Files
----/前端源码/uni-app/components/screens/ProfilePrivacy.vue

285 lines
6.4 KiB
Vue
Raw Permalink 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.
<template>
<view class="privacy-screen">
<view class="privacy-bg"></view>
<!-- 状态栏占位 -->
<view class="status-bar-placeholder"></view>
<!-- Header -->
<view class="privacy-header">
<view class="privacy-back-btn" @click="handleBack">
<text class="privacy-back-icon"></text>
</view>
<text class="privacy-title">隐私政策</text>
<view class="privacy-header-placeholder"></view>
</view>
<!-- Content -->
<scroll-view scroll-y class="privacy-content">
<view class="privacy-content-inner">
<view v-if="loading" class="privacy-loading">
<text class="privacy-loading-text">加载中...</text>
</view>
<template v-else-if="policy">
<!-- 标题和版本信息 -->
<view class="privacy-header-info">
<text class="privacy-doc-title">{{ policy.title }}</text>
<view class="privacy-meta">
<text class="privacy-meta-item">版本{{ policy.version }}</text>
<text class="privacy-meta-item">生效日期{{ formatDate(policy.effective_date) }}</text>
<text class="privacy-meta-item">更新时间{{ formatDate(policy.updated_at) }}</text>
</view>
</view>
<!-- 内容 -->
<view class="privacy-body">
<rich-text :nodes="formattedContent" class="privacy-rich-text"></rich-text>
</view>
</template>
<view v-else class="privacy-empty">
<text class="privacy-empty-icon">📄</text>
<text class="privacy-empty-text">暂无隐私政策</text>
</view>
<!-- 底部提示 -->
<view v-if="policy" class="privacy-footer">
<text class="privacy-footer-text">如有疑问请联系客服</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import { userApi } from "@/api";
declare const uni: any;
const emit = defineEmits<{
back: [];
}>();
const loading = ref(false);
const policy = ref<any>(null);
// 格式化内容将换行符转换为HTML
const formattedContent = computed(() => {
if (!policy.value?.content) return '';
// 简单的文本格式化:将换行符转换为<br>,段落添加样式
let content = policy.value.content;
// 如果内容包含HTML标签直接返回
if (content.includes('<')) {
return content;
}
// 否则进行简单格式化
content = content
.replace(/\n\n/g, '</p><p>')
.replace(/\n/g, '<br>')
.replace(/^(.+)$/, '<p>$1</p>');
return content;
});
const loadPrivacyPolicy = async () => {
loading.value = true;
try {
const res = await userApi.getPrivacyPolicy();
console.log('getPrivacyPolicy response:', res);
policy.value = res;
} catch (e: any) {
console.error('loadPrivacyPolicy error:', e);
uni.showToast({ title: e.msg || "加载失败", icon: "none" });
} finally {
loading.value = false;
}
};
const formatDate = (dateStr: string) => {
if (!dateStr) return "";
return dateStr.split("T")[0].replace(/-/g, ".");
};
const handleBack = () => {
emit('back');
};
onMounted(() => loadPrivacyPolicy());
</script>
<style scoped>
.privacy-screen {
height: 100%;
display: flex;
flex-direction: column;
background-color: #f0efe9;
position: relative;
}
.status-bar-placeholder {
height: var(--status-bar-height, 0);
width: 100%;
flex-shrink: 0;
}
.privacy-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
opacity: 0.3;
background-image: url("https://www.transparenttextures.com/patterns/rice-paper.png");
}
/* Header */
.privacy-header {
position: relative;
z-index: 10;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
border-bottom: 1rpx solid #dcd3c9;
background-color: rgba(253, 251, 247, 0.8);
backdrop-filter: blur(10rpx);
}
.privacy-back-btn {
width: 64rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
padding: 0;
margin-left: -16rpx;
}
.privacy-back-icon {
font-size: 48rpx;
color: #5a5a5a;
font-weight: 300;
}
.privacy-title {
font-size: 32rpx;
font-weight: 700;
color: #2c2c2c;
letter-spacing: 0.2em;
}
.privacy-header-placeholder {
width: 64rpx;
}
/* Content */
.privacy-content {
flex: 1;
height: 0;
position: relative;
z-index: 10;
}
.privacy-content-inner {
padding: 32rpx;
}
/* Loading */
.privacy-loading {
display: flex;
align-items: center;
justify-content: center;
height: 400rpx;
}
.privacy-loading-text {
font-size: 28rpx;
color: #999;
}
/* Header Info */
.privacy-header-info {
background-color: #fffdf9;
border-radius: 24rpx;
border: 1rpx solid #e5e5e5;
padding: 32rpx;
margin-bottom: 24rpx;
}
.privacy-doc-title {
font-size: 36rpx;
font-weight: 700;
color: #2c2c2c;
display: block;
margin-bottom: 24rpx;
text-align: center;
}
.privacy-meta {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.privacy-meta-item {
font-size: 24rpx;
color: #999;
text-align: center;
}
/* Body */
.privacy-body {
background-color: #fffdf9;
border-radius: 24rpx;
border: 1rpx solid #e5e5e5;
padding: 32rpx;
margin-bottom: 24rpx;
}
.privacy-rich-text {
font-size: 28rpx;
color: #2c2c2c;
line-height: 1.8;
}
/* Empty */
.privacy-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 400rpx;
}
.privacy-empty-icon {
font-size: 96rpx;
opacity: 0.3;
margin-bottom: 24rpx;
}
.privacy-empty-text {
font-size: 28rpx;
color: #999;
}
/* Footer */
.privacy-footer {
text-align: center;
padding: 32rpx 0;
}
.privacy-footer-text {
font-size: 24rpx;
color: #999;
}
</style>