2026-01-06 15:03:14 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="medical-form-page">
|
|
|
|
|
|
<div class="center-container">
|
|
|
|
|
|
<form class="medical-form" @submit.prevent="handleSubmit">
|
|
|
|
|
|
<!-- 标题区域 -->
|
|
|
|
|
|
<div class="form-header">
|
|
|
|
|
|
<h1 class="form-title">病案申请</h1>
|
|
|
|
|
|
<p class="form-desc">请填写以下信息,我们将尽快为您处理</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤条 -->
|
|
|
|
|
|
<div class="steps-container">
|
|
|
|
|
|
<div class="step-line"></div>
|
|
|
|
|
|
<div v-for="(step, index) in steps" :key="index" class="step-item" :class="{
|
|
|
|
|
|
'active': currentStep === index,
|
|
|
|
|
|
'completed': currentStep > index
|
|
|
|
|
|
}">
|
|
|
|
|
|
<div class="step-number">{{ completedStepNumbers[index] }}</div>
|
|
|
|
|
|
<div class="step-name">{{ step.name }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤内容区域 -->
|
|
|
|
|
|
<div class="step-content">
|
|
|
|
|
|
<!-- 步骤1:选择办理类型及领取方式 -->
|
|
|
|
|
|
<div v-if="currentStep === 0" class="step-panel">
|
|
|
|
|
|
<div class="form-section handling-type-section">
|
|
|
|
|
|
<h2 class="section-title">办理类型</h2>
|
|
|
|
|
|
<div class="handling-type-selector">
|
|
|
|
|
|
<label class="handling-option">
|
|
|
|
|
|
<input type="radio" name="handlingType" value="1" v-model="handlingType" class="handling-radio">
|
|
|
|
|
|
<span class="handling-text">本人办理</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
<label class="handling-option">
|
|
|
|
|
|
<input type="radio" name="handlingType" value="2" v-model="handlingType" class="handling-radio">
|
|
|
|
|
|
<span class="handling-text">他人代办</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="error-text" v-if="errors.handlingType">{{ errors.handlingType }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-section delivery-type-section">
|
|
|
|
|
|
<h2 class="section-title">领取方式</h2>
|
|
|
|
|
|
<div class="delivery-type-selector">
|
|
|
|
|
|
<label class="delivery-option">
|
|
|
|
|
|
<input type="radio" name="deliveryType" value="1" v-model="deliveryType" class="delivery-radio">
|
|
|
|
|
|
<span class="delivery-text">到场自取</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
<label class="delivery-option">
|
|
|
|
|
|
<input type="radio" name="deliveryType" value="2" v-model="deliveryType" class="delivery-radio">
|
|
|
|
|
|
<span class="delivery-text">快递邮寄</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="error-text" v-if="errors.deliveryType">{{ errors.deliveryType }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤2:患者信息 -->
|
|
|
|
|
|
<div v-if="currentStep === 1" class="step-panel">
|
|
|
|
|
|
<div class="form-section">
|
|
|
|
|
|
<h2 class="section-title">患者信息</h2>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-fields">
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="patientName">病人姓名 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="text" id="patientName" v-model="formData.patientName" placeholder="请输入病人姓名"
|
|
|
|
|
|
class="form-input" autocomplete="name" @input="syncRecipientName">
|
|
|
|
|
|
<span class="error-text" v-if="errors.patientName">{{ errors.patientName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="patientId">就诊人卡号 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="text" id="patientId" v-model="formData.patientId" placeholder="请输入就诊人卡号"
|
|
|
|
|
|
class="form-input">
|
|
|
|
|
|
<span class="error-text" v-if="errors.patientId">{{ errors.patientId }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label>就诊医院</label>
|
|
|
|
|
|
<div class="fixed-value">武警宁夏总队医院</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="phoneNumber">手机号码 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="tel" id="phoneNumber" v-model="formData.phone" placeholder="请输入手机号码" maxlength="11"
|
|
|
|
|
|
class="form-input" autocomplete="tel">
|
|
|
|
|
|
<span class="error-text" v-if="errors.phone">{{ errors.phone }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="idNumber">身份证号 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="text" id="idNumber" v-model="formData.idNumber" placeholder="请输入身份证号码" maxlength="18"
|
|
|
|
|
|
class="form-input">
|
|
|
|
|
|
<span class="error-text" v-if="errors.idNumber">{{ errors.idNumber }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="hospitalNumber">住院号 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="text" id="hospitalNumber" v-model="formData.hospitalNumber" placeholder="请输入住院号"
|
|
|
|
|
|
class="form-input">
|
|
|
|
|
|
<span class="error-text" v-if="errors.hospitalNumber">{{ errors.hospitalNumber }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
|
<div class="form-group date-group">
|
|
|
|
|
|
<label>入院日期 <span class="required">*</span></label>
|
|
|
|
|
|
<div class="date-picker-wrapper">
|
|
|
|
|
|
<input type="text" v-model="formData.admissionDate" placeholder="选择入院日期"
|
|
|
|
|
|
class="form-input date-display" readonly @click="showAdmissionPicker = true">
|
|
|
|
|
|
<van-popup v-model="showAdmissionPicker" position="bottom">
|
|
|
|
|
|
<van-datetime-picker :value="admissionDate" type="date" title="选择入院日期" :min-date="minDate"
|
|
|
|
|
|
:max-date="new Date()" @confirm="handleAdmissionConfirm"
|
|
|
|
|
|
@cancel="showAdmissionPicker = false" />
|
|
|
|
|
|
</van-popup>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="error-text" v-if="errors.admissionDate">{{ errors.admissionDate }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group date-group">
|
|
|
|
|
|
<label>出院日期 <span class="required">*</span></label>
|
|
|
|
|
|
<div class="date-picker-wrapper">
|
|
|
|
|
|
<input type="text" v-model="formData.dischargeDate" placeholder="选择出院日期"
|
|
|
|
|
|
class="form-input date-display" readonly
|
|
|
|
|
|
@click="formData.admissionDate && (showDischargePicker = true)"
|
|
|
|
|
|
:disabled="!formData.admissionDate">
|
|
|
|
|
|
<van-popup v-model="showDischargePicker" position="bottom">
|
|
|
|
|
|
<van-datetime-picker :value="dischargeDate" type="date" title="选择出院日期"
|
|
|
|
|
|
:min-date="getMinDischargeDate()" :max-date="new Date()" @confirm="handleDischargeConfirm"
|
|
|
|
|
|
@cancel="showDischargePicker = false" />
|
|
|
|
|
|
</van-popup>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="error-text" v-if="errors.dischargeDate">{{ errors.dischargeDate }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤3:代办人信息 -->
|
|
|
|
|
|
<div v-if="currentStep === 2" class="step-panel">
|
|
|
|
|
|
<div class="form-section" v-if="handlingType === '2'">
|
|
|
|
|
|
<h2 class="section-title">代办人信息</h2>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-fields">
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="recipientName">代办人姓名 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="text" id="recipientName" v-model="formData.recipientName" placeholder="请输入代办人姓名"
|
|
|
|
|
|
class="form-input" autocomplete="name">
|
|
|
|
|
|
<span class="error-text" v-if="errors.recipientName">{{ errors.recipientName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="recipientPhone">代办人联系电话 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="tel" id="recipientPhone" v-model="formData.recipientPhone" placeholder="请输入代办人联系电话"
|
|
|
|
|
|
maxlength="11" class="form-input" autocomplete="tel">
|
|
|
|
|
|
<span class="error-text" v-if="errors.recipientPhone">{{ errors.recipientPhone }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="recipientIdNumber">代办人身份证号 <span class="required">*</span></label>
|
|
|
|
|
|
<input type="text" id="recipientIdNumber" v-model="formData.recipientIdNumber"
|
|
|
|
|
|
placeholder="请输入代办人身份证号码" maxlength="18" class="form-input">
|
|
|
|
|
|
<span class="error-text" v-if="errors.recipientIdNumber">{{ errors.recipientIdNumber }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="self-handling-step3">
|
|
|
|
|
|
<p>您选择的是本人办理,无需填写代办人信息</p>
|
|
|
|
|
|
<p>点击下一步继续上传证件</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤4:证件上传及确认 -->
|
|
|
|
|
|
<div v-if="currentStep === 3" class="step-panel">
|
|
|
|
|
|
<div class="form-section">
|
|
|
|
|
|
<h2 class="section-title">证件上传</h2>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="upload-section">
|
|
|
|
|
|
<p class="upload-desc">
|
|
|
|
|
|
{{ handlingType === '1' ? '请上传患者本人证件照片' : '请上传患者及代办人证件照片' }}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="upload-row">
|
|
|
|
|
|
<div class="upload-item">
|
|
|
|
|
|
<div class="upload-preview" :class="{ 'uploaded': formData.idFrontUrl }">
|
|
|
|
|
|
<img v-if="formData.idFrontUrl" :src="formData.idFrontUrl" alt="身份证正面" class="id-img">
|
|
|
|
|
|
<img v-else src="../assets/正面.png" alt="身份证正面示例" class="id-img">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="upload-btn" @click="selectFile('idFront')">
|
|
|
|
|
|
上传患者身份证正面
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<input type="file" ref="idFrontInput" accept="image/*" class="file-input"
|
|
|
|
|
|
@change="handleFileUpload('idFront', $event)">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="upload-item">
|
|
|
|
|
|
<div class="upload-preview" :class="{ 'uploaded': formData.idBackUrl }">
|
|
|
|
|
|
<img v-if="formData.idBackUrl" :src="formData.idBackUrl" alt="身份证反面" class="id-img">
|
|
|
|
|
|
<img v-else src="../assets/反面.png" alt="身份证反面示例" class="id-img">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="upload-btn" @click="selectFile('idBack')">
|
|
|
|
|
|
上传患者身份证反面
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<input type="file" ref="idBackInput" accept="image/*" class="file-input"
|
|
|
|
|
|
@change="handleFileUpload('idBack', $event)">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="handlingType === '2'" class="upload-row">
|
|
|
|
|
|
<div class="upload-item">
|
|
|
|
|
|
<div class="upload-preview" :class="{ 'uploaded': formData.recipientIdFrontUrl }">
|
|
|
|
|
|
<img v-if="formData.recipientIdFrontUrl" :src="formData.recipientIdFrontUrl" alt="代办人身份证正面"
|
|
|
|
|
|
class="id-img">
|
|
|
|
|
|
<img v-else src="../assets/正面.png" alt="代办人身份证正面示例" class="id-img">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="upload-btn" @click="selectFile('recipientIdFront')">
|
|
|
|
|
|
上传代办人身份证正面
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<input type="file" ref="recipientIdFrontInput" accept="image/*" class="file-input"
|
|
|
|
|
|
@change="handleFileUpload('recipientIdFront', $event)">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="upload-item">
|
|
|
|
|
|
<div class="upload-preview" :class="{ 'uploaded': formData.recipientIdBackUrl }">
|
|
|
|
|
|
<img v-if="formData.recipientIdBackUrl" :src="formData.recipientIdBackUrl" alt="代办人身份证反面"
|
|
|
|
|
|
class="id-img">
|
|
|
|
|
|
<img v-else src="../assets/反面.png" alt="代办人身份证反面示例" class="id-img">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="upload-btn" @click="selectFile('recipientIdBack')">
|
|
|
|
|
|
上传代办人身份证反面
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<input type="file" ref="recipientIdBackInput" accept="image/*" class="file-input"
|
|
|
|
|
|
@change="handleFileUpload('recipientIdBack', $event)">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="upload-item">
|
|
|
|
|
|
<div class="upload-preview" :class="{ 'uploaded': formData.powerOfAttorneyUrl }">
|
|
|
|
|
|
<img v-if="formData.powerOfAttorneyUrl" :src="formData.powerOfAttorneyUrl" alt="授权委托书"
|
|
|
|
|
|
class="id-img">
|
|
|
|
|
|
<img v-else src="../assets/示例书.png" alt="授权委托书示例" class="id-img">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="upload-btn" @click="selectFile('powerOfAttorney')">
|
|
|
|
|
|
上传病案复印授权委托书
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<input type="file" ref="powerOfAttorneyInput" accept="image/*" class="file-input"
|
|
|
|
|
|
@change="handleFileUpload('powerOfAttorney', $event)">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="upload-notes">
|
|
|
|
|
|
<p>1、支持上传身份证、护照、军官证、户口本等有效证件。</p>
|
|
|
|
|
|
<p>2、请上传清晰可见的证件,并确保证件内信息完整。</p>
|
|
|
|
|
|
<p v-if="handlingType === '2'">3、他人代办时需同时上传患者及代办人双方证件。</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="agreement-section">
|
|
|
|
|
|
<div class="agreement-check">
|
|
|
|
|
|
<div class="checkbox" :class="{ checked: hasAgreed }" @click="if (!hasAgreed) showAgreement = true">
|
|
|
|
|
|
<span v-if="hasAgreed">✓</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p>我已阅读并同意<a href="javascript:;" @click="showAgreement = true">《病案申请须知》</a></p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="error-text" v-if="errors.agreement">{{ errors.agreement }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤导航按钮 -->
|
|
|
|
|
|
<div class="step-navigation">
|
|
|
|
|
|
<button type="button" class="nav-btn prev-btn" @click="prevStep" :disabled="currentStep === 0">
|
|
|
|
|
|
上一步
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
<button type="button" class="nav-btn next-btn" @click="nextStep" :disabled="currentStep === totalSteps - 1">
|
|
|
|
|
|
下一步
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
<button type="submit" class="submit-btn" v-if="currentStep === totalSteps - 1" :disabled="!hasAgreed">
|
|
|
|
|
|
确认提交
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 信息确认弹窗 -->
|
|
|
|
|
|
<div class="modal-backdrop" v-if="showConfirmModal">
|
|
|
|
|
|
<div class="confirm-modal">
|
|
|
|
|
|
<h3 class="modal-title">确认申请信息</h3>
|
|
|
|
|
|
<div class="confirm-details">
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">办理类型:</span>
|
|
|
|
|
|
<span class="detail-value">{{ handlingType === '1' ? '本人办理' : '他人代办' }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">领取方式:</span>
|
|
|
|
|
|
<span class="detail-value">{{ deliveryType === '1' ? '到场自取' : '快递邮寄' }}</span>
|
|
|
|
|
|
</div>
|
2026-01-21 15:49:26 +08:00
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">打印份数:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.copies }}份</span>
|
|
|
|
|
|
</div>
|
2026-01-06 15:03:14 +08:00
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">病人姓名:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.patientName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">就诊人卡号:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.patientId }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">就诊医院:</span>
|
|
|
|
|
|
<span class="detail-value">武警宁夏总队医院</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">手机号码:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.phone }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">身份证号:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.idNumber }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">住院号:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.hospitalNumber }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">入院日期:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.admissionDate }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">出院日期:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.dischargeDate }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<template v-if="handlingType === '2'">
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">代办人姓名:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.recipientName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">代办人电话:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.recipientPhone }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
|
<span class="detail-label">代办人身份证号:</span>
|
|
|
|
|
|
<span class="detail-value">{{ formData.recipientIdNumber }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="confirm-buttons">
|
|
|
|
|
|
<button class="cancel-btn" @click="showConfirmModal = false">取消</button>
|
|
|
|
|
|
<button class="confirm-btn" @click="submitConfirmed" :disabled="isSubmitting">确认提交</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 病案申请须知弹窗 -->
|
|
|
|
|
|
<div class="modal-backdrop" v-if="showAgreement">
|
|
|
|
|
|
<div class="agreement-modal">
|
|
|
|
|
|
<h3 class="modal-title">病案申请须知</h3>
|
|
|
|
|
|
<div class="agreement-content">
|
|
|
|
|
|
<div class="notice-content">
|
|
|
|
|
|
<p>根据卫健委颁发的《医疗机构病历管理规定》,在申请病案复印前您需注意以下事项:</p>
|
|
|
|
|
|
<ol>
|
|
|
|
|
|
<li>1、申请人必须为患者本人或被委托代理人;</li>
|
|
|
|
|
|
<li>2、申请人为患者本人的需要提供患者身份证明材料;申请人为被委托代理人的需要提供患者身份证明材料、申请人身份证明材料及委托代理书;</li>
|
|
|
|
|
|
<li>3、公安、司法、保险等机构需到医院现场申请。</li>
|
|
|
|
|
|
<li>4、死亡患者只支持现场申请。</li>
|
|
|
|
|
|
</ol>
|
|
|
|
|
|
<p><strong>委托代理书示例:</strong></p>
|
|
|
|
|
|
<img src="../assets/示例书.png" alt="病案复印授权委托书示例"
|
|
|
|
|
|
style="max-width: 100%; border: 1px solid #ddd; border-radius: 0.05rem; margin: 0.2rem 0;">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="agreement-footer">
|
|
|
|
|
|
<button class="agree-btn" @click="agreeAgreement">我已阅读并同意</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { apiBayj } from "@/request/api.js";
|
|
|
|
|
|
import { Toast, DatetimePicker, Popup } from "vant";
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
components: {
|
|
|
|
|
|
[DatetimePicker.name]: DatetimePicker,
|
|
|
|
|
|
[Popup.name]: Popup
|
|
|
|
|
|
},
|
|
|
|
|
|
mounted() {
|
|
|
|
|
|
let card = JSON.parse(sessionStorage.getItem("card"))
|
|
|
|
|
|
console.log("card:",card)
|
|
|
|
|
|
// 将card对象的值赋给表单字段作为默认值,允许用户自行修改
|
|
|
|
|
|
if (card) {
|
|
|
|
|
|
this.formData.patientName = card.name || '';
|
|
|
|
|
|
this.formData.patientId = card.patientId || '';
|
|
|
|
|
|
this.formData.idNumber = card.idNo || '';
|
|
|
|
|
|
this.formData.phone = card.phone || '';
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
steps: [
|
|
|
|
|
|
{ name: '选择办理类型及领取方式' },
|
|
|
|
|
|
{ name: '填写患者信息' },
|
|
|
|
|
|
{ name: '填写代办人信息' },
|
|
|
|
|
|
{ name: '上传证件及确认' }
|
|
|
|
|
|
],
|
|
|
|
|
|
currentStep: 0,
|
|
|
|
|
|
card: {},
|
|
|
|
|
|
handlingType: '',
|
|
|
|
|
|
deliveryType: '',
|
|
|
|
|
|
formData: {
|
|
|
|
|
|
patientName: '',
|
|
|
|
|
|
patientId: '', // 新增就诊人卡号字段
|
|
|
|
|
|
phone: '',
|
|
|
|
|
|
idNumber: '',
|
|
|
|
|
|
hospitalNumber: '',
|
|
|
|
|
|
admissionDate: '',
|
|
|
|
|
|
dischargeDate: '',
|
|
|
|
|
|
recipientName: '',
|
|
|
|
|
|
recipientPhone: '',
|
|
|
|
|
|
recipientIdNumber: '',
|
2026-01-21 15:49:26 +08:00
|
|
|
|
copies: 1, // 打印份数,默认1份
|
2026-01-06 15:03:14 +08:00
|
|
|
|
idFrontUrl: '',
|
|
|
|
|
|
idBackUrl: '',
|
|
|
|
|
|
recipientIdFrontUrl: '',
|
|
|
|
|
|
recipientIdBackUrl: '',
|
|
|
|
|
|
powerOfAttorneyUrl: '',
|
|
|
|
|
|
idFrontFile: null,
|
|
|
|
|
|
idBackFile: null,
|
|
|
|
|
|
recipientIdFrontFile: null,
|
|
|
|
|
|
recipientIdBackFile: null,
|
|
|
|
|
|
powerOfAttorneyFile: null,
|
|
|
|
|
|
},
|
|
|
|
|
|
errors: {},
|
|
|
|
|
|
showConfirmModal: false,
|
|
|
|
|
|
showAgreement: false,
|
|
|
|
|
|
hasAgreed: false,
|
|
|
|
|
|
isSubmitting: false, // 提交状态标记
|
|
|
|
|
|
// 日期选择器相关
|
|
|
|
|
|
showAdmissionPicker: false,
|
|
|
|
|
|
showDischargePicker: false,
|
|
|
|
|
|
admissionDate: new Date(),
|
|
|
|
|
|
dischargeDate: new Date(),
|
|
|
|
|
|
minDate: new Date(1999, 0, 1) // 最小日期设为1900年1月1日
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
totalSteps() {
|
|
|
|
|
|
return this.steps.length;
|
|
|
|
|
|
},
|
|
|
|
|
|
completedStepNumbers() {
|
|
|
|
|
|
return this.steps.map((_, index) => {
|
|
|
|
|
|
if (this.currentStep > index) {
|
|
|
|
|
|
return '✓';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return index + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
// 获取出院日期的最小值
|
|
|
|
|
|
getMinDischargeDate() {
|
|
|
|
|
|
if (this.formData.admissionDate) {
|
|
|
|
|
|
return new Date(this.formData.admissionDate);
|
|
|
|
|
|
}
|
|
|
|
|
|
return this.minDate;
|
|
|
|
|
|
},
|
|
|
|
|
|
syncRecipientName() {
|
|
|
|
|
|
if (this.handlingType === '1') {
|
|
|
|
|
|
this.formData.recipientName = this.formData.patientName;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 处理入院日期确认
|
|
|
|
|
|
handleAdmissionConfirm(date) {
|
|
|
|
|
|
this.showAdmissionPicker = false;
|
|
|
|
|
|
// 确保 date 是有效日期对象
|
|
|
|
|
|
if (date instanceof Date && !isNaN(date.getTime())) {
|
|
|
|
|
|
this.admissionDate = date;
|
|
|
|
|
|
this.formData.admissionDate = this.formatDate(date);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果出院日期早于入院日期,清空出院日期
|
|
|
|
|
|
if (this.formData.dischargeDate) {
|
|
|
|
|
|
const discharge = new Date(this.formData.dischargeDate);
|
|
|
|
|
|
if (discharge < date) {
|
|
|
|
|
|
this.formData.dischargeDate = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 处理出院日期确认
|
|
|
|
|
|
handleDischargeConfirm(date) {
|
|
|
|
|
|
this.showDischargePicker = false;
|
|
|
|
|
|
// 确保 date 是有效日期对象
|
|
|
|
|
|
if (date instanceof Date && !isNaN(date.getTime())) {
|
|
|
|
|
|
this.dischargeDate = date;
|
|
|
|
|
|
this.formData.dischargeDate = this.formatDate(date);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化日期为YYYY-MM-DD
|
|
|
|
|
|
formatDate(date) {
|
|
|
|
|
|
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
|
|
|
|
return `${year}-${month}-${day}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
,
|
|
|
|
|
|
|
|
|
|
|
|
selectFile(type) {
|
|
|
|
|
|
if (type === 'idFront') {
|
|
|
|
|
|
this.$refs.idFrontInput.click();
|
|
|
|
|
|
} else if (type === 'idBack') {
|
|
|
|
|
|
this.$refs.idBackInput.click();
|
|
|
|
|
|
} else if (type === 'recipientIdFront') {
|
|
|
|
|
|
this.$refs.recipientIdFrontInput.click();
|
|
|
|
|
|
} else if (type === 'recipientIdBack') {
|
|
|
|
|
|
this.$refs.recipientIdBackInput.click();
|
|
|
|
|
|
} else if (type === 'powerOfAttorney') {
|
|
|
|
|
|
this.$refs.powerOfAttorneyInput.click();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
handleFileUpload(type, e) {
|
|
|
|
|
|
const file = e.target.files[0];
|
|
|
|
|
|
if (!file) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (!file.type.startsWith('image/')) {
|
|
|
|
|
|
Toast.fail('请上传图片文件');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.compressImage(file).then(compressedFile => {
|
|
|
|
|
|
if (compressedFile.size > 10 * 1024 * 1024) {
|
|
|
|
|
|
Toast.fail('图片大小不能超过10MB');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type === 'idFront') {
|
|
|
|
|
|
this.formData.idFrontFile = compressedFile;
|
|
|
|
|
|
} else if (type === 'idBack') {
|
|
|
|
|
|
this.formData.idBackFile = compressedFile;
|
|
|
|
|
|
} else if (type === 'recipientIdFront') {
|
|
|
|
|
|
this.formData.recipientIdFrontFile = compressedFile;
|
|
|
|
|
|
} else if (type === 'recipientIdBack') {
|
|
|
|
|
|
this.formData.recipientIdBackFile = compressedFile;
|
|
|
|
|
|
} else if (type === 'powerOfAttorney') {
|
|
|
|
|
|
this.formData.powerOfAttorneyFile = compressedFile;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
|
reader.onload = (event) => {
|
|
|
|
|
|
if (type === 'idFront') {
|
|
|
|
|
|
this.formData.idFrontUrl = event.target.result;
|
|
|
|
|
|
} else if (type === 'idBack') {
|
|
|
|
|
|
this.formData.idBackUrl = event.target.result;
|
|
|
|
|
|
} else if (type === 'recipientIdFront') {
|
|
|
|
|
|
this.formData.recipientIdFrontUrl = event.target.result;
|
|
|
|
|
|
} else if (type === 'recipientIdBack') {
|
|
|
|
|
|
this.formData.recipientIdBackUrl = event.target.result;
|
|
|
|
|
|
} else if (type === 'powerOfAttorney') {
|
|
|
|
|
|
this.formData.powerOfAttorneyUrl = event.target.result;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
reader.readAsDataURL(compressedFile);
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
compressImage(file) {
|
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
if (file.size < 2 * 1024 * 1024) {
|
|
|
|
|
|
resolve(file);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
|
|
const img = new Image();
|
|
|
|
|
|
|
|
|
|
|
|
img.onload = function () {
|
|
|
|
|
|
const maxSize = 1200;
|
|
|
|
|
|
let width = img.width;
|
|
|
|
|
|
let height = img.height;
|
|
|
|
|
|
|
|
|
|
|
|
if (width > height) {
|
|
|
|
|
|
if (width > maxSize) {
|
|
|
|
|
|
height = (height * maxSize) / width;
|
|
|
|
|
|
width = maxSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (height > maxSize) {
|
|
|
|
|
|
width = (width * maxSize) / height;
|
|
|
|
|
|
height = maxSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
canvas.width = width;
|
|
|
|
|
|
canvas.height = height;
|
|
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(img, 0, 0, width, height);
|
|
|
|
|
|
|
|
|
|
|
|
canvas.toBlob((blob) => {
|
|
|
|
|
|
const compressedFile = new File([blob], file.name, {
|
|
|
|
|
|
type: 'image/jpeg',
|
|
|
|
|
|
lastModified: Date.now()
|
|
|
|
|
|
});
|
|
|
|
|
|
resolve(compressedFile);
|
|
|
|
|
|
}, 'image/jpeg', 0.7);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
img.src = URL.createObjectURL(file);
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
validateStep(step) {
|
|
|
|
|
|
const errors = {};
|
|
|
|
|
|
|
|
|
|
|
|
switch (step) {
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
if (!this.handlingType) {
|
|
|
|
|
|
errors.handlingType = '请选择办理类型';
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!this.deliveryType) {
|
|
|
|
|
|
errors.deliveryType = '请选择领取方式';
|
|
|
|
|
|
}
|
2026-01-21 15:49:26 +08:00
|
|
|
|
if (!this.formData.copies) {
|
|
|
|
|
|
errors.copies = '请选择打印份数';
|
|
|
|
|
|
}
|
2026-01-06 15:03:14 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
if (!this.formData.patientName.trim()) {
|
|
|
|
|
|
errors.patientName = '请输入病人姓名';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 新增就诊人卡号验证
|
|
|
|
|
|
if (!this.formData.patientId.trim()) {
|
|
|
|
|
|
errors.patientId = '请输入就诊人卡号';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.phone.trim()) {
|
|
|
|
|
|
errors.phone = '请输入联系电话';
|
|
|
|
|
|
} else if (!/^1[3-9]\d{9}$/.test(this.formData.phone.trim())) {
|
|
|
|
|
|
errors.phone = '请输入有效的11位手机号码(支持13-19开头)';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.idNumber.trim()) {
|
|
|
|
|
|
errors.idNumber = '请输入身份证号';
|
|
|
|
|
|
} else if (!this.validateIdCard(this.formData.idNumber.trim())) {
|
|
|
|
|
|
errors.idNumber = '请输入有效的18位身份证号码';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.hospitalNumber.trim()) {
|
|
|
|
|
|
errors.hospitalNumber = '请输入住院号';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.admissionDate) {
|
|
|
|
|
|
errors.admissionDate = '请选择入院日期';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.dischargeDate) {
|
|
|
|
|
|
errors.dischargeDate = '请选择出院日期';
|
|
|
|
|
|
} else if (this.formData.admissionDate && new Date(this.formData.dischargeDate) < new Date(this.formData.admissionDate)) {
|
|
|
|
|
|
errors.dischargeDate = '出院日期不能早于入院日期';
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
if (this.handlingType === '2') {
|
|
|
|
|
|
if (!this.formData.recipientName.trim()) {
|
|
|
|
|
|
errors.recipientName = '请输入代办人姓名';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.recipientPhone.trim()) {
|
|
|
|
|
|
errors.recipientPhone = '请输入代办人联系电话';
|
|
|
|
|
|
} else if (!/^1[3-9]\d{9}$/.test(this.formData.recipientPhone.trim())) {
|
|
|
|
|
|
errors.recipientPhone = '请输入有效的11位手机号码(支持13-19开头)';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.formData.recipientIdNumber.trim()) {
|
|
|
|
|
|
errors.recipientIdNumber = '请输入代办人身份证号';
|
|
|
|
|
|
} else if (!this.validateIdCard(this.formData.recipientIdNumber.trim())) {
|
|
|
|
|
|
errors.recipientIdNumber = '请输入有效的18位身份证号码';
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
if (!this.formData.idFrontFile) {
|
|
|
|
|
|
errors.idFront = '请上传患者身份证正面照片';
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!this.formData.idBackFile) {
|
|
|
|
|
|
errors.idBack = '请上传患者身份证反面照片';
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.handlingType === '2' && !this.formData.powerOfAttorneyFile) {
|
|
|
|
|
|
errors.powerOfAttorney = '请上传病案复印授权委托书';
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!this.hasAgreed) {
|
|
|
|
|
|
errors.agreement = '请阅读并同意病案申请须知';
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.errors = errors;
|
|
|
|
|
|
return Object.keys(errors).length === 0;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
validateIdCard(idCard) {
|
|
|
|
|
|
// 使用更严格的正则表达式验证身份证号码格式
|
|
|
|
|
|
const idCardRegex = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
|
|
|
|
|
|
if (!idCardRegex.test(idCard)) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 校验码验证
|
|
|
|
|
|
const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
|
|
|
|
|
const parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
|
|
|
|
|
let sum = 0;
|
|
|
|
|
|
let code = idCard.substring(17);
|
|
|
|
|
|
for (let i = 0; i < 17; i++) {
|
|
|
|
|
|
sum += parseInt(idCard[i], 10) * factor[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
return parity[sum % 11].toUpperCase() === code.toUpperCase();
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
nextStep() {
|
|
|
|
|
|
if (this.validateStep(this.currentStep)) {
|
|
|
|
|
|
if (this.currentStep === 1 && this.handlingType === '1') {
|
|
|
|
|
|
this.syncRecipientName();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
|
|
|
|
this.currentStep++;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (this.currentStep === 3 && (this.errors.idFront || this.errors.idBack || this.errors.recipientIdFront || this.errors.recipientIdBack)) {
|
|
|
|
|
|
Toast.fail(this.handlingType === '2' ? '请上传完整的患者及代办人证件照片' : '请上传完整的身份证照片');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const firstError = Object.keys(this.errors)[0];
|
|
|
|
|
|
if (firstError) {
|
|
|
|
|
|
const elementIdMap = {
|
|
|
|
|
|
patientName: 'patientName',
|
|
|
|
|
|
patientId: 'patientId', // 新增就诊人卡号的元素ID映射
|
|
|
|
|
|
phone: 'phoneNumber',
|
|
|
|
|
|
idNumber: 'idNumber',
|
|
|
|
|
|
hospitalNumber: 'hospitalNumber',
|
|
|
|
|
|
admissionDate: 'admissionDate',
|
|
|
|
|
|
dischargeDate: 'dischargeDate',
|
|
|
|
|
|
recipientName: 'recipientName',
|
|
|
|
|
|
recipientPhone: 'recipientPhone',
|
|
|
|
|
|
recipientIdNumber: 'recipientIdNumber'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const elementId = elementIdMap[firstError];
|
|
|
|
|
|
if (elementId) {
|
|
|
|
|
|
document.getElementById(elementId)?.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
prevStep() {
|
|
|
|
|
|
this.errors = {};
|
|
|
|
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
|
|
|
|
this.currentStep--;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
handleSubmit() {
|
|
|
|
|
|
if (this.validateStep(this.currentStep)) {
|
|
|
|
|
|
this.showConfirmModal = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
submitConfirmed() {
|
|
|
|
|
|
// 防止重复点击(如果用户快速点击)
|
|
|
|
|
|
if (this.isSubmitting) return;
|
|
|
|
|
|
|
|
|
|
|
|
this.isSubmitting = true; // 标记为提交中,禁用按钮
|
|
|
|
|
|
this.showConfirmModal = false;
|
|
|
|
|
|
|
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
|
|
|
|
|
|
|
formData.append('patientName', this.formData.patientName);
|
|
|
|
|
|
formData.append('patientId', this.formData.patientId); // 新增就诊人卡号字段
|
|
|
|
|
|
formData.append('idNumber', this.formData.idNumber);
|
|
|
|
|
|
formData.append('phone', this.formData.phone);
|
|
|
|
|
|
formData.append('hosNumber', this.formData.hospitalNumber);
|
|
|
|
|
|
formData.append('inhosDate', this.formData.admissionDate);
|
|
|
|
|
|
formData.append('outhosDate', this.formData.dischargeDate);
|
|
|
|
|
|
formData.append('handleType', this.handlingType);
|
|
|
|
|
|
formData.append('deliveryType', this.deliveryType);
|
|
|
|
|
|
formData.append('reName', this.formData.recipientName || '');
|
|
|
|
|
|
formData.append('reId', this.formData.recipientIdNumber || '');
|
|
|
|
|
|
formData.append('rePhone', this.formData.recipientPhone || '');
|
2026-01-21 15:49:26 +08:00
|
|
|
|
formData.append('copies', this.formData.copies);
|
2026-01-06 15:03:14 +08:00
|
|
|
|
|
|
|
|
|
|
const userId = localStorage.getItem("userid");
|
|
|
|
|
|
const token = localStorage.getItem("token");
|
|
|
|
|
|
|
|
|
|
|
|
if (userId && userId !== 'null') {
|
|
|
|
|
|
formData.append("userId", String(userId));
|
|
|
|
|
|
}
|
|
|
|
|
|
if (token && token !== 'null') {
|
|
|
|
|
|
formData.append("token", token);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this.formData.idFrontFile) {
|
|
|
|
|
|
formData.append('cardFrontFile', this.formData.idFrontFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.formData.idBackFile) {
|
|
|
|
|
|
formData.append('cardBackFile', this.formData.idBackFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.formData.recipientIdFrontFile) {
|
|
|
|
|
|
formData.append('recordFrontFile', this.formData.recipientIdFrontFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.formData.recipientIdBackFile) {
|
|
|
|
|
|
formData.append('recordBackFile', this.formData.recipientIdBackFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.formData.powerOfAttorneyFile) {
|
|
|
|
|
|
formData.append('powerOfAttorneyFile', this.formData.powerOfAttorneyFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
const loading = Toast.loading({
|
|
|
|
|
|
message: '提交中...', // 加载提示文字
|
|
|
|
|
|
duration: 0, // 0 表示不会自动关闭,需要手动清除
|
|
|
|
|
|
forbidClick: true, // 禁止背景点击(防止重复提交)
|
|
|
|
|
|
loadingType: 'spinner' // 加载图标样式(可选,默认是 circular)
|
|
|
|
|
|
});
|
|
|
|
|
|
apiBayj(formData).then(res => {
|
|
|
|
|
|
console.log('后台返回:', res);
|
|
|
|
|
|
// 关闭加载提示
|
|
|
|
|
|
loading.clear();
|
|
|
|
|
|
this.isSubmitting = false; // 恢复提交状态
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
|
|
|
|
|
|
Toast.success('提交成功');
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.$router.push('/Bayj_wdsq');
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
this.resetForm();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Toast.fail(res.message || '提交失败,请重试');
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
this.isSubmitting = false; // 恢复提交状态
|
|
|
|
|
|
// 关闭加载提示(错误情况也要关闭)
|
|
|
|
|
|
loading.clear();
|
|
|
|
|
|
console.error('申请提交失败:', err);
|
|
|
|
|
|
Toast.fail('网络异常,请检查网络后重试');
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
resetForm() {
|
|
|
|
|
|
this.currentStep = 0;
|
|
|
|
|
|
this.handlingType = '';
|
|
|
|
|
|
this.deliveryType = '';
|
|
|
|
|
|
this.hasAgreed = false;
|
|
|
|
|
|
this.formData = {
|
|
|
|
|
|
patientName: '',
|
|
|
|
|
|
patientId: '', // 新增就诊人卡号字段
|
|
|
|
|
|
phone: '',
|
|
|
|
|
|
idNumber: '',
|
|
|
|
|
|
hospitalNumber: '',
|
|
|
|
|
|
admissionDate: '',
|
|
|
|
|
|
dischargeDate: '',
|
|
|
|
|
|
recipientName: '',
|
|
|
|
|
|
recipientPhone: '',
|
|
|
|
|
|
recipientIdNumber: '',
|
2026-01-21 15:49:26 +08:00
|
|
|
|
copies: 1, // 打印份数,默认1份
|
2026-01-06 15:03:14 +08:00
|
|
|
|
idFrontFile: null,
|
|
|
|
|
|
idBackFile: null,
|
|
|
|
|
|
recipientIdFrontFile: null,
|
|
|
|
|
|
recipientIdBackFile: null,
|
|
|
|
|
|
powerOfAttorneyFile: null,
|
|
|
|
|
|
idFrontUrl: '',
|
|
|
|
|
|
idBackUrl: '',
|
|
|
|
|
|
recipientIdFrontUrl: '',
|
|
|
|
|
|
recipientIdBackUrl: '',
|
|
|
|
|
|
powerOfAttorneyUrl: '',
|
|
|
|
|
|
};
|
|
|
|
|
|
// 重置日期选择器
|
|
|
|
|
|
this.admissionDate = new Date();
|
|
|
|
|
|
this.dischargeDate = new Date();
|
|
|
|
|
|
this.showAdmissionPicker = false;
|
|
|
|
|
|
this.showDischargePicker = false;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
agreeAgreement() {
|
|
|
|
|
|
this.showAgreement = false;
|
|
|
|
|
|
this.hasAgreed = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
* {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
font-family: 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', sans-serif;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.medical-form-page {
|
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
padding: 0.4rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.center-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.medical-form {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
max-width: 950px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.5rem;
|
|
|
|
|
|
padding: 0.6rem;
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
border-radius: 0.1rem;
|
|
|
|
|
|
box-shadow: 0 0.02rem 0.08rem rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-header {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin-bottom: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-title {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 0.42rem;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
margin-bottom: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-desc {
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
font-size: 0.36rem;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.steps-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
margin: 0.5rem 0;
|
|
|
|
|
|
padding: 0 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-line {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 50%;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
height: 0.02rem;
|
|
|
|
|
|
background-color: #e5e7eb;
|
|
|
|
|
|
transform: translateY(-50%);
|
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-item {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-number {
|
|
|
|
|
|
width: 0.6rem;
|
|
|
|
|
|
height: 0.6rem;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
background-color: #e5e7eb;
|
|
|
|
|
|
color: #9ca3af;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 0.36rem;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
margin-bottom: 0.15rem;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-name {
|
|
|
|
|
|
font-size: 0.34rem;
|
|
|
|
|
|
color: #9ca3af;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-item.active .step-number {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-item.active .step-name {
|
|
|
|
|
|
color: #4299e1;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-item.completed .step-number {
|
|
|
|
|
|
background-color: #4ade80;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-item.completed .step-name {
|
|
|
|
|
|
color: #4ade80;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-content {
|
|
|
|
|
|
min-height: 3rem;
|
|
|
|
|
|
margin: 0.3rem 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-panel {
|
|
|
|
|
|
animation: fadeIn 0.3s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes fadeIn {
|
|
|
|
|
|
from {
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
transform: translateY(0.2rem);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
to {
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.self-handling-step3 {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 1rem 0.5rem;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-navigation {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
margin-top: 0.5rem;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.nav-btn {
|
|
|
|
|
|
padding: 0.25rem 0;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.prev-btn {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.prev-btn:disabled {
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
color: #ccc;
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.next-btn {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border: 1px solid #4299e1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.next-btn:disabled {
|
|
|
|
|
|
background-color: #b3d4fc;
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-section {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
margin-bottom: 0.4rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 0.4rem;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
padding-bottom: 0.2rem;
|
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-fields {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.date-group {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-group {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.15rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-group label {
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.required {
|
|
|
|
|
|
color: #DC2626;
|
|
|
|
|
|
margin-left: 0.05rem;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-input {
|
|
|
|
|
|
padding: 0.25rem 0.3rem;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
transition: border-color 0.2s;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-input:focus {
|
|
|
|
|
|
outline: none;
|
|
|
|
|
|
border-color: #4299e1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.error-text {
|
|
|
|
|
|
color: #EF4444;
|
|
|
|
|
|
font-size: 0.36rem;
|
|
|
|
|
|
min-height: 0.4rem;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-type-section {
|
|
|
|
|
|
margin-bottom: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-type-selector {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
margin-top: 0.2rem;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-option {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 0.15rem;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 0.25rem 0.3rem;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-option:hover {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-radio {
|
|
|
|
|
|
width: 0.32rem;
|
|
|
|
|
|
height: 0.32rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-text {
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.delivery-type-section {
|
|
|
|
|
|
margin-bottom: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.delivery-type-selector {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
margin-top: 0.2rem;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.delivery-option {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 0.15rem;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 0.25rem 0.3rem;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.delivery-option:hover {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.delivery-radio {
|
|
|
|
|
|
width: 0.32rem;
|
|
|
|
|
|
height: 0.32rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.delivery-text {
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-21 15:49:26 +08:00
|
|
|
|
.copies-options {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
margin-top: 0.2rem;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-option {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 0.15rem;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
padding: 0.25rem 0.3rem;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-option:hover {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-radio {
|
|
|
|
|
|
width: 0.32rem;
|
|
|
|
|
|
height: 0.32rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-text {
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-option:has(.copy-radio:checked) {
|
|
|
|
|
|
border-color: #4299e1;
|
|
|
|
|
|
background-color: #f0f7ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-06 15:03:14 +08:00
|
|
|
|
.handling-option:has(.handling-radio:checked),
|
|
|
|
|
|
.delivery-option:has(.delivery-radio:checked) {
|
|
|
|
|
|
border-color: #4299e1;
|
|
|
|
|
|
background-color: #f0f7ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.fixed-value {
|
|
|
|
|
|
padding: 0.25rem 0.3rem;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-section {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
margin: 0.3rem 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-item {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-preview {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 2.8rem;
|
|
|
|
|
|
border: 1px dashed #ddd;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.id-img {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
object-fit: contain;
|
|
|
|
|
|
padding: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-preview.uploaded {
|
|
|
|
|
|
border-style: solid;
|
|
|
|
|
|
border-color: #ccc;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-btn {
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
color: #4299e1;
|
|
|
|
|
|
border: 1px solid #4299e1;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
padding: 0.15rem 0.25rem;
|
|
|
|
|
|
font-size: 0.32rem;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-btn:hover {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.file-input {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-desc {
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
margin-top: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-notes {
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
font-size: 0.36rem;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
padding: 0.2rem;
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
border: 1px solid #eee;
|
|
|
|
|
|
margin-top: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
|
.upload-row {
|
|
|
|
|
|
gap: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.upload-preview {
|
|
|
|
|
|
height: 2.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-section {
|
|
|
|
|
|
margin: 0.3rem 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-check {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 0.15rem;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
font-size: 0.36rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.checkbox {
|
|
|
|
|
|
width: 0.36rem;
|
|
|
|
|
|
height: 0.36rem;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.checkbox.checked {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
border-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-check a {
|
|
|
|
|
|
color: #4299e1;
|
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-check a:hover {
|
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.submit-btn {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
padding: 0.25rem 0.4rem;
|
|
|
|
|
|
font-size: 0.4rem;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: background-color 0.2s;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.submit-btn:disabled {
|
|
|
|
|
|
background-color: #b3d4fc;
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.submit-btn:not(:disabled):hover {
|
|
|
|
|
|
background-color: #3182ce;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-backdrop {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
|
padding: 0.4rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.confirm-modal,
|
|
|
|
|
|
.agreement-modal {
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
border-radius: 0.1rem;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
box-shadow: 0 0.04rem 0.2rem rgba(0, 0, 0, 0.15);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-modal {
|
|
|
|
|
|
max-height: 90vh;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-title {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 0.4rem;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
padding: 0.3rem 0.4rem;
|
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.confirm-details {
|
|
|
|
|
|
padding: 0.4rem;
|
|
|
|
|
|
max-height: 60vh;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.detail-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
padding: 0.2rem 0;
|
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
|
font-size: 0.36rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.detail-item:last-child {
|
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.detail-label {
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
flex: 0 0 35%;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.detail-value {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
flex: 0 0 65%;
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.confirm-buttons {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
border-top: 1px solid #eee;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cancel-btn,
|
|
|
|
|
|
.confirm-btn {
|
|
|
|
|
|
padding: 0.25rem 0.4rem;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cancel-btn {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
border-right: 1px solid #eee;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.confirm-btn {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 0.4rem;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
color: #555;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agreement-footer {
|
|
|
|
|
|
padding: 0.3rem 0.4rem;
|
|
|
|
|
|
border-top: 1px solid #eee;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.agree-btn {
|
|
|
|
|
|
background-color: #4299e1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 0.05rem;
|
|
|
|
|
|
padding: 0.25rem 0.4rem;
|
|
|
|
|
|
font-size: 0.38rem;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: background-color 0.2s;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
|
.medical-form {
|
|
|
|
|
|
padding: 0.4rem;
|
|
|
|
|
|
gap: 0.4rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-row {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.3rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.handling-type-selector,
|
|
|
|
|
|
.delivery-type-selector {
|
|
|
|
|
|
gap: 0.2rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.detail-item {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 0.1rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.detail-label,
|
|
|
|
|
|
.detail-value {
|
|
|
|
|
|
flex: none;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.step-name {
|
|
|
|
|
|
font-size: 0.3rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.date-display {
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.date-display:disabled {
|
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|