星级厨房重构-梳理解耦优化客户端接口
This commit is contained in:
@@ -19,11 +19,10 @@ import com.accompany.admin.vo.luckysea.LuckySeaActAdminRoundDetailVo;
|
||||
import com.accompany.admin.vo.luckysea.LuckySeaActAdminUserDrawRecord;
|
||||
import com.accompany.admin.vo.luckysea.LuckySeaActPlatformStatVo;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.service.activities.LuckySeaItemService;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaItemService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.enumeration.BusinessStatusCodeEnum;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
@@ -184,32 +184,6 @@ public class MyApiService {
|
||||
actValentineCpService.settlement(now, true);
|
||||
}
|
||||
|
||||
public void pushLuckySeaAWechat(String date) {
|
||||
Date yesterday = DateTimeUtil.convertStrToDate(date, DateTimeUtil.DEFAULT_DATE_PATTERN);
|
||||
Date beginTimeOfDay = DateTimeUtil.getBeginTimeOfDay(yesterday);
|
||||
Date endTimeOfDay = DateTimeUtil.getEndTimeOfDay(yesterday);
|
||||
|
||||
List<LuckySeaRankListVo> rankList = luckySeaActMapper.listDiamondRank(0, 1, beginTimeOfDay, endTimeOfDay);
|
||||
for (LuckySeaRankListVo vo: rankList){
|
||||
MarkdownMessage msg = new MarkdownMessage();
|
||||
msg.add(MarkdownMessage.getHeaderText(3, String.format("%s 星级厨房奖励榜榜一大佬", date)));
|
||||
msg.add(MarkdownMessage.getReferenceText(String.format("平台ID [%d]", vo.getErbanNo())));
|
||||
msg.add(MarkdownMessage.getReferenceText(String.format("昵称 [%s]", vo.getNick())));
|
||||
msg.add(MarkdownMessage.getReferenceText(String.format("当日累计收礼钻石价值 [%d]", vo.getNum().longValue())));
|
||||
enterpriseWechatPushService.pushMessageByKey(webSecurityConfig.getActivityEnterpriseWechatPushKey(), msg);
|
||||
}
|
||||
|
||||
rankList = luckySeaActMapper.listLuckyManRank(0, 1, beginTimeOfDay, endTimeOfDay);
|
||||
for (LuckySeaRankListVo vo: rankList){
|
||||
MarkdownMessage msg = new MarkdownMessage();
|
||||
msg.add(MarkdownMessage.getHeaderText(3, String.format("%s 星级厨房欧皇榜榜一大佬", date)));
|
||||
msg.add(MarkdownMessage.getReferenceText(String.format("平台ID [%d]", vo.getErbanNo())));
|
||||
msg.add(MarkdownMessage.getReferenceText(String.format("昵称 [%s]", vo.getNick())));
|
||||
msg.add(MarkdownMessage.getReferenceText(String.format("当日累计收礼钻石价值 [%d]", vo.getNum().longValue())));
|
||||
enterpriseWechatPushService.pushMessageByKey(webSecurityConfig.getActivityEnterpriseWechatPushKey(), msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void initRegion() {
|
||||
UsersExample example = new UsersExample();
|
||||
example.createCriteria().andRegionIsNull();
|
||||
|
@@ -14,15 +14,14 @@ import com.accompany.admin.controller.BaseController;
|
||||
import com.accompany.admin.params.LuckySeaItemSaveReqParams;
|
||||
import com.accompany.admin.service.activity.LuckySeaActAdminService;
|
||||
import com.accompany.admin.util.ExcelUtils;
|
||||
import com.accompany.admin.vo.ChargeRecordPersonAdminVo;
|
||||
import com.accompany.admin.vo.luckysea.LuckySeaActAdminRoundDetailVo;
|
||||
import com.accompany.admin.vo.luckysea.LuckySeaActAdminUserDrawRecord;
|
||||
import com.accompany.admin.vo.luckysea.LuckySeaActPlatformStatVo;
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.LuckySeaActInfoService;
|
||||
import com.accompany.business.service.activities.impl.ActivitiesLuckySeaServiceImpl;
|
||||
import com.accompany.business.service.activities.luckySea.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaActInfoService;
|
||||
import com.accompany.business.service.activities.luckySea.impl.ActivitiesLuckySeaServiceImpl;
|
||||
import com.accompany.business.service.api.QinniuService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
@@ -45,7 +44,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
@@ -246,7 +244,7 @@ public class LuckySeaActAdminController extends BaseController {
|
||||
throw new ServiceException("当前正在开奖,请等待开奖结束再修改库存");
|
||||
}
|
||||
Double stockValue = Double.valueOf(stock.trim());
|
||||
Long stockLongValue = (long) (stockValue * ActivitiesLuckySeaServiceImpl.HANDLE_STOCK_MULTIPLE);
|
||||
Long stockLongValue = stockValue.longValue() * ActivitiesLuckySeaServiceImpl.HANDLE_STOCK_MULTIPLE;
|
||||
jedisService.set(RedisKey.LUCKY_SEA_ACT_STOCK.getKey(), String.valueOf(stockLongValue));
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS);
|
||||
}
|
||||
|
@@ -101,16 +101,6 @@ public class MyApiController {
|
||||
return new BusiResult<>(BusiStatus.SUCCESS);
|
||||
}
|
||||
|
||||
@RequestMapping("/pushLuckySeaWechat")
|
||||
@ResponseBody
|
||||
public BusiResult<Void> pushLuckySeaAWechat(Long roomId, String date) {
|
||||
if (null == roomId || !roomId.equals(603L)){
|
||||
throw new ServiceException(BusiStatus.PARAMERROR);
|
||||
}
|
||||
myApiService.pushLuckySeaAWechat(date);
|
||||
return new BusiResult<>(BusiStatus.SUCCESS);
|
||||
}
|
||||
|
||||
@RequestMapping("/initRegion")
|
||||
@ResponseBody
|
||||
public BusiResult<Void> initRegion(Long roomId) {
|
||||
|
@@ -1195,10 +1195,6 @@ public class Constant {
|
||||
* 深海奇缘活动开关配置
|
||||
*/
|
||||
public static final String LUCKY_SEA_SWITCH = "lucky_sea_switch";
|
||||
/**
|
||||
* 深海奇缘活动模式
|
||||
*/
|
||||
public static final String LUCKY_SEA_MODEL = "lucky_sea_model";
|
||||
/**
|
||||
* 深海奇缘活动模式
|
||||
*/
|
||||
|
@@ -1051,8 +1051,6 @@ public enum RedisKey {
|
||||
LOCK_USER_PIECE,
|
||||
/** 深海奇缘活动更新用户碎片数分布式锁 **/
|
||||
LOCK_LUCKY_SEA_UPDATE_PIECE,
|
||||
/** 深海奇缘活动更新用户单轮消耗碎片数分布式锁 **/
|
||||
LOCK_LUCKY_SEA_UPDATE_COST_PIECE,
|
||||
/** 深海奇缘活动库存**/
|
||||
LUCKY_SEA_ACT_STOCK,
|
||||
/** 深海奇缘活动用户抽奖分布式锁 **/
|
||||
|
@@ -1,20 +1,9 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaUserDrawResult
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/1/5
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.model.activity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -40,11 +29,9 @@ public class LuckySeaUserDrawResult {
|
||||
private String roundId;
|
||||
|
||||
@TableField("item_type")
|
||||
@ApiModelProperty("配置类型")
|
||||
private Byte itemType;
|
||||
|
||||
@TableField("item_name")
|
||||
@ApiModelProperty("配置类型")
|
||||
private String itemName;
|
||||
|
||||
@TableField(value = "result")
|
||||
|
@@ -15,19 +15,13 @@ import com.accompany.business.service.activities.vo.LuckySeaRankListVo;
|
||||
import com.accompany.business.vo.activities.LuckySeaActRoundRankUserVo;
|
||||
import com.accompany.business.vo.activities.LuckySeaActRoundStatVo;
|
||||
import com.accompany.business.vo.activities.LuckySeaActUserDrawItemVO;
|
||||
import com.accompany.business.vo.activities.LuckySeaActUserOneRoundDrawResult;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <br>接口描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/1/4]
|
||||
*/
|
||||
@Mapper
|
||||
public interface LuckySeaActMapper {
|
||||
/**
|
||||
* 获取深海奇缘活动钻石榜单
|
||||
|
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaActDrawParams
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/1/4
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.param.activity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <br>类描述: 深海奇缘活动抽奖请求参数
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/1/4]
|
||||
*/
|
||||
@Data
|
||||
@ApiModel
|
||||
public class LuckySeaActDrawParams {
|
||||
|
||||
@ApiModelProperty(value = "选择的itemId")
|
||||
private Long itemId;
|
||||
@ApiModelProperty(value = "选择的数量")
|
||||
private Long num;
|
||||
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 文 件 名: WishStarCupAddKeyParams
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/12/7
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.param.activity;
|
||||
|
||||
import com.accompany.business.enums.UserActPropertyObjType;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/12/7]
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class WishStarCupAddKeyParams {
|
||||
private UserActPropertyObjType objType;
|
||||
private Long uid;
|
||||
private Integer keyNum;
|
||||
private String deviceId;
|
||||
private Long goldNum;
|
||||
}
|
@@ -14,10 +14,9 @@ import com.accompany.business.config.LuckySeaPreWarningConfig;
|
||||
import com.accompany.business.dto.activity.LuckySeaBroadCastDTO;
|
||||
import com.accompany.business.dto.activity.LuckySeaGoldPreWarningDTO;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaPreWarningMapper;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.impl.ActivitiesLuckySeaServiceImpl;
|
||||
import com.accompany.business.service.activities.luckySea.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.luckySea.impl.ActivitiesLuckySeaServiceImpl;
|
||||
import com.accompany.business.service.push.EnterpriseWechatPushService;
|
||||
import com.accompany.common.config.SystemConfig;
|
||||
import com.accompany.common.config.WebSecurityConfig;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.push.MarkdownMessage;
|
||||
|
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaActInfoServiceImpl
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/31
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaActInfoMapper;
|
||||
import com.accompany.business.service.activities.LuckySeaActInfoService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class LuckySeaActInfoServiceImpl extends ServiceImpl<LuckySeaActInfoMapper, LuckySeaActInfo> implements LuckySeaActInfoService {
|
||||
|
||||
@Override
|
||||
public LuckySeaActInfo getByCurrTime() {
|
||||
Date currDate = new Date();
|
||||
QueryWrapper<LuckySeaActInfo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().le(LuckySeaActInfo::getStartTime, currDate).orderByDesc(LuckySeaActInfo::getCreateTime);
|
||||
IPage<LuckySeaActInfo> queryPage = new Page<>(1, 1);
|
||||
IPage<LuckySeaActInfo> actPageInfo = page(queryPage, wrapper);
|
||||
|
||||
LuckySeaActInfo info = null;
|
||||
if (actPageInfo != null && !CollectionUtils.isEmpty(actPageInfo.getRecords())) {
|
||||
info = actPageInfo.getRecords().get(0);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaItemServiceImpl
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/31
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaItemMapper;
|
||||
import com.accompany.business.service.activities.LuckySeaItemService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaItemServiceImpl extends ServiceImpl<LuckySeaItemMapper, LuckySeaItem> implements LuckySeaItemService {
|
||||
|
||||
}
|
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaUserDrawRecordServiceImpl
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/1/4
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.model.activity.LuckySeaUserDrawRecord;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaUserDrawRecordMapper;
|
||||
import com.accompany.business.service.activities.LuckySeaItemService;
|
||||
import com.accompany.business.service.activities.LuckySeaUserDrawRecordService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.service.common.JedisLockService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
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 org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/1/4]
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Slf4j
|
||||
public class LuckySeaUserDrawRecordServiceImpl extends ServiceImpl<LuckySeaUserDrawRecordMapper, LuckySeaUserDrawRecord>
|
||||
implements LuckySeaUserDrawRecordService {
|
||||
|
||||
@Autowired
|
||||
private LuckySeaItemService luckySeaItemService;
|
||||
|
||||
@Autowired
|
||||
private JedisLockService jedisLockService;
|
||||
|
||||
@Override
|
||||
public void updateUserDrawRecord(Long uid, Long roomUid, String roundId, Long itemId, Long costPieceNum) {
|
||||
LuckySeaItem item = luckySeaItemService.getById(itemId);
|
||||
if (null == item) {
|
||||
log.error("选择的配置item不存在, itemId: " + item);
|
||||
throw new ServiceException("选择的配置item不存在");
|
||||
}
|
||||
String lockVal = jedisLockService.lock(RedisKey.LOCK_LUCKY_SEA_UPDATE_COST_PIECE.getKey(uid.toString()));
|
||||
try {
|
||||
QueryWrapper<LuckySeaUserDrawRecord> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaUserDrawRecord::getUid, uid).eq(LuckySeaUserDrawRecord::getRoundId, roundId)
|
||||
.eq(LuckySeaUserDrawRecord::getItemId, itemId);
|
||||
LuckySeaUserDrawRecord record = getOne(wrapper);
|
||||
log.info("更新用户单轮消耗碎片数操作前, uid:{},roundId:{},itemId:{},costPiece:{}",
|
||||
uid, roundId, item, record == null ? 0 : record.getCostPriceNum());
|
||||
if (record == null) {
|
||||
record = new LuckySeaUserDrawRecord();
|
||||
record.setUid(uid);
|
||||
record.setRoomUid(roomUid);
|
||||
record.setRoundId(roundId);
|
||||
record.setItemId(itemId);
|
||||
record.setItemName(item.getName());
|
||||
record.setItemUrl(item.getImgUrl());
|
||||
record.setItemMultiple(item.getMultiple());
|
||||
record.setCostPriceNum(costPieceNum);
|
||||
record.setDrawStatus(Constant.status.invalid);
|
||||
record.setCreateTime(new Date());
|
||||
} else {
|
||||
record.setRoomUid(roomUid);
|
||||
record.setCostPriceNum(record.getCostPriceNum() + costPieceNum);
|
||||
}
|
||||
record.setUpdateTime(new Date());
|
||||
saveOrUpdate(record);
|
||||
log.info("更新用户单轮消耗碎片数操作后, uid:{},roomUid:{},roundId:{},itemId:{},costPiece:{}",
|
||||
uid, roomUid, roundId, item, record.getCostPriceNum());
|
||||
} finally {
|
||||
jedisLockService.unlock(RedisKey.LOCK_LUCKY_SEA_UPDATE_COST_PIECE.getKey(uid.toString()), lockVal);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +1,8 @@
|
||||
package com.accompany.business.service.activities;
|
||||
|
||||
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.param.activity.LuckySeaActDrawParams;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserDrawRecordVo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserInfo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
@@ -38,12 +35,6 @@ public interface ActivitiesLuckySeaService {
|
||||
*/
|
||||
LuckySeaActUserInfo getUserLuckySeaActInfo(Long uid);
|
||||
|
||||
/**
|
||||
* 获取深海奇缘活动配置奖项列表
|
||||
* @return
|
||||
*/
|
||||
List<LuckySeaItem> listLuckySeaItem();
|
||||
|
||||
/**
|
||||
* 获取深海奇缘活动信息列表
|
||||
* @param count
|
||||
@@ -72,9 +63,8 @@ public interface ActivitiesLuckySeaService {
|
||||
/**
|
||||
* 深海奇缘活动用户抽奖
|
||||
* @param uid
|
||||
* @param params
|
||||
*/
|
||||
void draw(Long uid, LuckySeaActDrawParams params);
|
||||
void draw(Long uid, Long itemId, Long num);
|
||||
|
||||
/**
|
||||
* 获取深海奇缘活动各阶段时间配置
|
||||
@@ -103,14 +93,6 @@ public interface ActivitiesLuckySeaService {
|
||||
*/
|
||||
void updateUserDrawRecordAsync(String roundId, List<LuckySeaItem> itemList);
|
||||
|
||||
/**
|
||||
* 创建新的一轮游戏
|
||||
* @return
|
||||
* @param startTime
|
||||
* @param chooseStageConfigTime
|
||||
*/
|
||||
String createNewRoundAct(Date startTime, Integer chooseStageConfigTime);
|
||||
|
||||
/**
|
||||
* 更新游戏状态
|
||||
* @param roundId
|
@@ -0,0 +1,17 @@
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
|
||||
/**
|
||||
* <br>接口描述: 深海奇缘活动信息service
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
public interface LuckySeaActConfigService {
|
||||
|
||||
LuckySeaActConfig getLuckySeaTimeConfig();
|
||||
|
||||
Double getLuckySeaActTicket();
|
||||
}
|
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaActInfoService
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/31
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities;
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <br>接口描述: 深海奇缘活动信息service
|
||||
* <br>功能详细描述:
|
||||
@@ -26,4 +19,10 @@ public interface LuckySeaActInfoService extends IService<LuckySeaActInfo> {
|
||||
* @return
|
||||
*/
|
||||
LuckySeaActInfo getByCurrTime();
|
||||
|
||||
List<LuckySeaActInfo> listActInfo(String roundId, Integer count);
|
||||
|
||||
Long getStock();
|
||||
|
||||
LuckySeaActInfo createNeewRoundAct(Date nextRoundStartTime, Integer chooseStageTime);
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
public interface LuckySeaDrawService {
|
||||
|
||||
void draw(Long uid, Long itemId, Long num);
|
||||
|
||||
void start();
|
||||
|
||||
}
|
@@ -1,18 +1,10 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaItemService
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/31
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities;
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <br>接口描述: 深海奇缘活动配置item
|
||||
* <br>功能详细描述:
|
||||
@@ -22,4 +14,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
*/
|
||||
public interface LuckySeaItemService extends IService<LuckySeaItem> {
|
||||
|
||||
LuckySeaItem getItemById(Long uid);
|
||||
|
||||
List<LuckySeaItem> listSingleItem();
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
|
||||
/**
|
||||
* <br>接口描述: 深海奇缘活动信息service
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
public interface LuckySeaRankService {
|
||||
|
||||
LuckySeaRankVo listRank(Integer type, Integer page, Integer pageSize, Long uid);
|
||||
|
||||
}
|
@@ -1,15 +1,6 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaUserDrawRecordService
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/1/4
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities;
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.model.activity.LuckySeaUserDrawRecord;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
@@ -25,8 +16,7 @@ public interface LuckySeaUserDrawRecordService extends IService<LuckySeaUserDraw
|
||||
* 更新用户抽奖记录
|
||||
* @param uid
|
||||
* @param roundId
|
||||
* @param itemId
|
||||
* @param costPieceNum
|
||||
*/
|
||||
void updateUserDrawRecord(Long uid, Long roomUid, String roundId, Long itemId, Long costPieceNum);
|
||||
boolean updateUserDrawRecord(Long uid, Long roomUid, String roundId, LuckySeaItem item, Long costPieceNum);
|
||||
}
|
@@ -1,14 +1,4 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaUserDrawResultService
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/1/5
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities;
|
||||
package com.accompany.business.service.activities.luckySea;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaUserDrawResult;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
@@ -1,14 +1,4 @@
|
||||
/*
|
||||
* 文 件 名: ActivitiesLuckySeaServiceImpl
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/29
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities.impl;
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.constant.activities.ActivitesPackTypeEnum;
|
||||
@@ -19,12 +9,9 @@ import com.accompany.business.model.ActivityPack;
|
||||
import com.accompany.business.model.UserPurse;
|
||||
import com.accompany.business.model.activity.*;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaActMapper;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaUserDrawResultMapper;
|
||||
import com.accompany.business.param.activity.LuckySeaActDrawParams;
|
||||
import com.accompany.business.service.activities.*;
|
||||
import com.accompany.business.service.activities.luckySea.*;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserDrawRecordVo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserInfo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankListVo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
import com.accompany.business.service.activity.ActivityPackService;
|
||||
import com.accompany.business.service.purse.UserPurseService;
|
||||
@@ -35,23 +22,23 @@ import com.accompany.business.service.user.UserActPropertyInfoV2Service;
|
||||
import com.accompany.business.service.user.UsersService;
|
||||
import com.accompany.business.vo.activities.*;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.exception.ApiException;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.BlankUtil;
|
||||
import com.accompany.common.utils.DateTimeUtil;
|
||||
import com.accompany.common.utils.RandomUtil;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.enumeration.BillObjTypeEnum;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.model.Users;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.accompany.core.service.common.JedisLockService;
|
||||
import com.accompany.core.service.common.JedisService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RAtomicLong;
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
@@ -61,25 +48,20 @@ import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/29]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService {
|
||||
|
||||
@Autowired
|
||||
private UserInOutRoomRecordService userInOutRoomRecordService;
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private JedisLockService jedisLockService;
|
||||
private LuckySeaActConfigService configService;
|
||||
@Autowired
|
||||
private ActivityPackService activityPackService;
|
||||
@Autowired
|
||||
@@ -93,46 +75,30 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
@Autowired
|
||||
private LuckySeaActInfoService luckySeaActInfoService;
|
||||
@Autowired
|
||||
private LuckySeaRankService rankService;
|
||||
@Autowired
|
||||
private LuckySeaActMapper luckySeaActMapper;
|
||||
@Autowired
|
||||
private LuckySeaDrawService drawService;
|
||||
@Autowired
|
||||
private LuckySeaUserDrawRecordService luckySeaUserDrawRecordService;
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
@Autowired
|
||||
private LuckySeaUserDrawResultService luckySeaUserDrawResultService;
|
||||
private LuckySeaUserDrawResultService userDrawResultService;
|
||||
@Autowired
|
||||
private JedisService jedisService;
|
||||
@Autowired
|
||||
private LuckySeaUserDrawResultMapper luckySeaUserDrawResultMapper;
|
||||
@Autowired
|
||||
private BillRecordService billRecordService;
|
||||
@Autowired
|
||||
private UserActPropertyInfoV2Service userActPropertyInfoV2Service;
|
||||
@Autowired
|
||||
private LuckySeaPushMsgService luckySeaPushMsgService;
|
||||
@Autowired
|
||||
private Executor taskExecutor;
|
||||
|
||||
/**
|
||||
* 默认返回的游戏记录数
|
||||
*/
|
||||
private final static Integer DEFAULT_RETURN_RECORD_NUM = 5;
|
||||
/**
|
||||
* 选择阶段默认时间(秒)
|
||||
*/
|
||||
private final static Integer DEFAULT_CHOOSE_STAGE_TIME = 30;
|
||||
/**
|
||||
* 开奖阶段默认时间(秒)
|
||||
*/
|
||||
private final static Integer DEFAULT_WAITING_DRAW_STAGE_TIME = 5;
|
||||
/**
|
||||
* 开奖结束阶段默认时间(秒)
|
||||
*/
|
||||
private final static Integer DEFAULT_DRAW_OVER_STAGE_TIME = 3;
|
||||
/**
|
||||
* 处理库存时需要换算的倍数
|
||||
*/
|
||||
public final static Integer HANDLE_STOCK_MULTIPLE = 100000;
|
||||
private final static Integer CACHE_EXPIRE_SECOND = 3;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@@ -147,12 +113,14 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
throw new ServiceException("购买礼包数必须大于0");
|
||||
}
|
||||
log.info("updateUserLuckySeaActPiece, uid = {}, packId = {}, packNum = {}", uid, packId, packNum);
|
||||
String lock = null;
|
||||
boolean locked = false;
|
||||
RLock lock = redissonClient.getLock(RedisKey.LOCK_LUCKY_SEA_UPDATE_PIECE.getKey(uid.toString()));
|
||||
try {
|
||||
lock = jedisLockService.lock(RedisKey.LOCK_LUCKY_SEA_UPDATE_PIECE.getKey(uid.toString()), 10 * 1000);
|
||||
if (BlankUtil.isBlank(lock)){
|
||||
throw new ApiException(BusiStatus.REQUEST_FAST);
|
||||
locked = lock.tryLock(3, TimeUnit.SECONDS);
|
||||
if (!locked){
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
}
|
||||
|
||||
ActivityPack pack = activityPackService.getPackById(packId);
|
||||
if (null == pack) {
|
||||
throw new ServiceException("购买的产品不存在");
|
||||
@@ -160,87 +128,96 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
int pieceNum = pack.getTicketNum() * packNum;
|
||||
userActPropertyInfoService.updatePiece(uid, (long)pieceNum);
|
||||
log.info("updateTicketNum, num = {}",pieceNum);
|
||||
}finally {
|
||||
jedisLockService.unlock(RedisKey.LOCK_LUCKY_SEA_UPDATE_PIECE.getKey(uid.toString()), lock);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("[春日游园]", e);
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
} finally {
|
||||
if (locked){
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckySeaActUserInfo getUserLuckySeaActInfo(Long uid) {
|
||||
if (null == uid) {
|
||||
throw new ServiceException("uid不能为空");
|
||||
}
|
||||
Users user = usersService.getUsersByUid(uid);
|
||||
if (user == null) {
|
||||
if (null == user) {
|
||||
throw new ServiceException(BusiStatus.USERNOTEXISTS);
|
||||
}
|
||||
|
||||
LuckySeaActUserInfo info = new LuckySeaActUserInfo();
|
||||
info.setAvatar(user.getAvatar());
|
||||
info.setNick(user.getNick());
|
||||
|
||||
// 获取用户钱包钻石数
|
||||
UserPurse userPurse = userPurseService.queryUserPurse(uid);
|
||||
info.setDiamonds(userPurse != null ? userPurse.getDiamonds() : 0);
|
||||
Date today = new Date();
|
||||
Date tomorrow = DateTimeUtil.addDays(today, 1);
|
||||
String todayStr = DateTimeUtil.convertDate(today, DateTimeUtil.DEFAULT_DATE_PATTERN);
|
||||
String tomorrowStr = DateTimeUtil.convertDate(tomorrow, DateTimeUtil.DEFAULT_DATE_PATTERN);
|
||||
Double diamondIncome = luckySeaActMapper.countUserDiamondIncome(uid, todayStr, tomorrowStr);
|
||||
info.setTodayReward(diamondIncome);
|
||||
info.setDiamonds(null != userPurse? userPurse.getDiamonds() : 0);
|
||||
|
||||
|
||||
/*Date today = new Date();
|
||||
Date todayStart = DateTimeUtil.getBeginTimeOfDay(today);
|
||||
Date todayEnd = DateTimeUtil.getEndTimeOfDay(today);
|
||||
String todayStartStr = DateTimeUtil.convertDate(todayStart, DateTimeUtil.DEFAULT_DATETIME_PATTERN);
|
||||
String todayEndStr = DateTimeUtil.convertDate(todayEnd, DateTimeUtil.DEFAULT_DATE_PATTERN);
|
||||
Double diamondIncome = luckySeaActMapper.countUserDiamondIncome(uid, todayStartStr, todayEndStr);
|
||||
info.setTodayReward(diamondIncome);*/
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaItem> listLuckySeaItem() {
|
||||
String cacheKey = RedisKey.lucky_sea_item.getKey();
|
||||
String cacheVal = jedisService.get(cacheKey);
|
||||
if (StringUtils.isNotBlank(cacheVal)){
|
||||
return JSON.parseArray(cacheVal, LuckySeaItem.class);
|
||||
}
|
||||
QueryWrapper<LuckySeaItem> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaItem::getStatus, Constant.status.valid)
|
||||
.orderByAsc(LuckySeaItem::getMultiple);
|
||||
List<LuckySeaItem> itemList = luckySeaItemService.list(wrapper);
|
||||
jedisService.setex(cacheKey, CACHE_EXPIRE_SECOND, JSON.toJSONString(itemList));
|
||||
return itemList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaActInfo> listLuckySeaActInfo(Integer count, String roundId) {
|
||||
if (null == count) {
|
||||
count = DEFAULT_RETURN_RECORD_NUM;
|
||||
}
|
||||
String cacheKey = RedisKey.lucky_sea_act_info.getKey(String.valueOf(count), roundId);
|
||||
String cacheVal = jedisService.get(cacheKey);
|
||||
if (StringUtils.isNotBlank(cacheVal)){
|
||||
return JSON.parseArray(cacheVal, LuckySeaActInfo.class);
|
||||
}
|
||||
QueryWrapper<LuckySeaActInfo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaActInfo::getStatus, Constant.LuckySeaActStatus.DRAW_OVER).ne(LuckySeaActInfo::getRoundId, roundId)
|
||||
.orderByDesc(LuckySeaActInfo::getStartTime);
|
||||
wrapper.last(String.format("limit %d", count));
|
||||
List<LuckySeaActInfo> actList = luckySeaActInfoService.list(wrapper);
|
||||
jedisService.setex(cacheKey, CACHE_EXPIRE_SECOND, JSON.toJSONString(actList));
|
||||
return actList;
|
||||
return luckySeaActInfoService.listActInfo(roundId, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckySeaActInfoVo getNewestLuckySeaActInfo(Long uid) {
|
||||
LuckySeaActInfoVo vo = new LuckySeaActInfoVo();
|
||||
|
||||
LuckySeaActInfo info = luckySeaActInfoService.getByCurrTime();
|
||||
if (null == info){
|
||||
return vo;
|
||||
}
|
||||
BeanUtils.copyProperties(info, vo);
|
||||
|
||||
LuckySeaActConfig luckySeaTimeConfig = getLuckySeaTimeConfig();
|
||||
if (null != info) {
|
||||
BeanUtils.copyProperties(info, vo);
|
||||
if (vo.getShowResultStageStartTime() == null) {
|
||||
vo.setShowResultStageStartTime(DateTimeUtil.addSeconds(vo.getDrawStageStartTime(), luckySeaTimeConfig.getWaitingDrawStageTime()));
|
||||
}
|
||||
if (Constant.LuckySeaActStatus.DRAW_OVER.equals(info.getStatus())) {
|
||||
// 获取排行榜前三
|
||||
List<LuckySeaActRoundRankUserVo> topThreeUser = luckySeaActMapper.listTopThreeInOneRound(info.getRoundId());
|
||||
vo.setRankUserList(topThreeUser);
|
||||
if (null != uid) {
|
||||
|
||||
if (vo.getShowResultStageStartTime() == null) {
|
||||
vo.setShowResultStageStartTime(DateTimeUtil.addSeconds(vo.getDrawStageStartTime(), luckySeaTimeConfig.getWaitingDrawStageTime()));
|
||||
}
|
||||
|
||||
if (Constant.LuckySeaActStatus.DRAW_OVER.equals(info.getStatus())) {
|
||||
vo.setEndTime(DateTimeUtil.addSeconds(vo.getShowResultStageStartTime(), luckySeaTimeConfig.getDrawOverStageTime()));
|
||||
|
||||
CountDownLatch cdl = new CountDownLatch(2);
|
||||
taskExecutor.execute(()->{
|
||||
try {
|
||||
// 获取排行榜前三
|
||||
List<LuckySeaActRoundRankUserVo> topThreeUser = luckySeaActMapper.listTopThreeInOneRound(info.getRoundId());
|
||||
if (!CollectionUtils.isEmpty(topThreeUser)){
|
||||
List<Long> uids = topThreeUser.stream().map(LuckySeaActRoundRankUserVo::getUid).distinct().collect(Collectors.toList());
|
||||
Map<Long, Users> usersMap = usersService.getUsersMapByUids(uids);
|
||||
for (LuckySeaActRoundRankUserVo e: topThreeUser){
|
||||
Users u = usersMap.get(e.getUid());
|
||||
if (null == u){
|
||||
continue;
|
||||
}
|
||||
e.setErbanNo(u.getErbanNo());
|
||||
e.setNick(u.getNick());
|
||||
e.setAvatar(u.getAvatar());
|
||||
}
|
||||
}
|
||||
vo.setRankUserList(topThreeUser);
|
||||
} catch (Exception e){
|
||||
log.error("[春日游园]", e);
|
||||
} finally {
|
||||
cdl.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
taskExecutor.execute(()->{
|
||||
try {
|
||||
// 获取用户中奖信息
|
||||
LuckySeaActUserOneRoundDrawResult result = new LuckySeaActUserOneRoundDrawResult();
|
||||
|
||||
List<LuckySeaActUserDrawItemVO> userRecords = listUserDrawItemInfo(uid, info.getRoundId());
|
||||
result.setDrawRecords(userRecords);
|
||||
|
||||
@@ -257,10 +234,19 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vo.setUserDrawResult(result);
|
||||
} catch (Exception e){
|
||||
log.error("[春日游园]", e);
|
||||
} finally {
|
||||
cdl.countDown();
|
||||
}
|
||||
vo.setEndTime(DateTimeUtil.addSeconds(vo.getShowResultStageStartTime(), luckySeaTimeConfig.getDrawOverStageTime()));
|
||||
});
|
||||
|
||||
try {
|
||||
cdl.await(3, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("[春日游园]", e);
|
||||
throw new ServiceException(BusiStatus.SERVERERROR);
|
||||
}
|
||||
}
|
||||
return vo;
|
||||
@@ -268,128 +254,76 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
|
||||
@Override
|
||||
public LuckySeaRankVo listRank(Integer type, Integer page, Integer pageSize, Long uid) {
|
||||
if (null == type) {
|
||||
throw new ServiceException("榜单type不能为空");
|
||||
}
|
||||
if (null == page) {
|
||||
page = Constant.DEFAULT_PAGE;
|
||||
}
|
||||
if (null == pageSize) {
|
||||
pageSize = Constant.DEFAULT_PAGE_SIZE;
|
||||
}
|
||||
int start = (page - 1) * pageSize;
|
||||
LuckySeaRankVo vo = new LuckySeaRankVo();
|
||||
List<LuckySeaRankListVo> rankList = new ArrayList<>();
|
||||
LuckySeaRankListVo userRankInfo = new LuckySeaRankListVo();
|
||||
Date beginTimeOfDay = DateTimeUtil.getBeginTimeOfDay(new Date());
|
||||
Date endTimeOfDay = DateTimeUtil.getEndTimeOfDay(new Date());
|
||||
if (type.equals(Constant.LuckySeaRankType.DIAMOND_RANK)) {
|
||||
rankList = luckySeaActMapper.listDiamondRank(start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
userRankInfo = luckySeaActMapper.listUserDiamondRank(uid, beginTimeOfDay, endTimeOfDay);
|
||||
} else if (type.equals(Constant.LuckySeaRankType.LUCKY_MAN_RANK)) {
|
||||
rankList = luckySeaActMapper.listLuckyManRank(start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
userRankInfo = luckySeaActMapper.listUserLuckyManRank(uid, beginTimeOfDay, endTimeOfDay);
|
||||
}
|
||||
// 最多返回100条
|
||||
if (page * pageSize > 100) {
|
||||
rankList = new ArrayList<>();
|
||||
}
|
||||
vo.setRankList(rankList);
|
||||
vo.setMyRankInfo(userRankInfo);
|
||||
return vo;
|
||||
return rankService.listRank(type, page, pageSize, uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Long uid, LuckySeaActDrawParams param) {
|
||||
if (null == uid) {
|
||||
throw new ServiceException("uid不能为空");
|
||||
}
|
||||
String lockVal = jedisLockService.lock(RedisKey.LOCK_LUCKY_SEA_USER_DRAW.getKey(uid.toString()));
|
||||
if (BlankUtil.isBlank(lockVal)) {
|
||||
log.error("春日游园,获取分布式锁失败,uid:{}", uid);
|
||||
throw new ServiceException(BusiStatus.JOIN_GAME_USER_TOO_MORE);
|
||||
}
|
||||
String roundId = null;
|
||||
try {
|
||||
Long costGoldTotal = checkDrawParam(param, uid);
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getByCurrTime();
|
||||
if (actInfo == null) {
|
||||
log.error("选择失败,当前时段不存在活动。actInfo:" + JSON.toJSONString(actInfo));
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
}
|
||||
roundId = actInfo.getRoundId();
|
||||
jedisService.incrBy(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId), 1);
|
||||
if (!actInfo.getStatus().equals(Constant.LuckySeaActStatus.CHOOSE_STAGE)) {
|
||||
log.error("选择失败,当前不处于选择阶段。actInfo:" + JSON.toJSONString(actInfo));
|
||||
throw new ServiceException("選擇失敗,當前不處於選擇階段");
|
||||
}
|
||||
|
||||
// 扣减用户钻石
|
||||
log.info("【春日游园活动】 uid {} 消耗钻石总数 {}", uid, costGoldTotal);
|
||||
Boolean ret = userPurseService.subDiamond(uid, (double) costGoldTotal, Constant.BusinessType.LUCKY_SEA_DRAW);
|
||||
if (!ret) {
|
||||
throw new ServiceException(BusiStatus.DIAMONDNUMNOTENOUGH);
|
||||
}
|
||||
|
||||
Long roomUid = userInOutRoomRecordService.getUserCurrentRoomUid(uid);
|
||||
luckySeaUserDrawRecordService.updateUserDrawRecord(uid, roomUid, actInfo.getRoundId(), param.getItemId(), param.getNum());
|
||||
|
||||
billRecordService.insertGeneralBillRecord(uid, null, null, BillObjTypeEnum.ACTIVITY_LUCKY_SEA_DRAW,
|
||||
-Double.valueOf(costGoldTotal));
|
||||
} finally {
|
||||
jedisLockService.unlock(RedisKey.LOCK_LUCKY_SEA_USER_DRAW.getKey(uid.toString()), lockVal);
|
||||
jedisService.decrBy(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId), 1);
|
||||
}
|
||||
public void draw(Long uid, Long itemId, Long num) {
|
||||
drawService.draw(uid, itemId, num);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckySeaActConfig getLuckySeaTimeConfig() {
|
||||
String luckySeaConfigStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_TIME_CONFIG);
|
||||
if (StringUtils.isBlank(luckySeaConfigStr)) {
|
||||
LuckySeaActConfig config = new LuckySeaActConfig();
|
||||
config.setChooseStageTime(DEFAULT_CHOOSE_STAGE_TIME);
|
||||
config.setWaitingDrawStageTime(DEFAULT_WAITING_DRAW_STAGE_TIME);
|
||||
config.setDrawOverStageTime(DEFAULT_DRAW_OVER_STAGE_TIME);
|
||||
return config;
|
||||
}
|
||||
return JSON.parseObject(luckySeaConfigStr, LuckySeaActConfig.class);
|
||||
return configService.getLuckySeaTimeConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaActUserDrawRecordVo> listUserDrawResult(Long uid, Integer page, Integer pageSize) {
|
||||
if (page == null) {
|
||||
page = Constant.DEFAULT_PAGE;
|
||||
}
|
||||
if (pageSize == null) {
|
||||
page = Constant.DEFAULT_PAGE_SIZE;
|
||||
}
|
||||
QueryWrapper<LuckySeaUserDrawResult> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaUserDrawResult::getUid, uid).orderByDesc(LuckySeaUserDrawResult::getDrawTime);
|
||||
Page<LuckySeaUserDrawResult> recordVoPage = new Page<>(page, pageSize);
|
||||
List<LuckySeaUserDrawResult> list = luckySeaUserDrawResultMapper.selectPage(recordVoPage, wrapper).getRecords();
|
||||
|
||||
Page<LuckySeaUserDrawResult> pageInfo = new Page<>(page, pageSize);
|
||||
QueryWrapper<LuckySeaUserDrawResult> wrapper = Wrappers.query();
|
||||
wrapper.lambda().eq(LuckySeaUserDrawResult::getUid, uid)
|
||||
.orderByDesc(LuckySeaUserDrawResult::getDrawTime);
|
||||
userDrawResultService.page(pageInfo, wrapper);
|
||||
|
||||
List<LuckySeaActUserDrawRecordVo> results = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
for (LuckySeaUserDrawResult result : list) {
|
||||
LuckySeaActUserDrawRecordVo vo = new LuckySeaActUserDrawRecordVo();
|
||||
Long reward = 0L;
|
||||
LuckySeaActInfo actInfo = luckySeaActInfoService.getById(result.getRoundId());
|
||||
if (actInfo != null) {
|
||||
vo.setRoundId(actInfo.getRoundId());
|
||||
vo.setDrawTime(actInfo.getEndTime());
|
||||
vo.setDrawId(actInfo.getDrawId());
|
||||
}
|
||||
List<LuckySeaUserDrawResultVo> resultVos = handleDrawResult(result.getResult());
|
||||
for (LuckySeaUserDrawResultVo resultVo : resultVos) {
|
||||
if (null != result.getDrawId() && result.getDrawId().equals(resultVo.getItemId())) {
|
||||
reward = resultVo.getCostPiece() * resultVo.getMultiple();
|
||||
}
|
||||
}
|
||||
vo.setResults(resultVos);
|
||||
vo.setDrawStatus(result.getDrawStatus());
|
||||
vo.setReward(reward);
|
||||
results.add(vo);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(pageInfo.getRecords())){
|
||||
return results;
|
||||
}
|
||||
|
||||
for (LuckySeaUserDrawResult result : pageInfo.getRecords()) {
|
||||
LuckySeaActUserDrawRecordVo vo = new LuckySeaActUserDrawRecordVo();
|
||||
BeanUtils.copyProperties(result, vo);
|
||||
|
||||
long reward = 0L;
|
||||
List<LuckySeaUserDrawResultVo> resultVos = handleDrawResult(result.getResult());
|
||||
for (LuckySeaUserDrawResultVo resultVo : resultVos) {
|
||||
if (null != result.getDrawId() && result.getDrawId().equals(resultVo.getItemId())) {
|
||||
reward += resultVo.getCostPiece() * resultVo.getMultiple();
|
||||
}
|
||||
}
|
||||
vo.setResults(resultVos);
|
||||
vo.setReward(reward);
|
||||
results.add(vo);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理抽奖结果返回
|
||||
* @param resultJson
|
||||
* @return
|
||||
*/
|
||||
private List<LuckySeaUserDrawResultVo> handleDrawResult(String resultJson) {
|
||||
List<LuckySeaUserDrawResultVo> results = new ArrayList<>();
|
||||
if (StringUtils.isBlank(resultJson)){
|
||||
return results;
|
||||
}
|
||||
|
||||
List<LuckySeaItem> itemList = luckySeaItemService.listSingleItem();
|
||||
Map<Long, String> itemUrlMap = itemList.stream().collect(Collectors.toMap(LuckySeaItem::getId, LuckySeaItem::getImgUrl));
|
||||
|
||||
List<LuckySeaUserDrawResultDto> dtoList = JSON.parseArray(resultJson, LuckySeaUserDrawResultDto.class);
|
||||
for (LuckySeaUserDrawResultDto dto : dtoList) {
|
||||
LuckySeaUserDrawResultVo vo = new LuckySeaUserDrawResultVo();
|
||||
vo.setItemUrl(itemUrlMap.get(dto.getItemId()));
|
||||
vo.setCostPiece(dto.getCostNum());
|
||||
vo.setItemId(dto.getItemId());
|
||||
vo.setMultiple(dto.getMultiple());
|
||||
results.add(vo);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -470,8 +404,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 异步写入用户的游戏记录
|
||||
* @param roundId
|
||||
@@ -514,7 +446,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
result.setUpdateTime(new Date());
|
||||
results.add(result);
|
||||
}
|
||||
luckySeaUserDrawResultService.saveBatch(results);
|
||||
userDrawResultService.saveBatch(results);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +456,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
* @param itemList
|
||||
* @return
|
||||
*/
|
||||
private Map<Long, Map<Long, LuckySeaUserDrawResultDto>> initUserDrawResultMap( Map<Long, List<LuckySeaUserDrawRecord>> userDrawRecordMap,
|
||||
private Map<Long, Map<Long, LuckySeaUserDrawResultDto>> initUserDrawResultMap(Map<Long, List<LuckySeaUserDrawRecord>> userDrawRecordMap,
|
||||
List<LuckySeaItem> itemList) {
|
||||
Map<Long, Map<Long, LuckySeaUserDrawResultDto>> userDrawResultMap = new HashMap<>();
|
||||
for (Long uid : userDrawRecordMap.keySet()) {
|
||||
@@ -632,19 +564,37 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
luckySeaActInfoService.updateById(act);
|
||||
QueryWrapper<LuckySeaUserDrawResult> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaUserDrawResult::getRoundId, roundId);
|
||||
List<LuckySeaUserDrawResult> results = luckySeaUserDrawResultService.list(wrapper);
|
||||
List<LuckySeaUserDrawResult> results = userDrawResultService.list(wrapper);
|
||||
if (!CollectionUtils.isEmpty(results)) {
|
||||
for (LuckySeaUserDrawResult result : results) {
|
||||
result.setDrawTime(endTime);
|
||||
}
|
||||
luckySeaUserDrawResultService.updateBatchById(results);
|
||||
userDrawResultService.updateBatchById(results);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaActUserDrawItemVO> listUserDrawItemInfo(Long uid, String roundId) {
|
||||
List<LuckySeaActUserDrawItemVO> itemVOS = luckySeaActMapper.listUserDrawItemInfo(roundId, uid);
|
||||
return itemVOS;
|
||||
List<LuckySeaItem> singleItemList = luckySeaItemService.listSingleItem();
|
||||
|
||||
Map<Long, LuckySeaActUserDrawItemVO> voMap = singleItemList.stream().map(r->{
|
||||
LuckySeaActUserDrawItemVO vo = new LuckySeaActUserDrawItemVO();
|
||||
BeanUtils.copyProperties(r, vo);
|
||||
vo.setCostPieceNum(0);
|
||||
return vo;
|
||||
}).collect(Collectors.toMap(LuckySeaActUserDrawItemVO::getId, i->i));
|
||||
|
||||
List<LuckySeaActUserDrawItemVO> userDrawRecord = luckySeaActMapper.listUserDrawItemInfo(roundId, uid);
|
||||
if (!CollectionUtils.isEmpty(userDrawRecord)){
|
||||
for (LuckySeaActUserDrawItemVO record: userDrawRecord){
|
||||
LuckySeaActUserDrawItemVO vo = voMap.get(record.getId());
|
||||
vo.setCostPieceNum(record.getCostPieceNum());
|
||||
}
|
||||
}
|
||||
|
||||
return voMap.values().stream()
|
||||
.sorted(Comparator.comparing(LuckySeaActUserDrawItemVO::getMultiple))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -662,31 +612,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
log.info("春日游园活动,结束处理发生异常的活动, roundId:{}, 处理的投入列表statList:{}", roundId, JSON.toJSONString(statList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新的一轮游戏
|
||||
* @return
|
||||
* @param startTime
|
||||
* @param chooseStageConfigTime
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public String createNewRoundAct(Date startTime, Integer chooseStageConfigTime) {
|
||||
if (startTime == null) {
|
||||
startTime = new Date();
|
||||
}
|
||||
String roundId = DateTimeUtil.convertDate(startTime, DateTimeUtil.LUCKY_SEA_ACT_ROUND_PATTERN);
|
||||
LuckySeaActInfo act = new LuckySeaActInfo();
|
||||
act.setRoundId(roundId);
|
||||
act.setStartTime(startTime);
|
||||
act.setStatus(Constant.LuckySeaActStatus.CHOOSE_STAGE);
|
||||
act.setDrawStageStartTime(DateTimeUtil.addSeconds(startTime, chooseStageConfigTime));
|
||||
act.setCreateTime(new Date());
|
||||
act.setUpdateTime(new Date());
|
||||
luckySeaActInfoService.save(act);
|
||||
log.info("春日游园活动, 创建新的一轮游戏 roundId:{}, startTime:{}", roundId, startTime);
|
||||
return roundId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理开奖
|
||||
* @param statList
|
||||
@@ -731,8 +656,6 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
return drawId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param itemList
|
||||
@@ -751,15 +674,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
* @return
|
||||
*/
|
||||
private Double getLuckySeaActTicket() {
|
||||
String ticketStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_TICKET);
|
||||
if (StringUtils.isBlank(ticketStr)) {
|
||||
throw new ServiceException("配置的门票为空");
|
||||
}
|
||||
Double ticket = Double.valueOf(ticketStr);
|
||||
if (ticket >= 1) {
|
||||
throw new ServiceException("门票配置不能大于或等于1");
|
||||
}
|
||||
return ticket;
|
||||
return configService.getLuckySeaActTicket();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,59 +692,7 @@ public class ActivitiesLuckySeaServiceImpl implements ActivitiesLuckySeaService
|
||||
*/
|
||||
@Override
|
||||
public Long getStock() {
|
||||
String stockStr = jedisService.get(RedisKey.LUCKY_SEA_ACT_STOCK.getKey());
|
||||
if (StringUtils.isBlank(stockStr)) {
|
||||
stockStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_STOCK);
|
||||
jedisService.set(RedisKey.LUCKY_SEA_ACT_STOCK.getKey(), String.valueOf((Long.valueOf(stockStr)*HANDLE_STOCK_MULTIPLE)));
|
||||
}
|
||||
return Long.valueOf(stockStr);
|
||||
return luckySeaActInfoService.getStock();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验抽奖参数
|
||||
* @param param
|
||||
* @param uid
|
||||
*/
|
||||
private Long checkDrawParam(LuckySeaActDrawParams param, Long uid) {
|
||||
if (null == param) {
|
||||
throw new ServiceException("至少需要选中一项");
|
||||
}
|
||||
if (param.getItemId() == null) {
|
||||
throw new ServiceException("itemId不能为空");
|
||||
}
|
||||
if (param.getNum() <= 0) {
|
||||
throw new ServiceException("选择数量需要大于0");
|
||||
}
|
||||
LuckySeaItem item = luckySeaItemService.getById(param.getItemId());
|
||||
if (null == item || !item.getStatus().equals(Constant.status.valid)) {
|
||||
log.error("选择的配置不存在, itemId:" + param.getItemId());
|
||||
throw new ServiceException("选择的配置不存在");
|
||||
}
|
||||
// 扣减用户钻石
|
||||
// log.info("【春日游园活动】 uid {} 消耗钻石总数 {}", uid, costPieceTotal);
|
||||
// userPurseService.subDiamond(uid, (double)costPieceTotal, Constant.BusinessType.LUCKY_SEA_DRAW);
|
||||
return param.getNum();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理抽奖结果返回
|
||||
* @param resultJson
|
||||
* @return
|
||||
*/
|
||||
private List<LuckySeaUserDrawResultVo> handleDrawResult(String resultJson) {
|
||||
List<LuckySeaUserDrawResultVo> results = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(resultJson)) {
|
||||
List<LuckySeaUserDrawResultDto> dtoList = JSON.parseArray(resultJson, LuckySeaUserDrawResultDto.class);
|
||||
for (LuckySeaUserDrawResultDto dto : dtoList) {
|
||||
LuckySeaUserDrawResultVo vo = new LuckySeaUserDrawResultVo();
|
||||
LuckySeaItem item = luckySeaItemService.getById(dto.getItemId());
|
||||
vo.setItemUrl(item != null ? item.getImgUrl() : null);
|
||||
vo.setCostPiece(dto.getCostNum());
|
||||
vo.setItemId(dto.getItemId());
|
||||
vo.setMultiple(dto.getMultiple());
|
||||
results.add(vo);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaActConfigService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaActConfigServiceImpl implements LuckySeaActConfigService {
|
||||
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
|
||||
/**
|
||||
* 选择阶段默认时间(秒)
|
||||
*/
|
||||
private final static Integer DEFAULT_CHOOSE_STAGE_TIME = 30;
|
||||
/**
|
||||
* 开奖阶段默认时间(秒)
|
||||
*/
|
||||
private final static Integer DEFAULT_WAITING_DRAW_STAGE_TIME = 5;
|
||||
/**
|
||||
* 开奖结束阶段默认时间(秒)
|
||||
*/
|
||||
private final static Integer DEFAULT_DRAW_OVER_STAGE_TIME = 3;
|
||||
private final static Integer DEFAULT_MODE = 1;
|
||||
|
||||
@Override
|
||||
public LuckySeaActConfig getLuckySeaTimeConfig() {
|
||||
String luckySeaConfigStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_TIME_CONFIG);
|
||||
if (StringUtils.isNoneBlank(luckySeaConfigStr)) {
|
||||
return JSON.parseObject(luckySeaConfigStr, LuckySeaActConfig.class);
|
||||
}
|
||||
|
||||
LuckySeaActConfig config = new LuckySeaActConfig();
|
||||
config.setChooseStageTime(DEFAULT_CHOOSE_STAGE_TIME);
|
||||
config.setWaitingDrawStageTime(DEFAULT_WAITING_DRAW_STAGE_TIME);
|
||||
config.setDrawOverStageTime(DEFAULT_DRAW_OVER_STAGE_TIME);
|
||||
config.setModelType(DEFAULT_MODE);
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getLuckySeaActTicket() {
|
||||
String ticketStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_TICKET);
|
||||
if (StringUtils.isBlank(ticketStr)) {
|
||||
throw new ServiceException("配置的门票为空");
|
||||
}
|
||||
Double ticket = Double.valueOf(ticketStr);
|
||||
if (ticket >= 1d) {
|
||||
throw new ServiceException("门票配置不能大于或等于1");
|
||||
}
|
||||
return ticket;
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaActInfoMapper;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaActInfoService;
|
||||
import com.accompany.business.vo.activities.LuckySeaActInfoVo;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.DateTimeUtil;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaActInfoServiceImpl extends ServiceImpl<LuckySeaActInfoMapper, LuckySeaActInfo> implements LuckySeaActInfoService {
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
|
||||
private final static Integer CACHE_EXPIRE_SECOND = 3;
|
||||
|
||||
/**
|
||||
* 处理库存时需要换算的倍数
|
||||
*/
|
||||
public final static Integer HANDLE_STOCK_MULTIPLE = 100000;
|
||||
|
||||
@Override
|
||||
public Long getStock() {
|
||||
RBucket<String> stockRBucket = redissonClient.getBucket(RedisKey.LUCKY_SEA_ACT_STOCK.getKey());
|
||||
if (stockRBucket.isExists()) {
|
||||
return Long.valueOf(stockRBucket.get());
|
||||
}
|
||||
String stockStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_STOCK);
|
||||
Long stock = Long.parseLong(stockStr) * HANDLE_STOCK_MULTIPLE;
|
||||
stockRBucket.set(String.valueOf(stock));
|
||||
return stock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckySeaActInfo createNeewRoundAct(Date startTime, Integer chooseStageConfigTime) {
|
||||
Date now = new Date();
|
||||
if (startTime == null) {
|
||||
startTime = now;
|
||||
}
|
||||
String roundId = DateTimeUtil.convertDate(startTime, DateTimeUtil.LUCKY_SEA_ACT_ROUND_PATTERN);
|
||||
LuckySeaActInfo act = new LuckySeaActInfo();
|
||||
act.setRoundId(roundId);
|
||||
act.setStartTime(startTime);
|
||||
act.setStatus(Constant.LuckySeaActStatus.CHOOSE_STAGE);
|
||||
act.setDrawStageStartTime(DateTimeUtil.addSeconds(startTime, chooseStageConfigTime));
|
||||
act.setCreateTime(now);
|
||||
act.setUpdateTime(now);
|
||||
if (!save(act)){
|
||||
log.error("春日游园活动, 保存新的一轮游戏失败 roundId:{}, startTime:{}", roundId, startTime);
|
||||
throw new ServiceException(BusiStatus.SERVERERROR);
|
||||
}
|
||||
log.info("春日游园活动, 创建新的一轮游戏 roundId:{}, startTime:{}", roundId, startTime);
|
||||
return act;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckySeaActInfo getByCurrTime() {
|
||||
QueryWrapper<LuckySeaActInfo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().orderByDesc(LuckySeaActInfo::getRoundId)
|
||||
.last("limit 1");
|
||||
return getOne(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaActInfo> listActInfo(String roundId, Integer count) {
|
||||
String cacheKey = RedisKey.lucky_sea_act_info.getKey(String.valueOf(count), roundId);
|
||||
RBucket<String> cacheVal = redissonClient.getBucket(cacheKey);
|
||||
if (cacheVal.isExists()){
|
||||
return JSON.parseArray(cacheVal.get(), LuckySeaActInfo.class);
|
||||
}
|
||||
|
||||
QueryWrapper<LuckySeaActInfo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda()
|
||||
.lt(LuckySeaActInfo::getRoundId, roundId)
|
||||
.eq(LuckySeaActInfo::getStatus, Constant.LuckySeaActStatus.DRAW_OVER)
|
||||
.orderByDesc(LuckySeaActInfo::getRoundId);
|
||||
wrapper.last(String.format("limit %d", count));
|
||||
List<LuckySeaActInfo> actList = list(wrapper);
|
||||
cacheVal.set(JSON.toJSONString(actList), CACHE_EXPIRE_SECOND, TimeUnit.SECONDS);
|
||||
return actList;
|
||||
}
|
||||
}
|
@@ -0,0 +1,217 @@
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.service.LuckySeaPreWarningService;
|
||||
import com.accompany.business.service.activities.luckySea.*;
|
||||
import com.accompany.business.service.purse.UserPurseService;
|
||||
import com.accompany.business.service.record.BillRecordService;
|
||||
import com.accompany.business.service.room.UserInOutRoomRecordService;
|
||||
import com.accompany.business.vo.activities.LuckySeaActInfoVo;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.enumeration.BillObjTypeEnum;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RAtomicLong;
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaDrawServiceImpl implements LuckySeaDrawService {
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private LuckySeaActConfigService configService;
|
||||
@Autowired
|
||||
private LuckySeaActInfoService actInfoService;
|
||||
@Autowired
|
||||
private LuckySeaItemService itemService;
|
||||
@Autowired
|
||||
private LuckySeaUserDrawRecordService drawRecordService;
|
||||
@Autowired
|
||||
private UserPurseService userPurseService;
|
||||
@Autowired
|
||||
private BillRecordService billRecordService;
|
||||
@Autowired
|
||||
private UserInOutRoomRecordService userInOutRoomRecordService;
|
||||
|
||||
@Autowired
|
||||
private ActivitiesLuckySeaService activitiesLuckySeaService;
|
||||
@Autowired
|
||||
private LuckySeaPreWarningService luckySeaPreWarningService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void draw(Long uid, Long itemId, Long num) {
|
||||
String roundId = null;
|
||||
boolean locked = false;
|
||||
RLock lock = redissonClient.getLock(RedisKey.LOCK_LUCKY_SEA_USER_DRAW.getKey(uid.toString()));
|
||||
try {
|
||||
locked = lock.tryLock(5L, TimeUnit.SECONDS);
|
||||
if (!locked) {
|
||||
log.error("[春日游园] 获取分布式锁失败,uid:{}", uid);
|
||||
throw new ServiceException(BusiStatus.JOIN_GAME_USER_TOO_MORE);
|
||||
}
|
||||
|
||||
LuckySeaItem item = itemService.getItemById(itemId);
|
||||
if (null == item || !item.getStatus().equals(Constant.status.valid)) {
|
||||
log.error("选择的配置不存在, itemId:" + item);
|
||||
throw new ServiceException("選擇的配置不存在");
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
LuckySeaActInfo actInfo = actInfoService.getByCurrTime();
|
||||
if (actInfo == null || !Constant.LuckySeaActStatus.CHOOSE_STAGE.equals(actInfo.getStatus())
|
||||
|| now.compareTo(actInfo.getDrawStageStartTime()) >= 0) {
|
||||
log.error("选择失败,当前时段不存在活动。actInfo:" + JSON.toJSONString(actInfo));
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
}
|
||||
|
||||
// 扣减用户钻石
|
||||
if (!userPurseService.subDiamond(uid, num.doubleValue(), Constant.BusinessType.LUCKY_SEA_DRAW)) {
|
||||
throw new ServiceException(BusiStatus.DIAMONDNUMNOTENOUGH);
|
||||
}
|
||||
log.info("[春日游园] uid {} 消耗钻石总数 {}", uid, num);
|
||||
|
||||
RAtomicLong atomic = redissonClient.getAtomicLong(RedisKey.lucky_sea_curr_write_data_user_count.getKey(actInfo.getRoundId()));
|
||||
atomic.incrementAndGet();
|
||||
roundId = actInfo.getRoundId();
|
||||
|
||||
Long roomUid = userInOutRoomRecordService.getUserCurrentRoomUid(uid);
|
||||
if (!drawRecordService.updateUserDrawRecord(uid, roomUid, roundId, item, num)){
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
}
|
||||
|
||||
billRecordService.insertGeneralBillRecord(uid, null, null, BillObjTypeEnum.ACTIVITY_LUCKY_SEA_DRAW, num.doubleValue());
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
} finally {
|
||||
if (StringUtils.isNoneBlank(roundId)){
|
||||
RAtomicLong atomic = redissonClient.getAtomicLong(RedisKey.lucky_sea_curr_write_data_user_count.getKey(roundId));
|
||||
atomic.decrementAndGet();
|
||||
}
|
||||
if (locked){
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
String roundId = null;
|
||||
Date nextRoundStartTime = null;
|
||||
Long stock = actInfoService.getStock();
|
||||
// 获取游戏的配置
|
||||
List<LuckySeaItem> itemList = itemService.listSingleItem();
|
||||
LuckySeaActConfig timeConfig = configService.getLuckySeaTimeConfig();
|
||||
int totalTime = timeConfig.getWaitingDrawStageTime() + timeConfig.getChooseStageTime() + timeConfig.getDrawOverStageTime();
|
||||
|
||||
// 加锁,确保创建与开奖是单线程执行
|
||||
boolean locked = false;
|
||||
RLock lock = redissonClient.getLock(RedisKey.lucky_sea_run_task.getKey());
|
||||
try {
|
||||
locked = lock.tryLock(10, totalTime, TimeUnit.SECONDS);
|
||||
if (!locked){
|
||||
log.error("春日游园活动, 获取锁失败");
|
||||
throw new ServiceException(BusiStatus.SERVER_BUSY);
|
||||
}
|
||||
|
||||
long drawMills = 0L;
|
||||
boolean needCreateNewAct = true;
|
||||
boolean needWaitUserDraw = true;
|
||||
Integer waitUserDrawTime = timeConfig.getChooseStageTime();
|
||||
|
||||
// 处理异常活动
|
||||
LuckySeaActInfo lastLuckySeaActInfo = actInfoService.getByCurrTime();
|
||||
// 处理上轮游戏
|
||||
if (null != lastLuckySeaActInfo && StringUtils.isNotBlank(lastLuckySeaActInfo.getRoundId())) {
|
||||
roundId = lastLuckySeaActInfo.getRoundId();
|
||||
if (Constant.LuckySeaActStatus.CHOOSE_STAGE.equals(lastLuckySeaActInfo.getStatus())){
|
||||
needCreateNewAct = false;
|
||||
Long intervalSecond = (System.currentTimeMillis() - lastLuckySeaActInfo.getStartTime().getTime()) / 1000;
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动到现在的间隔时间{}秒, roundId:{}", intervalSecond, roundId);
|
||||
if (intervalSecond <= timeConfig.getChooseStageTime()) {
|
||||
waitUserDrawTime = timeConfig.getChooseStageTime() - intervalSecond.intValue();
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动留给用户的下注时间{}秒", waitUserDrawTime);
|
||||
} else {
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
|
||||
needWaitUserDraw = false;
|
||||
}
|
||||
} else if (Constant.LuckySeaActStatus.DRAWING.equals(lastLuckySeaActInfo.getStatus())){
|
||||
needCreateNewAct = false;
|
||||
needWaitUserDraw = false;
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
|
||||
}
|
||||
}
|
||||
// 创建新的一轮游戏
|
||||
if (needCreateNewAct) {
|
||||
lastLuckySeaActInfo = actInfoService.createNeewRoundAct(nextRoundStartTime, timeConfig.getChooseStageTime());
|
||||
roundId = lastLuckySeaActInfo.getRoundId();
|
||||
}
|
||||
// 等待用户投碎片
|
||||
if (needWaitUserDraw) {
|
||||
log.info("春日游园活动, 开始等待用户投入碎片, currTime: {}", System.currentTimeMillis());
|
||||
Thread.sleep(waitUserDrawTime * 1000);
|
||||
log.info("春日游园活动, 结束等待用户投入碎片, currTime: {}", System.currentTimeMillis());
|
||||
}
|
||||
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.DRAWING);
|
||||
// 开奖
|
||||
drawMills = activitiesLuckySeaService.luckySeaActDraw(itemList, roundId, timeConfig, stock);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (locked){
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
} catch (Exception e) {
|
||||
// 更新活动状态, 此轮游戏标识为异常,不开始下一轮游戏
|
||||
log.error("春日游园活动开奖时出现异常, roundId: " + roundId, e);
|
||||
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.GAME_ABNORMAL);
|
||||
activitiesLuckySeaService.compensateUserPieceWhenGameAbnormal(roundId, stock);
|
||||
break;
|
||||
} finally {
|
||||
jedisLockService.unlock(RedisKey.lucky_sea_run_task.getKey(), lockVal);
|
||||
}
|
||||
try {
|
||||
// 异步更新用户抽奖记录
|
||||
activitiesLuckySeaService.updateUserDrawRecordAsync(roundId, itemList);
|
||||
// 等待开奖动画与页面渲染开奖结果时间
|
||||
long sleepMills = (timeConfig.getDrawOverStageTime() + timeConfig.getWaitingDrawStageTime()) * 1000
|
||||
- drawMills;
|
||||
if (sleepMills > 0) {
|
||||
log.info("春日游园活动, 等待开奖动画与页面渲染开奖结果时间{}毫秒", sleepMills);
|
||||
Thread.sleep(sleepMills);
|
||||
}
|
||||
log.info("春日游园活动此轮结束, roundId:{}", roundId);
|
||||
// 异步更新活动endTime
|
||||
nextRoundStartTime = new Date();
|
||||
activitiesLuckySeaService.endLuckyAct(roundId, nextRoundStartTime);
|
||||
// 进行预警数据统计
|
||||
luckySeaPreWarningService.handleGoldPreWarning();
|
||||
} catch (Exception e) {
|
||||
// 更新活动状态
|
||||
log.error("春日游园活动更新用户抽奖记录与分发奖励时出现异常, roundId: " + roundId, e);
|
||||
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.SUCCESS_DRAW_UPDATE_DATA_FAIL);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaItemServiceImpl
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/31
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaItemMapper;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaItemService;
|
||||
import com.accompany.business.util.SpringContextHolder;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RList;
|
||||
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.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2020/12/31]
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaItemServiceImpl extends ServiceImpl<LuckySeaItemMapper, LuckySeaItem> implements LuckySeaItemService, InitializingBean {
|
||||
|
||||
private RMap<Long, LuckySeaItem> cacheMap;
|
||||
private final static Integer CACHE_EXPIRE_SECOND = 3;
|
||||
|
||||
@Override
|
||||
public LuckySeaItem getItemById(Long itemId) {
|
||||
LuckySeaItem item = cacheMap.get(itemId);
|
||||
if (null != item){
|
||||
return item;
|
||||
}
|
||||
|
||||
List<LuckySeaItem> dbList = listSingleItemByDB();
|
||||
if (CollectionUtils.isEmpty(dbList)){
|
||||
return item;
|
||||
}
|
||||
|
||||
Optional<LuckySeaItem> optional = dbList.stream().filter(e->itemId.equals(e.getId())).findAny();
|
||||
if (optional.isPresent()){
|
||||
item = optional.get();
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LuckySeaItem> listSingleItem() {
|
||||
Collection<LuckySeaItem> cacheList = cacheMap.values();
|
||||
if (!CollectionUtils.isEmpty(cacheList)){
|
||||
return cacheList.stream()
|
||||
.sorted(Comparator.comparing(LuckySeaItem::getMultiple))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return listSingleItemByDB();
|
||||
}
|
||||
|
||||
private List<LuckySeaItem> listSingleItemByDB() {
|
||||
QueryWrapper<LuckySeaItem> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(LuckySeaItem::getStatus, Constant.status.valid)
|
||||
.orderByAsc(LuckySeaItem::getMultiple);
|
||||
List<LuckySeaItem> itemList = list(wrapper);
|
||||
cacheMap.putAll(itemList.stream().collect(Collectors.toMap(LuckySeaItem::getId, e->e)));
|
||||
cacheMap.expire(CACHE_EXPIRE_SECOND, TimeUnit.SECONDS);
|
||||
return itemList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
cacheMap = SpringContextHolder.getBean(RedissonClient.class).getMap(RedisKey.lucky_sea_item.getKey());
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package com.accompany.business.service.activities.impl;
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaRoomTipConfig;
|
||||
import com.accompany.business.model.activity.LuckySeaUserDrawRecord;
|
@@ -0,0 +1,77 @@
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaActMapper;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaRankService;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankListVo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
import com.accompany.business.service.user.UsersService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.utils.DateTimeUtil;
|
||||
import com.accompany.core.model.Users;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LuckySeaRankServiceImpl implements LuckySeaRankService {
|
||||
|
||||
@Autowired
|
||||
private UsersService usersService;
|
||||
@Autowired
|
||||
private LuckySeaActMapper luckySeaActMapper;
|
||||
|
||||
@Override
|
||||
public LuckySeaRankVo listRank(Integer type, Integer page, Integer pageSize, Long uid) {
|
||||
LuckySeaRankVo vo = new LuckySeaRankVo();
|
||||
List<LuckySeaRankListVo> rankList = null;
|
||||
LuckySeaRankListVo userRankInfo = null;
|
||||
|
||||
Date now = new Date();
|
||||
Date beginTimeOfDay = DateTimeUtil.getBeginTimeOfDay(now);
|
||||
Date endTimeOfDay = DateTimeUtil.getEndTimeOfDay(now);
|
||||
|
||||
int start = (page - 1) * pageSize;
|
||||
if (type.equals(Constant.LuckySeaRankType.DIAMOND_RANK)) {
|
||||
rankList = luckySeaActMapper.listDiamondRank(start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
userRankInfo = luckySeaActMapper.listUserDiamondRank(uid, beginTimeOfDay, endTimeOfDay);
|
||||
} else if (type.equals(Constant.LuckySeaRankType.LUCKY_MAN_RANK)) {
|
||||
rankList = luckySeaActMapper.listLuckyManRank(start, pageSize, beginTimeOfDay, endTimeOfDay);
|
||||
userRankInfo = luckySeaActMapper.listUserLuckyManRank(uid, beginTimeOfDay, endTimeOfDay);
|
||||
}
|
||||
|
||||
if (null == rankList){
|
||||
rankList = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (null == userRankInfo){
|
||||
userRankInfo = new LuckySeaRankListVo();
|
||||
userRankInfo.setUid(uid);
|
||||
}
|
||||
|
||||
vo.setRankList(rankList);
|
||||
vo.setMyRankInfo(userRankInfo);
|
||||
|
||||
List<LuckySeaRankListVo> all = new ArrayList<>(rankList);
|
||||
all.add(userRankInfo);
|
||||
List<Long> uids = all.stream().map(LuckySeaRankListVo::getUid).distinct().collect(Collectors.toList());
|
||||
Map<Long, Users> usersMap = usersService.getUsersMapByUids(uids);
|
||||
for (LuckySeaRankListVo e: all){
|
||||
Users u = usersMap.get(e.getUid());
|
||||
if (null == u){
|
||||
continue;
|
||||
}
|
||||
e.setErbanNo(u.getErbanNo());
|
||||
e.setNick(u.getNick());
|
||||
e.setAvatar(u.getAvatar());
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.model.activity.LuckySeaUserDrawRecord;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaUserDrawRecordMapper;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaUserDrawRecordService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/1/4]
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Slf4j
|
||||
public class LuckySeaUserDrawRecordServiceImpl extends ServiceImpl<LuckySeaUserDrawRecordMapper, LuckySeaUserDrawRecord>
|
||||
implements LuckySeaUserDrawRecordService {
|
||||
|
||||
@Override
|
||||
public boolean updateUserDrawRecord(Long uid, Long roomUid, String roundId, LuckySeaItem item, Long costPieceNum) {
|
||||
Date now = new Date();
|
||||
Long itemId = item.getId();
|
||||
boolean succeed = false;
|
||||
|
||||
QueryWrapper<LuckySeaUserDrawRecord> wrapper = Wrappers.query();
|
||||
wrapper.lambda().eq(LuckySeaUserDrawRecord::getUid, uid).eq(LuckySeaUserDrawRecord::getRoundId, roundId)
|
||||
.eq(LuckySeaUserDrawRecord::getItemId, itemId);
|
||||
LuckySeaUserDrawRecord record = getOne(wrapper);
|
||||
log.info("更新用户单轮消耗碎片数操作前, uid:{},roundId:{},itemId:{},costPiece:{}",
|
||||
uid, roundId, itemId, record == null ? 0 : record.getCostPriceNum());
|
||||
if (record == null) {
|
||||
record = new LuckySeaUserDrawRecord();
|
||||
record.setUid(uid);
|
||||
record.setRoomUid(roomUid);
|
||||
record.setRoundId(roundId);
|
||||
record.setItemId(itemId);
|
||||
record.setItemName(item.getName());
|
||||
record.setItemUrl(item.getImgUrl());
|
||||
record.setItemMultiple(item.getMultiple());
|
||||
record.setCostPriceNum(costPieceNum);
|
||||
record.setDrawStatus(Constant.LuckySeaUserStatus.NOT_WIN);
|
||||
record.setCreateTime(now);
|
||||
record.setUpdateTime(now);
|
||||
succeed = save(record);
|
||||
} else {
|
||||
UpdateWrapper<LuckySeaUserDrawRecord> updateWrapper = Wrappers.update();
|
||||
updateWrapper.lambda().eq(LuckySeaUserDrawRecord::getId, record.getId())
|
||||
.eq(LuckySeaUserDrawRecord::getDrawStatus, Constant.LuckySeaUserStatus.NOT_WIN)
|
||||
.set(LuckySeaUserDrawRecord::getRoomUid, roomUid)
|
||||
.set(LuckySeaUserDrawRecord::getCostPriceNum, record.getCostPriceNum() + costPieceNum)
|
||||
.set(LuckySeaUserDrawRecord::getUpdateTime, now);
|
||||
succeed = update(updateWrapper);
|
||||
}
|
||||
log.info("更新用户单轮消耗碎片数操作后, succeed:{},uid:{},roomUid:{},roundId:{},itemId:{},costPiece:{}",
|
||||
succeed, uid, roomUid, roundId, itemId,
|
||||
succeed? record.getCostPriceNum() + costPieceNum: record.getCostPriceNum());
|
||||
|
||||
return succeed;
|
||||
}
|
||||
}
|
@@ -8,13 +8,12 @@
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.service.activities.impl;
|
||||
package com.accompany.business.service.activities.luckySea.impl;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaUserDrawResult;
|
||||
import com.accompany.business.mybatismapper.activity.LuckySeaUserDrawResultMapper;
|
||||
import com.accompany.business.service.activities.LuckySeaUserDrawResultService;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaUserDrawResultService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@@ -11,7 +11,7 @@ import com.accompany.business.mybatismapper.UserActivityPackRecordMapper;
|
||||
import com.accompany.business.param.neteasepush.NeteaseSendMsgParam;
|
||||
import com.accompany.business.service.SendSysMsgService;
|
||||
import com.accompany.business.service.activities.ActivitiesDrawService;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.luckySea.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.box.BoxPrizeContext;
|
||||
import com.accompany.business.service.box.BoxPrizeStrategyFactory;
|
||||
import com.accompany.business.service.purse.UserPurseService;
|
||||
|
@@ -1,13 +1,3 @@
|
||||
/*
|
||||
* 文 件 名: LuckySeaActUserDrawItemVO
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/1/12
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.vo.activities;
|
||||
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
@@ -24,8 +14,21 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
@ApiModel
|
||||
public class LuckySeaActUserDrawItemVO extends LuckySeaItem {
|
||||
public class LuckySeaActUserDrawItemVO {
|
||||
|
||||
@ApiModelProperty("id")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("图片")
|
||||
private String imgUrl;
|
||||
|
||||
@ApiModelProperty("倍数")
|
||||
private Integer multiple;
|
||||
|
||||
@ApiModelProperty(value = "用户此轮投的碎片数")
|
||||
private Integer costPieceNum;
|
||||
|
||||
}
|
||||
|
@@ -18,87 +18,80 @@
|
||||
</resultMap>
|
||||
|
||||
<select id="listDiamondRank" resultMap="luckySeaRankListVo">
|
||||
select u.uid, u.avatar, u.erban_no, u.nick,
|
||||
IFNULL(SUM(cost_piece_num * item_multiple),0) num
|
||||
from lucky_sea_user_draw_record d, users u, lucky_sea_act_info a
|
||||
where draw_status = 1 and d.uid = u.uid and d.round_id = a.round_id
|
||||
select uid, SUM(cost_piece_num * item_multiple) num
|
||||
from lucky_sea_user_draw_record
|
||||
where draw_status = 1
|
||||
<if test="null != startTime">
|
||||
and a.end_time >= #{startTime}
|
||||
and update_time >= #{startTime}
|
||||
</if>
|
||||
<if test="null != endTime">
|
||||
and a.end_time <= #{endTime}
|
||||
and update_time <= #{endTime}
|
||||
</if>
|
||||
group by d.uid
|
||||
order BY num desc
|
||||
group by uid
|
||||
order by num desc
|
||||
limit #{start}, #{pageSize}
|
||||
</select>
|
||||
|
||||
<select id="listLuckyManRank" resultMap="luckySeaRankListVo">
|
||||
select u.uid, u.avatar, u.erban_no, u.nick, count(1) num
|
||||
from lucky_sea_user_draw_record d, users u, lucky_sea_act_info a
|
||||
where draw_status = 1 and d.uid = u.uid and d.round_id = a.round_id
|
||||
<select id="listUserDiamondRank" resultMap="luckySeaRankListVo">
|
||||
select uid, SUM(cost_piece_num * item_multiple) num
|
||||
from lucky_sea_user_draw_record
|
||||
where uid = #{uid}
|
||||
and draw_status = 1
|
||||
<if test="null != startTime">
|
||||
and a.end_time >= #{startTime}
|
||||
and update_time >= #{startTime}
|
||||
</if>
|
||||
<if test="null != endTime">
|
||||
and a.end_time <= #{endTime}
|
||||
and update_time <= #{endTime}
|
||||
</if>
|
||||
group by d.uid
|
||||
group by uid
|
||||
</select>
|
||||
|
||||
<select id="listLuckyManRank" resultMap="luckySeaRankListVo">
|
||||
select uid, count(distinct round_id) num
|
||||
from lucky_sea_user_draw_record
|
||||
where draw_status = 1
|
||||
<if test="null != startTime">
|
||||
and update_time >= #{startTime}
|
||||
</if>
|
||||
<if test="null != endTime">
|
||||
and update_time <= #{endTime}
|
||||
</if>
|
||||
group by uid
|
||||
order by num desc
|
||||
limit #{start}, #{pageSize}
|
||||
</select>
|
||||
|
||||
|
||||
<select id="listUserDiamondRank" resultMap="luckySeaRankListVo">
|
||||
SELECT u.uid, u.avatar, u.erban_no, u.nick, IFNULL(t.num, 0) num
|
||||
FROM users u
|
||||
LEFT JOIN
|
||||
(SELECT r.uid, IFNULL(SUM(r.cost_piece_num * r.item_multiple),0) num FROM
|
||||
lucky_sea_user_draw_record r LEFT JOIN lucky_sea_act_info a ON r.round_id = a.round_id
|
||||
WHERE r.draw_status = 1
|
||||
<if test="null != startTime">
|
||||
and a.end_time >= #{startTime}
|
||||
</if>
|
||||
<if test="null != endTime">
|
||||
and a.end_time <= #{endTime}
|
||||
</if>
|
||||
GROUP BY r.uid) t ON u.uid = t.uid
|
||||
WHERE u.uid = #{uid}
|
||||
</select>
|
||||
|
||||
<select id="listUserLuckyManRank" resultMap="luckySeaRankListVo">
|
||||
SELECT u.uid, u.avatar, u.erban_no, u.nick, IFNULL(t.num, 0) num
|
||||
FROM users u
|
||||
LEFT JOIN
|
||||
(SELECT r.uid, count(1) num FROM
|
||||
lucky_sea_user_draw_record r LEFT JOIN lucky_sea_act_info a ON r.round_id = a.round_id
|
||||
WHERE r.draw_status = 1
|
||||
select uid, count(distinct round_id) num
|
||||
from lucky_sea_user_draw_record
|
||||
where uid = #{uid}
|
||||
and draw_status = 1
|
||||
<if test="null != startTime">
|
||||
and a.end_time >= #{startTime}
|
||||
and update_time >= #{startTime}
|
||||
</if>
|
||||
<if test="null != endTime">
|
||||
and a.end_time <= #{endTime}
|
||||
and update_time <= #{endTime}
|
||||
</if>
|
||||
GROUP BY r.uid) t ON u.uid = t.uid
|
||||
WHERE u.uid = #{uid}
|
||||
group by uid
|
||||
</select>
|
||||
|
||||
<select id="countUserDiamondIncome" resultType="java.lang.Double">
|
||||
SELECT IFNULL(SUM(d.cost_piece_num * d.item_multiple),0)
|
||||
FROM `lucky_sea_user_draw_record` d , lucky_sea_act_info a where d.uid = #{uid} and d.draw_status = 1
|
||||
and d.round_id = a.round_id
|
||||
and DATE(a.end_time) >= #{startTime}
|
||||
and DATE(a.end_time) < #{endTime}
|
||||
FROM `lucky_sea_user_draw_record` d
|
||||
where d.uid = #{uid}
|
||||
and d.create_time >= #{startTime}
|
||||
and d.create_time <= #{endTime}
|
||||
and d.draw_status = 1
|
||||
</select>
|
||||
|
||||
<select id="listTopThreeInOneRound" resultMap="luckySeaActRoundRankUserVo">
|
||||
SELECT u.uid, u.erban_no erbanNo, u.nick, u.avatar, d.cost_piece_num * d.item_multiple prizeDiamonds
|
||||
FROM `lucky_sea_user_draw_record` d, users u
|
||||
where d.round_id = #{roundId}
|
||||
and d.draw_status = 1
|
||||
and d.uid = u.uid
|
||||
ORDER BY d.cost_piece_num DESC, d.uid ASC
|
||||
LIMIT 3
|
||||
SELECT uid, cost_piece_num * item_multiple prizeDiamonds
|
||||
FROM `lucky_sea_user_draw_record`
|
||||
where round_id = #{roundId}
|
||||
and draw_status = 1
|
||||
group by uid
|
||||
ORDER BY cost_piece_num DESC, uid ASC
|
||||
LIMIT 3
|
||||
</select>
|
||||
|
||||
<select id="countUserInputPiece" resultType="java.lang.Long">
|
||||
@@ -127,25 +120,16 @@
|
||||
</update>
|
||||
|
||||
<resultMap id="luckySeaActUserDrawItemVO" type="com.accompany.business.vo.activities.LuckySeaActUserDrawItemVO">
|
||||
<result column="id" property="id" jdbcType="BIGINT"/>
|
||||
<result column="name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="image_url" property="imgUrl" jdbcType="VARCHAR"/>
|
||||
<result column="multiple" property="multiple" jdbcType="INTEGER"/>
|
||||
<result column="costPieceNum" property="costPieceNum" jdbcType="INTEGER"/>
|
||||
<result column="item_id" property="id" jdbcType="BIGINT"/>
|
||||
<result column="cost_piece_num" property="costPieceNum" jdbcType="INTEGER"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="listUserDrawItemInfo" resultMap="luckySeaActUserDrawItemVO">
|
||||
SELECT i.id, i.name,i.image_url,i.multiple,
|
||||
IFNULL(r.cost_piece_num,0) costPieceNum
|
||||
from lucky_sea_item i LEFT JOIN
|
||||
lucky_sea_user_draw_record r ON i.id = r.item_id
|
||||
AND r.round_id = #{roundId}
|
||||
and r.uid = #{uid}
|
||||
WHERE i.status = 1
|
||||
ORDER BY i.multiple ASC;
|
||||
SELECT r.item_id, r.cost_piece_num,
|
||||
from lucky_sea_user_draw_record r
|
||||
where r.round_id = #{roundId} and r.uid = #{uid}
|
||||
</select>
|
||||
|
||||
|
||||
<resultMap id="luckySeaActUserRoundStatDTO" type="com.accompany.business.dto.LuckySeaActUserRoundStatDTO">
|
||||
<result column="uid" property="uid" jdbcType="BIGINT"/>
|
||||
<result column="costPieceNum" property="costPieceNum" jdbcType="BIGINT"/>
|
||||
|
@@ -1,29 +1,22 @@
|
||||
/*
|
||||
* 文 件 名: ActivitiesLuckySeaController
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2020/12/30
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.business.controller.activities;
|
||||
|
||||
import com.accompany.business.common.BaseController;
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.constant.activities.ActivitesPackTypeEnum;
|
||||
import com.accompany.business.model.ActivityPack;
|
||||
import com.accompany.business.model.activity.LuckySeaActInfo;
|
||||
import com.accompany.business.param.activity.LuckySeaActDrawParams;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.luckySea.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserDrawRecordVo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaActUserInfo;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
import com.accompany.business.service.activity.ActivityPackService;
|
||||
import com.accompany.business.vo.activities.LuckySeaActInfoVo;
|
||||
import com.accompany.business.vo.activities.LuckySeaActUserDrawItemVO;
|
||||
import com.accompany.common.annotation.Authorization;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.enumeration.BusinessStatusCodeEnum;
|
||||
import com.accompany.core.vo.BaseRequestVO;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.vo.BaseResponseVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@@ -31,11 +24,9 @@ import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -49,64 +40,81 @@ import java.util.List;
|
||||
@RequestMapping("/act/luckySea")
|
||||
@Slf4j
|
||||
@Api(tags = "深海奇缘活动")
|
||||
public class ActivitiesLuckySeaController {
|
||||
public class ActivitiesLuckySeaController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ActivityPackService activityPackService;
|
||||
@Autowired
|
||||
private ActivitiesLuckySeaService activitiesLuckySeaService;
|
||||
|
||||
@ApiOperation("获取游戏各阶段的时间配置")
|
||||
@GetMapping("/getTimeConfig")
|
||||
public BaseResponseVO<LuckySeaActConfig> getActTimeConfig() {
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.getLuckySeaTimeConfig());
|
||||
}
|
||||
|
||||
@ApiOperation("获取活动礼包列表")
|
||||
@RequestMapping(value = "/listPack", method = RequestMethod.GET)
|
||||
@GetMapping("/listPack")
|
||||
@Deprecated
|
||||
public BaseResponseVO<List<ActivityPack>> listPack() {
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activityPackService.getPackListByType(ActivitesPackTypeEnum.LUCKY_SEA.getValue().byteValue()));
|
||||
}
|
||||
|
||||
@ApiOperation(tags = "获取用户活动信息", value = "获取用户活动信息,包含用户基本信息,碎片数、钻石数与今日收益")
|
||||
@RequestMapping(value = "/getUserActInfo", method = RequestMethod.GET)
|
||||
public BaseResponseVO<LuckySeaActUserInfo> getUserLuckySeaActInfo() {
|
||||
BaseRequestVO baseRequestVO = new BaseRequestVO();
|
||||
Long myUserId = baseRequestVO.getMyUserId();
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.getUserLuckySeaActInfo(myUserId));
|
||||
}
|
||||
|
||||
@ApiOperation("获取活动配置列表")
|
||||
@RequestMapping(value = "/listItem", method = RequestMethod.GET)
|
||||
public BaseResponseVO<List<LuckySeaActUserDrawItemVO>> listItem(String roundId) {
|
||||
BaseRequestVO baseRequestVO = new BaseRequestVO();
|
||||
Long myUserId = baseRequestVO.getMyUserId();
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.listUserDrawItemInfo(myUserId, roundId));
|
||||
}
|
||||
|
||||
@ApiOperation("获取指定数量的中奖纪录")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "count", value = "需要获取的条数", required = false, dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "roundId", value = "当前进行轮的roundId", required = false, dataType = "String", paramType = "query"),
|
||||
})
|
||||
@RequestMapping(value = "/listLuckySeaActInfo", method = RequestMethod.GET)
|
||||
public BaseResponseVO<List<LuckySeaActInfo>> listLuckySeaActInfo(Integer count, String roundId) {
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.listLuckySeaActInfo(count, roundId));
|
||||
return new BaseResponseVO<>(activityPackService.getPackListByType(ActivitesPackTypeEnum.LUCKY_SEA.getValue().byteValue()));
|
||||
}
|
||||
|
||||
@ApiOperation("获取最新一次的深海奇缘活动信息")
|
||||
@RequestMapping(value = "/getNewestAct", method = RequestMethod.GET)
|
||||
public BaseResponseVO<LuckySeaActInfoVo> getNewestLuckySeaActInfo() {
|
||||
BaseRequestVO baseRequestVO = new BaseRequestVO();
|
||||
Long myUserId = baseRequestVO.getMyUserId();
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.getNewestLuckySeaActInfo(myUserId));
|
||||
@GetMapping("/getNewestAct")
|
||||
@Authorization
|
||||
public BaseResponseVO<LuckySeaActInfoVo> getNewestLuckySeaActInfo(HttpServletRequest request) {
|
||||
Long myUserId = getUid(request);
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.getNewestLuckySeaActInfo(myUserId));
|
||||
}
|
||||
|
||||
@ApiOperation(tags = "获取用户活动信息", value = "获取用户活动信息,包含用户基本信息,碎片数、钻石数与今日收益")
|
||||
@GetMapping("/getUserActInfo")
|
||||
@Authorization
|
||||
public BaseResponseVO<LuckySeaActUserInfo> getUserLuckySeaActInfo(HttpServletRequest request) {
|
||||
Long myUserId = getUid(request);
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.getUserLuckySeaActInfo(myUserId));
|
||||
}
|
||||
|
||||
@ApiOperation("获取活动配置列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "roundId", value = "当前进行轮的roundId"),
|
||||
})
|
||||
@GetMapping("/listItem")
|
||||
@Authorization
|
||||
public BaseResponseVO<List<LuckySeaActUserDrawItemVO>> listItem(HttpServletRequest request, String roundId) {
|
||||
Long myUserId = getUid(request);
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.listUserDrawItemInfo(myUserId, roundId));
|
||||
}
|
||||
|
||||
@ApiOperation("获取指定数量的中奖纪录,往轮结果")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "count", value = "需要获取的条数"),
|
||||
@ApiImplicitParam(name = "roundId", value = "当前进行轮的roundId"),
|
||||
})
|
||||
@GetMapping("/listLuckySeaActInfo")
|
||||
public BaseResponseVO<List<LuckySeaActInfo>> listLuckySeaActInfo(Integer count, String roundId) {
|
||||
if (null == count){
|
||||
throw new ServiceException(BusiStatus.PARAMERROR);
|
||||
}
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.listLuckySeaActInfo(count, roundId));
|
||||
}
|
||||
|
||||
@ApiOperation("获取深海奇缘活动榜单信息")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "type", value = "榜单类型(1:钻石榜 2:欧皇榜)", required = true, dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "page", value = "页数", required = false, dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "每页大小", required = false, dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "page", value = "页数", dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "Integer", paramType = "query"),
|
||||
})
|
||||
@RequestMapping(value = "/listRank", method = RequestMethod.GET)
|
||||
public BaseResponseVO<LuckySeaRankVo> listRank(Integer type, Integer page, Integer pageSize) {
|
||||
BaseRequestVO baseRequestVO = new BaseRequestVO();
|
||||
Long myUserId = baseRequestVO.getMyUserId();
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.listRank(type, page, pageSize, myUserId));
|
||||
@GetMapping("/listRank")
|
||||
@Authorization
|
||||
public BaseResponseVO<LuckySeaRankVo> listRank(HttpServletRequest request,
|
||||
Integer type, Integer page, Integer pageSize) {
|
||||
if (null == type || null == page || null == pageSize) {
|
||||
throw new ServiceException(BusiStatus.PARAMERROR);
|
||||
}
|
||||
Long myUserId = getUid(request);
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.listRank(type, page, pageSize, myUserId));
|
||||
}
|
||||
|
||||
@ApiOperation("抽奖")
|
||||
@@ -114,29 +122,30 @@ public class ActivitiesLuckySeaController {
|
||||
@ApiImplicitParam(name = "itemId", value = "选择的配置id", required = true, dataType = "number", paramType = "body"),
|
||||
@ApiImplicitParam(name = "num", value = "选择的配置数量", required = true, dataType = "number", paramType = "body")
|
||||
})
|
||||
@RequestMapping(value = "/draw", method = RequestMethod.POST)
|
||||
public BaseResponseVO<Void> draw(LuckySeaActDrawParams param) {
|
||||
BaseRequestVO baseRequestVO = new BaseRequestVO();
|
||||
Long myUserId = baseRequestVO.getMyUserId();
|
||||
activitiesLuckySeaService.draw(myUserId, param);
|
||||
@PostMapping("/draw")
|
||||
@Authorization
|
||||
public BaseResponseVO<Void> draw(HttpServletRequest request, Long itemId, Long num) {
|
||||
if (null == itemId || null == num || num <= 0){
|
||||
throw new ServiceException(BusiStatus.PARAMERROR);
|
||||
}
|
||||
Long myUserId = getUid(request);
|
||||
activitiesLuckySeaService.draw(myUserId, itemId, num);
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS);
|
||||
}
|
||||
|
||||
@ApiOperation("分页获取用户的游戏记录")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "page", value = "页数", required = false, dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "每页大小", required = false, dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "page", value = "页数", dataType = "Integer", paramType = "query"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "Integer", paramType = "query"),
|
||||
})
|
||||
@RequestMapping(value = "/listDrawRecord", method = RequestMethod.GET)
|
||||
public BaseResponseVO<List<LuckySeaActUserDrawRecordVo>> listUserDrawRecord(Integer page, Integer pageSize) {
|
||||
BaseRequestVO baseRequestVO = new BaseRequestVO();
|
||||
Long myUserId = baseRequestVO.getMyUserId();
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.listUserDrawResult(myUserId, page, pageSize));
|
||||
@GetMapping("/listDrawRecord")
|
||||
public BaseResponseVO<List<LuckySeaActUserDrawRecordVo>> listUserDrawRecord(HttpServletRequest request,
|
||||
Integer page, Integer pageSize) {
|
||||
if (null == page || null == pageSize) {
|
||||
throw new ServiceException(BusiStatus.PARAMERROR);
|
||||
}
|
||||
Long myUserId = getUid(request);
|
||||
return new BaseResponseVO<>(activitiesLuckySeaService.listUserDrawResult(myUserId, page, pageSize));
|
||||
}
|
||||
|
||||
@ApiOperation("获取游戏各阶段的时间配置")
|
||||
@RequestMapping(value = "/getTimeConfig", method = RequestMethod.GET)
|
||||
public BaseResponseVO<LuckySeaActConfig> getActTimeConfig() {
|
||||
return new BaseResponseVO<>(BusinessStatusCodeEnum.SUCCESS, activitiesLuckySeaService.getLuckySeaTimeConfig());
|
||||
}
|
||||
}
|
||||
|
@@ -11,8 +11,7 @@
|
||||
package servicetest;
|
||||
|
||||
import com.accompany.business.BusinessApplication;
|
||||
import com.accompany.business.dto.LuckySeaUserDrawResultDto;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.luckySea.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.service.activities.vo.LuckySeaRankVo;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.junit.Test;
|
||||
@@ -21,9 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
|
@@ -1,149 +1,38 @@
|
||||
package com.accompany.scheduler.task.activity;
|
||||
|
||||
import com.accompany.business.config.LuckySeaActConfig;
|
||||
import com.accompany.business.model.activity.LuckySeaItem;
|
||||
import com.accompany.business.service.LuckySeaPreWarningService;
|
||||
import com.accompany.business.service.activities.ActivitiesLuckySeaService;
|
||||
import com.accompany.business.vo.activities.LuckySeaActInfoVo;
|
||||
import com.accompany.business.service.activities.luckySea.LuckySeaDrawService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.accompany.core.service.common.JedisLockService;
|
||||
import com.accompany.scheduler.base.BaseTask;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* <br>类描述:
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @author H1
|
||||
* @date [2021/1/6]
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LuckySeaActTask extends BaseTask {
|
||||
public class LuckySeaActTask extends BaseTask implements InitializingBean, Runnable {
|
||||
|
||||
@Autowired
|
||||
private ActivitiesLuckySeaService activitiesLuckySeaService;
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
@Autowired
|
||||
private JedisLockService jedisLockService;
|
||||
@Autowired
|
||||
private LuckySeaPreWarningService luckySeaPreWarningService;
|
||||
|
||||
@PostConstruct
|
||||
public void handleLuckySeaAct() {
|
||||
ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
executorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runTask();
|
||||
}
|
||||
});
|
||||
@Autowired
|
||||
private LuckySeaDrawService drawService;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Executors.newSingleThreadExecutor().execute(this);
|
||||
}
|
||||
|
||||
public void runTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
// 活动开关是否开着
|
||||
Boolean actSwitch = Optional.of(
|
||||
Boolean.parseBoolean(sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_SEA_SWITCH))).orElse(false);
|
||||
log.info("星级厨房活动, 开关状态: {}", actSwitch);
|
||||
if (actSwitch) {
|
||||
String roundId = null;
|
||||
Date nextRoundStartTime = null;
|
||||
Long stock = activitiesLuckySeaService.getStock();
|
||||
// 获取游戏的配置
|
||||
List<LuckySeaItem> itemList = activitiesLuckySeaService.listLuckySeaItem();
|
||||
LuckySeaActConfig timeConfig = activitiesLuckySeaService.getLuckySeaTimeConfig();
|
||||
int totalTime = timeConfig.getWaitingDrawStageTime() + timeConfig.getChooseStageTime() + timeConfig.getDrawOverStageTime();
|
||||
// 加锁,确保创建与开奖是单线程执行
|
||||
String lockVal = jedisLockService.lock(RedisKey.lucky_sea_run_task.getKey(), 10 * 1000, totalTime * 1000);
|
||||
if (StringUtils.isBlank(lockVal)) {
|
||||
log.info("春日游园活动, 获取锁失败");
|
||||
break;
|
||||
}
|
||||
long drawMills = 0L;
|
||||
try {
|
||||
boolean needCreateNewAct = true;
|
||||
boolean needWaitUserDraw = true;
|
||||
Integer waitUserDrawTime = timeConfig.getChooseStageTime();
|
||||
// 处理异常活动
|
||||
LuckySeaActInfoVo lastLuckySeaActInfo = activitiesLuckySeaService.getNewestLuckySeaActInfo(null);
|
||||
if (null != lastLuckySeaActInfo && StringUtils.isNotBlank(lastLuckySeaActInfo.getRoundId())) {
|
||||
if (lastLuckySeaActInfo.getStatus().equals(Constant.LuckySeaActStatus.CHOOSE_STAGE)) {
|
||||
needCreateNewAct = false;
|
||||
roundId = lastLuckySeaActInfo.getRoundId();
|
||||
Long intervalSecond = (System.currentTimeMillis() - lastLuckySeaActInfo.getStartTime().getTime()) / 1000;
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动到现在的间隔时间{}秒, roundId:{}", intervalSecond, roundId);
|
||||
if (intervalSecond <= timeConfig.getChooseStageTime()) {
|
||||
waitUserDrawTime = timeConfig.getChooseStageTime() - intervalSecond.intValue();
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动留给用户的下注时间{}秒", waitUserDrawTime);
|
||||
} else {
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
|
||||
needWaitUserDraw = false;
|
||||
}
|
||||
} else if (lastLuckySeaActInfo.getStatus().equals(Constant.LuckySeaActStatus.DRAWING)) {
|
||||
needCreateNewAct = false;
|
||||
needWaitUserDraw = false;
|
||||
roundId = lastLuckySeaActInfo.getRoundId();
|
||||
log.info("春日游园活动, 上一轮投注时间发生异常的活动直接进行开奖, roundId:{}", roundId);
|
||||
}
|
||||
}
|
||||
// 创建新的一轮游戏
|
||||
if (needCreateNewAct) {
|
||||
roundId = activitiesLuckySeaService.createNewRoundAct(nextRoundStartTime,timeConfig.getChooseStageTime() );
|
||||
}
|
||||
// 等待用户投碎片
|
||||
if (needWaitUserDraw) {
|
||||
log.info("春日游园活动, 开始等待用户投入碎片, currTime: {}", System.currentTimeMillis());
|
||||
Thread.sleep(waitUserDrawTime * 1000);
|
||||
log.info("春日游园活动, 结束等待用户投入碎片, currTime: {}", System.currentTimeMillis());
|
||||
}
|
||||
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.DRAWING);
|
||||
// 开奖
|
||||
drawMills = activitiesLuckySeaService.luckySeaActDraw(itemList, roundId, timeConfig, stock);
|
||||
} catch (Exception e) {
|
||||
// 更新活动状态, 此轮游戏标识为异常,不开始下一轮游戏
|
||||
log.error("春日游园活动开奖时出现异常, roundId: " + roundId, e);
|
||||
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.GAME_ABNORMAL);
|
||||
activitiesLuckySeaService.compensateUserPieceWhenGameAbnormal(roundId, stock);
|
||||
break;
|
||||
} finally {
|
||||
jedisLockService.unlock(RedisKey.lucky_sea_run_task.getKey(), lockVal);
|
||||
}
|
||||
try {
|
||||
// 异步更新用户抽奖记录
|
||||
activitiesLuckySeaService.updateUserDrawRecordAsync(roundId, itemList);
|
||||
// 等待开奖动画与页面渲染开奖结果时间
|
||||
long sleepMills = (timeConfig.getDrawOverStageTime() + timeConfig.getWaitingDrawStageTime()) * 1000
|
||||
- drawMills;
|
||||
if (sleepMills > 0) {
|
||||
log.info("春日游园活动, 等待开奖动画与页面渲染开奖结果时间{}毫秒", sleepMills);
|
||||
Thread.sleep(sleepMills);
|
||||
}
|
||||
log.info("春日游园活动此轮结束, roundId:{}", roundId);
|
||||
// 异步更新活动endTime
|
||||
nextRoundStartTime = new Date();
|
||||
activitiesLuckySeaService.endLuckyAct(roundId, nextRoundStartTime);
|
||||
// 进行预警数据统计
|
||||
luckySeaPreWarningService.handleGoldPreWarning();
|
||||
} catch (Exception e) {
|
||||
// 更新活动状态
|
||||
log.error("春日游园活动更新用户抽奖记录与分发奖励时出现异常, roundId: " + roundId, e);
|
||||
activitiesLuckySeaService.updateLuckyActStatus(roundId, Constant.LuckySeaActStatus.SUCCESS_DRAW_UPDATE_DATA_FAIL);
|
||||
}
|
||||
} else {
|
||||
boolean actSwitch = Boolean.parseBoolean(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.LUCKY_SEA_SWITCH, "false"));
|
||||
log.info("春日游园活动, 开关状态: {}", actSwitch);
|
||||
if (!actSwitch){
|
||||
try {
|
||||
log.info("春日游园活动, 开关未开启,线程进入休眠: {}", actSwitch);
|
||||
Thread.sleep(60 * 1000);
|
||||
@@ -152,6 +41,7 @@ public class LuckySeaActTask extends BaseTask {
|
||||
log.error("春日游园活动线程休眠时出现异常", e);
|
||||
}
|
||||
}
|
||||
drawService.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user