feat(平台): 补齐服务端持久化和AI拆解契约
This commit is contained in:
@@ -3,8 +3,7 @@ import { create } from 'zustand';
|
||||
import type { Department, Member, RoleItem, PasswordRule } from '@/lib/members';
|
||||
import { DEFAULT_PASSWORD_RULE, generatePassword } from '@/lib/members';
|
||||
import { DEFAULT_ROLE_PERMISSIONS } from '@/lib/permissions';
|
||||
|
||||
const STORAGE_KEY = 'ftb_members_v1';
|
||||
import { loadServerData, saveServerData } from '@/lib/server-data';
|
||||
|
||||
const PRESET_DEPARTMENTS: Department[] = [
|
||||
{ id: 'dept-1', name: '产品部', order: 1, createdAt: '2024-01-01' },
|
||||
@@ -25,14 +24,7 @@ const PRESET_ROLES: RoleItem[] = [
|
||||
];
|
||||
|
||||
const MOCK_MEMBERS: Member[] = [
|
||||
{ id: 'm-1', name: '张三', departmentId: 'dept-1', roleId: 'role-pm', phone: '13800138001', email: 'zhangsan@company.com', password: 'Ftb@2024', createdAt: '2024-01-10' },
|
||||
{ id: 'm-2', name: '李四', departmentId: 'dept-2-1', roleId: 'role-dev', phone: '13900139002', email: 'lisi@company.com', password: 'Ftb@2024', createdAt: '2024-01-12' },
|
||||
{ id: 'm-3', name: '王五', departmentId: 'dept-2-2', roleId: 'role-dev', phone: '13700137003', email: 'wangwu@company.com', password: 'Ftb@2024', createdAt: '2024-01-15' },
|
||||
{ id: 'm-4', name: '赵六', departmentId: 'dept-2-3', roleId: 'role-test', phone: '13600136004', email: 'zhaoliu@company.com', password: 'Ftb@2024', createdAt: '2024-02-01' },
|
||||
{ id: 'm-5', name: '孙七', departmentId: 'dept-3', roleId: 'role-design', phone: '13500135005', email: 'sunqi@company.com', password: 'Ftb@2024', createdAt: '2024-02-10' },
|
||||
{ id: 'm-6', name: '周八', departmentId: 'dept-4', roleId: 'role-pm', phone: '13400134006', email: 'zhouba@company.com', password: 'Ftb@2024', createdAt: '2024-02-15' },
|
||||
{ id: 'm-7', name: '吴九', departmentId: 'dept-2-1', roleId: 'role-dev', phone: '13300133007', email: 'wujiu@company.com', password: 'Ftb@2024', createdAt: '2024-03-01' },
|
||||
{ id: 'm-8', name: '陈十', departmentId: 'dept-1', roleId: 'role-admin', phone: '13200132008', email: 'chenshi@company.com', password: 'Ftb@2024', createdAt: '2024-01-01' },
|
||||
{ id: 'm-8', name: '超级管理员', departmentId: 'dept-1', roleId: 'role-admin', phone: '13200132008', email: 'chenshi@company.com', password: 'Ftb@2024', createdAt: '2024-01-01' },
|
||||
];
|
||||
|
||||
interface MemberState {
|
||||
@@ -54,14 +46,13 @@ interface MemberState {
|
||||
deleteRole: (id: string) => void;
|
||||
}
|
||||
|
||||
function saveLocal(state: { departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule }) {
|
||||
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch {}
|
||||
function saveStored(state: { departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule }) {
|
||||
saveServerData('members', state).catch(() => {});
|
||||
}
|
||||
|
||||
function loadLocal(): { departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule } | null {
|
||||
async function loadStored(): Promise<{ departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule } | null> {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (raw) return JSON.parse(raw);
|
||||
return await loadServerData<{ departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule }>('members');
|
||||
} catch {}
|
||||
return null;
|
||||
}
|
||||
@@ -73,8 +64,8 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
passwordRule: DEFAULT_PASSWORD_RULE,
|
||||
loading: false,
|
||||
|
||||
fetchMembers: () => {
|
||||
const cached = loadLocal();
|
||||
fetchMembers: async () => {
|
||||
const cached = await loadStored();
|
||||
if (cached) {
|
||||
// 迁移:旧 RoleItem 没 permissions 字段,补默认值
|
||||
const migratedRoles = cached.roles.map((r) => {
|
||||
@@ -89,41 +80,41 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
|
||||
updatePasswordRule: (rule) => {
|
||||
set({ passwordRule: rule });
|
||||
saveLocal({ departments: get().departments, members: get().members, roles: get().roles, passwordRule: rule });
|
||||
saveStored({ departments: get().departments, members: get().members, roles: get().roles, passwordRule: rule });
|
||||
},
|
||||
|
||||
createDepartment: (data) => {
|
||||
const dept: Department = { ...data, id: `dept-${Date.now()}`, createdAt: new Date().toISOString().slice(0, 10) };
|
||||
const departments = [...get().departments, dept];
|
||||
set({ departments });
|
||||
saveLocal({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
updateDepartment: (id, data) => {
|
||||
const departments = get().departments.map((d) => d.id === id ? { ...d, ...data } : d);
|
||||
set({ departments });
|
||||
saveLocal({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
deleteDepartment: (id) => {
|
||||
const departments = get().departments.filter((d) => d.id !== id && d.parentId !== id);
|
||||
set({ departments });
|
||||
saveLocal({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments, members: get().members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
|
||||
createMember: (data) => {
|
||||
const member: Member = { ...data, id: `m-${Date.now()}`, createdAt: new Date().toISOString().slice(0, 10) };
|
||||
const members = [...get().members, member];
|
||||
set({ members });
|
||||
saveLocal({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
updateMember: (id, data) => {
|
||||
const members = get().members.map((m) => m.id === id ? { ...m, ...data } : m);
|
||||
set({ members });
|
||||
saveLocal({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
deleteMember: (id) => {
|
||||
const members = get().members.filter((m) => m.id !== id);
|
||||
set({ members });
|
||||
saveLocal({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
|
||||
createRole: (data) => {
|
||||
@@ -135,7 +126,7 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
};
|
||||
const roles = [...get().roles, role];
|
||||
set({ roles });
|
||||
saveLocal({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
updateRole: (id, data) => {
|
||||
const roles = get().roles.map((r) => {
|
||||
@@ -148,11 +139,11 @@ export const useMemberStore = create<MemberState>((set, get) => ({
|
||||
return { ...r, ...data };
|
||||
});
|
||||
set({ roles });
|
||||
saveLocal({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
deleteRole: (id) => {
|
||||
const roles = get().roles.filter((r) => r.id !== id);
|
||||
set({ roles });
|
||||
saveLocal({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule });
|
||||
saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule });
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user