feat(患者签署): 接入签署上下文接口并补齐文书渲染与手写签名链路
This commit is contained in:
@@ -5,6 +5,7 @@ import type {
|
||||
ApiResponse,
|
||||
SignatureUploadInput,
|
||||
SignatureUploadResponse,
|
||||
SigningContextResponse,
|
||||
TokenConsumeRequest,
|
||||
TokenConsumeResponse,
|
||||
} from './types'
|
||||
@@ -19,6 +20,21 @@ export function consumeSigningToken(payload: TokenConsumeRequest): Promise<Token
|
||||
.then(unwrapApiResponse)
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取本次签署的完整上下文:患者信息 / 签署人 / 文书正文 / 医生已填结果。
|
||||
*
|
||||
* 契约见 `.workbuddy-ai/患者端H5真实接入方案-2026-09-28.md` 第三节。
|
||||
* **后端就绪前这个调用会失败**,所以调用方必须能优雅降级 ——
|
||||
* 拿不到正文就不能放行签署(见 `useSignFlow` 的 `documentError`)。
|
||||
*/
|
||||
export function fetchSigningContext(token: string): Promise<SigningContextResponse> {
|
||||
return request
|
||||
.get<ApiResponse<SigningContextResponse>>('/v1/sign-deliveries/token/context', {
|
||||
params: { token },
|
||||
})
|
||||
.then(unwrapApiResponse)
|
||||
}
|
||||
|
||||
function createIdempotencyKey(value?: string) {
|
||||
if (value) {
|
||||
return value
|
||||
|
||||
@@ -6,10 +6,20 @@ export interface ApiResponse<T> {
|
||||
timestamp?: string
|
||||
}
|
||||
|
||||
export type SignDeliveryChannel = 'PAD' | 'SMS'
|
||||
/**
|
||||
* 投递渠道。
|
||||
*
|
||||
* - `PAD`:现场手写板,设备上跑的就是本 H5;
|
||||
* - `SMS`:短信链接;
|
||||
* - `WX`:微信公众号(2026-09-28 补 —— 原契约只有 PAD / SMS,公众号一直没落点)。
|
||||
*
|
||||
* 注意 **Pad 移动端签署不走这里**:那是在医护端工作台里用平板现场签的,不产生投递。
|
||||
*/
|
||||
export type SignDeliveryChannel = 'PAD' | 'SMS' | 'WX'
|
||||
|
||||
export interface TokenConsumeRequest {
|
||||
token: string
|
||||
/** 允许不传:渠道由 token 决定,前端不该替后端写死一个 */
|
||||
channel?: SignDeliveryChannel
|
||||
taskId?: string
|
||||
}
|
||||
@@ -23,6 +33,82 @@ export interface TokenConsumeResponse {
|
||||
timestamp?: string | null
|
||||
}
|
||||
|
||||
/** 患者端看到的任务状态。不是 `WAITING_SIGN` 时不该放行签署 */
|
||||
export type SigningTaskSignStatus =
|
||||
| 'WAITING_SIGN'
|
||||
| 'SIGNED'
|
||||
| 'EXPIRED'
|
||||
| 'VOIDED'
|
||||
| 'FAILED'
|
||||
| string
|
||||
|
||||
export interface SigningContextPatient {
|
||||
name?: string | null
|
||||
sex?: string | null
|
||||
age?: number | null
|
||||
visitNo?: string | null
|
||||
department?: string | null
|
||||
}
|
||||
|
||||
/** 签署人信息。按业务口径由医生在医护端填好,患者端只展示、不修改 */
|
||||
export interface SigningContextSigner {
|
||||
/** `SELF` = 本人;`FAMILY` = 家属代签 */
|
||||
type?: string | null
|
||||
name?: string | null
|
||||
relation?: string | null
|
||||
}
|
||||
|
||||
export interface SigningContextTemplate {
|
||||
name?: string | null
|
||||
category?: string | null
|
||||
versionNo?: string | null
|
||||
}
|
||||
|
||||
export interface SigningContextDocument {
|
||||
contentHtml?: string | null
|
||||
contentSha256?: string | null
|
||||
}
|
||||
|
||||
export interface SigningContextFieldOption {
|
||||
value: string
|
||||
label?: string | null
|
||||
}
|
||||
|
||||
export interface SigningContextField {
|
||||
id: string
|
||||
label?: string | null
|
||||
kind?: string | null
|
||||
required?: boolean | null
|
||||
options?: SigningContextFieldOption[] | null
|
||||
}
|
||||
|
||||
/**
|
||||
* 患者端读取本次签署的完整上下文。
|
||||
*
|
||||
* 与 `token/consume` 的职责**分开**:consume 是「消费一次」换投递凭证,
|
||||
* 这个接口要能**重复调用**(患者刷新、返回上一步都要能重进)。
|
||||
*/
|
||||
export interface SigningContextResponse {
|
||||
taskId: string
|
||||
deliveryId?: string | null
|
||||
channel?: SignDeliveryChannel | null
|
||||
status?: SigningTaskSignStatus | null
|
||||
expiresAt?: string | null
|
||||
patient?: SigningContextPatient | null
|
||||
signer?: SigningContextSigner | null
|
||||
template?: SigningContextTemplate | null
|
||||
document?: SigningContextDocument | null
|
||||
/**
|
||||
* 医生已填的结果(含医师签名图),患者端**只读**渲染进正文占位符。
|
||||
*
|
||||
* 刻意与 `document.contentHtml` 分开:医生填了什么要能单独追溯,
|
||||
* 烙进正文 HTML 就查不出「谁在什么时候填了什么」。
|
||||
*/
|
||||
staffAnswers?: Record<string, string> | null
|
||||
/** 患者端可交互的字段。按约定只有主签名位(`id === 'signature'`) */
|
||||
fields?: SigningContextField[] | null
|
||||
}
|
||||
|
||||
export type SignatureUploadStatus =
|
||||
'CREATED' | 'WAITING_SIGN' | 'SIGNED' | 'EXPIRED' | 'VOIDED' | 'GENERATING' | 'FAILED' | string
|
||||
|
||||
|
||||
Reference in New Issue
Block a user