- {{ levelInfo.exp }} / {{ levelInfo.nextExp }}
+
+
+ {{ levelInfo.exp }} / {{ levelInfo.nextExp }}
+
+
🎉目标 Lv.{{ levelInfo.currentLevel + 1 }}
目标 Lv.{{ levelInfo.currentLevel + 1 }}
@@ -584,6 +587,13 @@ export default {
background-color: var(--primary-color);
}
+.profile-level-info {
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+ align-items: center;
+}
+
.profile-level-exp,
.profile-level-target {
font-size: 12px;
diff --git a/src/main/java/com/openisle/model/ExperienceLog.java b/src/main/java/com/openisle/model/ExperienceLog.java
new file mode 100644
index 000000000..4edb53d55
--- /dev/null
+++ b/src/main/java/com/openisle/model/ExperienceLog.java
@@ -0,0 +1,37 @@
+package com.openisle.model;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.time.LocalDate;
+
+/** Daily experience gain counts for a user. */
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+@Table(name = "experience_logs",
+ uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "log_date"}))
+public class ExperienceLog {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY, optional = false)
+ @JoinColumn(name = "user_id")
+ private User user;
+
+ @Column(name = "log_date", nullable = false)
+ private LocalDate logDate;
+
+ @Column(name = "post_count", nullable = false)
+ private int postCount;
+
+ @Column(name = "comment_count", nullable = false)
+ private int commentCount;
+
+ @Column(name = "reaction_count", nullable = false)
+ private int reactionCount;
+}
diff --git a/src/main/java/com/openisle/repository/ExperienceLogRepository.java b/src/main/java/com/openisle/repository/ExperienceLogRepository.java
new file mode 100644
index 000000000..e50d354fe
--- /dev/null
+++ b/src/main/java/com/openisle/repository/ExperienceLogRepository.java
@@ -0,0 +1,12 @@
+package com.openisle.repository;
+
+import com.openisle.model.ExperienceLog;
+import com.openisle.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.time.LocalDate;
+import java.util.Optional;
+
+public interface ExperienceLogRepository extends JpaRepository {
+ Optional findByUserAndLogDate(User user, LocalDate logDate);
+}
diff --git a/src/main/java/com/openisle/service/LevelService.java b/src/main/java/com/openisle/service/LevelService.java
index 12e43d8c2..b6d84e213 100644
--- a/src/main/java/com/openisle/service/LevelService.java
+++ b/src/main/java/com/openisle/service/LevelService.java
@@ -1,27 +1,38 @@
package com.openisle.service;
import com.openisle.model.User;
-import com.openisle.repository.CommentRepository;
-import com.openisle.repository.PostRepository;
-import com.openisle.repository.ReactionRepository;
import com.openisle.repository.UserRepository;
+import com.openisle.repository.ExperienceLogRepository;
+import com.openisle.model.ExperienceLog;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
-import java.time.LocalDateTime;
@Service
@RequiredArgsConstructor
public class LevelService {
private final UserRepository userRepository;
- private final PostRepository postRepository;
- private final CommentRepository commentRepository;
- private final ReactionRepository reactionRepository;
+ // repositories for experience-related entities
+ private final ExperienceLogRepository experienceLogRepository;
private final UserVisitService userVisitService;
private static final int[] LEVEL_EXP = {100,200,300,600,1200,10000};
+ private ExperienceLog getTodayLog(User user) {
+ LocalDate today = LocalDate.now();
+ return experienceLogRepository.findByUserAndLogDate(user, today)
+ .orElseGet(() -> {
+ ExperienceLog log = new ExperienceLog();
+ log.setUser(user);
+ log.setLogDate(today);
+ log.setPostCount(0);
+ log.setCommentCount(0);
+ log.setReactionCount(0);
+ return experienceLogRepository.save(log);
+ });
+ }
+
private int addExperience(User user, int amount) {
user.setExperience(user.getExperience() + amount);
userRepository.save(user);
@@ -30,25 +41,28 @@ public class LevelService {
public int awardForPost(String username) {
User user = userRepository.findByUsername(username).orElseThrow();
- LocalDateTime start = LocalDate.now().atStartOfDay();
- long count = postRepository.countByAuthorAfter(username, start);
- if (count >= 1) return 0;
+ ExperienceLog log = getTodayLog(user);
+ if (log.getPostCount() > 1) return 0;
+ log.setPostCount(log.getPostCount() + 1);
+ experienceLogRepository.save(log);
return addExperience(user,30);
}
public int awardForComment(String username) {
User user = userRepository.findByUsername(username).orElseThrow();
- LocalDateTime start = LocalDate.now().atStartOfDay();
- long count = commentRepository.countByAuthorAfter(username, start);
- if (count >= 3) return 0;
+ ExperienceLog log = getTodayLog(user);
+ if (log.getCommentCount() > 3) return 0;
+ log.setCommentCount(log.getCommentCount() + 1);
+ experienceLogRepository.save(log);
return addExperience(user,10);
}
public int awardForReaction(String username) {
User user = userRepository.findByUsername(username).orElseThrow();
- LocalDateTime start = LocalDate.now().atStartOfDay();
- long count = reactionRepository.countByUserAfter(username, start);
- if (count >= 3) return 0;
+ ExperienceLog log = getTodayLog(user);
+ if (log.getReactionCount() > 3) return 0;
+ log.setReactionCount(log.getReactionCount() + 1);
+ experienceLogRepository.save(log);
return addExperience(user,5);
}