前端对应页面,从左至右依次为:评论数、收藏数、分享数、置顶/点赞数:
攻略浏览量
打开模块:trip-article-server,找到:StrategyController,修改其中的/detail
接口,添加增加浏览量的方法
StrategyController@GetMapping("/detail") public R<Strategy> detail(Long id) { strategyService.viewnumIncr(id); return R.ok(strategyService.getById(id)); }
|
在 StrategyService 接口中定义该方法
StrategyService
void viewnumIncr(Long id);
|
在 StrategyServiceImpl 类中实现该方法
这里需要在RedisService中添加hash的值增加方法
public void hashIncrement(KeyPrefix prefix, String hashKey, int increment, String... suffix) { redisTemplate.opsForHash().increment(prefix.fullKey(suffix), hashKey, 1); }
|
StrategyServiceImpl@Service public class StrategyServiceImpl extends ServiceImpl<StrategyMapper, Strategy> implements StrategyService {
private final RedisService redisService; public StrategyServiceImpl(RedisService redisService) { this.redisService = redisService; }
@Override public void viewnumIncr(Long id) { this.statDataIncr("viewnum", id); }
private void statDataIncr(String hashKey, Long sid) { redisService.hashIncrement(StrategyRedisKeyPrefix.STRATEGIES_STAT_DATA_MAP, hashKey, 1, sid + ""); } }
|
攻略点赞/置顶
对于一篇攻略文章来说,每个用户每天只能顶一次,且无法取消置顶,当时间过了23:59:59,用户可再次顶。
为此需要维护一个状态,用来判断用户当天是否顶过,同时维护过期时间,实现方案:
使用Redis 的 Map 来存储,以文章ID为 Map 的 key ,其中 hash key 为顶过攻略的用户的ID。
Redis Key:STRATEGIES:TOP:sid
,sid为该篇攻略的ID,hash key:用户的ID。
当用户顶该篇攻略时,刷新 map 的过期时间(当前时间到23:59:59的时间间隔)。
修改 RedisService 的 hashIncrement 方法
RedisService
public void hashIncrement(KeyPrefix prefix, String hashKey, int increment, String... suffix) { Long ret = redisTemplate.opsForHash().increment(prefix.fullKey(suffix), hashKey, 1); if (prefix.getTimeout() != null && prefix.getTimeout() > 0 && ret == 1) { expire(prefix.fullKey(suffix), prefix.getTimeout(), prefix.getUnit()); } }
|
注意,这里当一个用户第一次置顶时 ret 为1,可以设置过期时间, 但是每个用户第一次置顶时都会更新该篇攻略 map 的过期时间,无所谓,只要时间没到23:59:59,map 就不会过期,顶过的用户就不能再顶。
接口信息
Controller
打开模块:trip-article-server,找到:StrategyController,添加点赞/置顶方法
StrategyController@RequireLogin @GetMapping("/thumbnumIncr") public R<Boolean> thumbnumIncr(Long sid) { return R.ok(strategyService.thumbnumIncr(sid)); }
|
Service
找到:StrategyService 接口,定义点赞/置顶方法
StrategyService
Boolean thumbnumIncr(Long sid);
|
找到:StrategyServiceImpl 类,实现点赞/置顶方法
获取当前时间到23:59:59时间间隔的方法,
DateUtilspublic class DateUtils {
public static long getLastMillisSeconds() { LocalDateTime now = LocalDateTime.now(); LocalDateTime lastSeconds = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 23, 59, 59); return Duration.between(now, lastSeconds).toMillis(); }
public static Long getLastMillisSecondsOld() { Calendar instance = Calendar.getInstance(); instance.set(Calendar.HOUR_OF_DAY, 23); instance.set(Calendar.MINUTE, 59); instance.set(Calendar.SECOND, 29); long lastMillis = instance.getTimeInMillis(); return lastMillis - System.currentTimeMillis();
} }
|
StrategyServiceImpl@Service public class StrategyServiceImpl extends ServiceImpl<StrategyMapper, Strategy> implements StrategyService {
private final RedisService redisService; public StrategyServiceImpl(RedisService redisService) { this.redisService = redisService; }
@Override public Boolean thumbnumIncr(Long sid) { LoginUser loginUser = AuthenticationUtil.getLoginUser(); StrategyRedisKeyPrefix keyPrefix = StrategyRedisKeyPrefix.STRATEGIES_TOP_MAP; String key = keyPrefix.fullKey(sid + ""); String hashKey = loginUser.getId() + ""; Integer count = redisService.getCacheMapValue(key, hashKey); if (count != null && count > 0) { return false; } keyPrefix.setTimeout(DateUtils.getLastMillisSeconds()); keyPrefix.setUnit(TimeUnit.MILLISECONDS); redisService.hashIncrement(keyPrefix, hashKey, 1, sid + ""); this.statDataIncr("thumbsupnum", sid); return true; }
private void statDataIncr(String hashKey, Long sid) { redisService.hashIncrement(StrategyRedisKeyPrefix.STRATEGIES_STAT_DATA_MAP, hashKey, 1, sid + ""); } }
|
攻略收藏量
数据库
攻略的收藏属于用户模块的功能,用户可以查看自己收藏的攻略,因此在trip-user
数据库中增加表user_favor_strategies
user_favor_strategiesCREATE TABLE `user_favor_strategies` ( `user_id` bigint NOT NULL, `strategy_id` bigint NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
Redis Key
找到模块:trip-user-api 中的com.swx.user.redis.key
包下的 UserRedisKeyPrefix,添加一个 key
public static final UserRedisKeyPrefix STRATEGIES_STAT_DATA_MAP = new UserRedisKeyPrefix("STRATEGIES:STAT:DATA");
|
接口信息
获取用户收藏的攻略
添加或者删除攻略收藏
Controller
打开模块:trip-user-server,找到:UserInfoController,添加收藏方法
UserInfoController@GetMapping("/favor/strategies") R<List<Long>> getFavorStrategyIdList(@RequestParam Long userId) { return R.ok(userInfoService.getFavorStrategyIdList(userId)); }
@RequireLogin @PostMapping("/favor/strategies") public R<Boolean> favoriteStrategy(Long sid) { return R.ok(userInfoService.favoriteStrategy(sid)); }
|
Service
找到:StrategyService 接口,定义获取和添加收藏攻略方法
StrategyService
List<Long> getFavorStrategyIdList(Long userId);
Boolean favoriteStrategy(Long sid);
|
找到:StrategyServiceImpl 类,实现获取和添加收藏攻略方法
UserServiceImpl@Service public class UserServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
private final RedisService redisService;
public UserServiceImpl(RedisService redisService, TokenService tokenService) { this.redisService = redisService; }
@Override public List<Long> getFavorStrategyIdList(Long userId) { return getBaseMapper().getFavorStrategyIdList(userId); }
@Override public Boolean favoriteStrategy(Long sid) { LoginUser loginUser = AuthenticationUtil.getLoginUser(); List<Long> ids = this.getFavorStrategyIdList(loginUser.getId()); if (ids.contains(sid)) { redisService.hashIncrement(UserRedisKeyPrefix.STRATEGIES_STAT_DATA_MAP, "favornum", -1, sid + ""); return getBaseMapper().deleteFavorStrategy(loginUser.getId(), sid); } redisService.hashIncrement(UserRedisKeyPrefix.STRATEGIES_STAT_DATA_MAP, "favornum", 1, sid + ""); return getBaseMapper().insertFavorStrategy(loginUser.getId(), sid); } }
|
攻略评论数量
Controller
打开模块:trip-comment-server,找到:StrategyCommentController,修改/save
方法,添加增加评论数量方法
StrategyCommentController@RequireLogin @PostMapping("/save") public R<?> saveComment(Long strategyId, String strategyTitle) { strategyCommentService.save(strategyId, strategyTitle); strategyCommentService.replyNumIncr(strategyId); return R.ok(); }
|
Service
找到:StrategyCommentService 接口,定义增加评论数量方法
StrategyCommentService
void replyNumIncr(Long strategyId);
|
找到:StrategyCommentServiceImpl 类,实现增加评论数量方法
StrategyCommentServiceImpl@Slf4j @Service public class StrategyCommentServiceImpl implements StrategyCommentService {
private final RedisService redisService;
public StrategyCommentServiceImpl(RedisService redisService) { this.redisService = redisService; }
@Override public void replyNumIncr(Long strategyId) { redisService.hashIncrement(CommentRedisKeyPrefix.STRATEGIES_STAT_DATA_MAP, "replynum", 1, strategyId + ""); } }
|