From af0d6cd019e77762b1e657bf8e9ed7fe41fc0e59 Mon Sep 17 00:00:00 2001 From: patdelphi Date: Tue, 19 Aug 2025 09:05:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=95=B4=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=98=93=E7=BB=8F=E5=8D=A0=E5=8D=9C=E7=B3=BB=E7=BB=9F=20-=20?= =?UTF-8?q?=E4=B8=93=E4=B8=9A=E5=8C=96=E5=8D=87=E7=BA=A7=E5=92=8C=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎯 主要更新: - 重构易经分析器:增加多种起卦方法、高级分析、象数理论 - 创建专业前端组件:CompleteYijingAnalysis,参考八字分析样式 - 修复表单验证逻辑:易经占卜只需问题,无需个人信息 - 优化后端API接口:适配新的参数格式和验证逻辑 🚀 功能增强: - 多种起卦方法:时间、梅花易数、金钱卦、数字起卦 - 高级分析:互卦、错卦、综卦四卦综合分析 - 象数理论:八卦数理、时间共振、五行分析 - 动态分析:问题类型识别、时间因素、针对性指导 - 专业展示:卦象符号、爻辞象传、哲学洞察 🔧 技术优化: - 前端表单条件渲染:根据分析类型显示不同表单 - 后端参数验证:易经占卜验证问题而非姓名 - API接口统一:标准化数据传递格式 - 数据库适配:易经记录使用合理默认值 ✅ 问题修复: - 解决'缺少姓名'错误 - 修复按钮无法点击问题 - 优化用户体验和界面响应 --- numerology.db-shm | Bin 32768 -> 32768 bytes numerology.db-wal | Bin 4161232 -> 4161232 bytes server/routes/analysis.cjs | 26 +- server/services/yijingAnalyzer.cjs | 870 ++++++++++++++++++++-- src/components/AnalysisResultDisplay.tsx | 40 +- src/components/CompleteYijingAnalysis.tsx | 736 ++++++++++++++++++ src/lib/localApi.ts | 4 +- src/pages/AnalysisPage.tsx | 156 ++-- 8 files changed, 1690 insertions(+), 142 deletions(-) create mode 100644 src/components/CompleteYijingAnalysis.tsx diff --git a/numerology.db-shm b/numerology.db-shm index f21198d5e933f9716c0a843c1fd5d2ced1c42423..6f33558a0ec7d8650e61a37a7cd4beb2b5cfb129 100644 GIT binary patch delta 1736 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 diff --git a/server/routes/analysis.cjs b/server/routes/analysis.cjs index 4233f11..09fb3f4 100644 --- a/server/routes/analysis.cjs +++ b/server/routes/analysis.cjs @@ -78,21 +78,19 @@ router.post('/bazi', authenticate, asyncHandler(async (req, res) => { // 易经分析接口 router.post('/yijing', authenticate, asyncHandler(async (req, res) => { - const { birth_data, question } = req.body; + const { question, user_id, divination_method } = req.body; // 输入验证 - if (!birth_data || !birth_data.name) { - throw new AppError('缺少必要参数:姓名', 400, 'MISSING_BIRTH_DATA'); + if (!question) { + throw new AppError('缺少必要参数:占卜问题', 400, 'MISSING_QUESTION'); } - const finalQuestion = question || '人生运势综合占卜'; - try { // 执行易经分析 const analysisResult = yijingAnalyzer.performYijingAnalysis({ - question: finalQuestion, - user_id: req.user.id, - birth_data: birth_data + question: question, + user_id: user_id || req.user.id, + divination_method: divination_method || 'time' }); // 保存到数据库 @@ -107,12 +105,12 @@ router.post('/yijing', authenticate, asyncHandler(async (req, res) => { const result = insertReading.run( req.user.id, 'yijing', - birth_data.name, - birth_data.birth_date || null, - birth_data.birth_time || null, - birth_data.birth_place || null, - birth_data.gender || null, - JSON.stringify({ question: finalQuestion, birth_data }), + '易经占卜用户', // 易经占卜不需要真实姓名 + null, // 不需要出生日期 + null, // 不需要出生时间 + null, // 不需要出生地点 + null, // 不需要性别 + JSON.stringify({ question, divination_method }), JSON.stringify(analysisResult), 'completed' ); diff --git a/server/services/yijingAnalyzer.cjs b/server/services/yijingAnalyzer.cjs index 0e7292d..bdb787c 100644 --- a/server/services/yijingAnalyzer.cjs +++ b/server/services/yijingAnalyzer.cjs @@ -1,20 +1,60 @@ -// 易经分析服务模块 -// 完全基于logic/yijing.txt的原始逻辑实现 +// 专业易经分析服务模块 +// 基于传统易学理论的完整实现 class YijingAnalyzer { constructor() { this.initializeHexagrams(); + this.initializeTrigramData(); + this.initializeNumerology(); } - // 易经分析主函数 + // 初始化八卦基础数据 + initializeTrigramData() { + this.TRIGRAMS = { + '乾': { binary: '111', nature: '天', attribute: '刚健', direction: '西北', season: '秋冬之交', family: '父', body: '头', animal: '马', element: '金' }, + '坤': { binary: '000', nature: '地', attribute: '柔顺', direction: '西南', season: '夏秋之交', family: '母', body: '腹', animal: '牛', element: '土' }, + '震': { binary: '001', nature: '雷', attribute: '动', direction: '东', season: '春', family: '长男', body: '足', animal: '龙', element: '木' }, + '巽': { binary: '011', nature: '风', attribute: '入', direction: '东南', season: '春夏之交', family: '长女', body: '股', animal: '鸡', element: '木' }, + '坎': { binary: '010', nature: '水', attribute: '陷', direction: '北', season: '冬', family: '中男', body: '耳', animal: '豕', element: '水' }, + '离': { binary: '101', nature: '火', attribute: '丽', direction: '南', season: '夏', family: '中女', body: '目', animal: '雉', element: '火' }, + '艮': { binary: '100', nature: '山', attribute: '止', direction: '东北', season: '冬春之交', family: '少男', body: '手', animal: '狗', element: '土' }, + '兑': { binary: '110', nature: '泽', attribute: '悦', direction: '西', season: '秋', family: '少女', body: '口', animal: '羊', element: '金' } + }; + } + + // 初始化象数理论 + initializeNumerology() { + this.NUMBERS = { + 1: { trigram: '乾', meaning: '天,创始,领导' }, + 2: { trigram: '兑', meaning: '泽,喜悦,交流' }, + 3: { trigram: '离', meaning: '火,光明,智慧' }, + 4: { trigram: '震', meaning: '雷,震动,行动' }, + 5: { trigram: '巽', meaning: '风,渗透,顺从' }, + 6: { trigram: '坎', meaning: '水,险难,智慧' }, + 7: { trigram: '艮', meaning: '山,静止,稳定' }, + 8: { trigram: '坤', meaning: '地,承载,包容' } + }; + } + + // 专业易经分析主函数 performYijingAnalysis(inputData) { try { - const { question, user_id, birth_data } = inputData; + const { question, user_id, birth_data, divination_method = 'time' } = inputData; const currentTime = new Date(); - const hexagramData = this.generateHexagram(currentTime, user_id); + + // 根据不同方法起卦 + const hexagramData = this.generateHexagramByMethod(divination_method, currentTime, user_id, question); const mainHexagramInfo = this.getHexagramInfo(hexagramData.mainHex); const changingHexagramInfo = this.getChangingHexagram(mainHexagramInfo, hexagramData.changingLines); - const changingLineAnalysis = this.analyzeChangingLines(mainHexagramInfo, hexagramData.changingLines); + + // 高级分析:互卦、错卦、综卦 + const advancedAnalysis = this.performAdvancedAnalysis(mainHexagramInfo, changingHexagramInfo); + + // 动态分析:基于问题类型和时间因素 + const dynamicAnalysis = this.generateDynamicAnalysis(mainHexagramInfo, changingHexagramInfo, question, currentTime); + + // 象数分析 + const numerologyAnalysis = this.performNumerologyAnalysis(hexagramData, currentTime); return { analysis_type: 'yijing', @@ -23,44 +63,40 @@ class YijingAnalyzer { divination_data: { question: question, divination_time: currentTime.toISOString(), - method: '梅花易数时间起卦法' + method: this.getMethodName(divination_method), + lunar_info: this.calculateLunarInfo(currentTime) }, hexagram_info: { main_hexagram: mainHexagramInfo.name, main_hexagram_symbol: mainHexagramInfo.symbol, + main_hexagram_number: mainHexagramInfo.number, + upper_trigram: mainHexagramInfo.upperTrigram, + lower_trigram: mainHexagramInfo.lowerTrigram, changing_hexagram: changingHexagramInfo ? changingHexagramInfo.name : '无', changing_hexagram_symbol: changingHexagramInfo ? changingHexagramInfo.symbol : '无', changing_lines: hexagramData.changingLines, - detailed_interpretation: `您得到的本卦是【${mainHexagramInfo.name}】,${mainHexagramInfo.judgment}` + hexagram_structure: this.analyzeHexagramStructure(mainHexagramInfo) } }, detailed_analysis: { hexagram_analysis: { - primary_meaning: `【${mainHexagramInfo.name}卦】 - ${mainHexagramInfo.meaning}`, + primary_meaning: `【${mainHexagramInfo.name}卦】第${mainHexagramInfo.number}卦 - ${mainHexagramInfo.meaning}`, judgment: `【彖传】曰:${mainHexagramInfo.judgment}`, - image: `【象传】曰:${mainHexagramInfo.image}` + image: `【象传】曰:${mainHexagramInfo.image}`, + trigram_analysis: this.analyzeTrigramCombination(mainHexagramInfo.upperTrigram, mainHexagramInfo.lowerTrigram), + five_elements: this.analyzeFiveElements(mainHexagramInfo) }, - changing_lines_analysis: changingLineAnalysis, - changing_hexagram_analysis: changingHexagramInfo ? { - name: `变卦为【${changingHexagramInfo.name}】`, - meaning: changingHexagramInfo.meaning, - transformation_insight: `从【${mainHexagramInfo.name}】到【${changingHexagramInfo.name}】的变化,预示着:${changingHexagramInfo.transformation || '事态将发生转变'}` - } : { - name: '无变卦', - meaning: '事态稳定,应以本卦为主要参考。', - transformation_insight: '没有动爻,表示当前状况将持续一段时间,应专注于当下。' - } - }, - life_guidance: { - overall_fortune: this.generateOverallFortune(mainHexagramInfo, changingHexagramInfo, question), - career_guidance: this.generateCareerAdvice(mainHexagramInfo, changingHexagramInfo), - relationship_guidance: this.generateRelationshipAdvice(mainHexagramInfo, changingHexagramInfo) + changing_lines_analysis: this.analyzeChangingLines(mainHexagramInfo, hexagramData.changingLines), + changing_hexagram_analysis: this.analyzeChangingHexagram(mainHexagramInfo, changingHexagramInfo), + advanced_analysis: advancedAnalysis, + numerology_analysis: numerologyAnalysis }, + dynamic_guidance: dynamicAnalysis, divination_wisdom: { - key_message: mainHexagramInfo.keyMessage || '保持平常心,顺势而为', - action_advice: mainHexagramInfo.actionAdvice || '谨慎行事,稳步前进', - warning: mainHexagramInfo.warning || '无特别警示', - philosophical_insight: `《易经》${mainHexagramInfo.name}卦的核心智慧在于:${mainHexagramInfo.philosophy || '顺应自然,把握时机'}` + key_message: this.generateKeyMessage(mainHexagramInfo, changingHexagramInfo, question), + action_advice: this.generateActionAdvice(mainHexagramInfo, changingHexagramInfo, currentTime), + timing_guidance: this.generateTimingGuidance(mainHexagramInfo, currentTime), + philosophical_insight: this.generatePhilosophicalInsight(mainHexagramInfo, changingHexagramInfo) } }; } catch (error) { @@ -69,8 +105,24 @@ class YijingAnalyzer { } } - // 生成卦象 - generateHexagram(currentTime, userId) { + // 根据不同方法生成卦象 + generateHexagramByMethod(method, currentTime, userId, question) { + switch (method) { + case 'time': + return this.generateHexagramByTime(currentTime, userId); + case 'plum_blossom': + return this.generateHexagramByPlumBlossom(currentTime, question); + case 'coin': + return this.generateHexagramByCoin(); + case 'number': + return this.generateHexagramByNumber(currentTime, userId); + default: + return this.generateHexagramByTime(currentTime, userId); + } + } + + // 梅花易数时间起卦法 + generateHexagramByTime(currentTime, userId) { const year = currentTime.getFullYear(); const month = currentTime.getMonth() + 1; const day = currentTime.getDate(); @@ -87,10 +139,99 @@ class YijingAnalyzer { return { mainHex: mainHexNumber, - changingLines: [changingLinePos] + changingLines: [changingLinePos], + method: '梅花易数时间起卦法', + upperTrigram: upperTrigramNum, + lowerTrigram: lowerTrigramNum }; } + // 梅花易数外应起卦法 + generateHexagramByPlumBlossom(currentTime, question) { + const questionLength = question ? question.length : 8; + const timeSum = currentTime.getHours() + currentTime.getMinutes(); + + const upperTrigramNum = (questionLength + timeSum) % 8 || 8; + const lowerTrigramNum = (questionLength * 2 + timeSum) % 8 || 8; + const changingLinePos = (questionLength + timeSum) % 6 + 1; + + const mainHexNumber = this.getHexagramNumber(upperTrigramNum, lowerTrigramNum); + + return { + mainHex: mainHexNumber, + changingLines: [changingLinePos], + method: '梅花易数外应起卦法', + upperTrigram: upperTrigramNum, + lowerTrigram: lowerTrigramNum + }; + } + + // 金钱卦起卦法(模拟) + generateHexagramByCoin() { + const lines = []; + const changingLines = []; + + for (let i = 0; i < 6; i++) { + // 模拟投掷三枚硬币 + const coin1 = Math.random() > 0.5 ? 3 : 2; // 正面3,反面2 + const coin2 = Math.random() > 0.5 ? 3 : 2; + const coin3 = Math.random() > 0.5 ? 3 : 2; + const sum = coin1 + coin2 + coin3; + + if (sum === 6) { // 老阴,变阳 + lines.push(0); + changingLines.push(i + 1); + } else if (sum === 7) { // 少阳 + lines.push(1); + } else if (sum === 8) { // 少阴 + lines.push(0); + } else if (sum === 9) { // 老阳,变阴 + lines.push(1); + changingLines.push(i + 1); + } + } + + const binary = lines.join(''); + const mainHexNumber = this.getHexagramByBinary(binary); + + return { + mainHex: mainHexNumber, + changingLines: changingLines, + method: '金钱卦起卦法', + binary: binary + }; + } + + // 数字起卦法 + generateHexagramByNumber(currentTime, userId) { + const timeNum = currentTime.getTime(); + const userNum = userId ? parseInt(String(userId).slice(-3)) || 123 : 123; + + const upperTrigramNum = (Math.floor(timeNum / 1000) + userNum) % 8 || 8; + const lowerTrigramNum = (Math.floor(timeNum / 100) + userNum * 2) % 8 || 8; + const changingLinePos = (timeNum + userNum) % 6 + 1; + + const mainHexNumber = this.getHexagramNumber(upperTrigramNum, lowerTrigramNum); + + return { + mainHex: mainHexNumber, + changingLines: [changingLinePos], + method: '数字起卦法', + upperTrigram: upperTrigramNum, + lowerTrigram: lowerTrigramNum + }; + } + + // 根据二进制获取卦象 + getHexagramByBinary(binary) { + for (const hexNum in this.ALL_HEXAGRAMS) { + if (this.ALL_HEXAGRAMS[hexNum].binary === binary) { + return parseInt(hexNum); + } + } + return 1; + } + // 获取卦象编号 getHexagramNumber(upper, lower) { const trigramMap = { @@ -115,39 +256,86 @@ class YijingAnalyzer { return this.ALL_HEXAGRAMS[hexNumber] || this.ALL_HEXAGRAMS[1]; } - // 分析动爻 + // 专业动爻分析 analyzeChangingLines(hexagramInfo, changingLines) { if (!changingLines || changingLines.length === 0) { return { method: '以本卦卦辞为断', analysis: `无动爻,应以【${hexagramInfo.name}】的整体卦辞为主要判断依据。`, - guidance: hexagramInfo.judgment + guidance: hexagramInfo.judgment, + interpretation: '静卦主静,事态稳定,当前状况将持续一段时间。应专注于当下,不宜有大的变动。' }; } - const linePos = changingLines[0]; - const lineIndex = linePos - 1; - const lineData = hexagramInfo.lines[lineIndex]; + const analyses = []; - if (!lineData) { - return { - method: '动爻分析异常', - analysis: '无法找到对应的爻辞信息。', - guidance: '' - }; - } - - const lineName = ['初', '二', '三', '四', '五', '上'][lineIndex] + (lineData.type === 'yang' ? '九' : '六'); + changingLines.forEach(linePos => { + const lineIndex = linePos - 1; + const lineData = hexagramInfo.lines[lineIndex]; + + if (lineData) { + const lineName = ['初', '二', '三', '四', '五', '上'][lineIndex] + (lineData.type === 'yang' ? '九' : '六'); + const linePosition = this.getLinePosition(lineIndex); + + analyses.push({ + line_position: `${lineName}(第${linePos}爻)`, + line_nature: lineData.type === 'yang' ? '阳爻' : '阴爻', + position_meaning: linePosition.meaning, + line_text: `【爻辞】曰:${lineData.text}`, + line_image: `【象传】曰:${lineData.image}`, + practical_guidance: this.generateLineGuidance(lineData, lineIndex, hexagramInfo) + }); + } + }); return { - method: '以动爻爻辞为断', - changing_line_position: `${lineName}(第${linePos}爻)`, - line_meaning: `【爻辞】曰:${lineData.text}`, - line_image_meaning: `【象传】对该爻的解释:${lineData.image}`, - guidance: `当前阶段的关键点在于理解和应对"${lineData.text}"所揭示的情况。` + method: changingLines.length === 1 ? '以动爻爻辞为断' : '以多爻变化综合判断', + changing_lines_count: changingLines.length, + detailed_analysis: analyses, + overall_guidance: this.generateChangingLinesGuidance(analyses, changingLines.length) }; } + // 获取爻位含义 + getLinePosition(lineIndex) { + const positions = [ + { name: '初爻', meaning: '事物的开始阶段,基础地位,需要谨慎起步' }, + { name: '二爻', meaning: '臣位,中正之位,适合辅助和配合' }, + { name: '三爻', meaning: '人位,多忧之位,需要特别小心' }, + { name: '四爻', meaning: '近君之位,接近成功,但需谨慎' }, + { name: '五爻', meaning: '君位,最尊贵的位置,主导地位' }, + { name: '上爻', meaning: '事物的终结阶段,物极必反' } + ]; + return positions[lineIndex] || { name: '未知', meaning: '位置不明' }; + } + + // 生成爻辞指导 + generateLineGuidance(lineData, lineIndex, hexagramInfo) { + const position = this.getLinePosition(lineIndex); + const baseGuidance = `在${position.name}的位置上,${lineData.text}的含义是:`; + + // 根据爻的阴阳和位置生成具体指导 + if (lineData.type === 'yang' && lineIndex % 2 === 0) { + return baseGuidance + '阳爻居阳位,得正,行动力强,但需要把握分寸。'; + } else if (lineData.type === 'yin' && lineIndex % 2 === 1) { + return baseGuidance + '阴爻居阴位,得正,柔顺有利,适合守静待时。'; + } else { + return baseGuidance + '爻位不正,需要调整策略,避免过于激进或消极。'; + } + } + + // 生成动爻综合指导 + generateChangingLinesGuidance(analyses, count) { + if (count === 1) { + return '单爻发动,变化明确,应重点关注该爻的指示。'; + } else if (count === 2) { + return '两爻发动,变化复杂,需要综合考虑两个方面的因素。'; + } else if (count >= 3) { + return '多爻发动,变化剧烈,事态复杂多变,需要格外谨慎。'; + } + return '变化情况需要仔细分析。'; + } + // 获取变卦 getChangingHexagram(originalHexInfo, changingLines) { if (!changingLines || changingLines.length === 0) { @@ -172,17 +360,537 @@ class YijingAnalyzer { return null; } - // 生成整体运势分析 - generateOverallFortune(mainHex, changeHex, question) { - let fortune = `针对您的问题"${question}",本卦为【${mainHex.name}】,指示了当前的基本状况:${mainHex.guidance}。`; + // 高级分析:互卦、错卦、综卦 + performAdvancedAnalysis(mainHex, changeHex) { + const interHex = this.getInterHexagram(mainHex); + const oppositeHex = this.getOppositeHexagram(mainHex); + const reverseHex = this.getReverseHexagram(mainHex); - if (changeHex) { - fortune += ` 动爻预示着变化,未来趋势可参考变卦【${changeHex.name}】:${changeHex.guidance}。`; + return { + inter_hexagram: { + name: interHex.name, + symbol: interHex.symbol, + meaning: interHex.meaning, + analysis: `互卦【${interHex.name}】揭示了事物的内在发展趋势和隐藏因素。${interHex.guidance}` + }, + opposite_hexagram: { + name: oppositeHex.name, + symbol: oppositeHex.symbol, + meaning: oppositeHex.meaning, + analysis: `错卦【${oppositeHex.name}】代表了相对立的状态和需要避免的方向。${oppositeHex.guidance}` + }, + reverse_hexagram: { + name: reverseHex.name, + symbol: reverseHex.symbol, + meaning: reverseHex.meaning, + analysis: `综卦【${reverseHex.name}】显示了事物的另一面和可能的转化方向。${reverseHex.guidance}` + }, + comprehensive_insight: this.generateComprehensiveInsight(mainHex, interHex, oppositeHex, reverseHex) + }; + } + + // 获取互卦 + getInterHexagram(hexInfo) { + const binary = hexInfo.binary; + // 互卦取2、3、4爻为下卦,3、4、5爻为上卦 + const lowerInter = binary.substring(3, 6); // 2、3、4爻 + const upperInter = binary.substring(2, 5); // 3、4、5爻 + const interBinary = upperInter + lowerInter; + + for (const hexNum in this.ALL_HEXAGRAMS) { + if (this.ALL_HEXAGRAMS[hexNum].binary === interBinary) { + return this.ALL_HEXAGRAMS[hexNum]; + } + } + return this.ALL_HEXAGRAMS[1]; // 默认返回乾卦 + } + + // 获取错卦(阴阳相反) + getOppositeHexagram(hexInfo) { + const binary = hexInfo.binary; + const oppositeBinary = binary.split('').map(bit => bit === '1' ? '0' : '1').join(''); + + for (const hexNum in this.ALL_HEXAGRAMS) { + if (this.ALL_HEXAGRAMS[hexNum].binary === oppositeBinary) { + return this.ALL_HEXAGRAMS[hexNum]; + } + } + return this.ALL_HEXAGRAMS[2]; // 默认返回坤卦 + } + + // 获取综卦(上下颠倒) + getReverseHexagram(hexInfo) { + const binary = hexInfo.binary; + const reverseBinary = binary.split('').reverse().join(''); + + for (const hexNum in this.ALL_HEXAGRAMS) { + if (this.ALL_HEXAGRAMS[hexNum].binary === reverseBinary) { + return this.ALL_HEXAGRAMS[hexNum]; + } + } + return hexInfo; // 如果没找到,返回原卦 + } + + // 生成综合洞察 + generateComprehensiveInsight(mainHex, interHex, oppositeHex, reverseHex) { + return `通过四卦分析:本卦【${mainHex.name}】显示当前状态,互卦【${interHex.name}】揭示内在动力,错卦【${oppositeHex.name}】提醒对立面,综卦【${reverseHex.name}】指示转化方向。综合来看,需要在${mainHex.meaning}的基础上,注意${interHex.meaning}的内在发展,避免${oppositeHex.meaning}的极端,向${reverseHex.meaning}的方向转化。`; + } + + // 动态分析:基于问题类型和时间因素 + generateDynamicAnalysis(mainHex, changeHex, question, currentTime) { + const questionType = this.analyzeQuestionType(question); + const timeFactors = this.analyzeTimeFactors(currentTime); + + return { + question_analysis: { + type: questionType.type, + focus: questionType.focus, + approach: questionType.approach + }, + time_analysis: timeFactors, + targeted_guidance: this.generateTargetedGuidance(mainHex, changeHex, questionType, timeFactors), + practical_advice: this.generatePracticalAdvice(mainHex, changeHex, questionType) + }; + } + + // 分析问题类型 + analyzeQuestionType(question) { + const lowerQuestion = question.toLowerCase(); + + if (lowerQuestion.includes('事业') || lowerQuestion.includes('工作') || lowerQuestion.includes('职业')) { + return { + type: '事业发展', + focus: '职场发展、事业规划、工作机会', + approach: '重点关注事业宫位和变化趋势' + }; + } else if (lowerQuestion.includes('感情') || lowerQuestion.includes('爱情') || lowerQuestion.includes('婚姻')) { + return { + type: '感情婚姻', + focus: '情感关系、婚姻状况、人际和谐', + approach: '重点关注感情因素和人际关系' + }; + } else if (lowerQuestion.includes('财运') || lowerQuestion.includes('投资') || lowerQuestion.includes('金钱')) { + return { + type: '财运投资', + focus: '财富积累、投资机会、经济状况', + approach: '重点关注财运变化和投资时机' + }; + } else if (lowerQuestion.includes('健康') || lowerQuestion.includes('身体')) { + return { + type: '健康养生', + focus: '身体状况、健康维护、疾病预防', + approach: '重点关注身体状态和养生方法' + }; } else { - fortune += ` 事态稳定,应专注于当前状况。`; + return { + type: '综合运势', + focus: '整体发展、综合状况、全面分析', + approach: '全面分析各个方面的发展趋势' + }; + } + } + + // 分析时间因素 + analyzeTimeFactors(currentTime) { + const month = currentTime.getMonth() + 1; + const season = this.getSeason(month); + const hour = currentTime.getHours(); + const timeOfDay = this.getTimeOfDay(hour); + + return { + season: season, + time_of_day: timeOfDay, + lunar_phase: this.getLunarPhase(currentTime), + energy_state: this.getEnergyState(season, timeOfDay) + }; + } + + // 获取季节 + getSeason(month) { + if (month >= 3 && month <= 5) return { name: '春季', energy: '生发之气', advice: '适合开始新事物' }; + if (month >= 6 && month <= 8) return { name: '夏季', energy: '旺盛之气', advice: '适合积极行动' }; + if (month >= 9 && month <= 11) return { name: '秋季', energy: '收敛之气', advice: '适合收获总结' }; + return { name: '冬季', energy: '潜藏之气', advice: '适合休养生息' }; + } + + // 获取时辰 + getTimeOfDay(hour) { + if (hour >= 5 && hour < 7) return { name: '卯时', energy: '日出东方', advice: '新的开始' }; + if (hour >= 7 && hour < 9) return { name: '辰时', energy: '朝阳初升', advice: '积极进取' }; + if (hour >= 9 && hour < 11) return { name: '巳时', energy: '阳气渐盛', advice: '努力工作' }; + if (hour >= 11 && hour < 13) return { name: '午时', energy: '阳气最盛', advice: '把握机会' }; + if (hour >= 13 && hour < 15) return { name: '未时', energy: '阳气渐衰', advice: '稳步前进' }; + if (hour >= 15 && hour < 17) return { name: '申时', energy: '阳气转阴', advice: '谨慎行事' }; + if (hour >= 17 && hour < 19) return { name: '酉时', energy: '日落西山', advice: '收敛锋芒' }; + if (hour >= 19 && hour < 21) return { name: '戌时', energy: '阴气渐盛', advice: '休息调整' }; + if (hour >= 21 && hour < 23) return { name: '亥时', energy: '夜深人静', advice: '内省思考' }; + if (hour >= 23 || hour < 1) return { name: '子时', energy: '阴极阳生', advice: '蓄势待发' }; + if (hour >= 1 && hour < 3) return { name: '丑时', energy: '阴气深重', advice: '静心养神' }; + return { name: '寅时', energy: '阳气初动', advice: '准备行动' }; + } + + // 象数分析 + performNumerologyAnalysis(hexagramData, currentTime) { + const upperNum = hexagramData.upperTrigram || 1; + const lowerNum = hexagramData.lowerTrigram || 1; + const totalNum = upperNum + lowerNum; + + return { + upper_trigram_number: { + number: upperNum, + meaning: this.NUMBERS[upperNum]?.meaning || '未知', + influence: '代表外在环境和表面现象' + }, + lower_trigram_number: { + number: lowerNum, + meaning: this.NUMBERS[lowerNum]?.meaning || '未知', + influence: '代表内在动机和根本原因' + }, + combined_energy: { + total: totalNum, + interpretation: this.interpretCombinedNumber(totalNum), + harmony: this.analyzeNumberHarmony(upperNum, lowerNum) + }, + time_resonance: this.analyzeTimeResonance(totalNum, currentTime) + }; + } + + // 解释组合数字 + interpretCombinedNumber(num) { + const interpretations = { + 2: '极简之数,需要积累', + 3: '生发之数,开始行动', + 4: '稳定之数,循序渐进', + 5: '变化之数,灵活应对', + 6: '和谐之数,平衡发展', + 7: '完善之数,精益求精', + 8: '丰盛之数,收获时机', + 9: '圆满之数,功德圆满', + 10: '完成之数,新的开始', + 11: '突破之数,创新变革', + 12: '循环之数,周而复始', + 13: '转化之数,质的飞跃', + 14: '调和之数,协调统一', + 15: '圆融之数,和谐共生', + 16: '极盛之数,物极必反' + }; + return interpretations[num] || '特殊之数,需要特别关注'; + } + + // 分析数字和谐度 + analyzeNumberHarmony(upper, lower) { + const diff = Math.abs(upper - lower); + if (diff === 0) return '完全和谐,内外一致'; + if (diff === 1) return '基本和谐,略有差异'; + if (diff === 2) return '适度张力,需要平衡'; + if (diff >= 3) return '较大差异,需要调和'; + return '需要进一步分析'; + } + + // 添加更多专业分析方法 + + // 获取起卦方法名称 + getMethodName(method) { + const methods = { + 'time': '梅花易数时间起卦法', + 'plum_blossom': '梅花易数外应起卦法', + 'coin': '金钱卦起卦法', + 'number': '数字起卦法' + }; + return methods[method] || '传统起卦法'; + } + + // 计算农历信息 + calculateLunarInfo(currentTime) { + // 简化的农历计算,实际应用中需要更精确的算法 + const year = currentTime.getFullYear(); + const month = currentTime.getMonth() + 1; + const day = currentTime.getDate(); + + return { + year: `${year}年`, + month: `${month}月`, + day: `${day}日`, + note: '农历信息需要专业历法计算' + }; + } + + // 分析卦象结构 + analyzeHexagramStructure(hexInfo) { + const upperTrigram = this.TRIGRAMS[hexInfo.upperTrigram]; + const lowerTrigram = this.TRIGRAMS[hexInfo.lowerTrigram]; + + return { + upper_trigram: { + name: hexInfo.upperTrigram, + nature: upperTrigram?.nature || '未知', + attribute: upperTrigram?.attribute || '未知', + element: upperTrigram?.element || '未知' + }, + lower_trigram: { + name: hexInfo.lowerTrigram, + nature: lowerTrigram?.nature || '未知', + attribute: lowerTrigram?.attribute || '未知', + element: lowerTrigram?.element || '未知' + }, + interaction: this.analyzeTrigramInteraction(upperTrigram, lowerTrigram) + }; + } + + // 分析八卦组合 + analyzeTrigramCombination(upperName, lowerName) { + const upper = this.TRIGRAMS[upperName]; + const lower = this.TRIGRAMS[lowerName]; + + if (!upper || !lower) { + return '八卦信息不完整,无法分析'; } - return fortune; + return `上卦${upperName}(${upper.nature})代表${upper.attribute},下卦${lowerName}(${lower.nature})代表${lower.attribute}。${upper.nature}在上,${lower.nature}在下,形成${upperName}${lowerName}的组合,象征着${this.getTrigramCombinationMeaning(upperName, lowerName)}。`; + } + + // 获取八卦组合含义 + getTrigramCombinationMeaning(upper, lower) { + const combinations = { + '乾乾': '天行健,自强不息的力量', + '坤坤': '地势坤,厚德载物的包容', + '乾坤': '天地定位,阴阳和谐', + '坤乾': '地天泰,通达顺畅', + '震巽': '雷风相薄,变化迅速', + '巽震': '风雷益,增益发展', + '坎离': '水火既济,阴阳调和', + '离坎': '火水未济,尚需努力' + }; + return combinations[upper + lower] || '特殊的能量组合,需要深入分析'; + } + + // 分析八卦相互作用 + analyzeTrigramInteraction(upper, lower) { + if (!upper || !lower) return '无法分析八卦相互作用'; + + const upperElement = upper.element; + const lowerElement = lower.element; + + return this.analyzeFiveElementsInteraction(upperElement, lowerElement); + } + + // 分析五行关系 + analyzeFiveElements(hexInfo) { + const upperTrigram = this.TRIGRAMS[hexInfo.upperTrigram]; + const lowerTrigram = this.TRIGRAMS[hexInfo.lowerTrigram]; + + if (!upperTrigram || !lowerTrigram) { + return '五行信息不完整'; + } + + const upperElement = upperTrigram.element; + const lowerElement = lowerTrigram.element; + + return { + upper_element: upperElement, + lower_element: lowerElement, + relationship: this.analyzeFiveElementsInteraction(upperElement, lowerElement), + balance: this.analyzeFiveElementsBalance(upperElement, lowerElement) + }; + } + + // 分析五行相互作用 + analyzeFiveElementsInteraction(element1, element2) { + const interactions = { + '金金': '同气相求,力量集中', + '金木': '金克木,需要调和', + '金水': '金生水,相生有利', + '金火': '火克金,存在冲突', + '金土': '土生金,得到支持', + '木木': '同气相求,生机勃勃', + '木水': '水生木,滋养成长', + '木火': '木生火,能量转化', + '木土': '木克土,需要平衡', + '水水': '同气相求,流动不息', + '水火': '水火不容,需要调和', + '水土': '土克水,存在阻碍', + '火火': '同气相求,热情高涨', + '火土': '火生土,稳固发展', + '土土': '同气相求,稳重厚实' + }; + + return interactions[element1 + element2] || interactions[element2 + element1] || '五行关系复杂,需要综合分析'; + } + + // 分析五行平衡 + analyzeFiveElementsBalance(element1, element2) { + if (element1 === element2) { + return '五行同类,力量集中,但可能缺乏变化'; + } + + const generative = ['金水', '水木', '木火', '火土', '土金']; + const destructive = ['金木', '木土', '土水', '水火', '火金']; + + const combination = element1 + element2; + const reverseCombination = element2 + element1; + + if (generative.includes(combination) || generative.includes(reverseCombination)) { + return '五行相生,和谐发展,有利于事物的成长'; + } else if (destructive.includes(combination) || destructive.includes(reverseCombination)) { + return '五行相克,存在冲突,需要化解或利用这种张力'; + } + + return '五行关系中性,需要根据具体情况分析'; + } + + // 分析变卦 + analyzeChangingHexagram(mainHex, changeHex) { + if (!changeHex) { + return { + name: '无变卦', + meaning: '事态稳定,应以本卦为主要参考', + transformation_insight: '没有动爻,表示当前状况将持续一段时间,应专注于当下,不宜有大的变动。', + guidance: '保持现状,稳步发展,等待时机成熟再做改变。' + }; + } + + return { + name: `变卦为【${changeHex.name}】`, + meaning: changeHex.meaning, + transformation_insight: `从【${mainHex.name}】到【${changeHex.name}】的变化,预示着${this.generateTransformationInsight(mainHex, changeHex)}`, + guidance: `变卦指示:${changeHex.guidance}`, + timing: this.analyzeTransformationTiming(mainHex, changeHex) + }; + } + + // 生成转化洞察 + generateTransformationInsight(mainHex, changeHex) { + const mainMeaning = mainHex.meaning; + const changeMeaning = changeHex.meaning; + + return `事态将从${mainMeaning}转向${changeMeaning},这是一个重要的转折点。需要适应这种变化,调整策略和心态。`; + } + + // 分析转化时机 + analyzeTransformationTiming(mainHex, changeHex) { + // 根据卦象的性质分析转化的快慢 + const fastChangingHexagrams = [1, 4, 16, 25, 34, 51]; // 乾、蒙、豫、无妄、大壮、震等 + const slowChangingHexagrams = [2, 15, 23, 52]; // 坤、谦、剥、艮等 + + if (fastChangingHexagrams.includes(changeHex.number)) { + return '变化将会比较迅速,需要及时应对'; + } else if (slowChangingHexagrams.includes(changeHex.number)) { + return '变化将会比较缓慢,有充分的准备时间'; + } + + return '变化的速度适中,需要保持关注'; + } + + // 生成关键信息 + generateKeyMessage(mainHex, changeHex, question) { + const baseMessage = mainHex.keyMessage || '顺应自然,把握时机'; + + if (changeHex) { + return `${baseMessage}。变化在即,${changeHex.keyMessage || '需要适应新的形势'}。`; + } + + return baseMessage; + } + + // 生成行动建议 + generateActionAdvice(mainHex, changeHex, currentTime) { + const season = this.getSeason(currentTime.getMonth() + 1); + const timeOfDay = this.getTimeOfDay(currentTime.getHours()); + + let advice = mainHex.actionAdvice || '谨慎行事,稳步前进'; + + // 结合时间因素 + advice += ` 当前正值${season.name},${season.advice}。`; + advice += ` 现在是${timeOfDay.name},${timeOfDay.advice}。`; + + if (changeHex) { + advice += ` 考虑到即将到来的变化,建议:${changeHex.actionAdvice || '做好准备,迎接转变'}。`; + } + + return advice; + } + + // 生成时机指导 + generateTimingGuidance(mainHex, currentTime) { + const hour = currentTime.getHours(); + const month = currentTime.getMonth() + 1; + + let guidance = '时机分析:'; + + // 根据时辰分析 + if (hour >= 5 && hour < 11) { + guidance += '上午时光,阳气上升,适合开始新的行动。'; + } else if (hour >= 11 && hour < 17) { + guidance += '下午时光,阳气鼎盛,适合推进重要事务。'; + } else { + guidance += '晚间时光,阴气渐盛,适合思考和规划。'; + } + + // 根据季节分析 + const season = this.getSeason(month); + guidance += ` ${season.name}${season.advice}。`; + + return guidance; + } + + // 生成哲学洞察 + generatePhilosophicalInsight(mainHex, changeHex) { + let insight = `《易经》${mainHex.name}卦的核心智慧在于:${mainHex.philosophy || '顺应自然规律,把握变化时机'}。`; + + if (changeHex) { + insight += ` 而变卦${changeHex.name}则提醒我们:${changeHex.philosophy || '变化是永恒的,适应是智慧的'}。`; + } + + insight += ' 《易经》告诉我们,万事万物都在变化之中,智者应该顺应这种变化,在变化中寻找机遇,在稳定中积蓄力量。'; + + return insight; + } + + // 获取月相(简化版) + getLunarPhase(currentTime) { + const day = currentTime.getDate(); + if (day <= 7) return { name: '新月', energy: '新的开始', advice: '适合播种和规划' }; + if (day <= 14) return { name: '上弦月', energy: '成长发展', advice: '适合努力和进取' }; + if (day <= 21) return { name: '满月', energy: '圆满充实', advice: '适合收获和庆祝' }; + return { name: '下弦月', energy: '反思总结', advice: '适合整理和准备' }; + } + + // 获取能量状态 + getEnergyState(season, timeOfDay) { + const seasonEnergy = season.energy; + const timeEnergy = timeOfDay.energy; + + return { + overall: `${seasonEnergy}与${timeEnergy}相结合`, + recommendation: `在${season.name}的${timeOfDay.name},${season.advice},同时${timeOfDay.advice}` + }; + } + + // 生成针对性指导 + generateTargetedGuidance(mainHex, changeHex, questionType, timeFactors) { + let guidance = `针对您关于${questionType.type}的问题,`; + guidance += `本卦【${mainHex.name}】在${questionType.focus}方面的指示是:${mainHex.guidance}。`; + + if (changeHex) { + guidance += ` 变卦【${changeHex.name}】预示着在${questionType.focus}方面将会有所转变。`; + } + + guidance += ` 结合当前的时间因素(${timeFactors.season.name},${timeFactors.time_of_day.name}),建议您${timeFactors.season.advice}。`; + + return guidance; + } + + // 生成实用建议 + generatePracticalAdvice(mainHex, changeHex, questionType) { + const adviceMap = { + '事业发展': this.generateCareerAdvice(mainHex, changeHex), + '感情婚姻': this.generateRelationshipAdvice(mainHex, changeHex), + '财运投资': this.generateFinancialAdvice(mainHex, changeHex), + '健康养生': this.generateHealthAdvice(mainHex, changeHex), + '综合运势': this.generateGeneralAdvice(mainHex, changeHex) + }; + + return adviceMap[questionType.type] || this.generateGeneralAdvice(mainHex, changeHex); } // 生成事业建议 @@ -207,6 +915,52 @@ class YijingAnalyzer { return advice; } + // 生成财运建议 + generateFinancialAdvice(mainHex, changeHex) { + let advice = `财运方面,本卦【${mainHex.name}】显示:"${mainHex.wealth || mainHex.guidance}"。`; + + if (changeHex) { + advice += ` 变卦【${changeHex.name}】预示财运可能向"${changeHex.wealth || changeHex.guidance}"的方向发展。`; + } + + return advice; + } + + // 生成健康建议 + generateHealthAdvice(mainHex, changeHex) { + let advice = `健康方面,本卦【${mainHex.name}】提醒:"${mainHex.health || mainHex.guidance}"。`; + + if (changeHex) { + advice += ` 变卦【${changeHex.name}】暗示健康状况可能朝"${changeHex.health || changeHex.guidance}"的方向变化。`; + } + + return advice; + } + + // 生成综合建议 + generateGeneralAdvice(mainHex, changeHex) { + let advice = `综合来看,本卦【${mainHex.name}】的总体指导是:"${mainHex.guidance}"。`; + + if (changeHex) { + advice += ` 变卦【${changeHex.name}】提示未来趋势:"${changeHex.guidance}"。`; + } + + return advice; + } + + // 分析时间共振 + analyzeTimeResonance(totalNum, currentTime) { + const hour = currentTime.getHours(); + const day = currentTime.getDate(); + const resonance = (totalNum + hour + day) % 8 + 1; + + return { + resonance_number: resonance, + meaning: this.NUMBERS[resonance]?.meaning || '未知', + interpretation: `当前时间与卦象数字的共振显示:${this.NUMBERS[resonance]?.meaning || '特殊的能量状态'}` + }; + } + // 初始化64卦数据 initializeHexagrams() { this.ALL_HEXAGRAMS = { diff --git a/src/components/AnalysisResultDisplay.tsx b/src/components/AnalysisResultDisplay.tsx index 814342b..14acd6b 100644 --- a/src/components/AnalysisResultDisplay.tsx +++ b/src/components/AnalysisResultDisplay.tsx @@ -1,6 +1,7 @@ import React from 'react'; import CompleteBaziAnalysis from './CompleteBaziAnalysis'; import CompleteZiweiAnalysis from './CompleteZiweiAnalysis'; +import CompleteYijingAnalysis from './CompleteYijingAnalysis'; import BaziAnalysisDisplay from './BaziAnalysisDisplay'; interface AnalysisResultDisplayProps { @@ -10,9 +11,19 @@ interface AnalysisResultDisplayProps { date: string; time: string; }; + question?: string; + userId?: string; + divinationMethod?: string; } -const AnalysisResultDisplay: React.FC = ({ analysisResult, analysisType, birthDate }) => { +const AnalysisResultDisplay: React.FC = ({ + analysisResult, + analysisType, + birthDate, + question, + userId, + divinationMethod +}) => { // 安全地获取数据的辅助函数 const safeGet = (obj: any, path: string, defaultValue: any = '暂无数据') => { const keys = path.split('.'); @@ -238,7 +249,32 @@ const AnalysisResultDisplay: React.FC = ({ analysisR // 渲染易经占卜分析 const renderYijingAnalysis = () => { - // 处理新的数据结构: { type: 'yijing', data: analysisResult } + // 如果有问题参数,使用新的 CompleteYijingAnalysis 组件 + if (question) { + return ( + + ); + } + + // 如果有分析结果但没有问题参数,尝试从结果中提取问题信息 + if (analysisResult && analysisResult.data) { + const basicInfo = analysisResult.data.basic_info; + if (basicInfo && basicInfo.divination_data) { + return ( + + ); + } + } + + // 回退到旧的渲染方式(向后兼容) const data = analysisResult?.data || analysisResult; return ( diff --git a/src/components/CompleteYijingAnalysis.tsx b/src/components/CompleteYijingAnalysis.tsx new file mode 100644 index 0000000..9d2f7b0 --- /dev/null +++ b/src/components/CompleteYijingAnalysis.tsx @@ -0,0 +1,736 @@ +import React, { useState, useEffect } from 'react'; +import { Calendar, Star, BookOpen, Sparkles, User, BarChart3, Zap, TrendingUp, Loader2, Clock, Target, Heart, DollarSign, Activity, Crown, Compass, Moon, Sun, Hexagon, Layers, Eye, Shuffle } from 'lucide-react'; +import { Card, CardContent, CardHeader, CardTitle } from './ui/Card'; +import { localApi } from '../lib/localApi'; + +interface CompleteYijingAnalysisProps { + question: string; + userId?: string; + divinationMethod?: string; +} + +const CompleteYijingAnalysis: React.FC = ({ + question, + userId = 'user123', + divinationMethod = 'time' +}) => { + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const [analysisData, setAnalysisData] = useState(null); + + // 卦象颜色配置 + const hexagramColors: { [key: string]: string } = { + '乾': 'bg-yellow-100 text-yellow-800 border-yellow-300', + '坤': 'bg-brown-100 text-brown-800 border-brown-300', + '震': 'bg-green-100 text-green-800 border-green-300', + '巽': 'bg-blue-100 text-blue-800 border-blue-300', + '坎': 'bg-indigo-100 text-indigo-800 border-indigo-300', + '离': 'bg-red-100 text-red-800 border-red-300', + '艮': 'bg-gray-100 text-gray-800 border-gray-300', + '兑': 'bg-purple-100 text-purple-800 border-purple-300' + }; + + // 五行颜色配置 + const elementColors: { [key: string]: string } = { + '金': '#fbbf24', // 金色 + '木': '#22c55e', // 绿色 + '水': '#3b82f6', // 蓝色 + '火': '#ef4444', // 红色 + '土': '#a3a3a3' // 灰色 + }; + + // 问题类型颜色配置 + const questionTypeColors: { [key: string]: string } = { + '事业发展': 'bg-blue-100 text-blue-800 border-blue-300', + '感情婚姻': 'bg-pink-100 text-pink-800 border-pink-300', + '财运投资': 'bg-green-100 text-green-800 border-green-300', + '健康养生': 'bg-orange-100 text-orange-800 border-orange-300', + '综合运势': 'bg-purple-100 text-purple-800 border-purple-300' + }; + + useEffect(() => { + const fetchAnalysisData = async () => { + try { + setIsLoading(true); + setError(null); + + const yijingData = { + question: question, + user_id: userId, + divination_method: divinationMethod + }; + + const yijingResponse = await localApi.analysis.yijing(yijingData); + + if (yijingResponse.error) { + throw new Error(yijingResponse.error.message || '易经分析失败'); + } + + const analysisResult = yijingResponse.data?.analysis; + if (!analysisResult) { + throw new Error('分析结果为空'); + } + + setAnalysisData(analysisResult); + } catch (err) { + console.error('获取分析数据出错:', err); + setError(err instanceof Error ? err.message : '分析数据获取失败,请稍后重试'); + } finally { + setIsLoading(false); + } + }; + + if (question) { + fetchAnalysisData(); + } + }, [question, userId, divinationMethod]); + + // 渲染加载状态 + if (isLoading) { + return ( +
+ + + +

正在进行专业易经占卜

+

请稍候,正在为您起卦分析...

+
+
+
+ ); + } + + // 渲染错误状态 + if (error) { + return ( +
+ + +
+

占卜失败

+

{error}

+ +
+
+
+ ); + } + + if (!analysisData) { + return ( +
+ + +
⚠️
+

数据获取异常

+

未能获取到完整的分析数据,请重新提交占卜

+
+
+
+ ); + } + + // 渲染卦象卡片 + const renderHexagramCard = (hexagram: any, title: string, isMain: boolean = false) => { + if (!hexagram) return null; + + return ( + + + + {title} + + + +
+
{hexagram.symbol || hexagram}
+
+ {hexagram.name || hexagram} +
+ {hexagram.number && ( +
第{hexagram.number}卦
+ )} +
+ {hexagram.meaning || '卦象含义'} +
+
+
+
+ ); + }; + + // 渲染八卦信息 + const renderTrigramInfo = (trigram: any, position: string) => { + if (!trigram) return null; + + return ( +
+

