497【住院医生工作站-检查申请】检查申请列表缺失“申请单状态”列及全流程闭环状态流转逻辑

523 [住院医生站-临床医嘱] 待保存医嘱总金额显示缺失且编辑态单位选择框变为数字控件
560 [住院医生站-检验申请] “已签发”状态的申请单在操作列缺失“详情”查看按钮
563 [住院医生站-临床医嘱-手术] 打开手术申请单弹窗时出现异常,功能无法使用
This commit is contained in:
Ranyunqiao
2026-05-21 17:06:09 +08:00
parent 8c81c52f4e
commit 966e4f6544
8 changed files with 121 additions and 41 deletions

View File

@@ -31,4 +31,9 @@ public class OrgLocQueryParam implements Serializable {
/** 发放类别 */
private String distributionCategoryCode;
/**
* 项目编码 | 药品:1 耗材:2
*/
private String itemCode;
}

View File

@@ -894,7 +894,6 @@
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
</if>
ORDER BY t1.ID, t1.name ASC, t2.ID ASC
LIMIT #{limit} OFFSET #{offset}
</select>
<!-- 检查/检验项目专用分页查询:仅查指定 category_code + 定价,无库存/草稿库存/取药科室等无关逻辑 -->

View File

@@ -23,7 +23,7 @@
</template>
<script setup lang="ts">
import {computed, nextTick, onMounted, ref} from 'vue';
import {computed, nextTick, ref} from 'vue';
import {throttle} from 'lodash-es';
import Table from '@/components/TableLayout/Table.vue';
import {getAdviceBaseInfo} from './api';
@@ -204,11 +204,6 @@ defineExpose({
handleKeyDown,
refresh,
});
// 组件挂载时自动加载数据el-popover 懒渲染,父组件 refresh 可能因时序问题未生效onMounted 最可靠)
onMounted(() => {
getList();
});
</script>
<style scoped lang="scss">

View File

@@ -127,9 +127,19 @@
<el-button link type="warning" @click="handleWithdraw(scope.row)">撤回</el-button>
</template>
</template>
<template v-if="isReportStatus(scope.row)">
<!-- 报告已出可查看报告 -->
<template v-else-if="isReportStatus(scope.row)">
<el-button link type="success" @click="handleViewReport(scope.row)">查看报告</el-button>
</template>
<!-- 已签发可查看详情可撤回 -->
<template v-else-if="isIssuedStatus(scope.row)">
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
<el-button link type="warning" @click="handleWithdraw(scope.row)">撤回</el-button>
</template>
<!-- 已采证已送检已作废仅查看详情 -->
<template v-else>
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
</template>
</template>
</el-table-column>
</el-table>

View File

@@ -633,11 +633,11 @@ const calculateTotalAmount = () => {
nextTick(() => {
const row = props.row;
const qty = new Decimal(row.doseQuantity || 0);
const isMinUnit = row.unitCode == row.minUnitCode;
const price = isMinUnit ? row.minUnitPrice : row.unitPrice;
// 四舍五入到2位再算与页面显示的单价一致
// 根据首次用量单位类型决定使用哪个单价
const unitType = row.unitCodeList?.find((k) => k.value == row.doseUnitCode)?.type;
const price = unitType == 'unit' ? row.unitPrice : row.minUnitPrice;
const roundedPrice = new Decimal(price || 0).toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
row.totalPrice = qty.mul(roundedPrice).toFixed(6);
row.totalPrice = qty.mul(roundedPrice).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toString();
});
};
const setInputRef = props.handlers.setInputRef;

View File

