2026-01-07 10:36:02 +08:00
|
|
|
|
package com.guahao.api.task;
|
|
|
|
|
|
|
|
|
|
|
|
import com.guahao.api.task.model.UserReserve8;
|
|
|
|
|
|
import com.guahao.common.util.DateUtils;
|
|
|
|
|
|
import com.guahao.common.util.XmlUtil;
|
|
|
|
|
|
import com.guahao.h5.reserve.mapper.Reserve8Mapper;
|
|
|
|
|
|
import com.guahao.h5.reserve.service.Reserve8Service;
|
|
|
|
|
|
import com.guahao.h5.reserve.vo.HisRefundVo;
|
|
|
|
|
|
import com.guahao.h5.reserve.vo.Reserve8Vo;
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @author SangChengZhi
|
|
|
|
|
|
* @date 2025年11月13日 15:39
|
|
|
|
|
|
* @desc 每日结束查询未就诊的挂号记录进行退费退号操作。
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
@Component
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
|
public class GuahaoTask {
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private Reserve8Mapper reserve8Mapper;
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private Reserve8Service reserve8Service;
|
|
|
|
|
|
@Scheduled(cron = "0 52 20 * * ?", zone = "GMT+8")
|
|
|
|
|
|
public void returnGuahaoNum() {
|
|
|
|
|
|
log.info("执行每日退未就诊号的操作");
|
|
|
|
|
|
String date = DateUtils.getHisDate();
|
|
|
|
|
|
String StartTime = date + " 00:00:00";
|
|
|
|
|
|
String EndTime = date + " 23:59:59";
|
|
|
|
|
|
List<Map<String, Object>> cardlist = reserve8Mapper.selectListOut(date);
|
|
|
|
|
|
HisRefundVo vo = new HisRefundVo();
|
|
|
|
|
|
vo.setTxsend("过期");
|
|
|
|
|
|
vo.setPaynature("1");
|
|
|
|
|
|
vo.setPaytype("微信");
|
|
|
|
|
|
vo.setHisopernum("wx");
|
|
|
|
|
|
|
|
|
|
|
|
cardlist.forEach(map -> {
|
|
|
|
|
|
try {
|
|
|
|
|
|
resetVoProperties(vo);
|
|
|
|
|
|
vo.setPatientid(map.get("cardId").toString());
|
|
|
|
|
|
vo.setUserId((Integer) map.get("userId"));
|
|
|
|
|
|
|
|
|
|
|
|
String xml = reserve8Service.MOP_OutpRegisterListQuery(map.get("cardId").toString(), 1, StartTime, EndTime);
|
|
|
|
|
|
List<Map<Object, Object>> maps = XmlUtil.parseQueryGH(xml);
|
|
|
|
|
|
log.info("opRegisterListQuery:{}", maps);
|
|
|
|
|
|
|
|
|
|
|
|
if (!maps.isEmpty()) {
|
|
|
|
|
|
maps.forEach(map2 -> {
|
|
|
|
|
|
boolean refundSuccess = false;
|
|
|
|
|
|
boolean cancelSuccess = false;
|
|
|
|
|
|
String orderNo = map2.get("ORDERNO").toString();
|
|
|
|
|
|
//先判断是否是线上的挂号
|
|
|
|
|
|
Reserve8Vo reserve8Vo = reserve8Mapper.getInfoByReptNo(orderNo);
|
|
|
|
|
|
if (reserve8Vo == null){
|
|
|
|
|
|
log.info("此订单不是线上的挂号,跳过处理: {}", orderNo);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 先退号再退费
|
|
|
|
|
|
vo.setBillsmsg(orderNo);
|
|
|
|
|
|
vo.setPowertranid(reserve8Vo.getOrderno());
|
|
|
|
|
|
vo.setZfamount(String.valueOf(reserve8Vo.getZfamount()));
|
|
|
|
|
|
vo.setYbzhamount(String.valueOf(reserve8Vo.getYbzhamount()));
|
|
|
|
|
|
vo.setYbtcamount(String.valueOf(reserve8Vo.getYbtcamount()));
|
|
|
|
|
|
vo.setYboutmsg(reserve8Vo.getYboutmsg());
|
|
|
|
|
|
|
|
|
|
|
|
String registRefundResult = reserve8Service.MOP_RegistRefund(vo);
|
|
|
|
|
|
log.info("退号结果: {}", registRefundResult);
|
|
|
|
|
|
|
|
|
|
|
|
if (!registRefundResult.equals("success")) {
|
|
|
|
|
|
log.warn("退号失败,结果: {}", registRefundResult);
|
|
|
|
|
|
log.warn("退号失败,继续处理下一个记录");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cancelSuccess = true;
|
|
|
|
|
|
log.info("退号成功");
|
2026-01-22 10:41:24 +08:00
|
|
|
|
if (vo.getZfamount().equals("0.00")){
|
|
|
|
|
|
log.info("0元挂号,跳过退费处理");
|
|
|
|
|
|
refundSuccess = true;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-01-07 10:36:02 +08:00
|
|
|
|
|
|
|
|
|
|
// 2. 执行退费
|
|
|
|
|
|
Map<String, Object> refundResult = reserve8Service.MOP_BillsPayedRefund(vo);
|
|
|
|
|
|
log.info("退费结果: {}", refundResult + ",判断结果:" + (refundResult != null ? refundResult.get("return_code") : "null"));
|
|
|
|
|
|
|
|
|
|
|
|
if (refundResult == null ||
|
|
|
|
|
|
!"SUCCESS".equals(refundResult.get("return_code")) ||
|
|
|
|
|
|
!"SUCCESS".equals(refundResult.get("result_code"))) {
|
|
|
|
|
|
reserve8Mapper.insertRefundError(vo);
|
|
|
|
|
|
log.warn("退费接口返回失败: {}", refundResult);
|
|
|
|
|
|
log.warn("退费失败,继续处理下一个记录");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
refundSuccess = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("处理单个挂号记录时出错,cardId: {}, ORDERNO: {}, 退号状态: {}, 退费状态: {}",
|
|
|
|
|
|
map.get("cardId"), orderNo, cancelSuccess ? "成功" : "失败",
|
|
|
|
|
|
refundSuccess ? "成功" : "失败", e);
|
|
|
|
|
|
if (!refundSuccess){
|
|
|
|
|
|
// 将失败内容存到数据库,进行每1小时一次退款任务
|
|
|
|
|
|
reserve8Service.insertRefundError(vo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("处理用户记录时出错,cardId: {}", map.get("cardId"), e);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 退号失败的费用
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Scheduled(cron = "0 0 */1 * * ?", zone = "GMT+8")
|
|
|
|
|
|
public void RefundGuahaoAmount() {
|
|
|
|
|
|
|
|
|
|
|
|
List<HisRefundVo> refundList = reserve8Mapper.getRefundSelect();
|
|
|
|
|
|
if (!refundList.isEmpty()){
|
|
|
|
|
|
log.info("执行定时的退号失败的费用退款处理");
|
|
|
|
|
|
refundList.forEach(vo -> {
|
|
|
|
|
|
try {
|
|
|
|
|
|
Map<String, Object> refundResult = reserve8Service.MOP_BillsPayedRefund(vo);
|
|
|
|
|
|
|
|
|
|
|
|
// 安全处理 refundResult 为 null 的情况
|
|
|
|
|
|
if (refundResult == null) {
|
|
|
|
|
|
log.warn("退费接口返回 null,订单号: {}", vo.getBillsmsg());
|
|
|
|
|
|
return; // 或根据业务逻辑处理(如直接跳过)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 安全判断特殊成功条件:refundResult 字段存在 OR returncode=1
|
|
|
|
|
|
boolean isSpecialSuccess = false;
|
|
|
|
|
|
Object refundResultField = refundResult.get("refundResult");
|
|
|
|
|
|
if (refundResultField != null) {
|
|
|
|
|
|
isSpecialSuccess = true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 安全处理 returncode 字段(避免 NPE)
|
|
|
|
|
|
Object returncodeObj = refundResult.get("returncode");
|
|
|
|
|
|
if (returncodeObj != null) {
|
|
|
|
|
|
String returncodeStr = String.valueOf(returncodeObj).trim();
|
|
|
|
|
|
isSpecialSuccess = "1".equals(returncodeStr);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 如果是特殊成功条件,设置返回码为 SUCCESS
|
|
|
|
|
|
if (isSpecialSuccess) {
|
|
|
|
|
|
log.info("特殊成功: 退费结果={}, 条件: refundResult字段存在或returncode=1", refundResult);
|
|
|
|
|
|
refundResult.put("return_code", "SUCCESS");
|
|
|
|
|
|
refundResult.put("result_code", "SUCCESS");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 标准成功判断(基于 return_code/result_code)
|
|
|
|
|
|
if ("SUCCESS".equals(refundResult.get("return_code")) &&
|
|
|
|
|
|
"SUCCESS".equals(refundResult.get("result_code"))) {
|
|
|
|
|
|
|
|
|
|
|
|
// 标准成功:删除错误记录
|
|
|
|
|
|
reserve8Mapper.deleteRefundError(vo.getBillsmsg());
|
|
|
|
|
|
log.info("用户{},订单号{},定时退费成功", vo.getPatientid(), vo.getBillsmsg());
|
|
|
|
|
|
|
|
|
|
|
|
} else if ("订单已全额退款".equals(refundResult.get("err_code_des")) &&
|
|
|
|
|
|
"FAIL".equals(refundResult.get("result_code"))) {
|
|
|
|
|
|
|
|
|
|
|
|
// 特殊成功:订单已全额退款
|
|
|
|
|
|
reserve8Mapper.deleteRefundError(vo.getBillsmsg());
|
|
|
|
|
|
log.info("用户{},订单号{},订单已全额退款,删除错误记录", vo.getPatientid(), vo.getBillsmsg());
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 真正的失败
|
|
|
|
|
|
log.warn("退费接口返回失败: {}", refundResult);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void resetVoProperties(HisRefundVo vo) {
|
|
|
|
|
|
vo.setBillsmsg(null);
|
|
|
|
|
|
vo.setPatientid(null);
|
|
|
|
|
|
vo.setPowertranid(null);
|
|
|
|
|
|
vo.setZfamount(null);
|
|
|
|
|
|
vo.setYbzhamount(null);
|
|
|
|
|
|
vo.setYbtcamount(null);
|
|
|
|
|
|
vo.setYboutmsg(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|