206 lines
3.8 KiB
Vue
206 lines
3.8 KiB
Vue
<script setup>
|
|
/**
|
|
* 隐私政策页面
|
|
* 展示隐私政策内容
|
|
*/
|
|
import { ref, onMounted } from 'vue'
|
|
import { getPrivacy } from '@/api/system.js'
|
|
|
|
// 页面状态
|
|
const loading = ref(true)
|
|
const content = ref('')
|
|
const title = ref('隐私政策')
|
|
const updateTime = ref('')
|
|
|
|
/**
|
|
* 获取隐私政策内容
|
|
*/
|
|
async function fetchPrivacy() {
|
|
loading.value = true
|
|
try {
|
|
const res = await getPrivacy()
|
|
if (res.code === 0 && res.data) {
|
|
content.value = res.data.content || ''
|
|
title.value = res.data.title || '隐私政策'
|
|
updateTime.value = res.data.updateTime || ''
|
|
}
|
|
} catch (error) {
|
|
console.error('获取隐私政策失败:', error)
|
|
uni.showToast({
|
|
title: '加载失败,请重试',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 页面加载
|
|
*/
|
|
onMounted(() => {
|
|
fetchPrivacy()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<view class="privacy-page">
|
|
<!-- 加载状态 -->
|
|
<view v-if="loading" class="loading-container">
|
|
<view class="loading-spinner"></view>
|
|
<text class="loading-text">加载中...</text>
|
|
</view>
|
|
|
|
<!-- 隐私政策内容 -->
|
|
<view v-else class="privacy-content">
|
|
|
|
<!-- 正文内容 -->
|
|
<view class="privacy-body">
|
|
<rich-text v-if="content" :nodes="content" class="rich-content"></rich-text>
|
|
<view v-else class="empty-content">
|
|
<text>暂无内容</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
@import '@/styles/variables.scss';
|
|
|
|
.privacy-page {
|
|
min-height: 100vh;
|
|
background-color: $bg-white;
|
|
}
|
|
|
|
// 加载状态
|
|
.loading-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 60vh;
|
|
|
|
.loading-spinner {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border: 4rpx solid $border-color;
|
|
border-top-color: $primary-color;
|
|
border-radius: 50%;
|
|
animation: spin 0.8s linear infinite;
|
|
margin-bottom: $spacing-md;
|
|
}
|
|
|
|
.loading-text {
|
|
font-size: $font-size-md;
|
|
color: $text-placeholder;
|
|
}
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
// 隐私政策内容
|
|
.privacy-content {
|
|
padding: $spacing-lg;
|
|
padding-bottom: calc(#{$spacing-xl} + env(safe-area-inset-bottom));
|
|
}
|
|
|
|
// 头部
|
|
.privacy-header {
|
|
margin-bottom: $spacing-lg;
|
|
padding-bottom: $spacing-lg;
|
|
border-bottom: 1rpx solid $border-light;
|
|
|
|
.privacy-title {
|
|
display: block;
|
|
font-size: $font-size-xl;
|
|
font-weight: $font-weight-bold;
|
|
color: $text-color;
|
|
text-align: center;
|
|
margin-bottom: $spacing-sm;
|
|
}
|
|
|
|
.update-time {
|
|
display: block;
|
|
font-size: $font-size-sm;
|
|
color: $text-placeholder;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
// 正文
|
|
.privacy-body {
|
|
.rich-content {
|
|
font-size: $font-size-md;
|
|
color: $text-color;
|
|
line-height: 1.8;
|
|
|
|
// 富文本内部样式
|
|
:deep(p) {
|
|
margin-bottom: $spacing-md;
|
|
}
|
|
|
|
:deep(h1),
|
|
:deep(h2),
|
|
:deep(h3),
|
|
:deep(h4) {
|
|
font-weight: $font-weight-bold;
|
|
color: $text-color;
|
|
margin-top: $spacing-lg;
|
|
margin-bottom: $spacing-md;
|
|
}
|
|
|
|
:deep(h1) {
|
|
font-size: $font-size-xl;
|
|
}
|
|
|
|
:deep(h2) {
|
|
font-size: $font-size-lg;
|
|
}
|
|
|
|
:deep(h3),
|
|
:deep(h4) {
|
|
font-size: $font-size-md;
|
|
}
|
|
|
|
:deep(ul),
|
|
:deep(ol) {
|
|
padding-left: $spacing-lg;
|
|
margin-bottom: $spacing-md;
|
|
}
|
|
|
|
:deep(li) {
|
|
margin-bottom: $spacing-xs;
|
|
}
|
|
|
|
:deep(a) {
|
|
color: $primary-color;
|
|
}
|
|
|
|
:deep(strong),
|
|
:deep(b) {
|
|
font-weight: $font-weight-bold;
|
|
}
|
|
}
|
|
|
|
.empty-content {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 200rpx;
|
|
|
|
text {
|
|
font-size: $font-size-md;
|
|
color: $text-placeholder;
|
|
}
|
|
}
|
|
}
|
|
</style>
|