圣诞节活动-迁移

This commit is contained in:
khalil
2023-12-01 16:11:39 +08:00
parent ba13bb3693
commit 8a9c84af8f
38 changed files with 2262 additions and 0 deletions

View File

@@ -0,0 +1,258 @@
package com.accompany.business.christmas;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.christmas.dto.ChristmasCpProp;
import com.accompany.business.christmas.dto.ChristmasCpUserProp;
import com.accompany.business.common.dto.CpRankActConfigDto;
import com.accompany.common.constant.AppEnum;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.base.SpringContextHolder;
import com.accompany.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
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 java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ChristmasCpDao implements InitializingBean {
private final String MODULE_NAME = "cp_rank";
@Autowired
private RedissonClient redissonClient;
private RMap<Long, Integer> userCpRewardMap;
private RMap<String, ChristmasCpProp> cpPropMap;
private RMap<Long, Map<Long, ChristmasCpUserProp>> userCpPropMap;
@Override
public void afterPropertiesSet() throws Exception {
String userCpRewardKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "user_cp_reward");
userCpRewardMap = redissonClient.getMap(userCpRewardKey);
String cpPropKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "cp_prop");
cpPropMap = redissonClient.getMap(cpPropKey);
String userCpProp = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "user_cp_prop");
userCpPropMap = redissonClient.getMap(userCpProp);
}
public List<ChristmasCpUserProp> listCpByUid(Long uid) {
Map<Long, ChristmasCpUserProp> propMap = userCpPropMap.get(uid);
if (CollectionUtils.isEmpty(propMap)){
return null;
}
return propMap.values().stream()
.sorted(Comparator.comparing(ChristmasCpUserProp::getScore).reversed()).collect(Collectors.toList());
}
public ChristmasCpUserProp getCpByUid(Long fromUid, Long toUid) {
Map<Long, ChristmasCpUserProp> propMap = userCpPropMap.get(fromUid);
if (CollectionUtils.isEmpty(propMap)){
return null;
}
return propMap.get(toUid);
}
public Integer getCpRewardStatus(Long uid) {
return userCpRewardMap.getOrDefault(uid, ChristmasConstant.BtnStatus.NONE);
}
public boolean saveCpRewardStatus(Long uid) {
return userCpRewardMap.replace(uid, ChristmasConstant.BtnStatus.CAN, ChristmasConstant.BtnStatus.HAD);
}
public String getTheBestCpUidByUid(Long uid) {
Map<Long, ChristmasCpUserProp> propMap = userCpPropMap.get(uid);
if (CollectionUtils.isEmpty(propMap)){
return null;
}
ChristmasCpUserProp prop = propMap.values().stream()
.max(Comparator.comparing(ChristmasCpUserProp::getScore)).get();
return buildCpUid(prop.getFromUid(), prop.getToUid());
}
public String buildCpUid(Long fromUid, Long toUid){
List<Long> uidList = new ArrayList<>(2);
uidList.add(fromUid);
uidList.add(toUid);
return uidList.stream().sorted()
.map(Object::toString)
.collect(Collectors.joining("_"));
}
public List<Long> takeApartCpUid(String cpUid) {
return Arrays.stream(cpUid.split("_")).map(Long::parseLong).collect(Collectors.toList());
}
public ChristmasCpProp getCpPropByCpUid(String cpUid) {
return cpPropMap.get(cpUid);
}
private <R> R withLock(Long uid, String redisKey, Function<Map<Long, ChristmasCpUserProp>, R> function){
String lockKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, redisKey, uid.toString());
RLock lock = redissonClient.getLock(lockKey);
boolean isLocked = false;
try {
isLocked = lock.tryLock(3, TimeUnit.SECONDS);
if (!isLocked){
log.error("[2023圣诞节活动] {} 获取 {} 锁超时", uid, lockKey);
throw new ServiceException(BusiStatus.SERVER_BUSY);
}
Map<Long, ChristmasCpUserProp> propMap = userCpPropMap.get(uid);
return function.apply(propMap);
} catch (InterruptedException e) {
log.error("[2023圣诞节活动] {} 获取 {} 锁异常", uid, lockKey, e);
throw new ServiceException(BusiStatus.SERVER_BUSY);
} finally {
if (isLocked){
lock.unlock();
}
}
}
public boolean saveUserCpPropTaskStatus(Long fromUid, Long toUid, Integer taskId, Integer status){
return withLock(fromUid, "user_cp_prop_lock", propMap->{
if (CollectionUtils.isEmpty(propMap)){
return false;
}
ChristmasCpUserProp cpUserProp = propMap.get(toUid);
if (null == cpUserProp){
return false;
}
Integer curStatus = cpUserProp.getCpTaskStatus().get(taskId);
if (null == curStatus){
return false;
}
if (status.compareTo(curStatus) <= 0){
return false;
}
cpUserProp.getCpTaskStatus().put(taskId, status);
return userCpPropMap.fastPut(fromUid, propMap);
});
}
public void saveCpProp(ChristmasCpProp cpProp) {
if (!cpPropMap.fastPutIfAbsent(cpProp.getCpUid(), cpProp)){
return;
}
userCpRewardMap.fastPutIfAbsent(cpProp.getFromUid(), ChristmasConstant.BtnStatus.CAN);
userCpRewardMap.fastPutIfAbsent(cpProp.getToUid(), ChristmasConstant.BtnStatus.CAN);
ChristmasCpUserProp userProp = new ChristmasCpUserProp();
BeanUtils.copyProperties(cpProp, userProp);
userProp.setCpTaskStatus(new HashMap<>());
SpringContextHolder.getBean(ChristmasCpDao.class).saveUserCpProp(cpProp.getFromUid(), cpProp.getToUid(), userProp);
SpringContextHolder.getBean(ChristmasCpDao.class).saveUserCpProp(cpProp.getToUid(), cpProp.getFromUid(), userProp);
}
@Async
public boolean saveUserCpProp(Long fromUid, Long toUid, ChristmasCpUserProp userProp){
return withLock(fromUid, "user_cp_prop_lock", propMap->{
if (CollectionUtils.isEmpty(propMap)){
propMap.put(toUid, userProp);
userCpPropMap.fastPut(fromUid, propMap);
return false;
}
ChristmasCpUserProp cpUserProp = propMap.get(toUid);
if (null == cpUserProp){
propMap.put(toUid, userProp);
userCpPropMap.fastPut(fromUid, propMap);
return false;
}
if (cpUserProp.getScore() >= userProp.getScore()){
return false;
}
//更新分数
cpUserProp.setScore(userProp.getScore());
//更新任务状态
for (Map.Entry<Integer, Integer> entry: userProp.getCpTaskStatus().entrySet()) {
Integer taskId = entry.getKey();
Integer taskStatus = entry.getValue();
Integer curStatus = cpUserProp.getCpTaskStatus().getOrDefault(taskId, ChristmasConstant.BtnStatus.NONE);
if (taskStatus.compareTo(curStatus) > 0){
cpUserProp.getCpTaskStatus().put(taskId, taskStatus);
}
}
userCpPropMap.fastPut(fromUid, propMap);
return true;
});
}
public void updateCpScore(String cpUid, Double totalScore, CpRankActConfigDto config) {
ChristmasCpProp cpProp = getCpPropByCpUid(cpUid);
if (null == cpProp){
return;
}
long score = BigDecimal.valueOf(totalScore).setScale(0, RoundingMode.DOWN).longValue();
if (cpProp.getScore() >= score){
return;
}
boolean needUpdate = false;
boolean locked = false;
String lockKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "cp_prop_lock", cpUid);
RLock lock = redissonClient.getLock(lockKey);
try {
locked = lock.tryLock(3, TimeUnit.SECONDS);
if (!locked){
throw new ServiceException(BusiStatus.SERVER_BUSY);
}
cpProp = getCpPropByCpUid(cpUid);
if (cpProp.getScore() < score){
cpProp.setScore(score);
needUpdate = cpPropMap.fastPut(cpUid, cpProp);
}
} catch (InterruptedException e) {
//todo log
throw new RuntimeException(e);
} finally {
if (locked){
lock.unlock();
}
}
if (!needUpdate){
return;
}
Map<Integer, Integer> taskMap = config.getCpScoreTasks().stream()
.filter(task-> score >= task.getScore())
.collect(Collectors.toMap(CpRankActConfigDto.CpScoreTask::getId, task->ChristmasConstant.BtnStatus.CAN));
ChristmasCpUserProp userProp = new ChristmasCpUserProp();
BeanUtils.copyProperties(cpProp, userProp);
userProp.setCpTaskStatus(taskMap);
SpringContextHolder.getBean(ChristmasCpDao.class).saveUserCpProp(cpProp.getFromUid(), cpProp.getToUid(), userProp);
SpringContextHolder.getBean(ChristmasCpDao.class).saveUserCpProp(cpProp.getToUid(), cpProp.getFromUid(), userProp);
}
}

View File

