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' }); } });