feat: 初始化医护端与患者端页面骨架
完成两个 Vite 应用的基础工程化配置、路由、状态管理及第一版业务页面,当前使用演示数据,尚未接入真实后端接口。
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { signingState } from '@/composables/useSignFlow'
|
||||
|
||||
const router = useRouter()
|
||||
const hasRead = ref(false)
|
||||
const errorMessage = ref('')
|
||||
|
||||
function continueToSigner() {
|
||||
if (!hasRead.value) {
|
||||
errorMessage.value = '请先确认已阅读文书内容。'
|
||||
return
|
||||
}
|
||||
|
||||
signingState.consentAccepted = true
|
||||
void router.push('/signer')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="mobile-shell">
|
||||
<div class="mobile-stepper">
|
||||
<span class="is-active">1 阅读</span>
|
||||
<i />
|
||||
<span>2 确认</span>
|
||||
<i />
|
||||
<span>3 完成</span>
|
||||
</div>
|
||||
|
||||
<section class="mobile-heading">
|
||||
<p class="eyebrow">知情同意书</p>
|
||||
<h1>{{ signingState.documentTitle }}</h1>
|
||||
<p>请完整阅读以下内容。如有疑问,请联系为您说明情况的医生。</p>
|
||||
</section>
|
||||
|
||||
<article class="document-card">
|
||||
<div class="document-meta">
|
||||
<span>患者:{{ signingState.patientName }}</span>
|
||||
<span>版本:V1.0</span>
|
||||
</div>
|
||||
<h2>一、检查/治疗说明</h2>
|
||||
<p>
|
||||
医生已向患者或监护人说明拟实施的检查、治疗目的、操作过程、可能风险及替代方案。患者或监护人可以就相关内容向医务人员提出问题。
|
||||
</p>
|
||||
<h2>二、可能风险</h2>
|
||||
<p>
|
||||
具体风险因患者病情、检查方式和治疗方案而异。请在充分了解相关情况后,结合医生建议决定是否同意。
|
||||
</p>
|
||||
<h2>三、患者权利</h2>
|
||||
<p>
|
||||
患者或监护人有权选择同意或拒绝本次检查/治疗。拒绝可能影响后续诊疗安排,相关情况将按医院流程记录。
|
||||
</p>
|
||||
<div class="document-placeholder">正式文书 PDF 将在接入后端后展示</div>
|
||||
</article>
|
||||
|
||||
<label class="check-row">
|
||||
<input v-model="hasRead" type="checkbox" />
|
||||
<span>我已阅读并理解上述内容,愿意继续确认签署人信息。</span>
|
||||
</label>
|
||||
<p v-if="errorMessage" class="form-error">{{ errorMessage }}</p>
|
||||
|
||||
<button class="mobile-primary-button" type="button" @click="continueToSigner">下一步</button>
|
||||
<button class="mobile-text-button" type="button" @click="router.back()">返回</button>
|
||||
</main>
|
||||
</template>
|
||||
@@ -0,0 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { resetSignFlow, signingState } from '@/composables/useSignFlow'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
function startSigning() {
|
||||
resetSignFlow()
|
||||
void router.push('/consent')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="mobile-shell">
|
||||
<header class="mobile-brand">
|
||||
<div class="mobile-brand-mark">签</div>
|
||||
<div>
|
||||
<strong>医签通</strong>
|
||||
<span>医疗知情同意签署</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="mobile-hero">
|
||||
<p class="eyebrow">待签署文书</p>
|
||||
<h1>{{ signingState.documentTitle }}</h1>
|
||||
<p>请确认以下任务信息,并在阅读文书后完成签署。</p>
|
||||
</section>
|
||||
|
||||
<section class="mobile-card patient-card">
|
||||
<div class="card-label">患者信息</div>
|
||||
<div class="patient-row">
|
||||
<div class="patient-avatar">{{ signingState.patientName.slice(0, 1) }}</div>
|
||||
<div>
|
||||
<strong>{{ signingState.patientName }}</strong>
|
||||
<span>{{ signingState.visitNo }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-number">任务编号:{{ signingState.taskNo }}</div>
|
||||
</section>
|
||||
|
||||
<section class="mobile-card notice-card">
|
||||
<div class="notice-icon">i</div>
|
||||
<div>
|
||||
<strong>请使用实际签署人的信息</strong>
|
||||
<p>如果由家属或监护人代签,请在下一步选择与患者的关系。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<button class="mobile-primary-button" type="button" @click="startSigning">
|
||||
开始阅读并签署
|
||||
</button>
|
||||
|
||||
<p class="secure-note">本页面仅用于本次知情同意签署,请勿转发签署链接。</p>
|
||||
</main>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { resetSignFlow, signingState } from '@/composables/useSignFlow'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
function returnToEntry() {
|
||||
resetSignFlow()
|
||||
void router.replace('/entry')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="mobile-shell result-shell">
|
||||
<div class="result-icon">✓</div>
|
||||
<p class="eyebrow">签署完成</p>
|
||||
<h1>知情同意书已提交</h1>
|
||||
<p class="result-copy">本次签署结果已提交至医签通。请按照医务人员指引完成后续诊疗安排。</p>
|
||||
|
||||
<section class="mobile-card result-card">
|
||||
<div>
|
||||
<span>患者</span>
|
||||
<strong>{{ signingState.patientName }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>签署人</span>
|
||||
<strong>{{ signingState.signerName }}({{ signingState.relation }})</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>提交时间</span>
|
||||
<strong>{{ signingState.submittedAt }}</strong>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<p class="secure-note">请不要重复提交。如需修改,请联系现场医务人员。</p>
|
||||
<button class="mobile-text-button" type="button" @click="returnToEntry">返回首页</button>
|
||||
</main>
|
||||
</template>
|
||||
@@ -0,0 +1,78 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import SignatureCanvas from '@/components/SignatureCanvas.vue'
|
||||
import { signingState } from '@/composables/useSignFlow'
|
||||
import { relationOptions, type SignerRelation } from '@/types/signing'
|
||||
|
||||
interface SignatureCanvasExpose {
|
||||
clearSignature: () => void
|
||||
isEmpty: () => boolean
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
const signerName = ref('')
|
||||
const relation = ref<SignerRelation | ''>('')
|
||||
const errorMessage = ref('')
|
||||
const signatureCanvas = ref<SignatureCanvasExpose | null>(null)
|
||||
|
||||
function submitSigning() {
|
||||
const trimmedName = signerName.value.trim()
|
||||
if (!trimmedName) {
|
||||
errorMessage.value = '请输入实际签署人姓名。'
|
||||
return
|
||||
}
|
||||
if (!relation.value) {
|
||||
errorMessage.value = '请选择签署人与患者的关系。'
|
||||
return
|
||||
}
|
||||
if (signatureCanvas.value?.isEmpty()) {
|
||||
errorMessage.value = '请完成手写签名。'
|
||||
return
|
||||
}
|
||||
|
||||
signingState.signerName = trimmedName
|
||||
signingState.relation = relation.value
|
||||
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-form">
|
||||
<label class="field-label" for="signer-name">签署人姓名</label>
|
||||
<input id="signer-name" v-model="signerName" class="mobile-input" placeholder="请输入姓名" />
|
||||
|
||||
<label class="field-label" for="signer-relation">与患者关系</label>
|
||||
<select id="signer-relation" v-model="relation" class="mobile-input">
|
||||
<option value="" disabled>请选择关系</option>
|
||||
<option v-for="option in relationOptions" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</option>
|
||||
</select>
|
||||
</section>
|
||||
|
||||
<SignatureCanvas ref="signatureCanvas" />
|
||||
|
||||
<p v-if="errorMessage" class="form-error">{{ errorMessage }}</p>
|
||||
<button class="mobile-primary-button" type="button" @click="submitSigning">确认提交签署</button>
|
||||
<button class="mobile-text-button" type="button" @click="router.back()">返回修改</button>
|
||||
</main>
|
||||
</template>
|
||||
Reference in New Issue
Block a user