|
@@ -9,6 +9,7 @@ import com.fs.activity.domain.AccWork;
|
|
|
import com.fs.activity.mapper.AccVoteRecordMapper;
|
|
import com.fs.activity.mapper.AccVoteRecordMapper;
|
|
|
import com.fs.activity.param.AccVoteRecordRequest;
|
|
import com.fs.activity.param.AccVoteRecordRequest;
|
|
|
import com.fs.activity.param.AccVoteRecordResponse;
|
|
import com.fs.activity.param.AccVoteRecordResponse;
|
|
|
|
|
+import com.fs.activity.param.AccWorkRequest;
|
|
|
import com.fs.activity.service.AccActivityService;
|
|
import com.fs.activity.service.AccActivityService;
|
|
|
import com.fs.activity.service.AccWorkService;
|
|
import com.fs.activity.service.AccWorkService;
|
|
|
import com.fs.activity.mapper.AccWorkMapper;
|
|
import com.fs.activity.mapper.AccWorkMapper;
|
|
@@ -17,6 +18,8 @@ import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.redis.RedisCache;
|
|
import com.fs.common.core.redis.RedisCache;
|
|
|
import com.fs.common.exception.ServiceException;
|
|
import com.fs.common.exception.ServiceException;
|
|
|
import com.fs.common.exception.base.BusinessException;
|
|
import com.fs.common.exception.base.BusinessException;
|
|
|
|
|
+import com.github.pagehelper.PageHelper;
|
|
|
|
|
+import com.github.pagehelper.PageInfo;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.redisson.api.RLock;
|
|
import org.redisson.api.RLock;
|
|
|
import org.redisson.api.RedissonClient;
|
|
import org.redisson.api.RedissonClient;
|
|
@@ -40,13 +43,17 @@ import java.util.concurrent.TimeUnit;
|
|
|
public class AccWorkServiceImpl extends ServiceImpl<AccWorkMapper, AccWork>
|
|
public class AccWorkServiceImpl extends ServiceImpl<AccWorkMapper, AccWork>
|
|
|
implements AccWorkService{
|
|
implements AccWorkService{
|
|
|
|
|
|
|
|
|
|
+ // 今日投票数
|
|
|
private static final String DAILY_VOTE_LIMIT = "vote:daily:limit";
|
|
private static final String DAILY_VOTE_LIMIT = "vote:daily:limit";
|
|
|
|
|
|
|
|
|
|
+ // 锁
|
|
|
private static final String VOTE_LOCK_KEY = "vote:lock:";
|
|
private static final String VOTE_LOCK_KEY = "vote:lock:";
|
|
|
|
|
|
|
|
|
|
+ // 作品数量
|
|
|
private static final String VOTE_COUNT_KEY = "vote:count:";
|
|
private static final String VOTE_COUNT_KEY = "vote:count:";
|
|
|
|
|
|
|
|
- private static final String VOTE_RANKING_KEY = "vote:ranking";
|
|
|
|
|
|
|
+ // 今日是否已经投给该作品
|
|
|
|
|
+ private static final String VOTE_WORK_KEY = "vote:work:";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -206,11 +213,10 @@ public class AccWorkServiceImpl extends ServiceImpl<AccWorkMapper, AccWork>
|
|
|
lockAcquired = lock.tryLock(3, 10, TimeUnit.SECONDS);
|
|
lockAcquired = lock.tryLock(3, 10, TimeUnit.SECONDS);
|
|
|
if (lockAcquired) {
|
|
if (lockAcquired) {
|
|
|
|
|
|
|
|
- // 5. 检查今日是否已给该作品投票
|
|
|
|
|
- if (accVoteRecordMapper.selectCount(new LambdaQueryWrapper<AccVoteRecord>()
|
|
|
|
|
- .eq(AccVoteRecord::getUserId, userId)
|
|
|
|
|
- .eq(AccVoteRecord::getWorkId, workId)
|
|
|
|
|
- .eq(AccVoteRecord::getVoteDate, today)) > 0) {
|
|
|
|
|
|
|
+ // 5. 检查今日是否已给该作品投票 (从 Redis 检查)
|
|
|
|
|
+ String userVoteKey = VOTE_WORK_KEY + userId + ":" + workId + ":" + todayStr;
|
|
|
|
|
+ Boolean hasVoted = redisTemplate.hasKey(userVoteKey);
|
|
|
|
|
+ if (hasVoted != null && hasVoted) {
|
|
|
throw new ServiceException("今日已给该作品投票");
|
|
throw new ServiceException("今日已给该作品投票");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -224,6 +230,9 @@ public class AccWorkServiceImpl extends ServiceImpl<AccWorkMapper, AccWork>
|
|
|
throw new ServiceException("投票失败");
|
|
throw new ServiceException("投票失败");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 7. 标记用户今日已投票到 Redis
|
|
|
|
|
+ redisTemplate.opsForValue().set(userVoteKey, true, 2, TimeUnit.DAYS);
|
|
|
|
|
+
|
|
|
// 8. 更新Redis缓存
|
|
// 8. 更新Redis缓存
|
|
|
// 8.1 更新作品票数缓存
|
|
// 8.1 更新作品票数缓存
|
|
|
String countKey = VOTE_COUNT_KEY + workId;
|
|
String countKey = VOTE_COUNT_KEY + workId;
|
|
@@ -286,6 +295,32 @@ public class AccWorkServiceImpl extends ServiceImpl<AccWorkMapper, AccWork>
|
|
|
return accVoteRecordMapper.selectCount(new LambdaQueryWrapper<AccVoteRecord>()
|
|
return accVoteRecordMapper.selectCount(new LambdaQueryWrapper<AccVoteRecord>()
|
|
|
.eq(AccVoteRecord::getUserId, userId).eq(AccVoteRecord::getVoteDate, todayStr));
|
|
.eq(AccVoteRecord::getUserId, userId).eq(AccVoteRecord::getVoteDate, todayStr));
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @Description: 作品查询
|
|
|
|
|
+ * @Param:
|
|
|
|
|
+ * @Return:
|
|
|
|
|
+ * @Author xgb
|
|
|
|
|
+ * @Date 2026/3/10 16:03
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R getWorkList(AccWorkRequest request) {
|
|
|
|
|
+
|
|
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
|
|
+ String todayStr = today.format(DateTimeFormatter.ISO_DATE);
|
|
|
|
|
+
|
|
|
|
|
+ PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
|
|
|
|
+ List<AccWork> accWorks=baseMapper.selectListForApp(request);
|
|
|
|
|
+ for (AccWork work : accWorks) {
|
|
|
|
|
+ String userVoteKey = VOTE_WORK_KEY + request.getUserId() + ":" + work.getId() + ":" + todayStr;
|
|
|
|
|
+ Boolean hasVoted = redisTemplate.hasKey(userVoteKey);
|
|
|
|
|
+ // 假设 AccWork 有 isVoted 字段
|
|
|
|
|
+ work.setIsVoted(hasVoted != null && hasVoted);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return R.ok().put("data",new PageInfo<>(accWorks));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|