2 Commit-ok e12748073b ... 1db4804d06

Szerző SHA1 Üzenet Dátum
  zhou 1db4804d06 refactor(game): 使用枚举替换硬编码项目分类 4 hónapja
  zhou 2ea1d80cee refactor(game-event): 调整队伍相关接口及权限注解配置 4 hónapja

+ 7 - 0
ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/handler/SaTokenExceptionHandler.java

@@ -8,6 +8,7 @@ import cn.hutool.http.HttpStatus;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.domain.R;
+import org.springframework.core.annotation.Order;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
@@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
  * @author Lion Li
  */
 @Slf4j
+@Order(-1) // 设置更高优先级,确保在GlobalExceptionHandler之前执行
 @RestControllerAdvice
 public class SaTokenExceptionHandler {
 
@@ -46,6 +48,11 @@ public class SaTokenExceptionHandler {
     @ExceptionHandler(NotLoginException.class)
     public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
+        // 检查是否是token被冻结的情况
+        if (e.getMessage() != null && e.getMessage().contains("已被冻结")) {
+            log.error("请求地址'{}',Token被冻结'{}',请重新登录", requestURI, e.getMessage());
+            return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "账号已在其他地点登录或被管理员强制下线,请重新登录");
+        }
         log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage());
         return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源");
     }

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

@@ -24,22 +24,22 @@ public interface AdviceMapper extends BaseMapperPlus<Advice, AdviceVo> {
     /**
      * 分页查询队伍列表,并进行数据权限控制
      */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "create_dept"),
-        @DataColumn(key = "userName", value = "create_by")
-    })
-    default Page<AdviceVo> selectPageAdviceList(Page<Advice> page, Wrapper<Advice> queryWrapper) {
-        return this.selectVoPage(page, queryWrapper);
-    }
+//    @DataPermission({
+//        @DataColumn(key = "deptName", value = "create_dept"),
+//        @DataColumn(key = "userName", value = "create_by")
+//    })
+//    default Page<AdviceVo> selectPageAdviceList(Page<Advice> page, Wrapper<Advice> queryWrapper) {
+//        return this.selectVoPage(page, queryWrapper);
+//    }
 
     /**
      * 获取队伍列表,并进行数据权限控制
      */
-    @DataPermission({
-        @DataColumn(key = "deptName", value = "create_dept"),
-        @DataColumn(key = "userName", value = "create_by")
-    })
-    default List<AdviceVo> selectAdviceList(Wrapper<Advice> queryWrapper) {
-        return this.selectVoList(queryWrapper);
-    }
+//    @DataPermission({
+//        @DataColumn(key = "deptName", value = "create_dept"),
+//        @DataColumn(key = "userName", value = "create_by")
+//    })
+//    default List<AdviceVo> selectAdviceList(Wrapper<Advice> queryWrapper) {
+//        return this.selectVoList(queryWrapper);
+//    }
 }

+ 2 - 4
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/GameTeamMapper.java

@@ -6,10 +6,8 @@ import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Select;
 import org.dromara.common.mybatis.annotation.DataColumn;
 import org.dromara.common.mybatis.annotation.DataPermission;
-import org.dromara.system.domain.GameEventProject;
 import org.dromara.system.domain.GameTeam;
 import org.dromara.system.domain.bo.GameTeamBo;
-import org.dromara.system.domain.vo.GameEventProjectVo;
 import org.dromara.system.domain.vo.GameTeamVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
@@ -82,8 +80,8 @@ public interface GameTeamMapper extends BaseMapperPlus<GameTeam, GameTeamVo> {
      * @return 队伍列表
      */
     @DataPermission({
-        @DataColumn(key = "deptName", value = "create_dept"),
-        @DataColumn(key = "userName", value = "create_by")
+        @DataColumn(key = "deptName", value = "gt.create_dept"),
+        @DataColumn(key = "userName", value = "gt.create_by")
     })
     List<GameTeamVo> selectVoListWithGroupName(GameTeamBo bo);
 }

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

