Files
xh-medical-sign-web/patient-h5/src/views/signer/SignerView.vue
T

157 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
/**
* 签署页。
*
* 按业务口径,**患者只签自己的名**:文书里的选项、医师签名都由医生在医护端填好,
* 因此这一页去掉了原来的「签署人姓名 + 与患者关系」填写 —— 那两项现在由医生填,
* 这里只做只读展示。
*
* 签名仍走 Canvas(`SignatureCanvas`)。将来接真实手写板设备时,换的是采集层
* (设备适配器),这一页的交互不用动。
*/
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import DocumentPaper from '@/components/DocumentPaper.vue'
import SignatureCanvas from '@/components/SignatureCanvas.vue'
import { signingState, submitRealSignature } from '@/composables/useSignFlow'
const router = useRouter()
const signatureDataUrl = ref('')
const errorMessage = ref('')
const submitting = ref(false)
/** 签署人由医生在医护端填好,这里只展示 */
const signerLine = computed(() => {
const name = signingState.signerName || signingState.patientName
const relation = signingState.relation || '本人'
return `${name}(${relation})`
})
function dataUrlToBlob(dataUrl: string) {
const [header, encoded] = dataUrl.split(',')
const mimeType = header?.match(/data:(.*?);base64/)?.[1] ?? 'image/png'
const binary = atob(encoded ?? '')
const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0))
return new Blob([bytes], { type: mimeType })
}
async function submitSigning() {
if (!signatureDataUrl.value) {
errorMessage.value = '请完成手写签名。'
return
}
if (signingState.mode === 'real') {
submitting.value = true
errorMessage.value = ''
try {
await submitRealSignature({
file: dataUrlToBlob(signatureDataUrl.value),
consentAccepted: signingState.consentAccepted,
})
await router.push('/result')
} catch (error) {
errorMessage.value = error instanceof Error ? error.message : '签署提交失败,请稍后重试。'
} finally {
submitting.value = false
}
return
}
signingState.signatureCaptured = true
signingState.submittedAt = new Date().toLocaleString('zh-CN')
void router.push('/result')
}
</script>
<template>
<main class="mobile-shell">
<div class="mobile-stepper">
<span>1 阅读</span>
<i />
<span class="is-active">2 确认</span>
<i />
<span>3 完成</span>
</div>
<section class="mobile-heading">
<p class="eyebrow">签署确认</p>
<h1>请在文书签名处签名</h1>
<p>文书内容已由医务人员填写完成,您只需完成患者签名。</p>
</section>
<section class="mobile-card signer-summary">
<div>
<span>患者</span>
<strong>{{ signingState.patientName }}</strong>
</div>
<div>
<span>签署人</span>
<strong>{{ signerLine }}</strong>
</div>
<div>
<span>文书</span>
<strong>{{ signingState.documentTitle }} · {{ signingState.templateVersion }}</strong>
</div>
</section>
<!-- 签完的字会实时回填到文书里的签名位,患者能立刻看到自己签在哪一格 -->
<DocumentPaper
:content-html="signingState.documentContentHtml"
:answers="signingState.staffAnswers"
:patient-signature="signatureDataUrl || null"
/>
<SignatureCanvas
:height="200"
placeholder="请在此签名"
@update:data-url="signatureDataUrl = $event ?? ''"
/>
<p v-if="errorMessage" class="form-error">{{ errorMessage }}</p>
<button
class="mobile-primary-button"
type="button"
:disabled="submitting"
@click="submitSigning"
>
{{ submitting ? '提交中…' : '确认提交签署' }}
</button>
<button class="mobile-text-button" type="button" @click="router.back()">返回修改</button>
</main>
</template>
<style scoped>
.signer-summary {
display: flex;
flex-direction: column;
gap: 10px;
padding: 18px 20px;
margin-bottom: 14px;
}
.signer-summary div {
display: flex;
gap: 10px;
align-items: baseline;
justify-content: space-between;
}
.signer-summary span {
flex-shrink: 0;
color: #8aa0aa;
font-size: 12px;
}
.signer-summary strong {
color: #173b56;
font-size: 14px;
text-align: right;
}
</style>