This commit is contained in:
“xHuPo” 2025-06-09 13:35:15 +08:00
commit 2b8870a40e
51 changed files with 5845 additions and 0 deletions

217
pages/mine/mine.js Normal file
View file

@ -0,0 +1,217 @@
// pages/mine/mine.js
const {
syncTokens,
getCloudTokens,
showToast,
showLoading,
hideLoading
} = require('../../utils/util');
Page({
/**
* 页面的初始数据
*/
data: {
loading: false,
uploading: false,
isLoggedIn: false,
userInfo: null,
currentYear: new Date().getFullYear()
},
onShow: function() {
// 每次显示页面时检查登录状态
const app = getApp();
this.setData({
isLoggedIn: !!app.globalData.token,
userInfo: app.globalData.userInfo
});
},
/**
* 数据备份
*/
uploadData: async function() {
// 检查登录状态
if (!this.data.isLoggedIn) {
showToast('请先登录');
return;
}
try {
const tokens = wx.getStorageSync('tokens') || [];
if (!tokens.length) {
showToast('未发现本地数据');
return;
}
// 显示确认对话框
const confirmed = await new Promise(resolve => {
wx.showModal({
title: '数据备份',
content: '确定备份本地数据到云端?',
confirmText: '确定',
confirmColor: '#ff9c10',
success: res => resolve(res.confirm)
});
});
if (!confirmed) return;
this.setData({ uploading: true });
showLoading('正在备份...');
// 同步到云端
await syncTokens(tokens);
showToast('数据备份成功', 'success');
} catch (error) {
console.error('数据备份失败:', error);
showToast('数据备份失败,请重试');
} finally {
this.setData({ uploading: false });
hideLoading();
}
},
/**
* 数据恢复
*/
restoreData: async function() {
// 检查登录状态
if (!this.data.isLoggedIn) {
showToast('请先登录');
return;
}
try {
this.setData({ loading: true });
showLoading('正在获取云端数据...');
// 获取云端数据
const cloudTokens = await getCloudTokens();
if (!cloudTokens || !cloudTokens.length) {
showToast('未发现备份数据');
return;
}
// 显示确认对话框
const confirmed = await new Promise(resolve => {
wx.showModal({
title: '云端数据恢复',
content: `发现${cloudTokens.length}条数据,确定使用云端数据覆盖本地记录?`,
confirmColor: '#ff9c10',
success: res => resolve(res.confirm)
});
});
if (!confirmed) return;
// 保存到本地
await wx.setStorageSync('tokens', cloudTokens);
showToast('数据恢复成功', 'success');
} catch (error) {
console.error('数据恢复失败:', error);
showToast('数据恢复失败,请重试');
} finally {
this.setData({ loading: false });
hideLoading();
}
},
/**
* 用户授权登录
*/
goAuth: async function() {
if (this.data.isLoggedIn) return;
try {
showLoading('登录中...');
const app = getApp();
await app.userLogin();
// 更新登录状态,使用默认值
this.setData({
isLoggedIn: !!app.globalData.token,
userInfo: {
avatarUrl: wx.getStorageSync('userAvatar') || '/images/default-avatar.png',
nickName: wx.getStorageSync('userNickName') || '微信用户'
}
});
showToast('登录成功', 'success');
} catch (error) {
console.error('登录失败:', error);
showToast('登录失败,请重试');
} finally {
hideLoading();
}
},
/**
* 处理头像选择
*/
onChooseAvatar: async function(e) {
const { avatarUrl } = e.detail;
try {
showLoading('更新头像中...');
// 更新头像
this.setData({
'userInfo.avatarUrl': avatarUrl
});
// 保存到本地存储
wx.setStorageSync('userAvatar', avatarUrl);
showToast('头像更新成功', 'success');
} catch (error) {
console.error('头像更新失败:', error);
showToast('头像更新失败,请重试');
} finally {
hideLoading();
}
},
/**
* 处理昵称修改
*/
onNicknameChange: function(e) {
const nickName = e.detail.value;
if (!nickName) return;
try {
// 更新昵称
this.setData({
'userInfo.nickName': nickName
});
// 保存到本地存储
wx.setStorageSync('userNickName', nickName);
} catch (error) {
console.error('昵称更新失败:', error);
showToast('昵称更新失败,请重试');
}
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
wx.stopPullDownRefresh();
},
/**
* 转发
*/
onShareAppMessage: function() {
return {
title: '支持云端备份的动态验证码',
path: '/pages/index/index',
imageUrl: '/images/share.png'
};
}
});

