Parcourir la source

feat(schedule): 添加赛事组别配置功能

- 新增赛事组别配置主Service接口和实现类
- 创建赛事组别配置相关的实体类和业务对象
- 实现赛事组别配置的增删改查功能
- 添加赛事组别配置的控制器和映射文件
- 实现生成系列赛功能,支持常规赛和决赛的生成
- 在TournamentsTemplateService中添加模板列表查询方法
- 修复PhysicalJudgePositionRelationMapper的返回类型
- 添加spring-test依赖支持测试功能
fugui001 il y a 23 heures
Parent
commit
075958a26a
20 fichiers modifiés avec 1374 ajouts et 1 suppressions
  1. 4 0
      ruoyi-modules/ruoyi-system/pom.xml
  2. 118 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/controller/ScheduleEventGroupConfigController.java
  3. 7 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/controller/TournamentsTemplateController.java
  4. 57 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/ScheduleEventGroupConfig.java
  5. 68 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/ScheduleEventGroupItem.java
  6. 65 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/bo/ScheduleEventGroupConfigBo.java
  7. 69 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/bo/ScheduleEventGroupItemBo.java
  8. 85 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/vo/ScheduleEventGroupConfigVo.java
  9. 82 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/vo/ScheduleEventGroupItemVo.java
  10. 43 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ScheduleEventGroupConfigMapper.java
  11. 38 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ScheduleEventGroupItemMapper.java
  12. 2 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/TournamentsTemplateMapper.java
  13. 76 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/IScheduleEventGroupConfigService.java
  14. 2 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/ITournamentsTemplateService.java
  15. 478 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/ScheduleEventGroupConfigServiceImpl.java
  16. 5 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/impl/TournamentsTemplateServiceImpl.java
  17. 90 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ScheduleEventGroupConfigMapper.xml
  18. 81 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ScheduleEventGroupItemMapper.xml
  19. 3 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/TournamentsTemplateMapper.xml
  20. 1 1
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalJudgePositionRelationMapper.xml

+ 4 - 0
ruoyi-modules/ruoyi-system/pom.xml

@@ -114,6 +114,10 @@
             <artifactId>aliyun-java-sdk-core</artifactId>
             <version>4.5.9</version> <!-- 请检查是否有更新版本 -->
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 118 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/controller/ScheduleEventGroupConfigController.java

@@ -0,0 +1,118 @@
+package org.dromara.business.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.business.domain.bo.ScheduleEventGroupConfigBo;
+import org.dromara.business.domain.vo.ScheduleEventGroupConfigVo;
+import org.dromara.business.service.IScheduleEventGroupConfigService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil; ;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 赛事组别配置主
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/business/eventGroupConfig")
+public class ScheduleEventGroupConfigController extends BaseController {
+
+    private final IScheduleEventGroupConfigService scheduleEventGroupConfigService;
+
+    /**
+     * 查询赛事组别配置主列表
+     */
+    @SaCheckPermission("business:eventGroupConfig:list")
+    @GetMapping("/list")
+    public TableDataInfo<ScheduleEventGroupConfigVo> list(ScheduleEventGroupConfigBo bo, PageQuery pageQuery) {
+        return scheduleEventGroupConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出赛事组别配置主列表
+     */
+    @SaCheckPermission("business:eventGroupConfig:export")
+    @Log(title = "赛事组别配置主", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ScheduleEventGroupConfigBo bo, HttpServletResponse response) {
+        List<ScheduleEventGroupConfigVo> list = scheduleEventGroupConfigService.queryList(bo);
+        ExcelUtil.exportExcel(list, "赛事组别配置主", ScheduleEventGroupConfigVo.class, response);
+    }
+
+    /**
+     * 获取赛事组别配置主详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("business:eventGroupConfig:query")
+    @GetMapping("/{id}")
+    public R<ScheduleEventGroupConfigVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable Long id) {
+        return R.ok(scheduleEventGroupConfigService.queryById(id));
+    }
+
+    /**
+     * 新增赛事组别配置主
+     */
+    @SaCheckPermission("business:eventGroupConfig:add")
+    @Log(title = "赛事组别配置主", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ScheduleEventGroupConfigBo bo) {
+        if(bo.getFinalTemplateId().equals(bo.getRegularTemplateId())){
+            return R.fail("常规组和决赛组请选择不同的模板");
+        }
+        return toAjax(scheduleEventGroupConfigService.insertByBo(bo));
+    }
+
+    /**
+     * 修改赛事组别配置主
+     */
+    @SaCheckPermission("business:eventGroupConfig:edit")
+    @Log(title = "赛事组别配置主", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ScheduleEventGroupConfigBo bo) {
+        if(bo.getFinalTemplateId().equals(bo.getRegularTemplateId())){
+            return R.fail("常规组和决赛组请选择不同的模板");
+        }
+        return toAjax(scheduleEventGroupConfigService.updateByBo(bo));
+    }
+
+    /**
+     * 删除赛事组别配置主
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("business:eventGroupConfig:remove")
+    @Log(title = "赛事组别配置主", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(scheduleEventGroupConfigService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    @Log(title = "生成系列赛")
+    @PostMapping("/generateXiLieTournament")
+    public void generateMatchesForToday(@RequestParam Long eventId) {
+        scheduleEventGroupConfigService.generateXiLieTournament(eventId);
+    }
+
+}

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/controller/TournamentsTemplateController.java

@@ -159,4 +159,11 @@ public class TournamentsTemplateController extends BaseController {
         return R.ok(list);
     }
 
+
+    @GetMapping("/selectTournamentsVoListTemplateList")
+    public R<List<TournamentsVo>> selectTournamentsVoListTemplateList() {
+        List<TournamentsVo> list = tournamentsService.selectTournamentsVoListTemplateList();
+        return R.ok(list);
+    }
+
 }

+ 57 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/ScheduleEventGroupConfig.java

@@ -0,0 +1,57 @@
+package org.dromara.business.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;
+
+/**
+ * 赛事组别配置主对象 schedule_event_group_config
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("schedule_event_group_config")
+public class ScheduleEventGroupConfig extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 配置名称(如“篮球小组赛”)
+     */
+    private String name;
+
+    /**
+     * 常规组别模板ID(关联 event_template)
+     */
+    private Long regularTemplateId;
+
+    /**
+     * 决赛组别模板ID
+     */
+    private Long finalTemplateId;
+
+    /**
+     * 开始日期(所有组别的基准日)
+     */
+    private Date startDate;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+    private Date finalStartDate;
+}

+ 68 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/ScheduleEventGroupItem.java

@@ -0,0 +1,68 @@
+package org.dromara.business.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 com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 赛事组别配置项对象 schedule_event_group_item
+ *
+ * @author Lion Li
+ * @date 2025-12-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("schedule_event_group_item")
+public class ScheduleEventGroupItem extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 关联 schedule_event_group_config.id
+     */
+    private Long configId;
+
+    /**
+     * 组别名称(A, B, C...)
+     */
+    private String groupName;
+
+    /**
+     * 相对于 start_date 的间隔天数
+     */
+    private Long intervalDays;
+
+    /**
+     * 执行时间(HH:mm:ss)
+     */
+    private String executionTime;
+
+    /**
+     *
+     */
+    private Long durationMinutes;
+
+    /**
+     * 'ACTIVE', 'SKIPPED', 'PAUSED'
+     */
+    private String status;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+
+}

