主要修复: - 检查申请医嘱类型正确设置为诊疗(3),避免被错误归类为药品 - 检查申请收费项获取真实自费账户,预结算验证accountId必须有效存在 - 签发时补充诊疗费用项诊断关联信息变更模块: - ExamApplyController:使用ItemType枚举,获取真实账户替代占位值0 -DoctorStationAdviceAppService:按枚举标准分类医嘱,验证accountId有效性 - IChargeBillService:productId=0时从ServiceRequest.contentJson获取项目名称 - PaymentRecService:预结算自动修复账户不存在的历史数据 - Mapper:排除衍生执行记录,productId=0时补充查询逻辑 - ServiceRequest实体:activityId字段添加ALWAYS插入策略
This commit is contained in:
@@ -41,7 +41,9 @@ import com.openhis.web.paymentmanage.appservice.IChargeBillService;
|
||||
import com.openhis.web.paymentmanage.dto.*;
|
||||
import com.openhis.web.paymentmanage.mapper.ChargeBillMapper;
|
||||
import com.openhis.workflow.domain.ActivityDefinition;
|
||||
import com.openhis.workflow.domain.ServiceRequest;
|
||||
import com.openhis.workflow.service.IActivityDefinitionService;
|
||||
import com.openhis.workflow.service.IServiceRequestService;
|
||||
import com.openhis.yb.domain.ClinicSettle;
|
||||
import com.openhis.yb.domain.ClinicUnSettle;
|
||||
import com.openhis.yb.domain.InfoPerson;
|
||||
@@ -111,6 +113,8 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
||||
@Autowired
|
||||
private IActivityDefinitionService iActivityDefinitionService;
|
||||
@Autowired
|
||||
private IServiceRequestService iServiceRequestService;
|
||||
@Autowired
|
||||
private IPractitionerService iPractitionerService;
|
||||
@Autowired
|
||||
private IHealthcareServiceService iHealthcareServiceService;
|
||||
@@ -265,10 +269,31 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
||||
.setTotalPrice(chargeItem.getTotalPrice()).setQuantityUnit(chargeItem.getQuantityUnit())
|
||||
.setTotalVolume(device.getSize()).setQuantityValue(chargeItem.getQuantityValue());
|
||||
} else if (CommonConstants.TableName.WOR_ACTIVITY_DEFINITION.equals(chargeItem.getProductTable())) {
|
||||
ActivityDefinition activity = iActivityDefinitionService.getById(chargeItem.getProductId());
|
||||
chargeItemDetailVO.setDirClass(activity.getChrgitmLv() + "").setChargeItemName(activity.getName())
|
||||
.setTotalPrice(chargeItem.getTotalPrice()).setQuantityUnit(chargeItem.getQuantityUnit())
|
||||
.setTotalVolume("").setQuantityValue(chargeItem.getQuantityValue());
|
||||
// 🔧 BugFix#385: 检查申请创建的收费项 productId=0,需从 ServiceRequest.contentJson 获取项目名称
|
||||
if (chargeItem.getProductId() != null && chargeItem.getProductId() > 0) {
|
||||
ActivityDefinition activity = iActivityDefinitionService.getById(chargeItem.getProductId());
|
||||
chargeItemDetailVO.setDirClass(activity.getChrgitmLv() + "").setChargeItemName(activity.getName())
|
||||
.setTotalPrice(chargeItem.getTotalPrice()).setQuantityUnit(chargeItem.getQuantityUnit())
|
||||
.setTotalVolume("").setQuantityValue(chargeItem.getQuantityValue());
|
||||
} else {
|
||||
// productId=0 时,从关联的 ServiceRequest 获取项目名称
|
||||
ServiceRequest serviceRequest = iServiceRequestService.getById(chargeItem.getServiceId());
|
||||
String itemName = "未知项目";
|
||||
String dirClass = "3"; // 默认诊疗类
|
||||
if (serviceRequest != null && serviceRequest.getContentJson() != null) {
|
||||
try {
|
||||
JSONObject json = JSON.parseObject(serviceRequest.getContentJson());
|
||||
if (json.containsKey("adviceName")) {
|
||||
itemName = json.getString("adviceName");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析ServiceRequest.contentJson失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
chargeItemDetailVO.setDirClass(dirClass).setChargeItemName(itemName)
|
||||
.setTotalPrice(chargeItem.getTotalPrice()).setQuantityUnit(chargeItem.getQuantityUnit())
|
||||
.setTotalVolume("").setQuantityValue(chargeItem.getQuantityValue());
|
||||
}
|
||||
} else {
|
||||
HealthcareService healthcareService = iHealthcareServiceService.getById(chargeItem.getServiceId());
|
||||
chargeItemDetailVO.setDirClass("3").setChargeItemName(healthcareService.getName())
|
||||
@@ -347,7 +372,19 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
||||
|
||||
Long definitionId = chargeItem.getDefinitionId();
|
||||
|
||||
ChargeItemDefinition chargeItemDefinition = iChargeItemDefinitionService.getById(definitionId);
|
||||
// 🔧 BugFix#385: 检查申请创建的收费项 definition_id=0,chargeItemDefinition 会为 null
|
||||
ChargeItemDefinition chargeItemDefinition = null;
|
||||
if (definitionId != null && definitionId > 0) {
|
||||
chargeItemDefinition = iChargeItemDefinitionService.getById(definitionId);
|
||||
}
|
||||
|
||||
// 当 definitionId=0 或 chargeItemDefinition 为 null 时,跳过医保分类统计
|
||||
// 检查类项目默认归类为"检查费"
|
||||
if (chargeItemDefinition == null) {
|
||||
// 检查申请的收费项,归类为检查费(03)
|
||||
sum03 = sum03.add(chargeItem.getTotalPrice());
|
||||
continue;
|
||||
}
|
||||
|
||||
YbMedChrgItmType medChrgItmType
|
||||
= YbMedChrgItmType.getByCode(Integer.parseInt(chargeItemDefinition.getYbType()));
|
||||
|
||||
@@ -6,6 +6,7 @@ package com.openhis.web.paymentmanage.appservice.impl;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
@@ -241,14 +242,21 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
.collect(Collectors.toList());
|
||||
// account去重
|
||||
List<Long> distinctAccountIdList = accountIdList.stream().distinct().collect(Collectors.toList());
|
||||
// 检查是否存在accountId为null的收费项
|
||||
// 检查是否存在accountId为null或0的收费项
|
||||
long nullAccountIdCount = chargeItemList.stream()
|
||||
.map(ChargeItem::getAccountId)
|
||||
.filter(Objects::isNull)
|
||||
.count();
|
||||
long zeroAccountIdCount = chargeItemList.stream()
|
||||
.map(ChargeItem::getAccountId)
|
||||
.filter(id -> id != null && id == 0L)
|
||||
.count();
|
||||
if (nullAccountIdCount > 0) {
|
||||
throw new ServiceException("部分收费项缺少账户信息,请检查收费项数据");
|
||||
}
|
||||
if (zeroAccountIdCount > 0) {
|
||||
throw new ServiceException("部分收费项账户ID为0(无效),请检查收费项数据或重新创建检查申请");
|
||||
}
|
||||
if (distinctAccountIdList.isEmpty()) {
|
||||
throw new ServiceException("未找到有效的账户信息");
|
||||
}
|
||||
@@ -257,15 +265,66 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
// 在挂号费等场景下可能因数据不一致导致查不到,引发误报
|
||||
List<Account> accountList = iAccountService.list(new LambdaQueryWrapper<Account>()
|
||||
.in(Account::getId, distinctAccountIdList));
|
||||
|
||||
// 🔧 Bug Fix: 处理账户不存在的情况(历史数据修复)
|
||||
if (accountList.size() != distinctAccountIdList.size()) {
|
||||
// 部分账户查不到时,记录警告日志,并校验是否每个收费项都能找到对应账户
|
||||
Set<Long> foundAccountIds = accountList.stream().map(Account::getId).collect(Collectors.toSet());
|
||||
List<Long> missingAccountIds = distinctAccountIdList.stream()
|
||||
.filter(id -> !foundAccountIds.contains(id)).collect(Collectors.toList());
|
||||
if (accountList.isEmpty()) {
|
||||
throw new ServiceException("未查询到任何账户信息,encounterId:" + prePaymentDto.getEncounterId()
|
||||
+ ",期望accountId列表:" + distinctAccountIdList);
|
||||
|
||||
logger.warn("预结算发现部分账户不存在,missingAccountIds={},将自动修复收费项的accountId",
|
||||
missingAccountIds);
|
||||
|
||||
// 获取或创建有效的自费账户
|
||||
Account selfAccount = iAccountService.getSelfAccount(prePaymentDto.getEncounterId());
|
||||
if (selfAccount == null) {
|
||||
// 自动创建自费账户
|
||||
Account newAccount = new Account();
|
||||
newAccount.setPatientId(chargeItemList.get(0).getPatientId());
|
||||
newAccount.setEncounterId(prePaymentDto.getEncounterId());
|
||||
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||
selfAccount = iAccountService.getById(newAccountId);
|
||||
logger.info("预结算自动创建自费账户,newAccountId={}", newAccountId);
|
||||
}
|
||||
|
||||
// 修复收费项的 accountId
|
||||
for (Long missingAccountId : missingAccountIds) {
|
||||
// 找到使用该无效 accountId 的收费项
|
||||
List<ChargeItem> affectedChargeItems = chargeItemList.stream()
|
||||
.filter(ci -> ci.getAccountId() != null && ci.getAccountId().equals(missingAccountId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (ChargeItem ci : affectedChargeItems) {
|
||||
LambdaUpdateWrapper<ChargeItem> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(ChargeItem::getId, ci.getId())
|
||||
.set(ChargeItem::getAccountId, selfAccount.getId());
|
||||
iChargeItemService.update(updateWrapper);
|
||||
logger.info("预结算修复收费项accountId,chargeItemId={},oldAccountId={},newAccountId={}",
|
||||
ci.getId(), missingAccountId, selfAccount.getId());
|
||||
|
||||
// 更新本地对象的 accountId,以便后续处理使用正确的值
|
||||
ci.setAccountId(selfAccount.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// 重新查询账户列表
|
||||
accountList = iAccountService.list(new LambdaQueryWrapper<Account>()
|
||||
.eq(Account::getId, selfAccount.getId()));
|
||||
|
||||
// 重新构建 accountIdList(已修复)
|
||||
distinctAccountIdList = chargeItemList.stream()
|
||||
.map(ChargeItem::getAccountId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
logger.info("预结算账户修复完成,最终使用accountId={}", selfAccount.getId());
|
||||
}
|
||||
|
||||
// 账户id,对应的账单列表
|
||||
|
||||
Reference in New Issue
Block a user