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")
|
@GetMapping("/sites")
|
||||||
public ApiResponse<List<com.par.core.dto.SiteDTO>> listAllSites(HttpServletRequest request) {
|
public ApiResponse<List<com.par.core.dto.SiteDTO>> listAllSites(HttpServletRequest request) {
|
||||||
checkAdmin(request);
|
checkAdmin(request);
|
||||||
@@ -505,6 +520,43 @@ public class AdminController {
|
|||||||
catch (Exception e) { return java.util.List.of(); }
|
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) {
|
private void checkAdmin(HttpServletRequest request) {
|
||||||
TrustLevel level = (TrustLevel) request.getAttribute("trustLevel");
|
TrustLevel level = (TrustLevel) request.getAttribute("trustLevel");
|
||||||
if (level == null || level != TrustLevel.ADMIN) {
|
if (level == null || level != TrustLevel.ADMIN) {
|
||||||
|
|||||||
@@ -55,8 +55,9 @@
|
|||||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
||||||
<h2 style="margin:0">站点编辑: {{ editSiteId }}</h2>
|
<h2 style="margin:0">站点编辑: {{ editSiteId }}</h2>
|
||||||
<div style="display:flex;gap:8px">
|
<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" @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>
|
</div>
|
||||||
<div style="display:flex;gap:12px;flex:1;min-height:0">
|
<div style="display:flex;gap:12px;flex:1;min-height:0">
|
||||||
@@ -106,7 +107,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import api from '../api'
|
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 sites = ref([]), editSiteId = ref(''), editorJson = ref('{}'), jsonError = ref(false)
|
||||||
const form = reactive({ siteId:'', namesStr:'', urlsStr:'', tagsStr:'', desc:'', siteType:'nexusphp', status:'active' })
|
const form = reactive({ siteId:'', namesStr:'', urlsStr:'', tagsStr:'', desc:'', siteType:'nexusphp', status:'active' })
|
||||||
let syncing = false
|
let syncing = false
|
||||||
@@ -153,6 +154,15 @@ const newSite = () => {
|
|||||||
editorJson.value = JSON.stringify({siteId:'',names:[''],urls:[''],siteType:'nexusphp',status:'active'}, null, 2)
|
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 () => {
|
const saveSite = async () => {
|
||||||
saving.value = true
|
saving.value = true
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user