bug 614 625 628 639 642

This commit is contained in:
Ranyunqiao
2026-06-12 16:20:59 +08:00
parent a18143ef41
commit 5e594e7c25
13 changed files with 606 additions and 513 deletions

View File

@@ -655,6 +655,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
* @return 操作结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<?> adviceCancel(AdviceExecuteParam adviceExecuteParam) {
// 获取当前执行时间
Date exeDate = DateUtils.getNowDate();
@@ -701,6 +702,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
longMedDispensedList.add(medicationDispense);
} else if (DispenseStatus.EXECUTED.getValue().equals(medicationDispense.getStatusEnum())
|| DispenseStatus.SUBMITTED.getValue().equals(medicationDispense.getStatusEnum())) {
longMedDispensedList.add(medicationDispense);
longMedUndispenseList.add(medicationDispense);
}
}
@@ -729,6 +731,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
tempMedDispensedList.add(medicationDispense);
} else if (DispenseStatus.EXECUTED.getValue().equals(medicationDispense.getStatusEnum())
|| DispenseStatus.SUBMITTED.getValue().equals(medicationDispense.getStatusEnum())) {
tempMedDispensedList.add(medicationDispense);
tempMedUndispenseList.add(medicationDispense);
}
}
@@ -876,7 +879,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
if (!longMedUndispenseList.isEmpty()) {
// 排除已汇总的药品
List<MedicationDispense> medicationDispenseList
= tempMedUndispenseList.stream().filter(x -> x.getSummaryNo() == null).toList();
= longMedUndispenseList.stream().filter(x -> x.getSummaryNo() == null).toList();
medicationDispenseService
.removeByIds(medicationDispenseList.stream().map(MedicationDispense::getId).toList());
}

View File

@@ -13,6 +13,7 @@ import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -227,6 +228,7 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
* @return 处理结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList) {
if (medicineReturnList == null || medicineReturnList.isEmpty()) {
return R.ok();
@@ -249,6 +251,10 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
// 进销存参数
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
// 记录未发药无库存变动的发药单ID
Set<Long> noInventoryUpdateMedIds = new HashSet<>();
Set<Long> noInventoryUpdateDevIds = new HashSet<>();
// 处理退药
// 获取药品退药id列表
List<Long> medReturnIdList = new ArrayList<>();
@@ -278,6 +284,14 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
throw new ServiceException("药品已退药,请勿重复退药");
}
// 在更新退药单状态前统计出实际没有发药已发药数量为0/空)的退药单,避免后续加回库存和报错
for (MedicationDispense medicationDispense : refundMedList) {
if (medicationDispense.getDispenseQuantity() == null
|| medicationDispense.getDispenseQuantity().compareTo(BigDecimal.ZERO) == 0) {
noInventoryUpdateMedIds.add(medicationDispense.getId());
}
}
// 更新退药单
for (MedicationDispense medicationDispense : refundMedList) {
// 退药状态
@@ -291,20 +305,22 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
// 退药人
medicationDispense.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
// 设置库存变更参数
SupplyItemDetailDto supplyItemDetailDto = new SupplyItemDetailDto();
for (MedicationRequest medicationRequest : refundMedRequestList) {
// 根据退药id查询退药请求id用于医保关联
if (medicationDispense.getMedReqId().equals(medicationRequest.getId())) {
supplyItemDetailDto.setRequestId(medicationRequest.getRefundMedicineId());
// 设置库存变更参数(仅针对实际发过药的药品)
if (!noInventoryUpdateMedIds.contains(medicationDispense.getId())) {
SupplyItemDetailDto supplyItemDetailDto = new SupplyItemDetailDto();
for (MedicationRequest medicationRequest : refundMedRequestList) {
// 根据退药id查询退药请求id用于医保关联
if (medicationDispense.getMedReqId().equals(medicationRequest.getId())) {
supplyItemDetailDto.setRequestId(medicationRequest.getRefundMedicineId());
}
}
supplyItemDetailDto.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
.setItemId(medicationDispense.getMedicationId()).setLotNumber(medicationDispense.getLotNumber());
supplyItemDetailList.add(supplyItemDetailDto);
}
supplyItemDetailDto.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
.setItemId(medicationDispense.getMedicationId()).setLotNumber(medicationDispense.getLotNumber());
supplyItemDetailList.add(supplyItemDetailDto);
// 追溯码表相关处理
if (medicationDispense.getTraceNo() != null) {
// 追溯码表相关处理(仅针对实际发过药的药品)
if (!noInventoryUpdateMedIds.contains(medicationDispense.getId()) && medicationDispense.getTraceNo() != null) {
// 使用逗号分割追溯码并转换为List
String[] traceNoList = medicationDispense.getTraceNo().split(CommonConstants.Common.COMMA);
for (String item : traceNoList) {
@@ -345,7 +361,7 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
devReturnIdList =
returnDeviceList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
// 获取退耗材请求id列表
List<Long> devRequestIdList = returnDeviceList.stream().map(ReturnMedicineDto::getRequestId).toList();
List<Long> devRequestIdList = returnDeviceList.stream().map(ReturnMedicineDto::getRequestId).collect(Collectors.toList());
if (devReturnIdList.isEmpty()) {
throw new ServiceException("请选择要退的耗材");
}
@@ -362,6 +378,15 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
throw new ServiceException("耗材已退,请勿重复操作");
}
// 在更新退耗材单状态前统计出实际没有发放已发放数量为0/空)的退耗材单
for (DeviceDispense deviceDispense : refundDevList) {
if (deviceDispense.getDispenseQuantity() == null
|| deviceDispense.getDispenseQuantity().compareTo(BigDecimal.ZERO) == 0) {
noInventoryUpdateDevIds.add(deviceDispense.getId());
}
}
// 更新退耗材单状态
for (DeviceDispense deviceDispense : refundDevList) {
// 退药时间
@@ -370,40 +395,20 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
deviceDispense.setDispenseQuantity(deviceDispense.getQuantity());
// 退药状态
deviceDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
// 设置库存变更参数
supplyItemDetailList
.add(new SupplyItemDetailDto().setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
.setItemId(deviceDispense.getDeviceDefId()).setLotNumber(deviceDispense.getLotNumber()));
// // 使用逗号分割追溯码并转换为List
// String[] traceNoList = deviceDispense.getTraceNo().split(CommonConstants.Common.COMMA);
// for (String item : traceNoList) {
// traceNoManage = new TraceNoManage();
// // 追溯码处理
// traceNoManage.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
// // 项目id
// .setItemId(deviceDispense.getDeviceDefId())
// // 仓库类型
// .setLocationTypeEnum(LocationForm.PHARMACY.getValue())
// // 仓库
// .setLocationId(deviceDispense.getLocationId())
// // 产品批号
// .setLotNumber(deviceDispense.getLotNumber())
// // 追溯码
// .setTraceNo(item)
// // 追溯码状态
// .setStatusEnum(TraceNoStatus.IN.getValue())
// // 追溯码单位
// .setUnitCode(deviceDispense.getUnitCode())
// // 操作类型
// .setOperationType(SupplyType.RETURN_MEDICATION.getValue());
// traceNoManageList.add(traceNoManage);
// }
// 设置库存变更参数(仅针对实际发放过的耗材)
if (!noInventoryUpdateDevIds.contains(deviceDispense.getId())) {
supplyItemDetailList
.add(new SupplyItemDetailDto().setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
.setItemId(deviceDispense.getDeviceDefId()).setLotNumber(deviceDispense.getLotNumber()));
}
}
deviceDispenseService.updateBatchById(refundDevList);
}
// 追溯码管理表数据追加
traceNoManageService.saveBatch(traceNoManageList);
if (!traceNoManageList.isEmpty()) {
traceNoManageService.saveBatch(traceNoManageList);
}
// 处理退库存
// 获取库存信息
@@ -424,6 +429,11 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
BigDecimal minQuantity = BigDecimal.ZERO;
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
// 过滤未实际发药/发耗材的项目,其库存不加回
if (noInventoryUpdateMedIds.contains(unDispenseInventoryDto.getDispenseId())
|| noInventoryUpdateDevIds.contains(unDispenseInventoryDto.getDispenseId())) {
continue;
}
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
if (!unDispenseInventoryDto.getDispenseUnit()
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
@@ -433,14 +443,19 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
}
minQuantity = minQuantity.add(quantity);
}
// 理论上不出bug的情况下以项目id批号仓库进行分组处理库存一定唯一所以get(0)
// 设置待更新的库存信息
inventoryItemList.add(new InventoryItem().setId(inventoryList.get(0).getInventoryId())
.setQuantity(inventoryList.get(0).getInventoryQuantity().add(minQuantity)));
// 只有当有需要恢复库存的药品/器材时才加回库存
if (minQuantity.compareTo(BigDecimal.ZERO) > 0) {
// 理论上不出bug的情况下以项目id批号仓库进行分组处理库存一定唯一所以get(0)
// 设置待更新的库存信息
inventoryItemList.add(new InventoryItem().setId(inventoryList.get(0).getInventoryId())
.setQuantity(inventoryList.get(0).getInventoryQuantity().add(minQuantity)));
}
}
}
// 库存更新
iInventoryItemService.updateBatchById(inventoryItemList);
if (!inventoryItemList.isEmpty()) {
iInventoryItemService.updateBatchById(inventoryItemList);
}
} else {
throw new ServiceException("请检查库存信息");
}
@@ -497,13 +512,26 @@ public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturn
}
}
}
uploadFailedNoList = this.ybReturnIntegrated(medReturnIdList, null);
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
if (uploadFailedNoList != null) {
returnMsg = "3506商品销售退货上传错误错误项目编码" + uploadFailedNoList;
} else {
returnMsg = "3506商品销售退货上传成功";
// 仅对实际发过药(生成了收费记录且计费的)调用医保退货接口
List<Long> medReturnIdsForYb = medReturnIdList.stream()
.filter(id -> !noInventoryUpdateMedIds.contains(id))
.collect(Collectors.toList());
if (!medReturnIdsForYb.isEmpty()) {
uploadFailedNoList = this.ybReturnIntegrated(medReturnIdsForYb, null);
if (uploadFailedNoList != null) {
returnMsg = "3506商品销售退货上传错误错误项目编码" + uploadFailedNoList;
} else {
returnMsg = "3506商品销售退货上传成功";
}
}
if (!supplyItemDetailList.isEmpty()) {
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
if (uploadFailedNoList != null) {
returnMsg = (returnMsg != null ? returnMsg + "" : "") + "医保进销存集成上传错误: " + uploadFailedNoList;
}
}
}
// 返回退药成功信息