@@ -910,6 +910,11 @@ function handleFocus(row, index) {
categoryCode = selectedItem ? selectedItem.categoryCode : (row.categoryCode || '');
}
adviceQueryParams.value = { adviceType, categoryCode, searchKey: '' };
// handleFocus 打开 popover 时也要加载数据
const tableRef = Array.isArray(adviceTableRef.value) ? adviceTableRef.value[index] : adviceTableRef.value;
if (tableRef && tableRef.refresh) {
tableRef.refresh(adviceType, categoryCode, '');
}
}
function handleBlur(row) {

View File

@@ -46,7 +46,8 @@
<div style="display: flex; gap: 20px; height: 70vh">
<div
style="
width: 250px;
width: 350px;
min-width: 350px;
border: 1px solid #e4e7ed;
border-radius: 4px;
display: flex;
@@ -70,21 +71,35 @@
<span class="status-dot"></span>
{{ getItemType_Text(item.adviceType) }}
</div>
<div class="item-name">{{ item.adviceName }}</div>
<div class="item-name">
{{
<el-tooltip :content="item.adviceName" placement="top" :show-after="500">
<div class="item-name">{{ item.adviceName }}</div>
</el-tooltip>
<el-tooltip
:content="
item.priceList && item.priceList.length > 0
? (item.priceList[0].price / item.partPercent).toFixed(2) +
'元' +
'/' +
item.minUnitCode_dictText
? (item.priceList[0].price / item.partPercent).toFixed(2) + '元/' + item.minUnitCode_dictText
: ''
}}
</div>
<div class="item-name" v-if="item.adviceType === 2">
库存数量
{{ handleQuantity(item) }}
</div>
"
placement="top"
:show-after="500"
>
<div class="item-name">
{{
item.priceList && item.priceList.length > 0
? (item.priceList[0].price / item.partPercent).toFixed(2) +
'元' +
'/' +
item.minUnitCode_dictText
: ''
}}
</div>
</el-tooltip>
<el-tooltip v-if="item.adviceType === 2" :content="'库存数量:' + handleQuantity(item)" placement="top" :show-after="500">
<div class="item-name">
库存数量
{{ handleQuantity(item) }}
</div>
</el-tooltip>
</div>
<!-- 只显示暂无数据文本 -->
<div
@@ -308,7 +323,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 {getAdviceBaseInfo, getDiseaseTreatmentInitLoc, getOrgList, getOrgLocConfig} from './api.js';
import {getOrderGroup} from '@/views/doctorstation/components/api.js';
import useUserStore from '@/store/modules/user';
@@ -366,6 +381,7 @@ const executeTime = ref('');
const departmentOptions = ref([]);
const AdviceBaseInfoList = ref([]);
const locationOptions = ref([]);
const consumableDefaultLocId = ref(null); // 患者科室耗材默认库房ID来自取药科室配置
const searchText = ref('');
const userId = ref('');
const orgId = ref('');
@@ -471,11 +487,8 @@ onMounted(() => {
const userStore = useUserStore();
userId.value = userStore.id;
orgId.value = userStore.orgId;
console.log(props.patientInfo, 'patientInfo in FeeDialog');
console.log('initialData in FeeDialog');
loadDepartmentOptions();
getAdviceBaseInfos();
getDiseaseInitLoc();
// 数据加载由 watch(visible) 统一触发,避免 patientInfo 未就绪时调用报错
});
// 监听弹窗显示状态
@@ -484,10 +497,12 @@ watch(
(visible) => {
if (visible) {
executeTime.value = formatDateStr(new Date(), 'YYYY-MM-DD HH:mm:ss');
consumableDefaultLocId.value = null; // 重置耗材默认库房,避免复用上次患者配置
// 弹窗打开时按当前患者科室重新加载,避免复用上一次患者/登录科室的结果
loadDepartmentOptions();
getAdviceBaseInfos();
getDiseaseInitLoc(16);
loadConsumableDefaultLoc();
} else {
resetData();
}
@@ -516,7 +531,16 @@ watch(
if (!locs || locs.length === 0) return;
feeItemsList.value.forEach(item => {
if (item.adviceType === 2 && !item.positionId) {
item.positionId = String(locs[0].value);
if (consumableDefaultLocId.value) {
const matched = locs.find(d => String(d.value) === consumableDefaultLocId.value);
if (matched) {
item.positionId = String(matched.value);
} else {
ElMessage.warning(`"${item.adviceName}" 未找到匹配的执行科室,请手动选择`);
}
} else {
ElMessage.warning(`"${item.adviceName}" 所在科室未配置耗材执行科室,请手动选择`);
}
}
});
}
@@ -586,14 +610,33 @@ function getAdviceBaseInfos() {
});
}
function getDiseaseInitLoc() {
getDiseaseTreatmentInitLoc(16)
.then((response) => {
console.log('Disease Treatment Init Loc:', response);
locationOptions.value = response.data.locationOptions;
// 16=药房17=耗材库,合并后作为耗材执行科室下拉选项
Promise.all([
getDiseaseTreatmentInitLoc(16).catch(() => ({ data: { locationOptions: [] } })),
getDiseaseTreatmentInitLoc(17).catch(() => ({ data: { locationOptions: [] } })),
]).then(([pharmacyRes, warehouseRes]) => {
const pharmacies = pharmacyRes.data?.locationOptions || [];
const warehouses = warehouseRes.data?.locationOptions || [];
locationOptions.value = [...pharmacies, ...warehouses];
});
}
/**
* 查询患者科室的耗材默认库房(取药科室配置 itemCode=2
*/
function loadConsumableDefaultLoc() {
const deptId = props.patientInfo?.organizationId;
if (!deptId) {
consumableDefaultLocId.value = null;
return;
}
getOrgLocConfig({ organizationId: deptId, itemCode: '2', pageNo: 1, pageSize: 100 })
.then((res) => {
const records = res.data?.records || [];
consumableDefaultLocId.value = records.length > 0 ? String(records[0].defLocationId) : null;
})
.catch(() => {
console.warn('位置列表加载失败(可能无权限)');
locationOptions.value = [];
consumableDefaultLocId.value = null;
});
}
// 下拉框模糊搜索过滤自定义filter-method配合element-plus filterable使用
@@ -744,8 +787,19 @@ function selectChange(row) {
defaultPositionId = String(departmentOptions.value[0].id);
}
} else if (row.adviceType === 2 && locationOptions.value.length > 0) {
// 耗材:默认取第一个药房/耗材房
defaultPositionId = String(locationOptions.value[0].value);
// 耗材:必须从取药科室配置中匹配默认库房,未配置则提示用户
if (consumableDefaultLocId.value) {
const matched = locationOptions.value.find(
d => String(d.value) === consumableDefaultLocId.value
);
if (matched) {
defaultPositionId = String(matched.value);
} else {
ElMessage.warning(`"${row.adviceName}" 未找到匹配的执行科室,请手动选择`);
}
} else {
ElMessage.warning(`"${row.adviceName}" 所在科室未配置耗材执行科室请手动选择`);
}
}
//插入费用列表
feeItemsList.value.push({
@@ -1023,6 +1077,8 @@ function applyGroupSet() {
font-weight: 600;
color: #303133;
margin-bottom: 8px;
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@@ -111,6 +111,16 @@ export function getDiseaseTreatmentInitLoc(id) {
method: 'get',
});
}
/**
* 查询科室取药配置(耗材默认库房)
*/
export function getOrgLocConfig(params) {
return request({
url: '/base-data-manage/org-loc/org-loc',
method: 'get',
params: params,
});
}
// 住院护士站费用明细
export function getCostDetail(queryParams) {
return request({