feat(演示): 持久化 Mock 数据并打通文档库发起签署闭环

This commit is contained in:
yelan
2026-09-14 14:28:51 +08:00
parent f4e2671da6
commit d34ef0a0ce
8 changed files with 260 additions and 9 deletions
@@ -0,0 +1,62 @@
/**
* 本地演示文书库的读取与转换(仅 Mock 模式)。
*
* 管理端文档库的数据只存在前端:科室在 Word 编辑器里建好文书后写进 localStorage。
* 文档库页面和签署侧的模板列表都要读这份数据,共享同一份读取逻辑,
* 否则会出现「文档库刚建好文书,签署工作台却选不到」。
*
* 这里只声明实际用到的字段,不绑定文档库页面的类型,避免 api 层反向依赖 views。
*/
import type { SigningMethod, SigningTemplate } from '@/api/workbench/types'
import { MOCK_STORAGE_KEYS, readMockState } from './mock-storage'
interface LocalDocument {
id: string
name: string
code: string
version: string
description?: string
versionId?: string
departmentId?: string | null
campusId?: string | null
contentHtml?: string
}
interface LocalCategory {
name: string
documents: LocalDocument[]
}
interface LocalDepartment {
key: string
name: string
categories: LocalCategory[]
}
/**
* 把本地保存的文档库摊平成签署模板。
* 科室刚建好的文书因此能直接在签署工作台、文档库「发起」里选到。
*/
export function readLocalSigningTemplates(): SigningTemplate[] {
const departments = readMockState<LocalDepartment[]>(MOCK_STORAGE_KEYS.documentLibrary) ?? []
return departments.flatMap((department) =>
(department.categories ?? []).flatMap((category) =>
(category.documents ?? []).map((document) => ({
id: document.id,
versionId: document.versionId ?? document.id,
name: document.name,
code: document.code,
version: document.version,
department: department.name,
departmentId: document.departmentId ?? null,
campusId: document.campusId ?? undefined,
category: category.name,
description: document.description ?? '',
supportedMethods: ['pad', 'sms'] as SigningMethod[],
contentHtml: document.contentHtml,
})),
),
)
}
+46
View File
@@ -0,0 +1,46 @@
/**
* 演示数据的本地持久化(仅 Mock 模式使用)。
*
* 文档库与签署任务的演示数据原本只存在模块内存里,刷新页面就回到初始状态,
* 自测「文档库建文书 → 发起签署 → 签署 → 查看留痕」每次都要重来一遍。
* 这里把这份数据镜像到 localStorage,刷新后可以接着测。
*
* 只存演示数据,不涉及登录态、权限或真实患者信息;写入失败(容量超限、
* 浏览器禁用存储)时静默降级为纯内存数据,不打断正在进行的操作。
*/
const STORAGE_PREFIX = 'medical-sign:mock:'
/** 演示数据键名:清空演示数据时按这里的清单统一清理 */
export const MOCK_STORAGE_KEYS = {
documentLibrary: `${STORAGE_PREFIX}document-library`,
signingTasks: `${STORAGE_PREFIX}signing-tasks`,
} as const
export function readMockState<T>(key: string): T | null {
try {
const raw = window.localStorage.getItem(key)
return raw ? (JSON.parse(raw) as T) : null
} catch {
// 存储被禁用,或存量数据与当前结构不兼容:按「没有本地数据」处理,页面照常初始化
return null
}
}
export function writeMockState(key: string, value: unknown): void {
try {
window.localStorage.setItem(key, JSON.stringify(value))
} catch {
// 容量超限或存储被禁用:退化为纯内存演示数据,不打扰使用者
}
}
/** 清空全部演示数据,调用方负责重新加载数据或刷新页面 */
export function clearMockState(): void {
try {
Object.values(MOCK_STORAGE_KEYS).forEach((key) => window.localStorage.removeItem(key))
} catch {
// 存储不可用时本来就无需清理
}
}