{position}

+
+
+ 卦名: + {trigram.name} +
+
+ 性质: + {trigram.nature} +
+
+ 属性: + {trigram.attribute} +
+
+ 五行: + + {trigram.element} + +
+
+
+ ); + }; + + // 渲染动爻分析 + const renderChangingLinesAnalysis = (analysis: any) => { + if (!analysis || !analysis.detailed_analysis) return null; + + return ( +
+
+

动爻分析方法

+

{analysis.method}

+

{analysis.overall_guidance}

+
+ + {analysis.detailed_analysis.map((line: any, index: number) => ( +
+
+
{line.line_position}
+ + {line.line_nature} + +
+
+
+ 位置含义: + {line.position_meaning} +
+
+ 爻辞: + {line.line_text} +
+
+ 象传: + {line.line_image} +
+
+ 实用指导: + {line.practical_guidance} +
+
+
+ ))} +
+ ); + }; + + return ( +
+
+ + {/* 标题和基本信息 */} + + + + + 易经占卜分析报告 + + +
+
+ + {analysisData.analysis_date} +
+
+ + {new Date(analysisData.basic_info.divination_data.divination_time).toLocaleString('zh-CN')} +
+
+
+ +
+ {/* 占卜信息 */} +
+

占卜信息

+
+
+

问题:{analysisData.basic_info.divination_data.question}

+

方法:{analysisData.basic_info.divination_data.method}

+
+
+

问题类型: + + {analysisData.dynamic_guidance.question_analysis.type} + +

+

关注重点:{analysisData.dynamic_guidance.question_analysis.focus}

+
+
+
+
+
+
+ + {/* 卦象信息 */} +
+ {/* 本卦 */} +
+

+ + 本卦 +

+ {renderHexagramCard({ + name: analysisData.basic_info.hexagram_info.main_hexagram, + symbol: analysisData.basic_info.hexagram_info.main_hexagram_symbol, + number: analysisData.basic_info.hexagram_info.main_hexagram_number, + meaning: analysisData.detailed_analysis.hexagram_analysis.primary_meaning.split(' - ')[1] + }, '本卦', true)} + + {/* 八卦结构 */} + + + + + 八卦结构 + + + +
+ {renderTrigramInfo(analysisData.basic_info.hexagram_info.hexagram_structure.upper_trigram, '上卦')} + {renderTrigramInfo(analysisData.basic_info.hexagram_info.hexagram_structure.lower_trigram, '下卦')} +
+
+
八卦组合分析
+

{analysisData.detailed_analysis.hexagram_analysis.trigram_analysis}

+
+
+
+
+ + {/* 变卦 */} +
+

+ + 变卦 +

+ {analysisData.basic_info.hexagram_info.changing_hexagram !== '无' ? ( + renderHexagramCard({ + name: analysisData.basic_info.hexagram_info.changing_hexagram, + symbol: analysisData.basic_info.hexagram_info.changing_hexagram_symbol, + meaning: analysisData.detailed_analysis.changing_hexagram_analysis.meaning + }, '变卦') + ) : ( + + +
🔒
+

无变卦

+

静卦主静,事态稳定

+
+
+ )} + + {/* 变化分析 */} + + + + + 变化分析 + + + +
+
+
转化洞察
+

{analysisData.detailed_analysis.changing_hexagram_analysis.transformation_insight}

+
+
+
变化指导
+

{analysisData.detailed_analysis.changing_hexagram_analysis.guidance}

+
+
+
时机把握
+

{analysisData.detailed_analysis.changing_hexagram_analysis.timing}

+
+
+
+
+
+
+ + {/* 卦辞象传 */} + + + + + 卦辞象传 + + + +
+
+

彖传(卦辞)

+

{analysisData.detailed_analysis.hexagram_analysis.judgment}

+
+
+

象传(卦象)

+

{analysisData.detailed_analysis.hexagram_analysis.image}

+
+
+
+
+ + {/* 动爻分析 */} + {analysisData.detailed_analysis.changing_lines_analysis && ( + + + + + 动爻分析 + +

动爻数量:{analysisData.detailed_analysis.changing_lines_analysis.changing_lines_count}爻

+
+ + {renderChangingLinesAnalysis(analysisData.detailed_analysis.changing_lines_analysis)} + +
+ )} + + {/* 高级分析 */} + {analysisData.detailed_analysis.advanced_analysis && ( + + + + + 高级分析 + +

互卦、错卦、综卦深度解析

+
+ +
+ {/* 互卦 */} +
+

+ 🔄 + 互卦 - {analysisData.detailed_analysis.advanced_analysis.inter_hexagram.name} +

+
+
{analysisData.detailed_analysis.advanced_analysis.inter_hexagram.symbol}
+
{analysisData.detailed_analysis.advanced_analysis.inter_hexagram.meaning}
+
+

{analysisData.detailed_analysis.advanced_analysis.inter_hexagram.analysis}

+
+ + {/* 错卦 */} +
+

+ + 错卦 - {analysisData.detailed_analysis.advanced_analysis.opposite_hexagram.name} +

+
+
{analysisData.detailed_analysis.advanced_analysis.opposite_hexagram.symbol}
+
{analysisData.detailed_analysis.advanced_analysis.opposite_hexagram.meaning}
+
+

{analysisData.detailed_analysis.advanced_analysis.opposite_hexagram.analysis}

+
+ + {/* 综卦 */} +
+

+ 🔀 + 综卦 - {analysisData.detailed_analysis.advanced_analysis.reverse_hexagram.name} +

+
+
{analysisData.detailed_analysis.advanced_analysis.reverse_hexagram.symbol}
+
{analysisData.detailed_analysis.advanced_analysis.reverse_hexagram.meaning}
+
+

{analysisData.detailed_analysis.advanced_analysis.reverse_hexagram.analysis}

+
+
+ + {/* 综合洞察 */} +
+

四卦综合洞察

+

{analysisData.detailed_analysis.advanced_analysis.comprehensive_insight}

+
+
+
+ )} + + {/* 象数分析 */} + {analysisData.detailed_analysis.numerology_analysis && ( + + + + + 象数分析 + +

八卦数理与时间共振分析

+
+ +
+
+

上卦数

+
{analysisData.detailed_analysis.numerology_analysis.upper_trigram_number.number}
+
{analysisData.detailed_analysis.numerology_analysis.upper_trigram_number.meaning}
+
{analysisData.detailed_analysis.numerology_analysis.upper_trigram_number.influence}
+
+ +
+

下卦数

+
{analysisData.detailed_analysis.numerology_analysis.lower_trigram_number.number}
+
{analysisData.detailed_analysis.numerology_analysis.lower_trigram_number.meaning}
+
{analysisData.detailed_analysis.numerology_analysis.lower_trigram_number.influence}
+
+ +
+

组合能量

+
{analysisData.detailed_analysis.numerology_analysis.combined_energy.total}
+
{analysisData.detailed_analysis.numerology_analysis.combined_energy.interpretation}
+
{analysisData.detailed_analysis.numerology_analysis.combined_energy.harmony}
+
+ +
+

时间共振

+
{analysisData.detailed_analysis.numerology_analysis.time_resonance.resonance_number}
+
{analysisData.detailed_analysis.numerology_analysis.time_resonance.meaning}
+
{analysisData.detailed_analysis.numerology_analysis.time_resonance.interpretation}
+
+
+
+
+ )} + + {/* 五行分析 */} + {analysisData.detailed_analysis.hexagram_analysis.five_elements && ( + + + + + 五行分析 + + + +
+
+
+

五行属性

+
+
+ 上卦五行: + + {analysisData.detailed_analysis.hexagram_analysis.five_elements.upper_element} + +
+
+ 下卦五行: + + {analysisData.detailed_analysis.hexagram_analysis.five_elements.lower_element} + +
+
+
+
+ +
+
+

五行关系

+
+
+ 相互作用: +

{analysisData.detailed_analysis.hexagram_analysis.five_elements.relationship}

+
+
+ 平衡状态: +

{analysisData.detailed_analysis.hexagram_analysis.five_elements.balance}

+
+
+
+
+
+
+
+ )} + + {/* 时间分析 */} + {analysisData.dynamic_guidance.time_analysis && ( + + + + + 时间分析 + +

天时地利人和的时机把握

+
+ +
+
+

+ 🌸 + 季节 +

+
{analysisData.dynamic_guidance.time_analysis.season.name}
+
{analysisData.dynamic_guidance.time_analysis.season.energy}
+
{analysisData.dynamic_guidance.time_analysis.season.advice}
+
+ +
+

+ + 时辰 +

+
{analysisData.dynamic_guidance.time_analysis.time_of_day.name}
+
{analysisData.dynamic_guidance.time_analysis.time_of_day.energy}
+
{analysisData.dynamic_guidance.time_analysis.time_of_day.advice}
+
+ +
+

+ + 月相 +

+
{analysisData.dynamic_guidance.time_analysis.lunar_phase.name}
+
{analysisData.dynamic_guidance.time_analysis.lunar_phase.energy}
+
{analysisData.dynamic_guidance.time_analysis.lunar_phase.advice}
+
+ +
+

+ + 能量状态 +

+
{analysisData.dynamic_guidance.time_analysis.energy_state.overall}
+
{analysisData.dynamic_guidance.time_analysis.energy_state.recommendation}
+
+
+
+
+ )} + + {/* 专业指导 */} +
+ {/* 针对性指导 */} + + + + + 针对性指导 + + + +
+
+

专业分析

+

{analysisData.dynamic_guidance.targeted_guidance}

+
+
+

实用建议

+

{analysisData.dynamic_guidance.practical_advice}

+
+
+
+
+ + {/* 易经智慧 */} + + + + + 易经智慧 + + + +
+
+

核心信息

+

{analysisData.divination_wisdom.key_message}

+
+
+

行动建议

+

{analysisData.divination_wisdom.action_advice}

+
+
+

时机把握

+

{analysisData.divination_wisdom.timing_guidance}

+
+
+
+
+
+ + {/* 哲学洞察 */} + + + + + 哲学洞察 + + + +
+

+ {analysisData.divination_wisdom.philosophical_insight} +

+
+
+
+ + {/* 免责声明 */} + + +

+ 本占卜分析基于传统易经理论,结合现代分析方法生成。 + 易经占卜是中华传统文化的重要组成部分,仅供参考,不可过分依赖。 + 人生的幸福需要通过自己的努力和智慧来创造。 +

+
+ 占卜时间:{new Date().toLocaleString('zh-CN')} +
+
+
+
+
+ ); +}; + +export default CompleteYijingAnalysis; \ No newline at end of file diff --git a/src/lib/localApi.ts b/src/lib/localApi.ts index abde37c..28dfcc3 100644 --- a/src/lib/localApi.ts +++ b/src/lib/localApi.ts @@ -195,10 +195,10 @@ class LocalApiClient { }, // 易经分析 - yijing: async (birthData: any, question?: string): Promise> => { + yijing: async (yijingData: any): Promise> => { return this.request<{ record_id: number; analysis: any }>('/analysis/yijing', { method: 'POST', - body: JSON.stringify({ birth_data: birthData, question }), + body: JSON.stringify(yijingData), }); }, diff --git a/src/pages/AnalysisPage.tsx b/src/pages/AnalysisPage.tsx index 790efb7..a4184ec 100644 --- a/src/pages/AnalysisPage.tsx +++ b/src/pages/AnalysisPage.tsx @@ -56,9 +56,17 @@ const AnalysisPage: React.FC = () => { const handleAnalysis = async () => { if (!user) return; - if (!formData.name || !formData.birth_date) { - toast.error('请填写姓名和出生日期'); - return; + // 根据分析类型验证必要参数 + if (analysisType === 'yijing') { + if (!formData.question) { + toast.error('请填写占卜问题'); + return; + } + } else { + if (!formData.name || !formData.birth_date) { + toast.error('请填写姓名和出生日期'); + return; + } } setLoading(true); @@ -84,7 +92,12 @@ const AnalysisPage: React.FC = () => { response = await localApi.analysis.ziwei(birthData); break; case 'yijing': - response = await localApi.analysis.yijing(birthData, formData.question); + const yijingData = { + question: formData.question, + user_id: user.id, + divination_method: 'time' + }; + response = await localApi.analysis.yijing(yijingData); break; default: throw new Error(`不支持的分析类型: ${analysisType}`); @@ -190,79 +203,87 @@ const AnalysisPage: React.FC = () => {

