package la.moony.friends.rest; import la.moony.friends.finders.FriendFinder; import la.moony.friends.vo.FriendPostVo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; import run.halo.app.plugin.ReactiveSettingFetcher; import run.halo.app.theme.TemplateNameResolver; import run.halo.app.theme.router.ModelConst; import run.halo.app.theme.router.PageUrlUtils; import run.halo.app.theme.router.UrlContextListResult; import java.util.HashMap; import java.util.Map; import static run.halo.app.theme.router.PageUrlUtils.totalPage; @Configuration @RequiredArgsConstructor @Slf4j public class FriendRouter { private final FriendFinder friendFinder; private final TemplateNameResolver templateNameResolver; private final ReactiveSettingFetcher settingFetcher; @Bean RouterFunction friendTemplateRoute() { return RouterFunctions.route().GET("/friends",this::handlerFunction) .GET("/friends/page/{page:\\d+}",this::handlerFunction) .GET("/friends/{friendPostName:\\S+}", this::friendPostDetail) .build(); } private Mono handlerFunction(ServerRequest request) { return templateNameResolver.resolveTemplateNameOrDefault(request.exchange(), "friends") .flatMap( templateName -> ServerResponse.ok().render(templateName, java.util.Map.of(ModelConst.TEMPLATE_ID, templateName, "friends", friendPostList(request), "authors", friendFinder.listAllAuthors().collectList(), "title",getFriendTitle()) )); } private Mono friendPostDetail(ServerRequest request) { String friendPostName = request.pathVariable("friendPostName"); return templateNameResolver.resolveTemplateNameOrDefault(request.exchange(), "friend-post") .flatMap(templateName -> ServerResponse.ok().render(templateName, Map.of(ModelConst.TEMPLATE_ID, templateName, "friend", friendFinder.getByName(friendPostName), "title", getFriendTitle()) )); } Mono getFriendTitle() { return this.settingFetcher.get("base").map( setting -> setting.get("title").asText("友链朋友圈")).defaultIfEmpty( "友链朋友圈"); } private Mono> friendPostList(ServerRequest request) { String path = request.path(); int pageNum = pageNumInPathVariable(request); String linkName = request.queryParam("linkName") .filter(StringUtils::isNotBlank) .orElse(null); // --- 新增:获取 author 参数 --- String author = request.queryParam("author") .filter(StringUtils::isNotBlank) .orElse(null); // --- 新增:构建查询参数字符串 --- StringBuilder queryString = new StringBuilder(); if (StringUtils.isNotBlank(linkName)) { queryString.append("linkName=").append(linkName); } if (StringUtils.isNotBlank(author)) { if (queryString.length() > 0) { queryString.append("&"); } queryString.append("author=").append(author); } final String finalQueryString = queryString.toString(); return this.settingFetcher.get("base") .map(item -> item.get("pageSize").asInt(10)) .defaultIfEmpty(10) .flatMap(pageSize -> { Map params = new HashMap<>(); params.put("page",pageNum); params.put("size",pageSize); if(StringUtils.isNotBlank(linkName)){ params.put("linkName",linkName); } // --- 新增:把 author 也放进 params --- if(StringUtils.isNotBlank(author)){ params.put("author",author); } return friendFinder.list(params) .map(list -> { // --- 修改:生成链接时带上查询参数 --- String baseNextUrl = PageUrlUtils.nextPageUrl(path, totalPage(list)); String basePrevUrl = PageUrlUtils.prevPageUrl(path); String nextUrl = appendQueryString(baseNextUrl, finalQueryString); String prevUrl = appendQueryString(basePrevUrl, finalQueryString); return new UrlContextListResult.Builder() .listResult(list) .nextUrl(nextUrl) .prevUrl(prevUrl) .build(); }); }); } // --- 新增:辅助方法,用于拼接查询参数 --- private String appendQueryString(String url, String queryString) { if (StringUtils.isBlank(queryString)) { return url; } if (url.contains("?")) { return url + "&" + queryString; } else { return url + "?" + queryString; } } private int pageNumInPathVariable(ServerRequest request) { String page = request.pathVariables().get("page"); return NumberUtils.toInt(page, 1); } }