-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
实现首页数据缓存以及入参 limit 限制为最大50 #122
Changes from 3 commits
04ce6f2
75feca2
5e8d342
7b8d35e
f6c91e4
f9632cd
9f7dbd4
7d7b96f
5c0a408
ce2a250
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,53 @@ | ||
package plus.maa.backend.controller.request.copilot; | ||
|
||
import com.fasterxml.jackson.annotation.JsonAlias; | ||
import com.fasterxml.jackson.annotation.JsonIgnore; | ||
import jakarta.validation.constraints.Max; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
/** | ||
* @author LoMu | ||
* Date 2022-12-26 2:48 | ||
*/ | ||
@AllArgsConstructor | ||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class CopilotQueriesRequest { | ||
private int page; | ||
private int limit; | ||
private int page = 0; | ||
@Max(value = 50, message = "单页大小不得超过50") | ||
private int limit = 10; | ||
@JsonAlias("level_keyword") | ||
private String levelKeyword; | ||
private String operator; | ||
private String content; | ||
private String document; | ||
@JsonAlias("uploader_id") | ||
private String uploaderId; | ||
private boolean desc; | ||
private boolean desc = true; | ||
@JsonAlias("order_by") | ||
private String orderBy; | ||
private String language; | ||
} | ||
|
||
/* | ||
* 这里为了正确接收前端的下划线风格,手动写了三个 setter 用于起别名 | ||
* 因为 Get 请求传入的参数不是 JSON,所以没办法使用 Jackson 的注解直接实现别名 | ||
* 添加 @JsonAlias 和 @JsonIgnore 注解只是为了保障 Swagger 的文档正确显示 | ||
* (吐槽一下,同样是Get请求,怎么CommentsQueries是驼峰命名,到了CopilotQueries就成了下划线命名) | ||
*/ | ||
@JsonIgnore | ||
public void setLevel_keyword(String levelKeyword) { | ||
this.levelKeyword = levelKeyword; | ||
} | ||
|
||
@JsonIgnore | ||
public void setUploader_id(String uploaderId) { | ||
this.uploaderId = uploaderId; | ||
} | ||
|
||
@JsonIgnore | ||
public void setOrder_by(String orderBy) { | ||
this.orderBy = orderBy; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,7 @@ | |
import java.util.*; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
|
||
|
@@ -161,6 +162,11 @@ public void delete(String loginUserId, CopilotCUDRequest request) { | |
Assert.state(Objects.equals(copilot.getUploaderId(), loginUserId), "您无法修改不属于您的作业"); | ||
copilot.setDelete(true); | ||
copilotRepository.save(copilot); | ||
/* | ||
* 删除作业时,删除首页的所有缓存,因为此时首页内容可能发生变化 | ||
* 新增作业就不必,因为新作业显然不会那么快就登上热度榜和浏览量榜 | ||
*/ | ||
redisCache.removeCacheByPattern("home:*"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 新作业不需要的话可以先加个简单的判断 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 但是如果缓存时间够长,期间就可能出现用户看得到热度榜上的作业,但作业实际被作者删除了的情况,显然会给用户带来困扰。目前新的逻辑通过Redis的Set集合记录被缓存的作业ID,当删除的作业处于缓存中时,清空对应的缓存。 |
||
}); | ||
} | ||
|
||
|
@@ -200,12 +206,31 @@ public Optional<CopilotInfo> getCopilotById(String userIdOrIpAddress, Long id) { | |
|
||
/** | ||
* 分页查询。传入 userId 不为空时限制为用户所有的数据 | ||
* 会缓存默认状态下热度和访问量排序的结果 | ||
* | ||
* @param userId 获取已登录用户自己的作业数据 | ||
* @param request 模糊查询 | ||
* @return CopilotPageInfo | ||
*/ | ||
public CopilotPageInfo queriesCopilot(@Nullable String userId, CopilotQueriesRequest request) { | ||
// 只缓存默认状态下热度和访问量排序的结果,并且最多只缓存前三页 | ||
AtomicReference<String> cacheKey = new AtomicReference<>(); | ||
if (request.getPage() <= 3 && request.getDocument() == null && request.getLevelKeyword() == null && | ||
request.getUploaderId() == null && request.getOperator() == null) { | ||
Optional<CopilotPageInfo> cacheOptional = Optional.ofNullable(request.getOrderBy()) | ||
.filter(StringUtils::isNotBlank) | ||
.map(ob -> switch (ob) { | ||
case "hot", "views" -> { | ||
cacheKey.set(String.format("home:%s:%s", ob, request.hashCode())); | ||
yield redisCache.getCache(cacheKey.get(), CopilotPageInfo.class); | ||
} | ||
default -> null; | ||
}); | ||
if (cacheOptional.isPresent()) { | ||
return cacheOptional.get(); | ||
} | ||
} | ||
|
||
Sort.Order sortOrder = new Sort.Order( | ||
request.isDesc() ? Sort.Direction.DESC : Sort.Direction.ASC, | ||
Optional.ofNullable(request.getOrderBy()) | ||
|
@@ -278,13 +303,13 @@ public CopilotPageInfo queriesCopilot(@Nullable String userId, CopilotQueriesReq | |
} | ||
|
||
// 封装查询 | ||
if (andQueries.size() > 0) { | ||
if (!andQueries.isEmpty()) { | ||
criteriaObj.andOperator(andQueries); | ||
} | ||
if (norQueries.size() > 0) { | ||
if (!norQueries.isEmpty()) { | ||
criteriaObj.norOperator(norQueries); | ||
} | ||
if (orQueries.size() > 0) { | ||
if (!orQueries.isEmpty()) { | ||
criteriaObj.orOperator(orQueries); | ||
} | ||
queryObj.addCriteria(criteriaObj); | ||
|
@@ -317,11 +342,18 @@ public CopilotPageInfo queriesCopilot(@Nullable String userId, CopilotQueriesReq | |
boolean hasNext = count - (long) page * limit > 0; | ||
|
||
// 封装数据 | ||
return new CopilotPageInfo() | ||
CopilotPageInfo data = new CopilotPageInfo() | ||
.setTotal(count) | ||
.setHasNext(hasNext) | ||
.setData(infos) | ||
.setPage(pageNumber); | ||
|
||
// 决定是否缓存 | ||
if (cacheKey.get() != null) { | ||
// 缓存一小时 | ||
redisCache.setCache(cacheKey.get(), data, 3600); | ||
} | ||
return data; | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为后端是换语言重写开发的 评论区是现在java新开发的功能 其他则是继承之前C#的 (