feat: 站点编辑加发布按钮生成manifest上传七牛云
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user