const { getLayout } = require('../../utils/layout'); // pages/pet/pet.js const { api } = require('../../utils/request'); const BREED_NAMES = { 'golden': '金毛', 'husky': '哈士奇', 'corgi': '柯基', 'shiba': '柴犬' }; const BREED_EMOJIS = { 'golden': '🐕', 'husky': '🐺', 'corgi': '🦊', 'shiba': '🐶' }; const STAGE_NAMES = ['', '幼犬期', '少年期', '青年期', '成年期', '终极期']; Page({ onResize: function() { this.setData(getLayout()); }, data: { loading: true, loadError: false, hasPet: false, pet: null, daily: null, achievements: [], dynamics: [], displayDynamics: [], equipped: [], // 领养表单 breedSelect: 'golden', genderSelect: 1, petName: '', adopting: false, // 宠物状态 dailyStatus: {}, partnerDaily: {}, allDone: false, expProgress: 0, expForNextLevel: 0, breedName: '', petEmoji: '', stageName: '', equippedCollar: false, // 最近成就 recentAchievements: [], achievementCount: 0, // 改名 showRename: false, renameValue: '', renaming: false, // 动态折叠(默认收起,收起时显示一条) showAllDynamics: false }, onLoad: function() { this.setData(getLayout()); this.loadPetInfo(); }, onShow: function() { this.loadPetInfo(); }, loadPetInfo: async function() { if (this._pageLoading) return; this._pageLoading = true; this.setData({loading:true, loadError:false}); try { const res = await api.petInfo(); if (res.has_pet && res.pet) { const pet = res.pet; const dailyStatus = {}; const partnerDaily = {}; if (res.daily) { const d = res.daily; const suffix = res.is_user1 ? 'u1' : 'u2'; const partnerSuffix = res.is_user1 ? 'u2' : 'u1'; ['feed', 'water', 'walk', 'bath', 'sleep', 'play'].forEach(a => { dailyStatus[a] = d[a + '_' + suffix] == 1; partnerDaily[a] = d[a + '_' + partnerSuffix] == 1; }); } // 获取已装备物品 const equipped = res.equipped || []; const equippedCollar = equipped.some(e => e.item_type === 'collar'); // 计算最近成就 const allAch = this.getAllAchievementDefs(); const recentAch = allAch.filter(a => res.achievements.indexOf(a.key) >= 0).slice(0, 5); // 计算领养天数 var adoptDays = 0; if (pet.adopted_at) { var adoptDate = new Date(pet.adopted_at.replace(/-/g, '/')); if (!isNaN(adoptDate.getTime())) { adoptDays = Math.floor((Date.now() - adoptDate.getTime()) / 86400000); } } var pageData = { hasPet: true, pet: pet, daily: res.daily, achievements: res.achievements, dynamics: this._formatDynamics(res.dynamics || []), showAllDynamics: false, equipped: equipped, dailyStatus: dailyStatus, partnerDaily: partnerDaily, allDone: res.daily ? res.daily.all_done == 1 : false, expProgress: res.exp_progress || 0, expForNextLevel: res.exp_for_next_level || 0, breedName: BREED_NAMES[pet.breed] || '金毛', petEmoji: BREED_EMOJIS[pet.breed] || '🐕', stageName: STAGE_NAMES[pet.stage] || '幼犬期', equippedCollar: equippedCollar, recentAchievements: recentAch, achievementCount: (res.achievements || []).length, adoptDays: adoptDays }; this.setData(pageData); this._buildDisplayDynamics(); } else { this.setData({ hasPet: false, pet:null, daily:null, achievements:[], dynamics:[], displayDynamics:[] }); } } catch (e) { this.setData({loadError:true}); console.error(e); } finally { this._pageLoading = false; this.setData({loading:false}); } }, // 格式化动态数据:时间转为友好显示,昵称取首字 _formatDynamics: function(list) { var now = Date.now(); return list.map(function(d) { var timeText = ''; if (d.created_at) { var t = new Date(String(d.created_at).replace(/-/g, '/').replace('T', ' ')); if (!isNaN(t.getTime())) { var diff = Math.floor((now - t.getTime()) / 1000); if (diff < 60) timeText = '刚刚'; else if (diff < 3600) timeText = Math.floor(diff / 60) + '分钟前'; else if (diff < 86400) timeText = Math.floor(diff / 3600) + '小时前'; else if (diff < 172800) timeText = '昨天'; else timeText = (t.getMonth() + 1) + '月' + t.getDate() + '日'; } } var initial = d.user_id == 0 ? '🐾' : (d.nickname ? String(d.nickname).trim()[0] : '?'); return { user_id: d.user_id, nickname: d.nickname, avatar: d.avatar || '', action: d.action, message: d.message, time_text: timeText, initial: initial }; }); }, getAllAchievementDefs: function() { return [ { key: 'first_adopt', name: '初次相遇', icon: '🐣' }, { key: 'level_5', name: '成长之路', icon: '⭐' }, { key: 'level_10', name: '小有成就', icon: '🌟' }, { key: 'level_20', name: '资深铲屎官', icon: '👑' }, { key: 'level_30', name: '终极陪伴', icon: '💎' }, { key: 'stage_2', name: '少年初长成', icon: '🐕' }, { key: 'stage_3', name: '青春活力', icon: '🦮' }, { key: 'stage_4', name: '成熟稳重', icon: '🐩' }, { key: 'stage_5', name: '终极形态', icon: '🦁' }, { key: 'all_done_7', name: '一周全勤', icon: '📅' }, { key: 'all_done_30', name: '月度之星', icon: '🏆' }, { key: 'feed_100', name: '大胃王', icon: '🍖' }, { key: 'walk_50', name: '散步达人', icon: '🚶' }, { key: 'bath_30', name: '爱干净', icon: '🛁' }, { key: 'play_50', name: '玩伴', icon: '🎾' }, { key: 'happiness_100', name: '快乐满分', icon: '😊' }, { key: 'rename_first', name: '取名大师', icon: '✏️' }, { key: 'adopt_7days', name: '一周陪伴', icon: '📆' }, { key: 'adopt_30days', name: '一月相伴', icon: '🗓️' }, { key: 'adopt_100days', name: '百日纪念', icon: '💯' } ]; }, // 选择品种 selectBreed: function(e) { this.setData({ breedSelect: e.currentTarget.dataset.breed }); }, // 选择性别 selectGender: function(e) { this.setData({ genderSelect: parseInt(e.currentTarget.dataset.gender) }); }, // 输入名字 onNameInput: function(e) { this.setData({ petName: e.detail.value }); }, // 领养 doAdopt: async function() { var name = this.data.petName.trim(); if (!name) { wx.showToast({ title: '请给宠物取个名字', icon: 'none' }); return; } this.setData({ adopting: true }); try { const res = await api.petAdopt({ name: name, breed: this.data.breedSelect, gender: this.data.genderSelect }); wx.showToast({ title: '🎉 领养成功!', icon: 'success' }); this.loadPetInfo(); } catch (e) { wx.showToast({ title: e.error || '领养失败', icon: 'none' }); } finally { this.setData({ adopting: false }); } }, // 执行日常任务 doDailyAction: async function(e) { var action = e.currentTarget.dataset.action; if (this.data.dailyStatus[action]) { wx.showToast({ title: '已完成', icon: 'none' }); return; } try { const res = await api.petDailyAction({ action: action }); wx.showToast({ title: '✅ +' + (res.exp_gain || 0) + '经验', icon: 'success', duration: 1500 }); this.loadPetInfo(); } catch (e) { if (e.already_done) { wx.showToast({ title: '今天已完成啦', icon: 'none' }); this.loadPetInfo(); } else { wx.showToast({ title: e.error || '操作失败', icon: 'none' }); } } }, // 改名 showRenameModal: function() { this.setData({ showRename: true, renameValue: this.data.pet ? this.data.pet.name : '' }); }, hideRenameModal: function() { this.setData({ showRename: false }); }, onRenameInput: function(e) { this.setData({ renameValue: e.detail.value }); }, doRename: async function() { var name = this.data.renameValue.trim(); if (!name) { wx.showToast({ title: '请输入名字', icon: 'none' }); return; } this.setData({ renaming: true }); try { await api.petRename({ name: name }); wx.showToast({ title: '改名成功 ✏️', icon: 'success' }); this.setData({ showRename: false }); this.loadPetInfo(); } catch (e) { wx.showToast({ title: e.error || '改名失败', icon: 'none' }); } finally { this.setData({ renaming: false }); } }, // 展开/收起动态 toggleDynamics: function() { this.setData({ showAllDynamics: !this.data.showAllDynamics }, () => { this._buildDisplayDynamics(); }); }, // 根据折叠状态计算要展示的动态列表(收起时只显示一条) _buildDisplayDynamics: function() { var list = this.data.dynamics || []; var show = this.data.showAllDynamics; this.setData({ displayDynamics: show ? list : list.slice(0, 1) }); }, // 跳转到成就页 goToAchievements: function() { wx.navigateTo({ url: '/pages/pet/achievements' }); }, // 返回 goBack: function() { wx.navigateBack(); }, stopPropagation: function() {} });