Kaynağa Gözat

feat(items): 添加线下道具选择功能和道具激活记录管理

- 新增 selectXianXiaItemsSelList 方法用于查询线下道具选择列表
- 在 ItemsController 中添加 /selectXianXiaItemsSelList 接口
- 在 ItemsMapper 中实现 selectXianXiaItemsSelList 查询方法
- 在 ItemsServiceImpl 中实现 selectXianXiaItemsSelList 业务逻辑
- 添加 PhysicalCardVo 视图对象用于卡包数据传输
- 新增 PhysicalPlayerItemActivation 实体用于玩家道具激活记录
- 添加 PhysicalPlayerItemActivationBo 业务对象
- 创建 PhysicalPlayerItemActivationMapper 数据访问接口
- 实现 PhysicalPlayerItemActivation 相关的 XML 映射文件
- 在 PhysicalTournamentMenuController 中添加审核菜单功能
- 实现 auditTournamentMenu 审核逻辑,包括预报名自动激活道具
- 修改 PhysicalTournamentsRegistration 添加 autoStatus 字段
- 在 UserService 中添加 queryUserList 方法
- 扩展 PlayerItemsMapper 支持卡片类型查询功能
fugui001 1 hafta önce
ebeveyn
işleme
a4b15c68e6
23 değiştirilmiş dosya ile 782 ekleme ve 17 silme
  1. 5 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/controller/ItemsController.java
  2. 102 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/vo/PhysicalCardVo.java
  3. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ItemsMapper.java
  4. 6 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/PlayerItemsMapper.java
  5. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/IItemsService.java
  6. 2 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/IUserService.java
  7. 4 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/ItemsServiceImpl.java
  8. 7 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/UserServiceImpl.java
  9. 13 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/controller/PhysicalTournamentMenuController.java
  10. 95 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/PhysicalPlayerItemActivation.java
  11. 5 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/PhysicalTournamentsRegistration.java
  12. 92 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/bo/PhysicalPlayerItemActivationBo.java
  13. 100 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/vo/PhysicalPlayerItemActivationVo.java
  14. 5 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/vo/PhysicalTournamentsRegistrationVo.java
  15. 42 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/mapper/PhysicalPlayerItemActivationMapper.java
  16. 8 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/IPhysicalTournamentMenuService.java
  17. 84 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/impl/PhysicalTournamentMenuServiceImpl.java
  18. 22 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ItemsMapper.xml
  19. 72 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/PlayerItemsMapper.xml
  20. 104 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalPlayerItemActivationMapper.xml
  21. 0 1
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentLevelHistoryMapper.xml
  22. 1 4
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentRuntimeMapper.xml
  23. 10 5
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentsRegistrationMapper.xml

+ 5 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/controller/ItemsController.java

@@ -112,5 +112,10 @@ public class ItemsController extends BaseController {
     }
 
 
+    @GetMapping("/selectXianXiaItemsSelList")
+    public R<List<ItemsVo>> selectXianXiaItemsSelList() {
+        return R.ok(itemsService.selectXianXiaItemsSelList());
+    }
+
 
 }

+ 102 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/vo/PhysicalCardVo.java

@@ -0,0 +1,102 @@
+package org.dromara.business.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+
+/**
+ * 卡包
+ *
+ * @author Lion Li
+ * @date 2025-09-12
+ */
+@Data
+public class PhysicalCardVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户ID
+     */
+    private Long playerId;
+
+    /**
+     * 道具ID
+     */
+    private Long itemId;
+
+    /**
+     * 道具名称
+     */
+    private String itemName;
+
+    /**
+     * 图标
+     */
+    private String itemUrl;
+
+    /**
+     * 道具数量
+     */
+    private int quantity;
+
+    /**
+     * 用户-真实姓名
+     */
+    private String realName;
+
+    /**
+     * 是否可拆 0 不可拆解 1 可拆
+     */
+    private Boolean isUnpackable;
+
+
+    /**
+     * 是否被绑定 0 未绑定  1 已绑定
+     */
+    private Boolean isBeforeType;
+
+    /**
+     * 过期时间(有效期时间)
+     */
+    private String expireTime;
+
+    /**
+     * 邀请截止类型  0 不限时  1 选择固定日期
+     */
+    private Boolean giveStopType;
+
+
+    /**
+     * 邀请截止时间(赠送截止时间)
+     */
+    private String giveStopTime;
+
+    /**
+     * 是否赠送  0 不可赠送  1 可赠送
+     */
+    private Boolean isGiveAway;
+
+
+    /**
+     * 联赛-赛事ID
+     */
+    private Long leagueTournamentId;
+
+    /**
+     * 道具价值
+     */
+    private BigDecimal itemValue;
+
+    /**
+     * 是否通用道具 0 不通用  1 通用
+     */
+    private Long isCommon;
+
+
+
+}

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ItemsMapper.java

