MVP: 按 07 风格重写前端 + Go 后端落地(长文/短文、编辑器、后台管理)
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { adminApi } from '../api'
|
||||
import { site } from '../site'
|
||||
|
||||
const form = reactive({
|
||||
site_title: '',
|
||||
site_desc: '',
|
||||
author_name: '',
|
||||
author_bio: '',
|
||||
footer_note: '',
|
||||
icp: '',
|
||||
posts_per_page: 10
|
||||
})
|
||||
|
||||
const loading = ref(true)
|
||||
const saving = ref(false)
|
||||
const error = ref('')
|
||||
const ok = ref('')
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
Object.assign(form, await adminApi.settings())
|
||||
} catch (e) {
|
||||
error.value = e.message || '加载失败'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
error.value = ''
|
||||
ok.value = ''
|
||||
try {
|
||||
const saved = await adminApi.saveSettings({ ...form })
|
||||
Object.assign(form, saved)
|
||||
Object.assign(site, saved)
|
||||
ok.value = '已保存'
|
||||
} catch (e) {
|
||||
error.value = e.message || '保存失败'
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<header class="head">
|
||||
<h1 class="title">站点设置</h1>
|
||||
</header>
|
||||
|
||||
<div v-if="loading" class="loading">载入中…</div>
|
||||
|
||||
<form v-else class="form" @submit.prevent="save">
|
||||
<div class="field">
|
||||
<label for="t">站点标题</label>
|
||||
<input id="t" v-model="form.site_title" class="input" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="d">站点简介</label>
|
||||
<input id="d" v-model="form.site_desc" class="input" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="a">作者名</label>
|
||||
<input id="a" v-model="form.author_name" class="input" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="b">作者简介</label>
|
||||
<textarea id="b" v-model="form.author_bio" class="textarea" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="f">页脚信息</label>
|
||||
<input id="f" v-model="form.footer_note" class="input" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="i">备案号(可留空)</label>
|
||||
<input id="i" v-model="form.icp" class="input" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="p">每页文章数</label>
|
||||
<input id="p" v-model.number="form.posts_per_page" type="number" min="1" max="100" class="input" />
|
||||
</div>
|
||||
|
||||
<p v-if="error" class="error">{{ error }}</p>
|
||||
<p v-if="ok" class="ok">{{ ok }}</p>
|
||||
|
||||
<button class="btn btn-primary" type="submit" :disabled="saving">
|
||||
{{ saving ? '保存中…' : '保存' }}
|
||||
</button>
|
||||
</form>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.head {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.form {
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #9a5b45;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.ok {
|
||||
color: var(--accent);
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user