Files
doodle-mini/miniprogram/pages/profile/profile.ts
T

223 lines
6.8 KiB
TypeScript

import { uploadAsset, memberStats } from '../../services/member-api';
import { getUser as getServerUser, startAccount } from '../../utils/auth';
import { disablePageShareMenu } from '../../base/pageMixin';
import { APP_VERSION } from '../../config/config';
import {
getCachedUser,
getUser,
type UserInfo,
updateUserProfile,
} from '../../utils/auth';
Page({
DEFAULT_AVATAR_URL: '/assets/imgs/doodle-head.png',
data: {
userName: '微信用户',
avatarUrl: '',
isDevEnv: false,
printCount: 0,
favoriteCount: 0,
version: APP_VERSION,
showProfileEditor: false,
draftNickName: '',
draftAvatarUrl: '/assets/imgs/doodle-head.png',
isSavingProfile: false,
serverAccountActionRequired: false,
isStartingAccount: false,
},
onLoad() {
disablePageShareMenu();
this.syncUserInfoFromApp();
const isDevEnv =
wx.getAccountInfoSync().miniProgram.envVersion === 'develop';
this.setData({
isDevEnv,
});
},
onShow() {
void this.checkServerAccount();
this.syncUserInfoFromApp();
void this.refreshStats();
},
/** 正常登录始终静默;账户不存在时才展示用户主动重新开始的入口。 */
async checkServerAccount() {
try {
await getServerUser();
this.setData({ serverAccountActionRequired: false });
} catch (error) {
const reason = (error as { reason?: string }).reason;
this.setData({
serverAccountActionRequired:
reason === 'ACCOUNT_NOT_FOUND' ||
reason === 'ACCOUNT_RESTART_REQUIRED',
});
}
},
async onStartServerAccount() {
if (this.data.isStartingAccount) return;
this.setData({ isStartingAccount: true });
try {
await startAccount();
this.setData({ serverAccountActionRequired: false });
wx.showToast({ title: '账户已就绪', icon: 'success' });
} catch {
wx.showToast({ title: '账户暂不可用,请稍后重试', icon: 'none' });
} finally {
this.setData({ isStartingAccount: false });
}
},
async syncUserInfoFromApp() {
const app = getApp<IAppOption>();
const cachedUser = app.globalData.user || getCachedUser();
if (cachedUser) this.applyUserInfo(cachedUser);
else
this.setData({
userName: '微信用户',
avatarUrl: this.DEFAULT_AVATAR_URL,
printCount: 0,
favoriteCount: 0,
});
try {
const latestUser = await getUser();
this.applyUserInfo(latestUser);
} catch (error) {
console.error('获取用户信息失败', error);
}
},
applyUserInfo(user: UserInfo) {
const userName = user.nickName?.trim() || '微信用户';
const avatarUrl =
user.avatarUrl || (this as any).DEFAULT_AVATAR_URL || '';
this.setData({
userName,
avatarUrl,
draftNickName: userName === '微信用户' ? '' : userName,
draftAvatarUrl: avatarUrl,
});
},
async refreshStats() {
try {
const stats = await memberStats();
const { downloadCount: printCount, favoriteCount } = stats;
this.setData({ printCount, favoriteCount });
} catch {
this.setData({ printCount: 0, favoriteCount: 0 });
}
},
onOpenProfileEditor() {
this.setData({
showProfileEditor: true,
draftNickName:
this.data.userName === '微信用户' ? '' : this.data.userName,
draftAvatarUrl: this.data.avatarUrl,
});
},
onCloseProfileEditor() {
if (this.data.isSavingProfile) return;
this.setData({ showProfileEditor: false });
},
onChooseAvatar(e: WechatMiniprogram.CustomEvent<{ avatarUrl?: string }>) {
const avatarUrl = e.detail?.avatarUrl || '';
if (!avatarUrl) return;
this.setData({ draftAvatarUrl: avatarUrl });
},
onNicknameInput(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
const nickName = (e.detail?.value || '').trim();
this.setData({ draftNickName: nickName });
},
async onSubmitProfile() {
if (this.data.isSavingProfile) return;
const nickName = this.data.draftNickName.trim();
if (!nickName) {
wx.showToast({ title: '请输入昵称', icon: 'none' });
return;
}
if (!this.data.draftAvatarUrl) {
wx.showToast({ title: '请选择头像', icon: 'none' });
return;
}
this.setData({ isSavingProfile: true });
try {
const avatarAssetId = await this.persistAvatarIfNeeded(
this.data.draftAvatarUrl,
);
const user = await updateUserProfile({
nickName,
avatarAssetId,
});
this.applyUserInfo(user);
this.setData({ showProfileEditor: false });
wx.showToast({ title: '资料已更新', icon: 'success' });
} catch (error) {
console.error('更新用户资料失败', error);
wx.showToast({ title: '更新失败,请稍后重试', icon: 'none' });
} finally {
this.setData({ isSavingProfile: false });
}
},
async persistAvatarIfNeeded(avatarUrl: string): Promise<string | null> {
const user = await getUser();
if (!avatarUrl || avatarUrl === this.DEFAULT_AVATAR_URL) return null;
if (avatarUrl === user.avatarUrl) return user.avatarAssetId || null;
return (await uploadAsset(avatarUrl, 'avatar')).id;
},
onGoToDownloads() {
wx.setStorageSync('favorites_active_tab', 'downloads');
wx.switchTab({ url: '/pages/favorites/favorites' });
},
onGoToFavorites() {
wx.setStorageSync('favorites_active_tab', 'favorites');
wx.switchTab({ url: '/pages/favorites/favorites' });
},
onGoToGuide() {
wx.navigateTo({ url: '/supportPages/guide/guide' });
},
onGoToPrintSettings() {
wx.showToast({ title: '功能开发中', icon: 'none' });
},
onGoToSettings() {
wx.navigateTo({ url: '/supportPages/settings/settings' });
},
onGoToDebug() {
wx.navigateTo({ url: '/supportPages/debug/debug' });
},
onGoToFeedback() {
wx.showToast({ title: '功能开发中', icon: 'none' });
},
onGoToAbout() {
wx.showToast({ title: '涂鸦丫练习纸', icon: 'none' });
},
onGoToPremium() {
wx.showToast({ title: '功能开发中', icon: 'none' });
},
});