From 7ad9c3c93f0cc103347ae2e2429e0122fb512e24 Mon Sep 17 00:00:00 2001
From: lrj <owen.stl@gmail.com>
Date: 星期三, 01 十月 2025 21:26:12 +0800
Subject: [PATCH] feat: 修复员工管理功能并优化UI

---
 backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java |  365 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 278 insertions(+), 87 deletions(-)

diff --git a/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java b/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java
index 216689c..75bebca 100644
--- a/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java
+++ b/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java
@@ -2,31 +2,45 @@
 
 import com.rongyichuang.activity.dto.ActivityInput;
 import com.rongyichuang.activity.dto.ActivityJudgeInput;
+import com.rongyichuang.activity.dto.ActivityJudgeResponse;
 import com.rongyichuang.activity.dto.ActivityResponse;
 import com.rongyichuang.activity.dto.ActivityStageInput;
 import com.rongyichuang.activity.entity.Activity;
 import com.rongyichuang.activity.entity.ActivityJudge;
 import com.rongyichuang.activity.repository.ActivityJudgeRepository;
 import com.rongyichuang.activity.repository.ActivityRepository;
+import com.rongyichuang.judge.entity.Judge;
+import com.rongyichuang.player.repository.ActivityPlayerRepository;
+import com.rongyichuang.judge.repository.JudgeRepository;
 import com.rongyichuang.common.dto.PageRequest;
 import com.rongyichuang.common.dto.PageResponse;
 import com.rongyichuang.rating.entity.RatingScheme;
 import com.rongyichuang.rating.repository.RatingSchemeRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 @Service
 @Transactional
 public class ActivityService {
+    
+    private static final Logger log = LoggerFactory.getLogger(ActivityService.class);
     
     @Autowired
     private ActivityRepository activityRepository;
@@ -35,23 +49,46 @@
     private ActivityJudgeRepository activityJudgeRepository;
     
     @Autowired
+    private JudgeRepository judgeRepository;
+    
+    @Autowired
     private RatingSchemeRepository ratingSchemeRepository;
+    
+    @Autowired
+    private ActivityPlayerRepository activityPlayerRepository;
     
     /**
      * 鍒嗛〉鏌ヨ姣旇禌鍒楄〃
      */
-    public PageResponse<ActivityResponse> findCompetitions(PageRequest pageRequest, String name) {
+    public PageResponse<ActivityResponse> findActivities(PageRequest pageRequest, String name) {
         Pageable pageable = pageRequest.toPageable();
         Page<Activity> page;
-        
+
         if (StringUtils.hasText(name)) {
-            page = activityRepository.findByPidAndStateAndNameContainingOrderByCreateTimeDesc(0L, 1, name, pageable);
+            page = activityRepository.findByPidAndNameContainingOrderByCreateTimeDesc(0L, name, pageable);
         } else {
-            page = activityRepository.findByPidAndStateOrderByCreateTimeDesc(0L, 1, pageable);
+            // 鏌ヨ鎵�鏈変富娲诲姩锛坧id = 0锛�
+            page = activityRepository.findByPidOrderByCreateTimeDesc(0L, pageable);
         }
-        
+
         List<ActivityResponse> content = page.getContent().stream()
-            .map(ActivityResponse::new)
+            .map(activity -> {
+                ActivityResponse response = new ActivityResponse(activity);
+                // 璁剧疆鍙傝禌浜烘暟锛堝彧缁熻绗竴闃舵鐨勫鏍搁�氳繃瀛﹀憳浜烘暟锛�
+                int playerCount = 0;
+                Activity firstStage = activityRepository.findFirstStageByActivityId(activity.getId());
+                if (firstStage != null) {
+                    // 濡傛灉鏈夌涓�闃舵锛岀粺璁$涓�闃舵鐨勫鏍搁�氳繃浜烘暟
+                    Long playerCountLong = activityPlayerRepository.countByStageIdAndState(firstStage.getId(), 1);
+                    playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+                } else {
+                    // 濡傛灉娌℃湁闃舵锛岀粺璁℃椿鍔ㄦ湰韬殑瀹℃牳閫氳繃浜烘暟
+                    Long playerCountLong = activityPlayerRepository.countByActivityIdAndState(activity.getId(), 1);
+                    playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+                }
+                response.setPlayerCount(playerCount);
+                return response;
+            })
             .collect(Collectors.toList());
         
         return new PageResponse<>(content, page.getTotalElements(), page.getNumber(), page.getSize());
@@ -66,14 +103,30 @@
             Activity activity = activityOpt.get();
             ActivityResponse response = new ActivityResponse(activity);
             
+            // 璁剧疆鍙傝禌浜烘暟锛堝鏍搁�氳繃鐨勬姤鍚嶆暟閲忥級
+            Long playerCountLong = activityPlayerRepository.countByActivityId(activity.getId());
+            int playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+            response.setPlayerCount(playerCount);
+            
             // 濡傛灉鏄瘮璧涳紝鍔犺浇鍏堕樁娈�
-            if (activity.isCompetition()) {
+            if (activity.isMainActivity()) {
                 List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(id, 1);
                 List<ActivityResponse> stageResponses = stages.stream()
-                    .map(ActivityResponse::new)
+                    .map(stage -> {
+                        ActivityResponse stageResponse = new ActivityResponse(stage);
+                        // 璁剧疆闃舵鐨勫弬璧涗汉鏁�
+                        Long stagePlayerCountLong = activityPlayerRepository.countByActivityId(stage.getId());
+                        int stagePlayerCount = stagePlayerCountLong != null ? stagePlayerCountLong.intValue() : 0;
+                        stageResponse.setPlayerCount(stagePlayerCount);
+                        return stageResponse;
+                    })
                     .collect(Collectors.toList());
                 response.setStages(stageResponses);
             }
+            
+            // 鍔犺浇璇勫鏁版嵁
+            List<ActivityJudgeResponse> judges = loadActivityJudges(id);
+            response.setJudges(judges);
             
             return response;
         }
@@ -118,16 +171,34 @@
             }
         }
         
+        // 濡傛灉鏄瘮璧涳紝楠岃瘉蹇呴』鑷冲皯鏈変竴涓樁娈�
+        if (input.isMainActivity()) {
+            if (input.getStages() == null || input.getStages().isEmpty()) {
+                throw new RuntimeException("姣旇禌蹇呴』鑷冲皯鏈変竴涓樁娈�");
+            }
+            
+            // 楠岃瘉闃舵鏁伴噺涓嶈秴杩�5涓�
+            if (input.getStages().size() > 5) {
+                throw new RuntimeException("姣旇禌闃舵鏁伴噺涓嶈兘瓒呰繃5涓�");
+            }
+            
+            // 楠岃瘉sort_order杩炵画鎬�
+            validateSortOrderContinuity(input.getStages());
+        }
+        
         // 淇濆瓨姣旇禌
         activity = activityRepository.save(activity);
         
+        // 璁板綍鏃ュ織浠ヤ究璋冭瘯
+        log.info("淇濆瓨姣旇禌鎴愬姛锛屾瘮璧汭D: {}, 姣旇禌鍚嶇О: {}", activity.getId(), activity.getName());
+        
         // 濡傛灉鏄瘮璧涗笖鏈夐樁娈典俊鎭紝淇濆瓨闃舵
-        if (input.isCompetition() && input.getStages() != null && !input.getStages().isEmpty()) {
+        if (input.isMainActivity() && input.getStages() != null && !input.getStages().isEmpty()) {
             saveActivityStages(activity.getId(), input.getStages());
         }
         
         // 濡傛灉鏄瘮璧涗笖鏈夎瘎濮斾俊鎭紝淇濆瓨璇勫
-        if (input.isCompetition() && input.getJudges() != null && !input.getJudges().isEmpty()) {
+        if (input.isMainActivity() && input.getJudges() != null && !input.getJudges().isEmpty()) {
             saveActivityJudges(activity.getId(), input.getJudges());
         }
         
@@ -138,9 +209,9 @@
     /**
      * 淇濆瓨姣旇禌闃舵
      */
-    private void saveActivityStages(Long competitionId, List<ActivityStageInput> stageInputs) {
+    private void saveActivityStages(Long activityId, List<ActivityStageInput> stageInputs) {
         // 鑾峰彇鐜版湁鐨勬墍鏈夐樁娈�
-        List<Activity> existingStages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competitionId, 1);
+        List<Activity> existingStages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(activityId, 1);
         
         // 鏀堕泦浼犲叆鐨勯樁娈礗D
         List<Long> inputStageIds = stageInputs.stream()
@@ -157,11 +228,11 @@
         }
         
         // 鑾峰彇姣旇禌淇℃伅锛岀敤浜庣户鎵挎姤鍚嶆埅姝㈡椂闂村拰璇勫垎妯℃澘
-        Optional<Activity> competitionOpt = activityRepository.findById(competitionId);
-        if (!competitionOpt.isPresent()) {
+        Optional<Activity> activityOpt = activityRepository.findById(activityId);
+        if (!activityOpt.isPresent()) {
             throw new RuntimeException("姣旇禌涓嶅瓨鍦�");
         }
-        Activity competition = competitionOpt.get();
+        Activity activity = activityOpt.get();
         
         // 澶勭悊浼犲叆鐨勯樁娈碉紙鏂板鎴栨洿鏂帮級
         for (ActivityStageInput stageInput : stageInputs) {
@@ -170,8 +241,8 @@
             if (stageInput.isNew()) {
                 // 鏂板闃舵
                 stage = new Activity();
-                stage.setPid(competitionId);
-                stage.setPath(generatePath(competitionId));
+                stage.setPid(activityId);
+                stage.setPath(generatePath(activityId));
             } else {
                 // 缂栬緫闃舵
                 Optional<Activity> existingOpt = activityRepository.findById(stageInput.getId());
@@ -187,56 +258,72 @@
             stage.setMatchTime(stageInput.getMatchTime());
             stage.setAddress(stageInput.getAddress());
             stage.setPlayerMax(stageInput.getPlayerMax());
+            stage.setSortOrder(stageInput.getSortOrder());
             stage.setState(stageInput.getState());
             
             // 闃舵缁ф壙姣旇禌鐨勬姤鍚嶆埅姝㈡椂闂�
-            stage.setSignupDeadline(competition.getSignupDeadline());
+            stage.setSignupDeadline(activity.getSignupDeadline());
             
             // 闃舵鐨勮瘎鍒嗘ā鏉匡細濡傛灉鎸囧畾浜嗗垯浣跨敤鎸囧畾鐨勶紝鍚﹀垯缁ф壙姣旇禌鐨勮瘎鍒嗘ā鏉�
             if (stageInput.getRatingSchemeId() != null) {
                 stage.setRatingSchemeId(stageInput.getRatingSchemeId());
             } else {
-                stage.setRatingSchemeId(competition.getRatingSchemeId());
+                stage.setRatingSchemeId(activity.getRatingSchemeId());
             }
             
-            activityRepository.save(stage);
+            // 淇濆瓨闃舵骞惰幏鍙栬嚜澧濱D
+            stage = activityRepository.save(stage);
+            
+            // 璁板綍鏃ュ織浠ヤ究璋冭瘯
+            log.info("淇濆瓨闃舵鎴愬姛锛岄樁娈礗D: {}, 闃舵鍚嶇О: {}", stage.getId(), stage.getName());
         }
     }
     
     /**
      * 淇濆瓨姣旇禌璇勫
      */
-    private void saveActivityJudges(Long competitionId, List<ActivityJudgeInput> judgeInputs) {
+    private void saveActivityJudges(Long activityId, List<ActivityJudgeInput> judgeInputs) {
         if (judgeInputs == null || judgeInputs.isEmpty()) {
+            log.info("娌℃湁璇勫闇�瑕佷繚瀛橈紝姣旇禌ID: {}", activityId);
             return;
         }
         
+        log.info("寮�濮嬩繚瀛樿瘎濮旓紝姣旇禌ID: {}, 璇勫鏁伴噺: {}", activityId, judgeInputs.size());
+        
         // 鑾峰彇姣旇禌鐨勬墍鏈夐樁娈碉紙濡傛灉鏈夌殑璇濓級
-        List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competitionId, 1);
+        List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(activityId, 1);
         
         // 淇濆瓨璇勫鍏宠仈
         for (ActivityJudgeInput judgeInput : judgeInputs) {
+            log.info("澶勭悊璇勫: ID={}, 濮撳悕={}, 闃舵IDs={}", 
+                judgeInput.getJudgeId(), judgeInput.getJudgeName(), judgeInput.getStageIds());
+            
             // 鍏堝垹闄よ璇勫鐨勭幇鏈夊叧鑱�
-            activityJudgeRepository.deleteByActivityIdAndJudgeId(competitionId, judgeInput.getJudgeId());
+            activityJudgeRepository.deleteByActivityIdAndJudgeId(activityId, judgeInput.getJudgeId());
             
             if (judgeInput.getStageIds() == null || judgeInput.getStageIds().isEmpty()) {
                 // 濡傛灉娌℃湁鎸囧畾闃舵锛屽垱寤哄叧鑱斿埌鎵�鏈夐樁娈碉紙濡傛灉鏈夐樁娈碉級鎴栫洿鎺ュ叧鑱斿埌姣旇禌锛堝鏋滄病鏈夐樁娈碉級
                 if (stages.isEmpty()) {
                     // 姣旇禌娌℃湁闃舵锛岀洿鎺ュ叧鑱斿埌姣旇禌锛坰tage_id涓簄ull琛ㄧず鎵�鏈夐樁娈碉級
-                    ActivityJudge activityJudge = new ActivityJudge(competitionId, judgeInput.getJudgeId(), null);
-                    activityJudgeRepository.save(activityJudge);
+                    ActivityJudge activityJudge = new ActivityJudge(activityId, judgeInput.getJudgeId(), null);
+                    activityJudge = activityJudgeRepository.save(activityJudge);
+                    log.info("淇濆瓨璇勫鍏宠仈鎴愬姛: 姣旇禌ID={}, 璇勫ID={}, 闃舵ID=null", activityId, judgeInput.getJudgeId());
                 } else {
                     // 涓烘瘡涓樁娈靛垱寤哄叧鑱�
                     for (Activity stage : stages) {
-                        ActivityJudge activityJudge = new ActivityJudge(competitionId, judgeInput.getJudgeId(), stage.getId());
-                        activityJudgeRepository.save(activityJudge);
+                        ActivityJudge activityJudge = new ActivityJudge(activityId, judgeInput.getJudgeId(), stage.getId());
+                        activityJudge = activityJudgeRepository.save(activityJudge);
+                        log.info("淇濆瓨璇勫鍏宠仈鎴愬姛: 姣旇禌ID={}, 璇勫ID={}, 闃舵ID={}", activityId, judgeInput.getJudgeId(), stage.getId());
                     }
                 }
             } else {
                 // 涓烘瘡涓寚瀹氱殑闃舵鍒涘缓鍏宠仈
                 for (Long stageId : judgeInput.getStageIds()) {
-                    ActivityJudge activityJudge = new ActivityJudge(competitionId, judgeInput.getJudgeId(), stageId);
-                    activityJudgeRepository.save(activityJudge);
+                    // 濡傛灉stageId绛変簬褰撳墠姣旇禌ID锛岃〃绀鸿瘎濮旇礋璐f暣涓瘮璧涳紝stage_id璁句负null
+                    Long actualStageId = stageId.equals(activityId) ? null : stageId;
+                    ActivityJudge activityJudge = new ActivityJudge(activityId, judgeInput.getJudgeId(), actualStageId);
+                    activityJudge = activityJudgeRepository.save(activityJudge);
+                    log.info("淇濆瓨璇勫鍏宠仈鎴愬姛: 姣旇禌ID={}, 璇勫ID={}, 闃舵ID={}", activityId, judgeInput.getJudgeId(), actualStageId);
                 }
             }
         }
@@ -251,7 +338,7 @@
             Activity activity = activityOpt.get();
             
             // 濡傛灉鏄瘮璧涳紝鍏堝垹闄ゅ叾鎵�鏈夐樁娈�
-            if (activity.isCompetition()) {
+            if (activity.isMainActivity()) {
                 List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(id, 1);
                 for (Activity stage : stages) {
                     stage.setState(0); // 杞垹闄�
@@ -268,61 +355,30 @@
     }
     
     /**
-     * 鑾峰彇鎵�鏈夋湁鏁堟瘮璧涘拰闃舵锛堢敤浜庝笅鎷夐�夋嫨锛�
+     * 鑾峰彇鎵�鏈夋湁鏁堜富姣旇禌锛堢敤浜庝笅鎷夐�夋嫨锛�
      */
     public List<ActivityResponse> findAllActivitiesForSelection() {
-        // 鑾峰彇鎵�鏈夋椿鍔紙鍖呮嫭姣旇禌鍜岄樁娈碉級
-        List<Activity> activities = activityRepository.findByStateOrderByPidAscNameAsc(1);
+        // 鑾峰彇鎵�鏈夌姸鎬佷负1鐨勬椿鍔�
+        List<Activity> allActivities = activityRepository.findByStateOrderByPidAscNameAsc(1);
         
-        // 鍒涘缓姣旇禌ID鍒版瘮璧涘璞$殑鏄犲皠锛岀敤浜庡揩閫熸煡鎵剧埗姣旇禌
-        Map<Long, Activity> competitionMap = activities.stream()
+        // 杩囨护锛氬彧淇濈暀涓绘瘮璧涳紙pid=0锛�
+        List<Activity> filteredActivities = allActivities.stream()
             .filter(activity -> activity.getPid() == 0)
-            .collect(Collectors.toMap(Activity::getId, activity -> activity));
-        
-        // 杞崲涓篈ctivityResponse骞跺~鍏卲arent淇℃伅
-        List<ActivityResponse> result = activities.stream()
-            .map(activity -> {
-                ActivityResponse response = new ActivityResponse(activity);
-                // 濡傛灉鏄樁娈碉紙pid > 0锛夛紝濉厖parent淇℃伅
-                if (activity.getPid() > 0) {
-                    Activity parentActivity = competitionMap.get(activity.getPid());
-                    if (parentActivity != null) {
-                        response.setParent(new ActivityResponse(parentActivity));
-                    }
-                }
-                return response;
-            })
             .collect(Collectors.toList());
         
-        // 鑷畾涔夋帓搴忥細姣旇禌鍜屽叾闃舵鏀惧湪涓�璧�
-        result.sort((a, b) -> {
-            // 濡傛灉閮芥槸姣旇禌锛坧id=0锛夛紝鎸夊悕绉版帓搴�
-            if (a.getPid() == 0 && b.getPid() == 0) {
-                return a.getName().compareTo(b.getName());
-            }
-            // 濡傛灉閮芥槸闃舵锛屽厛鎸夌埗姣旇禌鍚嶇О鎺掑簭锛屽啀鎸夐樁娈靛悕绉版帓搴�
-            if (a.getPid() > 0 && b.getPid() > 0) {
-                String aParentName = a.getParent() != null ? a.getParent().getName() : "";
-                String bParentName = b.getParent() != null ? b.getParent().getName() : "";
-                int parentCompare = aParentName.compareTo(bParentName);
-                if (parentCompare != 0) {
-                    return parentCompare;
-                }
-                return a.getName().compareTo(b.getName());
-            }
-            // 濡傛灉涓�涓槸姣旇禌锛屼竴涓槸闃舵
-            if (a.getPid() == 0 && b.getPid() > 0) {
-                String bParentName = b.getParent() != null ? b.getParent().getName() : "";
-                int compare = a.getName().compareTo(bParentName);
-                return compare <= 0 ? -1 : 1; // 姣旇禌鎺掑湪鍏堕樁娈靛墠闈�
-            }
-            if (a.getPid() > 0 && b.getPid() == 0) {
-                String aParentName = a.getParent() != null ? a.getParent().getName() : "";
-                int compare = aParentName.compareTo(b.getName());
-                return compare < 0 ? -1 : 1; // 闃舵鎺掑湪鍏舵瘮璧涘悗闈�
-            }
-            return 0;
-        });
+        // 杞崲涓篈ctivityResponse
+        List<ActivityResponse> result = filteredActivities.stream()
+            .map(activity -> {
+                ActivityResponse response = new ActivityResponse(activity);
+                // 璁剧疆鍙傝禌浜烘暟锛堟墍鏈夐樁娈电殑鎶ュ悕鏁伴噺鎬诲拰锛�
+                Long playerCountLong = activityPlayerRepository.countByActivityId(activity.getId());
+                int playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+                response.setPlayerCount(playerCount);
+                
+                return response;
+            })
+            .sorted((a, b) -> a.getName().compareTo(b.getName()))
+            .collect(Collectors.toList());
         
         return result;
     }
@@ -330,27 +386,88 @@
     /**
      * 鑾峰彇姣旇禌鐨勬墍鏈夐樁娈�
      */
-    public List<ActivityResponse> findStagesByCompetitionId(Long competitionId) {
-        List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competitionId, 1);
+    public List<ActivityResponse> findStagesByActivityId(Long activityId) {
+        List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(activityId, 1);
         return stages.stream()
-            .map(ActivityResponse::new)
+            .map(activity -> {
+                ActivityResponse response = new ActivityResponse(activity);
+                // 璁剧疆鍙傝禌浜烘暟锛堝鏍搁�氳繃鐨勬姤鍚嶆暟閲忥級
+                Long playerCountLong = activityPlayerRepository.countByActivityId(activity.getId());
+                int playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+                response.setPlayerCount(playerCount);
+                return response;
+            })
             .collect(Collectors.toList());
+    }
+    
+    /**
+     * 鑾峰彇鎵�鏈夋瘮璧涢樁娈碉紙鐢ㄤ簬璇勫椤甸潰涓嬫媺閫夋嫨锛�
+     * 杩斿洖鎵�鏈夌姸鎬佷负1涓攑id>0鐨勬瘮璧涢樁娈�
+     */
+    public List<ActivityResponse> findAllStagesForSelection() {
+        // 鑾峰彇鎵�鏈夌姸鎬佷负1鐨勬椿鍔�
+        List<Activity> allActivities = activityRepository.findByStateOrderByPidAscNameAsc(1);
+        
+        // 鍒嗙涓绘瘮璧涘拰闃舵
+        Map<Long, Activity> parentActivitiesMap = allActivities.stream()
+            .filter(activity -> activity.getPid() == 0)
+            .collect(Collectors.toMap(Activity::getId, activity -> activity));
+        
+        // 杩囨护锛氬彧淇濈暀姣旇禌闃舵锛坧id>0锛�
+        List<Activity> filteredStages = allActivities.stream()
+            .filter(activity -> activity.getPid() > 0)
+            .collect(Collectors.toList());
+        
+        // 杞崲涓篈ctivityResponse
+        List<ActivityResponse> result = filteredStages.stream()
+            .map(activity -> {
+                ActivityResponse response = new ActivityResponse(activity);
+                // 璁剧疆鍙傝禌浜烘暟锛堝鏍搁�氳繃鐨勬姤鍚嶆暟閲忥級
+                Long playerCountLong = activityPlayerRepository.countByActivityId(activity.getId());
+                int playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+                response.setPlayerCount(playerCount);
+                
+                // 鎵嬪姩璁剧疆parent淇℃伅
+                Activity parentActivity = parentActivitiesMap.get(activity.getPid());
+                if (parentActivity != null) {
+                    ActivityResponse parentResponse = new ActivityResponse(parentActivity);
+                    response.setParent(parentResponse);
+                }
+                
+                return response;
+            })
+            .sorted((a, b) -> {
+                // 鍏堟寜鐖舵瘮璧汭D鎺掑簭锛屽啀鎸夐樁娈靛悕绉版帓搴�
+                int pidCompare = Long.compare(a.getPid(), b.getPid());
+                if (pidCompare != 0) return pidCompare;
+                return a.getName().compareTo(b.getName());
+            })
+            .collect(Collectors.toList());
+        
+        return result;
     }
     
     /**
      * 缁熻姣旇禌鏁伴噺
      */
-    public long countActiveCompetitions() {
-        return activityRepository.countActiveCompetitions();
+    public long countActiveActivities() {
+        return activityRepository.countActiveActivities();
     }
     
     /**
      * 鑾峰彇杩涜涓殑姣旇禌
      */
-    public List<ActivityResponse> findOngoingCompetitions() {
-        List<Activity> activities = activityRepository.findOngoingCompetitions();
+    public List<ActivityResponse> findOngoingActivities() {
+        List<Activity> activities = activityRepository.findOngoingActivities();
         return activities.stream()
-            .map(ActivityResponse::new)
+            .map(activity -> {
+                ActivityResponse response = new ActivityResponse(activity);
+                // 璁剧疆鍙傝禌浜烘暟锛堝鏍搁�氳繃鐨勬姤鍚嶆暟閲忥級
+                Long playerCountLong = activityPlayerRepository.countByActivityId(activity.getId());
+                int playerCount = playerCountLong != null ? playerCountLong.intValue() : 0;
+                response.setPlayerCount(playerCount);
+                return response;
+            })
             .collect(Collectors.toList());
     }
     
@@ -368,4 +485,78 @@
             return "/" + pid + "/";
         }
     }
+    
+    /**
+     * 鍔犺浇娲诲姩鐨勮瘎濮旀暟鎹�
+     */
+    private List<ActivityJudgeResponse> loadActivityJudges(Long activityId) {
+        // 鏌ヨ娲诲姩鐨勮瘎濮斿叧鑱�
+        List<ActivityJudge> activityJudges = activityJudgeRepository.findByActivityId(activityId);
+        
+        // 鎸夎瘎濮擨D鍒嗙粍锛屾敹闆嗘瘡涓瘎濮旇礋璐g殑闃舵
+        Map<Long, List<Long>> judgeStageMap = activityJudges.stream()
+            .collect(Collectors.groupingBy(
+                ActivityJudge::getJudgeId,
+                Collectors.mapping(
+                    aj -> aj.getStageId() != null ? aj.getStageId() : activityId, // 濡傛灉stage_id涓簄ull锛岃〃绀鸿礋璐f暣涓瘮璧涳紝浣跨敤activityId
+                    Collectors.toList()
+                )
+            ));
+        
+        // 鏌ヨ璇勫璇︾粏淇℃伅骞舵瀯寤哄搷搴�
+        List<ActivityJudgeResponse> result = new ArrayList<>();
+        for (Map.Entry<Long, List<Long>> entry : judgeStageMap.entrySet()) {
+            Long judgeId = entry.getKey();
+            List<Long> stageIds = entry.getValue();
+            
+            Optional<Judge> judgeOpt = judgeRepository.findById(judgeId);
+            if (judgeOpt.isPresent()) {
+                Judge judge = judgeOpt.get();
+                ActivityJudgeResponse judgeResponse = new ActivityJudgeResponse(
+                    judge.getId(),
+                    judge.getName(),
+                    judge.getPhone(),
+                    judge.getDescription(),
+                    stageIds
+                );
+                result.add(judgeResponse);
+            }
+        }
+        
+        return result;
+    }
+    
+    /**
+     * 楠岃瘉闃舵鐨剆ort_order杩炵画鎬�
+     */
+    private void validateSortOrderContinuity(List<ActivityStageInput> stages) {
+        if (stages == null || stages.isEmpty()) {
+            return;
+        }
+        
+        // 鏀堕泦鎵�鏈夌殑sortOrder鍊�
+        List<Integer> sortOrders = stages.stream()
+            .map(ActivityStageInput::getSortOrder)
+            .filter(Objects::nonNull)
+            .sorted()
+            .collect(Collectors.toList());
+        
+        // 妫�鏌ユ槸鍚︿粠1寮�濮�
+        if (sortOrders.isEmpty() || sortOrders.get(0) != 1) {
+            throw new RuntimeException("闃舵鎺掑簭蹇呴』浠�1寮�濮�");
+        }
+        
+        // 妫�鏌ヨ繛缁��
+        for (int i = 0; i < sortOrders.size(); i++) {
+            if (sortOrders.get(i) != i + 1) {
+                throw new RuntimeException("闃舵鎺掑簭蹇呴』杩炵画锛屼笉鑳借烦璺冿紙濡傦細1,2,3...锛�");
+            }
+        }
+        
+        // 妫�鏌ユ槸鍚︽湁閲嶅鐨剆ortOrder
+        Set<Integer> uniqueSortOrders = new HashSet<>(sortOrders);
+        if (uniqueSortOrders.size() != sortOrders.size()) {
+            throw new RuntimeException("闃舵鎺掑簭涓嶈兘閲嶅");
+        }
+    }
 }
\ No newline at end of file

--
Gitblit v1.8.0