211
检验项目设置-》套餐管理:点击【新增】跳转至套餐设置界面系统未进行初始化新增模式界面数据 212 检验项目设置-》套餐管理:点击行【编辑】跳转至套餐设置编辑模式该行的套餐数据未正确引入 213 检验项目设置-》套餐管理:点击行【查看】跳转至套餐设置界面套餐内容显示错误并且未进入只读模式
This commit is contained in:
@@ -813,7 +813,8 @@ import {
|
||||
updateInspectionPackage,
|
||||
getInspectionPackage,
|
||||
listInspectionPackageDetails,
|
||||
saveInspectionPackageDetails
|
||||
saveInspectionPackageDetails,
|
||||
batchSaveInspectionPackageDetails
|
||||
} from '@/api/system/inspectionPackage';
|
||||
import { getTenantPage } from '@/api/system/tenant';
|
||||
import {deptTreeSelect} from '@/api/system/user';
|
||||
@@ -1470,6 +1471,8 @@ const packageItems = ref([]);
|
||||
const packageMode = ref('add');
|
||||
// 当前编辑的套餐ID(用于编辑和查看模式)
|
||||
const currentPackageId = ref(null);
|
||||
// 正在从后端加载套餐数据的标志,加载期间跳过 calculateAmounts 防止覆盖后端金额
|
||||
const isLoadingPackage = ref(false);
|
||||
// 是否为查看模式(只读)
|
||||
const isViewMode = computed(() => packageMode.value === 'view');
|
||||
|
||||
@@ -2364,6 +2367,10 @@ const savePackageData = async (basicInfo, detailData) => {
|
||||
if (isEditMode) {
|
||||
// 编辑模式:调用更新API
|
||||
basicResponse = await updateInspectionPackage(basicInfo);
|
||||
if (basicResponse.code !== 200) {
|
||||
loading.close();
|
||||
throw new Error(basicResponse.msg || '更新基本信息失败');
|
||||
}
|
||||
packageId = currentPackageId.value;
|
||||
} else {
|
||||
// 新增模式:调用新增API
|
||||
@@ -2390,29 +2397,41 @@ const savePackageData = async (basicInfo, detailData) => {
|
||||
// 验证套餐ID是否存在
|
||||
if (!packageId) {
|
||||
loading.close();
|
||||
console.error('无法从响应中获取套餐ID,完整响应:', basicResponse);
|
||||
throw new Error('保存成功但未返回套餐ID。请检查后端接口是否正确返回了packageId或id字段');
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 分别保存每个明细数据到明细表,并将后端返回的 id 回填到 packageItems
|
||||
for (let i = 0; i < detailData.length; i++) {
|
||||
const detailItem = {
|
||||
...detailData[i],
|
||||
packageId: packageId
|
||||
// 2. 保存明细数据:编辑模式用批量接口(先删旧后插新),新增模式逐条新增
|
||||
if (isEditMode) {
|
||||
// 编辑模式:调用批量保存接口,后端会先删除旧明细再插入新明细
|
||||
const batchPayload = {
|
||||
basicInformationId: packageId,
|
||||
details: detailData.map(item => ({ ...item, packageId: packageId }))
|
||||
};
|
||||
|
||||
const detailResponse = await saveInspectionPackageDetails(detailItem);
|
||||
|
||||
if (detailResponse.code !== 200) {
|
||||
const batchResponse = await batchSaveInspectionPackageDetails(batchPayload);
|
||||
if (batchResponse.code !== 200) {
|
||||
loading.close();
|
||||
throw new Error(`保存第 ${i + 1} 个明细项失败: ${detailResponse.msg || '未知错误'}`);
|
||||
throw new Error(batchResponse.msg || '保存明细数据失败');
|
||||
}
|
||||
} else {
|
||||
// 新增模式:逐条保存并回填后端生成的明细 id
|
||||
for (let i = 0; i < detailData.length; i++) {
|
||||
const detailItem = {
|
||||
...detailData[i],
|
||||
packageId: packageId
|
||||
};
|
||||
|
||||
// 回填后端生成的明细 id,防止取消编辑时被误判为新增行
|
||||
// 后端返回字段名是 detailId(见 InspectionPackageDetail.java)
|
||||
if (detailResponse.data && (detailResponse.data.detailId || detailResponse.data.id)) {
|
||||
packageItems.value[i].id = detailResponse.data.detailId || detailResponse.data.id;
|
||||
const detailResponse = await saveInspectionPackageDetails(detailItem);
|
||||
|
||||
if (detailResponse.code !== 200) {
|
||||
loading.close();
|
||||
throw new Error(`保存第 ${i + 1} 个明细项失败: ${detailResponse.msg || '未知错误'}`);
|
||||
}
|
||||
|
||||
// 回填后端生成的明细 id,防止取消编辑时被误判为新增行
|
||||
if (detailResponse.data && (detailResponse.data.detailId || detailResponse.data.id)) {
|
||||
packageItems.value[i].id = detailResponse.data.detailId || detailResponse.data.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2421,8 +2440,14 @@ const savePackageData = async (basicInfo, detailData) => {
|
||||
|
||||
ElMessage.success('保存成功');
|
||||
|
||||
// 保存成功后重置表单
|
||||
doResetForm();
|
||||
if (isEditMode) {
|
||||
// 编辑模式:重新加载最新数据,保持在编辑页面
|
||||
loadInspectionPackage(String(packageId));
|
||||
} else {
|
||||
// 新增模式:保存成功后重置表单
|
||||
doResetForm();
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
// 确保在错误时也关闭loading
|
||||
@@ -2495,7 +2520,7 @@ const doResetForm = () => {
|
||||
// 清空明细数据
|
||||
packageItems.value = [];
|
||||
|
||||
// 重置模式为新增
|
||||
// 重置为新增模式(仅在外部未指定 mode 时,由调用方负责设置 packageMode)
|
||||
packageMode.value = 'add';
|
||||
currentPackageId.value = null;
|
||||
|
||||
@@ -2527,6 +2552,9 @@ const loadInspectionPackage = async (packageId) => {
|
||||
const basicData = basicResponse.data;
|
||||
const detailData = detailResponse.data || [];
|
||||
|
||||
// 【关键】暂停 packageItems 的 watch,防止赋值时触发 calculateAmounts 覆盖后端返回的金额
|
||||
isLoadingPackage.value = true;
|
||||
|
||||
// 填充基本信息
|
||||
packageLevel.value = basicData.packageLevel;
|
||||
packageName.value = basicData.packageName;
|
||||
@@ -2536,8 +2564,8 @@ const loadInspectionPackage = async (packageId) => {
|
||||
showPackageName.value = basicData.showPackageName !== false;
|
||||
generateServiceFee.value = basicData.generateServiceFee !== false;
|
||||
enablePackagePrice.value = basicData.enablePackagePrice !== false;
|
||||
packageAmount.value = basicData.packageAmount || 0.00;
|
||||
serviceFee.value = basicData.serviceFee || 0.00;
|
||||
packageAmount.value = parseFloat(basicData.packageAmount || 0);
|
||||
serviceFee.value = parseFloat(basicData.serviceFee || 0);
|
||||
selectedLisGroup.value = basicData.lisGroup || '';
|
||||
bloodVolume.value = basicData.bloodVolume || '';
|
||||
remarks.value = basicData.remarks || '';
|
||||
@@ -2559,11 +2587,15 @@ const loadInspectionPackage = async (packageId) => {
|
||||
origin: item.origin || ''
|
||||
}));
|
||||
|
||||
// 恢复监听
|
||||
isLoadingPackage.value = false;
|
||||
|
||||
loading.close();
|
||||
ElMessage.success('套餐数据加载成功');
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载套餐数据失败:', error);
|
||||
isLoadingPackage.value = false;
|
||||
|
||||
ElMessage.error(error.message || '加载套餐数据失败');
|
||||
}
|
||||
};
|
||||
@@ -2597,47 +2629,43 @@ watch(activity_category_code, (newVal) => {
|
||||
}, { immediate: true });
|
||||
|
||||
/**
|
||||
* 关键修复:
|
||||
* 从“套餐管理”跳转到这里时,通常只是改变 query(packageId/mode/tab),组件不会重新挂载,
|
||||
* 所以仅靠 onMounted 读取一次 query 会导致“查看/修改”出现空白,刷新才正常。
|
||||
* 这里监听 query 变化,自动切换 tab 并加载套餐数据。
|
||||
* 统一监听 query 变化,处理 tab 切换和套餐数据加载。
|
||||
* 使用 watch(route) 深度监听,确保在 keep-alive 场景下同路由 query 变化也能响应。
|
||||
*/
|
||||
watch(
|
||||
() => route.query.tab,
|
||||
(tab) => {
|
||||
if (tab === '0' || tab === '1' || tab === '2') {
|
||||
activeNav.value = parseInt(String(tab));
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const applyRouteForPackage = async (query) => {
|
||||
const tab = query?.tab;
|
||||
const packageId = query?.packageId;
|
||||
const mode = query?.mode || 'add';
|
||||
|
||||
// 设置当前模式和套餐ID
|
||||
packageMode.value = mode;
|
||||
currentPackageId.value = packageId ? String(packageId) : null;
|
||||
|
||||
// 如果是新增模式,重置表单
|
||||
|
||||
// 先切换 tab
|
||||
if (tab === '0' || tab === '1' || tab === '2') {
|
||||
activeNav.value = parseInt(tab);
|
||||
};
|
||||
|
||||
// 只有 tab=2(套餐设置)才处理套餐数据
|
||||
if (activeNav.value !== 2) return;
|
||||
|
||||
// 新增模式:重置表单,然后明确设置 mode
|
||||
if (mode === 'add' || !packageId) {
|
||||
activeNav.value = 2;
|
||||
doResetForm();
|
||||
doResetForm(); // 内部会设 packageMode='add',符合预期
|
||||
return;
|
||||
}
|
||||
|
||||
activeNav.value = 2;
|
||||
|
||||
// 编辑/查看模式:先设置 mode 和 ID,再加载数据
|
||||
packageMode.value = mode;
|
||||
currentPackageId.value = String(packageId);
|
||||
|
||||
await nextTick();
|
||||
loadInspectionPackage(String(packageId));
|
||||
};
|
||||
|
||||
// 监听整个 route.query,确保任何 query 变化(tab/packageId/mode)都能触发
|
||||
watch(
|
||||
() => route.query.packageId,
|
||||
async () => {
|
||||
await applyRouteForPackage(route.query);
|
||||
() => route.query,
|
||||
(newQuery) => {
|
||||
applyRouteForPackage(newQuery);
|
||||
},
|
||||
{ immediate: true, flush: 'post' }
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
// 兜底:如果该页面被 keep-alive 缓存,从别的页面返回时不会触发 onMounted
|
||||
@@ -2652,11 +2680,14 @@ onBeforeRouteUpdate((to) => {
|
||||
|
||||
// 监听生成服务费选项变更
|
||||
watch(generateServiceFee, (newVal) => {
|
||||
if (isLoadingPackage.value) return;
|
||||
calculateAmounts();
|
||||
});
|
||||
|
||||
// 监听套餐项目变化
|
||||
watch(packageItems, (newVal) => {
|
||||
// 加载期间跳过计算,防止覆盖后端返回的金额
|
||||
if (isLoadingPackage.value) return;
|
||||
calculateAmounts();
|
||||
}, { deep: true });
|
||||
// 样本类型数据
|
||||
|
||||
Reference in New Issue
Block a user