feat: enable patient form interactions and revision-aware signing

This commit is contained in:
cnxianyi
2026-09-29 21:37:30 +08:00
parent dc94265703
commit 9173d623a1
17 changed files with 451 additions and 49 deletions
+28 -11
View File
@@ -37,6 +37,7 @@ import type {
SignTaskResponseDto,
SignTaskSendPreparationResponseDto,
SigningAnswers,
SigningFormState,
SigningApiOptions,
SigningMethod,
SigningTaskEvent,
@@ -917,16 +918,21 @@ function mapSigningTask(
export async function hydrateSigningTaskContent(
task: SigningTaskRecord,
): Promise<SigningTaskRecord> {
if (task.documentContentHtml || useMockData || !task.templateVersionId) {
return task
}
const contentHtml = await fetchTemplateContentByVersion(
task.templateVersionId,
task.contentSha256,
if (useMockData || task.formState) return task
const response = await request.get<ApiResponseOf<SigningFormState>>(
`/v1/sign-tasks/${encodeURIComponent(task.id)}/form`,
)
return contentHtml ? { ...task, documentContentHtml: contentHtml } : task
const form = unwrapApiResponse(response)
const fieldAnswers: SigningAnswers = { ...form.staffAnswers, ...form.answers }
for (const field of form.fields) {
const value = fieldAnswers[field.id]
if (field.editable || typeof value !== 'string') continue
if (field.options.length && field.multi)
fieldAnswers[field.id] = value.split('、').filter(Boolean)
else if (field.kind === 'checkbox' && !field.options.length)
fieldAnswers[field.id] = !['', 'false', '0', 'off'].includes(value.toLowerCase())
}
return { ...task, documentContentHtml: form.contentHtml, fieldAnswers, formState: form }
}
function createTemplateFromInput(input: CreateSigningTaskInput): SigningTemplate {
@@ -1157,8 +1163,6 @@ export async function getSigningTaskDetail(
`/v1/sign-tasks/${encodeURIComponent(id)}`,
)
const task = mapSigningTask(unwrapApiResponse(response), options)
// 任务接口不返回正文,这里按哈希把正文快照补回;取不到就保持空,
// 由详情组件提示"后端未提供正文",不退化成前端写死的回退纸样
return hydrateSigningTaskContent(task)
} catch (error) {
if (isNotFoundError(error)) {
@@ -1731,3 +1735,16 @@ export function getSigningStatusLabel(status: SigningTaskStatus) {
export function getVisitTypeLabel(type: VisitType) {
return type
}
export async function saveSigningForm(
id: string,
expectedRevision: number,
answers: SigningAnswers,
): Promise<SigningFormState> {
return request
.post<ApiResponseOf<SigningFormState>>(`/v1/sign-tasks/${encodeURIComponent(id)}/form`, {
expectedRevision,
answers,
})
.then(unwrapApiResponse)
}
+19
View File
@@ -334,6 +334,7 @@ export interface SigningTaskRecord extends WorkbenchTask {
* 文书填写项取值(含签名图),签署时固化。
* 重新打开文书时用它回显,签名因此落在文书原本的签名位上。
*/
formState?: SigningFormState
fieldAnswers?: SigningAnswers
}
@@ -663,6 +664,7 @@ export interface SigningContextResponseDto {
}
export interface PatientSignerAssertionInput {
answerRevision?: number
type: 'SELF' | 'FAMILY'
name: string
relation: string
@@ -775,3 +777,20 @@ export interface SigningTaskEvent {
}
export type ApiResponseOf<T> = ApiResponse<T>
export interface SigningFormState {
contentHtml: string
fields: {
id: string
label: string
kind: string
required: boolean
multi: boolean
options: string[]
editable: boolean
}[]
answers: SigningAnswers
staffAnswers: Record<string, string>
revision: number
editable: boolean
}