const api = require('../../utils/api'); const auth = require('../../utils/auth'); const ROLE_LABELS = { student: '学员', member: '成员', teacher: '老师', leader: '组长', 'group_leader': '组长', admin: '管理员' }; const LOGIN_TYPE_LABELS = { wechat: '微信', phone: '手机号', admin: '管理员' }; Page({ data: { view: 'loading', profile: null, phoneLoading: false, phoneError: '', loadError: '', avatarSrc: '', avatarFallback: '明', roleLabel: '', loginTypeLabel: '', classGroups: [], avatarUploading: false }, onShow() { this.setData({ phoneError: '' }); this.loadPage(); }, onPullDownRefresh() { this.refresh().then(() => wx.stopPullDownRefresh()); }, refresh() { if (this.data.view !== 'profile') { return this.loadPage(); } return new Promise((resolve) => { api.request({ url: '/api/v1/profile' }) .then((res) => { this.applyProfile(res); resolve(); }) .catch(() => { wx.showToast({ title: '刷新失败', icon: 'none' }); resolve(); }); }); }, loadPage() { this.setData({ loadError: '' }); return auth.ensureLogin() .then((token) => { if (!token) { this.showPhoneLogin(); return null; } this.setData({ view: 'loading' }); return this.loadProfile(); }) .catch(() => { this.showPhoneLogin(); }); }, loadProfile() { return api.request({ url: '/api/v1/profile' }) .then((res) => { this.applyProfile(res); }) .catch((err) => { if (!auth.getToken()) { this.showPhoneLogin(); } else { this.setData({ view: 'loadError', loadError: (err && err.error) || '加载失败' }); } }); }, applyProfile(res) { const displayName = res.display_name || res.name || ''; const classGroups = (res.class_groups || []).map((g) => ({ class_id: g.class_id, class_code: g.class_code, period: g.period, group: g.group, role: this.roleLabel(g.role) })); this.setData({ view: 'profile', profile: res, phoneError: '', loadError: '', avatarSrc: this.fullUrl(res.wechat_avatar), avatarFallback: this.firstChar(displayName), roleLabel: this.roleLabel(res.role), loginTypeLabel: this.loginTypeLabel(res.login_type), classGroups }); }, showPhoneLogin() { this.setData({ view: 'phoneLogin', phoneLoading: false }); }, roleLabel(role) { return ROLE_LABELS[role] || role || '学员'; }, loginTypeLabel(type) { return LOGIN_TYPE_LABELS[type] || type || '微信'; }, fullUrl(rel) { if (!rel) return ''; return /^https?:\/\//i.test(rel) ? rel : api.STATIC_BASE_URL + rel; }, firstChar(str) { const t = (str && typeof str === 'string') ? str.trim() : ''; return t ? t.charAt(0) : '明'; }, onChooseAvatar(e) { const path = e.detail && e.detail.avatarUrl; console.log('[avatar] chooseAvatar ->', path); if (!path) { wx.showToast({ title: '未选择头像', icon: 'none' }); return; } this.setData({ avatarUploading: true }); wx.uploadFile({ url: api.BASE_URL + '/api/v1/profile/avatar', filePath: path, name: 'file', header: { Authorization: 'Bearer ' + auth.getToken() }, success: (res) => { console.log('[avatar] upload success', res.statusCode, res.data); let data = {}; try { data = JSON.parse(res.data); } catch (e) { data = {}; } if (data.success && data.wechat_avatar) { const newAvatar = data.wechat_avatar; const newUrl = this.fullUrl(newAvatar); this.setData({ 'profile.wechat_avatar': newAvatar, avatarSrc: newUrl }); wx.showToast({ title: '头像已更新', icon: 'success' }); } else { wx.showToast({ title: data.error || '上传失败', icon: 'none' }); } }, fail: (err) => { console.error('[avatar] upload fail', err); console.error('[avatar] filePath', path); wx.showToast({ title: '上传失败', icon: 'none' }); }, complete: () => { this.setData({ avatarUploading: false }); } }); }, onGetPhoneNumber(e) { if (this.data.phoneLoading) { return; } const phoneCode = e.detail && e.detail.code; if (!phoneCode) { const message = '未授权手机号,请点击上方按钮重试'; this.setData({ phoneError: message }); wx.showToast({ title: message, icon: 'none' }); return; } this.setData({ phoneLoading: true, phoneError: '' }); auth.loginWithPhone(phoneCode) .then(() => this.loadProfile()) .catch((err) => { const message = (err && err.error) || '手机号登录失败'; this.setData({ phoneLoading: false, phoneError: message }); wx.showToast({ title: message, icon: 'none', duration: 2500 }); }); }, onRetry() { this.loadPage(); }, logout() { wx.showModal({ title: '退出登录', content: '确定要退出当前账号吗?', confirmText: '退出', confirmColor: '#c0392b', success: (res) => { if (!res.confirm) { return; } api.request({ url: '/api/v1/auth/logout', method: 'POST' }).catch(() => {}); auth.clearToken(); wx.reLaunch({ url: '/pages/home/home' }); } }); } });