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

This commit is contained in:
2026-06-16 16:12:16 +08:00

View File

@@ -193,13 +193,13 @@
/>
</div>
<vxe-table
ref="prescriptionRef"
:ref="(el) => { if (el) tableRefs[pIndex] = el }"
v-loading="loading"
:data="prescription.prescriptionList"
:row-config="{ keyField: 'uniqueKey', expandRowKeys: prescription.expandOrder }"
border
@cell-click="clickRow"
@cell-dblclick="(row) => clickRowDb(row, pIndex)"
@cell-dblclick="({ row }) => clickRowDb(row, pIndex)"
>
<vxe-column
type="expand"
@@ -217,8 +217,8 @@
style="padding: 16px; background: #f8f9fa; border-radius: 8px"
>
<template v-if="scope.row.adviceType == 1">
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 8px">
<span class="medicine-title">
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: nowrap">
<span class="medicine-title" style="flex-shrink: 0">
{{
scope.row.adviceName +
' ' +
@@ -230,119 +230,45 @@
']'
}}
</span>
<el-form-item
prop="lotNumber"
label="药房"
>
<el-select
v-model="scope.row.inventoryId"
style="width: 380px; margin-right: 20px"
placeholder="药房"
>
<el-form-item prop="lotNumber" label="药房" style="margin-bottom: 0; flex-shrink: 0">
<el-select v-model="scope.row.inventoryId" style="width: 280px" placeholder="药房">
<el-option
v-for="item in scope.row.stockList"
:key="item.inventoryId"
:value="item.inventoryId"
:label="
item.locationName +
' ' +
'批次号: ' +
item.lotNumber +
' ' +
' 库存:' +
item.quantity / scope.row.partPercent +
item.unitCode_dictText +
' 单价:' +
item.price.toFixed(2) +
'/' +
item.unitCode_dictText
"
:label="item.locationName + ' 库存:' + item.quantity / scope.row.partPercent + item.unitCode_dictText + ' 单价:' + item.price.toFixed(2) + '/' + item.unitCode_dictText"
@click="handleNumberClick(item, scope.rowIndex, pIndex)"
/>
</el-select>
</el-form-item>
<div class="form-group">
<!-- 单次剂量 -->
<el-form-item
label="数量"
prop="minUnitQuantity"
class="required-field"
data-prop="minUnitQuantity"
>
<el-input-number
:ref="(el) => (inputRefs.minUnitQuantity = el)"
v-model="scope.row.minUnitQuantity"
:min="0"
controls-position="right"
:controls="false"
style="width: 70px; margin-right: 20px"
@input="
() => {
nextTick(() => {
scope.row.totalPrice =
scope.row.minUnitQuantity * scope.row.unitPrice;
});
}
"
@keyup.enter.prevent="
handleEnter('minUnitQuantity', scope.row, scope.rowIndex, pIndex)
"
<el-form-item label="数量" prop="minUnitQuantity" class="required-field" data-prop="minUnitQuantity" style="margin-bottom: 0; flex-shrink: 0">
<el-input-number
:ref="(el) => (inputRefs.minUnitQuantity = el)"
v-model="scope.row.minUnitQuantity"
:min="0" controls-position="right" :controls="false" style="width: 75px"
@input="() => { nextTick(() => { scope.row.totalPrice = scope.row.minUnitQuantity * scope.row.unitPrice; }); }"
@keyup.enter.prevent="handleEnter('minUnitQuantity', scope.row, scope.rowIndex, pIndex)"
/>
</el-form-item>
<el-select v-model="scope.row.minUnitCode" style="width: 75px; flex-shrink: 0" placeholder=" ">
<template v-for="item in scope.row.unitCodeList" :key="item.value">
<el-option
v-if="scope.row.unitCodeList.length == 3 ? item.type == unitMap['minUnit'] : item.type == unitMap['unit']"
:value="item.value" :label="item.label"
/>
</el-form-item>
<!-- 剂量单位 -->
<el-select
v-model="scope.row.minUnitCode"
style="width: 80px; margin-right: 20px"
placeholder=" "
>
<template
v-for="item in scope.row.unitCodeList"
:key="item.value"
>
<el-option
v-if="
scope.row.unitCodeList.length == 3
? item.type == unitMap['minUnit']
: item.type == unitMap['unit']
"
:value="item.value"
:label="item.label"
/>
</template>
</el-select>
<el-form-item label="特殊煎法" prop="dosageInstruction" class="required-field" data-prop="dosageInstruction" style="margin-bottom: 0; flex-shrink: 0">
<el-select v-model="scope.row.dosageInstruction" style="width: 95px" placeholder=" ">
<template v-for="item in dosage_instruction" :key="item.value">
<el-option :value="item.value" :label="item.label" />
</template>
</el-select>
<!-- 单次剂量 -->
<el-form-item
label="特殊煎法"
prop="dosageInstruction"
class="required-field"
data-prop="dosageInstruction"
>
<el-select
v-model="scope.row.dosageInstruction"
style="width: 90px; margin-right: 20px"
placeholder=" "
>
<template
v-for="item in dosage_instruction"
:key="item.value"
>
<el-option
:value="item.value"
:label="item.label"
/>
</template>
</el-select>
</el-form-item>
</div>
<span class="total-amount">
总金额:{{
scope.row.totalPrice ? scope.row.totalPrice + ' 元' : '0.00 元'
}}
</el-form-item>
<span class="total-amount" style="flex-shrink: 0; white-space: nowrap">
总金额:{{ scope.row.totalPrice ? scope.row.totalPrice + ' 元' : '0.00 元' }}
</span>
<el-button
type="primary"
@click="handleSaveSign(scope.row, scope.rowIndex, pIndex)"
>
<el-button type="primary" style="flex-shrink: 0" @click="handleSaveSign(scope.row, scope.rowIndex, pIndex)">
确定
</el-button>
</div>
@@ -394,7 +320,7 @@
:width="1200"
>
<tcmMedicineList
ref="adviceTableRef"
:ref="(el) => { if (el) activeAdviceTable = el }"
:popover-visible="scope.row.showPopover"
:advice-query-params="adviceQueryParams"
:patient-info="props.patientInfo"
@@ -416,7 +342,7 @@
if (['ArrowUp', 'ArrowDown', 'Enter'].includes(e.key)) {
e.preventDefault();
// 传递事件到弹窗容器
adviceTableRef.handleKeyDown(e);
activeAdviceTable?.handleKeyDown(e);
}
}
"
@@ -602,7 +528,7 @@ const tcmPrescriptionList = ref([
},
]);
const unitCodeList = ref([]);
const adviceTableRef = ref([]);
const activeAdviceTable = ref(null);
const organization = ref([]);
const loading = ref(false);
const rowRules = ref({
@@ -625,7 +551,7 @@ const props = defineProps({
type: String,
},
});
const prescriptionRef = ref();
const tableRefs = ref({});
const stockList = ref([]);
const contractList = ref([]);
const tcmDiagnosisList = ref([]);
@@ -842,7 +768,7 @@ function handleAddMedicine(pIndex) {
/**
* 点击行赋值
*/
function clickRow(row) {
function clickRow({ row }) {
emit('selectDiagnosis', row);
}
@@ -856,7 +782,7 @@ function clickRowDb(row, pIndex) {
const index = prescription.prescriptionList.findIndex(
(item) => item.uniqueKey === row.uniqueKey
);
prescription.prescriptionList[index] = row;
prescription.prescriptionList.splice(index, 1, row);
prescription.expandOrder = [row.uniqueKey];
}
}
@@ -873,8 +799,14 @@ function handleFocus(row, index, pIndex) {
row.showPopover = true;
}
let blurTimer = null;
function handleBlur(row) {
row.showPopover = false;
if (blurTimer) clearTimeout(blurTimer);
blurTimer = setTimeout(() => {
row.showPopover = false;
blurTimer = null;
}, 200);
}
function handleChange(value) {
@@ -995,96 +927,59 @@ function getPrescriptionMedicineCount(prescriptionIndex) {
* 选择药品回调
*/
function selectAdviceBase(key, row, pIndex) {
// ... 保持原有逻辑,但使用对应处方的数据 ...
const prescription = tcmPrescriptionList.value[pIndex];
getOrgList();
unitCodeList.value = [];
unitCodeList.value.push({ value: row.unitCode, label: row.unitCode_dictText, type: 'unit' });
unitCodeList.value.push({ value: row.unitCode, label: row.unitCode_dictText, type: "unit" });
if (row.doseUnitCode != row.minUnitCode) {
unitCodeList.value.push({
value: row.doseUnitCode,
label: row.doseUnitCode_dictText,
type: 'dose',
});
unitCodeList.value.push({ value: row.doseUnitCode, label: row.doseUnitCode_dictText, type: "dose" });
}
if (
(row.partAttributeEnum == 1 || row.partAttributeEnum == 3) &&
row.minUnitCode != row.unitCode
) {
unitCodeList.value.push({
value: row.minUnitCode,
label: row.minUnitCode_dictText,
type: 'minUnit',
});
if ((row.partAttributeEnum == 1 || row.partAttributeEnum == 3) && row.minUnitCode != row.unitCode) {
unitCodeList.value.push({ value: row.minUnitCode, label: row.minUnitCode_dictText, type: "minUnit" });
}
if (row.adviceType == 2 && row.minUnitCode != row.unitCode) {
unitCodeList.value.push({
value: row.minUnitCode,
label: row.minUnitCode_dictText,
type: 'minUnit',
});
unitCodeList.value.push({ value: row.minUnitCode, label: row.minUnitCode_dictText, type: "minUnit" });
}
// vxe-table v4: keep row ref, mutate in-place (ref prescriptionlist.vue setValue)
const existingRow = prescription.prescriptionList[rowIndex.value];
if (!existingRow) return;
const pk = existingRow.uniqueKey, pe = existingRow.isEdit, pg = existingRow.groupId;
Object.keys(existingRow).forEach(k => { delete existingRow[k]; });
const rowData = JSON.parse(JSON.stringify(row));
prescription.prescriptionList[rowIndex.value] = {
...prescription.prescriptionList[rowIndex.value], // 保留原有属性(如 uniqueKey, groupId
...rowData, // 覆盖药品信息
statusEnum: 1, // 【关键修复】强制状态为“待签发/草稿”,确保能被保存过滤器捕获
adviceDefinitionId: rowData.adviceDefinitionId // 确保这个字段有值,后端会根据这个字段过滤空行
};
prescription.prescriptionList[rowIndex.value].orgId = undefined;
prescription.prescriptionList[rowIndex.value].dose = undefined;
prescription.prescriptionList[rowIndex.value].unitCodeList = unitCodeList.value;
prescription.prescriptionList[rowIndex.value].doseUnitCode = row.doseUnitCode;
prescription.prescriptionList[rowIndex.value].minUnitCode = row.minUnitCode;
prescription.prescriptionList[rowIndex.value].unitCode =
row.partAttributeEnum == 1 ? row.minUnitCode : row.unitCode;
prescription.prescriptionList[rowIndex.value].definitionId = JSON.parse(
JSON.stringify(row)
).chargeItemDefinitionId;
// 库存列表 + 价格列表拼成批次号的下拉框
Object.assign(existingRow, rowData);
existingRow.uniqueKey = pk; existingRow.isEdit = pe; existingRow.groupId = pg;
existingRow.statusEnum = 1; existingRow.showPopover = false;
existingRow.adviceDefinitionId = rowData.adviceDefinitionId;
existingRow.orgId = undefined; existingRow.dose = undefined;
existingRow.unitCodeList = unitCodeList.value;
existingRow.doseUnitCode = row.doseUnitCode;
existingRow.minUnitCode = row.minUnitCode;
existingRow.unitCode = row.partAttributeEnum == 1 ? row.minUnitCode : row.unitCode;
existingRow.definitionId = JSON.parse(JSON.stringify(row)).chargeItemDefinitionId;
if (row.adviceType == 1 || row.adviceType == 2) {
if (row.inventoryList && row.inventoryList.length == 0) {
prescription.expandOrder = [];
proxy.$modal.msgWarning('该项目无库存');
return;
prescription.expandOrder = []; proxy.$modal.msgWarning("无库存"); return;
}
stockList.value = row.inventoryList.map((item, index) => {
return { ...item, ...row.priceList[index] };
});
prescription.prescriptionList[rowIndex.value].stockList = stockList.value;
// 获取默认批次号的库存,如果没有让医生重新选
let stock = stockList.value.filter((item) => {
return item.lotNumber == row.defaultLotNumber;
})[0];
if (stock != {} && stock != undefined) {
if (stock.quantity <= 0) {
proxy.$modal.msgWarning('该项目库存不足,请选择其它库房');
// return;
}
prescription.prescriptionList[rowIndex.value].lotNumber = stock.lotNumber;
prescription.prescriptionList[rowIndex.value].inventoryId = stock.inventoryId;
prescription.prescriptionList[rowIndex.value].locationId = stock.locationId;
prescription.prescriptionList[rowIndex.value].unitPrice = stock.price;
prescription.prescriptionList[rowIndex.value].positionName = stock.locationName;
stockList.value = row.inventoryList.map((item, i) => ({ ...item, ...row.priceList[i] }));
existingRow.stockList = stockList.value;
const s = stockList.value.filter(it => it.lotNumber == row.defaultLotNumber)[0];
if (s && Object.keys(s).length > 0) {
if (s.quantity <= 0) proxy.$modal.msgWarning("库存不足");
existingRow.lotNumber = s.lotNumber; existingRow.inventoryId = s.inventoryId;
existingRow.locationId = s.locationId; existingRow.unitPrice = s.price;
existingRow.positionName = s.locationName;
}
} else {
prescription.prescriptionList[rowIndex.value].orgId = JSON.parse(
JSON.stringify(row)
).positionId;
prescription.prescriptionList[rowIndex.value].unitPrice = row.priceList[0].price;
existingRow.orgId = JSON.parse(JSON.stringify(row)).positionId;
existingRow.unitPrice = row.priceList[0].price;
}
prescription.expandOrder = [key];
nextTick(() => {
const t = tableRefs.value[pIndex];
if (t && t.setRowExpand) t.setRowExpand([existingRow], true);
if (row.adviceType == 1) {
if (row.injectFlag == 1) {
inputRefs.value['executeNum']?.focus();
} else {
inputRefs.value['dose']?.focus();
}
} else {
inputRefs.value['quantity']?.focus();
}
row.injectFlag == 1 ? inputRefs.value.executeNum?.focus() : inputRefs.value.dose?.focus();
} else { inputRefs.value.quantity?.focus(); }
});
}
@@ -1246,6 +1141,12 @@ function handleSaveSign(row, index, pIndex) {
}
row.contentJson = JSON.stringify(row);
// 强制刷新数组引用,触发 vxe-table 重渲染(切换只读模式 + 关闭展开行)
prescription.prescriptionList = [...prescription.prescriptionList];
nextTick(() => {
const t = tableRefs.value[pIndex];
if (t && t.clearRowExpand) t.clearRowExpand();
});
}
});
}
@@ -1345,6 +1246,8 @@ function escKeyListener(e) {
}
prescription.prescriptionList.shift();
prescription.isAdding = false;
// 强制刷新数组引用,触发 vxe-table 重渲染
prescription.prescriptionList = [...prescription.prescriptionList];
}
}
}