@@ -43,7 +43,8 @@ public interface ItemsMapper extends BaseMapperPlus<Items, ItemsVo> {
     @InterceptorIgnore(tenantLine = "true")
     List<ItemsVo> selectItemsSelList();
 
-
+    @InterceptorIgnore(tenantLine = "true")
+    List<ItemsVo> selectXianXiaItemsSelList();
 
 
 }

+ 6 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/PlayerItemsMapper.java

@@ -5,9 +5,8 @@ import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Param;
-import org.dromara.business.domain.Items;
 import org.dromara.business.domain.PlayerItems;
-import org.dromara.business.domain.vo.ItemsVo;
+import org.dromara.business.domain.vo.PhysicalCardVo;
 import org.dromara.business.domain.vo.PlayerItemsVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
@@ -48,6 +47,11 @@ public interface PlayerItemsMapper extends BaseMapperPlus<PlayerItems, PlayerIte
     @InterceptorIgnore(tenantLine = "true")
     Page<PlayerItemsVo> selectPlayerItemsBackPage(@Param("page") Page<PlayerItems> page, @Param("ew") Wrapper<PlayerItems> wrapper);
 
+    @InterceptorIgnore(tenantLine = "true")
+    List<PhysicalCardVo> selectPlayerItemsList(@Param("childTypeCode") String childTypeCode, @Param("parentTypeCode") String parentTypeCode);
+
+    @InterceptorIgnore(tenantLine = "true")
+    List<PhysicalCardVo> findCardTypeByUserList(@Param("userId") Long userId, @Param("childTypeCode") String childTypeCode, @Param("parentTypeCode") String parentTypeCode);
 
 
 }

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/IItemsService.java

@@ -73,6 +73,6 @@ public interface IItemsService {
      */
     List<ItemsVo> selectItemsSelList();
 
-
+    List<ItemsVo> selectXianXiaItemsSelList();
 
 }

+ 2 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/IUserService.java

@@ -98,4 +98,6 @@ public interface IUserService {
      */
     void removeUserCacheSystemData();
 
+    List<UserVo> queryUserList(UserBo bo);
+
 }

+ 4 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/ItemsServiceImpl.java

@@ -315,5 +315,8 @@ public class ItemsServiceImpl implements IItemsService {
         return baseMapper.selectItemsSelList();
     }
 
-
+    @Override
+    public List<ItemsVo> selectXianXiaItemsSelList() {
+        return baseMapper.selectXianXiaItemsSelList();
+    }
 }

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/UserServiceImpl.java

@@ -559,6 +559,13 @@ public class UserServiceImpl implements IUserService {
         baseMapper.deleteUserMessageStatus();
     }
 
