Files
xh-medical-sign-web/clinical-web/src/views/workbench/signing/components/SignaturePadDialog.vue
T

204 lines
4.1 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">
import { nextTick, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import type { SigningTaskRecord } from '@/api/workbench/types'
import SignatureCanvas from './SignatureCanvas.vue'
const props = defineProps<{
visible: boolean
task: SigningTaskRecord | null
}>()
const emit = defineEmits<{
close: []
confirm: [signatureDataUrl: string]
}>()
const signatureDataUrl = ref<string | null>(null)
const signatureCanvas = ref<{ clear: () => void } | null>(null)
watch(
() => props.visible,
async (visible) => {
if (visible) {
signatureDataUrl.value = null
await nextTick()
signatureCanvas.value?.clear()
}
},
)
function clearSignature() {
signatureCanvas.value?.clear()
signatureDataUrl.value = null
}
function confirmSignature() {
if (!signatureDataUrl.value) {
ElMessage.warning('请先完成患者签名')
return
}
emit('confirm', signatureDataUrl.value)
}
</script>
<template>
<Teleport to="body">
<div v-if="visible && task" class="dialog-mask" @click.self="emit('close')">
<section
class="dialog-card signature-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="pad-title"
>
<header class="dialog-header">
<strong id="pad-title">手写板签署</strong>
<span>{{ task.patientName }} · {{ task.documentName }}</span>
<button type="button" class="dialog-close" aria-label="关闭" @click="emit('close')">
×
</button>
</header>
<div class="dialog-body">
<p class="dialog-hint">
请患者在下框内签名(当前为 Canvas 演示,真实手写板接入走设备适配器):
</p>
<SignatureCanvas
ref="signatureCanvas"
:height="300"
@update:data-url="signatureDataUrl = $event"
/>
</div>
<footer class="dialog-footer">
<span>签名将实时合成到文档签名域</span>
<span class="footer-spacer" />
<button type="button" class="action-button action-button--ghost" @click="clearSignature">
清空重写
</button>
<button type="button" class="action-button" @click="confirmSignature">确认签署</button>
</footer>
</section>
</div>
</Teleport>
</template>
<style scoped>
.dialog-mask {
position: fixed;
z-index: 50;
inset: 0;
display: flex;
padding: 16px;
overflow-y: auto;
background: rgb(9 40 52 / 45%);
}
.dialog-card {
width: 680px;
max-width: 96vw;
max-height: calc(100vh - 32px);
margin: auto;
background: #fff;
border-radius: 14px;
box-shadow: var(--sh-modal);
animation: dialog-pop 0.18s ease;
}
.signature-dialog {
width: 760px;
}
.dialog-header {
display: flex;
gap: 10px;
align-items: center;
padding: 12px 18px;
border-bottom: 1px solid var(--line);
}
.dialog-header strong {
font-size: 15px;
}
.dialog-header span {
overflow: hidden;
color: var(--mut);
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
}
.dialog-close {
flex-shrink: 0;
padding: 0;
margin-left: auto;
color: var(--mut);
font-size: 20px;
line-height: 1;
background: transparent;
}
.dialog-body {
padding: 12px 18px;
}
.dialog-hint {
margin: 0 0 8px;
color: var(--mut);
font-size: 12px;
}
.dialog-footer {
display: flex;
gap: 10px;
align-items: center;
padding: 10px 18px;
color: var(--mut);
font-size: 12px;
background: #f8fbfc;
border-top: 1px solid var(--line);
border-radius: 0 0 14px 14px;
}
.footer-spacer {
flex: 1;
}
.action-button {
padding: 8px 16px;
color: #fff;
font-size: 13px;
font-weight: 700;
background: var(--brand);
border-radius: 7px;
}
.action-button:hover {
background: var(--brand-d);
}
.action-button--ghost {
color: var(--brand);
background: #fff;
border: 1px solid var(--brand);
}
.action-button--ghost:hover {
background: var(--brand-l);
}
@keyframes dialog-pop {
from {
opacity: 0;
transform: scale(0.96) translateY(8px);
}
to {
opacity: 1;
transform: none;
}
}
</style>