From 7fc1fa3727b40601f32cd56b947d7558749d94bb Mon Sep 17 00:00:00 2001 From: huangping Date: Tue, 9 Jun 2026 09:45:10 +0800 Subject: [PATCH] feat: add demo mode for prototype deployment (no backend) --- web/delivery-platform-ui/src/stores/auth.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/web/delivery-platform-ui/src/stores/auth.js b/web/delivery-platform-ui/src/stores/auth.js index f4f5737..540b623 100644 --- a/web/delivery-platform-ui/src/stores/auth.js +++ b/web/delivery-platform-ui/src/stores/auth.js @@ -9,7 +9,10 @@ function decodeJwtPayload(token) { const parts = token.split("."); if (parts.length !== 3) return null; const payload = parts[1]; - const decoded = atob(payload.replace(/-/g, "+").replace(/_/g, "/")); + 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; @@ -55,7 +58,18 @@ export const useAuthStore = defineStore("auth", { }, actions: { async login(username, password) { - const { data } = await axios.post("/api/v1/auth/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 || [];