package beilv.vipCardLog.service.impl; import beilv.admissionticket.domain.AdmissionTicket; import beilv.admissionticket.mapper.AdmissionTicketMapper; import beilv.admissionticket.service.IAdmissionTicketService; import beilv.carinformation.domain.CarInformation; import beilv.carinformation.service.ICarInformationService; import beilv.common.core.domain.AjaxResult; import beilv.common.core.text.Convert; import beilv.common.utils.DateUtils; import beilv.common.utils.DictUtils; import beilv.common.utils.StringUtils; import beilv.common.utils.uuid.IdUtils; import beilv.competition.domain.Competition; import beilv.competition.service.ICompetitionService; import beilv.system.service.ISysConfigService; import beilv.usermembershipcard.domain.UserMembershipCard; import beilv.usermembershipcard.service.IUserMembershipCardService; import beilv.vipCard.domain.VipCard; import beilv.vipCard.service.IVipCardService; import beilv.vipCardAmountLog.domain.VipCardAmountLog; import beilv.vipCardAmountLog.mapper.VipCardAmountLogMapper; import beilv.vipCardLog.domain.VipCardLog; import beilv.vipCardLog.mapper.VipCardLogMapper; import beilv.vipCardLog.service.IVipCardLogService; import beilv.voucher.domain.BeilvVoucherMember; import org.apache.commons.collections4.MapUtils; import org.checkerframework.checker.units.qual.A; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Map; import static beilv.competition.domain.Constant.ORDER_QUEUE; /** * 充值记录Service业务层处理 * * @author LG * @date 2025-11-12 */ @Service public class VipCardLogServiceImpl implements IVipCardLogService { @Resource private VipCardLogMapper vipCardLogMapper; @Autowired private IVipCardService vipCardService; @Autowired private ICompetitionService competitionService; @Autowired private IUserMembershipCardService userMembershipCardService; @Autowired private ICarInformationService carInformationService; @Autowired private IAdmissionTicketService ticketService; @Autowired private ISysConfigService configService; @Resource private VipCardAmountLogMapper amountLogMapper; @Autowired private StringRedisTemplate stringRedisTemplate; /** * 查询充值记录 * * @param id 充值记录主键 * @return 充值记录 */ @Override public VipCardLog selectVipCardLogById(String id) { return vipCardLogMapper.selectVipCardLogById(id); } /** * 查询充值记录列表 * * @param vipCardLog 充值记录 * @return 充值记录 */ @Override public List selectVipCardLogList(VipCardLog vipCardLog) { List list = vipCardLogMapper.selectVipCardLogList(vipCardLog); Map orderType = DictUtils.getDictCacheToMap("order_type"); Map paymentStatus = DictUtils.getDictCacheToMap("payment_status"); Map paymentType = DictUtils.getDictCacheToMap("payment_type"); for (VipCardLog var : list) { var.setOrderTypeText(MapUtils.getString(orderType, var.getOrderType())); var.setPaymentStatusText(MapUtils.getString(paymentStatus, var.getPaymentStatus())); var.setPaymentTypeText(MapUtils.getString(paymentType, var.getPaymentType())); } return list; } /** * 新增充值记录 * * @param vipCardLog 充值记录 * @return 结果 */ @Override public int insertVipCardLog(VipCardLog vipCardLog) { return vipCardLogMapper.insertVipCardLog(vipCardLog); } /** * 修改充值记录 * * @param vipCardLog 充值记录 * @return 结果 */ @Override public int updateVipCardLog(VipCardLog vipCardLog) { return vipCardLogMapper.updateVipCardLog(vipCardLog); } /** * 批量删除充值记录 * * @param ids 需要删除的充值记录主键 * @return 结果 */ @Override public int deleteVipCardLogByIds(String ids) { return vipCardLogMapper.deleteVipCardLogByIds(Convert.toStrArray(ids)); } /** * 删除充值记录信息 * * @param id 充值记录主键 * @return 结果 */ @Override public int deleteVipCardLogById(String id) { return vipCardLogMapper.deleteVipCardLogById(id); } @Override public int updateVipCardLogByOrderId(VipCardLog vipCardLog) { //验证订单编号是否为空 if (StringUtils.isEmpty(vipCardLog.getId())) { return 0; } //拉去订单信息 VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId()); //充值订单和其他订单处理方式不同 if ("chongzhi".equals(orderInfo.getOrderType())) { charging(vipCardLog, orderInfo); } else { other(vipCardLog, orderInfo); } //更新订单状态 return vipCardLogMapper.updateVipCardLog(vipCardLog); } /** * 充值回调 * * @param vipCardLog 订单请求信息 * @param orderInfo 原订单信息 * @return */ private void charging(VipCardLog vipCardLog, VipCardLog orderInfo) { if ("payment_status_have_paid".equals(vipCardLog.getPaymentStatus())) { //拉取订单信息 // VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId()); //获取会员卡信息 VipCard vipCard = vipCardService.selectVipCardByUserId(orderInfo.getUserId()); //获取当前余额 BigDecimal balance = BigDecimal.ZERO; String vipCardId; if (null == vipCard) { //true 没有会员卡; 新增会员卡, 并且设置本次充值金额 vipCardId = vipCardService.insertVipCard(new VipCard(Long.parseLong(orderInfo.getUserId()), orderInfo.getPracticalMoney(), BigDecimal.ZERO)); } else { balance = vipCard.getBalance(); vipCardId = vipCard.getId(); //false 有会员卡, vipCardService.updateVipCard(new VipCard(Long.parseLong(orderInfo.getUserId()), orderInfo.getPracticalMoney().add(vipCard.getBalance()).setScale(2, RoundingMode.HALF_UP), vipCard.getScore())); } //设定支付时间 vipCardLog.setPaymentTime(DateUtils.getNowDate()); //写入会员卡流水 insertAmountLog(new VipCardAmountLog(orderInfo.getUserId(), vipCardId, orderInfo.getId(), balance, orderInfo.getPracticalMoney(),"1")); //支付成功移除定时任务 stringRedisTemplate.delete(ORDER_QUEUE+orderInfo.getId()); } else if ("payment_status_cancelled".equals(vipCardLog.getPaymentStatus())) { //如果是取消, 设置支付状态为取消支付 vipCardLog.setCancellationTime(DateUtils.getNowDate()); } } /** * 其他支付回调 * * @param vipCardLog * @return */ private void other(VipCardLog vipCardLog, VipCardLog orderInfo) { //拉取订单信息 // VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId()); if ("payment_status_have_paid".equals(vipCardLog.getPaymentStatus())) { //支付成功流程 //设置支付时间 vipCardLog.setPaymentTime(DateUtils.getNowDate()); //获取订单类型 String orderType = orderInfo.getOrderType(); if ("gouka".equals(orderType)) { //如果是购买次卡订单, 拉去卡种信息 CarInformation carInformation = carInformationService.selectCarInformationById(Long.valueOf(orderInfo.getBusId())); //购卡订单, 支付成功, 生成卡片写入到次卡表 userMembershipCardService.insertUserMembershipCard(new UserMembershipCard(orderInfo.getUserId(), vipCardLog.getId(), carInformation.getTotalNumber(), "0", "3", DateUtils.getNowDate(), orderInfo.getBusId())); } if("yueqiu".equals(orderType)){ //如果是约球订单 AdmissionTicket admissionTicket = new AdmissionTicket(); admissionTicket.setId(orderInfo.getBusId()); //创建场次定时任务, 到时间自动核销 ticketService.createTask(admissionTicket); } } else if ("payment_status_cancelled".equals(vipCardLog.getPaymentStatus())) { //如果是取消订单,设置支付状态为取消支付 vipCardLog.setCancellationTime(DateUtils.getNowDate()); if ("yueqiu".equals(orderInfo.getOrderType())) { //如果是约球订单, 修改球场信息 AdmissionTicket admissionTicket = new AdmissionTicket(); admissionTicket.setId(orderInfo.getBusId()); admissionTicket.setAdmissionTicketStatus("0"); ticketService.updateBeilvAdmissionTicket(admissionTicket); } } } @Override public int getRegistrantsNumber(VipCardLog vipCardLog) { return vipCardLogMapper.getRegistrantsNumber(vipCardLog); } @Override public AjaxResult refundById(VipCardLog vipCardLog, boolean isOnline, boolean executeUpdate) { if(StringUtils.isEmpty(vipCardLog.getId())){ return AjaxResult.error("订单编号不能为空!"); } //拉去订单信息 VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId()); if ("payment_status_to_be_paid".equals(orderInfo.getPaymentStatus())) { return AjaxResult.error("订单未支付, 无需退款!"); } if ("payment_status_cancelled".equals(orderInfo.getPaymentStatus())) { return AjaxResult.error("订单已取消, 无需退款!"); } if ("payment_status_refunded".equals(orderInfo.getPaymentStatus())) { return AjaxResult.error("订单已退款, 无需重复操作!"); } if ("payment_status_verification".equals(orderInfo.getPaymentStatus())) { return AjaxResult.error("订单已核销, 无法退款!"); } //退款金额 BigDecimal refundPrice = BigDecimal.valueOf(0); int refundSum = 0; if ("yueqiu".equals(orderInfo.getOrderType())) { if (isOnline) { // 获取设定的取消时间范围(分钟) long cancelMinutes = Long.parseLong(configService.selectConfigByKey("cancel.minutes")); // 根据订单获取约场的开始时间 AdmissionTicket admissionTicket = ticketService.selectBeilvAdmissionTicketById(orderInfo.getBusId()); String format = new SimpleDateFormat("yyyy-MM-dd").format(admissionTicket.getTicketDate()); String startTime = admissionTicket.getSession().split("-")[0]; // 10:00 // 当前时间 LocalDateTime now = LocalDateTime.now(); // 定义日期时间格式器 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); if (startTime.length() == 4) { startTime = "0" + startTime; // 将 8:00 补充成 08:00 } // 将 startTime 转换为 LocalDateTime LocalDateTime startDateTime = LocalDateTime.parse(format + " " + startTime, formatter); // 计算 startTime 减去 cancelMinutes 后的时间 LocalDateTime cancelTime = startDateTime.minus(cancelMinutes, ChronoUnit.MINUTES); // 判断当前时间是否可以退款 if (cancelTime.isBefore(now)) { return AjaxResult.error("距离开场不足" + cancelMinutes + "分钟, 不允许线上退款!如需退款请线下联系工作人员!"); } } if ("numCard".equals(orderInfo.getPaymentType())) { refundSum++; } else { refundPrice = refundPrice.add(orderInfo.getPracticalMoney()); } } else if ("gouka".equals(orderInfo.getOrderType())) { //拿到次卡信息, 得到剩余使用次数 UserMembershipCard userMembershipCard = userMembershipCardService.selectUserMembershipCardRecordId(orderInfo.getId()); //获取原价信息 CarInformation carInformation = carInformationService.selectCarInformationById(Long.valueOf(orderInfo.getBusId())); //计算已使用次数 BigDecimal useSum = BigDecimal.valueOf(carInformation.getTotalNumber() - userMembershipCard.getRemainingNumber()); //计算需要支付的金额 BigDecimal userPrice = useSum.multiply(carInformation.getOriginalPrice()); //实际支付的金额 - 需要支付的金额 = 退款金额 BigDecimal refundMoner = orderInfo.getMemberPrice().subtract(userPrice); //判断如果退款金额 不大于0, 则设置退款金额为0 refundMoner = refundMoner.compareTo(BigDecimal.ZERO) > 0 ? refundMoner : BigDecimal.ZERO; //计算退款金额 refundPrice = refundPrice.add(refundMoner); } else if ("cansai".equals(orderInfo.getOrderType()) || "menpiao".equals(orderInfo.getOrderType())) { //验证赛事状态, 已经开始/已经结束/已经关闭 无法退款 Competition competition = competitionService.selectCompetitionById(Integer.valueOf(orderInfo.getBusId())); if ("competiton_state_5".equals(competition.getCompetitionState())) { return AjaxResult.error("赛事已开始, 无法退票!"); } if ("competiton_state_6".equals(competition.getCompetitionState())) { return AjaxResult.error("赛事已结束, 无法退票!"); } if ("competiton_state_3".equals(competition.getCompetitionState())) { return AjaxResult.error("报名已结束, 无法退票!"); } if ("competiton_state_4".equals(competition.getCompetitionState())) { return AjaxResult.error("赛事已关闭, 无法退票!"); } //计算退款金额 refundPrice = refundPrice.add(orderInfo.getPracticalMoney()); } vipCardLog.setRefundPrice(refundPrice); orderInfo.setRefundPrice(refundPrice); // executeUpdate=true 时才执行更新操作(包括订单状态、会员卡余额、次卡次数等) if (executeUpdate) { if("vipCard".equals(orderInfo.getPaymentType())){ //查询会员卡信息 VipCard vipCard = vipCardService.selectVipCardById(orderInfo.getPaymentId()); //写入会员卡流水 VipCardAmountLog vipCardAmountLog = new VipCardAmountLog(orderInfo.getUserId(), orderInfo.getPaymentId(), orderInfo.getId(), vipCard.getBalance(), refundPrice, "1"); amountLogMapper.insertVipCardAmountLog(vipCardAmountLog); vipCard.setBalance(vipCardAmountLog.getRemainingAmount()); vipCardService.updateVipCard(vipCard); } else if ("numCard".equals(orderInfo.getPaymentType())) { //查询次卡信息 UserMembershipCard userMembershipCard = userMembershipCardService.selectUserMembershipCardById(Long.valueOf(orderInfo.getPaymentId())); //剩余使用次数+1 userMembershipCard.setRemainingNumber(userMembershipCard.getRemainingNumber() + refundSum); //更新次卡信息 userMembershipCardService.updateUserMembershipCard(userMembershipCard); } vipCardLog.setRefundTime(DateUtils.getNowDate()); vipCardLog.setPaymentStatus("payment_status_refunded"); vipCardLogMapper.updateVipCardLog(vipCardLog); // 如果是约球订单,更新场次状态 if ("yueqiu".equals(orderInfo.getOrderType())) { AdmissionTicket admissionTicket = new AdmissionTicket(); admissionTicket.setId(orderInfo.getBusId()); admissionTicket.setAdmissionTicketStatus("0"); ticketService.updateBeilvAdmissionTicket(admissionTicket); } return AjaxResult.success("退款成功!"); } // executeUpdate=false 时只返回计算结果,不更新任何状态 if ("weChart".equals(orderInfo.getPaymentType())){ return AjaxResult.success(orderInfo); } return AjaxResult.success("退款金额计算成功!"); } @Override public List> selectYueQiuList(VipCardLog vipCardLog) { vipCardLog.setOrderType("yueqiu"); Map orderType = DictUtils.getDictCacheToMap("order_type"); Map paymentStatus = DictUtils.getDictCacheToMap("payment_status"); Map paymentType = DictUtils.getDictCacheToMap("payment_type"); List> maps = vipCardLogMapper.selectYueQiuList(vipCardLog); maps.forEach(map->{ map.put("orderTypeLabel", MapUtils.getString(orderType, MapUtils.getString(map,"orderType"))); map.put("paymentStatusLabel", MapUtils.getString(paymentStatus, MapUtils.getString(map,"paymentStatus"))); map.put("paymentTypeLabel", MapUtils.getString(paymentType, MapUtils.getString(map,"paymentType"))); map.put("createTime", MapUtils.getString(map, "createTime").replace("T", " ")); map.put("paymentTime", MapUtils.getString(map, "paymentTime").replace("T", " ")); }); return maps; } @Override public List> selectCanSaiList(VipCardLog vipCardLog) { List> maps = vipCardLogMapper.selectCanSaiList(vipCardLog); Map orderType = DictUtils.getDictCacheToMap("order_type"); Map paymentType = DictUtils.getDictCacheToMap("payment_type"); Map competitionState = DictUtils.getDictCacheToMap("competition_state"); Map paymentStatus = DictUtils.getDictCacheToMap("payment_status"); maps.forEach(map->{ map.put("orderTypeLabel", MapUtils.getString(orderType, MapUtils.getString(map,"orderType"))); map.put("paymentTypeLabel", MapUtils.getString(paymentType, MapUtils.getString(map,"paymentType"))); map.put("competitionStateLabel", MapUtils.getString(competitionState, MapUtils.getString(map,"competitionState"))); map.put("paymentStatusLabel", MapUtils.getString(paymentStatus, MapUtils.getString(map,"paymentStatus"))); map.put("publishTime", MapUtils.getString(map, "publishTime").replace("T", " ")); map.put("applyEndTime", MapUtils.getString(map, "applyEndTime").replace("T", " ")); map.put("applyStartTime", MapUtils.getString(map, "applyStartTime").replace("T", " ")); map.put("createTime", MapUtils.getString(map, "createTime").replace("T", " ")); map.put("paymentTime", MapUtils.getString(map, "paymentTime").replace("T", " ")); }); return maps; } public void insertAmountLog(VipCardAmountLog vipCardAmountLog){ amountLogMapper.insertVipCardAmountLog(vipCardAmountLog); } }