Files
anxinyan/admin-web/src/pages/content/policy.vue
wushumin 9aac78b8da first
2026-05-11 15:28:27 +08:00

173 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { ElMessage } from "element-plus";
import { adminApi, type AdminContentPolicyConfig, type AdminContentPolicyItem, type AdminHelpArticleItem } from "../../api/admin";
import { createPolicyItem, normalizePolicyConfig } from "./shared";
const loading = ref(false);
const saving = ref(false);
const articles = ref<AdminHelpArticleItem[]>([]);
const policyForm = ref<AdminContentPolicyConfig>({
legal_entries: [],
appraisal_agreements: [],
});
const helpArticleOptions = computed(() =>
articles.value.map((item) => ({
label: `${item.title}${item.category_text}`,
value: item.id,
})),
);
async function fetchPolicy() {
loading.value = true;
try {
const [policyResult, articleResult] = await Promise.all([
adminApi.getContentPolicy(),
adminApi.getHelpArticles(),
]);
policyForm.value = normalizePolicyConfig(policyResult.data.policy_config);
articles.value = articleResult.data.list;
} catch (error) {
console.error(error);
ElMessage.error("协议与说明加载失败");
} finally {
loading.value = false;
}
}
function addPolicyItem(section: "legal_entries" | "appraisal_agreements") {
policyForm.value[section].push(createPolicyItem());
}
function removePolicyItem(section: "legal_entries" | "appraisal_agreements", index: number) {
policyForm.value[section].splice(index, 1);
}
function bindPolicyArticle(item: AdminContentPolicyItem, articleId: number) {
item.article_id = Number(articleId || 0);
item.target_url = item.article_id > 0 ? `/pages/help/detail?id=${item.article_id}` : "";
}
async function savePolicy() {
saving.value = true;
try {
const response = await adminApi.saveContentPolicy(policyForm.value);
policyForm.value = normalizePolicyConfig(response.data.policy_config);
ElMessage.success("协议与说明已保存");
} catch (error) {
console.error(error);
ElMessage.error("协议与说明保存失败");
} finally {
saving.value = false;
}
}
onMounted(fetchPolicy);
</script>
<template>
<el-card class="panel-card" shadow="never" v-loading="loading">
<div class="filters-row" style="justify-content: space-between;">
<div>
<div style="font-size: 16px; font-weight: 700;">协议与说明</div>
<div style="color: var(--admin-text-subtle); margin-top: 6px;">
维护设置页说明入口以及下单确认页展示的服务协议鉴定须知与隐私政策
</div>
</div>
<el-button type="primary" :loading="saving" @click="savePolicy">保存协议与说明</el-button>
</div>
<el-form label-position="top">
<el-divider content-position="left">设置页说明入口</el-divider>
<div v-for="(item, index) in policyForm.legal_entries" :key="`legal-${index}`" class="content-block">
<div class="content-block__header">
<div class="content-block__title">入口 {{ index + 1 }}</div>
<el-button link type="danger" @click="removePolicyItem('legal_entries', index)">删除</el-button>
</div>
<el-row :gutter="16">
<el-col :span="6"><el-form-item label="编码"><el-input v-model="item.code" /></el-form-item></el-col>
<el-col :span="6"><el-form-item label="标题"><el-input v-model="item.title" /></el-form-item></el-col>
<el-col :span="12">
<el-form-item label="绑定文章">
<el-select
v-model="item.article_id"
clearable
filterable
style="width: 100%"
placeholder="请选择帮助中心文章"
@change="bindPolicyArticle(item, Number($event || 0))"
>
<el-option v-for="option in helpArticleOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="详情页链接">
<el-input v-model="item.target_url" placeholder="/pages/help/detail?id=12" />
</el-form-item>
</el-col>
<el-col :span="24"><el-form-item label="说明"><el-input v-model="item.desc" /></el-form-item></el-col>
</el-row>
</div>
<el-button plain @click="addPolicyItem('legal_entries')">新增设置入口</el-button>
<el-divider content-position="left">下单确认协议</el-divider>
<div v-for="(item, index) in policyForm.appraisal_agreements" :key="`agreement-${index}`" class="content-block">
<div class="content-block__header">
<div class="content-block__title">协议 {{ index + 1 }}</div>
<el-button link type="danger" @click="removePolicyItem('appraisal_agreements', index)">删除</el-button>
</div>
<el-row :gutter="16">
<el-col :span="6"><el-form-item label="编码"><el-input v-model="item.code" /></el-form-item></el-col>
<el-col :span="6"><el-form-item label="标题"><el-input v-model="item.title" /></el-form-item></el-col>
<el-col :span="12">
<el-form-item label="绑定文章">
<el-select
v-model="item.article_id"
clearable
filterable
style="width: 100%"
placeholder="请选择帮助中心文章"
@change="bindPolicyArticle(item, Number($event || 0))"
>
<el-option v-for="option in helpArticleOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="详情页链接">
<el-input v-model="item.target_url" placeholder="/pages/help/detail?id=12" />
</el-form-item>
</el-col>
<el-col :span="24"><el-form-item label="说明"><el-input v-model="item.desc" /></el-form-item></el-col>
</el-row>
</div>
<el-button plain @click="addPolicyItem('appraisal_agreements')">新增协议项</el-button>
</el-form>
</el-card>
</template>
<style scoped>
.content-block {
margin-bottom: 18px;
padding: 16px 18px;
border: 1px solid var(--admin-border);
border-radius: 14px;
background: linear-gradient(180deg, rgba(255, 251, 244, 0.7) 0%, rgba(255, 255, 255, 0.96) 100%);
}
.content-block__header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.content-block__title {
font-size: 14px;
font-weight: 700;
color: var(--admin-text);
}
</style>