package com.cyksj.service.register.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.snowflake.Sequence; import com.cyksj.common.util.Codec; import com.cyksj.common.util.Jsons; import com.cyksj.config.WeChatConfig; import com.cyksj.dto.RedisKey; import com.cyksj.mapper.RegisterOrderDonMapper; import com.cyksj.model.dto.H5JsPayParams; import com.cyksj.model.entity.*; import com.cyksj.model.manage.request.RegisterReq; import com.cyksj.model.request.OrderAttach; import com.cyksj.redis.RedisService; import com.cyksj.service.register.RegisterOrderDonService; import com.cyksj.service.register.SpotifyService; import com.cyksj.service.sys.SysConfigService; import com.cyksj.service.wechat.WeChatService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; /** * @author chan * @date 2022/11/7 2:39 PM */ @Service @Slf4j @RequiredArgsConstructor public class RegisterOrderDonServiceImpl extends ServiceImpl implements RegisterOrderDonService { private static final Sequence SEQUENCE = new Sequence(0); private static final String REGISTER_PRICE_KEY = "register_price"; private final SpotifyService spotifyService; private final RedisService redisService; private final WeChatService weChatService; private final WeChatConfig weChatConfig; private final SysConfigService sysConfigService; /** * 判断是否免费 * @author chan * @date 2022-11-07 3:34 PM */ @Override public boolean isFree(long userId, String platform) { int count = count(Wrappers.lambdaQuery(RegisterOrderDon.class) .eq(RegisterOrderDon::getUserId, userId) .ne(RegisterOrderDon::getStatus, RegisterOrderDon.Status.noPayment) .eq(RegisterOrderDon::getIsFree, true)); if(count > 0){ return false; } Long num = redisService.decr(RedisKey.SPOTIFY_FREE_NUM, 1L); if(num >= 0){ return true; }else { redisService.incr(RedisKey.SPOTIFY_FREE_NUM, 1L); } return false; } /** * 保存注册资料 * @author chan * @date 2022-11-07 3:34 PM */ @Override @Transactional(rollbackFor = Throwable.class) public RegisterOrderDon saveOrder(long userId, RegisterReq req, boolean isFree) throws Exception { RegisterOrderDon orderDon = new RegisterOrderDon(); BeanUtil.copyProperties(req,orderDon); SysConfig register_price = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "register_price").last("limit 1")); Map map = Jsons.toMap(register_price.getSysValue()); orderDon.setOrderNo(SEQUENCE.nextId() + ""); orderDon.setIsFree(isFree); orderDon.setMoney(isFree ? BigDecimal.ZERO : new BigDecimal(map.get(req.getPlatform()))); orderDon.setStatus(isFree ? RegisterOrderDon.Status.hasPayment : RegisterOrderDon.Status.noPayment); save(orderDon); return orderDon; } @Override public H5JsPayParams pay(Long orderId) throws Exception { log.info("注册 账号调起微信支付[start] orderId:{}", orderId); RegisterOrderDon orderDon = this.getById(orderId); OrderAttach attach = new OrderAttach(); attach.setO(orderDon.getId()); String toWechatAttach = Codec.DoBase64.custom() .setData(Jsons.toJson(attach)).encodeAsText(); H5JsPayParams params = weChatService.getJsPayParams( weChatConfig.getAppid(), orderDon.getOpenId(), orderDon.getMoney().intValue(), orderDon.getOrderNo(), weChatConfig.getDomain() + "applets/register/prepay/notify", toWechatAttach, "注册服务" ); log.info("微信支付成功[end]"); return params; } @Override @Transactional(rollbackFor = Throwable.class) public void prepayNotify(Map map) throws Exception { /* 此处处理订单等业务逻辑 */ // 获取订单 和 微信订单号 和 支付的金额 String attach = Codec.DoBase64.custom().setData(map.get("attach")).decodeAsText(); OrderAttach orderAttach = Jsons.parseObject(attach, OrderAttach.class); final Long oid = orderAttach.getO(); //final Long shareId = orderAttach.getShared(); RegisterOrderDon order = this.getById(oid); if (null == order) { throw BusinessRuntimeException.getInstance("订单不存在."); } // 校验签名 boolean f = weChatService.checkSignWithMd5(map, weChatConfig.getShopKey()); if (!f) { log.error("回调数据:{}", map); throw BusinessRuntimeException.getInstance("支付成功回调, 校验签名失败."); } String transactionId = map.get("transaction_id"); if (order.getStatus().equals(RegisterOrderDon.Status.hasPayment)) { log.info("已回调,重复修改状态 id:{}", order.getId()); return; } // 更改订单状态 order.setTransactionId(transactionId); order.setStatus(RegisterOrderDon.Status.hasPayment); order.setPayTime(DateUtil.parse(map.get("time_end"), "yyyyMMddHHmmss")); if (StringUtils.isBlank(order.getOpenId())) { order.setOpenId(map.get("openid")); } this.updateById(order); } }