- 将诊断组件中家长姓名输入框占位符从"≤14 岁必填"改为"≤14岁必填" - 将传染病报告组件中家长姓名输入框占位符统一为"≤14岁必填" - 移除多余的条件判断逻辑,简化占位符显示逻辑
1856 lines
59 KiB
Vue
1856 lines
59 KiB
Vue
<template>
|
||
<el-dialog
|
||
v-model="dialogVisible"
|
||
width="1100px"
|
||
append-to-body
|
||
destroy-on-close
|
||
:show-close="true"
|
||
@close="handleClose"
|
||
>
|
||
<template #header>
|
||
<el-card class="report-header" shadow="never">
|
||
<h1 class="report-title">中华人民共和国传染病报告卡</h1>
|
||
<el-space align="center" class="card-number-row">
|
||
<span class="card-number-label">卡片编号:</span>
|
||
<el-input
|
||
v-model="form.cardNo"
|
||
class="card-number-input"
|
||
placeholder="单位自编,与网络直报一致"
|
||
maxlength="12"
|
||
/>
|
||
</el-space>
|
||
</el-card>
|
||
</template>
|
||
|
||
<el-card class="report-form" shadow="never">
|
||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
|
||
<!-- 患者姓名、家长姓名、身份证号 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">患者姓名</span>
|
||
<el-input v-model="form.patName" class="underline-input" disabled />
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span :class="['form-label', isChildPatient ? 'required' : '']">家长姓名</span>
|
||
<el-input v-model="form.parentName" class="underline-input" placeholder="≤14岁必填" />
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">身份证号</span>
|
||
<el-input v-model="form.idNo" class="underline-input" maxlength="18" @change="handleIdCardChange" />
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 性别、出生日期、实足年龄 -->
|
||
<el-row :gutter="16" class="form-row align-bottom">
|
||
<el-col :span="6" class="form-item">
|
||
<span class="form-label required">性别</span>
|
||
<el-radio-group v-model="form.sex">
|
||
<el-radio label="男">男</el-radio>
|
||
<el-radio label="女">女</el-radio>
|
||
<el-radio label="未知">未知</el-radio>
|
||
</el-radio-group>
|
||
</el-col>
|
||
<el-col :span="10" class="form-item birth-date">
|
||
<span class="form-label required">出生日期</span>
|
||
<div class="date-inputs">
|
||
<el-input v-model="form.birthYear" class="underline-input small" maxlength="4" @change="calculateAge" />
|
||
<span>年</span>
|
||
<el-input v-model="form.birthMonth" class="underline-input small" maxlength="2" @change="calculateAge" />
|
||
<span>月</span>
|
||
<el-input v-model="form.birthDay" class="underline-input small" maxlength="2" @change="calculateAge" />
|
||
<span>日</span>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="8" class="form-item age-item">
|
||
<span class="form-label">或 实足年龄</span>
|
||
<div class="age-inputs">
|
||
<el-input v-model="form.age" class="underline-input small"/>
|
||
<el-select v-model="form.ageUnit" class="age-unit-select">
|
||
<el-option label="岁" value="岁" />
|
||
<el-option label="月" value="月" />
|
||
<el-option label="天" value="天" />
|
||
</el-select>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 工作单位 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="24" class="form-item full-width">
|
||
<span class="form-label">工作单位(学校)</span>
|
||
<el-input v-model="form.workplace" class="underline-input" />
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 联系电话、紧急联系人电话 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="12" class="form-item">
|
||
<span class="form-label required">联系电话</span>
|
||
<el-input v-model="form.phone" class="underline-input" maxlength="11" />
|
||
</el-col>
|
||
<el-col :span="12" class="form-item">
|
||
<span class="form-label required">紧急联系人电话</span>
|
||
<el-input v-model="form.contactPhone" class="underline-input" maxlength="11" />
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 现住地址 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="24" class="form-item full-width">
|
||
<span class="form-label required">现住地址</span>
|
||
<div class="address-selects">
|
||
<el-select v-model="provinceCode" placeholder="省" clearable @change="handleProvinceChange">
|
||
<el-option v-for="item in provinceOptions" :key="item.code" :label="item.name" :value="item.code" />
|
||
</el-select>
|
||
<el-select v-model="cityCode" placeholder="市" clearable @change="handleCityChange">
|
||
<el-option v-for="item in cityOptions" :key="item.code" :label="item.name" :value="item.code" />
|
||
</el-select>
|
||
<el-select v-model="countyCode" placeholder="区县" clearable @change="handleCountyChange">
|
||
<el-option v-for="item in countyOptions" :key="item.code" :label="item.name" :value="item.code" />
|
||
</el-select>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="8" class="form-item">
|
||
<el-select v-model="townCode" placeholder="街道" clearable @change="handleTownChange" class="underline-select">
|
||
<el-option v-for="item in townOptions" :key="item.code" :label="item.name" :value="item.code" />
|
||
</el-select>
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<el-input v-model="form.addressVillage" class="underline-input" placeholder="村(居)" />
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<el-input v-model="form.addressHouse" class="underline-input" placeholder="门牌号" />
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 病人属于 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="24" class="form-item full-width">
|
||
<span class="form-label required">病人属于</span>
|
||
<el-radio-group v-model="form.patientBelong">
|
||
<el-radio label="1">本县区</el-radio>
|
||
<el-radio label="2">本市其他县区</el-radio>
|
||
<el-radio label="3">本省其他地市</el-radio>
|
||
<el-radio label="4">外省</el-radio>
|
||
<el-radio label="5">港澳台</el-radio>
|
||
<el-radio label="6">外籍</el-radio>
|
||
</el-radio-group>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 职业 -->
|
||
<!-- 职业、病例分类 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">职业</span>
|
||
<el-select v-model="form.occupation" placeholder="请选择职业" class="full-select">
|
||
<el-option v-for="item in occupationList" :key="item.value" :label="item.label" :value="item.value" />
|
||
</el-select>
|
||
</el-col>
|
||
<el-col :span="16" class="form-item">
|
||
<span class="form-label required">病例分类</span>
|
||
<div class="case-class-group">
|
||
<div class="case-class-row">
|
||
<el-radio v-model="form.caseClass" label="1">疑似病例</el-radio>
|
||
<el-radio v-model="form.caseClass" label="2">临床诊断病例</el-radio>
|
||
<el-radio v-model="form.caseClass" label="3">确诊病例</el-radio>
|
||
</div>
|
||
<div class="case-class-row">
|
||
<el-radio v-model="form.caseClass" label="4">病原携带者</el-radio>
|
||
<el-radio v-model="form.caseClass" label="5">阳性检测结果(采供血机构填写)</el-radio>
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 发病日期、诊断日期、死亡日期 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">发病日期</span>
|
||
<el-date-picker
|
||
v-model="form.onsetDate"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
class="full-width-picker"
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
/>
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">诊断日期</span>
|
||
<el-date-picker
|
||
v-model="form.diagDate"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
class="full-width-picker"
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
/>
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label">死亡日期</span>
|
||
<el-date-picker
|
||
v-model="form.deathDate"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
class="full-width-picker"
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
/>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 疾病名称 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="24" class="form-item full-width">
|
||
<span class="form-label required">疾病名称(勾选或补填)</span>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 甲类传染病 -->
|
||
<el-card class="disease-section">
|
||
<div class="disease-title">甲类传染病</div>
|
||
<div class="disease-list">
|
||
<el-checkbox
|
||
:model-value="form.selectedClassA === '0101'"
|
||
@update:model-value="(checked) => handleClassACheckbox('0101', checked)"
|
||
label="0101"
|
||
>鼠疫</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassA === '0102'"
|
||
@update:model-value="(checked) => handleClassACheckbox('0102', checked)"
|
||
label="0102"
|
||
>霍乱</el-checkbox>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- 乙类传染病 -->
|
||
<el-card class="disease-section">
|
||
<div class="disease-title">乙类传染病</div>
|
||
<div class="disease-list four-columns">
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0201'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0201', checked)"
|
||
label="0201"
|
||
>传染性非典型肺炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0202'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0202', checked)"
|
||
label="0202"
|
||
>艾滋病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0203'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0203', checked)"
|
||
label="0203"
|
||
>病毒性肝炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0204'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0204', checked)"
|
||
label="0204"
|
||
>脊髓灰质炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0205'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0205', checked)"
|
||
label="0205"
|
||
>人感染高致病性禽流感</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0206'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0206', checked)"
|
||
label="0206"
|
||
>麻疹</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0207'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0207', checked)"
|
||
label="0207"
|
||
>流行性出血热</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0208'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0208', checked)"
|
||
label="0208"
|
||
>狂犬病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0209'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0209', checked)"
|
||
label="0209"
|
||
>流行性乙型脑炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0210'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0210', checked)"
|
||
label="0210"
|
||
>登革热</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0211'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0211', checked)"
|
||
label="0211"
|
||
>炭疽</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0212'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0212', checked)"
|
||
label="0212"
|
||
>细菌性和阿米巴性痢疾</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0213'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0213', checked)"
|
||
label="0213"
|
||
>肺结核</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0214'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0214', checked)"
|
||
label="0214"
|
||
>伤寒和副伤寒</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0215'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0215', checked)"
|
||
label="0215"
|
||
>流行性脑脊髓膜炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0216'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0216', checked)"
|
||
label="0216"
|
||
>百日咳</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0217'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0217', checked)"
|
||
label="0217"
|
||
>白喉</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0218'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0218', checked)"
|
||
label="0218"
|
||
>新生儿破伤风</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0219'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0219', checked)"
|
||
label="0219"
|
||
>猩红热</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0220'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0220', checked)"
|
||
label="0220"
|
||
>布鲁氏菌病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0221'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0221', checked)"
|
||
label="0221"
|
||
>淋病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0222'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0222', checked)"
|
||
label="0222"
|
||
>梅毒</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0223'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0223', checked)"
|
||
label="0223"
|
||
>钩端螺旋体病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0224'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0224', checked)"
|
||
label="0224"
|
||
>血吸虫病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0225'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0225', checked)"
|
||
label="0225"
|
||
>疟疾</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0226'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0226', checked)"
|
||
label="0226"
|
||
>新型冠状病毒肺炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0227'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0227', checked)"
|
||
label="0227"
|
||
>甲型H1N1流感</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassB === '0228'"
|
||
@update:model-value="(checked) => handleClassBCheckbox('0228', checked)"
|
||
label="0228"
|
||
>人感染H7N9禽流感</el-checkbox>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- 丙类传染病 -->
|
||
<el-card class="disease-section">
|
||
<div class="disease-title">丙类传染病</div>
|
||
<div class="disease-list four-columns">
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0301'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0301', checked)"
|
||
label="0301"
|
||
>流行性感冒</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0302'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0302', checked)"
|
||
label="0302"
|
||
>流行性腮腺炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0303'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0303', checked)"
|
||
label="0303"
|
||
>风疹</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0304'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0304', checked)"
|
||
label="0304"
|
||
>急性出血性结膜炎</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0305'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0305', checked)"
|
||
label="0305"
|
||
>麻风病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0306'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0306', checked)"
|
||
label="0306"
|
||
>流行性和地方性斑疹伤寒</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0307'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0307', checked)"
|
||
label="0307"
|
||
>黑热病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0308'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0308', checked)"
|
||
label="0308"
|
||
>包虫病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0309'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0309', checked)"
|
||
label="0309"
|
||
>丝虫病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0310'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0310', checked)"
|
||
label="0310"
|
||
class="wide-checkbox"
|
||
>除霍乱/菌痢/伤寒副伤寒以外的感染性腹泻病</el-checkbox>
|
||
<el-checkbox
|
||
:model-value="form.selectedClassC === '0311'"
|
||
@update:model-value="(checked) => handleClassCCheckbox('0311', checked)"
|
||
label="0311"
|
||
>手足口病</el-checkbox>
|
||
</div>
|
||
</el-card>
|
||
|
||
<!-- 其他法定管理传染病 -->
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="showSubtypeSelect ? 16 : 24" class="form-item">
|
||
<span class="form-label">其他法定管理以及重点监测传染病</span>
|
||
<el-input v-model="form.otherDisease" class="underline-input" placeholder="手动输入非列表疾病" />
|
||
</el-col>
|
||
<el-col v-if="showSubtypeSelect" :span="8" class="form-item">
|
||
<span class="form-label required">分型</span>
|
||
<el-select
|
||
v-model="form.diseaseType"
|
||
placeholder="请选择分型"
|
||
class="full-select"
|
||
>
|
||
<el-option
|
||
v-for="option in currentSubtypeOptions"
|
||
:key="option.value"
|
||
:label="option.label"
|
||
:value="option.value"
|
||
/>
|
||
</el-select>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label">报告单位</span>
|
||
<el-input v-model="form.reportOrg" class="underline-input" disabled />
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label">联系电话</span>
|
||
<el-input v-model="form.reportOrgPhone" class="underline-input" />
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">报告医生</span>
|
||
<el-input v-model="form.reportDoc" class="underline-input" disabled />
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label required">填卡日期</span>
|
||
<el-date-picker
|
||
v-model="form.reportDate"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
class="full-width-picker"
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
/>
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label">修正病名</span>
|
||
<el-input v-model="form.correctName" class="underline-input" />
|
||
</el-col>
|
||
<el-col :span="8" class="form-item">
|
||
<span class="form-label">退卡原因</span>
|
||
<el-input v-model="form.withdrawReason" class="underline-input" />
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="16" class="form-row">
|
||
<el-col :span="24" class="form-item full-width">
|
||
<span class="form-label">备注</span>
|
||
<el-input v-model="form.remark" type="textarea" :rows="2" />
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</el-card>
|
||
|
||
<template #footer>
|
||
<el-space :size="16" justify="center" class="dialog-footer-space" style="display: flex; justify-content: center; width: 100%;">
|
||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading" class="blue-button">保 存</el-button>
|
||
<el-button type="info" @click="handleClose">关 闭</el-button>
|
||
<el-button type="danger" @click="handleReset">重 置</el-button>
|
||
</el-space>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, getCurrentInstance, watch } from 'vue';
|
||
import pcas from 'china-division/dist/pcas-code.json';
|
||
import { saveInfectiousDiseaseReport } from '../api';
|
||
import useUserStore from '@/store/modules/user';
|
||
import { useDict } from '@/utils/dict';
|
||
|
||
const { proxy } = getCurrentInstance();
|
||
const userStore = useUserStore();
|
||
|
||
// 获取职业字典数据
|
||
const { prfs: occupationList } = useDict('prfs');
|
||
|
||
// 公共常量
|
||
const PHONE_REGEX = /^1[3-9]\d{9}$|^0\d{2,3}-?\d{7,8}$/;
|
||
const DISEASE_NAMES = {
|
||
'0203': '病毒性肝炎',
|
||
'0211': '炭疽',
|
||
'0213': '肺结核',
|
||
'0222': '梅毒',
|
||
'0224': '血吸虫病',
|
||
'0225': '疟疾'
|
||
};
|
||
|
||
const dialogVisible = ref(false);
|
||
const formRef = ref(null);
|
||
// 保存按钮加载状态,防止重复提交
|
||
const submitLoading = ref(false);
|
||
|
||
const props = defineProps({
|
||
patientInfo: {
|
||
type: Object,
|
||
default: () => ({}),
|
||
},
|
||
encounterDiagnosisId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
deptId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
doctorId: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
});
|
||
|
||
const emit = defineEmits(['close', 'success']);
|
||
|
||
|
||
// 地址选择器数据
|
||
const addressData = ref(pcas);
|
||
const provinceCode = ref('');
|
||
const cityCode = ref('');
|
||
const countyCode = ref('');
|
||
const townCode = ref('');
|
||
const provinceOptions = ref([]);
|
||
const cityOptions = ref([]);
|
||
const countyOptions = ref([]);
|
||
const townOptions = ref([]);
|
||
|
||
// 直辖市列表(这些城市的省级和市级相同)
|
||
const municipalities = ['北京市', '天津市', '上海市', '重庆市'];
|
||
|
||
// 初始化省级选项
|
||
function initProvinceOptions() {
|
||
provinceOptions.value = addressData.value.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
}));
|
||
}
|
||
|
||
// 省级变化处理
|
||
function handleProvinceChange(code) {
|
||
cityCode.value = '';
|
||
countyCode.value = '';
|
||
townCode.value = '';
|
||
cityOptions.value = [];
|
||
countyOptions.value = [];
|
||
townOptions.value = [];
|
||
form.value.addressProv = '';
|
||
form.value.addressCity = '';
|
||
form.value.addressCounty = '';
|
||
form.value.addressTown = '';
|
||
|
||
if (code) {
|
||
const province = addressData.value.find(item => item.code === code);
|
||
if (province) {
|
||
form.value.addressProv = province.name;
|
||
// 直辖市特殊处理:市级选项与省级相同
|
||
if (municipalities.includes(province.name)) {
|
||
cityOptions.value = [{ code: province.code, name: province.name }];
|
||
cityCode.value = province.code;
|
||
form.value.addressCity = province.name;
|
||
// 直辖市的区县是省级的children
|
||
if (province.children && province.children.length > 0) {
|
||
countyOptions.value = province.children[0].children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
}
|
||
} else {
|
||
cityOptions.value = province.children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 市级变化处理
|
||
function handleCityChange(code) {
|
||
countyCode.value = '';
|
||
townCode.value = '';
|
||
countyOptions.value = [];
|
||
townOptions.value = [];
|
||
form.value.addressCity = '';
|
||
form.value.addressCounty = '';
|
||
form.value.addressTown = '';
|
||
|
||
if (code) {
|
||
const province = addressData.value.find(item => item.code === provinceCode.value);
|
||
if (province) {
|
||
// 直辖市处理
|
||
if (municipalities.includes(province.name)) {
|
||
const county = province.children?.[0]?.children?.find(item => item.code === code);
|
||
if (county) {
|
||
form.value.addressCounty = county.name;
|
||
townOptions.value = county.children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
}
|
||
} else {
|
||
const city = province.children?.find(item => item.code === code);
|
||
if (city) {
|
||
form.value.addressCity = city.name;
|
||
countyOptions.value = city.children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 区县变化处理
|
||
function handleCountyChange(code) {
|
||
townCode.value = '';
|
||
townOptions.value = [];
|
||
form.value.addressCounty = '';
|
||
form.value.addressTown = '';
|
||
|
||
if (code) {
|
||
const province = addressData.value.find(item => item.code === provinceCode.value);
|
||
if (province) {
|
||
if (municipalities.includes(province.name)) {
|
||
// 直辖市
|
||
const county = province.children?.[0]?.children?.find(item => item.code === code);
|
||
if (county) {
|
||
form.value.addressCounty = county.name;
|
||
townOptions.value = county.children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
}
|
||
} else {
|
||
const city = province.children?.find(item => item.code === cityCode.value);
|
||
if (city) {
|
||
const county = city.children?.find(item => item.code === code);
|
||
if (county) {
|
||
form.value.addressCounty = county.name;
|
||
townOptions.value = county.children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 街道变化处理
|
||
function handleTownChange(code) {
|
||
form.value.addressTown = '';
|
||
if (code) {
|
||
const town = townOptions.value.find(item => item.code === code);
|
||
if (town) {
|
||
form.value.addressTown = town.name;
|
||
}
|
||
}
|
||
}
|
||
|
||
const form = ref({
|
||
cardNo: '',
|
||
patName: '',
|
||
parentName: '',
|
||
idNo: '',
|
||
sex: '男',
|
||
birthYear: '',
|
||
birthMonth: '',
|
||
birthDay: '',
|
||
age: '',
|
||
ageUnit: '岁',
|
||
workplace: '',
|
||
phone: '',
|
||
contactPhone: '',
|
||
addressProv: '',
|
||
addressCity: '',
|
||
addressCounty: '',
|
||
addressTown: '',
|
||
addressVillage: '',
|
||
addressHouse: '',
|
||
patientBelong: '1',
|
||
occupation: '',
|
||
caseClass: '',
|
||
onsetDate: '',
|
||
diagDate: '',
|
||
deathDate: '',
|
||
selectedDiseases: [],
|
||
selectedClassA: '',
|
||
selectedClassB: '',
|
||
selectedClassC: '',
|
||
// 其他传染病名称(手动输入非列表疾病)
|
||
otherDisease: '',
|
||
// 疾病分型:需分型的疾病(如病毒性肝炎、肺结核等)需选择具体分型
|
||
diseaseType: '',
|
||
reportOrg: '',
|
||
reportOrgPhone: '',
|
||
reportDoc: '',
|
||
reportDate: '',
|
||
correctName: '',
|
||
withdrawReason: '',
|
||
remark: '',
|
||
encounterId: '',
|
||
patientId: '',
|
||
diagnosisId: '',
|
||
});
|
||
|
||
// 根据地址名称初始化下拉选择器(用于回显)
|
||
function initAddressByName(provName, cityName, countyName, townName) {
|
||
if (!provName) return;
|
||
|
||
// 初始化省级选项
|
||
initProvinceOptions();
|
||
|
||
// 查找省份
|
||
const province = addressData.value.find(item => item.name === provName);
|
||
if (!province) return;
|
||
|
||
provinceCode.value = province.code;
|
||
form.value.addressProv = province.name;
|
||
|
||
// 直辖市处理
|
||
if (municipalities.includes(provName)) {
|
||
cityOptions.value = [{ code: province.code, name: province.name }];
|
||
cityCode.value = province.code;
|
||
form.value.addressCity = province.name;
|
||
|
||
// 直辖市的区县
|
||
if (province.children && province.children.length > 0) {
|
||
countyOptions.value = province.children[0].children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
|
||
if (countyName) {
|
||
const county = countyOptions.value.find(item => item.name === countyName);
|
||
if (county) {
|
||
countyCode.value = county.code;
|
||
form.value.addressCounty = county.name;
|
||
|
||
// 获取原始区县数据以查找街道
|
||
const countyData = province.children[0].children?.find(item => item.code === county.code);
|
||
if (countyData && countyData.children) {
|
||
townOptions.value = countyData.children.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
}));
|
||
|
||
if (townName) {
|
||
const town = townOptions.value.find(item => item.name === townName);
|
||
if (town) {
|
||
townCode.value = town.code;
|
||
form.value.addressTown = town.name;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// 非直辖市处理
|
||
cityOptions.value = province.children?.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
})) || [];
|
||
|
||
if (cityName) {
|
||
const city = cityOptions.value.find(item => item.name === cityName);
|
||
if (city) {
|
||
cityCode.value = city.code;
|
||
form.value.addressCity = city.name;
|
||
|
||
const cityData = province.children?.find(item => item.code === city.code);
|
||
if (cityData && cityData.children) {
|
||
countyOptions.value = cityData.children.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
}));
|
||
|
||
if (countyName) {
|
||
const county = countyOptions.value.find(item => item.name === countyName);
|
||
if (county) {
|
||
countyCode.value = county.code;
|
||
form.value.addressCounty = county.name;
|
||
|
||
const countyData = cityData.children.find(item => item.code === county.code);
|
||
if (countyData && countyData.children) {
|
||
townOptions.value = countyData.children.map(item => ({
|
||
code: item.code,
|
||
name: item.name
|
||
}));
|
||
|
||
if (townName) {
|
||
const town = townOptions.value.find(item => item.name === townName);
|
||
if (town) {
|
||
townCode.value = town.code;
|
||
form.value.addressTown = town.name;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 疾病类型与分型选项映射
|
||
const diseaseSubtypeMap = {
|
||
// 肺结核
|
||
'0213': [
|
||
{ label: '涂阳', value: '涂阳' },
|
||
{ label: '仅培阳', value: '仅培阳' },
|
||
{ label: '菌阴', value: '菌阴' },
|
||
{ label: '未痰检', value: '未痰检' }
|
||
],
|
||
// 梅毒
|
||
'0222': [
|
||
{ label: 'Ⅰ期', value: 'Ⅰ期' },
|
||
{ label: 'Ⅱ期', value: 'Ⅱ期' },
|
||
{ label: 'Ⅲ期', value: 'Ⅲ期' },
|
||
{ label: '胎传', value: '胎传' },
|
||
{ label: '隐性', value: '隐性' }
|
||
],
|
||
// 炭疽
|
||
'0211': [
|
||
{ label: '肺炭疽', value: '肺炭疽' },
|
||
{ label: '皮肤炭疽', value: '皮肤炭疽' },
|
||
{ label: '胃肠炭疽', value: '胃肠炭疽' },
|
||
{ label: '未分型', value: '未分型' }
|
||
],
|
||
// 病毒性肝炎
|
||
'0203': [
|
||
{ label: '甲型', value: '甲型' },
|
||
{ label: '乙型', value: '乙型' },
|
||
{ label: '丙型', value: '丙型' },
|
||
{ label: '戊型', value: '戊型' }
|
||
],
|
||
// 疟疾
|
||
'0225': [
|
||
{ label: '间日疟', value: '间日疟' },
|
||
{ label: '恶性疟', value: '恶性疟' },
|
||
{ label: '三日疟', value: '三日疟' },
|
||
{ label: '卵形疟', value: '卵形疟' },
|
||
{ label: '未分型', value: '未分型' }
|
||
],
|
||
// 血吸虫病
|
||
'0224': [
|
||
{ label: '急性', value: '急性' },
|
||
{ label: '慢性', value: '慢性' },
|
||
{ label: '晚期', value: '晚期' },
|
||
{ label: '未分型', value: '未分型' }
|
||
]
|
||
};
|
||
|
||
// 计算当前选中的疾病对应的分型选项
|
||
const currentSubtypeOptions = computed(() => {
|
||
if (!form.value.selectedClassA && !form.value.selectedClassB && !form.value.selectedClassC) {
|
||
return [];
|
||
}
|
||
|
||
// 优先使用甲类或乙类疾病(因为它们是单选)
|
||
const selectedDisease = form.value.selectedClassA || form.value.selectedClassB || form.value.selectedClassC;
|
||
return diseaseSubtypeMap[selectedDisease] || [];
|
||
});
|
||
|
||
// 计算是否显示分型选择
|
||
const showSubtypeSelect = computed(() => {
|
||
return (form.value.selectedClassA || form.value.selectedClassB || form.value.selectedClassC) && currentSubtypeOptions.value.length > 0;
|
||
});
|
||
|
||
// 传染病选择为单选模式(甲、乙、丙类各只能选一个)
|
||
// 监听疾病选择变化,自动清空分型选择
|
||
watch(() => [form.value.selectedClassA, form.value.selectedClassB, form.value.selectedClassC], (newVal, oldVal) => {
|
||
// 如果疾病选择发生变化,清空分型选择
|
||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||
form.value.diseaseType = '';
|
||
}
|
||
}, { deep: true });
|
||
|
||
/**
|
||
* 通用疾病选择处理函数
|
||
* 实现单选逻辑:选中时设置值,取消选中时清空
|
||
* @param {string} category - 疾病分类字段名(selectedClassA/selectedClassB/selectedClassC)
|
||
* @param {string} value - 疾病编码
|
||
* @param {boolean} checked - 是否选中
|
||
*/
|
||
const handleDiseaseCheckbox = (category, value, checked) => {
|
||
if (checked) {
|
||
form.value[category] = value;
|
||
} else {
|
||
form.value[category] = '';
|
||
}
|
||
updateSelectedDiseases();
|
||
};
|
||
|
||
// 甲类传染病选择处理(单选)
|
||
const handleClassACheckbox = (value, checked) => {
|
||
handleDiseaseCheckbox('selectedClassA', value, checked);
|
||
};
|
||
|
||
// 乙类传染病选择处理(单选)
|
||
const handleClassBCheckbox = (value, checked) => {
|
||
handleDiseaseCheckbox('selectedClassB', value, checked);
|
||
};
|
||
|
||
// 丙类传染病选择处理(单选)
|
||
const handleClassCCheckbox = (value, checked) => {
|
||
handleDiseaseCheckbox('selectedClassC', value, checked);
|
||
};
|
||
|
||
/**
|
||
* 更新selectedDiseases数组
|
||
* 将甲、乙、丙类选中的疾病编码合并到数组中,用于提交
|
||
*/
|
||
const updateSelectedDiseases = () => {
|
||
const diseases = [];
|
||
if (form.value.selectedClassA) diseases.push(form.value.selectedClassA);
|
||
if (form.value.selectedClassB) diseases.push(form.value.selectedClassB);
|
||
if (form.value.selectedClassC) diseases.push(form.value.selectedClassC);
|
||
form.value.selectedDiseases = diseases;
|
||
};
|
||
|
||
/**
|
||
* 计算是否为14岁以下儿童
|
||
* 用于判断家长姓名是否必填
|
||
*/
|
||
const isChildPatient = computed(() => {
|
||
const age = parseInt(form.value.age);
|
||
return !isNaN(age) && form.value.ageUnit === '岁' && age <= 14;
|
||
});
|
||
|
||
// 需要分型的疾病编码列表(与 diseaseSubtypeMap 保持一致)
|
||
const diseasesRequiringSubtype = ['0203', '0211', '0213', '0222', '0224', '0225'];
|
||
|
||
// 获取当前日期
|
||
function getCurrentDate() {
|
||
const date = new Date();
|
||
const year = date.getFullYear();
|
||
let month = date.getMonth() + 1;
|
||
let day = date.getDate();
|
||
month = month < 10 ? '0' + month : month;
|
||
day = day < 10 ? '0' + day : day;
|
||
return `${year}-${month}-${day}`;
|
||
}
|
||
|
||
// 解析出生日期
|
||
function parseBirthDate(birthDate) {
|
||
if (!birthDate) return { year: '', month: '', day: '' };
|
||
const date = new Date(birthDate);
|
||
if (Number.isNaN(date.getTime())) return { year: '', month: '', day: '' };
|
||
return {
|
||
year: date.getFullYear().toString(),
|
||
month: (date.getMonth() + 1).toString().padStart(2, '0'),
|
||
day: date.getDate().toString().padStart(2, '0'),
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 从身份证号自动解析出生日期和性别
|
||
* @param {string} idNo - 身份证号码(15位或18位)
|
||
* @returns {object|null} - 包含出生日期和性别信息,或null表示解析失败
|
||
*/
|
||
function parseIdCardInfo(idNo) {
|
||
if (!idNo) return null;
|
||
|
||
// 标准化处理:去除空格,大写X
|
||
idNo = idNo.trim().toUpperCase();
|
||
|
||
// 18位身份证
|
||
if (idNo.length === 18) {
|
||
const birthYear = idNo.substring(6, 10);
|
||
const birthMonth = idNo.substring(10, 12);
|
||
const birthDay = idNo.substring(12, 14);
|
||
const genderCode = idNo.substring(16, 17);
|
||
|
||
// 验证日期有效性
|
||
const birthDate = new Date(parseInt(birthYear), parseInt(birthMonth) - 1, parseInt(birthDay));
|
||
if (isNaN(birthDate.getTime())) {
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
birthYear,
|
||
birthMonth,
|
||
birthDay,
|
||
sex: parseInt(genderCode, 10) % 2 === 1 ? '男' : '女',
|
||
birthDate: `${birthYear}-${birthMonth}-${birthDay}`
|
||
};
|
||
}
|
||
|
||
// 15位身份证(老版)
|
||
if (idNo.length === 15) {
|
||
const birthYear = '19' + idNo.substring(6, 8);
|
||
const birthMonth = idNo.substring(8, 10);
|
||
const birthDay = idNo.substring(10, 12);
|
||
const genderCode = idNo.substring(13, 14);
|
||
|
||
// 验证日期有效性
|
||
const birthDate = new Date(parseInt(birthYear), parseInt(birthMonth) - 1, parseInt(birthDay));
|
||
if (isNaN(birthDate.getTime())) {
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
birthYear,
|
||
birthMonth,
|
||
birthDay,
|
||
sex: parseInt(genderCode, 10) % 2 === 1 ? '男' : '女',
|
||
birthDate: `${birthYear}-${birthMonth}-${birthDay}`
|
||
};
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 身份证号变化时自动填充出生日期和性别
|
||
*/
|
||
function handleIdCardChange(value) {
|
||
if (!value) return;
|
||
|
||
const info = parseIdCardInfo(value);
|
||
if (info) {
|
||
// 自动填充出生日期
|
||
form.value.birthYear = info.birthYear;
|
||
form.value.birthMonth = info.birthMonth;
|
||
form.value.birthDay = info.birthDay;
|
||
|
||
// 自动填充性别
|
||
form.value.sex = info.sex;
|
||
|
||
// 计算年龄
|
||
calculateAge();
|
||
}
|
||
}
|
||
|
||
// 计算年龄
|
||
function calculateAge() {
|
||
const { birthYear, birthMonth, birthDay } = form.value;
|
||
if (!birthYear || !birthMonth || !birthDay) return;
|
||
|
||
const birthDate = new Date(parseInt(birthYear), parseInt(birthMonth) - 1, parseInt(birthDay));
|
||
const today = new Date();
|
||
|
||
let age = today.getFullYear() - birthDate.getFullYear();
|
||
const monthDiff = today.getMonth() - birthDate.getMonth();
|
||
|
||
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||
age--;
|
||
}
|
||
|
||
if (age < 0) age = 0;
|
||
|
||
form.value.age = age.toString();
|
||
form.value.ageUnit = '岁';
|
||
}
|
||
|
||
/**
|
||
* 显示对话框并初始化表单数据
|
||
* @param {Object} diagnosisData - 诊断数据,包含已选疾病和地址信息
|
||
*/
|
||
function show(diagnosisData) {
|
||
dialogVisible.value = true;
|
||
|
||
// 重置地址选择器状态
|
||
provinceCode.value = '';
|
||
cityCode.value = '';
|
||
countyCode.value = '';
|
||
townCode.value = '';
|
||
cityOptions.value = [];
|
||
countyOptions.value = [];
|
||
townOptions.value = [];
|
||
|
||
// 初始化省级地址选项
|
||
initProvinceOptions();
|
||
|
||
const patientInfo = props.patientInfo || {};
|
||
const birthInfo = parseBirthDate(patientInfo.birthDate || patientInfo.birthday);
|
||
|
||
// 初始化疾病选择字段
|
||
let selectedClassA = '';
|
||
let selectedClassB = '';
|
||
let selectedClassC = '';
|
||
|
||
// 如果有已选疾病,解析分类
|
||
if (diagnosisData?.selectedDiseases && diagnosisData.selectedDiseases.length > 0) {
|
||
diagnosisData.selectedDiseases.forEach(diseaseCode => {
|
||
if (diseaseCode.startsWith('01')) {
|
||
selectedClassA = diseaseCode;
|
||
} else if (diseaseCode.startsWith('02')) {
|
||
selectedClassB = diseaseCode;
|
||
} else if (diseaseCode.startsWith('03')) {
|
||
selectedClassC = diseaseCode; // 丙类改为单选
|
||
}
|
||
});
|
||
}
|
||
|
||
// 生成默认卡片编号:医疗机构编码+当前年月日+4位流水
|
||
const orgCode = userStore.fixmedinsCode || '0000';
|
||
|
||
form.value = {
|
||
// 卡片编号:单位自编,与网络直报一致
|
||
cardNo: '',
|
||
|
||
// 患者基本信息
|
||
patName: patientInfo.patientName || patientInfo.name || '', // 患者姓名
|
||
parentName: '', // 家长姓名(14岁以下患者必填)
|
||
idNo: patientInfo.idCard, // 身份证号
|
||
sex: patientInfo.sex || patientInfo.genderName || '男', // 性别
|
||
|
||
// 出生日期信息
|
||
birthYear: birthInfo.year, // 出生年份
|
||
birthMonth: birthInfo.month, // 出生月份
|
||
birthDay: birthInfo.day, // 出生日期
|
||
age: patientInfo.age || '', // 实足年龄
|
||
ageUnit: '岁', // 年龄单位(岁/月/天)
|
||
|
||
// 工作单位信息
|
||
workplace: patientInfo.workplace || '', // 工作单位(学校)
|
||
|
||
// 联系方式
|
||
phone: patientInfo.phone || patientInfo.mobile || '', // 联系电话
|
||
contactPhone: '', // 紧急联系人电话
|
||
|
||
// 现住地址信息(省市区街道)
|
||
addressProv: diagnosisData?.addressProv || '', // 省份
|
||
addressCity: diagnosisData?.addressCity || '', // 城市
|
||
addressCounty: diagnosisData?.addressCounty || '', // 区县
|
||
addressTown: diagnosisData?.addressTown || '', // 街道
|
||
addressVillage: diagnosisData?.addressVillage || '', // 乡镇/村
|
||
addressHouse: diagnosisData?.addressHouse || '', // 门牌号
|
||
|
||
// 患者类型和职业
|
||
patientBelong: '1', // 患者属于(本县区/本市其他县区/本省其他地市/外省/港澳台/外籍)
|
||
occupation: '', // 职业
|
||
caseClass: '', // 病例分类(疑似病例/临床诊断病例/确诊病例/病原携带者/阳性检测)
|
||
|
||
// 疾病相关日期
|
||
onsetDate: getCurrentDate(), // 发病日期
|
||
diagDate: getCurrentDate(), // 诊断日期
|
||
deathDate: '', // 死亡日期(如死亡)
|
||
|
||
// 疾病选择信息
|
||
selectedDiseases: [], // 已选疾病列表
|
||
selectedClassA: selectedClassA, // 甲类传染病选择
|
||
selectedClassB: selectedClassB, // 乙类传染病选择
|
||
selectedClassC: selectedClassC, // 丙类传染病选择
|
||
|
||
// 其他传染病信息
|
||
otherDisease: '', // 其他法定管理以及重点监测传染病
|
||
diseaseType: '', // 疾病分型(如病毒性肝炎分型、肺结核分型等)
|
||
|
||
// 报告单位信息
|
||
reportOrg: userStore.fixmedinsCode || '', // 报告单位(统一社会信用代码/组织机构代码)
|
||
reportOrgPhone: '', // 报告单位联系电话
|
||
reportDoc: userStore.nickName || userStore.name || '', // 报告医生
|
||
reportDate: getCurrentDate(), // 报告日期
|
||
|
||
// 订正信息
|
||
correctName: '', // 订正病名
|
||
withdrawReason: '', // 退回原因
|
||
|
||
// 备注信息
|
||
remark: '', // 备注
|
||
|
||
// 系统关联信息
|
||
encounterId: patientInfo.encounterId || '', // 就诊ID
|
||
patientId: patientInfo.patientId || '', // 患者ID
|
||
diagnosisId: diagnosisData?.conditionId || diagnosisData?.definitionId || '', // 诊断ID
|
||
};
|
||
|
||
// 更新selectedDiseases数组
|
||
updateSelectedDiseases();
|
||
|
||
// 设置地址选择组件初始值
|
||
const provName = diagnosisData?.addressProv || '';
|
||
const cityName = diagnosisData?.addressCity || '';
|
||
const countyName = diagnosisData?.addressCounty || '';
|
||
const townName = diagnosisData?.addressTown || '';
|
||
|
||
initAddressByName(provName, cityName, countyName, townName);
|
||
|
||
if (birthInfo.year) {
|
||
calculateAge();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 构建提交数据,将表单字段转换为后端 DTO 期望的格式
|
||
* 包括字段映射、枚举值转换等
|
||
* @returns {Object} 后端期望的提交数据对象
|
||
*/
|
||
async function buildSubmitData() {
|
||
const formData = form.value;
|
||
|
||
// 获取选中的疾病编码
|
||
let diseaseCode = '';
|
||
let diseaseType = null;
|
||
|
||
if (formData.selectedClassA || formData.selectedClassB || formData.selectedClassC) {
|
||
// 优先使用选中的疾病编码(甲类、乙类、丙类)
|
||
diseaseCode = formData.selectedClassA || formData.selectedClassB || formData.selectedClassC;
|
||
// 如果有分型,设置分型编码
|
||
if (formData.diseaseType) {
|
||
diseaseType = formData.diseaseType;
|
||
}
|
||
} else if (formData.otherDisease) {
|
||
// 其他传染病使用自定义编码
|
||
diseaseCode = 'OTHER';
|
||
}
|
||
|
||
// 转换年龄单位:岁=1, 月=2, 天=3
|
||
const ageUnitMap = { '岁': '1', '月': '2', '天': '3' };
|
||
|
||
// 转换病人属于:本县区=1, 本市其他县区=2, 本省其他地市=3, 外省=4, 港澳台=5, 外籍=6
|
||
const patientBelongMap = {
|
||
'本县区': 1, '本市其他县区': 2, '本省其他地市': 3, '外省': 4, '港澳台': 5, '外籍': 6
|
||
};
|
||
|
||
// 构建最终提交数据(字段名与后端 DTO 一致)
|
||
const submitData = {
|
||
cardNo: formData.cardNo,
|
||
visitId: props.patientInfo?.encounterId || formData.encounterId || null,
|
||
diagId: formData.diagnosisId || null,
|
||
patId: formData.patientId || null,
|
||
idType: 1, // 默认身份证
|
||
idNo: formData.idNo,
|
||
patName: formData.patName || '',
|
||
parentName: formData.parentName || null,
|
||
sex: formData.sex === '男' ? '1' : formData.sex === '女' ? '2' : '0',
|
||
birthday: formData.birthYear && formData.birthMonth && formData.birthDay
|
||
? `${formData.birthYear}-${formData.birthMonth}-${formData.birthDay}`
|
||
: null,
|
||
age: formData.age ? parseInt(formData.age) : null,
|
||
ageUnit: ageUnitMap[formData.ageUnit] || '1',
|
||
workplace: formData.workplace || null,
|
||
phone: formData.phone || null,
|
||
contactPhone: formData.contactPhone || null,
|
||
addressProv: formData.addressProv || '',
|
||
addressCity: formData.addressCity || '',
|
||
addressCounty: formData.addressCounty || '',
|
||
addressTown: formData.addressTown || '',
|
||
addressVillage: formData.addressVillage || '',
|
||
addressHouse: formData.addressHouse || '',
|
||
patientBelong: patientBelongMap[formData.patientBelong] || 1,
|
||
occupation: formData.occupation || null,
|
||
diseaseCode: diseaseCode || null,
|
||
diseaseType: diseaseType || null,
|
||
otherDisease: formData.otherDisease || null,
|
||
caseClass: formData.caseClass ? parseInt(formData.caseClass) : null,
|
||
onsetDate: formData.onsetDate || null,
|
||
diagDate: formData.diagDate ? `${formData.diagDate}T00:00:00` : null,
|
||
deathDate: formData.deathDate || null,
|
||
correctName: formData.correctName || null,
|
||
withdrawReason: formData.withdrawReason || null,
|
||
reportOrg: formData.reportOrg || '',
|
||
reportOrgPhone: formData.reportOrgPhone || null,
|
||
reportDoc: formData.reportDoc || '',
|
||
reportDate: formData.reportDate || null,
|
||
cardNameCode: 1, // 默认中华人民共和国传染病报告卡
|
||
registrationSource: 1, // 默认门诊
|
||
status: '',
|
||
deptId: props.deptId || null,
|
||
doctorId: props.doctorId || null,
|
||
};
|
||
|
||
return submitData;
|
||
}
|
||
|
||
/**
|
||
* 手动验证表单字段(用于非 el-form-item 包裹的字段)
|
||
* @returns {boolean} 是否验证通过
|
||
*/
|
||
function validateFormManually() {
|
||
const errors = [];
|
||
|
||
// 卡片编号验证(可选,但如果填写了必须是12位)
|
||
if (form.value.cardNo && form.value.cardNo.length !== 12) {
|
||
errors.push('卡片编号必须为12位');
|
||
}
|
||
|
||
// 身份证号验证
|
||
if (!form.value.idNo) {
|
||
errors.push('请输入身份证号');
|
||
} else {
|
||
const idCardReg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||
if (!idCardReg.test(form.value.idNo)) {
|
||
errors.push('请输入有效的身份证号码');
|
||
}
|
||
}
|
||
|
||
// 联系电话验证
|
||
if (!form.value.phone) {
|
||
errors.push('请输入联系电话');
|
||
} else if (!PHONE_REGEX.test(form.value.phone)) {
|
||
errors.push('请输入有效的联系电话');
|
||
}
|
||
|
||
// 紧急联系人电话验证
|
||
if (!form.value.contactPhone) {
|
||
errors.push('请输入紧急联系人电话');
|
||
} else if (!PHONE_REGEX.test(form.value.contactPhone)) {
|
||
errors.push('请输入有效的紧急联系人电话');
|
||
}
|
||
|
||
// 14岁以下患者家长姓名验证
|
||
if (isChildPatient.value && !form.value.parentName) {
|
||
errors.push('14岁以下患者必须填写家长姓名');
|
||
}
|
||
|
||
// 发病日期验证
|
||
if (!form.value.onsetDate) {
|
||
errors.push('请选择发病日期');
|
||
} else if (form.value.diagDate && new Date(form.value.onsetDate) > new Date(form.value.diagDate)) {
|
||
errors.push('发病日期不能晚于诊断日期');
|
||
}
|
||
|
||
// 诊断日期验证
|
||
if (!form.value.diagDate) {
|
||
errors.push('请选择诊断日期');
|
||
}
|
||
|
||
// 填卡日期验证
|
||
if (!form.value.reportDate) {
|
||
errors.push('请选择填卡日期');
|
||
}
|
||
|
||
// 病例分类验证
|
||
if (!form.value.caseClass) {
|
||
errors.push('请选择病例分类');
|
||
}
|
||
|
||
// 职业验证
|
||
if (!form.value.occupation) {
|
||
errors.push('请选择职业');
|
||
}
|
||
|
||
// 病人属于验证
|
||
if (!form.value.patientBelong) {
|
||
errors.push('请选择病人属于');
|
||
}
|
||
|
||
// 现住地址验证 - 至少需要填写省和市
|
||
if (!form.value.addressProv || !form.value.addressCity) {
|
||
errors.push('请至少选择省和市');
|
||
}
|
||
|
||
// 死亡日期验证
|
||
if (form.value.deathDate) {
|
||
if (form.value.diagDate && new Date(form.value.deathDate) < new Date(form.value.diagDate)) {
|
||
errors.push('死亡日期不能早于诊断日期');
|
||
}
|
||
if (new Date(form.value.deathDate) > new Date()) {
|
||
errors.push('死亡日期不能晚于当前日期');
|
||
}
|
||
}
|
||
|
||
// 疾病分型验证
|
||
const selectedDisease = form.value.selectedClassA || form.value.selectedClassB || form.value.selectedClassC;
|
||
if (diseasesRequiringSubtype.includes(selectedDisease) && !form.value.diseaseType) {
|
||
errors.push(`${DISEASE_NAMES[selectedDisease]}必须选择分型`);
|
||
}
|
||
|
||
// 显示错误信息
|
||
if (errors.length > 0) {
|
||
proxy.$modal.msgError(errors[0]);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 提交表单
|
||
* 使用 async/await 重构,优化错误处理和加载状态
|
||
*/
|
||
async function handleSubmit() {
|
||
try {
|
||
// 手动验证表单字段
|
||
if (!validateFormManually()) {
|
||
return;
|
||
}
|
||
|
||
// 检查是否选择了疾病
|
||
if (form.value.selectedDiseases.length === 0 && !form.value.otherDisease) {
|
||
proxy.$modal.msgError('请至少选择一种疾病或填写其他传染病');
|
||
return;
|
||
}
|
||
|
||
// 开始加载状态,防止重复提交
|
||
submitLoading.value = true;
|
||
|
||
// 构建提交数据
|
||
const submitData = await buildSubmitData();
|
||
|
||
// 调用保存API
|
||
const res = await saveInfectiousDiseaseReport(submitData);
|
||
|
||
if (res.code === 200) {
|
||
proxy.$modal.msgSuccess('传染病报告卡保存成功');
|
||
dialogVisible.value = false;
|
||
emit('success');
|
||
} else {
|
||
proxy.$modal.msgError(res.msg || '保存失败');
|
||
}
|
||
} catch (err) {
|
||
console.error('传染病报告卡保存失败:', err);
|
||
proxy.$modal.msgError(err.message || '保存失败,请检查网络连接');
|
||
} finally {
|
||
// 结束加载状态
|
||
submitLoading.value = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 重置表单
|
||
* 保留患者基本信息(姓名、身份证、性别、出生日期等),清空其他可编辑字段
|
||
*/
|
||
function handleReset() {
|
||
const { patName, idNo, sex, birthYear, birthMonth, birthDay, age, ageUnit, phone, reportOrg, reportDoc } = form.value;
|
||
formRef.value?.resetFields();
|
||
form.value.patName = patName;
|
||
form.value.idNo = idNo;
|
||
form.value.sex = sex;
|
||
form.value.birthYear = birthYear;
|
||
form.value.birthMonth = birthMonth;
|
||
form.value.birthDay = birthDay;
|
||
form.value.age = age;
|
||
form.value.ageUnit = ageUnit;
|
||
form.value.phone = phone;
|
||
form.value.reportOrg = reportOrg;
|
||
form.value.reportDoc = reportDoc;
|
||
form.value.reportDate = getCurrentDate();
|
||
form.value.selectedClassA = '';
|
||
form.value.selectedClassB = '';
|
||
form.value.selectedClassC = ''; // 丙类重置为字符串空值
|
||
form.value.diseaseType = ''; // 重置分型字段
|
||
updateSelectedDiseases(); // 更新selectedDiseases数组
|
||
}
|
||
|
||
/**
|
||
* 关闭对话框
|
||
* 触发 close 事件通知父组件
|
||
*/
|
||
function handleClose() {
|
||
dialogVisible.value = false;
|
||
emit('close');
|
||
}
|
||
|
||
defineExpose({ show });
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 通用输入框样式 */
|
||
:deep(.el-input__wrapper) {
|
||
box-shadow: 0 0 0 1px var(--el-input-border-color, #dcdfe6) inset;
|
||
border-radius: var(--el-input-border-radius, var(--el-border-radius-base, 4px));
|
||
background-color: var(--el-input-bg-color, var(--el-fill-color-blank));
|
||
transition: var(--el-transition-duration);
|
||
}
|
||
|
||
:deep(.el-input__wrapper:hover) {
|
||
box-shadow: 0 0 0 1px var(--el-input-hover-border-color, #c0c4cc) inset;
|
||
}
|
||
|
||
:deep(.el-input__wrapper.is-focus) {
|
||
box-shadow: 0 0 0 1px var(--el-input-focus-border-color, #409eff) inset;
|
||
}
|
||
|
||
/* 标题区样式 */
|
||
.report-header {
|
||
text-align: center;
|
||
padding-bottom: 10px;
|
||
}
|
||
|
||
.report-title {
|
||
color: #2c3e50;
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
margin: 0 0 12px 0;
|
||
}
|
||
|
||
.card-number-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.card-number-label {
|
||
color: #666;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.card-number-input {
|
||
width: 240px;
|
||
|
||
:deep(.el-input__wrapper) {
|
||
border: none;
|
||
border-bottom: 1px solid #dcdfe6;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
background: transparent;
|
||
}
|
||
|
||
:deep(.el-input__inner) {
|
||
font-size: 12px;
|
||
color: #666;
|
||
text-align: center;
|
||
letter-spacing: 2px;
|
||
}
|
||
|
||
:deep(.el-input__inner::placeholder) {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
/* 表单区域样式 */
|
||
.report-form {
|
||
padding: 0 16px;
|
||
max-height: 65vh;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.section-title {
|
||
color: #2c3e50;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
margin: 16px 0 12px 0;
|
||
padding-bottom: 8px;
|
||
border-bottom: 2px solid #3498db;
|
||
}
|
||
|
||
.form-row {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.form-item {
|
||
min-width: 180px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.form-label {
|
||
display: block;
|
||
color: #333;
|
||
font-size: 14px;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.form-label.required::before {
|
||
content: '*';
|
||
color: #e74c3c;
|
||
margin-right: 4px;
|
||
}
|
||
|
||
/* 日期输入样式 */
|
||
.date-inputs {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.date-inputs span {
|
||
color: #606266;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.age-inputs {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
/* 地址选择样式 - 四个下拉框并排 */
|
||
.address-selects {
|
||
display: flex;
|
||
gap: 8px;
|
||
flex: 1;
|
||
}
|
||
|
||
.address-selects .el-select {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.address-selects :deep(.el-input__wrapper) {
|
||
border: none;
|
||
border-bottom: 1px solid #dcdfe6;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
background: transparent;
|
||
}
|
||
|
||
.address-selects :deep(.el-input__wrapper:hover) {
|
||
border-bottom-color: #c0c4cc;
|
||
}
|
||
|
||
.address-selects :deep(.el-input__wrapper.is-focus) {
|
||
border-bottom-color: #409eff;
|
||
}
|
||
|
||
.address-selects :deep(.el-input__inner) {
|
||
font-size: 12px;
|
||
color: #666;
|
||
}
|
||
|
||
.address-selects :deep(.el-input__inner::placeholder) {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
/* 街道下拉框下划线样式 */
|
||
.underline-select {
|
||
width: 100%;
|
||
}
|
||
|
||
.underline-select :deep(.el-input__wrapper) {
|
||
border: none;
|
||
border-bottom: 1px solid #dcdfe6;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
background: transparent;
|
||
}
|
||
|
||
.underline-select :deep(.el-input__wrapper:hover) {
|
||
border-bottom-color: #c0c4cc;
|
||
}
|
||
|
||
.underline-select :deep(.el-input__wrapper.is-focus) {
|
||
border-bottom-color: #409eff;
|
||
}
|
||
|
||
.underline-select :deep(.el-input__inner) {
|
||
font-size: 12px;
|
||
color: #666;
|
||
}
|
||
|
||
.underline-select :deep(.el-input__inner::placeholder) {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
/* 病例分类两行排布 */
|
||
.case-class-group {
|
||
width: 100%;
|
||
}
|
||
|
||
.case-class-row {
|
||
display: flex;
|
||
gap: 16px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.case-class-row:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
|
||
.full-select {
|
||
width: 100%;
|
||
}
|
||
|
||
.age-unit-select {
|
||
width: 70px;
|
||
}
|
||
|
||
/* Element Plus 默认输入框样式 */
|
||
/* 日期选择器样式 */
|
||
:deep(.full-width-picker) {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 单选按钮样式 */
|
||
:deep(.el-radio-group) {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
:deep(.el-radio) {
|
||
margin-right: 16px;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
/* 疾病选择区样式 */
|
||
.disease-section {
|
||
margin-bottom: 12px;
|
||
border: 1px solid #e4e7ed;
|
||
border-radius: 4px;
|
||
padding: 12px;
|
||
background: #fafafa;
|
||
}
|
||
|
||
.disease-title {
|
||
color: #2c3e50;
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
margin-bottom: 10px;
|
||
padding-bottom: 6px;
|
||
border-bottom: 1px solid #e4e7ed;
|
||
}
|
||
|
||
.disease-list {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
.disease-list .el-checkbox {
|
||
width: calc(50% - 8px);
|
||
margin-right: 0;
|
||
}
|
||
|
||
.disease-list.four-columns .el-checkbox {
|
||
width: calc(25% - 8px);
|
||
}
|
||
|
||
.disease-list.four-columns .el-checkbox.wide-checkbox {
|
||
width: calc(50% - 8px);
|
||
}
|
||
|
||
.disease-with-subtype {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
width: calc(25% - 8px);
|
||
}
|
||
|
||
.disease-with-subtype .el-checkbox {
|
||
width: auto;
|
||
}
|
||
|
||
.subtype-select {
|
||
width: 90px;
|
||
}
|
||
|
||
/* 错误状态样式 */
|
||
:deep(.el-form-item.is-error .el-input__wrapper) {
|
||
border-bottom-color: #e74c3c !important;
|
||
}
|
||
|
||
:deep(.el-form-item__error) {
|
||
color: #e74c3c;
|
||
}
|
||
|
||
|
||
/* 响应式调整 */
|
||
@media (max-width: 900px) {
|
||
.disease-list.four-columns .el-checkbox,
|
||
.disease-with-subtype {
|
||
width: calc(50% - 8px);
|
||
}
|
||
.disease-list.four-columns .el-checkbox.wide-checkbox {
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.disease-list .el-checkbox,
|
||
.disease-list.four-columns .el-checkbox,
|
||
.disease-with-subtype {
|
||
width: 100%;
|
||
}
|
||
|
||
}
|
||
|
||
/* 蓝色按钮样式 - 提高优先级 */
|
||
.blue-button {
|
||
background-color: #3498db !important;
|
||
border-color: #3498db !important;
|
||
color: white !important;
|
||
}
|
||
|
||
.blue-button:hover {
|
||
background-color: #2980b9 !important;
|
||
border-color: #2980b9 !important;
|
||
}
|
||
|
||
.blue-button:focus {
|
||
background-color: #2980b9 !important;
|
||
border-color: #2980b9 !important;
|
||
}
|
||
|
||
/* 对话框底部按钮空间居中样式 */
|
||
.dialog-footer-space {
|
||
display: flex !important;
|
||
justify-content: center !important;
|
||
width: 100% !important;
|
||
}
|
||
|
||
.dialog-footer-space :deep(.el-space__item) {
|
||
margin: 0 !important;
|
||
}
|
||
|
||
/* 确保对话框底部内容居中 */
|
||
:deep(.el-dialog__footer) {
|
||
text-align: center !important;
|
||
display: flex !important;
|
||
justify-content: center !important;
|
||
}
|
||
</style>
|