feat: 站点编辑加发布按钮生成manifest上传七牛云

This commit is contained in:
mediabot-pt
2026-07-05 23:54:25 +08:00
parent 25df4203d7
commit b7adbfd18a
2 changed files with 64 additions and 2 deletions

View File

@@ -337,6 +337,21 @@ public class AdminController {
// ===================== 站点审核 =====================
/** 发布站点配置到七牛云(生成 manifest/manifest.json) */
@PostMapping("/sites/publish")
public ApiResponse<Map<String,Object>> 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<List<com.par.core.dto.SiteDTO>> 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<String, Object> buildManifest() {
var sites = siteService.listAllSites();
List<Map<String,Object>> list = new ArrayList<>();
int total = 0;
for (var site : sites) {
var dto = siteService.toDTO(site);
Map<String,Object> 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<com.par.core.entity.SitePages>()
.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<com.par.core.entity.RiskRule>()
.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<String,Object> 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) {

View File

@@ -55,8 +55,9 @@
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
<h2 style="margin:0">站点编辑: {{ editSiteId }}</h2>
<div style="display:flex;gap:8px">
<el-button size="small" type="primary" @click="saveSite" :loading="saving">保存</el-button>
<el-button size="small" @click="editSiteId=''">返回列表</el-button>
<el-button size="small" type="primary" @click="saveSite" :loading="saving">保存</el-button>
<el-button size="small" @click="publishAll" :loading="publishing">发布</el-button>
</div>
</div>
<div style="display:flex;gap:12px;flex:1;min-height:0">
@@ -106,7 +107,7 @@
<script setup>
import api from '../api'
const loading = ref(false), saving = ref(false), pendingCount = ref(0)
const loading = ref(false), saving = ref(false), publishing = ref(false), pendingCount = ref(0)
const sites = ref([]), editSiteId = ref(''), editorJson = ref('{}'), jsonError = ref(false)
const form = reactive({ siteId:'', namesStr:'', urlsStr:'', tagsStr:'', desc:'', siteType:'nexusphp', status:'active' })
let syncing = false
@@ -153,6 +154,15 @@ const newSite = () => {
editorJson.value = JSON.stringify({siteId:'',names:[''],urls:[''],siteType:'nexusphp',status:'active'}, null, 2)
}
const publishAll = async () => {
publishing.value = true
try {
await api.raw.post('/admin/sites/publish')
ElMessage.success('已发布到云存储')
} catch { ElMessage.error('发布失败') }
finally { publishing.value = false }
}
const saveSite = async () => {
saving.value = true
try {