需求85 门诊挂号-》预约号源已缴费签到未看诊进行退号;建立退费表,在退诊时将相应数据插入到表中。

This commit is contained in:
HuangShun
2026-02-03 10:31:58 +08:00
parent d1b290881f
commit fa06a52d71
5 changed files with 297 additions and 1 deletions

View File

@@ -10,16 +10,21 @@ import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.StringUtils;
import com.core.common.utils.bean.BeanUtils;
import com.core.common.core.domain.entity.SysRole;
import com.core.common.core.domain.model.LoginUser;
import com.openhis.administration.domain.*;
import com.openhis.administration.mapper.PatientMapper;
import com.openhis.administration.service.*;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.enums.ybenums.YbPayment;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.financial.domain.PaymentReconciliation;
import com.openhis.financial.domain.RefundLog;
import com.openhis.financial.service.IRefundLogService;
import com.openhis.web.basicservice.dto.HealthcareServiceDto;
import com.openhis.web.basicservice.mapper.HealthcareServiceBizMapper;
import com.openhis.web.chargemanage.appservice.IOutpatientRegistrationAppService;
@@ -40,10 +45,14 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* 门诊挂号 应用实现类
@@ -85,6 +94,9 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
@Resource
TriageCandidateExclusionService triageCandidateExclusionService;
@Resource
IRefundLogService iRefundLogService;
/**
* 门诊挂号 - 查询患者信息
*
@@ -260,7 +272,7 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
R<?> result = iPaymentRecService.cancelRegPayment(cancelPaymentDto);
PaymentReconciliation paymentRecon = null;
if (PaymentReconciliation.class.isAssignableFrom(result.getData().getClass())) {
if (result.getData() != null && PaymentReconciliation.class.isAssignableFrom(result.getData().getClass())) {
paymentRecon = (PaymentReconciliation)result.getData();
}
if (paymentRecon != null) {
@@ -275,6 +287,9 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
}
}
// 记录退号日志
recordRefundLog(cancelRegPaymentDto, byId, result, paymentRecon);
// 2025/05/05 该处保存费用项后,会通过统一收费处理进行收费
return R.ok(paymentRecon, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"退号"}));
}
@@ -394,4 +409,124 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
return R.ok(null, "补打挂号成功");
}
/**
* 记录退号日志
*
* @param cancelRegPaymentDto 退号请求对象
* @param encounter 就诊信息
* @param result 退号结果
* @param paymentRecon 支付对账信息
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void recordRefundLog(CancelRegPaymentDto cancelRegPaymentDto,
Encounter encounter,
R<?> result,
PaymentReconciliation paymentRecon) {
RefundLog refundLog = new RefundLog();
try {
// 1. 订单ID唯一
String orderId = String.valueOf(cancelRegPaymentDto.getEncounterId());
refundLog.setOrderId(orderId);
// 已存在则不重复插入(防止唯一约束异常)
long exist = iRefundLogService.lambdaQuery()
.eq(RefundLog::getOrderId, orderId)
.count();
if (exist > 0) {
log.warn("退号日志已存在orderId={}", orderId);
return;
}
// 2. 患者信息
if (encounter != null) {
refundLog.setPatientId(String.valueOf(encounter.getPatientId()));
Patient patient = patientMapper.selectById(encounter.getPatientId());
refundLog.setPatientName(patient != null ? patient.getName() : "未知");
} else {
refundLog.setPatientId("0");
refundLog.setPatientName("未知");
}
// 3. 金额
// 优先使用paymentRecon中的displayAmount如果没有则尝试使用cancelRegPaymentDto中的displayAmount
BigDecimal refundAmount = BigDecimal.ZERO;
if (paymentRecon != null) {
// 使用退号后生成的paymentRecon的实际金额这个金额应该是负数
refundAmount = paymentRecon.getDisplayAmount() != null
? paymentRecon.getDisplayAmount().abs() // 取绝对值,因为退费金额通常显示为正数
: BigDecimal.ZERO;
} else if (cancelRegPaymentDto.getDisplayAmount() != null) {
refundAmount = cancelRegPaymentDto.getDisplayAmount();
}
refundLog.setRefundAmount(refundAmount);
// 4. 原因 & 类型
refundLog.setRefundReason(
StringUtils.isNotEmpty(cancelRegPaymentDto.getReason())
? cancelRegPaymentDto.getReason()
: "诊前退号-已缴费签到未就诊"
);
refundLog.setRefundType("FULL");
// 5. 退款方式
String refundMethod = "UNKNOWN";
if (cancelRegPaymentDto.getPaymentDetails() != null
&& !cancelRegPaymentDto.getPaymentDetails().isEmpty()) {
Integer payEnum = cancelRegPaymentDto.getPaymentDetails().get(0).getPayEnum();
if (payEnum != null) {
YbPayment ybPayment = YbPayment.getByValue(payEnum);
refundMethod = (ybPayment != null ? ybPayment.getInfo() : payEnum.toString());
}
}
refundLog.setRefundMethod(refundMethod);
// 6. 原交易号
refundLog.setOriginalTradeNo(
paymentRecon != null ? paymentRecon.getPaymentNo() : null
);
// 7. 时间
refundLog.setRefundTime(LocalDateTime.now());
// 8. 操作人
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
refundLog.setOpUserId(String.valueOf(loginUser.getUserId()));
refundLog.setOpUserName(loginUser.getUsername());
List<SysRole> roles = loginUser.getRoleList();
refundLog.setOpRole(
roles != null && !roles.isEmpty() ? roles.get(0).getRoleName() : "SYSTEM"
);
} else {
refundLog.setOpUserId("0");
refundLog.setOpUserName("SYSTEM");
refundLog.setOpRole("SYSTEM");
}
// 9. 状态
if (result != null && result.getCode() == 200) {
refundLog.setState(1);
} else {
refundLog.setState(0);
refundLog.setFailReason(result != null ? result.getMsg() : "未知错误");
}
// 10. 创建时间
refundLog.setCreatedAt(LocalDateTime.now());
refundLog.setUpdatedAt(LocalDateTime.now());
// 11. 保存
boolean saved = iRefundLogService.save(refundLog);
if (!saved) {
throw new RuntimeException("退号日志保存失败");
}
log.info("退号日志入库成功, orderId={}", orderId);
} catch (Exception e) {
log.error("退号日志入库失败,数据={}", refundLog, e);
throw e; // 让事务感知(你也可以只记录不抛)
}
}
}

View File

@@ -0,0 +1,127 @@
package com.openhis.financial.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
/**
* 退号日志表
*/
@TableName(value = "refund_log")
@Data
public class RefundLog implements Serializable {
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 订单ID
*/
@TableField(value = "order_id")
private String orderId;
/**
* 患者ID
*/
@TableField(value = "patient_id")
private String patientId;
/**
* 患者姓名
*/
@TableField(value = "patient_name")
private String patientName;
/**
* 退款金额
*/
@TableField(value = "refund_amount")
private BigDecimal refundAmount;
/**
* 退款原因
*/
@TableField(value = "refund_reason")
private String refundReason;
/**
* 退款类型(FULL-全额退号PART-部分退号)
*/
@TableField(value = "refund_type")
private String refundType;
/**
* 退款方式
*/
@TableField(value = "refund_method")
private String refundMethod;
/**
* 原交易流水号
*/
@TableField(value = "original_trade_no")
private String originalTradeNo;
/**
* 退款交易流水号
*/
@TableField(value = "refund_trade_no")
private String refundTradeNo;
/**
* 退款时间
*/
@TableField(value = "refund_time")
private LocalDateTime refundTime;
/**
* 操作用户ID
*/
@TableField(value = "op_user_id")
private String opUserId;
/**
* 操作用户名
*/
@TableField(value = "op_user_name")
private String opUserName;
/**
* 操作角色
*/
@TableField(value = "op_role")
private String opRole;
/**
* 状态(0-失败1-成功2-处理中)
*/
@TableField(value = "state")
private Integer state;
/**
* 失败原因
*/
@TableField(value = "fail_reason")
private String failReason;
/**
* 创建时间
*/
@TableField(value = "created_at")
private LocalDateTime createdAt;
/**
* 更新时间
*/
@TableField(value = "updated_at")
private LocalDateTime updatedAt;
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,10 @@
package com.openhis.financial.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.openhis.financial.domain.RefundLog;
/**
* 退号日志 Mapper接口
*/
public interface RefundLogMapper extends BaseMapper<RefundLog> {
}

View File

@@ -0,0 +1,10 @@
package com.openhis.financial.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.openhis.financial.domain.RefundLog;
/**
* 退号日志 Service接口
*/
public interface IRefundLogService extends IService<RefundLog> {
}

View File

@@ -0,0 +1,14 @@
package com.openhis.financial.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.openhis.financial.domain.RefundLog;
import com.openhis.financial.mapper.RefundLogMapper;
import com.openhis.financial.service.IRefundLogService;
import org.springframework.stereotype.Service;
/**
* 退号日志 Service实现类
*/
@Service
public class RefundLogServiceImpl extends ServiceImpl<RefundLogMapper, RefundLog> implements IRefundLogService {
}