Kaynağa Gözat

feat:修改恶意评价

刘云鑫 7 saat önce
ebeveyn
işleme
346e132e61

+ 9 - 3
alien-entity/src/main/java/shop/alien/mapper/StoreCommentAppealMapper.java

@@ -133,9 +133,15 @@ public interface StoreCommentAppealMapper extends BaseMapper<StoreCommentAppeal>
                           @Param("appealStatus") Integer appealStatus,
                           @Param("finalResult") String finalResult);
 
-    @Select("select count(1)\n" +
+    /**
+     * 查询用户近30天评价被申诉通过的记录,按通过时间倒序(最新在前)
+     */
+    @Select("select *\n" +
             "from store_comment_appeal sca\n" +
             "where sca.comment_id in (select id from common_rating cr where cr.user_id=#{userId} and cr.business_type = 1)\n" +
-            "and sca.created_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)")
-    int canRate(@Param("userId") Integer userId);
+            "and sca.appeal_status = 2\n" +
+            "and sca.delete_flag = 0\n" +
+            "and sca.created_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)\n" +
+            "order by sca.updated_time desc")
+    List<StoreCommentAppeal> canRate(@Param("userId") Integer userId);
 }

+ 4 - 4
alien-store/src/main/java/shop/alien/store/controller/StoreCommentAppealController.java

@@ -13,6 +13,7 @@ import shop.alien.entity.store.vo.StoreCommentAppealVo;
 import shop.alien.store.annotation.TrackEvent;
 import shop.alien.store.service.StoreCommentAppealService;
 
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -157,11 +158,10 @@ public class StoreCommentAppealController {
         return R.data(storeCommentAppealService.getAppealHistoryCountStatus(storeId));
     }
 
-    // TODO 查询当前用户前30天所有评价被申诉通过的次数,如果> 3 次返回true
-    @ApiOperation("是否可以评价")
+    @ApiOperation("是否可以评价(含最新申诉通过记录与10天冷却倒计时)")
     @GetMapping("/canRate")
-    public R<Boolean> canRate(Integer userId) {
-        log.info("StoreCommentAppealController.canRate");
+    public R<Map<String, Object>> canRate(Integer userId) {
+        log.info("StoreCommentAppealController.canRate?userId={}", userId);
         return R.data(storeCommentAppealService.canRate(userId));
     }
 }

+ 7 - 1
alien-store/src/main/java/shop/alien/store/service/StoreCommentAppealService.java

@@ -104,5 +104,11 @@ public interface StoreCommentAppealService extends IService<StoreCommentAppeal>
      */
     ResponseEntity<byte[]> exportToExcel();
 
-    Boolean canRate(Integer userId);
+    /**
+     * 判断用户是否可以评价,并返回最新申诉通过记录及10天冷却倒计时
+     *
+     * @param userId 用户ID
+     * @return canRate-是否可评价, passedCount-近30天申诉通过次数, latestPassedAppeal-最新通过记录, countdown-10天内剩余冷却(X天X小时)
+     */
+    Map<String, Object> canRate(Integer userId);
 }

+ 60 - 2
alien-store/src/main/java/shop/alien/store/service/impl/StoreCommentAppealServiceImpl.java

@@ -47,6 +47,9 @@ import shop.alien.util.common.constant.CommentSourceTypeEnum;
 
 import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -722,9 +725,64 @@ public class StoreCommentAppealServiceImpl extends ServiceImpl<StoreCommentAppea
         }
     }
 
+    /**
+     * 判断用户是否可以评价
+     * 规则:近30天申诉通过次数不超过3次,且距最近一次申诉通过未满10天不可评价
+     */
     @Override
-    public Boolean canRate(Integer userId) {
-        return storeCommentAppealMapper.canRate(userId) <= 3;
+    public Map<String, Object> canRate(Integer userId) {
+        log.info("StoreCommentAppealServiceImpl.canRate, userId={}", userId);
+        Map<String, Object> resultMap = new HashMap<>();
+        List<StoreCommentAppeal> passedAppealList = storeCommentAppealMapper.canRate(userId);
+
+        int passedCount = passedAppealList.size();
+        // 列表已按 updated_time 降序,第一条即为最新通过记录
+        StoreCommentAppeal latestPassedAppeal = passedAppealList.isEmpty() ? null : passedAppealList.get(0);
+        long countdownMillis = 0l;
+        if (passedCount > 3) {
+            countdownMillis = calculateAppealPassCooldownCountdown(latestPassedAppeal);
+        }
+
+        boolean canRate = passedCount <= 3 || countdownMillis <= 0;
+        resultMap.put("canRate", canRate);
+        resultMap.put("passedCount", passedCount);
+        resultMap.put("latestPassedAppeal", latestPassedAppeal);
+        resultMap.put("countdown", formatCountdownToDayHour(countdownMillis));
+
+        log.info("StoreCommentAppealServiceImpl.canRate result, userId={}, canRate={}, passedCount={}, countdown={}",
+                userId, canRate, passedCount, formatCountdownToDayHour(countdownMillis));
+        return resultMap;
+    }
+
+    /**
+     * 将毫秒倒计时转换为「X天X小时」格式
+     */
+    private String formatCountdownToDayHour(long countdownMillis) {
+        if (countdownMillis <= 0) {
+            return "0天0小时";
+        }
+        long totalHours = countdownMillis / (1000 * 60 * 60);
+        long days = totalHours / 24;
+        long hours = totalHours % 24;
+        return days + "天" + hours + "小时";
+    }
+
+    /**
+     * 计算申诉通过后的10天冷却倒计时(毫秒)
+     * 以申诉更新时间(通过时间)为起点,10天内返回剩余毫秒数,否则返回0
+     */
+    private long calculateAppealPassCooldownCountdown(StoreCommentAppeal latestPassedAppeal) {
+        if (latestPassedAppeal == null || latestPassedAppeal.getUpdatedTime() == null) {
+            return 0L;
+        }
+        LocalDateTime passTime = latestPassedAppeal.getUpdatedTime().toInstant()
+                .atZone(ZoneId.systemDefault()).toLocalDateTime();
+        LocalDateTime cooldownEndTime = passTime.plusDays(10);
+        LocalDateTime now = LocalDateTime.now();
+        if (now.isBefore(cooldownEndTime)) {
+            return Duration.between(now, cooldownEndTime).toMillis();
+        }
+        return 0L;
     }
 
     /**