feat: 脚本批量导出(JSON)和导入接口+清理重复import
This commit is contained in:
@@ -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<byte[]> exportScripts(HttpServletRequest request) {
|
||||
checkAdmin(request);
|
||||
Map<String, String> all = new LinkedHashMap<>();
|
||||
for (SiteConfig sc : siteConfigMapper.selectList(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SiteConfig>()
|
||||
.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<Map<String, Object>> importScripts(
|
||||
@RequestBody Map<String, String> payload,
|
||||
HttpServletRequest request) {
|
||||
checkAdmin(request);
|
||||
int ok = 0, fail = 0;
|
||||
for (Map.Entry<String, String> e : payload.entrySet()) {
|
||||
String siteId = e.getKey();
|
||||
String script = e.getValue();
|
||||
if (script == null || script.isBlank()) continue;
|
||||
try {
|
||||
int nextVersion = 1;
|
||||
List<SiteConfig> approved = siteConfigMapper.selectList(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SiteConfig>()
|
||||
.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) {
|
||||
|
||||
Reference in New Issue
Block a user