198 lines
6.9 KiB
TypeScript
198 lines
6.9 KiB
TypeScript
import { ProjectSession, ChatMessage, DeliverableItem } from '../types/workbench';
|
|
import { RoleDefinition } from '../types/rbac';
|
|
import { UserProfile } from '../types/docgov';
|
|
|
|
const STORAGE_PREFIX = 'smdf_agent_workbench_';
|
|
|
|
export const STORAGE_KEYS = {
|
|
SESSIONS: `${STORAGE_PREFIX}sessions`,
|
|
ACTIVE_SESSION: `${STORAGE_PREFIX}active_session`,
|
|
MESSAGES: `${STORAGE_PREFIX}messages`,
|
|
DELIVERABLES: `${STORAGE_PREFIX}deliverables`,
|
|
DOC_CACHE: `${STORAGE_PREFIX}doc_cache`,
|
|
ROLES: `${STORAGE_PREFIX}roles`,
|
|
USERS: `${STORAGE_PREFIX}users`,
|
|
};
|
|
|
|
/**
|
|
* 默认预设项目会话
|
|
*/
|
|
export const DEFAULT_SESSIONS: ProjectSession[] = [
|
|
{
|
|
sessionId: 'sess-001',
|
|
projectId: 1,
|
|
title: '4K超高清荧光内窥镜系统',
|
|
deviceType: '硬管荧光腹腔内窥镜',
|
|
stage: 'V0.5',
|
|
stageLabel: 'V0.5 方案成型与法规对齐',
|
|
messageCount: 3,
|
|
updatedAt: '14:20',
|
|
},
|
|
{
|
|
sessionId: 'sess-002',
|
|
projectId: 2,
|
|
title: '便携式掌上无线超声诊断仪',
|
|
deviceType: '便携式超声探头',
|
|
stage: 'V0.1',
|
|
stageLabel: 'V0.1 需求摸底与产品定义',
|
|
messageCount: 2,
|
|
updatedAt: '昨天',
|
|
},
|
|
];
|
|
|
|
/**
|
|
* 默认预设消息流(按 sessionId 严格隔离)
|
|
*/
|
|
export const DEFAULT_MESSAGES: ChatMessage[] = [
|
|
// sess-001 专属对话 (4K超高清荧光内窥镜)
|
|
{
|
|
id: 'm-001-0',
|
|
sessionId: 'sess-001',
|
|
role: 'system',
|
|
content: '水木东方协同参谋小队已就位,当前项目进入【V0.5 方案成型与法规对齐】阶段。',
|
|
timestamp: '14:00',
|
|
},
|
|
{
|
|
id: 'm-001-1',
|
|
sessionId: 'sess-001',
|
|
role: 'assistant',
|
|
authorName: '水木东方协同参谋',
|
|
intentTag: '🎯 推进立项阶段',
|
|
content:
|
|
'张工您好!参谋小队已依据法规知识库完成《4K超高清荧光内窥镜系统立项与可行性报告》初稿编制。右侧已就绪块状结构化视图,您可以直接审阅或下达修改指令。',
|
|
timestamp: '14:02',
|
|
phaseEvents: [
|
|
{ step: '1', icon: '👥', label: '组装小队', status: 'completed' },
|
|
{ step: '2', icon: '📚', label: '检索法规', status: 'completed' },
|
|
{ step: '3', icon: '⚙️', label: '执行编制', status: 'completed' },
|
|
{ step: '4', icon: '🛡️', label: '门禁把关', status: 'completed' },
|
|
],
|
|
recommendedCases: [
|
|
{
|
|
docId: 'SMDF-MD-2025-09',
|
|
taskKey: 'feasibility_reg',
|
|
artifactTitle: '4K硬管内窥镜摄像系统注册申报经验',
|
|
sectionTitle: '电气安全与高频电刀抗扰度评价',
|
|
similarityScore: 0.89,
|
|
keyRegulations: ['GB 9706.1-2020', 'IEC 60601-1-2'],
|
|
summarySnippet:
|
|
'在型式检验中,腹腔内窥镜主机需特别注意电刀高频耦合对荧光信噪比的干扰,建议在前端光电接收处增加硬件陷波滤波。',
|
|
},
|
|
],
|
|
},
|
|
|
|
// sess-002 专属对话 (便携式掌上无线超声诊断仪)
|
|
{
|
|
id: 'm-002-0',
|
|
sessionId: 'sess-002',
|
|
role: 'system',
|
|
content: '水木东方协同参谋小队已就位,当前项目进入【V0.1 需求摸底与产品定义】阶段。',
|
|
timestamp: '09:30',
|
|
},
|
|
{
|
|
id: 'm-002-1',
|
|
sessionId: 'sess-002',
|
|
role: 'assistant',
|
|
authorName: '水木东方协同参谋',
|
|
intentTag: '💡 掌超项目摸底',
|
|
content:
|
|
'张工,便携式掌上无线超声诊断仪立项需求摸底已启动!\n\n小队已针对其换能器阵元数 (128阵元)、无线 Wi-Fi 6 低延迟图传以及 GB 9706.237-2020 超声声输出安全标准进行技术基线梳理。您可以直接提出需求调整或测算指令。',
|
|
timestamp: '09:35',
|
|
phaseEvents: [
|
|
{ step: '1', icon: '🔍', label: '超声盲区探测', status: 'completed' },
|
|
{ step: '2', icon: '📋', label: '声功率标准初筛', status: 'completed' },
|
|
],
|
|
},
|
|
];
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// 安全的 localStorage 存取包装器
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
function safeGetItem<T>(key: string, fallback: T): T {
|
|
if (typeof window === 'undefined' || !window.localStorage) return fallback;
|
|
try {
|
|
const item = window.localStorage.getItem(key);
|
|
if (!item) return fallback;
|
|
return JSON.parse(item) as T;
|
|
} catch (e) {
|
|
console.warn(`[storage] Failed to parse localStorage item: ${key}`, e);
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
function safeSetItem<T>(key: string, val: T): void {
|
|
if (typeof window === 'undefined' || !window.localStorage) return;
|
|
try {
|
|
window.localStorage.setItem(key, JSON.stringify(val));
|
|
} catch (e) {
|
|
console.warn(`[storage] Failed to set localStorage item: ${key}`, e);
|
|
}
|
|
}
|
|
|
|
export function loadSessions(): ProjectSession[] {
|
|
return safeGetItem<ProjectSession[]>(STORAGE_KEYS.SESSIONS, DEFAULT_SESSIONS);
|
|
}
|
|
|
|
export function saveSessions(sessions: ProjectSession[]): void {
|
|
safeSetItem(STORAGE_KEYS.SESSIONS, sessions);
|
|
}
|
|
|
|
export function loadActiveSessionId(fallback = 'sess-001'): string {
|
|
if (typeof window === 'undefined' || !window.localStorage) return fallback;
|
|
return window.localStorage.getItem(STORAGE_KEYS.ACTIVE_SESSION) || fallback;
|
|
}
|
|
|
|
export function saveActiveSessionId(sessionId: string): void {
|
|
if (typeof window === 'undefined' || !window.localStorage) return;
|
|
window.localStorage.setItem(STORAGE_KEYS.ACTIVE_SESSION, sessionId);
|
|
}
|
|
|
|
export function loadMessages(): ChatMessage[] {
|
|
return safeGetItem<ChatMessage[]>(STORAGE_KEYS.MESSAGES, DEFAULT_MESSAGES);
|
|
}
|
|
|
|
export function saveMessages(messages: ChatMessage[]): void {
|
|
safeSetItem(STORAGE_KEYS.MESSAGES, messages);
|
|
}
|
|
|
|
export function loadDeliverables(fallback: DeliverableItem[]): DeliverableItem[] {
|
|
return safeGetItem<DeliverableItem[]>(STORAGE_KEYS.DELIVERABLES, fallback);
|
|
}
|
|
|
|
export function saveDeliverables(deliverables: DeliverableItem[]): void {
|
|
safeSetItem(STORAGE_KEYS.DELIVERABLES, deliverables);
|
|
}
|
|
|
|
export function loadDocCache(): Record<string, string> {
|
|
return safeGetItem<Record<string, string>>(STORAGE_KEYS.DOC_CACHE, {});
|
|
}
|
|
|
|
export function saveDocCache(cache: Record<string, string>): void {
|
|
safeSetItem(STORAGE_KEYS.DOC_CACHE, cache);
|
|
}
|
|
|
|
export function loadRoles(fallback: RoleDefinition[]): RoleDefinition[] {
|
|
return safeGetItem<RoleDefinition[]>(STORAGE_KEYS.ROLES, fallback);
|
|
}
|
|
|
|
export function saveRoles(roles: RoleDefinition[]): void {
|
|
safeSetItem(STORAGE_KEYS.ROLES, roles);
|
|
}
|
|
|
|
export function loadUsers(fallback: UserProfile[]): UserProfile[] {
|
|
return safeGetItem<UserProfile[]>(STORAGE_KEYS.USERS, fallback);
|
|
}
|
|
|
|
export function saveUsers(users: UserProfile[]): void {
|
|
safeSetItem(STORAGE_KEYS.USERS, users);
|
|
}
|
|
|
|
/**
|
|
* resetWorkbenchStorage: 清空工作台缓存,恢复系统默认体验状态
|
|
*/
|
|
export function resetWorkbenchStorage(): void {
|
|
if (typeof window === 'undefined' || !window.localStorage) return;
|
|
Object.values(STORAGE_KEYS).forEach((k) => window.localStorage.removeItem(k));
|
|
}
|