151 lines
6.7 KiB
Java
151 lines
6.7 KiB
Java
package com.par.api.controller;
|
||
|
||
import com.par.core.adapter.GroovyScriptEngine;
|
||
import com.par.core.dto.ApiResponse;
|
||
import com.par.core.entity.SiteConfig;
|
||
import com.par.core.entity.Site;
|
||
import com.par.core.mapper.SiteMapper;
|
||
import com.par.core.service.ConfigService;
|
||
import com.par.core.storage.CachedStorageService;
|
||
import jakarta.servlet.http.HttpServletRequest;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.http.HttpHeaders;
|
||
import org.springframework.http.ResponseEntity;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* Groovy 脚本接口(mediabot 使用)
|
||
*/
|
||
@Slf4j
|
||
@RestController
|
||
@RequiredArgsConstructor
|
||
public class ScriptController {
|
||
|
||
private final ConfigService configService;
|
||
private final CachedStorageService storageService;
|
||
private final SiteMapper siteMapper;
|
||
private final com.par.core.mapper.SiteConfigMapper siteConfigMapper;
|
||
|
||
/** 下载最新 Groovy 脚本 */
|
||
@GetMapping("/api/v1/scripts/{siteId}")
|
||
public ResponseEntity<String> downloadScript(@PathVariable String siteId) {
|
||
SiteConfig latest = configService.getLatestConfig(siteId);
|
||
// 优先自定义脚本
|
||
if (latest != null && latest.getScriptStoragePath() != null
|
||
&& !latest.getScriptStoragePath().isBlank()) {
|
||
try {
|
||
String script = storageService.read(latest.getScriptStoragePath());
|
||
if (script != null && !script.isBlank()) {
|
||
return ResponseEntity.ok()
|
||
.header(HttpHeaders.CONTENT_TYPE, "text/plain;charset=UTF-8")
|
||
.body(script);
|
||
}
|
||
} catch (Exception ignored) {}
|
||
}
|
||
// 回退到默认模板
|
||
var site = siteMapper.selectBySiteId(siteId);
|
||
String siteType = site != null && site.getSiteType() != null
|
||
? site.getSiteType().getValue() : null;
|
||
String defaultScript = GroovyScriptEngine.loadDefaultByType(siteType);
|
||
if (defaultScript != null) {
|
||
return ResponseEntity.ok()
|
||
.header(HttpHeaders.CONTENT_TYPE, "text/plain;charset=UTF-8")
|
||
.body(defaultScript);
|
||
}
|
||
return ResponseEntity.notFound().build();
|
||
}
|
||
|
||
/** 删除站点自定义脚本(回退到默认模板) */
|
||
@DeleteMapping("/api/v1/admin/configs/{siteId}/script")
|
||
public ApiResponse<Void> deleteScript(@PathVariable String siteId, HttpServletRequest request) {
|
||
checkAdmin(request);
|
||
SiteConfig latest = configService.getLatestConfig(siteId);
|
||
if (latest == null) return ApiResponse.success();
|
||
latest.setScriptStoragePath(null);
|
||
latest.setIsLatest(false);
|
||
siteConfigMapper.updateById(latest);
|
||
log.info("Custom script deleted for siteId={}, fallback to default", siteId);
|
||
return ApiResponse.success();
|
||
}
|
||
|
||
/** 获取脚本版本(自定义脚本优先,否则返回默认模板版本) */
|
||
@GetMapping("/api/v1/scripts/{siteId}/version")
|
||
public ApiResponse<Map<String, String>> getVersion(@PathVariable String siteId) {
|
||
SiteConfig latest = configService.getLatestConfig(siteId);
|
||
if (latest != null && latest.getScriptStoragePath() != null && !latest.getScriptStoragePath().isBlank()) {
|
||
return ApiResponse.success(Map.of("version", latest.getVersion(), "source", "custom"));
|
||
}
|
||
// 回退到默认模板版本
|
||
var site = siteMapper.selectBySiteId(siteId);
|
||
String siteType = site != null && site.getSiteType() != null ? site.getSiteType().getValue() : null;
|
||
int defVer = GroovyScriptEngine.getDefaultVersion(siteType);
|
||
return ApiResponse.success(Map.of("version", String.valueOf(defVer), "source", "default"));
|
||
}
|
||
|
||
/** 获取站点类型默认脚本(管理员) */
|
||
@GetMapping("/api/v1/admin/scripts/default/{siteType}")
|
||
public ApiResponse<Map<String, String>> getDefaultScript(@PathVariable String siteType, HttpServletRequest request) {
|
||
checkAdmin(request);
|
||
String script = GroovyScriptEngine.loadDefaultByType(siteType);
|
||
int version = GroovyScriptEngine.getDefaultVersion(siteType);
|
||
return ApiResponse.success(Map.of("siteType", siteType, "script", script != null ? script : "", "version", String.valueOf(version)));
|
||
}
|
||
|
||
/** 保存站点类型默认脚本到本地 */
|
||
@PutMapping("/api/v1/admin/scripts/default/{siteType}/save")
|
||
public ApiResponse<Void> saveDefaultScript(
|
||
@PathVariable String siteType,
|
||
@RequestBody Map<String, String> payload,
|
||
HttpServletRequest request) {
|
||
checkAdmin(request);
|
||
String script = payload.get("script");
|
||
if (script == null || script.isBlank()) return ApiResponse.error(400, "script is required");
|
||
GroovyScriptEngine.saveDefaultLocal(siteType, script);
|
||
return ApiResponse.success();
|
||
}
|
||
|
||
/** 上传站点类型默认脚本到七牛云 */
|
||
@PutMapping("/api/v1/admin/scripts/default/{siteType}/upload")
|
||
public ApiResponse<Void> uploadDefaultScript(
|
||
@PathVariable String siteType,
|
||
@RequestBody Map<String, String> payload,
|
||
HttpServletRequest request) {
|
||
checkAdmin(request);
|
||
String script = payload.get("script");
|
||
if (script == null || script.isBlank()) return ApiResponse.error(400, "script is required");
|
||
GroovyScriptEngine.saveDefaultScript(siteType, script);
|
||
return ApiResponse.success();
|
||
}
|
||
|
||
private void checkAdmin(HttpServletRequest request) {
|
||
var level = request.getAttribute("trustLevel");
|
||
if (level == null || !"ADMIN".equals(level.toString())) {
|
||
throw new IllegalArgumentException("Admin permission required");
|
||
}
|
||
}
|
||
|
||
/** 上传 Groovy 脚本(PSK 签名认证) */
|
||
@PutMapping("/api/v1/scripts/{siteId}")
|
||
public ApiResponse<?> uploadScript(
|
||
@PathVariable String siteId,
|
||
@RequestBody String script,
|
||
HttpServletRequest request) {
|
||
if (script == null || script.isBlank()) {
|
||
return ApiResponse.error(400, "script body is required");
|
||
}
|
||
// 版本号递增
|
||
SiteConfig latest = configService.getLatestConfig(siteId);
|
||
int nextVersion = 1;
|
||
if (latest != null) {
|
||
try { nextVersion = Integer.parseInt(latest.getVersion()) + 1; }
|
||
catch (NumberFormatException ignored) {}
|
||
}
|
||
Long submitterId = (Long) request.getAttribute("accountId");
|
||
SiteConfig config = configService.submitConfig(siteId, String.valueOf(nextVersion), script, submitterId);
|
||
return ApiResponse.success(Map.of("version", config.getVersion()));
|
||
}
|
||
}
|