- 八字页:未绑定生辰时展示虚构示例排盘(1990-08-08 10:30男)与15条字段说明, 附传统文化声明文案;已绑定时支持多档案切换,排盘增强(十神/藏干/纳音/五行配色/命盘概览) - 个人中心:新增生辰管理卡片,每用户免费绑定3个出生年月;登录改为真实微信登录 - 服务端:新增 BirthProfile 模型与 /api/user/birth-profiles 增删查接口,AutoMigrate 建表 - 前端:新增 birth-profile.js 本地存储优先+登录后云端双向同步 - 修复:个人中心 tabBar 页面入口误用 navigateTo 改为 switchTab
154 lines
7.5 KiB
JavaScript
154 lines
7.5 KiB
JavaScript
const { birthInfoToBazi, analyzeElementBalance } = require('../../utils/core/index.js');
|
|
const birthProfile = require('../../utils/birth-profile.js');
|
|
|
|
// 空态演示用的示例生辰(虚构,仅作排盘样式展示)
|
|
const DEMO_BIRTH = { year: 1990, month: 8, day: 8, hour: 10, minute: 30, gender: 'male', ziSect: 'lateZiNextDay' };
|
|
|
|
// 五行 → 样式类名
|
|
const ELEMENT_CLASS = { '木': 'el-wood', '火': 'el-fire', '土': 'el-earth', '金': 'el-metal', '水': 'el-water' };
|
|
|
|
// 八字知识词条:逐字段详细说明
|
|
const GLOSSARY = [
|
|
{ term: '四柱八字', desc: '用天干地支记录出生年、月、日、时的方法,年、月、日、时各一对干支,合称"四柱",共八个字,故称"八字"。它源于古代干支纪时体系,是传统历法文化的一部分。' },
|
|
{ term: '天干地支', desc: '天干共十个(甲乙丙丁戊己庚辛壬癸),地支共十二个(子丑寅卯辰巳午未申酉戌亥),是古人用于纪年、纪月、纪日、纪时的符号系统,也是传统历法的基础。' },
|
|
{ term: '年柱', desc: '出生年份的干支。传统上以立春为界划分年份(立春前出生按上一年)。年柱在民俗说法中对应祖辈与少年时期。' },
|
|
{ term: '月柱', desc: '出生月份的干支。月份以节气划分(如立春至惊蛰为正月),并非公历或农历的自然月。民俗说法中对应父母与青年时期。' },
|
|
{ term: '日柱', desc: '出生当日的干支,按六十甲子循环纪日。日柱的天干代表本人(日主),是整个命盘分析的核心。' },
|
|
{ term: '时柱', desc: '出生时辰的干支。古人将一昼夜分为十二个时辰,每个时辰合今两小时(如子时为 23:00-01:00)。' },
|
|
{ term: '日主', desc: '日柱的天干,代表命主本人。日主的五行属性(木火土金水)是分析命盘五行强弱与十神关系的出发点。' },
|
|
{ term: '十神', desc: '以日主为参照,按五行生克关系对其他干支的十种称谓:比肩、劫财、食神、伤官、偏财、正财、七杀、正官、偏印、正印。它是古代的一种关系分类符号,用于描述干支之间的生克比和。' },
|
|
{ term: '五行', desc: '木、火、土、金、水五种基本元素,源于古代哲学,认为万物由五行构成并相生相克(木生火、火生土、土生金、金生水、水生木;木克土、土克水、水克火、火克金、金克木)。五行分析统计八字中各元素的数量与强弱。' },
|
|
{ term: '藏干', desc: '又称"人元",指每个地支内部按传统规则所含的一个至三个天干。例如寅中藏甲、丙、戊。排盘时作为辅助信息列出。' },
|
|
{ term: '纳音', desc: '将六十甲子两两配对归入五行所得的三十种称谓,如"甲子乙丑海中金"、"丙寅丁卯炉中火"。年命纳音(年柱纳音)在民俗中常被用来称呼人的"命",如"金命"、"火命"。' },
|
|
{ term: '空亡', desc: '六十甲子分为六旬,每旬十个干支配十二地支,余下两个地支无天干相配,称为该旬"空亡"。这是干支纪法本身的结构性概念,此处仅作历法知识展示。' },
|
|
{ term: '大运', desc: '传统上以月柱为基础、按十年一换的节奏推演出的干支序列,用来描述人生不同阶段的节律。属于传统民俗推演方法,供文化了解。' },
|
|
{ term: '流年', desc: '即每一年的干支(如 2026 年为丙午年)。传统做法将流年与本命干支对照,观察逐年的变化关系。' },
|
|
{ term: '子时流派', desc: '子时(23:00-01:00)横跨两天,晚子时(23:00-24:00)出生者的日柱按当天还是次日起算,历代流派说法不一。可在"我的-偏好设置"中选择。' }
|
|
];
|
|
|
|
/** 根据出生信息构建排盘展示数据 */
|
|
function buildChart({ year, month, day, hour, minute, gender, ziSect }) {
|
|
const bazi = birthInfoToBazi({ year, month, day, hour, minute, gender, ziSect });
|
|
const elementAnalysis = analyzeElementBalance(bazi.eightChar);
|
|
|
|
const pillars = [
|
|
{ label: '年柱', ...bazi.eightChar.yearPillar },
|
|
{ label: '月柱', ...bazi.eightChar.monthPillar },
|
|
{ label: '日柱', ...bazi.eightChar.dayPillar },
|
|
{ label: '时柱', ...bazi.eightChar.hourPillar }
|
|
].map(p => ({
|
|
label: p.label,
|
|
ganzhi: p.ganzhi,
|
|
tenStar: p.tenStar || '日主',
|
|
heavenStem: p.heavenStem,
|
|
earthBranch: p.earthBranch,
|
|
stemClass: ELEMENT_CLASS[p.elementStem] || '',
|
|
branchClass: ELEMENT_CLASS[p.elementBranch] || '',
|
|
hideStems: (p.hideStems || []).map(h => h.stem + (h.tenStar ? `(${h.tenStar})` : '')).join(' '),
|
|
nayin: p.nayin
|
|
}));
|
|
|
|
const total = elementAnalysis.total || 1;
|
|
const elements = [
|
|
{ name: '木', count: elementAnalysis.wood, percent: Math.round(elementAnalysis.wood / total * 100), cls: 'el-wood' },
|
|
{ name: '火', count: elementAnalysis.fire, percent: Math.round(elementAnalysis.fire / total * 100), cls: 'el-fire' },
|
|
{ name: '土', count: elementAnalysis.earth, percent: Math.round(elementAnalysis.earth / total * 100), cls: 'el-earth' },
|
|
{ name: '金', count: elementAnalysis.metal, percent: Math.round(elementAnalysis.metal / total * 100), cls: 'el-metal' },
|
|
{ name: '水', count: elementAnalysis.water, percent: Math.round(elementAnalysis.water / total * 100), cls: 'el-water' }
|
|
];
|
|
|
|
return { bazi, pillars, elements, elementAnalysis };
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
isDemo: true,
|
|
profiles: [],
|
|
activeProfileId: '',
|
|
profile: null,
|
|
bazi: null,
|
|
pillars: [],
|
|
elements: [],
|
|
elementAnalysis: {},
|
|
glossary: GLOSSARY,
|
|
showGlossary: false
|
|
},
|
|
|
|
onShow() {
|
|
this.refresh();
|
|
},
|
|
|
|
refresh() {
|
|
const render = () => {
|
|
const profiles = birthProfile.getProfiles();
|
|
if (profiles.length === 0) {
|
|
this.showDemo();
|
|
} else {
|
|
this.showProfile(profiles, birthProfile.getActiveProfile());
|
|
}
|
|
};
|
|
// 已登录时先同步云端档案,失败静默回退本地
|
|
if (birthProfile.isLoggedIn()) {
|
|
birthProfile.syncFromServer().then(render).catch(render);
|
|
} else {
|
|
render();
|
|
}
|
|
},
|
|
|
|
/** 空态:展示示例排盘 */
|
|
showDemo() {
|
|
const chart = buildChart(DEMO_BIRTH);
|
|
this.setData({
|
|
isDemo: true,
|
|
profiles: [],
|
|
activeProfileId: '',
|
|
profile: null,
|
|
showGlossary: true,
|
|
...chart
|
|
});
|
|
},
|
|
|
|
/** 已绑定:展示所选档案的排盘 */
|
|
showProfile(profiles, profile) {
|
|
if (!profile) return;
|
|
const [year, month, day] = profile.birthday.split('-').map(Number);
|
|
const [hour, minute] = profile.birthTime.split(':').map(Number);
|
|
const settings = wx.getStorageSync('lunar-settings') || {};
|
|
const chart = buildChart({
|
|
year, month, day, hour, minute,
|
|
gender: profile.gender,
|
|
ziSect: settings.ziHourSect || 'lateZiNextDay'
|
|
});
|
|
// 保存八字供运势页使用
|
|
wx.setStorageSync('lunar-user-bazi', chart.bazi);
|
|
this.setData({
|
|
isDemo: false,
|
|
profiles,
|
|
activeProfileId: profile.id,
|
|
profile,
|
|
showGlossary: false,
|
|
...chart
|
|
});
|
|
},
|
|
|
|
selectProfile(e) {
|
|
const id = e.currentTarget.dataset.id;
|
|
const profile = this.data.profiles.find(p => p.id === id);
|
|
if (!profile) return;
|
|
birthProfile.setActiveProfile(id);
|
|
this.showProfile(this.data.profiles, profile);
|
|
},
|
|
|
|
toggleGlossary() {
|
|
this.setData({ showGlossary: !this.data.showGlossary });
|
|
},
|
|
|
|
goSettings() {
|
|
wx.switchTab({ url: '/pages/settings/settings' });
|
|
},
|
|
|
|
goFortune() {
|
|
wx.switchTab({ url: '/pages/fortune/fortune' });
|
|
}
|
|
});
|