From 6d519474e44855682043d3c40db2c86a6822caca Mon Sep 17 00:00:00 2001
From: lrj <owen.stl@gmail.com>
Date: 星期三, 24 九月 2025 19:37:59 +0800
Subject: [PATCH] 修改员工和评委的设置

---
 backend/src/main/java/com/rongyichuang/employee/entity/Employee.java                               |   15 
 backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingRepository.java     |    4 
 backend/src/main/java/com/rongyichuang/judge/dto/request/JudgeInput.java                           |    9 
 backend/src/main/java/com/rongyichuang/user/repository/UserRepository.java                         |   34 +
 backend/src/main/java/com/rongyichuang/player/dto/response/RegionInfoResponse.java                 |   52 +
 backend/src/main/java/com/rongyichuang/judge/service/JudgeService.java                             |   19 
 backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java             |   31 
 backend/src/main/java/com/rongyichuang/player/dto/response/ActivityPlayerDetailResponse.java       |    4 
 backend/src/main/java/com/rongyichuang/player/repository/PlayerRepository.java                     |   60 +
 backend/src/test/java/com/rongyichuang/CheckJudgeDataTest.java                                     |   51 +
 backend/src/test/java/com/rongyichuang/tools/ActivityPlayerRegionUpdater.java                      |   91 ++
 backend/src/test/java/CheckRatingItemTableStructureTest2.java                                      |   37 +
 backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java             |   38 
 backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRating.java                   |   71 +
 backend/src/main/java/com/rongyichuang/player/entity/ActivityPlayer.java                           |  219 ++++++
 backend/src/main/java/com/rongyichuang/player/repository/ActivityPlayerRepository.java             |   91 ++
 backend/src/main/resources/graphql/player.graphqls                                                 |   27 
 web/src/api/graphql.ts                                                                             |    1 
 backend/src/test/java/com/rongyichuang/SetupJudgeUserTest.java                                     |   32 
 backend/src/test/java/com/rongyichuang/CheckTableStructureTest.java                                |   40 +
 backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingItemRepository.java |    2 
 web/src/views/employee/EmployeeForm.vue                                                            |   36 
 backend/src/test/java/com/rongyichuang/CheckActivityJudgeTest.java                                 |   73 ++
 backend/src/main/java/com/rongyichuang/employee/service/EmployeeService.java                       |   27 
 backend/src/test/java/com/rongyichuang/CheckRatingItemTableStructureTest.java                      |   37 +
 web/src/components/PlayerInfoCard.vue                                                              |    9 
 web/src/views/judge/index.vue                                                                      |   17 
 backend/src/main/resources/graphql/judge.graphqls                                                  |    1 
 backend/src/test/java/com/rongyichuang/CheckActivityPlayerDataTest.java                            |   68 ++
 backend/src/test/java/com/rongyichuang/CheckActivityPlayerRatingTableTest.java                     |   48 +
 backend/src/test/java/com/rongyichuang/SetupActivityJudgeTest.java                                 |   33 
 backend/src/main/java/com/rongyichuang/user/service/UserService.java                               |   80 ++
 backend/src/main/java/com/rongyichuang/user/entity/User.java                                       |  134 +++
 backend/src/main/java/com/rongyichuang/player/entity/Player.java                                   |  193 +++++
 web/src/api/activityPlayer.js                                                                      |    5 
 backend/add_region_to_activity_player.sql                                                          |   13 
 backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRatingItem.java               |  190 ++--
 web/src/components/JudgeFormSimple.vue                                                             |   95 ++
 web/src/views/activity-player/rating.vue                                                           |    2 
 backend/src/main/java/com/rongyichuang/player/dto/input/ActivityPlayerRatingItemInput.java         |    6 
 40 files changed, 1,793 insertions(+), 202 deletions(-)

diff --git a/backend/add_region_to_activity_player.sql b/backend/add_region_to_activity_player.sql
new file mode 100644
index 0000000..413c38d
--- /dev/null
+++ b/backend/add_region_to_activity_player.sql
@@ -0,0 +1,13 @@
+-- 涓� t_activity_player 琛ㄦ坊鍔� region_id 瀛楁
+ALTER TABLE t_activity_player 
+ADD COLUMN region_id bigint DEFAULT NULL COMMENT '鍖哄煙ID锛屽叧鑱攖_region琛�' 
+AFTER player_id;
+
+-- 娣诲姞澶栭敭绾︽潫
+ALTER TABLE t_activity_player 
+ADD CONSTRAINT fk_activity_player_region 
+FOREIGN KEY (region_id) REFERENCES t_region(id) 
+ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- 楠岃瘉瀛楁娣诲姞
+DESCRIBE t_activity_player;
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRating.java b/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRating.java
index 99b1d5d..1abc8c5 100644
--- a/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRating.java
+++ b/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRating.java
@@ -26,6 +26,12 @@
     private Long activityPlayerId;
 
     /**
+     * 闃舵ID
+     */
+    @Column(name = "stage_id", nullable = false)
+    private Long stageId;
+
+    /**
      * 閫夋墜ID
      */
     @Column(name = "player_id", nullable = false)
@@ -34,44 +40,47 @@
     /**
      * 璇勫ID
      */
-    @Column(name = "judge_id", nullable = false)
+    @Column(name = "judge_id")
     private Long judgeId;
 
     /**
      * 璇勫垎鏂规ID
      */
-    @Column(name = "rating_scheme_id", nullable = false)
+    @Column(name = "rating_scheme_id")
     private Long ratingSchemeId;
 
     /**
      * 鎬诲垎
      */
-    @Column(name = "total_score", precision = 10, scale = 2)
+    @Column(name = "total_score", precision = 19, scale = 2)
     private BigDecimal totalScore;
 
     /**
-     * 璇勫垎鐘舵�侊細0-鏈瘎鍒嗭紝1-宸茶瘎鍒�
+     * 鍙嶉淇℃伅
      */
-    @Column(name = "status", nullable = false)
-    private Integer status = 0;
+    @Column(name = "feedback", columnDefinition = "TEXT")
+    private String feedback;
 
     /**
-     * 璇勫垎澶囨敞
+     * 鐘舵�侊細0-鏈瘎鍒嗭紝1-宸茶瘎鍒�
      */
-    @Column(name = "remark", length = 500)
-    private String remark;
+    @Column(name = "state", nullable = false)
+    private Integer state = 0;
+
+
 
     // 鏋勯�犲嚱鏁�
     public ActivityPlayerRating() {}
 
