fix: 第一轮修复 - 记忆管理/IoT操控/历史消息持久化/动作消息/链路优化/安全配置
- 修复记忆管理数据库连接不可用 (ai-core重编译+Unicode修复) - 修复IoT子会话工具调用链路日志缺失 - 新增最终审查子会话(review_provider) 支持消息格式解析拆分 - 实现历史消息持久化(后端存储+前端分页加载) - 前端新增动作消息(ActionMessage)类型和渲染 - 优化对话链路速度(非阻塞子会话+快速问候通道) - JWT密钥环境变量化(无默认值启动panic) - Token自动刷新机制(401拦截器+refresh接口) - WebSocket指数退避重连(jitter+最大10次) - localStorage清理一致性(cyrene_前缀+版本检查) - IoT环境变量统一为IOT_SERVICE_URL
This commit is contained in:
@@ -3,24 +3,58 @@
|
||||
* 用于跨组件共享登录/退出状态
|
||||
*/
|
||||
import { create } from 'zustand';
|
||||
import { login as apiLogin, register as apiRegister, clearToken, isAuthenticated, getToken } from '@/api/client';
|
||||
import { login as apiLogin, register as apiRegister, clearToken, isAuthenticated, getToken, getRefreshToken, setTokens } from '@/api/client';
|
||||
|
||||
/** localStorage key 前缀 */
|
||||
const LS_VERSION_KEY = 'cyrene_store_version';
|
||||
const CURRENT_VERSION = 1;
|
||||
|
||||
/** 所有 cyrene_ 前缀的 localStorage keys,logout 时全部清除 */
|
||||
const CYRENE_KEYS = [
|
||||
'token',
|
||||
'refresh_token',
|
||||
'user_id',
|
||||
'user_nickname',
|
||||
'cyrene_store_version',
|
||||
];
|
||||
|
||||
function clearAllCyreneData(): void {
|
||||
for (const key of CYRENE_KEYS) {
|
||||
try {
|
||||
localStorage.removeItem(key);
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
interface AuthStore {
|
||||
isLoggedIn: boolean;
|
||||
userId: string | null;
|
||||
token: string | null;
|
||||
refreshToken: string | null;
|
||||
loading: boolean;
|
||||
login: (username: string, password: string) => Promise<{ success: boolean; error?: string }>;
|
||||
register: (username: string, password: string, email: string, nickname: string, verifyCode: string) => Promise<{ success: boolean; error?: string }>;
|
||||
logout: () => void;
|
||||
setTokens: (accessToken: string, refreshToken?: string) => void;
|
||||
clearAuth: () => void;
|
||||
}
|
||||
|
||||
export const useAuthStore = create<AuthStore>((set) => ({
|
||||
isLoggedIn: isAuthenticated(),
|
||||
userId: localStorage.getItem('user_id'),
|
||||
token: getToken(),
|
||||
refreshToken: getRefreshToken(),
|
||||
loading: false,
|
||||
|
||||
setTokens: (accessToken: string, refreshTokenValue?: string) => {
|
||||
setTokens(accessToken, refreshTokenValue);
|
||||
set({
|
||||
isLoggedIn: true,
|
||||
token: accessToken,
|
||||
refreshToken: refreshTokenValue || null,
|
||||
});
|
||||
},
|
||||
|
||||
login: async (username: string, password: string) => {
|
||||
set({ loading: true });
|
||||
try {
|
||||
@@ -33,6 +67,7 @@ export const useAuthStore = create<AuthStore>((set) => ({
|
||||
isLoggedIn: true,
|
||||
userId: resp.data?.user_id || null,
|
||||
token: resp.data?.token || null,
|
||||
refreshToken: resp.data?.refresh_token || null,
|
||||
loading: false,
|
||||
});
|
||||
return { success: true };
|
||||
@@ -58,6 +93,7 @@ export const useAuthStore = create<AuthStore>((set) => ({
|
||||
isLoggedIn: true,
|
||||
userId: resp.data?.user_id || null,
|
||||
token: resp.data?.token || null,
|
||||
refreshToken: resp.data?.refresh_token || null,
|
||||
loading: false,
|
||||
});
|
||||
return { success: true };
|
||||
@@ -69,16 +105,50 @@ export const useAuthStore = create<AuthStore>((set) => ({
|
||||
|
||||
logout: () => {
|
||||
clearToken();
|
||||
localStorage.removeItem('user_nickname');
|
||||
clearAllCyreneData();
|
||||
set({
|
||||
isLoggedIn: false,
|
||||
userId: null,
|
||||
token: null,
|
||||
refreshToken: null,
|
||||
loading: false,
|
||||
});
|
||||
},
|
||||
|
||||
clearAuth: () => {
|
||||
clearToken();
|
||||
clearAllCyreneData();
|
||||
set({
|
||||
isLoggedIn: false,
|
||||
userId: null,
|
||||
token: null,
|
||||
refreshToken: null,
|
||||
loading: false,
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
/**
|
||||
* 在应用启动时检查 localStorage 数据版本
|
||||
* 如果版本不兼容,清除所有数据
|
||||
*/
|
||||
export function checkAndMigrateStore(): void {
|
||||
try {
|
||||
const storedVersion = localStorage.getItem(LS_VERSION_KEY);
|
||||
if (storedVersion) {
|
||||
const version = parseInt(storedVersion, 10);
|
||||
if (version !== CURRENT_VERSION) {
|
||||
console.log(`[store] localStorage 版本不兼容 (${version} → ${CURRENT_VERSION}),清除旧数据`);
|
||||
clearAllCyreneData();
|
||||
}
|
||||
}
|
||||
// 写入当前版本
|
||||
localStorage.setItem(LS_VERSION_KEY, String(CURRENT_VERSION));
|
||||
} catch {
|
||||
// 忽略存储错误
|
||||
}
|
||||
}
|
||||
|
||||
/** 兼容旧代码的 Hook 导出 */
|
||||
export function useAuth() {
|
||||
return useAuthStore();
|
||||
|
||||
Reference in New Issue
Block a user