1298 lines
50 KiB
Vue
1298 lines
50 KiB
Vue
<template>
|
||
<!-- <div class="app-container"> -->
|
||
<!-- 添加或修改对话框 -->
|
||
<el-dialog :title="title" v-model="visible" width="1200px" append-to-body>
|
||
<el-form ref="patientRef" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||
<!-- 第一行:姓名、民族、文化程度、性别 -->
|
||
<el-row :gutter="10">
|
||
<el-col :span="6">
|
||
<el-form-item label="姓名" prop="name" label-width="80px">
|
||
<el-input v-model="form.name" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="性别" prop="genderEnum">
|
||
<el-radio-group v-model="form.genderEnum" :disabled="isViewMode">
|
||
<el-radio
|
||
v-for="item in administrativegenderList"
|
||
:key="item.value"
|
||
:label="item.value"
|
||
>
|
||
{{ item.info }}
|
||
</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="活动标识" prop="tempFlag">
|
||
<el-radio-group v-model="form.tempFlag" :disabled="isViewMode">
|
||
<el-radio v-for="dict in patient_temp_flag" :key="dict.value" :label="dict.value">
|
||
{{ dict.label }}
|
||
</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="联系方式" prop="phone">
|
||
<el-input v-model="form.phone" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<!-- <el-col :span="8">
|
||
<el-form-item label="证件类型" prop="typeCode">
|
||
<el-select
|
||
v-model="form.typeCode"
|
||
placeholder="证件类型"
|
||
clearable
|
||
:disabled="isViewMode"
|
||
@change="typeChange"
|
||
>
|
||
<el-option
|
||
v-for="dict in sys_idtype"
|
||
:key="dict.value"
|
||
:label="dict.label"
|
||
:value="dict.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col> -->
|
||
<el-col :span="8">
|
||
<el-form-item label="身份证号码" prop="idCard">
|
||
<el-input v-model="form.idCard" clearable :disabled="isViewMode" @blur="onBlur" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="民族" prop="nationalityCode">
|
||
<el-select v-model="form.nationalityCode" clearable filterable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in nationality_code"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="文化程度" prop="educationLevel" label-width="80px">
|
||
<el-select v-model="form.educationLevel" placeholder="请选择文化程度" clearable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in educationLevelList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="性别" prop="genderEnum" label-width="80px">
|
||
<el-select v-model="form.genderEnum" placeholder="请选择性别" clearable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in administrativegenderList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 第二行:证件类别、证件号码、*年龄 -->
|
||
<el-row :gutter="10">
|
||
<el-col :span="8">
|
||
<el-form-item label="就诊卡号" prop="identifierNo">
|
||
<el-input v-model="form.identifierNo" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<!-- <el-col :span="8">
|
||
<el-form-item label="国家编码" prop="countryCode">
|
||
<el-input v-model="form.countryCode" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col> -->
|
||
</el-row>
|
||
<!-- <el-col :span="6">
|
||
<el-form-item label="年龄" prop="age">
|
||
<el-input v-model="form.age" clearable :disabled="isViewMode"/>
|
||
</el-form-item>
|
||
</el-col> -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="职业" prop="prfsEnum">
|
||
<el-select v-model="form.prfsEnum" placeholder="职业" clearable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in occupationtypeList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="邮政编码" prop="postalCode">
|
||
<el-input v-model="form.postalCode" clearable :disabled="isViewMode" placeholder="请输入邮政编码" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<!-- 第四行:工作单位 -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="工作单位" prop="workCompany">
|
||
<el-input v-model="form.workCompany" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<el-form-item label="单位地址" prop="companyAddress">
|
||
<el-input v-model="form.companyAddress" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<!-- 现住址选择、详细地址 -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="现住址" prop="addressSelect">
|
||
<el-cascader
|
||
:options="options"
|
||
:props="{ checkStrictly: true, value: 'code', label: 'name' }"
|
||
v-model="selectedOptions"
|
||
@change="handleChange"
|
||
:disabled="isViewMode"
|
||
>
|
||
<template #default="{ node, data }">
|
||
<span>{{ data.name }}</span>
|
||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||
</template>
|
||
</el-cascader>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<el-form-item label="详细地址" prop="address">
|
||
<el-input v-model="form.address" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 户籍地址选择、详细地址 -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="户籍地址" prop="hukouAddressSelect">
|
||
<el-cascader
|
||
:options="options"
|
||
:props="{ checkStrictly: true, value: 'code', label: 'name' }"
|
||
v-model="selectedHukouOptions"
|
||
@change="handleHukouChange"
|
||
:disabled="isViewMode"
|
||
>
|
||
<template #default="{ node, data }">
|
||
<span>{{ data.name }}</span>
|
||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||
</template>
|
||
</el-cascader>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<el-form-item label="详细地址" prop="hukouAddress">
|
||
<el-input v-model="form.hukouAddress" clearable :disabled="isViewMode" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 第六行:血型ABO、血型RH -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="血型ABO" prop="bloodAbo">
|
||
<el-select
|
||
v-model="form.bloodAbo"
|
||
placeholder="血型ABO"
|
||
clearable
|
||
:disabled="isViewMode"
|
||
>
|
||
<el-option
|
||
v-for="item in bloodtypeaboList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="血型RH" prop="bloodRh">
|
||
<el-select v-model="form.bloodRh" placeholder="血型RH" clearable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in bloodtypearhList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="患者来源" prop="patientDerived">
|
||
<el-select v-model="form.patientDerived" placeholder="患者来源" clearable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in patientDerivedList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 第七行:婚姻状态、死亡时间 -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="婚姻状态" prop="maritalStatusEnum">
|
||
<el-select
|
||
v-model="form.maritalStatusEnum"
|
||
placeholder="婚姻状态"
|
||
clearable
|
||
:disabled="isViewMode"
|
||
>
|
||
<el-option
|
||
v-for="item in maritalstatusList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<el-form-item label="死亡时间" prop="deceasedDate">
|
||
<el-date-picker
|
||
v-model="form.deceasedDate"
|
||
type="datetime"
|
||
placeholder="请选择时间"
|
||
format="YYYY/MM/DD HH:mm:ss"
|
||
:disabled="isViewMode"
|
||
value-format="YYYY/MM/DD HH:mm:ss"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 第八行:监护人、监护人关系、监护人电话 -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="监护人" prop="guardianName">
|
||
<el-input v-model="form.guardianName" clearable :disabled="isViewMode" placeholder="请输入监护人" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="监护人关系" prop="guardianRelation">
|
||
<el-select v-model="form.guardianRelation" placeholder="监护人关系" clearable :disabled="isViewMode">
|
||
<el-option
|
||
v-for="item in familyrelationshiptypeList"
|
||
:key="item.value"
|
||
:label="item.info"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="监护人电话" prop="guardianPhone">
|
||
<el-input v-model="form.guardianPhone" clearable :disabled="isViewMode" placeholder="请输入监护人电话" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 第九行:监护人证件类型、监护人证件号码 -->
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="监护人证件类型" prop="guardianIdType">
|
||
<el-select v-model="form.guardianIdType" placeholder="请选择" clearable :disabled="isViewMode">
|
||
<el-option label="身份证" value="id_card" />
|
||
<el-option label="护照" value="passport" />
|
||
<el-option label="其他" value="other" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<el-form-item label="监护人证件号码" prop="guardianIdNo">
|
||
<el-input v-model="form.guardianIdNo" clearable :disabled="isViewMode" placeholder="请输入监护人证件号码" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 第十行:监护人地址 -->
|
||
<el-row>
|
||
<el-col :span="24">
|
||
<el-form-item label="监护人地址" prop="guardianAddress">
|
||
<el-input v-model="form.guardianAddress" clearable :disabled="isViewMode" placeholder="请输入监护人详细地址" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||
<el-button @click="cancel">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
<!-- </div> -->
|
||
</template>
|
||
|
||
<script setup name="PatientAddDialog">
|
||
import pcas from 'china-division/dist/pcas-code.json';
|
||
import {addPatient, getOutpatientRegistrationList, patientlLists} from './outpatientregistration';
|
||
import {getGenderAndAge, isValidCNidCardNumber, isValidCNPhoneNumber,} from '../../../../utils/validate';
|
||
import {ElMessage} from 'element-plus';
|
||
|
||
const router = useRouter();
|
||
const { proxy } = getCurrentInstance();
|
||
const {
|
||
patient_gender_enum,
|
||
sys_idtype,
|
||
prfs_enum,
|
||
blood_rh,
|
||
blood_abo,
|
||
marital_status_enum,
|
||
patient_temp_flag,
|
||
link_relation_code,
|
||
nationality_code,
|
||
} = proxy.useDict(
|
||
'patient_gender_enum',
|
||
'sys_idtype',
|
||
'prfs_enum',
|
||
'blood_rh',
|
||
'blood_abo',
|
||
'marital_status_enum',
|
||
'patient_temp_flag',
|
||
'link_relation_code',
|
||
'nationality_code'
|
||
);
|
||
|
||
const selectedOptions = ref([]); // v-model 绑定的选中值
|
||
const selectedHukouOptions = ref([]); // 户籍地址v-model 绑定的选中值
|
||
const maritalstatusList = ref([]); //婚姻
|
||
const occupationtypeList = ref([]); //职业
|
||
const administrativegenderList = ref([]); //性别
|
||
const bloodtypeaboList = ref([]); //血型abo
|
||
const bloodtypearhList = ref([]); //血型RH
|
||
const familyrelationshiptypeList = ref([]); //家庭关系
|
||
const patientDerivedList = ref([]); //患者来源
|
||
// 使用 ref 定义查询所得用户信息数据
|
||
const patientInfo = ref(undefined);
|
||
const addressCom = ref(''); //地址
|
||
const educationLevelList = ref([]); //文化程度
|
||
const countryCodeList = ref([]); //国家地区代码
|
||
|
||
// 从字典管理获取患者来源数据
|
||
const getPatientDerivedOptions = async () => {
|
||
try {
|
||
console.log('开始获取患者来源字典数据...');
|
||
// 从字典管理获取患者来源数据,字典类型为patient_derived
|
||
const patientDerivedDict = await proxy.getDictDataByType('patient_derived');
|
||
console.log('获取到的患者来源原始数据:', patientDerivedDict);
|
||
|
||
// 确保数据是数组
|
||
if (!Array.isArray(patientDerivedDict)) {
|
||
console.error('患者来源数据格式错误,不是数组:', patientDerivedDict);
|
||
return;
|
||
}
|
||
|
||
// 按字典排序字段(sort字段)升序排序
|
||
const sortedPatientDerived = patientDerivedDict.sort((a, b) => {
|
||
// 尝试获取排序字段,可能的字段名:sort, orderNum, dictSort等
|
||
const sortA = a.sort || a.orderNum || a.dictSort || 0;
|
||
const sortB = b.sort || b.orderNum || b.dictSort || 0;
|
||
return sortA - sortB;
|
||
});
|
||
console.log('按排序字段排序后的患者来源数据:', sortedPatientDerived);
|
||
|
||
// 转换为组件需要的格式,确保使用正确的字段名称
|
||
patientDerivedList.value = sortedPatientDerived.map(item => ({
|
||
value: item.value || item.dictValue || item.code || '', // 使用字典键值
|
||
info: item.label || item.dictLabel || item.name || '' // 使用info字段作为显示文本(与模板中的:label="item.info"匹配)
|
||
}));
|
||
console.log('处理后的患者来源选项:', patientDerivedList.value);
|
||
} catch (error) {
|
||
console.error('获取患者来源字典数据失败:', error);
|
||
|
||
// 改进的降级方案:使用默认的患者来源选项
|
||
patientDerivedList.value = [
|
||
{ value: '1', info: '熟人介绍' },
|
||
{ value: '2', info: '电视广告' },
|
||
{ value: '3', info: '公交站牌' },
|
||
{ value: '99', info: '其他' }
|
||
];
|
||
console.warn('使用默认患者来源数据作为降级方案');
|
||
}
|
||
};
|
||
|
||
// 从字典管理获取性别数据
|
||
const getGenderOptions = async () => {
|
||
try {
|
||
// 从字典管理获取性别数据
|
||
const genderDict = await proxy.getDictDataByType('性别');
|
||
// 按字典排序字段排序
|
||
const sortedGenders = genderDict.sort((a, b) => {
|
||
return (a.sort || 0) - (b.sort || 0);
|
||
});
|
||
// 转换为组件需要的格式
|
||
administrativegenderList.value = sortedGenders.map(item => ({
|
||
value: item.value, // 使用字典键值
|
||
info: item.label // 使用字典标签
|
||
}));
|
||
} catch (error) {
|
||
console.error('获取性别字典数据失败:', error);
|
||
// 降级方案:使用默认的性别选项
|
||
administrativegenderList.value = [
|
||
{ value: '1', info: '男' },
|
||
{ value: '2', info: '女' },
|
||
{ value: '9', info: '未说明性别' },
|
||
{ value: '0', info: '未知的性别' }
|
||
];
|
||
}
|
||
};
|
||
|
||
// 从字典管理获取文化程度数据
|
||
const getEducationLevelOptions = async () => {
|
||
try {
|
||
// 从字典管理获取文化程度数据
|
||
const educationDict = await proxy.getDictDataByType('文化程度');
|
||
console.log('获取到的文化程度数据:', educationDict);
|
||
|
||
// 确保数据是数组
|
||
if (!Array.isArray(educationDict)) {
|
||
console.error('文化程度数据格式错误,不是数组:', educationDict);
|
||
return;
|
||
}
|
||
|
||
// 按字典编码顺序升序排列(根据截图显示,排序字段为字典编码)
|
||
const sortedEducation = educationDict.sort((a, b) => {
|
||
// 获取字典编码,可能的字段名:code, dictCode, 或 value
|
||
const codeA = a.code || a.dictCode || a.value || '';
|
||
const codeB = b.code || b.dictCode || b.value || '';
|
||
|
||
// 尝试将编码转换为数字进行升序排序
|
||
const numA = parseInt(codeA);
|
||
const numB = parseInt(codeB);
|
||
|
||
// 如果都是有效数字,则按数字排序,否则按字符串排序
|
||
if (!isNaN(numA) && !isNaN(numB)) {
|
||
return numA - numB;
|
||
} else {
|
||
return codeA.localeCompare(codeB);
|
||
}
|
||
});
|
||
|
||
console.log('按字典编码排序后的文化程度数据:', sortedEducation);
|
||
|
||
// 转换为组件需要的格式
|
||
educationLevelList.value = sortedEducation.map(item => ({
|
||
value: item.value || item.dictValue || item.code || '', // 使用字典键值或编码
|
||
info: item.label || item.dictLabel || item.name || '' // 使用字典标签
|
||
}));
|
||
|
||
console.log('处理后的文化程度选项:', educationLevelList.value);
|
||
} catch (error) {
|
||
console.error('获取文化程度字典数据失败:', error);
|
||
// 降级方案:使用默认的文化程度选项,按编码顺序排列
|
||
educationLevelList.value = [
|
||
{ value: '3912', info: '大学本科' },
|
||
{ value: '3913', info: '硕士研究生' },
|
||
{ value: '3914', info: '博士研究生' },
|
||
{ value: '3915', info: '初中毕业' },
|
||
{ value: '3916', info: '大学毕业' },
|
||
{ value: '3917', info: '技工学校毕业' },
|
||
{ value: '3918', info: '职业高中毕业' },
|
||
{ value: '3919', info: '小学毕业' },
|
||
{ value: '3920', info: '普通高中毕业' },
|
||
{ value: '3921', info: '中等专科毕业' }
|
||
].sort((a, b) => parseInt(a.value) - parseInt(b.value)); // 确保默认选项也按编码排序
|
||
}
|
||
};
|
||
const options = ref(pcas); // 地区数据
|
||
|
||
const title = ref('新增患者');
|
||
const visible = ref(false);
|
||
const emits = defineEmits(['submit']); // 声明自定义事件
|
||
|
||
const validateUniquePatient = (rule, value, callback) => {
|
||
const { name, idCard } = form.value;
|
||
// 确保姓名和身份证都已填写且身份证为18位
|
||
if (!name || !idCard || idCard.length !== 18) {
|
||
return callback(); // 不满足条件,不校验
|
||
}
|
||
|
||
// 使用 axios 直接请求,避免依赖 proxy.$http
|
||
import('@/utils/request').then(({ default: request }) => {
|
||
request({
|
||
url: '/patient-manage/information/check-exists',
|
||
method: 'get',
|
||
params: {
|
||
name: name,
|
||
idCardNo: idCard
|
||
}
|
||
}).then(res => {
|
||
if (res.code === 200 && res.data === true) {
|
||
callback(new Error('该患者档案已存在!'));
|
||
} else {
|
||
callback();
|
||
}
|
||
}).catch(error => {
|
||
console.error('校验患者是否存在失败:', error);
|
||
callback(); // 出错时不阻塞表单
|
||
});
|
||
});
|
||
};
|
||
|
||
|
||
|
||
// 身份证号码校验函数
|
||
const validateIdCard = (rule, value, callback) => {
|
||
if (!value) {
|
||
callback();
|
||
return;
|
||
}
|
||
|
||
// 18位身份证正则
|
||
const reg = /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
|
||
if (!reg.test(value)) {
|
||
return callback(new Error('请输入正确的18位身份证号码'));
|
||
}
|
||
|
||
// 校验码验证(第18位)
|
||
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;
|
||
for (let i = 0; i < 17; i++) {
|
||
sum += parseInt(value.charAt(i)) * factor[i];
|
||
}
|
||
const last = parity[sum % 11];
|
||
if (last !== value.charAt(17).toUpperCase()) {
|
||
return callback(new Error('身份证校验码错误'));
|
||
}
|
||
|
||
callback(); // 校验通过
|
||
}
|
||
|
||
// 监护人信息条件验证函数
|
||
const validateGuardianInfo = (rule, value, callback) => {
|
||
// 只有当年龄小于规定年龄时才验证监护人信息
|
||
if (form.value.age) {
|
||
// 提取年龄数字部分
|
||
const ageMatch = form.value.age.toString().match(/\d+/);
|
||
if (ageMatch) {
|
||
const age = parseInt(ageMatch[0]);
|
||
const guardianAgeValue = parseInt(props.guardianAge) || 16;
|
||
// 如果年龄小于规定年龄,监护人信息必须填写
|
||
if (age < guardianAgeValue && !value) {
|
||
return callback(new Error(`年龄小于${guardianAgeValue}岁的患者必须填写监护人信息`));
|
||
}
|
||
}
|
||
}
|
||
callback();
|
||
}
|
||
|
||
const data = reactive({
|
||
isViewMode: false,
|
||
form: {
|
||
typeCode: '01',
|
||
tempFlag: '1',
|
||
// genderEnum: 0,
|
||
},
|
||
rules: {
|
||
name: [{ required: true, message: '姓名不能为空', trigger: 'change' },
|
||
{ validator: validateUniquePatient, trigger: 'blur' }
|
||
],
|
||
postalCode: [
|
||
{ required: false, message: '邮政编码非必填', trigger: 'change' },
|
||
{ pattern: /^\d{6}$/, message: '邮政编码格式应为6位数字', trigger: 'blur' }
|
||
],
|
||
hukouAddressSelect: [{ required: false, message: '户籍地址选择非必填', trigger: 'change' }],
|
||
hukouAddress: [{ required: false, message: '户籍详细地址非必填', trigger: 'change' }],
|
||
companyAddress: [{ required: false, message: '单位地址非必填', trigger: 'change' }],
|
||
patientDerived: [{ required: false, message: '患者来源非必填', trigger: 'change' }],
|
||
genderEnum: [{ required: true, message: '请选择性别', trigger: 'change' }],
|
||
age: [{ required: true, message: '年龄不能为空', trigger: 'change' }],
|
||
phone: [{ required: true, message: '联系方式不能为空', trigger: 'change' }],
|
||
idCard: [{ required: true, message: '证件号不能为空', trigger: 'change' }],
|
||
},
|
||
});
|
||
|
||
|
||
|
||
|
||
|
||
|
||
const { queryParams, form, rules, isViewMode } = toRefs(data);
|
||
|
||
const props = defineProps({
|
||
item: {
|
||
type: Object,
|
||
required: false,
|
||
},
|
||
guardianAge: {
|
||
type: String,
|
||
default: '18'
|
||
}
|
||
});
|
||
|
||
// watch(
|
||
// () => form.value.idCard,
|
||
// (newIdCard) => {
|
||
// if (newIdCard && newIdCard.length === 18) {
|
||
// const birthYear = parseInt(newIdCard.substring(6, 10));
|
||
// const birthMonth = parseInt(newIdCard.substring(10, 12));
|
||
// const birthDay = parseInt(newIdCard.substring(12, 14));
|
||
|
||
// const today = new Date();
|
||
// const currentYear = today.getFullYear();
|
||
// const currentMonth = today.getMonth() + 1;
|
||
// const currentDay = today.getDate();
|
||
|
||
// let age = currentYear - birthYear;
|
||
|
||
// // 如果当前月份小于出生月份,或者月份相同但当前日期小于出生日期,则年龄减1
|
||
// if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
|
||
// age--;
|
||
// }
|
||
|
||
// form.value.age = age;
|
||
// }
|
||
// }
|
||
// );
|
||
/** 查询菜单列表 */
|
||
function getList() {
|
||
patientlLists().then((response) => {
|
||
console.log(response);
|
||
occupationtypeList.value = response.data.occupationType;
|
||
// 移除直接从patientlLists设置性别的代码
|
||
bloodtypeaboList.value = response.data.bloodTypeABO;
|
||
bloodtypearhList.value = response.data.bloodTypeRH;
|
||
familyrelationshiptypeList.value = response.data.familyRelationshipType;
|
||
maritalstatusList.value = response.data.maritalStatus;
|
||
console.log('administrativegenderList======>', JSON.stringify(administrativegenderList.value));
|
||
});
|
||
}
|
||
|
||
/** 打开用户信息弹窗 */
|
||
function getPatientInfo(idCard) {
|
||
const param = {
|
||
searchKey: idCard,
|
||
};
|
||
getOutpatientRegistrationList(param).then((res) => {
|
||
console.log(param, 'param');
|
||
if (res.data.records.length == 1) {
|
||
patientInfo.value = res.data.records[0];
|
||
console.log(patientInfo.value, 'patientInfo.value');
|
||
// 将表单数据发送给父组件
|
||
emits('submit', patientInfo.value);
|
||
}
|
||
});
|
||
}
|
||
//现住址选择
|
||
const handleChange = () => {
|
||
const checkedNodes = selectedOptions.value.map((code) => {
|
||
const node = findNodeByCode(options.value, code);
|
||
return node ? node.name : null;
|
||
});
|
||
form.value.addressProvince = checkedNodes[0] || '';
|
||
form.value.addressCity = checkedNodes[1] || '';
|
||
form.value.addressDistrict = checkedNodes[2] || '';
|
||
form.value.addressStreet = checkedNodes[3] || '';
|
||
form.value.address = '';
|
||
};
|
||
|
||
//户籍地址选择
|
||
const handleHukouChange = () => {
|
||
const checkedNodes = selectedHukouOptions.value.map((code) => {
|
||
const node = findNodeByCode(options.value, code);
|
||
return node ? node.name : null;
|
||
});
|
||
form.value.hukouAddressProvince = checkedNodes[0] || '';
|
||
form.value.hukouAddressCity = checkedNodes[1] || '';
|
||
form.value.hukouAddressDistrict = checkedNodes[2] || '';
|
||
form.value.hukouAddressStreet = checkedNodes[3] || '';
|
||
form.value.hukouAddress = '';
|
||
};
|
||
|
||
// 递归查找节点
|
||
const findNodeByCode = (data, code) => {
|
||
for (const item of data) {
|
||
if (item.code === code) return item;
|
||
if (item.children) {
|
||
const result = findNodeByCode(item.children, code);
|
||
if (result) return result;
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
// 从字典管理获取国家地区代码数据
|
||
const getCountryCodeOptions = async () => {
|
||
try {
|
||
console.log('开始获取国家地区代码数据...');
|
||
|
||
// 确保使用正确的字典名称获取完整数据
|
||
let countryDict = [];
|
||
|
||
// 定义多个可能的字典类型名称,优先使用nat_regn_code
|
||
const dictTypes = ['nat_regn_code', 'country_code', 'COUNTRY_CODE', '国家地区代码'];
|
||
let success = false;
|
||
|
||
// 尝试使用useDict方法获取数据,遍历不同的字典类型
|
||
if (proxy.useDict && typeof proxy.useDict === 'function') {
|
||
for (const dictType of dictTypes) {
|
||
try {
|
||
const dictResult = await proxy.useDict(dictType);
|
||
if (dictResult && dictResult[dictType] && Array.isArray(dictResult[dictType]) && dictResult[dictType].length > 0) {
|
||
countryDict = dictResult[dictType];
|
||
console.log(`通过useDict(${dictType})获取到的国家地区代码数据数量:`, countryDict.length);
|
||
success = true;
|
||
break;
|
||
}
|
||
} catch (err) {
|
||
console.warn(`useDict(${dictType})调用失败,尝试下一种方式:`, err.message);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果useDict失败,尝试直接调用API获取字典数据
|
||
if (!success && proxy.request && typeof proxy.request === 'function') {
|
||
try {
|
||
console.log('尝试直接调用API获取国家地区代码数据...');
|
||
// 直接调用字典数据API,优先使用nat_regn_code接口路径
|
||
const response = await proxy.request({
|
||
url: '/system/dict/data/type/nat_regn_code',
|
||
method: 'get'
|
||
});
|
||
|
||
if (response && response.code === 200 && Array.isArray(response.data)) {
|
||
countryDict = response.data;
|
||
console.log('通过API直接调用获取到的国家地区代码数据数量:', countryDict.length);
|
||
success = true;
|
||
} else {
|
||
// 如果nat_regn_code接口失败,尝试使用country_code
|
||
const fallbackResponse = await proxy.request({
|
||
url: '/system/dict/data/type/country_code',
|
||
method: 'get'
|
||
});
|
||
|
||
if (fallbackResponse && fallbackResponse.code === 200 && Array.isArray(fallbackResponse.data)) {
|
||
countryDict = fallbackResponse.data;
|
||
console.log('通过备用API获取到的国家地区代码数据数量:', countryDict.length);
|
||
success = true;
|
||
}
|
||
}
|
||
} catch (apiError) {
|
||
console.error('API直接调用失败:', apiError);
|
||
}
|
||
}
|
||
|
||
// 如果仍然未获取到数据,使用与nat_regn_code字典一致的模拟数据
|
||
if (!Array.isArray(countryDict) || countryDict.length === 0) {
|
||
console.warn('未获取到国家地区代码数据或数据格式错误,使用与nat_regn_code字典一致的模拟数据');
|
||
|
||
// 创建与nat_regn_code字典一致的模拟数据(基于数据库中的数据格式)
|
||
const mockCountries = [
|
||
{ dictValue: 'CHN', dictLabel: '中国' },
|
||
{ dictValue: 'HKG', dictLabel: '香港' },
|
||
{ dictValue: 'MAC', dictLabel: '澳门' },
|
||
{ dictValue: 'TWN', dictLabel: '台湾' },
|
||
{ dictValue: 'AFG', dictLabel: '阿富汗' },
|
||
{ dictValue: 'ALB', dictLabel: '阿尔巴尼亚' },
|
||
{ dictValue: 'DZA', dictLabel: '阿尔及利亚' },
|
||
{ dictValue: 'ASM', dictLabel: '美属萨摩亚' },
|
||
{ dictValue: 'AND', dictLabel: '安道尔' },
|
||
{ dictValue: 'AGO', dictLabel: '安哥拉' },
|
||
{ dictValue: 'AIA', dictLabel: '安圭拉' },
|
||
{ dictValue: 'ATA', dictLabel: '南极洲' },
|
||
{ dictValue: 'ATG', dictLabel: '安提瓜和巴布达' },
|
||
{ dictValue: 'ARG', dictLabel: '阿根廷' },
|
||
{ dictValue: 'ARM', dictLabel: '亚美尼亚' },
|
||
{ dictValue: 'ABW', dictLabel: '阿鲁巴' },
|
||
{ dictValue: 'AUS', dictLabel: '澳大利亚' },
|
||
{ dictValue: 'AUT', dictLabel: '奥地利' },
|
||
{ dictValue: 'AZE', dictLabel: '阿塞拜疆' },
|
||
{ dictValue: 'BHS', dictLabel: '巴哈马' },
|
||
{ dictValue: 'BHR', dictLabel: '巴林' },
|
||
{ dictValue: 'BGD', dictLabel: '孟加拉国' },
|
||
{ dictValue: 'BRB', dictLabel: '巴巴多斯' },
|
||
{ dictValue: 'BLR', dictLabel: '白俄罗斯' },
|
||
{ dictValue: 'BEL', dictLabel: '比利时' },
|
||
{ dictValue: 'BLZ', dictLabel: '伯利兹' },
|
||
{ dictValue: 'BEN', dictLabel: '贝宁' },
|
||
{ dictValue: 'BMU', dictLabel: '百慕大' },
|
||
{ dictValue: 'BTN', dictLabel: '不丹' },
|
||
{ dictValue: 'BOL', dictLabel: '玻利维亚' },
|
||
{ dictValue: 'BIH', dictLabel: '波黑' },
|
||
{ dictValue: 'BWA', dictLabel: '博茨瓦纳' },
|
||
{ dictValue: 'BVT', dictLabel: '布维岛' },
|
||
{ dictValue: 'BRA', dictLabel: '巴西' },
|
||
{ dictValue: 'IOT', dictLabel: '英属印度洋领土' },
|
||
{ dictValue: 'BRN', dictLabel: '文莱' },
|
||
{ dictValue: 'BGR', dictLabel: '保加利亚' },
|
||
{ dictValue: 'BFA', dictLabel: '布基纳法索' },
|
||
{ dictValue: 'BDI', dictLabel: '布隆迪' },
|
||
{ dictValue: 'KHM', dictLabel: '柬埔寨' },
|
||
{ dictValue: 'CMR', dictLabel: '喀麦隆' },
|
||
{ dictValue: 'CAN', dictLabel: '加拿大' },
|
||
{ dictValue: 'CPV', dictLabel: '佛得角' },
|
||
{ dictValue: 'CYM', dictLabel: '开曼群岛' },
|
||
{ dictValue: 'CAF', dictLabel: '中非' },
|
||
{ dictValue: 'TCD', dictLabel: '乍得' },
|
||
{ dictValue: 'CHL', dictLabel: '智利' },
|
||
{ dictValue: 'CXR', dictLabel: '圣诞岛' },
|
||
{ dictValue: 'CCK', dictLabel: '科科斯(基林)群岛' },
|
||
{ dictValue: 'COL', dictLabel: '哥伦比亚' },
|
||
{ dictValue: 'COM', dictLabel: '科摩罗' },
|
||
{ dictValue: 'COG', dictLabel: '刚果(布)' },
|
||
{ dictValue: 'COD', dictLabel: '刚果(金)' },
|
||
{ dictValue: 'COK', dictLabel: '库克群岛' },
|
||
{ dictValue: 'CRI', dictLabel: '哥斯达黎加' },
|
||
{ dictValue: 'CIV', dictLabel: '科特迪瓦' },
|
||
{ dictValue: 'HRV', dictLabel: '克罗地亚' },
|
||
{ dictValue: 'CUB', dictLabel: '古巴' },
|
||
{ dictValue: 'CYP', dictLabel: '塞浦路斯' },
|
||
{ dictValue: 'CZE', dictLabel: '捷克' },
|
||
{ dictValue: 'DNK', dictLabel: '丹麦' },
|
||
{ dictValue: 'DJI', dictLabel: '吉布提' },
|
||
{ dictValue: 'DMA', dictLabel: '多米尼克' },
|
||
{ dictValue: 'DOM', dictLabel: '多米尼加' },
|
||
{ dictValue: 'TLS', dictLabel: '东帝汶' },
|
||
{ dictValue: 'ECU', dictLabel: '厄瓜多尔' },
|
||
{ dictValue: 'EGY', dictLabel: '埃及' },
|
||
{ dictValue: 'SLV', dictLabel: '萨尔瓦多' },
|
||
{ dictValue: 'GNQ', dictLabel: '赤道几内亚' },
|
||
{ dictValue: 'ERI', dictLabel: '厄立特里亚' },
|
||
{ dictValue: 'EST', dictLabel: '爱沙尼亚' },
|
||
{ dictValue: 'ETH', dictLabel: '埃塞俄比亚' },
|
||
{ dictValue: 'FLK', dictLabel: '福克兰群岛' },
|
||
{ dictValue: 'FRO', dictLabel: '法罗群岛' },
|
||
{ dictValue: 'FJI', dictLabel: '斐济' },
|
||
{ dictValue: 'FIN', dictLabel: '芬兰' },
|
||
{ dictValue: 'FRA', dictLabel: '法国' },
|
||
{ dictValue: 'GUF', dictLabel: '法属圭亚那' },
|
||
{ dictValue: 'PYF', dictLabel: '法属波利尼西亚' },
|
||
{ dictValue: 'ATF', dictLabel: '法属南部领地' },
|
||
{ dictValue: 'GAB', dictLabel: '加蓬' },
|
||
{ dictValue: 'GMB', dictLabel: '冈比亚' },
|
||
{ dictValue: 'GEO', dictLabel: '格鲁吉亚' },
|
||
{ dictValue: 'DEU', dictLabel: '德国' },
|
||
{ dictValue: 'GHA', dictLabel: '加纳' },
|
||
{ dictValue: 'GIB', dictLabel: '直布罗陀' },
|
||
{ dictValue: 'GRC', dictLabel: '希腊' },
|
||
{ dictValue: 'GRL', dictLabel: '格陵兰' },
|
||
{ dictValue: 'GRD', dictLabel: '格林纳达' },
|
||
{ dictValue: 'GLP', dictLabel: '瓜德罗普' },
|
||
{ dictValue: 'GUM', dictLabel: '关岛' },
|
||
{ dictValue: 'GTM', dictLabel: '危地马拉' },
|
||
{ dictValue: 'GGY', dictLabel: '根西岛' },
|
||
{ dictValue: 'GIN', dictLabel: '几内亚' },
|
||
{ dictValue: 'GNB', dictLabel: '几内亚比绍' },
|
||
{ dictValue: 'GUY', dictLabel: '圭亚那' },
|
||
{ dictValue: 'HTI', dictLabel: '海地' },
|
||
{ dictValue: 'HMD', dictLabel: '赫德岛和麦克唐纳群岛' },
|
||
{ dictValue: 'VAT', dictLabel: '梵蒂冈' },
|
||
{ dictValue: 'HND', dictLabel: '洪都拉斯' },
|
||
{ dictValue: 'HUN', dictLabel: '匈牙利' },
|
||
{ dictValue: 'ISL', dictLabel: '冰岛' },
|
||
{ dictValue: 'IND', dictLabel: '印度' },
|
||
{ dictValue: 'IDN', dictLabel: '印度尼西亚' },
|
||
{ dictValue: 'IRN', dictLabel: '伊朗' },
|
||
{ dictValue: 'IRQ', dictLabel: '伊拉克' },
|
||
{ dictValue: 'IRL', dictLabel: '爱尔兰' },
|
||
{ dictValue: 'IMN', dictLabel: '马恩岛' },
|
||
{ dictValue: 'ISR', dictLabel: '以色列' },
|
||
{ dictValue: 'ITA', dictLabel: '意大利' },
|
||
{ dictValue: 'JAM', dictLabel: '牙买加' },
|
||
{ dictValue: 'JPN', dictLabel: '日本' },
|
||
{ dictValue: 'JEY', dictLabel: '泽西岛' },
|
||
{ dictValue: 'JOR', dictLabel: '约旦' },
|
||
{ dictValue: 'KAZ', dictLabel: '哈萨克斯坦' },
|
||
{ dictValue: 'KEN', dictLabel: '肯尼亚' },
|
||
{ dictValue: 'KIR', dictLabel: '基里巴斯' },
|
||
{ dictValue: 'PRK', dictLabel: '朝鲜' },
|
||
{ dictValue: 'KOR', dictLabel: '韩国' },
|
||
{ dictValue: 'KWT', dictLabel: '科威特' },
|
||
{ dictValue: 'KGZ', dictLabel: '吉尔吉斯斯坦' },
|
||
{ dictValue: 'LAO', dictLabel: '老挝' },
|
||
{ dictValue: 'LVA', dictLabel: '拉脱维亚' },
|
||
{ dictValue: 'LBN', dictLabel: '黎巴嫩' },
|
||
{ dictValue: 'LSO', dictLabel: '莱索托' },
|
||
{ dictValue: 'LBR', dictLabel: '利比里亚' },
|
||
{ dictValue: 'LBY', dictLabel: '利比亚' },
|
||
{ dictValue: 'LIE', dictLabel: '列支敦士登' },
|
||
{ dictValue: 'LTU', dictLabel: '立陶宛' },
|
||
{ dictValue: 'LUX', dictLabel: '卢森堡' },
|
||
{ dictValue: 'MKD', dictLabel: '前南马其顿' },
|
||
{ dictValue: 'MDG', dictLabel: '马达加斯加' },
|
||
{ dictValue: 'MWI', dictLabel: '马拉维' },
|
||
{ dictValue: 'MYS', dictLabel: '马来西亚' },
|
||
{ dictValue: 'MDV', dictLabel: '马尔代夫' },
|
||
{ dictValue: 'MLI', dictLabel: '马里' },
|
||
{ dictValue: 'MLT', dictLabel: '马耳他' },
|
||
{ dictValue: 'MHL', dictLabel: '马绍尔群岛' },
|
||
{ dictValue: 'MTQ', dictLabel: '马提尼克' },
|
||
{ dictValue: 'MRT', dictLabel: '毛里塔尼亚' },
|
||
{ dictValue: 'MUS', dictLabel: '毛里求斯' },
|
||
{ dictValue: 'MYT', dictLabel: '马约特' },
|
||
{ dictValue: 'MEX', dictLabel: '墨西哥' },
|
||
{ dictValue: 'FSM', dictLabel: '密克罗尼西亚联邦' },
|
||
{ dictValue: 'MDA', dictLabel: '摩尔多瓦' },
|
||
{ dictValue: 'MCO', dictLabel: '摩纳哥' },
|
||
{ dictValue: 'MNG', dictLabel: '蒙古' },
|
||
{ dictValue: 'MSR', dictLabel: '蒙特塞拉特' },
|
||
{ dictValue: 'MAR', dictLabel: '摩洛哥' },
|
||
{ dictValue: 'MOZ', dictLabel: '莫桑比克' },
|
||
{ dictValue: 'MMR', dictLabel: '缅甸' },
|
||
{ dictValue: 'NAM', dictLabel: '纳米比亚' },
|
||
{ dictValue: 'NRU', dictLabel: '瑙鲁' },
|
||
{ dictValue: 'NPL', dictLabel: '尼泊尔' },
|
||
{ dictValue: 'NLD', dictLabel: '荷兰' },
|
||
{ dictValue: 'ANT', dictLabel: '荷属安的列斯' },
|
||
{ dictValue: 'NCL', dictLabel: '新喀里多尼亚' },
|
||
{ dictValue: 'NZL', dictLabel: '新西兰' },
|
||
{ dictValue: 'NIC', dictLabel: '尼加拉瓜' },
|
||
{ dictValue: 'NER', dictLabel: '尼日尔' },
|
||
{ dictValue: 'NGA', dictLabel: '尼日利亚' },
|
||
{ dictValue: 'NIU', dictLabel: '纽埃' },
|
||
{ dictValue: 'NFK', dictLabel: '诺福克岛' },
|
||
{ dictValue: 'MNP', dictLabel: '北马里亚纳' },
|
||
{ dictValue: 'NOR', dictLabel: '挪威' },
|
||
{ dictValue: 'OMN', dictLabel: '阿曼' },
|
||
{ dictValue: 'PAK', dictLabel: '巴基斯坦' },
|
||
{ dictValue: 'PLW', dictLabel: '帕劳' },
|
||
{ dictValue: 'PSE', dictLabel: '巴勒斯坦' },
|
||
{ dictValue: 'PAN', dictLabel: '巴拿马' },
|
||
{ dictValue: 'PNG', dictLabel: '巴布亚新几内亚' },
|
||
{ dictValue: 'PRY', dictLabel: '巴拉圭' },
|
||
{ dictValue: 'PER', dictLabel: '秘鲁' },
|
||
{ dictValue: 'PHL', dictLabel: '菲律宾' },
|
||
{ dictValue: 'PCN', dictLabel: '皮特凯恩群岛' },
|
||
{ dictValue: 'POL', dictLabel: '波兰' },
|
||
{ dictValue: 'PRT', dictLabel: '葡萄牙' },
|
||
{ dictValue: 'PRI', dictLabel: '波多黎各' },
|
||
{ dictValue: 'QAT', dictLabel: '卡塔尔' },
|
||
{ dictValue: 'REU', dictLabel: '留尼汪' },
|
||
{ dictValue: 'ROM', dictLabel: '罗马尼亚' },
|
||
{ dictValue: 'RUS', dictLabel: '俄罗斯联邦' },
|
||
{ dictValue: 'RWA', dictLabel: '卢旺达' },
|
||
{ dictValue: 'SHN', dictLabel: '圣赫勒拿' },
|
||
{ dictValue: 'KNA', dictLabel: '圣基茨和尼维斯' },
|
||
{ dictValue: 'LCA', dictLabel: '圣卢西亚' },
|
||
{ dictValue: 'SPM', dictLabel: '圣皮埃尔和密克隆' },
|
||
{ dictValue: 'VCT', dictLabel: '圣文森特和格林纳丁斯' },
|
||
{ dictValue: 'WSM', dictLabel: '萨摩亚' },
|
||
{ dictValue: 'SMR', dictLabel: '圣马力诺' },
|
||
{ dictValue: 'STP', dictLabel: '圣多美和普林西比' },
|
||
{ dictValue: 'SAU', dictLabel: '沙特阿拉伯' },
|
||
{ dictValue: 'SEN', dictLabel: '塞内加尔' },
|
||
{ dictValue: 'SYC', dictLabel: '塞舌尔' },
|
||
{ dictValue: 'SLE', dictLabel: '塞拉利昂' },
|
||
{ dictValue: 'SGP', dictLabel: '新加坡' },
|
||
{ dictValue: 'SVK', dictLabel: '斯洛伐克' },
|
||
{ dictValue: 'SVN', dictLabel: '斯洛文尼亚' },
|
||
{ dictValue: 'SLB', dictLabel: '所罗门群岛' },
|
||
{ dictValue: 'SOM', dictLabel: '索马里' },
|
||
{ dictValue: 'ZAF', dictLabel: '南非' },
|
||
{ dictValue: 'SGS', dictLabel: '南乔治亚岛和南桑威奇群岛' },
|
||
{ dictValue: 'ESP', dictLabel: '西班牙' },
|
||
{ dictValue: 'LKA', dictLabel: '斯里兰卡' },
|
||
{ dictValue: 'SDN', dictLabel: '苏丹' },
|
||
{ dictValue: 'SUR', dictLabel: '苏里南' },
|
||
{ dictValue: 'SJM', dictLabel: '斯瓦尔巴群岛和扬马延岛' },
|
||
{ dictValue: 'SWZ', dictLabel: '斯威士兰' },
|
||
{ dictValue: 'SWE', dictLabel: '瑞典' },
|
||
{ dictValue: 'CHE', dictLabel: '瑞士' },
|
||
{ dictValue: 'SYR', dictLabel: '叙利亚' },
|
||
{ dictValue: 'TWN', dictLabel: '台湾' },
|
||
{ dictValue: 'TJK', dictLabel: '塔吉克斯坦' },
|
||
{ dictValue: 'TZA', dictLabel: '坦桑尼亚' },
|
||
{ dictValue: 'THA', dictLabel: '泰国' },
|
||
{ dictValue: 'TGO', dictLabel: '多哥' },
|
||
{ dictValue: 'TKL', dictLabel: '托克劳' },
|
||
{ dictValue: 'TON', dictLabel: '汤加' },
|
||
{ dictValue: 'TTO', dictLabel: '特立尼达和多巴哥' },
|
||
{ dictValue: 'TUN', dictLabel: '突尼斯' },
|
||
{ dictValue: 'TUR', dictLabel: '土耳其' },
|
||
{ dictValue: 'TKM', dictLabel: '土库曼斯坦' },
|
||
{ dictValue: 'TCA', dictLabel: '特克斯和凯科斯群岛' },
|
||
{ dictValue: 'TUV', dictLabel: '图瓦卢' },
|
||
{ dictValue: 'UGA', dictLabel: '乌干达' },
|
||
{ dictValue: 'UKR', dictLabel: '乌克兰' },
|
||
{ dictValue: 'ARE', dictLabel: '阿联酋' },
|
||
{ dictValue: 'GBR', dictLabel: '英国' },
|
||
{ dictValue: 'USA', dictLabel: '美国' },
|
||
{ dictValue: 'UMI', dictLabel: '美国本土外小岛屿' },
|
||
{ dictValue: 'URY', dictLabel: '乌拉圭' },
|
||
{ dictValue: 'UZB', dictLabel: '乌兹别克斯坦' },
|
||
{ dictValue: 'VUT', dictLabel: '瓦努阿图' },
|
||
{ dictValue: 'VEN', dictLabel: '委内瑞拉' },
|
||
{ dictValue: 'VNM', dictLabel: '越南' },
|
||
{ dictValue: 'VGB', dictLabel: '英属维尔京群岛' },
|
||
{ dictValue: 'VIR', dictLabel: '美属维尔京群岛' },
|
||
{ dictValue: 'WLF', dictLabel: '瓦利斯和富图纳' },
|
||
{ dictValue: 'ESH', dictLabel: '西撒哈拉' },
|
||
{ dictValue: 'YEM', dictLabel: '也门' },
|
||
{ dictValue: 'ZMB', dictLabel: '赞比亚' },
|
||
{ dictValue: 'ZWE', dictLabel: '津巴布韦' }
|
||
];
|
||
|
||
countryDict = mockCountries;
|
||
console.log('使用与nat_regn_code字典一致的模拟数据,共生成:', countryDict.length, '条国家地区代码数据');
|
||
|
||
// 提示管理员检查数据库中的国家地区代码数据
|
||
console.warn('提示: 请检查数据库中的sys_dict_type和sys_dict_data表,确保存在nat_regn_code类型的完整国家地区代码数据');
|
||
}
|
||
|
||
// 确保有足够的数据
|
||
console.log('最终获取到的国家地区代码数据数量:', countryDict.length);
|
||
|
||
// 转换为统一格式
|
||
const formattedCountries = countryDict.map(item => ({
|
||
value: item.value || item.dictValue || item.code || '', // 使用字典键值或编码
|
||
label: item.label || item.dictLabel || item.name || '' // 使用字典标签
|
||
}));
|
||
|
||
// 数据去重:根据value字段去重
|
||
const uniqueCountries = [];
|
||
const valueSet = new Set();
|
||
|
||
formattedCountries.forEach(item => {
|
||
if (item.value && !valueSet.has(item.value)) {
|
||
valueSet.add(item.value);
|
||
uniqueCountries.push(item);
|
||
}
|
||
});
|
||
|
||
console.log('去重后的数据数量:', uniqueCountries.length);
|
||
|
||
// 按字典编码升序排序
|
||
const sortedCountries = uniqueCountries.sort((a, b) => {
|
||
// 获取字典编码
|
||
const codeA = a.value || '';
|
||
const codeB = b.value || '';
|
||
|
||
// 按字典编码字符串升序排序
|
||
return codeA.localeCompare(codeB);
|
||
});
|
||
|
||
countryCodeList.value = sortedCountries;
|
||
|
||
// 确保中国是第一个选项(如果存在)
|
||
const chinaIndex = countryCodeList.value.findIndex(item => item.label === '中国');
|
||
if (chinaIndex > 0) {
|
||
// 将中国选项移到数组开头
|
||
const chinaOption = countryCodeList.value.splice(chinaIndex, 1)[0];
|
||
countryCodeList.value.unshift(chinaOption);
|
||
}
|
||
|
||
// 设置中国为默认值(查找标签为'中国'的选项)
|
||
const chinaOption = countryCodeList.value.find(item => item.label === '中国');
|
||
if (chinaOption && !form.value.countryCode) {
|
||
form.value.countryCode = chinaOption.value;
|
||
}
|
||
|
||
console.log('最终处理后的国家地区代码选项数量:', countryCodeList.value.length);
|
||
console.log('前5个国家地区代码选项:', countryCodeList.value.slice(0, 5));
|
||
} catch (error) {
|
||
console.error('获取国家地区代码字典数据失败:', error);
|
||
|
||
// 改进的降级方案:提供更完整的默认选项
|
||
countryCodeList.value = [
|
||
{ value: 'CHN', label: '中国' },
|
||
{ value: 'USA', label: '美国' },
|
||
{ value: 'JPN', label: '日本' },
|
||
{ value: 'KOR', label: '韩国' },
|
||
{ value: 'GBR', label: '英国' },
|
||
{ value: 'FRA', label: '法国' },
|
||
{ value: 'DEU', label: '德国' },
|
||
{ value: 'CAN', label: '加拿大' },
|
||
{ value: 'AUS', label: '澳大利亚' },
|
||
{ value: 'RUS', label: '俄罗斯' }
|
||
];
|
||
|
||
// 设置中国为默认值
|
||
if (!form.value.countryCode) {
|
||
form.value.countryCode = 'CHN';
|
||
}
|
||
|
||
// 显示错误提示,提醒用户检查系统配置
|
||
if (proxy && proxy.modal && proxy.modal.msgError) {
|
||
proxy.modal.msgError('获取国家地区代码数据失败,请联系系统管理员');
|
||
}
|
||
}
|
||
};
|
||
|
||
// 显示弹框
|
||
function show() {
|
||
// queryParams.roleId = props.roleId;
|
||
getList();
|
||
// 调用从字典管理获取性别数据的函数
|
||
getGenderOptions();
|
||
// 调用从字典管理获取文化程度数据的函数
|
||
getEducationLevelOptions();
|
||
// 调用从字典管理获取国家地区代码数据的函数
|
||
getCountryCodeOptions();
|
||
// 调用从字典管理获取患者来源数据的函数
|
||
getPatientDerivedOptions();
|
||
visible.value = true;
|
||
}
|
||
|
||
/** 表单重置 */
|
||
function reset() {
|
||
form.value = {
|
||
name: undefined,
|
||
nameJson: undefined,
|
||
menuName: undefined,
|
||
age: undefined,
|
||
genderEnum: undefined,
|
||
typeCode: '01',
|
||
idCard: undefined,
|
||
phone: undefined,
|
||
prfsEnum: undefined,
|
||
address: undefined,
|
||
tempFlag: undefined,
|
||
countryCode: undefined,
|
||
bloodRh: undefined,
|
||
bloodAbo: undefined,
|
||
nationalityCode: undefined,
|
||
deceasedDate: undefined,
|
||
linkName: undefined,
|
||
linkRelationCode: undefined,
|
||
linkTelcom: undefined,
|
||
workCompany: undefined,
|
||
addressCity: undefined,
|
||
addressDistrict: undefined,
|
||
addressStreet: undefined,
|
||
addressProvince: undefined,
|
||
maritalStatusEnum: undefined,
|
||
busNo: undefined,
|
||
organizationId: undefined,
|
||
birthDate: undefined,
|
||
};
|
||
proxy.resetForm('patientRef');
|
||
}
|
||
/** 提交按钮 */
|
||
function submitForm() {
|
||
if (!isValidCNPhoneNumber(form.value.phone)) {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '手机号有误,请重新输入',
|
||
});
|
||
return;
|
||
}
|
||
if (form.value.typeCode === '01') {
|
||
if (!isValidCNidCardNumber(form.value.idCard)) {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '身份证号有误,请重新输入',
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
// 活动标识 2 启用 3 停用
|
||
if (form.value.tempFlag == '1') {
|
||
form.value.activeFlag = 2;
|
||
} else {
|
||
form.value.activeFlag = 3;
|
||
}
|
||
form.value.patientIdInfoList = [
|
||
{
|
||
typeCode: form.value.typeCode,
|
||
},
|
||
];
|
||
if (form.value.idCard) {
|
||
if (form.value.typeCode === '01') {
|
||
form.value.birthDate =
|
||
form.value.idCard.toString().substring(6, 10) +
|
||
'-' +
|
||
form.value.idCard.toString().substring(10, 12) +
|
||
'-' +
|
||
form.value.idCard.toString().substring(12, 14);
|
||
console.log(form.value.birthDate, 123);
|
||
} else {
|
||
form.value.birthDate = undefined;
|
||
}
|
||
}
|
||
// 进行表单验证
|
||
proxy.$refs['patientRef'].validate((valid) => {
|
||
if (valid) {
|
||
// 提交表单前的处理
|
||
if (!form.value.identifierNo) {
|
||
form.value.typeCode = undefined;
|
||
}
|
||
form.value.address = getAddress(form);
|
||
|
||
// 提交新增患者请求
|
||
addPatient(form.value).then((response) => {
|
||
proxy.$modal.msgSuccess('新增成功');
|
||
getPatientInfo(response.data.idCard);
|
||
visible.value = false;
|
||
reset();
|
||
});
|
||
}
|
||
});
|
||
}
|
||
// 获取完整地址字符串
|
||
function getAddress(form) {
|
||
const addressParts = [
|
||
form.value.addressProvince,
|
||
form.value.addressCity,
|
||
form.value.addressDistrict,
|
||
form.value.addressStreet,
|
||
form.value.address,
|
||
];
|
||
|
||
// 使用 reduce 方法拼接地址
|
||
return addressParts.reduce((acc, part) => {
|
||
return part ? acc + part : acc;
|
||
}, '');
|
||
}
|
||
/** 取消按钮 */
|
||
function cancel() {
|
||
visible.value = false;
|
||
reset();
|
||
}
|
||
// 身份证号失去焦点获取年龄和性别
|
||
const onBlur = () => {
|
||
if (form.value.typeCode === '01') {
|
||
const info = getGenderAndAge(form.value.idCard || '');
|
||
form.value.age = info.age;
|
||
form.value.genderEnum = info.gender;
|
||
}
|
||
};
|
||
//切换证件类型
|
||
const typeChange = () => {
|
||
if (form.value.typeCode === '01') {
|
||
const info = getGenderAndAge(form.value.idCard || '');
|
||
form.value.age = info.age;
|
||
form.value.genderEnum = info.gender;
|
||
}
|
||
};
|
||
defineExpose({
|
||
show,
|
||
});
|
||
</script>
|
||
<style scoped>
|
||
.el-form--inline .el-form-item {
|
||
display: inline-flex;
|
||
vertical-align: middle;
|
||
margin-right: 10px !important;
|
||
}
|
||
|
||
/* 使用深度选择器 */
|
||
.custom-label-spacing :deep(.el-form-item__label) {
|
||
line-height: 1.2; /* 调整行间距 */
|
||
margin-bottom: 4px; /* 调整 label 和输入框之间的间距 */
|
||
}
|
||
|
||
/* 防止表单标签换行 */
|
||
:deep(.el-form-item__label) {
|
||
white-space: nowrap;
|
||
overflow: visible;
|
||
text-overflow: clip;
|
||
width: 120px;
|
||
}
|
||
</style>
|