Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74ef47fcc0 |
@@ -83,14 +83,9 @@ public class AdviceUtils {
|
|||||||
* @return 提示信息
|
* @return 提示信息
|
||||||
*/
|
*/
|
||||||
public String checkInventory(List<AdviceSaveDto> adviceSaveList) {
|
public String checkInventory(List<AdviceSaveDto> adviceSaveList) {
|
||||||
// 医嘱定义ID集合(过滤null值,避免SQL查询异常)
|
// 医嘱定义ID集合
|
||||||
List<Long> adviceDefinitionIdList
|
List<Long> adviceDefinitionIdList
|
||||||
= adviceSaveList.stream().map(AdviceSaveDto::getAdviceDefinitionId)
|
= adviceSaveList.stream().map(AdviceSaveDto::getAdviceDefinitionId).collect(Collectors.toList());
|
||||||
.filter(id -> id != null).collect(Collectors.toList());
|
|
||||||
// 🔧 Bug #504 修复:如果所有adviceDefinitionId都为null,跳过库存校验
|
|
||||||
if (adviceDefinitionIdList.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// 医嘱库存集合
|
// 医嘱库存集合
|
||||||
List<AdviceInventoryDto> adviceInventoryList
|
List<AdviceInventoryDto> adviceInventoryList
|
||||||
= doctorStationAdviceAppMapper.getAdviceInventory(null, adviceDefinitionIdList,
|
= doctorStationAdviceAppMapper.getAdviceInventory(null, adviceDefinitionIdList,
|
||||||
@@ -104,10 +99,6 @@ public class AdviceUtils {
|
|||||||
= this.subtractInventory(adviceInventoryList, adviceDraftInventoryList);
|
= this.subtractInventory(adviceInventoryList, adviceDraftInventoryList);
|
||||||
// 检查库存
|
// 检查库存
|
||||||
for (AdviceSaveDto saveDto : adviceSaveList) {
|
for (AdviceSaveDto saveDto : adviceSaveList) {
|
||||||
// 🔧 Bug #504 修复:退回医嘱可能adviceDefinitionId为空,跳过校验
|
|
||||||
if (saveDto.getAdviceDefinitionId() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
boolean matched = false;
|
boolean matched = false;
|
||||||
for (AdviceInventoryDto inventoryDto : adviceInventory) {
|
for (AdviceInventoryDto inventoryDto : adviceInventory) {
|
||||||
// 匹配条件:adviceDefinitionId, adviceTableName, locationId, lotNumber 同时相等
|
// 匹配条件:adviceDefinitionId, adviceTableName, locationId, lotNumber 同时相等
|
||||||
@@ -117,12 +108,10 @@ public class AdviceUtils {
|
|||||||
|| saveDto.getLotNumber().equals(inventoryDto.getLotNumber());
|
|| saveDto.getLotNumber().equals(inventoryDto.getLotNumber());
|
||||||
boolean tableNameMatch = StringUtils.isEmpty(saveDto.getAdviceTableName())
|
boolean tableNameMatch = StringUtils.isEmpty(saveDto.getAdviceTableName())
|
||||||
|| inventoryDto.getItemTable().equals(saveDto.getAdviceTableName());
|
|| inventoryDto.getItemTable().equals(saveDto.getAdviceTableName());
|
||||||
// 🔧 Bug #504 修复:退回医嘱可能locationId为空,跳过location匹配
|
// if (saveDto.)
|
||||||
boolean locationMatch = saveDto.getLocationId() == null
|
|
||||||
|| inventoryDto.getLocationId().equals(saveDto.getLocationId());
|
|
||||||
if (inventoryDto.getItemId().equals(saveDto.getAdviceDefinitionId())
|
if (inventoryDto.getItemId().equals(saveDto.getAdviceDefinitionId())
|
||||||
&& tableNameMatch
|
&& tableNameMatch
|
||||||
&& locationMatch && lotNumberMatch) {
|
&& inventoryDto.getLocationId().equals(saveDto.getLocationId()) && lotNumberMatch) {
|
||||||
matched = true;
|
matched = true;
|
||||||
// 检查库存是否充足
|
// 检查库存是否充足
|
||||||
BigDecimal minUnitQuantity = saveDto.getMinUnitQuantity();
|
BigDecimal minUnitQuantity = saveDto.getMinUnitQuantity();
|
||||||
|
|||||||
@@ -206,8 +206,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
e.setTherapyEnum_enumText(EnumUtils.getInfoByValue(TherapyTimeType.class, e.getTherapyEnum()));
|
e.setTherapyEnum_enumText(EnumUtils.getInfoByValue(TherapyTimeType.class, e.getTherapyEnum()));
|
||||||
// 请求状态
|
// 请求状态
|
||||||
e.setRequestStatus_enumText(EnumUtils.getInfoByValue(RequestStatus.class, e.getRequestStatus()));
|
e.setRequestStatus_enumText(EnumUtils.getInfoByValue(RequestStatus.class, e.getRequestStatus()));
|
||||||
// 发药状态
|
|
||||||
e.setDispenseStatus_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, e.getDispenseStatus()));
|
|
||||||
// 性别枚举
|
// 性别枚举
|
||||||
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
|
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
|
||||||
// 计算年龄
|
// 计算年龄
|
||||||
@@ -358,17 +356,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
medRequestList.add(item);
|
medRequestList.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 校验药品医嘱是否已发药,已发药的医嘱不允许退回
|
|
||||||
if (!medRequestList.isEmpty()) {
|
|
||||||
List<Long> medReqIds = medRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
|
||||||
List<MedicationDispense> dispenseList = medicationDispenseService.list(
|
|
||||||
new LambdaQueryWrapper<MedicationDispense>()
|
|
||||||
.in(MedicationDispense::getMedReqId, medReqIds)
|
|
||||||
.eq(MedicationDispense::getStatusEnum, DispenseStatus.COMPLETED.getValue()));
|
|
||||||
if (!dispenseList.isEmpty()) {
|
|
||||||
return R.fail("该医嘱已发药,无法退回");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||||
Date checkDate = new Date();
|
Date checkDate = new Date();
|
||||||
if (!serviceRequestList.isEmpty()) {
|
if (!serviceRequestList.isEmpty()) {
|
||||||
|
|||||||
@@ -255,8 +255,4 @@ public class InpatientAdviceDto {
|
|||||||
|
|
||||||
/** 总价 */
|
/** 总价 */
|
||||||
private BigDecimal totalPrice;
|
private BigDecimal totalPrice;
|
||||||
|
|
||||||
/** 发药状态 */
|
|
||||||
private Integer dispenseStatus;
|
|
||||||
private String dispenseStatus_enumText;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,8 +153,7 @@
|
|||||||
ii.balance_amount AS balance_amount,
|
ii.balance_amount AS balance_amount,
|
||||||
ii.account_id AS account_id,
|
ii.account_id AS account_id,
|
||||||
ii.performer_check_id,
|
ii.performer_check_id,
|
||||||
ii.category_code,
|
ii.category_code
|
||||||
ii.dispense_status
|
|
||||||
FROM (( SELECT T1.encounter_id,
|
FROM (( SELECT T1.encounter_id,
|
||||||
T1.tenant_id,
|
T1.tenant_id,
|
||||||
#{medMedicationRequest} AS advice_table,
|
#{medMedicationRequest} AS advice_table,
|
||||||
@@ -198,8 +197,7 @@
|
|||||||
pra."name" AS admitting_doctor_name,
|
pra."name" AS admitting_doctor_name,
|
||||||
personal_account.balance_amount,
|
personal_account.balance_amount,
|
||||||
personal_account.id AS account_id,
|
personal_account.id AS account_id,
|
||||||
T2.category_code,
|
T2.category_code
|
||||||
mmd.status_enum AS dispense_status
|
|
||||||
FROM med_medication_request AS T1
|
FROM med_medication_request AS T1
|
||||||
LEFT JOIN med_medication_definition AS T2
|
LEFT JOIN med_medication_definition AS T2
|
||||||
ON T2.id = T1.medication_id
|
ON T2.id = T1.medication_id
|
||||||
@@ -280,9 +278,6 @@
|
|||||||
aa.balance_amount
|
aa.balance_amount
|
||||||
) AS personal_account
|
) AS personal_account
|
||||||
ON personal_account.encounter_id = ae.id
|
ON personal_account.encounter_id = ae.id
|
||||||
LEFT JOIN med_medication_dispense mmd
|
|
||||||
ON mmd.med_req_id = T1.id
|
|
||||||
AND mmd.delete_flag = '0'
|
|
||||||
WHERE T1.delete_flag = '0'
|
WHERE T1.delete_flag = '0'
|
||||||
AND T1.refund_medicine_id IS NULL
|
AND T1.refund_medicine_id IS NULL
|
||||||
AND T1.generate_source_enum = #{doctorPrescription}
|
AND T1.generate_source_enum = #{doctorPrescription}
|
||||||
@@ -336,8 +331,7 @@
|
|||||||
pra."name" AS admitting_doctor_name,
|
pra."name" AS admitting_doctor_name,
|
||||||
personal_account.balance_amount,
|
personal_account.balance_amount,
|
||||||
personal_account.id AS account_id,
|
personal_account.id AS account_id,
|
||||||
T2.category_code,
|
T2.category_code
|
||||||
NULL AS dispense_status
|
|
||||||
FROM wor_service_request AS T1
|
FROM wor_service_request AS T1
|
||||||
LEFT JOIN wor_activity_definition AS T2
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
ON T2.id = T1.activity_id
|
ON T2.id = T1.activity_id
|
||||||
|
|||||||
@@ -96,17 +96,23 @@
|
|||||||
INNER JOIN med_medication_request AS T5
|
INNER JOIN med_medication_request AS T5
|
||||||
ON T4.med_req_id = T5.id
|
ON T4.med_req_id = T5.id
|
||||||
AND T5.delete_flag = '0'
|
AND T5.delete_flag = '0'
|
||||||
WHERE <if test="statusEnum == null">
|
WHERE EXISTS (
|
||||||
T4.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared})
|
SELECT 1 FROM wor_supply_request wsr
|
||||||
</if>
|
WHERE wsr.type_enum = 3
|
||||||
<if test="statusEnum == 3">
|
AND wsr.delete_flag = '0'
|
||||||
T4.status_enum IN (#{inProgress},#{preparation},#{prepared})
|
AND wsr.bus_no = T4.summary_no
|
||||||
</if>
|
|
||||||
<if test="statusEnum == 4">
|
|
||||||
T4.status_enum = #{completed}
|
|
||||||
</if>
|
|
||||||
AND T4.summary_no IS NOT NULL
|
AND T4.summary_no IS NOT NULL
|
||||||
AND T4.summary_no != ''
|
AND T4.summary_no != ''
|
||||||
|
)
|
||||||
|
AND <if test="statusEnum == null">
|
||||||
|
T4.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared},8)
|
||||||
|
</if>
|
||||||
|
<if test="statusEnum == 3">
|
||||||
|
T4.status_enum IN (#{inProgress},#{preparation},#{prepared},8)
|
||||||
|
</if>
|
||||||
|
<if test="statusEnum == 4">
|
||||||
|
T4.status_enum IN (#{completed},8)
|
||||||
|
</if>
|
||||||
) AS ii
|
) AS ii
|
||||||
${ew.customSqlSegment}
|
${ew.customSqlSegment}
|
||||||
GROUP BY ii.encounter_id,
|
GROUP BY ii.encounter_id,
|
||||||
@@ -265,8 +271,6 @@
|
|||||||
AND T15.delete_flag = '0'
|
AND T15.delete_flag = '0'
|
||||||
WHERE T1.delete_flag = '0'
|
WHERE T1.delete_flag = '0'
|
||||||
-- 因发药配药合并,前台只能看到待发药,已发药状态,但是后台配药发药状态都查
|
-- 因发药配药合并,前台只能看到待发药,已发药状态,但是后台配药发药状态都查
|
||||||
AND T1.summary_no IS NOT NULL
|
|
||||||
AND T1.summary_no != ''
|
|
||||||
AND
|
AND
|
||||||
<if test="dispenseStatus == null">
|
<if test="dispenseStatus == null">
|
||||||
T1.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared})
|
T1.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared})
|
||||||
|
|||||||
@@ -216,8 +216,7 @@
|
|||||||
ccd.name AS condition_definition_name,
|
ccd.name AS condition_definition_name,
|
||||||
T1.therapy_enum AS therapyEnum,
|
T1.therapy_enum AS therapyEnum,
|
||||||
T1.sort_number AS sort_number,
|
T1.sort_number AS sort_number,
|
||||||
T1.based_on_id AS based_on_id,
|
T1.based_on_id AS based_on_id
|
||||||
T1.medication_id AS advice_definition_id
|
|
||||||
FROM med_medication_request AS T1
|
FROM med_medication_request AS T1
|
||||||
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||||
AND T2.delete_flag = '0'
|
AND T2.delete_flag = '0'
|
||||||
@@ -269,8 +268,7 @@
|
|||||||
'' AS condition_definition_name,
|
'' AS condition_definition_name,
|
||||||
2 AS therapyEnum,
|
2 AS therapyEnum,
|
||||||
99 AS sort_number,
|
99 AS sort_number,
|
||||||
T1.based_on_id AS based_on_id,
|
T1.based_on_id AS based_on_id
|
||||||
T1.device_def_id AS advice_definition_id
|
|
||||||
FROM wor_device_request AS T1
|
FROM wor_device_request AS T1
|
||||||
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
||||||
AND T2.delete_flag = '0'
|
AND T2.delete_flag = '0'
|
||||||
@@ -319,8 +317,7 @@
|
|||||||
'' AS condition_definition_name,
|
'' AS condition_definition_name,
|
||||||
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
||||||
99 AS sort_number,
|
99 AS sort_number,
|
||||||
T1.based_on_id AS based_on_id,
|
T1.based_on_id AS based_on_id
|
||||||
T1.activity_id AS advice_definition_id
|
|
||||||
FROM wor_service_request AS T1
|
FROM wor_service_request AS T1
|
||||||
LEFT JOIN wor_activity_definition AS T2
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
ON T2.ID = T1.activity_id
|
ON T2.ID = T1.activity_id
|
||||||
|
|||||||
@@ -314,7 +314,6 @@
|
|||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<span class="cat-title">{{ cat.categoryName }}</span>
|
<span class="cat-title">{{ cat.categoryName }}</span>
|
||||||
<span v-if="categoryLoadingSet.has(cat.typeId)" class="loading-dot"></span>
|
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
v-for="item in cat.items"
|
v-for="item in cat.items"
|
||||||
@@ -330,9 +329,6 @@
|
|||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
<span class="item-price">¥{{ item.price }}/{{ item.unit || "次" }}</span>
|
<span class="item-price">¥{{ item.price }}/{{ item.unit || "次" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="categoryLoadingSet.has(cat.typeId)" class="category-loading-hint">
|
|
||||||
加载中...
|
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</div>
|
</div>
|
||||||
@@ -521,7 +517,6 @@ const rules = {
|
|||||||
const categoryList = ref([]); // 原始分类+项目数据
|
const categoryList = ref([]); // 原始分类+项目数据
|
||||||
const dictSearchKey = ref('');
|
const dictSearchKey = ref('');
|
||||||
const activeNames = ref(''); // 当前展开的折叠项
|
const activeNames = ref(''); // 当前展开的折叠项
|
||||||
const categoryLoadingSet = ref(new Set()); // Bug #500: 正在加载方法的分类集合
|
|
||||||
|
|
||||||
const allMethods = ref([]);
|
const allMethods = ref([]);
|
||||||
|
|
||||||
@@ -637,14 +632,9 @@ const availableMethods = computed(() => {
|
|||||||
|
|
||||||
// 当可选方法列表改变时,如果当前选中的方法不在新列表中,则清空
|
// 当可选方法列表改变时,如果当前选中的方法不在新列表中,则清空
|
||||||
// #428: 分类展开时联动加载检查方法
|
// #428: 分类展开时联动加载检查方法
|
||||||
// Bug #500: 使用 categoryLoadingSet 替代 dictLoading,避免切换分类时整个区域闪烁
|
|
||||||
async function handleCategoryExpand(cat) {
|
async function handleCategoryExpand(cat) {
|
||||||
if (!cat || !cat.typeName) return;
|
if (!cat || !cat.typeName) return;
|
||||||
|
|
||||||
// 如果已加载过或正在加载中,跳过
|
|
||||||
if ((cat.methods && cat.methods.length > 0) || categoryLoadingSet.value.has(cat.typeId)) return;
|
|
||||||
|
|
||||||
categoryLoadingSet.value.add(cat.typeId);
|
|
||||||
try {
|
try {
|
||||||
const res = await searchCheckMethod({ checkType: cat.typeName });
|
const res = await searchCheckMethod({ checkType: cat.typeName });
|
||||||
let data = res?.data?.data || res?.data || res?.rows || res;
|
let data = res?.data?.data || res?.data || res?.rows || res;
|
||||||
@@ -665,16 +655,14 @@ async function handleCategoryExpand(cat) {
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载分类检查方法失败', err);
|
console.error('加载分类检查方法失败', err);
|
||||||
} finally {
|
|
||||||
categoryLoadingSet.value.delete(cat.typeId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bug #500: 改为非 async 函数,避免 el-collapse 的 @change 等待异步完成导致抖动
|
async function handleCollapseChange(activeName) {
|
||||||
function handleCollapseChange(activeName) {
|
// 当折叠面板展开时,加载对应分类的检查方法
|
||||||
if (activeName) {
|
if (activeName) {
|
||||||
const cat = filteredCategoryList.value.find(c => c.typeId == activeName);
|
const cat = filteredCategoryList.value.find(c => c.typeId == activeName);
|
||||||
if (cat && (!cat.methods || cat.methods.length === 0)) {
|
if (cat && (!cat.methods || cat.methods.length === 0)) {
|
||||||
handleCategoryExpand(cat); // 异步加载,不 await
|
await handleCategoryExpand(cat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1321,20 +1309,6 @@ defineExpose({ getList });
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
}
|
}
|
||||||
/* Bug #500: 分类加载中的小圆点动画 */
|
|
||||||
.loading-dot {
|
|
||||||
display: inline-block;
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #409eff;
|
|
||||||
margin-left: 6px;
|
|
||||||
animation: dotPulse 1s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
@keyframes dotPulse {
|
|
||||||
0%, 100% { opacity: 0.3; transform: scale(0.8); }
|
|
||||||
50% { opacity: 1; transform: scale(1.2); }
|
|
||||||
}
|
|
||||||
.item-row {
|
.item-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1474,24 +1448,10 @@ defineExpose({ getList });
|
|||||||
height: auto;
|
height: auto;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
/* Bug #500: 折叠内容添加平滑过渡动画,避免切换时高度跳变 */
|
|
||||||
:deep(.el-collapse-item__content) {
|
:deep(.el-collapse-item__content) {
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
}
|
||||||
/* Bug #500: 折叠面板展开/收起动画使用 will-change 优化性能 */
|
|
||||||
:deep(.el-collapse-item__wrap) {
|
:deep(.el-collapse-item__wrap) {
|
||||||
border: none;
|
border: none;
|
||||||
will-change: height;
|
|
||||||
}
|
|
||||||
:deep(.el-collapse-item) {
|
|
||||||
transition: margin 0.2s ease;
|
|
||||||
}
|
|
||||||
/* Bug #500: 分类加载中提示样式 */
|
|
||||||
.category-loading-hint {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="primary" @click="openGroupSetDialog">划价组套</el-button>
|
<el-button type="primary">划价组套</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 弹窗内容 - 左右布局 -->
|
<!-- 弹窗内容 - 左右布局 -->
|
||||||
<div style="display: flex; gap: 20px; height: 70vh">
|
<div style="display: flex; gap: 20px; height: 70vh">
|
||||||
@@ -147,7 +147,6 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.selectUnitCode"
|
v-model="scope.row.selectUnitCode"
|
||||||
placeholder="单位"
|
placeholder="单位"
|
||||||
filterable
|
|
||||||
style="width: 100px"
|
style="width: 100px"
|
||||||
@change="unitCodeChange(scope.row)"
|
@change="unitCodeChange(scope.row)"
|
||||||
>
|
>
|
||||||
@@ -172,13 +171,12 @@
|
|||||||
v-if="scope.row.adviceType == 3"
|
v-if="scope.row.adviceType == 3"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:filter-method="(val) => filterOptions(val, scope.row, 'departmentOptions')"
|
|
||||||
v-model="scope.row.positionId"
|
v-model="scope.row.positionId"
|
||||||
placeholder="选择科室"
|
placeholder="选择科室"
|
||||||
style="width: 220px"
|
style="width: 220px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dept in getFilteredOptions(scope.row, 'departmentOptions')"
|
v-for="dept in departmentOptions"
|
||||||
:key="dept.id"
|
:key="dept.id"
|
||||||
:label="dept.name"
|
:label="dept.name"
|
||||||
:value="dept.id"
|
:value="dept.id"
|
||||||
@@ -188,13 +186,12 @@
|
|||||||
v-if="scope.row.adviceType == 2"
|
v-if="scope.row.adviceType == 2"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:filter-method="(val) => filterOptions(val, scope.row, 'locationOptions')"
|
|
||||||
v-model="scope.row.positionId"
|
v-model="scope.row.positionId"
|
||||||
placeholder="选择药房/耗材房"
|
placeholder="选择药房/耗材房"
|
||||||
style="width: 220px"
|
style="width: 220px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dept in getFilteredOptions(scope.row, 'locationOptions')"
|
v-for="dept in locationOptions"
|
||||||
:key="dept.value"
|
:key="dept.value"
|
||||||
:label="dept.label"
|
:label="dept.label"
|
||||||
:value="dept.value"
|
:value="dept.value"
|
||||||
@@ -250,49 +247,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 划价组套选择对话框 -->
|
|
||||||
<el-dialog v-model="groupSetDialogVisible" title="划价组套选择" width="600px" :close-on-click-modal="false" append-to-body>
|
|
||||||
<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>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -300,7 +254,6 @@ import {computed, getCurrentInstance, onMounted, reactive, ref, watch} from 'vue
|
|||||||
import {ElMessage} from 'element-plus';
|
import {ElMessage} from 'element-plus';
|
||||||
import {formatDateStr} from '@/utils/index';
|
import {formatDateStr} from '@/utils/index';
|
||||||
import {getAdviceBaseInfo, getDiseaseTreatmentInitLoc, getOrgList} from './api.js';
|
import {getAdviceBaseInfo, getDiseaseTreatmentInitLoc, getOrgList} from './api.js';
|
||||||
import {getOrderGroup} from '@/views/doctorstation/components/api.js';
|
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
@@ -359,8 +312,6 @@ const locationOptions = ref([]);
|
|||||||
const searchText = ref('');
|
const searchText = ref('');
|
||||||
const userId = ref('');
|
const userId = ref('');
|
||||||
const orgId = ref('');
|
const orgId = ref('');
|
||||||
// 下拉框模糊搜索关键字(按行存储)
|
|
||||||
const filterKeywords = ref({});
|
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
@@ -438,14 +389,6 @@ const submitData = reactive({
|
|||||||
});
|
});
|
||||||
const adviceLoading = ref(false);
|
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(() => {
|
const totalAmount = computed(() => {
|
||||||
return feeItemsList.value.reduce((sum, item) => {
|
return feeItemsList.value.reduce((sum, item) => {
|
||||||
@@ -509,25 +452,6 @@ function getDiseaseInitLoc() {
|
|||||||
locationOptions.value = response.data.locationOptions;
|
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) {
|
function getItemType_Text(type) {
|
||||||
const map = { 2: '耗材', 3: '诊疗' };
|
const map = { 2: '耗材', 3: '诊疗' };
|
||||||
@@ -603,24 +527,14 @@ function selectChange(row) {
|
|||||||
const price = row.priceList?.[0]?.price || 0;
|
const price = row.priceList?.[0]?.price || 0;
|
||||||
//获取大小单位
|
//获取大小单位
|
||||||
const uniqueUnitCodes = getUnitCodeOptions(row);
|
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({
|
feeItemsList.value.push({
|
||||||
...row,
|
...row,
|
||||||
uniqueUnitCodes: uniqueUnitCodes,
|
uniqueUnitCodes: uniqueUnitCodes,
|
||||||
unitPrice: (price / (row.partPercent || 1)).toFixed(6), // 根据拆零比计算单价
|
unitPrice: (price / (row.partPercent || 1)).toFixed(6), // 根据拆零比计算单价
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
positionId: defaultPositionId, // 默认执行科室/位置
|
// positionId: row.positionId === null || row.positionId === undefined ? orgId : row.positionId, // 默认执行科室
|
||||||
selectUnitCode: String(row.minUnitCode || ''), // 默认选择小单位,确保字符串类型
|
selectUnitCode: row.minUnitCode, // 默认选择小单位
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,94 +648,6 @@ function resetData() {
|
|||||||
searchText.value = '';
|
searchText.value = '';
|
||||||
executeTime.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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -67,9 +67,6 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
style="padding: 10px; background-color: #eef9fd; height: 100%; overflow-y: auto"
|
style="padding: 10px; background-color: #eef9fd; height: 100%; overflow-y: auto"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
@@ -500,15 +497,8 @@ function handleCancel() {
|
|||||||
let list = getSelectRows();
|
let list = getSelectRows();
|
||||||
let producerIds = [];
|
let producerIds = [];
|
||||||
list.forEach((item) => {
|
list.forEach((item) => {
|
||||||
// 从 exePerformRecordList 直接提取 procedureId,确保取消执行时数据完整
|
|
||||||
const procedureIds = (item.exePerformRecordList || []).map((record) => record.procedureId);
|
|
||||||
if (procedureIds.length === 0 && (!item.procedureIds || item.procedureIds.length === 0)) {
|
|
||||||
proxy.$modal.msgError('请选择已执行的医嘱记录');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const ids = procedureIds.length > 0 ? procedureIds : item.procedureIds;
|
|
||||||
producerIds.push(
|
producerIds.push(
|
||||||
...ids.map((value) => {
|
...item.procedureIds.map((value) => {
|
||||||
return {
|
return {
|
||||||
procedureId: value,
|
procedureId: value,
|
||||||
therapyEnum: item.therapyEnum,
|
therapyEnum: item.therapyEnum,
|
||||||
@@ -516,9 +506,6 @@ function handleCancel() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if (producerIds.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => {
|
adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg || '取消执行成功');
|
proxy.$modal.msgSuccess(res.msg || '取消执行成功');
|
||||||
|
|||||||
@@ -288,12 +288,6 @@ function handleCheck() {
|
|||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
let list = getSelectRows();
|
let list = getSelectRows();
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
// 校验已发药的医嘱不允许退回
|
|
||||||
let dispensedItems = list.filter(item => item.dispenseStatus === 4);
|
|
||||||
if (dispensedItems.length > 0) {
|
|
||||||
proxy.$message.error('该医嘱已发药,无法退回');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cancel(list).then((res) => {
|
cancel(list).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg);
|
proxy.$modal.msgSuccess(res.msg);
|
||||||
|
|||||||
Reference in New Issue
Block a user