修正了 pages 名为拼音的问题

This commit is contained in:
2026-06-13 10:44:02 +08:00
parent 76cc4ac55e
commit 296e41a8a7
249 changed files with 29660 additions and 29505 deletions

227
pages/edit/edit.js Normal file
View File

@@ -0,0 +1,227 @@
// pages/edit/edit.js
const app = getApp()
import upload from '../../utils/upload.js'
Page({
data: {
avatarUrl: '',
uid: '',
nicheng: '',
phone: '',
originalAvatar: '',
originalNicheng: '',
isSaving: false,
hasChanges: false,
newAvatarFile: null,
isLoading: true,
isAvatarActive: false,
nicknameError: ''
},
onLoad() {
wx.setNavigationBarTitle({ title: '编辑资料' })
this.loadUserData()
},
onShow() {
this.registerNotificationComponent();
},
registerNotificationComponent() {
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
};
}
},
// 加载用户数据
loadUserData() {
try {
const uid = wx.getStorageSync('uid') || ''
const nicheng = wx.getStorageSync('nicheng') || ''
const phone = wx.getStorageSync('phone') || ''
const touxiang = wx.getStorageSync('touxiang') || ''
const ossImageUrl = app.globalData.ossImageUrl || ''
const defaultAvatar = app.globalData.morentouxiang || ''
let avatarUrl = ''
if (touxiang) {
avatarUrl = touxiang.startsWith('http') ? touxiang : `${ossImageUrl}${touxiang}`
} else if (defaultAvatar) {
avatarUrl = defaultAvatar.startsWith('http') ? defaultAvatar : `${ossImageUrl}${defaultAvatar}`
}
this.setData({
avatarUrl,
uid,
nicheng,
phone,
originalAvatar: touxiang,
originalNicheng: nicheng,
isLoading: false
})
} catch (error) {
console.error('加载用户数据失败:', error)
this.setData({ isLoading: false })
wx.showToast({ title: '加载数据失败', icon: 'none' })
}
},
// 微信头像选择
onChooseAvatar(e) {
const avatarTempPath = e.detail.avatarUrl
this.setData({
avatarUrl: avatarTempPath,
newAvatarFile: avatarTempPath
}, () => {
this.checkChanges()
})
},
chooseAvatar() {
this.setData({ isAvatarActive: true })
setTimeout(() => {
this.setData({ isAvatarActive: false })
}, 500)
},
// 昵称输入
onNicknameInput(e) {
const value = e.detail.value.trim()
this.setData({
nicheng: value,
nicknameError: ''
}, () => {
this.checkChanges()
})
},
// 检查变化
checkChanges() {
const { originalNicheng, nicheng, newAvatarFile } = this.data;
const hasChanges = (nicheng !== originalNicheng) || (newAvatarFile !== null);
this.setData({ hasChanges });
},
// 保存
async onSave() {
if (!this.data.hasChanges) {
wx.showToast({ title: '没有需要保存的更改', icon: 'none' });
return;
}
if (this.data.isSaving) return;
// 验证数据
if (!this.validateData()) return;
this.setData({ isSaving: true });
wx.showLoading({ title: '保存中...', mask: true });
try {
const formData = {};
if (this.data.nicheng !== this.data.originalNicheng) {
formData.nicheng = this.data.nicheng;
}
const res = await upload({
url: '/yonghu/xiugai',
formData,
filePath: this.data.newAvatarFile,
fileName: 'avatar'
});
if (res.statusCode === 200 && res.data) {
const response = res.data;
if (response.code === 0) {
await this.handleUpdateSuccess(response.data);
} else {
throw new Error(response.msg || '保存失败');
}
} else {
throw new Error('网络错误');
}
} catch (error) {
console.error('保存失败:', error);
if (error.message.includes('认证失败') || error.message.includes('401')) {
wx.showModal({
title: '提示',
content: '登录已过期,请重新登录',
complete: (res) => {
if (res.confirm) {
wx.removeStorageSync('token');
wx.removeStorageSync('userInfo');
wx.switchTab({ url: '/pages/mine/mine' });
}
}
});
} else {
wx.showToast({ title: error.message || '保存失败', icon: 'none' });
}
} finally {
wx.hideLoading();
this.setData({ isSaving: false });
}
},
// 验证数据
validateData() {
const { nicheng } = this.data;
let hasError = false;
this.setData({ nicknameError: '' });
if (nicheng && nicheng.length > 20) {
this.setData({ nicknameError: '昵称不能超过20个字符' });
hasError = true;
}
if (nicheng !== this.data.originalNicheng && nicheng.trim() === '') {
this.setData({ nicknameError: '昵称不能为空' });
hasError = true;
}
if (hasError) {
if (this.data.nicknameError) {
wx.showToast({ title: this.data.nicknameError, icon: 'none' });
}
return false;
}
return true;
},
// 更新成功处理
async handleUpdateSuccess(updateData) {
if (updateData.touxiang !== undefined && updateData.touxiang !== null) {
wx.setStorageSync('touxiang', updateData.touxiang);
}
if (updateData.nicheng !== undefined && updateData.nicheng !== null) {
wx.setStorageSync('nicheng', updateData.nicheng);
}
if (updateData.nicheng) {
app.globalData.userNicheng = updateData.nicheng;
}
const ossImageUrl = app.globalData.ossImageUrl || '';
let avatarUrl = this.data.avatarUrl;
if (updateData.touxiang) {
avatarUrl = updateData.touxiang.startsWith('http') ?
updateData.touxiang : `${ossImageUrl}${updateData.touxiang}`;
}
this.setData({
avatarUrl,
originalAvatar: updateData.touxiang || this.data.originalAvatar,
originalNicheng: updateData.nicheng || this.data.originalNicheng,
newAvatarFile: null,
hasChanges: false
});
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
}
});