View File

@@ -2,11 +2,11 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.healthlink.his.web.pharmacymanage.mapper.InHospitalReturnMedicineAppMapper">
<select id="selectEncounterInfoListPage" resultType="com.healthlink.his.web.pharmacymanage.dto.EncounterInfoDto">
SELECT ii.reception_time,
ii.start_time,
SELECT MAX(ii.reception_time) AS reception_time,
MAX(ii.start_time) AS start_time,
ii.encounter_id,
ii.encounter_no,
ii.refund_enum,
MAX(ii.refund_enum) AS refund_enum,
ii.patient_name,
ii.patient_wb_str,
ii.patient_py_str,
@@ -15,11 +15,11 @@
ii.birth_date,
ii.department_name
FROM (
SELECT ae.reception_time,
SELECT mmd.create_time AS reception_time,
ae.id AS encounter_id,
ae.bus_no AS encounter_no,
ae.tenant_id,
ae.start_time,
mmd.create_time AS start_time,
ae.class_enum,
mmd.status_enum AS refund_enum,
ap."name" AS patient_name,
@@ -52,11 +52,11 @@
AND mmd.status_enum = #{refundStatus}
</if>
UNION
SELECT ae.reception_time,
SELECT wdd.create_time AS reception_time,
ae.id AS encounter_id,
ae.bus_no AS encounter_no,
ae.tenant_id,
ae.start_time,
wdd.create_time AS start_time,
ae.class_enum,
wdd.status_enum AS refund_enum,
ap."name" AS patient_name,
@@ -90,7 +90,16 @@
</if>
) AS ii
${ew.customSqlSegment}
ORDER BY ii.reception_time DESC
GROUP BY ii.encounter_id,
ii.encounter_no,
ii.patient_name,
ii.patient_wb_str,
ii.patient_py_str,
ii.id_card,
ii.gender_enum,
ii.birth_date,
ii.department_name
ORDER BY reception_time DESC
</select>
<select id="selectReturnMedicineInfo"
resultType="com.healthlink.his.web.pharmacymanage.dto.ReturnMedicineInfoDto">

View File

