Эх сурвалжийг харах

feat: 新增用户反馈、赛事关联菜单及App端富文本赛事公告

- 新增用户反馈功能,支持用户提交意见与问题
- 实现赛事与菜单的关联管理,提升赛事内容组织灵活性
- 支持App端富文本格式的赛事公告,增强公告展示效果与信息表达能力
wenkai 1 долоо хоног өмнө
parent
commit
7c8e4627b0
33 өөрчлөгдсөн 1769 нэмэгдсэн , 10 устгасан
  1. 5 5
      ruoyi-admin/src/main/resources/application-prod.yml
  2. 84 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/EventMenuController.java
  3. 23 1
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/GameNavigatorController.java
  4. 86 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/MarkdownController.java
  5. 83 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/UserAdviceController.java
  6. 46 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/AdviceController.java
  7. 4 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/AppMarkdownController.java
  8. 47 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/Advice.java
  9. 58 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/AppEventMd.java
  10. 40 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/EventMenu.java
  11. 55 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/AdviceBo.java
  12. 59 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/AppEventMdBo.java
  13. 42 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/EventMenuBo.java
  14. 58 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AdviceVo.java
  15. 71 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AppEventMdVo.java
  16. 53 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/EventMenuVo.java
  17. 15 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/AdviceMapper.java
  18. 15 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/AppEventMdMapper.java
  19. 15 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/EventMenuMapper.java
  20. 68 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IAdviceService.java
  21. 92 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IAppEventMdService.java
  22. 83 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IEventMenuService.java
  23. 8 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameNavigatorService.java
  24. 9 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameTeamService.java
  25. 164 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AdviceServiceImpl.java
  26. 191 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AppEventMdServiceImpl.java
  27. 208 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/EventMenuServiceImpl.java
  28. 18 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameTeamServiceImpl.java
  29. 33 4
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/IGameNavigatorServiceImpl.java
  30. 7 0
      ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/AdviceMapper.xml
  31. 7 0
      ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/AppEventMdMapper.xml
  32. 7 0
      ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/EventMenuMapper.xml
  33. 15 0
      本周改动.md

+ 5 - 5
ruoyi-admin/src/main/resources/application-prod.yml

@@ -40,7 +40,7 @@ spring:
     # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
     dynamic:
       # 性能分析插件(有性能损耗 不建议生产环境使用)
-      p6spy: false
+      p6spy: true
       # 设置默认的数据源或者数据源组,默认值即为 master
       primary: master
       # 严格模式 匹配不到数据源则报错
@@ -52,9 +52,9 @@ spring:
           driverClassName: com.mysql.cj.jdbc.Driver
           # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
           # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
-          url: jdbc:mysql://182.92.79.54:3306/game_event?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
+          url: jdbc:mysql://localhost:3306/game_event?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
           username: game_event
-          password: EMRPt6LebAij3m6j
+          password: TxtYJXEtnC6ecmBw
 #        # 从库数据源
 #        slave:
 #          lazy: true
@@ -101,13 +101,13 @@ spring:
 spring.data:
   redis:
     # 地址
-    host: 182.92.79.54
+    host: 127.0.0.1
     # 端口,默认为6379
     port: 6379
     # 数据库索引
     database: 0
     # redis 密码必须配置
-    password: game_event
+#    password: game_event
     # 连接超时时间
     timeout: 10s
     # 是否开启ssl

+ 84 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/EventMenuController.java

