ai-clone/frontend-ai/pages/settings/settings.vue
2026-03-05 14:29:21 +08:00

414 lines
9.7 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="settings-container">
<!-- 设置列表 -->
<view class="settings-content">
<!-- 账号设置 -->
<view class="setting-group">
<view class="group-title">账号设置</view>
<view class="setting-item" @click="editProfile">
<view class="item-left">
<text class="item-icon">👤</text>
<text class="item-text">编辑资料</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="changePassword">
<view class="item-left">
<text class="item-icon">🔐</text>
<text class="item-text">修改密码</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="bindPhone">
<view class="item-left">
<text class="item-icon">📱</text>
<text class="item-text">绑定手机</text>
</view>
<view class="item-right">
<text class="item-value">{{ phone || '未绑定' }}</text>
<text class="item-arrow"></text>
</view>
</view>
</view>
<!-- 隐私设置 -->
<view class="setting-group">
<view class="group-title">隐私设置</view>
<view class="setting-item" @click="clearCache">
<view class="item-left">
<image src="/static/iconfont/delete.svg" class="delete-icon" mode="aspectFit"></image>
<text class="item-text">清除缓存</text>
</view>
<view class="item-right">
<text class="item-value">{{ cacheSize }}</text>
<text class="item-arrow"></text>
</view>
</view>
<view class="setting-item" @click="showPrivacy">
<view class="item-left">
<text class="item-icon">🔒</text>
<text class="item-text">隐私政策</text>
</view>
<text class="item-arrow"></text>
</view>
<view class="setting-item" @click="showAgreement">
<view class="item-left">
<text class="item-icon">📄</text>
<text class="item-text">用户协议</text>
</view>
<text class="item-arrow"></text>
</view>
</view>
<!-- 关于 -->
<view class="setting-group">
<view class="group-title">关于</view>
<view class="setting-item" @click="showAbout">
<view class="item-left">
<text class="item-icon"></text>
<text class="item-text">关于我们</text>
</view>
<text class="item-arrow"></text>
</view>
</view>
<!-- 退出登录 -->
<view class="logout-section">
<button class="logout-btn" @click="handleLogout">退出登录</button>
</view>
</view>
</view>
</template>
<script>
import { API_BASE, API_ENDPOINTS } from '@/config/api.js';
export default {
data() {
return {
phone: '',
cacheSize: '12.5MB',
userInfo: {
nickname: '',
avatar: ''
},
useWechatService: true,
servicePhone: ''
};
},
onLoad() {
this.loadSettings();
this.loadServiceConfig();
this.calculateCacheSize();
},
methods: {
loadSettings() {
const userInfo = uni.getStorageSync('userInfo');
if (userInfo && userInfo.phone) {
this.phone = userInfo.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
},
editProfile() {
uni.navigateTo({
url: '/pages/profile/edit-profile'
});
},
changePassword() {
uni.navigateTo({
url: '/pages/settings/change-password'
});
},
bindPhone() {
uni.navigateTo({
url: '/pages/settings/bind-phone'
});
},
clearCache() {
uni.showModal({
title: '清除缓存',
content: '确定要清除所有缓存吗?此操作将清除应用缓存数据(不包括登录信息)。',
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: '清除中...'
});
try {
// 获取所有存储的 key
const storageInfo = uni.getStorageInfoSync();
const keys = storageInfo.keys || [];
// 需要保留的 key登录相关数据
const keepKeys = ['token', 'userId', 'userInfo', 'userNickname', 'userPhone', 'username', 'avatarUrl', 'nickname'];
// 清除不需要保留的缓存数据
keys.forEach(key => {
if (!keepKeys.includes(key)) {
uni.removeStorageSync(key);
}
});
// 清除文件缓存(如果支持)
// #ifdef APP-PLUS
plus.cache.clear(() => {
console.log('文件缓存已清除');
});
// #endif
// 清除图片缓存
// #ifdef APP-PLUS
plus.io.resolveLocalFileSystemURL('_doc/cache/', (entry) => {
entry.removeRecursively(() => {
console.log('图片缓存已清除');
}, (err) => {
console.error('清除图片缓存失败:', err);
});
}, (err) => {
// 目录不存在,忽略
});
// #endif
setTimeout(() => {
uni.hideLoading();
this.cacheSize = '0MB';
uni.showToast({
title: '清除成功',
icon: 'success'
});
// 重新计算缓存大小
this.calculateCacheSize();
}, 1000);
} catch (error) {
console.error('清除缓存失败:', error);
uni.hideLoading();
uni.showToast({
title: '清除失败,请重试',
icon: 'none'
});
}
}
}
});
},
// 计算缓存大小
calculateCacheSize() {
try {
const storageInfo = uni.getStorageInfoSync();
// 估算存储大小(每个 key-value 对大约占用一定空间)
// 这里使用一个简单的估算方法
let totalSize = 0;
const keys = storageInfo.keys || [];
keys.forEach(key => {
const value = uni.getStorageSync(key);
if (value) {
// 估算JSON 字符串长度 * 2 字节UTF-16
const jsonStr = JSON.stringify(value);
totalSize += jsonStr.length * 2;
}
});
// 转换为 MB
const sizeMB = (totalSize / 1024 / 1024).toFixed(2);
this.cacheSize = sizeMB > 0 ? `${sizeMB}MB` : '0MB';
} catch (error) {
console.error('计算缓存大小失败:', error);
this.cacheSize = '0MB';
}
},
showPrivacy() {
uni.navigateTo({
url: '/pages/settings/privacy-policy'
});
},
showAgreement() {
uni.navigateTo({
url: '/pages/settings/user-agreement'
});
},
showAbout() {
uni.navigateTo({
url: '/pages/settings/about'
});
},
async loadServiceConfig() {
try {
// 先从本地存储读取缓存
const cachedConfig = uni.getStorageSync('appConfig');
if (cachedConfig && cachedConfig.common) {
this.useWechatService = cachedConfig.common.useWechatService !== false;
this.servicePhone = cachedConfig.common.servicePhone || '';
}
// 从后端获取最新配置(公开接口,不需要认证)
const res = await uni.request({
url: `${API_BASE}${API_ENDPOINTS.config.getAppConfig}`,
method: 'GET',
header: {
'Content-Type': 'application/json'
// 不添加认证头,因为这是公开接口
}
});
// 兼容不同平台的返回格式:可能是 [error, res] 或直接是 res
const response = Array.isArray(res) ? res[1] : res;
if (response && response.data && response.data.success && response.data.data) {
const config = response.data.data;
// 保存到本地存储
uni.setStorageSync('appConfig', config);
// 更新页面数据
if (config.common) {
this.useWechatService = config.common.useWechatService !== false;
this.servicePhone = config.common.servicePhone || '';
}
}
} catch (error) {
console.error('加载配置失败:', error);
}
},
callService() {
uni.makePhoneCall({
phoneNumber: this.servicePhone
});
},
handleLogout() {
uni.showModal({
title: '退出登录',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
// 清除所有本地存储的用户相关数据
uni.removeStorageSync('token');
uni.removeStorageSync('userId');
uni.removeStorageSync('userInfo');
uni.removeStorageSync('nickname');
uni.removeStorageSync('userNickname');
uni.removeStorageSync('userPhone');
uni.removeStorageSync('username');
uni.removeStorageSync('avatarUrl');
uni.showToast({
title: '已退出登录',
icon: 'success',
duration: 1500
});
setTimeout(() => {
uni.reLaunch({
url: '/pages/login/login'
});
}, 1500);
}
}
});
}
}
};
</script>
<style lang="scss" scoped>
.settings-container {
min-height: 100vh;
background: #FDF8F2;
}
/* 设置内容 */
.settings-content {
padding: 30upx;
}
.setting-group {
background: white;
border-radius: 30upx;
padding: 0 30upx;
margin-bottom: 30upx;
box-shadow: 0 8upx 30upx rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.group-title {
font-size: 26upx;
color: #999;
padding: 30upx 0 20upx;
}
.setting-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30upx 0;
border-bottom: 1upx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.item-left {
display: flex;
align-items: center;
flex: 1;
.item-icon {
font-size: 40upx;
margin-right: 20upx;
}
.item-text {
font-size: 28upx;
color: #333;
}
}
.item-right {
display: flex;
align-items: center;
.item-value {
font-size: 26upx;
color: #999;
margin-right: 10upx;
}
}
.item-arrow {
font-size: 32upx;
color: #999;
}
}
/* 退出登录 */
.logout-section {
padding: 30upx 0;
}
.logout-btn {
width: 100%;
padding: 30upx;
background: white;
border: 2upx solid #ff4757;
border-radius: 50upx;
color: #ff4757;
font-size: 32upx;
font-weight: 600;
box-shadow: 0 8upx 30upx rgba(255, 71, 87, 0.2);
&:active {
background: #ff4757;
color: white;
}
}
</style>