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

228 lines
4.4 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 { ref, watch } from 'vue'
import type { SigningTaskRecord } from '@/api/workbench/types'
const props = defineProps<{
visible: boolean
task: SigningTaskRecord | null
}>()
const emit = defineEmits<{
close: []
confirm: [reason: string]
}>()
const reason = ref('患者信息录入有误')
watch(
() => props.visible,
(visible) => {
if (visible) {
reason.value = '患者信息录入有误'
}
},
)
</script>
<template>
<Teleport to="body">
<div v-if="visible && task" class="dialog-mask" @click.self="emit('close')">
<section
class="dialog-card void-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="void-title"
>
<header class="dialog-header">
<strong id="void-title">作废确认</strong>
<button type="button" class="dialog-close" aria-label="关闭" @click="emit('close')">
×
</button>
</header>
<div class="dialog-body">
<div class="void-summary">
<span class="void-icon" aria-hidden="true">⚠</span>
<div>
<p>
确定作废任务 <strong>{{ task.id }}</strong
>({{ task.documentName }})吗?
</p>
<span>作废后不可恢复,将记录操作人、时间与原因,全程留痕。</span>
</div>
</div>
<label class="reason-field">
<span>作废原因(必填)</span>
<select v-model="reason" aria-label="作废原因">
<option>患者信息录入有误</option>
<option>文档选择错误</option>
<option>患者拒绝签署</option>
<option>重复发起</option>
<option>其他</option>
</select>
</label>
</div>
<footer class="dialog-footer">
<span class="footer-spacer" />
<button type="button" class="action-button action-button--ghost" @click="emit('close')">
取消
</button>
<button
type="button"
class="action-button action-button--danger"
@click="emit('confirm', reason)"
>
确认作废
</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: 440px;
max-width: 96vw;
margin: auto;
background: #fff;
border-radius: 14px;
box-shadow: var(--sh-modal);
animation: dialog-pop 0.18s ease;
}
.dialog-header {
display: flex;
align-items: center;
padding: 12px 18px;
border-bottom: 1px solid var(--line);
}
.dialog-header strong {
font-size: 15px;
}
.dialog-close {
padding: 0;
margin-left: auto;
color: var(--mut);
font-size: 20px;
line-height: 1;
background: transparent;
}
.dialog-body {
padding: 16px 18px 12px;
}
.void-summary {
display: flex;
gap: 12px;
align-items: flex-start;
}
.void-icon {
font-size: 30px;
line-height: 1;
}
.void-summary p {
margin: 0;
color: var(--ink);
line-height: 1.6;
}
.void-summary > div > span {
display: block;
margin-top: 6px;
color: var(--mut);
font-size: 12px;
line-height: 1.6;
}
.reason-field {
display: flex;
gap: 8px;
flex-direction: column;
margin-top: 14px;
}
.reason-field span {
color: var(--mut);
font-size: 12px;
}
.reason-field select {
width: 100%;
padding: 7px 10px;
color: var(--ink);
border: 1px solid var(--line);
border-radius: 6px;
}
.dialog-footer {
display: flex;
gap: 10px;
align-items: center;
padding: 10px 18px;
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--ghost {
color: var(--brand);
background: #fff;
border: 1px solid var(--brand);
}
.action-button--ghost:hover {
background: var(--brand-l);
}
.action-button--danger {
color: var(--err);
background: #fff;
border: 1px solid var(--err);
}
.action-button--danger:hover {
background: var(--err-l);
}
@keyframes dialog-pop {
from {
opacity: 0;
transform: scale(0.96) translateY(8px);
}
to {
opacity: 1;
transform: none;
}
}
</style>