提交roll日创建
This commit is contained in:
@@ -17,7 +17,9 @@ CREATE TABLE IF NOT EXISTS `tt_official_roll_config` (
|
||||
`roll_password` varchar(32) DEFAULT '' COMMENT '房间密码,为空则无密码',
|
||||
`min_recharge` decimal(10,2) DEFAULT '0.00' COMMENT '充值门槛,0为无门槛',
|
||||
`people_num` int DEFAULT '50' COMMENT '人数上限',
|
||||
`robot_num` int DEFAULT '0' COMMENT '每次自动加入的机器人数量,0则不加',
|
||||
`robot_num` int DEFAULT '0' COMMENT '每次自动加入的机器人数量,0则不加(兼容旧数据)',
|
||||
`robot_min` int DEFAULT '0' COMMENT '每次自动加入的机器人数量下限,0则不加',
|
||||
`robot_max` int DEFAULT '0' COMMENT '每次自动加入的机器人数量上限,0则不加',
|
||||
`cdk_count` int DEFAULT '0' COMMENT '每次自动创建房间生成的CDK数量,0则不启用CDK',
|
||||
`sort_by` int DEFAULT '0' COMMENT '排序',
|
||||
`status` char(1) DEFAULT '0' COMMENT '状态 0启用 1停用',
|
||||
@@ -33,6 +35,10 @@ CREATE TABLE IF NOT EXISTS `tt_official_roll_config` (
|
||||
-- 若 tt_official_roll_config 表此前已创建(无 cdk_count 列),执行下句补列;全新执行本脚本已含该列,可跳过:
|
||||
-- ALTER TABLE `tt_official_roll_config` ADD COLUMN `cdk_count` int DEFAULT '0' COMMENT '每次自动创建房间生成的CDK数量,0则不启用CDK';
|
||||
|
||||
-- 若 tt_official_roll_config 表此前已创建(无 robot_min/robot_max 列),执行下句补列;全新执行本脚本已含该列,可跳过:
|
||||
-- ALTER TABLE `tt_official_roll_config` ADD COLUMN `robot_min` int DEFAULT '0' COMMENT '每次自动加入的机器人数量下限,0则不加';
|
||||
-- ALTER TABLE `tt_official_roll_config` ADD COLUMN `robot_max` int DEFAULT '0' COMMENT '每次自动加入的机器人数量上限,0则不加';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 2) tt_roll 增加 official_config_id 列(标记房间由哪条配置生成,用于每日幂等)
|
||||
-- 注意:MySQL 不支持 ADD COLUMN IF NOT EXISTS,若该列已存在请跳过本句。
|
||||
|
||||
@@ -41,7 +41,11 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="roomName" label="房间名"></el-table-column>
|
||||
<el-table-column align="center" prop="robotNum" label="机器人数量" width="100"></el-table-column>
|
||||
<el-table-column align="center" label="机器人范围" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.robotMin }} ~ {{ scope.row.robotMax }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="cdkCount" label="CDK数量" width="90"></el-table-column>
|
||||
<el-table-column align="center" prop="peopleNum" label="人数上限" width="90"></el-table-column>
|
||||
<el-table-column align="center" prop="rollPassword" label="密码" width="80"></el-table-column>
|
||||
@@ -92,10 +96,14 @@
|
||||
<el-form-item label="房间描述" prop="description">
|
||||
<el-input type="textarea" v-model="form.description" placeholder="请输入房间描述"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="机器人数量" prop="robotNum">
|
||||
<el-input-number v-model="form.robotNum" :min="0" :max="100000" label="机器人数量"></el-input-number>
|
||||
<el-form-item label="机器人范围" prop="robotRange">
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<el-input-number v-model="form.robotMin" :min="0" :max="100000" label="机器人数量下限"></el-input-number>
|
||||
<span>~</span>
|
||||
<el-input-number v-model="form.robotMax" :min="0" :max="100000" label="机器人数量上限"></el-input-number>
|
||||
</div>
|
||||
<span style="font-size: 12px;">
|
||||
<i class="el-icon-info"></i> 每天自动创建房间后加入的机器人数量,为0则不加机器人
|
||||
<i class="el-icon-info"></i> 每天自动创建房间后随机加入[下限,上限]个机器人,均为0则不加机器人
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="人数上限" prop="peopleNum">
|
||||
@@ -161,7 +169,19 @@ export default {
|
||||
configName: [{ required: true, message: "请输入配置名称", trigger: "blur" }],
|
||||
jackpotId: [{ required: true, message: "请选择奖池", trigger: "change" }],
|
||||
roomName: [{ required: true, message: "请输入房间名", trigger: "blur" }],
|
||||
peopleNum: [{ required: true, message: "请输入人数上限", trigger: "blur" }]
|
||||
peopleNum: [{ required: true, message: "请输入人数上限", trigger: "blur" }],
|
||||
robotRange: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.form.robotMin > this.form.robotMax) {
|
||||
callback(new Error("机器人数量下限不能大于上限"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "change"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -180,6 +200,8 @@ export default {
|
||||
description: null,
|
||||
minRecharge: 0,
|
||||
robotNum: 0,
|
||||
robotMin: 0,
|
||||
robotMax: 0,
|
||||
cdkCount: 0,
|
||||
peopleNum: 100,
|
||||
rollPassword: null,
|
||||
|
||||
@@ -59,10 +59,18 @@ public class TtOfficialRollConfig implements Serializable {
|
||||
@Excel(name = "人数上限")
|
||||
private Integer peopleNum;
|
||||
|
||||
/** 每天(每周期)自动加入的机器人数量 */
|
||||
/** 每天(每周期)自动加入的机器人数量(兼容旧数据) */
|
||||
@Excel(name = "机器人数量")
|
||||
private Integer robotNum;
|
||||
|
||||
/** 每天自动加入的机器人数量下限 */
|
||||
@Excel(name = "机器人数量下限")
|
||||
private Integer robotMin;
|
||||
|
||||
/** 每天自动加入的机器人数量上限 */
|
||||
@Excel(name = "机器人数量上限")
|
||||
private Integer robotMax;
|
||||
|
||||
/** 每次自动创建房间生成的CDK数量,0则不启用CDK(使用普通密码) */
|
||||
@Excel(name = "CDK数量")
|
||||
private Integer cdkCount;
|
||||
|
||||
+4
@@ -3,6 +3,7 @@ package com.ruoyi.admin.domain.body;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class AddRobotBody {
|
||||
@@ -11,4 +12,7 @@ public class AddRobotBody {
|
||||
private Integer rollId;
|
||||
|
||||
private Integer robotNum;
|
||||
|
||||
/** 需要排除的机器人ID列表(例如已在其他官方房中使用的机器人) */
|
||||
private List<Integer> excludeRobotIds;
|
||||
}
|
||||
|
||||
@@ -18,4 +18,9 @@ public interface TtRollMapper extends BaseMapper<TtRoll> {
|
||||
List<TtUser> getRollUser(Integer rollId);
|
||||
|
||||
List<Integer> getRollRobotIds(Integer rollId);
|
||||
|
||||
/**
|
||||
* 查询所有未开奖官方日Roll房中的机器人ID
|
||||
*/
|
||||
List<Integer> getActiveOfficialRollRobotIds();
|
||||
}
|
||||
|
||||
+12
@@ -63,6 +63,16 @@ public class TtOfficialRollConfigServiceImpl
|
||||
if (config.getRobotNum() != null && config.getRobotNum() < 0) {
|
||||
return AjaxResult.error("机器人数量不能为负数");
|
||||
}
|
||||
if (config.getRobotMin() != null && config.getRobotMin() < 0) {
|
||||
return AjaxResult.error("机器人数量下限不能为负数");
|
||||
}
|
||||
if (config.getRobotMax() != null && config.getRobotMax() < 0) {
|
||||
return AjaxResult.error("机器人数量上限不能为负数");
|
||||
}
|
||||
if (config.getRobotMin() != null && config.getRobotMax() != null
|
||||
&& config.getRobotMin() > config.getRobotMax()) {
|
||||
return AjaxResult.error("机器人数量下限不能大于上限");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -72,6 +82,8 @@ public class TtOfficialRollConfigServiceImpl
|
||||
private void normalize(TtOfficialRollConfig config) {
|
||||
if (config.getMinRecharge() == null) config.setMinRecharge(BigDecimal.ZERO);
|
||||
if (config.getRobotNum() == null) config.setRobotNum(0);
|
||||
if (config.getRobotMin() == null) config.setRobotMin(0);
|
||||
if (config.getRobotMax() == null) config.setRobotMax(0);
|
||||
if (config.getSortBy() == null) config.setSortBy(0);
|
||||
if (StringUtils.isEmpty(config.getStatus())) config.setStatus("0");
|
||||
}
|
||||
|
||||
+5
-1
@@ -556,9 +556,13 @@ public class TtRollServiceImpl extends ServiceImpl<TtRollMapper, TtRoll> impleme
|
||||
// 查询已经在房间中的机器人ID
|
||||
List<Integer> rollRobotIds = ttRollMapper.getRollRobotIds(addRobotBody.getRollId());
|
||||
|
||||
// 过滤掉已经在房间中的机器人ID
|
||||
// 查询需要排除的机器人ID(例如已在其他官方房中使用的机器人)
|
||||
List<Integer> excludeRobotIds = addRobotBody.getExcludeRobotIds();
|
||||
|
||||
// 过滤掉已经在房间中或被排除的机器人ID
|
||||
List<Integer> filteredRobotIdList = robotIdList.stream()
|
||||
.filter(robotId -> !rollRobotIds.contains(robotId))
|
||||
.filter(robotId -> excludeRobotIds == null || !excludeRobotIds.contains(robotId))
|
||||
.collect(Collectors.toList());
|
||||
if (filteredRobotIdList.size() < addRobotBody.getRobotNum()) {
|
||||
return AjaxResult.error("可用机器人数量不足");
|
||||
|
||||
+33
-4
@@ -4,11 +4,13 @@ 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.mapper.TtRollMapper;
|
||||
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.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
import com.ruoyi.domain.entity.roll.TtRoll;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
@@ -20,6 +22,7 @@ import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 官方周期Roll房定时创建任务。
|
||||
@@ -54,6 +57,9 @@ public class OfficialRollTask {
|
||||
@Autowired
|
||||
private TtRollCdkService rollCdkService;
|
||||
|
||||
@Autowired
|
||||
private TtRollMapper rollMapper;
|
||||
|
||||
/**
|
||||
* 每天为所有启用的 DAILY 配置创建当日官方roll房并自动加入机器人。
|
||||
* 充值统计起点=当天0点(今日充值),开奖=当日23:59:59。
|
||||
@@ -135,10 +141,12 @@ public class OfficialRollTask {
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定房间按配置数量加入机器人。数量取 min(配置机器人数, 可用机器人总数),避免"可用机器人数量不足"导致一个都不加。
|
||||
* 为指定房间按配置数量加入机器人。
|
||||
* 若配置指定了 robotMin/robotMax 范围,则在范围内随机生成数量;否则使用固定 robotNum。
|
||||
* 会排除当前已在其他未开奖官方日Roll房中的机器人,保证不同日期的官方房间机器人不重复。
|
||||
*/
|
||||
private void addRobots(Integer rollId, TtOfficialRollConfig config) {
|
||||
Integer robotNum = config.getRobotNum();
|
||||
Integer robotNum = resolveRobotNum(config);
|
||||
if (rollId == null || robotNum == null || robotNum <= 0) {
|
||||
return;
|
||||
}
|
||||
@@ -149,16 +157,37 @@ public class OfficialRollTask {
|
||||
log.warn("[官方周期Roll] 配置{}需要{}个机器人,但用户表无可用机器人,跳过加入", config.getId(), robotNum);
|
||||
return;
|
||||
}
|
||||
// 查询其他未开奖官方日Roll房中已使用的机器人,避免重复
|
||||
List<Integer> activeOfficialRobots = rollMapper.getActiveOfficialRollRobotIds();
|
||||
AddRobotBody body = new AddRobotBody();
|
||||
body.setRollId(rollId);
|
||||
body.setRobotNum(toAdd);
|
||||
rollService.addRobot(body);
|
||||
log.info("[官方周期Roll] 配置{} 房间{} 已尝试加入{}个机器人", config.getId(), rollId, toAdd);
|
||||
body.setExcludeRobotIds(activeOfficialRobots);
|
||||
AjaxResult result = rollService.addRobot(body);
|
||||
if (!result.isSuccess()) {
|
||||
log.warn("[官方周期Roll] 配置{} 房间{} 加入机器人结果:{}", config.getId(), rollId, result.get(AjaxResult.MSG_TAG));
|
||||
} else {
|
||||
log.info("[官方周期Roll] 配置{} 房间{} 已尝试加入{}个机器人", config.getId(), rollId, toAdd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[官方周期Roll] 配置{} 房间{} 加入机器人失败:{}", config.getId(), rollId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析配置中的机器人数量:优先使用 robotMin/robotMax 范围随机,否则回退到固定 robotNum
|
||||
*/
|
||||
private Integer resolveRobotNum(TtOfficialRollConfig config) {
|
||||
Integer min = config.getRobotMin();
|
||||
Integer max = config.getRobotMax();
|
||||
if (min != null && min > 0 && max != null && max > 0) {
|
||||
int lower = Math.min(min, max);
|
||||
int upper = Math.max(min, max);
|
||||
return ThreadLocalRandom.current().nextInt(lower, upper + 1);
|
||||
}
|
||||
return config.getRobotNum();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按配置数量为房间生成CDK;0或空则不生成(使用普通密码)。
|
||||
*/
|
||||
|
||||
+16
@@ -61,4 +61,20 @@
|
||||
WHERE
|
||||
tru.roll_id = #{rollId} AND tu.user_type = 03
|
||||
</select>
|
||||
|
||||
<select id="getActiveOfficialRollRobotIds" resultType="Integer">
|
||||
SELECT DISTINCT
|
||||
tu.user_id
|
||||
FROM
|
||||
tt_roll_user AS tru
|
||||
LEFT JOIN
|
||||
tt_user AS tu ON tru.user_id = tu.user_id
|
||||
LEFT JOIN
|
||||
tt_roll AS tr ON tru.roll_id = tr.id
|
||||
WHERE
|
||||
tu.user_type = '03'
|
||||
AND tr.roll_type = '0'
|
||||
AND tr.official_config_id IS NOT NULL
|
||||
AND tr.roll_status = '0'
|
||||
</select>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user