This commit is contained in:
2026-04-28 10:34:29 +08:00
parent 77b16a12f1
commit db76c41753
13 changed files with 428 additions and 55 deletions

View File

@@ -3,6 +3,7 @@ package com.ruoyi.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.admin.domain.body.AddRobotBody;
import com.ruoyi.admin.service.TtRollCdkService;
import com.ruoyi.admin.service.TtRollService;
import com.ruoyi.admin.service.TtRollUserService;
import com.ruoyi.common.core.controller.BaseController;
@@ -16,6 +17,7 @@ import com.ruoyi.domain.dto.roll.GetRollPrizePool;
import com.ruoyi.domain.dto.roll.InviteRollUser;
import com.ruoyi.domain.entity.roll.TtRoll;
import com.ruoyi.domain.entity.roll.TtRollBody;
import com.ruoyi.domain.entity.roll.TtRollCdk;
import com.ruoyi.domain.entity.roll.TtRollUser;
import com.ruoyi.domain.entity.sys.TtUser;
import com.ruoyi.domain.vo.TtRollPrizeDataVO;
@@ -37,11 +39,14 @@ public class TtRollController extends BaseController {
private final TtRollService rollService;
private final TtRollUserService rollUserService;
private final TtRollCdkService rollCdkService;
public TtRollController(TtRollService rollService,
TtRollUserService rollUserService) {
TtRollUserService rollUserService,
TtRollCdkService rollCdkService) {
this.rollService = rollService;
this.rollUserService = rollUserService;
this.rollCdkService = rollCdkService;
}
@GetMapping("/list")
@@ -177,4 +182,37 @@ public class TtRollController extends BaseController {
public AjaxResult addRobot(@RequestBody AddRobotBody addRobotBody) {
return rollService.addRobot(addRobotBody);
}
@Data
public static class GenerateCdkBody {
/** Roll房ID */
@NotNull(message = "rollId不能为空")
private Integer rollId;
/** 要生成的CDK数量 */
@NotNull(message = "数量不能为空")
private Integer count;
}
/** 为Roll房批量生成CDK */
@ApiOperation("为Roll房批量生成CDK")
@PostMapping("/cdk/generate")
public AjaxResult generateCdk(@RequestBody @Validated GenerateCdkBody body) {
rollCdkService.generateCdks(body.getRollId(), body.getCount());
return success("生成成功");
}
/** 查看Roll房所有CDK列表 */
@ApiOperation("查看Roll房CDK列表")
@GetMapping("/cdk/list/{rollId}")
public AjaxResult getCdkList(@PathVariable("rollId") Integer rollId) {
List<TtRollCdk> list = rollCdkService.listByRollId(rollId);
return success(list);
}
/** 删除指定CDK */
@ApiOperation("删除CDK")
@DeleteMapping("/cdk/{cdkId}")
public AjaxResult deleteCdk(@PathVariable("cdkId") Integer cdkId) {
return toAjax(rollCdkService.removeById(cdkId));
}
}

View File

@@ -0,0 +1,17 @@
package com.ruoyi.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.domain.entity.roll.TtRollCdk;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface TtRollCdkMapper extends BaseMapper<TtRollCdk> {
/**
* 查询Roll房的所有CDK列表
*/
List<TtRollCdk> listByRollId(@Param("rollId") Integer rollId);
}

View File

@@ -0,0 +1,28 @@
package com.ruoyi.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.domain.entity.roll.TtRollCdk;
import java.util.List;
public interface TtRollCdkService extends IService<TtRollCdk> {
/**
* 为指定Roll房批量生成 count 个 CDK
*/
void generateCdks(Integer rollId, int count);
/**
* 查询Roll房所有CDK列表
*/
List<TtRollCdk> listByRollId(Integer rollId);
/**
* 使用CDK验证并占用成功返回 true失败返回错误信息
* @param rollId Roll房ID
* @param cdkCode 用户输入的CDK码
* @param userId 使用者ID
* @return null 表示验证通过;非 null 字符串为错误原因
*/
String useCdk(Integer rollId, String cdkCode, Integer userId);
}

View File

@@ -0,0 +1,72 @@
package com.ruoyi.admin.service.impl;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.admin.mapper.TtRollCdkMapper;
import com.ruoyi.admin.service.TtRollCdkService;
import com.ruoyi.domain.entity.roll.TtRollCdk;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Service
public class TtRollCdkServiceImpl extends ServiceImpl<TtRollCdkMapper, TtRollCdk>
implements TtRollCdkService {
@Override
public void generateCdks(Integer rollId, int count) {
List<TtRollCdk> cdkList = new ArrayList<>();
for (int i = 0; i < count; i++) {
// 生成32位随机码去掉横线全大写
String code = UUID.randomUUID().toString().replace("-", "").toUpperCase();
TtRollCdk cdk = TtRollCdk.builder()
.rollId(rollId)
.cdkCode(code)
.status("0") // 0=未使用
.createTime(new Date())
.build();
cdkList.add(cdk);
}
this.saveBatch(cdkList);
}
@Override
public List<TtRollCdk> listByRollId(Integer rollId) {
return baseMapper.listByRollId(rollId);
}
@Override
public String useCdk(Integer rollId, String cdkCode, Integer userId) {
// 1. 查找这个 CDK 是否存在且属于该Roll房
TtRollCdk cdk = new LambdaQueryChainWrapper<>(baseMapper)
.eq(TtRollCdk::getRollId, rollId)
.eq(TtRollCdk::getCdkCode, cdkCode)
.one();
if (cdk == null) {
return "CDK不存在或不属于该房间";
}
if ("1".equals(cdk.getStatus())) {
return "该CDK已被使用请使用新的CDK";
}
// 2. 原子更新CAS 将 status 从 0 改为 1防止并发
boolean updated = new LambdaUpdateChainWrapper<>(baseMapper)
.eq(TtRollCdk::getId, cdk.getId())
.eq(TtRollCdk::getStatus, "0") // 乐观锁:只有未使用才能更新
.set(TtRollCdk::getStatus, "1")
.set(TtRollCdk::getUsedUserId, userId)
.set(TtRollCdk::getUsedTime, new Date())
.update();
if (!updated) {
return "该CDK已被使用请使用新的CDK";
}
return null; // null 表示成功
}
}

View File

@@ -0,0 +1,12 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.admin.mapper.TtRollCdkMapper">
<select id="listByRollId" resultType="com.ruoyi.domain.entity.roll.TtRollCdk">
SELECT id, roll_id, cdk_code, status, used_user_id, used_time, create_time
FROM tt_roll_cdk
WHERE roll_id = #{rollId}
ORDER BY id ASC
</select>
</mapper>

View File

@@ -62,6 +62,8 @@ public class ApiRollController extends BaseController {
@NotNull(message = "roll房id不能为空。")
private Integer rollId;
private String rollPassword;
// 新增CDK码有CDK的房间必填
private String cdkCode;
}
@ApiOperation("加入ROLL房")
@@ -173,4 +175,5 @@ public class ApiRollController extends BaseController {
return "1";
}
}