@@ -172,13 +172,13 @@ function getPatchedVxeTable() {
// 修补 cell-click在 dispatchEvent 前注入参数归一化
code = code.replace(
"dispatchEvent('cell-click', params, evnt);",
`params.row = params; params.column = params.column; dispatchEvent('cell-click', params, evnt);`
`var _orgRow = params.row; Object.assign(params, _orgRow); params.row = _orgRow; dispatchEvent('cell-click', params, evnt);`
)
// 修补 current-change在 dispatchEvent 前注入参数归一化
code = code.replace(
"dispatchEvent('current-change', Object.assign({ oldValue, newValue }, params), evnt);",
`var _ccp = Object.assign({ oldValue, newValue }, params); _ccp.newValue = _ccp; _ccp.oldValue = oldValue; dispatchEvent('current-change', _ccp, evnt);`
`var _ccp = Object.assign({ oldValue, newValue }, params); Object.assign(_ccp, newValue); _ccp.newValue = newValue; _ccp.oldValue = oldValue; dispatchEvent('current-change', _ccp, evnt);`
)
cachedVxeTable = code

View File

@@ -52,40 +52,43 @@
搜索
</el-button>
</div>
<vxe-table
:row-config="{ isCurrent: true }" :data="encounterList"
border
style="width: 100%"
height="calc(100vh - 300px)"
@cell-click="handleGetReturnDrugList"
>
<vxe-column
field="patientName"
align="center"
title="姓名"
width="130"
show-overflow
/>
<vxe-column
field="genderEnum_enumText"
align="center"
title="性别"
show-overflow
/>
<vxe-column
align="center"
width="140"
title="就诊日期"
show-overflow
<div style="flex: 1; overflow: hidden; margin-top: 10px;">
<vxe-table
:row-config="{ isCurrent: true }"
:data="encounterList"
border
style="width: 100%"
height="100%"
@cell-click="handleGetReturnDrugList"
>
<template #default="scope">
{{
scope.row.receptionTime ? formatDateStr(scope.row.receptionTime, 'YYYY-MM-DD') : '-'
}}
</template>
</vxe-column>
<!-- <vxe-column title="状态" align="center" field="refundEnum_enumText" /> -->
</vxe-table>
<vxe-column
field="patientName"
align="center"
title="姓名"
width="130"
show-overflow
/>
<vxe-column
field="genderEnum_enumText"
align="center"
title="性别"
show-overflow
/>
<vxe-column
align="center"
width="140"
title="就诊日期"
show-overflow
>
<template #default="scope">
{{
scope.row.receptionTime ? formatDateStr(scope.row.receptionTime, 'YYYY-MM-DD') : '-'
}}
</template>
</vxe-column>
<!-- <vxe-column title="状态" align="center" field="refundEnum_enumText" /> -->
</vxe-table>
</div>
</el-card>
<!-- 右侧退药列表 -->
@@ -100,130 +103,132 @@
</div>
</template>
<el-button
type="primary"
:disabled="!selectedMedicines.length"
style="margin-bottom: 10px"
@click="handleReturnDrug(undefined)"
>
确认退药
</el-button>
<el-button
type="primary"
style="margin-bottom: 10px"
@click="handleScan()"
>
扫码
</el-button>
<vxe-table
ref="returnDrugRef"
:data="returDrugList"
style="width: 100%"
height="calc(100vh - 300px)"
border
:span-method="handelSpanMethod"
class="no-hover-table"
@select="handleSelection"
@checkbox-change="handelSelectRows"
>
<vxe-column
type="checkbox"
width="55"
align="center"
/>
<vxe-column
field="itemName"
title="药品名称"
show-overflow
align="center"
/>
<vxe-column
field="totalPrice"
title="总价"
width="100"
align="right"
header-align="center"
<div style="display: flex; gap: 10px; margin-bottom: 10px;">
<el-button
type="primary"
:disabled="!selectedMedicines.length"
@click="handleReturnDrug(undefined)"
>
<template #default="scope">
{{ scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) + ' 元' : '-' }}
</template>
</vxe-column>
<vxe-column
field="lotNumber"
title="批号"
width="180"
align="center"
/>
<vxe-column
field="traceNo"
title="追溯码"
width="180"
align="center"
确认退药
</el-button>
<el-button
type="primary"
@click="handleScan()"
>
<template #default="scope">
<el-input
v-model="scope.row.traceNo"
placeholder="请输入追溯码"
/>
</template>
</vxe-column>
<vxe-column
field="reqStatus_enumText"
title="退药状态"
width="100"
align="center"
扫码
</el-button>
</div>
<div style="flex: 1; overflow: hidden; margin-bottom: 10px;">
<vxe-table
ref="returnDrugRef"
:data="returDrugList"
style="width: 100%"
height="100%"
border
:span-method="handelSpanMethod"
class="no-hover-table"
@checkbox-all="handelSelectRows"
@checkbox-change="handelSelectRows"
>
<template #default="scope">
{{ scope.row.refundEnum_enumText }}
</template>
</vxe-column>
<vxe-column
field="waitingQuantity"
title="退药数量"
width="100"
align="center"
>
<template #default="scope">
<span>{{
scope.row.quantity
? Math.abs(scope.row.quantity) + ' ' + scope.row.unitCode_dictText
: '0' + ' ' + scope.row.unitCode_dictText
}}</span>
</template>
</vxe-column>
<vxe-column
field="doctorName"
title="开单医生"
align="center"
width="180"
/>
<vxe-column
title="操作"
width="100"
align="center"
fixed="right"
>
<template #default="scope">
<el-popconfirm
width="150"
hide-after="10"
title="操作确认"
placement="top-start"
@confirm="handleReturnDrug(scope.row)"
>
<template #reference>
<el-button
type="primary"
link
:disabled="scope.row.refundEnum != 16"
>
退药
</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</vxe-table>
<vxe-column
type="checkbox"
width="55"
align="center"
/>
<vxe-column
field="itemName"
title="药品名称"
show-overflow
align="center"
/>
<vxe-column
field="totalPrice"
title="总价"
width="100"
align="right"
header-align="center"
>
<template #default="scope">
{{ scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) + ' 元' : '-' }}
</template>
</vxe-column>
<vxe-column
field="lotNumber"
title="批号"
width="180"
align="center"
/>
<vxe-column
field="traceNo"
title="追溯码"
width="180"
align="center"
>
<template #default="scope">
<el-input
v-model="scope.row.traceNo"
placeholder="请输入追溯码"
/>
</template>
</vxe-column>
<vxe-column
field="reqStatus_enumText"
title="退药状态"
width="100"
align="center"
>
<template #default="scope">
{{ scope.row.refundEnum_enumText }}
</template>
</vxe-column>
<vxe-column
field="waitingQuantity"
title="退药数量"
width="100"
align="center"
>
<template #default="scope">
<span>{{
scope.row.quantity
? Math.abs(scope.row.quantity) + ' ' + scope.row.unitCode_dictText
: '0' + ' ' + scope.row.unitCode_dictText
}}</span>
</template>
</vxe-column>
<vxe-column
field="doctorName"
title="开单医生"
align="center"
width="180"
/>
<vxe-column
title="操作"
width="100"
align="center"
fixed="right"
>
<template #default="scope">
<el-popconfirm
width="150"
hide-after="10"
title="操作确认"
placement="top-start"
@confirm="handleReturnDrug(scope.row)"
>
<template #reference>
<el-button
type="primary"
link
:disabled="scope.row.refundEnum != 16"
>
退药
</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</vxe-table>
</div>
<!-- 底部操作栏 -->
<div class="footer">
@@ -288,7 +293,7 @@ function initOptions() {
});
}
function handleGetReturnDrugList(row) {
function handleGetReturnDrugList({ row }) {
encounterId.value = row.encounterId;
getReturnDrugList({
encounterId: row.encounterId,
@@ -363,7 +368,7 @@ function handleReturnDrug(row) {
};
});
} else {
saveList = proxy.$refs.returnDrugRef.getSelectionRows().map((item) => {
saveList = proxy.$refs.returnDrugRef.getCheckboxRecords().map((item) => {
return {
requestId: item.requestId,
dispenseId: item.dispenseId,
@@ -387,31 +392,22 @@ function handleReturnDrug(row) {
});
}
// 选择框改变时的处理
function handleSelection(selection, row) {
const isSelected = selection.some((item) => item.dispenseId === row.dispenseId);
returDrugList.value
.filter((item) => {
return item.requestId == row.requestId;
})
.forEach((row) => {
proxy.$refs['returnDrugRef'].toggleCheckboxRow(row, isSelected);
});
function handelSelectRows({ checked, row }) {
if (row) {
returDrugList.value
.filter((item) => item.requestId == row.requestId)
.forEach((r) => {
proxy.$refs['returnDrugRef'].setCheckboxRow(r, checked);
});
}
nextTick(() => {
selectedMedicines.value = proxy.$refs['returnDrugRef'].getSelectionRows();
selectedMedicines.value = proxy.$refs['returnDrugRef'].getCheckboxRecords();
totalAmount.value = selectedMedicines.value.reduce((accumulator, currentRow) => {
return accumulator + (currentRow.totalPrice || 0);
}, 0);
});
}
function handelSelectRows(selection) {
selectedMedicines.value = selection;
totalAmount.value = selectedMedicines.value.reduce((accumulator, currentRow) => {
return accumulator + (currentRow.totalPrice || 0);
}, 0);
}
// 根据 requestId 合并相同行的方法(只合并药品名称和总价列)
function handelSpanMethod({ row, column, rowIndex, columnIndex }) {
// 定义需要合并的列索引
@@ -465,7 +461,7 @@ function handelSpanMethod({ row, column, rowIndex, columnIndex }) {
<style lang="scss" scoped>
.container {
display: flex;
height: 90vh;
height: calc(100vh - 150px);
gap: 16px;
padding: 16px;
background: #f0f2f5;
@@ -474,10 +470,24 @@ function handelSpanMethod({ row, column, rowIndex, columnIndex }) {
.patient-list {
width: 600px;
flex-shrink: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.refund-list {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
}
:deep(.el-card__body) {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 16px;
}
.patient-item {

View File

@@ -1,4 +1,4 @@
<!--
<!--
* @Description: 门诊手术申请
-->
<template>
@@ -339,9 +339,11 @@
<el-select
v-model="form.surgeryName"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索手术"
:filter-method="filterSurgery"
:remote-method="remoteSearchSurgery"
:loading="surgeryLoading"
style="width: 100%"
@change="handleSurgeryChange"
>
@@ -414,9 +416,11 @@
<el-select
v-model="scope.row.surgeryName"
filterable
remote
reserve-keyword
placeholder="搜索次要手术"
:filter-method="filterSurgery"
:remote-method="remoteSearchSurgery"
:loading="surgeryLoading"
style="width: 100%"
@change="(val) => handleSecondarySurgeryChange(val, scope.row)"
>
@@ -1344,6 +1348,8 @@ function remoteSearchSurgery(query) {
function doSearchSurgery(query) {
surgeryLoading.value = true
getDiagnosisTreatmentList({
categoryCode: '24',
statusEnum: 2,
searchKey: query || '',
pageNo: 1,
pageSize: 100
@@ -1438,10 +1444,13 @@ function filterAnesthesia(query) {
// 加载手术和麻醉全量数据供本地过滤
function loadSurgeryAndAnesthesiaOptions() {
// 1. 初始加载前 100 个启用状态的手术项目,供下拉菜单默认展示,避免全量加载 10,102 条数据导致卡顿
getDiagnosisTreatmentList({
categoryCode: '24',
statusEnum: 2,
searchKey: '',
pageNo: 1,
pageSize: 1000
pageSize: 100
}).then(res => {
let data = []
if (res.data && res.data.records) {
@@ -1455,14 +1464,34 @@ function loadSurgeryAndAnesthesiaOptions() {
(item.categoryCode === '24' || item.categoryCode_dictText === '手术') &&
(item.statusEnum === 2 || item.statusEnum_enumText === '启用' || !item.statusEnum)
)
surgeryNameList.value = allSurgeryItems.value
}).catch(error => {
console.error('加载手术选项失败:', error)
})
// 2. 加载全部启用状态的麻醉项目(麻醉数量较少,可以直接加载全部)
getDiagnosisTreatmentList({
categoryCode: '25',
statusEnum: 2,
searchKey: '',
pageNo: 1,
pageSize: 200
}).then(res => {
let data = []
if (res.data && res.data.records) {
data = res.data.records
} else if (res.data && Array.isArray(res.data)) {
data = res.data
} else if (res.records && Array.isArray(res.records)) {
data = res.records
}
allAnesthesiaItems.value = data.filter(item =>
(item.categoryCode === '25' || item.categoryCode_dictText === '麻醉') &&
(item.statusEnum === 2 || item.statusEnum_enumText === '启用' || !item.statusEnum)
)
surgeryNameList.value = allSurgeryItems.value
anesthesiaNameList.value = allAnesthesiaItems.value
}).catch(error => {
console.error('加载手术/麻醉选项失败:', error)
console.error('加载麻醉选项失败:', error)
})
}
@@ -1664,6 +1693,8 @@ function reset() {
if (surgeryRef.value) {
surgeryRef.value.resetFields()
}
surgeryNameList.value = allSurgeryItems.value
anesthesiaNameList.value = allAnesthesiaItems.value
}
// 获取状态标签类型

View File

@@ -52,40 +52,43 @@
搜索
</el-button>
</div>
<vxe-table
:row-config="{ isCurrent: true }" :data="encounterList"
border
style="width: 100%"
height="calc(100vh - 300px)"
@cell-click="handleGetReturnDrugList"
>
<vxe-column
field="patientName"
align="center"
title="姓名"
width="130"
show-overflow
/>
<vxe-column
field="genderEnum_enumText"
align="center"
title="性别"
show-overflow
/>
<vxe-column
align="center"
width="140"
title="就诊日期"
show-overflow
<div style="flex: 1; overflow: hidden; margin-top: 10px;">
<vxe-table
:row-config="{ isCurrent: true }"
:data="encounterList"
border
style="width: 100%"
height="100%"
@cell-click="handleGetReturnDrugList"
>
<template #default="scope">
{{
scope.row.receptionTime ? formatDateStr(scope.row.receptionTime, 'YYYY-MM-DD') : '-'
}}
</template>
</vxe-column>
<!-- <vxe-column title="状态" align="center" field="refundEnum_enumText" /> -->
</vxe-table>
<vxe-column
field="patientName"
align="center"
title="姓名"
width="130"
show-overflow
/>
<vxe-column
field="genderEnum_enumText"
align="center"
title="性别"
show-overflow
/>
<vxe-column
align="center"
width="140"
title="就诊日期"
show-overflow
>
<template #default="scope">
{{
scope.row.receptionTime ? formatDateStr(scope.row.receptionTime, 'YYYY-MM-DD') : '-'
}}
</template>
</vxe-column>
<!-- <vxe-column title="状态" align="center" field="refundEnum_enumText" /> -->
</vxe-table>
</div>
</el-card>
<!-- 右侧退药列表 -->
@@ -100,130 +103,132 @@
</div>
</template>
<el-button
type="primary"
:disabled="!selectedMedicines.length"
style="margin-bottom: 10px"
@click="handleReturnDrug(undefined)"
>
确认退药
</el-button>
<el-button
type="primary"
style="margin-bottom: 10px"
@click="handleScan()"
>
扫码
</el-button>
<vxe-table
ref="returnDrugRef"
:data="returDrugList"
style="width: 100%"
height="calc(100vh - 300px)"
border
:span-method="handelSpanMethod"
class="no-hover-table"
@select="handleSelection"
@checkbox-change="handelSelectRows"
>
<vxe-column
type="checkbox"
width="55"
align="center"
/>
<vxe-column
field="itemName"
title="药品名称"
show-overflow
align="center"
/>
<vxe-column
field="totalPrice"
title="总价"
width="100"
align="right"
header-align="center"
<div style="display: flex; gap: 10px; margin-bottom: 10px;">
<el-button
type="primary"
:disabled="!selectedMedicines.length"
@click="handleReturnDrug(undefined)"
>
<template #default="scope">
{{ scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) + ' 元' : '-' }}
</template>
</vxe-column>
<vxe-column
field="lotNumber"
title="批号"
width="180"
align="center"
/>
<vxe-column
field="traceNo"
title="追溯码"
width="180"
align="center"
确认退药
</el-button>
<el-button
type="primary"
@click="handleScan()"
>
<template #default="scope">
<el-input
v-model="scope.row.traceNo"
placeholder="请输入追溯码"
/>
</template>
</vxe-column>
<vxe-column
field="reqStatus_enumText"
title="退药状态"
width="100"
align="center"
扫码
</el-button>
</div>
<div style="flex: 1; overflow: hidden; margin-bottom: 10px;">
<vxe-table
ref="returnDrugRef"
:data="returDrugList"
style="width: 100%"
height="100%"
border
:span-method="handelSpanMethod"
class="no-hover-table"
@checkbox-all="handelSelectRows"
@checkbox-change="handelSelectRows"
>
<template #default="scope">
{{ scope.row.refundEnum_enumText }}
</template>
</vxe-column>
<vxe-column
field="waitingQuantity"
title="退药数量"
width="100"
align="center"
>
<template #default="scope">
<span>{{
scope.row.quantity
? Math.abs(scope.row.quantity) + ' ' + scope.row.unitCode_dictText
: '0' + ' ' + scope.row.unitCode_dictText
}}</span>
</template>
</vxe-column>
<vxe-column
field="doctorName"
title="开单医生"
align="center"
width="180"
/>
<vxe-column
title="操作"
width="100"
align="center"
fixed="right"
>
<template #default="scope">
<el-popconfirm
width="150"
hide-after="10"
title="操作确认"
placement="top-start"
@confirm="handleReturnDrug(scope.row)"
>
<template #reference>
<el-button
type="primary"
link
:disabled="scope.row.refundEnum != 16"
>
退药
</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</vxe-table>
<vxe-column
type="checkbox"
width="55"
align="center"
/>
<vxe-column
field="itemName"
title="药品名称"
show-overflow
align="center"
/>
<vxe-column
field="totalPrice"
title="总价"
width="100"
align="right"
header-align="center"
>
<template #default="scope">
{{ scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) + ' 元' : '-' }}
</template>
</vxe-column>
<vxe-column
field="lotNumber"
title="批号"
width="180"
align="center"
/>
<vxe-column
field="traceNo"
title="追溯码"
width="180"
align="center"
>
<template #default="scope">
<el-input
v-model="scope.row.traceNo"
placeholder="请输入追溯码"
/>
</template>
</vxe-column>
<vxe-column
field="reqStatus_enumText"
title="退药状态"
width="100"
align="center"
>
<template #default="scope">
{{ scope.row.refundEnum_enumText }}
</template>
</vxe-column>
<vxe-column
field="waitingQuantity"
title="退药数量"
width="100"
align="center"
>
<template #default="scope">
<span>{{
scope.row.quantity
? Math.abs(scope.row.quantity) + ' ' + scope.row.unitCode_dictText
: '0' + ' ' + scope.row.unitCode_dictText
}}</span>
</template>
</vxe-column>
<vxe-column
field="doctorName"
title="开单医生"
align="center"
width="180"
/>
<vxe-column
title="操作"
width="100"
align="center"
fixed="right"
>
<template #default="scope">
<el-popconfirm
width="150"
hide-after="10"
title="操作确认"
placement="top-start"
@confirm="handleReturnDrug(scope.row)"
>
<template #reference>
<el-button
type="primary"
link
:disabled="scope.row.refundEnum != 16"
>
退药
</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</vxe-table>
</div>
<!-- 底部操作栏 -->
<div class="footer">
@@ -289,7 +294,7 @@ function initOptions() {
});
}
function handleGetReturnDrugList(row) {
function handleGetReturnDrugList({ row }) {
encounterId.value = row.encounterId;
getReturnDrugList({
encounterId: row.encounterId,
@@ -364,7 +369,7 @@ function handleReturnDrug(row) {
};
});
} else {
saveList = proxy.$refs.returnDrugRef.getSelectionRows().map((item) => {
saveList = proxy.$refs.returnDrugRef.getCheckboxRecords().map((item) => {
return {
requestId: item.requestId,
dispenseId: item.dispenseId,
@@ -388,31 +393,22 @@ function handleReturnDrug(row) {
});
}
// 选择框改变时的处理
function handleSelection(selection, row) {
const isSelected = selection.some((item) => item.dispenseId === row.dispenseId);
returDrugList.value
.filter((item) => {
return item.requestId == row.requestId;
})
.forEach((row) => {
proxy.$refs['returnDrugRef'].toggleCheckboxRow(row, isSelected);
});
function handelSelectRows({ checked, row }) {
if (row) {
returDrugList.value
.filter((item) => item.requestId == row.requestId)
.forEach((r) => {
proxy.$refs['returnDrugRef'].setCheckboxRow(r, checked);
});
}
nextTick(() => {
selectedMedicines.value = proxy.$refs['returnDrugRef'].getSelectionRows();
selectedMedicines.value = proxy.$refs['returnDrugRef'].getCheckboxRecords();
totalAmount.value = selectedMedicines.value.reduce((accumulator, currentRow) => {
return accumulator + (currentRow.totalPrice || 0);
}, 0);
});
}
function handelSelectRows(selection) {
selectedMedicines.value = selection;
totalAmount.value = selectedMedicines.value.reduce((accumulator, currentRow) => {
return accumulator + (currentRow.totalPrice || 0);
}, 0);
}
// 根据 requestId 合并相同行的方法(只合并药品名称和总价列)
function handelSpanMethod({ row, column, rowIndex, columnIndex }) {
// 定义需要合并的列索引
@@ -466,17 +462,31 @@ function handelSpanMethod({ row, column, rowIndex, columnIndex }) {
<style lang="scss" scoped>
.container {
display: flex;
height: 80vh;
height: calc(100vh - 150px);
gap: 16px;
}
.patient-list {
width: 600px;
flex-shrink: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.refund-list {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
}
:deep(.el-card__body) {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 16px;
}
.patient-item {

View File

@@ -247,13 +247,13 @@ export function medicineMatch(data) {
});
}
// ----------------------------------------------门诊退药接口----------------------------------------------------------------------
// ----------------------------------------------住院退药接口----------------------------------------------------------------------
/**
* 获取患者列表
*/
export function getList(queryParams) {
return request({
url: '/pharmacy-manage/return-medicine/return-patient-page',
url: '/pharmacy-manage/inHospital-return-medicine/return-patient-page',
method: 'get',
params: queryParams,
});
@@ -264,7 +264,7 @@ export function getList(queryParams) {
*/
export function getReturnDrugList(params) {
return request({
url: '/pharmacy-manage/return-medicine/medicine-return-list',
url: '/pharmacy-manage/inHospital-return-medicine/medicine-return-list',
method: 'get',
params: params,
});
@@ -275,7 +275,7 @@ export function getReturnDrugList(params) {
*/
export function returnDrug(data) {
return request({
url: '/pharmacy-manage/return-medicine/medicine-return',
url: '/pharmacy-manage/inHospital-return-medicine/medicine-return',
method: 'put',
data: data,
});
@@ -286,7 +286,7 @@ export function returnDrug(data) {
*/
export function init() {
return request({
url: '/pharmacy-manage/return-medicine/init',
url: '/pharmacy-manage/inHospital-return-medicine/init',
method: 'get',
});
}

View File

@@ -1,4 +1,4 @@
<template>
<template>
<div>
<el-row :gutter="24">
<el-col
@@ -187,7 +187,7 @@
style="width: 150px"
>
<el-option
v-for="item in diag_type"
v-for="item in inpatient_diag_category"
:key="item.value"
:label="item.label"
:value="item.value"
@@ -423,7 +423,7 @@ const emits = defineEmits(['diagnosisSave']);
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
// 获取诊断类型字典(住院诊断类别)
const { diag_type } = proxy.useDict('diag_type');
const { inpatient_diag_category } = proxy.useDict('inpatient_diag_category');
const rules = ref({
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],

View File

@@ -95,7 +95,7 @@
style="width: 100%"
>
<el-option
v-for="item in diag_type"
v-for="item in inpatient_diag_category"
:key="item.value"
:label="item.label"
:value="item.value"
@@ -324,7 +324,7 @@ const syndromeSearchkey = ref('')
const syndromeList = ref([])
// 获取诊断类型字典(住院诊断类别)
const { diag_type } = proxy.useDict('diag_type')
const { inpatient_diag_category } = proxy.useDict('inpatient_diag_category')
const filteredSyndromeList = computed(() => {
if (!syndromeSearchkey.value) {

View File

@@ -362,7 +362,7 @@
:popper-style="{ padding: '0' }"
placement="bottom-start"
:visible="scope.row.showPopover"
:width="1200"
:width="950"
>
<adviceBaseList
ref="adviceTableRef"

View File

@@ -1,4 +1,4 @@
<template>
<template>
<div style="height: calc(100vh - 126px)">
<div
style="
@@ -7,6 +7,8 @@
display: flex;
align-items: center;
justify-content: space-between;
overflow-x: auto;
overflow-y: hidden;
"
>
<div style="display: flex; align-items: center; flex-wrap: nowrap; flex-shrink: 0">
@@ -83,7 +85,7 @@
class="ml20"
style="flex-shrink: 0"
type="danger"
:disabled="props.exeStatus != 6"
:disabled="props.exeStatus != 6 || selectedCount === 0"
plain
@click="handleCancel"
>
@@ -174,8 +176,8 @@
:data="item"
border
:header-cell-style="{ background: '#eef9fd !important' }"
@checkbox-change="({ records, row }) => handleRowSelect(records, row, index)"
@checkbox-all="({ records }) => handleSelectAll(records, index)"
@checkbox-change="handleRowSelect"
@checkbox-all="handleSelectAll"
>
<vxe-column
type="checkbox"
@@ -246,24 +248,24 @@
>
<template #default="scope">
<div
v-for="(item, timeIndex) in scope.row.times"
v-for="(timeItem, timeIndex) in scope.row.times"
:key="timeIndex"
style="padding-bottom: 5px"
>
<span>{{ item }}</span>
<span>{{ timeItem }}</span>
<el-checkbox-group
v-model="scope.row.checkedRates[timeIndex]"
style="display: inline-block; margin-left: 15px"
>
<el-checkbox
v-for="(rateItem, rateIndex) in scope.row.rate[item]"
v-for="(rateItem, rateIndex) in scope.row.rate[timeItem]"
:key="rateIndex"
:value="rateItem.rate"
border
size="small"
style="margin-right: 15px"
@change="
(value) => handleRateChange(value, item, rateItem.rate, scope.row, rateItem)
(value) => handleRateChange(value, timeItem, rateItem.rate, scope.row, rateItem)
"
>
{{ rateItem.rate }}
@@ -292,7 +294,7 @@ import {patientInfoList} from '../../components/store/patient.js';
import {lotNumberMatch} from '@/api/public';
import {formatDateStr} from '@/utils/index';
import {RequestStatus} from '@/utils/medicalConstants';
import {getCurrentInstance, nextTick, ref, provide} from 'vue';
import {getCurrentInstance, nextTick, ref, provide, computed} from 'vue';
/** 请求状态 → 医嘱状态映射表(开具/签发/校对) */
const REQUEST_STATUS_DISPLAY = {
@@ -380,8 +382,9 @@ const therapyEnum = ref(undefined);
const { proxy } = getCurrentInstance();
const loading = ref(false);
const chooseAll = ref(false);
// 独立维护选中行ID集合避免vxe-table内部selection状态异常导致联动全选
const selectedRowIds = ref(new Set());
// 独立维护选中行ID列表避免vxe-table内部selection状态异常导致联动全选
// 使用数组而非Set确保Vue 3响应式系统能可靠追踪变更
const selectedRowIds = ref([]);
const props = defineProps({
exeStatus: {
type: Number,
@@ -393,6 +396,15 @@ const props = defineProps({
},
});
const selectedCount = computed(() => selectedRowIds.value.length);
function getTableRef(index) {
const tableRef = proxy.$refs['tableRef' + index];
if (!tableRef) return null;
return Array.isArray(tableRef) ? tableRef[0] : tableRef;
}
function handleRadioChange() {
handleGetPrescription();
}
@@ -414,7 +426,7 @@ function normalizeDayTimeHm(part) {
function handleGetPrescription(skipAutoSelectAll = false) {
if (patientInfoList.value.length > 0) {
// 刷新前保存当前选中状态,刷新后恢复(用于执行/不执行后的列表更新)
const previousSelectedIds = skipAutoSelectAll ? new Set(selectedRowIds.value) : null;
const previousSelectedIds = skipAutoSelectAll ? [...selectedRowIds.value] : null;
loading.value = true;
let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(',');
getPrescriptionList({
@@ -585,14 +597,14 @@ function handleGetPrescription(skipAutoSelectAll = false) {
if (skipAutoSelectAll && previousSelectedIds) {
// 执行/不执行后刷新只恢复父checkbox行选中子checkbox保持未选中
nextTick(() => {
selectedRowIds.value.clear();
selectedRowIds.value = [];
prescriptionList.value.forEach((item, index) => {
const tableRef = proxy.$refs['tableRef' + index];
const tableRef = getTableRef(index);
item.forEach((row) => {
if (previousSelectedIds.has(row.requestId)) {
selectedRowIds.value.add(row.requestId);
if (tableRef && tableRef[0]) {
tableRef[0].setCheckboxRow([row], true);
if (previousSelectedIds.includes(row.requestId)) {
if (!selectedRowIds.value.includes(row.requestId)) selectedRowIds.value = [...selectedRowIds.value, row.requestId];
if (tableRef) {
tableRef.setCheckboxRow([row], true);
}
}
// 清空子checkbox选中状态避免刷新后自动勾选
@@ -622,7 +634,7 @@ function handleGetPrescription(skipAutoSelectAll = false) {
});
} else {
prescriptionList.value = [];
selectedRowIds.value.clear();
selectedRowIds.value = [];
loading.value = false;
// proxy.$message.warning('请选择患者');
}
@@ -749,7 +761,7 @@ function getSelectRows() {
const list = [];
prescriptionList.value.forEach((item) => {
item.forEach((row) => {
if (selectedRowIds.value.has(row.requestId)) {
if (selectedRowIds.value.includes(row.requestId)) {
list.push(row);
}
});
@@ -823,16 +835,16 @@ function handleRateChange(value, date, time, row, rateItem) {
function handelSwicthChange(value) {
prescriptionList.value.forEach((item, index) => {
const tableRef = proxy.$refs['tableRef' + index];
if (tableRef && tableRef[0]) {
const tableRef = getTableRef(index);
if (tableRef) {
// 批量设置选中/取消选中setCheckboxRow 显式设置,比 toggleCheckboxRow 更可靠)
tableRef[0].setCheckboxRow(item, value);
tableRef.setCheckboxRow(item, value);
item.forEach((row) => {
if (value) {
selectedRowIds.value.add(row.requestId);
if (!selectedRowIds.value.includes(row.requestId)) selectedRowIds.value = [...selectedRowIds.value, row.requestId];
selectAllCheckboxesInRow(row);
} else {
selectedRowIds.value.delete(row.requestId);
selectedRowIds.value = selectedRowIds.value.filter(id => id !== row.requestId);
unselectAllCheckboxesInRow(row);
}
});
@@ -843,14 +855,14 @@ function handelSwicthChange(value) {
// 默认选中全部行
function defaultSelectAllRows() {
// 清空并重建选中集合
selectedRowIds.value.clear();
selectedRowIds.value = [];
prescriptionList.value.forEach((item, index) => {
const tableRef = proxy.$refs['tableRef' + index];
if (tableRef && tableRef[0]) {
const tableRef = getTableRef(index);
if (tableRef) {
// 批量选中该表格的所有行setCheckboxRow 显式设置选中状态,比 toggleCheckboxRow 更可靠)
tableRef[0].setCheckboxRow(item, true);
tableRef.setCheckboxRow(item, true);
item.forEach((row) => {
selectedRowIds.value.add(row.requestId);
if (!selectedRowIds.value.includes(row.requestId)) selectedRowIds.value = [...selectedRowIds.value, row.requestId];
// 同时选中该行内部的所有checkbox
selectAllCheckboxesInRow(row);
});
@@ -926,18 +938,18 @@ function checkAndToggleRowSelection(row) {
prescriptionList.value.forEach((item, tableIndex) => {
const rowIndex = item.findIndex((r) => r.requestId === row.requestId);
if (rowIndex !== -1) {
const tableRef = proxy.$refs['tableRef' + tableIndex];
if (tableRef && tableRef[0]) {
const tableRef = getTableRef(tableIndex);
if (tableRef) {
const isAllSelected = isAllCheckboxesSelected(row);
const isCurrentlySelected = selectedRowIds.value.has(row.requestId);
const isCurrentlySelected = selectedRowIds.value.includes(row.requestId);
// 根据checkbox状态更新表格行选中状态使用 setCheckboxRow 显式设置,避免 toggleCheckboxRow 翻转方向不确定)
if (isAllSelected && !isCurrentlySelected) {
selectedRowIds.value.add(row.requestId);
tableRef[0].setCheckboxRow([row], true);
if (!selectedRowIds.value.includes(row.requestId)) selectedRowIds.value = [...selectedRowIds.value, row.requestId];
tableRef.setCheckboxRow([row], true);
} else if (!isAllSelected && isCurrentlySelected) {
selectedRowIds.value.delete(row.requestId);
tableRef[0].setCheckboxRow([row], false);
selectedRowIds.value = selectedRowIds.value.filter(id => id !== row.requestId);
tableRef.setCheckboxRow([row], false);
}
}
}
@@ -954,49 +966,39 @@ function findOriginalRow(requestId) {
return null;
}
// 处理表格行选中事件
function handleRowSelect(selection, row, tableIndex) {
// 回查原始行引用,避免修改 vxe-table 代理对象导致 el-checkbox 不更新
const originalRow = findOriginalRow(row.requestId);
if (!originalRow) return;
// 处理表格行选中事件(不依赖事件参数,通过 getCheckboxRecords 查询真实状态)
function handleRowSelect() {
// 从所有表格的内部状态获取当前选中行
const selectedIds = new Set();
prescriptionList.value.forEach((item, index) => {
const tableRef = getTableRef(index);
if (tableRef) {
tableRef.getCheckboxRecords().forEach((row) => {
selectedIds.add(row.requestId);
});
}
});
selectedRowIds.value = [...selectedIds];
const isSelected = selection.some((item) => item.requestId === row.requestId);
// 同步子checkbox状态
prescriptionList.value.forEach((item) => {
item.forEach((row) => {
const originalRow = findOriginalRow(row.requestId);
if (!originalRow) return;
if (selectedIds.has(row.requestId)) {
selectAllCheckboxesInRow(originalRow);
} else {
unselectAllCheckboxesInRow(originalRow);
}
});
});
if (isSelected) {
selectedRowIds.value.add(row.requestId);
// 选中行时选中该行内部的所有checkbox
selectAllCheckboxesInRow(originalRow);
} else {
selectedRowIds.value.delete(row.requestId);
// 取消选中行时取消选中该行内部的所有checkbox
unselectAllCheckboxesInRow(originalRow);
}
// 更新全选开关状态
updateChooseAllStatus();
}
// 处理表格全选事件
function handleSelectAll(selection, tableIndex) {
const tableData = prescriptionList.value[tableIndex];
if (!tableData) return;
if (selection.length > 0) {
// 全选时选中所有行内部的所有checkbox
tableData.forEach((row) => {
selectedRowIds.value.add(row.requestId);
selectAllCheckboxesInRow(row);
});
} else {
// 取消全选时取消选中所有行内部的所有checkbox
tableData.forEach((row) => {
selectedRowIds.value.delete(row.requestId);
unselectAllCheckboxesInRow(row);
});
}
// 更新全选开关状态
updateChooseAllStatus();
// 处理表格全选事件(不依赖事件参数,通过 getCheckboxRecords 查询真实状态)
function handleSelectAll() {
handleRowSelect();
}
// 更新全选开关状态
@@ -1004,7 +1006,7 @@ function updateChooseAllStatus() {
let allSelected = true;
prescriptionList.value.forEach((item) => {
item.forEach((row) => {
if (!selectedRowIds.value.has(row.requestId)) {
if (!selectedRowIds.value.includes(row.requestId)) {
allSelected = false;
}
});

View File

@@ -53,8 +53,8 @@
<!-- 使用模板引用 -->
<PrescriptionList
:ref="(el) => setPrescriptionRef(el, tab.name)"
:exe-status="exeStatus"
:request-status="requestStatus"
:exe-status="tab.exeStatus"
:request-status="tab.requestStatus"
/>
</el-tab-pane>
</el-tabs>
@@ -79,10 +79,10 @@ const prescriptionRefs = ref({});
// 定义处方列表tabs配置
const prescriptionTabs = [
{ label: '待执行', name: 'preparation' },
{ label: '已执行', name: 'completed' },
{ label: '不执行', name: 'stopped' },
{ label: '取消执行', name: 'cancel' },
{ label: '待执行', name: 'preparation', exeStatus: 1, requestStatus: RequestStatus.COMPLETED },
{ label: '已执行', name: 'completed', exeStatus: 6, requestStatus: RequestStatus.COMPLETED },
{ label: '不执行', name: 'stopped', exeStatus: 5, requestStatus: RequestStatus.COMPLETED },
{ label: '取消', name: 'cancel', exeStatus: 9, requestStatus: RequestStatus.CANCELLED },
];
// 设置处方组件引用