609f7d06cf
- 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>
101 lines
1.9 KiB
JavaScript
101 lines
1.9 KiB
JavaScript
// 全局状态:登录、宠物列表、当前宠物;服务端驱动 + 发布订阅
|
|
const api = require('./api.js');
|
|
|
|
const state = {
|
|
user: null,
|
|
pets: [],
|
|
currentId: 0,
|
|
};
|
|
|
|
const listeners = new Set();
|
|
let bootstrapPromise = null;
|
|
|
|
function getPets() {
|
|
return state.pets;
|
|
}
|
|
function getPet() {
|
|
return state.pets.find((p) => p.id === state.currentId) || state.pets[0] || {};
|
|
}
|
|
function currentPetId() {
|
|
const p = getPet();
|
|
return p && p.id;
|
|
}
|
|
|
|
function notify() {
|
|
const pet = getPet();
|
|
listeners.forEach((fn) => {
|
|
try {
|
|
fn(pet);
|
|
} catch (e) {
|
|
/* noop */
|
|
}
|
|
});
|
|
}
|
|
|
|
function subscribe(fn) {
|
|
listeners.add(fn);
|
|
return () => listeners.delete(fn);
|
|
}
|
|
|
|
// 登录 + 拉宠物列表(只跑一次)
|
|
function ready() {
|
|
if (!bootstrapPromise) {
|
|
bootstrapPromise = (async () => {
|
|
const res = await api.login();
|
|
state.user = res.user;
|
|
await loadPets();
|
|
})().catch((e) => {
|
|
bootstrapPromise = null; // 允许重试
|
|
throw e;
|
|
});
|
|
}
|
|
return bootstrapPromise;
|
|
}
|
|
|
|
async function loadPets() {
|
|
const pets = await api.getPets();
|
|
state.pets = pets || [];
|
|
if (!state.currentId && state.pets[0]) {
|
|
state.currentId = state.pets[0].id;
|
|
}
|
|
// 当前宠物被删或不存在时回退第一只
|
|
if (!state.pets.find((p) => p.id === state.currentId) && state.pets[0]) {
|
|
state.currentId = state.pets[0].id;
|
|
}
|
|
notify();
|
|
return state.pets;
|
|
}
|
|
|
|
function switchPet(id) {
|
|
if (state.currentId === id) return;
|
|
state.currentId = id;
|
|
notify();
|
|
}
|
|
|
|
// 本地更新当前宠物字段(服务端已改动后同步 UI)
|
|
function patchCurrent(patch) {
|
|
const pet = getPet();
|
|
Object.assign(pet, patch);
|
|
notify();
|
|
}
|
|
|
|
function setUser(u) {
|
|
state.user = u;
|
|
}
|
|
function getUser() {
|
|
return state.user;
|
|
}
|
|
|
|
module.exports = {
|
|
ready,
|
|
loadPets,
|
|
getPets,
|
|
getPet,
|
|
currentPetId,
|
|
switchPet,
|
|
patchCurrent,
|
|
subscribe,
|
|
setUser,
|
|
getUser,
|
|
};
|