From 55fdf24f3afb448fb094d48ba30ae781d3e6afdd Mon Sep 17 00:00:00 2001
From: Fdily <2949549024@qq.com>
Date: Sun, 19 Jul 2026 12:05:45 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4roll=E6=97=A5=E5=88=9B?=
=?UTF-8?q?=E5=BB=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
doc/官方日Roll与机器人管理.sql | 8 +++-
.../views/skins/ttRoll/officialRollConfig.vue | 32 +++++++++++++---
.../entity/roll/TtOfficialRollConfig.java | 10 ++++-
.../ruoyi/admin/domain/body/AddRobotBody.java | 4 ++
.../com/ruoyi/admin/mapper/TtRollMapper.java | 5 +++
.../impl/TtOfficialRollConfigServiceImpl.java | 12 ++++++
.../admin/service/impl/TtRollServiceImpl.java | 6 ++-
.../ruoyi/admin/task/OfficialRollTask.java | 37 +++++++++++++++++--
.../com/ruoyi/admin/mapper/TtRollMapper.xml | 16 ++++++++
9 files changed, 118 insertions(+), 12 deletions(-)
diff --git a/doc/官方日Roll与机器人管理.sql b/doc/官方日Roll与机器人管理.sql
index 2b8f956..6a6c94a 100644
--- a/doc/官方日Roll与机器人管理.sql
+++ b/doc/官方日Roll与机器人管理.sql
@@ -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,若该列已存在请跳过本句。
diff --git a/ruoyi-ui/src/views/skins/ttRoll/officialRollConfig.vue b/ruoyi-ui/src/views/skins/ttRoll/officialRollConfig.vue
index aceb120..ab76bcd 100644
--- a/ruoyi-ui/src/views/skins/ttRoll/officialRollConfig.vue
+++ b/ruoyi-ui/src/views/skins/ttRoll/officialRollConfig.vue
@@ -41,7 +41,11 @@
-
+
+
+ {{ scope.row.robotMin }} ~ {{ scope.row.robotMax }}
+
+
@@ -92,10 +96,14 @@
-
-
+
+
+
+ ~
+
+
- 每天自动创建房间后加入的机器人数量,为0则不加机器人
+ 每天自动创建房间后随机加入[下限,上限]个机器人,均为0则不加机器人
@@ -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,
diff --git a/skins-model/src/main/java/com/ruoyi/domain/entity/roll/TtOfficialRollConfig.java b/skins-model/src/main/java/com/ruoyi/domain/entity/roll/TtOfficialRollConfig.java
index 4c2f8e1..1eb35f9 100644
--- a/skins-model/src/main/java/com/ruoyi/domain/entity/roll/TtOfficialRollConfig.java
+++ b/skins-model/src/main/java/com/ruoyi/domain/entity/roll/TtOfficialRollConfig.java
@@ -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;
diff --git a/skins-service/service-admin/src/main/java/com/ruoyi/admin/domain/body/AddRobotBody.java b/skins-service/service-admin/src/main/java/com/ruoyi/admin/domain/body/AddRobotBody.java
index 453baf9..a749c99 100644
--- a/skins-service/service-admin/src/main/java/com/ruoyi/admin/domain/body/AddRobotBody.java
+++ b/skins-service/service-admin/src/main/java/com/ruoyi/admin/domain/body/AddRobotBody.java
@@ -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 excludeRobotIds;
}
diff --git a/skins-service/service-admin/src/main/java/com/ruoyi/admin/mapper/TtRollMapper.java b/skins-service/service-admin/src/main/java/com/ruoyi/admin/mapper/TtRollMapper.java
index 2e531d6..8c44dd6 100644
--- a/skins-service/service-admin/src/main/java/com/ruoyi/admin/mapper/TtRollMapper.java
+++ b/skins-service/service-admin/src/main/java/com/ruoyi/admin/mapper/TtRollMapper.java
@@ -18,4 +18,9 @@ public interface TtRollMapper extends BaseMapper {
List getRollUser(Integer rollId);
List getRollRobotIds(Integer rollId);
+
+ /**
+ * 查询所有未开奖官方日Roll房中的机器人ID
+ */
+ List getActiveOfficialRollRobotIds();
}
diff --git a/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtOfficialRollConfigServiceImpl.java b/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtOfficialRollConfigServiceImpl.java
index 42ce524..4f8b4f6 100644
--- a/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtOfficialRollConfigServiceImpl.java
+++ b/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtOfficialRollConfigServiceImpl.java
@@ -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");
}
diff --git a/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtRollServiceImpl.java b/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtRollServiceImpl.java
index a630810..6d3fd3c 100644
--- a/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtRollServiceImpl.java
+++ b/skins-service/service-admin/src/main/java/com/ruoyi/admin/service/impl/TtRollServiceImpl.java
@@ -556,9 +556,13 @@ public class TtRollServiceImpl extends ServiceImpl impleme
// 查询已经在房间中的机器人ID
List rollRobotIds = ttRollMapper.getRollRobotIds(addRobotBody.getRollId());
- // 过滤掉已经在房间中的机器人ID
+ // 查询需要排除的机器人ID(例如已在其他官方房中使用的机器人)
+ List excludeRobotIds = addRobotBody.getExcludeRobotIds();
+
+ // 过滤掉已经在房间中或被排除的机器人ID
List 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("可用机器人数量不足");
diff --git a/skins-service/service-admin/src/main/java/com/ruoyi/admin/task/OfficialRollTask.java b/skins-service/service-admin/src/main/java/com/ruoyi/admin/task/OfficialRollTask.java
index 7b3a27d..346f75c 100644
--- a/skins-service/service-admin/src/main/java/com/ruoyi/admin/task/OfficialRollTask.java
+++ b/skins-service/service-admin/src/main/java/com/ruoyi/admin/task/OfficialRollTask.java
@@ -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 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或空则不生成(使用普通密码)。
*/
diff --git a/skins-service/service-admin/src/main/resources/com/ruoyi/admin/mapper/TtRollMapper.xml b/skins-service/service-admin/src/main/resources/com/ruoyi/admin/mapper/TtRollMapper.xml
index be526ba..123d425 100644
--- a/skins-service/service-admin/src/main/resources/com/ruoyi/admin/mapper/TtRollMapper.xml
+++ b/skins-service/service-admin/src/main/resources/com/ruoyi/admin/mapper/TtRollMapper.xml
@@ -61,4 +61,20 @@
WHERE
tru.roll_id = #{rollId} AND tu.user_type = 03
+
+
\ No newline at end of file