From b7adbfd18a0ae96627dbcd920acbf34fcddcbb4e Mon Sep 17 00:00:00 2001 From: mediabot-pt <295750538+mediabot-pt@users.noreply.github.com> Date: Sun, 5 Jul 2026 23:54:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AB=99=E7=82=B9=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=8A=A0=E5=8F=91=E5=B8=83=E6=8C=89=E9=92=AE=E7=94=9F=E6=88=90?= =?UTF-8?q?manifest=E4=B8=8A=E4=BC=A0=E4=B8=83=E7=89=9B=E4=BA=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../par/api/controller/AdminController.java | 52 +++++++++++++++++++ web/src/views/Sites.vue | 14 ++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/par-api/src/main/java/com/par/api/controller/AdminController.java b/par-api/src/main/java/com/par/api/controller/AdminController.java index ec6ec8c..da93b5a 100644 --- a/par-api/src/main/java/com/par/api/controller/AdminController.java +++ b/par-api/src/main/java/com/par/api/controller/AdminController.java @@ -337,6 +337,21 @@ public class AdminController { // ===================== 站点审核 ===================== + /** 发布站点配置到七牛云(生成 manifest/manifest.json) */ + @PostMapping("/sites/publish") + public ApiResponse> publishManifest(HttpServletRequest request) { + checkAdmin(request); + try { + var manifest = buildManifest(); + String json = new com.fasterxml.jackson.databind.ObjectMapper() + .writerWithDefaultPrettyPrinter().writeValueAsString(manifest); + storageService.store("manifest/manifest.json", json); + log.info("Manifest published: {} sites", ((List)manifest.get("sites")).size()); + return ApiResponse.success(Map.of("version", manifest.get("version"), + "sites", ((List)manifest.get("sites")).size())); + } catch (Exception e) { return ApiResponse.error(500, "发布失败: " + e.getMessage()); } + } + @GetMapping("/sites") public ApiResponse> listAllSites(HttpServletRequest request) { checkAdmin(request); @@ -505,6 +520,43 @@ public class AdminController { catch (Exception e) { return java.util.List.of(); } } + // buildManifest = 复用 ManifestController 逻辑 + @SuppressWarnings("unchecked") + private Map buildManifest() { + var sites = siteService.listAllSites(); + List> list = new ArrayList<>(); + int total = 0; + for (var site : sites) { + var dto = siteService.toDTO(site); + Map e = new LinkedHashMap<>(); + e.put("siteId", site.getSiteId()); + e.put("names", dto.getNames()); + e.put("urls", dto.getUrls()); + e.put("tags", dto.getTags()); + e.put("description", dto.getDescription()); + e.put("siteType", site.getSiteType() != null ? site.getSiteType().getValue() : null); + e.put("status", site.getStatus() != null ? site.getStatus().getValue() : null); + e.put("version", site.getVersion() != null ? site.getVersion() : 1); + var latest = siteConfigMapper.selectLatestBySiteId(site.getSiteId()); + e.put("latestVersion", latest != null ? latest.getVersion() : null); + e.put("hasScript", latest != null && latest.getScriptStoragePath() != null && !latest.getScriptStoragePath().isBlank()); + e.put("hasPages", sitePagesMapper.selectCount( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(com.par.core.entity.SitePages::getSiteId, site.getSiteId()) + .eq(com.par.core.entity.SitePages::getDeleted, 0)) > 0); + e.put("hasRisk", riskRuleMapper.selectCount( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(com.par.core.entity.RiskRule::getSiteType, site.getSiteType().getValue()) + .eq(com.par.core.entity.RiskRule::getDeleted, 0)) > 0); + total += (site.getVersion() != null ? site.getVersion() : 1); + list.add(e); + } + Map m = new LinkedHashMap<>(); + m.put("version", total); + m.put("sites", list); + return m; + } + private void checkAdmin(HttpServletRequest request) { TrustLevel level = (TrustLevel) request.getAttribute("trustLevel"); if (level == null || level != TrustLevel.ADMIN) { diff --git a/web/src/views/Sites.vue b/web/src/views/Sites.vue index b3be8c2..aaf6ee0 100644 --- a/web/src/views/Sites.vue +++ b/web/src/views/Sites.vue @@ -55,8 +55,9 @@

站点编辑: {{ editSiteId }}

- 保存 返回列表 + 保存 + 发布
@@ -106,7 +107,7 @@