5
pages/mine/mine.json Normal file
View file

@ -0,0 +1,5 @@
{
"navigationStyle": "custom",
"enablePullDownRefresh": false,
"component": true
}

29
pages/mine/mine.wxml Normal file
View file

@ -0,0 +1,29 @@
<!--pages/mine/mine.wxml-->
<view class='mine' data-weui-theme="dark">
<view class="top-bg"></view>
<view class="user-bg">
<view class="userinfo">
<block wx:if="{{isLoggedIn && userInfo}}">
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
<image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="aspectFit"></image>
</button>
<input type="nickname" class="userinfo-nickname" placeholder="请输入昵称" value="{{userInfo.nickName}}" bindchange="onNicknameChange"/>
</block>
<block wx:else>
<button class="login-btn" bindtap="goAuth">
<image class="userinfo-avatar" src="/images/default-avatar.png" mode="aspectFit"></image>
<text class="userinfo-nickname">点击登录</text>
</button>
</block>
</view>
</view>
<view class="btns">
<button class="btn" loading="{{uploading}}" disabled="{{uploading}}" bindtap="uploadData">数据备份</button>
<button class="btn" loading="{{loading}}" disabled="{{loading}}" bindtap="restoreData">数据恢复</button>
</view>
<view class="footer">
<navigator url="/pages/info/info" hover-class="none">
<view>Copyright © {{currentYear}}</view>
</navigator>
</view>
</view>

121
pages/mine/mine.wxss Normal file
View file

@ -0,0 +1,121 @@
/* pages/info/info.wxss */
page {
background: #f5f5f5;
}
.mine{
z-index: 0;
}
.top-bg{
z-index: -1;
position: fixed;
top:0;
width: 100%;
height: 550rpx;
background: #f8f9fa;
background-image: -webkit-radial-gradient(top, circle cover, #ffffff 0%, #f8f9fa 80%);
background-image: -moz-radial-gradient(top, circle cover, #ffffff 0%, #f8f9fa 80%);
background-image: -o-radial-gradient(top, circle cover, #ffffff 0%, #f8f9fa 80%);
background-image: radial-gradient(top, circle cover, #ffffff 0%, #f8f9fa 80%);
}
.user-bg {
height: 550rpx;
display: flex;
justify-content: center;
padding-top: 40rpx;
overflow: hidden;
position: relative;
flex-direction: column;
align-items: center;
color: #333;
font-weight: 400;
text-shadow: 0 0 3px rgba(255, 255, 255, 0.3);
}
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20rpx;
}
.userinfo-avatar {
width: 150rpx;
height: 150rpx;
border-radius: 50%;
overflow: hidden;
margin: 20rpx auto;
justify-content: center;
}
.userinfo-nickname {
color: #666;
text-align: center;
background-color: transparent;
}
.avatar-wrapper {
padding: 0;
width: 150rpx !important;
height: 150rpx !important;
border-radius: 50%;
background-color: transparent;
margin: 20rpx auto;
}
.avatar-wrapper::after {
border: none;
}
.login-btn {
display: flex;
flex-direction: column;
align-items: center;
background-color: transparent;
padding: 0;
margin: 0;
line-height: normal;
}
.login-btn::after {
border: none;
}
input.userinfo-nickname {
width: 200rpx;
border-bottom: 1px solid rgba(102, 102, 102, 0.5);
padding: 5rpx 10rpx;
margin-top: 10rpx;
}
.user-bg text {
opacity: 0.9;
}
.user-bg image {
width: 400rpx;
height: 200rpx;
}
.btns{
z-index: 10;
position: relative;
}
.btn{
z-index: 10;
margin: 1rem;
border-radius: 100px;
background: #ffffff;
color: #ff9c10;
border: 2px solid #e8e8e8;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.btn[disabled]:not([type]){
background: #ffffff;
color: #ff9c10;
}
.footer{
position: absolute;
bottom: 20px;
margin-top: 10rem;
font-size: 12px;
text-align: center;
width: 100%;
color: #999;
}