+ 65 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/bo/ScheduleEventGroupConfigBo.java

@@ -0,0 +1,65 @@
+package org.dromara.business.domain.bo;
+
+import org.dromara.business.domain.ScheduleEventGroupConfig;
+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 java.util.Date;
+import java.util.List;
+
+/**
+ * 赛事组别配置主业务对象 schedule_event_group_config
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ScheduleEventGroupConfig.class, reverseConvertGenerate = false)
+public class ScheduleEventGroupConfigBo extends BaseEntity {
+
+    /**
+     *
+     */
+    @NotNull(message = "不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 配置名称(如“篮球小组赛”)
+     */
+    @NotBlank(message = "配置名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String name;
+
+    /**
+     * 常规组别模板ID(关联 event_template)
+     */
+    private Long regularTemplateId;
+
+    /**
+     * 决赛组别模板ID
+     */
+    private Long finalTemplateId;
+
+    /**
+     * 开始日期(所有组别的基准日)
+     */
+    @NotNull(message = "开始日期(所有组别的基准日)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date startDate;
+
+    /**
+     *final_start_date
+     */
+    private Date createdAt;
+
+
+    private List<ScheduleEventGroupItemBo> groups;
+
+    private Date finalStartDate;
+
+
+
+}

+ 69 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/bo/ScheduleEventGroupItemBo.java

@@ -0,0 +1,69 @@
+package org.dromara.business.domain.bo;
+
+ import org.dromara.business.domain.ScheduleEventGroupItem;
+ 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 java.util.Date;
+
+/**
+ * 赛事组别配置项业务对象 schedule_event_group_item
+ *
+ * @author Lion Li
+ * @date 2025-12-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ScheduleEventGroupItem.class, reverseConvertGenerate = false)
+public class ScheduleEventGroupItemBo extends BaseEntity {
+
+    /**
+     *
+     */
+    @NotNull(message = "不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 关联 schedule_event_group_config.id
+     */
+    //@NotNull(message = "关联 schedule_event_group_config.id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long configId;
+
+    /**
+     * 组别名称(A, B, C...)
+     */
+    @NotBlank(message = "组别名称(A, B, C...)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String groupName;
+
+    /**
+     * 相对于 start_date 的间隔天数
+     */
+    private Long intervalDays;
+
+    /**
+     * 执行时间(HH:mm:ss)
+     */
+    @NotNull(message = "执行时间(HH:mm:ss)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String executionTime;
+
+    /**
+     *
+     */
+    private Long durationMinutes;
+
+    /**
+     * 'ACTIVE', 'SKIPPED', 'PAUSED'
+     */
+    private String status;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+
+}

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

@@ -0,0 +1,85 @@
+package org.dromara.business.domain.vo;
+
+import java.util.Date;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.business.domain.ScheduleEventGroupConfig;
+import org.dromara.business.domain.dto.ItemsPrizeDto;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * 赛事组别配置主视图对象 schedule_event_group_config
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ScheduleEventGroupConfig.class)
+public class ScheduleEventGroupConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 配置名称(如“篮球小组赛”)
+     */
+    @ExcelProperty(value = "配置名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=“篮球小组赛”")
+    private String name;
+
+    /**
+     * 常规组别模板ID(关联 event_template)
+     */
+    @ExcelProperty(value = "常规组别模板ID", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "关=联,e=vent_template")
+    private Long regularTemplateId;
+
+    private String regularTemplateName;
+
+    /**
+     * 决赛组别模板ID
+     */
+    @ExcelProperty(value = "决赛组别模板ID")
+    private Long finalTemplateId;
+
+    private String finalTemplateName;
+
+    /**
+     * 开始日期(所有组别的基准日)
+     */
+    @ExcelProperty(value = "开始日期", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "所=有组别的基准日")
+    private String startDate;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Date createdAt;
+
+    private List<ScheduleEventGroupItemVo> groups;
+    /**
+     * 决赛日期
+     */
+    private String finalStartDate;
+
+    private String itemsName;
+    private Long itemsNum;
+    private List<ItemsPrizeDto> itemsPrizeList;
+    private String blindStructuresName;
+}

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

@@ -0,0 +1,82 @@
+package org.dromara.business.domain.vo;
+
+import java.util.Date;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.business.domain.ScheduleEventGroupItem;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+
+/**
+ * 赛事组别配置项视图对象 schedule_event_group_item
+ *
+ * @author Lion Li
+ * @date 2025-12-27
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ScheduleEventGroupItem.class)
+public class ScheduleEventGroupItemVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 关联 schedule_event_group_config.id
+     */
+    @ExcelProperty(value = "关联 schedule_event_group_config.id")
+    private Long configId;
+
+    /**
+     * 组别名称(A, B, C...)
+     */
+    @ExcelProperty(value = "组别名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "A=,,B=,,C=...")
+    private String groupName;
+
+    /**
+     * 相对于 start_date 的间隔天数
+     */
+    @ExcelProperty(value = "相对于 start_date 的间隔天数")
+    private Long intervalDays;
+
+    /**
+     * 执行时间(HH:mm:ss)
+     */
+    @ExcelProperty(value = "执行时间", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "H=H:mm:ss")
+    private String executionTime;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long durationMinutes;
+
+    /**
+     * 'ACTIVE', 'SKIPPED', 'PAUSED'
+     */
+    @ExcelProperty(value = "'ACTIVE', 'SKIPPED', 'PAUSED'")
+    private String status;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Date createdAt;
+
+
+}

+ 43 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ScheduleEventGroupConfigMapper.java

@@ -0,0 +1,43 @@
+package org.dromara.business.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.business.domain.ScheduleEventGroupConfig;
+import org.dromara.business.domain.vo.ScheduleEventGroupConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 赛事组别配置主Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+@DS("mysql2")
+public interface ScheduleEventGroupConfigMapper extends BaseMapperPlus<ScheduleEventGroupConfig, ScheduleEventGroupConfigVo> {
+
+
+    @InterceptorIgnore(tenantLine = "true")
+    Page<ScheduleEventGroupConfigVo> selectScheduleEventGroupPage(@Param("page") Page<ScheduleEventGroupConfig> page, @Param("ew") Wrapper<ScheduleEventGroupConfig> wrapper);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int insertScheduleEventGroup(ScheduleEventGroupConfig scheduleRepeat);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int updateScheduleEventGroup(ScheduleEventGroupConfig scheduleRepeat);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int deleteScheduleEventGroup(@Param("ids") Collection<Long> ids);
+
+    @InterceptorIgnore(tenantLine = "true")
+    ScheduleEventGroupConfigVo selectScheduleEventGroupById(Long id);
+
+    @InterceptorIgnore(tenantLine = "true")
+    List<ScheduleEventGroupConfigVo> selectScheduleEventGroupList(@Param("ew") Wrapper<ScheduleEventGroupConfig> wrapper);
+
+}

+ 38 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/ScheduleEventGroupItemMapper.java

@@ -0,0 +1,38 @@
+package org.dromara.business.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import org.dromara.business.domain.ScheduleEventGroupItem;
+import org.dromara.business.domain.vo.ScheduleEventGroupItemVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+import java.util.List;
+
+/**
+ * 赛事组别配置项Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-12-27
+ */
+@DS("mysql2")
+public interface ScheduleEventGroupItemMapper extends BaseMapperPlus<ScheduleEventGroupItem, ScheduleEventGroupItemVo> {
+
+
+    @InterceptorIgnore(tenantLine = "true")
+    int insertScheduleEventGroupConfig(ScheduleEventGroupItem scheduleRepeat);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int updateScheduleEventGroupConfig(ScheduleEventGroupItem scheduleRepeat);
+
+    @InterceptorIgnore(tenantLine = "true")
+    ScheduleEventGroupItemVo selectScheduleEventGroupConfigById(Long id);
+
+    @InterceptorIgnore(tenantLine = "true")
+    List<ScheduleEventGroupItemVo> selectScheduleEventGroupConfigByConfigId(Long configId);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int delScheduleEventGroupByConfigId(Long configId);
+
+
+
+}

+ 2 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/TournamentsTemplateMapper.java

@@ -57,6 +57,8 @@ public interface TournamentsTemplateMapper extends BaseMapperPlus<TournamentsTem
     @InterceptorIgnore(tenantLine = "true")
     int updateUseTournamentTemplate(@Param("templateId") Long templateId);
 
+    @InterceptorIgnore(tenantLine = "true")
+    List<TournamentsVo> selectTournamentsVoListTemplateList();
 
 }
 

+ 76 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/service/IScheduleEventGroupConfigService.java

@@ -0,0 +1,76 @@
+package org.dromara.business.service;
+
+import org.dromara.business.domain.bo.ScheduleEventGroupConfigBo;
+import org.dromara.business.domain.vo.ScheduleEventGroupConfigVo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 赛事组别配置主Service接口
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+public interface IScheduleEventGroupConfigService {
+
+    /**
+     * 查询赛事组别配置主
+     *
+     * @param id 主键
+     * @return 赛事组别配置主
+     */
+    ScheduleEventGroupConfigVo queryById(Long id);
+
+    /**
+     * 分页查询赛事组别配置主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 赛事组别配置主分页列表
+     */
+    TableDataInfo<ScheduleEventGroupConfigVo> queryPageList(ScheduleEventGroupConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的赛事组别配置主列表
+     *
+     * @param bo 查询条件
+     * @return 赛事组别配置主列表
+     */
+    List<ScheduleEventGroupConfigVo> queryList(ScheduleEventGroupConfigBo bo);
+
+    /**
+     * 新增赛事组别配置主
+     *
+     * @param bo 赛事组别配置主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ScheduleEventGroupConfigBo bo);
+
+    /**
+     * 修改赛事组别配置主
+     *
+     * @param bo 赛事组别配置主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ScheduleEventGroupConfigBo bo);
+
+    /**
+     * 校验并批量删除赛事组别配置主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 生成赛列赛事
+     *
+     * @param eventId 配置id
+     */
+    void generateXiLieTournament(Long eventId);
+
+}

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

@@ -94,4 +94,6 @@ public interface ITournamentsTemplateService {
      */
     SysOssVo uploadTournament(MultipartFile file);
 
+
+    List<TournamentsVo> selectTournamentsVoListTemplateList();
 }

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

@@ -0,0 +1,478 @@
+package org.dromara.business.service.impl;
+
+import org.dromara.business.domain.ScheduleEventGroupConfig;
+import org.dromara.business.domain.ScheduleEventGroupItem;
+import org.dromara.business.domain.ScheduleTournamentsReletion;
+import org.dromara.business.domain.bo.ScheduleEventGroupConfigBo;
+import org.dromara.business.domain.bo.ScheduleEventGroupItemBo;
+import org.dromara.business.domain.dto.ItemsPrizeDto;
+import org.dromara.business.domain.dto.TournamentsDto;
+import org.dromara.business.domain.vo.*;
+import org.dromara.business.mapper.*;
+import org.dromara.business.service.IScheduleEventGroupConfigService;
+import org.dromara.business.service.ITournamentsService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 赛事组别配置主Service业务层处理
+ *
+ * @author Lion Li
+ * @date 2025-12-26
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ScheduleEventGroupConfigServiceImpl implements IScheduleEventGroupConfigService {
+
+    private final ScheduleEventGroupConfigMapper baseMapper;
+
+    private final ScheduleEventGroupItemMapper scheduleEventGroupItemMapper;
+
+    private final TournamentsTemplateMapper tournamentsTemplateMapper;
+
+    private final TournamentEntryConditionsTemplateMapper tournamentEntryConditionsMapper;
+
+    private final TournamentBlindStructuresTemplateMapper tournamentBlindStructuresMapper;
+
+    private final PrizeDistributionsTemplateMapper prizeDistributionsMapper;
+
+    private final PrizeDistributionItemsTemplateMapper prizeDistributionItemsMapper;
+
+    private final TournamentCategoryTagTemplateMapper tournamentCategoryTagTemplateMapper;
+
+    private final ITournamentsService iTournamentsService;
+
+    private final ScheduleTournamentsReletionMapper scheduleTournamentsReletionMapper;
+
+    /**
+     * 查询赛事组别配置主
+     *
+     * @param id 主键
+     * @return 赛事组别配置主
+     */
+    @Override
+    public ScheduleEventGroupConfigVo queryById(Long id){
+        ScheduleEventGroupConfigVo scheduleEventGroupConfigVo = baseMapper.selectScheduleEventGroupById(id);
+        if(scheduleEventGroupConfigVo!=null){
+            List<ScheduleEventGroupItemVo> scheduleEventGroupItemVoList = scheduleEventGroupItemMapper.selectScheduleEventGroupConfigByConfigId(id);
+            scheduleEventGroupConfigVo.setGroups(scheduleEventGroupItemVoList);
+        }
+        return scheduleEventGroupConfigVo;
+    }
+
+    /**
+     * 分页查询赛事组别配置主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 赛事组别配置主分页列表
+     */
+    @Override
+    public TableDataInfo<ScheduleEventGroupConfigVo> queryPageList(ScheduleEventGroupConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ScheduleEventGroupConfig> lqw = buildQueryWrapper(bo);
+        Page<ScheduleEventGroupConfigVo> result = baseMapper.selectScheduleEventGroupPage(pageQuery.build(), lqw);
+        result.getRecords().forEach(item -> {
+            List<ScheduleEventGroupItemVo> scheduleEventGroupItemVoList = scheduleEventGroupItemMapper.selectScheduleEventGroupConfigByConfigId(item.getId());
+            item.setGroups(scheduleEventGroupItemVoList);
+            //查询对应模版名称
+            TournamentsVo tournamentsVo = tournamentsTemplateMapper.selectVoByIdInfoTemplate(item.getRegularTemplateId());
+            if(tournamentsVo!=null){
+                item.setRegularTemplateName(tournamentsVo.getName());
+            }
+            TournamentsVo finalTournamentsVo = tournamentsTemplateMapper.selectVoByIdInfoTemplate(item.getFinalTemplateId());
+            if(finalTournamentsVo!=null){
+                item.setFinalTemplateName(finalTournamentsVo.getName());
+                //赛事报名条件
+                TournamentEntryConditionsVo tournamentEntryConditionsVo = tournamentEntryConditionsMapper.selectByTournamentInfoTemplate(finalTournamentsVo.getId());
+                if(tournamentEntryConditionsVo!=null){
+                    item.setItemsNum(tournamentEntryConditionsVo.getRequiredQuantity());
+                    item.setItemsName(tournamentEntryConditionsVo.getItemsName());
+                }
+                //绑定的盲注信息
+                TournamentBlindStructuresVo tournamentBlindStructuresVo = tournamentBlindStructuresMapper.selectTournamentBlindStructureByTournamentIdTemplate(finalTournamentsVo.getId());
+                if(tournamentBlindStructuresVo!=null){
+                    item.setBlindStructuresName(tournamentBlindStructuresVo.getBlindStructuresName());
+                }
+                //排名
+                List<PrizeDistributionsVo> prizeDistributionsVos = prizeDistributionsMapper.selectByTournamentIdTemplate(finalTournamentsVo.getId());
+                if(prizeDistributionsVos!=null){
+                    List<ItemsPrizeDto> itemsPrizeList=new ArrayList<>();
+
+                    // 提取并按排名正序排序后,取出 id 列表
+                    List<Long> ids = prizeDistributionsVos.stream()
+                        .sorted(Comparator.comparing(PrizeDistributionsVo::getPaiming))
+                        .map(PrizeDistributionsVo::getId)
+                        .collect(Collectors.toList());
+                    int i=0;
+                    for (Long id2 : ids) {
+                        i++;
+                        //奖品
+                        PrizeDistributionItemsVo prizeDistributionItemsVos = prizeDistributionItemsMapper.selectByPrizeDistributionIdTemplate(id2);
+                        ItemsPrizeDto itemsPrizeBo = new ItemsPrizeDto();
+                        itemsPrizeBo.setRanking(Long.valueOf(i));
+                        itemsPrizeBo.setItemId(prizeDistributionItemsVos.getItemId());
+                        itemsPrizeBo.setQuantity(prizeDistributionItemsVos.getQuantity());
+                        itemsPrizeList.add(itemsPrizeBo);
+
+                    }
+                    item.setItemsPrizeList(itemsPrizeList);
+                }
+            }
+        });
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的赛事组别配置主列表
+     *
+     * @param bo 查询条件
+     * @return 赛事组别配置主列表
+     */
+    @Override
+    public List<ScheduleEventGroupConfigVo> queryList(ScheduleEventGroupConfigBo bo) {
+        LambdaQueryWrapper<ScheduleEventGroupConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectScheduleEventGroupList(lqw);
+    }
+
+    private LambdaQueryWrapper<ScheduleEventGroupConfig> buildQueryWrapper(ScheduleEventGroupConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ScheduleEventGroupConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ScheduleEventGroupConfig::getId);
+        lqw.like(StringUtils.isNotBlank(bo.getName()), ScheduleEventGroupConfig::getName, bo.getName());
+        lqw.eq(bo.getRegularTemplateId() != null, ScheduleEventGroupConfig::getRegularTemplateId, bo.getRegularTemplateId());
+        lqw.eq(bo.getFinalTemplateId() != null, ScheduleEventGroupConfig::getFinalTemplateId, bo.getFinalTemplateId());
+        lqw.eq(bo.getStartDate() != null, ScheduleEventGroupConfig::getStartDate, bo.getStartDate());
+        lqw.eq(bo.getCreatedAt() != null, ScheduleEventGroupConfig::getCreatedAt, bo.getCreatedAt());
+        return lqw;
+    }
+
+    /**
+     * 新增赛事组别配置主
+     *
+     * @param bo 赛事组别配置主
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ScheduleEventGroupConfigBo bo) {
+        ScheduleEventGroupConfig add = MapstructUtils.convert(bo, ScheduleEventGroupConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insertScheduleEventGroup(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+            List<ScheduleEventGroupItemBo> eventGroupItemBoList = bo.getGroups();
+            for (ScheduleEventGroupItemBo scheduleEventGroupItemBo : eventGroupItemBoList) {
+                ScheduleEventGroupItem scheduleEventGroupItem = new ScheduleEventGroupItem();
+                scheduleEventGroupItem.setConfigId(add.getId());
+                scheduleEventGroupItem.setGroupName(scheduleEventGroupItemBo.getGroupName());
+                scheduleEventGroupItem.setIntervalDays(scheduleEventGroupItemBo.getIntervalDays());
+                scheduleEventGroupItem.setDurationMinutes(scheduleEventGroupItemBo.getDurationMinutes());
+                scheduleEventGroupItem.setExecutionTime(scheduleEventGroupItemBo.getExecutionTime());
+                scheduleEventGroupItem.setStatus("ACTIVE");
+                scheduleEventGroupItemMapper.insertScheduleEventGroupConfig(scheduleEventGroupItem);
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * 修改赛事组别配置主
+     *
+     * @param bo 赛事组别配置主
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ScheduleEventGroupConfigBo bo) {
+        ScheduleEventGroupConfig update = MapstructUtils.convert(bo, ScheduleEventGroupConfig.class);
+        validEntityBeforeSave(update);
+        int updated = baseMapper.updateScheduleEventGroup(update);
+        if (updated > 0) {
+            scheduleEventGroupItemMapper.delScheduleEventGroupByConfigId(update.getId());
+            List<ScheduleEventGroupItemBo> eventGroupItemBoList = bo.getGroups();
+            for (ScheduleEventGroupItemBo scheduleEventGroupItemBo : eventGroupItemBoList) {
+                ScheduleEventGroupItem scheduleEventGroupItem = new ScheduleEventGroupItem();
+                scheduleEventGroupItem.setConfigId(update.getId());
+                scheduleEventGroupItem.setGroupName(scheduleEventGroupItemBo.getGroupName());
+                scheduleEventGroupItem.setIntervalDays(scheduleEventGroupItemBo.getIntervalDays());
+                scheduleEventGroupItem.setDurationMinutes(scheduleEventGroupItemBo.getDurationMinutes());
+                scheduleEventGroupItem.setExecutionTime(scheduleEventGroupItemBo.getExecutionTime());
+                scheduleEventGroupItem.setStatus("ACTIVE");
+                scheduleEventGroupItemMapper.insertScheduleEventGroupConfig(scheduleEventGroupItem);
+            }
+        }
+        return updated > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ScheduleEventGroupConfig entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除赛事组别配置主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        for (Long id : ids) {
+            scheduleEventGroupItemMapper.delScheduleEventGroupByConfigId(id);
+        }
+        return baseMapper.deleteScheduleEventGroup(ids) > 0;
+    }
+
+    @Override
+    public void generateXiLieTournament(Long eventId) {
+        log.info("开始生成系列赛,eventId: {}", eventId);
+
+        // 校验对应日期是否生成过赛事
+        ScheduleEventGroupConfigVo scheduleEventGroupConfigVo = baseMapper.selectScheduleEventGroupById(eventId);
+        if (scheduleEventGroupConfigVo == null) {
+            log.warn("未找到对应的赛事组别配置,eventId: {}", eventId);
+            return;
+        }
+
+        log.info("赛事组别配置信息 - id: {}, 名称: {}, 开始日期: {}, 决赛开始日期: {}",
+            scheduleEventGroupConfigVo.getId(),
+            scheduleEventGroupConfigVo.getName(),
+            scheduleEventGroupConfigVo.getStartDate(),
+            scheduleEventGroupConfigVo.getFinalStartDate());
+
+        // 决赛模版
+        Long finalTemplateId = scheduleEventGroupConfigVo.getFinalTemplateId();
+        // 常规赛模版
+        Long regularTemplateId = scheduleEventGroupConfigVo.getRegularTemplateId();
+        String finalStartDate = scheduleEventGroupConfigVo.getFinalStartDate();
+
+        if (finalTemplateId == null) {
+            log.warn("决赛模板ID为空,无法生成系列赛,eventId: {}", eventId);
+            return;
+        }
+
+        // 先生成决赛
+        log.info("开始生成决赛,模板ID: {}, 开始时间: {}", finalTemplateId, finalStartDate);
+        Long finalTournamentId = generateXiLieTournamentDetail(
+            scheduleEventGroupConfigVo.getId(),
+            finalTemplateId,
+            finalStartDate,
+            null,
+            null);
+
+        if (finalTournamentId == null) {
+            log.error("决赛生成失败,模板ID: {}", finalTemplateId);
+            return;
+        }
+
+        log.info("决赛生成成功,赛事ID: {}", finalTournamentId);
+
+        String startDate = scheduleEventGroupConfigVo.getStartDate();
+        if (StringUtils.isBlank(startDate)) {
+            log.warn("开始日期为空,无法生成常规赛,eventId: {}", eventId);
+            return;
+        }
+
+        // 赛事详情的日期相关
+        List<ScheduleEventGroupItemVo> scheduleEventGroupItemVoList =
+            scheduleEventGroupItemMapper.selectScheduleEventGroupConfigByConfigId(scheduleEventGroupConfigVo.getId());
+
+        if (CollectionUtils.isEmpty(scheduleEventGroupItemVoList)) {
+            log.warn("未找到赛事组别配置项,eventId: {}", eventId);
+            return;
+        }
+
+        log.info("找到 {} 个赛事组别配置项", scheduleEventGroupItemVoList.size());
+
+        for (ScheduleEventGroupItemVo scheduleEventGroupItemVo : scheduleEventGroupItemVoList) {
+            // 生成的相关时间
+            String groupName = scheduleEventGroupItemVo.getGroupName();
+            String executionTime = scheduleEventGroupItemVo.getExecutionTime();
+            Long intervalDays = scheduleEventGroupItemVo.getIntervalDays();
+
+            if (StringUtils.isBlank(executionTime)) {
+                log.warn("执行时间为空,跳过配置项: {}, 组名: {}", scheduleEventGroupItemVo.getId(), groupName);
+                continue;
+            }
+
+            try {
+                // 计算实际执行日期:start_date + interval_days
+                LocalDate actualDate = LocalDate.parse(startDate).plusDays(intervalDays != null ? intervalDays : 0);
+
+                // 将日期和时间拼接
+                LocalDateTime actualDateTime = LocalDateTime.of(actualDate, LocalTime.parse(executionTime));
+
+                // 如果需要转换为字符串格式
+                String actualDateTimeStr = actualDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+                log.info("生成常规赛 - 组名: {}, 执行时间: {}, 模板ID: {}", groupName, actualDateTimeStr, regularTemplateId);
+
+                if (regularTemplateId != null) {
+                    // 生成对应系列赛
+                    Long regularTournamentId = generateXiLieTournamentDetail(
+                        scheduleEventGroupConfigVo.getId(),
+                        regularTemplateId,
+                        actualDateTimeStr,
+                        finalTournamentId,
+                        groupName);
+
+                    if (regularTournamentId != null) {
+                        log.info("常规赛生成成功 - 组名: {}, 赛事ID: {}", groupName, regularTournamentId);
+                    } else {
+                        log.error("常规赛生成失败 - 组名: {}, 模板ID: {}", groupName, regularTemplateId);
+                    }
+                } else {
+                    log.warn("常规赛模板ID为空,跳过生成常规赛,组名: {}", groupName);
+                }
+            } catch (Exception e) {
+                log.error("处理赛事组别配置项时发生错误,配置项ID: {}, 组名: {}", scheduleEventGroupItemVo.getId(), groupName, e);
+            }
+        }
+
+        log.info("系列赛生成完成,eventId: {}", eventId);
+    }
+
+
+    /**
+     * 生成赛事
+     * @param templateId
+     * @param beginTime
+     * @param targetTournamentId
+     * @param groupName
+     * @return
+     */
+    public Long generateXiLieTournamentDetail(Long eventId,Long templateId,String beginTime,Long targetTournamentId,String groupName) {
+        try {
+            TournamentsVo tournamentsVo = tournamentsTemplateMapper.selectVoByIdInfoTemplate(templateId);
+            if(tournamentsVo==null){
+                return null;
+            }
+            // 模拟构造 TournamentsDto 数据
+            TournamentsDto bo = new TournamentsDto();
+            //晋级目标赛事,没有则为空 为决赛
+
+            bo.setName(tournamentsVo.getName());
+            // 设置基础字段
+            if(StringUtils.isNotBlank(groupName)){
+                bo.setName(tournamentsVo.getName()+"("+groupName+"组)");
+            }
+
+            // 定义你想要的日期时间格式
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+            // 使用指定的格式器格式化 LocalDateTime 对象
+            bo.setStartTime(beginTime);
+
+            bo.setGameType(tournamentsVo.getGameType()); // 假设有5种类型
+            bo.setStartingChips(tournamentsVo.getStartingChips());
+            bo.setLevelDuration(tournamentsVo.getLevelDuration());
+            bo.setLateRegistrationLevel(tournamentsVo.getLateRegistrationLevel());
+            bo.setMaxPlayers(tournamentsVo.getMaxPlayers());
+            bo.setStatus(0L); // 默认状态为进行中等
+            bo.setCompetitionIcon(tournamentsVo.getCompetitionIcon());
+            bo.setRewardPlayers(tournamentsVo.getRewardPlayers());
+            bo.setSignTime(tournamentsVo.getSignTime());
+            bo.setRobotCount(tournamentsVo.getRobotCount());
+
+            bo.setDelayCardNum(tournamentsVo.getDelayCardNum());
+            bo.setDelayCardTime(tournamentsVo.getDelayCardTime());
+            bo.setActionTime(tournamentsVo.getActionTime());
+            bo.setMinPlayers(tournamentsVo.getMinPlayers());
+
+            bo.setGameVariant(tournamentsVo.getGameVariant());
+            bo.setQualifierType(tournamentsVo.getQualifierType());
+            bo.setQualifierValue(tournamentsVo.getQualifierValue());
+            //查询模版 赛事对应盲注
+            TournamentBlindStructuresVo tournamentBlindStructuresVo = tournamentBlindStructuresMapper.selectTournamentBlindStructureByTournamentIdTemplate(tournamentsVo.getId());
+
+            if(tournamentBlindStructuresVo!=null){
+                // 设置盲注结构 ID
+                bo.setBlindStructureId(tournamentBlindStructuresVo.getBlindStructureId());
+            }
+
+            //查询模版  设置报名条件
+            TournamentEntryConditionsVo tournamentEntryConditionsVo = tournamentEntryConditionsMapper.selectByTournamentInfoTemplate(tournamentsVo.getId());
+            bo.setItemsId(tournamentEntryConditionsVo.getItemId());
+            bo.setItemsNum(tournamentEntryConditionsVo.getRequiredQuantity());
+
+            //查询模版对应的排名
+            List<PrizeDistributionsVo> prizeDistributionsVos = prizeDistributionsMapper.selectByTournamentIdTemplate(tournamentsVo.getId());
+
+            List<PrizeDistributionsVo> sortedList = prizeDistributionsVos.stream()
+                .sorted(Comparator.comparing(
+                    PrizeDistributionsVo::getPaiming,
+                    Comparator.nullsLast(Long::compareTo) // null 值排在最后
+                ))
+                .collect(Collectors.toList());
+
+
+            // 设置奖励列表
+            List<ItemsPrizeDto> prizeList = new ArrayList<>();
+
+            for (PrizeDistributionsVo prizeDistributionsVo : sortedList) {
+
+                PrizeDistributionItemsVo prizeDistributionItemsVo = prizeDistributionItemsMapper.selectByPrizeDistributionIdTemplate(prizeDistributionsVo.getId());
+
+                ItemsPrizeDto prize = new ItemsPrizeDto();
+                prize.setRanking(prizeDistributionsVo.getPaiming());
+                prize.setItemId(prizeDistributionItemsVo.getItemId());
+                prize.setQuantity(prizeDistributionItemsVo.getQuantity());
+                prize.setItemsName(prizeDistributionItemsVo.getItemsName());
+                prizeList.add(prize);
+
+            }
+
+            bo.setItemsPrizeList(prizeList);
+            bo.setCompetitionBg(tournamentsVo.getCompetitionBg());
+            //查询类目和标签ID
+            List<Long> categoryList = tournamentCategoryTagTemplateMapper.selectCategoryOrTagId("CATEGORY", tournamentsVo.getId());
+            bo.setCategoryId(categoryList);
+            List<Long> tagList = tournamentCategoryTagTemplateMapper.selectCategoryOrTagId("TAG", tournamentsVo.getId());
+            bo.setTagId(tagList);
+            bo.setRebuy(tournamentsVo.getRebuy());
+            bo.setDelayShow(tournamentsVo.getDelayShow());
+            bo.setRemark(tournamentsVo.getRemark());
+            bo.setStatus(0L);
+            bo.setTargetTournamentId(targetTournamentId);
+            // 调用已有的插入方法
+            if (!iTournamentsService.insertByBo(bo)) {
+                return null;
+            }
+
+            //保存对应生成赛事记录信息
+            ScheduleTournamentsReletion scheduleTournamentsReletion2=new ScheduleTournamentsReletion();
+            scheduleTournamentsReletion2.setTournamentsId(bo.getId());
+            scheduleTournamentsReletion2.setTournamentsTemplateId(templateId);
+            scheduleTournamentsReletion2.setScBeginTime(beginTime);
+            scheduleTournamentsReletion2.setConfigId(eventId);
+            scheduleTournamentsReletionMapper.insertScheduleRelation(scheduleTournamentsReletion2);
+
+            return bo.getId();
+        } catch (Exception e) {
+            return null;
+        }
+
+    }
+
+}

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

@@ -566,6 +566,11 @@ public class TournamentsTemplateServiceImpl implements ITournamentsTemplateServi
         return sysOssVo;
     }
 
+    @Override
+    public List<TournamentsVo> selectTournamentsVoListTemplateList() {
+        return baseMapper.selectTournamentsVoListTemplateList();
+    }
+
 
     private List<ItemsPrizeDto> parsePrizeList(String itemsPrizeListJson, ObjectMapper mapper) throws Exception {
         if (itemsPrizeListJson == null || itemsPrizeListJson.isBlank()) {

+ 90 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ScheduleEventGroupConfigMapper.xml

@@ -0,0 +1,90 @@
+<?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.business.mapper.ScheduleEventGroupConfigMapper">
+
+    <select id="selectScheduleEventGroupPage" resultType="org.dromara.business.domain.vo.ScheduleEventGroupConfigVo">
+        SELECT
+            id,
+            name,
+            regular_template_id,
+            final_template_id,
+            start_date,
+            created_at,
+            final_start_date
+        FROM schedule_event_group_config  ${ew.customSqlSegment}
+    </select>
+    <select id="selectScheduleEventGroupList" resultType="org.dromara.business.domain.vo.ScheduleEventGroupConfigVo">
+        SELECT
+            id,
+            name,
+            regular_template_id,
+            final_template_id,
+            start_date,
+            created_at,
+            final_start_date
+        FROM schedule_event_group_config  ${ew.customSqlSegment}
+    </select>
+    <!-- 查询所有字段 -->
+    <select id="selectScheduleEventGroupById" resultType="org.dromara.business.domain.vo.ScheduleEventGroupConfigVo">
+        SELECT
+            id,
+            name,
+            regular_template_id,
+            final_template_id,
+            start_date,
+            created_at,
+            final_start_date
+        FROM schedule_event_group_config
+        WHERE id = #{id}
+    </select>
+    <!-- 插入:只插入非空字段(但 name 和 start_date 是 NOT NULL,必须传) -->
+    <insert id="insertScheduleEventGroup" useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO schedule_event_group_config (
+        <trim suffixOverrides=",">
+            name,
+            <if test="regularTemplateId != null">regular_template_id,</if>
+            <if test="finalTemplateId != null">final_template_id,</if>
+            final_start_date,
+            start_date
+            <!-- 注意:created_at 有默认值,可不传 -->
+        </trim>
+        ) VALUES (
+        <trim suffixOverrides=",">
+            #{name},
+            <if test="regularTemplateId != null">#{regularTemplateId},</if>
+            <if test="finalTemplateId != null">#{finalTemplateId},</if>
+            #{finalStartDate}
+            #{startDate}
+        </trim>
+        )
+    </insert>
+
+    <!-- 更新:只更新非空字段 -->
+    <update id="updateScheduleEventGroup">
+        UPDATE schedule_event_group_config
+        <set>
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="regularTemplateId != null">regular_template_id = #{regularTemplateId},</if>
+            <if test="finalTemplateId != null">final_template_id = #{finalTemplateId},</if>
+            <if test="startDate != null">start_date = #{startDate},</if>
+            <if test="finalStartDate != null">final_start_date = #{finalStartDate},</if>
+            <!-- 注意:created_at 一般不更新 -->
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <delete id="deleteScheduleEventGroup">
+        DELETE FROM schedule_event_group_config
+        <where>
+            id IN
+            <foreach item="id" collection="ids" open="(" separator="," close=")">
+                <if test="id > 0">
+                    #{id}
+                </if>
+            </foreach>
+        </where>
+    </delete>
+
+</mapper>

+ 81 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/ScheduleEventGroupItemMapper.xml

@@ -0,0 +1,81 @@
+<?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.business.mapper.ScheduleEventGroupItemMapper">
+
+    <!-- 查询单条 -->
+    <select id="selectScheduleEventGroupConfigById" resultType="org.dromara.business.domain.vo.ScheduleEventGroupItemVo">
+        SELECT
+            id,
+            config_id,
+            group_name,
+            interval_days,
+            execution_time,
+            duration_minutes,
+            status,
+            created_at
+        FROM schedule_event_group_item
+        WHERE id = #{id}
+    </select>
+
+    <!-- 查询单条 -->
+    <select id="selectScheduleEventGroupConfigByConfigId" resultType="org.dromara.business.domain.vo.ScheduleEventGroupItemVo">
+        SELECT
+            id,
+            config_id,
+            group_name,
+            interval_days,
+            execution_time,
+            duration_minutes,
+            status,
+            created_at
+        FROM schedule_event_group_item
+        WHERE config_id = #{configId}
+        ORDER BY group_name ASC
+    </select>
+
+    <!-- 插入:只插入非空字段(但 config_id, group_name, execution_time 必须传) -->
+    <insert id="insertScheduleEventGroupConfig" useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO schedule_event_group_item (
+        <trim suffixOverrides=",">
+            config_id,
+            group_name,
+            <if test="intervalDays != null">interval_days,</if>
+            execution_time,
+            <if test="durationMinutes != null">duration_minutes,</if>
+            <if test="status != null and status != ''">status,</if>
+            <!-- created_at 有默认值,不传 -->
+        </trim>
+        ) VALUES (
+        <trim suffixOverrides=",">
+            #{configId},
+            #{groupName},
+            <if test="intervalDays != null">#{intervalDays},</if>
+            #{executionTime},
+            <if test="durationMinutes != null">#{durationMinutes},</if>
+            <if test="status != null and status != ''">#{status},</if>
+        </trim>
+        )
+    </insert>
+
+    <!-- 更新:只更新非空字段 -->
+    <update id="updateScheduleEventGroupConfig">
+        UPDATE schedule_event_group_item
+        <set>
+            <if test="configId != null">config_id = #{configId},</if>
+            <if test="groupName != null and groupName != ''">group_name = #{groupName},</if>
+            <if test="intervalDays != null">interval_days = #{intervalDays},</if>
+            <if test="executionTime != null">execution_time = #{executionTime},</if>
+            <if test="durationMinutes != null">duration_minutes = #{durationMinutes},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <!-- created_at 一般不更新 -->
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <delete id="delScheduleEventGroupByConfigId">
+        delete from schedule_event_group_item where config_id = #{configId}
+    </delete>
+
+</mapper>

+ 3 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/TournamentsTemplateMapper.xml

@@ -17,6 +17,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        SELECT id, name, start_time, end_time,game_type, starting_chips, level_duration, late_registration_level, max_players, status, created_at, updated_at,sign_time,competition_icon,tournaments_bi_id,reward_players,total_signup,robot_count,delay_card_time,delay_card_num,action_time,competition_bg,min_players,game_variant,target_tournament_id,qualifier_value,qualifier_type,start_blind_level,rebuy,delay_show,remark FROM tournaments_template WHERE id =  #{id}
     </select>
 
+    <select id="selectTournamentsVoListTemplateList" resultType="org.dromara.business.domain.vo.TournamentsVo">
+        SELECT id, name, start_time, end_time,game_type, starting_chips, level_duration, late_registration_level, max_players, status, created_at, updated_at,sign_time,competition_icon,tournaments_bi_id,reward_players,total_signup,robot_count,delay_card_time,delay_card_num,action_time,competition_bg,min_players,game_variant,target_tournament_id,qualifier_value,qualifier_type,start_blind_level,rebuy,delay_show,remark FROM tournaments_template  ${ew.customSqlSegment}
+    </select>
 
     <update id="updateTournamentsByIdTemplate">
         UPDATE tournaments_template

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

@@ -16,7 +16,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
     <!-- 根据 ID 查询 -->
-    <select id="selectJudgePositionRelationById" parameterType="long" resultMap="BaseResultMap">
+    <select id="selectJudgePositionRelationById" parameterType="long" resultType="org.dromara.physical.domain.vo.PhysicalJudgePositionRelationVo">
         SELECT
             id,
             judge_id,