提交roll日创建
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
package com.ruoyi.admin.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.admin.service.TtOfficialRollConfigService;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 官方周期Roll配置")
|
||||
@RestController
|
||||
@RequestMapping("/admin/officialRollConfig")
|
||||
public class TtOfficialRollConfigController extends BaseController {
|
||||
|
||||
private final TtOfficialRollConfigService configService;
|
||||
|
||||
public TtOfficialRollConfigController(TtOfficialRollConfigService configService) {
|
||||
this.configService = configService;
|
||||
}
|
||||
|
||||
@ApiOperation("配置列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtOfficialRollConfig> list(
|
||||
@RequestParam(value = "configName", required = false) String configName,
|
||||
@RequestParam(value = "periodType", required = false) String periodType,
|
||||
@RequestParam(value = "status", required = false) String status) {
|
||||
startPage();
|
||||
LambdaQueryWrapper<TtOfficialRollConfig> wrapper = Wrappers.lambdaQuery();
|
||||
if (StringUtils.isNotEmpty(configName)) wrapper.like(TtOfficialRollConfig::getConfigName, configName);
|
||||
if (StringUtils.isNotEmpty(periodType)) wrapper.eq(TtOfficialRollConfig::getPeriodType, periodType);
|
||||
if (StringUtils.isNotEmpty(status)) wrapper.eq(TtOfficialRollConfig::getStatus, status);
|
||||
wrapper.orderByAsc(TtOfficialRollConfig::getSortBy).orderByDesc(TtOfficialRollConfig::getCreateTime);
|
||||
List<TtOfficialRollConfig> configList = configService.list(wrapper);
|
||||
return getPageData(configList);
|
||||
}
|
||||
|
||||
@ApiOperation("配置详情")
|
||||
@GetMapping("/{id}")
|
||||
public R<TtOfficialRollConfig> getInfo(@PathVariable("id") Integer id) {
|
||||
return R.ok(configService.getById(id));
|
||||
}
|
||||
|
||||
@ApiOperation("新增配置")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TtOfficialRollConfig config) {
|
||||
config.setCreateBy(getUsername());
|
||||
config.setCreateTime(DateUtils.getNowDate());
|
||||
return configService.addConfig(config);
|
||||
}
|
||||
|
||||
@ApiOperation("编辑配置")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtOfficialRollConfig config) {
|
||||
config.setUpdateBy(getUsername());
|
||||
config.setUpdateTime(DateUtils.getNowDate());
|
||||
return configService.editConfig(config);
|
||||
}
|
||||
|
||||
@ApiOperation("删除配置")
|
||||
@DeleteMapping("/{id}")
|
||||
public AjaxResult remove(@PathVariable("id") Integer id) {
|
||||
return configService.removeById(id) ? AjaxResult.success() : AjaxResult.error("删除失败");
|
||||
}
|
||||
|
||||
@ApiOperation("启用/停用配置")
|
||||
@PutMapping("/changeStatus")
|
||||
public AjaxResult changeStatus(@RequestBody TtOfficialRollConfig config) {
|
||||
if (config.getId() == null) return AjaxResult.error("配置ID不能为空");
|
||||
if (!"0".equals(config.getStatus()) && !"1".equals(config.getStatus())) {
|
||||
return AjaxResult.error("状态不合法");
|
||||
}
|
||||
TtOfficialRollConfig update = new TtOfficialRollConfig();
|
||||
update.setId(config.getId());
|
||||
update.setStatus(config.getStatus());
|
||||
update.setUpdateBy(getUsername());
|
||||
update.setUpdateTime(DateUtils.getNowDate());
|
||||
return configService.updateById(update) ? AjaxResult.success() : AjaxResult.error("操作失败");
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -201,12 +201,13 @@ public class TtRollController extends BaseController {
|
||||
return success("生成成功");
|
||||
}
|
||||
|
||||
/** 查看Roll房所有CDK列表 */
|
||||
/** 查看Roll房所有CDK列表(分页) */
|
||||
@ApiOperation("查看Roll房CDK列表")
|
||||
@GetMapping("/cdk/list/{rollId}")
|
||||
public AjaxResult getCdkList(@PathVariable("rollId") Integer rollId) {
|
||||
public PageDataInfo<TtRollCdk> getCdkList(@PathVariable("rollId") Integer rollId) {
|
||||
startPage();
|
||||
List<TtRollCdk> list = rollCdkService.listByRollId(rollId);
|
||||
return success(list);
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
/** 删除指定CDK */
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.ruoyi.admin.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface TtOfficialRollConfigMapper extends BaseMapper<TtOfficialRollConfig> {
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.ruoyi.admin.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
|
||||
public interface TtOfficialRollConfigService extends IService<TtOfficialRollConfig> {
|
||||
|
||||
/** 新增配置(含校验) */
|
||||
AjaxResult addConfig(TtOfficialRollConfig config);
|
||||
|
||||
/** 编辑配置(含校验) */
|
||||
AjaxResult editConfig(TtOfficialRollConfig config);
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package com.ruoyi.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.admin.mapper.TtOfficialRollConfigMapper;
|
||||
import com.ruoyi.admin.service.TtOfficialRollConfigService;
|
||||
import com.ruoyi.admin.service.TtRollJackpotService;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
import com.ruoyi.domain.entity.roll.TtRollJackpot;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class TtOfficialRollConfigServiceImpl
|
||||
extends ServiceImpl<TtOfficialRollConfigMapper, TtOfficialRollConfig>
|
||||
implements TtOfficialRollConfigService {
|
||||
|
||||
/** 周期类型:每日 */
|
||||
public static final String PERIOD_DAILY = "DAILY";
|
||||
|
||||
@Autowired
|
||||
private TtRollJackpotService rollJackpotService;
|
||||
|
||||
@Override
|
||||
public AjaxResult addConfig(TtOfficialRollConfig config) {
|
||||
AjaxResult check = validate(config);
|
||||
if (check != null) return check;
|
||||
normalize(config);
|
||||
return save(config) ? AjaxResult.success() : AjaxResult.error("新增失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult editConfig(TtOfficialRollConfig config) {
|
||||
if (config.getId() == null) return AjaxResult.error("配置ID不能为空");
|
||||
AjaxResult check = validate(config);
|
||||
if (check != null) return check;
|
||||
return updateById(config) ? AjaxResult.success() : AjaxResult.error("修改失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 基本校验:配置名、房间名、奖池存在、周期合法、人数>0、门槛/机器人数非负;返回 null 表示通过
|
||||
*/
|
||||
private AjaxResult validate(TtOfficialRollConfig config) {
|
||||
if (config == null) return AjaxResult.error("参数不能为空");
|
||||
if (StringUtils.isEmpty(config.getConfigName())) return AjaxResult.error("配置标识不能为空");
|
||||
if (StringUtils.isEmpty(config.getRoomName())) return AjaxResult.error("房间名称不能为空");
|
||||
if (config.getJackpotId() == null) return AjaxResult.error("请选择奖池");
|
||||
TtRollJackpot jackpot = rollJackpotService.getById(config.getJackpotId());
|
||||
if (jackpot == null) return AjaxResult.error("指定的奖池不存在");
|
||||
String period = config.getPeriodType();
|
||||
if (!PERIOD_DAILY.equals(period)) {
|
||||
return AjaxResult.error("周期类型不合法,仅支持 DAILY");
|
||||
}
|
||||
if (config.getPeopleNum() == null || config.getPeopleNum() <= 0) {
|
||||
return AjaxResult.error("人数上限必须大于0");
|
||||
}
|
||||
if (config.getMinRecharge() != null && config.getMinRecharge().compareTo(BigDecimal.ZERO) < 0) {
|
||||
return AjaxResult.error("充值门槛不能为负数");
|
||||
}
|
||||
if (config.getRobotNum() != null && config.getRobotNum() < 0) {
|
||||
return AjaxResult.error("机器人数量不能为负数");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 归一化默认值
|
||||
*/
|
||||
private void normalize(TtOfficialRollConfig config) {
|
||||
if (config.getMinRecharge() == null) config.setMinRecharge(BigDecimal.ZERO);
|
||||
if (config.getRobotNum() == null) config.setRobotNum(0);
|
||||
if (config.getSortBy() == null) config.setSortBy(0);
|
||||
if (StringUtils.isEmpty(config.getStatus())) config.setStatus("0");
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -132,7 +132,12 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
wrapper.like(TtUser::getUserName, ttUserBody.getUserName());
|
||||
if (StringUtils.isNotNull(ttUserBody.getNickName()))
|
||||
wrapper.like(TtUser::getNickName, ttUserBody.getNickName());
|
||||
if (StringUtils.isNotNull(ttUserBody.getUserType())) wrapper.eq(TtUser::getUserType, ttUserBody.getUserType());
|
||||
if (StringUtils.isNotEmpty(ttUserBody.getUserType())) {
|
||||
wrapper.eq(TtUser::getUserType, ttUserBody.getUserType());
|
||||
} else {
|
||||
// 用户列表默认排除机器人(userType=03),机器人在独立的机器人管理页显式传 userType=03 查询
|
||||
wrapper.and(w -> w.isNull(TtUser::getUserType).or().ne(TtUser::getUserType, "03"));
|
||||
}
|
||||
if (StringUtils.isNotEmpty(ttUserBody.getPhoneNumber()))
|
||||
wrapper.likeRight(TtUser::getPhoneNumber, ttUserBody.getPhoneNumber());
|
||||
if (StringUtils.isNotEmpty(ttUserBody.getStatus())) wrapper.eq(TtUser::getStatus, ttUserBody.getStatus());
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
package com.ruoyi.admin.task;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.admin.domain.body.AddRobotBody;
|
||||
import com.ruoyi.admin.service.TtOfficialRollConfigService;
|
||||
import com.ruoyi.admin.service.TtRollCdkService;
|
||||
import com.ruoyi.admin.service.TtRollService;
|
||||
import com.ruoyi.admin.service.TtUserService;
|
||||
import com.ruoyi.admin.service.impl.TtOfficialRollConfigServiceImpl;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
import com.ruoyi.domain.entity.roll.TtRoll;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 官方周期Roll房定时创建任务。
|
||||
* <p>
|
||||
* 注册到 RuoYi 系统监控-定时任务(由 sys_job 统一调度,不加 @Scheduled):
|
||||
* - 任务名称:官方日Roll生成 调用目标:officialRollTask.generateDailyRolls() 默认cron:0 0 10 * * ?(每天10:00)
|
||||
* <p>
|
||||
* 复用官方房(roll_type=0)语义,直接创建 tt_roll,并按配置的机器人数量自动加入机器人。
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("officialRollTask")
|
||||
public class OfficialRollTask {
|
||||
|
||||
/** 官方房类型 */
|
||||
private static final String ROLL_TYPE_OFFICIAL = "0";
|
||||
/** 未开奖状态 */
|
||||
private static final String ROLL_STATUS_OPEN = "0";
|
||||
/** 官方房创建者ID(0=官方) */
|
||||
private static final Integer OFFICIAL_USER_ID = 0;
|
||||
/** 机器人用户类型 */
|
||||
private static final String ROBOT_USER_TYPE = "03";
|
||||
|
||||
@Autowired
|
||||
private TtOfficialRollConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private TtRollService rollService;
|
||||
|
||||
@Autowired
|
||||
private TtUserService userService;
|
||||
|
||||
@Autowired
|
||||
private TtRollCdkService rollCdkService;
|
||||
|
||||
/**
|
||||
* 每天为所有启用的 DAILY 配置创建当日官方roll房并自动加入机器人。
|
||||
* 充值统计起点=当天0点(今日充值),开奖=当日23:59:59。
|
||||
*/
|
||||
public void generateDailyRolls() {
|
||||
Date start = todayStart();
|
||||
Date end = todayEnd();
|
||||
generate(TtOfficialRollConfigServiceImpl.PERIOD_DAILY, start, end);
|
||||
}
|
||||
|
||||
private void generate(String periodType, Date rechargeStartTime, Date endTime) {
|
||||
log.info("[官方周期Roll] 开始生成 period={}, start={}, end={}", periodType, rechargeStartTime, endTime);
|
||||
|
||||
LambdaQueryWrapper<TtOfficialRollConfig> query = Wrappers.lambdaQuery();
|
||||
query.eq(TtOfficialRollConfig::getStatus, "0")
|
||||
.eq(TtOfficialRollConfig::getPeriodType, periodType);
|
||||
List<TtOfficialRollConfig> configs = configService.list(query);
|
||||
|
||||
if (configs == null || configs.isEmpty()) {
|
||||
log.info("[官方周期Roll] 无启用的 {} 配置,跳过", periodType);
|
||||
return;
|
||||
}
|
||||
|
||||
int created = 0;
|
||||
int skipped = 0;
|
||||
for (TtOfficialRollConfig config : configs) {
|
||||
try {
|
||||
// 幂等:同一配置 + 同一充值统计起点 至多生成一个房间
|
||||
long exists = rollService.count(Wrappers.<TtRoll>lambdaQuery()
|
||||
.eq(TtRoll::getOfficialConfigId, config.getId())
|
||||
.eq(TtRoll::getRechargeStartTime, rechargeStartTime));
|
||||
if (exists > 0) {
|
||||
skipped++;
|
||||
log.info("[官方周期Roll] 配置{}({})本周期房间已存在,跳过", config.getId(), config.getConfigName());
|
||||
continue;
|
||||
}
|
||||
|
||||
TtRoll roll = TtRoll.builder()
|
||||
.jackpotId(config.getJackpotId())
|
||||
.userId(OFFICIAL_USER_ID)
|
||||
.rollType(ROLL_TYPE_OFFICIAL)
|
||||
.rollName(config.getRoomName())
|
||||
.description(config.getDescription())
|
||||
.endTime(endTime)
|
||||
.peopleNum(config.getPeopleNum())
|
||||
.rollPassword(config.getRollPassword())
|
||||
.minRecharge(config.getMinRecharge() != null ? config.getMinRecharge() : BigDecimal.ZERO)
|
||||
.rechargeStartTime(rechargeStartTime)
|
||||
.sortBy(config.getSortBy())
|
||||
.rollStatus(ROLL_STATUS_OPEN)
|
||||
.officialConfigId(config.getId())
|
||||
.createBy("system")
|
||||
.createTime(new Date())
|
||||
.build();
|
||||
rollService.save(roll);
|
||||
|
||||
// 自动加入机器人:数量取配置值,且不超过可用机器人总数;addRobot 会自动跳过该房已有机器人
|
||||
addRobots(roll.getId(), config);
|
||||
|
||||
// 按配置数量为房间生成CDK(0则不生成,使用普通密码)
|
||||
generateCdks(roll.getId(), config);
|
||||
|
||||
// 回写上次生成时间(幂等辅助/可观测)
|
||||
TtOfficialRollConfig update = new TtOfficialRollConfig();
|
||||
update.setId(config.getId());
|
||||
update.setLastGenerateTime(new Date());
|
||||
configService.updateById(update);
|
||||
|
||||
created++;
|
||||
log.info("[官方周期Roll] 配置{}({}) 已生成房间 rollId={},起点={},开奖={}",
|
||||
config.getId(), config.getConfigName(), roll.getId(), rechargeStartTime, endTime);
|
||||
} catch (Exception e) {
|
||||
log.error("[官方周期Roll] 配置{}生成房间失败:{}", config.getId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("[官方周期Roll] 生成完成 period={}, 配置数={}, 新建={}, 跳过={}",
|
||||
periodType, configs.size(), created, skipped);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定房间按配置数量加入机器人。数量取 min(配置机器人数, 可用机器人总数),避免"可用机器人数量不足"导致一个都不加。
|
||||
*/
|
||||
private void addRobots(Integer rollId, TtOfficialRollConfig config) {
|
||||
Integer robotNum = config.getRobotNum();
|
||||
if (rollId == null || robotNum == null || robotNum <= 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
long robotTotal = userService.count(new QueryWrapper<TtUser>().eq("user_type", ROBOT_USER_TYPE));
|
||||
int toAdd = (int) Math.min(robotNum.longValue(), robotTotal);
|
||||
if (toAdd <= 0) {
|
||||
log.warn("[官方周期Roll] 配置{}需要{}个机器人,但用户表无可用机器人,跳过加入", config.getId(), robotNum);
|
||||
return;
|
||||
}
|
||||
AddRobotBody body = new AddRobotBody();
|
||||
body.setRollId(rollId);
|
||||
body.setRobotNum(toAdd);
|
||||
rollService.addRobot(body);
|
||||
log.info("[官方周期Roll] 配置{} 房间{} 已尝试加入{}个机器人", config.getId(), rollId, toAdd);
|
||||
} catch (Exception e) {
|
||||
log.error("[官方周期Roll] 配置{} 房间{} 加入机器人失败:{}", config.getId(), rollId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按配置数量为房间生成CDK;0或空则不生成(使用普通密码)。
|
||||
*/
|
||||
private void generateCdks(Integer rollId, TtOfficialRollConfig config) {
|
||||
Integer cdkCount = config.getCdkCount();
|
||||
if (rollId == null || cdkCount == null || cdkCount <= 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
rollCdkService.generateCdks(rollId, cdkCount);
|
||||
log.info("[官方周期Roll] 配置{} 房间{} 已生成{}个CDK", config.getId(), rollId, cdkCount);
|
||||
} catch (Exception e) {
|
||||
log.error("[官方周期Roll] 配置{} 房间{} 生成CDK失败:{}", config.getId(), rollId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/** 今天0点 */
|
||||
private Date todayStart() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
clearTime(c);
|
||||
return c.getTime();
|
||||
}
|
||||
|
||||
/** 今天23:59:59 */
|
||||
private Date todayEnd() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(Calendar.HOUR_OF_DAY, 23);
|
||||
c.set(Calendar.MINUTE, 59);
|
||||
c.set(Calendar.SECOND, 59);
|
||||
c.set(Calendar.MILLISECOND, 0);
|
||||
return c.getTime();
|
||||
}
|
||||
|
||||
private void clearTime(Calendar c) {
|
||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||
c.set(Calendar.MINUTE, 0);
|
||||
c.set(Calendar.SECOND, 0);
|
||||
c.set(Calendar.MILLISECOND, 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user