202 检验项目设置-》检验项目:点击【编辑】按钮检验类型字段的内容显示数字
This commit is contained in:
@@ -268,14 +268,14 @@
|
||||
<template #default="{ row }">
|
||||
<template v-if="editingRowId === row.id">
|
||||
<el-select v-model="row.feePackageId" placeholder="选择费用套餐" size="small" style="width: 100%;" filterable clearable
|
||||
@change="(val) => { const pkg = feePackages.find(p => p.id === val); row.package = pkg ? pkg.packageName : ''; updateAmountFromPackage(row); }"
|
||||
@change="(val) => { const pkg = feePackages.find(p => String(p.id) === String(val)); row.package = pkg ? pkg.packageName : ''; updateAmountFromPackage(row); }"
|
||||
@visible-change="(visible) => { if (visible && feePackages.length === 0) getFeePackages() }">
|
||||
<el-option label="选择费用套餐" value="" />
|
||||
<el-option
|
||||
v-for="pkg in feePackages"
|
||||
:key="pkg.id"
|
||||
:label="pkg.packageName"
|
||||
:value="pkg.id"
|
||||
:value="String(pkg.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
@@ -353,7 +353,7 @@
|
||||
v-for="item in (row.subItemOptions || [])"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
:value="Number(item.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
@@ -1160,18 +1160,33 @@ const handleEditRow = (row) => {
|
||||
|
||||
// 初始化行内属性
|
||||
if (!row.subItemOptions) row.subItemOptions = [];
|
||||
row.loadingSubItems = false;
|
||||
|
||||
// 回显名称
|
||||
// 预加载费用套餐列表(确保下拉框能显示名称而不是ID)
|
||||
if (feePackages.value.length === 0) {
|
||||
getFeePackages();
|
||||
}
|
||||
|
||||
// 如果已有子项ID但选项列表为空,且有大类ID,则主动加载子类列表
|
||||
if (row.inspectionTypeId && row.subItemOptions.length === 0) {
|
||||
row.loadingSubItems = true;
|
||||
fetchInspectionTypesRequest({ parentId: row.inspectionTypeId }).then(res => {
|
||||
let subData = [];
|
||||
if (res.code === 200) {
|
||||
if (res.data && Array.isArray(res.data)) subData = res.data;
|
||||
else if (res.data && res.data.rows) subData = res.data.rows;
|
||||
else if (res.data && res.data.data && Array.isArray(res.data.data)) subData = res.data.data;
|
||||
}
|
||||
row.subItemOptions = subData;
|
||||
}).finally(() => {
|
||||
row.loadingSubItems = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 回显检验大类名称
|
||||
if (row.inspectionTypeId && !row.inspectionTypeName) {
|
||||
const p = parentTypeOptions.value.find(i => i.id === row.inspectionTypeId);
|
||||
if (p) row.inspectionTypeName = p.name;
|
||||
}
|
||||
|
||||
if (row.subItemId && row.subItemOptions.length > 0) {
|
||||
const s = row.subItemOptions.find(i => i.id === row.subItemId);
|
||||
if (s) row.subItemName = s.name;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
@@ -1292,15 +1307,15 @@ const loadObservationItems = async (resetPage = false) => {
|
||||
code: item.busNo || '',
|
||||
name: item.name || '',
|
||||
testType: item.inspectionTypeId_dictText || item.testType || '',
|
||||
inspectionTypeId: item.inspectionTypeId || null,
|
||||
inspectionTypeId: item.inspectionTypeId ? Number(item.inspectionTypeId) : null,
|
||||
package: item.packageName || '',
|
||||
feePackageId: item.feePackageId || null,
|
||||
feePackageId: item.feePackageId ? String(item.feePackageId) : null,
|
||||
sampleType: item.specimenCode || '',
|
||||
amount: parseFloat(item.retailPrice || 0),
|
||||
sortOrder: item.sortOrder || null,
|
||||
serviceRange: item.serviceRange || '全部',
|
||||
subItemName: item.subItemName || '',
|
||||
subItemId: item.subItemId || null,
|
||||
subItemId: item.subItemId ? Number(item.subItemId) : null,
|
||||
remark: item.descriptionText || '',
|
||||
status: true
|
||||
}));
|
||||
@@ -1466,7 +1481,7 @@ let addingItem = false;
|
||||
const addPackageItem = () => {
|
||||
if (addingItem) return; // 防止重复调用
|
||||
addingItem = true;
|
||||
|
||||
|
||||
const newItem = {
|
||||
name: '',
|
||||
dosage: '',
|
||||
@@ -1482,7 +1497,7 @@ const addPackageItem = () => {
|
||||
origin: ''
|
||||
};
|
||||
packageItems.value.push(newItem);
|
||||
|
||||
|
||||
// 延迟重置标志位,确保不会影响其他操作
|
||||
setTimeout(() => {
|
||||
addingItem = false;
|
||||
@@ -1509,23 +1524,23 @@ const deletePackageItem = (index) => {
|
||||
const updateItemAmount = (item) => {
|
||||
// 计算项目原价金额
|
||||
const originalAmount = (item.quantity || 1) * (item.unitPrice || 0.00);
|
||||
|
||||
|
||||
// 应用折扣到项目金额
|
||||
let discountedAmount = originalAmount;
|
||||
if (discount.value && !isNaN(parseFloat(discount.value))) {
|
||||
const discountRate = parseFloat(discount.value) / 100;
|
||||
discountedAmount = originalAmount * (1 - discountRate);
|
||||
}
|
||||
|
||||
|
||||
// 更新项目金额
|
||||
item.amount = parseFloat(discountedAmount.toFixed(2));
|
||||
|
||||
|
||||
// 基于折扣后的金额计算服务费
|
||||
item.serviceFee = calculateItemServiceFee(item);
|
||||
|
||||
|
||||
// 更新项目总金额
|
||||
updateItemTotalAmount(item);
|
||||
|
||||
|
||||
// 重新计算套餐金额和服务费
|
||||
calculateAmounts();
|
||||
};
|
||||
@@ -1581,7 +1596,7 @@ const cancelEditItem = (index) => {
|
||||
// 计算单个项目的服务费(基于折扣后的金额)
|
||||
const calculateItemServiceFee = (item) => {
|
||||
if (!generateServiceFee.value) return 0;
|
||||
|
||||
|
||||
// 服务费是项目折扣后金额的10%
|
||||
return parseFloat((item.amount * 0.1).toFixed(2));
|
||||
};
|
||||
@@ -1596,7 +1611,7 @@ const redistributeServiceFee = () => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 重新计算每个项目的服务费
|
||||
packageItems.value.forEach(item => {
|
||||
item.serviceFee = calculateItemServiceFee(item);
|
||||
@@ -1610,27 +1625,27 @@ const calculateAmounts = () => {
|
||||
packageItems.value.forEach(item => {
|
||||
// 计算项目原价金额
|
||||
const originalAmount = (item.quantity || 1) * (item.unitPrice || 0.00);
|
||||
|
||||
|
||||
// 应用折扣到项目金额
|
||||
let discountedAmount = originalAmount;
|
||||
if (discount.value && !isNaN(parseFloat(discount.value))) {
|
||||
const discountRate = parseFloat(discount.value) / 100;
|
||||
discountedAmount = originalAmount * (1 - discountRate);
|
||||
}
|
||||
|
||||
|
||||
// 更新项目金额
|
||||
item.amount = parseFloat(discountedAmount.toFixed(2));
|
||||
});
|
||||
|
||||
|
||||
// 重新分配所有项目的服务费
|
||||
redistributeServiceFee();
|
||||
|
||||
|
||||
// 计算套餐总金额(基于项目的折扣后金额)
|
||||
const totalAmount = packageItems.value.reduce((sum, item) => sum + (item.amount || 0), 0);
|
||||
|
||||
|
||||
// 更新套餐金额
|
||||
packageAmount.value = parseFloat(totalAmount.toFixed(2));
|
||||
|
||||
|
||||
// 计算套餐总服务费
|
||||
if (generateServiceFee.value) {
|
||||
serviceFee.value = parseFloat(packageItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0).toFixed(2));
|
||||
@@ -1724,12 +1739,12 @@ const handleConfirm = (row) => {
|
||||
ElMessage.warning('请选择执行科室');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 注意:编码唯一性由后端统一校验;这里不做硬编码拦截(避免误判)
|
||||
|
||||
|
||||
// 去除code字段的前后空格,确保唯一性验证准确
|
||||
submitData.code = submitData.code.trim();
|
||||
|
||||
|
||||
// 区分新增和更新操作:使用 temp_ 前缀的临时ID判断,避免时间戳阈值在不同年份失效
|
||||
if (isTempId(row.id)) { // 新增的临时ID
|
||||
// 处理 parentId:如果是子类且 parentId 是临时ID,需要先找到父类的真实 id
|
||||
@@ -1740,7 +1755,7 @@ const handleConfirm = (row) => {
|
||||
const parts = parseCodeParts(submitData.code);
|
||||
if (parts.subRaw) {
|
||||
const parentCode = parts.mainRaw;
|
||||
const parent = tableData.value.find(r =>
|
||||
const parent = tableData.value.find(r =>
|
||||
!isTempId(r.id) && (r?.code ?? '').toString().trim() === parentCode
|
||||
);
|
||||
if (parent) {
|
||||
@@ -1751,11 +1766,11 @@ const handleConfirm = (row) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 新增数据时移除临时ID,让后端自动生成主键
|
||||
const { id, ...newData } = submitData;
|
||||
newData.parentId = finalParentId || null; // 确保 parentId 正确设置(大类为 null,子类为父类 id)
|
||||
|
||||
|
||||
addInspectionType(newData).then(response => {
|
||||
ElMessage.success('新增成功');
|
||||
getInspectionTypeList();
|
||||
@@ -1778,7 +1793,7 @@ const handleConfirm = (row) => {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
editingRowId.value = null;
|
||||
};
|
||||
|
||||
@@ -1826,7 +1841,7 @@ const handleAdd = (row, index) => {
|
||||
tableData.value.splice(index + 1, 0, newRow);
|
||||
editingRowId.value = newRow.id;
|
||||
};
|
||||
|
||||
|
||||
const handleDelete = (id) => {
|
||||
ElMessageBox.confirm('确定要删除该检验类型吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -1881,19 +1896,47 @@ const addNewItem = () => {
|
||||
editingRowId.value = newItem.id;
|
||||
};
|
||||
|
||||
const editItem = (item) => {
|
||||
const editItem = async (item) => {
|
||||
if (editingRowId.value === item.id) {
|
||||
// 如果当前行已经在编辑模式,点击编辑按钮则保存
|
||||
saveItem(item);
|
||||
} else {
|
||||
// 否则进入编辑模式
|
||||
editingRowId.value = item.id;
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化行内属性
|
||||
if (!item.subItemOptions) item.subItemOptions = [];
|
||||
|
||||
// 并行预加载:费用套餐列表 + 当前行的子类列表
|
||||
const tasks = [];
|
||||
|
||||
if (feePackages.value.length === 0) {
|
||||
tasks.push(getFeePackages());
|
||||
}
|
||||
|
||||
if (item.inspectionTypeId && item.subItemOptions.length === 0) {
|
||||
item.loadingSubItems = true;
|
||||
tasks.push(
|
||||
fetchInspectionTypesRequest({ parentId: item.inspectionTypeId }).then(res => {
|
||||
let subData = [];
|
||||
if (res.code === 200) {
|
||||
if (res.data && Array.isArray(res.data)) subData = res.data;
|
||||
else if (res.data && res.data.rows) subData = res.data.rows;
|
||||
else if (res.data && res.data.data && Array.isArray(res.data.data)) subData = res.data.data;
|
||||
}
|
||||
item.subItemOptions = subData;
|
||||
}).finally(() => {
|
||||
item.loadingSubItems = false;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// 等所有数据加载完再切换编辑态,确保 el-select 能回显正确文字
|
||||
await Promise.all(tasks);
|
||||
editingRowId.value = item.id;
|
||||
};
|
||||
|
||||
const updateAmountFromPackage = (item) => {
|
||||
if (item.feePackageId) {
|
||||
const selectedPackage = feePackages.value.find(pkg => pkg.id === item.feePackageId);
|
||||
const selectedPackage = feePackages.value.find(pkg => String(pkg.id) === String(item.feePackageId));
|
||||
if (selectedPackage) {
|
||||
// 套餐总金额 = 套餐金额 + 服务费
|
||||
const packageAmount = parseFloat(selectedPackage.packageAmount || 0);
|
||||
@@ -1911,42 +1954,42 @@ const saveItem = async (item) => {
|
||||
ElMessage.error('小类编码不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 验证小类编码格式:4位数字
|
||||
const codeRegex = /^\d{4}$/;
|
||||
if (!codeRegex.test(item.code.trim())) {
|
||||
ElMessage.error('小类编码必须为4位数字');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!item.name || item.name.trim() === '') {
|
||||
ElMessage.error('小类项目名称不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!item.inspectionTypeId) {
|
||||
ElMessage.error('检验类型不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!item.sampleType) {
|
||||
ElMessage.error('样本类型不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 验证小类编码唯一性
|
||||
const isDuplicate = inspectionItems.value.some(i =>
|
||||
const isDuplicate = inspectionItems.value.some(i =>
|
||||
i.id !== item.id && i.code.trim() === item.code.trim()
|
||||
);
|
||||
|
||||
|
||||
if (isDuplicate) {
|
||||
ElMessage.error('小类编码已存在');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 从费用套餐获取金额
|
||||
updateAmountFromPackage(item);
|
||||
|
||||
|
||||
try {
|
||||
// 准备提交给后端的数据
|
||||
const submitData = {
|
||||
@@ -1964,7 +2007,7 @@ const saveItem = async (item) => {
|
||||
sortOrder: item.sortOrder ? parseInt(item.sortOrder) : null,
|
||||
serviceRange: item.serviceRange || '全部'
|
||||
};
|
||||
|
||||
|
||||
// 判断是新增还是更新
|
||||
if (typeof item.id === 'number') { // 临时ID(数字类型),新增
|
||||
const response = await addDiagnosisTreatment(submitData);
|
||||
@@ -1984,7 +2027,7 @@ const saveItem = async (item) => {
|
||||
ElMessage.error(response.msg || '更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
editingRowId.value = null;
|
||||
} catch (error) {
|
||||
console.error('保存检验项目失败:', error);
|
||||
@@ -2048,19 +2091,19 @@ const exportTable = () => {
|
||||
|
||||
// 创建Blob对象
|
||||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
||||
|
||||
|
||||
// 创建下载链接
|
||||
const link = document.createElement('a');
|
||||
const url = URL.createObjectURL(blob);
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', `检验项目导出_${new Date().toISOString().split('T')[0]}.csv`);
|
||||
link.style.visibility = 'hidden';
|
||||
|
||||
|
||||
// 添加到DOM并触发下载
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
|
||||
ElMessage.success('导出成功');
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user