feat: 合并配置审核到适配验证页,支持版本切换、编辑、审批/拒绝

This commit is contained in:
mediabot-pt
2026-06-30 23:14:16 +08:00
parent 03addbdb18
commit 2d8fce78ea
8 changed files with 291 additions and 102 deletions

View File

@@ -2,6 +2,7 @@ package com.par.api.controller;
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.SiteConfig;
import com.par.core.enums.ConfigStatus;
@@ -12,13 +13,16 @@ 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.web.bind.annotation.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@@ -39,6 +43,7 @@ public class AdminController {
private final SiteMapper siteMapper;
private final AccountService accountService;
private final PskService pskService;
private final ConfigService configService;
private final CachedStorageService storageService;
private final com.par.core.service.SiteService siteService;
@@ -124,7 +129,7 @@ public class AdminController {
@PostMapping("/reviews/{reviewId}/reject")
public ApiResponse<Void> rejectConfig(
@PathVariable Long reviewId,
@RequestParam("comment") String comment,
@RequestParam(value = "comment", required = false, defaultValue = "") String comment,
HttpServletRequest request) {
checkAdmin(request);
@@ -151,6 +156,69 @@ public class AdminController {
return ApiResponse.success();
}
/**
* 获取指定站点的待审核配置列表
*/
@GetMapping("/configs/pending/{siteId}")
public ApiResponse<List<SiteConfigDTO>> listPendingConfigsBySite(
@PathVariable String siteId, HttpServletRequest request) {
checkAdmin(request);
List<SiteConfig> configs = siteConfigMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SiteConfig>()
.eq(SiteConfig::getSiteId, siteId)
.eq(SiteConfig::getStatus, ConfigStatus.PENDING)
.eq(SiteConfig::getDeleted, 0));
return ApiResponse.success(configs.stream().map(configService::toDTO).toList());
}
/**
* 查看指定版本配置内容
*/
@GetMapping("/configs/{configId}/content")
public ApiResponse<Map<String, Object>> getConfigContent(
@PathVariable Long configId, HttpServletRequest request) {
checkAdmin(request);
SiteConfig config = siteConfigMapper.selectById(configId);
if (config == null) return ApiResponse.error(404, "Config not found");
String content = null;
try { content = storageService.read(config.getStoragePath()); } catch (Exception e) {
return ApiResponse.error(500, "读取配置失败: " + e.getMessage());
}
return ApiResponse.success(Map.of("id", config.getId(), "content", content != null ? content : ""));
}
/**
* 编辑待审核配置内容
*/
@PutMapping("/configs/{configId}/content")
public ApiResponse<SiteConfigDTO> updateConfigContent(
@PathVariable Long configId,
@RequestBody Map<String, String> payload,
HttpServletRequest request) {
checkAdmin(request);
SiteConfig config = siteConfigMapper.selectById(configId);
if (config == null) return ApiResponse.error(404, "Config not found");
if (config.getStatus() != ConfigStatus.PENDING) {
return ApiResponse.error(400, "只能编辑待审核的配置");
}
String content = payload.get("content");
if (content == null || content.isBlank()) {
return ApiResponse.error(400, "content is required");
}
// 更新存储文件
storageService.store(config.getStoragePath(), content);
// 更新 hash 和文件大小
config.setConfigHash(HmacUtil.sha256(content));
config.setFileSize((long) content.getBytes(StandardCharsets.UTF_8).length);
siteConfigMapper.updateById(config);
log.info("Config content updated: id={}, siteId={}", configId, config.getSiteId());
return ApiResponse.success(configService.toDTO(config));
}
/**
* 设置用户信任等级(禁止修改管理员、禁止提升为管理员)
*/