414 lines
9.7 KiB
Vue
414 lines
9.7 KiB
Vue
<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>
|