10
pages/edit/edit.json Normal file
View File

@@ -0,0 +1,10 @@
{
"usingComponents": {
"global-notification": "/components/global-notification/global-notification"
},
"navigationBarTitleText": "编辑资料",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"backgroundColor": "#f8f9fa",
"enablePullDownRefresh": false
}

69
pages/edit/edit.wxml Normal file
View File

@@ -0,0 +1,69 @@
<!-- pages/edit/edit.wxml -->
<view class="xiugai-page">
<!-- 头像区域(未改动) -->
<view class="avatar-section">
<view class="avatar-container {{isAvatarActive ? 'active' : ''}}">
<!-- 新增:头像包装器,把头像+光晕包在一起,和提示文字隔离 -->
<view class="avatar-image-wrapper">
<image class="avatar-image" src="{{avatarUrl}}" mode="aspectFill"></image>
<view class="avatar-halo"></view>
</view>
<view class="avatar-hint">点击更换头像</view>
</view>
<button
class="avatar-trigger-button"
open-type="chooseAvatar"
bindchooseavatar="onChooseAvatar"
hover-class="none"
></button>
</view>
<!-- 表单区域 -->
<view class="form-section">
<!-- UID只读 -->
<view class="form-item">
<view class="item-label">UID</view>
<view class="item-value readonly">{{uid || '••••••'}}</view>
</view>
<!-- 昵称(可编辑) -->
<view class="form-item">
<view class="item-label">昵称</view>
<view class="input-container">
<input
class="item-input {{nicknameError ? 'error' : ''}}"
type="text"
placeholder="请输入昵称"
placeholder-class="placeholder"
maxlength="20"
value="{{nicheng}}"
bindinput="onNicknameInput"
/>
<view class="error-hint" wx:if="{{nicknameError}}">{{nicknameError}}</view>
</view>
</view>
<!-- 手机号(只读展示,不可修改) -->
<view class="form-item">
<view class="item-label">手机号</view>
<view class="item-value readonly">{{phone || '未绑定'}}</view>
</view>
</view>
<!-- 保存按钮(未改动) -->
<button
class="save-btn"
bindtap="onSave"
hover-class="btn-hover"
disabled="{{isSaving || !hasChanges}}"
>
<view class="btn-content">
{{isSaving ? '保存中...' : '确认保存'}}
<view class="btn-sparkle" wx:if="{{!isSaving}}"></view>
</view>
</button>
<view class="safe-area"></view>
<global-notification id="global-notification" />
</view>

380
pages/edit/edit.wxss Normal file
View File

