幸运数字-首页和投入

This commit is contained in:
khalil
2025-04-28 20:00:27 +08:00
parent 7ca58326a8
commit a2046dea52
12 changed files with 381 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
package com.accompany.business.dto.activity;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalTime;
@Data
public class LuckyNumberActConfig {
private BigDecimal price;
private BigDecimal jackpotRatio;
private LocalTime roundWaitTime;
private LocalTime roundEndTime;
}

View File

@@ -0,0 +1,24 @@
package com.accompany.business.model.activity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class LuckyNumberActInputRecord {
@TableId(type = IdType.AUTO)
private Long id;
private String date;
private Long uid;
private Integer partitionId;
private BigDecimal price;
private BigDecimal jackpotRatio;
private BigDecimal input;
private Integer number;
private Date createTime;
}

View File

@@ -0,0 +1,19 @@
package com.accompany.business.model.activity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class LuckyNumberActRound {
private String date;
private Integer partitionId;
private Integer playerNum;
private BigDecimal jackpot;
private Integer luckyNumber;
private Date createTime;
private Date updateTime;
}

View File

@@ -0,0 +1,32 @@
package com.accompany.business.vo.activity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@ApiModel
public class LuckyNumberActVo {
@ApiModelProperty(value = "日期")
private String date;
@ApiModelProperty(value = "参与玩家数量")
private Integer playerNum;
private Long uid;
@ApiModelProperty(value = "玩家本轮投入号码")
private List<Integer> numberList;
@ApiModelProperty(value = "活动状态(0=可投入、1=停止投入原地等待、2=结果展示)")
private Byte status;
@ApiModelProperty(value = "倒计时秒数")
private Long countDownSecond;
@ApiModelProperty(value = "中奖号码")
private Integer luckyNumber;
@ApiModelProperty(value = "投入")
private BigDecimal price;
}

View File

@@ -0,0 +1,7 @@
package com.accompany.business.mybatismapper.activity;
import com.accompany.business.model.activity.LuckyNumberActInputRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface LuckyNumberActInputRecordMapper extends BaseMapper<LuckyNumberActInputRecord> {
}

View File

@@ -0,0 +1,13 @@
package com.accompany.business.mybatismapper.activity;
import com.accompany.business.model.activity.LuckyNumberActRound;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
public interface LuckyNumberActRoundMapper extends BaseMapper<LuckyNumberActRound> {
void updateJackpot(@Param("date") String date, @Param("partitionId") Integer partitionId, @Param("jackpot") BigDecimal jackpot);
}

View File

