|
@@ -47,6 +47,9 @@ import shop.alien.util.common.constant.CommentSourceTypeEnum;
|
|
|
|
|
|
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
+import java.time.Duration;
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
@@ -722,9 +725,64 @@ public class StoreCommentAppealServiceImpl extends ServiceImpl<StoreCommentAppea
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断用户是否可以评价
|
|
|
|
|
+ * 规则:近30天申诉通过次数不超过3次,且距最近一次申诉通过未满10天不可评价
|
|
|
|
|
+ */
|
|
|
@Override
|
|
@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;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|