feat: 站点增加标签+简介字段+表单编辑双向同步
This commit is contained in:
@@ -52,13 +52,15 @@ public class SiteController {
|
|||||||
List<String> names = (List<String>) payload.get("names");
|
List<String> names = (List<String>) payload.get("names");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<String> urls = (List<String>) payload.get("urls");
|
List<String> urls = (List<String>) payload.get("urls");
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<String> tags = (List<String>) payload.get("tags");
|
||||||
String siteType = (String) payload.get("siteType");
|
String siteType = (String) payload.get("siteType");
|
||||||
String status = (String) payload.get("status");
|
String status = (String) payload.get("status");
|
||||||
String description = (String) payload.get("description");
|
String description = (String) payload.get("description");
|
||||||
Long operatorId = (Long) request.getAttribute("accountId");
|
Long operatorId = (Long) request.getAttribute("accountId");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Site site = siteService.updateSite(siteId, names, urls, description, siteType, status, operatorId);
|
Site site = siteService.updateSite(siteId, names, urls, tags, description, siteType, status, operatorId);
|
||||||
return ApiResponse.success(siteService.toDTO(site));
|
return ApiResponse.success(siteService.toDTO(site));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return ApiResponse.error(404, e.getMessage());
|
return ApiResponse.error(404, e.getMessage());
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public class SiteDTO {
|
|||||||
private String description;
|
private String description;
|
||||||
private String notes;
|
private String notes;
|
||||||
private List<String> urls;
|
private List<String> urls;
|
||||||
|
private List<String> tags;
|
||||||
private String iconUrl;
|
private String iconUrl;
|
||||||
private SiteType siteType;
|
private SiteType siteType;
|
||||||
private String schemaVersion;
|
private String schemaVersion;
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ public class Site {
|
|||||||
@TableField("description")
|
@TableField("description")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@TableField("tags")
|
||||||
|
private String tagsJson;
|
||||||
|
|
||||||
@TableField("notes")
|
@TableField("notes")
|
||||||
private String notes;
|
private String notes;
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ public interface SiteService {
|
|||||||
/**
|
/**
|
||||||
* 管理员编辑站点基本信息
|
* 管理员编辑站点基本信息
|
||||||
*/
|
*/
|
||||||
Site updateSite(String siteId, List<String> names, List<String> urls, String description,
|
Site updateSite(String siteId, List<String> names, List<String> urls, List<String> tags,
|
||||||
String siteType, String status, Long operatorId);
|
String description, String siteType, String status, Long operatorId);
|
||||||
|
|
||||||
/** 所有站点列表(管理员用) */
|
/** 所有站点列表(管理员用) */
|
||||||
List<Site> listAllSites();
|
List<Site> listAllSites();
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ public class SiteServiceImpl implements SiteService {
|
|||||||
dto.setDescription(site.getDescription());
|
dto.setDescription(site.getDescription());
|
||||||
dto.setNotes(site.getNotes());
|
dto.setNotes(site.getNotes());
|
||||||
dto.setUrls(fromJsonArray(site.getUrlsJson()));
|
dto.setUrls(fromJsonArray(site.getUrlsJson()));
|
||||||
|
dto.setTags(fromJsonArray(site.getTagsJson()));
|
||||||
dto.setIconUrl(site.getIconUrl());
|
dto.setIconUrl(site.getIconUrl());
|
||||||
dto.setSiteType(site.getSiteType());
|
dto.setSiteType(site.getSiteType());
|
||||||
dto.setSchemaVersion(site.getSchemaVersion());
|
dto.setSchemaVersion(site.getSchemaVersion());
|
||||||
@@ -208,8 +209,8 @@ public class SiteServiceImpl implements SiteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Site updateSite(String siteId, List<String> names, List<String> urls, String description,
|
public Site updateSite(String siteId, List<String> names, List<String> urls, List<String> tags,
|
||||||
String siteType, String status, Long operatorId) {
|
String description, String siteType, String status, Long operatorId) {
|
||||||
Site site = siteMapper.selectBySiteId(siteId);
|
Site site = siteMapper.selectBySiteId(siteId);
|
||||||
if (site == null) throw new IllegalArgumentException("站点不存在: " + siteId);
|
if (site == null) throw new IllegalArgumentException("站点不存在: " + siteId);
|
||||||
|
|
||||||
@@ -219,6 +220,9 @@ public class SiteServiceImpl implements SiteService {
|
|||||||
if (urls != null && !urls.isEmpty()) {
|
if (urls != null && !urls.isEmpty()) {
|
||||||
site.setUrlsJson(toJsonArray(urls.stream().filter(u -> u != null && !u.isBlank()).toList()));
|
site.setUrlsJson(toJsonArray(urls.stream().filter(u -> u != null && !u.isBlank()).toList()));
|
||||||
}
|
}
|
||||||
|
if (tags != null) {
|
||||||
|
site.setTagsJson(toJsonArray(tags.stream().filter(t -> t != null && !t.isBlank()).toList()));
|
||||||
|
}
|
||||||
if (description != null) site.setDescription(description);
|
if (description != null) site.setDescription(description);
|
||||||
if (siteType != null && !siteType.isBlank()) {
|
if (siteType != null && !siteType.isBlank()) {
|
||||||
try { site.setSiteType(SiteType.fromValue(siteType)); } catch (Exception ignored) {}
|
try { site.setSiteType(SiteType.fromValue(siteType)); } catch (Exception ignored) {}
|
||||||
|
|||||||
@@ -72,6 +72,12 @@
|
|||||||
<el-form-item label="地址">
|
<el-form-item label="地址">
|
||||||
<el-input v-model="form.urlsStr" type="textarea" :rows="2" @input="formToJson" placeholder="一行一个" />
|
<el-input v-model="form.urlsStr" type="textarea" :rows="2" @input="formToJson" placeholder="一行一个" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="标签">
|
||||||
|
<el-input v-model="form.tagsStr" @input="formToJson" placeholder="用逗号分隔" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介">
|
||||||
|
<el-input v-model="form.desc" type="textarea" :rows="2" @input="formToJson" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="类型">
|
<el-form-item label="类型">
|
||||||
<el-select v-model="form.siteType" @change="formToJson" style="width:100%">
|
<el-select v-model="form.siteType" @change="formToJson" style="width:100%">
|
||||||
<el-option v-for="t in ['nexusphp','mtorrent','gazelle','unit3d','unknown']" :key="t" :label="t" :value="t" />
|
<el-option v-for="t in ['nexusphp','mtorrent','gazelle','unit3d','unknown']" :key="t" :label="t" :value="t" />
|
||||||
@@ -93,12 +99,16 @@ import api from '../api'
|
|||||||
|
|
||||||
const loading = ref(false), saving = ref(false), pendingCount = ref(0)
|
const loading = ref(false), saving = 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:'', siteType:'nexusphp', status:'active' })
|
const form = reactive({ siteId:'', namesStr:'', urlsStr:'', tagsStr:'', desc:'', siteType:'nexusphp', status:'active' })
|
||||||
let syncing = false
|
let syncing = false
|
||||||
|
|
||||||
const jsonToForm = () => {
|
const jsonToForm = () => {
|
||||||
try { const s = JSON.parse(editorJson.value); form.siteId = s.siteId||''; form.namesStr = (s.names||[]).join('\n'); form.urlsStr = (s.urls||[]).join('\n'); form.siteType = s.siteType||'nexusphp'; form.status = s.status||'active'; jsonError.value = false }
|
try {
|
||||||
catch { jsonError.value = true }
|
const s = JSON.parse(editorJson.value)
|
||||||
|
form.siteId = s.siteId||''; form.namesStr = (s.names||[]).join('\n'); form.urlsStr = (s.urls||[]).join('\n')
|
||||||
|
form.tagsStr = (s.tags||[]).join(','); form.desc = s.description||''; form.siteType = s.siteType||'nexusphp'; form.status = s.status||'active'
|
||||||
|
jsonError.value = false
|
||||||
|
} catch { jsonError.value = true }
|
||||||
}
|
}
|
||||||
|
|
||||||
const formToJson = () => {
|
const formToJson = () => {
|
||||||
@@ -107,7 +117,8 @@ const formToJson = () => {
|
|||||||
editorJson.value = JSON.stringify({
|
editorJson.value = JSON.stringify({
|
||||||
siteId: form.siteId, names: (form.namesStr||'').split('\n').map(s=>s.trim()).filter(Boolean),
|
siteId: form.siteId, names: (form.namesStr||'').split('\n').map(s=>s.trim()).filter(Boolean),
|
||||||
urls: (form.urlsStr||'').split('\n').map(s=>s.trim()).filter(Boolean),
|
urls: (form.urlsStr||'').split('\n').map(s=>s.trim()).filter(Boolean),
|
||||||
siteType: form.siteType, status: form.status,
|
tags: (form.tagsStr||'').split(',').map(s=>s.trim()).filter(Boolean),
|
||||||
|
description: form.desc||'', siteType: form.siteType, status: form.status,
|
||||||
}, null, 2)
|
}, null, 2)
|
||||||
nextTick(() => { syncing = false })
|
nextTick(() => { syncing = false })
|
||||||
}
|
}
|
||||||
@@ -128,7 +139,7 @@ const refresh = async () => {
|
|||||||
|
|
||||||
const editSite = (row) => {
|
const editSite = (row) => {
|
||||||
editSiteId.value = row.siteId
|
editSiteId.value = row.siteId
|
||||||
editorJson.value = JSON.stringify({siteId:row.siteId,names:row.names,urls:row.urls,siteType:row.siteType,status:row.status||'active'}, null, 2)
|
editorJson.value = JSON.stringify({siteId:row.siteId,names:row.names,urls:row.urls,tags:row.tags||[],description:row.description||'',siteType:row.siteType,status:row.status||'active'}, null, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
const newSite = () => {
|
const newSite = () => {
|
||||||
@@ -141,7 +152,7 @@ const saveSite = async () => {
|
|||||||
try {
|
try {
|
||||||
const s = JSON.parse(editorJson.value)
|
const s = JSON.parse(editorJson.value)
|
||||||
if (!s.siteId) { ElMessage.warning('siteId不能为空'); return }
|
if (!s.siteId) { ElMessage.warning('siteId不能为空'); return }
|
||||||
await api.raw.put('/admin/sites/'+s.siteId, {names:s.names||[],urls:s.urls||[],siteType:s.siteType||'unknown',status:s.status||'active'})
|
await api.raw.put('/admin/sites/'+s.siteId, {names:s.names||[],urls:s.urls||[],tags:s.tags||[],description:s.description||'',siteType:s.siteType||'unknown',status:s.status||'active'})
|
||||||
ElMessage.success('已保存'); editSiteId.value = ''; refresh()
|
ElMessage.success('已保存'); editSiteId.value = ''; refresh()
|
||||||
} catch { ElMessage.error('保存失败') }
|
} catch { ElMessage.error('保存失败') }
|
||||||
finally { saving.value = false }
|
finally { saving.value = false }
|
||||||
|
|||||||
Reference in New Issue
Block a user