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> 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> 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("退号成功"); if (vo.getZfamount().equals("0.00")){ log.info("0元挂号,跳过退费处理"); refundSuccess = true; return; } // 2. 执行退费 Map 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 refundList = reserve8Mapper.getRefundSelect(); if (!refundList.isEmpty()){ log.info("执行定时的退号失败的费用退款处理"); refundList.forEach(vo -> { try { Map 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); } }