fix(medical-order): 解决医嘱编辑界面显示和验证问题 BUG#250,145

- 修复医嘱集合对话框中的条件判断逻辑,统一新增行的显示规则
- 更新医嘱集合对话框中剂量、给药途径、频次、天数等字段的显示逻辑
- 为西药类医嘱添加必填字段验证功能,包括剂量、给药途径、频次等
- 优化处方列表组件中编辑状态下的输入控件显示
- 修复处方详情数据合并逻辑,确保正确的字段优先级处理
- 解决多个库存管理模块中API请求数据格式错误的问题
- 修复医嘱库信息保存和数据回填的相关问题
This commit is contained in:
2026-03-23 15:46:30 +08:00
parent 316c1478fc
commit b5cf685b13
10 changed files with 144 additions and 46 deletions

View File

@@ -138,9 +138,9 @@
<el-table-column label="单次剂量" align="center" width="250" prop="sortNumber"> <el-table-column label="单次剂量" align="center" width="250" prop="sortNumber">
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.adviceType == 1"> <template v-if="!scope.row.groupPackageId">
<!-- 新增/未保存行统一按数量 + 单位 = 剂量 + 单位展示 --> <template v-if="scope.row.adviceType == 1 || !scope.row.adviceDefinitionId">
<template v-if="!scope.row.groupPackageId"> <!-- 新增/未保存行统一按"数量 + 单位 = 剂量 + 单位"展示 -->
<el-input <el-input
style="width: 70px; margin-right: 10px" style="width: 70px; margin-right: 10px"
v-model="scope.row.doseQuantity" v-model="scope.row.doseQuantity"
@@ -177,16 +177,19 @@
}} }}
</span> </span>
</template> </template>
<span v-else>{{ scope.row.dose }}</span> <span v-else>-</span>
</template>
<template v-else>
<span v-if="scope.row.adviceType == 1">{{ scope.row.dose }}</span>
<span v-else>-</span>
</template> </template>
<span v-else>{{ '-' }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="给药途径" align="center" width="150" prop="sortNumber"> <el-table-column label="给药途径" align="center" width="150" prop="sortNumber">
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.adviceType == 1"> <template v-if="!scope.row.groupPackageId">
<template v-if="!scope.row.groupPackageId"> <template v-if="scope.row.adviceType == 1 || !scope.row.adviceDefinitionId">
<el-select v-model="scope.row.methodCode" placeholder="给药途径" clearable filterable> <el-select v-model="scope.row.methodCode" placeholder="给药途径" clearable filterable>
<el-option <el-option
v-for="dict in method_code" v-for="dict in method_code"
@@ -196,16 +199,19 @@
/> />
</el-select> </el-select>
</template> </template>
<span v-else>{{ scope.row.methodCode }}</span> <span v-else>-</span>
</template>
<template v-else>
<span v-if="scope.row.adviceType == 1">{{ scope.row.methodCode_dictText || scope.row.methodCode }}</span>
<span v-else>-</span>
</template> </template>
<span v-else>{{ '-' }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="用药频次" align="center" width="150" prop="sortNumber"> <el-table-column label="用药频次" align="center" width="150" prop="sortNumber">
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.adviceType == 1"> <template v-if="!scope.row.groupPackageId">
<template v-if="!scope.row.groupPackageId"> <template v-if="scope.row.adviceType == 1 || !scope.row.adviceDefinitionId">
<el-select <el-select
v-model="scope.row.rateCode" v-model="scope.row.rateCode"
placeholder="频次" placeholder="频次"
@@ -220,24 +226,30 @@
/> />
</el-select> </el-select>
</template> </template>
<span v-else>{{ scope.row.rateCode_dictText }}</span> <span v-else>-</span>
</template>
<template v-else>
<span v-if="scope.row.adviceType == 1">{{ scope.row.rateCode_dictText }}</span>
<span v-else>-</span>
</template> </template>
<span v-else>{{ '-' }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="用药天数" align="center" width="100" prop="sortNumber"> <el-table-column label="用药天数" align="center" width="100" prop="sortNumber">
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.adviceType == 1"> <template v-if="!scope.row.groupPackageId">
<template v-if="!scope.row.groupPackageId"> <template v-if="scope.row.adviceType == 1 || !scope.row.adviceDefinitionId">
<el-input <el-input
v-model="scope.row.dispensePerDuration" v-model="scope.row.dispensePerDuration"
@change="handleQuantityChange(scope.row)" @change="handleQuantityChange(scope.row)"
/> />
</template> </template>
<span v-else>{{ scope.row.dispensePerDuration }}</span> <span v-else>-</span>
</template>
<template v-else>
<span v-if="scope.row.adviceType == 1">{{ scope.row.dispensePerDuration }}</span>
<span v-else>-</span>
</template> </template>
<span v-else>{{ '-' }}</span>
</template> </template>
</el-table-column> </el-table-column>
@@ -700,6 +712,35 @@ function submitForm() {
return; return;
} }
// 验证西药类医嘱的必填字段
const westernMedicineRows = detailList.filter((item) => item.adviceType == 1);
for (const row of westernMedicineRows) {
if (!row.dose && row.dose !== 0) {
proxy?.$modal?.msgWarning?.('单次剂量为必填项');
return;
}
if (!row.methodCode) {
proxy?.$modal?.msgWarning?.('给药途径为必填项');
return;
}
if (!row.rateCode) {
proxy?.$modal?.msgWarning?.('用药频次为必填项');
return;
}
if (!row.dispensePerDuration && row.dispensePerDuration !== 0) {
proxy?.$modal?.msgWarning?.('用药天数为必填项');
return;
}
if (!row.sortNumber && row.sortNumber !== 0) {
proxy?.$modal?.msgWarning?.('总量/执行次数为必填项');
return;
}
if (!row.selectUnitCode) {
proxy?.$modal?.msgWarning?.('单位为必填项');
return;
}
}
submitLoading.value = true; submitLoading.value = true;
setTimeout(() => { setTimeout(() => {
console.log('[submitForm] 当前tab:', currentTab.value); console.log('[submitForm] 当前tab:', currentTab.value);

View File

@@ -648,21 +648,49 @@
</el-table-column> </el-table-column>
<el-table-column label="单次剂量" align="center" prop=""> <el-table-column label="单次剂量" align="center" prop="">
<template #default="scope"> <template #default="scope">
<span v-if="!scope.row.isEdit"> <template v-if="scope.row.isEdit">
<el-input-number
v-model="scope.row.dose"
:min="0"
:precision="2"
:controls="false"
style="width: 70px"
size="small"
/>
<span style="margin-left: 4px">{{ scope.row.doseUnitCode_dictText }}</span>
</template>
<span v-else>
{{ scope.row.dose ? scope.row.dose + ' ' + scope.row.doseUnitCode_dictText : '' }} {{ scope.row.dose ? scope.row.dose + ' ' + scope.row.doseUnitCode_dictText : '' }}
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="总量" align="center" prop=""> <el-table-column label="总量" align="center" prop="">
<template #default="scope"> <template #default="scope">
<span v-if="!scope.row.isEdit"> <template v-if="scope.row.isEdit">
<el-input-number
v-model="scope.row.quantity"
:min="1"
:precision="0"
:controls="false"
style="width: 60px"
size="small"
/>
<span style="margin-left: 4px">{{ scope.row.unitCode_dictText }}</span>
</template>
<span v-else>
{{ scope.row.quantity ? scope.row.quantity + ' ' + scope.row.unitCode_dictText : '' }} {{ scope.row.quantity ? scope.row.quantity + ' ' + scope.row.unitCode_dictText : '' }}
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="总金额" align="right" prop="" header-align="center" width="100"> <el-table-column label="总金额" align="right" prop="" header-align="center" width="100">
<template #default="scope"> <template #default="scope">
<span v-if="!scope.row.isEdit" style="text-align: right"> <template v-if="scope.row.isEdit">
<span style="text-align: right; color: var(--el-color-primary); font-weight: bold;">
{{ (scope.row.totalPrice !== undefined && scope.row.totalPrice !== null && !isNaN(scope.row.totalPrice) &&
isFinite(scope.row.totalPrice)) ? Number(scope.row.totalPrice).toFixed(2) : '0.00' }} 元
</span>
</template>
<span v-else style="text-align: right">
{{ (scope.row.totalPrice !== undefined && scope.row.totalPrice !== null && !isNaN(scope.row.totalPrice) && {{ (scope.row.totalPrice !== undefined && scope.row.totalPrice !== null && !isNaN(scope.row.totalPrice) &&
isFinite(scope.row.totalPrice)) ? Number(scope.row.totalPrice).toFixed(2) + ' 元' : '-' }} isFinite(scope.row.totalPrice)) ? Number(scope.row.totalPrice).toFixed(2) + ' 元' : '-' }}
</span> </span>
@@ -670,14 +698,34 @@
</el-table-column> </el-table-column>
<el-table-column label="药房/科室" align="center" prop="" width="200"> <el-table-column label="药房/科室" align="center" prop="" width="200">
<template #default="scope"> <template #default="scope">
<span v-if="!scope.row.isEdit"> <template v-if="scope.row.isEdit">
<span style="color: var(--el-text-color-secondary);">{{ scope.row.positionName || '请选择药房' }}</span>
</template>
<span v-else>
{{ scope.row.positionName }} {{ scope.row.positionName }}
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="频次/用法" align="center" prop="" width="180"> <el-table-column label="频次/用法" align="center" prop="" width="180">
<template #default="scope"> <template #default="scope">
<span v-if="!scope.row.isEdit && scope.row.adviceType == 1" style="text-align: right"> <template v-if="scope.row.isEdit && scope.row.adviceType == 1">
<el-select v-model="scope.row.rateCode" size="small" style="width: 65px" placeholder="频次">
<el-option v-for="item in rate_code" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-input-number
v-model="scope.row.dispensePerDuration"
:min="1"
:precision="0"
:controls="false"
style="width: 45px; margin-left: 2px"
size="small"
/>
<span style="margin: 0 2px; font-size: 12px;">天</span>
<el-select v-model="scope.row.methodCode" size="small" style="width: 65px" placeholder="用法">
<el-option v-for="item in method_code" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
<span v-else-if="scope.row.adviceType == 1" style="text-align: right">
{{ {{
scope.row.rateCode_dictText scope.row.rateCode_dictText
? scope.row.rateCode_dictText + ? scope.row.rateCode_dictText +
@@ -3041,25 +3089,29 @@ function handleSaveGroup(orderGroupList) {
// 🔥 新版组件已经预处理了数据,优先使用 mergedDetail // 🔥 新版组件已经预处理了数据,优先使用 mergedDetail
// 如果没有 mergedDetail则回退到旧版处理逻辑 // 如果没有 mergedDetail则回退到旧版处理逻辑
const mergedDetail = item.mergedDetail || { const mergedDetail = item.mergedDetail || {
// 医嘱库基础信息 // 医嘱库基础信息(作为默认值)
...(item.orderDetailInfos || {}), ...(item.orderDetailInfos || {}),
// 组套级别字段 // 组套级别字段(优先级更高,覆盖医嘱库字段)
adviceName: item.orderDetailInfos?.adviceName || item.orderDefinitionName || '未知项目', adviceName: item.orderDefinitionName || item.orderDetailInfos?.adviceName || '未知项目',
adviceType: item.orderDetailInfos?.adviceType, adviceType: item.adviceType || item.orderDetailInfos?.adviceType,
adviceDefinitionId: item.orderDefinitionId || item.orderDetailInfos?.adviceDefinitionId, adviceDefinitionId: item.orderDefinitionId || item.orderDetailInfos?.adviceDefinitionId,
quantity: item.quantity, quantity: item.quantity,
unitCode: item.unitCode || item.orderDetailInfos?.unitCode, unitCode: item.unitCode || item.orderDetailInfos?.unitCode,
unitCodeName: item.unitCodeName, unitCodeName: item.unitCodeName || item.orderDetailInfos?.unitCode_dictText,
dose: item.dose || item.orderDetailInfos?.dose, dose: item.dose !== undefined && item.dose !== null ? item.dose : item.orderDetailInfos?.dose,
rateCode: item.rateCode || item.orderDetailInfos?.rateCode, rateCode: item.rateCode || item.orderDetailInfos?.rateCode,
methodCode: item.methodCode || item.orderDetailInfos?.methodCode, methodCode: item.methodCode || item.orderDetailInfos?.methodCode,
dispensePerDuration: item.dispensePerDuration || item.orderDetailInfos?.dispensePerDuration, dispensePerDuration: item.dispensePerDuration !== undefined && item.dispensePerDuration !== null
doseQuantity: item.doseQuantity, ? item.dispensePerDuration
: item.orderDetailInfos?.dispensePerDuration,
doseQuantity: item.doseQuantity !== undefined && item.doseQuantity !== null
? item.doseQuantity
: item.orderDetailInfos?.doseQuantity,
inventoryList: item.orderDetailInfos?.inventoryList || [], inventoryList: item.orderDetailInfos?.inventoryList || [],
priceList: item.orderDetailInfos?.priceList || [], priceList: item.orderDetailInfos?.priceList || [],
partPercent: item.orderDetailInfos?.partPercent || 1, partPercent: item.orderDetailInfos?.partPercent || 1,
// 🔧 Bug #218 修复positionId 可能存储在 item 本身,优先使用 item.positionId // positionId 优先使用 item 中设置的(从 checkOrderGroupAvailability 中)
positionId: item.positionId || item.orderDetailInfos?.positionId, positionId: item.positionId || item.orderDetailInfos?.positionId,
defaultLotNumber: item.orderDetailInfos?.defaultLotNumber, defaultLotNumber: item.orderDetailInfos?.defaultLotNumber,
}; };
@@ -3715,6 +3767,11 @@ async function checkOrderGroupAvailability(detailList) {
} }
const adviceInfo = res.data.records[0]; const adviceInfo = res.data.records[0];
// 🔧 Bug Fix: 将医嘱库信息保存到 item 中,供后续使用
item.orderDetailInfos = adviceInfo;
item.adviceType = adviceInfo.adviceType;
item.positionId = adviceInfo.positionId;
if (adviceInfo.adviceType != 3) { if (adviceInfo.adviceType != 3) {
if (!adviceInfo.positionId) { if (!adviceInfo.positionId) {

View File

@@ -74,7 +74,7 @@ export function submitApproval(busNo) {
return request({ return request({
url: '/inventory-manage/stocktaking/submit-approval', url: '/inventory-manage/stocktaking/submit-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -83,7 +83,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/stocktaking/withdraw-approval', url: '/inventory-manage/stocktaking/withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -74,7 +74,7 @@ export function submitApproval(busNo) {
return request({ return request({
url: '/inventory-manage/stocktaking/submit-approval', url: '/inventory-manage/stocktaking/submit-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -83,7 +83,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/stocktaking/withdraw-approval', url: '/inventory-manage/stocktaking/withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -58,7 +58,7 @@ export function submitApproval(busNo) {
return request({ return request({
url: '/inventory-manage/purchase/submit-approval', url: '/inventory-manage/purchase/submit-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -67,7 +67,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/purchase/withdraw-approval', url: '/inventory-manage/purchase/withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -74,7 +74,7 @@ export function submitApproval(busNo) {
return request({ return request({
url: '/inventory-manage/stocktaking/submit-approval', url: '/inventory-manage/stocktaking/submit-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -83,7 +83,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/stocktaking/withdraw-approval', url: '/inventory-manage/stocktaking/withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -56,7 +56,7 @@ export function submitApproval(busNo) {
return request({ return request({
url: '/inventory-manage/loss/submit-approval', url: '/inventory-manage/loss/submit-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -65,7 +65,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/loss/withdraw-approval', url: '/inventory-manage/loss/withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -144,6 +144,6 @@ export function withdrawApprovalReturn(busNo) {
return request({ return request({
url: '/inventory-manage/return/return-withdraw-approval', url: '/inventory-manage/return/return-withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo: busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -89,7 +89,7 @@ export function submitApproval(busNo) {
return request({ return request({
url: '/inventory-manage/return/return-submit-approval', url: '/inventory-manage/return/return-submit-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -98,7 +98,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/return/return-withdraw-approval', url: '/inventory-manage/return/return-withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }

View File

@@ -77,7 +77,7 @@ export function submitApproval(busNo) {
url: '/inventory-manage/transfer/submit-approval', url: '/inventory-manage/transfer/submit-approval',
// product-transfer-approved // product-transfer-approved
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }
@@ -86,7 +86,7 @@ export function withdrawApproval(busNo) {
return request({ return request({
url: '/inventory-manage/transfer/withdraw-approval', url: '/inventory-manage/transfer/withdraw-approval',
method: 'put', method: 'put',
data: busNo data: { busNo } // 修复:发送对象而不是字符串
}) })
} }