时空幸运儿活动-实现
This commit is contained in:
@@ -6,16 +6,11 @@ import lombok.Data;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ApiModel
|
@ApiModel
|
||||||
public class ActivityRankItemVo {
|
public class ActivityRankItemVo extends ActivityUserVo {
|
||||||
|
|
||||||
@ApiModelProperty("排名(0=未上榜)")
|
@ApiModelProperty("排名(0=未上榜)")
|
||||||
private Integer ranking;
|
private Integer ranking;
|
||||||
@ApiModelProperty("得分")
|
@ApiModelProperty("得分")
|
||||||
private Long score;
|
private Long score;
|
||||||
|
|
||||||
private Long uid;
|
|
||||||
private Long erbanNo;
|
|
||||||
private String nick;
|
|
||||||
private String avatar;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
package com.accompany.business.common.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ActivityUserVo {
|
||||||
|
|
||||||
|
private Long uid;
|
||||||
|
private Long erbanNo;
|
||||||
|
private String nick;
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.constant;
|
||||||
|
|
||||||
|
public class LuckyProcessBarConstant {
|
||||||
|
|
||||||
|
public static String actName = "act_lucky_process_bar_2023";
|
||||||
|
|
||||||
|
public static class SysConfId {
|
||||||
|
public static final String ACT_CONFIG = actName + "_config";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String LUCKY_TIP = "恭喜您在【时空幸运儿】成为第%d个幸运儿获得奖励,奖励已经发放至您的背包注意查收哦~";
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.dto;
|
||||||
|
|
||||||
|
import com.accompany.business.common.dto.RewardDto;
|
||||||
|
import com.accompany.business.common.dto.TimeRangeActConfigDto;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LuckyProcessBarConfigDto extends TimeRangeActConfigDto {
|
||||||
|
|
||||||
|
private Set<Integer> giftIds;
|
||||||
|
private Map<Long, StageReward> stageRewardMap;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class StageReward {
|
||||||
|
private Long stage;
|
||||||
|
private List<RewardDto> rewardList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMax(){
|
||||||
|
return stageRewardMap.keySet().stream().max(Comparator.comparing(Long::longValue)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,17 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LuckyProcessBarRewardRecord implements Serializable {
|
||||||
|
|
||||||
|
private String date;
|
||||||
|
private Long uid;
|
||||||
|
private Byte type;
|
||||||
|
private Integer taskId;
|
||||||
|
private Integer proc;
|
||||||
|
private Integer need;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,39 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.vo;
|
||||||
|
|
||||||
|
import com.accompany.business.common.vo.ActivityRankItemVo;
|
||||||
|
import com.accompany.business.common.vo.ActivityUserVo;
|
||||||
|
import com.accompany.business.common.vo.RewardVo;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ApiModel
|
||||||
|
@Data
|
||||||
|
public class LuckyProcessBarConfigVo {
|
||||||
|
|
||||||
|
@ApiModelProperty("开始时间")
|
||||||
|
private Date startTime;
|
||||||
|
@ApiModelProperty("结束时间")
|
||||||
|
private Date endTime;
|
||||||
|
@ApiModelProperty("用户uid")
|
||||||
|
private Long uid;
|
||||||
|
|
||||||
|
@ApiModelProperty("上限")
|
||||||
|
private Long max;
|
||||||
|
@ApiModelProperty("当前")
|
||||||
|
private Long cur;
|
||||||
|
@ApiModelProperty("stage")
|
||||||
|
private Map<Long, StageReward> stageMap;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class StageReward {
|
||||||
|
private Long stage;
|
||||||
|
private ActivityUserVo luckyUser;
|
||||||
|
//private List<RewardVo> rewardList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.listener;
|
||||||
|
|
||||||
|
import com.accompany.business.event.GiftMessageEvent;
|
||||||
|
import com.accompany.business.luckyprocessbar.dto.LuckyProcessBarConfigDto;
|
||||||
|
import com.accompany.business.luckyprocessbar.service.LuckyProcessBarService;
|
||||||
|
import com.accompany.business.message.GiftMessage;
|
||||||
|
import com.accompany.common.utils.DateTimeUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class LuckyProcessBarGiftListener implements ApplicationListener<GiftMessageEvent> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LuckyProcessBarService service;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async
|
||||||
|
public void onApplicationEvent(GiftMessageEvent giftMessageEvent) {
|
||||||
|
GiftMessage giftMessage = (GiftMessage) giftMessageEvent.getSource();
|
||||||
|
Date sendGiftTime = DateTimeUtil.convertMsToDate(giftMessage.getMessTime());
|
||||||
|
LocalDateTime sendGiftLocalDateTime = DateTimeUtil.converDateToLocalDateTime(sendGiftTime);
|
||||||
|
|
||||||
|
LuckyProcessBarConfigDto config = service.getConfig();
|
||||||
|
if (!config.inActTimeRange(sendGiftLocalDateTime)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer giftId = giftMessage.getGiftId();
|
||||||
|
if (CollectionUtils.isEmpty(config.getGiftIds()) || !config.getGiftIds().contains(giftId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 送礼人Uid
|
||||||
|
Long sendUid = giftMessage.getSendUid();
|
||||||
|
String giftRecordId = giftMessage.getMessId();
|
||||||
|
Integer giftNum = giftMessage.getGiftNum();
|
||||||
|
|
||||||
|
service.process(config, sendUid, giftRecordId, giftId, giftNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,61 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.service;
|
||||||
|
|
||||||
|
import com.accompany.business.doubleeleven.DoubleElevenTaskDao;
|
||||||
|
import com.accompany.business.doubleeleven.model.DoubleElevenTaskRecord;
|
||||||
|
import com.accompany.business.mapper.DoubleElevenTaskRecordDao;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class LuckyProcessBarRewardRecordService extends ServiceImpl<DoubleElevenTaskRecordDao, DoubleElevenTaskRecord> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DoubleElevenTaskDao dao;
|
||||||
|
|
||||||
|
public void writeDb() {
|
||||||
|
List<DoubleElevenTaskRecord> dailyTaskRecord = new ArrayList<>();
|
||||||
|
Map<String, Integer> dailyTaskMap = dao.getAllUserDailyTaskProgress();
|
||||||
|
for (String key: dailyTaskMap.keySet()) {
|
||||||
|
String[] keys = key.split("_");
|
||||||
|
Long uid = Long.parseLong(keys[0]);
|
||||||
|
String date = keys[1];
|
||||||
|
Integer taskId = Integer.parseInt(keys[2]);
|
||||||
|
Integer proc = dailyTaskMap.get(key);
|
||||||
|
|
||||||
|
DoubleElevenTaskRecord record = new DoubleElevenTaskRecord();
|
||||||
|
record.setDate(date);
|
||||||
|
record.setUid(uid);
|
||||||
|
record.setTaskId(taskId);
|
||||||
|
record.setType((byte) 1);
|
||||||
|
record.setProc(proc);
|
||||||
|
dailyTaskRecord.add(record);
|
||||||
|
}
|
||||||
|
saveBatch(dailyTaskRecord);
|
||||||
|
|
||||||
|
List<DoubleElevenTaskRecord> loopTaskRecord = new ArrayList<>();
|
||||||
|
Map<String, Integer> loopTaskMap = dao.getAllUserLoopTaskProgress();
|
||||||
|
for (String key: loopTaskMap.keySet()) {
|
||||||
|
String[] keys = key.split("_");
|
||||||
|
Long uid = Long.parseLong(keys[0]);
|
||||||
|
String date = keys[1];
|
||||||
|
Integer taskId = Integer.parseInt(keys[2]);
|
||||||
|
Integer proc = loopTaskMap.get(key);
|
||||||
|
|
||||||
|
DoubleElevenTaskRecord record = new DoubleElevenTaskRecord();
|
||||||
|
record.setDate(date);
|
||||||
|
record.setUid(uid);
|
||||||
|
record.setTaskId(taskId);
|
||||||
|
record.setType((byte) 2);
|
||||||
|
record.setProc(proc);
|
||||||
|
loopTaskRecord.add(record);
|
||||||
|
}
|
||||||
|
saveBatch(loopTaskRecord);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,146 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar.service;
|
||||||
|
|
||||||
|
import com.accompany.business.common.dto.RewardDto;
|
||||||
|
import com.accompany.business.common.vo.ActivityUserVo;
|
||||||
|
import com.accompany.business.luckyprocessbar.constant.LuckyProcessBarConstant;
|
||||||
|
import com.accompany.business.luckyprocessbar.dto.LuckyProcessBarConfigDto;
|
||||||
|
import com.accompany.business.luckyprocessbar.vo.LuckyProcessBarConfigVo;
|
||||||
|
import com.accompany.business.qixi.common.RewardUtil;
|
||||||
|
import com.accompany.business.service.SendSysMsgService;
|
||||||
|
import com.accompany.business.service.user.UsersService;
|
||||||
|
import com.accompany.common.config.SystemConfig;
|
||||||
|
import com.accompany.common.constant.AppEnum;
|
||||||
|
import com.accompany.common.status.BusiStatus;
|
||||||
|
import com.accompany.common.utils.DateTimeUtil;
|
||||||
|
import com.accompany.core.exception.ServiceException;
|
||||||
|
import com.accompany.core.model.Users;
|
||||||
|
import com.accompany.core.service.SysConfService;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.redisson.api.RAtomicLong;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class LuckyProcessBarService implements InitializingBean {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
|
||||||
|
private RAtomicLong process;
|
||||||
|
private RMap<Long, Long> luckyUserMap;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysConfService sysConfService;
|
||||||
|
@Autowired
|
||||||
|
private UsersService usersService;
|
||||||
|
@Autowired
|
||||||
|
private RewardUtil rewardUtil;
|
||||||
|
@Autowired
|
||||||
|
private SendSysMsgService sendSysMsgService;
|
||||||
|
|
||||||
|
@Async
|
||||||
|
public void sendSecretMsg(Long uid, Long stage) {
|
||||||
|
String tip = String.format(LuckyProcessBarConstant.LUCKY_TIP, stage);
|
||||||
|
sendSysMsgService.sendPersonTextMsg(SystemConfig.secretaryUid, uid, tip);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LuckyProcessBarConfigVo getConfigVo(Long uid){
|
||||||
|
LuckyProcessBarConfigDto dto = getConfig();
|
||||||
|
|
||||||
|
LuckyProcessBarConfigVo vo = new LuckyProcessBarConfigVo();
|
||||||
|
vo.setUid(uid);
|
||||||
|
vo.setStartTime(DateTimeUtil.localDateTime2Date(dto.getStartTime()));
|
||||||
|
vo.setEndTime(DateTimeUtil.localDateTime2Date(dto.getEndTime()));
|
||||||
|
|
||||||
|
vo.setMax(dto.getMax());
|
||||||
|
vo.setCur(process.get());
|
||||||
|
|
||||||
|
Map<Long, Long> luckyUidMap = luckyUserMap.readAllMap();
|
||||||
|
Map<Long, Users> usersMap = CollectionUtils.isEmpty(luckyUidMap)?
|
||||||
|
Collections.emptyMap():
|
||||||
|
usersService.getUsersMapByUids(luckyUidMap.values().stream().distinct().collect(Collectors.toList()));
|
||||||
|
|
||||||
|
Map<Long, LuckyProcessBarConfigVo.StageReward> stageRewardMap = dto.getStageRewardMap().values().stream().map(stageReward->{
|
||||||
|
LuckyProcessBarConfigVo.StageReward stageVo = new LuckyProcessBarConfigVo.StageReward();
|
||||||
|
stageVo.setStage(stageReward.getStage());
|
||||||
|
Long luckyUid = luckyUidMap.get(stageReward.getStage());
|
||||||
|
if (null == luckyUid){
|
||||||
|
return stageVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
Users luckyUser = usersMap.get(luckyUid);
|
||||||
|
if (null == luckyUser){
|
||||||
|
return stageVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityUserVo luckyUserVo = new ActivityUserVo(luckyUid, luckyUser.getErbanNo(), luckyUser.getNick(), luckyUser.getAvatar());
|
||||||
|
stageVo.setLuckyUser(luckyUserVo);
|
||||||
|
|
||||||
|
return stageVo;
|
||||||
|
}).collect(Collectors.toMap(LuckyProcessBarConfigVo.StageReward::getStage, s->s));
|
||||||
|
vo.setStageMap(stageRewardMap);
|
||||||
|
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(LuckyProcessBarConfigDto config, Long uid, String giftRecordId, Integer giftId, Integer giftNum) {
|
||||||
|
Long max = config.getMax();
|
||||||
|
|
||||||
|
long cur;
|
||||||
|
long target;
|
||||||
|
do {
|
||||||
|
cur = process.get();
|
||||||
|
if (cur >= max){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target = Math.min(cur + giftNum, max);
|
||||||
|
} while (!process.compareAndSet(cur, target));
|
||||||
|
|
||||||
|
log.info("[2023时空幸运儿活动]-进度 {} 送出 {} 个 {}, 进度从 {} 增加到 {}, 送礼记录id {}",
|
||||||
|
uid, giftNum, giftId, cur, target, giftRecordId);
|
||||||
|
|
||||||
|
for (LuckyProcessBarConfigDto.StageReward stageReward: config.getStageRewardMap().values()){
|
||||||
|
if (cur >= stageReward.getStage() || target < stageReward.getStage()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = luckyUserMap.fastPut(stageReward.getStage(), uid);
|
||||||
|
|
||||||
|
log.info("[2023时空幸运儿活动]-阶段奖励 {} 进度从 {} 增加到 {},获得第 {} 阶段奖励 {},保存幸运儿结果 {}",
|
||||||
|
uid, cur, target, stageReward.getStage(), JSON.toJSONString(stageReward.getRewardList()), success);
|
||||||
|
|
||||||
|
for (RewardDto reward: stageReward.getRewardList()) {
|
||||||
|
rewardUtil.sendRewardByType(uid, reward, "[2023时空幸运儿活动]-阶段奖励");
|
||||||
|
}
|
||||||
|
|
||||||
|
sendSecretMsg(uid, stageReward.getStage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LuckyProcessBarConfigDto getConfig(){
|
||||||
|
String configStr = sysConfService.getSysConfValueById(LuckyProcessBarConstant.SysConfId.ACT_CONFIG);
|
||||||
|
if (!StringUtils.hasText(configStr)){
|
||||||
|
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
|
||||||
|
}
|
||||||
|
return JSON.parseObject(configStr, LuckyProcessBarConfigDto.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
String processKey = String.join("_", AppEnum.getCurApp().getValue(), LuckyProcessBarConstant.actName, "process");
|
||||||
|
process = redissonClient.getAtomicLong(processKey);
|
||||||
|
String luckyUserKey = String.join("_", AppEnum.getCurApp().getValue(), LuckyProcessBarConstant.actName, "lucky_user");
|
||||||
|
luckyUserMap = redissonClient.getMap(luckyUserKey);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
package com.accompany.business.luckyprocessbar;
|
||||||
|
|
||||||
|
import com.accompany.business.common.vo.ActivityRankVo;
|
||||||
|
import com.accompany.business.luckyprocessbar.service.LuckyProcessBarService;
|
||||||
|
import com.accompany.business.luckyprocessbar.vo.LuckyProcessBarConfigVo;
|
||||||
|
import com.accompany.common.annotation.Authorization;
|
||||||
|
import com.accompany.common.constant.ApplicationConstant;
|
||||||
|
import com.accompany.common.result.BusiResult;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Api(tags = "2023时空幸运儿",value = "2023时空幸运儿")
|
||||||
|
@RequestMapping("/act/2023LuckyProcessBar/")
|
||||||
|
@RestController
|
||||||
|
public class LuckyProcessBarController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LuckyProcessBarService service;
|
||||||
|
|
||||||
|
@ApiOperation("首页")
|
||||||
|
@GetMapping("/getConfig")
|
||||||
|
@Authorization
|
||||||
|
public BusiResult<LuckyProcessBarConfigVo> getRank(HttpServletRequest request){
|
||||||
|
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
|
||||||
|
Long uid = Long.parseLong(uidStr);
|
||||||
|
LuckyProcessBarConfigVo configVo = service.getConfigVo(uid);
|
||||||
|
return new BusiResult<>(configVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user