var api = require('../../utils/api') var config = require('../../config/env') var i18n = require('../../i18n/index') var app = getApp() Page({ data: { userInfo: null, subscription: null, deviceCount: 0, subRemaining: 0, loading: true, editing: false, editNickname: '', editAvatarUrl: '', saving: false }, onShow: function () { i18n.bind(this) this.loadProfile() // 临时调试入口:仅设备已连接时显示(上线前随 ble-debug 页一并移除) var ble = require('../../services/ble') this.setData({ debugVisible: ble.isConnected() }) }, onOpenDebug: function () { wx.navigateTo({ url: '/pages/ble-debug/ble-debug' }) }, onLightInfo: function () { wx.navigateTo({ url: '/pages/light-info/light-info' }) }, onSwitchLanguage: function () { var self = this var supported = i18n.SUPPORTED var names = supported.map(function (l) { return i18n.LOCALE_NAMES[l] || l }) wx.showActionSheet({ itemList: names, success: function (res) { var target = supported[res.tapIndex] if (target && target !== i18n.getLocale()) { i18n.setLocale(target) i18n.bind(self) } } }) }, loadProfile: function () { var self = this self.setData({ loading: true }) var p1 = api.getProfile().then(function (profile) { self.setData({ userInfo: profile, deviceCount: profile.device_count || 0 }) }).catch(function (err) { console.error('getProfile failed', err) }) var p2 = api.getSubscription().then(function (sub) { var remaining = sub.remaining_days || 0 self.setData({ subscription: sub, subRemaining: remaining, subRemainingText: i18n.t('profile.remainDays', { days: remaining }) }) }).catch(function (err) { console.error('getSubscription failed', err) }) Promise.all([p1, p2]).then(function () { self.setData({ loading: false }) }) }, onManageDevice: function () { var self = this if (this.data.deviceCount > 0) { wx.showActionSheet({ itemList: [i18n.t('profile.unbindAction')], success: function (res) { if (res.tapIndex === 0) { wx.showModal({ title: i18n.t('profile.unbindConfirmTitle'), content: i18n.t('profile.unbindConfirmText'), success: function (modalRes) { if (modalRes.confirm) { api.unbindDevice().then(function () { wx.showToast({ title: i18n.t('profile.unbindDone'), icon: 'success' }) self.loadProfile() }).catch(function (err) { wx.showToast({ title: err.message || i18n.t('profile.unbindFailed'), icon: 'none' }) }) } } }) } } }) } else { wx.navigateTo({ url: '/pages/scan/scan' }) } }, onViewSubscription: function () { wx.navigateTo({ url: '/pages/subscribe-plans/subscribe-plans' }) }, onViewHistory: function () { wx.switchTab({ url: '/pages/history/history' }) }, onHelp: function () { wx.navigateTo({ url: '/pages/help/help' }) }, onContact: function () { wx.navigateTo({ url: '/pages/contact/contact' }) }, onEditProfile: function () { var info = this.data.userInfo || {} this.setData({ editing: true, editNickname: info.nickname || '', editAvatarUrl: info.avatar || '' }) }, onCancelEdit: function () { this.setData({ editing: false }) }, onEditNicknameInput: function (e) { this.setData({ editNickname: e.detail.value || '' }) }, onPickAvatar: function () { var self = this wx.chooseMedia({ count: 1, mediaType: ['image'], sourceType: ['album', 'camera'], success: function (res) { if (res.tempFiles && res.tempFiles[0]) { self.setData({ editAvatarUrl: res.tempFiles[0].tempFilePath }) } } }) }, uploadAvatar: function (tempPath) { return new Promise(function (resolve, reject) { var token = wx.getStorageSync('token') wx.uploadFile({ url: config.API_BASE + '/api/v1/user/avatar', filePath: tempPath, name: 'file', header: { Authorization: 'Bearer ' + token }, success: function (res) { try { var data = JSON.parse(res.data) if (data.code === 0 && data.data && data.data.avatar) { resolve(data.data.avatar) } else { reject(new Error(data.message || '上传失败')) } } catch (e) { reject(new Error('上传失败')) } }, fail: function () { reject(new Error('上传失败')) } }) }) }, onSaveProfile: function () { var self = this var nickname = (self.data.editNickname || '').trim() if (!nickname) { wx.showToast({ title: i18n.t('profile.nicknameRequired'), icon: 'none' }) return } self.setData({ saving: true }) var avatarUrl = self.data.editAvatarUrl var isLocalFile = avatarUrl && (avatarUrl.indexOf('wxfile://') === 0 || avatarUrl.indexOf('http://tmp') === 0) var avatarPromise = isLocalFile ? self.uploadAvatar(avatarUrl) : Promise.resolve(avatarUrl || '') avatarPromise.then(function (permanentUrl) { return api.updateProfile({ nickname: nickname, avatar: permanentUrl || '' }) }).then(function () { self.setData({ saving: false, editing: false }) wx.showToast({ title: i18n.t('common.saveSuccess'), icon: 'success' }) self.loadProfile() }).catch(function (err) { self.setData({ saving: false }) wx.showToast({ title: err.message || i18n.t('common.saveFailed'), icon: 'none' }) }) }, onLogout: function () { wx.showModal({ title: i18n.t('profile.logoutConfirmTitle'), content: i18n.t('profile.logoutConfirmText'), success: function (res) { if (res.confirm) { wx.removeStorageSync('token') wx.reLaunch({ url: '/pages/login/login' }) } } }) } })