@@ -63,8 +63,8 @@ public class AdviceServiceImpl implements IAdviceService {
         Long defaultEventId = Long.valueOf(cacheObject.toString());
         bo.setEventId(defaultEventId);
         LambdaQueryWrapper<Advice> lqw = buildQueryWrapper(bo);
-//        Page<AdviceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        Page<AdviceVo> result = baseMapper.selectPageAdviceList(pageQuery.build(), lqw);
+        Page<AdviceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+//        Page<AdviceVo> result = baseMapper.selectPageAdviceList(pageQuery.build(), lqw);
         //提前查询出队伍id和name的映射并缓存
         Set<Long> ids = result.getRecords()
             .stream()
@@ -87,8 +87,8 @@ public class AdviceServiceImpl implements IAdviceService {
     @Override
     public List<AdviceVo> queryList(AdviceBo bo) {
         LambdaQueryWrapper<Advice> lqw = buildQueryWrapper(bo);
-//        return baseMapper.selectVoList(lqw);
-        return baseMapper.selectAdviceList(lqw);
+        return baseMapper.selectVoList(lqw);
+//        return baseMapper.selectAdviceList(lqw);
     }
 
     private LambdaQueryWrapper<Advice> buildQueryWrapper(AdviceBo bo) {

+ 37 - 8
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameScoreServiceImpl.java

@@ -519,7 +519,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
 
         Boolean result = false;
 
-        if (project != null && "1".equals(project.getClassification())) {
+        if (project != null && ProjectClassification.TEAM.getValue().equals(project.getClassification())) {
             // 团体项目:为队伍中的所有运动员创建或更新成绩记录
             log.info("处理团体项目成绩更新");
             result = handleTeamScoreUpdate(bo);
@@ -1339,18 +1339,47 @@ public class GameScoreServiceImpl implements IGameScoreService {
                     .eq(GameScore::getEventId, eventId)
             );
 
-            // 构建 teamId -> (projectId -> 积分累计和)
-            Map<Long, Map<Long, Integer>> teamProjectPointSumMap = new HashMap<>();
+            // 创建项目ID到项目信息的映射
+            Map<Long, GameEventProjectVo> projectMap = projects.stream()
+                .collect(Collectors.toMap(GameEventProjectVo::getProjectId, p -> p));
+
+            // 构建 teamId -> (projectId -> 积分)
+            Map<Long, Map<Long, Integer>> teamProjectPointMap = new HashMap<>();
+
+            // 为每个队伍初始化积分映射
+            for (GameTeamVo team : teams) {
+                teamProjectPointMap.put(team.getTeamId(), new HashMap<>());
+            }
+
+            // 处理积分计算
             for (GameScoreVo score : allScores) {
                 Long teamId = score.getTeamId();
                 Long projectId = score.getProjectId();
                 if (teamId == null || projectId == null) {
                     continue;
                 }
+
                 int points = score.getScorePoint() != null ? score.getScorePoint() : 0;
 
-                Map<Long, Integer> projectPointMap = teamProjectPointSumMap.computeIfAbsent(teamId, k -> new HashMap<>());
-                projectPointMap.merge(projectId, points, Integer::sum);
+                // 获取项目信息
+                GameEventProjectVo project = projectMap.get(projectId);
+                if (project == null) {
+                    continue;
+                }
+
+                // 为队伍初始化项目积分映射
+                Map<Long, Integer> projectPointMap = teamProjectPointMap.computeIfAbsent(teamId, k -> new HashMap<>());
+
+                // 区分项目类型处理积分
+                if (ProjectClassification.TEAM.getValue().equals(project.getClassification())) { // 团体项目
+                    // 团体项目:一个队伍只需记录一次积分(取任意一个运动员的积分)
+                    if (!projectPointMap.containsKey(projectId)) {
+                        projectPointMap.put(projectId, points);
+                    }
+                } else { // 个人项目
+                    // 个人项目:累加计算所有运动员的积分
+                    projectPointMap.merge(projectId, points, Integer::sum);
+                }
             }
 
             // 构建导出/前端展示数据
@@ -1365,7 +1394,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 Map<String, Integer> projectScores = new HashMap<>();
                 int totalScore = 0;
 
-                Map<Long, Integer> projectPointMap = teamProjectPointSumMap.getOrDefault(team.getTeamId(), Collections.emptyMap());
+                Map<Long, Integer> projectPointMap = teamProjectPointMap.getOrDefault(team.getTeamId(), Collections.emptyMap());
 
                 for (GameEventProjectVo project : projects) {
                     int projectScore = projectPointMap.getOrDefault(project.getProjectId(), 0);
@@ -1793,7 +1822,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
         int colIndex = 0;
 
         // 根据项目类型确定列标题
-        if ("0".equals(project.getClassification())) {
+        if (ProjectClassification.SINGLE.getValue().equals(project.getClassification())) {
             // 个人项目列标题
             String[] headers = {
                 "序号", "队伍编号", "队伍名称", "姓名", "号码",
@@ -1836,7 +1865,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
 
             int colIndex = 0;
 
-            if ("0".equals(project.getClassification())) {
+            if (ProjectClassification.SINGLE.getValue().equals(project.getClassification())) {
                 // 个人项目数据
                 createCellWithStyle(dataRow, colIndex++, i + 1, currentRowStyle); // 序号
                 createCellWithStyle(dataRow, colIndex++, data.get("teamCode"), currentRowStyle); // 队伍编号

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

@@ -0,0 +1,58 @@
+package org.dromara.system.utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import java.util.Objects;
+
+@Getter
+@AllArgsConstructor
+public enum ProjectClassification {
+
+    /**
+     * 枚举值:0-个人项目  1-团队项目
+     */
+    PERSONAL("0", "个人项目"),
+    TEAM("1", "团队项目");
+
+    /**
+     * 枚举编码
+     */
+    private final String code;
+
+    /**
+     * 枚举描述
+     */
+    private final String desc;
+
+    /**
+     * 获取枚举对象
+     *
+     * @param code 枚举编码
+     * @return 枚举对象
+     */
+    public static ProjectClassification findByCode(String code) {
+        Objects.requireNonNull(code, "The matching value cannot be empty");
+        for (ProjectClassification obj : values()) {
+            if (code.equals(obj.getCode())) {
+                return obj;
+            }
+        }
+        throw new IllegalArgumentException("No matching constant for [" + code + "]");
+    }
+
+    /**
+     * 获取枚举对象
+     *
+     * @param code 枚举编码
+     * @return 枚举对象
+     */
+    public static ProjectClassification findByCode(Integer code) {
+        Objects.requireNonNull(code, "The matching value cannot be empty");
+        for (ProjectClassification obj : values()) {
+            if (code.toString().equals(obj.getCode())) {
+                return obj;
+            }
+        }
+        throw new IllegalArgumentException("No matching constant for [" + code + "]");
+    }
+}