feat(admin): 新增三语协议设置页
This commit is contained in:
1 parent
91f1f7d793
commit
c1fb6cc21c
3 files changed
+145
No files matched your search
@@ -0,0 +1,18 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import request from '@/axios'
|
||||
|
||||
export interface LegalDocument {
|
||||
docCode: 'terms' | 'privacy' | string
|
||||
lang: 'zh' | 'en' | 'id' | string
|
||||
title: string
|
||||
content: string
|
||||
}
|
||||
|
||||
export const listLegalDocumentsApi = () => {
|
||||
return request.get<LegalDocument[]>({ url: '/admin/legal-documents' })
|
||||
}
|
||||
|
||||
export const saveLegalDocumentsApi = (items: LegalDocument[]) => {
|
||||
return request.put<void>({ url: '/admin/legal-documents', data: items })
|
||||
}
|
||||
@@ -211,6 +211,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||
meta: {
|
||||
title: '操作日志'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'legal-documents',
|
||||
name: 'legal-documents',
|
||||
component: () => import('@/views/systemManagement/LegalDocumentView.vue'),
|
||||
meta: {
|
||||
title: '协议设置'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {
|
||||
listLegalDocumentsApi,
|
||||
saveLegalDocumentsApi,
|
||||
type LegalDocument
|
||||
} from '@/api/admin/legalDocument'
|
||||
|
||||
const languages = [
|
||||
{ code: 'zh', label: '中文' },
|
||||
{ code: 'en', label: 'English' },
|
||||
{ code: 'id', label: 'Indonesia' }
|
||||
]
|
||||
|
||||
const documents = [
|
||||
{ code: 'terms', label: '服务条款', path: '/terms' },
|
||||
{ code: 'privacy', label: '隐私协议', path: '/privacy' }
|
||||
]
|
||||
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const activeDoc = ref('terms')
|
||||
const form = reactive<Record<string, LegalDocument>>({})
|
||||
|
||||
const blank = (docCode: string, lang: string): LegalDocument => ({
|
||||
docCode,
|
||||
lang,
|
||||
title: '',
|
||||
content: ''
|
||||
})
|
||||
|
||||
const fieldKey = (docCode: string, lang: string) => `${docCode}:${lang}`
|
||||
|
||||
function ensureFields() {
|
||||
for (const doc of documents) {
|
||||
for (const lang of languages) {
|
||||
const key = fieldKey(doc.code, lang.code)
|
||||
if (!form[key]) form[key] = blank(doc.code, lang.code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
ensureFields()
|
||||
const res = await listLegalDocumentsApi()
|
||||
for (const item of res.data || []) {
|
||||
form[fieldKey(item.docCode, item.lang)] = { ...item }
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
try {
|
||||
ensureFields()
|
||||
const items = documents.flatMap((doc) =>
|
||||
languages.map((lang) => ({ ...form[fieldKey(doc.code, lang.code)], title: '' }))
|
||||
)
|
||||
await saveLegalDocumentsApi(items)
|
||||
ElMessage.success('协议已保存')
|
||||
await load()
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
ensureFields()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-heading">
|
||||
<div>
|
||||
<div class="eyebrow">系统管理</div>
|
||||
<h1>协议设置</h1>
|
||||
<p>服务条款与隐私协议各维护中文、英文、印尼语。正文用 Markdown,打开后的页面不另加标题。</p>
|
||||
</div>
|
||||
</div>
|
||||
<section v-loading="loading" class="panel settings-panel">
|
||||
<el-tabs v-model="activeDoc">
|
||||
<el-tab-pane v-for="doc in documents" :key="doc.code" :name="doc.code" :label="doc.label" />
|
||||
</el-tabs>
|
||||
<template v-for="doc in documents" :key="doc.code">
|
||||
<div v-show="activeDoc === doc.code">
|
||||
<p class="legal-path"
|
||||
>公开地址:{{ doc.path }}/zh 、{{ doc.path }}/en 、{{ doc.path }}/id</p
|
||||
>
|
||||
<div v-for="lang in languages" :key="`${doc.code}-${lang.code}`" class="legal-block">
|
||||
<h2>{{ lang.label }}</h2>
|
||||
<el-input
|
||||
v-model="form[`${doc.code}:${lang.code}`].content"
|
||||
type="textarea"
|
||||
:rows="14"
|
||||
placeholder="直接写 Markdown,页面不再另加标题"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.legal-path {
|
||||
margin: 0 0 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.legal-block + .legal-block {
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user