红包退款

This commit is contained in:
2025-02-08 15:01:51 +08:00
parent 583f9c7190
commit 624f694027
10 changed files with 178 additions and 306 deletions

View File

@@ -1,6 +1,7 @@
package com.accompany.business.constant.redenvelope;
public enum RedEnvelopStateEnum {
NOT_BEGIN(0, "未开始"),
ING(1, "开抢中"),
TIME_OUT(2, "过时"),
REMAIN_ZERO(3, "抢光了"),

View File

@@ -405,4 +405,12 @@ public class RedEnvelopeService extends ServiceImpl<RedEnvelopeMapper, RedEnvelo
.eq(RedEnvelope::getId, redEnvelopeId));
}
public List<RedEnvelope> selectExpireRecord(Integer kind, Integer state) {
return list(Wrappers.<RedEnvelope>lambdaQuery()
.eq(RedEnvelope::getKind, kind)
.eq(RedEnvelope::getState, state)
.lt(RedEnvelope::getEndTime, new Date())
.orderByAsc(RedEnvelope::getCreateTime));
}
}

View File

@@ -8,8 +8,11 @@ import com.accompany.business.model.Gift;
import com.accompany.business.model.redenvelope.RedEnvelope;
import com.accompany.business.model.redenvelope.RedEnvelopeGiftItem;
import com.accompany.business.model.redenvelope.RedEnvelopeItem;
import com.accompany.business.service.BaseSendService;
import com.accompany.business.service.gift.GiftService;
import com.accompany.business.service.give.GiveUserService;
import com.accompany.business.service.purse.UserPurseService;
import com.accompany.business.service.record.BillRecordService;
import com.accompany.business.service.redenvelope.strategv2.IRedEnvelopeV2Strategy;
import com.accompany.business.service.redenvelope.strategv2.RedEnvelopeV2Context;
import com.accompany.business.service.redenvelope.strategv2.RedEnvelopeV2Factory;
@@ -19,10 +22,13 @@ import com.accompany.business.vo.redenvelope.*;
import com.accompany.common.constant.Constant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.enumeration.BillObjTypeEnum;
import com.accompany.core.enumeration.I18nAlertEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Users;
import com.accompany.core.service.SysConfService;
import com.accompany.core.util.DoubleUtil;
import com.accompany.core.util.I18NMessageSourceUtil;
import com.accompany.core.util.JsonUtil;
import com.accompany.core.vo.UserVo;
import com.accompany.payment.service.RechargeUserService;
@@ -75,9 +81,14 @@ public class RedEnvelopeV2Service {
private RedissonClient redissonClient;
@Autowired
private RedEnvelopeGiftItemService redEnvelopGiftItemService;
@Autowired
private GiftService giftService;
@Autowired
private BillRecordService billRecordService;
@Autowired
private UserPurseService userPurseService;
@Autowired
private BaseSendService baseSendService;
private RateLimiter rateLimiter = RateLimiter.create(10.0);
@@ -282,12 +293,8 @@ public class RedEnvelopeV2Service {
List<Long> openedId = redEnvelopeItems.stream().map(RedEnvelopeItem::getRedEnvelopeId).collect(Collectors.toList());
redEnvelopes = redEnvelopes.stream().filter(x -> {
boolean b = !openedId.contains(x.getId());
boolean cache =false;
if (RedEnvelopTypeEnum.DIAMOND.getCode() == x.getType().getCode()) {
cache = getGoldList(x.getId()).size()>0;
} else if (RedEnvelopTypeEnum.GIFT.getCode() == x.getType().getCode()) {
cache = getGiftList(x.getId()).size()>0;
}
boolean cache = Objects.requireNonNull(redEnvelopeV2Factory.getStrategy(x.getKind(), x.getType().getCode(), x.getPosition().getCode()))
.getItemCache(x.getId()).size()>0;
return b && cache;
}).collect(Collectors.toList());
}
@@ -306,285 +313,67 @@ public class RedEnvelopeV2Service {
return BusiResult.success(roomRedEnvelopeInfo);
}
//
// public RedEnvelopStateEnum stateByIdAndUserId(Long redEnvelopeId, Long uid) {
// RedEnvelopeItem redEnvelopeItem = redEnvelopeItemService.getByRedEnvelopeIdAndUserId(redEnvelopeId, uid);
// if (redEnvelopeItem != null) {
// return RedEnvelopStateEnum.SUCCESS;
// }
// return stateById(redEnvelopeId);
// }
//
// public RedEnvelopStateEnum stateById(Long redEnvelopeId) {
// RedEnvelope redEnvelope = getById(redEnvelopeId);
// if (redEnvelopeBackService.isBack(redEnvelopeId)) {
// return RedEnvelopStateEnum.TIME_OUT_BACK;
// }
// if (redEnvelopeItemService.countByRedEnvelopeId(redEnvelopeId) >= redEnvelope.getNum()) {
// return RedEnvelopStateEnum.REMAIN_ZERO;
// }
// Date now = new Date();
// if (redEnvelope.getEndTime().getTime() < now.getTime()) {
// return RedEnvelopStateEnum.TIME_OUT;
// }
// if (now.getTime() > redEnvelope.getBeginTime().getTime() && now.getTime() < redEnvelope.getEndTime().getTime()) {
// return RedEnvelopStateEnum.ING;
// }
// if (redEnvelope.getBeginTime().getTime() > now.getTime()) {
// return RedEnvelopStateEnum.WILL;
// }
// return RedEnvelopStateEnum.TIME_OUT;
// }
//
// public Long createRedEnvelop(RedEnvelopeDTO redEnvelopeDTO) {
// RedEnvelope redEnvelope = new RedEnvelope();
// redEnvelope.setUserId(redEnvelopeDTO.getUserId());
// redEnvelope.setRoomUid(redEnvelopeDTO.getRoomUId());
// redEnvelope.setMessage(redEnvelopeDTO.getMessage());
// redEnvelope.setOriginalAmount(redEnvelopeDTO.getOriginalAmount());
// redEnvelope.setCommissionAmount(redEnvelopeDTO.getCommissionAmount());
// redEnvelope.setNum(redEnvelopeDTO.getTotalNum());
// redEnvelope.setType(redEnvelopeDTO.getType());
// redEnvelope.setPosition(redEnvelopeDTO.getPosition());
// redEnvelope.setBeginTime(redEnvelopeDTO.getBeginTime());
// redEnvelope.setEndTime(redEnvelopeDTO.getEndTime());
// redEnvelope.setKind(redEnvelopeDTO.getKind());
// redEnvelope.setValidityType(redEnvelopeDTO.getValidityType());
// save(redEnvelope);
// redEnvelopeDTO.setId(redEnvelope.getId());
// return redEnvelope.getId();
// }
//
// public long unPickNum(Long redEnvelopeId) {
// RedEnvelope redEnvelope = getById(redEnvelopeId);
// return redEnvelope.getNum() - redEnvelopeItemService.countByRedEnvelopeId(redEnvelopeId);
// }
//
// public Double unOpenAmount(Long redEnvelopeId) {
// RedEnvelope redEnvelope = getById(redEnvelopeId);
// List<RedEnvelopeItem> items = redEnvelopeItemService.listByRedEnvelopId(redEnvelopeId);
// double openAmount = 0.0;
// if (CollectionUtil.isNotEmpty(items)) {
// openAmount = items.stream().mapToDouble(RedEnvelopeItem::getAmount).sum();
// }
// return DoubleUtil.sub(DoubleUtil.sub(redEnvelope.getOriginalAmount(),
// redEnvelope.getCommissionAmount()), openAmount);
// }
//
// public RedEnvelopeConfigDto getConfig() {
// RedEnvelopeConfigDto config = new RedEnvelopeConfigDto();
// RedEnvelopeConfig redEnvelopeConfig = redEnvelopeConfig();
// config.setOpen(redEnvelopeConfig.isOpen());
// config.setRoomRedEnvelopeMinAmount(redEnvelopeConfig.getRoom().getRedEnvelopeMinAmount());
// config.setRoomRedEnvelopeMaxAmount(redEnvelopeConfig.getRoom().getRedEnvelopeMaxAmount());
// config.setRoomRedEnvelopeMinNum(redEnvelopeConfig.getRoom().getRedEnvelopeMinNum());
// config.setRoomRedEnvelopeMaxNum(redEnvelopeConfig.getRoom().getRedEnvelopeMaxNum());
// config.setServerRedEnvelopeMinAmount(redEnvelopeConfig.getServer().getRedEnvelopeMinAmount());
// config.setServerRedEnvelopeMaxAmount(redEnvelopeConfig.getServer().getRedEnvelopeMaxAmount());
// config.setServerRedEnvelopeMinNum(redEnvelopeConfig.getServer().getRedEnvelopeMinNum());
// config.setServerRedEnvelopeMaxNum(redEnvelopeConfig.getServer().getRedEnvelopeMaxNum());
// config.setExchangeDiamondsRate(redEnvelopeConfig.getExchangeDiamondsRate());
// config.setRedEnvelopedPosition(redEnvelopeConfig.getRedEnvelopedPosition());
// config.setBeginSecond(redEnvelopeConfig.getBeginSecond());
// config.setEndSecond(redEnvelopeConfig.getEndSecond());
// return config;
// }
//
// public void saveOpenRecord(Long redEnvelopeId, Long uid, Double amount) {
// RedEnvelopeItem item = new RedEnvelopeItem();
// item.setRedEnvelopeId(redEnvelopeId);
// item.setUserId(uid);
// item.setAmount(amount);
// redEnvelopeItemService.save(item);
// }
//
// /**
// * 我发送的红包
// */
// public List<RedEnvelopeVo> sendByUserId(Long userId, Integer pageNum, Integer pageSize, Date createTime) {
// String limit = String.format("%d,%d", (pageNum - 1) * pageSize, pageSize);
// List<RedEnvelopeVo> result = redEnvelopeMapper.sendByUserId(userId, createTime, limit);
// List<Long> roomUids = result.stream().map(RedEnvelopeVo::getRoomUid).collect(Collectors.toList());
// List<Room> rooms = roomService.getRoomListByUids(roomUids.stream().distinct().collect(Collectors.toList()));
// Map<Long, String> roomTitles = new HashMap<>();
// rooms.forEach(room -> roomTitles.put(room.getUid(), room.getTitle()));
// result.forEach(item -> {
// item.setRoomTitle(roomTitles.getOrDefault(item.getRoomUid(), ""));
// });
// return result;
// }
//
// public List<Long> listTimeOutAndNotBackRedEnvelope() {
// return redEnvelopeMapper.listTimeOutAndNotBackRedEnvelope();
// }
//
// public List<RedEnvelope> getValidRedEnvelopes(Long roomUid) {
// return list(Wrappers.<RedEnvelope>lambdaQuery()
// .eq(RedEnvelope::getPosition, RedEnvelopPositionEnum.IN_ROOM.name())
// .notIn(RedEnvelope::getState, RedEnvelopStateEnum.REMAIN_ZERO.getCode(), RedEnvelopStateEnum.TIME_OUT_BACK.getCode())
// .eq(RedEnvelope::getRoomUid, roomUid)
// .gt(RedEnvelope::getEndTime, new Date())
// .orderByAsc(RedEnvelope::getCreateTime));
// }
//
// public List<RedEnvelopeResponseVo> getValidRedEnvelopeList(Long roomUid, Long uid, Long redEnvelopeId, Boolean isShowKind) {
// // 房间没有过期的红包
// List<RedEnvelope> redEnvelopeList = list(Wrappers.<RedEnvelope>lambdaQuery()
// .eq(redEnvelopeId != null, RedEnvelope::getId, redEnvelopeId)
// .eq(Boolean.FALSE.equals(isShowKind), RedEnvelope::getKind, RedEnvelopeKindEnum.NONE.ordinal())
// .eq(Boolean.TRUE.equals(isShowKind), RedEnvelope::getPosition, RedEnvelopPositionEnum.IN_ROOM.name())
// .notIn(RedEnvelope::getState, RedEnvelopStateEnum.REMAIN_ZERO.getCode(), RedEnvelopStateEnum.TIME_OUT_BACK.getCode())
// .eq(RedEnvelope::getRoomUid, roomUid)
// .gt(RedEnvelope::getEndTime, new Date())
// .orderByAsc(RedEnvelope::getCreateTime));
// if (CollectionUtil.isEmpty(redEnvelopeList)) {
// return new ArrayList<>();
// }
// List<Long> redEnvelopeIds = redEnvelopeList.stream().map(RedEnvelope::getId).collect(Collectors.toList());
// // 去掉领完的和用户领过的红包
// HashMap<Long, Integer> redEnvelopePickNum =
// redEnvelopeItemService.getDiamondRedEnvelopePickNum(redEnvelopeIds, null);
// HashMap<Long, Integer> redEnvelopeUserPickNum =
// redEnvelopeItemService.getDiamondRedEnvelopePickNum(redEnvelopeIds, uid);
// List<RedEnvelopeResponseVo> data = new ArrayList<>();
// redEnvelopeList.forEach(v -> {
// Integer pickNum = redEnvelopePickNum.getOrDefault(v.getId(), 0);
// Integer userPickNum = redEnvelopeUserPickNum.getOrDefault(v.getId(), 0);
// //新版本抢过的也要展示
// if (isShowKind || (pickNum < v.getNum() && userPickNum < 1)) {
// RedEnvelopeResponseVo response = new RedEnvelopeResponseVo();
// response.setId(v.getId());
// response.setUserId(v.getUserId());
// UserVo userVoByUid = usersService.getUserVoByUid(v.getUserId());
// userVoByUid.setPrivatePhoto(null);
// response.setUserVO(userVoByUid);
// response.setRoomUId(v.getRoomUid());
// response.setMessage(v.getMessage());
// response.setRedEnvelopeAmount(DoubleUtil.sub(v.getOriginalAmount(), v.getCommissionAmount()));
// response.setTotalNum(v.getNum());
// response.setPickNum(redEnvelopePickNum.getOrDefault(v.getId(), 0));
// response.setType(OuterRedEnvelopeTypeEnum.get(v.getType(), v.getPosition()).getCode());
// response.setBeginTime(v.getBeginTime());
// response.setEndTime(v.getEndTime());
// response.setCreateTime(v.getCreateTime());
// response.setUpdateTime(v.getUpdateTime());
// response.setKind(v.getKind());
// response.setValidityType(v.getValidityType());
// //倒计时
// Date now = new Date();
// Date beginTime = v.getBeginTime();
// if (beginTime.after(now)) {
// response.setDuration((beginTime.getTime() - now.getTime()) / 1000);
// }
// Integer kind = v.getKind();
// //是否完成条件
// if (kind != RedEnvelopeKindEnum.NONE.ordinal()) {
// InRoomRedEnvelopeStrategy redEnvelopeStrategy = (InRoomRedEnvelopeStrategy) RedEnvelopeFactory.getInstance(kind);
// RedEnvelopeContext context = new RedEnvelopeContext();
// context.setRoomUid(v.getRoomUid());
// context.setUid(uid);
// context.setRedEnvelopeId(v.getId());
// assert redEnvelopeStrategy != null;
// response.setFinish(redEnvelopeStrategy.isFinish(context));
// }
// //红包状态
// response.setState(stateById(v.getId()).getCode());
// data.add(response);
// }
// });
// return data;
// }
//
// public RedEnvelopeVo getRedEnvelope(long redEnvelopeId) {
// RedEnvelopeVo vo = new RedEnvelopeVo();
// RedEnvelope redEnvelope = getById(redEnvelopeId);
// if (redEnvelope == null) {
// return vo;
// }
// BeanUtils.copyProperties(redEnvelope, vo);
// Integer kind = redEnvelope.getKind();
// //是否完成条件
// if (kind != RedEnvelopeKindEnum.NONE.ordinal()) {
// InRoomRedEnvelopeStrategy redEnvelopeStrategy = (InRoomRedEnvelopeStrategy) RedEnvelopeFactory.getInstance(kind);
// RedEnvelopeContext context = new RedEnvelopeContext();
// context.setRoomUid(redEnvelope.getRoomUid());
// context.setUid(UidContextHolder.get());
// context.setRedEnvelopeId(redEnvelopeId);
// assert redEnvelopeStrategy != null;
// vo.setFinish(redEnvelopeStrategy.isFinish(context));
// }
// //倒计时
// Date now = new Date();
// Date beginTime = redEnvelope.getBeginTime();
// if (beginTime.after(now)) {
// vo.setDuration((beginTime.getTime() - now.getTime()) / 1000);
// }
// //红包用户
// Users redEnvelopeUser = usersService.getUsersByUid(redEnvelope.getUserId());
// if (redEnvelopeUser != null) {
// vo.setNick(redEnvelopeUser.getNick());
// vo.setAvatar(redEnvelopeUser.getAvatar());
// }
// //红包状态
// Integer state = vo.getState();
// if (state == RedEnvelopStateEnum.ING.getCode()) {
// state = stateByIdAndUserId(redEnvelopeId, UidContextHolder.get()).getCode();
// }
// vo.setState(state);
// return vo;
// }
//
// @Transactional(rollbackFor = Exception.class)
// public void back(Long redEnvelopeId) {
// RedEnvelopeContext context = new RedEnvelopeContext();
// context.setRedEnvelopeId(redEnvelopeId);
// RedEnvelope redEnvelope = getById(redEnvelopeId);
// if (redEnvelope == null) {
// log.info("redEnvelopeId : {} 不存在", redEnvelopeId);
// return;
// }
// Integer state = redEnvelope.getState();
// if (RedEnvelopStateEnum.REMAIN_ZERO.getCode() == state) {
// log.info("redEnvelopeId : {} 红包已抢光", redEnvelopeId);
// return;
// }
// if (RedEnvelopStateEnum.TIME_OUT_BACK.getCode() == state) {
// log.info("redEnvelopeId : {} 红包已退完", redEnvelopeId);
// return;
// }
// Objects.requireNonNull(RedEnvelopeFactory.getInstance(redEnvelope.getKind())).back(context);
// }
//
// /**
// * 更新退还手续费
// *
// * @param redEnvelopeId
// * @param backCommissionAmount
// */
// public void updateBackCommissionAmount(Long redEnvelopeId, Double backCommissionAmount) {
// if (redEnvelopeId == null || redEnvelopeId == 0 || backCommissionAmount == 0) {
// return;
// }
// update(Wrappers.<RedEnvelope>lambdaUpdate()
// .set(RedEnvelope::getBackCommissionAmount, backCommissionAmount)
// .eq(RedEnvelope::getId, redEnvelopeId));
// }
public RDeque<Integer> getGoldList(Long redEnvelopeId) {
return redissonClient.getDeque(red_envelop_list.getKey(redEnvelopeId), IntegerCodec.INSTANCE);
}
public RSet<Long> getOpenUserSet(Long redEnvelopeId) {
return redissonClient.getSet(red_envelop_open_user_set.getKey(redEnvelopeId), LongCodec.INSTANCE);
}
public RDeque<Integer> getGiftList(Long redEnvelopeId) {
return redissonClient.getDeque(red_envelop_gift_list.getKey(redEnvelopeId), IntegerCodec.INSTANCE);
}
public RedEnvelopeV2Config redEnvelopeConfig() {
return JsonUtil.parseToClass(sysConfService.getSysConfValueById(Constant.SysConfId.NEW_RED_ENVELOPE_CONFIG), RedEnvelopeV2Config.class);
}
public void redEnvelopeExpireTask() {
log.info("redEnvelopeExpireTask-begin");
List<RedEnvelope> redEnvelopes = redEnvelopeService.selectExpireRecord(RedEnvelopeKindEnum.NEWER.ordinal(), RedEnvelopStateEnum.NOT_BEGIN.getCode());
if (CollectionUtils.isEmpty(redEnvelopes)) {
log.info("redEnvelopeExpireTask-empty-list");
return;
}
for (RedEnvelope redEnvelope : redEnvelopes) {
try {
Long redEnvelopeId = redEnvelope.getId();
List<RedEnvelopeItem> redEnvelopeItems = redEnvelopeItemService.listByRedEnvelopId(redEnvelopeId);
IRedEnvelopeV2Strategy strategy = Objects.requireNonNull(redEnvelopeV2Factory.getStrategy(redEnvelope.getKind(), redEnvelope.getType().getCode(), redEnvelope.getPosition().getCode()));
RDeque<Integer> itemCache = strategy.getItemCache(redEnvelopeId);
log.info("redEnvelopeExpireTask-redEnvelope:{}, itemSize:{},itemCacheSize:{}", JSONObject.toJSONString(redEnvelope), redEnvelopeItems.size(), itemCache.size());
if ((CollectionUtils.isNotEmpty(redEnvelopeItems) && redEnvelopeItems.size() == redEnvelope.getNum())
|| itemCache.size() == 0) {
redEnvelope.setState(RedEnvelopStateEnum.REMAIN_ZERO.getCode());
redEnvelope.setUpdateTime(new Date());
redEnvelopeService.updateById(redEnvelope);
continue;
}
redEnvelope.setState(RedEnvelopStateEnum.TIME_OUT_BACK.getCode());
redEnvelope.setUpdateTime(new Date());
redEnvelopeService.updateById(redEnvelope);
if ((redEnvelopeItems.size() + itemCache.size()) != redEnvelope.getNum().intValue()) {
log.info("redEnvelopeExpireTask-数量对不上,不作退款操作,等追回-redEnvelope:{}", JSONObject.toJSONString(redEnvelope));
//如果数量对不上,不作退款操作,等追回
continue;
}
itemCache.delete();
strategy.getOpenUserSet(redEnvelopeId).delete();
Long originalAmount = redEnvelope.getOriginalAmount().longValue();
Long receiveGold = 0L;
if (CollectionUtils.isNotEmpty(redEnvelopeItems)) {
for (RedEnvelopeItem redEnvelopeItem : redEnvelopeItems) {
receiveGold += receiveGold + redEnvelopeItem.getAmount().longValue();
}
}
Long backGold = originalAmount - receiveGold;
if (backGold <= 0) {
log.info("redEnvelopeExpireTask-退款金额为0无退款操作-redEnvelope:{}", JSONObject.toJSONString(redEnvelope));
continue;
}
redEnvelopeBackService.backRecord(redEnvelopeId, backGold);
Long uid = redEnvelope.getUserId();
userPurseService.addDiamond(uid, backGold.doubleValue(), BillObjTypeEnum.REDENVELOPE_BACK,
(userPurse -> billRecordService.insertGeneralBillRecord(uid, null, redEnvelope.getRoomUid(), redEnvelopeId.toString(), BillObjTypeEnum.REDENVELOPE_BACK, backGold.doubleValue(), userPurse)));
if (redEnvelope.getType().getCode() == RedEnvelopTypeEnum.DIAMOND.getCode()) {
baseSendService.sendSystemMsg(uid.toString(), I18NMessageSourceUtil.getMessage(I18nAlertEnum.RED_ENVELOPE_GOLD_BACK, new Object[]{}, uid));
} else {
baseSendService.sendSystemMsg(uid.toString(), I18NMessageSourceUtil.getMessage(I18nAlertEnum.RED_ENVELOPE_GIFT_BACK, new Object[]{}, uid));
}
} catch (Exception e) {
log.error("redEnvelopeExpireTask-退款金额为0无退款操作-redEnvelope:{},e:{}", JSONObject.toJSONString(redEnvelope), e.getMessage(), e);
}
}
log.info("redEnvelopeExpireTask-end");
}
}

