去除变片编号生成器,修改地区选择器,修改报告卡的样式。

This commit is contained in:
wangjian963
2026-03-16 14:40:35 +08:00
parent 449209a79b
commit 0bf29a53a4
5 changed files with 403 additions and 182 deletions

View File

@@ -1089,17 +1089,6 @@ export function checkInfectiousDisease(params) {
});
}
/**
* 获取下一个传染病报告卡编号
*/
export function getNextCardNo(orgCode) {
return request({
url: '/doctor-station/diagnosis/next-card-no',
method: 'get',
params: { orgCode },
});
}
/**
* 保存传染病报告卡
*/

View File

@@ -15,8 +15,8 @@
<el-input
v-model="form.cardNo"
class="card-number-input"
placeholder="系统自动生成"
disabled
placeholder="单位自编,与网络直报一致"
maxlength="12"
/>
</el-space>
</el-card>
@@ -32,7 +32,7 @@
</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="isChildPatient ? '14岁以下必填' : ''" />
<el-input v-model="form.parentName" class="underline-input" :placeholder="isChildPatient ? '14岁必填' : ''" />
</el-col>
<el-col :span="8" class="form-item">
<span class="form-label required">身份证号</span>
@@ -98,23 +98,29 @@
<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-inputs region-selects-wrapper">
<el-cascader
v-model="addressCodes"
:options="addressOptions"
:props="addressCascaderProps"
placeholder="请选择省/市/区县/街道"
clearable
@change="handleAddressChange"
/>
<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="12" class="form-item">
<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="12" class="form-item">
<el-col :span="8" class="form-item">
<el-input v-model="form.addressHouse" class="underline-input" placeholder="门牌号" />
</el-col>
</el-row>
@@ -135,26 +141,27 @@
</el-row>
<!-- 职业 -->
<!-- 职业病例分类 -->
<el-row :gutter="16" class="form-row">
<el-col :span="24" class="form-item">
<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-row>
<!-- 病例分类 -->
<el-row :gutter="16" class="form-row">
<el-col :span="24" class="form-item full-width">
<el-col :span="16" class="form-item">
<span class="form-label required">病例分类</span>
<el-radio-group v-model="form.caseClass">
<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-group>
<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>
@@ -327,7 +334,7 @@
:model-value="form.selectedClassB === '0221'"
@update:model-value="(checked) => handleClassBCheckbox('0221', checked)"
label="0221"
><EFBFBD><EFBFBD><EFBFBD><EFBFBD>病</el-checkbox>
>病</el-checkbox>
<el-checkbox
:model-value="form.selectedClassB === '0222'"
@update:model-value="(checked) => handleClassBCheckbox('0222', checked)"
@@ -348,6 +355,21 @@
@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>
@@ -400,11 +422,12 @@
@update:model-value="(checked) => handleClassCCheckbox('0309', checked)"
label="0309"
>丝虫病</el-checkbox>
<el-checkbox
:model-value="form.selectedClassC === '0310'"
<el-checkbox
:model-value="form.selectedClassC === '0310'"
@update:model-value="(checked) => handleClassCCheckbox('0310', checked)"
label="0310"
>其它感染性腹泻病</el-checkbox>
class="wide-checkbox"
>除霍乱/菌痢/伤寒副伤寒以外的感染性腹泻病</el-checkbox>
<el-checkbox
:model-value="form.selectedClassC === '0311'"
@update:model-value="(checked) => handleClassCCheckbox('0311', checked)"
@@ -495,7 +518,7 @@
<script setup>
import { ref, computed, getCurrentInstance, watch } from 'vue';
import pcas from 'china-division/dist/pcas-code.json';
import { saveInfectiousDiseaseReport, getNextCardNo } from '../api';
import { saveInfectiousDiseaseReport } from '../api';
import useUserStore from '@/store/modules/user';
import { useDict } from '@/utils/dict';
@@ -543,17 +566,151 @@ const props = defineProps({
const emit = defineEmits(['close', 'success']);
// 地址级联选择器配置
const addressOptions = ref(pcas);
const addressCodes = ref([]);
// 地址选择器数据
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 = ['北京市', '天津市', '上海市', '重庆市'];
const addressCascaderProps = {
checkStrictly: true,
value: 'code',
label: 'name',
children: 'children'
};
// 初始化省级选项
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: '',
@@ -601,65 +758,104 @@ const form = ref({
diagnosisId: '',
});
// 根据地址名称数组查找对应的代码数组(用于初始化地址选择器回显)
function findCodesByNames(names) {
const codes = [];
let currentNodes = addressOptions.value;
// 根据地址名称初始化下拉选择器(用于回显)
function initAddressByName(provName, cityName, countyName, townName) {
if (!provName) return;
for (const name of names) {
if (!name) break;
const node = currentNodes?.find(n => n.name === name);
if (node) {
codes.push(node.code);
currentNodes = node.children;
} else {
break;
}
}
return codes;
}
// 初始化省级选项
initProvinceOptions();
// 地址级联选择器变化处理
function handleAddressChange(values) {
if (!values || values.length === 0) {
form.value.addressProv = '';
form.value.addressCity = '';
form.value.addressCounty = '';
form.value.addressTown = '';
return;
}
// 查找省份
const province = addressData.value.find(item => item.name === provName);
if (!province) return;
// 根据选中的代码获取对应的名称
const names = [];
let currentNodes = addressOptions.value;
provinceCode.value = province.code;
form.value.addressProv = province.name;
for (const code of values) {
const node = currentNodes?.find(n => n.code === code);
if (node) {
names.push(node.name);
currentNodes = node.children;
}
}
// 处理直辖市情况:如果是直辖市,市级和省级相同
const provName = names[0] || '';
let cityName = names[1] || '';
const countyName = names[2] || '';
const townName = names[3] || '';
// 如果是直辖市,市级应该与省级相同
// 直辖市处理
if (municipalities.includes(provName)) {
// 直辖市:省级=市级
form.value.addressProv = provName;
form.value.addressCity = provName; // 直辖市的市级与省级相同
form.value.addressCounty = cityName; // 原来的市级变成区县
form.value.addressTown = countyName; // 原来的区县变成街道
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 {
// 非直辖市:正常处理
form.value.addressProv = provName;
form.value.addressCity = cityName;
form.value.addressCounty = countyName;
form.value.addressTown = townName;
// 非直辖市处理
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;
}
}
}
}
}
}
}
}
}
}
@@ -920,6 +1116,19 @@ function calculateAge() {
*/
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);
@@ -1019,37 +1228,16 @@ function show(diagnosisData) {
updateSelectedDiseases();
// 设置地址选择组件初始值
// 根据地址名称查找对应的代码数组
const provName = diagnosisData?.addressProv || '';
let cityName = diagnosisData?.addressCity || '';
const cityName = diagnosisData?.addressCity || '';
const countyName = diagnosisData?.addressCounty || '';
const townName = diagnosisData?.addressTown || '';
// 处理直辖市情况:如果是直辖市,需要调整地址层级
let names = [];
if (municipalities.includes(provName)) {
// 直辖市:省级=市级,所以传给级联选择器的应该是 [省, 区县, 街道]
names = [provName, countyName, townName].filter(n => n);
} else {
// 非直辖市:正常处理 [省, 市, 区县, 街道]
names = [provName, cityName, countyName, townName].filter(n => n);
}
addressCodes.value = findCodesByNames(names);
initAddressByName(provName, cityName, countyName, townName);
if (birthInfo.year) {
calculateAge();
}
// 从后端获取下一个卡片编号(含流水号)
getNextCardNo(orgCode).then(res => {
if (res.code === 200 && res.data) {
form.value.cardNo = res.data;
}
}).catch(err => {
// 后端不可用时提示用户,不生成可能重复的编号
proxy.$modal.msgError('获取卡片编号失败,请稍后重试');
console.error('获取卡片编号失败:', err);
});
}
/**
@@ -1141,6 +1329,11 @@ async function buildSubmitData() {
function validateFormManually() {
const errors = [];
// 卡片编号验证可选但如果填写了必须是12位
if (form.value.cardNo && form.value.cardNo.length !== 12) {
errors.push('卡片编号必须为12位');
}
// 身份证号验证
if (!form.value.idNo) {
errors.push('请输入身份证号');
@@ -1356,6 +1549,26 @@ defineExpose({ show });
.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;
}
}
/* 表单区域样式 */
@@ -1414,36 +1627,90 @@ defineExpose({ show });
gap: 4px;
}
/* 地址选择样式 */
.address-inputs {
/* 地址选择样式 - 四个下拉框并排 */
.address-selects {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
/* 地址级联选择器样式 */
.region-selects-wrapper {
flex: 1;
}
.region-selects-wrapper :deep(.el-cascader) {
width: 100%;
.address-selects .el-select {
flex: 1;
min-width: 0;
}
.region-selects-wrapper :deep(.el-cascader .el-input__wrapper) {
.address-selects :deep(.el-input__wrapper) {
border: none;
border-bottom: 1px solid #dcdfe6;
border-radius: 0;
box-shadow: none;
background: transparent;
}
.region-selects-wrapper :deep(.el-cascader .el-input__wrapper:hover) {
.address-selects :deep(.el-input__wrapper:hover) {
border-bottom-color: #c0c4cc;
}
.region-selects-wrapper :deep(.el-cascader .el-input__wrapper.is-focus) {
.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%;
@@ -1502,6 +1769,10 @@ defineExpose({ show });
width: calc(25% - 8px);
}
.disease-list.four-columns .el-checkbox.wide-checkbox {
width: calc(50% - 8px);
}
.disease-with-subtype {
display: flex;
align-items: center;
@@ -1533,6 +1804,9 @@ defineExpose({ show });
.disease-with-subtype {
width: calc(50% - 8px);
}
.disease-list.four-columns .el-checkbox.wide-checkbox {
width: 100%;
}
}
@media (max-width: 600px) {