From dc0a9a09d89319600d27c991aea846f67ab903e1 Mon Sep 17 00:00:00 2001 From: mediabot-pt <295750538+mediabot-pt@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:55:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=84=9A=E6=9C=AC=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=AF=BC=E5=87=BA(JSON)=E5=92=8C=E5=AF=BC=E5=85=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3+=E6=B8=85=E7=90=86=E9=87=8D=E5=A4=8Dimport?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../par/api/controller/AdminController.java | 72 +++++++++++++++++-- 1 file changed, 68 insertions(+), 4 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 623c61e..088052f 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 @@ -1,9 +1,11 @@ package com.par.api.controller; +import com.par.common.util.HmacUtil; import com.par.core.dto.AccountDTO; import com.par.core.dto.ApiResponse; import com.par.core.dto.SiteConfigDTO; import com.par.core.entity.Account; +import com.par.core.entity.Psk; import com.par.core.entity.SiteConfig; import com.par.core.enums.ConfigStatus; import com.par.core.enums.TrustLevel; @@ -11,21 +13,21 @@ import com.par.core.mapper.AccountMapper; import com.par.core.mapper.ConfigReviewMapper; import com.par.core.mapper.SiteConfigMapper; import com.par.core.mapper.SiteMapper; -import com.par.core.entity.Psk; import com.par.core.service.AccountService; import com.par.core.service.ConfigService; import com.par.core.service.PskService; import com.par.core.storage.CachedStorageService; -import com.par.common.util.HmacUtil; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; -import java.util.List; -import java.util.Map; +import java.util.*; /** * 管理员控制器 @@ -400,6 +402,68 @@ public class AdminController { return ApiResponse.success(); } + // ==================== 脚本批量导入导出 ==================== + + /** + * 导出所有站点脚本 JSON:{siteId: scriptContent} + */ + @GetMapping("/scripts/export") + public ResponseEntity exportScripts(HttpServletRequest request) { + checkAdmin(request); + Map all = new LinkedHashMap<>(); + for (SiteConfig sc : siteConfigMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(SiteConfig::getDeleted, 0) + .eq(SiteConfig::getIsLatest, true) + .isNotNull(SiteConfig::getScriptStoragePath))) { + try { + String script = storageService.read(sc.getScriptStoragePath()); + if (script != null && !script.isBlank()) all.put(sc.getSiteId(), script); + } catch (Exception ignored) {} + } + byte[] json = new com.fasterxml.jackson.databind.ObjectMapper() + .writerWithDefaultPrettyPrinter().writeValueAsBytes(all); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=scripts-export.json") + .contentType(MediaType.APPLICATION_JSON) + .body(json); + } + + /** + * 导入脚本:{siteId: scriptContent},保存到本地存储 + */ + @PostMapping("/scripts/import") + public ApiResponse> importScripts( + @RequestBody Map payload, + HttpServletRequest request) { + checkAdmin(request); + int ok = 0, fail = 0; + for (Map.Entry e : payload.entrySet()) { + String siteId = e.getKey(); + String script = e.getValue(); + if (script == null || script.isBlank()) continue; + try { + int nextVersion = 1; + List approved = siteConfigMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(SiteConfig::getSiteId, siteId) + .eq(SiteConfig::getDeleted, 0) + .orderByDesc(SiteConfig::getVersion) + .last("limit 1")); + if (!approved.isEmpty()) { + try { nextVersion = Integer.parseInt(approved.get(0).getVersion()) + 1; } + catch (NumberFormatException ex) {} + } + configService.submitConfig(siteId, String.valueOf(nextVersion), script, null); + ok++; + } catch (Exception ex) { + log.error("导入脚本失败 siteId={}: {}", siteId, ex.getMessage()); + fail++; + } + } + return ApiResponse.success(Map.of("ok", ok, "fail", fail)); + } + private void checkAdmin(HttpServletRequest request) { TrustLevel level = (TrustLevel) request.getAttribute("trustLevel"); if (level == null || level != TrustLevel.ADMIN) {