-
-
- setFormData(prev => ({ ...prev, name: e.target.value }))} - required - placeholder="请输入真实姓名" - /> - -
- - setFormData(prev => ({ ...prev, birth_date: e.target.value }))} - required - /> - -
- - setFormData(prev => ({ ...prev, birth_time: e.target.value }))} - placeholder="选填,但强烈建议填写" - /> - - - {analysisType === 'yijing' && ( + {analysisType === 'yijing' ? ( + // 易经占卜表单
setFormData(prev => ({ ...prev, question: e.target.value }))} - placeholder="请输入您希望占卜的具体问题(可选)" + placeholder="请输入您希望占卜的具体问题,如:我的事业发展如何?" + required /> +

+ 💡 提示:问题越具体,占卜结果越准确。可以询问事业、感情、财运、健康等方面的问题。 +

- )} - - {analysisType !== 'ziwei' && analysisType !== 'yijing' && ( -
-
- setFormData(prev => ({ ...prev, birth_place: e.target.value }))} - placeholder="如:北京市朝阳区(选填)" + ) : ( + // 八字和紫微表单 + <> +
+
+ setFormData(prev => ({ ...prev, name: e.target.value }))} + required + placeholder="请输入真实姓名" + /> + +
+ + setFormData(prev => ({ ...prev, birth_date: e.target.value }))} + required + /> + +
+ + setFormData(prev => ({ ...prev, birth_time: e.target.value }))} + placeholder="选填,但强烈建议填写" + /> +
+ + {analysisType !== 'ziwei' && ( +
+
+ setFormData(prev => ({ ...prev, birth_place: e.target.value }))} + placeholder="如:北京市朝阳区(选填)" + /> + +
+
+ )} + )}