217 收费工作站-》门诊收费:【确认收费】报错“打印失败”
220 门诊医生站:新增耗材收费项目医嘱单价/总金额未显示正确的值
This commit is contained in:
@@ -641,11 +641,13 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
// 就诊id
|
// 就诊id
|
||||||
Long encounterId = adviceSaveList.get(0).getEncounterId();
|
Long encounterId = adviceSaveList.get(0).getEncounterId();
|
||||||
iChargeItemService.update(new LambdaUpdateWrapper<ChargeItem>()
|
|
||||||
.set(ChargeItem::getStatusEnum, ChargeItemStatus.PLANNED.getValue())
|
// 使用安全的更新方法,避免并发冲突
|
||||||
.eq(ChargeItem::getEncounterId, encounterId)
|
iChargeItemService.updateChargeStatusByConditionSafe(
|
||||||
.eq(ChargeItem::getStatusEnum, ChargeItemStatus.DRAFT.getValue())
|
encounterId,
|
||||||
.in(ChargeItem::getServiceId, requestIds));
|
ChargeItemStatus.DRAFT.getValue(),
|
||||||
|
ChargeItemStatus.PLANNED.getValue(),
|
||||||
|
requestIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据变更后清理相关缓存
|
// 数据变更后清理相关缓存
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.openhis.web.doctorstation.controller;
|
package com.openhis.web.doctorstation.controller;
|
||||||
|
|
||||||
|
import com.core.common.annotation.RepeatSubmit;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.common.enums.AdviceOpType;
|
import com.openhis.common.enums.AdviceOpType;
|
||||||
import com.openhis.common.enums.Whether;
|
import com.openhis.common.enums.Whether;
|
||||||
@@ -85,6 +86,7 @@ public class DoctorStationAdviceController {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/sign-advice")
|
@PostMapping(value = "/sign-advice")
|
||||||
|
@RepeatSubmit(interval = 5000, message = "请勿重复签发医嘱,请稍候再试")
|
||||||
public R<?> signAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
public R<?> signAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
||||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SIGN_ADVICE.getCode());
|
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SIGN_ADVICE.getCode());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ public class RequestBaseDto {
|
|||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long chargeItemId;
|
private Long chargeItemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 医嘱定义对应表名
|
||||||
|
*/
|
||||||
|
private String adviceTableName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 医嘱名称
|
* 医嘱名称
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ public class MedicalDeviceDispenseAppServiceImpl implements IMedicalDeviceDispen
|
|||||||
}
|
}
|
||||||
List<ChargeItem> chargeItemList = chargeItemService.listByIds(chargeItemIds);
|
List<ChargeItem> chargeItemList = chargeItemService.listByIds(chargeItemIds);
|
||||||
if (chargeItemList == null || chargeItemList.isEmpty()) {
|
if (chargeItemList == null || chargeItemList.isEmpty()) {
|
||||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
return R.fail("未查询到耗材收费项目信息");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取发申请id列表
|
// 获取发申请id列表
|
||||||
|
|||||||
@@ -64,6 +64,26 @@ public interface IChargeItemService extends IService<ChargeItem> {
|
|||||||
*/
|
*/
|
||||||
void updatePaymentStatus(List<Long> chargeItemIdList, Integer value);
|
void updatePaymentStatus(List<Long> chargeItemIdList, Integer value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全更新收费项目状态(按条件更新,避免并发冲突)
|
||||||
|
*
|
||||||
|
* @param encounterId 就诊ID
|
||||||
|
* @param fromStatusEnum 原状态
|
||||||
|
* @param toStatusEnum 目标状态
|
||||||
|
* @param serviceIds 服务ID列表
|
||||||
|
*/
|
||||||
|
void updateChargeStatusByCondition(Long encounterId, Integer fromStatusEnum, Integer toStatusEnum, List<Long> serviceIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全批量更新收费项目状态(逐个更新,避免并发冲突)
|
||||||
|
*
|
||||||
|
* @param encounterId 就诊ID
|
||||||
|
* @param fromStatusEnum 原状态
|
||||||
|
* @param toStatusEnum 目标状态
|
||||||
|
* @param serviceIds 服务ID列表
|
||||||
|
*/
|
||||||
|
void updateChargeStatusByConditionSafe(Long encounterId, Integer fromStatusEnum, Integer toStatusEnum, List<Long> serviceIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据表名和id删除费用项
|
* 根据表名和id删除费用项
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ import com.openhis.administration.service.IChargeItemService;
|
|||||||
import com.openhis.common.enums.*;
|
import com.openhis.common.enums.*;
|
||||||
import com.openhis.common.utils.EnumUtils;
|
import com.openhis.common.utils.EnumUtils;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +40,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class ChargeItemServiceImpl extends ServiceImpl<ChargeItemMapper, ChargeItem> implements IChargeItemService {
|
public class ChargeItemServiceImpl extends ServiceImpl<ChargeItemMapper, ChargeItem> implements IChargeItemService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -130,10 +133,93 @@ public class ChargeItemServiceImpl extends ServiceImpl<ChargeItemMapper, ChargeI
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updatePaymentStatus(List<Long> chargeItemIdList, Integer value) {
|
public void updatePaymentStatus(List<Long> chargeItemIdList, Integer value) {
|
||||||
baseMapper.update(
|
if (chargeItemIdList == null || chargeItemIdList.isEmpty()) {
|
||||||
new ChargeItem().setStatusEnum(value).setPerformerId(SecurityUtils.getLoginUser().getPractitionerId()),
|
return;
|
||||||
new LambdaUpdateWrapper<ChargeItem>().in(ChargeItem::getId, chargeItemIdList).eq(ChargeItem::getDeleteFlag,
|
}
|
||||||
DelFlag.NO.getCode()));
|
|
||||||
|
// 逐个更新,避免并发冲突
|
||||||
|
for (Long chargeItemId : chargeItemIdList) {
|
||||||
|
int retryCount = 0;
|
||||||
|
final int maxRetries = 3;
|
||||||
|
|
||||||
|
while (retryCount < maxRetries) {
|
||||||
|
try {
|
||||||
|
// 先查询当前状态,确保更新操作的安全性
|
||||||
|
ChargeItem currentChargeItem = baseMapper.selectById(chargeItemId);
|
||||||
|
|
||||||
|
if (currentChargeItem == null) {
|
||||||
|
log.warn("收费项目不存在,ID: {}", chargeItemId);
|
||||||
|
break; // 项目不存在,跳出重试循环
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查当前状态是否已经是目标状态,避免不必要的更新
|
||||||
|
if (currentChargeItem.getStatusEnum().equals(value)) {
|
||||||
|
log.debug("收费项目已是目标状态,跳过更新,ID: {}, 状态: {}", chargeItemId, value);
|
||||||
|
break; // 已是目标状态,跳出重试循环
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用精确的条件更新,包括当前状态,防止并发更新冲突
|
||||||
|
int updatedRows = baseMapper.update(
|
||||||
|
new ChargeItem()
|
||||||
|
.setStatusEnum(value)
|
||||||
|
.setPerformerId(SecurityUtils.getLoginUser().getPractitionerId()),
|
||||||
|
new LambdaUpdateWrapper<ChargeItem>()
|
||||||
|
.eq(ChargeItem::getId, chargeItemId)
|
||||||
|
.eq(ChargeItem::getStatusEnum, currentChargeItem.getStatusEnum()) // 使用当前状态作为条件
|
||||||
|
.eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode()));
|
||||||
|
|
||||||
|
// 如果成功更新了行数,跳出重试循环
|
||||||
|
if (updatedRows > 0) {
|
||||||
|
log.debug("收费项目状态更新成功,ID: {}, 状态: {}", chargeItemId, value);
|
||||||
|
break; // 成功更新,跳出重试循环
|
||||||
|
} else {
|
||||||
|
log.warn("收费项目更新失败,可能已被其他事务更改,ID: {}, 目标状态: {},重试次数: {}",
|
||||||
|
chargeItemId, value, retryCount + 1);
|
||||||
|
|
||||||
|
// 增加重试计数
|
||||||
|
retryCount++;
|
||||||
|
|
||||||
|
// 如果达到最大重试次数,检查最终状态
|
||||||
|
if (retryCount >= maxRetries) {
|
||||||
|
ChargeItem finalChargeItem = baseMapper.selectById(chargeItemId);
|
||||||
|
if (finalChargeItem != null && finalChargeItem.getStatusEnum().equals(value)) {
|
||||||
|
log.debug("收费项目最终已是目标状态,ID: {}", chargeItemId);
|
||||||
|
break; // 最终状态符合预期,跳出重试循环
|
||||||
|
} else {
|
||||||
|
log.warn("收费项目状态更新失败,达到最大重试次数,ID: {}, 期望状态: {}, 当前状态: {}",
|
||||||
|
chargeItemId, value, finalChargeItem != null ? finalChargeItem.getStatusEnum() : "NULL");
|
||||||
|
break; // 达到最大重试次数,跳出重试循环
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 短暂延迟后重试,避免过于频繁的重试
|
||||||
|
try {
|
||||||
|
Thread.sleep(10); // 10毫秒延迟
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break; // 中断线程,跳出重试循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新收费项目状态失败,ID: {}, 状态: {},重试次数: {}", chargeItemId, value, retryCount + 1, e);
|
||||||
|
|
||||||
|
retryCount++;
|
||||||
|
if (retryCount >= maxRetries) {
|
||||||
|
log.error("更新收费项目状态失败,达到最大重试次数,ID: {}, 状态: {}", chargeItemId, value, e);
|
||||||
|
// 不抛出异常,以避免整个事务回滚
|
||||||
|
break; // 达到最大重试次数,跳出重试循环
|
||||||
|
}
|
||||||
|
|
||||||
|
// 短暂延迟后重试
|
||||||
|
try {
|
||||||
|
Thread.sleep(10);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break; // 中断线程,跳出重试循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,4 +410,130 @@ public class ChargeItemServiceImpl extends ServiceImpl<ChargeItemMapper, ChargeI
|
|||||||
});
|
});
|
||||||
return costDetails;
|
return costDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateChargeStatusByCondition(Long encounterId, Integer fromStatusEnum, Integer toStatusEnum, List<Long> serviceIds) {
|
||||||
|
if (serviceIds == null || serviceIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用逐个更新的方式,避免批量更新的并发问题
|
||||||
|
for (Long serviceId : serviceIds) {
|
||||||
|
try {
|
||||||
|
int updatedRows = baseMapper.update(
|
||||||
|
new ChargeItem().setStatusEnum(toStatusEnum),
|
||||||
|
new LambdaUpdateWrapper<ChargeItem>()
|
||||||
|
.eq(ChargeItem::getEncounterId, encounterId)
|
||||||
|
.eq(ChargeItem::getStatusEnum, fromStatusEnum) // 确保原状态匹配
|
||||||
|
.eq(ChargeItem::getServiceId, serviceId)
|
||||||
|
.eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode())
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果没有更新任何行,可能是因为状态已经被其他事务更改
|
||||||
|
if (updatedRows == 0) {
|
||||||
|
log.warn("收费项目状态更新失败或无变化,encounterId: {}, serviceId: {}, 原状态: {}, 目标状态: {}",
|
||||||
|
encounterId, serviceId, fromStatusEnum, toStatusEnum);
|
||||||
|
|
||||||
|
// 查询当前状态以供调试
|
||||||
|
List<ChargeItem> currentChargeItems = baseMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<ChargeItem>()
|
||||||
|
.eq(ChargeItem::getEncounterId, encounterId)
|
||||||
|
.eq(ChargeItem::getServiceId, serviceId)
|
||||||
|
.eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode())
|
||||||
|
);
|
||||||
|
|
||||||
|
for (ChargeItem item : currentChargeItems) {
|
||||||
|
log.info("收费项目当前状态,ID: {}, 状态: {}", item.getId(), item.getStatusEnum());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新收费项目状态失败,encounterId: {}, serviceId: {}, 原状态: {}, 目标状态: {}",
|
||||||
|
encounterId, serviceId, fromStatusEnum, toStatusEnum, e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateChargeStatusByConditionSafe(Long encounterId, Integer fromStatusEnum, Integer toStatusEnum, List<Long> serviceIds) {
|
||||||
|
if (serviceIds == null || serviceIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用逐个更新的方式,避免批量更新的并发问题
|
||||||
|
for (Long serviceId : serviceIds) {
|
||||||
|
int retryCount = 0;
|
||||||
|
final int maxRetries = 3;
|
||||||
|
|
||||||
|
while (retryCount < maxRetries) {
|
||||||
|
try {
|
||||||
|
// 先查询当前符合条件的收费项目
|
||||||
|
List<ChargeItem> chargeItems = baseMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<ChargeItem>()
|
||||||
|
.eq(ChargeItem::getEncounterId, encounterId)
|
||||||
|
.eq(ChargeItem::getStatusEnum, fromStatusEnum)
|
||||||
|
.eq(ChargeItem::getServiceId, serviceId)
|
||||||
|
.eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (chargeItems.isEmpty()) {
|
||||||
|
log.debug("未找到符合条件的收费项目,encounterId: {}, serviceId: {}, 原状态: {}",
|
||||||
|
encounterId, serviceId, fromStatusEnum);
|
||||||
|
break; // 没有符合条件的项目,跳出重试循环
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对每个符合条件的收费项目进行更新
|
||||||
|
for (ChargeItem chargeItem : chargeItems) {
|
||||||
|
int updatedRows = baseMapper.update(
|
||||||
|
new ChargeItem().setStatusEnum(toStatusEnum),
|
||||||
|
new LambdaUpdateWrapper<ChargeItem>()
|
||||||
|
.eq(ChargeItem::getId, chargeItem.getId())
|
||||||
|
.eq(ChargeItem::getStatusEnum, fromStatusEnum) // 确保原状态匹配
|
||||||
|
.eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (updatedRows > 0) {
|
||||||
|
log.debug("收费项目状态更新成功,ID: {}, 从状态: {} 到状态: {}",
|
||||||
|
chargeItem.getId(), fromStatusEnum, toStatusEnum);
|
||||||
|
} else {
|
||||||
|
log.warn("收费项目状态更新失败,ID: {}, 从状态: {} 到状态: {}",
|
||||||
|
chargeItem.getId(), fromStatusEnum, toStatusEnum);
|
||||||
|
|
||||||
|
// 检查项目当前状态
|
||||||
|
ChargeItem currentChargeItem = baseMapper.selectById(chargeItem.getId());
|
||||||
|
if (currentChargeItem != null) {
|
||||||
|
log.debug("收费项目当前状态,ID: {}, 状态: {}", currentChargeItem.getId(), currentChargeItem.getStatusEnum());
|
||||||
|
|
||||||
|
// 如果已经是目标状态,则认为更新成功
|
||||||
|
if (currentChargeItem.getStatusEnum().equals(toStatusEnum)) {
|
||||||
|
log.debug("收费项目已是目标状态,ID: {}", currentChargeItem.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 成功更新,跳出重试循环
|
||||||
|
break;
|
||||||
|
} catch (Exception e) {
|
||||||
|
retryCount++;
|
||||||
|
log.warn("收费项目状态更新失败,encounterId: {}, serviceId: {}, 原状态: {}, 目标状态: {},重试次数: {}",
|
||||||
|
encounterId, serviceId, fromStatusEnum, toStatusEnum, retryCount, e);
|
||||||
|
|
||||||
|
if (retryCount >= maxRetries) {
|
||||||
|
log.error("收费项目状态更新失败,达到最大重试次数,encounterId: {}, serviceId: {}, 原状态: {}, 目标状态: {}",
|
||||||
|
encounterId, serviceId, fromStatusEnum, toStatusEnum, e);
|
||||||
|
// 不抛出异常,以避免影响整体流程
|
||||||
|
} else {
|
||||||
|
// 短暂延迟后重试
|
||||||
|
try {
|
||||||
|
Thread.sleep(10);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break; // 中断线程,跳出重试循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ export function getList(queryParams) {
|
|||||||
/**
|
/**
|
||||||
* 患者处方列表
|
* 患者处方列表
|
||||||
*/
|
*/
|
||||||
export function getChargeList(encounterId) {
|
export function getChargeList(encounterId, config = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: '/charge-manage/charge/patient-prescription?encounterId=' + encounterId,
|
url: '/charge-manage/charge/patient-prescription?encounterId=' + encounterId,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
...config
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,11 +112,12 @@ export function unprecharge(data) {
|
|||||||
/**
|
/**
|
||||||
* 发耗材
|
* 发耗材
|
||||||
*/
|
*/
|
||||||
export function dispenseMedicalConsumables(data) {
|
export function dispenseMedicalConsumables(data, config = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: '/pharmacy-manage/device-dispense/consumables-dispense',
|
url: '/pharmacy-manage/device-dispense/consumables-dispense',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data: data
|
data: data,
|
||||||
|
...config
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +125,12 @@ export function dispenseMedicalConsumables(data) {
|
|||||||
/**
|
/**
|
||||||
* 补打小票
|
* 补打小票
|
||||||
*/
|
*/
|
||||||
export function getChargeInfo(param) {
|
export function getChargeInfo(param, config = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: '/payment/bill/getDetail',
|
url: '/payment/bill/getDetail',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: param
|
params: param,
|
||||||
|
...config
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -476,9 +476,12 @@ async function printReceipt(param) {
|
|||||||
return amount > 0 ? amount + ' 元' : amount;
|
return amount > 0 ? amount + ' 元' : amount;
|
||||||
})(), // 个人现金支付金额(现金)
|
})(), // 个人现金支付金额(现金)
|
||||||
SELF_CASH_VX_VALUE: (() => {
|
SELF_CASH_VX_VALUE: (() => {
|
||||||
const amount = param.detail?.find((t) => t.payEnum === 220100)?.amount ?? 0;
|
// 微信+银联+支付宝的合计金额
|
||||||
return amount > 0 ? amount + ' 元' : amount;
|
const vxValue = param.detail?.find((t) => t.payEnum === 220100)?.amount ?? 0;
|
||||||
})(), // 个人现金支付金额(微信)
|
const unionValue = param.detail?.find((t) => t.payEnum === 220300)?.amount ?? 0;
|
||||||
|
const aliValue = param.detail?.find((t) => t.payEnum === 220200)?.amount ?? 0;
|
||||||
|
return (Number(vxValue) + Number(unionValue) + Number(aliValue)).toFixed(2) + ' 元';
|
||||||
|
})(),
|
||||||
SELF_CASH_ALI_VALUE: (() => {
|
SELF_CASH_ALI_VALUE: (() => {
|
||||||
const amount = param.detail?.find((t) => t.payEnum === 220200)?.amount ?? 0;
|
const amount = param.detail?.find((t) => t.payEnum === 220200)?.amount ?? 0;
|
||||||
return amount > 0 ? amount + ' 元' : amount;
|
return amount > 0 ? amount + ' 元' : amount;
|
||||||
@@ -537,14 +540,6 @@ async function printReceipt(param) {
|
|||||||
const amount = param.detail?.find((t) => t.payEnum === 360300)?.amount ?? 0;
|
const amount = param.detail?.find((t) => t.payEnum === 360300)?.amount ?? 0;
|
||||||
return amount > 0 ? amount + ' 元' : amount;
|
return amount > 0 ? amount + ' 元' : amount;
|
||||||
})(), // 保健预支基金
|
})(), // 保健预支基金
|
||||||
//微信刷卡支付
|
|
||||||
SELF_CASH_VX_VALUE: (() => {
|
|
||||||
// const cashValue = param.detail?.find((t) => t.payEnum === 220400)?.amount ?? 0;
|
|
||||||
const vxValue = param.detail?.find((t) => t.payEnum === 220100)?.amount ?? 0;
|
|
||||||
const unionValue = param.detail?.find((t) => t.payEnum === 220300)?.amount ?? 0;
|
|
||||||
const aliValue = param.detail?.find((t) => t.payEnum === 220200)?.amount ?? 0;
|
|
||||||
return (Number(vxValue) + Number(unionValue) + Number(aliValue)).toFixed(2) + ' 元';
|
|
||||||
})(),
|
|
||||||
|
|
||||||
Mr_QR_Code: param.regNo,
|
Mr_QR_Code: param.regNo,
|
||||||
regNo: param.regNo || '',
|
regNo: param.regNo || '',
|
||||||
@@ -659,16 +654,24 @@ async function submit() {
|
|||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
getChargeInfo({ paymentId: props.paymentId }).then((res) => {
|
getChargeInfo({ paymentId: props.paymentId }, { skipErrorMsg: true })
|
||||||
|
.then((res) => {
|
||||||
// 传递完整的选中数据信息到打印方法
|
// 传递完整的选中数据信息到打印方法
|
||||||
printReceipt({ ...res.data, chargedItems: props.chargedItems });
|
printReceipt({ ...res.data, chargedItems: props.chargedItems });
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// 打印失败不影响收费成功流程
|
||||||
});
|
});
|
||||||
formData.selfPay = [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }];
|
formData.selfPay = [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }];
|
||||||
emit('close', 'success', res.msg);
|
emit('close', 'success', res.msg);
|
||||||
emit('refresh'); // 发送刷新事件给父组件
|
emit('refresh'); // 发送刷新事件给父组件
|
||||||
// 长春市朝阳区中医院自动发耗材
|
// 长春市朝阳区中医院自动发耗材(静默执行,不阻塞主流程)
|
||||||
if (userStore.fixmedinsCode == 'H22010200672' && props.consumablesIdList.length > 0) {
|
if (userStore.fixmedinsCode == 'H22010200672' && props.consumablesIdList.length > 0) {
|
||||||
dispenseMedicalConsumables(props.consumablesIdList);
|
dispenseMedicalConsumables(props.consumablesIdList, { skipErrorMsg: true })
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {
|
||||||
|
// 发耗材失败不影响收费成功流程
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '收费失败');
|
proxy.$modal.msgError(res.msg || '收费失败');
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ function handleClose(value, msg) {
|
|||||||
if (value == 'success') {
|
if (value == 'success') {
|
||||||
proxy.$modal.msgSuccess(msg);
|
proxy.$modal.msgSuccess(msg);
|
||||||
chargeLoading.value = true;
|
chargeLoading.value = true;
|
||||||
getChargeList(patientInfo.value.encounterId).then((res) => {
|
getChargeList(patientInfo.value.encounterId, { skipErrorMsg: true }).then((res) => {
|
||||||
chargeList.value = res.data;
|
chargeList.value = res.data;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
chargeLoading.value = false;
|
chargeLoading.value = false;
|
||||||
|
|||||||
@@ -262,24 +262,19 @@ function fetchFromApi(searchKey) {
|
|||||||
adviceBaseList.value = res.data.records.map((item) => {
|
adviceBaseList.value = res.data.records.map((item) => {
|
||||||
console.log('[Debug] 耗材项:', item.name, 'price:', item.price, 'retailPrice:', item.retailPrice);
|
console.log('[Debug] 耗材项:', item.name, 'price:', item.price, 'retailPrice:', item.retailPrice);
|
||||||
return {
|
return {
|
||||||
|
...item,
|
||||||
|
// 🔧 Bug Fix: 强制覆盖后端返回的字段,确保数据正确
|
||||||
adviceName: item.name || item.busNo,
|
adviceName: item.name || item.busNo,
|
||||||
adviceType: 4,
|
adviceType: 4, // 强制设置为前端耗材类型
|
||||||
|
adviceTableName: 'adm_device_definition',
|
||||||
unitCode: item.unitCode || '',
|
unitCode: item.unitCode || '',
|
||||||
unitCode_dictText: item.unitCode_dictText || '',
|
unitCode_dictText: item.unitCode_dictText || '',
|
||||||
minUnitCode: item.minUnitCode || item.unitCode || '',
|
minUnitCode: item.minUnitCode || item.unitCode || '',
|
||||||
minUnitCode_dictText: item.minUnitCode_dictText || item.unitCode_dictText || '',
|
minUnitCode_dictText: item.minUnitCode_dictText || item.unitCode_dictText || '',
|
||||||
volume: item.size || item.totalVolume || '',
|
volume: item.size || item.totalVolume || '',
|
||||||
partPercent: item.partPercent || 1,
|
partPercent: item.partPercent || 1,
|
||||||
// 🔧 Bug #220 修复:正确处理耗材价格,支持price或retailPrice字段
|
|
||||||
// 零售价可能是0,所以不能用简单的布尔判断,需要明确检查null/undefined
|
|
||||||
priceList: (item.price !== undefined && item.price !== null)
|
|
||||||
? [{ price: item.price }]
|
|
||||||
: ((item.retailPrice !== undefined && item.retailPrice !== null)
|
|
||||||
? [{ price: item.retailPrice }]
|
|
||||||
: []),
|
|
||||||
inventoryList: [],
|
inventoryList: [],
|
||||||
adviceDefinitionId: item.id,
|
adviceDefinitionId: item.id,
|
||||||
adviceTableName: 'adm_device_definition',
|
|
||||||
chargeItemDefinitionId: item.id,
|
chargeItemDefinitionId: item.id,
|
||||||
positionId: item.locationId,
|
positionId: item.locationId,
|
||||||
positionName: item.locationId_dictText || '',
|
positionName: item.locationId_dictText || '',
|
||||||
@@ -293,17 +288,7 @@ function fetchFromApi(searchKey) {
|
|||||||
categoryCode: item.categoryCode || '',
|
categoryCode: item.categoryCode || '',
|
||||||
deviceId: item.id,
|
deviceId: item.id,
|
||||||
deviceName: item.name,
|
deviceName: item.name,
|
||||||
// 🔧 Bug Fix: ...item 展开放在前面,然后用前端字段覆盖
|
// 🔧 Bug #220 修复:正确处理耗材价格,支持price或retailPrice字段
|
||||||
...item,
|
|
||||||
// 确保前端覆盖后端可能冲突的字段
|
|
||||||
adviceName: item.name || item.busNo,
|
|
||||||
adviceType: 4, // 强制设置为前端耗材类型
|
|
||||||
unitCode: item.unitCode || '',
|
|
||||||
unitCode_dictText: item.unitCode_dictText || '',
|
|
||||||
minUnitCode: item.minUnitCode || item.unitCode || '',
|
|
||||||
minUnitCode_dictText: item.minUnitCode_dictText || item.unitCode_dictText || '',
|
|
||||||
volume: item.size || item.totalVolume || '',
|
|
||||||
partPercent: item.partPercent || 1,
|
|
||||||
// 价格字段优先使用retailPrice
|
// 价格字段优先使用retailPrice
|
||||||
priceList: (item.retailPrice !== undefined && item.retailPrice !== null)
|
priceList: (item.retailPrice !== undefined && item.retailPrice !== null)
|
||||||
? [{ price: item.retailPrice }]
|
? [{ price: item.retailPrice }]
|
||||||
|
|||||||
@@ -1588,6 +1588,11 @@ function getListInfo(addNewRow) {
|
|||||||
console.log('BugFix#219: 过滤掉已作废的会诊医嘱, requestId=', item.requestId);
|
console.log('BugFix#219: 过滤掉已作废的会诊医嘱, requestId=', item.requestId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// 🔧 Bug Fix: 过滤掉项目名称为空的无效医嘱
|
||||||
|
if (!item.adviceName || item.adviceName.trim() === '') {
|
||||||
|
console.log('BugFix: 过滤掉空白医嘱, requestId=', item.requestId, 'adviceType=', item.adviceType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2333,14 +2338,10 @@ function handleSave(prescriptionId) {
|
|||||||
|
|
||||||
// 签发核心逻辑
|
// 签发核心逻辑
|
||||||
function executeSaveLogic() {
|
function executeSaveLogic() {
|
||||||
// 🔧 Bug Fix: 获取当前选中的费用性质,如果是'ZIFEI'或0则转为null,让后端查询默认账户
|
// 🔧 Bug Fix: 获取当前选中的费用性质,保持字符串类型避免大整数精度丢失
|
||||||
let finalAccountId = accountId.value;
|
let finalAccountId = accountId.value;
|
||||||
if (finalAccountId === 'ZIFEI' || finalAccountId === 0) {
|
if (finalAccountId === 'ZIFEI' || finalAccountId === 0) {
|
||||||
finalAccountId = null;
|
finalAccountId = null;
|
||||||
} else if (finalAccountId && !isNaN(Number(finalAccountId))) {
|
|
||||||
finalAccountId = Number(finalAccountId);
|
|
||||||
} else {
|
|
||||||
finalAccountId = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix: 校验患者信息完整性
|
// 🔧 Bug Fix: 校验患者信息完整性
|
||||||
@@ -2878,11 +2879,10 @@ function handleSaveBatch(prescriptionId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix: 在保存时才转换 accountId
|
// 🔧 Bug Fix: 在保存时才转换 accountId
|
||||||
|
// 保持为字符串类型,避免 JavaScript 大整数精度丢失问题
|
||||||
let finalAccountId = accountId.value;
|
let finalAccountId = accountId.value;
|
||||||
if (finalAccountId === 'ZIFEI') {
|
if (finalAccountId === 'ZIFEI' || finalAccountId === 0) {
|
||||||
finalAccountId = null;
|
finalAccountId = null;
|
||||||
} else if (finalAccountId && !isNaN(Number(finalAccountId))) {
|
|
||||||
finalAccountId = Number(finalAccountId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新到处方对象
|
// 更新到处方对象
|
||||||
@@ -2964,12 +2964,10 @@ function handleSaveBatch(prescriptionId) {
|
|||||||
};
|
};
|
||||||
const contentJson = JSON.stringify(itemToSave);
|
const contentJson = JSON.stringify(itemToSave);
|
||||||
|
|
||||||
// 🔧 Bug Fix: 处理accountId,如果是'ZIFEI'或0则转为null,让后端查询默认账户
|
// 🔧 Bug Fix: 处理accountId,保持字符串类型避免大整数精度丢失
|
||||||
let itemAccountId = finalAccountId;
|
let itemAccountId = finalAccountId;
|
||||||
if (itemAccountId === 'ZIFEI' || itemAccountId === 0) {
|
if (itemAccountId === 'ZIFEI' || itemAccountId === 0) {
|
||||||
itemAccountId = null;
|
itemAccountId = null;
|
||||||
} else if (itemAccountId && !isNaN(Number(itemAccountId))) {
|
|
||||||
itemAccountId = Number(itemAccountId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix: 确保库存匹配成功的关键字段
|
// 🔧 Bug Fix: 确保库存匹配成功的关键字段
|
||||||
@@ -3143,6 +3141,12 @@ function syncGroupFields(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setValue(row) {
|
function setValue(row) {
|
||||||
|
// 🔧 Bug Fix: 强制设置耗材类型,确保 adviceType 为 4
|
||||||
|
// 如果 adviceTableName 是 adm_device_definition,强制设为耗材类型
|
||||||
|
if (row.adviceTableName === 'adm_device_definition') {
|
||||||
|
row.adviceType = 4;
|
||||||
|
}
|
||||||
|
|
||||||
unitCodeList.value = [];
|
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' });
|
||||||
unitCodeList.value.push({
|
unitCodeList.value.push({
|
||||||
|
|||||||
@@ -375,7 +375,9 @@ async function submit() {
|
|||||||
emit('refresh'); // 发送刷新事件给父组件
|
emit('refresh'); // 发送刷新事件给父组件
|
||||||
// 长春市朝阳区中医院自动发耗材
|
// 长春市朝阳区中医院自动发耗材
|
||||||
if (userStore.fixmedinsCode == 'H22010200672' && props.consumablesIdList.length > 0) {
|
if (userStore.fixmedinsCode == 'H22010200672' && props.consumablesIdList.length > 0) {
|
||||||
dispenseMedicalConsumables(props.consumablesIdList);
|
dispenseMedicalConsumables(props.consumablesIdList).catch(err => {
|
||||||
|
console.warn('自动发耗材失败:', err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user