-    public ActivityPlayerRating(Long activityId, Long activityPlayerId, Long playerId, 
+    public ActivityPlayerRating(Long activityId, Long activityPlayerId, Long stageId, Long playerId, 
                                Long judgeId, Long ratingSchemeId) {
         this.activityId = activityId;
         this.activityPlayerId = activityPlayerId;
+        this.stageId = stageId;
         this.playerId = playerId;
         this.judgeId = judgeId;
         this.ratingSchemeId = ratingSchemeId;
-        this.status = 0;
+        this.state = 0;
     }
 
     // Getter鍜孲etter鏂规硶
@@ -89,6 +98,14 @@
 
     public void setActivityPlayerId(Long activityPlayerId) {
         this.activityPlayerId = activityPlayerId;
+    }
+
+    public Long getStageId() {
+        return stageId;
+    }
+
+    public void setStageId(Long stageId) {
+        this.stageId = stageId;
     }
 
     public Long getPlayerId() {
@@ -123,21 +140,32 @@
         this.totalScore = totalScore;
     }
 
+    public String getFeedback() {
+        return feedback;
+    }
+
+    public void setFeedback(String feedback) {
+        this.feedback = feedback;
+    }
+
+    public Integer getState() {
+        return state;
+    }
+
+    public void setState(Integer state) {
+        this.state = state;
+    }
+
+    // 涓轰簡鍏煎鎬э紝淇濈暀status鐩稿叧鏂规硶
     public Integer getStatus() {
-        return status;
+        return state;
     }
 
     public void setStatus(Integer status) {
-        this.status = status;
+        this.state = status;
     }
 
-    public String getRemark() {
-        return remark;
-    }
 
-    public void setRemark(String remark) {
-        this.remark = remark;
-    }
 
     @Override
     public String toString() {
@@ -145,12 +173,13 @@
                 "id=" + getId() +
                 ", activityId=" + activityId +
                 ", activityPlayerId=" + activityPlayerId +
+                ", stageId=" + stageId +
                 ", playerId=" + playerId +
                 ", judgeId=" + judgeId +
                 ", ratingSchemeId=" + ratingSchemeId +
                 ", totalScore=" + totalScore +
-                ", status=" + status +
-                ", remark='" + remark + '\'' +
+                ", feedback='" + feedback + '\'' +
+                ", state=" + state +
                 '}';
     }
 }
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRatingItem.java b/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRatingItem.java
index 51405b1..de62b2e 100644
--- a/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRatingItem.java
+++ b/backend/src/main/java/com/rongyichuang/activity/entity/ActivityPlayerRatingItem.java
@@ -14,10 +14,46 @@
 public class ActivityPlayerRatingItem extends BaseEntity {
 
     /**
+     * 娲诲姩ID
+     */
+    @Column(name = "activity_id", nullable = false)
+    private Long activityId;
+
+    /**
+     * 娲诲姩閫夋墜ID
+     */
+    @Column(name = "activity_player_id", nullable = false)
+    private Long activityPlayerId;
+
+    /**
      * 娲诲姩閫夋墜璇勫垎ID锛堝叧鑱攖_activity_player_rating琛級
      */
     @Column(name = "activity_player_rating_id", nullable = false)
     private Long activityPlayerRatingId;
+
+    /**
+     * 闃舵ID
+     */
+    @Column(name = "stage_id", nullable = false)
+    private Long stageId;
+
+    /**
+     * 閫夋墜ID
+     */
+    @Column(name = "player_id", nullable = false)
+    private Long playerId;
+
+    /**
+     * 璇勫ID
+     */
+    @Column(name = "judge_id", nullable = false)
+    private Long judgeId;
+
+    /**
+     * 璇勫垎鏂规ID
+     */
+    @Column(name = "rating_scheme_id", nullable = false)
+    private Long ratingSchemeId;
 
     /**
      * 璇勫垎椤笽D锛堝叧鑱攖_rating_item琛級
@@ -26,66 +62,89 @@
     private Long ratingItemId;
 
     /**
-     * 璇勫垎椤瑰悕绉帮紙鍐椾綑瀛楁锛屼究浜庢煡璇級
-     */
-    @Column(name = "rating_item_name", length = 100)
-    private String ratingItemName;
-
-    /**
-     * 璇勫垎椤规潈閲嶏紙鍐椾綑瀛楁锛屼究浜庤绠楋級
-     */
-    @Column(name = "weight", precision = 5, scale = 2)
-    private BigDecimal weight;
-
-    /**
-     * 璇勫垎椤规弧鍒嗭紙鍐椾綑瀛楁锛屼究浜庤绠楋級
-     */
-    @Column(name = "max_score", precision = 10, scale = 2)
-    private BigDecimal maxScore;
-
-    /**
      * 瀹為檯寰楀垎
      */
     @Column(name = "score", precision = 10, scale = 2, nullable = false)
     private BigDecimal score;
 
     /**
-     * 鍔犳潈寰楀垎锛坰core * weight锛�
+     * 澶囨敞
      */
-    @Column(name = "weighted_score", precision = 10, scale = 2)
-    private BigDecimal weightedScore;
-
-    /**
-     * 璇勫垎澶囨敞
-     */
-    @Column(name = "remark", length = 500)
+    @Column(name = "feedback", columnDefinition = "TEXT")
     private String remark;
 
     // 鏋勯�犲嚱鏁�
     public ActivityPlayerRatingItem() {}
 
-    public ActivityPlayerRatingItem(Long activityPlayerRatingId, Long ratingItemId, 
-                                   String ratingItemName, BigDecimal weight, 
-                                   BigDecimal maxScore, BigDecimal score) {
+    public ActivityPlayerRatingItem(Long activityId, Long activityPlayerId, Long activityPlayerRatingId, 
+                                   Long stageId, Long playerId, Long judgeId, Long ratingSchemeId,
+                                   Long ratingItemId, BigDecimal score) {
+        this.activityId = activityId;
+        this.activityPlayerId = activityPlayerId;
         this.activityPlayerRatingId = activityPlayerRatingId;
+        this.stageId = stageId;
+        this.playerId = playerId;
+        this.judgeId = judgeId;
+        this.ratingSchemeId = ratingSchemeId;
         this.ratingItemId = ratingItemId;
-        this.ratingItemName = ratingItemName;
-        this.weight = weight;
-        this.maxScore = maxScore;
         this.score = score;
-        // 璁$畻鍔犳潈寰楀垎
-        if (score != null && weight != null) {
-            this.weightedScore = score.multiply(weight);
-        }
     }
 
     // Getter鍜孲etter鏂规硶
+    public Long getActivityId() {
+        return activityId;
+    }
+
+    public void setActivityId(Long activityId) {
+        this.activityId = activityId;
+    }
+
+    public Long getActivityPlayerId() {
+        return activityPlayerId;
+    }
+
+    public void setActivityPlayerId(Long activityPlayerId) {
+        this.activityPlayerId = activityPlayerId;
+    }
+
     public Long getActivityPlayerRatingId() {
         return activityPlayerRatingId;
     }
 
     public void setActivityPlayerRatingId(Long activityPlayerRatingId) {
         this.activityPlayerRatingId = activityPlayerRatingId;
+    }
+
+    public Long getStageId() {
+        return stageId;
+    }
+
+    public void setStageId(Long stageId) {
+        this.stageId = stageId;
+    }
+
+    public Long getPlayerId() {
+        return playerId;
+    }
+
+    public void setPlayerId(Long playerId) {
+        this.playerId = playerId;
+    }
+
+    public Long getJudgeId() {
+        return judgeId;
+    }
+
+    public void setJudgeId(Long judgeId) {
+        this.judgeId = judgeId;
+    }
+
+    public Long getRatingSchemeId() {
+        return ratingSchemeId;
+    }
+
+    public void setRatingSchemeId(Long ratingSchemeId) {
+        this.ratingSchemeId = ratingSchemeId;
     }
 
     public Long getRatingItemId() {
@@ -96,48 +155,12 @@
         this.ratingItemId = ratingItemId;
     }
 
-    public String getRatingItemName() {
-        return ratingItemName;
-    }
-
-    public void setRatingItemName(String ratingItemName) {
-        this.ratingItemName = ratingItemName;
-    }
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-        // 閲嶆柊璁$畻鍔犳潈寰楀垎
-        updateWeightedScore();
-    }
-
-    public BigDecimal getMaxScore() {
-        return maxScore;
-    }
-
-    public void setMaxScore(BigDecimal maxScore) {
-        this.maxScore = maxScore;
-    }
-
     public BigDecimal getScore() {
         return score;
     }
 
     public void setScore(BigDecimal score) {
         this.score = score;
-        // 閲嶆柊璁$畻鍔犳潈寰楀垎
-        updateWeightedScore();
-    }
-
-    public BigDecimal getWeightedScore() {
-        return weightedScore;
-    }
-
-    public void setWeightedScore(BigDecimal weightedScore) {
-        this.weightedScore = weightedScore;
     }
 
     public String getRemark() {
@@ -148,36 +171,13 @@
         this.remark = remark;
     }
 
-    /**
-     * 鏇存柊鍔犳潈寰楀垎
-     */
-    private void updateWeightedScore() {
-        if (score != null && weight != null) {
-            this.weightedScore = score.multiply(weight);
-        }
-    }
-
-    /**
-     * 璁$畻寰楀垎鐜囷紙瀹為檯寰楀垎/婊″垎锛�
-     */
-    public BigDecimal getScoreRate() {
-        if (score != null && maxScore != null && maxScore.compareTo(BigDecimal.ZERO) > 0) {
-            return score.divide(maxScore, 4, BigDecimal.ROUND_HALF_UP);
-        }
-        return BigDecimal.ZERO;
-    }
-
     @Override
     public String toString() {
         return "ActivityPlayerRatingItem{" +
                 "id=" + getId() +
                 ", activityPlayerRatingId=" + activityPlayerRatingId +
                 ", ratingItemId=" + ratingItemId +
-                ", ratingItemName='" + ratingItemName + '\'' +
-                ", weight=" + weight +
-                ", maxScore=" + maxScore +
                 ", score=" + score +
-                ", weightedScore=" + weightedScore +
                 ", remark='" + remark + '\'' +
                 '}';
     }
diff --git a/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingItemRepository.java b/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingItemRepository.java
index 1420a5d..014a9b9 100644
--- a/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingItemRepository.java
+++ b/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingItemRepository.java
@@ -33,7 +33,7 @@
     /**
      * 璁$畻鎸囧畾娲诲姩閫夋墜璇勫垎鐨勬�诲垎
      */
-    @Query("SELECT SUM(i.weightedScore) FROM ActivityPlayerRatingItem i WHERE i.activityPlayerRatingId = :activityPlayerRatingId")
+    @Query("SELECT SUM(i.score) FROM ActivityPlayerRatingItem i WHERE i.activityPlayerRatingId = :activityPlayerRatingId")
     BigDecimal calculateTotalScoreByActivityPlayerRatingId(@Param("activityPlayerRatingId") Long activityPlayerRatingId);
 
     /**
diff --git a/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingRepository.java b/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingRepository.java
index 9b208ad..7261077 100644
--- a/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingRepository.java
+++ b/backend/src/main/java/com/rongyichuang/activity/repository/ActivityPlayerRatingRepository.java
@@ -48,13 +48,13 @@
     /**
      * 缁熻鎸囧畾娲诲姩閫夋墜鐨勮瘎鍒嗘暟閲�
      */
-    @Query("SELECT COUNT(r) FROM ActivityPlayerRating r WHERE r.activityPlayerId = :activityPlayerId AND r.status = 1")
+    @Query("SELECT COUNT(r) FROM ActivityPlayerRating r WHERE r.activityPlayerId = :activityPlayerId AND r.state = 1")
     long countCompletedRatingsByActivityPlayerId(@Param("activityPlayerId") Long activityPlayerId);
 
     /**
      * 鑾峰彇鎸囧畾娲诲姩閫夋墜鐨勬墍鏈夊凡瀹屾垚璇勫垎
      */
-    @Query("SELECT r FROM ActivityPlayerRating r WHERE r.activityPlayerId = :activityPlayerId AND r.status = 1")
+    @Query("SELECT r FROM ActivityPlayerRating r WHERE r.activityPlayerId = :activityPlayerId AND r.state = 1")
     List<ActivityPlayerRating> findCompletedRatingsByActivityPlayerId(@Param("activityPlayerId") Long activityPlayerId);
 
     /**
diff --git a/backend/src/main/java/com/rongyichuang/employee/entity/Employee.java b/backend/src/main/java/com/rongyichuang/employee/entity/Employee.java
index c7599ed..86909cc 100644
--- a/backend/src/main/java/com/rongyichuang/employee/entity/Employee.java
+++ b/backend/src/main/java/com/rongyichuang/employee/entity/Employee.java
@@ -24,11 +24,7 @@
     @Column(name = "phone", length = 32, nullable = false)
     private String phone;
 
-    /**
-     * 瀵嗙爜
-     */
-    @Column(name = "password", length = 128, nullable = false)
-    private String password;
+
 
     /**
      * 瑙掕壊ID
@@ -70,10 +66,9 @@
     // 鏋勯�犲嚱鏁�
     public Employee() {}
 
-    public Employee(String name, String phone, String password, String roleId) {
+    public Employee(String name, String phone, String roleId) {
         this.name = name;
         this.phone = phone;
-        this.password = password;
         this.roleId = roleId;
     }
 
@@ -94,13 +89,7 @@
         this.phone = phone;
     }
 
-    public String getPassword() {
-        return password;
-    }
 
-    public void setPassword(String password) {
-        this.password = password;
-    }
 
     public String getRoleId() {
         return roleId;
diff --git a/backend/src/main/java/com/rongyichuang/employee/service/EmployeeService.java b/backend/src/main/java/com/rongyichuang/employee/service/EmployeeService.java
index 16a8e91..3c429e7 100644
--- a/backend/src/main/java/com/rongyichuang/employee/service/EmployeeService.java
+++ b/backend/src/main/java/com/rongyichuang/employee/service/EmployeeService.java
@@ -4,6 +4,8 @@
 import com.rongyichuang.employee.dto.response.EmployeeResponse;
 import com.rongyichuang.employee.entity.Employee;
 import com.rongyichuang.employee.repository.EmployeeRepository;
+import com.rongyichuang.user.service.UserService;
+import com.rongyichuang.user.entity.User;
 import com.rongyichuang.common.exception.BusinessException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,6 +33,9 @@
 
     @Autowired
     private EmployeeRepository employeeRepository;
+
+    @Autowired
+    private UserService userService;
 
     private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
 
@@ -87,6 +92,16 @@
         // 楠岃瘉杈撳叆
         validateEmployeeInput(input);
 
+        // 澶勭悊User琛ㄩ�昏緫
+        User user;
+        if (input.getPassword() != null && !input.getPassword().trim().isEmpty()) {
+            // 鏈夊瘑鐮佹椂锛屽垱寤烘垨鏇存柊鐢ㄦ埛锛堝寘鍚瘑鐮侊級
+            user = userService.findOrCreateUserByPhone(input.getPhone(), input.getName(), input.getPassword());
+        } else {
+            // 鏃犲瘑鐮佹椂锛屽彧鏇存柊鐢ㄦ埛鍩烘湰淇℃伅锛堜笉鏇存柊瀵嗙爜锛�
+            user = userService.findOrCreateUserByPhone(input.getPhone(), input.getName(), null);
+        }
+
         Employee employee;
         if (input.getId() != null) {
             // 鏇存柊鍛樺伐
@@ -103,7 +118,6 @@
                 throw new BusinessException("PHONE_ALREADY_EXISTS", "鎵嬫満鍙峰凡瀛樺湪");
             }
             employee = new Employee();
-            employee.setUserId(1L); // 涓存椂璁剧疆锛屽疄闄呭簲璇ヤ粠褰撳墠鐧诲綍鐢ㄦ埛鑾峰彇
         }
 
         // 璁剧疆鍩烘湰淇℃伅
@@ -111,11 +125,7 @@
         employee.setPhone(input.getPhone());
         employee.setRoleId(input.getRoleId());
         employee.setDescription(input.getDescription());
-
-        // 澶勭悊瀵嗙爜
-        if (input.getPassword() != null && !input.getPassword().trim().isEmpty()) {
-            employee.setPassword(passwordEncoder.encode(input.getPassword()));
-        }
+        employee.setUserId(user.getId()); // 璁剧疆鍏宠仈鐨勭敤鎴稩D
 
         Employee savedEmployee = employeeRepository.save(employee);
         logger.info("鍛樺伐淇濆瓨鎴愬姛: {}", savedEmployee.getName());
@@ -154,13 +164,14 @@
             throw new BusinessException("ROLE_REQUIRED", "瑙掕壊涓嶈兘涓虹┖");
         }
 
-        // 鏂板鍛樺伐鏃跺瘑鐮佸繀濉�
+        // 瀵嗙爜楠岃瘉锛氭柊澧炴椂蹇呭~锛岀紪杈戞椂鍙��
         if (input.getId() == null) {
+            // 鏂板鍛樺伐鏃跺瘑鐮佸繀濉�
             if (input.getPassword() == null || input.getPassword().trim().isEmpty()) {
                 throw new BusinessException("PASSWORD_REQUIRED", "瀵嗙爜涓嶈兘涓虹┖");
             }
         }
-
+        
         // 濡傛灉鎻愪緵浜嗗瘑鐮侊紝楠岃瘉瀵嗙爜鏍煎紡
         if (input.getPassword() != null && !input.getPassword().trim().isEmpty()) {
             if (!PASSWORD_PATTERN.matcher(input.getPassword()).matches()) {
diff --git a/backend/src/main/java/com/rongyichuang/judge/dto/request/JudgeInput.java b/backend/src/main/java/com/rongyichuang/judge/dto/request/JudgeInput.java
index 1070444..efeadcf 100644
--- a/backend/src/main/java/com/rongyichuang/judge/dto/request/JudgeInput.java
+++ b/backend/src/main/java/com/rongyichuang/judge/dto/request/JudgeInput.java
@@ -6,6 +6,7 @@
     private Long id;
     private String name;
     private String phone;
+    private String password;
     private Integer gender;
     private String description;
     private String title;
@@ -39,6 +40,14 @@
         this.phone = phone;
     }
 
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
     public Integer getGender() {
         return gender;
     }
diff --git a/backend/src/main/java/com/rongyichuang/judge/service/JudgeService.java b/backend/src/main/java/com/rongyichuang/judge/service/JudgeService.java
index 6f8fd7c..f078372 100644
--- a/backend/src/main/java/com/rongyichuang/judge/service/JudgeService.java
+++ b/backend/src/main/java/com/rongyichuang/judge/service/JudgeService.java
@@ -13,6 +13,8 @@
 import com.rongyichuang.common.exception.BusinessException;
 import com.rongyichuang.common.enums.MediaTargetType;
 import com.rongyichuang.tag.repository.TagRepository;
+import com.rongyichuang.user.service.UserService;
+import com.rongyichuang.user.entity.User;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.data.domain.Sort;
@@ -36,16 +38,19 @@
     private final TagRepository tagRepository;
     private final MediaRepository mediaRepository;
     private final MediaService mediaService;
+    private final UserService userService;
     
     @Value("${app.media-url:${app.media.url:}}")
     private String mediaBaseUrl;
 
     public JudgeService(JudgeRepository judgeRepository, TagRepository tagRepository, 
-                       MediaRepository mediaRepository, MediaService mediaService) {
+                       MediaRepository mediaRepository, MediaService mediaService,
+                       UserService userService) {
         this.judgeRepository = judgeRepository;
         this.tagRepository = tagRepository;
         this.mediaRepository = mediaRepository;
         this.mediaService = mediaService;
+        this.userService = userService;
     }
 
     public List<JudgeResponse> findAll() {
@@ -69,6 +74,17 @@
     @Transactional
     public JudgeResponse save(JudgeInput input) {
         Judge judge;
+        User user;
+        
+        // 澶勭悊User琛ㄩ�昏緫
+        if (input.getPassword() != null && !input.getPassword().trim().isEmpty() && !"鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��".equals(input.getPassword())) {
+            // 鏈夊瘑鐮佷笖涓嶆槸鍗犱綅绗︽椂锛屽垱寤烘垨鏇存柊鐢ㄦ埛锛堝寘鍚瘑鐮侊級
+            user = userService.findOrCreateUserByPhone(input.getPhone(), input.getName(), input.getPassword());
+        } else {
+            // 鏃犲瘑鐮佹垨鏄崰浣嶇鏃讹紝鍙洿鏂扮敤鎴峰熀鏈俊鎭紙涓嶆洿鏂板瘑鐮侊級
+            user = userService.findOrCreateUserByPhone(input.getPhone(), input.getName(), null);
+        }
+
         if (input.getId() != null) {
             judge = judgeRepository.findById(input.getId())
                     .orElseThrow(() -> new BusinessException("璇勫涓嶅瓨鍦�"));
@@ -87,6 +103,7 @@
         judge.setTitle(input.getTitle());
         judge.setCompany(input.getCompany());
         judge.setIntroduction(input.getIntroduction());
+        judge.setUserId(user.getId()); // 璁剧疆鍏宠仈鐨勭敤鎴稩D
         // 澶村儚淇℃伅閫氳繃t_media琛ㄧ殑target_type鍜宼arget_id鍏宠仈
 
         // 璁剧疆涓撲笟鏍囩
diff --git a/backend/src/main/java/com/rongyichuang/player/dto/input/ActivityPlayerRatingItemInput.java b/backend/src/main/java/com/rongyichuang/player/dto/input/ActivityPlayerRatingItemInput.java
index c18017c..1134547 100644
--- a/backend/src/main/java/com/rongyichuang/player/dto/input/ActivityPlayerRatingItemInput.java
+++ b/backend/src/main/java/com/rongyichuang/player/dto/input/ActivityPlayerRatingItemInput.java
@@ -2,7 +2,7 @@
 
 public class ActivityPlayerRatingItemInput {
     private Long itemId;
-    private Integer score;
+    private Double score;
 
     public Long getItemId() {
         return itemId;
@@ -12,11 +12,11 @@
         this.itemId = itemId;
     }
 
-    public Integer getScore() {
+    public Double getScore() {
         return score;
     }
 
-    public void setScore(Integer score) {
+    public void setScore(Double score) {
         this.score = score;
     }
 }
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/player/dto/response/ActivityPlayerDetailResponse.java b/backend/src/main/java/com/rongyichuang/player/dto/response/ActivityPlayerDetailResponse.java
index a40fe29..890437e 100644
--- a/backend/src/main/java/com/rongyichuang/player/dto/response/ActivityPlayerDetailResponse.java
+++ b/backend/src/main/java/com/rongyichuang/player/dto/response/ActivityPlayerDetailResponse.java
@@ -8,6 +8,7 @@
 public class ActivityPlayerDetailResponse {
     private Long id; // activity_player_id
     private PlayerInfoResponse playerInfo; // 瀛﹀憳淇℃伅
+    private RegionInfoResponse regionInfo; // 鍖哄煙淇℃伅
     private String activityName; // 姣旇禌鍚嶇О
     private String description; // 鍙傝禌椤圭洰绠�浠�
     private List<SubmissionMediaResponse> submissionFiles; // 鎻愪氦鐨勮祫鏂�
@@ -23,6 +24,9 @@
     public PlayerInfoResponse getPlayerInfo() { return playerInfo; }
     public void setPlayerInfo(PlayerInfoResponse playerInfo) { this.playerInfo = playerInfo; }
 
+    public RegionInfoResponse getRegionInfo() { return regionInfo; }
+    public void setRegionInfo(RegionInfoResponse regionInfo) { this.regionInfo = regionInfo; }
+
     public String getActivityName() { return activityName; }
     public void setActivityName(String activityName) { this.activityName = activityName; }
 
diff --git a/backend/src/main/java/com/rongyichuang/player/dto/response/RegionInfoResponse.java b/backend/src/main/java/com/rongyichuang/player/dto/response/RegionInfoResponse.java
new file mode 100644
index 0000000..8b76973
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/player/dto/response/RegionInfoResponse.java
@@ -0,0 +1,52 @@
+package com.rongyichuang.player.dto.response;
+
+/**
+ * 鍖哄煙淇℃伅鍝嶅簲绫�
+ */
+public class RegionInfoResponse {
+    
+    private Long id;
+    private String name;
+    private String fullPath;
+
+    public RegionInfoResponse() {}
+
+    public RegionInfoResponse(Long id, String name, String fullPath) {
+        this.id = id;
+        this.name = name;
+        this.fullPath = fullPath;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getFullPath() {
+        return fullPath;
+    }
+
+    public void setFullPath(String fullPath) {
+        this.fullPath = fullPath;
+    }
+
+    @Override
+    public String toString() {
+        return "RegionInfoResponse{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", fullPath='" + fullPath + '\'' +
+                '}';
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/player/entity/ActivityPlayer.java b/backend/src/main/java/com/rongyichuang/player/entity/ActivityPlayer.java
new file mode 100644
index 0000000..0c7e2df
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/player/entity/ActivityPlayer.java
@@ -0,0 +1,219 @@
+package com.rongyichuang.player.entity;
+
+import com.rongyichuang.common.entity.BaseEntity;
+import com.rongyichuang.region.entity.Region;
+import jakarta.persistence.*;
+
+import java.math.BigDecimal;
+
+/**
+ * 娲诲姩閫夋墜瀹炰綋绫�
+ * 瀵瑰簲鏁版嵁搴撹〃锛歵_activity_player
+ */
+@Entity
+@Table(name = "t_activity_player")
+public class ActivityPlayer extends BaseEntity {
+
+    /**
+     * 娲诲姩ID
+     */
+    @Column(name = "activity_id", nullable = false)
+    private Long activityId;
+
+    /**
+     * 闃舵ID
+     */
+    @Column(name = "stage_id")
+    private Long stageId;
+
+    /**
+     * 閫夋墜ID
+     */
+    @Column(name = "player_id", nullable = false)
+    private Long playerId;
+
+    /**
+     * 鍖哄煙ID锛屽叧鑱攖_region琛�
+     */
+    @Column(name = "region_id")
+    private Long regionId;
+
+    /**
+     * 鎻忚堪
+     */
+    @Column(name = "description", columnDefinition = "TEXT")
+    private String description;
+
+    /**
+     * 椹冲洖鍘熷洜
+     */
+    @Column(name = "reject_reason", length = 500)
+    private String rejectReason;
+
+    /**
+     * 璇勫ID
+     */
+    @Column(name = "judge_id")
+    private Long judgeId;
+
+    /**
+     * 鍙嶉
+     */
+    @Column(name = "feedback", columnDefinition = "TEXT")
+    private String feedback;
+
+    /**
+     * 鎬诲垎
+     */
+    @Column(name = "total_score", precision = 10, scale = 2)
+    private BigDecimal totalScore;
+
+    /**
+     * 鎺掑悕
+     */
+    @Column(name = "rank")
+    private Integer rank;
+
+    // JPA鍏宠仈鍏崇郴
+    /**
+     * 鍏宠仈閫夋墜淇℃伅
+     */
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "player_id", insertable = false, updatable = false)
+    private Player player;
+
+    /**
+     * 鍏宠仈鍖哄煙淇℃伅
+     */
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "region_id", insertable = false, updatable = false)
+    private Region region;
+
+    // 鏋勯�犲嚱鏁�
+    public ActivityPlayer() {}
+
+    public ActivityPlayer(Long activityId, Long playerId, String description) {
+        this.activityId = activityId;
+        this.playerId = playerId;
+        this.description = description;
+    }
+
+    public ActivityPlayer(Long activityId, Long stageId, Long playerId, Long regionId, String description) {
+        this.activityId = activityId;
+        this.stageId = stageId;
+        this.playerId = playerId;
+        this.regionId = regionId;
+        this.description = description;
+    }
+
+    // Getter鍜孲etter鏂规硶
+    public Long getActivityId() {
+        return activityId;
+    }
+
+    public void setActivityId(Long activityId) {
+        this.activityId = activityId;
+    }
+
+    public Long getStageId() {
+        return stageId;
+    }
+
+    public void setStageId(Long stageId) {
+        this.stageId = stageId;
+    }
+
+    public Long getPlayerId() {
+        return playerId;
+    }
+
+    public void setPlayerId(Long playerId) {
+        this.playerId = playerId;
+    }
+
+    public Long getRegionId() {
+        return regionId;
+    }
+
+    public void setRegionId(Long regionId) {
+        this.regionId = regionId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
+    public Long getJudgeId() {
+        return judgeId;
+    }
+
+    public void setJudgeId(Long judgeId) {
+        this.judgeId = judgeId;
+    }
+
+    public String getFeedback() {
+        return feedback;
+    }
+
+    public void setFeedback(String feedback) {
+        this.feedback = feedback;
+    }
+
+    public BigDecimal getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(BigDecimal totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public Integer getRank() {
+        return rank;
+    }
+
+    public void setRank(Integer rank) {
+        this.rank = rank;
+    }
+
+    public Player getPlayer() {
+        return player;
+    }
+
+    public void setPlayer(Player player) {
+        this.player = player;
+    }
+
+    public Region getRegion() {
+        return region;
+    }
+
+    public void setRegion(Region region) {
+        this.region = region;
+    }
+
+    @Override
+    public String toString() {
+        return "ActivityPlayer{" +
+                "id=" + getId() +
+                ", activityId=" + activityId +
+                ", stageId=" + stageId +
+                ", playerId=" + playerId +
+                ", regionId=" + regionId +
+                ", description='" + description + '\'' +
+                ", totalScore=" + totalScore +
+                ", rank=" + rank +
+                '}';
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/player/entity/Player.java b/backend/src/main/java/com/rongyichuang/player/entity/Player.java
new file mode 100644
index 0000000..0fc4492
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/player/entity/Player.java
@@ -0,0 +1,193 @@
+package com.rongyichuang.player.entity;
+
+import com.rongyichuang.common.entity.BaseEntity;
+import jakarta.persistence.*;
+
+import java.math.BigDecimal;
+
+/**
+ * 瀛﹀憳瀹炰綋绫�
+ * 瀵瑰簲鏁版嵁搴撹〃锛歵_player
+ */
+@Entity
+@Table(name = "t_player")
+public class Player extends BaseEntity {
+
+    /**
+     * 濮撳悕
+     */
+    @Column(name = "name", length = 255)
+    private String name;
+
+    /**
+     * 鎵嬫満鍙�
+     */
+    @Column(name = "phone", length = 32, nullable = false, unique = true)
+    private String phone;
+
+    /**
+     * 瑙掕壊ID
+     */
+    @Column(name = "role_id", nullable = false)
+    private Long roleId;
+
+    /**
+     * 鎻忚堪
+     */
+    @Column(name = "description", length = 255)
+    private String description;
+
+    /**
+     * 鎬у埆锛�0-濂筹紝1-鐢�
+     */
+    @Column(name = "gender")
+    private Integer gender;
+
+    /**
+     * 瀛﹀巻
+     */
+    @Column(name = "education", length = 32)
+    private String education;
+
+    /**
+     * 涓汉浠嬬粛
+     */
+    @Column(name = "introduction", columnDefinition = "TEXT")
+    private String introduction;
+
+    /**
+     * 瀹℃牳鐘舵�侊細0-绛夊緟瀹℃牳锛�1-瀹℃牳閫氳繃锛�2-涓嶉�氳繃
+     */
+    @Column(name = "audit_state", nullable = false)
+    private Integer auditState;
+
+    /**
+     * 椹冲洖鍘熷洜
+     */
+    @Column(name = "reject_reason", length = 255)
+    private String rejectReason;
+
+    /**
+     * 鏈�缁堝緱鍒�
+     */
+    @Column(name = "final_score", precision = 10, scale = 2)
+    private BigDecimal finalScore;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @Column(name = "user_id", nullable = false)
+    private Long userId;
+
+    // 鏋勯�犲嚱鏁�
+    public Player() {}
+
+    public Player(String name, String phone, Long roleId, Integer auditState, Long userId) {
+        this.name = name;
+        this.phone = phone;
+        this.roleId = roleId;
+        this.auditState = auditState;
+        this.userId = userId;
+    }
+
+    // Getter鍜孲etter鏂规硶
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public Long getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId) {
+        this.roleId = roleId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Integer getGender() {
+        return gender;
+    }
+
+    public void setGender(Integer gender) {
+        this.gender = gender;
+    }
+
+    public String getEducation() {
+        return education;
+    }
+
+    public void setEducation(String education) {
+        this.education = education;
+    }
+
+    public String getIntroduction() {
+        return introduction;
+    }
+
+    public void setIntroduction(String introduction) {
+        this.introduction = introduction;
+    }
+
+    public Integer getAuditState() {
+        return auditState;
+    }
+
+    public void setAuditState(Integer auditState) {
+        this.auditState = auditState;
+    }
+
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
+    public BigDecimal getFinalScore() {
+        return finalScore;
+    }
+
+    public void setFinalScore(BigDecimal finalScore) {
+        this.finalScore = finalScore;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    @Override
+    public String toString() {
+        return "Player{" +
+                "id=" + getId() +
+                ", name='" + name + '\'' +
+                ", phone='" + phone + '\'' +
+                ", roleId=" + roleId +
+                ", auditState=" + auditState +
+                ", userId=" + userId +
+                '}';
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/player/repository/ActivityPlayerRepository.java b/backend/src/main/java/com/rongyichuang/player/repository/ActivityPlayerRepository.java
new file mode 100644
index 0000000..ed28626
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/player/repository/ActivityPlayerRepository.java
@@ -0,0 +1,91 @@
+package com.rongyichuang.player.repository;
+
+import com.rongyichuang.player.entity.ActivityPlayer;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 娲诲姩閫夋墜Repository鎺ュ彛
+ */
+@Repository
+public interface ActivityPlayerRepository extends JpaRepository<ActivityPlayer, Long> {
+
+    /**
+     * 鏍规嵁娲诲姩ID鏌ユ壘鍙傝禌閫夋墜
+     */
+    List<ActivityPlayer> findByActivityId(Long activityId);
+
+    /**
+     * 鏍规嵁閫夋墜ID鏌ユ壘鍙傝禌璁板綍
+     */
+    List<ActivityPlayer> findByPlayerId(Long playerId);
+
+    /**
+     * 鏍规嵁娲诲姩ID鍜岄�夋墜ID鏌ユ壘鍙傝禌璁板綍
+     */
+    Optional<ActivityPlayer> findByActivityIdAndPlayerId(Long activityId, Long playerId);
+
+    /**
+     * 鏍规嵁闃舵ID鏌ユ壘鍙傝禌閫夋墜
+     */
+    List<ActivityPlayer> findByStageId(Long stageId);
+
+    /**
+     * 鏍规嵁鍖哄煙ID鏌ユ壘鍙傝禌閫夋墜
+     */
+    List<ActivityPlayer> findByRegionId(Long regionId);
+
+    /**
+     * 鏍规嵁娲诲姩ID鍜屽尯鍩烮D鏌ユ壘鍙傝禌閫夋墜
+     */
+    List<ActivityPlayer> findByActivityIdAndRegionId(Long activityId, Long regionId);
+
+    /**
+     * 鏍规嵁鐘舵�佹煡鎵惧弬璧涢�夋墜
+     */
+    List<ActivityPlayer> findByState(Integer state);
+
+    /**
+     * 鏌ユ壘娲诲姩鐨勫弬璧涢�夋墜鏁伴噺
+     */
+    @Query("SELECT COUNT(ap) FROM ActivityPlayer ap WHERE ap.activityId = :activityId AND ap.state = 1")
+    Long countByActivityId(@Param("activityId") Long activityId);
+
+    /**
+     * 鏌ユ壘鍖哄煙鐨勫弬璧涢�夋墜鏁伴噺
+     */
+    @Query("SELECT COUNT(ap) FROM ActivityPlayer ap WHERE ap.regionId = :regionId AND ap.state = 1")
+    Long countByRegionId(@Param("regionId") Long regionId);
+
+    /**
+     * 鏍规嵁娲诲姩ID鏌ユ壘鍙傝禌閫夋墜锛屽寘鍚�夋墜鍜屽尯鍩熶俊鎭�
+     */
+    @Query("SELECT ap FROM ActivityPlayer ap " +
+           "LEFT JOIN FETCH ap.player p " +
+           "LEFT JOIN FETCH ap.region r " +
+           "WHERE ap.activityId = :activityId AND ap.state = 1 " +
+           "ORDER BY ap.createTime DESC")
+    List<ActivityPlayer> findByActivityIdWithPlayerAndRegion(@Param("activityId") Long activityId);
+
+    /**
+     * 鏍规嵁鍖哄煙缁熻鍚勬椿鍔ㄧ殑鍙傝禌浜烘暟
+     */
+    @Query("SELECT ap.activityId, ap.regionId, COUNT(ap) " +
+           "FROM ActivityPlayer ap " +
+           "WHERE ap.state = 1 " +
+           "GROUP BY ap.activityId, ap.regionId")
+    List<Object[]> countByActivityAndRegion();
+
+    /**
+     * 鏌ユ壘鎺掑悕鍓峃鐨勯�夋墜
+     */
+    @Query("SELECT ap FROM ActivityPlayer ap " +
+           "WHERE ap.activityId = :activityId AND ap.state = 1 AND ap.rank IS NOT NULL " +
+           "ORDER BY ap.rank ASC")
+    List<ActivityPlayer> findTopRankedPlayers(@Param("activityId") Long activityId);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/player/repository/PlayerRepository.java b/backend/src/main/java/com/rongyichuang/player/repository/PlayerRepository.java
new file mode 100644
index 0000000..45cdab7
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/player/repository/PlayerRepository.java
@@ -0,0 +1,60 @@
+package com.rongyichuang.player.repository;
+
+import com.rongyichuang.player.entity.Player;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 瀛﹀憳Repository鎺ュ彛
+ */
+@Repository
+public interface PlayerRepository extends JpaRepository<Player, Long> {
+
+    /**
+     * 鏍规嵁鎵嬫満鍙锋煡鎵惧鍛�
+     */
+    Optional<Player> findByPhone(String phone);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ユ壘瀛﹀憳
+     */
+    Optional<Player> findByUserId(Long userId);
+
+    /**
+     * 鏍规嵁瀹℃牳鐘舵�佹煡鎵惧鍛�
+     */
+    List<Player> findByAuditState(Integer auditState);
+
+    /**
+     * 鏍规嵁瑙掕壊ID鏌ユ壘瀛﹀憳
+     */
+    List<Player> findByRoleId(Long roleId);
+
+    /**
+     * 鏍规嵁鐘舵�佹煡鎵惧鍛�
+     */
+    List<Player> findByState(Integer state);
+
+    /**
+     * 鏌ユ壘瀹℃牳閫氳繃鐨勫鍛�
+     */
+    @Query("SELECT p FROM Player p WHERE p.auditState = 1 AND p.state = 1")
+    List<Player> findApprovedPlayers();
+
+    /**
+     * 鏍规嵁濮撳悕妯$硦鏌ヨ瀛﹀憳
+     */
+    @Query("SELECT p FROM Player p WHERE p.name LIKE %:name% AND p.state = 1")
+    List<Player> findByNameContaining(@Param("name") String name);
+
+    /**
+     * 缁熻鍚勫鏍哥姸鎬佺殑瀛﹀憳鏁伴噺
+     */
+    @Query("SELECT p.auditState, COUNT(p) FROM Player p WHERE p.state = 1 GROUP BY p.auditState")
+    List<Object[]> countByAuditState();
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java
index 00413de..0eb0337 100644
--- a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java
+++ b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java
@@ -1,6 +1,7 @@
 package com.rongyichuang.player.service;
 
 import com.rongyichuang.player.dto.response.*;
+import com.rongyichuang.player.dto.response.RegionInfoResponse;
 import com.rongyichuang.rating.dto.response.RatingItemResponse;
 import com.rongyichuang.rating.entity.RatingScheme;
 import com.rongyichuang.rating.repository.RatingSchemeRepository;
@@ -45,14 +46,16 @@
     public ActivityPlayerDetailResponse getDetailForRating(Long activityPlayerId) {
         log.info("鑾峰彇鎶ュ悕璇︽儏鐢ㄤ簬璇勫垎锛宎ctivityPlayerId: {}", activityPlayerId);
 
-        // 鏌ヨ鍩烘湰淇℃伅
+        // 鏌ヨ鍩烘湰淇℃伅锛屽寘鍚尯鍩熶俊鎭�
         String sql = """
-            SELECT ap.id, ap.description, ap.activity_id,
+            SELECT ap.id, ap.description, ap.activity_id, ap.region_id,
                    p.id as player_id, p.name as player_name, p.phone, p.description as player_desc,
-                   a.name as activity_name, a.rating_scheme_id
+                   a.name as activity_name, a.rating_scheme_id,
+                   r.id as r_id, r.name as region_name, r.full_path as region_path
             FROM t_activity_player ap
             JOIN t_player p ON p.id = ap.player_id
             JOIN t_activity a ON a.id = ap.activity_id
+            LEFT JOIN t_region r ON r.id = ap.region_id
             WHERE ap.id = ?
             """;
 
@@ -70,14 +73,24 @@
         ActivityPlayerDetailResponse response = new ActivityPlayerDetailResponse();
         response.setId(activityPlayerId);
         response.setDescription(row[1] != null ? row[1].toString() : "");
-        response.setActivityName(row[7] != null ? row[7].toString() : "");
+        response.setActivityName(row[8] != null ? row[8].toString() : "");
 
         // 鏋勫缓瀛﹀憳淇℃伅
         PlayerInfoResponse playerInfo = new PlayerInfoResponse();
-        playerInfo.setId(row[3] != null ? ((Number) row[3]).longValue() : null);
-        playerInfo.setName(row[4] != null ? row[4].toString() : "");
-        playerInfo.setPhone(row[5] != null ? row[5].toString() : "");
-        playerInfo.setDescription(row[6] != null ? row[6].toString() : "");
+        playerInfo.setId(row[4] != null ? ((Number) row[4]).longValue() : null);
+        playerInfo.setName(row[5] != null ? row[5].toString() : "");
+        playerInfo.setPhone(row[6] != null ? row[6].toString() : "");
+        playerInfo.setDescription(row[7] != null ? row[7].toString() : "");
+
+        // 鏋勫缓鍖哄煙淇℃伅
+        RegionInfoResponse regionInfo = new RegionInfoResponse();
+        if (row[10] != null) {
+            regionInfo.setId(((Number) row[10]).longValue());
+            regionInfo.setName(row[11] != null ? row[11].toString() : "");
+            regionInfo.setFullPath(row[12] != null ? row[12].toString() : "");
+            response.setRegionInfo(regionInfo);
+            log.info("鎵惧埌鍖哄煙淇℃伅: {}", regionInfo.getName());
+        }
 
         // 鏌ヨ瀛﹀憳澶村儚锛堜娇鐢ㄦ灇涓惧父閲忚〃绀哄鍛樺ご鍍忕被鍨嬶級
         if (playerInfo.getId() != null) {
@@ -102,7 +115,7 @@
         log.info("鎵惧埌鎻愪氦璧勬枡 {} 涓�", submissionFiles.size());
 
         // 鏌ヨ璇勫垎妯℃澘
-        Long ratingSchemeId = row[8] != null ? ((Number) row[8]).longValue() : null;
+        Long ratingSchemeId = row[9] != null ? ((Number) row[9]).longValue() : null;
         if (ratingSchemeId != null) {
             RatingFormResponse ratingForm = buildRatingForm(ratingSchemeId);
             response.setRatingForm(ratingForm);
diff --git a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java
index 24ca43f..e26369e 100644
--- a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java
+++ b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java
@@ -95,8 +95,8 @@
                 // 鍒犻櫎宸叉湁鐨勮瘎鍒嗛」
                 activityPlayerRatingItemRepository.deleteByActivityPlayerRatingId(rating.getId());
             } else {
-                // 鍒涘缓鏂扮殑璇勫垎璁板綍
-                rating = new ActivityPlayerRating(activityId, activityPlayerId, playerId, currentJudgeId, ratingSchemeId);
+                // 鍒涘缓鏂扮殑璇勫垎璁板綍锛屾殏鏃朵娇鐢�1浣滀负stageId鐨勯粯璁ゅ��
+                rating = new ActivityPlayerRating(activityId, activityPlayerId, 1L, playerId, currentJudgeId, ratingSchemeId);
                 rating = activityPlayerRatingRepository.save(rating);
                 log.info("鍒涘缓鏂扮殑璇勫垎璁板綍锛孖D: {}", rating.getId());
             }
@@ -118,30 +118,32 @@
                 
                 // 鍒涘缓璇勫垎椤硅褰�
                 ActivityPlayerRatingItem ratingItemEntity = new ActivityPlayerRatingItem(
+                        activityId,
+                        activityPlayerId,
                         rating.getId(),
+                        1L, // stageId锛屾殏鏃朵娇鐢�1
+                        playerId,
+                        currentJudgeId,
+                        ratingSchemeId,
                         itemId,
-                        ratingItem.getName(),
-                        BigDecimal.ONE, // 榛樿鏉冮噸涓�1
-                        BigDecimal.valueOf(ratingItem.getMaxScore()),
                         score
                 );
-                ratingItemEntity.setRemark(input.getComment());
                 
                 activityPlayerRatingItemRepository.save(ratingItemEntity);
                 
-                // 绱姞鍔犳潈寰楀垎
-                if (ratingItemEntity.getWeightedScore() != null) {
-                    totalScore = totalScore.add(ratingItemEntity.getWeightedScore());
+                // 绱姞寰楀垎
+                if (score != null) {
+                    totalScore = totalScore.add(score);
                 }
                 
-                log.info("淇濆瓨璇勫垎椤圭洰: itemId={}, score={}, weightedScore={}", 
-                        itemId, score, ratingItemEntity.getWeightedScore());
+                log.info("淇濆瓨璇勫垎椤圭洰: itemId={}, score={}", 
+                        itemId, score);
             }
             
             // 鏇存柊鎬诲垎鍜岀姸鎬�
             rating.setTotalScore(totalScore);
-            rating.setStatus(1); // 宸茶瘎鍒�
-            rating.setRemark(input.getComment());
+            rating.setState(1); // 宸茶瘎鍒�
+            rating.setFeedback(input.getComment());
             activityPlayerRatingRepository.save(rating);
             
             log.info("璇勫垎淇濆瓨瀹屾垚锛屾�诲垎: {}", totalScore);
@@ -200,8 +202,8 @@
         CurrentJudgeRatingResponse response = new CurrentJudgeRatingResponse();
         response.setId(rating.getId());
         response.setTotalScore(rating.getTotalScore());
-        response.setStatus(rating.getStatus());
-        response.setRemark(rating.getRemark());
+        response.setStatus(rating.getState());
+        response.setRemark(rating.getFeedback());
         
         // 鑾峰彇璇勫垎椤�
         List<ActivityPlayerRatingItem> items = activityPlayerRatingItemRepository
@@ -210,9 +212,9 @@
         List<CurrentJudgeRatingResponse.CurrentJudgeRatingItemResponse> itemResponses = items.stream()
                 .map(item -> new CurrentJudgeRatingResponse.CurrentJudgeRatingItemResponse(
                         item.getRatingItemId(),
-                        item.getRatingItemName(),
+                        "", // 璇勫垎椤瑰悕绉版殏鏃朵负绌�
                         item.getScore(),
-                        item.getWeightedScore()
+                        item.getScore() // 浣跨敤寰楀垎浣滀负鍔犳潈寰楀垎
                 ))
                 .collect(java.util.stream.Collectors.toList());
         
@@ -267,7 +269,7 @@
             if (ratingOpt.isPresent()) {
                 ActivityPlayerRating rating = ratingOpt.get();
                 totalScore = rating.getTotalScore();
-                status = rating.getStatus();
+                status = rating.getState();
             }
             
             Boolean isCurrentJudge = judgeId.equals(currentJudgeId);
diff --git a/backend/src/main/java/com/rongyichuang/user/entity/User.java b/backend/src/main/java/com/rongyichuang/user/entity/User.java
new file mode 100644
index 0000000..0cbe8e6
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/user/entity/User.java
@@ -0,0 +1,134 @@
+package com.rongyichuang.user.entity;
+
+import com.rongyichuang.common.entity.BaseEntity;
+import jakarta.persistence.*;
+
+/**
+ * 鐢ㄦ埛瀹炰綋绫�
+ */
+@Entity
+@Table(name = "t_user")
+public class User extends BaseEntity {
+
+    /**
+     * 鐢ㄦ埛濮撳悕
+     */
+    @Column(name = "name", length = 64)
+    private String name;
+
+    /**
+     * 鎬у埆锛�0-濂�, 1-鐢�
+     */
+    @Column(name = "gender")
+    private Integer gender;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    @Column(name = "phone", length = 32)
+    private String phone;
+
+    /**
+     * 瀵嗙爜
+     */
+    @Column(name = "password", length = 128)
+    private String password;
+
+    /**
+     * 寰俊openid
+     */
+    @Column(name = "wx_openid", length = 64)
+    private String wxOpenid;
+
+    /**
+     * 寰俊unionid
+     */
+    @Column(name = "wx_unionid", length = 64)
+    private String wxUnionid;
+
+    /**
+     * 寰俊鍏紬鍙穙penid
+     */
+    @Column(name = "wx_oa_openid", length = 64)
+    private String wxOaOpenid;
+
+    /**
+     * 鎵嬫満鍙风爜锛堝鐢ㄥ瓧娈碉級
+     */
+    @Column(name = "mobile", length = 32)
+    private String mobile;
+
+    // 鏋勯�犲嚱鏁�
+    public User() {}
+
+    public User(String name, String phone, String password) {
+        this.name = name;
+        this.phone = phone;
+        this.password = password;
+    }
+
+    // Getter鍜孲etter鏂规硶
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getGender() {
+        return gender;
+    }
+
+    public void setGender(Integer gender) {
+        this.gender = gender;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getWxOpenid() {
+        return wxOpenid;
+    }
+
+    public void setWxOpenid(String wxOpenid) {
+        this.wxOpenid = wxOpenid;
+    }
+
+    public String getWxUnionid() {
+        return wxUnionid;
+    }
+
+    public void setWxUnionid(String wxUnionid) {
+        this.wxUnionid = wxUnionid;
+    }
+
+    public String getWxOaOpenid() {
+        return wxOaOpenid;
+    }
+
+    public void setWxOaOpenid(String wxOaOpenid) {
+        this.wxOaOpenid = wxOaOpenid;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/user/repository/UserRepository.java b/backend/src/main/java/com/rongyichuang/user/repository/UserRepository.java
new file mode 100644
index 0000000..cff5a6b
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/user/repository/UserRepository.java
@@ -0,0 +1,34 @@
+package com.rongyichuang.user.repository;
+
+import com.rongyichuang.user.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+/**
+ * 鐢ㄦ埛鏁版嵁璁块棶灞�
+ */
+@Repository
+public interface UserRepository extends JpaRepository<User, Long> {
+
+    /**
+     * 鏍规嵁鎵嬫満鍙锋煡鎵剧敤鎴�
+     */
+    Optional<User> findByPhone(String phone);
+
+    /**
+     * 妫�鏌ユ墜鏈哄彿鏄惁宸插瓨鍦�
+     */
+    boolean existsByPhone(String phone);
+
+    /**
+     * 鏍规嵁寰俊openid鏌ユ壘鐢ㄦ埛
+     */
+    Optional<User> findByWxOpenid(String wxOpenid);
+
+    /**
+     * 鏍规嵁寰俊unionid鏌ユ壘鐢ㄦ埛
+     */
+    Optional<User> findByWxUnionid(String wxUnionid);
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/rongyichuang/user/service/UserService.java b/backend/src/main/java/com/rongyichuang/user/service/UserService.java
new file mode 100644
index 0000000..ad01ab3
--- /dev/null
+++ b/backend/src/main/java/com/rongyichuang/user/service/UserService.java
@@ -0,0 +1,80 @@
+package com.rongyichuang.user.service;
+
+import com.rongyichuang.user.entity.User;
+import com.rongyichuang.user.repository.UserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Optional;
+
+/**
+ * 鐢ㄦ埛鏈嶅姟绫�
+ */
+@Service
+@Transactional
+public class UserService {
+
+    @Autowired
+    private UserRepository userRepository;
+    
+    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+
+    /**
+     * 鏍规嵁鎵嬫満鍙锋煡鎵炬垨鍒涘缓鐢ㄦ埛
+     * 濡傛灉鐢ㄦ埛瀛樺湪锛屾洿鏂板鍚嶅拰瀵嗙爜锛堝鏋滄彁渚涗簡瀵嗙爜锛�
+     * 濡傛灉鐢ㄦ埛涓嶅瓨鍦紝鍒涘缓鏂扮敤鎴�
+     * 
+     * @param phone 鎵嬫満鍙�
+     * @param name 濮撳悕
+     * @param password 瀵嗙爜锛堝彲浠ヤ负null锛岃〃绀轰笉鏇存柊瀵嗙爜锛�
+     * @return 鐢ㄦ埛瀹炰綋
+     */
+    public User findOrCreateUserByPhone(String phone, String name, String password) {
+        Optional<User> existingUser = userRepository.findByPhone(phone);
+        
+        if (existingUser.isPresent()) {
+            // 鐢ㄦ埛瀛樺湪锛屾洿鏂板鍚嶅拰瀵嗙爜锛堝鏋滄彁渚涗簡瀵嗙爜锛�
+            User user = existingUser.get();
+            user.setName(name);
+            if (password != null && !password.trim().isEmpty()) {
+                user.setPassword(passwordEncoder.encode(password));
+            }
+            return userRepository.save(user);
+        } else {
+            // 鐢ㄦ埛涓嶅瓨鍦紝鍒涘缓鏂扮敤鎴�
+            User newUser = new User();
+            newUser.setName(name);
+            newUser.setPhone(phone);
+            if (password != null && !password.trim().isEmpty()) {
+                newUser.setPassword(passwordEncoder.encode(password));
+            } else {
+                // 濡傛灉娌℃湁鎻愪緵瀵嗙爜锛岃缃竴涓粯璁ゅ瘑鐮�
+                newUser.setPassword(passwordEncoder.encode("123456"));
+            }
+            return userRepository.save(newUser);
+        }
+    }
+
+    /**
+     * 鏍规嵁鎵嬫満鍙锋煡鎵剧敤鎴�
+     */
+    public Optional<User> findByPhone(String phone) {
+        return userRepository.findByPhone(phone);
+    }
+
+    /**
+     * 淇濆瓨鐢ㄦ埛
+     */
+    public User save(User user) {
+        return userRepository.save(user);
+    }
+
+    /**
+     * 鏍规嵁ID鏌ユ壘鐢ㄦ埛
+     */
+    public Optional<User> findById(Long id) {
+        return userRepository.findById(id);
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/resources/graphql/judge.graphqls b/backend/src/main/resources/graphql/judge.graphqls
index 32b8f19..8e6fe49 100644
--- a/backend/src/main/resources/graphql/judge.graphqls
+++ b/backend/src/main/resources/graphql/judge.graphqls
@@ -27,6 +27,7 @@
     title: String
     company: String
     phone: String
+    password: String
     gender: Int
     description: String
     introduction: String
diff --git a/backend/src/main/resources/graphql/player.graphqls b/backend/src/main/resources/graphql/player.graphqls
index f11a00a..c3d8336 100644
--- a/backend/src/main/resources/graphql/player.graphqls
+++ b/backend/src/main/resources/graphql/player.graphqls
@@ -26,6 +26,7 @@
 type ActivityPlayerDetailResponse {
   id: ID!
   playerInfo: PlayerInfoResponse!
+  regionInfo: RegionInfoResponse
   activityName: String!
   description: String
   submissionFiles: [SubmissionMediaResponse!]!
@@ -39,6 +40,13 @@
   phone: String
   description: String
   avatarUrl: String
+}
+
+# 鍖哄煙淇℃伅鍝嶅簲
+type RegionInfoResponse {
+  id: ID!
+  name: String!
+  fullPath: String
 }
 
 # 鎻愪氦璧勬枡鍝嶅簲
@@ -69,7 +77,7 @@
 # 璇勫垎椤圭洰杈撳叆绫诲瀷
 input ActivityPlayerRatingItemInput {
   itemId: ID!
-  score: Int!
+  score: Float!
 }
 
 # 璇勫璇勫垎鐘舵�佸搷搴旂被鍨�
@@ -83,12 +91,19 @@
 
 # 褰撳墠璇勫璇勫垎鍝嶅簲绫诲瀷
 type CurrentJudgeRatingResponse {
-  activityPlayerId: ID!
-  judgeId: ID!
-  ratings: [RatingItemScoreResponse!]!
-  comment: String
+  id: ID!
   totalScore: Float
-  ratingTime: String
+  status: Int
+  remark: String
+  items: [CurrentJudgeRatingItemResponse!]!
+}
+
+# 褰撳墠璇勫璇勫垎椤瑰搷搴旂被鍨�
+type CurrentJudgeRatingItemResponse {
+  ratingItemId: ID!
+  ratingItemName: String!
+  score: Float!
+  weightedScore: Float!
 }
 
 # 璇勫垎椤圭洰鍒嗘暟鍝嶅簲绫诲瀷
diff --git a/backend/src/test/java/CheckRatingItemTableStructureTest2.java b/backend/src/test/java/CheckRatingItemTableStructureTest2.java
new file mode 100644
index 0000000..6955178
--- /dev/null
+++ b/backend/src/test/java/CheckRatingItemTableStructureTest2.java
@@ -0,0 +1,37 @@
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import com.rongyichuang.RycBackendApplication;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest(classes = RycBackendApplication.class)
+public class CheckRatingItemTableStructureTest2 {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void checkTableStructure() {
+        try {
+            // 鏌ヨ琛ㄧ粨鏋�
+            String sql = "DESCRIBE t_activity_player_rating_item";
+            List<Map<String, Object>> columns = jdbcTemplate.queryForList(sql);
+            
+            System.out.println("=== t_activity_player_rating_item 琛ㄧ粨鏋� ===");
+            for (Map<String, Object> column : columns) {
+                System.out.println("瀛楁鍚�: " + column.get("Field") + 
+                                 ", 绫诲瀷: " + column.get("Type") + 
+                                 ", 鏄惁涓虹┖: " + column.get("Null") + 
+                                 ", 閿�: " + column.get("Key") + 
+                                 ", 榛樿鍊�: " + column.get("Default"));
+            }
+            
+        } catch (Exception e) {
+            System.err.println("鏌ヨ琛ㄧ粨鏋勫け璐�: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/CheckActivityJudgeTest.java b/backend/src/test/java/com/rongyichuang/CheckActivityJudgeTest.java
new file mode 100644
index 0000000..d35e419
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/CheckActivityJudgeTest.java
@@ -0,0 +1,73 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ActiveProfiles;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+@ActiveProfiles("test")
+public class CheckActivityJudgeTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void checkActivityJudgeData() {
+        try {
+            // 妫�鏌ユ椿鍔ㄨ瘎濮斿叧鑱旇〃缁撴瀯
+            String describeTableSql = "DESCRIBE t_activity_judge";
+            List<Map<String, Object>> tableStructure = jdbcTemplate.queryForList(describeTableSql);
+            
+            System.out.println("=== t_activity_judge 琛ㄧ粨鏋� ===");
+            for (Map<String, Object> column : tableStructure) {
+                System.out.println("瀛楁: " + column.get("Field") + 
+                                 ", 绫诲瀷: " + column.get("Type") + 
+                                 ", 鏄惁涓虹┖: " + column.get("Null") + 
+                                 ", 閿�: " + column.get("Key") + 
+                                 ", 榛樿鍊�: " + column.get("Default"));
+            }
+            
+            // 妫�鏌ュ叧鑱旀暟鎹�
+            String countSql = "SELECT COUNT(*) as count FROM t_activity_judge";
+            Map<String, Object> countResult = jdbcTemplate.queryForMap(countSql);
+            System.out.println("\n=== 娲诲姩璇勫鍏宠仈鏁版嵁缁熻 ===");
+            System.out.println("鍏宠仈璁板綍鎬绘暟: " + countResult.get("count"));
+            
+            // 鏌ョ湅鍓�5鏉″叧鑱旀暟鎹�
+            String dataSql = "SELECT * FROM t_activity_judge LIMIT 5";
+            List<Map<String, Object>> relationData = jdbcTemplate.queryForList(dataSql);
+            System.out.println("\n=== 鍓�5鏉℃椿鍔ㄨ瘎濮斿叧鑱旀暟鎹� ===");
+            for (Map<String, Object> relation : relationData) {
+                System.out.println("娲诲姩ID: " + relation.get("activity_id") + 
+                                 ", 璇勫ID: " + relation.get("judge_id") + 
+                                 ", 鐘舵��: " + relation.get("state"));
+            }
+            
+            // 妫�鏌ユ椿鍔↖D涓�1鐨勮瘎濮斿叧鑱�
+            String activity1Sql = "SELECT * FROM t_activity_judge WHERE activity_id = 1";
+            List<Map<String, Object>> activity1Judges = jdbcTemplate.queryForList(activity1Sql);
+            System.out.println("\n=== 娲诲姩ID涓�1鐨勮瘎濮斿叧鑱� ===");
+            for (Map<String, Object> relation : activity1Judges) {
+                System.out.println("娲诲姩ID: " + relation.get("activity_id") + 
+                                 ", 璇勫ID: " + relation.get("judge_id") + 
+                                 ", 鐘舵��: " + relation.get("state"));
+            }
+            
+        } catch (Exception e) {
+            System.out.println("琛ㄤ笉瀛樺湪鎴栨煡璇㈠け璐�: " + e.getMessage());
+            
+            // 灏濊瘯鏌ョ湅鎵�鏈夎〃
+            String showTablesSql = "SHOW TABLES LIKE '%judge%'";
+            List<Map<String, Object>> tables = jdbcTemplate.queryForList(showTablesSql);
+            System.out.println("\n=== 鍖呭惈judge鐨勮〃 ===");
+            for (Map<String, Object> table : tables) {
+                System.out.println("琛ㄥ悕: " + table.values().iterator().next());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/CheckActivityPlayerDataTest.java b/backend/src/test/java/com/rongyichuang/CheckActivityPlayerDataTest.java
new file mode 100644
index 0000000..fe0d15d
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/CheckActivityPlayerDataTest.java
@@ -0,0 +1,68 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.Query;
+import java.util.List;
+
+@SpringBootTest
+@ActiveProfiles("test")
+public class CheckActivityPlayerDataTest {
+
+    @Autowired
+    private EntityManager entityManager;
+
+    @Test
+    public void checkActivityPlayerData() {
+        System.out.println("=== 妫�鏌� t_activity_player 琛ㄦ暟鎹� ===");
+        
+        // 鏌ヨ琛ㄧ粨鏋�
+        String describeQuery = "DESCRIBE t_activity_player";
+        Query query = entityManager.createNativeQuery(describeQuery);
+        List<Object[]> columns = query.getResultList();
+        
+        System.out.println("琛ㄧ粨鏋�:");
+        for (Object[] column : columns) {
+            System.out.println("  " + column[0] + " - " + column[1]);
+        }
+        
+        // 鏌ヨ鏁版嵁
+        String dataQuery = "SELECT id, player_id, activity_id, region_id, description FROM t_activity_player LIMIT 5";
+        Query dataQueryObj = entityManager.createNativeQuery(dataQuery);
+        List<Object[]> results = dataQueryObj.getResultList();
+        
+        System.out.println("\n琛ㄦ暟鎹�:");
+        System.out.println("ID | Player_ID | Activity_ID | Region_ID | Description");
+        System.out.println("---|-----------|-------------|-----------|------------");
+        
+        for (Object[] row : results) {
+            System.out.printf("%s | %s | %s | %s | %s%n", 
+                row[0], row[1], row[2], row[3], 
+                row[4] != null ? row[4].toString().substring(0, Math.min(20, row[4].toString().length())) + "..." : "null");
+        }
+        
+        // 妫�鏌ユ槸鍚︽湁region_id涓嶄负绌虹殑鏁版嵁
+        String regionQuery = "SELECT COUNT(*) FROM t_activity_player WHERE region_id IS NOT NULL";
+        Query regionQueryObj = entityManager.createNativeQuery(regionQuery);
+        Object regionCount = regionQueryObj.getSingleResult();
+        
+        System.out.println("\n鏈塺egion_id鐨勮褰曟暟: " + regionCount);
+        
+        // 鏌ョ湅region琛ㄦ暟鎹�
+        String regionDataQuery = "SELECT id, name, full_path FROM t_region LIMIT 5";
+        Query regionDataQueryObj = entityManager.createNativeQuery(regionDataQuery);
+        List<Object[]> regionResults = regionDataQueryObj.getResultList();
+        
+        System.out.println("\nt_region 琛ㄦ暟鎹�:");
+        System.out.println("ID | Name | Full_Path");
+        System.out.println("---|------|----------");
+        
+        for (Object[] row : regionResults) {
+            System.out.printf("%s | %s | %s%n", row[0], row[1], row[2]);
+        }
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/CheckActivityPlayerRatingTableTest.java b/backend/src/test/java/com/rongyichuang/CheckActivityPlayerRatingTableTest.java
new file mode 100644
index 0000000..6ef737f
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/CheckActivityPlayerRatingTableTest.java
@@ -0,0 +1,48 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest(classes = RycBackendApplication.class)
+public class CheckActivityPlayerRatingTableTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void checkTableStructure() {
+        try {
+            String sql1 = "DESCRIBE t_activity_player_rating";
+            List<Map<String, Object>> result1 = jdbcTemplate.queryForList(sql1);
+            
+            System.out.println("=== t_activity_player_rating 琛ㄧ粨鏋� ===");
+            for (Map<String, Object> row : result1) {
+                System.out.println("Field: " + row.get("Field") + 
+                                 ", Type: " + row.get("Type") + 
+                                 ", Null: " + row.get("Null") + 
+                                 ", Key: " + row.get("Key") + 
+                                 ", Default: " + row.get("Default"));
+            }
+            
+            System.out.println("\n=== t_activity_player_rating_item 琛ㄧ粨鏋� ===");
+            String sql2 = "DESCRIBE t_activity_player_rating_item";
+            List<Map<String, Object>> result2 = jdbcTemplate.queryForList(sql2);
+            
+            for (Map<String, Object> row : result2) {
+                System.out.println("Field: " + row.get("Field") + 
+                                 ", Type: " + row.get("Type") + 
+                                 ", Null: " + row.get("Null") + 
+                                 ", Key: " + row.get("Key") + 
+                                 ", Default: " + row.get("Default"));
+            }
+        } catch (Exception e) {
+            System.err.println("妫�鏌ヨ〃缁撴瀯澶辫触: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/CheckJudgeDataTest.java b/backend/src/test/java/com/rongyichuang/CheckJudgeDataTest.java
new file mode 100644
index 0000000..bbfea51
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/CheckJudgeDataTest.java
@@ -0,0 +1,51 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ActiveProfiles;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+@ActiveProfiles("test")
+public class CheckJudgeDataTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void checkJudgeData() {
+        // 妫�鏌ヨ瘎濮旇〃缁撴瀯
+        String describeTableSql = "DESCRIBE t_judge";
+        List<Map<String, Object>> tableStructure = jdbcTemplate.queryForList(describeTableSql);
+        
+        System.out.println("=== t_judge 琛ㄧ粨鏋� ===");
+        for (Map<String, Object> column : tableStructure) {
+            System.out.println("瀛楁: " + column.get("Field") + 
+                             ", 绫诲瀷: " + column.get("Type") + 
+                             ", 鏄惁涓虹┖: " + column.get("Null") + 
+                             ", 閿�: " + column.get("Key") + 
+                             ", 榛樿鍊�: " + column.get("Default"));
+        }
+        
+        // 妫�鏌ヨ瘎濮旀暟鎹�
+        String countSql = "SELECT COUNT(*) as count FROM t_judge";
+        Map<String, Object> countResult = jdbcTemplate.queryForMap(countSql);
+        System.out.println("\n=== 璇勫鏁版嵁缁熻 ===");
+        System.out.println("璇勫鎬绘暟: " + countResult.get("count"));
+        
+        // 鏌ョ湅鍓�5鏉¤瘎濮旀暟鎹�
+        String dataSql = "SELECT * FROM t_judge LIMIT 5";
+        List<Map<String, Object>> judgeData = jdbcTemplate.queryForList(dataSql);
+        System.out.println("\n=== 鍓�5鏉¤瘎濮旀暟鎹� ===");
+        for (Map<String, Object> judge : judgeData) {
+            System.out.println("ID: " + judge.get("id") + 
+                             ", 濮撳悕: " + judge.get("name") + 
+                             ", 鐢ㄦ埛ID: " + judge.get("user_id") + 
+                             ", 鐘舵��: " + judge.get("state"));
+        }
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/CheckRatingItemTableStructureTest.java b/backend/src/test/java/com/rongyichuang/CheckRatingItemTableStructureTest.java
new file mode 100644
index 0000000..0c42c14
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/CheckRatingItemTableStructureTest.java
@@ -0,0 +1,37 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+public class CheckRatingItemTableStructureTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void checkTableStructure() {
+        System.out.println("=== 妫�鏌� t_activity_player_rating_item 琛ㄧ粨鏋� ===");
+        
+        String sql = "DESCRIBE t_activity_player_rating_item";
+        List<Map<String, Object>> columns = jdbcTemplate.queryForList(sql);
+        
+        for (Map<String, Object> column : columns) {
+            System.out.println("瀛楁: " + column.get("Field") + 
+                             ", 绫诲瀷: " + column.get("Type") + 
+                             ", 鏄惁涓虹┖: " + column.get("Null") + 
+                             ", 閿�: " + column.get("Key") + 
+                             ", 榛樿鍊�: " + column.get("Default"));
+        }
+        
+        // 妫�鏌ユ槸鍚﹀瓨鍦╮emark瀛楁
+        boolean hasRemarkField = columns.stream()
+                .anyMatch(column -> "remark".equals(column.get("Field")));
+        System.out.println("鏄惁瀛樺湪remark瀛楁: " + hasRemarkField);
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/CheckTableStructureTest.java b/backend/src/test/java/com/rongyichuang/CheckTableStructureTest.java
new file mode 100644
index 0000000..db0a1ba
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/CheckTableStructureTest.java
@@ -0,0 +1,40 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ActiveProfiles;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+@ActiveProfiles("dev")
+public class CheckTableStructureTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void checkActivityPlayerRatingTableStructure() {
+        System.out.println("=== 妫�鏌� t_activity_player_rating 琛ㄧ粨鏋� ===");
+        
+        String sql = "DESCRIBE t_activity_player_rating";
+        List<Map<String, Object>> columns = jdbcTemplate.queryForList(sql);
+        
+        for (Map<String, Object> column : columns) {
+            System.out.println("瀛楁: " + column.get("Field") + 
+                             ", 绫诲瀷: " + column.get("Type") + 
+                             ", 鏄惁涓虹┖: " + column.get("Null") + 
+                             ", 閿�: " + column.get("Key") + 
+                             ", 榛樿鍊�: " + column.get("Default"));
+        }
+        
+        // 妫�鏌ユ槸鍚﹀瓨鍦╮ating_scheme_id瀛楁
+        boolean hasRatingSchemeId = columns.stream()
+            .anyMatch(col -> "rating_scheme_id".equals(col.get("Field")));
+        
+        System.out.println("鏄惁瀛樺湪rating_scheme_id瀛楁: " + hasRatingSchemeId);
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/SetupActivityJudgeTest.java b/backend/src/test/java/com/rongyichuang/SetupActivityJudgeTest.java
new file mode 100644
index 0000000..bb4b420
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/SetupActivityJudgeTest.java
@@ -0,0 +1,33 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ActiveProfiles;
+
+@SpringBootTest
+@ActiveProfiles("test")
+public class SetupActivityJudgeTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void setupActivityJudge() {
+        // 涓鸿瘎濮擨D涓�21鐨勮瘎濮旀坊鍔犳椿鍔↖D涓�1鐨勫叧鑱旇褰�
+        String insertSql = "INSERT INTO t_activity_judge (activity_id, stage_id, judge_id, state) VALUES (1, 1, 21, 1)";
+        int insertedRows = jdbcTemplate.update(insertSql);
+        
+        System.out.println("鎻掑叆浜� " + insertedRows + " 鏉℃椿鍔ㄨ瘎濮斿叧鑱旇褰�");
+        
+        // 楠岃瘉鎻掑叆缁撴灉
+        String verifySql = "SELECT * FROM t_activity_judge WHERE activity_id = 1 AND judge_id = 21";
+        jdbcTemplate.queryForList(verifySql).forEach(row -> {
+            System.out.println("娲诲姩ID: " + row.get("activity_id") + 
+                             ", 璇勫ID: " + row.get("judge_id") + 
+                             ", 闃舵ID: " + row.get("stage_id") + 
+                             ", 鐘舵��: " + row.get("state"));
+        });
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/SetupJudgeUserTest.java b/backend/src/test/java/com/rongyichuang/SetupJudgeUserTest.java
new file mode 100644
index 0000000..f2f836c
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/SetupJudgeUserTest.java
@@ -0,0 +1,32 @@
+package com.rongyichuang;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ActiveProfiles;
+
+@SpringBootTest
+@ActiveProfiles("test")
+public class SetupJudgeUserTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void setupJudgeUser() {
+        // 涓虹涓�涓瘎濮旇缃畊ser_id涓�1锛屼互渚挎祴璇曡瘎鍒嗗姛鑳�
+        String updateSql = "UPDATE t_judge SET user_id = 1 WHERE id = 21";
+        int updatedRows = jdbcTemplate.update(updateSql);
+        
+        System.out.println("鏇存柊浜� " + updatedRows + " 鏉¤瘎濮旇褰�");
+        
+        // 楠岃瘉鏇存柊缁撴灉
+        String verifySql = "SELECT id, name, user_id FROM t_judge WHERE user_id = 1";
+        jdbcTemplate.queryForList(verifySql).forEach(row -> {
+            System.out.println("璇勫ID: " + row.get("id") + 
+                             ", 濮撳悕: " + row.get("name") + 
+                             ", 鐢ㄦ埛ID: " + row.get("user_id"));
+        });
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/com/rongyichuang/tools/ActivityPlayerRegionUpdater.java b/backend/src/test/java/com/rongyichuang/tools/ActivityPlayerRegionUpdater.java
new file mode 100644
index 0000000..7cbfb1e
--- /dev/null
+++ b/backend/src/test/java/com/rongyichuang/tools/ActivityPlayerRegionUpdater.java
@@ -0,0 +1,91 @@
+package com.rongyichuang.tools;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+public class ActivityPlayerRegionUpdater {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Test
+    public void addRegionFieldToActivityPlayer() {
+        System.out.println("=== 涓� t_activity_player 琛ㄦ坊鍔� region_id 瀛楁 ===");
+        
+        try {
+            // 1. 妫�鏌ュ瓧娈垫槸鍚﹀凡瀛樺湪
+            String checkColumnSql = """
+                SELECT COLUMN_NAME 
+                FROM INFORMATION_SCHEMA.COLUMNS 
+                WHERE TABLE_SCHEMA = DATABASE() 
+                AND TABLE_NAME = 't_activity_player' 
+                AND COLUMN_NAME = 'region_id'
+                """;
+            
+            List<Map<String, Object>> existingColumns = jdbcTemplate.queryForList(checkColumnSql);
+            
+            if (!existingColumns.isEmpty()) {
+                System.out.println("鉁� region_id 瀛楁宸插瓨鍦紝鏃犻渶娣诲姞");
+                return;
+            }
+            
+            // 2. 娣诲姞 region_id 瀛楁
+            String addColumnSql = """
+                ALTER TABLE t_activity_player 
+                ADD COLUMN region_id bigint DEFAULT NULL COMMENT '鍖哄煙ID锛屽叧鑱攖_region琛�' 
+                AFTER player_id
+                """;
+            
+            jdbcTemplate.execute(addColumnSql);
+            System.out.println("鉁� 鎴愬姛娣诲姞 region_id 瀛楁");
+            
+            // 3. 娣诲姞澶栭敭绾︽潫
+            try {
+                String addForeignKeySql = """
+                    ALTER TABLE t_activity_player 
+                    ADD CONSTRAINT fk_activity_player_region 
+                    FOREIGN KEY (region_id) REFERENCES t_region(id) 
+                    ON DELETE SET NULL ON UPDATE CASCADE
+                    """;
+                
+                jdbcTemplate.execute(addForeignKeySql);
+                System.out.println("鉁� 鎴愬姛娣诲姞澶栭敭绾︽潫");
+            } catch (Exception e) {
+                System.out.println("鈿狅笍 澶栭敭绾︽潫娣诲姞澶辫触锛堝彲鑳藉凡瀛樺湪锛�: " + e.getMessage());
+            }
+            
+            // 4. 楠岃瘉琛ㄧ粨鏋�
+            String describeTableSql = """
+                SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT
+                FROM INFORMATION_SCHEMA.COLUMNS 
+                WHERE TABLE_SCHEMA = DATABASE() 
+                AND TABLE_NAME = 't_activity_player' 
+                ORDER BY ORDINAL_POSITION
+                """;
+            
+            List<Map<String, Object>> columns = jdbcTemplate.queryForList(describeTableSql);
+            System.out.println("\n=== t_activity_player 琛ㄧ粨鏋� ===");
+            for (Map<String, Object> column : columns) {
+                System.out.println(String.format("%-20s %-15s %-10s %-15s %s", 
+                    column.get("COLUMN_NAME"),
+                    column.get("DATA_TYPE"),
+                    column.get("IS_NULLABLE"),
+                    column.get("COLUMN_DEFAULT"),
+                    column.get("COLUMN_COMMENT")
+                ));
+            }
+            
+        } catch (Exception e) {
+            System.err.println("鉂� 鎿嶄綔澶辫触: " + e.getMessage());
+            e.printStackTrace();
+        }
+        
+        System.out.println("\n鉁� region_id 瀛楁娣诲姞瀹屾垚锛�");
+    }
+}
\ No newline at end of file
diff --git a/web/src/api/activityPlayer.js b/web/src/api/activityPlayer.js
index 9eb3d43..6c0ef11 100644
--- a/web/src/api/activityPlayer.js
+++ b/web/src/api/activityPlayer.js
@@ -40,6 +40,11 @@
         description
         avatarUrl
       }
+      regionInfo {
+        id
+        name
+        fullPath
+      }
       activityName
       description
       submissionFiles {
diff --git a/web/src/api/graphql.ts b/web/src/api/graphql.ts
index 77046bb..7dd2e56 100644
--- a/web/src/api/graphql.ts
+++ b/web/src/api/graphql.ts
@@ -165,6 +165,7 @@
   id?: string
   name: string
   phone?: string
+  password?: string
   gender?: number
   description?: string
   avatarMediaId?: string
diff --git a/web/src/components/JudgeFormSimple.vue b/web/src/components/JudgeFormSimple.vue
index 6445dc7..9c335e2 100644
--- a/web/src/components/JudgeFormSimple.vue
+++ b/web/src/components/JudgeFormSimple.vue
@@ -25,6 +25,28 @@
         <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
       </el-form-item>
 
+      <el-form-item label="瀵嗙爜" prop="password">
+        <div style="display: flex; align-items: center; gap: 10px;">
+          <el-input 
+            v-model="form.password" 
+            type="password"
+            :placeholder="isEdit ? '璇疯緭鍏ユ柊瀵嗙爜锛�6-20浣嶏紝鍖呭惈瀛楁瘝鍜屾暟瀛楋級' : '璇疯緭鍏ョ櫥褰曞瘑鐮侊紙6-20浣嶏紝鍖呭惈瀛楁瘝鍜屾暟瀛楋級'"
+            maxlength="20"
+            @focus="handlePasswordFocus"
+            @input="handlePasswordInput"
+            style="flex: 1;"
+          />
+          <el-button 
+            v-if="isEdit" 
+            type="primary" 
+            size="small"
+            @click="handleResetPassword"
+          >
+            閲嶇疆瀵嗙爜
+          </el-button>
+        </div>
+      </el-form-item>
+
       <el-form-item label="鎬у埆" prop="gender">
         <el-radio-group v-model="form.gender">
           <el-radio :value="1">鐢�</el-radio>
@@ -144,6 +166,8 @@
 // 鏄惁涓虹紪杈戞ā寮�
 const isEdit = computed(() => !!props.judgeData?.id)
 
+
+
 // 琛ㄥ崟鏁版嵁
 const form = reactive<JudgeInput & { 
   avatarUrl?: string; 
@@ -160,6 +184,7 @@
   id: undefined,
   name: '',
   phone: '',
+  password: '',
   gender: undefined,
   description: '',
   specialtyIds: [],
@@ -171,6 +196,9 @@
 // 鍙�夌殑涓撲笟鏍囩锛堜粠鍚庣鑾峰彇锛�
 const availableTags = ref<Tag[]>([])
 
+// 璺熻釜瀵嗙爜鏄惁琚慨鏀�
+const isPasswordModified = ref(false)
+
 // 琛ㄥ崟楠岃瘉瑙勫垯
 const rules = {
   name: [
@@ -180,16 +208,41 @@
   phone: [
     { required: true, message: '璇疯緭鍏ヨ仈绯荤數璇�', trigger: 'blur' },
     { pattern: /^1[3-9]\d{9}$/, message: '璇疯緭鍏ユ纭殑鎵嬫満鍙风爜', trigger: 'blur' }
+  ],
+  password: [
+    { 
+      validator: (rule: any, value: string, callback: any) => {
+        // 缂栬緫妯″紡涓嬶紝濡傛灉鏄崰浣嶇瀵嗙爜涓旀湭淇敼锛屽垯璺宠繃楠岃瘉
+        if (isEdit.value && value === '鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��' && !isPasswordModified.value) {
+          callback()
+          return
+        }
+        
+        if (!value || value.trim() === '') {
+          callback(new Error('璇疯緭鍏ョ櫥褰曞瘑鐮�'))
+        } else if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*?&]{6,}$/.test(value)) {
+          callback(new Error('瀵嗙爜鑷冲皯6涓瓧绗︼紝蹇呴』鍖呭惈瀛楁瘝鍜屾暟瀛�'))
+        } else {
+          callback()
+        }
+      }, 
+      trigger: 'blur' 
+    }
   ]
 }
 
 // 鐩戝惉璇勫鏁版嵁鍙樺寲锛屽~鍏呰〃鍗�
 watch(() => props.judgeData, (data) => {
+  console.log('馃攳 Watch triggered, judgeData:', data)
+  console.log('馃攳 isEdit computed:', isEdit.value)
   nextTick(async () => {
     if (data && data.id) {
+      // 缂栬緫妯″紡锛氬~鍏呰〃鍗曟暟鎹�
       form.id = data.id
       form.name = data.name || ''
       form.phone = data.phone || ''
+      form.password = '' // 缂栬緫妯″紡涓嬫竻绌哄瘑鐮佸瓧娈碉紝鐢ㄦ埛闇�瑕佽緭鍏ユ柊瀵嗙爜鎴栫偣鍑婚噸缃瘑鐮�
+      isPasswordModified.value = false
       form.gender = data.gender
       form.description = data.description || ''
       form.specialtyIds = data.specialties?.map(tag => tag.id) || []
@@ -197,10 +250,7 @@
       
       // 鍔犺浇璇勫澶村儚/濯掍綋锛坱argetType=1 琛ㄧず璇勫锛�
       try {
-        console.log('=== 鍔犺浇璇勫濯掍綋 ===');
-        console.log('璇勫ID:', data.id);
         const medias = await getMediasByTarget(MediaTargetType.JUDGE_AVATAR, parseInt(data.id))
-        console.log('鑾峰彇鍒扮殑濯掍綋鍒楄〃:', medias);
         
         // 鍙彇绗竴涓浘鐗囦綔涓哄ご鍍忥紙璇勫鍙兘鏈変竴涓ご鍍忥級
         const firstImage = (medias || []).find((m: Media) => {
@@ -217,7 +267,6 @@
             url: firstImage.fullUrl
           };
           form.avatarUrl = firstImage.fullUrl;
-          console.log('璁剧疆褰撳墠澶村儚:', form.currentAvatar);
         } else {
           form.currentAvatar = null;
         }
@@ -235,16 +284,39 @@
   form.id = undefined
   form.name = ''
   form.phone = ''
+  form.password = ''
   form.gender = undefined
   form.description = ''
   form.specialtyIds = []
   form.avatarUrl = ''
   form.avatarMediaId = undefined
   form.currentAvatar = null
+  isPasswordModified.value = false
   
   nextTick(() => {
     formRef.value?.clearValidate()
   })
+}
+
+// 澶勭悊瀵嗙爜瀛楁鐒︾偣浜嬩欢
+const handlePasswordFocus = () => {
+  if (isEdit.value && form.password === '鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��') {
+    form.password = ''
+  }
+}
+
+// 澶勭悊瀵嗙爜杈撳叆浜嬩欢
+const handlePasswordInput = (value: string) => {
+  if (isEdit.value) {
+    isPasswordModified.value = value !== '' && value !== '鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��'
+  }
+}
+
+// 澶勭悊閲嶇疆瀵嗙爜
+const handleResetPassword = () => {
+  form.password = ''
+  isPasswordModified.value = true
+  ElMessage.success('瀵嗙爜宸叉竻绌猴紝璇疯緭鍏ユ柊瀵嗙爜')
 }
 
 // 澶勭悊澶村儚涓婁紶
@@ -253,14 +325,9 @@
     return; // 娌℃湁鏂板ご鍍忛渶瑕佷笂浼�
   }
   
-  console.log('=== 寮�濮嬩笂浼犲ご鍍忔枃浠� ===');
-  console.log('璇勫ID:', judgeId);
-  console.log('寰呬笂浼犵殑澶村儚:', form.currentAvatar.name);
-  
   try {
     // 涓婁紶鏂囦欢
     const uploadResult = await uploadFile(form.currentAvatar.file!);
-    console.log('涓婁紶缁撴灉:', uploadResult);
     
     if (uploadResult.success) {
       // 淇濆瓨濯掍綋淇℃伅鍒版暟鎹簱
@@ -278,7 +345,6 @@
       form.currentAvatar.uploaded = true;
       form.currentAvatar.url = uploadResult.fullUrl;
       form.avatarUrl = uploadResult.fullUrl;
-      console.log('澶村儚涓婁紶骞朵繚瀛樻垚鍔�:', form.currentAvatar.name);
     }
   } catch (error) {
     console.error('澶村儚涓婁紶澶辫触:', error);
@@ -299,9 +365,7 @@
     
     if (form.currentAvatar.isExisting && form.currentAvatar.id) {
       // 鍒犻櫎宸插瓨鍦ㄧ殑澶村儚鏂囦欢
-      console.log('鍒犻櫎宸插瓨鍦ㄧ殑澶村儚鏂囦欢:', form.currentAvatar.id);
       const result = await deleteMedia(form.currentAvatar.id);
-      console.log('鍒犻櫎缁撴灉:', result);
       
       if (result) {
         form.currentAvatar = null;
@@ -346,8 +410,12 @@
       majorIds: form.specialtyIds?.length ? form.specialtyIds.map(id => parseInt(id)) : undefined
     }
 
+    // 鍙湁鍦ㄦ柊寤烘垨瀵嗙爜琚慨鏀规椂鎵嶅寘鍚瘑鐮佸瓧娈�
+    if (!isEdit.value || isPasswordModified.value) {
+      submitData.password = form.password
+    }
+
     const savedJudge = await JudgeApi.saveJudge(submitData)
-    console.log('璇勫淇濆瓨鎴愬姛:', savedJudge);
     
     // 2. 涓婁紶鏂伴�夋嫨鐨勫ご鍍忔枃浠�
     if (savedJudge.id) {
@@ -415,7 +483,6 @@
     if (form.currentAvatar?.isExisting && form.currentAvatar.id) {
       try {
         await deleteMedia(form.currentAvatar.id);
-        console.log('宸插垹闄ゆ棫澶村儚');
       } catch (error) {
         console.warn('鍒犻櫎鏃уご鍍忓け璐ワ紝缁х画涓婁紶鏂板ご鍍�:', error);
       }
diff --git a/web/src/components/PlayerInfoCard.vue b/web/src/components/PlayerInfoCard.vue
index d3bd64d..88f82e4 100644
--- a/web/src/components/PlayerInfoCard.vue
+++ b/web/src/components/PlayerInfoCard.vue
@@ -26,6 +26,10 @@
     
     <!-- 璇︾粏淇℃伅 -->
     <div class="detail-info">
+      <div v-if="regionInfo" class="info-item">
+        <label>鎵�灞炲尯鍩燂細</label>
+        <p>{{ regionInfo.fullPath || regionInfo.name || '鏈缃�' }}</p>
+      </div>
       <div v-if="playerInfo.description" class="info-item">
         <label>涓汉绠�浠嬶細</label>
         <p>{{ playerInfo.description }}</p>
@@ -44,6 +48,11 @@
     type: Object,
     required: true,
     default: () => ({})
+  },
+  regionInfo: {
+    type: Object,
+    required: false,
+    default: () => null
   }
 })
 
diff --git a/web/src/views/activity-player/rating.vue b/web/src/views/activity-player/rating.vue
index d6aa53a..6c30f39 100644
--- a/web/src/views/activity-player/rating.vue
+++ b/web/src/views/activity-player/rating.vue
@@ -8,7 +8,7 @@
       <!-- 宸︿晶闈㈡澘锛氬鍛樹俊鎭拰鍙傝禌淇℃伅 -->
       <div class="left-panel">
         <!-- 瀛﹀憳淇℃伅鍗$墖 -->
-        <PlayerInfoCard :player-info="detail.playerInfo" />
+        <PlayerInfoCard :player-info="detail.playerInfo" :region-info="detail.regionInfo" />
         
         <!-- 鍙傝禌淇℃伅鍗$墖 -->
         <div class="submission-card">
diff --git a/web/src/views/employee/EmployeeForm.vue b/web/src/views/employee/EmployeeForm.vue
index d5151f8..263cd38 100644
--- a/web/src/views/employee/EmployeeForm.vue
+++ b/web/src/views/employee/EmployeeForm.vue
@@ -43,9 +43,11 @@
         <el-input 
           v-model="form.password" 
           type="password"
-          placeholder="鐣欑┖鍒欎笉淇敼瀵嗙爜"
+          placeholder="璇疯緭鍏ユ柊瀵嗙爜锛�6-20浣嶏級"
           maxlength="20"
           show-password
+          @focus="handlePasswordFocus"
+          @input="handlePasswordInput"
         />
       </el-form-item>
 
@@ -115,6 +117,9 @@
 const roles = ref<Role[]>([])
 const rolesLoading = ref(false)
 
+// 璺熻釜瀵嗙爜鏄惁琚慨鏀�
+const isPasswordModified = ref(false)
+
 // 璁$畻鏄惁涓虹紪杈戞ā寮�
 const isEdit = computed(() => !!props.employee?.id)
 
@@ -159,10 +164,7 @@
   password: [
     { 
       validator: (rule, value, callback) => {
-        if (isEdit.value && !value) {
-          // 缂栬緫妯″紡涓嬪瘑鐮佸彲浠ヤ负绌猴紙涓嶄慨鏀癸級
-          callback()
-        } else if (!value) {
+        if (!value) {
           callback(new Error('璇疯緭鍏ョ櫥褰曞瘑鐮�'))
         } else if (value.length < 6 || value.length > 20) {
           callback(new Error('瀵嗙爜闀垮害搴斿湪6-20涓瓧绗︿箣闂�'))
@@ -192,6 +194,7 @@
   form.password = ''
   form.roleId = ''
   form.description = ''
+  isPasswordModified.value = false
   formRef.value?.clearValidate()
 }
 
@@ -202,7 +205,8 @@
     form.id = employee.id
     form.name = employee.name
     form.phone = employee.phone
-    form.password = '' // 瀵嗙爜涓嶅洖鏄�
+    form.password = '鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��' // 缂栬緫鏃舵樉绀哄崰浣嶇瀵嗙爜
+    isPasswordModified.value = false // 閲嶇疆瀵嗙爜淇敼鐘舵��
     form.roleId = employee.roleId
     form.description = employee.description || ''
   } else {
@@ -215,6 +219,20 @@
 const handleClose = () => {
   visible.value = false
   resetForm()
+}
+
+// 澶勭悊瀵嗙爜瀛楁鐒︾偣浜嬩欢
+const handlePasswordFocus = () => {
+  if (isEdit.value && form.password === '鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��') {
+    form.password = ''
+  }
+}
+
+// 澶勭悊瀵嗙爜杈撳叆浜嬩欢
+const handlePasswordInput = (value: string) => {
+  if (isEdit.value) {
+    isPasswordModified.value = value !== '' && value !== '鈥⑩�⑩�⑩�⑩�⑩�⑩�⑩��'
+  }
 }
 
 // 鎻愪氦琛ㄥ崟
@@ -232,11 +250,15 @@
       id: form.id,
       name: form.name.trim(),
       phone: form.phone.trim(),
-      password: form.password || undefined, // 绌哄瘑鐮佷紶 undefined
       roleId: form.roleId,
       description: form.description?.trim() || undefined
     }
 
+    // 鍙湁鍦ㄦ柊寤烘垨瀵嗙爜琚慨鏀规椂鎵嶅寘鍚瘑鐮佸瓧娈�
+    if (!isEdit.value || isPasswordModified.value) {
+      submitData.password = form.password
+    }
+
     await employeeApi.saveEmployee(submitData)
     
     ElMessage.success(isEdit.value ? '鍛樺伐淇℃伅鏇存柊鎴愬姛' : '鍛樺伐鍒涘缓鎴愬姛')
diff --git a/web/src/views/judge/index.vue b/web/src/views/judge/index.vue
index 78b217a..0c100a0 100644
--- a/web/src/views/judge/index.vue
+++ b/web/src/views/judge/index.vue
@@ -148,9 +148,20 @@
   dialogVisible.value = true
 }
 
-const editJudge = (judge: Judge) => {
-  currentJudge.value = { ...judge }
-  dialogVisible.value = true
+const editJudge = async (judge: Judge) => {
+  try {
+    // 璋冪敤API鑾峰彇瀹屾暣鐨凧udge璇︽儏鏁版嵁
+    const judgeDetail = await JudgeApi.getJudge(judge.id)
+    if (judgeDetail) {
+      currentJudge.value = judgeDetail
+      dialogVisible.value = true
+    } else {
+      ElMessage.error('鑾峰彇璇勫璇︽儏澶辫触')
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇璇勫璇︽儏澶辫触')
+    console.error(error)
+  }
 }
 
 const deleteJudge = async (id: string) => {

--
Gitblit v1.8.0