@@ -0,0 +1,84 @@
+package org.dromara.system.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.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.system.domain.vo.EventMenuVo;
+import org.dromara.system.domain.bo.EventMenuBo;
+import org.dromara.system.service.IEventMenuService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 赛事菜单关联
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/relateMenu")
+public class EventMenuController extends BaseController {
+
+    private final IEventMenuService eventMenuService;
+
+    /**
+     * 查询赛事菜单关联列表
+     */
+    // @SaCheckPermission("system:menu:list")
+    @GetMapping("/list")
+    public TableDataInfo<EventMenuVo> list(EventMenuBo bo, PageQuery pageQuery) {
+        return eventMenuService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出赛事菜单关联列表
+     */
+    // @SaCheckPermission("system:menu:export")
+    @Log(title = "赛事菜单关联", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(EventMenuBo bo, HttpServletResponse response) {
+        List<EventMenuVo> list = eventMenuService.queryList(bo);
+        ExcelUtil.exportExcel(list, "赛事菜单关联", EventMenuVo.class, response);
+    }
+
+
+
+    /**
+     * 修改赛事菜单关联
+     */
+    // @SaCheckPermission("system:menu:edit")
+    @Log(title = "赛事菜单关联", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EventMenuBo bo) {
+        return toAjax(eventMenuService.updateByBo(bo));
+    }
+
+    /**
+     * 删除赛事菜单关联
+     *
+     * @param ids 主键串
+     */
+    // @SaCheckPermission("system:menu:remove")
+    @Log(title = "赛事菜单关联", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(eventMenuService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 23 - 1
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/GameNavigatorController.java

@@ -16,9 +16,12 @@ import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.EventMenuBo;
 import org.dromara.system.domain.bo.GameNavigatorBo;
+import org.dromara.system.domain.vo.EventMenuVo;
 import org.dromara.system.domain.vo.GameNavigatorVo;
 import org.dromara.system.domain.vo.VsNavBottomMainVo;
+import org.dromara.system.service.IEventMenuService;
 import org.dromara.system.service.IGameNavigatorService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -40,6 +43,7 @@ import java.util.List;
 public class GameNavigatorController extends BaseController {
 
     private final IGameNavigatorService gameNavigatorService;
+    private final IEventMenuService eventMenuService;
 
     /**
      * 查询底部主导航表列表
@@ -81,7 +85,7 @@ public class GameNavigatorController extends BaseController {
     @SaCheckPermission("scenic:navigator:query")
     @GetMapping("/{navId}")
     public R<GameNavigatorVo> getInfo(@NotNull(message = "主键不能为空")
-                                        @PathVariable Long navId) {
+                                      @PathVariable Long navId) {
         return R.ok(gameNavigatorService.queryById(navId));
     }
 
@@ -128,4 +132,22 @@ public class GameNavigatorController extends BaseController {
         return R.ok(gameNavigatorService.getEnabledNavList());
     }
 
+    /**
+     * 获取赛事导航关联菜单列表
+     */
+    @GetMapping("/list/relate")
+    public TableDataInfo<GameNavigatorVo> listRelateMenu(EventMenuBo bo, PageQuery pageQuery) {
+        return gameNavigatorService.queryPageListByEventId(bo.getEventId(), pageQuery);
+    }
+
+    /**
+     * 编辑赛事菜单关联
+     */
+    @Log(title = "赛事菜单关联", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/edit/relate")
+    public R<Void> editRelate(@Validated({AddGroup.class, EditGroup.class}) @RequestBody EventMenuBo bo) {
+        return toAjax(eventMenuService.editByVo(bo));
+    }
+
 }

+ 86 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/MarkdownController.java

@@ -0,0 +1,86 @@
+package org.dromara.system.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+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.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.AppEventMdBo;
+import org.dromara.system.domain.vo.AppEventMdVo;
+import org.dromara.system.service.IAppEventMdService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * app markdown
+ *
+ * @author Lion Li
+ * @date 2025-08-18
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/markdown")
+public class MarkdownController extends BaseController {
+    private final IAppEventMdService appEventMdService;
+
+    /**
+     * 获取移动端富文本详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:eventMd:query")
+    @GetMapping("/{id}")
+    public R<AppEventMdVo> getInfo(@NotNull(message = "主键不能为空")
+                                   @PathVariable Long id) {
+        return R.ok(appEventMdService.queryById(id));
+    }
+
+    /**
+     * 根据赛事id和类型获取移动端富文本详细信息
+     *
+     * @param eventId 赛事id
+     * @param type    类型
+     */
+    @SaCheckPermission("system:eventMd:query")
+    @GetMapping("/{eventId}/{type}")
+    public R<AppEventMdVo> getInfoByEventAndType(@NotNull(message = "赛事id不能为空")
+                                   @PathVariable Long eventId,
+                                   @NotNull(message = "赛事id不能为空")
+                                   @PathVariable Integer type) {
+        return R.ok(appEventMdService.queryByEventIdAndType(eventId, type));
+    }
+
+    /**
+     * 编辑移动端富文本
+     */
+    @SaCheckPermission("system:eventMd:edit")
+    @Log(title = "移动端富文本", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> edit(@Validated({AddGroup.class, EditGroup.class}) @RequestBody AppEventMdBo bo) {
+        return toAjax(appEventMdService.editByBo(bo));
+    }
+
+    /**
+     * 删除移动端富文本
+     *
+     */
+    @SaCheckPermission("system:eventMd:remove")
+    @Log(title = "移动端富文本", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{eventId}/{type}")
+    public R<Void> remove(@NotNull(message = "赛事id不能为空")
+                          @PathVariable Long eventId,
+                          @NotNull(message = "赛事id不能为空")
+                          @PathVariable Integer type) {
+        return toAjax(appEventMdService.deleteByEventIdAndType(eventId, type));
+    }
+}

+ 83 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/UserAdviceController.java

@@ -0,0 +1,83 @@
+package org.dromara.system.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.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.system.domain.vo.AdviceVo;
+import org.dromara.system.domain.bo.AdviceBo;
+import org.dromara.system.service.IAdviceService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 用户反馈建议
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/advice")
+public class UserAdviceController extends BaseController {
+
+    private final IAdviceService adviceService;
+
+    /**
+     * 查询用户反馈建议列表
+     */
+    @SaCheckPermission("system:advice:list")
+    @GetMapping("/list")
+    public TableDataInfo<AdviceVo> list(AdviceBo bo, PageQuery pageQuery) {
+        return adviceService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出用户反馈建议列表
+     */
+    @SaCheckPermission("system:advice:export")
+    @Log(title = "用户反馈建议", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(AdviceBo bo, HttpServletResponse response) {
+        List<AdviceVo> list = adviceService.queryList(bo);
+        ExcelUtil.exportExcel(list, "用户反馈建议", AdviceVo.class, response);
+    }
+
+    /**
+     * 获取用户反馈建议详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:advice:query")
+    @GetMapping("/{id}")
+    public R<AdviceVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable Long id) {
+        return R.ok(adviceService.queryById(id));
+    }
+
+    /**
+     * 删除用户反馈建议
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:advice:remove")
+    @Log(title = "用户反馈建议", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(adviceService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 46 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/AdviceController.java

@@ -0,0 +1,46 @@
+package org.dromara.system.controller.app;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.system.domain.bo.AdviceBo;
+import org.dromara.system.service.IAdviceService;
+import org.dromara.system.service.IGameTeamService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/app/advice")
+public class AdviceController {
+    private final IAdviceService adviceService;
+    private final IGameTeamService gameTeamService;
+
+    /**
+     * 用户反馈建议
+     */
+    @Log(title = "用户反馈建议", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody AdviceBo bo) {
+        adviceService.insertByBo(bo);
+        return R.ok("反馈成功");
+    }
+
+    /**
+     * 获取队伍id name的映射关系
+     * @param eventId
+     * @return
+     */
+    @GetMapping("/teamList/{eventId}")
+    public R<Map<Long, String>> teamList(@PathVariable String eventId) {
+        return R.ok(gameTeamService.getTeamIdAndNameMap(eventId));
+    }
+
+}

+ 4 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/AppMarkdownController.java

@@ -0,0 +1,4 @@
+package org.dromara.system.controller.app;
+
+public class AppMarkdownController {
+}

+ 47 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/Advice.java

@@ -0,0 +1,47 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.sql.Timestamp;
+
+/**
+ * 用户反馈建议对象 advice
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+@TableName("advice")
+public class Advice {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+    private Long eventId;
+
+    /**
+     * 姓名
+     */
+    private String name;
+
+    /**
+     * 队伍id
+     */
+    private Long teamId;
+
+    /**
+     * 反馈内容
+     */
+    private String content;
+
+    private Timestamp createTime;
+}

+ 58 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/AppEventMd.java

@@ -0,0 +1,58 @@
+package org.dromara.system.domain;
+
+import lombok.Builder;
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 移动端富文本对象 app_event_md
+ *
+ * @author Lion Li
+ * @date 2025-08-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("app_event_md")
+public class AppEventMd extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 赛事id
+     */
+    private Long eventId;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程
+  6:赛事分组 7:运动员号码簿 8:项目场地
+     */
+    private Integer type;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 40 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/EventMenu.java

@@ -0,0 +1,40 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 赛事菜单关联对象 event_menu
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("event_menu")
+public class EventMenu extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 赛事id
+     */
+    private Long eventId;
+
+    /**
+     * 菜单列表
+     */
+    private String menuList;
+
+}

+ 55 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/AdviceBo.java

@@ -0,0 +1,55 @@
+package org.dromara.system.domain.bo;
+
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.system.domain.Advice;
+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.*;
+
+/**
+ * 用户反馈建议业务对象 advice
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+@AutoMapper(target = Advice.class, reverseConvertGenerate = false)
+public class AdviceBo {
+
+    /**
+     *
+     */
+    private Long id;
+
+    @NotNull(message = "赛事id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long eventId;
+
+    /**
+     * 姓名
+     */
+    @NotBlank(message = "姓名不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String name;
+
+    /**
+     * 队伍id
+     */
+    @NotNull(message = "队伍id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long teamId;
+
+    /**
+     * 队伍名称
+     */
+    private String teamName;
+
+    /**
+     * 反馈内容
+     */
+    @NotBlank(message = "反馈内容不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String content;
+
+
+}

+ 59 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/AppEventMdBo.java

@@ -0,0 +1,59 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.AppEventMd;
+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.*;
+
+/**
+ * 移动端富文本业务对象 app_event_md
+ *
+ * @author Lion Li
+ * @date 2025-08-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = AppEventMd.class, reverseConvertGenerate = false)
+public class AppEventMdBo extends BaseEntity {
+
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 赛事id
+     */
+    @NotNull(message = "赛事id不能为空")
+    private Long eventId;
+
+    /**
+     * 标题
+     */
+    @NotEmpty(message = "标题不能为空")
+    private String title;
+
+    /**
+     * 内容
+     */
+    @NotEmpty(message = "内容不能为空")
+    private String content;
+
+    /**
+     * 类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程
+  6:赛事分组 7:运动员号码簿 8:项目场地
+     */
+    @NotNull(message = "类型不能为空")
+    private Integer type;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 42 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/EventMenuBo.java

@@ -0,0 +1,42 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.EventMenu;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 赛事菜单关联业务对象 event_menu
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = EventMenu.class, reverseConvertGenerate = false)
+public class EventMenuBo extends BaseEntity {
+
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 赛事id
+     */
+    private Long eventId;
+
+    /**
+     * 菜单列表
+     */
+    private String menuList;
+
+
+    /**
+     * 菜单列表
+     */
+    private List<Long> menus;
+}

+ 58 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AdviceVo.java

@@ -0,0 +1,58 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.Advice;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 用户反馈建议视图对象 advice
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = Advice.class)
+public class AdviceVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+    private Long eventId;
+    /**
+     * 姓名
+     */
+    @ExcelProperty(value = "姓名")
+    private String name;
+
+    /**
+     * 队伍id
+     */
+    @ExcelProperty(value = "队伍id")
+    private Long teamId;
+
+    /**
+     * 队伍名称
+     */
+    @ExcelProperty(value = "队伍名称")
+    private String teamName;
+
+    /**
+     * 反馈内容
+     */
+    @ExcelProperty(value = "反馈内容")
+    private String content;
+
+
+}

+ 71 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AppEventMdVo.java

@@ -0,0 +1,71 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.AppEventMd;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+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.Date;
+
+
+
+/**
+ * 移动端富文本视图对象 app_event_md
+ *
+ * @author Lion Li
+ * @date 2025-08-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = AppEventMd.class)
+public class AppEventMdVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 赛事id
+     */
+    @ExcelProperty(value = "赛事id")
+    private Long eventId;
+
+    /**
+     * 标题
+     */
+    @ExcelProperty(value = "标题")
+    private String title;
+
+    /**
+     * 内容
+     */
+    @ExcelProperty(value = "内容")
+    private String content;
+
+    /**
+     * 类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程
+  6:赛事分组 7:运动员号码簿 8:项目场地
+     */
+    @ExcelProperty(value = "类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程 " +
+        "6:赛事分组 7:运动员号码簿 8:项目场地", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "markdown_location")
+    private Integer type;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 53 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/EventMenuVo.java

@@ -0,0 +1,53 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.EventMenu;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * 赛事菜单关联视图对象 event_menu
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = EventMenu.class)
+public class EventMenuVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 赛事id
+     */
+    @ExcelProperty(value = "赛事id")
+    private Long eventId;
+
+    /**
+     * 菜单列表
+     */
+    @ExcelProperty(value = "菜单列表")
+    private String menuList;
+
+    /**
+     * 菜单列表
+     */
+    @ExcelProperty(value = "菜单列表")
+    private List<Long> menus;
+
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/AdviceMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.Advice;
+import org.dromara.system.domain.vo.AdviceVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 用户反馈建议Mapper接口
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+public interface AdviceMapper extends BaseMapperPlus<Advice, AdviceVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/AppEventMdMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.AppEventMd;
+import org.dromara.system.domain.vo.AppEventMdVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 移动端富文本Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-08-18
+ */
+public interface AppEventMdMapper extends BaseMapperPlus<AppEventMd, AppEventMdVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/EventMenuMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.EventMenu;
+import org.dromara.system.domain.vo.EventMenuVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 赛事菜单关联Mapper接口
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+public interface EventMenuMapper extends BaseMapperPlus<EventMenu, EventMenuVo> {
+
+}

+ 68 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IAdviceService.java

@@ -0,0 +1,68 @@
+package org.dromara.system.service;
+
+import org.dromara.system.domain.vo.AdviceVo;
+import org.dromara.system.domain.bo.AdviceBo;
+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 wenkai
+ * @date 2025-08-18
+ */
+public interface IAdviceService {
+
+    /**
+     * 查询用户反馈建议
+     *
+     * @param id 主键
+     * @return 用户反馈建议
+     */
+    AdviceVo queryById(Long id);
+
+    /**
+     * 分页查询用户反馈建议列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 用户反馈建议分页列表
+     */
+    TableDataInfo<AdviceVo> queryPageList(AdviceBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的用户反馈建议列表
+     *
+     * @param bo 查询条件
+     * @return 用户反馈建议列表
+     */
+    List<AdviceVo> queryList(AdviceBo bo);
+
+    /**
+     * 新增用户反馈建议
+     *
+     * @param bo 用户反馈建议
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(AdviceBo bo);
+
+    /**
+     * 修改用户反馈建议
+     *
+     * @param bo 用户反馈建议
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(AdviceBo bo);
+
+    /**
+     * 校验并批量删除用户反馈建议信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 92 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IAppEventMdService.java

@@ -0,0 +1,92 @@
+package org.dromara.system.service;
+
+import jakarta.validation.constraints.NotNull;
+import org.dromara.system.domain.vo.AppEventMdVo;
+import org.dromara.system.domain.bo.AppEventMdBo;
+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-08-18
+ */
+public interface IAppEventMdService {
+
+    /**
+     * 查询移动端富文本
+     *
+     * @param id 主键
+     * @return 移动端富文本
+     */
+    AppEventMdVo queryById(Long id);
+
+    /**
+     * 分页查询移动端富文本列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 移动端富文本分页列表
+     */
+    TableDataInfo<AppEventMdVo> queryPageList(AppEventMdBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的移动端富文本列表
+     *
+     * @param bo 查询条件
+     * @return 移动端富文本列表
+     */
+    List<AppEventMdVo> queryList(AppEventMdBo bo);
+
+    /**
+     * 新增移动端富文本
+     *
+     * @param bo 移动端富文本
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(AppEventMdBo bo);
+
+    /**
+     * 修改移动端富文本
+     *
+     * @param bo 移动端富文本
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(AppEventMdBo bo);
+
+    /**
+     * 校验并批量删除移动端富文本信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 根据赛事id和类型获取移动端富文本详细信息
+     * @param eventId
+     * @param type
+     * @return
+     */
+    AppEventMdVo queryByEventIdAndType( Long eventId,  Integer type);
+
+    /**
+     * 编辑移动端富文本
+     * @param bo
+     * @return
+     */
+    Boolean editByBo(AppEventMdBo bo);
+
+    /**
+     * 删除移动端富文本
+     * @param eventId
+     * @param type
+     * @return
+     */
+    int deleteByEventIdAndType(Long eventId,  Integer type);
+}

+ 83 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IEventMenuService.java

@@ -0,0 +1,83 @@
+package org.dromara.system.service;
+
+import org.dromara.system.domain.vo.EventMenuVo;
+import org.dromara.system.domain.bo.EventMenuBo;
+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 wenkai
+ * @date 2025-08-18
+ */
+public interface IEventMenuService {
+
+    /**
+     * 查询赛事菜单关联
+     *
+     * @param id 主键
+     * @return 赛事菜单关联
+     */
+    EventMenuVo queryById(Long id);
+
+    /**
+     * 查询赛事菜单关联
+     *
+     * @param eventId 赛事id
+     * @return 赛事菜单关联
+     */
+    EventMenuVo queryByEventId(Long eventId);
+
+    /**
+     * 分页查询赛事菜单关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 赛事菜单关联分页列表
+     */
+    TableDataInfo<EventMenuVo> queryPageList(EventMenuBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的赛事菜单关联列表
+     *
+     * @param bo 查询条件
+     * @return 赛事菜单关联列表
+     */
+    List<EventMenuVo> queryList(EventMenuBo bo);
+
+    /**
+     * 新增赛事菜单关联
+     *
+     * @param bo 赛事菜单关联
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(EventMenuBo bo);
+
+    /**
+     * 修改赛事菜单关联
+     *
+     * @param bo 赛事菜单关联
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(EventMenuBo bo);
+
+    /**
+     * 校验并批量删除赛事菜单关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 更新赛事关联菜单
+     * @param bo
+     * @return
+     */
+    Boolean editByVo(EventMenuBo bo);
+}

+ 8 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameNavigatorService.java

@@ -3,6 +3,7 @@ package org.dromara.system.service;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.domain.bo.GameNavigatorBo;
+import org.dromara.system.domain.vo.EventMenuVo;
 import org.dromara.system.domain.vo.GameNavigatorVo;
 
 import java.util.Collection;
@@ -73,4 +74,11 @@ public interface IGameNavigatorService {
      */
     List<GameNavigatorVo> getEnabledNavList();
 
+    /**
+     * 获取赛事对应的菜单
+     * @param eventId
+     * @param pageQuery
+     * @return
+     */
+    TableDataInfo<GameNavigatorVo> queryPageListByEventId(Long eventId, PageQuery pageQuery);
 }

+ 9 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameTeamService.java

@@ -8,6 +8,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -88,4 +89,12 @@ public interface IGameTeamService {
      * @return
      */
     List<GameTeamVo> listByIds(Collection<Long> teamIds);
+
+
+    /**
+     * 获取队伍id和名称的映射关系
+     * @param eventId
+     * @return
+     */
+    Map<Long, String> getTeamIdAndNameMap(String eventId);
 }

+ 164 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AdviceServiceImpl.java

@@ -0,0 +1,164 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+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.dromara.common.redis.utils.RedisUtils;
+import org.dromara.system.domain.bo.GameTeamBo;
+import org.dromara.system.domain.constant.GameEventConstant;
+import org.dromara.system.domain.vo.GameTeamVo;
+import org.dromara.system.service.IGameTeamService;
+import org.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.AdviceBo;
+import org.dromara.system.domain.vo.AdviceVo;
+import org.dromara.system.domain.Advice;
+import org.dromara.system.mapper.AdviceMapper;
+import org.dromara.system.service.IAdviceService;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * 用户反馈建议Service业务层处理
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class AdviceServiceImpl implements IAdviceService {
+
+    private final AdviceMapper baseMapper;
+    private final IGameTeamService gameTeamService;
+
+    /**
+     * 查询用户反馈建议
+     *
+     * @param id 主键
+     * @return 用户反馈建议
+     */
+    @Override
+    public AdviceVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询用户反馈建议列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 用户反馈建议分页列表
+     */
+    @Override
+    public TableDataInfo<AdviceVo> queryPageList(AdviceBo bo, PageQuery pageQuery) {
+        Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
+        Long defaultEventId = Long.valueOf(cacheObject.toString());
+        bo.setEventId(defaultEventId);
+        LambdaQueryWrapper<Advice> lqw = buildQueryWrapper(bo);
+        Page<AdviceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        result.getRecords().stream()
+            .map(vo -> {
+                GameTeamVo gameTeamVo = gameTeamService.queryById(vo.getTeamId());
+                vo.setTeamName(gameTeamVo.getTeamName());
+                return vo;
+            })
+            .collect(Collectors.toList());
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的用户反馈建议列表
+     *
+     * @param bo 查询条件
+     * @return 用户反馈建议列表
+     */
+    @Override
+    public List<AdviceVo> queryList(AdviceBo bo) {
+        LambdaQueryWrapper<Advice> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<Advice> buildQueryWrapper(AdviceBo bo) {
+        LambdaQueryWrapper<Advice> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(Advice::getId);
+        lqw.like(StringUtils.isNotBlank(bo.getName()), Advice::getName, bo.getName());
+        if (StrUtil.isNotEmpty(bo.getTeamName())) {
+            GameTeamBo gameTeamBo = new GameTeamBo();
+            gameTeamBo.setTeamName(bo.getTeamName());
+            List<GameTeamVo> gameTeamVos = gameTeamService.queryList(gameTeamBo);
+            if (!gameTeamVos.isEmpty()) {
+                List<Long> ids = gameTeamVos.stream()
+                    .map(GameTeamVo::getTeamId)
+                    .collect(Collectors.toList());
+                lqw.in(Advice::getTeamId, ids);
+            } else {
+                lqw.in(Advice::getTeamId, Collections.singletonList(-1L));
+            }
+        }
+        lqw.eq(StringUtils.isNotBlank(bo.getContent()), Advice::getContent, bo.getContent());
+        return lqw;
+    }
+
+    /**
+     * 新增用户反馈建议
+     *
+     * @param bo 用户反馈建议
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(AdviceBo bo) {
+        Advice add = MapstructUtils.convert(bo, Advice.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改用户反馈建议
+     *
+     * @param bo 用户反馈建议
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(AdviceBo bo) {
+        Advice update = MapstructUtils.convert(bo, Advice.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(Advice entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除用户反馈建议信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 191 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AppEventMdServiceImpl.java

@@ -0,0 +1,191 @@
+package org.dromara.system.service.impl;
+
+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.dromara.system.domain.bo.AppEventMdBo;
+import org.dromara.system.domain.vo.AppEventMdVo;
+import org.dromara.system.domain.AppEventMd;
+import org.dromara.system.mapper.AppEventMdMapper;
+import org.dromara.system.service.IAppEventMdService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * 移动端富文本Service业务层处理
+ *
+ * @author Lion Li
+ * @date 2025-08-18
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class AppEventMdServiceImpl implements IAppEventMdService {
+
+    private final AppEventMdMapper baseMapper;
+
+    /**
+     * 查询移动端富文本
+     *
+     * @param id 主键
+     * @return 移动端富文本
+     */
+    @Override
+    public AppEventMdVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询移动端富文本列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 移动端富文本分页列表
+     */
+    @Override
+    public TableDataInfo<AppEventMdVo> queryPageList(AppEventMdBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<AppEventMd> lqw = buildQueryWrapper(bo);
+        Page<AppEventMdVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的移动端富文本列表
+     *
+     * @param bo 查询条件
+     * @return 移动端富文本列表
+     */
+    @Override
+    public List<AppEventMdVo> queryList(AppEventMdBo bo) {
+        LambdaQueryWrapper<AppEventMd> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<AppEventMd> buildQueryWrapper(AppEventMdBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<AppEventMd> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(AppEventMd::getId);
+        lqw.eq(bo.getEventId() != null, AppEventMd::getEventId, bo.getEventId());
+        lqw.like(StringUtils.isNotBlank(bo.getTitle()), AppEventMd::getTitle, bo.getTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getContent()), AppEventMd::getContent, bo.getContent());
+        lqw.eq(bo.getType() != null, AppEventMd::getType, bo.getType());
+        return lqw;
+    }
+
+    /**
+     * 新增移动端富文本
+     *
+     * @param bo 移动端富文本
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(AppEventMdBo bo) {
+        AppEventMd add = MapstructUtils.convert(bo, AppEventMd.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改移动端富文本
+     *
+     * @param bo 移动端富文本
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(AppEventMdBo bo) {
+        AppEventMd update = MapstructUtils.convert(bo, AppEventMd.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(AppEventMd entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除移动端富文本信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 根据赛事id和类型获取移动端富文本详细信息
+     *
+     * @param eventId
+     * @param type
+     * @return
+     */
+    @Override
+    public AppEventMdVo queryByEventIdAndType(Long eventId, Integer type) {
+        return baseMapper.selectVoOne(
+            Wrappers.lambdaQuery(AppEventMd.class)
+                .eq(AppEventMd::getEventId, eventId)
+                .eq(AppEventMd::getType, type)
+        );
+    }
+
+    /**
+     * 编辑移动端富文本
+     *
+     * @param bo
+     * @return
+     */
+    @Override
+    public Boolean editByBo(AppEventMdBo bo) {
+        //查询是否存在
+        AppEventMdVo vo = this.queryByEventIdAndType(bo.getEventId(), bo.getType());
+        if (Optional.ofNullable(vo).isPresent()) {
+            bo.setId(vo.getId());
+            return this.updateByBo(bo);
+        } else {
+            return this.insertByBo(bo);
+        }
+    }
+
+    /**
+     * 删除移动端富文本
+     *
+     * @param eventId
+     * @param type
+     * @return
+     */
+    @Override
+    public int deleteByEventIdAndType(Long eventId, Integer type) {
+        //并不是删除  而是情况所有内容
+        AppEventMd appEventMd = new AppEventMd();
+        appEventMd.setEventId(eventId);
+        appEventMd.setTitle("");
+        appEventMd.setContent("");
+        appEventMd.setType(type);
+        appEventMd.setRemark("");
+        return baseMapper.update(appEventMd,Wrappers.lambdaQuery(AppEventMd.class)
+            .eq(AppEventMd::getEventId, eventId)
+            .eq(AppEventMd::getType, type));
+    }
+}

+ 208 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/EventMenuServiceImpl.java

@@ -0,0 +1,208 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.json.JSONUtil;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.ObjectUtils;
+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.dromara.system.domain.bo.EventMenuBo;
+import org.dromara.system.domain.vo.EventMenuVo;
+import org.dromara.system.domain.EventMenu;
+import org.dromara.system.mapper.EventMenuMapper;
+import org.dromara.system.service.IEventMenuService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 赛事菜单关联Service业务层处理
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class EventMenuServiceImpl implements IEventMenuService {
+
+    private final EventMenuMapper baseMapper;
+
+    /**
+     * 查询赛事菜单关联
+     *
+     * @param id 主键
+     * @return 赛事菜单关联
+     */
+    @Override
+    public EventMenuVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 查询赛事菜单关联
+     *
+     * @param eventId 赛事id
+     * @return 赛事菜单关联
+     */
+    @Override
+    public EventMenuVo queryByEventId(Long eventId) {
+        return baseMapper.selectVoOne(
+            Wrappers.lambdaQuery(EventMenu.class)
+                .eq(EventMenu::getEventId, eventId)
+        );
+    }
+
+    /**
+     * 分页查询赛事菜单关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 赛事菜单关联分页列表
+     */
+    @Override
+    public TableDataInfo<EventMenuVo> queryPageList(EventMenuBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<EventMenu> lqw = buildQueryWrapper(bo);
+        Page<EventMenuVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        result.getRecords().stream()
+            .map(item -> {
+                Optional.ofNullable(item.getMenuList())
+                    .ifPresent(menuList -> item.setMenus(JSONUtil.toList(menuList, Long.class)));
+                return item;
+            })
+            .collect(Collectors.toList());
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的赛事菜单关联列表
+     *
+     * @param bo 查询条件
+     * @return 赛事菜单关联列表
+     */
+    @Override
+    public List<EventMenuVo> queryList(EventMenuBo bo) {
+        LambdaQueryWrapper<EventMenu> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<EventMenu> buildQueryWrapper(EventMenuBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<EventMenu> lqw = Wrappers.lambdaQuery();
+        lqw.eq(EventMenu::getEventId, bo.getEventId());
+        lqw.orderByAsc(EventMenu::getId);
+        return lqw;
+    }
+
+    /**
+     * 新增赛事菜单关联
+     *
+     * @param bo 赛事菜单关联
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(EventMenuBo bo) {
+        EventMenu add = MapstructUtils.convert(bo, EventMenu.class);
+        validEntityBeforeSave(add);
+        Optional.ofNullable(bo.getMenuList())
+            .ifPresent(menuList -> add.setMenuList(JSONUtil.toJsonStr(menuList)));
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改赛事菜单关联
+     *
+     * @param bo 赛事菜单关联
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(EventMenuBo bo) {
+        EventMenu update = MapstructUtils.convert(bo, EventMenu.class);
+        Optional.ofNullable(bo.getMenuList())
+            .ifPresent(menuList -> update.setMenuList(JSONUtil.toJsonStr(menuList)));
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(EventMenu entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除赛事菜单关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 更新赛事关联菜单
+     *
+     * @param bo
+     * @return
+     */
+    @Override
+    public Boolean editByVo(EventMenuBo bo) {
+        if (ObjectUtils.isNull(bo)) {
+            throw new ServiceException("参数不能为空");
+        }
+        if (ObjectUtils.isNull(bo.getEventId())) {
+            throw new ServiceException("赛事id不能为空");
+        }
+
+        Long eventId = bo.getEventId();
+
+        // 如果 menus 为空或 null,则视为删除该赛事的菜单关联
+        if (ObjectUtils.isEmpty(bo.getMenus())) {
+            // 删除该 eventId 对应的记录
+            LambdaQueryWrapper<EventMenu> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(EventMenu::getEventId, eventId);
+            baseMapper.delete(queryWrapper);
+            return Boolean.TRUE;
+        }
+
+        // 转换并设置菜单 JSON 字符串
+        EventMenu entity = MapstructUtils.convert(bo, EventMenu.class);
+        entity.setMenuList(JSONUtil.toJsonStr(bo.getMenus()));
+
+        // 根据 eventId 查询是否存在记录
+        LambdaQueryWrapper<EventMenu> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(EventMenu::getEventId, eventId);
+        EventMenu old = baseMapper.selectOne(queryWrapper);
+
+        if (old != null) {
+            // 存在则更新
+            entity.setId(old.getId()); // 保持主键一致
+            baseMapper.updateById(entity);
+        } else {
+            // 不存在则插入
+            baseMapper.insert(entity);
+        }
+
+        return Boolean.TRUE;
+    }
+}

+ 18 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameTeamServiceImpl.java

@@ -141,6 +141,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
             }
         }
         LambdaQueryWrapper<GameTeam> lqw = buildQueryWrapper(bo);
+        lqw.like(GameTeam::getTeamName, bo.getTeamName());
         return baseMapper.selectVoList(lqw);
     }
 
@@ -281,4 +282,21 @@ public class GameTeamServiceImpl implements IGameTeamService {
                 .in(GameTeam::getTeamId, teamIds)
         );
     }
+
+    /**
+     * 获取队伍id和名称的映射关系
+     *
+     * @param eventId
+     * @return
+     */
+    @Override
+    public Map<Long, String> getTeamIdAndNameMap(String eventId) {
+        List<GameTeamVo> list = baseMapper.selectVoList(
+            Wrappers.lambdaQuery(GameTeam.class)
+                .eq(GameTeam::getEventId, eventId)
+        );
+        Map<Long, String> map = list.stream()
+            .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
+        return map;
+    }
 }

+ 33 - 4
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/IGameNavigatorServiceImpl.java

@@ -1,6 +1,8 @@
 package org.dromara.system.service.impl;
 
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
@@ -10,16 +12,16 @@ import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.domain.GameNavigator;
+import org.dromara.system.domain.bo.EventMenuBo;
 import org.dromara.system.domain.bo.GameNavigatorBo;
+import org.dromara.system.domain.vo.EventMenuVo;
 import org.dromara.system.domain.vo.GameNavigatorVo;
 import org.dromara.system.mapper.GameNavigatorMapper;
+import org.dromara.system.service.IEventMenuService;
 import org.dromara.system.service.IGameNavigatorService;
 import org.springframework.stereotype.Service;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * 主导航表Service业务层处理
@@ -33,6 +35,7 @@ import java.util.Objects;
 public class IGameNavigatorServiceImpl implements IGameNavigatorService {
 
     private final GameNavigatorMapper baseMapper;
+    private final IEventMenuService eventMenuService;
 
     /**
      * 查询主导航表
@@ -149,4 +152,30 @@ public class IGameNavigatorServiceImpl implements IGameNavigatorService {
         return baseMapper.getEnabledNavList();
     }
 
+    /**
+     * 获取赛事对应的菜单
+     *
+     * @param eventId
+     * @param pageQuery
+     * @return
+     */
+    @Override
+    public TableDataInfo<GameNavigatorVo> queryPageListByEventId(Long eventId, PageQuery pageQuery) {
+        EventMenuVo vo = eventMenuService.queryByEventId(eventId);
+        List<Long> navIdList = Optional.ofNullable(vo)
+            .map(v -> JSONUtil.toList(v.getMenuList(), Long.class))
+            .orElse(Collections.emptyList());
+        // 如果 navIdList 为空,直接返回空分页
+        if (navIdList.isEmpty()) {
+            IPage<GameNavigatorVo> emptyPage = pageQuery.build();
+            emptyPage.setRecords(Collections.emptyList());
+            emptyPage.setTotal(0);
+            return TableDataInfo.build(emptyPage);
+        }
+        IPage<GameNavigatorVo> result = baseMapper.selectVoPage(pageQuery.build(),
+            Wrappers.lambdaQuery(GameNavigator.class)
+                .in(GameNavigator::getNavId, navIdList)
+        );
+        return TableDataInfo.build(result);
+    }
 }

+ 7 - 0
ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/AdviceMapper.xml

@@ -0,0 +1,7 @@
+<?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.system.mapper.AdviceMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/AppEventMdMapper.xml

@@ -0,0 +1,7 @@
+<?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.system.mapper.AppEventMdMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/EventMenuMapper.xml

@@ -0,0 +1,7 @@
+<?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.system.mapper.EventMenuMapper">
+
+</mapper>

+ 15 - 0
本周改动.md

@@ -0,0 +1,15 @@
+<h1>本周改动</h1>
+
+<h2>8.18</h2>
+
+<li>完成赛事与菜单的关联</li>
+<li>完成部分App端查询接口</li>
+<li>完成App端用户建议相关接口</li>
+<li>完善菜单栏相关接口</li>
+<li>统一活动菜单管理的图标颜色的传值类型</li>
+<li>完善活动菜单管理的搜索条件区域功能</li>
+<li>增加全局默认赛事显示功能</li>
+<li>美化赛事操作列样式</li>
+
+
+