- 八字页:未绑定生辰时展示虚构示例排盘(1990-08-08 10:30男)与15条字段说明, 附传统文化声明文案;已绑定时支持多档案切换,排盘增强(十神/藏干/纳音/五行配色/命盘概览) - 个人中心:新增生辰管理卡片,每用户免费绑定3个出生年月;登录改为真实微信登录 - 服务端:新增 BirthProfile 模型与 /api/user/birth-profiles 增删查接口,AutoMigrate 建表 - 前端:新增 birth-profile.js 本地存储优先+登录后云端双向同步 - 修复:个人中心 tabBar 页面入口误用 navigateTo 改为 switchTab
148 lines
4.5 KiB
JavaScript
148 lines
4.5 KiB
JavaScript
// 生辰档案管理工具
|
|
// 本地存储优先;已登录(存在 token)时与服务端双向同步
|
|
const { request } = require('./request.js');
|
|
|
|
const STORAGE_KEY = 'lunar-birth-profiles';
|
|
// 每个用户可免费绑定的生辰数量上限
|
|
const MAX_PROFILES = 3;
|
|
|
|
/** 读取本地生辰档案列表 */
|
|
function getProfiles() {
|
|
return wx.getStorageSync(STORAGE_KEY) || [];
|
|
}
|
|
|
|
/** 保存本地生辰档案列表 */
|
|
function saveProfiles(profiles) {
|
|
wx.setStorageSync(STORAGE_KEY, profiles);
|
|
}
|
|
|
|
/** 获取当前激活的档案(第一个为默认) */
|
|
function getActiveProfile() {
|
|
const profiles = getProfiles();
|
|
if (profiles.length === 0) return null;
|
|
const activeId = wx.getStorageSync('lunar-birth-active-id');
|
|
return profiles.find(p => p.id === activeId) || profiles[0];
|
|
}
|
|
|
|
/** 设置激活档案 */
|
|
function setActiveProfile(id) {
|
|
wx.setStorageSync('lunar-birth-active-id', id);
|
|
}
|
|
|
|
/** 新增生辰档案(本地),超出上限或重复时返回错误信息 */
|
|
function addProfile(profile) {
|
|
const profiles = getProfiles();
|
|
if (profiles.length >= MAX_PROFILES) {
|
|
return { ok: false, msg: `最多可免费绑定 ${MAX_PROFILES} 个生辰` };
|
|
}
|
|
const dup = profiles.find(p => p.birthday === profile.birthday && p.birthTime === profile.birthTime);
|
|
if (dup) {
|
|
return { ok: false, msg: '该生辰已绑定,请勿重复添加' };
|
|
}
|
|
const item = {
|
|
id: `local-${Date.now()}`,
|
|
name: profile.name || '未命名',
|
|
gender: profile.gender || 'male',
|
|
birthday: profile.birthday,
|
|
birthTime: profile.birthTime,
|
|
serverId: 0,
|
|
createdAt: Date.now()
|
|
};
|
|
profiles.push(item);
|
|
saveProfiles(profiles);
|
|
if (!getActiveProfile()) setActiveProfile(item.id);
|
|
return { ok: true, profile: item };
|
|
}
|
|
|
|
/** 删除生辰档案(本地) */
|
|
function removeProfile(id) {
|
|
const profiles = getProfiles().filter(p => p.id !== id);
|
|
saveProfiles(profiles);
|
|
if (wx.getStorageSync('lunar-birth-active-id') === id) {
|
|
setActiveProfile(profiles.length > 0 ? profiles[0].id : '');
|
|
}
|
|
}
|
|
|
|
/** 是否已登录(存在有效 token) */
|
|
function isLoggedIn() {
|
|
return !!wx.getStorageSync('token');
|
|
}
|
|
|
|
/** 推送单个档案到服务端(静默失败,不影响本地) */
|
|
function pushProfileToServer(profile) {
|
|
if (!isLoggedIn()) return Promise.resolve(null);
|
|
return request({
|
|
url: '/api/user/birth-profiles',
|
|
method: 'POST',
|
|
data: {
|
|
name: profile.name,
|
|
gender: profile.gender === 'female' ? 2 : 1,
|
|
birthday: profile.birthday,
|
|
birthTime: profile.birthTime
|
|
}
|
|
}).then(res => {
|
|
if (res && res.code === 0 && res.data && res.data.profile) {
|
|
// 回填 serverId
|
|
const profiles = getProfiles();
|
|
const target = profiles.find(p => p.id === profile.id);
|
|
if (target) {
|
|
target.serverId = res.data.profile.id;
|
|
saveProfiles(profiles);
|
|
}
|
|
return res.data.profile;
|
|
}
|
|
return null;
|
|
}).catch(() => null);
|
|
}
|
|
|
|
/** 删除服务端档案(静默失败) */
|
|
function removeProfileFromServer(profile) {
|
|
if (!isLoggedIn() || !profile.serverId) return Promise.resolve();
|
|
return request({
|
|
url: `/api/user/birth-profiles/${profile.serverId}`,
|
|
method: 'DELETE'
|
|
}).catch(() => null);
|
|
}
|
|
|
|
/** 从服务端拉取档案并与本地合并(以服务端为准) */
|
|
function syncFromServer() {
|
|
if (!isLoggedIn()) return Promise.resolve(getProfiles());
|
|
return request({ url: '/api/user/birth-profiles' })
|
|
.then(res => {
|
|
if (!res || res.code !== 0 || !Array.isArray(res.data && res.data.profiles)) {
|
|
return getProfiles();
|
|
}
|
|
const serverList = res.data.profiles.map(sp => ({
|
|
id: `server-${sp.id}`,
|
|
serverId: sp.id,
|
|
name: sp.name || '未命名',
|
|
gender: sp.gender === 2 ? 'female' : 'male',
|
|
birthday: sp.birthday,
|
|
birthTime: sp.birthTime,
|
|
createdAt: sp.createdAt ? new Date(sp.createdAt).getTime() : 0
|
|
}));
|
|
// 本地尚未成功推送的档案保留,按 (birthday+birthTime) 去重
|
|
const merged = [...serverList];
|
|
getProfiles().forEach(lp => {
|
|
const exists = merged.some(m => m.birthday === lp.birthday && m.birthTime === lp.birthTime);
|
|
if (!exists) merged.push(lp);
|
|
});
|
|
saveProfiles(merged.slice(0, MAX_PROFILES));
|
|
return getProfiles();
|
|
})
|
|
.catch(() => getProfiles());
|
|
}
|
|
|
|
module.exports = {
|
|
MAX_PROFILES,
|
|
getProfiles,
|
|
getActiveProfile,
|
|
setActiveProfile,
|
|
addProfile,
|
|
removeProfile,
|
|
isLoggedIn,
|
|
pushProfileToServer,
|
|
removeProfileFromServer,
|
|
syncFromServer
|
|
};
|