View File

@@ -10,6 +10,7 @@ import com.ruoyi.admin.config.RedisConstants;
import com.ruoyi.admin.mapper.*;
import com.ruoyi.admin.service.TtBoxRecordsService;
import com.ruoyi.admin.service.TtOrnamentsLevelService;
import com.ruoyi.admin.service.TtRollCdkService;
import com.ruoyi.admin.service.TtRollUserService;
import com.ruoyi.admin.util.RandomUtils;
import com.ruoyi.common.core.domain.R;
@@ -121,9 +122,12 @@ public class ApiRollServiceImpl extends ServiceImpl<TtRollMapper, TtRoll> implem
@Autowired
private TtBoxRecordsMapper ttBoxRecordsMapper;
@Autowired
private TtRollCdkService ttRollCdkService;
public R<TtRoll> joinRollCheck(TtRoll ttRoll, TtRollUser rollUser, TtUser player, JoinRollParam param) {
if (StringUtils.isNull(ttRoll)) return R.fail("当前Roll房已结束");
/*if (StringUtils.isNull(ttRoll)) return R.fail("当前Roll房已结束");
if (StringUtils.isNotNull(rollUser)) return R.fail("您当前已在该房间内,请勿重复加入房间!");
String password = ttRoll.getRollPassword();
@@ -139,6 +143,41 @@ public class ApiRollServiceImpl extends ServiceImpl<TtRollMapper, TtRoll> implem
if (minRecharge.compareTo(rechargeTotalAmount) > 0) return R.fail("未满足该房间的充值条件!");
}
return R.ok();*/
if (StringUtils.isNull(ttRoll)) return R.fail("当前Roll房已结束");
if (StringUtils.isNotNull(rollUser)) return R.fail("您当前已在该房间内,请勿重复加入房间!");
// ---- CDK 模式校验有CDK则走CDK否则走普通密码----
boolean hasCdk = ttRollCdkService.count(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TtRollCdk>()
.eq(TtRollCdk::getRollId, ttRoll.getId())
) > 0;
if (hasCdk) {
// CDK 模式:必须提供 cdkCode
if (StringUtils.isEmpty(param.getCdkCode())) {
return R.fail("该房间需要CDK才能参与请输入CDK");
}
String cdkError = ttRollCdkService.useCdk(ttRoll.getId(), param.getCdkCode(), player.getUserId());
if (cdkError != null) {
return R.fail(cdkError);
}
} else {
// 普通密码模式(兼容原有逻辑)
String password = ttRoll.getRollPassword();
if (StringUtils.isNotEmpty(password)) {
if (StringUtils.isEmpty(param.getRollPassword())) return R.fail("请输入密码!");
if (!password.equals(param.getRollPassword())) return R.fail("密码错误!");
}
}
// 检查加入条件:充值下限(原有逻辑保留)
BigDecimal minRecharge = ttRoll.getMinRecharge();
if (minRecharge != null && minRecharge.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal rechargeTotalAmount = getRechargeTotalAmount(player.getUserId(), ttRoll.getRechargeStartTime());
if (minRecharge.compareTo(rechargeTotalAmount) > 0) return R.fail("未满足该房间的充值条件!");
}
return R.ok();
}
@@ -524,6 +563,12 @@ public class ApiRollServiceImpl extends ServiceImpl<TtRollMapper, TtRoll> implem
RollDetailsDataVO data = apiRollMapper.getRollDetails(rollId);
data.setHasPW(!StringUtils.isBlank(ttRoll.getRollPassword()));
// 判断是否有CDK
long cdkCount = ttRollCdkService.count(
new LambdaQueryWrapper<TtRollCdk>().eq(TtRollCdk::getRollId, rollId)
);
data.setHasCdk(cdkCount > 0);
// 成员
// List<TtRollUser> list = new LambdaQueryChainWrapper<>(ttRollUserMapper)
// .eq(TtRollUser::getRollId, rollId)