fix(data): 增加全局保存失败保护
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
ensureSystemAdminMember,
|
||||
sanitizeSystemAdminPatch,
|
||||
} from '@/lib/member-system';
|
||||
import { scheduleSaveWithOptimisticRollback } from '@/lib/optimistic-persistence';
|
||||
import { DEFAULT_ROLE_PERMISSIONS, DEFAULT_ROLE_PRESETS } from '@/lib/permissions';
|
||||
import { mergePresetRolePermissions } from '@/lib/role-permission-migration';
|
||||
import { loadServerData, saveServerData, SERVER_DATA_CACHE_MS } from '@/lib/server-data';
|
||||
@@ -108,38 +109,68 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
},
|
||||
|
||||
updatePasswordRule: (rule) => {
|
||||
const previous = get().passwordRule;
|
||||
set({ passwordRule: rule });
|
||||
void saveStored({ departments: get().departments, members: get().members, roles: get().roles, passwordRule: rule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments: get().departments, members: get().members, roles: get().roles, passwordRule: rule }),
|
||||
expected: rule,
|
||||
getCurrent: () => get().passwordRule,
|
||||
rollback: () => set({ passwordRule: previous }),
|
||||
});
|
||||
},
|
||||
|
||||
createDepartment: (data) => {
|
||||
const previous = get().departments;
|
||||
const dept: Department = { ...data, id: `dept-${Date.now()}`, createdAt: new Date().toISOString().slice(0, 10) };
|
||||
const departments = [...get().departments, dept];
|
||||
const departments = [...previous, dept];
|
||||
set({ departments });
|
||||
void saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule }),
|
||||
expected: departments,
|
||||
getCurrent: () => get().departments,
|
||||
rollback: () => set({ departments: previous }),
|
||||
});
|
||||
},
|
||||
updateDepartment: (id, data) => {
|
||||
const departments = get().departments.map((d) => d.id === id ? { ...d, ...data } : d);
|
||||
const previous = get().departments;
|
||||
const departments = previous.map((d) => d.id === id ? { ...d, ...data } : d);
|
||||
set({ departments });
|
||||
void saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule }),
|
||||
expected: departments,
|
||||
getCurrent: () => get().departments,
|
||||
rollback: () => set({ departments: previous }),
|
||||
});
|
||||
},
|
||||
deleteDepartment: (id) => {
|
||||
const departments = get().departments.filter((d) => d.id !== id && d.parentId !== id);
|
||||
const previous = get().departments;
|
||||
const departments = previous.filter((d) => d.id !== id && d.parentId !== id);
|
||||
set({ departments });
|
||||
void saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule }),
|
||||
expected: departments,
|
||||
getCurrent: () => get().departments,
|
||||
rollback: () => set({ departments: previous }),
|
||||
});
|
||||
},
|
||||
|
||||
createMember: (data) => {
|
||||
const previous = get().members;
|
||||
const member: Member = {
|
||||
...data,
|
||||
username: data.username || generateUsernameFromName(data.name, get().members.map((m) => m.username ?? '')),
|
||||
username: data.username || generateUsernameFromName(data.name, previous.map((m) => m.username ?? '')),
|
||||
phone: data.phone ?? '',
|
||||
id: `m-${Date.now()}`,
|
||||
createdAt: new Date().toISOString().slice(0, 10),
|
||||
};
|
||||
const members = [...get().members, member];
|
||||
const members = [...previous, member];
|
||||
set({ members });
|
||||
void saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule }),
|
||||
expected: members,
|
||||
getCurrent: () => get().members,
|
||||
rollback: () => set({ members: previous }),
|
||||
});
|
||||
},
|
||||
updateMember: async (id, data) => {
|
||||
const previousMembers = get().members;
|
||||
@@ -156,24 +187,37 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
},
|
||||
deleteMember: (id) => {
|
||||
if (!canDeleteSystemMember(id)) return;
|
||||
const members = get().members.filter((m) => m.id !== id);
|
||||
const previous = get().members;
|
||||
const members = previous.filter((m) => m.id !== id);
|
||||
set({ members });
|
||||
void saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule }),
|
||||
expected: members,
|
||||
getCurrent: () => get().members,
|
||||
rollback: () => set({ members: previous }),
|
||||
});
|
||||
},
|
||||
|
||||
createRole: (data) => {
|
||||
const previous = get().roles;
|
||||
const role: RoleItem = {
|
||||
...data,
|
||||
id: `role-${Date.now()}`,
|
||||
createdAt: new Date().toISOString().slice(0, 10),
|
||||
permissions: data.permissions ?? [],
|
||||
};
|
||||
const roles = [...get().roles, role];
|
||||
const roles = [...previous, role];
|
||||
set({ roles });
|
||||
void saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }),
|
||||
expected: roles,
|
||||
getCurrent: () => get().roles,
|
||||
rollback: () => set({ roles: previous }),
|
||||
});
|
||||
},
|
||||
updateRole: (id, data) => {
|
||||
const roles = get().roles.map((r) => {
|
||||
const previous = get().roles;
|
||||
const roles = previous.map((r) => {
|
||||
if (r.id !== id) return r;
|
||||
// 超管不允许改 permissions(防误操作锁死系统)
|
||||
if (r.id === 'role-admin' && data.permissions) {
|
||||
@@ -183,12 +227,23 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
return { ...r, ...data };
|
||||
});
|
||||
set({ roles });
|
||||
void saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }),
|
||||
expected: roles,
|
||||
getCurrent: () => get().roles,
|
||||
rollback: () => set({ roles: previous }),
|
||||
});
|
||||
},
|
||||
deleteRole: (id) => {
|
||||
if (id === SYSTEM_ADMIN_ROLE_ID) return;
|
||||
const roles = get().roles.filter((r) => r.id !== id);
|
||||
const previous = get().roles;
|
||||
const roles = previous.filter((r) => r.id !== id);
|
||||
set({ roles });
|
||||
void saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }).catch(() => {});
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }),
|
||||
expected: roles,
|
||||
getCurrent: () => get().roles,
|
||||
rollback: () => set({ roles: previous }),
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user