@@ -0,0 +1,42 @@
package com.accompany.business.service.activity;
import com.accompany.business.model.activity.LuckyNumberActInputRecord;
import com.accompany.business.mybatismapper.activity.LuckyNumberActInputRecordMapper;
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 java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class LuckyNumberActPlayerRecordService extends ServiceImpl<LuckyNumberActInputRecordMapper, LuckyNumberActInputRecord> {
public void saveRecord(String date, Long uid, Integer partitionId, Integer number, BigDecimal price, BigDecimal jackpotRatio, BigDecimal input) {
LuckyNumberActInputRecord record = new LuckyNumberActInputRecord();
record.setDate(date);
record.setUid(uid);
record.setPartitionId(partitionId);
record.setNumber(number);
record.setPrice(price);
record.setJackpotRatio(jackpotRatio);
record.setInput(input);
record.setCreateTime(new Date());
save(record);
}
public List<Integer> listInputNumber(String date, Long uid, Integer partitionId) {
List<LuckyNumberActInputRecord> recordList = list(Wrappers.<LuckyNumberActInputRecord>lambdaQuery()
.select(LuckyNumberActInputRecord::getNumber)
.eq(LuckyNumberActInputRecord::getDate, date)
.eq(LuckyNumberActInputRecord::getUid, uid)
.eq(LuckyNumberActInputRecord::getPartitionId, partitionId));
return recordList.stream().map(LuckyNumberActInputRecord::getNumber).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,41 @@
package com.accompany.business.service.activity;
import com.accompany.business.model.activity.LuckyNumberActRound;
import com.accompany.business.mybatismapper.activity.LuckyNumberActRoundMapper;
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 java.math.BigDecimal;
@Slf4j
@Service
public class LuckyNumberActRoundService extends ServiceImpl<LuckyNumberActRoundMapper, LuckyNumberActRound> {
public LuckyNumberActRound getByDate(String date, Integer partitionId) {
return baseMapper.selectOne(Wrappers.<LuckyNumberActRound>lambdaQuery()
.eq(LuckyNumberActRound::getDate, date)
.eq(LuckyNumberActRound::getPartitionId, partitionId));
}
public LuckyNumberActRound getOrDefault(String date, Integer partitionId) {
LuckyNumberActRound round = getByDate(date, partitionId);
if (null != round){
return round;
}
round = new LuckyNumberActRound();
round.setDate(date);
round.setPartitionId(partitionId);
round.setPlayerNum(0);
round.setJackpot(BigDecimal.ZERO);
round.setLuckyNumber(null);
return round;
}
public void updateJackpot(String roundId, Integer partitionId, BigDecimal input) {
baseMapper.updateJackpot(roundId, partitionId, input);
}
}

View File

@@ -0,0 +1,114 @@
package com.accompany.business.service.activity;
import com.accompany.business.dto.activity.LuckyNumberActConfig;
import com.accompany.business.model.activity.LuckyNumberActRound;
import com.accompany.business.service.purse.UserPurseService;
import com.accompany.business.service.user.UsersService;
import com.accompany.business.vo.activity.LuckyNumberActVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.enumeration.BillObjTypeEnum;
import com.accompany.core.enumeration.PartitionEnum;
import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Users;
import com.accompany.core.service.SysConfService;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.util.List;
@Slf4j
@Service
public class LuckyNumberActService {
@Autowired
private UsersService usersService;
@Autowired
public SysConfService sysConfService;
@Autowired
private UserPurseService userPurseService;
@Autowired
private LuckyNumberActRoundService roundService;
@Autowired
private LuckyNumberActPlayerRecordService playerRecordService;
public LuckyNumberActVo getConfigVo(Long uid) {
Users u = usersService.getNotNullUsersByUid(uid);
PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(u.getPartitionId());
ZonedDateTime now = DateTimeUtil.getDateTimeByZoneId(partitionEnum.getZoneId());
LuckyNumberActConfig config = getConfig();
LocalDate today = LocalDate.now();
ZoneId zoneId = ZoneId.of(partitionEnum.getZoneId());
ZonedDateTime roundWaitTime = LocalDateTime.of(today, config.getRoundWaitTime()).atZone(zoneId);
ZonedDateTime roundEndTime = LocalDateTime.of(today, config.getRoundEndTime()).atZone(zoneId);
String date = now.format(DateTimeUtil.dateFormatter);
LuckyNumberActRound round = roundService.getOrDefault(date, u.getPartitionId());
List<Integer> playerInputNumberList = playerRecordService.listInputNumber(date, uid, u.getPartitionId());
byte status = now.compareTo(roundWaitTime) < 0? Constant.status.delete:
now.compareTo(roundEndTime) < 0? Constant.status.valid: Constant.status.invalid;
long countDownSecond = status != Constant.status.valid? Duration.between(now, roundEndTime).getSeconds(): 0L;
LuckyNumberActVo vo = new LuckyNumberActVo();
vo.setUid(uid);
vo.setDate(date);
vo.setStatus(status);
vo.setCountDownSecond(countDownSecond);
vo.setPrice(config.getPrice());
vo.setNumberList(playerInputNumberList);
vo.setPlayerNum(round.getPlayerNum());
vo.setLuckyNumber(round.getLuckyNumber());
return vo;
}
public void input(Long uid, Integer number){
if (number <= 0 || number >= 100){
throw new ServiceException(BusiStatus.PARAMERROR);
}
Users u = usersService.getNotNullUsersByUid(uid);
PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(u.getPartitionId());
ZonedDateTime now = DateTimeUtil.getDateTimeByZoneId(partitionEnum.getZoneId());
LuckyNumberActConfig config = getConfig();
LocalDate today = LocalDate.now();
ZoneId zoneId = ZoneId.of(partitionEnum.getZoneId());
ZonedDateTime roundWaitTime = LocalDateTime.of(today, config.getRoundWaitTime()).atZone(zoneId);
ZonedDateTime roundEndTime = LocalDateTime.of(today, config.getRoundEndTime()).atZone(zoneId);
if (now.compareTo(roundWaitTime) >= 0 && now.compareTo(roundEndTime) < 0){
throw new ServiceException(BusiStatus.NOT_IN_ACT_TIME_RANGE);
}
String roundId = now.compareTo(roundWaitTime) < 0 ? now.format(DateTimeUtil.dateFormatter) : now.plusDays(1L).format(DateTimeUtil.dateFormatter);
userPurseService.subDiamond(uid, config.getPrice().doubleValue(), BillObjTypeEnum.ACTIVITY_DIAMOND_OUT);
BigDecimal input = config.getPrice().multiply(config.getJackpotRatio()).setScale(2, RoundingMode.HALF_DOWN);
playerRecordService.saveRecord(roundId, uid, u.getPartitionId(), number, config.getPrice(), config.getJackpotRatio(), input);
roundService.updateJackpot(roundId, u.getPartitionId(), input);
}
private LuckyNumberActConfig getConfig() {
String configStr = sysConfService.getSysConfValueById(Constant.SysConfId.LUCKY_NUMBER_ACT_CONFIG);
if (!StringUtils.hasText(configStr)){
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
}
return JSON.parseObject(configStr, LuckyNumberActConfig.class);
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.accompany.business.mybatismapper.activity.LuckyNumberActInputRecordMapper">
</mapper>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.accompany.business.mybatismapper.activity.LuckyNumberActRoundMapper">
<update id="updateJackpot">
insert into lucky_number_act_round(date, partition_id, player_num, jackpot, create_time, update_time)
select #{date} as `date`, #{partitionId} as `partition_id`,
(select count(distinct uid) from lucky_number_act_input_record where date = #{date} and partition_id = #{partitionId}) as `player_num`,
#{jackpot} as `jackpot`,
now() as `create_time`,
now() as `update_time`
from dual
on duplicate key update player_num = values(player_num),
jackpot = jackpot + values(jackpot),
update_time = values(update_time)
</update>
</mapper>

View File

@@ -0,0 +1,50 @@
package com.accompany.business.controller.activity;
import com.accompany.business.service.activity.LuckyNumberActService;
import com.accompany.business.vo.activity.LuckyNumberActVo;
import com.accompany.common.annotation.Authorization;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.base.UidContextHolder;
import com.accompany.core.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "幸运数字活动",value = "幸运数字活动")
@Slf4j
@RestController
@RequestMapping("/luckyNumber")
public class LuckyNumberActController {
@Autowired
private LuckyNumberActService actService;
@ApiOperation(value = "获取活动首页")
@Authorization
@GetMapping(value = "/getConfig")
public BusiResult<LuckyNumberActVo> getWeekStarList(){
Long uid = UidContextHolder.get();
LuckyNumberActVo vo = actService.getConfigVo(uid);
return BusiResult.success(vo);
}
@ApiOperation(value = "投入")
@Authorization
@PostMapping(value = "/input")
public BusiResult<Void> input(Integer number){
if (null == number){
throw new ServiceException(BusiStatus.PARAMERROR);
}
Long uid = UidContextHolder.get();
actService.input(uid, number);
return BusiResult.success();
}
}