View File

@@ -1,5 +1,6 @@
package com.accompany.business.service.redenvelope.strategv2;
import com.accompany.business.constant.redenvelope.RedEnvelopeRedisKey;
import com.accompany.business.dto.redenvelope.RedEnvelopeV2NotifyDTO;
import com.accompany.business.model.UserPurse;
import com.accompany.business.model.redenvelope.RedEnvelope;
@@ -19,6 +20,10 @@ import com.accompany.core.model.Room;
import com.accompany.core.model.Users;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RDeque;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.LongCodec;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
@@ -26,6 +31,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Random;
import static com.accompany.business.constant.redenvelope.RedEnvelopeRedisKey.red_envelop_open_user_set;
@Slf4j
public abstract class AbstractRedEnvelopeV2Strategy implements IRedEnvelopeV2Strategy {
@@ -53,6 +60,9 @@ public abstract class AbstractRedEnvelopeV2Strategy implements IRedEnvelopeV2Str
@Autowired
protected RoomService roomService;
@Autowired
protected RedissonClient redissonClient;
@Override
@@ -88,6 +98,11 @@ public abstract class AbstractRedEnvelopeV2Strategy implements IRedEnvelopeV2Str
this.sendChatRoom(context);
}
@Override
public RSet<Long> getOpenUserSet(Long redEnvelopeId) {
return redissonClient.getSet(red_envelop_open_user_set.getKey(redEnvelopeId), LongCodec.INSTANCE);
}
protected void sendChatRoom(RedEnvelopeV2Context context) {
Users user = usersService.getUsersByUid(context.getUid());
Long roomUid = context.getRoomUid();
@@ -149,4 +164,5 @@ public abstract class AbstractRedEnvelopeV2Strategy implements IRedEnvelopeV2Str
return result;
}
}

