211
检验项目设置-》套餐管理:点击【新增】跳转至套餐设置界面系统未进行初始化新增模式界面数据 212 检验项目设置-》套餐管理:点击行【编辑】跳转至套餐设置编辑模式该行的套餐数据未正确引入 213 检验项目设置-》套餐管理:点击行【查看】跳转至套餐设置界面套餐内容显示错误并且未进入只读模式
This commit is contained in:
@@ -194,10 +194,13 @@ import {ElMessage} from 'element-plus';
|
|||||||
import {getLocationTree} from '@/views/charge/outpatientregistration/components/outpatientregistration';
|
import {getLocationTree} from '@/views/charge/outpatientregistration/components/outpatientregistration';
|
||||||
import {listInspectionPackage, delInspectionPackage} from '@/api/system/inspectionPackage';
|
import {listInspectionPackage, delInspectionPackage} from '@/api/system/inspectionPackage';
|
||||||
import { getTenantPage } from '@/api/system/tenant';
|
import { getTenantPage } from '@/api/system/tenant';
|
||||||
|
import useTagsViewStore from '@/store/modules/tagsView';
|
||||||
|
|
||||||
|
|
||||||
// 创建路由实例
|
// 创建路由实例
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const tagsViewStore = useTagsViewStore();
|
||||||
|
|
||||||
|
|
||||||
// 侧边栏状态
|
// 侧边栏状态
|
||||||
const sidebarActive = ref(false);
|
const sidebarActive = ref(false);
|
||||||
@@ -207,7 +210,6 @@ const departments = ref([]);
|
|||||||
|
|
||||||
// 获取科室数据 - 与门诊挂号页面保持一致
|
// 获取科室数据 - 与门诊挂号页面保持一致
|
||||||
function getDepartmentList() {
|
function getDepartmentList() {
|
||||||
console.log('调用getLocationTree API...');
|
|
||||||
getLocationTree().then((response) => {
|
getLocationTree().then((response) => {
|
||||||
|
|
||||||
|
|
||||||
@@ -430,13 +432,17 @@ const fetchTenantList = async () => {
|
|||||||
// 初始化数据
|
// 初始化数据
|
||||||
// 整合后的 onMounted 钩子
|
// 整合后的 onMounted 钩子
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 1. 加载科室数据
|
// 1. 加载科室数据(不需要等待)
|
||||||
getDepartmentList();
|
getDepartmentList();
|
||||||
|
|
||||||
// 2. 加载机构列表 (包含默认选中逻辑)
|
// 2. 并行发起:机构列表 + 表格数据,减少串行等待
|
||||||
await fetchTenantList();
|
const tenantPromise = fetchTenantList();
|
||||||
|
|
||||||
// 3. 等待 DOM 更新
|
// 先用默认参数(不带 tenantId)立刻加载表格,让用户尽快看到数据
|
||||||
|
loadData();
|
||||||
|
|
||||||
|
// 3. 等待机构列表加载完成
|
||||||
|
await tenantPromise;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
// 4. 防御性检查
|
// 4. 防御性检查
|
||||||
@@ -444,9 +450,10 @@ onMounted(async () => {
|
|||||||
selectedTenantId.value = tenantOptions.value[0].value;
|
selectedTenantId.value = tenantOptions.value[0].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 加载表格数据
|
// 5. 如果选中了机构,用 tenantId 重新过滤一次
|
||||||
loadData();
|
if (selectedTenantId.value) {
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 过滤后的数据 - 现在直接从API获取,这里保留前端过滤作为补充
|
// 过滤后的数据 - 现在直接从API获取,这里保留前端过滤作为补充
|
||||||
@@ -583,51 +590,27 @@ const pageButtons = computed(() => {
|
|||||||
|
|
||||||
// 处理新增
|
// 处理新增
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
router.push({
|
window.location.href = '/maintainSystem/Inspection?tab=2&mode=add';
|
||||||
path: '/maintainSystem/Inspection',
|
|
||||||
query: {
|
|
||||||
tab: '2',
|
|
||||||
mode: 'add'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理编辑
|
// 处理编辑
|
||||||
function handleEdit(item) {
|
function handleEdit(item) {
|
||||||
// 跳转到套餐设置主界面,并传递套餐ID用于加载数据
|
|
||||||
// 后端接口使用 basicInformationId 作为路径参数
|
|
||||||
const packageId = item.basicInformationId || item.id;
|
const packageId = item.basicInformationId || item.id;
|
||||||
if (!packageId) {
|
if (!packageId) {
|
||||||
ElMessage.error('无法获取套餐ID,请刷新页面后重试');
|
ElMessage.error('无法获取套餐ID,请刷新页面后重试');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push({
|
window.location.href = `/maintainSystem/Inspection?tab=2&mode=edit&packageId=${packageId}`;
|
||||||
path: '/maintainSystem/Inspection',
|
|
||||||
query: {
|
|
||||||
tab: '2',
|
|
||||||
packageId: packageId,
|
|
||||||
mode: 'edit'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理查看
|
// 处理查看
|
||||||
function handleView(item) {
|
function handleView(item) {
|
||||||
// 跳转到套餐设置主界面,并传递套餐ID用于加载数据
|
|
||||||
// 后端接口使用 basicInformationId 作为路径参数
|
|
||||||
const packageId = item.basicInformationId || item.id;
|
const packageId = item.basicInformationId || item.id;
|
||||||
if (!packageId) {
|
if (!packageId) {
|
||||||
ElMessage.error('无法获取套餐ID,请刷新页面后重试');
|
ElMessage.error('无法获取套餐ID,请刷新页面后重试');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push({
|
window.location.href = `/maintainSystem/Inspection?tab=2&mode=view&packageId=${packageId}`;
|
||||||
path: '/maintainSystem/Inspection',
|
|
||||||
query: {
|
|
||||||
tab: '2',
|
|
||||||
packageId: packageId,
|
|
||||||
mode: 'view'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理删除
|
// 处理删除
|
||||||
|
|||||||
@@ -813,7 +813,8 @@ import {
|
|||||||
updateInspectionPackage,
|
updateInspectionPackage,
|
||||||
getInspectionPackage,
|
getInspectionPackage,
|
||||||
listInspectionPackageDetails,
|
listInspectionPackageDetails,
|
||||||
saveInspectionPackageDetails
|
saveInspectionPackageDetails,
|
||||||
|
batchSaveInspectionPackageDetails
|
||||||
} from '@/api/system/inspectionPackage';
|
} from '@/api/system/inspectionPackage';
|
||||||
import { getTenantPage } from '@/api/system/tenant';
|
import { getTenantPage } from '@/api/system/tenant';
|
||||||
import {deptTreeSelect} from '@/api/system/user';
|
import {deptTreeSelect} from '@/api/system/user';
|
||||||
@@ -1470,6 +1471,8 @@ const packageItems = ref([]);
|
|||||||
const packageMode = ref('add');
|
const packageMode = ref('add');
|
||||||
// 当前编辑的套餐ID(用于编辑和查看模式)
|
// 当前编辑的套餐ID(用于编辑和查看模式)
|
||||||
const currentPackageId = ref(null);
|
const currentPackageId = ref(null);
|
||||||
|
// 正在从后端加载套餐数据的标志,加载期间跳过 calculateAmounts 防止覆盖后端金额
|
||||||
|
const isLoadingPackage = ref(false);
|
||||||
// 是否为查看模式(只读)
|
// 是否为查看模式(只读)
|
||||||
const isViewMode = computed(() => packageMode.value === 'view');
|
const isViewMode = computed(() => packageMode.value === 'view');
|
||||||
|
|
||||||
@@ -2364,6 +2367,10 @@ const savePackageData = async (basicInfo, detailData) => {
|
|||||||
if (isEditMode) {
|
if (isEditMode) {
|
||||||
// 编辑模式:调用更新API
|
// 编辑模式:调用更新API
|
||||||
basicResponse = await updateInspectionPackage(basicInfo);
|
basicResponse = await updateInspectionPackage(basicInfo);
|
||||||
|
if (basicResponse.code !== 200) {
|
||||||
|
loading.close();
|
||||||
|
throw new Error(basicResponse.msg || '更新基本信息失败');
|
||||||
|
}
|
||||||
packageId = currentPackageId.value;
|
packageId = currentPackageId.value;
|
||||||
} else {
|
} else {
|
||||||
// 新增模式:调用新增API
|
// 新增模式:调用新增API
|
||||||
@@ -2390,29 +2397,41 @@ const savePackageData = async (basicInfo, detailData) => {
|
|||||||
// 验证套餐ID是否存在
|
// 验证套餐ID是否存在
|
||||||
if (!packageId) {
|
if (!packageId) {
|
||||||
loading.close();
|
loading.close();
|
||||||
console.error('无法从响应中获取套餐ID,完整响应:', basicResponse);
|
|
||||||
throw new Error('保存成功但未返回套餐ID。请检查后端接口是否正确返回了packageId或id字段');
|
throw new Error('保存成功但未返回套餐ID。请检查后端接口是否正确返回了packageId或id字段');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 分别保存每个明细数据到明细表,并将后端返回的 id 回填到 packageItems
|
// 2. 保存明细数据:编辑模式用批量接口(先删旧后插新),新增模式逐条新增
|
||||||
for (let i = 0; i < detailData.length; i++) {
|
if (isEditMode) {
|
||||||
const detailItem = {
|
// 编辑模式:调用批量保存接口,后端会先删除旧明细再插入新明细
|
||||||
...detailData[i],
|
const batchPayload = {
|
||||||
packageId: packageId
|
basicInformationId: packageId,
|
||||||
|
details: detailData.map(item => ({ ...item, packageId: packageId }))
|
||||||
};
|
};
|
||||||
|
const batchResponse = await batchSaveInspectionPackageDetails(batchPayload);
|
||||||
const detailResponse = await saveInspectionPackageDetails(detailItem);
|
if (batchResponse.code !== 200) {
|
||||||
|
|
||||||
if (detailResponse.code !== 200) {
|
|
||||||
loading.close();
|
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,防止取消编辑时被误判为新增行
|
const detailResponse = await saveInspectionPackageDetails(detailItem);
|
||||||
// 后端返回字段名是 detailId(见 InspectionPackageDetail.java)
|
|
||||||
if (detailResponse.data && (detailResponse.data.detailId || detailResponse.data.id)) {
|
if (detailResponse.code !== 200) {
|
||||||
packageItems.value[i].id = detailResponse.data.detailId || detailResponse.data.id;
|
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('保存成功');
|
ElMessage.success('保存成功');
|
||||||
|
|
||||||
// 保存成功后重置表单
|
if (isEditMode) {
|
||||||
doResetForm();
|
// 编辑模式:重新加载最新数据,保持在编辑页面
|
||||||
|
loadInspectionPackage(String(packageId));
|
||||||
|
} else {
|
||||||
|
// 新增模式:保存成功后重置表单
|
||||||
|
doResetForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 确保在错误时也关闭loading
|
// 确保在错误时也关闭loading
|
||||||
@@ -2495,7 +2520,7 @@ const doResetForm = () => {
|
|||||||
// 清空明细数据
|
// 清空明细数据
|
||||||
packageItems.value = [];
|
packageItems.value = [];
|
||||||
|
|
||||||
// 重置模式为新增
|
// 重置为新增模式(仅在外部未指定 mode 时,由调用方负责设置 packageMode)
|
||||||
packageMode.value = 'add';
|
packageMode.value = 'add';
|
||||||
currentPackageId.value = null;
|
currentPackageId.value = null;
|
||||||
|
|
||||||
@@ -2527,6 +2552,9 @@ const loadInspectionPackage = async (packageId) => {
|
|||||||
const basicData = basicResponse.data;
|
const basicData = basicResponse.data;
|
||||||
const detailData = detailResponse.data || [];
|
const detailData = detailResponse.data || [];
|
||||||
|
|
||||||
|
// 【关键】暂停 packageItems 的 watch,防止赋值时触发 calculateAmounts 覆盖后端返回的金额
|
||||||
|
isLoadingPackage.value = true;
|
||||||
|
|
||||||
// 填充基本信息
|
// 填充基本信息
|
||||||
packageLevel.value = basicData.packageLevel;
|
packageLevel.value = basicData.packageLevel;
|
||||||
packageName.value = basicData.packageName;
|
packageName.value = basicData.packageName;
|
||||||
@@ -2536,8 +2564,8 @@ const loadInspectionPackage = async (packageId) => {
|
|||||||
showPackageName.value = basicData.showPackageName !== false;
|
showPackageName.value = basicData.showPackageName !== false;
|
||||||
generateServiceFee.value = basicData.generateServiceFee !== false;
|
generateServiceFee.value = basicData.generateServiceFee !== false;
|
||||||
enablePackagePrice.value = basicData.enablePackagePrice !== false;
|
enablePackagePrice.value = basicData.enablePackagePrice !== false;
|
||||||
packageAmount.value = basicData.packageAmount || 0.00;
|
packageAmount.value = parseFloat(basicData.packageAmount || 0);
|
||||||
serviceFee.value = basicData.serviceFee || 0.00;
|
serviceFee.value = parseFloat(basicData.serviceFee || 0);
|
||||||
selectedLisGroup.value = basicData.lisGroup || '';
|
selectedLisGroup.value = basicData.lisGroup || '';
|
||||||
bloodVolume.value = basicData.bloodVolume || '';
|
bloodVolume.value = basicData.bloodVolume || '';
|
||||||
remarks.value = basicData.remarks || '';
|
remarks.value = basicData.remarks || '';
|
||||||
@@ -2559,11 +2587,15 @@ const loadInspectionPackage = async (packageId) => {
|
|||||||
origin: item.origin || ''
|
origin: item.origin || ''
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// 恢复监听
|
||||||
|
isLoadingPackage.value = false;
|
||||||
|
|
||||||
loading.close();
|
loading.close();
|
||||||
ElMessage.success('套餐数据加载成功');
|
ElMessage.success('套餐数据加载成功');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载套餐数据失败:', error);
|
isLoadingPackage.value = false;
|
||||||
|
|
||||||
ElMessage.error(error.message || '加载套餐数据失败');
|
ElMessage.error(error.message || '加载套餐数据失败');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2597,47 +2629,43 @@ watch(activity_category_code, (newVal) => {
|
|||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关键修复:
|
* 统一监听 query 变化,处理 tab 切换和套餐数据加载。
|
||||||
* 从“套餐管理”跳转到这里时,通常只是改变 query(packageId/mode/tab),组件不会重新挂载,
|
* 使用 watch(route) 深度监听,确保在 keep-alive 场景下同路由 query 变化也能响应。
|
||||||
* 所以仅靠 onMounted 读取一次 query 会导致“查看/修改”出现空白,刷新才正常。
|
|
||||||
* 这里监听 query 变化,自动切换 tab 并加载套餐数据。
|
|
||||||
*/
|
*/
|
||||||
watch(
|
|
||||||
() => route.query.tab,
|
|
||||||
(tab) => {
|
|
||||||
if (tab === '0' || tab === '1' || tab === '2') {
|
|
||||||
activeNav.value = parseInt(String(tab));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
const applyRouteForPackage = async (query) => {
|
const applyRouteForPackage = async (query) => {
|
||||||
|
const tab = query?.tab;
|
||||||
const packageId = query?.packageId;
|
const packageId = query?.packageId;
|
||||||
const mode = query?.mode || 'add';
|
const mode = query?.mode || 'add';
|
||||||
|
|
||||||
// 设置当前模式和套餐ID
|
// 先切换 tab
|
||||||
packageMode.value = mode;
|
if (tab === '0' || tab === '1' || tab === '2') {
|
||||||
currentPackageId.value = packageId ? String(packageId) : null;
|
activeNav.value = parseInt(tab);
|
||||||
|
};
|
||||||
// 如果是新增模式,重置表单
|
|
||||||
|
// 只有 tab=2(套餐设置)才处理套餐数据
|
||||||
|
if (activeNav.value !== 2) return;
|
||||||
|
|
||||||
|
// 新增模式:重置表单,然后明确设置 mode
|
||||||
if (mode === 'add' || !packageId) {
|
if (mode === 'add' || !packageId) {
|
||||||
activeNav.value = 2;
|
doResetForm(); // 内部会设 packageMode='add',符合预期
|
||||||
doResetForm();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
activeNav.value = 2;
|
// 编辑/查看模式:先设置 mode 和 ID,再加载数据
|
||||||
|
packageMode.value = mode;
|
||||||
|
currentPackageId.value = String(packageId);
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
loadInspectionPackage(String(packageId));
|
loadInspectionPackage(String(packageId));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 监听整个 route.query,确保任何 query 变化(tab/packageId/mode)都能触发
|
||||||
watch(
|
watch(
|
||||||
() => route.query.packageId,
|
() => route.query,
|
||||||
async () => {
|
(newQuery) => {
|
||||||
await applyRouteForPackage(route.query);
|
applyRouteForPackage(newQuery);
|
||||||
},
|
},
|
||||||
{ immediate: true, flush: 'post' }
|
{ immediate: true, deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// 兜底:如果该页面被 keep-alive 缓存,从别的页面返回时不会触发 onMounted
|
// 兜底:如果该页面被 keep-alive 缓存,从别的页面返回时不会触发 onMounted
|
||||||
@@ -2652,11 +2680,14 @@ onBeforeRouteUpdate((to) => {
|
|||||||
|
|
||||||
// 监听生成服务费选项变更
|
// 监听生成服务费选项变更
|
||||||
watch(generateServiceFee, (newVal) => {
|
watch(generateServiceFee, (newVal) => {
|
||||||
|
if (isLoadingPackage.value) return;
|
||||||
calculateAmounts();
|
calculateAmounts();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听套餐项目变化
|
// 监听套餐项目变化
|
||||||
watch(packageItems, (newVal) => {
|
watch(packageItems, (newVal) => {
|
||||||
|
// 加载期间跳过计算,防止覆盖后端返回的金额
|
||||||
|
if (isLoadingPackage.value) return;
|
||||||
calculateAmounts();
|
calculateAmounts();
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
// 样本类型数据
|
// 样本类型数据
|
||||||
|
|||||||
Reference in New Issue
Block a user