添加等级机制,每小时依据用户上传量下载量和积分进行更新

Change-Id: I152375a20103c2693ce8a5d64a130a1c1f598abf
diff --git a/src/main/java/com/pt/BackendApplication.java b/src/main/java/com/pt/BackendApplication.java
index 28bc5cb..5f21e15 100644
--- a/src/main/java/com/pt/BackendApplication.java
+++ b/src/main/java/com/pt/BackendApplication.java
@@ -2,8 +2,10 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
+@EnableScheduling
 public class BackendApplication {
 
     public static void main(String[] args) {
diff --git a/src/main/java/com/pt/entity/User.java b/src/main/java/com/pt/entity/User.java
index 9caab3e..aef2cd3 100644
--- a/src/main/java/com/pt/entity/User.java
+++ b/src/main/java/com/pt/entity/User.java
@@ -14,6 +14,8 @@
     private String email;
     private int level;
     private int points;
+    private long uploaded;
+    private long downloaded;
 
     public User() {
     }
@@ -61,6 +63,22 @@
         this.points = points;
     }
 
+    public long getUploaded() {
+        return uploaded;
+    }
+
+    public void setUploaded(long uploaded) {
+        this.uploaded = uploaded;
+    }
+
+    public long getDownloaded() {
+        return downloaded;
+    }
+
+    public void setDownloaded(long downloaded) {
+        this.downloaded = downloaded;
+    }
+
     @Override
     public String toString() {
         return "{" +
@@ -70,6 +88,8 @@
                 ",\nemail:'" + email + '\'' +
                 ",\nlevel:" + level +
                 ",\npoints:" + points +
+                ",\nuploaded:" + uploaded +
+                ",\ndownloaded:" + downloaded +
                 '}';
     }
 }
diff --git a/src/main/java/com/pt/scheduler/UserLevelUpdateScheduler.java b/src/main/java/com/pt/scheduler/UserLevelUpdateScheduler.java
new file mode 100644
index 0000000..64aa6ca
--- /dev/null
+++ b/src/main/java/com/pt/scheduler/UserLevelUpdateScheduler.java
@@ -0,0 +1,36 @@
+package com.pt.scheduler;
+
+import com.pt.service.UserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 定时任务,用于定期更新用户的等级。
+ */
+@Component
+public class UserLevelUpdateScheduler {
+
+    private static final Logger logger = LoggerFactory.getLogger(UserLevelUpdateScheduler.class);
+
+    @Autowired
+    private UserService userService;
+
+    /**
+     * 使用CRON表达式定义任务执行时间。
+     * "0 0 * * * ?" 表示在每个小时的整点(例如 01:00, 02:00)执行。
+     * 该任务会调用服务来更新所有用户的等级。
+     */
+    @Scheduled(cron = "0 0 * * * ?")
+    public void scheduleUserLevelUpdate() {
+        logger.info("开始执行定时任务:更新所有用户等级...");
+        try {
+            userService.updateAllUsersLevel();
+            logger.info("定时任务完成:所有用户等级已根据最新数据检查并更新。");
+        } catch (Exception e) {
+            logger.error("执行用户等级更新定时任务时发生错误", e);
+        }
+    }
+} 
\ No newline at end of file
diff --git a/src/main/java/com/pt/service/UserService.java b/src/main/java/com/pt/service/UserService.java
index bdffeea..6c0a56f 100644
--- a/src/main/java/com/pt/service/UserService.java
+++ b/src/main/java/com/pt/service/UserService.java
@@ -48,4 +48,66 @@
     public List<User> listAll() {
         return userRepository.findAll();
     }
+
+    /**
+     * 根据用户的统计数据(上传量、下载量、积分)更新其等级。
+     * 该方法包含等级提升的规则,且只升不降。
+     * @param userId 要更新等级的用户的ID
+     */
+    public void updateUserLevel(String userId) {
+        User user = userRepository.findById(userId).orElse(null);
+        if (user == null) {
+            // 在实际应用中,这里可能需要记录日志或抛出异常
+            return;
+        }
+
+        long uploaded = user.getUploaded();
+        long downloaded = user.getDownloaded();
+        int points = user.getPoints();
+
+        // 定义数据大小常量
+        final long GB = 1024L * 1024L * 1024L;
+        final long TB = 1024L * GB;
+
+        // 计算分享率。如果下载量为0,分享率视为无限大(只要有上传)
+        double shareRatio = (downloaded == 0 && uploaded > 0) ? Double.MAX_VALUE :
+                            (downloaded == 0 && uploaded == 0) ? 0 : (double) uploaded / downloaded;
+
+        int newLevel = 1; // 默认为1级
+
+        // 等级规则(从高到低判断)
+        // 规则5: 大佬级
+        if (uploaded > 5 * TB && shareRatio > 2.0 && points > 10000) {
+            newLevel = 5;
+        }
+        // 规则4: 专家级
+        else if (uploaded > 1 * TB && shareRatio > 1.5 && points > 2000) {
+            newLevel = 4;
+        }
+        // 规则3: 熟练级
+        else if (uploaded > 200 * GB && shareRatio > 1.0 && points > 500) {
+            newLevel = 3;
+        }
+        // 规则2: 入门级 (获得发布权限)
+        else if (uploaded > 50 * GB && shareRatio > 0.5 && points > 100) {
+            newLevel = 2;
+        }
+
+        // 如果计算出的新等级高于当前等级,则更新用户等级
+        if (newLevel > user.getLevel()) {
+            user.setLevel(newLevel);
+            userRepository.save(user);
+        }
+    }
+
+    /**
+     * 批量更新所有用户的等级。
+     * 适合用于定时任务,定期刷新所有用户的等级。
+     */
+    public void updateAllUsersLevel() {
+        List<User> allUsers = userRepository.findAll();
+        for (User user : allUsers) {
+            updateUserLevel(user.getUid());
+        }
+    }
 }