feat: 完善文档中心与报销申请交互及侧边栏重构

后端优化编排器报销查询和本体检测精度,增强报销单草稿保
存和附件回填逻辑,前端重构侧边栏组件支持折叠和图标导
航,完善文档中心状态筛选和详情提示,报销创建和审批详情
页优化会话管理和费用明细交互,新增助手应用服务和预设动
作工具函数,补充单元测试覆盖。
This commit is contained in:
caoxiaozhu
2026-05-25 13:35:39 +08:00
parent 50b1c3f9a9
commit d0e946cf47
59 changed files with 5117 additions and 416 deletions

View File

@@ -0,0 +1,71 @@
const STORAGE_KEY = 'x-financial.documents.viewed'
const SCOPE_STORAGE_KEY = 'x-financial.documents.scope'
function getStorage() {
return typeof window === 'undefined' ? null : window.localStorage
}
export function resolveDocumentNewKey(row) {
const source = String(row?.source || 'document').trim()
const id = String(row?.claimId || row?.documentNo || row?.documentKey || row?.id || '').trim()
return id ? `${source}:${id}` : ''
}
export function readViewedDocumentKeys(storage = getStorage()) {
if (!storage) {
return new Set()
}
try {
const parsed = JSON.parse(storage.getItem(STORAGE_KEY) || '[]')
return new Set(Array.isArray(parsed) ? parsed.map((item) => String(item || '').trim()).filter(Boolean) : [])
} catch {
return new Set()
}
}
export function writeViewedDocumentKeys(keys, storage = getStorage()) {
if (!storage) {
return
}
storage.setItem(STORAGE_KEY, JSON.stringify(Array.from(keys).filter(Boolean)))
}
export function readDocumentScope(fallback, allowedScopes = [], storage = getStorage()) {
if (!storage) {
return fallback
}
const storedScope = String(storage.getItem(SCOPE_STORAGE_KEY) || '').trim()
return allowedScopes.includes(storedScope) ? storedScope : fallback
}
export function writeDocumentScope(scope, allowedScopes = [], storage = getStorage()) {
if (!storage || !allowedScopes.includes(scope)) {
return
}
storage.setItem(SCOPE_STORAGE_KEY, scope)
}
export function isNewDocument(row, viewedKeys) {
const key = resolveDocumentNewKey(row)
return Boolean(key) && !viewedKeys.has(key)
}
export function countNewDocuments(rows, viewedKeys) {
return rows.filter((row) => isNewDocument(row, viewedKeys)).length
}
export function markDocumentViewed(row, viewedKeys, storage = getStorage()) {
const key = resolveDocumentNewKey(row)
if (!key) {
return viewedKeys
}
const nextKeys = new Set(viewedKeys)
nextKeys.add(key)
writeViewedDocumentKeys(nextKeys, storage)
return nextKeys
}