diff --git a/backend/src/main/java/com/openisle/repository/PointHistoryRepository.java b/backend/src/main/java/com/openisle/repository/PointHistoryRepository.java index dabc1f805..2e3d6647e 100644 --- a/backend/src/main/java/com/openisle/repository/PointHistoryRepository.java +++ b/backend/src/main/java/com/openisle/repository/PointHistoryRepository.java @@ -10,6 +10,7 @@ import java.util.List; public interface PointHistoryRepository extends JpaRepository { List findByUserOrderByIdDesc(User user); + List findByUserOrderByIdAsc(User user); long countByUser(User user); List findByUserAndCreatedAtAfterOrderByCreatedAtDesc(User user, LocalDateTime createdAt); diff --git a/backend/src/main/java/com/openisle/service/PointService.java b/backend/src/main/java/com/openisle/service/PointService.java index 677fd0a0d..f1b1db081 100644 --- a/backend/src/main/java/com/openisle/service/PointService.java +++ b/backend/src/main/java/com/openisle/service/PointService.java @@ -225,17 +225,20 @@ public class PointService { */ public int recalculateUserPoints(User user) { // 获取用户所有的积分历史记录(由于@Where注解,已删除的记录会被自动过滤) - List histories = pointHistoryRepository.findByUserOrderByIdDesc(user); - + List histories = pointHistoryRepository.findByUserOrderByIdAsc(user); + int totalPoints = 0; for (PointHistory history : histories) { totalPoints += history.getAmount(); + // 重新计算每条历史记录的余额 + history.setBalance(totalPoints); } - - // 更新用户积分 + + // 批量更新历史记录及用户积分 + pointHistoryRepository.saveAll(histories); user.setPoint(totalPoints); userRepository.save(user); - + return totalPoints; } diff --git a/backend/src/test/java/com/openisle/service/PointServiceRecalculateUserPointsTest.java b/backend/src/test/java/com/openisle/service/PointServiceRecalculateUserPointsTest.java new file mode 100644 index 000000000..a06d4501e --- /dev/null +++ b/backend/src/test/java/com/openisle/service/PointServiceRecalculateUserPointsTest.java @@ -0,0 +1,67 @@ +package com.openisle.service; + +import com.openisle.model.PointHistory; +import com.openisle.model.PointHistoryType; +import com.openisle.model.Role; +import com.openisle.model.User; +import com.openisle.repository.PointHistoryRepository; +import com.openisle.repository.UserRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DataJpaTest +@Import(PointService.class) +class PointServiceRecalculateUserPointsTest { + + @Autowired + private PointService pointService; + + @Autowired + private UserRepository userRepository; + + @Autowired + private PointHistoryRepository pointHistoryRepository; + + @Test + void recalculatesBalanceAfterDeletion() { + User user = new User(); + user.setUsername("u"); + user.setEmail("u@example.com"); + user.setPassword("p"); + user.setRole(Role.USER); + userRepository.save(user); + + PointHistory h1 = new PointHistory(); + h1.setUser(user); + h1.setType(PointHistoryType.POST); + h1.setAmount(30); + h1.setBalance(30); + h1.setCreatedAt(LocalDateTime.now().minusMinutes(2)); + pointHistoryRepository.save(h1); + + PointHistory h2 = new PointHistory(); + h2.setUser(user); + h2.setType(PointHistoryType.COMMENT); + h2.setAmount(10); + h2.setBalance(40); + h2.setCreatedAt(LocalDateTime.now().minusMinutes(1)); + pointHistoryRepository.save(h2); + + user.setPoint(40); + userRepository.save(user); + + pointHistoryRepository.delete(h1); + + int total = pointService.recalculateUserPoints(user); + + assertEquals(10, total); + assertEquals(10, userRepository.findById(user.getId()).orElseThrow().getPoint()); + assertEquals(10, pointHistoryRepository.findById(h2.getId()).orElseThrow().getBalance()); + } +}