diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java index 20b59d6..b9face6 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java @@ -1291,14 +1291,14 @@ public class AppVerifyController extends BaseController } /** - * 优惠券购买 + * 优惠券购买(预支付) */ @GetMapping("/coupon/buy") public AjaxResult couponBuy(Long userId, Long couponId) { logger.info("优惠券购买:【userId="+userId+"】,【couponId="+couponId+"】"); - Boolean result =etCouponService.couponBuy(userId, couponId); - return success(result); + PrepayWithRequestPaymentResponse paymentResponse = etCouponService.couponBuy(userId, couponId); + return success(paymentResponse); } /** diff --git a/electripper-system/src/main/java/com/ruoyi/system/domain/EtOrder.java b/electripper-system/src/main/java/com/ruoyi/system/domain/EtOrder.java index 2d15eb1..5d88c55 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/domain/EtOrder.java +++ b/electripper-system/src/main/java/com/ruoyi/system/domain/EtOrder.java @@ -66,6 +66,10 @@ public class EtOrder extends BaseEntity @Excel(name = "计费规则") private Long ruleId; + /** 优惠券id */ + @Excel(name = "优惠券id") + private Long couponId; + /** 套餐对象 */ @TableField(exist = false) private EtFeeRule rule; diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/IEtCouponService.java b/electripper-system/src/main/java/com/ruoyi/system/service/IEtCouponService.java index 903aaea..bfe35cb 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/IEtCouponService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/IEtCouponService.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service; import java.util.List; import com.ruoyi.system.domain.EtCoupon; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; /** * 优惠券Service接口 @@ -65,5 +66,5 @@ public interface IEtCouponService * @param couponId * @return */ - Boolean couponBuy(Long userId, Long couponId); + PrepayWithRequestPaymentResponse couponBuy(Long userId, Long couponId); } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java b/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java index cd6c08a..04baafe 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java @@ -29,6 +29,13 @@ public interface IWxPayService { */ PrepayWithRequestPaymentResponse prepayWithRequestPayment(String payType, EtOrder order); + /** + * 生成微信预支付订单(优惠券) + * @param order 平台订单 + * @return JSAPI调用 + */ + PrepayWithRequestPaymentResponse prepayWithRequestPayment(EtOrder order); + // /** // * 关闭订单 diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java index c8ac3b4..15f56b7 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java @@ -48,10 +48,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -125,7 +122,10 @@ public class CallbackServiceImpl implements CallbackService { private CallbackService callbackService; @Resource - private EtModelMapper etModelMapper; + private EtCouponMapper etCouponMapper; + + @Resource + private EtCouponClaimLogMapper etCouponClaimLogMapper; @Value("${aliyun.accessKeyId}") private String accessKeyId; @@ -245,6 +245,14 @@ public class CallbackServiceImpl implements CallbackService { order.setMark("取消预约支付"); asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//取消预约支付后车辆正常运营 asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); + }else if(attachVo.getType().equals(ServiceConstants.ORDER_TYPE_COUPON)){ + /** 优惠券订单 */ + logger.info("【微信支付回调】优惠券支付"); + // 3-优惠券支付 + order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); + order.setMark("优惠券支付"); + // 优惠券成功处理逻辑 + couponSuccessHandle(order); }else if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_DEPOSIT)){ logger.info("【微信支付回调】押金支付"); // 4-押金支付 @@ -289,6 +297,56 @@ public class CallbackServiceImpl implements CallbackService { } } + private void couponSuccessHandle(EtOrder order) { + /** + * 购买分为抵用券订单,会员卡订单、折扣卡订单 + * 1. 插入一条记录,et_coupon_user_log 获取方式是购买 + * 2. 增加订单记录,类型是优惠券订单 + * 3. 增加账变, 所属人为运营商 + * */ + // 1. 插入一条记录,et_coupon_user_log 获取方式是购买 + Long userId = order.getUserId(); + Long couponId = order.getCouponId(); + AsUser asUser = asUserMapper.selectUserById(userId); + if(ObjectUtil.isNull(asUser)){ + throw new ServiceException("用户【"+userId+"】不存在"); + } + EtCoupon etCoupon = etCouponMapper.selectEtCouponByCouponId(couponId); + if(ObjectUtil.isNull(etCoupon)){ + throw new ServiceException("优惠券【"+couponId+"】不存在"); + } + EtCouponUserLog etCouponUserLog = new EtCouponUserLog(); + etCouponUserLog.setCouponId(couponId); + etCouponUserLog.setUserId(userId); + etCouponUserLog.setUserName(asUser.getUserName()); + etCouponUserLog.setCreateTime(DateUtils.getNowDate()); + etCouponUserLog.setGainMethod(ServiceConstants.COUPON_GAIN_METHOD_BUY); + etCouponUserLog.setAreaId(etCoupon.getAreaId()); + etCouponUserLog.setAreaName(etCoupon.getAreaName()); + etCouponUserLog.setExpirationTime(DateUtils.addValidity(new Date(),etCoupon.getValidityUnit(),etCoupon.getValidityValue())); + if(ServiceConstants.COUPON_TYPE_TIME_CARD.equals(etCoupon.getType()) || ServiceConstants.COUPON_TYPE_VIP_CARD.equals(etCoupon.getType())){ + AsUser asUser1 = new AsUser(userId); + asUser1.setVipType(etCoupon.getType()); + Date expirationTime; + if(ObjectUtil.isNull(asUser.getExpirationTime())){ + expirationTime = DateUtils.getNowDate(); + }else{ + expirationTime = asUser.getExpirationTime(); + } + asUser1.setExpirationTime(DateUtils.addValidity(expirationTime,etCoupon.getValidityUnit(),etCoupon.getValidityValue())); + asUser1.setUserId(userId); + int updateUser = asUserMapper.updateUser(asUser1); + } + int i1 = etCouponClaimLogMapper.insertEtCouponClaimLog(etCouponUserLog); + if(i1 == 0){ + throw new ServiceException("保存优惠券领取记录失败"); + } + + // 增加优惠券账变 + callbackService.capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_INCOME, + ServiceConstants.ORDER_TYPE_COUPON_INCOME,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_WX); + } + private void asynchronousMsg(EtOrder order, BigDecimal amount) { scheduledExecutorService.schedule(() -> { /** 发送一个短信给运营商*/ diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtCouponServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtCouponServiceImpl.java index b8222b1..903e8f0 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtCouponServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtCouponServiceImpl.java @@ -1,26 +1,29 @@ package com.ruoyi.system.service.impl; -import java.util.Date; -import java.util.List; - import cn.hutool.core.util.ObjectUtil; import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.core.domain.entity.AsUser; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.uuid.IdUtils; -import com.ruoyi.system.domain.*; +import com.ruoyi.system.domain.EtCoupon; +import com.ruoyi.system.domain.EtOrder; +import com.ruoyi.system.domain.vo.PrepayWithRequestPaymentResponseVo; import com.ruoyi.system.mapper.AsUserMapper; -import com.ruoyi.system.mapper.EtCouponClaimLogMapper; +import com.ruoyi.system.mapper.EtCouponMapper; import com.ruoyi.system.mapper.EtOrderMapper; -import com.ruoyi.system.service.CallbackService; +import com.ruoyi.system.service.IEtCouponService; +import com.ruoyi.system.service.IWxPayService; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.ruoyi.system.mapper.EtCouponMapper; -import com.ruoyi.system.service.IEtCouponService; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.util.List; /** * 优惠券Service业务层处理 @@ -29,14 +32,12 @@ import javax.annotation.Resource; * @date 2024-08-05 */ @Service +@Slf4j public class EtCouponServiceImpl implements IEtCouponService { @Resource private EtCouponMapper etCouponMapper; - @Resource - private EtCouponClaimLogMapper etCouponClaimLogMapper; - @Resource private AsUserMapper userMapper; @@ -44,7 +45,7 @@ public class EtCouponServiceImpl implements IEtCouponService private EtOrderMapper etOrderMapper; @Autowired - private CallbackService callbackService; + private IWxPayService wxPayService; /** * 查询优惠券 @@ -127,66 +128,29 @@ public class EtCouponServiceImpl implements IEtCouponService */ @Override @Transactional - public Boolean couponBuy(Long userId, Long couponId) { - /** - * 购买分为抵用券订单,会员卡订单、折扣卡订单 - * 1. 插入一条记录,et_coupon_user_log 获取方式是购买 - * 2. 增加订单记录,类型是优惠券订单 - * 3. 增加账变, 所属人为运营商 - * */ - // 1. 插入一条记录,et_coupon_user_log 获取方式是购买 + public PrepayWithRequestPaymentResponse couponBuy(Long userId, Long couponId) { + EtCoupon etCoupon = etCouponMapper.selectEtCouponByCouponId(couponId); + if(ObjectUtils.isEmpty(etCoupon)){ + throw new ServiceException("优惠券【"+couponId+"】不存在"); + } AsUser asUser = userMapper.selectUserById(userId); if(ObjectUtil.isNull(asUser)){ throw new ServiceException("用户【"+userId+"】不存在"); } - EtCoupon etCoupon = etCouponMapper.selectEtCouponByCouponId(couponId); - if(ObjectUtil.isNull(etCoupon)){ - throw new ServiceException("优惠券【"+couponId+"】不存在"); - } - EtCouponUserLog etCouponUserLog = new EtCouponUserLog(); - etCouponUserLog.setCouponId(couponId); - etCouponUserLog.setUserId(userId); - etCouponUserLog.setUserName(asUser.getUserName()); - etCouponUserLog.setCreateTime(DateUtils.getNowDate()); - etCouponUserLog.setGainMethod(ServiceConstants.COUPON_GAIN_METHOD_BUY); - etCouponUserLog.setAreaId(etCoupon.getAreaId()); - etCouponUserLog.setAreaName(etCoupon.getAreaName()); - etCouponUserLog.setExpirationTime(DateUtils.addValidity(new Date(),etCoupon.getValidityUnit(),etCoupon.getValidityValue())); - if(ServiceConstants.COUPON_TYPE_TIME_CARD.equals(etCoupon.getType()) || ServiceConstants.COUPON_TYPE_VIP_CARD.equals(etCoupon.getType())){ - AsUser asUser1 = new AsUser(userId); - asUser1.setVipType(etCoupon.getType()); - Date expirationTime; - if(ObjectUtil.isNull(asUser.getExpirationTime())){ - expirationTime = DateUtils.getNowDate(); - }else{ - expirationTime = asUser.getExpirationTime(); - } - asUser1.setExpirationTime(DateUtils.addValidity(expirationTime,etCoupon.getValidityUnit(),etCoupon.getValidityValue())); - int updateUser = userMapper.updateUser(asUser1); - } - int i1 = etCouponClaimLogMapper.insertEtCouponClaimLog(etCouponUserLog); - if(i1 == 0){ - throw new ServiceException("保存优惠券领取记录失败"); - } - // 2. 增加订单记录,类型是优惠券订单 EtOrder order = createOrder(etCoupon, asUser); - if(ObjectUtil.isNotNull(order)){ - int i = etOrderMapper.insertEtOrder(order); - if(i > 0){ - // 账变是针对账户而言的,优惠券充值后的入账是进入到那个账户? 有效期 季度 quarter - callbackService.capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_INCOME, - ServiceConstants.ORDER_TYPE_COUPON_INCOME,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_WX); - return true; - } - } - return false; + PrepayWithRequestPaymentResponse response = wxPayService.prepayWithRequestPayment(order); + PrepayWithRequestPaymentResponseVo responseVo = new PrepayWithRequestPaymentResponseVo(); + BeanUtils.copyProperties(response,responseVo); + responseVo.setSessionId(IdUtils.randomUUIDByDigit(8)); + responseVo.setOrderNo(order.getOrderNo()); + return responseVo; } private EtOrder createOrder(EtCoupon etCoupon,AsUser user) { EtOrder etOrder = new EtOrder(); - etOrder.setOrderNo(IdUtils.getOrderNo("wx")); + etOrder.setOrderNo(IdUtils.getOrderNo("yhj")); etOrder.setUserId(user.getUserId()); etOrder.setUserName(user.getUserName()); etOrder.setMark("优惠券购买"); @@ -197,6 +161,10 @@ public class EtCouponServiceImpl implements IEtCouponService etOrder.setType(ServiceConstants.ORDER_TYPE_COUPON); etOrder.setTotalFee(etCoupon.getRetailPrice()); etOrder.setPayFee(etCoupon.getRetailPrice()); + int i = etOrderMapper.insertEtOrder(etOrder); + if(i == 0){ + throw new ServiceException("订单生成失败"); + } return etOrder; } } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java index fb27a6a..c5f3f5e 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java @@ -143,6 +143,58 @@ public class WxPayService implements IWxPayService { } } + @Override + public PrepayWithRequestPaymentResponse prepayWithRequestPayment(EtOrder order) { + String billNo = order.getOrderNo(); + // 创建订单 + AsUser user = asUserService.selectUserById(order.getUserId()); + try { + List areaId1 = etAreaDeptMapper.selectList(new QueryWrapper().eq("area_id", order.getAreaId())); + if (ObjectUtil.isNotEmpty(areaId1) && areaId1.size() > 0){ + EtAreaDept etAreaDept = areaId1.get(0); + SysDept sysDept = deptService.selectDeptById(etAreaDept.getDeptId()); + log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept)); + if(ObjectUtil.isNull(sysDept)){ + throw new ServiceException("没有运营商:【"+etAreaDept.getDeptId()+"】"); + } + // 获取JSAPI所需参数 + PrepayRequest request = new PrepayRequest(); + request.setAmount(getAmount(order.getPayFee())); + JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept); + if(StrUtil.isNotBlank(order.getOutTradeNo())){ + String tradeNo = order.getOutTradeNo(); + // 关闭订单 + CloseOrderRequest closeOrderRequest = new CloseOrderRequest(); + closeOrderRequest.setMchid(sysDept.getMerchantId()); + closeOrderRequest.setOutTradeNo(tradeNo); + jsapiServiceExtension.closeOrder(closeOrderRequest); + } + String outTradeNo = IdUtils.getOrderNo("wx"); + order.setOutTradeNo(outTradeNo); + int updateEtOrder = etOrderService.updateEtOrder(order); + if(updateEtOrder == 0){ + throw new ServiceException("更新订单outTradeNo失败"); + } + request.setOutTradeNo(outTradeNo); + request.setAppid(sysDept.getAppid()); + request.setMchid(sysDept.getMerchantId()); + String description = "优惠券订单-"+billNo; + request.setAttach(JSON.toJSONString(new AttachVo(order.getType(),user.getUserId(), ""))); + request.setDescription(description); + request.setNotifyUrl(sysDept.getNotifyUrl()); + request.setPayer(getPayer(user.getWxopenid())); + PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request); + return res; + }else{ + log.info("区域:【{}】没有绑定运营商",order.getAreaId()); + throw new ServiceException("区域:【"+order.getAreaId()+"】没有绑定运营商"); + } + } finally { + redisLock.unlock(PREPAY_LOCK + billNo); + } + } + + private JsapiServiceExtension getJsapiServiceExtension(SysDept sysDept) { // 初始化商户配置 Config config = new RSAAutoCertificateConfig.Builder()