@@ -0,0 +1,27 @@
package com.accompany.business.christmas;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ChristmasFirstLetterNumDao extends BaseTicketActDao {
@Override
protected String getActName() {
return ChristmasConstant.actName + "_first";
}
@Override
protected void logAfterAddUserTicketNum(Long uid, Integer num, Integer curTicketNum, Integer totalTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 增加 {} 个first情书 剩余 {} 个first情书 累计获得 {} 个first情书", uid, num, curTicketNum, totalTicketNum);
}
@Override
protected void logAfterReduceUserTicketNum(Long uid, Integer num, Integer curTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 消耗 {} 个first情书 剩余 {} 个first情书", uid, num, curTicketNum);
}
}

View File

@@ -0,0 +1,27 @@
package com.accompany.business.christmas;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ChristmasFourthLetterNumDao extends BaseTicketActDao {
@Override
protected String getActName() {
return ChristmasConstant.actName + "_fourth";
}
@Override
protected void logAfterAddUserTicketNum(Long uid, Integer num, Integer curTicketNum, Integer totalTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 增加 {} 个fourth情书 剩余 {} 个fourth情书 累计获得 {} 个fourth情书", uid, num, curTicketNum, totalTicketNum);
}
@Override
protected void logAfterReduceUserTicketNum(Long uid, Integer num, Integer curTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 消耗 {} 个fourth情书 剩余 {} 个fourth情书", uid, num, curTicketNum);
}
}

View File

@@ -0,0 +1,104 @@
package com.accompany.business.christmas;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.christmas.dto.ChristmasLetterDto;
import com.accompany.common.constant.AppEnum;
import com.accompany.common.exception.BusinessException;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.base.SpringContextHolder;
import com.accompany.core.exception.ServiceException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.redisson.client.protocol.ScoredEntry;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ChristmasLetterDao implements InitializingBean {
private final String MODULE_NAME = "letter";
@Autowired
private RedissonClient redissonClient;
private RMap<Long, List<ChristmasLetterDto>> userLetterMap;
private RScoredSortedSet<ChristmasLetterDto> letterSortedSet;
public List<ChristmasLetterDto> listUserLetter(Long uid){
return userLetterMap.getOrDefault(uid, Collections.emptyList());
}
public List<ChristmasLetterDto> listUserSquare(){
Collection<ScoredEntry<ChristmasLetterDto>> uidScoreList = letterSortedSet.entryRangeReversed(0, 30);
if (CollectionUtils.isEmpty(uidScoreList)){
return Collections.emptyList();
}
return uidScoreList.stream()
.map(ScoredEntry::getValue)
.collect(Collectors.toList());
}
public void saveLetter(Long uid, Long toUid, Integer letterType, String text) {
Date now = new Date();
ChristmasLetterDto dto = new ChristmasLetterDto();
dto.setFromUid(uid);
dto.setToUid(toUid);
dto.setLetterId(letterType);
dto.setContext(text);
dto.setCreateTime(now);
boolean locked = false;
String lockKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "save_letter_lock", uid.toString());
RLock lock = redissonClient.getLock(lockKey);
try {
locked = lock.tryLock(3, TimeUnit.SECONDS);
if (!locked){
throw new ServiceException(BusiStatus.SERVER_BUSY);
}
//扣费
SpringContextHolder.getBean(ChristmasLetterNumDao.class).consumeLetter(uid, letterType);
List<ChristmasLetterDto> uidLetterList = userLetterMap.get(uid);
if (CollectionUtils.isEmpty(uidLetterList)){
uidLetterList = new ArrayList<>();
}
uidLetterList.add(dto);
uidLetterList.sort(Comparator.comparing(ChristmasLetterDto::getCreateTime).reversed());
boolean success = userLetterMap.fastPut(uid, uidLetterList);
log.info("[2023-圣诞节活动]-信 {} 给 {} 发出情信 {} 结果 {}", uid, toUid, JSON.toJSONString(dto), success);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (locked){
lock.unlock();
}
}
double score = now.getTime();
boolean success = letterSortedSet.add(score, dto);
log.info("[2023-圣诞节活动]-信 添加 fromUid {} toUid {} 情信 {} 到告白广场, score {} 结果 {}", uid, toUid, JSON.toJSONString(dto), score, success);
}
@Override
public void afterPropertiesSet() throws Exception {
String userLetterKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "user_letter");
userLetterMap = redissonClient.getMap(userLetterKey);
String letterKey = String.join("_", AppEnum.getCurApp().getValue(), ChristmasConstant.actName, MODULE_NAME, "letter_square");
letterSortedSet = redissonClient.getScoredSortedSet(letterKey);
}
}

View File

