检验项目设置-》套餐设置:卫生机构字段取值当前登录账户的科室名称了
210 检验项目设置-》套餐管理:卫生机构筛选字段下拉选项取值错误
This commit is contained in:
2026-03-24 16:42:24 +08:00
parent 22d73e5b44
commit b03f563df4
2 changed files with 259 additions and 147 deletions

View File

@@ -25,9 +25,20 @@
</div>
<div class="filter-item">
<label>卫生机构</label>
<select>
<option>演示医院</option>
</select>
<el-select
v-model="selectedTenantId"
placeholder="请选择机构"
style="width: 150px;"
clearable
@change="handleSearch"
>
<el-option
v-for="item in tenantOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="filter-item">
<label>套餐名称</label>
@@ -182,9 +193,8 @@ import {useRouter} from 'vue-router';
import {ElMessage} from 'element-plus';
import {getLocationTree} from '@/views/charge/outpatientregistration/components/outpatientregistration';
import {listInspectionPackage} from '@/api/system/inspectionPackage';
import { getTenantPage } from '@/api/system/tenant';
console.log('PackageManagement 组件脚本开始执行')
console.log('listInspectionPackage 函数:', listInspectionPackage)
// 创建路由实例
const router = useRouter();
@@ -199,8 +209,7 @@ const departments = ref([]);
function getDepartmentList() {
console.log('调用getLocationTree API...');
getLocationTree().then((response) => {
console.log('getLocationTree API完整返回:', response);
console.log('getLocationTree API数据结构:', JSON.stringify(response.data, null, 2));
// 检查数据结构并转换为适合el-tree-select的格式
if (Array.isArray(response.data)) {
@@ -213,13 +222,12 @@ function getDepartmentList() {
// 处理另一种分页格式数据
departments.value = response.data.rows;
} else {
console.error('API返回数据格式不符合预期:', response.data);
departments.value = [];
}
console.log('最终科室数据:', JSON.stringify(departments.value, null, 2));
}).catch((error) => {
console.error('获取科室数据失败:', error);
departments.value = [];
});
}
@@ -257,7 +265,7 @@ const searchParams = ref({
// 从API加载数据
async function loadData() {
try {
console.log('loadData 函数被调用')
loading.value = true
// 构建查询参数(匹配后端 InspectionPackage 实体字段)
@@ -274,6 +282,9 @@ async function loadData() {
// if (searchParams.value.endDate) {
// params.endDate = searchParams.value.endDate
// }
if (selectedTenantId.value) {
params.tenantId = selectedTenantId.value;
}
if (searchParams.value.packageName) {
params.packageName = searchParams.value.packageName
@@ -285,13 +296,9 @@ async function loadData() {
params.department = searchParams.value.department
}
console.log('准备调用 listInspectionPackage API参数:', params)
const response = await listInspectionPackage(params)
console.log('listInspectionPackage API 完整返回:', response)
console.log('response 类型:', typeof response)
console.log('response.data 是否存在:', !!response.data)
console.log('response.rows 是否存在:', !!response.rows)
console.log('response.total 是否存在:', !!response.total)
if (response) {
// 处理不同的响应格式优先按若依风格response.rows / response.total
@@ -301,44 +308,39 @@ async function loadData() {
// 优先检查 response.dataaxios 包装的响应)
if (response.data) {
const data = response.data
console.log('response.data 内容:', data)
console.log('response.data.rows:', data.rows)
console.log('response.data.total:', data.total)
if (Array.isArray(data.rows)) {
// TableDataInfo 格式:{ rows: [], total: 0 }
dataList = data.rows
totalCount = data.total || 0
console.log('使用 response.data.rows 和 response.data.total, totalCount:', totalCount)
} else if (Array.isArray(data.records)) {
// MyBatis Plus 分页格式
dataList = data.records
totalCount = data.total || 0
console.log('使用 response.data.records 和 response.data.total, totalCount:', totalCount)
} else if (Array.isArray(data)) {
// 直接是数组
dataList = data
totalCount = data.length
console.log('使用 response.data 数组, totalCount:', totalCount)
}
} else if (Array.isArray(response.rows)) {
// 直接是 TableDataInfo 格式
dataList = response.rows
totalCount = response.total || 0
console.log('使用 response.rows 和 response.total, totalCount:', totalCount)
} else if (Array.isArray(response)) {
// 直接返回数组
dataList = response
totalCount = response.length
console.log('使用 response 数组, totalCount:', totalCount)
}
total.value = totalCount
console.log('设置 total.value =', total.value)
// 转换数据格式以匹配前端显示InspectionPackage 字段映射)
console.log('原始数据列表:', dataList)
console.log('数据列表长度:', dataList.length)
tableData.value = (dataList || []).map(item => {
const mappedItem = {
@@ -362,22 +364,18 @@ async function loadData() {
enabled: item.isDisabled === true ? '否' : '是',
operator: item.createBy || ''
}
console.log('原始数据项:', item)
console.log('映射后的数据项:', mappedItem)
return mappedItem
})
console.log('最终 tableData.value:', tableData.value)
console.log('tableData.value 长度:', tableData.value.length)
console.log('最终 total.value:', total.value)
console.log('计算的总页数 totalPages:', Math.ceil(total.value / pageSize.value))
} else {
tableData.value = []
total.value = 0
console.log('response 为空,重置数据')
}
} catch (error) {
console.error('加载数据失败:', error)
ElMessage.error('加载数据失败: ' + (error.message || '未知错误'))
tableData.value = []
total.value = 0
@@ -386,11 +384,70 @@ async function loadData() {
}
}
const selectedTenantId = ref(null); // 绑定下拉框的值
const tenantOptions = ref([]); // 存储机构选项
const loadingTenant = ref(false);
// 获取机构列表函数
const fetchTenantList = async () => {
if (loadingTenant.value) return;
loadingTenant.value = true;
try {
const response = await getTenantPage({ pageNum: 1, pageSize: 100 });
if (response.code !== 200) throw new Error(response.msg || '获取机构列表失败');
let tenantData = [];
const data = response.data;
if (Array.isArray(data)) {
tenantData = data;
} else if (data && typeof data === 'object') {
tenantData = data.records || data.rows || data.list || [];
}
// 过滤启用的机构
const activeTenants = (Array.isArray(tenantData) ? tenantData : []).filter(item => item && item.status === "0");
// 生成下拉选项
tenantOptions.value = activeTenants.map(item => ({
value: item.id,
label: item.tenantName || item.name || item.orgName || String(item.id)
}));
// 默认选中 ID=1 或第一个
if (activeTenants.length > 0) {
const zhonglianHospital = activeTenants.find(item => item.id === 1);
selectedTenantId.value = zhonglianHospital ? 1 : activeTenants[0].id;
}
} catch (error) {
console.error('获取机构列表失败:', error);
tenantOptions.value = [];
} finally {
loadingTenant.value = false;
}
};
// 初始化数据
onMounted(() => {
console.log('onMounted 被调用,准备加载数据')
loadData()
})
// 整合后的 onMounted 钩子
onMounted(async () => {
// 1. 加载科室数据
getDepartmentList();
// 2. 加载机构列表 (包含默认选中逻辑)
await fetchTenantList();
// 3. 等待 DOM 更新
await nextTick();
// 4. 防御性检查
if (tenantOptions.value.length > 0 && !selectedTenantId.value) {
selectedTenantId.value = tenantOptions.value[0].value;
}
// 5. 加载表格数据
loadData();
});
// 过滤后的数据 - 现在直接从API获取这里保留前端过滤作为补充
const filteredData = computed(() => {
@@ -434,7 +491,7 @@ function handleReset() {
// 计算总页数
const totalPages = computed(() => {
const pages = Math.ceil(total.value / pageSize.value)
console.log('[分页] 计算总页数: total=', total.value, 'pageSize=', pageSize.value, 'totalPages=', pages)
return pages > 0 ? pages : 1 // 至少返回1页
})
@@ -448,28 +505,28 @@ function handlePrevPage() {
// 处理分页 - 下一页
function handleNextPage() {
console.log('[分页] 点击下一页, currentPage:', currentPage.value, 'totalPages:', totalPages.value)
if (currentPage.value < totalPages.value) {
currentPage.value++
console.log('[分页] 跳转到第', currentPage.value, '页')
loadData()
} else {
console.log('[分页] 已经是最后一页,无法继续')
}
}
// 处理分页 - 跳转到指定页
function handlePageChange(page) {
console.log('[分页] 点击页码, page:', page, 'currentPage:', currentPage.value, 'totalPages:', totalPages.value)
if (page === '...') {
return // 省略号不可点击
}
if (page >= 1 && page <= totalPages.value && page !== currentPage.value) {
currentPage.value = page
console.log('[分页] 跳转到第', currentPage.value, '页')
loadData()
} else {
console.log('[分页] 无效的页码或已经是当前页')
}
}
@@ -479,7 +536,7 @@ const pageButtons = computed(() => {
const total = totalPages.value
const current = currentPage.value
console.log('[分页] 计算分页按钮, totalPages:', total, 'currentPage:', current)
if (total <= 0) {
// 如果没有数据至少显示第1页
@@ -520,7 +577,7 @@ const pageButtons = computed(() => {
}
}
console.log('[分页] 生成的按钮:', buttons)
return buttons
})

View File

@@ -789,6 +789,7 @@ import {
listInspectionPackageDetails,
saveInspectionPackageDetails
} from '@/api/system/inspectionPackage';
import { getTenantPage } from '@/api/system/tenant';
import {deptTreeSelect} from '@/api/system/user';
// 获取当前登录用户信息
@@ -1053,70 +1054,7 @@ const selectedTenantId = ref(null); // 存储当前选中的租户ID
// --- 新增:控制租户列表加载状态 ---
const loadingTenant = ref(false); // 控制下拉框的加载状态
const fetchTenantList = async () => {
if (loadingTenant.value) return; // 防止重复请求
loadingTenant.value = true;
try {
const response = await request({
url: '/system/tenant/page',
method: 'get',
params: {
pageNum: 1,
pageSize: 100
}
});
if (response.code === 200) {
let tenantData = [];
// --- 关键修改:优先检查 records 字段 ---
if (response.data && response.data.records && Array.isArray(response.data.records)) {
tenantData = response.data.records;
} else if (response.data && response.data.rows && Array.isArray(response.data.rows)) {
// 兼容旧的 rows 格式
tenantData = response.data.rows;
} else if (response.data && Array.isArray(response.data)) {
// 兼容最简单的数组格式
tenantData = response.data;
} else {
tenantData = [];
}
// 格式化数据以适应 el-select
tenantOptions.value = tenantData.map(item => ({
value: item.id,
label: item.tenantName || item.name || item.orgName || String(item.id) || '未知机构'
}));
// 如果仍未设置默认值且列表不为空,选择第一个
if (!selectedTenantId.value && tenantOptions.value.length > 0) {
selectedTenantId.value = tenantOptions.value[0].value;
}
} else {
ElMessage.error(response.msg || '获取机构列表失败,请联系管理员');
tenantOptions.value = [];
}
} catch (error) {
ElMessage.error('网络异常或数据解析错误,请检查控制台日志');
tenantOptions.value = [];
} finally {
// 确保无论成功还是失败都停止加载状态
loadingTenant.value = false;
}
};
// 展开时若列表为空则加载数据
const handleTenantVisibleChange = async (visible) => {
if (visible && tenantOptions.value.length === 0) { // 仅在展开且列表为空时加载
@@ -1301,9 +1239,7 @@ const handleEditRow = (row) => {
}
};
onMounted(() => {
loadParentTypes();
});
// 样本类型数据
@@ -2358,6 +2294,95 @@ const handleSave = () => {
savePackageData(basicInfo, detailData);
};
//定义表单数据
const form = ref({
tenantId: undefined, // 卫生机构 ID
packageType: '检验套餐', // 套餐类别
packageLevel: '', // 套餐级别
packageName: '', // 套餐名称
amount: 0.00, // 套餐金额
discount: '', // 折扣 %
creator: '超级管理员', // 制单人
remark: '', // 备注
isDisabled: false, // 是否停用 (false=启用)
showPackageName: true, // 显示套餐名
generateServiceFee: true, // 生成服务费
enablePackagePrice: true, // 套餐价格启用
serviceFee: 0.00, // 服务费
lisGroup: '', // lis分组
bloodVolume: '' // 血量
});
const fetchTenantList = async () => {
if (loadingTenant.value) return;
loadingTenant.value = true;
try {
const response = await getTenantPage({ pageNum: 1, pageSize: 100 });
// 1. 检查业务状态码
if (response.code !== 200) {
throw new Error(response.msg || '获取机构列表失败');
}
// 2. 安全提取数据列表
let tenantData = [];
const data = response.data;
if (Array.isArray(data)) {
tenantData = data;
} else if (data && typeof data === 'object') {
tenantData = data.records || data.rows || data.list || [];
}
if (!Array.isArray(tenantData)) {
tenantData = [];
}
// 3. 过滤启用的机构 (status === "0")
// 根据您提供的JSON这里会成功筛选出 ID=1 的 "中联医院"
const activeTenants = tenantData.filter(item => item && item.status === "0");
// 4. 生成下拉选项
tenantOptions.value = activeTenants.map(item => ({
value: item.id,
label: item.tenantName || item.name || item.orgName || String(item.id)
}));
// 5. 默认选中逻辑
if (activeTenants.length > 0) {
// 优先选中 ID 为 1 的 "中联医院"
const zhonglianHospital = activeTenants.find(item => item.id === 1);
if (zhonglianHospital) {
form.value.tenantId = 1;
} else {
// 增加 userInfoStore 的存在性检查
// 防止 store 未初始化导致报错
const userStore = userInfoStore; // 获取 store 引用
if (userStore && userStore.tenantId) {
const currentTenant = activeTenants.find(item => item.id === userStore.tenantId);
form.value.tenantId = currentTenant ? currentTenant.id : activeTenants[0].id;
} else {
// 如果没有用户信息或 store 未就绪,直接选第一个
form.value.tenantId = activeTenants[0].id;
}
}
} else {
form.value.tenantId = undefined;
}
} catch (error) {
// 打印详细错误,方便调试
ElMessage.error('获取机构列表失败:' + (error.message || '未知错误'));
tenantOptions.value = [];
} finally {
loadingTenant.value = false;
}
};
// 保存套餐数据到数据库
const savePackageData = async (basicInfo, detailData) => {
// 显示保存进度
@@ -2580,16 +2605,7 @@ const refreshPage = () => {
// loadPackageItemsFromAPI();
};
// 页面加载时获取数据
onMounted(() => {
getInspectionTypeList();
getLisGroupList();
// // 加载检验套餐明细项目
// loadPackageItemsFromAPI();
// // 初始化计算套餐金额和服务费
// calculateAmounts();
fetchTenantList(); // 页面加载时获取租户列表
});
// 监听检验分类代码,当字典数据加载完成后加载检验项目数据
@@ -2664,6 +2680,45 @@ const unitOptions = ref([
{ value: '次', label: '次' },
{ value: '天', label: '天' }
]);
onMounted(async () => {
// 1. 启动其他基础数据的加载(这些不需要等待,并行执行即可)
loadParentTypes();
getInspectionTypeList();
getLisGroupList();
// 2. 【关键】等待机构列表加载完成
// 等函数执行完成
await fetchTenantList();
// 3. 等待 Vue 完成下一轮的 DOM 更新
await nextTick();
// 4. 【核心逻辑】强制默认选中“中联医院” (ID = 1)
// 检查下拉列表中是否存在 value 为 1 的选项
const hasZhonglian = tenantOptions.value.some(item => item.value === 1);
if (hasZhonglian) {
// 直接赋值给模板中 v-model 绑定的变量
selectedTenantId.value = 1;
// 💡 防御性编程:防止因渲染延迟导致界面未刷新
// 如果赋值后界面还没变100毫秒后再强制赋一次值
setTimeout(() => {
if (selectedTenantId.value !== 1) {
selectedTenantId.value = 1;
}
}, 100);
} else {
// (可选) 如果没有中联医院,且列表不为空,默认选中第一个
if (tenantOptions.value.length > 0 && !selectedTenantId.value) {
selectedTenantId.value = tenantOptions.value[0].value;
}
}
});
</script>
<style>