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
+33 -2
View File
@@ -1,6 +1,8 @@
import axios from 'axios'
import { unwrapApiResponse } from '@/utils/api-response'
import { readLocalSigningTemplates } from '@/utils/mock-document-library'
import { MOCK_STORAGE_KEYS, readMockState, writeMockState } from '@/utils/mock-storage'
import { request } from '@/utils/request'
import { resendSigningSms as resendSigningSmsDelivery } from './deliveries'
@@ -215,7 +217,7 @@ const mockTemplates: SigningTemplate[] = [
},
]
const mockRecords: SigningTaskRecord[] = [
const defaultMockRecords: SigningTaskRecord[] = [
{
id: 'task-001',
templateVersionId: 'tpl-001-v2',
@@ -325,6 +327,17 @@ const mockRecords: SigningTaskRecord[] = [
},
]
/**
* 演示任务记录:优先用本地保存的,刷新后仍保留(任务固化的文书 HTML、签名图都在里面)。
* 所有写操作都要调用 persistMockRecords 落盘,否则刷新会回到切换前的状态。
*/
const mockRecords: SigningTaskRecord[] =
readMockState<SigningTaskRecord[]>(MOCK_STORAGE_KEYS.signingTasks) ?? defaultMockRecords
function persistMockRecords() {
writeMockState(MOCK_STORAGE_KEYS.signingTasks, mockRecords)
}
function clonePatient(patient: PatientProfile): PatientProfile {
return {
...patient,
@@ -371,6 +384,11 @@ function addHours(value: string, hours: number) {
export const isSigningMockEnabled = useMockData
/** 演示患者清单(仅 Mock 模式):给签署弹窗做“点一下就能定位”的输入提示 */
export function getMockPatientHints(): { id: string; name: string }[] {
return useMockData ? mockPatients.map((item) => ({ id: item.id, name: item.name })) : []
}
function isNotFoundError(error: unknown) {
return axios.isAxiosError(error) && error.response?.status === 404
}
@@ -852,6 +870,8 @@ export async function getPatientProfile(keyword: string): Promise<PatientProfile
const patient = mockPatients.find(
(item) =>
item.id === normalizedKeyword ||
// 演示数据里记不住患者 ID 是常态,允许直接按姓名定位
item.name === normalizedKeyword ||
item.visits.some((visit) => visit.visitNo === normalizedKeyword),
)
@@ -876,7 +896,12 @@ export async function getSigningTemplates(
return records.map(mapAvailableTemplate)
}
return Promise.resolve(mockTemplates.map((template) => ({ ...template })))
// 文档库本地新建的文书只存在 localStorage,必须一起返回;
// 否则文档库刚建好的文书在签署侧选不到(内置 Mock 模板是写死的演示数据)。
return Promise.resolve([
...readLocalSigningTemplates(),
...mockTemplates.map((template) => ({ ...template })),
])
}
export async function prepareSigningTask(
@@ -950,6 +975,7 @@ export async function createSigningTask(input: CreateSigningTaskInput): Promise<
}
mockRecords.unshift(task)
persistMockRecords()
return Promise.resolve(cloneTask(task))
}
@@ -969,6 +995,7 @@ export function updateSigningTaskMethod(
task.method = method
task.updatedAt = formatMockDate()
persistMockRecords()
return Promise.resolve(cloneTask(task))
}
@@ -990,6 +1017,7 @@ export function completeSigningTask(
task.signatureDataUrl = signatureDataUrl
task.signedAt = formatMockDate()
task.updatedAt = task.signedAt
persistMockRecords()
return Promise.resolve(cloneTask(task))
}
@@ -1015,6 +1043,7 @@ export async function reopenSigningTask(
task.signatureDataUrl = undefined
task.signedAt = undefined
task.updatedAt = formatMockDate()
persistMockRecords()
return Promise.resolve(cloneTask(task))
}
@@ -1041,6 +1070,7 @@ export async function voidSigningTask(
task.voidReason = reason
task.signatureDataUrl = undefined
task.updatedAt = formatMockDate()
persistMockRecords()
return Promise.resolve(cloneTask(task))
}
@@ -1063,6 +1093,7 @@ export async function resendSigningSms(
task.status = 'pending'
task.expiresAt = addHours('2026-08-27 12:00', 48)
task.updatedAt = formatMockDate()
persistMockRecords()
return Promise.resolve(cloneTask(task))
}