@@ -210,20 +246,39 @@ export default {
editor: {
visible: false,
id: null,
- form: { category: 'other', title: '', brief: '', content: '', sort: 0, status: 1 },
+ form: { category: 'other', title: '', brief: '', content: '', image: '', sort: 0, status: 1 },
+ extra: {},
},
+ termExtraFields: [
+ { key: 'alias', name: '别名' },
+ { key: 'english', name: '外文名' },
+ { key: 'meaning', name: '涵义' },
+ { key: 'solarDate', name: '公历时间' },
+ { key: 'ecliptic', name: '黄道位置' },
+ { key: 'climate', name: '气候特点' },
+ { key: 'phenology', name: '物候现象' },
+ { key: 'farming', name: '农事活动' },
+ { key: 'customs', name: '传统习俗' },
+ { key: 'health', name: '起居养生' },
+ { key: 'flower', name: '花信' },
+ ],
saving: false,
syncing: false,
syncStatus: {},
syncTimer: null,
+ termSync: {},
+ termSyncing: false,
+ termSyncTimer: null,
};
},
mounted() {
this.loadEntries();
this.loadSyncStatus();
+ this.loadTermSyncStatus();
},
beforeUnmount() {
if (this.syncTimer) clearInterval(this.syncTimer);
+ if (this.termSyncTimer) clearInterval(this.termSyncTimer);
},
methods: {
catName(key) {
@@ -265,22 +320,40 @@ export default {
openEditor(entry) {
this.editor.id = entry ? entry.id : null;
this.editor.form = entry
- ? { category: entry.category, title: entry.title, brief: entry.brief, content: entry.content, sort: entry.sort, status: entry.status }
- : { category: 'other', title: '', brief: '', content: '', sort: 0, status: 1 };
+ ? { category: entry.category, title: entry.title, brief: entry.brief, content: entry.content, image: entry.image || '', sort: entry.sort, status: entry.status }
+ : { category: 'other', title: '', brief: '', content: '', image: '', sort: 0, status: 1 };
+ let extra = {};
+ if (entry && entry.extra) {
+ try { extra = JSON.parse(entry.extra); } catch (e) { extra = {}; }
+ }
+ this.editor.extra = extra;
this.editor.visible = true;
},
async saveEntry() {
const f = this.editor.form;
if (!f.title.trim()) { alert('标题不能为空'); return; }
+ // 节气分类:把 extra 对象序列化为 JSON 字符串
+ const payload = { ...f };
+ if (f.category === 'term') {
+ const extra = {};
+ this.termExtraFields.forEach(fd => {
+ const v = (this.editor.extra[fd.key] || '').trim();
+ if (v) extra[fd.key] = v;
+ });
+ payload.extra = JSON.stringify(extra);
+ } else {
+ payload.extra = '';
+ }
this.saving = true;
try {
if (this.editor.id) {
- await this.api(`/admin/api/wiki/entries/${this.editor.id}`, { method: 'PUT', body: JSON.stringify(f) });
+ await this.api(`/admin/api/wiki/entries/${this.editor.id}`, { method: 'PUT', body: JSON.stringify(payload) });
} else {
- await this.api('/admin/api/wiki/entries', { method: 'POST', body: JSON.stringify(f) });
+ await this.api('/admin/api/wiki/entries', { method: 'POST', body: JSON.stringify(payload) });
}
this.editor.visible = false;
this.loadEntries();
+ this.loadTermSyncStatus();
} catch (e) {
alert(e.message);
} finally {
@@ -322,5 +395,31 @@ export default {
this.syncing = false;
}
},
+ async loadTermSyncStatus() {
+ try {
+ this.termSync = await this.api('/admin/api/wiki/term-sync-status');
+ if (this.termSync.running && !this.termSyncTimer) {
+ this.termSyncTimer = setInterval(() => this.loadTermSyncStatus(), 5000);
+ } else if (!this.termSync.running && this.termSyncTimer) {
+ clearInterval(this.termSyncTimer);
+ this.termSyncTimer = null;
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ },
+ async triggerTermSync() {
+ if (!confirm('将从百度百科抓取 24 节气的详细图文(约 30 秒),确认执行?')) return;
+ this.termSyncing = true;
+ try {
+ await this.api('/admin/api/wiki/term-sync', { method: 'POST' });
+ this.loadTermSyncStatus();
+ setTimeout(() => this.loadEntries(), 3000);
+ } catch (e) {
+ alert(e.message);
+ } finally {
+ this.termSyncing = false;
+ }
+ },
},
}