+    @Override
+    public List<UserVo> queryUserList(UserBo bo) {
+        Wrapper<User> lqw = buildQueryWrapper(bo);
+        List<UserVo> userVoList = baseMapper.selectUserList(lqw);
+        return userVoList;
+    }
+
     public boolean verifyCode(String email, String phone, String inputCode) {
         String target = (email != null ? email : phone);
         String storedCode = codeStore.get(target);

+ 13 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/controller/PhysicalTournamentMenuController.java

@@ -102,4 +102,17 @@ public class PhysicalTournamentMenuController extends BaseController {
                           @PathVariable Long[] ids) {
         return toAjax(physicalTournamentMenuService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+     * 审核菜单展示
+     * @param bo
+     * @return
+     */
+    @RepeatSubmit()
+    @PutMapping("/auditTournamentMenu")
+    public R<Void> auditTournamentMenu(@Validated(EditGroup.class) @RequestBody PhysicalTournamentMenuBo bo) {
+        return toAjax(physicalTournamentMenuService.auditTournamentMenu(bo));
+    }
+
+
 }

+ 95 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/PhysicalPlayerItemActivation.java

@@ -0,0 +1,95 @@
+package org.dromara.physical.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.util.Date;
+
+import java.io.Serial;
+
+/**
+ * 玩家道具激活记录对象 physical_player_item_activation
+ *
+ * @author Lion Li
+ * @date 2026-01-30
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("physical_player_item_activation")
+public class PhysicalPlayerItemActivation extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键,自增ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 玩家ID
+     */
+    private Long playerId;
+
+    /**
+     * 原始道具ID(即服务包的item_id)
+     */
+    private Long originalItemId;
+
+    /**
+     * 原始道具名称(如"和成天下挑战赛服务包")
+     */
+    private String originalItemName;
+
+    /**
+     * 激活时间
+     */
+    private Date activationTime;
+
+    /**
+     * 操作人ID(如果是后台操作)
+     */
+    private Long operatorId;
+
+    /**
+     * 操作类型:固定取值 - "user": 用户自助激活, "admin": 管理员后台激活
+     */
+    private String operatorType;
+
+    /**
+     * 激活状态:固定取值 - "success": 成功, "failed": 失败
+     */
+    private String activeStatus;
+
+    /**
+     * 失败原因(如库存不足、已过期等)
+     */
+    private String reason;
+
+    /**
+     * 联赛ID
+     */
+    private Long leagueTournamentId;
+
+    /**
+     * 拆分后的子道具列表(JSON格式),如:[{"item_id":1001,"name":"入场券","quantity":1}, ...]
+     */
+    private String splitItemsJson;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+    /**
+     *
+     */
+    private Date updatedAt;
+
+    /**
+     *  业务类型  user_split 用户拆包   web_action 后台激活
+     */
+    private String businessType;
+}

+ 5 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/PhysicalTournamentsRegistration.java

@@ -43,7 +43,7 @@ public class PhysicalTournamentsRegistration extends BaseEntity {
     private String imageUrl;
 
     /**
-     * 审核状态:pending=待审核,approved=已通过,rejected=已拒绝
+     * 审核状态:pending=待审核,approved=已通过,rejected=已拒绝  auto = 自动审核
      */
     private String status;
 
@@ -72,5 +72,8 @@ public class PhysicalTournamentsRegistration extends BaseEntity {
      */
     private String auditorName;
 
-
+    /**
+     * 1 后台自动绑定  2 用户提交
+     */
+    private Integer autoStatus;
 }

+ 92 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/bo/PhysicalPlayerItemActivationBo.java

@@ -0,0 +1,92 @@
+package org.dromara.physical.domain.bo;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import org.dromara.physical.domain.PhysicalPlayerItemActivation;
+
+import java.util.Date;
+
+/**
+ * 玩家道具激活记录业务对象 physical_player_item_activation
+ *
+ * @author Lion Li
+ * @date 2026-01-30
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = PhysicalPlayerItemActivation.class, reverseConvertGenerate = false)
+public class PhysicalPlayerItemActivationBo extends BaseEntity {
+
+    /**
+     * 主键,自增ID
+     */
+    @NotNull(message = "主键,自增ID不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 玩家ID
+     */
+    @NotNull(message = "玩家ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long playerId;
+
+    /**
+     * 原始道具ID(即服务包的item_id)
+     */
+    @NotNull(message = "原始道具ID(即服务包的item_id)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long originalItemId;
+
+    /**
+     * 原始道具名称(如"和成天下挑战赛服务包")
+     */
+    private String originalItemName;
+
+    /**
+     * 激活时间
+     */
+    @NotNull(message = "激活时间不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date activationTime;
+
+    /**
+     * 操作人ID(如果是后台操作)
+     */
+    private Long operatorId;
+
+    /**
+     * 操作类型:固定取值 - "user": 用户自助激活, "admin": 管理员后台激活
+     */
+    private String operatorType;
+
+    /**
+     * 激活状态:固定取值 - "success": 成功, "failed": 失败
+     */
+    private String activeStatus;
+
+    /**
+     * 失败原因(如库存不足、已过期等)
+     */
+    private String reason;
+
+    /**
+     * 拆分后的子道具列表(JSON格式),如:[{"item_id":1001,"name":"入场券","quantity":1}, ...]
+     */
+    private String splitItemsJson;
+
+    /**
+     *
+     */
+    @NotNull(message = "不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date createdAt;
+
+    /**
+     *
+     */
+    @NotNull(message = "不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date updatedAt;
+
+
+}

+ 100 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/vo/PhysicalPlayerItemActivationVo.java

@@ -0,0 +1,100 @@
+package org.dromara.physical.domain.vo;
+
+import java.util.Date;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.physical.domain.PhysicalPlayerItemActivation;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+
+/**
+ * 玩家道具激活记录视图对象 physical_player_item_activation
+ *
+ * @author Lion Li
+ * @date 2026-01-30
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = PhysicalPlayerItemActivation.class)
+public class PhysicalPlayerItemActivationVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键,自增ID
+     */
+    @ExcelProperty(value = "主键,自增ID")
+    private Long id;
+
+    /**
+     * 玩家ID
+     */
+    @ExcelProperty(value = "玩家ID")
+    private Long playerId;
+
+    /**
+     * 原始道具ID(即服务包的item_id)
+     */
+    @ExcelProperty(value = "原始道具ID", converter = ExcelDictConvert.class)
+    private Long originalItemId;
+
+    /**
+     * 原始道具名称(如"和成天下挑战赛服务包")
+     */
+    private String originalItemName;
+
+    /**
+     * 激活时间
+     */
+    @ExcelProperty(value = "激活时间")
+    private Date activationTime;
+
+    /**
+     * 操作人ID(如果是后台操作)
+     */
+    @ExcelProperty(value = "操作人ID", converter = ExcelDictConvert.class)
+    private Long operatorId;
+
+    /**
+     * 操作类型:固定取值 - "user": 用户自助激活, "admin": 管理员后台激活
+     */
+    private String operatorType;
+
+    /**
+     * 激活状态:固定取值 - "success": 成功, "failed": 失败
+     */
+    private String activeStatus;
+
+    /**
+     * 失败原因(如库存不足、已过期等)
+     */
+    @ExcelProperty(value = "失败原因", converter = ExcelDictConvert.class)
+    private String reason;
+
+    /**
+     * 拆分后的子道具列表(JSON格式),如:[{"item_id":1001,"name":"入场券","quantity":1}, ...]
+     */
+    @ExcelProperty(value = "拆分后的子道具列表", converter = ExcelDictConvert.class)
+    private String splitItemsJson;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Date createdAt;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Date updatedAt;
+
+
+}

+ 5 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/vo/PhysicalTournamentsRegistrationVo.java

@@ -73,6 +73,11 @@ public class PhysicalTournamentsRegistrationVo implements Serializable {
     //@ExcelProperty(value = "审核状态:pending=待审核,approved=已通过,rejected=已拒绝")
     private String status;
 
+    /**
+     * 1 后台自动绑定  2 用户提交
+     */
+    private Integer autoStatus;
+
     @ExcelProperty(value = "审核状态")
     private String statusText;
 

+ 42 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/mapper/PhysicalPlayerItemActivationMapper.java

@@ -0,0 +1,42 @@
+package org.dromara.physical.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.physical.domain.PhysicalPlayerItemActivation;
+import org.dromara.physical.domain.PhysicalTag;
+import org.dromara.physical.domain.vo.PhysicalPlayerItemActivationVo;
+
+import java.util.List;
+
+/**
+ * 玩家道具激活记录Mapper接口
+ *
+ * @author Lion Li
+ * @date 2026-01-30
+ */
+@DS("mysql2")
+public interface PhysicalPlayerItemActivationMapper extends BaseMapperPlus<PhysicalPlayerItemActivation, PhysicalPlayerItemActivationVo> {
+
+    @InterceptorIgnore(tenantLine = "true")
+    int insertPlayerItemActivation(PhysicalPlayerItemActivation physicalPlayerItemActivation);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int updatePlayerItemActivationById(PhysicalPlayerItemActivation physicalPlayerItemActivation);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int deletePlayerItemActivationById(Long id);
+
+    @InterceptorIgnore(tenantLine = "true")
+    Page<PhysicalPlayerItemActivationVo> selectPlayerItemActivationPage(@Param("page") Page<PhysicalTag> page, @Param("ew") Wrapper<PhysicalTag> wrapper);
+
+    @InterceptorIgnore(tenantLine = "true")
+    List<PhysicalPlayerItemActivationVo> selectPlayerItemActivationList(@Param("ew") Wrapper<PhysicalTag> wrapper);
+
+    @InterceptorIgnore(tenantLine = "true")
+    PhysicalPlayerItemActivationVo selectPlayerItemActivationById(Long id);
+
+}

+ 8 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/IPhysicalTournamentMenuService.java

@@ -65,4 +65,12 @@ public interface IPhysicalTournamentMenuService {
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     *  TournamentMenu 审核
+     *
+     * @param bo  TournamentMenu
+     * @return 是否审核成功
+     */
+    Boolean auditTournamentMenu(PhysicalTournamentMenuBo bo);
 }

+ 84 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/impl/PhysicalTournamentMenuServiceImpl.java

@@ -1,5 +1,11 @@
 package org.dromara.physical.service.impl;
 
+import org.dromara.business.domain.bo.UserBo;
+import org.dromara.business.domain.vo.PhysicalCardVo;
+import org.dromara.business.domain.vo.UserVo;
+import org.dromara.business.mapper.PlayerItemsMapper;
+import org.dromara.business.mapper.UserMapper;
+import org.dromara.business.service.IUserService;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -9,13 +15,21 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.physical.domain.PhysicalLeagueTournament;
+import org.dromara.physical.domain.PhysicalPlayerItemActivation;
 import org.dromara.physical.domain.PhysicalTournamentMenu;
+import org.dromara.physical.domain.PhysicalTournamentsRegistration;
 import org.dromara.physical.domain.bo.PhysicalTournamentMenuBo;
+import org.dromara.physical.domain.vo.PhysicalLeagueTournamentVo;
 import org.dromara.physical.domain.vo.PhysicalTournamentMenuVo;
+import org.dromara.physical.mapper.PhysicalLeagueTournamentMapper;
+import org.dromara.physical.mapper.PhysicalPlayerItemActivationMapper;
 import org.dromara.physical.mapper.PhysicalTournamentMenuMapper;
+import org.dromara.physical.mapper.PhysicalTournamentsRegistrationMapper;
 import org.dromara.physical.service.IPhysicalTournamentMenuService;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Collection;
@@ -33,6 +47,16 @@ public class PhysicalTournamentMenuServiceImpl implements IPhysicalTournamentMen
 
     private final PhysicalTournamentMenuMapper baseMapper;
 
+    private final PhysicalPlayerItemActivationMapper itemActivationMapper;
+
+    private final IUserService userService;
+
+    private final PlayerItemsMapper playerItemsMapper;
+
+    private final PhysicalLeagueTournamentMapper physicalLeagueTournamentMapper;
+
+    private final PhysicalTournamentsRegistrationMapper physicalTournamentsRegistrationMapper;
+
     /**
      * 查询锦标赛功能菜单配置
      *
@@ -151,4 +175,64 @@ public class PhysicalTournamentMenuServiceImpl implements IPhysicalTournamentMen
         }
         return baseMapper.deleteTournamentMenuById(ids) > 0;
     }
+
+    @Override
+    public Boolean auditTournamentMenu(PhysicalTournamentMenuBo bo) {
+        PhysicalTournamentMenu update = MapstructUtils.convert(bo, PhysicalTournamentMenu.class);
+        validEntityBeforeSave(update);
+        long currentTimeMillis = System.currentTimeMillis();
+        update.setUpdatedAt(currentTimeMillis);
+        //校验相关key 是否已存在
+        PhysicalTournamentMenuVo physicalTournamentMenuVo = baseMapper.selectTournamentMenuKeyExit(bo.getMenuKey(),bo.getId());
+        if (physicalTournamentMenuVo != null) {
+            throw new RuntimeException("唯一标识key已存在");
+        }
+        //联赛未开启 不能打开   会不会有用户在时间到了的时候再获得一次  也就是在开启菜单的时候
+        List<PhysicalLeagueTournamentVo> physicalLeagueTournamentVoList = physicalLeagueTournamentMapper.selectPhysicalLeagueTournamentSelList();
+        if(physicalLeagueTournamentVoList==null){
+            throw new RuntimeException("联赛未开启");
+        }
+
+        int counts=baseMapper.updateTournamentMenuById(update);
+        if(counts>0){
+            if(bo.getMenuKey().equals("pre_registration_type") && bo.getStatus()==1L){
+                //激活之后  插入预报名记录里面
+
+                //如果是预报名的   查看所有用户是不是有主赛卡,有的话默认激活一张
+                UserBo userBo=new UserBo();
+                List<UserVo> userVoList = userService.queryUserList(userBo);
+                for (UserVo userVo : userVoList) {
+                    List<PhysicalCardVo> cardVoUserList = playerItemsMapper.findCardTypeByUserList(userVo.getId(),"main_tournament","");
+                    if(!cardVoUserList.isEmpty()){
+                        // 随机选择一张用户的主赛卡进行激活
+                        int randomIndex = (int) (Math.random() * cardVoUserList.size());
+                        PhysicalCardVo selectedCard = cardVoUserList.get(randomIndex);
+                        PhysicalPlayerItemActivation physicalPlayerItemActivation = new PhysicalPlayerItemActivation();
+                        physicalPlayerItemActivation.setPlayerId(userVo.getId());
+                        physicalPlayerItemActivation.setOriginalItemId(selectedCard.getItemId());
+                        physicalPlayerItemActivation.setOriginalItemName(selectedCard.getItemName());
+                        physicalPlayerItemActivation.setActivationTime(new Date());
+                        physicalPlayerItemActivation.setActiveStatus("active");
+                        physicalPlayerItemActivation.setOperatorType("admin");
+                        physicalPlayerItemActivation.setBusinessType("web_action");
+                        physicalPlayerItemActivation.setCreatedAt(new Date());
+                        physicalPlayerItemActivation.setReason("预赛报名随机激活主赛相关道具");
+                        physicalPlayerItemActivation.setLeagueTournamentId(physicalLeagueTournamentVoList.get(0).getId());
+                        physicalPlayerItemActivation.setUpdatedAt(new Date());
+                        itemActivationMapper.insertPlayerItemActivation(physicalPlayerItemActivation);
+
+                        PhysicalTournamentsRegistration physicalTournamentsRegistration=new PhysicalTournamentsRegistration();
+                        physicalTournamentsRegistration.setLeagueTournamentId(physicalLeagueTournamentVoList.get(0).getId());
+                        physicalTournamentsRegistration.setCreatedAt(new Date());
+                        physicalTournamentsRegistration.setUserId(userVo.getId());
+                        physicalTournamentsRegistration.setAutoStatus(1);
+                        physicalTournamentsRegistration.setStatus("approved");
+                        physicalTournamentsRegistrationMapper.insertPhysicalTournamentsRegistration(physicalTournamentsRegistration);
+                    }
+                }
+           }
+         }
+        return counts > 0;
+    }
+
 }

+ 22 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ItemsMapper.xml

@@ -141,4 +141,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT  id,is_common,name, item_type,item_desc, created_at, updated_at,item_value,effective_type,expire_time, effective_day, gift_type_parent_id, gift_type_child_id, item_url, is_give_away, item_count,give_stop_type,give_stop_time FROM items
     </select>
 
+
+    <select id="selectXianXiaItemsSelList" resultType="org.dromara.business.domain.vo.ItemsVo">
+      SELECT DISTINCT
+            i.id, i.name, i.item_type,i.item_desc, i.created_at, i.updated_at,i.item_value,i.item_json
+                      ,i.item_type_code,i.effective_type,i.expire_time, i.effective_day, i.gift_type_parent_id,
+                       i.gift_type_child_id, i.item_url, i.is_give_away, i.item_count,i.is_common,
+                       i.give_stop_type,i.give_stop_time,
+           -- 布尔标志字段
+            (i.give_stop_type = 1) AS give_stop_type,
+            (i.is_give_away = 1) AS is_give_away_flag,
+            (gt_parent.type_code = 'combo_package') AS is_unpackable
+
+        FROM items i
+                 LEFT JOIN gift_type gt_child ON i.gift_type_child_id = gt_child.id
+                 LEFT JOIN gift_type gt_parent ON i.gift_type_parent_id = gt_parent.id
+        WHERE
+            (
+                gt_child.type_code = 'main_tournament'  OR     gt_child.type_code = 'side_tournament'
+
+                )
+    </select>
+
 </mapper>

+ 72 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/PlayerItemsMapper.xml

@@ -84,5 +84,77 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             player_items  ${ew.customSqlSegment}
     </select>
 
+    <select id="findCardTypeList" resultType="org.dromara.business.domain.vo.PhysicalCardVo" >
+        SELECT DISTINCT
+            i.id AS item_id,
+            i.name AS item_name,
+            i.item_url,
+            i.give_stop_time,
+            -- 布尔标志字段
+            (i.give_stop_type = 1) AS give_stop_type,
+            (i.is_give_away = 1) AS is_give_away_flag,
+            (gt_parent.type_code = 'combo_package') AS is_unpackable
+
+        FROM items i
+                 LEFT JOIN gift_type gt_child ON i.gift_type_child_id = gt_child.id
+                 LEFT JOIN gift_type gt_parent ON i.gift_type_parent_id = gt_parent.id
+        WHERE
+            (
+                gt_child.type_code =#{childTypeCode}
+                    OR gt_parent.type_code = #{parentTypeCode}
+                )
+    </select>
+
+
+    <select id="findCardTypeByUserList" resultType="org.dromara.business.domain.vo.PhysicalCardVo" >
+        SELECT DISTINCT
+            pi.player_id,
+            pi.item_id,
+            pi.quantity,
+            pi.expire_time,
+            i.give_stop_time,
+            i.name AS item_name,
+            i.item_value,
+            i.is_common,
+            uu.real_name,
+            i.item_url AS item_url,
+            -- 修复:添加 CASE
+            CASE
+                WHEN i.give_stop_type = 1 THEN TRUE
+                ELSE FALSE
+                END AS give_stop_type,  -- ⚠️ 建议改名,避免和原字段同名
+
+            CASE
+                WHEN pi.is_before_type = 1 THEN TRUE
+                ELSE FALSE
+                END AS is_before_type_flag,
+
+            CASE
+                WHEN i.is_give_away = 1 THEN TRUE
+                ELSE FALSE
+                END AS is_give_away_flag,
+
+            CASE
+                WHEN gt_parent.type_code = 'combo_package' THEN TRUE
+                ELSE FALSE
+                END AS is_unpackable
+        FROM player_items pi
+                 INNER JOIN items i ON pi.item_id = i.id
+                 LEFT JOIN gift_type gt_child ON i.gift_type_child_id = gt_child.id
+                 LEFT JOIN gift_type gt_parent ON i.gift_type_parent_id = gt_parent.id
+                 LEFT JOIN user uu ON pi.player_id = uu.id
+        WHERE
+            pi.player_id = #{userId}
+          AND (
+            gt_child.type_code = #{childTypeCode}
+                OR gt_parent.type_code = #{parentTypeCode}
+            )
+          AND (
+            pi.expire_time IS NULL
+                OR pi.expire_time >= NOW()
+            )
+    </select>
+
+
 </mapper>
 

+ 104 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalPlayerItemActivationMapper.xml

@@ -0,0 +1,104 @@
+<?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="org.dromara.physical.mapper.PhysicalPlayerItemActivationMapper">
+
+    <select id="selectPlayerItemActivationPage" resultType="org.dromara.physical.domain.vo.PhysicalPlayerItemActivationVo">
+         SELECT
+                 id, player_id, original_item_id, original_item_name,
+                 activation_time, operator_id, operator_type, active_status,
+                 reason, split_items_json, created_at, updated_at, business_type
+             FROM physical_player_item_activation  ${ew.customSqlSegment}
+    </select>
+
+    <select id="selectPlayerItemActivationList" resultType="org.dromara.physical.domain.vo.PhysicalPlayerItemActivationVo">
+        SELECT
+            id, player_id, original_item_id, original_item_name,
+            activation_time, operator_id, operator_type, active_status,
+            reason, split_items_json, created_at, updated_at, business_type
+        FROM physical_player_item_activation ${ew.customSqlSegment}
+    </select>
+
+    <select id="selectPlayerItemActivationById" resultType="org.dromara.physical.domain.vo.PhysicalPlayerItemActivationVo">
+        SELECT
+            id, player_id, original_item_id, original_item_name,
+            activation_time, operator_id, operator_type, active_status,
+            reason, split_items_json, created_at, updated_at, business_type
+        FROM physical_player_item_activation  where id = #{id}
+    </select>
+
+    <!-- 插入:校验非空字段(position, image_url 必填) -->
+    <insert id="insertPlayerItemActivation" useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO physical_player_item_activation (
+            player_id,
+            original_item_id,
+            original_item_name,
+            activation_time,
+            operator_id,
+            operator_type,
+            active_status,
+            reason,
+            split_items_json,
+            business_type,
+            created_at,
+            updated_at
+        ) VALUES (
+                     #{playerId},
+                     #{originalItemId},
+                     #{originalItemName},
+                     #{activationTime},
+                     #{operatorId},
+                     #{operatorType},
+                     #{activeStatus},
+                     #{reason},
+                     #{splitItemsJson},
+                     #{businessType},
+                     NOW(),
+                     NOW()
+                 )
+    </insert>
+
+    <!-- 更新:仅更新非空字段,且校验必要字段不为空 -->
+    <update id="updatePlayerItemActivationById">
+        UPDATE physical_player_item_activation
+        <set>
+            <if test="playerId != null">player_id = #{playerId},</if>
+            <if test="originalItemId != null">original_item_id = #{originalItemId},</if>
+            <if test="originalItemName != null and originalItemName != ''">
+                original_item_name = #{originalItemName},
+            </if>
+            <if test="activationTime != null">activation_time = #{activationTime},</if>
+            <if test="operatorId != null">operator_id = #{operatorId},</if>
+            <if test="operatorType != null and operatorType != ''">
+                operator_type = #{operatorType},
+            </if>
+            <if test="activeStatus != null and activeStatus != ''">
+                active_status = #{activeStatus},
+            </if>
+            <if test="reason != null">reason = #{reason},</if>
+            <if test="splitItemsJson != null and splitItemsJson != ''">
+                split_items_json = #{splitItemsJson},
+            </if>
+            <if test="businessType != null and businessType != ''">
+                business_type = #{businessType},
+            </if>
+            updated_at = NOW()
+        </set>
+        WHERE id = #{id}
+    </update>
+
+
+    <delete id="deletePlayerItemActivationById">
+        DELETE FROM physical_player_item_activation
+        <where>
+            id IN
+            <foreach item="id" collection="ids" open="(" separator="," close=")">
+                <if test="id > 0">
+                    #{id}
+                </if>
+            </foreach>
+        </where>
+    </delete>
+
+</mapper>

+ 0 - 1
ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentLevelHistoryMapper.xml

@@ -21,7 +21,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="adjustedDurationMinutes != null">adjusted_duration_minutes,</if>
         <if test="status != null and status != ''">status,</if>
         <if test="displayOrder != null and displayOrder != ''">display_order,</if>
-
     </trim>
     <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
         <if test="tournamentId != null">#{tournamentId},</if>

+ 1 - 4
ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentRuntimeMapper.xml

@@ -46,10 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="status != null">
                 status = #{status, jdbcType=VARCHAR},
             </if>
-            <if test="status != null">
-                tournament_begin_time = #{tournamentBeginTime},
-            </if>
-            <if test="lastLevelSwitchTime != null">
+             <if test="lastLevelSwitchTime != null">
                 last_level_switch_time = #{lastLevelSwitchTime, jdbcType=TIMESTAMP},
             </if>
             updated_at = CURRENT_TIMESTAMP

+ 10 - 5
ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentsRegistrationMapper.xml

@@ -17,7 +17,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             created_at,
             audited_at,
             auditor_id,
-            auditor_name
+            auditor_name,
+            auto_status
         FROM physical_tournaments_registration  ${ew.customSqlSegment}
     </select>
 
@@ -33,7 +34,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             created_at,
             audited_at,
             auditor_id,
-            auditor_name
+            auditor_name,
+            auto_status
         FROM physical_tournaments_registration   where id = #{id}
     </select>
 
@@ -48,7 +50,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             created_at,
             audited_at,
             auditor_id,
-            auditor_name
+            auditor_name,
+            auto_status
         FROM physical_tournaments_registration  ${ew.customSqlSegment}
     </select>
 
@@ -63,7 +66,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             created_at,
             audited_at,
             auditor_id,
-            auditor_name
+            auditor_name,
+            auto_status
         ) VALUES (
                      #{userId},
                      #{leagueTournamentId},
@@ -73,7 +77,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                      #{createdAt},
                      #{auditedAt},
                      #{auditorId},
-                     #{auditorName}
+                     #{auditorName},
+                     #{autoStatus}
                  )
     </insert>