Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Ranyunqiao
2026-06-16 13:06:40 +08:00
5 changed files with 247 additions and 203 deletions

View File

@@ -1,7 +1,7 @@
# HealthLink-HIS 代码模块索引 # HealthLink-HIS 代码模块索引
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。 > 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
> 最后更新: 2026-06-16 06:00 (300 个 Controller) > 最后更新: 2026-06-16 12:00 (300 个 Controller)
## 关键词 → 模块速查 ## 关键词 → 模块速查

View File

@@ -184,7 +184,7 @@ const handleDeleteRow = (row) => {
// 提交处理 // 提交处理
const handleSubmit = () => { const handleSubmit = () => {
const selectedRows = consumableTableRef.value.getSelectionRows(); const selectedRows = consumableTableRef.value.getCheckboxRecords();
// 保存到本地存储 // 保存到本地存储
localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value); localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
if (selectedRows.length === 0) { if (selectedRows.length === 0) {

View File

@@ -314,7 +314,7 @@
border border
@cell-click="clickRow" @cell-click="clickRow"
@cell-dblclick="clickRowDb" @cell-dblclick="clickRowDb"
@select="handleSelectionChange" @checkbox-change="handleSelectionChange"
> >
<vxe-column <vxe-column
type="expand" type="expand"
@@ -333,7 +333,7 @@
style="padding: 16px; background: #f8f9fa; border-radius: 8px" style="padding: 16px; background: #f8f9fa; border-radius: 8px"
> >
<template v-if="scope.row.adviceType == 1"> <template v-if="scope.row.adviceType == 1">
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px"> <div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px; flex-wrap: nowrap">
<span class="medicine-title"> <span class="medicine-title">
{{ {{
scope.row.adviceName + scope.row.adviceName +
@@ -411,9 +411,8 @@
}} }}
</span> </span>
</div> </div>
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap"> <div class="edit-form-row">
<div class="form-group"> <!-- 单次用量 -->
<!-- 单次剂量 -->
<el-form-item <el-form-item
label="单次用量:" label="单次用量:"
prop="doseQuantity" prop="doseQuantity"
@@ -426,7 +425,7 @@
:min="0" :min="0"
controls-position="right" controls-position="right"
:controls="false" :controls="false"
style="width: 70px; margin-right: 20px" style="width: 70px"
@input="convertValues(scope.row, scope.rowIndex)" @input="convertValues(scope.row, scope.rowIndex)"
@keyup.enter.prevent="handleEnter('doseQuantity', scope.row, scope.rowIndex)" @keyup.enter.prevent="handleEnter('doseQuantity', scope.row, scope.rowIndex)"
@change="calculateTotalAmount(scope.row, scope.rowIndex)" @change="calculateTotalAmount(scope.row, scope.rowIndex)"
@@ -435,7 +434,7 @@
<!-- 剂量单位 --> <!-- 剂量单位 -->
<el-select <el-select
v-model="scope.row.minUnitCode" v-model="scope.row.minUnitCode"
style="width: 70px; margin-right: 20px" style="width: 70px"
placeholder=" " placeholder=" "
> >
<template <template
@@ -461,7 +460,7 @@
v-model="scope.row.dose" v-model="scope.row.dose"
controls-position="right" controls-position="right"
:controls="false" :controls="false"
style="width: 70px; margin: 0 20px" style="width: 70px"
@input="convertDoseValues(scope.row, scope.rowIndex)" @input="convertDoseValues(scope.row, scope.rowIndex)"
@keyup.enter.prevent="handleEnter('dose', scope.row, scope.rowIndex)" @keyup.enter.prevent="handleEnter('dose', scope.row, scope.rowIndex)"
/> />
@@ -480,8 +479,6 @@
:label="item.label" :label="item.label"
/> />
</el-select> </el-select>
</div>
<div class="form-group">
<el-form-item <el-form-item
label="给药途径:" label="给药途径:"
prop="methodCode" prop="methodCode"
@@ -530,7 +527,6 @@
if (scope.row.rateCode) { if (scope.row.rateCode) {
handleEnter('rateCode', scope.row, scope.rowIndex); handleEnter('rateCode', scope.row, scope.rowIndex);
} }
// inputRefs.rateCode.blur();
} }
" "
@change="calculateTotalAmount(scope.row, scope.rowIndex)" @change="calculateTotalAmount(scope.row, scope.rowIndex)"
@@ -544,18 +540,8 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</div>
</div> </div>
<div <div class="edit-form-row">
style="
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
margin-top: 10px;
"
>
<div class="form-group">
<el-form-item <el-form-item
label="用药天数:" label="用药天数:"
prop="dispensePerDuration" prop="dispensePerDuration"
@@ -580,7 +566,6 @@
</template> </template>
</el-input-number> </el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="总量:" label="总量:"
prop="quantity" prop="quantity"
@@ -600,7 +585,7 @@
<el-form-item> <el-form-item>
<el-select <el-select
v-model="scope.row.unitCode" v-model="scope.row.unitCode"
style="width: 70px; margin-right: 20px" style="width: 70px"
placeholder=" " placeholder=" "
@change="calculateTotalAmount(scope.row, scope.rowIndex)" @change="calculateTotalAmount(scope.row, scope.rowIndex)"
> >
@@ -633,50 +618,34 @@
</template> </template>
</el-select> </el-select>
</el-form-item> </el-form-item>
</div>
</div>
<div
style="
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
margin-top: 10px;
"
>
<div class="form-group">
<el-form-item <el-form-item
label="备注:" label="备注:"
prop="remarks" prop="remarks"
style="margin: 0; margin-right: 20px"
> >
<el-input <el-input
v-model="scope.row.remarks" v-model="scope.row.remarks"
placeholder="请输入备注" placeholder="请输入备注"
maxlength="100" maxlength="100"
show-word-limit show-word-limit
style="width: 500px" style="width: 300px"
/> />
</el-form-item> </el-form-item>
</div>
<el-button <el-button
type="primary" type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex)" @click="handleSaveSign(scope.row, scope.rowIndex)"
> >
确定 确定
</el-button> </el-button>
<el-button
@click="handleCancelEdit(scope.row, scope.rowIndex)"
>
取消
</el-button>
</div> </div>
</template> </template>
<!-- 🔧 Bug #147 修复耗材类型(adviceType=4)的编辑模板 --> <!-- 🔧 Bug #147 修复耗材类型(adviceType=4)的编辑模板 -->
<template v-else-if="scope.row.adviceType == 4"> <template v-else-if="scope.row.adviceType == 4">
<div <div class="edit-form-row">
style="
display: flex;
align-items: center;
margin-bottom: 16px;
gap: 16px;
"
>
<span class="medicine-title"> <span class="medicine-title">
{{ {{
scope.row.adviceName + scope.row.adviceName +
@@ -711,7 +680,7 @@
<el-form-item> <el-form-item>
<el-select <el-select
v-model="scope.row.unitCode" v-model="scope.row.unitCode"
style="width: 70px; margin-right: 20px" style="width: 70px"
placeholder=" " placeholder=" "
@change="calculateTotalAmount(scope.row, scope.rowIndex)" @change="calculateTotalAmount(scope.row, scope.rowIndex)"
> >
@@ -723,7 +692,6 @@
v-if="item.type != unitMap['dose']" v-if="item.type != unitMap['dose']"
:value="item.value" :value="item.value"
:label="item.label" :label="item.label"
style="width: 70px; margin-right: 20px"
@click=" @click="
() => { () => {
scope.row.unitCode_dictText = item.label; scope.row.unitCode_dictText = item.label;
@@ -750,23 +718,21 @@
: '0.00 元' : '0.00 元'
}} }}
</span> </span>
<el-button
type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex)"
>
确定
</el-button>
<el-button
@click="handleCancelEdit(scope.row, scope.rowIndex)"
>
取消
</el-button>
</div> </div>
<el-button
type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex)"
>
确定
</el-button>
</template> </template>
<template v-else-if="scope.row.adviceType == 2"> <template v-else-if="scope.row.adviceType == 2">
<div <div class="edit-form-row">
style="
display: flex;
align-items: center;
margin-bottom: 16px;
gap: 16px;
"
>
<span class="medicine-title"> <span class="medicine-title">
{{ {{
scope.row.adviceName + scope.row.adviceName +
@@ -801,7 +767,7 @@
<el-form-item> <el-form-item>
<el-select <el-select
v-model="scope.row.unitCode" v-model="scope.row.unitCode"
style="width: 70px; margin-right: 20px" style="width: 70px"
placeholder=" " placeholder=" "
@change="calculateTotalAmount(scope.row, scope.rowIndex)" @change="calculateTotalAmount(scope.row, scope.rowIndex)"
> >
@@ -813,7 +779,6 @@
v-if="item.type != unitMap['dose']" v-if="item.type != unitMap['dose']"
:value="item.value" :value="item.value"
:label="item.label" :label="item.label"
style="width: 70px; margin-right: 20px"
@click=" @click="
() => { () => {
scope.row.unitCode_dictText = item.label; scope.row.unitCode_dictText = item.label;
@@ -853,17 +818,22 @@
: '0.00 元' : '0.00 元'
}} }}
</span> </span>
<el-button
type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex)"
>
确定
</el-button>
<el-button
@click="handleCancelEdit(scope.row, scope.rowIndex)"
>
取消
</el-button>
</div> </div>
<el-button
type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex)"
>
确定
</el-button>
</template> </template>
<template v-else> <template v-else>
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px"> <div class="edit-form-row">
<span style="font-size: 16px; font-weight: 600"> <span style="font-size: 16px; font-weight: 600; white-space: nowrap">
{{ scope.row.adviceName }} {{ scope.row.adviceName }}
{{ {{
(scope.row.unitPrice !== undefined && scope.row.unitPrice !== null && !isNaN(scope.row.unitPrice) && (scope.row.unitPrice !== undefined && scope.row.unitPrice !== null && !isNaN(scope.row.unitPrice) &&
@@ -872,61 +842,63 @@
: '-' + '元' : '-' + '元'
}} }}
</span> </span>
<div class="form-group"> <el-form-item
<el-form-item label="执行次数:"
label="执行次数:" prop="quantity"
prop="quantity" class="required-field"
class="required-field" data-prop="quantity"
data-prop="quantity" >
> <el-input-number
<el-input-number :ref="(el) => (inputRefs.quantity = el)"
:ref="(el) => (inputRefs.quantity = el)" v-model="scope.row.quantity"
v-model="scope.row.quantity" placeholder="执行次数"
placeholder="执行次数" style="width: 100px"
style="width: 100px; margin: 0 20px" controls-position="right"
controls-position="right" :controls="false"
:controls="false" @keyup.enter.prevent="handleEnter('quantity', scope.row, scope.rowIndex)"
@keyup.enter.prevent="handleEnter('quantity', scope.row, scope.rowIndex)" @input="calculateTotalPrice(scope.row, scope.rowIndex)"
@input="calculateTotalPrice(scope.row, scope.rowIndex)" />
/> </el-form-item>
</el-form-item> <el-form-item
<el-form-item label="执行科室:"
label="执行科室:" prop="orgId"
prop="orgId" class="required-field"
class="required-field" data-prop="orgId"
data-prop="orgId" >
> <el-tree-select
<el-tree-select :ref="(el) => (inputRefs.orgId = el)"
:ref="(el) => (inputRefs.orgId = el)" v-model="scope.row.orgId"
v-model="scope.row.orgId" clearable
clearable style="width: 200px"
style="width: 200px" :data="organization"
:data="organization" :props="{ value: 'id', label: 'name', children: 'children' }"
:props="{ value: 'id', label: 'name', children: 'children' }" value-key="id"
value-key="id" check-strictly
check-strictly default-expand-all
default-expand-all placeholder="请选择执行科室"
placeholder="请选择执行科室" @change="(value) => handleOrgChange(value, scope.rowIndex, scope.row)"
@change="(value) => handleOrgChange(value, scope.rowIndex, scope.row)" />
/> </el-form-item>
</el-form-item> <span class="total-amount">
<span class="total-amount"> 总金额
总金额 {{
{{ (scope.row.totalPrice !== undefined && scope.row.totalPrice !== null &&
(scope.row.totalPrice !== undefined && scope.row.totalPrice !== null && !isNaN(scope.row.totalPrice) && isFinite(scope.row.totalPrice))
!isNaN(scope.row.totalPrice) && isFinite(scope.row.totalPrice)) ? Number(scope.row.totalPrice).toFixed(2) + ' 元'
? Number(scope.row.totalPrice).toFixed(2) + ' 元' : '0.00 元'
: '0.00 元' }}
}} </span>
</span>
<!-- 金额: {{ scope.row.priceList[0].price }} -->
</div>
<el-button <el-button
type="primary" type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex)" @click="handleSaveSign(scope.row, scope.rowIndex)"
> >
确定 确定
</el-button> </el-button>
<el-button
@click="handleCancelEdit(scope.row, scope.rowIndex)"
>
取消
</el-button>
</div> </div>
</template> </template>
</div> </div>
@@ -1103,7 +1075,7 @@
</template> </template>
<div <div
v-else v-else
style="display: flex; align-items: center; gap: 8px;" style="display: flex; align-items: center; justify-content: center; gap: 8px;"
> >
<el-icon color="var(--el-color-primary)"> <el-icon color="var(--el-color-primary)">
<Memo /> <Memo />
@@ -1161,18 +1133,21 @@
title="单次剂量" title="单次剂量"
align="center" align="center"
field="" field=""
width="160"
> >
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.isEdit"> <template v-if="scope.row.isEdit">
<el-input-number <div style="display: flex; align-items: center; white-space: nowrap;">
v-model="scope.row.dose" <el-input-number
:min="0" v-model="scope.row.dose"
:precision="2" :min="0"
:controls="false" :precision="2"
style="width: 70px" :controls="false"
size="small" style="width: 80px"
/> size="small"
<span style="margin-left: 4px">{{ scope.row.doseUnitCode_dictText }}</span> />
<span style="margin-left: 4px">{{ scope.row.doseUnitCode_dictText }}</span>
</div>
</template> </template>
<span v-else> <span v-else>
{{ {{
@@ -1191,20 +1166,23 @@
title="总量" title="总量"
align="center" align="center"
field="" field=""
width="140"
> >
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.isEdit"> <template v-if="scope.row.isEdit">
<el-input-number <div style="display: flex; align-items: center; white-space: nowrap;">
v-model="scope.row.quantity" <el-input-number
:min="1" v-model="scope.row.quantity"
:precision="0" :min="1"
:controls="false" :precision="0"
style="width: 60px" :controls="false"
size="small" style="width: 70px"
@change="calculateTotalPrice(scope.row, scope.rowIndex)" size="small"
@input="calculateTotalPrice(scope.row, scope.rowIndex)" @change="calculateTotalPrice(scope.row, scope.rowIndex)"
/> @input="calculateTotalPrice(scope.row, scope.rowIndex)"
<span style="margin-left: 4px">{{ resolveTotalQuantityUnit(scope.row) }}</span> />
<span style="margin-left: 4px">{{ resolveTotalQuantityUnit(scope.row) }}</span>
</div>
</template> </template>
<span v-else> <span v-else>
{{ formatTotalQuantityWithUnit(scope.row) }} {{ formatTotalQuantityWithUnit(scope.row) }}
@@ -1216,7 +1194,7 @@
align="right" align="right"
field="" field=""
header-align="center" header-align="center"
width="100" width="120"
> >
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.isEdit"> <template v-if="scope.row.isEdit">
@@ -1238,7 +1216,7 @@
title="药房/科室" title="药房/科室"
align="center" align="center"
field="" field=""
width="200" width="150"
> >
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.isEdit"> <template v-if="scope.row.isEdit">
@@ -1576,6 +1554,19 @@ const orderGroupLoaded = ref({
const updateExpandOrder = (keys) => { const updateExpandOrder = (keys) => {
expandOrder.value = keys; expandOrder.value = keys;
}; };
// 收起所有展开行vxe-table v4: expandRowKeys只在初始化生效必须调实例方法收起行
function collapseAllExpanded() {
expandOrder.value = [];
if (prescriptionRef.value?.clearRowExpand) {
prescriptionRef.value.clearRowExpand();
} else if (prescriptionRef.value?.setRowExpand) {
const allRows = prescriptionRef.value.getData?.() || [];
if (allRows.length > 0) {
prescriptionRef.value.setRowExpand(allRows, false);
}
}
}
const stockList = ref([]); const stockList = ref([]);
const contractList = ref([]); const contractList = ref([]);
const conditionId = ref(''); const conditionId = ref('');
@@ -1764,7 +1755,7 @@ watch(
nextTick(() => { nextTick(() => {
const index = prescriptionList.value.findIndex((row) => row.uniqueKey === newValue[0]); const index = prescriptionList.value.findIndex((row) => row.uniqueKey === newValue[0]);
const items = proxy.$refs['formRef' + index]?.$el?.querySelectorAll('[data-prop]'); const items = proxy.$refs['formRef' + index]?.$el?.querySelectorAll('[data-prop]');
requiredProps.value = Array.from(items).map((item) => item.dataset.prop); requiredProps.value = items ? Array.from(items).map((item) => item.dataset.prop) : [];
}); });
} else { } else {
requiredProps.value = {}; requiredProps.value = {};
@@ -1876,7 +1867,7 @@ function handlePrintCommand(command) {
// 智能打印 - 根据选中数据的adviceType自动选择打印方式 // 智能打印 - 根据选中数据的adviceType自动选择打印方式
async function printPrescription() { async function printPrescription() {
// const selectedRows = prescriptionList.value.filter((item) => item.check); // const selectedRows = prescriptionList.value.filter((item) => item.check);
const selectedRows = prescriptionRef.value.getSelectionRows(); const selectedRows = prescriptionRef.value.getCheckboxRecords();
console.log('123456selectedRows', selectedRows); console.log('123456selectedRows', selectedRows);
if (selectedRows.length === 0) { if (selectedRows.length === 0) {
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败'); ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
@@ -2003,7 +1994,7 @@ async function printPrescription() {
// 处方打印 - 专门打印处方类型的数据 // 处方打印 - 专门打印处方类型的数据
async function prescriptionPrint() { async function prescriptionPrint() {
// const selectedRows = prescriptionList.value.filter((item) => item.check); // const selectedRows = prescriptionList.value.filter((item) => item.check);
const selectedRows = prescriptionRef.value.getSelectionRows(); const selectedRows = prescriptionRef.value.getCheckboxRecords();
if (selectedRows.length === 0) { if (selectedRows.length === 0) {
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败'); ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
return; return;
@@ -2086,7 +2077,7 @@ async function prescriptionPrint() {
async function disposalPrint() { async function disposalPrint() {
console.log('处置打印开始'); console.log('处置打印开始');
// const selectedRows = prescriptionList.value.filter((item) => item.check); // const selectedRows = prescriptionList.value.filter((item) => item.check);
const selectedRows = prescriptionRef.value.getSelectionRows(); const selectedRows = prescriptionRef.value.getCheckboxRecords();
if (selectedRows.length === 0) { if (selectedRows.length === 0) {
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败'); ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
return; return;
@@ -2355,14 +2346,17 @@ function getDiagnosisInfo() {
} }
// 选择框改变时的处理 // 选择框改变时的处理
function handleSelectionChange(selection, row) { function handleSelectionChange({ checked, selection, row }) {
const isSelected = selection.some((item) => item.uniqueKey === row.uniqueKey); if (!row) return;
// 优先使用selection回退到checked兼容不同vxe-table版本
const isSelected = selection ? selection.some((item) => item.uniqueKey === row.uniqueKey) : !!checked;
if (!row.groupId) return;
prescriptionList.value prescriptionList.value
.filter((item) => { .filter((item) => {
return item.groupId && item.groupId == row?.groupId; return item.groupId && item.groupId == row.groupId && item.uniqueKey !== row.uniqueKey;
}) })
.forEach((row) => { .forEach((item) => {
prescriptionRef.value.toggleCheckboxRow(row, isSelected); prescriptionRef.value.toggleCheckboxRow(item, isSelected);
}); });
} }
@@ -2419,7 +2413,7 @@ function handleAddPrescription(prescriptionId, showWarning = true) {
}); });
getGroupMarkers(); getGroupMarkers();
nextTick(() => { nextTick(() => {
const adviceRefName = 'adviceRef_' + (prescriptionId || currentPrescriptionId.value) + '_0'; const adviceRefName = 'adviceRef' + 0;
const adviceRef = proxy.$refs[adviceRefName]; const adviceRef = proxy.$refs[adviceRefName];
if (adviceRef && adviceRef.focus) { if (adviceRef && adviceRef.focus) {
adviceRef.focus(); adviceRef.focus();
@@ -2519,7 +2513,11 @@ function handleFocus(row, index) {
function handleBlur(row) { function handleBlur(row) {
setTimeout(() => { setTimeout(() => {
row.showPopover = false; // 通过uniqueKey找到当前行确保popover关闭
const currentRow = prescriptionList.value.find(r => r.uniqueKey === row.uniqueKey);
if (currentRow) {
currentRow.showPopover = false;
}
}, 200); }, 200);
} }
@@ -2618,32 +2616,38 @@ function selectAdviceBase(key, row) {
async function setNewRow(key, row) { async function setNewRow(key, row) {
console.log('[BugFix] setNewRow - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName); console.log('[BugFix] setNewRow - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
// 每次选择药品时,将当前行数据完全重置,清空所有旧数据 // 不再替换行对象引用保持vxe-table的行引用不变确保插槽模板正确响应数据更新
const preservedData = { const currentRow = prescriptionList.value[rowIndex.value];
uniqueKey: prescriptionList.value[rowIndex.value].uniqueKey, if (!currentRow) return;
isEdit: true, // 保持编辑状态
statusEnum: 1, currentRow.isEdit = true;
showPopover: false, // 确保popover关闭 currentRow.statusEnum = 1;
}; // 立即设置adviceName确保输入框即时显示选中项名称
currentRow.adviceName = row.adviceName;
currentRow.showPopover = false;
// 完全替换整个对象,只保留必要的初始字段 await setValue(row);
prescriptionList.value[rowIndex.value] = preservedData;
setValue(row);
console.log('[BugFix] setNewRow after setValue - prescriptionList[rowIndex].adviceType:', prescriptionList.value[rowIndex.value].adviceType, 'adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText); console.log('[BugFix] setNewRow after setValue - prescriptionList[rowIndex].adviceType:', prescriptionList.value[rowIndex.value].adviceType, 'adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
// 🔧 Bug #220 修复确保在setValue之后重新计算耗材类型的总金额 // 🔧 Bug #220 修复确保在setValue之后重新计算耗材类型的总金额
// 耗材(adviceType=4)和诊疗(adviceType=3)需要重新计算以确保显示正确 // 耗材(adviceType=4)和诊疗(adviceType=3)需要重新计算以确保显示正确
const currentRow = prescriptionList.value[rowIndex.value]; if (currentRow.adviceType == 3 || currentRow.adviceType == 4) {
if (currentRow && (currentRow.adviceType == 3 || currentRow.adviceType == 4)) {
calculateTotalPrice(currentRow, rowIndex.value); calculateTotalPrice(currentRow, rowIndex.value);
} }
// 确保在setValue之后再次设置showPopover为false防止被覆盖 // 确保在setValue之后再次设置showPopover为false防止被覆盖
prescriptionList.value[rowIndex.value].showPopover = false; currentRow.showPopover = false;
expandOrder.value = [key]; expandOrder.value = [key];
// vxe-table v4: expandRowKeys只在初始化生效必须调实例方法展开行
await nextTick();
if (prescriptionRef.value?.setRowExpand) {
const rowObj = prescriptionList.value.find(item => item.uniqueKey === key);
if (rowObj) {
prescriptionRef.value.setRowExpand([rowObj], true);
}
}
// 自动聚焦到单次用量字段 - 使用 async/await 多次尝试 // 自动聚焦到单次用量字段 - 使用 async/await 多次尝试
await nextTick(); await nextTick();
@@ -2717,7 +2721,7 @@ function getInspectionApplyNoFromAdviceRow(row) {
} }
function handleDelete() { function handleDelete() {
let selectRows = prescriptionRef.value.getSelectionRows(); let selectRows = prescriptionRef.value.getCheckboxRecords();
console.log('BugFix#219: handleDelete called, selectRows=', selectRows); console.log('BugFix#219: handleDelete called, selectRows=', selectRows);
if (selectRows.length == 0) { if (selectRows.length == 0) {
@@ -2883,7 +2887,7 @@ function handleDelete() {
console.log('BugFix#219: 普通医嘱删除列表, deleteList=', deleteList.length, 'sum=', sum); console.log('BugFix#219: 普通医嘱删除列表, deleteList=', deleteList.length, 'sum=', sum);
handleEmrTreatment(); handleEmrTreatment();
updateExpandOrder([]); collapseAllExpanded();
isAdding.value = false; isAdding.value = false;
adviceQueryParams.value.adviceTypes = undefined; // 🎯 修复:改为 adviceTypes复数 adviceQueryParams.value.adviceTypes = undefined; // 🎯 修复:改为 adviceTypes复数
@@ -2998,11 +3002,11 @@ function handleSave(prescriptionId) {
if (prescriptionList.value[0]?.isEdit && !prescriptionList.value[0].adviceType) { if (prescriptionList.value[0]?.isEdit && !prescriptionList.value[0].adviceType) {
prescriptionList.value.shift(); prescriptionList.value.shift();
isAdding.value = false; isAdding.value = false;
updateExpandOrder([]); collapseAllExpanded();
} }
// --- 【修改点1优先获取选中行】 --- // --- 【修改点1优先获取选中行】 ---
const selectedRows = prescriptionRef.value ? prescriptionRef.value.getSelectionRows() : []; const selectedRows = prescriptionRef.value ? prescriptionRef.value.getCheckboxRecords() : [];
let sourceList = []; let sourceList = [];
// 如果用户有勾选,只处理勾选的;否则处理当前列表所有数据 // 如果用户有勾选,只处理勾选的;否则处理当前列表所有数据
@@ -3496,6 +3500,19 @@ function handleSkinTest(selectRows) {
); );
} }
// 取消编辑 - 关闭展开区域
function handleCancelEdit(row, index) {
if (isAdding.value && !row.requestId) {
// 新增行取消:移除该行
prescriptionList.value.splice(index, 1);
isAdding.value = false;
} else {
// 已有行取消:恢复非编辑状态
row.isEdit = false;
}
collapseAllExpanded();
}
// 单行处方保存 // 单行处方保存
function handleSaveSign(row, index, prescriptionId) { function handleSaveSign(row, index, prescriptionId) {
// 如果传入了处方ID先切换到该处方 // 如果传入了处方ID先切换到该处方
@@ -3580,7 +3597,7 @@ function handleSaveSign(row, index, prescriptionId) {
} }
row.isEdit = false; row.isEdit = false;
isAdding.value = false; isAdding.value = false;
updateExpandOrder([]); collapseAllExpanded();
row.contentJson = undefined; row.contentJson = undefined;
row.patientId = props.patientInfo.patientId; row.patientId = props.patientInfo.patientId;
row.encounterId = props.patientInfo.encounterId; row.encounterId = props.patientInfo.encounterId;
@@ -3751,7 +3768,7 @@ function handleSaveBatch(prescriptionId) {
// --- 【修改开始:优先使用选中行】 --- // --- 【修改开始:优先使用选中行】 ---
// 1. 获取表格当前选中的行 // 1. 获取表格当前选中的行
const selectedRows = prescriptionRef.value ? prescriptionRef.value.getSelectionRows() : []; const selectedRows = prescriptionRef.value ? prescriptionRef.value.getCheckboxRecords() : [];
// 2. 确定数据源 // 2. 确定数据源
// 逻辑:如果用户有勾选,就只处理勾选的;如果没勾选,就处理所有数据(一键保存) // 逻辑:如果用户有勾选,就只处理勾选的;如果没勾选,就处理所有数据(一键保存)
@@ -4051,22 +4068,34 @@ async function setValue(row) {
? (typeof row.skinTestFlag === 'number' ? row.skinTestFlag : (row.skinTestFlag ? 1 : 0)) ? (typeof row.skinTestFlag === 'number' ? row.skinTestFlag : (row.skinTestFlag ? 1 : 0))
: 0; : 0;
// 创建一个新的对象,而不是合并旧数据,以避免残留数据问题 // 不再替换行对象引用保持vxe-table的行引用不变确保插槽模板正确响应数据更新
console.log('[BugFix] setValue - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName); console.log('[BugFix] setValue - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
prescriptionList.value[rowIndex.value] = { const existingRow = prescriptionList.value[rowIndex.value];
...JSON.parse(JSON.stringify(row)), if (!existingRow) return;
// 确保adviceType为数字类型避免类型不匹配导致的显示问题
adviceType: Number(row.adviceType), // 保存需要保留的字段
// 🔧 Bug Fix: 确保adviceType_dictText被正确设置避免展开行时显示错误 const preservedKey = existingRow.uniqueKey;
adviceType_dictText: row.adviceType_dictText || mapAdviceTypeLabel(row.adviceType, row.adviceTableName), const preservedIsEdit = existingRow.isEdit;
skinTestFlag: skinTestFlag, // 确保皮试字段是数字类型 const preservedStatus = existingRow.statusEnum;
skinTestFlag_enumText: skinTestFlag == 1 ? '是' : '否', // 更新显示文本
// 保留原来设置的初始状态值 // 清除行上所有自有属性(避免残留旧数据)
uniqueKey: prescriptionList.value[rowIndex.value].uniqueKey, Object.keys(existingRow).forEach(key => {
isEdit: prescriptionList.value[rowIndex.value].isEdit, delete existingRow[key];
statusEnum: prescriptionList.value[rowIndex.value].statusEnum, });
showPopover: false, // 确保查询框关闭
}; // 从选中项复制所有属性到现有行对象
const rowData = JSON.parse(JSON.stringify(row));
Object.assign(existingRow, rowData);
// 覆盖需要特殊处理的字段
existingRow.adviceType = Number(row.adviceType);
existingRow.adviceType_dictText = row.adviceType_dictText || mapAdviceTypeLabel(row.adviceType, row.adviceTableName);
existingRow.skinTestFlag = skinTestFlag;
existingRow.skinTestFlag_enumText = skinTestFlag == 1 ? '是' : '否';
existingRow.uniqueKey = preservedKey;
existingRow.isEdit = preservedIsEdit;
existingRow.statusEnum = preservedStatus;
existingRow.showPopover = false;
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText); console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
// 🔧 Bug #455: 诊疗医嘱(adviceType=3)的执行科室默认使用患者就诊科室, // 🔧 Bug #455: 诊疗医嘱(adviceType=3)的执行科室默认使用患者就诊科室,
// 不使用positionId(诊疗目录配置的执行科室)避免配置ID不在机构树中导致显示原始ID // 不使用positionId(诊疗目录配置的执行科室)避免配置ID不在机构树中导致显示原始ID
@@ -4489,7 +4518,7 @@ function escKeyListener(e) {
index = prescriptionList.value.findIndex((item) => item.uniqueKey == expandOrder.value[0]); index = prescriptionList.value.findIndex((item) => item.uniqueKey == expandOrder.value[0]);
} }
if (index == 0) { if (index == 0) {
updateExpandOrder([]); collapseAllExpanded();
} }
prescriptionList.value.shift(); prescriptionList.value.shift();
isAdding.value = false; isAdding.value = false;
@@ -4500,7 +4529,7 @@ function escKeyListener(e) {
// 签退/撤回 // 签退/撤回
function handleSingOut() { function handleSingOut() {
let selectRows = prescriptionRef.value.getSelectionRows(); let selectRows = prescriptionRef.value.getCheckboxRecords();
console.log('BugFix#219: handleSingOut called, selectRows=', selectRows); console.log('BugFix#219: handleSingOut called, selectRows=', selectRows);
console.log('BugFix#219: 选中行详情:', selectRows.map(item => ({ console.log('BugFix#219: 选中行详情:', selectRows.map(item => ({
adviceType: item.adviceType, adviceType: item.adviceType,
@@ -4686,7 +4715,7 @@ function handleGroupId(paramList) {
// 组合 // 组合
function combination() { function combination() {
let selectRows = prescriptionRef.value.getSelectionRows(); let selectRows = prescriptionRef.value.getCheckboxRecords();
if (selectRows.length <= 1) { if (selectRows.length <= 1) {
proxy.$modal.msgWarning('至少选择两项'); proxy.$modal.msgWarning('至少选择两项');
return; return;
@@ -4748,7 +4777,7 @@ function combination() {
// 拆组 // 拆组
function split() { function split() {
let selectRows = prescriptionRef.value.getSelectionRows(); let selectRows = prescriptionRef.value.getCheckboxRecords();
if (selectRows.length < 1) { if (selectRows.length < 1) {
proxy.$modal.msgWarning('至少选择一项'); proxy.$modal.msgWarning('至少选择一项');
return; return;
@@ -5342,8 +5371,8 @@ const orderSetDialogScope = ref('personal');
function openOrderSetDialog(scope) { function openOrderSetDialog(scope) {
orderSetDialogScope.value = scope || 'personal'; orderSetDialogScope.value = scope || 'personal';
const selectedRaw = const selectedRaw =
prescriptionRef.value && prescriptionRef.value.getSelectionRows prescriptionRef.value && prescriptionRef.value.getCheckboxRecords
? prescriptionRef.value.getSelectionRows() ? prescriptionRef.value.getCheckboxRecords()
: []; : [];
const selected = (selectedRaw || []).map((row) => { const selected = (selectedRaw || []).map((row) => {
@@ -5435,6 +5464,8 @@ defineExpose({ getListInfo, getDiagnosisInfo });
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
flex-wrap: nowrap;
white-space: nowrap;
background: #fff; background: #fff;
padding: 6px 10px; padding: 6px 10px;
border-radius: 4px; border-radius: 4px;
@@ -5442,6 +5473,18 @@ defineExpose({ getListInfo, getDiagnosisInfo });
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
} }
.edit-form-row {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: nowrap;
margin-top: 10px;
}
.edit-form-row .el-form-item {
margin-bottom: 0;
}
/* 调整element组件默认间距 */ /* 调整element组件默认间距 */
// .el-select, // .el-select,
// .el-input-number { // .el-input-number {

View File

@@ -1,6 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="props.open" :model-value="props.open"
@update:model-value="(val) => !val && emit('close')"
title="退费单" title="退费单"
width="1300px" width="1300px"
teleported teleported
@@ -221,7 +222,7 @@ function tableSpanMethod({ row, column, rowIndex }) {
function submit() { function submit() {
// 1. 获取当前选中行并提取去重的 paymentId 列表 // 1. 获取当前选中行并提取去重的 paymentId 列表
const selectedRows = proxy.$refs['refundListRef'].getSelectionRows(); const selectedRows = proxy.$refs['refundListRef'].getCheckboxRecords();
const selectedPaymentIds = [...new Set(selectedRows.map((row) => row.paymentId))]; const selectedPaymentIds = [...new Set(selectedRows.map((row) => row.paymentId))];
// 2. 遍历 refundList筛选出符合条件的数据并设置 refundFlag // 2. 遍历 refundList筛选出符合条件的数据并设置 refundFlag

View File

@@ -50,7 +50,7 @@
align="center" align="center"
width="120" width="120"
> >
<template #default="scope"> <template #default>
{{ '1' }} {{ '1' }}
</template> </template>
</vxe-column> </vxe-column>
@@ -166,7 +166,7 @@ const handleDeleteRow = (row) => {
// 提交处理 // 提交处理
const handleSubmit = () => { const handleSubmit = () => {
const selectedRows = consumableTableRef.value.getSelectionRows(); const selectedRows = consumableTableRef.value.getCheckboxRecords();
// 保存到本地存储 // 保存到本地存储
// localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value); // localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
if (selectedRows.length === 0) { if (selectedRows.length === 0) {