VipCardLogServiceImpl.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. package beilv.vipCardLog.service.impl;
  2. import beilv.admissionticket.domain.AdmissionTicket;
  3. import beilv.admissionticket.mapper.AdmissionTicketMapper;
  4. import beilv.admissionticket.service.IAdmissionTicketService;
  5. import beilv.carinformation.domain.CarInformation;
  6. import beilv.carinformation.service.ICarInformationService;
  7. import beilv.common.core.domain.AjaxResult;
  8. import beilv.common.core.text.Convert;
  9. import beilv.common.utils.DateUtils;
  10. import beilv.common.utils.DictUtils;
  11. import beilv.common.utils.StringUtils;
  12. import beilv.common.utils.uuid.IdUtils;
  13. import beilv.competition.domain.Competition;
  14. import beilv.competition.service.ICompetitionService;
  15. import beilv.system.service.ISysConfigService;
  16. import beilv.usermembershipcard.domain.UserMembershipCard;
  17. import beilv.usermembershipcard.service.IUserMembershipCardService;
  18. import beilv.vipCard.domain.VipCard;
  19. import beilv.vipCard.service.IVipCardService;
  20. import beilv.vipCardAmountLog.domain.VipCardAmountLog;
  21. import beilv.vipCardAmountLog.mapper.VipCardAmountLogMapper;
  22. import beilv.vipCardLog.domain.VipCardLog;
  23. import beilv.vipCardLog.mapper.VipCardLogMapper;
  24. import beilv.vipCardLog.service.IVipCardLogService;
  25. import beilv.voucher.domain.BeilvVoucherMember;
  26. import org.apache.commons.collections4.MapUtils;
  27. import org.checkerframework.checker.units.qual.A;
  28. import org.springframework.beans.factory.annotation.Autowired;
  29. import org.springframework.data.redis.core.StringRedisTemplate;
  30. import org.springframework.stereotype.Service;
  31. import javax.annotation.Resource;
  32. import java.math.BigDecimal;
  33. import java.math.RoundingMode;
  34. import java.text.SimpleDateFormat;
  35. import java.time.LocalDateTime;
  36. import java.time.format.DateTimeFormatter;
  37. import java.time.temporal.ChronoUnit;
  38. import java.util.List;
  39. import java.util.Map;
  40. import static beilv.competition.domain.Constant.ORDER_QUEUE;
  41. /**
  42. * 充值记录Service业务层处理
  43. *
  44. * @author LG
  45. * @date 2025-11-12
  46. */
  47. @Service
  48. public class VipCardLogServiceImpl implements IVipCardLogService {
  49. @Resource
  50. private VipCardLogMapper vipCardLogMapper;
  51. @Autowired
  52. private IVipCardService vipCardService;
  53. @Autowired
  54. private ICompetitionService competitionService;
  55. @Autowired
  56. private IUserMembershipCardService userMembershipCardService;
  57. @Autowired
  58. private ICarInformationService carInformationService;
  59. @Autowired
  60. private IAdmissionTicketService ticketService;
  61. @Autowired
  62. private ISysConfigService configService;
  63. @Resource
  64. private VipCardAmountLogMapper amountLogMapper;
  65. @Autowired
  66. private StringRedisTemplate stringRedisTemplate;
  67. /**
  68. * 查询充值记录
  69. *
  70. * @param id 充值记录主键
  71. * @return 充值记录
  72. */
  73. @Override
  74. public VipCardLog selectVipCardLogById(String id) {
  75. return vipCardLogMapper.selectVipCardLogById(id);
  76. }
  77. /**
  78. * 查询充值记录列表
  79. *
  80. * @param vipCardLog 充值记录
  81. * @return 充值记录
  82. */
  83. @Override
  84. public List<VipCardLog> selectVipCardLogList(VipCardLog vipCardLog) {
  85. List<VipCardLog> list = vipCardLogMapper.selectVipCardLogList(vipCardLog);
  86. Map<String, String> orderType = DictUtils.getDictCacheToMap("order_type");
  87. Map<String, String> paymentStatus = DictUtils.getDictCacheToMap("payment_status");
  88. Map<String, String> paymentType = DictUtils.getDictCacheToMap("payment_type");
  89. for (VipCardLog var : list) {
  90. var.setOrderTypeText(MapUtils.getString(orderType, var.getOrderType()));
  91. var.setPaymentStatusText(MapUtils.getString(paymentStatus, var.getPaymentStatus()));
  92. var.setPaymentTypeText(MapUtils.getString(paymentType, var.getPaymentType()));
  93. }
  94. return list;
  95. }
  96. /**
  97. * 新增充值记录
  98. *
  99. * @param vipCardLog 充值记录
  100. * @return 结果
  101. */
  102. @Override
  103. public int insertVipCardLog(VipCardLog vipCardLog) {
  104. return vipCardLogMapper.insertVipCardLog(vipCardLog);
  105. }
  106. /**
  107. * 修改充值记录
  108. *
  109. * @param vipCardLog 充值记录
  110. * @return 结果
  111. */
  112. @Override
  113. public int updateVipCardLog(VipCardLog vipCardLog) {
  114. return vipCardLogMapper.updateVipCardLog(vipCardLog);
  115. }
  116. /**
  117. * 批量删除充值记录
  118. *
  119. * @param ids 需要删除的充值记录主键
  120. * @return 结果
  121. */
  122. @Override
  123. public int deleteVipCardLogByIds(String ids) {
  124. return vipCardLogMapper.deleteVipCardLogByIds(Convert.toStrArray(ids));
  125. }
  126. /**
  127. * 删除充值记录信息
  128. *
  129. * @param id 充值记录主键
  130. * @return 结果
  131. */
  132. @Override
  133. public int deleteVipCardLogById(String id) {
  134. return vipCardLogMapper.deleteVipCardLogById(id);
  135. }
  136. @Override
  137. public int updateVipCardLogByOrderId(VipCardLog vipCardLog) {
  138. //验证订单编号是否为空
  139. if (StringUtils.isEmpty(vipCardLog.getId())) {
  140. return 0;
  141. }
  142. //拉去订单信息
  143. VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId());
  144. //充值订单和其他订单处理方式不同
  145. if ("chongzhi".equals(orderInfo.getOrderType())) {
  146. charging(vipCardLog, orderInfo);
  147. } else {
  148. other(vipCardLog, orderInfo);
  149. }
  150. //更新订单状态
  151. return vipCardLogMapper.updateVipCardLog(vipCardLog);
  152. }
  153. /**
  154. * 充值回调
  155. *
  156. * @param vipCardLog 订单请求信息
  157. * @param orderInfo 原订单信息
  158. * @return
  159. */
  160. private void charging(VipCardLog vipCardLog, VipCardLog orderInfo) {
  161. if ("payment_status_have_paid".equals(vipCardLog.getPaymentStatus())) {
  162. //拉取订单信息
  163. // VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId());
  164. //获取会员卡信息
  165. VipCard vipCard = vipCardService.selectVipCardByUserId(orderInfo.getUserId());
  166. //获取当前余额
  167. BigDecimal balance = BigDecimal.ZERO;
  168. String vipCardId;
  169. if (null == vipCard) {
  170. //true 没有会员卡; 新增会员卡, 并且设置本次充值金额
  171. vipCardId = vipCardService.insertVipCard(new VipCard(Long.parseLong(orderInfo.getUserId()), orderInfo.getPracticalMoney(), BigDecimal.ZERO));
  172. } else {
  173. balance = vipCard.getBalance();
  174. vipCardId = vipCard.getId();
  175. //false 有会员卡,
  176. vipCardService.updateVipCard(new VipCard(Long.parseLong(orderInfo.getUserId()), orderInfo.getPracticalMoney().add(vipCard.getBalance()).setScale(2, RoundingMode.HALF_UP), vipCard.getScore()));
  177. }
  178. //设定支付时间
  179. vipCardLog.setPaymentTime(DateUtils.getNowDate());
  180. //写入会员卡流水
  181. insertAmountLog(new VipCardAmountLog(orderInfo.getUserId(), vipCardId, orderInfo.getId(), balance, orderInfo.getPracticalMoney(),"1"));
  182. //支付成功移除定时任务
  183. stringRedisTemplate.delete(ORDER_QUEUE+orderInfo.getId());
  184. } else if ("payment_status_cancelled".equals(vipCardLog.getPaymentStatus())) {
  185. //如果是取消, 设置支付状态为取消支付
  186. vipCardLog.setCancellationTime(DateUtils.getNowDate());
  187. }
  188. }
  189. /**
  190. * 其他支付回调
  191. *
  192. * @param vipCardLog
  193. * @return
  194. */
  195. private void other(VipCardLog vipCardLog, VipCardLog orderInfo) {
  196. //拉取订单信息
  197. // VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId());
  198. if ("payment_status_have_paid".equals(vipCardLog.getPaymentStatus())) {
  199. //支付成功流程
  200. //设置支付时间
  201. vipCardLog.setPaymentTime(DateUtils.getNowDate());
  202. //获取订单类型
  203. String orderType = orderInfo.getOrderType();
  204. if ("gouka".equals(orderType)) {
  205. //如果是购买次卡订单, 拉去卡种信息
  206. CarInformation carInformation = carInformationService.selectCarInformationById(Long.valueOf(orderInfo.getBusId()));
  207. //购卡订单, 支付成功, 生成卡片写入到次卡表
  208. userMembershipCardService.insertUserMembershipCard(new UserMembershipCard(orderInfo.getUserId(), vipCardLog.getId(), carInformation.getTotalNumber(), "0", "3", DateUtils.getNowDate(), orderInfo.getBusId()));
  209. }
  210. if("yueqiu".equals(orderType)){
  211. //如果是约球订单
  212. AdmissionTicket admissionTicket = new AdmissionTicket();
  213. admissionTicket.setId(orderInfo.getBusId());
  214. //创建场次定时任务, 到时间自动核销
  215. ticketService.createTask(admissionTicket);
  216. }
  217. } else if ("payment_status_cancelled".equals(vipCardLog.getPaymentStatus())) {
  218. //如果是取消订单,设置支付状态为取消支付
  219. vipCardLog.setCancellationTime(DateUtils.getNowDate());
  220. if ("yueqiu".equals(orderInfo.getOrderType())) {
  221. //如果是约球订单, 修改球场信息
  222. AdmissionTicket admissionTicket = new AdmissionTicket();
  223. admissionTicket.setId(orderInfo.getBusId());
  224. admissionTicket.setAdmissionTicketStatus("0");
  225. ticketService.updateBeilvAdmissionTicket(admissionTicket);
  226. }
  227. }
  228. }
  229. @Override
  230. public int getRegistrantsNumber(VipCardLog vipCardLog) {
  231. return vipCardLogMapper.getRegistrantsNumber(vipCardLog);
  232. }
  233. @Override
  234. public AjaxResult refundById(VipCardLog vipCardLog, boolean isOnline, boolean executeUpdate) {
  235. if(StringUtils.isEmpty(vipCardLog.getId())){
  236. return AjaxResult.error("订单编号不能为空!");
  237. }
  238. //拉去订单信息
  239. VipCardLog orderInfo = vipCardLogMapper.selectVipCardLogById(vipCardLog.getId());
  240. if ("payment_status_to_be_paid".equals(orderInfo.getPaymentStatus())) {
  241. return AjaxResult.error("订单未支付, 无需退款!");
  242. }
  243. if ("payment_status_cancelled".equals(orderInfo.getPaymentStatus())) {
  244. return AjaxResult.error("订单已取消, 无需退款!");
  245. }
  246. if ("payment_status_refunded".equals(orderInfo.getPaymentStatus())) {
  247. return AjaxResult.error("订单已退款, 无需重复操作!");
  248. }
  249. if ("payment_status_verification".equals(orderInfo.getPaymentStatus())) {
  250. return AjaxResult.error("订单已核销, 无法退款!");
  251. }
  252. //退款金额
  253. BigDecimal refundPrice = BigDecimal.valueOf(0);
  254. int refundSum = 0;
  255. if ("yueqiu".equals(orderInfo.getOrderType())) {
  256. if (isOnline) {
  257. // 获取设定的取消时间范围(分钟)
  258. long cancelMinutes = Long.parseLong(configService.selectConfigByKey("cancel.minutes"));
  259. // 根据订单获取约场的开始时间
  260. AdmissionTicket admissionTicket = ticketService.selectBeilvAdmissionTicketById(orderInfo.getBusId());
  261. String format = new SimpleDateFormat("yyyy-MM-dd").format(admissionTicket.getTicketDate());
  262. String startTime = admissionTicket.getSession().split("-")[0]; // 10:00
  263. // 当前时间
  264. LocalDateTime now = LocalDateTime.now();
  265. // 定义日期时间格式器
  266. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
  267. if (startTime.length() == 4) {
  268. startTime = "0" + startTime; // 将 8:00 补充成 08:00
  269. }
  270. // 将 startTime 转换为 LocalDateTime
  271. LocalDateTime startDateTime = LocalDateTime.parse(format + " " + startTime, formatter);
  272. // 计算 startTime 减去 cancelMinutes 后的时间
  273. LocalDateTime cancelTime = startDateTime.minus(cancelMinutes, ChronoUnit.MINUTES);
  274. // 判断当前时间是否可以退款
  275. if (cancelTime.isBefore(now)) {
  276. return AjaxResult.error("距离开场不足" + cancelMinutes + "分钟, 不允许线上退款!如需退款请线下联系工作人员!");
  277. }
  278. }
  279. if ("numCard".equals(orderInfo.getPaymentType())) {
  280. refundSum++;
  281. } else {
  282. refundPrice = refundPrice.add(orderInfo.getPracticalMoney());
  283. }
  284. } else if ("gouka".equals(orderInfo.getOrderType())) {
  285. //拿到次卡信息, 得到剩余使用次数
  286. UserMembershipCard userMembershipCard = userMembershipCardService.selectUserMembershipCardRecordId(orderInfo.getId());
  287. //获取原价信息
  288. CarInformation carInformation = carInformationService.selectCarInformationById(Long.valueOf(orderInfo.getBusId()));
  289. //计算已使用次数
  290. BigDecimal useSum = BigDecimal.valueOf(carInformation.getTotalNumber() - userMembershipCard.getRemainingNumber());
  291. //计算需要支付的金额
  292. BigDecimal userPrice = useSum.multiply(carInformation.getOriginalPrice());
  293. //实际支付的金额 - 需要支付的金额 = 退款金额
  294. BigDecimal refundMoner = orderInfo.getMemberPrice().subtract(userPrice);
  295. //判断如果退款金额 不大于0, 则设置退款金额为0
  296. refundMoner = refundMoner.compareTo(BigDecimal.ZERO) > 0 ? refundMoner : BigDecimal.ZERO;
  297. //计算退款金额
  298. refundPrice = refundPrice.add(refundMoner);
  299. } else if ("cansai".equals(orderInfo.getOrderType()) || "menpiao".equals(orderInfo.getOrderType())) {
  300. //验证赛事状态, 已经开始/已经结束/已经关闭 无法退款
  301. Competition competition = competitionService.selectCompetitionById(Integer.valueOf(orderInfo.getBusId()));
  302. if ("competiton_state_5".equals(competition.getCompetitionState())) {
  303. return AjaxResult.error("赛事已开始, 无法退票!");
  304. }
  305. if ("competiton_state_6".equals(competition.getCompetitionState())) {
  306. return AjaxResult.error("赛事已结束, 无法退票!");
  307. }
  308. if ("competiton_state_3".equals(competition.getCompetitionState())) {
  309. return AjaxResult.error("报名已结束, 无法退票!");
  310. }
  311. if ("competiton_state_4".equals(competition.getCompetitionState())) {
  312. return AjaxResult.error("赛事已关闭, 无法退票!");
  313. }
  314. //计算退款金额
  315. refundPrice = refundPrice.add(orderInfo.getPracticalMoney());
  316. }
  317. vipCardLog.setRefundPrice(refundPrice);
  318. orderInfo.setRefundPrice(refundPrice);
  319. // executeUpdate=true 时才执行更新操作(包括订单状态、会员卡余额、次卡次数等)
  320. if (executeUpdate) {
  321. if("vipCard".equals(orderInfo.getPaymentType())){
  322. //查询会员卡信息
  323. VipCard vipCard = vipCardService.selectVipCardById(orderInfo.getPaymentId());
  324. //写入会员卡流水
  325. VipCardAmountLog vipCardAmountLog = new VipCardAmountLog(orderInfo.getUserId(), orderInfo.getPaymentId(), orderInfo.getId(), vipCard.getBalance(), refundPrice, "1");
  326. amountLogMapper.insertVipCardAmountLog(vipCardAmountLog);
  327. vipCard.setBalance(vipCardAmountLog.getRemainingAmount());
  328. vipCardService.updateVipCard(vipCard);
  329. } else if ("numCard".equals(orderInfo.getPaymentType())) {
  330. //查询次卡信息
  331. UserMembershipCard userMembershipCard = userMembershipCardService.selectUserMembershipCardById(Long.valueOf(orderInfo.getPaymentId()));
  332. //剩余使用次数+1
  333. userMembershipCard.setRemainingNumber(userMembershipCard.getRemainingNumber() + refundSum);
  334. //更新次卡信息
  335. userMembershipCardService.updateUserMembershipCard(userMembershipCard);
  336. }
  337. vipCardLog.setRefundTime(DateUtils.getNowDate());
  338. vipCardLog.setPaymentStatus("payment_status_refunded");
  339. vipCardLogMapper.updateVipCardLog(vipCardLog);
  340. // 如果是约球订单,更新场次状态
  341. if ("yueqiu".equals(orderInfo.getOrderType())) {
  342. AdmissionTicket admissionTicket = new AdmissionTicket();
  343. admissionTicket.setId(orderInfo.getBusId());
  344. admissionTicket.setAdmissionTicketStatus("0");
  345. ticketService.updateBeilvAdmissionTicket(admissionTicket);
  346. }
  347. return AjaxResult.success("退款成功!");
  348. }
  349. // executeUpdate=false 时只返回计算结果,不更新任何状态
  350. if ("weChart".equals(orderInfo.getPaymentType())){
  351. return AjaxResult.success(orderInfo);
  352. }
  353. return AjaxResult.success("退款金额计算成功!");
  354. }
  355. @Override
  356. public List<Map<String, Object>> selectYueQiuList(VipCardLog vipCardLog) {
  357. vipCardLog.setOrderType("yueqiu");
  358. Map<String, String> orderType = DictUtils.getDictCacheToMap("order_type");
  359. Map<String, String> paymentStatus = DictUtils.getDictCacheToMap("payment_status");
  360. Map<String, String> paymentType = DictUtils.getDictCacheToMap("payment_type");
  361. List<Map<String, Object>> maps = vipCardLogMapper.selectYueQiuList(vipCardLog);
  362. maps.forEach(map->{
  363. map.put("orderTypeLabel", MapUtils.getString(orderType, MapUtils.getString(map,"orderType")));
  364. map.put("paymentStatusLabel", MapUtils.getString(paymentStatus, MapUtils.getString(map,"paymentStatus")));
  365. map.put("paymentTypeLabel", MapUtils.getString(paymentType, MapUtils.getString(map,"paymentType")));
  366. map.put("createTime", MapUtils.getString(map, "createTime").replace("T", " "));
  367. map.put("paymentTime", MapUtils.getString(map, "paymentTime").replace("T", " "));
  368. });
  369. return maps;
  370. }
  371. @Override
  372. public List<Map<String, Object>> selectCanSaiList(VipCardLog vipCardLog) {
  373. List<Map<String, Object>> maps = vipCardLogMapper.selectCanSaiList(vipCardLog);
  374. Map<String, String> orderType = DictUtils.getDictCacheToMap("order_type");
  375. Map<String, String> paymentType = DictUtils.getDictCacheToMap("payment_type");
  376. Map<String, String> competitionState = DictUtils.getDictCacheToMap("competition_state");
  377. Map<String, String> paymentStatus = DictUtils.getDictCacheToMap("payment_status");
  378. maps.forEach(map->{
  379. map.put("orderTypeLabel", MapUtils.getString(orderType, MapUtils.getString(map,"orderType")));
  380. map.put("paymentTypeLabel", MapUtils.getString(paymentType, MapUtils.getString(map,"paymentType")));
  381. map.put("competitionStateLabel", MapUtils.getString(competitionState, MapUtils.getString(map,"competitionState")));
  382. map.put("paymentStatusLabel", MapUtils.getString(paymentStatus, MapUtils.getString(map,"paymentStatus")));
  383. map.put("publishTime", MapUtils.getString(map, "publishTime").replace("T", " "));
  384. map.put("applyEndTime", MapUtils.getString(map, "applyEndTime").replace("T", " "));
  385. map.put("applyStartTime", MapUtils.getString(map, "applyStartTime").replace("T", " "));
  386. map.put("createTime", MapUtils.getString(map, "createTime").replace("T", " "));
  387. map.put("paymentTime", MapUtils.getString(map, "paymentTime").replace("T", " "));
  388. });
  389. return maps;
  390. }
  391. public void insertAmountLog(VipCardAmountLog vipCardAmountLog){
  392. amountLogMapper.insertVipCardAmountLog(vipCardAmountLog);
  393. }
  394. }