From 5d7b65670282a4fad015e37d567cfa171b162052 Mon Sep 17 00:00:00 2001 From: huliguo <2023611923@qq.com> Date: 星期二, 20 五月 2025 12:25:19 +0800 Subject: [PATCH] 基础代码 --- pt-errand/src/main/java/com/ruoyi/errand/service/impl/VipOrderServiceImpl.java | 181 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 181 insertions(+), 0 deletions(-) diff --git a/pt-errand/src/main/java/com/ruoyi/errand/service/impl/VipOrderServiceImpl.java b/pt-errand/src/main/java/com/ruoyi/errand/service/impl/VipOrderServiceImpl.java new file mode 100644 index 0000000..849a970 --- /dev/null +++ b/pt-errand/src/main/java/com/ruoyi/errand/service/impl/VipOrderServiceImpl.java @@ -0,0 +1,181 @@ +package com.ruoyi.errand.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.errand.constant.DelFlagConstant; +import com.ruoyi.errand.domain.AppUser; +import com.ruoyi.errand.domain.VipOrder; +import com.ruoyi.errand.domain.VipSetting; +import com.ruoyi.errand.mapper.AppUserMapper; +import com.ruoyi.errand.mapper.VipOrderMapper; +import com.ruoyi.errand.mapper.VipSettingMapper; +import com.ruoyi.errand.object.dto.app.VipPaymentDTO; +import com.ruoyi.errand.service.VipOrderService; +import com.ruoyi.errand.utils.CloseOrderResult; +import com.ruoyi.errand.utils.PaymentUtil; +import com.ruoyi.errand.utils.UniPayCallbackResult; +import com.ruoyi.errand.utils.UniPayResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Set; + +@Service +@Slf4j +public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper, VipOrder> implements VipOrderService { + @Resource + private VipSettingMapper vipSettingMapper; + @Resource + private RedisTemplate redisTemplate; + @Resource + private AppUserMapper appUserMapper; + + @Override + public R vipPayment(VipPaymentDTO vipPaymentDTO) { + AppUser appuser = (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + VipOrder vipOrder = new VipOrder(); + vipOrder.setAppUserId(appuser.getId()); + + VipSetting vipSetting = vipSettingMapper.selectById(vipPaymentDTO.getId()); + vipOrder.setOrderAmount(vipSetting.getVip_price()); + vipOrder.setPaymentAmount(vipSetting.getVip_price()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + vipOrder.setOrderNumber("QJS" + getNumber(3) + sdf.format(new Date())); + vipOrder.setPayStatus(1); + vipOrder.setVipId(vipPaymentDTO.getId()); + this.save(vipOrder); + //判断需要支付的金额是否大于0 + BigDecimal paymentMoney = vipOrder.getOrderAmount(); + if ( BigDecimal.ZERO.compareTo(paymentMoney) < 0){ + //调起微信支付 + String vipName = vipSetting.getVip_name(); + UniPayResult uniPayResult = PaymentUtil.uniPay(vipOrder.getOrderNumber(), paymentMoney.doubleValue(), "购买会员", + vipName, "", "/app/vipOrder/orderPaymentCallback", appuser.getWxOpenid(), null); + if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){ + return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg()); + } + String rc_result = uniPayResult.getRc_Result(); + JSONObject jsonObject = JSON.parseObject(rc_result); + jsonObject.put("orderId", vipOrder.getId().toString()); + //将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。 + long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC); + redisTemplate.opsForZSet().add("VipOrderPayment", vipOrder.getOrderNumber(), second); + return R.ok(jsonObject.toJSONString()); + } + //设置vipOrder信息 + vipOrder.setPayStatus(2);//已支付 + vipOrder.setOrderTime(LocalDateTime.now());//下单时间 + this.updateById(vipOrder); + //更新用户信息 + Long appUserId = vipOrder.getAppUserId(); + AppUser appUser = appUserMapper.selectById(appUserId); + appUser.setVipId(vipOrder.getVipId()); + if (appUser.getEndTime().isBefore(LocalDateTime.now())) { + appUser.setStartTime(LocalDateTime.now()); + } + // 根据 vipId 计算会员到期时间 + LocalDateTime endTime = calculateEndTime(appUser.getEndTime(), vipOrder.getVipId()); + appUser.setEndTime(endTime); + appUserMapper.updateById(appUser); + return R.ok(); + + } + + @Override + public R orderPaymentCallback(UniPayCallbackResult uniPayCallbackResult) { + VipOrder vipOrder = this.getBaseMapper().selectOne(new LambdaQueryWrapper<VipOrder>().eq(VipOrder::getOrderNumber, uniPayCallbackResult.getR2_OrderNo())); + if(null == vipOrder || vipOrder.getPayStatus() == 2){ + return R.ok(); + } + //设置vipOrder信息 + vipOrder.setPayStatus(2);//已支付 + vipOrder.setOrderTime(LocalDateTime.now());//下单时间 + String r7TrxNo = uniPayCallbackResult.getR9_BankTrxNo(); + vipOrder.setSerialNumber(r7TrxNo); + this.updateById(vipOrder); + //更新用户信息 + //检查是否续期的 + Long appUserId = vipOrder.getAppUserId(); + AppUser appUser = appUserMapper.selectById(appUserId); + appUser.setVipId(vipOrder.getVipId()); + LocalDateTime now = LocalDateTime.now(); + appUser.setEndTime(appUser.getEndTime()==null?now:appUser.getEndTime()); + if (appUser.getEndTime().isBefore(now)) { + appUser.setStartTime(now); + } + // 根据 vipId 计算会员到期时间 + LocalDateTime endTime = calculateEndTime(appUser.getEndTime(), vipOrder.getVipId()); + appUser.setEndTime(endTime); + appUserMapper.updateById(appUser); + return R.ok(); + } + + @Override + public void closeOrder() { + //订单支付数据 + long second = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC); + Set<String> orderPayment = redisTemplate.opsForZSet().rangeByScore("VipOrderPayment", 0, second); + if(orderPayment.size() > 0){ + List<VipOrder> list = this.getBaseMapper().selectList(new LambdaQueryWrapper<VipOrder>().in(VipOrder::getOrderNumber, orderPayment)); + for (VipOrder order : list) { + if(null == order || order.getPayStatus() != 1){ + //不在待支付中的,移除 + redisTemplate.opsForZSet().remove("VipOrderPayment", order.getOrderNumber()); + continue; + } + //开始执行关闭订单操作 + CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(order.getOrderNumber()); + if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) && + Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){ + redisTemplate.opsForZSet().add("VipOrderPayment", order.getOrderNumber(), 0); + log.error("关闭订单失败:{}---->{}",order.getOrderNumber(), JSON.toJSONString(closeOrderResult)); + } + redisTemplate.opsForZSet().remove("VipOrderPayment", order.getOrderNumber()); + //删除订单 + order.setDelFlag(DelFlagConstant.DELETE); + this.updateById(order); + + } + } + } + + + private LocalDateTime calculateEndTime(LocalDateTime startTime, Integer vipId) { + switch (vipId) { + case 1: // 月卡 + return startTime.plusDays(31).withHour(23).withMinute(59).withSecond(59); + case 2: // 季卡 + return startTime.plusDays(90).withHour(23).withMinute(59).withSecond(59); + case 3: // 半年卡 + return startTime.plusDays(180).withHour(23).withMinute(59).withSecond(59); + case 4: // 年卡 + return startTime.plusDays(365).withHour(23).withMinute(59).withSecond(59); + default: + // 处理无效的 vipId 情况,例如抛出异常或记录日志 + throw new ServiceException("无效的 vipId: " + vipId); + } + } + + public String getNumber(Integer size){ + StringBuilder str = new StringBuilder(); + for (int i = 0; i < size; i++) { + str.append(Double.valueOf(Math.random() * 10).intValue()); + } + return str.toString(); + } + +} -- Gitblit v1.7.1