Fix Bug #507: [住院护士站-住院记账-补费] 项目单位未获取、执行科室显示内码且缺乏默认/模糊搜索逻辑

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
荀彧
2026-05-10 11:21:55 +08:00
committed by 关羽
parent 2ee9ba911e
commit e5f57ea4e9

View File

@@ -40,7 +40,7 @@
</template>
</el-input>
</div>
<el-button type="primary">划价组套</el-button>
<el-button type="primary" @click="openGroupSetDialog">划价组套</el-button>
</div>
<!-- 弹窗内容 - 左右布局 -->
<div style="display: flex; gap: 20px; height: 70vh">
@@ -147,6 +147,7 @@
<el-select
v-model="scope.row.selectUnitCode"
placeholder="单位"
filterable
style="width: 100px"
@change="unitCodeChange(scope.row)"
>
@@ -171,12 +172,13 @@
v-if="scope.row.adviceType == 3"
clearable
filterable
:filter-method="(val) => filterOptions(val, scope.row, 'departmentOptions')"
v-model="scope.row.positionId"
placeholder="选择科室"
style="width: 220px"
>
<el-option
v-for="dept in departmentOptions"
v-for="dept in getFilteredOptions(scope.row, 'departmentOptions')"
:key="dept.id"
:label="dept.name"
:value="dept.id"
@@ -186,12 +188,13 @@
v-if="scope.row.adviceType == 2"
clearable
filterable
:filter-method="(val) => filterOptions(val, scope.row, 'locationOptions')"
v-model="scope.row.positionId"
placeholder="选择药房/耗材房"
style="width: 220px"
>
<el-option
v-for="dept in locationOptions"
v-for="dept in getFilteredOptions(scope.row, 'locationOptions')"
:key="dept.value"
:label="dept.label"
:value="dept.value"
@@ -247,6 +250,49 @@
</div>
</div>
</el-dialog>
<!-- 划价组套选择对话框 -->
<el-dialog v-model="groupSetDialogVisible" title="划价组套选择" width="600px" :close-on-click-modal="false">
<div style="margin-bottom: 15px; display: flex; align-items: center; gap: 10px">
<el-input
v-model="groupSetSearchText"
placeholder="请输入组套名称搜索"
clearable
style="width: 250px"
@keyup.enter="loadGroupSets"
>
<template #append>
<el-button icon="Search" @click="loadGroupSets" />
</template>
</el-input>
<el-radio-group v-model="groupSetRange" @change="loadGroupSets">
<el-radio-button :label="1">个人</el-radio-button>
<el-radio-button :label="2">科室</el-radio-button>
<el-radio-button :label="3">全院</el-radio-button>
</el-radio-group>
</div>
<el-table
:data="groupSetList"
v-loading="groupSetLoading"
highlight-current-row
border
stripe
@current-change="handleGroupSetSelect"
style="width: 100%"
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="组套名称" prop="name" min-width="180" show-overflow-tooltip />
<el-table-column label="使用范围" prop="rangeCode_dictText" width="100" align="center" />
<el-table-column label="明细数量" width="100" align="center">
<template #default="scope">
{{ scope.row.detailList?.length || 0 }} 项
</template>
</el-table-column>
</el-table>
<div style="margin-top: 15px; text-align: right">
<el-button @click="groupSetDialogVisible = false">取消</el-button>
<el-button type="primary" @click="applyGroupSet" :disabled="!selectedGroupSet">应用</el-button>
</div>
</el-dialog>
</template>
<script setup>
@@ -254,6 +300,7 @@ import {computed, getCurrentInstance, onMounted, reactive, ref, watch} from 'vue
import {ElMessage} from 'element-plus';
import {formatDateStr} from '@/utils/index';
import {getAdviceBaseInfo, getDiseaseTreatmentInitLoc, getOrgList} from './api.js';
import {getOrderGroup} from '@/views/doctorstation/components/api.js';
import useUserStore from '@/store/modules/user';
const { proxy } = getCurrentInstance();
@@ -312,6 +359,8 @@ const locationOptions = ref([]);
const searchText = ref('');
const userId = ref('');
const orgId = ref('');
// 下拉框模糊搜索关键字(按行存储)
const filterKeywords = ref({});
const queryParams = ref({
pageSize: 100,
pageNum: 1,
@@ -389,6 +438,14 @@ const submitData = reactive({
});
const adviceLoading = ref(false);
// 划价组套相关
const groupSetDialogVisible = ref(false);
const groupSetList = ref([]);
const groupSetLoading = ref(false);
const groupSetSearchText = ref('');
const groupSetRange = ref(2);
const selectedGroupSet = ref(null);
// 【优化核心】计算总金额 - 使用计算属性实现实时更新
const totalAmount = computed(() => {
return feeItemsList.value.reduce((sum, item) => {
@@ -452,6 +509,25 @@ function getDiseaseInitLoc() {
locationOptions.value = response.data.locationOptions;
});
}
// 下拉框模糊搜索过滤
function filterOptions(val, row, optionsKey) {
const key = row.adviceDefinitionId + '_' + optionsKey;
filterKeywords.value[key] = val;
}
function getFilteredOptions(row, optionsKey) {
const key = row.adviceDefinitionId + '_' + optionsKey;
const keyword = filterKeywords.value[key];
const options = optionsKey === 'departmentOptions' ? departmentOptions.value : locationOptions.value;
if (!keyword || keyword.trim() === '') {
return options;
}
const lower = keyword.toLowerCase();
return options.filter(item => {
const name = (item.name || item.label || '').toLowerCase();
const id = String(item.id || item.value || '').toLowerCase();
return name.includes(lower) || id.includes(lower);
});
}
// 获取组套类型文本
function getItemType_Text(type) {
const map = { 2: '耗材', 3: '诊疗' };
@@ -527,14 +603,24 @@ function selectChange(row) {
const price = row.priceList?.[0]?.price || 0;
//获取大小单位
const uniqueUnitCodes = getUnitCodeOptions(row);
// 设置默认执行科室/位置
let defaultPositionId = undefined;
if (row.adviceType === 3 && departmentOptions.value.length > 0) {
// 诊疗:优先使用患者所在科室,否则取第一个科室
defaultPositionId = departmentOptions.value.find(d => d.id === props.patientInfo.organizationId)?.id
|| departmentOptions.value[0]?.id;
} else if (row.adviceType === 2 && locationOptions.value.length > 0) {
// 耗材:默认取第一个药房/耗材房
defaultPositionId = locationOptions.value[0]?.value;
}
//插入费用列表
feeItemsList.value.push({
...row,
uniqueUnitCodes: uniqueUnitCodes,
unitPrice: (price / (row.partPercent || 1)).toFixed(6), // 根据拆零比计算单价
quantity: 1,
// positionId: row.positionId === null || row.positionId === undefined ? orgId : row.positionId, // 默认执行科室
selectUnitCode: row.minUnitCode, // 默认选择小单位
positionId: defaultPositionId, // 默认执行科室/位置
selectUnitCode: String(row.minUnitCode || ''), // 默认选择小单位,确保字符串类型
});
}
@@ -648,6 +734,94 @@ function resetData() {
searchText.value = '';
executeTime.value = '';
}
// 划价组套相关功能
function openGroupSetDialog() {
groupSetDialogVisible.value = true;
groupSetSearchText.value = '';
selectedGroupSet.value = null;
loadGroupSets();
}
function loadGroupSets() {
groupSetLoading.value = true;
getOrderGroup({ organizationId: orgId.value, searchKey: groupSetSearchText.value })
.then((res) => {
const data = res?.data || {};
if (groupSetRange.value === 1) {
groupSetList.value = data.personalList || [];
} else if (groupSetRange.value === 2) {
groupSetList.value = data.organizationList || [];
} else {
groupSetList.value = data.hospitalList || [];
}
})
.catch(() => {
console.warn('组套列表加载失败(可能无权限)');
groupSetList.value = [];
})
.finally(() => {
groupSetLoading.value = false;
});
}
function handleGroupSetSelect(row) {
selectedGroupSet.value = row;
}
function applyGroupSet() {
if (!selectedGroupSet.value) {
ElMessage.warning('请先选择一个组套');
return;
}
const detailList = selectedGroupSet.value.detailList;
if (!detailList || detailList.length === 0) {
ElMessage.warning('该组套没有明细项');
return;
}
let successCount = 0;
detailList.forEach((item) => {
const orderDetail = item.orderDetailInfos || {};
const feeItem = {
adviceDefinitionId: item.orderDefinitionId || orderDetail.adviceDefinitionId,
adviceName: orderDetail.adviceName || item.orderDefinitionName || '未知项目',
adviceType: orderDetail.adviceType,
unitPrice: orderDetail.unitPrice,
minUnitPrice: orderDetail.minUnitPrice,
inventoryList: orderDetail.inventoryList || [],
priceList: orderDetail.priceList || [],
partPercent: orderDetail.partPercent || 1,
positionId: item.positionId || orderDetail.positionId,
defaultLotNumber: orderDetail.defaultLotNumber,
unitCode: item.unitCode || orderDetail.unitCode,
unitCode_dictText: item.unitCodeName || orderDetail.unitCode_dictText,
minUnitCode: orderDetail.minUnitCode,
doseUnitCode: orderDetail.doseUnitCode,
categoryCode: orderDetail.categoryCode,
pharmacologyCategoryCode: orderDetail.pharmacologyCategoryCode,
partAttributeEnum: orderDetail.partAttributeEnum,
chargeItemDefinitionId: orderDetail.chargeItemDefinitionId,
adviceTableName: orderDetail.adviceTableName,
methodCode: item.methodCode || orderDetail.methodCode,
rateCode: item.rateCode || orderDetail.rateCode,
dose: item.dose || orderDetail.dose,
doseQuantity: item.doseQuantity,
dispensePerDuration: item.dispensePerDuration || orderDetail.dispensePerDuration,
dosageInstruction: orderDetail.dosageInstruction,
skinTestFlag: orderDetail.skinTestFlag,
injectFlag: orderDetail.injectFlag,
quantity: item.quantity || 1,
chrgitmLv_dictText: orderDetail.chrgitmLv_dictText,
volume: orderDetail.volume,
};
selectChange(feeItem);
successCount++;
});
if (successCount > 0) {
ElMessage.success(`已添加 ${successCount} 项组套费用`);
}
groupSetDialogVisible.value = false;
}
</script>
<style scoped>