|
@@ -0,0 +1,92 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="agreement-page">
|
|
|
|
+ <div class="agreement-header">
|
|
|
|
+ <h2>{{ pageTitle }}</h2>
|
|
|
|
+ </div>
|
|
|
|
+ <el-scrollbar class="agreement-content" v-loading="loading">
|
|
|
|
+ <div v-if="error" class="agreement-error">{{ error }}</div>
|
|
|
|
+ <div v-else v-html="htmlContent"></div>
|
|
|
|
+ </el-scrollbar>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { onMounted, ref, computed } from 'vue';
|
|
|
|
+import { useRoute } from 'vue-router';
|
|
|
|
+import { GetObjByPath } from './api';
|
|
|
|
+
|
|
|
|
+const route = useRoute();
|
|
|
|
+
|
|
|
|
+const loading = ref(false);
|
|
|
|
+const error = ref('');
|
|
|
|
+const htmlContent = ref('');
|
|
|
|
+
|
|
|
|
+// 根据路径名默认映射 ID;也支持通过 ?id= 覆盖
|
|
|
|
+const defaultIdByPath: Record<string, number> = {
|
|
|
|
+ '/user-agreement': 3,
|
|
|
|
+ '/privacy-policy': 4,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const currentId = computed(() => {
|
|
|
|
+ const qid = Number(route.query.id);
|
|
|
|
+ if (!Number.isNaN(qid) && qid > 0) return qid;
|
|
|
|
+ return defaultIdByPath[route.path] ?? 3;
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const pageTitle = computed(() => {
|
|
|
|
+ if (route.path === '/privacy-policy') return '隐私协议';
|
|
|
|
+ return '用户服务协议';
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const parseContent = (data: any): string => {
|
|
|
|
+ // 兼容不同字段命名
|
|
|
|
+ return (
|
|
|
|
+ data?.content_html ||
|
|
|
|
+ data?.content ||
|
|
|
|
+ data?.detail ||
|
|
|
|
+ data?.description ||
|
|
|
|
+ ''
|
|
|
|
+ );
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const fetchAgreement = async () => {
|
|
|
|
+ loading.value = true;
|
|
|
|
+ error.value = '';
|
|
|
|
+ htmlContent.value = '';
|
|
|
|
+ try {
|
|
|
|
+ const res: any = await GetObjByPath(currentId.value as any);
|
|
|
|
+ // 兼容 service 里 code=200 / 2000 的返回
|
|
|
|
+ const payload = res?.data ?? res;
|
|
|
|
+ htmlContent.value = parseContent(payload) || '<p>暂无内容</p>';
|
|
|
|
+ } catch (e: any) {
|
|
|
|
+ error.value = e?.msg || '内容加载失败';
|
|
|
|
+ } finally {
|
|
|
|
+ loading.value = false;
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+onMounted(fetchAgreement);
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
+.agreement-page {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100vh;
|
|
|
|
+ background: #fff;
|
|
|
|
+}
|
|
|
|
+.agreement-header {
|
|
|
|
+ padding: 16px 20px;
|
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
|
+}
|
|
|
|
+.agreement-content {
|
|
|
|
+ padding: 20px;
|
|
|
|
+ height: calc(100vh - 64px);
|
|
|
|
+}
|
|
|
|
+.agreement-error {
|
|
|
|
+ color: #f56c6c;
|
|
|
|
+}
|
|
|
|
+</style>
|
|
|
|
+
|
|
|
|
+
|