import { defineStore } from "pinia"; import axios from "axios"; const TOKEN_KEY = "craftlabs_platform_token"; const AUTH_KEY = "craftlabs_platform_auth"; function decodeJwtPayload(token) { try { const parts = token.split("."); if (parts.length !== 3) return null; const payload = parts[1]; const latin1 = atob(payload.replace(/-/g, "+").replace(/_/g, "/")); // atob 返回 Latin-1 编码,需转为 UTF-8 才能正确解析中文 const bytes = Uint8Array.from(latin1, (c) => c.charCodeAt(0)); const decoded = new TextDecoder().decode(bytes); return JSON.parse(decoded); } catch { return null; } } function restoreAuth() { const token = localStorage.getItem(TOKEN_KEY); if (!token) return { token: "", displayName: "", roles: [], permissions: [] }; const saved = localStorage.getItem(AUTH_KEY); if (saved) { try { return { token, ...JSON.parse(saved) }; } catch { /* ignore */ } } const claims = decodeJwtPayload(token); if (claims) { return { token, displayName: claims.displayName || claims.sub || "", roles: claims.roles || [], permissions: [], }; } return { token: "", displayName: "", roles: [], permissions: [] }; } export const useAuthStore = defineStore("auth", { state: () => ({ ...restoreAuth(), }), getters: { hasAnyRole: (state) => { return (roleList) => { const need = roleList || []; const have = state.roles || []; return need.some((r) => have.includes(r)); }; }, }, actions: { async login(username, password) { let data; try { const res = await axios.post("/api/v1/auth/login", { username, password }); data = res.data; } catch { // Demo mode: no backend available, use mock login if (username === "admin" || username === "demo") { data = { token: "demo-token-xxx", displayName: "管理员", roles: ["SYS_ADMIN"], permissions: ["*"] }; } else { throw new Error("无法连接登录接口(原型模式无后端)"); } } this.token = data.token; this.displayName = data.displayName || username; this.roles = data.roles || []; this.permissions = data.permissions || []; localStorage.setItem(TOKEN_KEY, this.token); localStorage.setItem(AUTH_KEY, JSON.stringify({ displayName: this.displayName, roles: this.roles, permissions: this.permissions })); axios.defaults.headers.common.Authorization = `Bearer ${this.token}`; }, logout() { this.token = ""; this.displayName = ""; this.roles = []; this.permissions = []; localStorage.removeItem(TOKEN_KEY); localStorage.removeItem(AUTH_KEY); delete axios.defaults.headers.common.Authorization; if (window.__idleCleanup) { window.__idleCleanup() delete window.__idleCleanup } }, restoreAxiosAuth() { if (this.token) { axios.defaults.headers.common.Authorization = `Bearer ${this.token}`; } }, }, });