@@ -0,0 +1,380 @@
/* pages/edit/edit.wxss */
page {
background: linear-gradient(135deg, #fffaf0 0%, #f0f8ff 100%);
min-height: 100vh;
}
.xiugai-page {
padding: 30rpx 40rpx 100rpx;
}
/* 头像区域样式 */
.avatar-section {
position: relative;
display: flex;
justify-content: center;
margin-bottom: 60rpx;
padding-top: 30rpx;
}
.avatar-container {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
/* 头像包装器 */
.avatar-image-wrapper {
position: relative;
width: 200rpx;
height: 200rpx;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
/* 头像图片 */
.avatar-image {
width: 200rpx;
height: 200rpx;
border-radius: 50%;
border: 6rpx solid #fff;
background-color: #f8f9fa;
z-index: 2;
position: relative;
animation: gentleBreath 4s ease-in-out infinite;
box-shadow:
0 0 0 1rpx rgba(0, 200, 83, 0.3),
0 15rpx 40rpx rgba(0, 200, 83, 0.15);
box-sizing: border-box;
}
/* 光晕 */
.avatar-halo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 228rpx;
height: 228rpx;
border-radius: 50%;
background: transparent;
border: 3rpx solid transparent;
animation: gentleGlow 2s ease-in-out infinite, colorShift 3s ease-in-out infinite;
opacity: 0;
z-index: 1;
pointer-events: none;
}
/* 像素点环绕 */
.avatar-image-wrapper::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 230rpx;
height: 230rpx;
border-radius: 50%;
background:
radial-gradient(circle at 30% 30%, rgba(0, 200, 83, 0.1) 0%, transparent 50%),
radial-gradient(circle at 70% 70%, rgba(100, 221, 23, 0.1) 0%, transparent 50%);
animation: pixelOrbit 4s linear infinite;
z-index: 0;
pointer-events: none;
}
/* 温和的呼吸动画 */
@keyframes gentleBreath {
0%, 100% {
transform: scale(1);
box-shadow:
0 0 0 2rpx rgba(0, 200, 83, 0.4),
0 15rpx 40rpx rgba(0, 200, 83, 0.2);
}
50% {
transform: scale(1.03);
box-shadow:
0 0 0 5rpx rgba(0, 200, 83, 0.6),
0 20rpx 50rpx rgba(0, 200, 83, 0.3);
}
}
/* 光晕动画 */
@keyframes gentleGlow {
0%, 100% {
opacity: 0;
transform: translate(-50%, -50%) scale(0.98);
}
50% {
opacity: 1;
transform: translate(-50%, -50%) scale(1.05);
}
}
@keyframes colorShift {
0% {
border-color: rgba(0, 200, 83, 0.5);
}
33% {
border-color: rgba(100, 221, 23, 0.5);
}
66% {
border-color: rgba(0, 255, 153, 0.5);
}
100% {
border-color: rgba(0, 200, 83, 0.5);
}
}
@keyframes pixelOrbit {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
/* 更换提示 */
.avatar-hint {
margin-top: 25rpx;
font-size: 28rpx;
color: #666;
padding: 12rpx 30rpx;
background: rgba(255, 255, 255, 0.9);
border-radius: 25rpx;
border: 1rpx solid #eee;
box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05);
position: relative;
overflow: hidden;
}
.avatar-hint::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2rpx;
background: linear-gradient(90deg, transparent, #00C853, transparent);
animation: hintGlow 2s ease-in-out infinite;
}
@keyframes hintGlow {
0%, 100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
/* 点击特效 */
.avatar-container.active .avatar-image {
animation: clickScale 0.5s ease;
}
@keyframes clickScale {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(0.95);
}
}
/* 下载状态 */
.avatar-container.downloading .avatar-image {
opacity: 0.7;
filter: grayscale(30%);
}
/* 透明功能按钮 */
.avatar-trigger-button {
position: absolute;
top: 30rpx;
left: 50%;
transform: translateX(-50%);
width: 200rpx;
height: 200rpx;
border-radius: 50%;
z-index: 100;
background: transparent;
border: none;
padding: 0;
margin: 0;
opacity: 0;
line-height: 1;
font-size: 0;
}
.avatar-trigger-button::after {
border: none;
}
/* 表单区域 */
.form-section {
border-radius: 25rpx;
margin-bottom: 50rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.08);
border: 1rpx solid #f0f0f0;
}
.form-item {
display: flex;
align-items: center;
padding-left: 40rpx;
border-bottom: 1rpx solid #f0f0f0;
min-height: 110rpx;
}
.form-item:last-child {
border-bottom: none;
}
.item-label {
width: 150rpx;
font-size: 32rpx;
color: #333;
font-weight: 500;
flex-shrink: 0;
}
.item-value.readonly {
flex: 1;
font-size: 32rpx;
color: #666;
}
/* .item-input — 与全局 .input-inline 完全相同,已移除 */
.placeholder {
color: #ccc;
font-size: 30rpx;
}
.input-container {
flex: 1;
display: flex;
flex-direction: column;
}
.item-input.error {
border-bottom: 2rpx solid #ff4d4f;
animation: shake 0.5s;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-2rpx); }
20%, 40%, 60%, 80% { transform: translateX(2rpx); }
}
.error-hint {
font-size: 24rpx;
color: #ff4d4f;
margin-top: 8rpx;
padding-left: 10rpx;
animation: fadeIn 0.3s;
}
.phone-hint {
font-size: 24rpx;
color: #00C853;
margin-top: 8rpx;
padding-left: 10rpx;
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10rpx); }
to { opacity: 1; transform: translateY(0); }
}
/* 保存按钮 */
.save-btn {
height: 100rpx;
line-height: 100rpx;
border-radius: 50rpx;
background: linear-gradient(135deg, #00C853 0%, #64DD17 100%);
font-weight: 500;
box-shadow: 0 15rpx 40rpx rgba(0, 200, 83, 0.25);
margin-top: 30rpx;
}
.save-btn[disabled] {
background: linear-gradient(135deg, #cccccc 0%, #aaaaaa 100%);
color: #999;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1);
}
.btn-content {
position: relative;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.btn-sparkle {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.2) 50%,
transparent 100%
);
animation: sparkleMove 2.5s ease-in-out infinite;
z-index: 1;
}
@keyframes sparkleMove {
0% { left: -100%; }
100% { left: 100%; }
}
.btn-hover {
opacity: 0.9;
transform: scale(0.98);
}
/* 手机号获取按钮 */
.phone-row {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
}
.phone-value {
font-size: 32rpx;
color: #333;
flex: 1;
}
.get-phone-btn {
flex-shrink: 0;
margin-left: 20rpx;
padding: 10rpx 24rpx;
background: #4a6cf7;
line-height: 1.4;
height: 60rpx;
}
.phone-btn-hover {
opacity: 0.8;
}
.safe-area {
height: 100rpx;
width: 100%;
}