@@ -0,0 +1,69 @@
package com.accompany.business.christmas;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.base.SpringContextHolder;
import com.accompany.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Order(-1)
@Slf4j
public class ChristmasLetterNumDao implements InitializingBean, ApplicationContextAware {
private ApplicationContext applicationContext;
private Map<Integer, BaseTicketActDao> map;
public BaseTicketActDao getTicketActDao(Integer type) {
BaseTicketActDao dao = map.get(type);
if (null == dao){
throw new ServiceException(BusiStatus.PARAMERROR);
}
return dao;
}
public Integer getUserCurLetterNum(Long uid, Integer type) {
return map.get(type).getUserCurTicketNum(uid);
}
public Map<Integer, Integer> getUserCurLetterNumMap(Long uid) {
return map.entrySet()
.parallelStream()
.collect(Collectors.toMap(Map.Entry::getKey,
e->e.getValue().getUserCurTicketNum(uid)));
}
public void consumeLetter(Long uid, Integer type){
BaseTicketActDao dao = map.get(type);
Integer curNum = dao.getUserCurTicketNum(uid);
if (curNum < 1){
throw new ServiceException(BusiStatus.PARAMERROR, ChristmasConstant.BusiStatus.LETTER_NUM_UN_ENOUGH);
}
dao.reduceUserTicketNum(uid, -1);
}
@Override
public void afterPropertiesSet() throws Exception {
map = new HashMap<>();
map.put(ChristmasConstant.LetterTaskId.ORANGE, applicationContext.getBean(ChristmasFirstLetterNumDao.class));
map.put(ChristmasConstant.LetterTaskId.BLUE, applicationContext.getBean(ChristmasSecondLetterNumDao.class));
map.put(ChristmasConstant.LetterTaskId.PINK, applicationContext.getBean(ChristmasThirdLetterNumDao.class));
map.put(ChristmasConstant.LetterTaskId.GOLD, applicationContext.getBean(ChristmasFourthLetterNumDao.class));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

View File

@@ -0,0 +1,27 @@
package com.accompany.business.christmas;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ChristmasSecondLetterNumDao extends BaseTicketActDao {
@Override
protected String getActName() {
return ChristmasConstant.actName + "_second";
}
@Override
protected void logAfterAddUserTicketNum(Long uid, Integer num, Integer curTicketNum, Integer totalTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 增加 {} 个second情书 剩余 {} 个second情书 累计获得 {} 个second情书", uid, num, curTicketNum, totalTicketNum);
}
@Override
protected void logAfterReduceUserTicketNum(Long uid, Integer num, Integer curTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 消耗 {} 个second情书 剩余 {} 个second情书", uid, num, curTicketNum);
}
}

View File

@@ -0,0 +1,27 @@
package com.accompany.business.christmas;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ChristmasThirdLetterNumDao extends BaseTicketActDao {
@Override
protected String getActName() {
return ChristmasConstant.actName + "_third";
}
@Override
protected void logAfterAddUserTicketNum(Long uid, Integer num, Integer curTicketNum, Integer totalTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 增加 {} 个third情书 剩余 {} 个third情书 累计获得 {} 个third情书", uid, num, curTicketNum, totalTicketNum);
}
@Override
protected void logAfterReduceUserTicketNum(Long uid, Integer num, Integer curTicketNum) {
log.info("[2023圣诞节活动]-任务 {} 消耗 {} 个third情书 剩余 {} 个third情书", uid, num, curTicketNum);
}
}

View File

@@ -0,0 +1,17 @@
package com.accompany.business.christmas;
import com.accompany.business.base.BaseTicketTaskActDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.halloween.constant.HalloweenConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ChristmasTicketTaskDao extends BaseTicketTaskActDao {
@Override
protected String getActName() {
return ChristmasConstant.actName;
}
}

View File

@@ -0,0 +1,24 @@
package com.accompany.scheduler.christmas;
import com.accompany.business.christmas.service.ChristmasRankService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
@Slf4j
public class ChristmasRankTask {
@Autowired
private ChristmasRankService service;
@Scheduled(cron = "1 0 0 * * ?")
public void settlement(){
LocalDateTime now = LocalDateTime.now();
service.settlement(now);
}
}

View File

@@ -0,0 +1,34 @@
package com.accompany.business.christmas.constant;
public class ChristmasConstant {
public static String actName = "act_christmas_2023";
public static class SysConfId {
public static final String ACT_LETTER_CONFIG = actName + "_letter_config";
public static final String ACT_RANK_CONFIG = actName + "_rank_config";
public static final String ACT_CP_RANK_CONFIG = actName + "_cp_rank_config";
}
public static class LetterTaskId {
public static final Integer ORANGE = 1;
public static final Integer BLUE = 2;
public static final Integer PINK = 3;
public static final Integer GOLD = 4;
}
public static class BusiStatus {
public static final String CHAR_LENGTH_LIMIT = "最多输入50个字符";
public static final String LETTER_NUM_UN_ENOUGH = "当前情书数量不足,请赠送对应礼物获取";
public static final String CONTEXT_SENSITIVE = "文案不符合规范,请重新输入";
}
public static String LETTER_TIP = "用户【%s】在【圣诞恋曲】活动中赠送了你一封情书快去查看吧";
public static class BtnStatus {
public static final Integer NONE = 0;
public static final Integer CAN = 1;
public static final Integer HAD = 2;
}
}

View File

@@ -0,0 +1,16 @@
package com.accompany.business.christmas.dto;
import lombok.Data;
import java.util.Date;
@Data
public class ChristmasCpProp {
private String cpUid;
private Long fromUid;
private Long toUid;
private Long score;
private Date createTime;
}

View File

@@ -0,0 +1,12 @@
package com.accompany.business.christmas.dto;
import lombok.Data;
import java.util.Map;
@Data
public class ChristmasCpUserProp extends ChristmasCpProp {
private Map<Integer, Integer> cpTaskStatus;
}

View File

@@ -0,0 +1,14 @@
package com.accompany.business.christmas.dto;
import com.accompany.business.common.dto.TaskActConfigDto;
import com.accompany.business.common.dto.TimeRangeActConfigDto;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Data
public class ChristmasLetterActConfigDto extends TaskActConfigDto {
}

View File

@@ -0,0 +1,16 @@
package com.accompany.business.christmas.dto;
import lombok.Data;
import java.util.Date;
@Data
public class ChristmasLetterDto {
private Long fromUid;
private Long toUid;
private Integer letterId;
private String context;
private Date createTime;
}

View File

@@ -0,0 +1,24 @@
package com.accompany.business.christmas.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel
@Data
public class ChristmasCpUserPropVo {
@ApiModelProperty("cpUid")
private String cpUid;
@ApiModelProperty("左uid")
private Long fromUid;
@ApiModelProperty("右uid")
private Long toUid;
@ApiModelProperty("桃花值")
private Long score;
@ApiModelProperty("cp任务列表")
private List<ChristmasCpUserTaskVo> cpTaskList;
}

View File

@@ -0,0 +1,20 @@
package com.accompany.business.christmas.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel
@Data
public class ChristmasCpUserTaskVo {
@ApiModelProperty("taskId")
private Integer taskId;
@ApiModelProperty("需要的桃花值")
private Long score;
@ApiModelProperty("状态0=未1=可2=已)")
private Integer status;
}

View File

@@ -0,0 +1,18 @@
package com.accompany.business.christmas.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel
@Data
public class ChristmasCpVo {
private Long uid;
@ApiModelProperty("圣诞礼盒状态0=未1=可2=已)")
private Integer boxStatus;
@ApiModelProperty("cp列表")
private List<ChristmasCpUserPropVo> cpList;
}

View File

@@ -0,0 +1,26 @@
package com.accompany.business.christmas.vo;
import com.accompany.business.common.vo.ActivityRankItemVo;
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 ChristmasLetterConfigVo {
@ApiModelProperty("开始时间")
private Date startTime;
@ApiModelProperty("结束时间")
private Date endTime;
@ApiModelProperty("用户uid")
private Long uid;
@ApiModelProperty("情书券数")
private Map<Integer,Integer> letterNumMap;
@ApiModelProperty("cp列表")
private List<ActivityRankItemVo> cpList;
}

View File

@@ -0,0 +1,24 @@
package com.accompany.business.christmas.vo;
import lombok.Data;
import java.util.Date;
@Data
public class ChristmasLetterVo {
private Long fromUid;
private Long fromErbanNo;
private String fromNick;
private String fromAvatar;
private Long toUid;
private Long toErbanNo;
private String toNick;
private String toAvatar;
private Integer letterId;
private String context;
private Date createTime;
}

View File

@@ -0,0 +1,24 @@
package com.accompany.business.common.constant;
import lombok.Getter;
@Getter
public enum CpRankTypeEnum implements ByteTypeEnum {
DAY((byte)1, "cp日榜", "rank_day"),
TOTAL((byte)2, "cp总榜","rank_total"),
;
/** 奖品ID **/
private Byte type;
private String desc;
private String cacheKey;
CpRankTypeEnum(Byte awardType, String desc, String cacheKey) {
this.type = awardType;
this.desc = desc;
this.cacheKey = cacheKey;
}
}

View File

@@ -0,0 +1,36 @@
package com.accompany.business.common.dto;
import com.accompany.business.common.constant.CpRankTypeEnum;
import lombok.Data;
import java.util.*;
@Data
public class CpRankActConfigDto extends TimeRangeActConfigDto{
public Set<Integer> cpGiftId;
public List<RewardDto> cpRewardList;
public List<CpScoreTask> cpScoreTasks;
public Set<CpRankTypeEnum> rankTypes;
protected Double normalGiftScorePercent;
protected Double activityGiftScorePercent;
protected Set<Integer> activityGiftId = new HashSet<>();
protected Map<CpRankTypeEnum, List<Integer>> rankSettlentSizeMap;
protected Map<CpRankTypeEnum, List<List<RewardDto>>> rankRewardMap;
public double getScore(Integer giftId, Integer giftNum, Long totalGoldNum, Date sendGiftTime) {
return totalGoldNum * (activityGiftId.contains(giftId)? activityGiftScorePercent : normalGiftScorePercent);
}
@Data
public static class CpScoreTask {
private Integer id;
private String desc;
private Long score;
private List<RewardDto> rewardList;
}
}

View File

@@ -0,0 +1,26 @@
package com.accompany.business.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel
public class ActivityCpRankItemVo {
@ApiModelProperty("排名0=未上榜)")
private Integer ranking;
@ApiModelProperty("得分")
private Long score;
private String cpUid;
private Long leftUid;
private Long leftErbanNo;
private String leftNick;
private String leftAvatar;
private Long rightUid;
private Long rightErbanNo;
private String rightNick;
private String rightAvatar;
}

View File

@@ -0,0 +1,28 @@
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;
import java.util.List;
@ApiModel
@NoArgsConstructor
@AllArgsConstructor
@Data
public class ActivityCpRankVo {
@ApiModelProperty
private String startTime;
@ApiModelProperty
private String endTime;
@ApiModelProperty
private Byte rankType;
@ApiModelProperty("排行榜")
private List<ActivityCpRankItemVo> rankList;
@ApiModelProperty("我的排行信息")
private ActivityCpRankItemVo meRank;
}

View File

@@ -0,0 +1,63 @@
package com.accompany.business.base.listener;
import com.accompany.business.base.service.BaseCpRankActService;
import com.accompany.business.base.service.BaseRankActService;
import com.accompany.business.common.dto.CpRankActConfigDto;
import com.accompany.business.common.dto.RankActConfigDto;
import com.accompany.business.event.GiftMessageEvent;
import com.accompany.business.message.GiftMessage;
import com.accompany.business.model.Hall;
import com.accompany.business.service.hall.HallService;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.base.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.Date;
public abstract class CpRankGiftListener<S extends BaseCpRankActService> {
@Autowired
protected S service;
@Autowired
private HallService hallService;
public void handleEvent(GiftMessageEvent giftMessageEvent) {
GiftMessage giftMessage = (GiftMessage) giftMessageEvent.getSource();
Date sendGiftTime = DateTimeUtil.convertMsToDate(giftMessage.getMessTime());
LocalDateTime sendGiftLocalDateTime = DateTimeUtil.converDateToLocalDateTime(sendGiftTime);
CpRankActConfigDto config = service.getRankActConfig();
if (!config.inActTimeRange(sendGiftLocalDateTime)){
return;
}
Long senderUid = giftMessage.getSendUid();
Long receiverUid = giftMessage.getRecvUid();
Integer giftId = giftMessage.getGiftId();
Integer giftNum = giftMessage.getGiftNum();
Long totalGoldNum = giftMessage.getGoldNum();
Hall senderHall = hallService.getValidHallByUid(senderUid);
if (null != senderHall){
return;
}
Hall receiverHall = hallService.getValidHallByUid(receiverUid);
if (null != receiverHall){
return;
}
String cpUid = service.addAndGetCpUid(config, senderUid, receiverUid, giftId, giftNum, totalGoldNum, sendGiftTime);
if (StringUtils.isBlank(cpUid)){
return;
}
//收礼榜
service.updateRank(cpUid, config, giftId, giftNum, totalGoldNum, sendGiftTime);
}
}

View File

@@ -0,0 +1,38 @@
package com.accompany.business.base.rankobj;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class CpRankObject {
private CpRankObjectType type;
private String cpUid;
private Long leftUid;
private Long leftErbanNo;
private String leftNick;
private String leftAvatar;
private Long rightUid;
private Long rightErbanNo;
private String rightNick;
private String rightAvatar;
public enum CpRankObjectType {
CP_USER((byte)1),
;
private byte type;
CpRankObjectType(Byte type) {
this.type = type;
}
}
}

View File

@@ -0,0 +1,12 @@
package com.accompany.business.base.rankobj;
import java.util.List;
import java.util.Map;
public interface CpRankObjectProvider {
Map<String, CpRankObject> mapRankObjectByUids(List<String> uidList);
CpRankObject getRankObjectByUid(String uid);
}

View File

@@ -0,0 +1,101 @@
package com.accompany.business.base.rankobj;
import com.accompany.business.service.user.UsersService;
import com.accompany.core.model.Users;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class CpUsersRankObjectProvider implements CpRankObjectProvider{
@Autowired
private UsersService usersService;
@Override
public Map<String, CpRankObject> mapRankObjectByUids(List<String> cpUidList) {
Map<String, CpRankObject> map = new HashMap<>();
List<Long> uidList = cpUidList.stream()
.map(cpUid->cpUid.split("_"))
.flatMap(Arrays::stream)
.map(Long::parseLong)
.distinct().collect(Collectors.toList());
Map<Long, Users> userMap = usersService.getUsersMapByUids(uidList);
for (String cpUid: cpUidList) {
CpRankObject obj = new CpRankObject();
obj.setType(CpRankObject.CpRankObjectType.CP_USER);
obj.setCpUid(cpUid);
String[] uidArray = cpUid.split("_");
Long leftUid = Long.parseLong(uidArray[0]);
obj.setLeftUid(leftUid);
Users leftUser = userMap.get(leftUid);
if (null != leftUser){
obj.setLeftErbanNo(leftUser.getErbanNo());
obj.setLeftNick(leftUser.getNick());
obj.setLeftAvatar(leftUser.getAvatar());
}
Long rightUid = Long.parseLong(uidArray[1]);
obj.setRightUid(rightUid);
Users rightUser = userMap.get(rightUid);
if (null != rightUser){
obj.setRightErbanNo(rightUser.getErbanNo());
obj.setRightNick(rightUser.getNick());
obj.setRightAvatar(rightUser.getAvatar());
}
map.put(cpUid, obj);
}
return map;
}
@Override
public CpRankObject getRankObjectByUid(String cpUid) {
if (StringUtils.isBlank(cpUid)){
return null;
}
List<Long> uidList = Arrays.stream(cpUid.split("_"))
.map(Long::parseLong)
.distinct().collect(Collectors.toList());
Map<Long, Users> userMap = usersService.getUsersMapByUids(uidList);
CpRankObject obj = new CpRankObject();
obj.setType(CpRankObject.CpRankObjectType.CP_USER);
obj.setCpUid(cpUid);
String[] uidArray = cpUid.split("_");
Long leftUid = Long.parseLong(uidArray[0]);
obj.setLeftUid(leftUid);
Users leftUser = userMap.get(leftUid);
if (null != leftUser){
obj.setLeftErbanNo(leftUser.getErbanNo());
obj.setLeftNick(leftUser.getNick());
obj.setLeftAvatar(leftUser.getAvatar());
}
Long rightUid = Long.parseLong(uidArray[1]);
obj.setRightUid(rightUid);
Users rightUser = userMap.get(rightUid);
if (null != rightUser){
obj.setRightErbanNo(rightUser.getErbanNo());
obj.setRightNick(rightUser.getNick());
obj.setRightAvatar(rightUser.getAvatar());
}
return obj;
}
}

View File

@@ -0,0 +1,256 @@
package com.accompany.business.base.service;
import com.accompany.business.base.rankobj.CpRankObject;
import com.accompany.business.base.rankobj.CpRankObjectProvider;
import com.accompany.business.common.constant.CpRankTypeEnum;
import com.accompany.business.common.dto.CpRankActConfigDto;
import com.accompany.business.common.dto.RewardDto;
import com.accompany.business.common.vo.*;
import com.accompany.business.qixi.common.RewardUtil;
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 org.redisson.api.RScoredSortedSet;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.redisson.client.protocol.ScoredEntry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
public abstract class BaseCpRankActService<Provider extends CpRankObjectProvider> {
@Autowired
private RedissonClient redissonClient;
@Autowired
private Provider provider;
@Autowired
private RewardUtil rewardUtil;
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DateTimeUtil.DEFAULT_DATETIME_PATTERN);
protected abstract String getActName();
public abstract String addAndGetCpUid(CpRankActConfigDto config, Long fromUid, Long toUid, Integer giftId, Integer giftNum, Long totalGoldNum, Date sendGiftTime);
public ActivityCpRankVo getRank(String cpUid, CpRankTypeEnum rankType, String date, Integer rankSize) {
CpRankActConfigDto configDto = getRankActConfig();
String rankKey = getRankKey(rankType, date);
RScoredSortedSet<String> rank = redissonClient.getScoredSortedSet(rankKey);
//拿前30
Collection<ScoredEntry<String>> uidScoreList = rank.entryRangeReversed(0, rankSize - 1);
List<ActivityCpRankItemVo> rankItemVoList = new ArrayList<>();
if (!CollectionUtils.isEmpty(uidScoreList)){
List<String> uidList = uidScoreList.stream().map(ScoredEntry::getValue).collect(Collectors.toList());
Map<String, CpRankObject> objMap = provider.mapRankObjectByUids(uidList);
int rankIndex = 1;
for (ScoredEntry<String> uidScore: uidScoreList){
CpRankObject obj = objMap.get(uidScore.getValue());
ActivityCpRankItemVo rankItemVo = new ActivityCpRankItemVo();
rankItemVo.setRanking(rankIndex++);
rankItemVo.setScore(BigDecimal.valueOf(uidScore.getScore()).setScale(0, RoundingMode.DOWN).longValue());
rankItemVo.setCpUid(uidScore.getValue());
if (null != obj){
rankItemVo.setLeftUid(obj.getLeftUid());
rankItemVo.setLeftErbanNo(obj.getLeftErbanNo());
rankItemVo.setLeftNick(obj.getLeftNick());
rankItemVo.setLeftAvatar(obj.getLeftAvatar());
rankItemVo.setRightUid(obj.getRightUid());
rankItemVo.setRightErbanNo(obj.getRightErbanNo());
rankItemVo.setRightNick(obj.getRightNick());
rankItemVo.setRightAvatar(obj.getRightAvatar());
}
rankItemVoList.add(rankItemVo);
}
}
ActivityCpRankItemVo meRankVo = new ActivityCpRankItemVo();
meRankVo.setRanking(0);
meRankVo.setScore(0L);
CpRankObject me = provider.getRankObjectByUid(cpUid);
if (null != me){
meRankVo.setCpUid(me.getCpUid());
meRankVo.setLeftUid(me.getLeftUid());
meRankVo.setLeftErbanNo(me.getLeftErbanNo());
meRankVo.setLeftNick(me.getLeftNick());
meRankVo.setLeftAvatar(me.getLeftAvatar());
meRankVo.setRightUid(me.getRightUid());
meRankVo.setRightErbanNo(me.getRightErbanNo());
meRankVo.setRightNick(me.getRightNick());
meRankVo.setRightAvatar(me.getRightAvatar());
int rankIndex = rank.rank(me.getCpUid());
meRankVo.setRanking(rankIndex > rankSize - 1? 0: rankIndex + 1);
double score = rank.getScore(me.getCpUid());
meRankVo.setScore(BigDecimal.valueOf(score).setScale(0, RoundingMode.DOWN).longValue());
}
return buildActivityRankVo(rankItemVoList, meRankVo, configDto, rankType);
}
private ActivityCpRankVo buildActivityRankVo(List<ActivityCpRankItemVo> rankItemVoList, ActivityCpRankItemVo meRankVo,
CpRankActConfigDto config, CpRankTypeEnum rankType) {
String startTime = config.getStartTime().format(dateTimeFormatter);
String endTime = config.getEndTime().format(dateTimeFormatter);
return new ActivityCpRankVo(startTime, endTime, rankType.getType(), rankItemVoList, meRankVo);
}
protected String getRankKey(CpRankTypeEnum rankType, String date){
switch (rankType){
case DAY:
return String.join("_", AppEnum.getCurApp().getValue(), getActName(), rankType.getCacheKey(), date);
case TOTAL:
return String.join("_", AppEnum.getCurApp().getValue(), getActName(), rankType.getCacheKey());
default:
throw new ServiceException(BusiStatus.PARAMERROR);
}
}
public void updateRank(String cpUid, CpRankActConfigDto config, Integer giftId, Integer giftNum, Long totalGoldNum, Date sendGiftTime) {
double score = config.getScore(giftId, giftNum, totalGoldNum, sendGiftTime);
if (score <= 0d){
return;
}
for (CpRankTypeEnum rankType : config.rankTypes){
if (CpRankTypeEnum.DAY.equals(rankType)){
String sendDate = DateTimeUtil.convertDate(sendGiftTime, DateTimeUtil.DEFAULT_DATE_PATTERN);
String dayRankKey = getRankKey(CpRankTypeEnum.DAY, sendDate);
RScoredSortedSet<String> dayRank = redissonClient.getScoredSortedSet(dayRankKey);
dayRank.addScore(cpUid, score);
} else if (CpRankTypeEnum.TOTAL.equals(rankType)){
String totalRankKey = getRankKey(CpRankTypeEnum.TOTAL, null);
RScoredSortedSet<String> totalRank = redissonClient.getScoredSortedSet(totalRankKey);
Double afterScore = totalRank.addScore(cpUid, score);
afterUpdateTotalRank(cpUid, afterScore, config);
}
}
logUpdateRank(cpUid, giftId, giftNum, totalGoldNum, score);
}
protected void afterUpdateTotalRank(String cpUid, Double totalScore, CpRankActConfigDto config) {
}
protected void logUpdateRank(String uid, Integer giftId, Integer giftNum, Long goldNum, Double score) {
}
public abstract CpRankActConfigDto getRankActConfig();
public void settlement(LocalDateTime now) {
settlement(now, Boolean.TRUE);
}
public void settlement(LocalDateTime now, boolean needFlag) {
CpRankActConfigDto config = getRankActConfig();
String yesterDayStr = now.minusDays(1L).format(DateTimeFormatter.ofPattern(DateTimeUtil.DEFAULT_DATE_PATTERN));
List<CpRankTypeEnum> rankTypes = new ArrayList<>();
if (config.inActTimeRange(now)){
rankTypes.add(CpRankTypeEnum.DAY);
} else if (Duration.between(now, config.getEndTime()).toDays() == 0L){
rankTypes.add(CpRankTypeEnum.DAY);
rankTypes.add(CpRankTypeEnum.TOTAL);
}
if (CollectionUtils.isEmpty(rankTypes)){
return;
}
for (CpRankTypeEnum rankType: rankTypes) {
if (!config.rankTypes.contains(rankType)){
continue;
}
sendRankReward(config, rankType, yesterDayStr, needFlag);
}
}
@Async
public void sendRankReward(CpRankActConfigDto config, CpRankTypeEnum rankType, String date, boolean needFlag) {
if (CollectionUtils.isEmpty(config.getRankRewardMap())
|| CollectionUtils.isEmpty(config.getRankSettlentSizeMap())){
return;
}
String rankKey = getRankKey(rankType, date);
RScoredSortedSet<Long> rank = redissonClient.getScoredSortedSet(rankKey);
List<Integer> settlementSizes = config.getRankSettlentSizeMap().get(rankType);
if (CollectionUtils.isEmpty(settlementSizes)){
return;
}
int rankSize = settlementSizes.stream().mapToInt(Integer::intValue).max().getAsInt() - 1;
Collection<ScoredEntry<Long>> uidScoreList = rank.entryRangeReversed(0, rankSize);
if (CollectionUtils.isEmpty(uidScoreList)){
//todo log error
return;
}
List<List<RewardDto>> rewardConfigList = config.getRankRewardMap().get(rankType);
if (CollectionUtils.isEmpty(rewardConfigList)){
return;
}
String sendRewardFlagKey = rankKey + "_send_reward_flag";
RSet<String> flagSet = redissonClient.getSet(sendRewardFlagKey);
int rankIndex = 0;
for (ScoredEntry<Long> rankItem: uidScoreList) {
Long uid = rankItem.getValue();
int ranking = rankIndex + 1;
int rewardLevel = settlementSizes.stream().mapToInt(Integer::intValue).filter(level->ranking<=level).min().getAsInt();
int rewardIndex = settlementSizes.indexOf(rewardLevel);
List<RewardDto> rewards = rewardConfigList.get(rewardIndex);
for (RewardDto r: rewards) {
String uidRewardKey = uid + "_" + r.getType() + "_" + r.getRefId();
if (needFlag && flagSet.contains(uidRewardKey)){
continue;
}
RewardVo vo = rewardUtil.sendRewardByType(uid, r, getActName() + rankType.getDesc());
logRankReward(rankType, date, rankKey, rankIndex, uid, vo);
if (needFlag){
flagSet.add(uidRewardKey);
}
}
rankIndex++;
}
}
protected void logRankReward(CpRankTypeEnum rankType, String date, String rankKey, Integer rankIndex, Long uid, RewardVo reward) {
}
}

View File

@@ -0,0 +1,121 @@
package com.accompany.business.base.service;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.base.BaseTicketTaskActDao;
import com.accompany.business.common.dto.TaskActConfigDto;
import com.accompany.business.common.vo.ActivityTaskConfigVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public abstract class BaseMulitTicketTaskActService<TaskDao extends BaseTicketTaskActDao> {
@Autowired
protected TaskDao taskDao;
protected abstract BaseTicketActDao getTicketActDao(Integer taskId);
public void processDailyTask(TaskActConfigDto.DailyTask dailyTask, Long uid, String date, Integer process) {
if (null == dailyTask){
throw new ServiceException(BusiStatus.SERVERERROR);
}
Integer taskId = dailyTask.getId();
String taskKey = buildTaskKey(uid, date, taskId);
int reward = taskDao.processDailyTask(taskKey, dailyTask, process);
if (reward > 0) {
Integer curTicket = addTicket(uid, taskId, reward);
logAfterFinishDailyTask(uid, date, taskId, reward, curTicket);
}
}
protected abstract void logAfterFinishDailyTask(Long uid, String date, Integer taskId, Integer reward, Integer curTicket);
public void processLoopTask(TaskActConfigDto.LoopTask loopTask, Long uid, String date, Integer process) {
if (null == loopTask){
throw new ServiceException(BusiStatus.SERVERERROR);
}
Integer taskId = loopTask.getId();
String taskKey = buildTaskKey(uid, date, taskId);
int reward = taskDao.processLoopTask(taskKey, loopTask, process);
if (reward > 0) {
Integer curTicket = addTicket(uid, taskId, reward);
logAfterFinishLoopTask(uid, date, taskId, reward, curTicket);
}
}
protected abstract void logAfterFinishLoopTask(Long uid, String date, Integer taskId, Integer reward, Integer curTicket);
public Integer addTicket(Long uid, Integer taskId, Integer reward){
return getTicketActDao(taskId).addUserTicketNum(uid, reward);
}
public List<ActivityTaskConfigVo.DailyTask> listUserDailyTaskVo(Long uid, String date,
Map<Integer, TaskActConfigDto.DailyTask> dailyTaskConfig){
Set<String> keySet = dailyTaskConfig.keySet().stream()
.map(id->buildTaskKey(uid, date, id)).collect(Collectors.toSet());
Map<String, Integer> progressMap = taskDao.getUserDailyTaskProgress(keySet);
List<ActivityTaskConfigVo.DailyTask> taskVoList = new ArrayList<>();
for (Map.Entry<Integer, TaskActConfigDto.DailyTask> entry: dailyTaskConfig.entrySet()) {
String key = buildTaskKey(uid, date, entry.getKey());
Integer progress = progressMap.getOrDefault(key, 0);
TaskActConfigDto.DailyTask dto = entry.getValue();
Integer maxNeed = dto.getStageNeedMap().keySet().stream().mapToInt(Integer::intValue).max().getAsInt();
ActivityTaskConfigVo.DailyTask vo = new ActivityTaskConfigVo.DailyTask();
vo.setId(dto.getId());
vo.setDesc(dto.getDesc());
vo.setNeed(maxNeed);
vo.setCur(progress);
vo.setStatus(progress >= maxNeed?
Constant.StatusV2.valid:
Constant.StatusV2.invalid);
taskVoList.add(vo);
}
return taskVoList;
}
protected List<ActivityTaskConfigVo.LoopTask> listUserLoopTaskVo(Long uid, String date, Map<Integer, TaskActConfigDto.LoopTask> loopTaskConfig) {
Set<String> keySet = loopTaskConfig.keySet().stream()
.map(id->buildTaskKey(uid, date, id)).collect(Collectors.toSet());
Map<String, Integer> progressMap = taskDao.getUserLoopTaskProgress(keySet);
List<ActivityTaskConfigVo.LoopTask> taskVoList = new ArrayList<>();
for (Map.Entry<Integer, TaskActConfigDto.LoopTask> entry: loopTaskConfig.entrySet()) {
String key = buildTaskKey(uid, date, entry.getKey());
Integer progress = progressMap.getOrDefault(key, 0);
TaskActConfigDto.LoopTask dto = entry.getValue();
ActivityTaskConfigVo.LoopTask vo = new ActivityTaskConfigVo.LoopTask();
vo.setId(dto.getId());
vo.setDesc(dto.getDesc());
vo.setLoop((progress / dto.getNeed()) * dto.getReward());
vo.setStatus(Constant.StatusV2.invalid);
taskVoList.add(vo);
}
return taskVoList;
}
protected String buildTaskKey(Long uid, String date, Integer taskId){
return String.join("_", String.valueOf(uid), date, String.valueOf(taskId));
}
}

View File

@@ -0,0 +1,21 @@
package com.accompany.business.christmas.listener;
import com.accompany.business.base.listener.CpRankGiftListener;
import com.accompany.business.christmas.service.ChristmasCpRankService;
import com.accompany.business.event.GiftMessageEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ChristmasCpRankGiftListener extends CpRankGiftListener<ChristmasCpRankService> implements ApplicationListener<GiftMessageEvent>{
@Async
@Override
public void onApplicationEvent(GiftMessageEvent giftMessageEvent) {
handleEvent(giftMessageEvent);
}
}

View File

@@ -0,0 +1,21 @@
package com.accompany.business.christmas.listener;
import com.accompany.business.base.listener.RankGiftListener;
import com.accompany.business.christmas.service.ChristmasRankService;
import com.accompany.business.event.GiftMessageEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ChristmasRankGiftListener extends RankGiftListener<ChristmasRankService> implements ApplicationListener<GiftMessageEvent>{
@Async
@Override
public void onApplicationEvent(GiftMessageEvent giftMessageEvent) {
handleEvent(giftMessageEvent);
}
}

View File

@@ -0,0 +1,100 @@
package com.accompany.business.christmas.service;
import com.accompany.business.base.rankobj.CpUsersRankObjectProvider;
import com.accompany.business.base.service.BaseCpRankActService;
import com.accompany.business.christmas.ChristmasCpDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.christmas.dto.ChristmasCpProp;
import com.accompany.business.christmas.vo.ChristmasCpVo;
import com.accompany.business.common.constant.CpRankTypeEnum;
import com.accompany.business.common.dto.CpRankActConfigDto;
import com.accompany.business.common.vo.ActivityCpRankVo;
import com.accompany.business.common.vo.RewardVo;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.service.SysConfService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Date;
@Service
@Slf4j
public class ChristmasCpRankService extends BaseCpRankActService<CpUsersRankObjectProvider> {
@Autowired
private SysConfService sysConfService;
@Autowired
private ChristmasCpDao cpDao;
@Override
protected String getActName() {
return ChristmasConstant.actName;
}
@Override
public String addAndGetCpUid(CpRankActConfigDto config, Long fromUid, Long toUid, Integer giftId, Integer giftNum, Long totalGoldNum, Date sendGiftTime) {
if (null == fromUid || null == toUid || fromUid.equals(toUid)){
throw new ServiceException(BusiStatus.PARAMERROR);
}
String cpUid = cpDao.buildCpUid(fromUid, toUid);
ChristmasCpProp cpProp = cpDao.getCpPropByCpUid(cpUid);
if (null != cpProp){
return cpUid;
}
if (CollectionUtils.isEmpty(config.getCpGiftId())
|| !config.getCpGiftId().contains(giftId)) {
return null;
}
cpProp = new ChristmasCpProp();
cpProp.setCpUid(cpUid);
cpProp.setFromUid(fromUid);
cpProp.setToUid(toUid);
cpProp.setScore(0L);
cpProp.setCreateTime(sendGiftTime);
cpDao.saveCpProp(cpProp);
log.info("[2023圣诞节活动]-cp榜 fromUid {} toUid {} 组成cp {}", fromUid, toUid, cpUid);
return cpUid;
}
@Override
protected void afterUpdateTotalRank(String cpUid, Double totalScore, CpRankActConfigDto config) {
cpDao.updateCpScore(cpUid, totalScore, config);
}
public ActivityCpRankVo getRank(Long uid, CpRankTypeEnum rankType, String date) {
String cpUid = cpDao.getTheBestCpUidByUid(uid);
return super.getRank(cpUid, rankType, date, 30);
}
@Override
protected void logUpdateRank(String cpUid, Integer giftId, Integer giftNum, Long totalGoldNum, Double score) {
log.info("[2023圣诞节活动]-cp榜 {} 收礼 {} {} 个总价值 {} 钻石,增加值 {}", cpUid, giftId, giftNum, totalGoldNum, score);
}
@Override
protected void logRankReward(CpRankTypeEnum rankType, String date, String rankKey, Integer rankIndex, Long uid, RewardVo reward) {
log.info("[2023圣诞节活动]-cp榜 {} 发奖励, 第 {} 名 {} 奖励 {}", rankKey, rankIndex, uid, JSON.toJSONString(reward));
}
@Override
public CpRankActConfigDto getRankActConfig() {
return getConfig();
}
public CpRankActConfigDto getConfig(){
String configStr = sysConfService.getSysConfValueById(ChristmasConstant.SysConfId.ACT_CP_RANK_CONFIG);
if (!StringUtils.hasText(configStr)){
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
}
return JSON.parseObject(configStr, CpRankActConfigDto.class);
}
}

View File

@@ -0,0 +1,115 @@
package com.accompany.business.christmas.service;
import com.accompany.business.christmas.ChristmasCpDao;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.christmas.dto.ChristmasCpUserProp;
import com.accompany.business.christmas.vo.ChristmasCpUserPropVo;
import com.accompany.business.christmas.vo.ChristmasCpUserTaskVo;
import com.accompany.business.christmas.vo.ChristmasCpVo;
import com.accompany.business.common.dto.CpRankActConfigDto;
import com.accompany.business.common.dto.RewardDto;
import com.accompany.business.common.vo.RewardVo;
import com.accompany.business.qixi.common.RewardUtil;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ChristmasCpService {
@Autowired
private ChristmasCpRankService cpRankService;
@Autowired
private ChristmasCpDao cpDao;
@Autowired
private RewardUtil rewardUtil;
public ChristmasCpVo getCpVo(Long uid) {
CpRankActConfigDto configDto = cpRankService.getConfig();
ChristmasCpVo cpVo = new ChristmasCpVo();
cpVo.setUid(uid);
List<ChristmasCpUserProp> cpList = cpDao.listCpByUid(uid);
if (CollectionUtils.isEmpty(cpList)){
cpVo.setCpList(Collections.emptyList());
cpVo.setBoxStatus(ChristmasConstant.BtnStatus.NONE);
return cpVo;
}
List<ChristmasCpUserPropVo> cpVoList = cpList.stream().map(prop->{
ChristmasCpUserPropVo vo = new ChristmasCpUserPropVo();
vo.setCpUid(prop.getCpUid());
vo.setFromUid(uid);
vo.setToUid(uid.equals(prop.getToUid())? prop.getFromUid(): prop.getToUid());
vo.setScore(prop.getScore());
List<ChristmasCpUserTaskVo> taskVoList = configDto.cpScoreTasks.stream().map(task->{
ChristmasCpUserTaskVo taskVo = new ChristmasCpUserTaskVo();
taskVo.setTaskId(task.getId());
taskVo.setScore(task.getScore());
taskVo.setStatus(prop.getCpTaskStatus().getOrDefault(task.getId(), ChristmasConstant.BtnStatus.NONE));
return taskVo;
}).sorted(Comparator.comparing(ChristmasCpUserTaskVo::getScore))
.collect(Collectors.toList());
vo.setCpTaskList(taskVoList);
return vo;
}).collect(Collectors.toList());
cpVo.setCpList(cpVoList);
Integer status = cpDao.getCpRewardStatus(uid);
cpVo.setBoxStatus(status);
return cpVo;
}
public List<RewardVo> getCpReward(Long uid) {
CpRankActConfigDto configDto = cpRankService.getConfig();
Integer status = cpDao.getCpRewardStatus(uid);
if (ChristmasConstant.BtnStatus.NONE.equals(status)){
throw new ServiceException(BusiStatus.ACT_AWARD_NOT_ACCORD);
} else if (ChristmasConstant.BtnStatus.HAD.equals(status)) {
throw new ServiceException(BusiStatus.ACT_AWARD_HAS_GET);
}
if (!cpDao.saveCpRewardStatus(uid)){
throw new ServiceException(BusiStatus.ACT_AWARD_HAS_GET);
}
List<RewardDto> rewardList = configDto.getCpRewardList();
return rewardList.parallelStream()
.map(dto->rewardUtil.sendRewardByType(uid, dto, "[2023圣诞节活动]-圣诞礼盒"))
.collect(Collectors.toList());
}
public List<RewardVo> getCpTaskReward(Long uid, Long toUid, Integer taskId) {
CpRankActConfigDto configDto = cpRankService.getConfig();
Optional<CpRankActConfigDto.CpScoreTask> taskOptional = configDto.getCpScoreTasks().stream().filter(t->taskId.equals(t.getId())).findAny();
if (!taskOptional.isPresent()){
throw new ServiceException(BusiStatus.PARAMETERILLEGAL);
}
if (!cpDao.saveUserCpPropTaskStatus(uid, toUid, taskId, ChristmasConstant.BtnStatus.HAD)){
throw new ServiceException(BusiStatus.ACT_AWARD_HAS_GET);
}
CpRankActConfigDto.CpScoreTask task = taskOptional.get();
List<RewardDto> rewardList = task.getRewardList();
return rewardList.parallelStream()
.map(dto->rewardUtil.sendRewardByType(uid, dto, "[2023圣诞节活动]-cp任务"))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,193 @@
package com.accompany.business.christmas.service;
import com.accompany.business.base.BaseTicketActDao;
import com.accompany.business.base.service.BaseMulitTicketTaskActService;
import com.accompany.business.base.service.BaseTicketTaskActService;
import com.accompany.business.christmas.*;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.christmas.dto.ChristmasCpUserProp;
import com.accompany.business.christmas.dto.ChristmasLetterActConfigDto;
import com.accompany.business.christmas.dto.ChristmasLetterDto;
import com.accompany.business.christmas.vo.ChristmasLetterConfigVo;
import com.accompany.business.christmas.vo.ChristmasLetterVo;
import com.accompany.business.common.dto.TaskActConfigDto;
import com.accompany.business.common.vo.ActivityRankItemVo;
import com.accompany.business.halloween.constant.HalloweenConstant;
import com.accompany.business.service.SendSysMsgService;
import com.accompany.business.service.netease.YidunCheckUtil;
import com.accompany.business.service.user.UsersService;
import com.accompany.common.config.SystemConfig;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.base.SpringContextHolder;
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.springframework.beans.BeanUtils;
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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ChristmasLetterService extends BaseMulitTicketTaskActService<ChristmasTicketTaskDao> {
@Autowired
private ChristmasCpDao cpDao;
@Autowired
private ChristmasLetterDao letterDao;
@Autowired
private ChristmasLetterNumDao letterNumDao;
@Autowired
private SysConfService sysConfService;
@Autowired
private UsersService usersService;
@Autowired
private SendSysMsgService sendSysMsgService;
public List<ChristmasLetterVo> listLetterVo(Long uid) {
List<ChristmasLetterDto> dtoList =
null == uid?
letterDao.listUserSquare():
letterDao.listUserLetter(uid);
if (CollectionUtils.isEmpty(dtoList)){
return Collections.emptyList();
}
List<ChristmasLetterVo> voList = new ArrayList<>();
Set<Long> uidSet = new HashSet<>();
for (ChristmasLetterDto dto: dtoList) {
uidSet.add(dto.getFromUid());
uidSet.add(dto.getToUid());
}
List<Long> uidList = new ArrayList<>(uidSet);
Map<Long, Users> usersMap = usersService.getUsersMapByUids(uidList);
for (ChristmasLetterDto dto: dtoList) {
ChristmasLetterVo vo = new ChristmasLetterVo();
BeanUtils.copyProperties(dto, vo);
Users fromUser = usersMap.get(dto.getFromUid());
if (null != fromUser){
vo.setFromErbanNo(fromUser.getErbanNo());
vo.setFromNick(fromUser.getNick());
vo.setFromAvatar(fromUser.getAvatar());
}
Users toUser = usersMap.get(dto.getToUid());
if (null != toUser){
vo.setToErbanNo(toUser.getErbanNo());
vo.setToNick(toUser.getNick());
vo.setToAvatar(toUser.getAvatar());
}
voList.add(vo);
}
return voList;
}
public ChristmasLetterConfigVo getConfigVo(Long uid){
ChristmasLetterActConfigDto dto = getConfig();
ChristmasLetterConfigVo vo = new ChristmasLetterConfigVo();
vo.setUid(uid);
vo.setStartTime(DateTimeUtil.localDateTime2Date(dto.getStartTime()));
vo.setEndTime(DateTimeUtil.localDateTime2Date(dto.getEndTime()));
vo.setLetterNumMap(letterNumDao.getUserCurLetterNumMap(uid));
List<ChristmasCpUserProp> cpList = cpDao.listCpByUid(uid);
if (CollectionUtils.isEmpty(cpList)){
vo.setCpList(Collections.emptyList());
return vo;
}
List<ActivityRankItemVo> cpVoList = cpList.stream().map(cp->{
ActivityRankItemVo itemVo = new ActivityRankItemVo();
itemVo.setUid(uid.equals(cp.getFromUid())?cp.getToUid():cp.getFromUid());
itemVo.setScore(cp.getScore());
return itemVo;
}).sorted(Comparator.comparing(ActivityRankItemVo::getScore).reversed())
.collect(Collectors.toList());
vo.setCpList(cpVoList);
List<Long> uidList = cpVoList.stream().map(ActivityRankItemVo::getUid).distinct().collect(Collectors.toList());
Map<Long, Users> userMap = usersService.getUsersMapByUids(uidList);
for (ActivityRankItemVo itemVo: cpVoList) {
Users u = userMap.get(itemVo.getUid());
if (null == u){
continue;
}
itemVo.setErbanNo(u.getErbanNo());
itemVo.setNick(u.getNick());
itemVo.setAvatar(u.getAvatar());
}
return vo;
}
public void publishLetter(Long uid, Long toUid, Integer letterType, String text) {
Users toUser = usersService.getUsersByUid(toUid);
if (null == toUser){
throw new ServiceException(BusiStatus.USERNOTEXISTS);
}
ChristmasCpUserProp cpUserProp = cpDao.getCpByUid(uid, toUid);
if (null == cpUserProp){
throw new ServiceException(BusiStatus.PARAMETERILLEGAL);
}
Integer num = letterNumDao.getUserCurLetterNum(uid, letterType);
if (num <= 0){
throw new ServiceException(BusiStatus.PARAMERROR, ChristmasConstant.BusiStatus.LETTER_NUM_UN_ENOUGH);
}
if (YidunCheckUtil.checkHasSensitiveWord(text)){
throw new ServiceException(BusiStatus.PARAMERROR, ChristmasConstant.BusiStatus.CONTEXT_SENSITIVE);
}
letterDao.saveLetter(uid, toUid, letterType, text);
SpringContextHolder.getBean(ChristmasLetterService.class).sendSecretMsg(uid, toUid);
}
@Async
public void sendSecretMsg(Long uid, Long toUid) {
Users user = usersService.getUsersByUid(uid);
if (null == user){
return;
}
String tip = String.format(ChristmasConstant.LETTER_TIP, user.getNick());
sendSysMsgService.sendPersonTextMsg(SystemConfig.secretaryUid, toUid, tip);
}
@Override
protected BaseTicketActDao getTicketActDao(Integer type) {
return letterNumDao.getTicketActDao(type);
}
@Override
protected void logAfterFinishDailyTask(Long uid, String date, Integer taskId, Integer reward, Integer curTicket) {
}
@Override
protected void logAfterFinishLoopTask(Long uid, String date, Integer taskId, Integer reward, Integer curTicket) {
log.info("[2023圣诞节]-任务 {} 在 {} 完成 {} 循环任务,获得 {} 情书, 当前拥有 {} 情书", uid, date, taskId, reward, curTicket);
}
public ChristmasLetterActConfigDto getConfig(){
String configStr = sysConfService.getSysConfValueById(ChristmasConstant.SysConfId.ACT_LETTER_CONFIG);
if (!StringUtils.hasText(configStr)){
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
}
return JSON.parseObject(configStr, ChristmasLetterActConfigDto.class);
}
}

View File

@@ -0,0 +1,65 @@
package com.accompany.business.christmas.service;
import com.accompany.business.base.rankobj.UsersRankObjectProvider;
import com.accompany.business.base.service.BaseRankActService;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.common.constant.RankTypeEnum;
import com.accompany.business.common.dto.RankActConfigDto;
import com.accompany.business.common.vo.ActivityRankVo;
import com.accompany.business.common.vo.RewardVo;
import com.accompany.business.halloween.constant.HalloweenConstant;
import com.accompany.business.halloween.dto.HalloweenRankConfigDto;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.service.SysConfService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@Service
@Slf4j
public class ChristmasRankService extends BaseRankActService<UsersRankObjectProvider> {
@Autowired
private SysConfService sysConfService;
@Override
protected String getActName() {
return ChristmasConstant.actName;
}
public ActivityRankVo getRank(Long uid, RankTypeEnum rankType, String date) {
return super.getRank(uid, rankType, date, 30);
}
@Override
protected void logUpdateSendRank(Long uid, Integer giftId, Integer giftNum, Long totalGoldNum, Double score) {
log.info("[2023圣诞节活动]- 送礼榜 {} 收礼 {} {} 个 总价值 {} 钻石,增加值 {}", uid, giftId, giftNum, totalGoldNum, score);
}
@Override
protected void logUpdateReceiveRank(Long uid, Integer giftId, Integer giftNum, Long totalGoldNum, Double score) {
log.info("[2023圣诞节活动]- 收礼榜 {} 收礼 {} {} 个总价值 {} 钻石,增加值 {}", uid, giftId, giftNum, totalGoldNum, score);
}
@Override
protected void logRankReward(RankTypeEnum rankType, String date, String rankKey, Integer rankIndex, Long uid, RewardVo reward) {
log.info("[2023圣诞节活动]-收送礼榜 {} 发奖励, 第 {} 名 {} 奖励 {}", rankKey, rankIndex, uid, JSON.toJSONString(reward));
}
@Override
public RankActConfigDto getRankActConfig() {
return getConfig();
}
public RankActConfigDto getConfig(){
String configStr = sysConfService.getSysConfValueById(ChristmasConstant.SysConfId.ACT_RANK_CONFIG);
if (!StringUtils.hasText(configStr)){
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
}
return JSON.parseObject(configStr, RankActConfigDto.class);
}
}

View File

@@ -0,0 +1,103 @@
package com.accompany.business.christmas;
import com.accompany.business.christmas.service.ChristmasCpRankService;
import com.accompany.business.christmas.service.ChristmasCpService;
import com.accompany.business.christmas.vo.ChristmasCpVo;
import com.accompany.business.common.constant.CpRankTypeEnum;
import com.accompany.business.common.vo.ActivityCpRankVo;
import com.accompany.business.common.vo.RewardVo;
import com.accompany.common.annotation.Authorization;
import com.accompany.common.constant.ApplicationConstant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
@Api(tags = "2023圣诞节活动",value = "2023圣诞节活动")
@RequestMapping("/act/2023Christmas/cpRank")
@RestController
public class ChristmasCpRankController {
@Autowired
private ChristmasCpService cpService;
@Autowired
private ChristmasCpRankService service;
@ApiOperation("获取自己的cp情况")
@GetMapping("/getCp")
@Authorization
public BusiResult<ChristmasCpVo> getCp(HttpServletRequest request){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
ChristmasCpVo cpVo = cpService.getCpVo(uid);
return new BusiResult<>(cpVo);
}
@ApiOperation("获取cp奖励")
@PostMapping("/getCpReward")
@Authorization
public BusiResult<List<RewardVo>> getCpReward(HttpServletRequest request){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
List<RewardVo> rewardVoList = cpService.getCpReward(uid);
return new BusiResult<>(rewardVoList);
}
@ApiOperation("获取cp任务奖励")
@PostMapping("/getCpTaskReward")
@Authorization
public BusiResult<List<RewardVo>> getCpReward(HttpServletRequest request, Long toUid, Integer taskId){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
List<RewardVo> rewardVoList = cpService.getCpTaskReward(uid, toUid, taskId);
return new BusiResult<>(rewardVoList);
}
@ApiOperation("cp排行榜")
@ApiImplicitParams({
@ApiImplicitParam(name = "rankType", value = "排行榜类型1=日榜2=总榜)", required = true),
@ApiImplicitParam(name = "date", value = "日榜日期,总榜可不传", required = false)
})
@GetMapping("/getRank")
@Authorization
public BusiResult<ActivityCpRankVo> getRank(HttpServletRequest request, CpRankTypeEnum rankType, String date){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
ActivityCpRankVo rankVo = service.getRank(uid, rankType, date);
return new BusiResult<>(rankVo);
}
@ApiOperation("结算")
@ApiImplicitParams({
@ApiImplicitParam(name = "date", value = "结算日期", required = true)
})
@PostMapping("/settlement")
public BusiResult<Void> settlement(String date, Boolean needFlag){
if (!StringUtils.hasText(date)){
throw new ServiceException(BusiStatus.PARAMERROR);
}
Date time = DateTimeUtil.convertStrToDate(date, DateTimeUtil.DEFAULT_DATE_PATTERN);
LocalDateTime dateTime = DateTimeUtil.converDateToLocalDateTime(time);
if (null == needFlag){
needFlag = true;
}
service.settlement(dateTime, needFlag);
return new BusiResult<>(BusiStatus.SUCCESS);
}
}

View File

@@ -0,0 +1,88 @@
package com.accompany.business.christmas;
import com.accompany.business.christmas.constant.ChristmasConstant;
import com.accompany.business.christmas.service.ChristmasLetterService;
import com.accompany.business.christmas.vo.ChristmasLetterConfigVo;
import com.accompany.business.christmas.vo.ChristmasLetterVo;
import com.accompany.common.annotation.Authorization;
import com.accompany.common.constant.ApplicationConstant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Api(tags = "2023圣诞节活动",value = "2023圣诞节活动")
@RequestMapping("/act/2023Christmas/letter")
@RestController
public class ChristmasLetterController {
@Autowired
private ChristmasLetterService service;
@ApiOperation("情书列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "uid", value = "null=广场uid=我的情书", required = true)
})
@Authorization
@GetMapping("/listLetter")
public BusiResult<List<ChristmasLetterVo>> listLetterVo(HttpServletRequest request,
Long uid){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long headerUid = Long.parseLong(uidStr);
if (null != uid && !uid.equals(headerUid)){
throw new ServiceException(BusiStatus.PARAMETERILLEGAL);
}
List<ChristmasLetterVo> listVo = service.listLetterVo(uid);
return new BusiResult<>(listVo);
}
@ApiOperation("我要告白首页")
@Authorization
@GetMapping("/getConfig")
public BusiResult<ChristmasLetterConfigVo> getConfigVo(HttpServletRequest request){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
ChristmasLetterConfigVo configVo = service.getConfigVo(uid);
return new BusiResult<>(configVo);
}
@ApiOperation("告白")
@ApiImplicitParams({
@ApiImplicitParam(name = "toUid", value = "cp Uid", required = true),
@ApiImplicitParam(name = "letterType", value = "情信id 123 4", required = true),
@ApiImplicitParam(name = "text", value = "内容", required = true)
})
@Authorization
@PostMapping("/publishLetter")
public BusiResult<Void> publishLetter(HttpServletRequest request,
Long toUid, Integer letterType, String text){
if (null == toUid
|| (!ChristmasConstant.LetterTaskId.ORANGE.equals(letterType)
&& !ChristmasConstant.LetterTaskId.BLUE.equals(letterType)
&& !ChristmasConstant.LetterTaskId.PINK.equals(letterType)
&& !ChristmasConstant.LetterTaskId.GOLD.equals(letterType))
|| StringUtils.isBlank(text)){
throw new ServiceException(BusiStatus.PARAMERROR);
}
if (text.length() > 50){
throw new ServiceException(BusiStatus.PARAMERROR, ChristmasConstant.BusiStatus.CHAR_LENGTH_LIMIT);
}
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
service.publishLetter(uid, toUid, letterType, text);
return BusiResult.success();
}
}

View File

@@ -0,0 +1,67 @@
package com.accompany.business.christmas;
import com.accompany.business.christmas.service.ChristmasRankService;
import com.accompany.business.common.constant.RankTypeEnum;
import com.accompany.business.common.vo.ActivityRankVo;
import com.accompany.common.annotation.Authorization;
import com.accompany.common.constant.ApplicationConstant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Date;
@Api(tags = "2023圣诞节活动",value = "2023圣诞节活动")
@RequestMapping("/act/2023Christmas/rank")
@RestController
public class ChristmasRankController {
@Autowired
private ChristmasRankService service;
@ApiOperation("排行榜")
@ApiImplicitParams({
@ApiImplicitParam(name = "rankType", value = "排行榜类型1=送礼日榜2=送礼总榜3=收礼日榜4=收礼总榜)", required = true),
@ApiImplicitParam(name = "date", value = "日榜日期,总榜可不传", required = false)
})
@GetMapping("/getRank")
@Authorization
public BusiResult<ActivityRankVo> getRank(HttpServletRequest request, RankTypeEnum rankType, String date){
String uidStr = request.getHeader(ApplicationConstant.PublicParameters.PUB_UID);
Long uid = Long.parseLong(uidStr);
ActivityRankVo rankVo = service.getRank(uid, rankType, date);
return new BusiResult<>(rankVo);
}
@ApiOperation("结算")
@ApiImplicitParams({
@ApiImplicitParam(name = "date", value = "结算日期", required = true)
})
@PostMapping("/settlement")
public BusiResult<Void> settlement(String date, Boolean needFlag){
if (!StringUtils.hasText(date)){
throw new ServiceException(BusiStatus.PARAMERROR);
}
Date time = DateTimeUtil.convertStrToDate(date, DateTimeUtil.DEFAULT_DATE_PATTERN);
LocalDateTime dateTime = DateTimeUtil.converDateToLocalDateTime(time);
if (null == needFlag){
needFlag = true;
}
service.settlement(dateTime, needFlag);
return new BusiResult<>(BusiStatus.SUCCESS);
}
}