// Personal Profile Page Logic const app = getApp(); const config = require('../../config/config.js'); const apiClient = require('../../utils/api-client.js'); const authManager = require('../../utils/auth.js'); const imageCacheManager = require('../../utils/image-cache-manager.js'); Page({ data: { // User Information userInfo: null, // Statistics stats: { friendsCount: 0, postsCount: 0, visitorsCount: 0, likesCount: 0, groupsCount: 0 }, // App Information newMomentsCount: 0, fileSize: '0MB', cacheSize: '0MB', appVersion: '', // UI State showQRModal: false, selectedTab: 'gender', // System Adaptation Information systemInfo: {}, statusBarHeight: 0, menuButtonHeight: 0, menuButtonTop: 0, navBarHeight: 0, windowHeight: 0, safeAreaBottom: 0, // Debug Information debugInfo: { hasGlobalUserInfo: false, hasToken: false, tokenLength: 0, hasLocalStorage: false }, // Authentication State isLoggedIn: false, // Settings State currentTheme: 'Auto', notificationStatus: 'Enabled', currentLanguage: 'Chinese' }, /** * Page Lifecycle Methods */ onLoad: function (options) { console.log('Personal Center Page Loaded'); this.initSystemInfo(); this.initData(); }, onShow: function () { console.log('Personal Center Page Shown'); this.loadUserData(); this.loadUserStats(); }, onReady: function () { console.log('Personal Center Page Ready'); }, onHide: function () { console.log('Personal Center Page Hidden'); }, onUnload: function () { console.log('Personal Center Page Unloaded'); }, /** * Initialization Methods */ initData() { try { const userInfo = app.globalData.userInfo; this.setData({ userInfo: userInfo || { user: { nickname: 'Nickname Not Set', customId: '123456789', avatar: '', signature: '', gender: 'male', verified: false }, age: null, mood: '', personality: '', identity: '', constellation: '', school: '', occupation: '' }, appVersion: config.appVersion || '1.0.0', isLoggedIn: app.globalData.isLoggedIn || false }); } catch (error) { console.error('Failed to initialize data:', error); } }, initSystemInfo() { try { const systemInfo = wx.getSystemInfoSync(); const menuButtonInfo = wx.getMenuButtonBoundingClientRect(); const statusBarHeight = systemInfo.statusBarHeight || 0; const menuButtonHeight = menuButtonInfo.height || 0; const menuButtonTop = menuButtonInfo.top || 0; const menuButtonBottom = menuButtonInfo.bottom || 0; const navBarHeight = menuButtonBottom + menuButtonTop - statusBarHeight; const windowHeight = systemInfo.windowHeight || 0; const safeAreaBottom = systemInfo.safeArea ? systemInfo.screenHeight - systemInfo.safeArea.bottom : 0; this.setData({ systemInfo, statusBarHeight, menuButtonHeight, menuButtonTop, navBarHeight, windowHeight, safeAreaBottom }); console.log('System adaptation info:', { statusBarHeight, menuButtonHeight, menuButtonTop, navBarHeight, windowHeight, safeAreaBottom }); } catch (error) { console.error('Failed to initialize system info:', error); } }, /** * Data Loading Methods */ loadUserData() { try { const globalUserInfo = app.globalData.userInfo; const isLoggedIn = app.globalData.isLoggedIn; const currentToken = apiClient.getToken(); // Ensure user information contains customId let userInfo = globalUserInfo; if (userInfo?.user) { const user = userInfo.user; if (!user.customId && user.id) { user.customId = 'findme_' + user.id; } if (!user.customId) { user.customId = 'Not Set'; } } // Debug information const debugInfo = { hasGlobalUserInfo: !!globalUserInfo, hasToken: !!currentToken, tokenLength: currentToken ? currentToken.length : 0, tokenPrefix: currentToken ? currentToken.substring(0, 20) + '...' : 'null', hasLocalStorage: false }; // Check local storage try { const storedUserInfo = wx.getStorageSync('userInfo'); debugInfo.hasLocalStorage = !!(storedUserInfo?.token); } catch (storageError) { console.warn('Failed to check local storage:', storageError); } console.log('Personal Center Debug Information:', debugInfo); this.setData({ userInfo, isLoggedIn, debugInfo }); } catch (error) { console.error('Failed to load user data:', error); } }, async loadUserStats() { try { const response = await this.mockLoadStats(); if (response?.code === 0) { this.setData({ stats: response.data.stats || this.data.stats, newMomentsCount: response.data.newMomentsCount || 0, fileSize: response.data.fileSize || '0MB', cacheSize: response.data.cacheSize || '0MB' }); } } catch (error) { console.error('Failed to load user stats:', error); } }, async mockLoadStats() { // Simulate network delay await new Promise(resolve => setTimeout(resolve, 300)); return { code: 0, message: 'Success', data: { stats: { friendsCount: 42, postsCount: 18, visitorsCount: 156, likesCount: 89, groupsCount: 5 }, newMomentsCount: 2, fileSize: '125MB', cacheSize: '32MB' } }; }, refreshUserInfo() { const userInfo = app.globalData.userInfo; if (userInfo) { this.setData({ userInfo }); } }, /** * Avatar Management */ changeAvatar() { wx.showActionSheet({ itemList: ['Take Photo', 'Choose from Album'], success: (res) => { const sourceType = res.tapIndex === 0 ? ['camera'] : ['album']; wx.chooseMedia({ count: 1, mediaType: ['image'], sourceType: sourceType, maxDuration: 30, camera: 'back', success: (res) => { console.log('Avatar selection successful:', res.tempFiles[0]); this.uploadAvatar(res.tempFiles[0].tempFilePath); }, fail: (error) => { console.error('Failed to select avatar:', error); wx.showToast({ title: 'Failed to Select Avatar', icon: 'none' }); } }); } }); }, async uploadAvatar(tempFilePath) { try { wx.showLoading({ title: 'Uploading...' }); const uploadResult = await this.uploadAvatarToServer(tempFilePath); if (uploadResult.success) { // Cache new avatar const cachedAvatarUrl = await imageCacheManager.updateAvatarCache( this.data.userInfo?.user?.avatar, uploadResult.avatarUrl ); // Update local user information const userInfo = { ...this.data.userInfo }; if (userInfo?.user) { userInfo.user.avatar = cachedAvatarUrl; this.setData({ userInfo }); // Update global user information if (app.globalData.userInfo?.user) { app.globalData.userInfo.user.avatar = cachedAvatarUrl; } } wx.hideLoading(); wx.showToast({ title: 'Avatar Updated Successfully', icon: 'success' }); } else { throw new Error(uploadResult.message || 'Upload Failed'); } } catch (error) { wx.hideLoading(); console.error('Failed to upload avatar:', error); wx.showToast({ title: error.message || 'Upload Failed', icon: 'none' }); } }, async uploadAvatarToServer(tempFilePath) { try { console.log('Starting avatar upload:', tempFilePath); const uploadResult = await new Promise((resolve, reject) => { wx.uploadFile({ url: `${config.api.baseUrl}/api/v1/file/upload`, filePath: tempFilePath, name: 'file', formData: { file_type: 'avatar', usage_type: 'avatar' }, header: { 'Authorization': `Bearer ${apiClient.getToken()}` }, success: resolve, fail: reject }); }); console.log('Upload response:', uploadResult); if (uploadResult.statusCode === 200) { const result = JSON.parse(uploadResult.data); if (result.code === 0) { return { success: true, avatarUrl: result.data.file_url, message: result.message || 'Upload Successful' }; } else { return { success: false, message: result.message || 'Upload Failed' }; } } else { return { success: false, message: `HTTP Error: ${uploadResult.statusCode}` }; } } catch (error) { console.error('Failed to upload avatar to server:', error); return { success: false, message: error.message || 'Network Error' }; } }, /** * Tab Selection */ onTabSelect(e) { const tab = e.currentTarget.dataset.tab; if (tab) { this.setData({ selectedTab: tab }); } }, /** * Navigation Methods */ editProfile() { wx.navigateTo({ url: '/pages/personal-details/personal-details' }); }, openSettingsPage() { wx.navigateTo({ url: '/pages/settingss/settingss' }); }, navigateToQRCode() { wx.navigateTo({ url: '/pages/qr-code/qr-code' }); }, viewFriends() { wx.navigateTo({ url: '/pages/social/friends/friends' }); }, /** * Statistics Navigation */ viewPosts() { wx.showToast({ title: 'Moments Function Has Been Removed', icon: 'none' }); }, viewVisitors() { wx.showToast({ title: 'Visitor Records Available in the APP', icon: 'none' }); }, viewLikes() { wx.showToast({ title: 'Like Records Available in the APP', icon: 'none' }); }, /** * Settings Methods */ openThemeSettings() { const themes = ['Light', 'Dark', 'Auto']; wx.showActionSheet({ itemList: themes, success: (res) => { const selectedTheme = themes[res.tapIndex]; this.setData({ currentTheme: selectedTheme }); wx.showToast({ title: `Switched to ${selectedTheme} Theme`, icon: 'success' }); // Save theme preference wx.setStorageSync('theme', selectedTheme); } }); }, openNotificationSettings() { const options = ['Enabled', 'Disabled', 'Do Not Disturb']; wx.showActionSheet({ itemList: options, success: (res) => { const selectedStatus = options[res.tapIndex]; this.setData({ notificationStatus: selectedStatus }); const statusText = selectedStatus === 'Enabled' ? 'Enabled' : selectedStatus === 'Disabled' ? 'Disabled' : 'Set to Do Not Disturb'; wx.showToast({ title: `Notifications ${statusText}`, icon: 'success' }); // Save notification preference wx.setStorageSync('notificationStatus', selectedStatus); } }); }, openLanguageSettings() { const languages = ['Chinese', 'English']; wx.showActionSheet({ itemList: languages, success: (res) => { const selectedLanguage = languages[res.tapIndex]; this.setData({ currentLanguage: selectedLanguage }); wx.showToast({ title: `Switched to ${selectedLanguage}`, icon: 'success' }); // Save language preference wx.setStorageSync('language', selectedLanguage); } }); }, openChatSettings() { wx.showActionSheet({ itemList: ['Font Size', 'Chat Background', 'Message Preview'], success: (res) => { const options = ['Font Size', 'Chat Background', 'Message Preview']; const selectedOption = options[res.tapIndex]; wx.showToast({ title: `${selectedOption} Function Under Development`, icon: 'none' }); } }); }, /** * Feature Methods (Currently Limited) */ openWallet() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, openCards() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, openStickers() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, openGames() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, openShopping() { wx.showToast({ title: 'Function Under Development', icon: 'none' }); }, openBackupSettings() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, viewProfile() { wx.showToast({ title: 'Personal Homepage Available in the APP', icon: 'none' }); }, managePrivacy() { wx.showToast({ title: 'Privacy Settings Available in the APP', icon: 'none' }); }, viewMoments() { wx.showToast({ title: 'Moments Function Has Been Removed', icon: 'none' }); }, viewFavorites() { wx.showToast({ title: 'My Favorites Available in the APP', icon: 'none' }); }, viewGroups() { wx.showToast({ title: 'My Groups Available in the APP', icon: 'none' }); }, viewFiles() { wx.showToast({ title: 'File Management Available in the APP', icon: 'none' }); }, /** * Cache Management */ clearCache() { wx.showModal({ title: 'Clear Cache', content: 'Are you sure you want to clear the cache? Some data may need to be reloaded after clearing.', success: (res) => { if (res.confirm) { wx.showLoading({ title: 'Clearing...' }); // Clear image cache imageCacheManager.clearAllCache(); setTimeout(() => { wx.hideLoading(); this.setData({ cacheSize: '0MB' }); wx.showToast({ title: 'Cache Cleared Successfully', icon: 'success' }); }, 1000); } } }); }, showCacheStats() { try { const stats = imageCacheManager.getCacheStats(); wx.showModal({ title: 'Cache Statistics', content: `Total Cache: ${stats.total}\nAvatar Cache: ${stats.avatar}\nImage Cache: ${stats.image}\nExpired Cache: ${stats.expired}\nMax Cache: ${stats.maxSize}`, showCancel: false, confirmText: 'OK' }); } catch (error) { console.error('Failed to show cache stats:', error); wx.showToast({ title: 'Failed to Load Cache Stats', icon: 'none' }); } }, /** * App Information Methods */ checkUpdates() { wx.showLoading({ title: 'Checking...' }); setTimeout(() => { wx.hideLoading(); wx.showToast({ title: 'You Are Using the Latest Version', icon: 'success' }); }, 1000); }, aboutApp() { wx.showModal({ title: 'About FindMe', content: `FindMe v${this.data.appVersion}\n\nA location-based social application\nDiscover nearby, connect the world\n\n© 2025 FindMe`, showCancel: false, confirmText: 'Got it' }); }, viewHelp() { wx.showToast({ title: 'Help Center Available in the APP', icon: 'none' }); }, giveFeedback() { wx.showModal({ title: 'Feedback', editable: true, placeholderText: 'Please enter your comments or suggestions...', success: (res) => { if (res.confirm && res.content?.trim()) { wx.showLoading({ title: 'Submitting...' }); // Here you would typically call an API to submit feedback setTimeout(() => { wx.hideLoading(); wx.showToast({ title: 'Feedback Submitted Successfully', icon: 'success' }); }, 1000); } } }); }, /** * QR Code Methods */ showQRCode() { this.setData({ showQRModal: true }); }, hideQRCode() { this.setData({ showQRModal: false }); }, saveQRCode() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, shareQRCode() { wx.showToast({ title: 'Please Experience in the APP', icon: 'none' }); }, /** * Debug Methods */ async testApiCall() { try { wx.showLoading({ title: 'Testing API...' }); const response = await apiClient.getUserInfo(); wx.hideLoading(); wx.showModal({ title: 'API Test Successful', content: `User Information Retrieved: ${JSON.stringify(response.data)}`, showCancel: false }); } catch (error) { wx.hideLoading(); wx.showModal({ title: 'API Test Failed', content: `Error Message: ${error.message}`, showCancel: false }); } }, refreshDebugInfo() { this.loadUserData(); wx.showToast({ title: 'Refreshed', icon: 'success' }); }, /** * Authentication Methods */ async logout() { wx.showModal({ title: 'Logout', content: 'Are you sure you want to log out of the current account?', success: (res) => { if (res.confirm) { this.performLogout(); } } }); }, async performLogout() { try { wx.showLoading({ title: 'Logging Out...' }); const success = await app.logout(); wx.hideLoading(); if (success) { wx.showToast({ title: 'Logged Out Successfully', icon: 'success' }); setTimeout(() => { wx.reLaunch({ url: '/pages/login/login' }); }, 1500); } else { wx.showToast({ title: 'Logout Failed', icon: 'none' }); } } catch (error) { wx.hideLoading(); console.error('Logout failed:', error); wx.showToast({ title: 'Logout Error', icon: 'none' }); } } });