admin
2025-02-25 30d8e227e8d823b6c38c3b9c90ac2df03b63befe
fanli/src/main/java/com/yeshi/fanli/service/impl/redpack/RedPackGiveRecordServiceImpl.java
@@ -1,210 +1,290 @@
package com.yeshi.fanli.service.impl.redpack;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import com.google.gson.Gson;
import com.yeshi.fanli.dao.mybatis.redpack.RedPackGiveRecordMapper;
import com.yeshi.fanli.dto.msg.MsgRedPackGiveContentDTO;
import com.yeshi.fanli.entity.bus.msg.MsgMoneyDetail.MsgTypeMoneyTypeEnum;
import com.yeshi.fanli.entity.bus.user.TokenRecord;
import com.yeshi.fanli.entity.bus.user.TokenRecord.TokenTypeEnum;
import com.yeshi.fanli.entity.redpack.RedPackDetail;
import com.yeshi.fanli.entity.redpack.RedPackDetail.RedPackDetailTypeEnum;
import com.yeshi.fanli.entity.redpack.RedPackGiveRecord;
import com.yeshi.fanli.exception.redpack.RedPackBalanceException;
import com.yeshi.fanli.exception.redpack.RedPackGiveRecordException;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.redpack.RedPackBalanceService;
import com.yeshi.fanli.service.inter.redpack.RedPackConfigService;
import com.yeshi.fanli.service.inter.redpack.RedPackDetailService;
import com.yeshi.fanli.service.inter.redpack.RedPackGiveRecordService;
import com.yeshi.fanli.service.inter.user.TokenRecordService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TokenUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
import com.yeshi.fanli.util.factory.RedPackDetailFactory;
@Service
public class RedPackGiveRecordServiceImpl implements RedPackGiveRecordService {
   @Resource
   private RedPackGiveRecordMapper redPackGiveRecordMapper;
   @Resource
   private RedPackConfigService redPackConfigService;
   @Resource
   private RedPackBalanceService redPackBalanceService;
   @Resource
   private TokenRecordService tokenRecordService;
   @Resource
   private RedPackDetailService redPackDetailService;
   @Resource
   private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
   @Override
   public RedPackGiveRecord selectByPrimaryKey(Long id) {
      return redPackGiveRecordMapper.selectByPrimaryKey(id);
   }
   @Override
   public void updateByPrimaryKeySelective(RedPackGiveRecord record) {
      redPackGiveRecordMapper.updateByPrimaryKeySelective(record);
   }
   @Override
   @RequestSerializableByKeyService(key = "#id")
   @Transactional(rollbackFor = Exception.class)
   public void overdueByPrimaryKey(Long id) throws Exception {
      if (id == null)
         return;
      RedPackGiveRecord giveRecord = redPackGiveRecordMapper.selectByPrimaryKey(id);
      if (giveRecord == null)
         return;
      if (giveRecord.getState() != null && giveRecord.getState() != RedPackGiveRecord.STATE_INIT )
         return;
      // 赠送记录失效
      RedPackGiveRecord updateRecord = new RedPackGiveRecord();
      updateRecord.setId(giveRecord.getId());
      updateRecord.setState(RedPackGiveRecord.STATE_OVERDUE);
      redPackGiveRecordMapper.updateByPrimaryKeySelective(updateRecord);
      // 口令失效
      tokenRecordService.invalidByRedPack(id);
      // 退回红包
      redPackBalanceService.addRedPack(giveRecord.getGiveUid(), giveRecord.getAmount(), RedPackDetailFactory.createGiveOthersFail(giveRecord));
      // 退回消息
      SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm");
      MsgRedPackGiveContentDTO givedto = new MsgRedPackGiveContentDTO();
      givedto.setTitle("你赠送的红包未被成功领取");
      givedto.setMoney("¥" + giveRecord.getAmount().setScale(2));
      givedto.setTime(sd.format(new Date()));
      givedto.setGiveTime(sd.format(giveRecord.getGiveTime()));
      userMoneyMsgNotificationService.redPackMsg(giveRecord.getGiveUid(), MsgTypeMoneyTypeEnum.redPackGiveBack, new Gson().toJson(givedto), "请到我的-红包查看");
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public String giving(Long uid, BigDecimal amount) throws RedPackGiveRecordException {
      if (uid == null || amount == null)
         throw new RedPackGiveRecordException(1, "参数不正确");
      String giveMin = redPackConfigService.getValueByKey("give_money_min");
      String giveMax = redPackConfigService.getValueByKey("give_money_max");
      if (amount.compareTo(new BigDecimal(giveMin)) < 0 || amount.compareTo(new BigDecimal(giveMax)) > 0)
         throw new RedPackGiveRecordException(1, "赠送金额至少" + giveMin + "元至多" + giveMax + "元");
      BigDecimal balance = null;
      try {
         balance = redPackBalanceService.getBalance(uid);
      } catch (RedPackBalanceException e1) {
         throw new RedPackGiveRecordException(1, e1.getMsg());
      }
      if (balance == null || amount.compareTo(balance) > 0)
         throw new RedPackGiveRecordException(1, "余额不足");
      Date nowDate = new Date();
      // 赠送记录
      RedPackGiveRecord giveRecord = new RedPackGiveRecord();
      giveRecord.setAmount(amount);
      giveRecord.setGiveUid(uid);
      giveRecord.setState(RedPackGiveRecord.STATE_INIT);
      giveRecord.setGiveTime(nowDate);
      giveRecord.setEndTime(DateUtil.plusDayDate(Constant.GIVE_DAYS, new Date()));
      redPackGiveRecordMapper.insertSelective(giveRecord);
      // 口令记录
      TokenRecord tokenRecord = new TokenRecord();
      tokenRecord.setUid(uid);
      tokenRecord.setIdentify(giveRecord.getId() + "");
      tokenRecord.setType(TokenTypeEnum.redPack);
      tokenRecord.setStartTime(nowDate);
      tokenRecord.setEndTime(DateUtil.plusDayDate(Constant.TOKEN_DAYS, new Date()));
      tokenRecord.setState(0);
      tokenRecordService.insertSelective(tokenRecord);
      // 创建口令
      String token = TokenUtil.createToken(tokenRecord.getId());
      tokenRecord.setToken(token);
      tokenRecordService.updateByPrimaryKeySelective(tokenRecord);
      String tips = redPackConfigService.getValueByKey("give_tips");
      String projectChineseName = Constant.systemCommonConfig.getProjectChineseName();
      while (tips.contains("{APP名称}")) {
         tips = tips.replace("{APP名称}", projectChineseName);
      }
      tips = tips.replace("{口令}", token).replace("{下载链接}", redPackConfigService.getValueByKey("app_down_link")).replace("{面额}",
            amount.setScale(2).toString());
      // 减少红包
      try {
         redPackBalanceService.subRedPack(uid, amount, RedPackDetailFactory.createGiveOthers(giveRecord));
      } catch (Exception e) {
         throw new RedPackGiveRecordException(1, "红包创建失败");
      }
      return tips;
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public RedPackGiveRecord receiveFriendsGive(Long uid, Long id) throws RedPackGiveRecordException{
      RedPackGiveRecord giveRecord = redPackGiveRecordMapper.selectByPrimaryKey(id);
      if (giveRecord == null || giveRecord.getState() != RedPackGiveRecord.STATE_INIT)
         throw new RedPackGiveRecordException(1, "赠送记录失效或已被领取");
      Date now = new Date();
      Date endTime = giveRecord.getEndTime();
      if (endTime != null && endTime.getTime() < now.getTime())
         throw new RedPackGiveRecordException(1, "红包已失效了");
      giveRecord.setReceiveUid(uid);
      giveRecord.setReceiveTime(now);
      giveRecord.setState(RedPackGiveRecord.STATE_RECEIVE);
      // 领取人增加红包
      try {
         redPackBalanceService.addRedPack(uid, giveRecord.getAmount(), RedPackDetailFactory.createGiveOthersReceive(giveRecord));
      } catch (Exception e) {
         throw new RedPackGiveRecordException(1, "红包领取失败");
      }
      // 更新赠送记录
      redPackGiveRecordMapper.updateByPrimaryKey(giveRecord);
      try {
         String identifyCode = StringUtil.Md5(RedPackDetailTypeEnum.giveOthers.name() + ":" + giveRecord.getId());
         RedPackDetail redPackDetail = redPackDetailService.getByIdentifyCode(identifyCode);
         RedPackDetail updateDetail = RedPackDetailFactory.createGiveOthersSucceed(redPackDetail.getId(), giveRecord);
         redPackDetailService.updateByPrimaryKeySelective(updateDetail);
      } catch (Exception e) {
         throw new RedPackGiveRecordException(1,"更新提现明细出错");
      }
      return giveRecord;
   }
}
package com.yeshi.fanli.service.impl.redpack;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.google.gson.Gson;
import com.yeshi.fanli.dao.mybatis.redpack.RedPackGiveRecordMapper;
import com.yeshi.fanli.dto.mq.user.UserTopicTagEnum;
import com.yeshi.fanli.dto.mq.user.body.UserRedPackGiftMQMsg;
import com.yeshi.fanli.dto.msg.MsgRedPackGiveContentDTO;
import com.yeshi.fanli.entity.bus.msg.MsgMoneyDetail.MsgTypeMoneyTypeEnum;
import com.yeshi.fanli.entity.bus.user.TokenRecord;
import com.yeshi.fanli.entity.bus.user.TokenRecord.TokenTypeEnum;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.redpack.RedPackDetail;
import com.yeshi.fanli.entity.redpack.RedPackDetail.RedPackDetailTypeEnum;
import com.yeshi.fanli.entity.redpack.RedPackGiveRecord;
import com.yeshi.fanli.entity.system.ConfigKeyEnum;
import com.yeshi.fanli.exception.redpack.RedPackGiveRecordException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.money.msg.UserMoneyMsgNotificationService;
import com.yeshi.fanli.service.inter.redpack.RedPackBalanceService;
import com.yeshi.fanli.service.inter.redpack.RedPackConfigService;
import com.yeshi.fanli.service.inter.redpack.RedPackDetailService;
import com.yeshi.fanli.service.inter.redpack.RedPackForbidService;
import com.yeshi.fanli.service.inter.redpack.RedPackGiveRecordService;
import com.yeshi.fanli.service.inter.user.TokenRecordService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.manger.msg.RocketMQManager;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TokenUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
import com.yeshi.fanli.util.factory.RedPackDetailFactory;
import com.yeshi.fanli.util.rocketmq.MQMsgBodyFactory;
import com.yeshi.fanli.util.rocketmq.MQTopicName;
import com.yeshi.fanli.vo.redpack.RedPackGiveVO;
@Service
public class RedPackGiveRecordServiceImpl implements RedPackGiveRecordService {
   @Resource
   private RedPackGiveRecordMapper redPackGiveRecordMapper;
   @Resource
   private RedPackConfigService redPackConfigService;
   @Resource
   private RedPackBalanceService redPackBalanceService;
   @Resource
   private TokenRecordService tokenRecordService;
   @Resource
   private RedPackDetailService redPackDetailService;
   @Resource
   private UserMoneyMsgNotificationService userMoneyMsgNotificationService;
   @Resource
   private RedPackForbidService redPackForbidService;
   @Resource
   private RocketMQManager rocketMQManager;
   @Resource
   private UserInfoService userInfoService;
   @Override
   public RedPackGiveRecord selectByPrimaryKey(Long id) {
      return redPackGiveRecordMapper.selectByPrimaryKey(id);
   }
   @Override
   public void updateByPrimaryKeySelective(RedPackGiveRecord record) {
      redPackGiveRecordMapper.updateByPrimaryKeySelective(record);
   }
   @Override
   @RequestSerializableByKeyService(key = "#id")
   @Transactional(rollbackFor = Exception.class)
   public void overdueByPrimaryKey(Long id) throws Exception {
      if (id == null)
         return;
      RedPackGiveRecord giveRecord = redPackGiveRecordMapper.selectByPrimaryKey(id);
      if (giveRecord == null)
         return;
      if (giveRecord.getState() != null && giveRecord.getState() != RedPackGiveRecord.STATE_INIT)
         return;
      // 赠送记录失效
      RedPackGiveRecord updateRecord = new RedPackGiveRecord();
      updateRecord.setId(giveRecord.getId());
      updateRecord.setState(RedPackGiveRecord.STATE_OVERDUE);
      redPackGiveRecordMapper.updateByPrimaryKeySelective(updateRecord);
      // 口令失效
      tokenRecordService.invalidByRedPack(id);
      // 退回红包
      redPackBalanceService.addRedPack(giveRecord.getGiveUid(), giveRecord.getAmount(),
            RedPackDetailFactory.createGiveOthersFail(giveRecord));
      // 退回消息
      SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm");
      MsgRedPackGiveContentDTO givedto = new MsgRedPackGiveContentDTO();
      givedto.setTitle("你赠送的红包未被成功领取");
      givedto.setMoney("¥" + giveRecord.getAmount().setScale(2));
      givedto.setTime(sd.format(new Date()));
      givedto.setGiveTime(sd.format(giveRecord.getGiveTime()));
      userMoneyMsgNotificationService.redPackMsg(giveRecord.getGiveUid(), MsgTypeMoneyTypeEnum.redPackGiveBack,
            new Gson().toJson(givedto), "请到我的-红包查看");
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public String giving(Long uid, BigDecimal amount) throws RedPackGiveRecordException {
      if (uid == null || amount == null)
         throw new RedPackGiveRecordException(1, "参数不正确");
      if(redPackForbidService.verifyForbid(uid))
         throw new RedPackGiveRecordException(1, "红包功能已被封禁");
      String giveMin = redPackConfigService.getValueByKey("give_money_min");
      String giveMax = redPackConfigService.getValueByKey("give_money_max");
      if (amount.compareTo(new BigDecimal(giveMin)) < 0 || amount.compareTo(new BigDecimal(giveMax)) > 0)
         throw new RedPackGiveRecordException(1, "赠送金额至少" + giveMin + "元至多" + giveMax + "元");
      BigDecimal balance = redPackBalanceService.getBalance(uid);
      if (balance == null || amount.compareTo(balance) > 0)
         throw new RedPackGiveRecordException(1, "余额不足");
      Date nowDate = new Date();
      Date endTime = DateUtil.plusDayDate(Constant.TOKEN_DAYS, new Date());
      // 赠送记录
      RedPackGiveRecord giveRecord = new RedPackGiveRecord();
      giveRecord.setAmount(amount);
      giveRecord.setGiveUid(uid);
      giveRecord.setState(RedPackGiveRecord.STATE_INIT);
      giveRecord.setGiveTime(nowDate);
      giveRecord.setEndTime(endTime);
      redPackGiveRecordMapper.insertSelective(giveRecord);
      // 口令记录
      TokenRecord tokenRecord = new TokenRecord();
      tokenRecord.setUid(uid);
      tokenRecord.setIdentify(giveRecord.getId() + "");
      tokenRecord.setType(TokenTypeEnum.redPack);
      tokenRecord.setStartTime(nowDate);
      tokenRecord.setEndTime(endTime);
      tokenRecord.setState(0);
      tokenRecordService.insertSelective(tokenRecord);
      // 创建口令
      String token = TokenUtil.createToken(tokenRecord.getId());
      tokenRecord.setToken(token);
      tokenRecordService.updateByPrimaryKeySelective(tokenRecord);
      String tips = redPackConfigService.getValueByKey("give_tips");
      String projectChineseName = Constant.systemCommonConfig.getProjectChineseName();
      while (tips.contains("{APP名称}")) {
         tips = tips.replace("{APP名称}", projectChineseName);
      }
      tips = tips.replace("{口令}", token).replace("{下载链接}", redPackConfigService.getValueByKey("app_down_link"))
            .replace("{面额}", amount.setScale(2).toString());
      // 减少红包
      try {
         redPackBalanceService.subRedPack(uid, amount, RedPackDetailFactory.createGiveOthers(giveRecord));
      } catch (Exception e) {
         LogHelper.errorDetailInfo(e);
         throw new RedPackGiveRecordException(1, "红包创建失败");
      }
      // 发送消息(非测试下)
      if (!Constant.IS_TEST) {
         UserRedPackGiftMQMsg msg = new UserRedPackGiftMQMsg();
         msg.setId(giveRecord.getId());
         msg.setUid(uid);
         Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.redPackGiftDrawback,   msg);
         try {
            rocketMQManager.sendNormalMsg(message,1000 * 60L, null);
         } catch (Exception e) {
            LogHelper.errorDetailInfo(e);
            throw new RedPackGiveRecordException(1, "红包创建失败");
         }
      }
      return tips;
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public RedPackGiveRecord receiveFriendsGive(Long uid, Long id) throws RedPackGiveRecordException {
      RedPackGiveRecord giveRecord = redPackGiveRecordMapper.selectByPrimaryKey(id);
      if (giveRecord == null || giveRecord.getState() != RedPackGiveRecord.STATE_INIT)
         throw new RedPackGiveRecordException(1, "赠送记录失效或已被领取");
      Date now = new Date();
      Date endTime = giveRecord.getEndTime();
      if (endTime != null && endTime.getTime() < now.getTime())
         throw new RedPackGiveRecordException(1, "红包已失效了");
      giveRecord.setReceiveUid(uid);
      giveRecord.setReceiveTime(now);
      giveRecord.setState(RedPackGiveRecord.STATE_RECEIVE);
      // 领取人增加红包
      try {
         redPackBalanceService.addRedPack(uid, giveRecord.getAmount(),
               RedPackDetailFactory.createGiveOthersReceive(giveRecord));
      } catch (Exception e) {
         throw new RedPackGiveRecordException(1, "红包领取失败");
      }
      // 更新赠送记录
      redPackGiveRecordMapper.updateByPrimaryKey(giveRecord);
      try {
         String identifyCode = StringUtil.Md5(RedPackDetailTypeEnum.giveOthers.name() + ":" + giveRecord.getId());
         RedPackDetail redPackDetail = redPackDetailService.getByIdentifyCode(identifyCode);
         RedPackDetail updateDetail = RedPackDetailFactory.createGiveOthersSucceed(redPackDetail.getId(),
               giveRecord);
         redPackDetailService.updateByPrimaryKeySelective(updateDetail);
      } catch (Exception e) {
         throw new RedPackGiveRecordException(1, "更新提现明细出错");
      }
      return giveRecord;
   }
   @Override
   public List<RedPackGiveVO> getGiveList(int page, int pageSzie, Long uid) {
      List<RedPackGiveVO> list = redPackGiveRecordMapper.getGiveList((page-1)*pageSzie, pageSzie, uid);
      if (list == null) {
         list = new ArrayList<RedPackGiveVO>();
      }
      if (list.isEmpty()) {
         return list;
      }
      String tips = redPackConfigService.getValueByKey("give_tips");
      String appLink = redPackConfigService.getValueByKey("app_down_link");
      String projectChineseName = Constant.systemCommonConfig.getProjectChineseName();
      for (RedPackGiveVO record: list) {
         Long receiveUid = record.getReceiveUid();
         if (receiveUid != null) {
            UserInfo userInfo = userInfoService.selectByPKey(receiveUid);
            record.setReceiveName(userInfo.getNickName());
            record.setReceivePortrait(userInfo.getPortrait());
            record.setReceiveTip("领取了你的红包");
         }
         TokenRecord token = tokenRecordService.getByTypeAndIdentify(TokenTypeEnum.redPack.name(),
               record.getId().toString());
         String desc = tips;
         while (desc.contains("{APP名称}")) {
            desc = desc.replace("{APP名称}", projectChineseName);
         }
         desc = desc.replace("{口令}", token.getToken()).replace("{下载链接}", appLink).replace("{面额}", record.getAmount().setScale(2).toString());
         record.setDesc(desc);
      }
      return list;
   }
   @Override
   public long countGiveList(Long uid) {
      return redPackGiveRecordMapper.countGiveList(uid);
   }
}