Files
past-go/weapp/pages/pet/pet.js
T
2026-10-07 09:28:43 +08:00

310 lines
9.4 KiB
JavaScript

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() {}
});