View File

@@ -2,8 +2,15 @@ package com.accompany.business.service.redenvelope.strategv2;
import com.accompany.business.constant.redenvelope.RedEnvelopPositionEnum;
import com.accompany.business.constant.redenvelope.RedEnvelopTypeEnum;
import com.accompany.business.constant.redenvelope.RedEnvelopeRedisKey;
import com.accompany.business.enums.redenvelope.RedEnvelopeKindEnum;
import com.accompany.business.model.redenvelope.RedEnvelope;
import com.accompany.business.model.redenvelope.RedEnvelopeItem;
import com.accompany.business.vo.redenvelope.OpenRedEnvelopeResponse;
import org.redisson.api.RDeque;
import org.redisson.api.RSet;
import java.util.List;
public interface IRedEnvelopeV2Strategy {
@@ -27,7 +34,8 @@ public interface IRedEnvelopeV2Strategy {
Integer doOpen(RedEnvelopeV2Context context);
void doBack(RedEnvelopeV2Context context);
RDeque<Integer> getItemCache(Long redEnvelopeId);
RSet<Long> getOpenUserSet(Long redEnvelopeId);
RedEnvelopeKindEnum kind();

View File

@@ -8,6 +8,7 @@ import com.accompany.business.enums.redenvelope.RedEnvelopeKindEnum;
import com.accompany.business.model.Gift;
import com.accompany.business.model.redenvelope.RedEnvelope;
import com.accompany.business.model.redenvelope.RedEnvelopeGift;
import com.accompany.business.model.redenvelope.RedEnvelopeItem;
import com.accompany.business.service.gift.GiftService;
import com.accompany.business.service.redenvelope.RedEnvelopeGiftItemService;
import com.accompany.business.service.redenvelope.RedEnvelopeGiftService;
@@ -16,10 +17,15 @@ import com.accompany.business.vo.GiftVo;
import com.accompany.business.vo.redenvelope.OpenRedEnvelopeResponse;
import com.accompany.business.vo.redenvelope.SendRedEnvelopeV2Request;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.enumeration.I18nAlertEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Users;
import com.accompany.core.util.I18NMessageSourceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RDeque;
import org.redisson.api.RSet;
import org.redisson.client.codec.IntegerCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@@ -30,6 +36,9 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import static com.accompany.business.constant.redenvelope.RedEnvelopeRedisKey.red_envelop_gift_list;
import static com.accompany.business.constant.redenvelope.RedEnvelopeRedisKey.red_envelop_list;
@Slf4j
@Component
@Qualifier("serverGiftRedEnvelopeV2Strategy")
@@ -97,18 +106,18 @@ public class ServerGiftRedEnvelopeV2Strategy extends AbstractRedEnvelopeV2Strate
}
redEnvelopeGiftService.saveBatch(giftDbAdds);
Collections.shuffle(cacheGiftIds);
redEnvelopeV2Service.getGiftList(redEnvelopeId).addAll(cacheGiftIds);
this.getItemCache(redEnvelopeId).addAll(cacheGiftIds);
}
@Override
public Integer doOpen(RedEnvelopeV2Context context) {
Long redEnvelopeId = context.getRedEnvelopeId();
Long uid = context.getUid();
RSet<Long> giftUserSet = redEnvelopeV2Service.getOpenUserSet(redEnvelopeId);
RSet<Long> giftUserSet = this.getOpenUserSet(redEnvelopeId);
if (giftUserSet.contains(uid)) {
return RedEnvelopStateEnum.EXIST.getCode();
}
Integer giftId = redEnvelopeV2Service.getGiftList(redEnvelopeId).poll();
Integer giftId = this.getItemCache(redEnvelopeId).poll();
if (giftId == null) {
return RedEnvelopStateEnum.REMAIN_ZERO.getCode();
}
@@ -127,16 +136,22 @@ public class ServerGiftRedEnvelopeV2Strategy extends AbstractRedEnvelopeV2Strate
redEnvelopeGiftItemDTO.setGiftId(giftId);
redEnvelopeGiftItemDTO.setGiftNum(1);
redEnvelopeGiftItemService.record(redEnvelopeGiftItemDTO);
Gift giftById = giftService.getGiftById(giftId);
userBackpackService.sendGiftToUser(uid, giftId, 1, giftById.getGiftType());
Gift gift = giftService.getGiftById(giftId);
userBackpackService.sendGiftToUser(uid, giftId, 1, gift.getGiftType());
Users users = usersService.getUsersByUid(context.getRedEnvelope().getUserId());
Users recvUser = usersService.getUsersByUid(uid);
String message = I18NMessageSourceUtil.getMessage(String.join(".", "Gift", gift.getGiftName()),
gift.getGiftName(), recvUser.getPartitionId());
baseSendService.sendSystemMsg(uid.toString(), I18NMessageSourceUtil.getMessage(I18nAlertEnum.RED_ENVELOPE_GIFT_RECEV, new Object[]{users.getErbanNo(), message}, uid));
return RedEnvelopStateEnum.SUCCESS.getCode();
}
@Override
public void doBack(RedEnvelopeV2Context context) {
public RDeque<Integer> getItemCache(Long redEnvelopeId) {
return redissonClient.getDeque(red_envelop_gift_list.getKey(redEnvelopeId), IntegerCodec.INSTANCE);
}
@Override
public RedEnvelopeKindEnum kind() {
return RedEnvelopeKindEnum.NEWER;

View File

@@ -3,29 +3,27 @@ package com.accompany.business.service.redenvelope.strategv2;
import com.accompany.business.constant.redenvelope.RedEnvelopPositionEnum;
import com.accompany.business.constant.redenvelope.RedEnvelopStateEnum;
import com.accompany.business.constant.redenvelope.RedEnvelopTypeEnum;
import com.accompany.business.dto.redenvelope.*;
import com.accompany.business.enums.redenvelope.RedEnvelopeKindEnum;
import com.accompany.business.model.Gift;
import com.accompany.business.model.redenvelope.RedEnvelope;
import com.accompany.business.model.redenvelope.RedEnvelopeGift;
import com.accompany.business.vo.redenvelope.OpenRedEnvelopeResponse;
import com.accompany.common.constant.Constant;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.enumeration.BillObjTypeEnum;
import com.accompany.core.enumeration.I18nAlertEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Room;
import com.accompany.core.model.Users;
import com.accompany.core.util.I18NMessageSourceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RDeque;
import org.redisson.api.RList;
import org.redisson.api.RSet;
import org.redisson.client.codec.IntegerCodec;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static com.accompany.business.constant.redenvelope.RedEnvelopeRedisKey.red_envelop_list;
@Component
@Slf4j
@Qualifier("serverGoldRedEnvelopeV2Strategy")
@@ -43,7 +41,7 @@ public class ServerGoldRedEnvelopeV2Strategy extends AbstractRedEnvelopeV2Strate
if (CollectionUtils.isEmpty(redPackets)) {
throw new ServiceException(BusiStatus.SERVERERROR);
}
RDeque<Integer> goldList = redEnvelopeV2Service.getGoldList(context.getRedEnvelopeId());
RDeque<Integer> goldList = this.getItemCache(context.getRedEnvelopeId());
boolean added = goldList.addAll(redPackets);
if (!added) {
throw new ServiceException(BusiStatus.SERVERERROR);
@@ -56,11 +54,11 @@ public class ServerGoldRedEnvelopeV2Strategy extends AbstractRedEnvelopeV2Strate
Long redEnvelopeId = context.getRedEnvelopeId();
RedEnvelope redEnvelope = redEnvelopeService.getById(redEnvelopeId);
Long uid = context.getUid();
RSet<Long> giftUserSet = redEnvelopeV2Service.getOpenUserSet(redEnvelopeId);
RSet<Long> giftUserSet = this.getOpenUserSet(redEnvelopeId);
if (giftUserSet.contains(uid)) {
return RedEnvelopStateEnum.EXIST.getCode();
}
Integer openAmount = redEnvelopeV2Service.getGoldList(redEnvelopeId).poll();
Integer openAmount = this.getItemCache(redEnvelopeId).poll();
if (openAmount == null) {
return RedEnvelopStateEnum.REMAIN_ZERO.getCode();
}
@@ -69,12 +67,14 @@ public class ServerGoldRedEnvelopeV2Strategy extends AbstractRedEnvelopeV2Strate
redEnvelopeService.saveOpenRecord(redEnvelopeId, uid, openAmount.doubleValue());
userPurseService.addDiamond(uid, openAmount.doubleValue(), BillObjTypeEnum.REDENVELOPE_SERVER_GET,
(userPurse -> billRecordService.insertGeneralBillRecord(uid, null, redEnvelope.getRoomUid(), redEnvelopeId.toString(), BillObjTypeEnum.REDENVELOPE_SERVER_GET, openAmount.doubleValue(), userPurse)));
Users users = usersService.getUsersByUid(context.getRedEnvelope().getUserId());
baseSendService.sendSystemMsg(uid.toString(), I18NMessageSourceUtil.getMessage(I18nAlertEnum.RED_ENVELOPE_GOLD_RECEV, new Object[]{users.getErbanNo(), openAmount}, uid));
return RedEnvelopStateEnum.SUCCESS.getCode();
}
@Override
public void doBack(RedEnvelopeV2Context context) {
public RDeque<Integer> getItemCache(Long redEnvelopeId) {
return redissonClient.getDeque(red_envelop_list.getKey(redEnvelopeId), IntegerCodec.INSTANCE);
}
@Override

View File

@@ -28,7 +28,7 @@
SELECT red_envelope.id
FROM red_envelope
WHERE num &gt; (SELECT count(*) FROM red_envelope_item WHERE red_envelope_id = red_envelope.id)
AND end_time &lt; now()
AND end_time &lt; now() and kind != 5
AND NOT EXISTS(SELECT id FROM red_envelope_back WHERE red_envelope_back.red_envelope_id = red_envelope.id)
order by red_envelope.id
</select>

View File

@@ -14,6 +14,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.List;
@@ -57,4 +58,14 @@ public class RedEnvelopeV2Controller {
return redEnvelopeV2Service.list(roomUid, UidContextHolder.get());
}
/**
* 定时任务
*/
@ApiIgnore
@GetMapping("/task")
public BusiResult<Void> task() {
redEnvelopeV2Service.redEnvelopeExpireTask();
return BusiResult.success();
}
}

View File

@@ -0,0 +1,24 @@
package com.accompany.scheduler.task;
import com.accompany.business.service.redenvelope.RedEnvelopeV2Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RedEnvelopeTask {
@Autowired
private RedEnvelopeV2Service redEnvelopeV2Service;
/**
* 每10minutes
*/
@Scheduled(cron = "0 0/10 * * * ?")
public void redEnvelopeExpireTask() {
redEnvelopeV2Service.redEnvelopeExpireTask();
}
}