本人按照微信的红包实现的功能,首先红包分为个人红包和群红包,群红包又分为随机红包和定额红包,红包超时24小时未领取剩余的金额会退回到发红包的人的账户。发红包的过程分为以下几步:创建红包、获取红包信息、领红包、红包领取记录、红包发送记录信息等,根据公司需求稍微有所差异:
以下是countroller层,只列出最关键的几个接口:
@RestController
@RequestMapping(method = RequestMethod.POST)
@Slf4j
@Api(value = "红包接口", tags = { "红包操作接口" })
public class RedPacketController {
@Autowired
private LocaleMessageSourceService msService;
@Autowired
private MemberService memberService;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RedPacketService redPacketService;
@Autowired
private MemberWalletService memberWalletService;
@RequestMapping(value = "/createRedPacket")
public MessageResult createRedPacket(String name, String unit, BigDecimal quantity, BigDecimal amount,
Integer type,Integer redPacketType, Long drawNo, String jyPassword,
@ApiIgnore @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
//入参非空验证
ValidateUtil.hasText(name, 500, msService.getMessage("NAME_IS_NOT_EMPTY"));
ValidateUtil.hasText(unit, 500, msService.getMessage("UNIT_IS_NOT_EMPTY"));
ValidateUtil.notNull(quantity, 500, msService.getMessage("QUANTITY_IS_NOT_EMPTY"));
ValidateUtil.notNull(amount, 500, msService.getMessage("AMOUNT_IS_NOT_EMPTY"));
ValidateUtil.notNull(redPacketType, 500, msService.getMessage("REDPACKET_TYPE_IS_NOT_EMPTY"));
ValidateUtil.notNull(drawNo, 500, msService.getMessage("DRAW_NO_IS_NOT_EMPTY"));
ValidateUtil.hasText(jyPassword, 500, msService.getMessage("TRANSFER_PASSWORD_IS_NOT_EMPTY"));
//调用创建红包的方法
return redPacketService.createRedPacket(name, unit, quantity, amount,type, redPacketType, drawNo, jyPassword, user.getId());
}
public MessageResult getRedPacket(Long id, @ApiIgnore @SessionAttribute(SESSION_MEMBER) AuthMember user) throws BusinessValidationException {
// 1 检查参数
ValidateUtil.notNull(id, 500, msService.getMessage("REDPACKET_ID_IS_NOT_EMPTY"));
// 业务处理
RedPacket redPacket = redPacketService.findRedPacketById(id);
RedPacketInfo info = RedPacketInfo.toRedPacketInfo(redPacket);
Member member = memberService.findOne(user.getId());
info.setAvatar(member.getAvatar());
info.setJid(member.getJid());
info.setNickname(member.getNickname());
MessageResult result = MessageResult.success();
result.setData(info);
return result;
}
@Transactional(rollbackFor = Exception.class)
public MessageResult drawRedPacket(Long id, @ApiIgnore @SessionAttribute(SESSION_MEMBER) AuthMember user) throws BusinessValidationException {
// 1. 检查参数
ValidateUtil.notNull(id, 500, msService.getMessage("REDPACKET_ID_IS_NOT_EMPTY"));
// 业务实现:Redis方式:
//return redPacketService.drawRedPacketRedis(id, user.getId());
// 业务实现:数据库方式:
return redPacketService.drawRedPacketDB(id, user.getId());
}
这是service层:
package com.spark.bitrade.service;
import static com.spark.bitrade.util.BigDecimalUtils.compare;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import com.spark.bitrade.constant.TypeEnum;
import com.spark.bitrade.constant.RedPacketTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.spark.bitrade.constant.ReceivedStatusEnum;
import com.spark.bitrade.constant.RedPacketStatusEnum;
import com.spark.bitrade.dao.CoinDao;
import com.spark.bitrade.dao.RedPacketDao;
import com.spark.bitrade.dao.RedPacketOverviewDao;
import com.spark.bitrade.dao.RedPacketRecordDao;
import com.spark.bitrade.dao.RedPacketRecordOverviewDao;
import com.spark.bitrade.entity.Coin;
import com.spark.bitrade.entity.Member;
import com.spark.bitrade.entity.MemberWallet;
import com.spark.bitrade.entity.RedPacket;
import com.spark.bitrade.entity.RedPacketOverview;
import com.spark.bitrade.entity.RedPacketRecord;
import com.spark.bitrade.entity.RedPacketRecordOverview;
import com.spark.bitrade.exception.BusinessValidationException;
import com.spark.bitrade.exception.InformationExpiredException;
import com.spark.bitrade.job.CheckRedPacketTask;
import com.spark.bitrade.system.LocaleMessageSourceService;
import com.spark.bitrade.util.BigDecimalUtils;
import com.spark.bitrade.util.HttpRequestUtil;
import com.spark.bitrade.util.Md5;
import com.spark.bitrade.util.MessageResult;
import com.spark.bitrade.util.ValidateUtil;
import com.spark.bitrade.vo.RedPacketInfo;
import com.spark.bitrade.vo.RedPacketRecordInfo;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class RedPacketService {
@Value("${im.api.url}")
private String ImApiUrl;
@Autowired
private LocaleMessageSourceService msService;
@Autowired
private MemberService memberService;
@Autowired
private MemberWalletService memberWalletService;
@Autowired
private RedPacketDao redPacketDao;
@Autowired
private RedPacketOverviewDao redPacketOverviewDao;
@Autowired
private RedPacketRecordDao redPacketRecordDao;
@Autowired
private RedPacketRecordOverviewDao r