init: 毛孩子计划 小程序 + Go 后端 + 内嵌后台
- pets-fe: 微信原生小程序(首页/计划/记录/报告/社区/引导), 服务端驱动、无假数据;弹层改用 scroll-view,打开时隐藏自定义 tabBar - pets-be: Gin + GORM(MySQL, sundynix_ 前缀) + MinIO,统一响应/分页, 微信 code2session 登录,provider-neutral AI(DeepSeek),go:embed React 后台 - 修复:分段选择类型不匹配(字符串 vs 数字)导致选不中 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
const store = require('../../utils/store.js');
|
||||
const api = require('../../utils/api.js');
|
||||
|
||||
const GENDERS = ['男孩', '女孩', '不确定'];
|
||||
|
||||
function ageFromBirthday(bdayStr) {
|
||||
if (!bdayStr) return '';
|
||||
const b = new Date(bdayStr);
|
||||
const now = new Date();
|
||||
let months = (now.getFullYear() - b.getFullYear()) * 12 + (now.getMonth() - b.getMonth());
|
||||
if (months < 0) months = 0;
|
||||
return months < 24 ? months + '个月' : Math.floor(months / 12) + '岁';
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
step: 0,
|
||||
petType: '猫猫',
|
||||
petEmoji: '🐱',
|
||||
petName: '',
|
||||
birthday: '',
|
||||
genderIdx: 0,
|
||||
weight: '',
|
||||
stage: '幼年期',
|
||||
goals: [
|
||||
{ label: '不知道每天该做什么', on: true },
|
||||
{ label: '疫苗驱虫怕忘记', on: true },
|
||||
{ label: '想记录体重和健康', on: false },
|
||||
{ label: '担心生病不会判断', on: false },
|
||||
{ label: '想控制养宠开销', on: false },
|
||||
{ label: '想生成成长报告', on: false },
|
||||
],
|
||||
submitting: false,
|
||||
},
|
||||
onLoad() {
|
||||
// 已有宠物则直接进首页
|
||||
store
|
||||
.ready()
|
||||
.then(() => {
|
||||
if (store.getPets().length > 0) {
|
||||
wx.switchTab({ url: '/pages/home/home' });
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
nextStep() {
|
||||
this.setData({ step: Math.min(this.data.step + 1, 5) });
|
||||
},
|
||||
choosePet(e) {
|
||||
const { type, emoji } = e.currentTarget.dataset;
|
||||
this.setData({ petType: type, petEmoji: emoji });
|
||||
},
|
||||
onName(e) { this.setData({ petName: e.detail.value }); },
|
||||
onWeight(e) { this.setData({ weight: e.detail.value }); },
|
||||
onBirthday(e) { this.setData({ birthday: e.detail.value }); },
|
||||
selectGender(e) { this.setData({ genderIdx: Number(e.currentTarget.dataset.index) }); },
|
||||
// 先随便看看:不建数据,直接进首页浏览(无宠物时首页显示空态)
|
||||
skipBrowse() { wx.switchTab({ url: '/pages/home/home' }); },
|
||||
savePetNext() {
|
||||
if (!(this.data.petName || '').trim()) {
|
||||
wx.showToast({ title: '给它起个名字吧', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.nextStep();
|
||||
},
|
||||
chooseStage(e) {
|
||||
this.setData({ stage: e.currentTarget.dataset.stage });
|
||||
},
|
||||
toggleGoal(e) {
|
||||
const i = e.currentTarget.dataset.index;
|
||||
this.setData({ [`goals[${i}].on`]: !this.data.goals[i].on });
|
||||
},
|
||||
async submit() {
|
||||
if (this.data.submitting) return;
|
||||
this.setData({ submitting: true });
|
||||
wx.showLoading({ title: '生成计划中...' });
|
||||
const body = {
|
||||
name: (this.data.petName || '').trim(),
|
||||
emoji: this.data.petEmoji,
|
||||
type: this.data.petType,
|
||||
gender: GENDERS[this.data.genderIdx],
|
||||
birthday: this.data.birthday,
|
||||
weight: this.data.weight,
|
||||
stage: this.data.stage,
|
||||
age: ageFromBirthday(this.data.birthday),
|
||||
goals: this.data.goals.filter((g) => g.on).map((g) => g.label),
|
||||
};
|
||||
try {
|
||||
await store.ready();
|
||||
await api.onboarding(body);
|
||||
await store.loadPets();
|
||||
wx.hideLoading();
|
||||
wx.switchTab({ url: '/pages/home/home' });
|
||||
} catch (e) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: e.message || '创建失败', icon: 'none' });
|
||||
this.setData({ submitting: false });
|
||||
}
|
||||
},
|
||||
finishOnboard() { this.submit(); },
|
||||
});
|
||||
Reference in New Issue
Block a user