Files
ftb-project-management/apps/web/stores/useAuthStore.ts
Script Generator 7c49868c4f feat: 个人中心管理(编辑信息 + 修改密码 + 退出登录)
- 新增 /profile 路由:两个 Tab(个人信息 / 修改密码)+ 退出按钮
- Sidebar 底部用户区改造:绑定真实登录用户(头像/姓名/角色)+ 加 Settings icon 跳 /profile
- useAuthStore 加 refreshUser:保存信息后立即同步 Sidebar 显示
- 个人信息表单:姓名/手机/邮箱可改,部门/角色只读,复用 updateMember
- 密码修改:原密 + 新密(≥8位且≠原密) + 确认 三档校验,眼睛 icon 切换可见,下次登录生效
- 退出登录:confirm → useAuthStore.logout → /login

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-16 19:51:22 +08:00

111 lines
4.0 KiB
TypeScript

'use client';
import { create } from 'zustand';
interface AuthUser {
id: string;
name: string;
roleId: string;
departmentId: string;
phone: string;
email: string;
}
interface AuthState {
user: AuthUser | null;
isAuthenticated: boolean;
login: (phone: string, password: string, remember: boolean) => boolean;
logout: () => void;
checkAuth: () => void;
refreshUser: () => void;
}
const SESSION_KEY = 'ftb_auth_session';
const PERSIST_KEY = 'ftb_auth_persist';
export const useAuthStore = create<AuthState>((set) => ({
user: null,
isAuthenticated: false,
login: (phone, password, remember) => {
const membersRaw = localStorage.getItem('ftb_members_v1');
let members: any[] = [];
if (membersRaw) {
const parsed = JSON.parse(membersRaw);
members = parsed.members || [];
}
// fallback: 如果 localStorage 没有数据或为空,使用默认 mock
if (members.length === 0) {
members = [
{ id: 'm-1', name: '张三', departmentId: 'dept-1', roleId: 'role-pm', phone: '13800138001', email: 'zhangsan@company.com', password: 'Ftb@2024' },
{ id: 'm-2', name: '李四', departmentId: 'dept-2-1', roleId: 'role-dev', phone: '13900139002', email: 'lisi@company.com', password: 'Ftb@2024' },
{ id: 'm-3', name: '王五', departmentId: 'dept-2-2', roleId: 'role-dev', phone: '13700137003', email: 'wangwu@company.com', password: 'Ftb@2024' },
{ id: 'm-4', name: '赵六', departmentId: 'dept-2-3', roleId: 'role-test', phone: '13600136004', email: 'zhaoliu@company.com', password: 'Ftb@2024' },
{ id: 'm-5', name: '孙七', departmentId: 'dept-3', roleId: 'role-design', phone: '13500135005', email: 'sunqi@company.com', password: 'Ftb@2024' },
{ id: 'm-6', name: '周八', departmentId: 'dept-4', roleId: 'role-pm', phone: '13400134006', email: 'zhouba@company.com', password: 'Ftb@2024' },
{ id: 'm-7', name: '吴九', departmentId: 'dept-2-1', roleId: 'role-dev', phone: '13300133007', email: 'wujiu@company.com', password: 'Ftb@2024' },
{ id: 'm-8', name: '陈十', departmentId: 'dept-1', roleId: 'role-admin', phone: '13200132008', email: 'chenshi@company.com', password: 'Ftb@2024' },
];
}
const member = members.find((m: any) => m.phone === phone && (m.password || 'Ftb@2024') === password);
if (!member) return false;
const user: AuthUser = {
id: member.id,
name: member.name,
roleId: member.roleId,
departmentId: member.departmentId,
phone: member.phone,
email: member.email,
};
set({ user, isAuthenticated: true });
sessionStorage.setItem(SESSION_KEY, JSON.stringify(user));
if (remember) {
localStorage.setItem(PERSIST_KEY, JSON.stringify(user));
}
return true;
},
logout: () => {
set({ user: null, isAuthenticated: false });
sessionStorage.removeItem(SESSION_KEY);
localStorage.removeItem(PERSIST_KEY);
},
checkAuth: () => {
const session = sessionStorage.getItem(SESSION_KEY);
if (session) {
set({ user: JSON.parse(session), isAuthenticated: true });
return;
}
const persist = localStorage.getItem(PERSIST_KEY);
if (persist) {
const user = JSON.parse(persist);
set({ user, isAuthenticated: true });
sessionStorage.setItem(SESSION_KEY, JSON.stringify(user));
return;
}
},
refreshUser: () => {
const cur = useAuthStore.getState().user;
if (!cur) return;
try {
const raw = localStorage.getItem('ftb_members_v1');
if (!raw) return;
const parsed = JSON.parse(raw);
const m = parsed.members?.find((x: any) => x.id === cur.id);
if (!m) return;
const next: AuthUser = { id: m.id, name: m.name, roleId: m.roleId, departmentId: m.departmentId, phone: m.phone, email: m.email };
useAuthStore.setState({ user: next });
sessionStorage.setItem(SESSION_KEY, JSON.stringify(next));
if (localStorage.getItem(PERSIST_KEY)) {
localStorage.setItem(PERSIST_KEY, JSON.stringify(next));
}
} catch {}
},
}));