feat: 站点编辑右侧表单双向同步JSON编辑器
This commit is contained in:
@@ -58,13 +58,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="flex:1;overflow:auto;min-height:0">
|
<div style="flex:1;overflow:auto;min-height:0">
|
||||||
<div style="font-size:13px;font-weight:500;margin-bottom:8px">预览</div>
|
<div style="font-size:13px;font-weight:500;margin-bottom:8px;display:flex;gap:8px;align-items:center">
|
||||||
<el-form label-width="70px" label-position="left" size="small">
|
<span>表单编辑(双向同步)</span>
|
||||||
<el-form-item label="站点ID"><span style="font-weight:500">{{ preview.siteId||'-' }}</span></el-form-item>
|
<el-tag v-if="jsonError" type="danger" size="small">JSON解析错误</el-tag>
|
||||||
<el-form-item label="名称"><span>{{ (preview.names||[]).join(' / ') }}</span></el-form-item>
|
</div>
|
||||||
<el-form-item label="地址"><span>{{ (preview.urls||[]).join(' / ') }}</span></el-form-item>
|
<el-form v-if="!jsonError" label-width="80px" label-position="left" size="small">
|
||||||
<el-form-item label="类型"><el-tag size="small">{{ preview.siteType }}</el-tag></el-form-item>
|
<el-form-item label="站点ID">
|
||||||
<el-form-item label="状态"><el-tag size="small" :type="preview.status==='active'?'success':'info'">{{ preview.status }}</el-tag></el-form-item>
|
<el-input v-model="form.siteId" @input="formToJson" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="名称">
|
||||||
|
<el-input v-model="form.namesStr" type="textarea" :rows="2" @input="formToJson" placeholder="一行一个" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址">
|
||||||
|
<el-input v-model="form.urlsStr" type="textarea" :rows="2" @input="formToJson" placeholder="一行一个" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="类型">
|
||||||
|
<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-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-select v-model="form.status" @change="formToJson" style="width:100%">
|
||||||
|
<el-option label="活跃" value="active" /><el-option label="弃用" value="deprecated" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,8 +92,30 @@
|
|||||||
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), pendingCount = ref(0)
|
||||||
const sites = ref([]), editSiteId = ref(''), editorJson = ref('{}')
|
const sites = ref([]), editSiteId = ref(''), editorJson = ref('{}'), jsonError = ref(false)
|
||||||
const preview = computed(() => { try { return JSON.parse(editorJson.value) } catch { return {} } })
|
const form = reactive({ siteId:'', namesStr:'', urlsStr:'', siteType:'nexusphp', status:'active' })
|
||||||
|
let syncing = false
|
||||||
|
|
||||||
|
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 }
|
||||||
|
catch { jsonError.value = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
const formToJson = () => {
|
||||||
|
if (syncing) return; syncing = true
|
||||||
|
jsonError.value = false
|
||||||
|
editorJson.value = JSON.stringify({
|
||||||
|
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),
|
||||||
|
siteType: form.siteType, status: form.status,
|
||||||
|
}, null, 2)
|
||||||
|
nextTick(() => { syncing = false })
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonToFormDebounced = null
|
||||||
|
watch(editorJson, () => { if (!syncing) jsonToForm() })
|
||||||
|
|
||||||
|
const refresh = async () => {
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|||||||
Reference in New Issue
Block a user