'use client'; import { create } from 'zustand'; import type { Department, Member, RoleItem, PasswordRule } from '@/lib/members'; import { DEFAULT_PASSWORD_RULE, generatePassword } from '@/lib/members'; import { SYSTEM_ADMIN_MEMBER, SYSTEM_ADMIN_ROLE_ID, canDeleteSystemMember, ensureSystemAdminMember, sanitizeSystemAdminPatch, } from '@/lib/member-system'; import { DEFAULT_ROLE_PERMISSIONS } from '@/lib/permissions'; import { loadServerData, saveServerData } from '@/lib/server-data'; const PRESET_DEPARTMENTS: Department[] = [ { id: 'dept-1', name: '产品部', order: 1, createdAt: '2024-01-01' }, { id: 'dept-2', name: '技术部', order: 2, createdAt: '2024-01-01' }, { id: 'dept-2-1', name: '前端组', parentId: 'dept-2', order: 1, createdAt: '2024-01-01' }, { id: 'dept-2-2', name: '后端组', parentId: 'dept-2', order: 2, createdAt: '2024-01-01' }, { id: 'dept-2-3', name: '测试组', parentId: 'dept-2', order: 3, createdAt: '2024-01-01' }, { id: 'dept-3', name: '设计部', order: 3, createdAt: '2024-01-01' }, { id: 'dept-4', name: '运营部', order: 4, createdAt: '2024-01-01' }, ]; const PRESET_ROLES: RoleItem[] = [ { id: 'role-admin', name: '超级管理员', description: '拥有系统全部权限', createdAt: '2024-01-01', isSystem: true, permissions: DEFAULT_ROLE_PERMISSIONS['role-admin'] }, { id: 'role-pm', name: '产品经理', description: '管理产品和需求', createdAt: '2024-01-01', permissions: DEFAULT_ROLE_PERMISSIONS['role-pm'] }, { id: 'role-dev', name: '开发工程师', description: '负责开发任务', createdAt: '2024-01-01', permissions: DEFAULT_ROLE_PERMISSIONS['role-dev'] }, { id: 'role-test', name: '测试工程师', description: '负责测试任务', createdAt: '2024-01-01', permissions: DEFAULT_ROLE_PERMISSIONS['role-test'] }, { id: 'role-design', name: '设计师', description: '负责UI/UX设计', createdAt: '2024-01-01', permissions: DEFAULT_ROLE_PERMISSIONS['role-design'] }, ]; const MOCK_MEMBERS: Member[] = [ SYSTEM_ADMIN_MEMBER, ]; interface MemberState { departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule; loading: boolean; fetchMembers: () => void; updatePasswordRule: (rule: PasswordRule) => void; createDepartment: (data: Omit) => void; updateDepartment: (id: string, data: Partial) => void; deleteDepartment: (id: string) => void; createMember: (data: Omit) => void; updateMember: (id: string, data: Partial) => void; deleteMember: (id: string) => void; createRole: (data: Omit) => void; updateRole: (id: string, data: Partial) => void; deleteRole: (id: string) => void; } function saveStored(state: { departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule }) { saveServerData('members', state).catch(() => {}); } async function loadStored(): Promise<{ departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule } | null> { try { return await loadServerData<{ departments: Department[]; members: Member[]; roles: RoleItem[]; passwordRule: PasswordRule }>('members'); } catch {} return null; } export const useMemberStore = create((set, get) => ({ departments: PRESET_DEPARTMENTS, members: MOCK_MEMBERS, roles: PRESET_ROLES, passwordRule: DEFAULT_PASSWORD_RULE, loading: false, fetchMembers: async () => { const cached = await loadStored(); if (cached) { // 迁移:旧 RoleItem 没 permissions 字段,补默认值 const migratedRoles = cached.roles.map((r) => { if (!('permissions' in r) || !Array.isArray((r as any).permissions)) { return { ...r, permissions: DEFAULT_ROLE_PERMISSIONS[r.id] ?? [] }; } return r; }); const adminRole = PRESET_ROLES.find((r) => r.id === SYSTEM_ADMIN_ROLE_ID)!; const roles = migratedRoles.some((r) => r.id === SYSTEM_ADMIN_ROLE_ID) ? migratedRoles.map((r) => r.id === SYSTEM_ADMIN_ROLE_ID ? { ...adminRole, ...r, isSystem: true, permissions: DEFAULT_ROLE_PERMISSIONS[SYSTEM_ADMIN_ROLE_ID] } : r) : [adminRole, ...migratedRoles]; const rolesChanged = roles.length !== migratedRoles.length || roles.some((role, index) => JSON.stringify(role) !== JSON.stringify(migratedRoles[index])); const ensured = ensureSystemAdminMember(cached.members); const next = { departments: cached.departments, members: ensured.members, roles, passwordRule: cached.passwordRule || DEFAULT_PASSWORD_RULE, }; set(next); if (ensured.changed || rolesChanged) saveStored(next); } }, updatePasswordRule: (rule) => { set({ 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 }); 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 }); 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 }); 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 }); saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule }); }, updateMember: (id, data) => { const safeData = sanitizeSystemAdminPatch(id, data); const updatedMembers = get().members.map((m) => m.id === id ? { ...m, ...safeData } : m); const ensured = ensureSystemAdminMember(updatedMembers); set({ members: ensured.members }); saveStored({ departments: get().departments, members: ensured.members, roles: get().roles, passwordRule: get().passwordRule }); }, deleteMember: (id) => { if (!canDeleteSystemMember(id)) return; const members = get().members.filter((m) => m.id !== id); set({ members }); saveStored({ departments: get().departments, members, roles: get().roles, passwordRule: get().passwordRule }); }, createRole: (data) => { const role: RoleItem = { ...data, id: `role-${Date.now()}`, createdAt: new Date().toISOString().slice(0, 10), permissions: data.permissions ?? [], }; const roles = [...get().roles, role]; set({ roles }); saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }); }, updateRole: (id, data) => { const roles = get().roles.map((r) => { if (r.id !== id) return r; // 超管不允许改 permissions(防误操作锁死系统) if (r.id === 'role-admin' && data.permissions) { const { permissions, ...rest } = data; return { ...r, ...rest }; } return { ...r, ...data }; }); set({ roles }); saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }); }, deleteRole: (id) => { if (id === SYSTEM_ADMIN_ROLE_ID) return; const roles = get().roles.filter((r) => r.id !== id); set({ roles }); saveStored({ departments: get().departments, members: get().members, roles, passwordRule: get().passwordRule }); }, }));