th commited on
Commit
f25ebdc
·
1 Parent(s): 84bace8

feat: add /analyze-marriage-destiny endpoint for Love Clarity product

Browse files

New LoveClarityAnalyzer module with:
- Day Blade (日刃格) detection - 6 extreme risk day pillars
- Enhanced peach blossom analysis - 5 types with quality grading
- Hidden clash (暗克) analysis - marriage palace latent conflicts
- Children star (食伤星) analysis - child impact on marriage
- 2026 annual impact analysis - 丙午年 marriage influence
- Cold reading hooks - 3 emotion-resonance anchors per chart

New endpoint: POST /analyze-marriage-destiny
Returns comprehensive structured JSON for love-clarity AI prompt consumption

🦊 Generated with Sisi

Files changed (2) hide show
  1. app.py +141 -0
  2. love_clarity_analyzer.py +1208 -0
app.py CHANGED
@@ -43,6 +43,9 @@ from rituals_service import rituals_service
43
  # 🖐️ Body Reading Analyzer (2026-02-16)
44
  from body_reading_analyzer import analyze_body_reading
45
 
 
 
 
46
  logging.basicConfig(level=logging.INFO)
47
  logger = logging.getLogger(__name__)
48
 
@@ -3795,6 +3798,144 @@ async def analyze_body_reading_endpoint(
3795
  raise HTTPException(status_code=500, detail=f"Body reading analysis failed: {str(e)}")
3796
 
3797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3798
  if __name__ == "__main__":
3799
  import uvicorn
3800
  import sys
 
43
  # 🖐️ Body Reading Analyzer (2026-02-16)
44
  from body_reading_analyzer import analyze_body_reading
45
 
46
+ # 💕 Love Clarity Analyzer (2026-02-28)
47
+ from love_clarity_analyzer import LoveClarityAnalyzer
48
+
49
  logging.basicConfig(level=logging.INFO)
50
  logger = logging.getLogger(__name__)
51
 
 
3798
  raise HTTPException(status_code=500, detail=f"Body reading analysis failed: {str(e)}")
3799
 
3800
 
3801
+ # ============================================================================
3802
+ # 💕 LOVE CLARITY - Marriage Destiny Analysis (2026-02-28)
3803
+ # ============================================================================
3804
+
3805
+ class MarriageDestinyRequest(BaseModel):
3806
+ """Love Clarity 婚姻命运分析请求"""
3807
+ birth_date: str = Field(
3808
+ ...,
3809
+ description="Birth date in YYYY-MM-DD format",
3810
+ example="1992-08-15"
3811
+ )
3812
+ birth_time: str = Field(
3813
+ ...,
3814
+ description="Birth time in HH:MM format",
3815
+ example="14:30"
3816
+ )
3817
+ gender: str = Field(
3818
+ default="female",
3819
+ description="Gender: 'male' or 'female'",
3820
+ example="female"
3821
+ )
3822
+ is_lunar: bool = Field(
3823
+ default=False,
3824
+ description="True if birth date is lunar calendar"
3825
+ )
3826
+ relationship_status: Optional[str] = Field(
3827
+ default=None,
3828
+ description="Current relationship status for context",
3829
+ example="cold_war"
3830
+ )
3831
+ children_status: Optional[str] = Field(
3832
+ default=None,
3833
+ description="Children status for enhanced analysis",
3834
+ example="teenager"
3835
+ )
3836
+
3837
+
3838
+ @app.post("/analyze-marriage-destiny")
3839
+ @app.post("/api/analyze-marriage-destiny")
3840
+ async def analyze_marriage_destiny(
3841
+ req: MarriageDestinyRequest,
3842
+ api_key: str = Depends(verify_api_key)
3843
+ ):
3844
+ """
3845
+ 💕 Love & Marriage Clarity 婚姻命运深度分析
3846
+
3847
+ 为 Love Clarity 产品 ($39/$99) 提供规则化命理数据,包含:
3848
+ 1. 日刃格检测 — 6个极端风险日柱
3849
+ 2. 增强桃花分析 — 5种类型(正桃花/野桃花/桃花劫/桃花煞/滚浪桃花)
3850
+ 3. 暗克分析 — 婚姻宫隐性冲克
3851
+ 4. 子女星分析 — 食伤星对婚姻影响
3852
+ 5. 2026流年影响 — 丙午年婚姻冲击
3853
+ 6. 冷读钩子 — 3个情绪共鸣锚点
3854
+ + 完整的传统婚姻分析(配偶星、婚姻宫、100分评分、女命规则等)
3855
+
3856
+ 🔒 Protected endpoint - Requires API key
3857
+ """
3858
+ try:
3859
+ logger.info(f"💕 Marriage destiny analysis: {req.birth_date} {req.birth_time} ({req.gender})")
3860
+
3861
+ # 1. Calculate complete BaZi with dayun
3862
+ bazi_result = BaZiCalculator.calculate_bazi_complete(
3863
+ birth_date=req.birth_date,
3864
+ birth_time=req.birth_time,
3865
+ gender=req.gender,
3866
+ is_lunar=req.is_lunar,
3867
+ num_dayun=8 # 80年大运
3868
+ )
3869
+
3870
+ # 2. Traditional marriage analysis
3871
+ marriage_analyzer = MarriageAnalyzer(bazi_result)
3872
+ traditional_analysis = marriage_analyzer.analyze_marriage()
3873
+
3874
+ # 3. Love Clarity enhanced analysis
3875
+ clarity_analyzer = LoveClarityAnalyzer(bazi_result)
3876
+ enhanced_analysis = clarity_analyzer.analyze_all()
3877
+
3878
+ # 4. BaZi chart summary
3879
+ chart = bazi_result.get('bazi_chart', {})
3880
+ bazi_summary = {
3881
+ 'four_pillars': {
3882
+ 'year': {'stem': chart.get('year', {}).get('gan', ''), 'branch': chart.get('year', {}).get('zhi', '')},
3883
+ 'month': {'stem': chart.get('month', {}).get('gan', ''), 'branch': chart.get('month', {}).get('zhi', '')},
3884
+ 'day': {'stem': chart.get('day', {}).get('gan', ''), 'branch': chart.get('day', {}).get('zhi', '')},
3885
+ 'hour': {'stem': chart.get('hour', {}).get('gan', ''), 'branch': chart.get('hour', {}).get('zhi', '')},
3886
+ },
3887
+ 'day_master': bazi_result.get('day_master', {}),
3888
+ 'ten_gods': bazi_result.get('ten_gods', {}),
3889
+ }
3890
+
3891
+ # 5. Combine all data
3892
+ result = {
3893
+ # Enhanced (new)
3894
+ 'day_blade_check': enhanced_analysis['day_blade_check'],
3895
+ 'peach_blossom_analysis': enhanced_analysis['peach_blossom_analysis'],
3896
+ 'hidden_clash_analysis': enhanced_analysis['hidden_clash_analysis'],
3897
+ 'children_star_analysis': enhanced_analysis['children_star_analysis'],
3898
+ 'annual_impact_2026': enhanced_analysis['annual_impact_2026'],
3899
+ 'cold_reading_hooks': enhanced_analysis['cold_reading_hooks'],
3900
+ # Traditional
3901
+ 'spouse_star_analysis': traditional_analysis['spouse_star_analysis'],
3902
+ 'marriage_palace_analysis': traditional_analysis['marriage_palace_analysis'],
3903
+ 'spouse_characteristics': traditional_analysis['spouse_characteristics'],
3904
+ 'marriage_quality': traditional_analysis['marriage_quality'],
3905
+ 'marriage_palace_score': traditional_analysis['marriage_palace_score'],
3906
+ 'marriage_fortune_years': traditional_analysis['marriage_fortune_years'],
3907
+ 'marriage_advice': traditional_analysis['marriage_advice'],
3908
+ 'female_marriage_rules': traditional_analysis.get('female_marriage_rules', []),
3909
+ 'spouse_direction': traditional_analysis.get('spouse_direction', {}),
3910
+ # Context
3911
+ 'bazi_summary': bazi_summary,
3912
+ 'user_context': {
3913
+ 'relationship_status': req.relationship_status,
3914
+ 'children_status': req.children_status,
3915
+ }
3916
+ }
3917
+
3918
+ logger.info(
3919
+ f"✅ Marriage destiny complete: "
3920
+ f"palace_score={traditional_analysis['marriage_palace_score'].get('score', 'N/A')}, "
3921
+ f"day_blade={enhanced_analysis['day_blade_check']['detected']}, "
3922
+ f"peach_blossom={enhanced_analysis['peach_blossom_analysis']['has_peach_blossom']}"
3923
+ )
3924
+
3925
+ return {
3926
+ "success": True,
3927
+ "data": result
3928
+ }
3929
+
3930
+ except HTTPException:
3931
+ raise
3932
+ except Exception as e:
3933
+ logger.error(f"❌ Marriage destiny analysis error: {e}")
3934
+ import traceback
3935
+ logger.error(traceback.format_exc())
3936
+ raise HTTPException(status_code=500, detail=f"Marriage destiny analysis failed: {str(e)}")
3937
+
3938
+
3939
  if __name__ == "__main__":
3940
  import uvicorn
3941
  import sys
love_clarity_analyzer.py ADDED
@@ -0,0 +1,1208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ 💕 Love & Marriage Clarity Analyzer (关系清晰度分析器)
3
+ Specialized marriage destiny analysis for the Love Clarity product ($39/$99)
4
+
5
+ 新增分析维度(在 MarriageAnalyzer 基础上扩展):
6
+ 1. 日刃格检测 (Day Blade) — 6个必离日柱
7
+ 2. 增强桃花分析 — 5种桃花类型 + 品质分级
8
+ 3. 暗克分析 — 日柱配偶宫暗克
9
+ 4. 子女星分析 — 食伤星对婚姻影响 + 亲子关系
10
+ 5. 冷读钩子 — 基于命盘数据的冷读法断语
11
+ 6. 2026流年婚姻影响
12
+
13
+ 🦊 Created: 2026-02-28
14
+ """
15
+
16
+ from typing import Dict, List, Any, Optional
17
+ import logging
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ class LoveClarityAnalyzer:
23
+ """
24
+ 关系清晰度专用分析器
25
+ 接收完整八字数据,输出 love-clarity 产品所需的增强分析
26
+ """
27
+
28
+ # ========== 日刃格 (Day Blade) — 必离婚6日柱 ==========
29
+ # 来源:極為準確的一柱論命法斷婚姻
30
+ DAY_BLADE_PILLARS = {
31
+ '戊午': {
32
+ 'element': '火',
33
+ 'description': '日坐羊刃,配偶性格刚烈,婚姻冲突剧烈',
34
+ 'risk_level': 'extreme',
35
+ 'detail': '戊土日主坐午火羊刃,午中丁火为印星夺夫,己土比肩争夫/争财'
36
+ },
37
+ '丙午': {
38
+ 'element': '火',
39
+ 'description': '日坐羊刃帝旺,性格太强势,难以与配偶和谐',
40
+ 'risk_level': 'extreme',
41
+ 'detail': '丙火坐午火帝旺,阳刃之地,刚烈太过,克妻严重'
42
+ },
43
+ '壬子': {
44
+ 'element': '水',
45
+ 'description': '日坐羊刃帝旺,感情波动如水,婚姻难稳定',
46
+ 'risk_level': 'extreme',
47
+ 'detail': '壬水坐子水帝旺,羊刃最旺之地,克配偶力量极强'
48
+ },
49
+ '丁巳': {
50
+ 'element': '火',
51
+ 'description': '日坐禄位带刃,配偶关系紧张,容易离异',
52
+ 'risk_level': 'high',
53
+ 'detail': '丁火坐巳火临官禄地,巳中庚金为正财但被火克,暗伤配偶'
54
+ },
55
+ '己巳': {
56
+ 'element': '土',
57
+ 'description': '日主太旺无制,自我意识太强,婚姻不顺',
58
+ 'risk_level': 'high',
59
+ 'detail': '己土坐巳火长生,得印生扶太过,配偶星被克泄'
60
+ },
61
+ '癸亥': {
62
+ 'element': '水',
63
+ 'description': '日坐禄位,水势太旺冲散感情基础',
64
+ 'risk_level': 'high',
65
+ 'detail': '癸水坐亥水临官禄,亥中甲木伤官泄秀,女命伤官克夫'
66
+ }
67
+ }
68
+
69
+ # ========== 桃花查法表 ==========
70
+ PEACH_BLOSSOM_TABLE = {
71
+ # 年支/日支 → 桃花地支
72
+ '寅': '卯', '午': '卯', '戌': '卯', # 火局 → 卯
73
+ '申': '酉', '子': '酉', '辰': '酉', # 水局 → 酉
74
+ '巳': '午', '酉': '午', '丑': '午', # 金局 → 午
75
+ '亥': '子', '卯': '子', '未': '子', # 木局 → 子
76
+ }
77
+
78
+ # ========== 天干五行 ==========
79
+ GAN_ELEMENT = {
80
+ '甲': '木', '乙': '木',
81
+ '丙': '火', '丁': '火',
82
+ '戊': '土', '己': '土',
83
+ '庚': '金', '辛': '金',
84
+ '壬': '水', '癸': '水',
85
+ }
86
+
87
+ # ========== 天干阴阳 ==========
88
+ GAN_YIN_YANG = {
89
+ '甲': '阳', '乙': '阴',
90
+ '丙': '阳', '丁': '阴',
91
+ '戊': '阳', '己': '阴',
92
+ '庚': '阳', '辛': '阴',
93
+ '壬': '阳', '癸': '阴',
94
+ }
95
+
96
+ # ========== 地支藏干 ==========
97
+ ZHI_HIDDEN_STEMS = {
98
+ '子': ['癸'],
99
+ '丑': ['己', '癸', '辛'],
100
+ '寅': ['甲', '丙', '戊'],
101
+ '卯': ['乙'],
102
+ '辰': ['戊', '乙', '癸'],
103
+ '巳': ['丙', '戊', '庚'],
104
+ '午': ['丁', '己'],
105
+ '未': ['己', '丁', '乙'],
106
+ '申': ['庚', '壬', '戊'],
107
+ '酉': ['辛'],
108
+ '戌': ['戊', '辛', '丁'],
109
+ '亥': ['壬', '甲']
110
+ }
111
+
112
+ # ========== 地支六冲 ==========
113
+ ZHI_CLASH = {
114
+ '子': '午', '午': '子',
115
+ '丑': '未', '未': '丑',
116
+ '寅': '申', '申': '寅',
117
+ '卯': '酉', '酉': '卯',
118
+ '辰': '戌', '戌': '辰',
119
+ '巳': '亥', '亥': '巳',
120
+ }
121
+
122
+ # ========== 地支六合 ==========
123
+ ZHI_COMBINE = {
124
+ '子': '丑', '丑': '子',
125
+ '寅': '亥', '亥': '寅',
126
+ '卯': '戌', '戌': '卯',
127
+ '辰': '酉', '酉': '辰',
128
+ '巳': '申', '申': '巳',
129
+ '午': '未', '未': '午',
130
+ }
131
+
132
+ # ========== 地支三刑 ==========
133
+ ZHI_PENALTY = {
134
+ ('寅', '巳'): '无恩之刑',
135
+ ('巳', '申'): '无恩之刑',
136
+ ('寅', '申'): '无恩之刑',
137
+ ('丑', '戌'): '恃势之刑',
138
+ ('戌', '未'): '恃势之刑',
139
+ ('丑', '未'): '恃势之刑',
140
+ ('子', '卯'): '无礼之刑',
141
+ ('卯', '子'): '无礼之刑',
142
+ ('辰', '辰'): '���刑',
143
+ ('午', '午'): '自刑',
144
+ ('酉', '酉'): '自刑',
145
+ ('亥', '亥'): '自刑',
146
+ }
147
+
148
+ # ========== 地支六害 ==========
149
+ ZHI_HARM = {
150
+ '子': '未', '未': '子',
151
+ '丑': '午', '午': '丑',
152
+ '寅': '巳', '巳': '寅',
153
+ '卯': '辰', '辰': '卯',
154
+ '申': '亥', '亥': '申',
155
+ '酉': '戌', '戌': '酉',
156
+ }
157
+
158
+ def __init__(self, bazi_complete: Dict[str, Any]):
159
+ """
160
+ 初始化
161
+
162
+ Args:
163
+ bazi_complete: 完整八字数据(来自 BaZiCalculator.calculate_bazi 或 calculate_bazi_complete)
164
+ """
165
+ self.bazi = bazi_complete
166
+ self.gender = bazi_complete.get('gender', 'female') # love-clarity默认女性
167
+
168
+ self.bazi_chart = bazi_complete.get('bazi_chart', {})
169
+ self.year_pillar = self.bazi_chart.get('year', {})
170
+ self.month_pillar = self.bazi_chart.get('month', {})
171
+ self.day_pillar = self.bazi_chart.get('day', {})
172
+ self.hour_pillar = self.bazi_chart.get('hour', {})
173
+
174
+ # 提取天干地支
175
+ self.year_gan = self.year_pillar.get('gan', '')
176
+ self.year_zhi = self.year_pillar.get('zhi', '')
177
+ self.month_gan = self.month_pillar.get('gan', '')
178
+ self.month_zhi = self.month_pillar.get('zhi', '')
179
+ self.day_gan = self.day_pillar.get('gan', '')
180
+ self.day_zhi = self.day_pillar.get('zhi', '') # 婚姻宫
181
+ self.hour_gan = self.hour_pillar.get('gan', '')
182
+ self.hour_zhi = self.hour_pillar.get('zhi', '') # 子女宫
183
+
184
+ # 日柱干支组合
185
+ self.day_ganzhi = self.day_gan + self.day_zhi
186
+
187
+ # 十神数据
188
+ ten_gods = self.bazi.get('ten_gods', {})
189
+ self.stem_gods = ten_gods.get('heavenly_stems', ['', '', '--', ''])
190
+ self.branch_gods = ten_gods.get('earthly_branches', ['', '', '', ''])
191
+
192
+ # 所有地支
193
+ self.all_zhis = [self.year_zhi, self.month_zhi, self.day_zhi, self.hour_zhi]
194
+
195
+ # 出生年份
196
+ solar_date = bazi_complete.get('solar_date', '1990-01-01')
197
+ try:
198
+ self.birth_year = int(solar_date.split('-')[0])
199
+ except (ValueError, IndexError):
200
+ self.birth_year = 1990
201
+
202
+ def analyze_all(self) -> Dict[str, Any]:
203
+ """
204
+ 执行全部增强分析,返回完整的 love-clarity 专用数据
205
+ """
206
+ return {
207
+ 'day_blade_check': self.check_day_blade(),
208
+ 'peach_blossom_analysis': self.analyze_peach_blossom(),
209
+ 'hidden_clash_analysis': self.analyze_hidden_clash(),
210
+ 'children_star_analysis': self.analyze_children_star(),
211
+ 'annual_impact_2026': self.analyze_annual_impact(2026),
212
+ 'cold_reading_hooks': self.generate_cold_reading_hooks(),
213
+ }
214
+
215
+ # ==================== 1. 日刃格检测 ====================
216
+
217
+ def check_day_blade(self) -> Dict[str, Any]:
218
+ """
219
+ 检测日刃格 — 6个几乎必定婚姻出问题的日柱
220
+ 来源: 極為準確的一柱論命法斷婚姻
221
+ """
222
+ is_day_blade = self.day_ganzhi in self.DAY_BLADE_PILLARS
223
+
224
+ if is_day_blade:
225
+ info = self.DAY_BLADE_PILLARS[self.day_ganzhi]
226
+ return {
227
+ 'detected': True,
228
+ 'day_pillar': self.day_ganzhi,
229
+ 'risk_level': info['risk_level'],
230
+ 'description': info['description'],
231
+ 'detail': info['detail'],
232
+ 'cold_reading': self._day_blade_cold_reading(info)
233
+ }
234
+ else:
235
+ return {
236
+ 'detected': False,
237
+ 'day_pillar': self.day_ganzhi,
238
+ 'risk_level': 'none',
239
+ 'description': '日柱不属于日刃格,婚姻宫无此极端风险',
240
+ }
241
+
242
+ def _day_blade_cold_reading(self, info: Dict) -> str:
243
+ """日刃格冷读法描述"""
244
+ if self.gender == 'female':
245
+ return (
246
+ f'你的日柱{self.day_ganzhi},在命理中属于"日刃格"——'
247
+ f'你天生性格中有一股不服输的劲,可能连自己都不完全意识到。'
248
+ f'在感情里,你不是那种愿意委屈自己的人,但有时候你的"不愿意将就"'
249
+ f'会让对方感到压力。你是不是有时候觉得,明明自己没做错什么,'
250
+ f'但关系就是走到了一个死角?'
251
+ )
252
+ else:
253
+ return (
254
+ f'你的日柱{self.day_ganzhi},命理称为"日刃格"——'
255
+ f'你骨子里有一种很强的自我意识,在事业上这是优势,'
256
+ f'但在感情中,你可能不自觉地让伴侣感到无法靠近你真实的内心。'
257
+ f'你是不是有时候觉得,自己其实很想对方理解你,但就是表达不出来?'
258
+ )
259
+
260
+ # ==================== 2. 增强桃花分析 ====================
261
+
262
+ def analyze_peach_blossom(self) -> Dict[str, Any]:
263
+ """
264
+ 增强桃花分析 — 5种类型 + 品质分级 + 冷读描述
265
+
266
+ 类型:
267
+ 1. 正桃花(墙内桃花)— 年月柱
268
+ 2. 野桃花(墙外桃花)— 日时柱
269
+ 3. 桃花劫(破财桃花)— 与劫财同柱
270
+ 4. 桃花煞(凶险桃花)— 与七杀/羊刃同柱
271
+ 5. 滚浪桃花 — 子午卯酉全见
272
+ """
273
+ results = {
274
+ 'has_peach_blossom': False,
275
+ 'peach_blossom_positions': [],
276
+ 'types': [],
277
+ 'quality': 'none',
278
+ 'quality_score': 0, # 0-100, 越高越好(正桃花高,煞桃花低)
279
+ 'rolling_wave': False, # 滚浪桃花
280
+ 'cold_reading': '',
281
+ 'detail_notes': [],
282
+ }
283
+
284
+ # Step 1: 用年支和日支分别查桃花
285
+ peach_positions = []
286
+
287
+ for check_source, source_name in [(self.year_zhi, '年支'), (self.day_zhi, '日支')]:
288
+ target_peach = self.PEACH_BLOSSOM_TABLE.get(check_source)
289
+ if not target_peach:
290
+ continue
291
+
292
+ for i, (zhi, pillar_name) in enumerate([
293
+ (self.year_zhi, '年柱'), (self.month_zhi, '月柱'),
294
+ (self.day_zhi, '日柱'), (self.hour_zhi, '时柱')
295
+ ]):
296
+ if zhi == target_peach:
297
+ position = {
298
+ 'source': source_name,
299
+ 'pillar': pillar_name,
300
+ 'pillar_index': i,
301
+ 'peach_zhi': target_peach,
302
+ }
303
+ # 避免重复
304
+ if not any(p['pillar'] == pillar_name and p['peach_zhi'] == target_peach
305
+ for p in peach_positions):
306
+ peach_positions.append(position)
307
+
308
+ if not peach_positions:
309
+ results['cold_reading'] = self._no_peach_blossom_reading()
310
+ return results
311
+
312
+ results['has_peach_blossom'] = True
313
+ results['peach_blossom_positions'] = peach_positions
314
+
315
+ # Step 2: 判断桃花类型
316
+ types = []
317
+ quality_score = 50 # 基础分
318
+ detail_notes = []
319
+
320
+ for pos in peach_positions:
321
+ pillar_idx = pos['pillar_index']
322
+ pillar_name = pos['pillar']
323
+
324
+ # 获取该柱的十神
325
+ stem_god = self.stem_gods[pillar_idx] if pillar_idx < len(self.stem_gods) else ''
326
+ branch_god = self.branch_gods[pillar_idx] if pillar_idx < len(self.branch_gods) else ''
327
+
328
+ # 判断墙内/墙外
329
+ if pillar_idx <= 1: # 年柱或月柱
330
+ wall_type = '墙内桃花(正桃花)'
331
+ quality_score += 20
332
+ detail_notes.append(f'{pillar_name}有桃花,属墙内正桃花,配偶有魅力,感情正当')
333
+ types.append({
334
+ 'type': 'wall_inside',
335
+ 'label': '正桃花',
336
+ 'pillar': pillar_name,
337
+ 'risk': 'low',
338
+ 'description': '桃花在年月柱为墙内桃花,主正当感情,配偶俊美有魅力'
339
+ })
340
+ else: # 日柱或时柱
341
+ wall_type = '墙外桃花(野桃花)'
342
+ quality_score -= 10
343
+ detail_notes.append(f'{pillar_name}有桃花,属墙外桃花,感情易有波折')
344
+ types.append({
345
+ 'type': 'wall_outside',
346
+ 'label': '野桃花',
347
+ 'pillar': pillar_name,
348
+ 'risk': 'medium',
349
+ 'description': '桃花在日时柱为墙外桃花,婚后需注意防范第三者'
350
+ })
351
+
352
+ # 判断桃花劫(与劫财同柱)
353
+ if '劫' in stem_god or '劫' in branch_god:
354
+ quality_score -= 20
355
+ detail_notes.append(f'{pillar_name}桃花与劫财同柱 → 桃花劫!因感情破财风险')
356
+ types.append({
357
+ 'type': 'peach_robbery',
358
+ 'label': '桃花劫',
359
+ 'pillar': pillar_name,
360
+ 'risk': 'high',
361
+ 'description': '桃花与劫财同柱,因色破财、感情骗局风险高'
362
+ })
363
+
364
+ # 判断桃花煞(与七杀/羊刃同柱)
365
+ if '杀' in stem_god or '杀' in branch_god:
366
+ quality_score -= 25
367
+ detail_notes.append(f'{pillar_name}桃花与七杀同柱 → 桃花煞!感情中易遇危险人物')
368
+ types.append({
369
+ 'type': 'peach_evil',
370
+ 'label': '桃花煞',
371
+ 'pillar': pillar_name,
372
+ 'risk': 'very_high',
373
+ 'description': '桃花与七杀同柱,感情纠纷严重,轻则破财重则伤身'
374
+ })
375
+
376
+ # 正桃花加分(与正官/正印同柱)
377
+ if ('官' in stem_god and '杀' not in stem_god) or '印' in stem_god:
378
+ quality_score += 15
379
+ detail_notes.append(f'{pillar_name}桃花与正官/正印同柱 → 贵人桃花,配偶高贵')
380
+
381
+ # Step 3: 检测滚浪桃花(子午卯酉全见)
382
+ four_peach = {'子', '午', '卯', '酉'}
383
+ present_peach = four_peach.intersection(set(self.all_zhis))
384
+ if len(present_peach) == 4:
385
+ results['rolling_wave'] = True
386
+ quality_score = max(0, quality_score - 40)
387
+ detail_notes.append('子午卯酉四大桃花全见 → 滚浪桃花!感情极度复杂')
388
+ types.append({
389
+ 'type': 'rolling_wave',
390
+ 'label': '滚浪桃花',
391
+ 'pillar': '全局',
392
+ 'risk': 'extreme',
393
+ 'description': '四大桃花齐聚,一生感情波折不断,多次婚变风险极高'
394
+ })
395
+ elif len(present_peach) >= 3:
396
+ detail_notes.append(f'八字有{len(present_peach)}个桃花位,异性缘极旺,需注意感情管理')
397
+
398
+ # Clamp score
399
+ quality_score = max(0, min(100, quality_score))
400
+
401
+ # Quality label
402
+ if quality_score >= 70:
403
+ quality = '正桃花为主,感情运佳'
404
+ elif quality_score >= 50:
405
+ quality = '桃花中等,需注意经营'
406
+ elif quality_score >= 30:
407
+ quality = '桃花有隐患,感情易有波折'
408
+ else:
409
+ quality = '桃花凶煞较重,感情风险高'
410
+
411
+ results['types'] = types
412
+ results['quality'] = quality
413
+ results['quality_score'] = quality_score
414
+ results['detail_notes'] = detail_notes
415
+ results['cold_reading'] = self._peach_blossom_cold_reading(types, quality_score)
416
+
417
+ return results
418
+
419
+ def _no_peach_blossom_reading(self) -> str:
420
+ """无桃花的冷读"""
421
+ if self.gender == 'female':
422
+ return (
423
+ '你的八字中没有明显的桃花位——这不意味着你没有魅力,'
424
+ '而是你的感情模式更"慢热"。你可能不是那种一见钟情的人,'
425
+ '但一旦认定了,就会很深很认真。你是不是经常觉得,'
426
+ '身边的人不太理解你在感情里的那种"认真"?'
427
+ )
428
+ else:
429
+ return (
430
+ '你的八字中没有明显的桃花位,这说明你在感情上比较理性。'
431
+ '你不是那种靠冲动做决定的人,但有时候,'
432
+ '你是不是觉得自己在感情表达上不够主动?'
433
+ )
434
+
435
+ def _peach_blossom_cold_reading(self, types: List[Dict], quality_score: int) -> str:
436
+ """桃花冷读法描述"""
437
+ type_labels = [t['label'] for t in types]
438
+
439
+ if '滚浪桃花' in type_labels:
440
+ return (
441
+ '你的八字子午卯酉齐聚——这在命理中是极其罕见的桃花格局。'
442
+ '你的人生中,感情从来不是一条简单的线。你可能已经经历过'
443
+ '不止一次深刻的感情冲击,每一次都以为是最后一次。'
444
+ '但你有没有想过,也许你需要的不是"对的人",而是先理清自己的内心?'
445
+ )
446
+
447
+ if '桃花煞' in type_labels:
448
+ if self.gender == 'female':
449
+ return (
450
+ '你命中有"桃花煞"——你可能特别容易吸引到那种很有魅力但又带着危险感的人。'
451
+ '你是不是有过这样的经历:明明知道对方不是好选择,但就是忍不住被吸引?'
452
+ '这不是你的错,但了解这个模式,可以帮你在下一次做出不同的选择。'
453
+ )
454
+ return (
455
+ '你命中有"桃花煞"——在感情中你可能容易遇到比较复杂的情况。'
456
+ '你可能需要特别注意分辨对方的真实意图。'
457
+ )
458
+
459
+ if '桃花劫' in type_labels:
460
+ return (
461
+ '你命中有"桃花劫"——这意味着你在感情上有一种"为对方付出一切"的倾向。'
462
+ '你是不是曾经为了感情做过一些事后觉得不值得的付出?'
463
+ '命理上说,有桃花劫的人不是运气不好,而是容易在感情中失去理性判断。'
464
+ '学会在感情中保留一份清醒,是你最重要的功课。'
465
+ )
466
+
467
+ if '正桃花' in type_labels and quality_score >= 60:
468
+ if self.gender == 'female':
469
+ return (
470
+ '你命中有"正桃花"——你天生有一种让人舒服的魅力,不是那种很张扬的类型,'
471
+ '但相处久了,别人会越来越喜欢你。你的配偶很可能外貌不错,'
472
+ '而且两个人之间有一种"互相欣赏"的默契。'
473
+ '你在感情中是不是比较重视那种精神上的共鸣?'
474
+ )
475
+ return (
476
+ '你命中有"正桃花"——你有不错的异性缘,配偶条件也不差。'
477
+ '但正桃花更需要的是经营,不是等待。'
478
+ )
479
+
480
+ if '野桃花' in type_labels:
481
+ return (
482
+ '你的桃花落在日柱或时柱,命理上叫"墙外桃花"——'
483
+ '这不是说你一定会出问题,而是你的感情模式里,'
484
+ '有一部分吸引力是在"安全区域之外"的。你可能偶尔会对'
485
+ '不应该有感觉的人产生某种说不清道不明的吸引。'
486
+ '意识到这一点,就是保护自己的第一步。'
487
+ )
488
+
489
+ return '你的桃花格局较为平和,感情运势中等。'
490
+
491
+ # ==================== 3. 暗克分析 ====================
492
+
493
+ def analyze_hidden_clash(self) -> Dict[str, Any]:
494
+ """
495
+ 暗克分析 — 日柱配偶宫的隐性冲克
496
+ 来源: 極為準確的一柱論命法斷婚姻
497
+
498
+ 检查:
499
+ 1. 日支与月支/时支的冲、刑、害关系
500
+ 2. 日干克日支藏干(暗克配偶)
501
+ 3. 日支藏干之间的冲克
502
+ """
503
+ issues = []
504
+ severity = 0 # 0-100
505
+
506
+ # 1. 日支被冲
507
+ for zhi, pillar_name in [(self.month_zhi, '月支'), (self.hour_zhi, '时支'), (self.year_zhi, '年支')]:
508
+ if self.ZHI_CLASH.get(self.day_zhi) == zhi:
509
+ severity += 25
510
+ issues.append({
511
+ 'type': 'clash',
512
+ 'detail': f'{pillar_name}({zhi})冲日支({self.day_zhi})',
513
+ 'impact': '婚姻宫被冲,感情根基动摇,婚姻容易有变故',
514
+ 'severity': 'high'
515
+ })
516
+
517
+ # 2. 日支被刑
518
+ for zhi, pillar_name in [(self.month_zhi, '月支'), (self.hour_zhi, '时支'), (self.year_zhi, '年支')]:
519
+ penalty_key = (self.day_zhi, zhi)
520
+ penalty_key_rev = (zhi, self.day_zhi)
521
+ penalty_type = self.ZHI_PENALTY.get(penalty_key) or self.ZHI_PENALTY.get(penalty_key_rev)
522
+ if penalty_type:
523
+ severity += 15
524
+ issues.append({
525
+ 'type': 'penalty',
526
+ 'detail': f'{pillar_name}({zhi})与日支({self.day_zhi})构成{penalty_type}',
527
+ 'impact': f'{penalty_type}作用于婚姻宫,夫妻关系紧张,易有口舌纷争',
528
+ 'severity': 'medium'
529
+ })
530
+
531
+ # 3. 日支被害
532
+ for zhi, pillar_name in [(self.month_zhi, '月支'), (self.hour_zhi, '时支'), (self.year_zhi, '年支')]:
533
+ if self.ZHI_HARM.get(self.day_zhi) == zhi:
534
+ severity += 12
535
+ issues.append({
536
+ 'type': 'harm',
537
+ 'detail': f'{pillar_name}({zhi})与日支({self.day_zhi})相害',
538
+ 'impact': '相害为暗伤,表面看起来还好,但内心渐行渐远',
539
+ 'severity': 'medium'
540
+ })
541
+
542
+ # 4. 日干克日支藏干(暗克配偶宫)
543
+ day_hidden = self.ZHI_HIDDEN_STEMS.get(self.day_zhi, [])
544
+ day_element = self.GAN_ELEMENT.get(self.day_gan, '')
545
+
546
+ for hidden in day_hidden:
547
+ hidden_element = self.GAN_ELEMENT.get(hidden, '')
548
+ if self._element_conquers(day_element, hidden_element):
549
+ # 检查是否克的是配偶星相关的藏干
550
+ severity += 8
551
+ issues.append({
552
+ 'type': 'hidden_conquer',
553
+ 'detail': f'日干{self.day_gan}({day_element})克日支藏干{hidden}({hidden_element})',
554
+ 'impact': '日主暗克婚姻宫藏干,对配偶有无意识的压制倾向',
555
+ 'severity': 'low'
556
+ })
557
+
558
+ # 5. 日支合走(被月支或时支合走)
559
+ combine_target = self.ZHI_COMBINE.get(self.day_zhi)
560
+ for zhi, pillar_name in [(self.month_zhi, '月支'), (self.hour_zhi, '时支')]:
561
+ if zhi == combine_target:
562
+ # 合有可能是好的,但也可能代表配偶被合走
563
+ issues.append({
564
+ 'type': 'combine_away',
565
+ 'detail': f'{pillar_name}({zhi})合日支({self.day_zhi})',
566
+ 'impact': '日支被合,一方面增进感情融洽,但严重时可能代表配偶被"合走"(外遇)',
567
+ 'severity': 'note'
568
+ })
569
+
570
+ severity = min(100, severity)
571
+
572
+ if severity >= 50:
573
+ risk_level = 'high'
574
+ summary = '婚姻宫暗克较重,感情中存在多个隐性压力源'
575
+ elif severity >= 25:
576
+ risk_level = 'medium'
577
+ summary = '婚姻宫有部分冲克,需要留意感情经营'
578
+ elif severity > 0:
579
+ risk_level = 'low'
580
+ summary = '婚姻宫有轻微冲克,整体可控'
581
+ else:
582
+ risk_level = 'none'
583
+ summary = '婚姻宫无明显冲克,感情基���较稳'
584
+
585
+ return {
586
+ 'severity_score': severity,
587
+ 'risk_level': risk_level,
588
+ 'summary': summary,
589
+ 'issues': issues,
590
+ 'cold_reading': self._hidden_clash_cold_reading(issues, severity)
591
+ }
592
+
593
+ def _element_conquers(self, el1: str, el2: str) -> bool:
594
+ """检查五行相克: el1 是否克 el2"""
595
+ conquers = {
596
+ '木': '土', '土': '水', '水': '火', '火': '金', '金': '木'
597
+ }
598
+ return conquers.get(el1) == el2
599
+
600
+ def _hidden_clash_cold_reading(self, issues: List, severity: int) -> str:
601
+ """暗克冷读"""
602
+ if severity >= 50:
603
+ return (
604
+ '你的命盘里,婚姻宫受到了多重暗克——'
605
+ '你可能一直有一种感觉:明明两个人看起来"还好",'
606
+ '但总有一种说不清的不舒服。这种暗克的力量是潜移默化的,'
607
+ '它不会让你突然爆发,但会让你在日积月累中消耗殆尽。'
608
+ '你是不是已经觉得,你们之间有什么东西在慢慢流失?'
609
+ )
610
+ elif severity >= 25:
611
+ return (
612
+ '你的婚姻宫有一些隐性的压力——不是那种明面上的大冲突,'
613
+ '而是那种"闷在心里"的不舒服。你可能有时候会突然觉得很委屈,'
614
+ '但又说不出具体是为什么。这种感受不是你想多了,命盘确实显示了这种暗流。'
615
+ )
616
+ elif issues:
617
+ return (
618
+ '你的婚姻宫有一些轻微的波动——整体还好,但有些细节需要留意。'
619
+ '你们的感情基础是稳的,但不代表不需要经营。'
620
+ )
621
+ return '你的婚姻宫比较清净,没有明显的暗克力量干扰。感情基础相对稳固。'
622
+
623
+ # ==================== 4. 子女星分析 ====================
624
+
625
+ def analyze_children_star(self) -> Dict[str, Any]:
626
+ """
627
+ 子女星分析 — 食伤星对婚姻的影响 + 亲子关系 + 子女宫(时柱)分析
628
+
629
+ 女命: 食神=女儿, 伤官=儿子
630
+ 男命: 正官=女儿, 七杀=儿子 (也参考食伤)
631
+
632
+ 重点: 分析子女因素如何影响当前婚姻关系
633
+ """
634
+ all_gods = list(self.stem_gods) + list(self.branch_gods)
635
+ # 排除日主标记
636
+ clean_gods = [g for g in all_gods if g and g != '--']
637
+
638
+ # 统计食伤星
639
+ shishen_count = sum(1 for g in clean_gods if '食' in g)
640
+ shangguan_count = sum(1 for g in clean_gods if '伤' in g)
641
+ total_shi_shang = shishen_count + shangguan_count
642
+
643
+ # 时柱十神(子女宫)
644
+ hour_stem_god = self.stem_gods[3] if len(self.stem_gods) > 3 else ''
645
+ hour_branch_god = self.branch_gods[3] if len(self.branch_gods) > 3 else ''
646
+
647
+ # 子女缘分判断
648
+ children_affinity = self._judge_children_affinity(total_shi_shang)
649
+
650
+ # 子女对婚姻的影响
651
+ marriage_impact = self._judge_children_marriage_impact(
652
+ shishen_count, shangguan_count, hour_stem_god, hour_branch_god
653
+ )
654
+
655
+ # 子女宫分析
656
+ children_palace = self._analyze_children_palace(hour_stem_god, hour_branch_god)
657
+
658
+ # 亲子关系预测
659
+ parenting_style = self._predict_parenting_style()
660
+
661
+ return {
662
+ 'shishen_count': shishen_count,
663
+ 'shangguan_count': shangguan_count,
664
+ 'total_food_injury': total_shi_shang,
665
+ 'children_affinity': children_affinity,
666
+ 'marriage_impact': marriage_impact,
667
+ 'children_palace': children_palace,
668
+ 'parenting_style': parenting_style,
669
+ 'cold_reading': self._children_cold_reading(
670
+ total_shi_shang, marriage_impact, children_affinity
671
+ )
672
+ }
673
+
674
+ def _judge_children_affinity(self, total: int) -> Dict[str, Any]:
675
+ """判断子女缘分"""
676
+ if total == 0:
677
+ return {
678
+ 'level': '子女缘薄',
679
+ 'score': 30,
680
+ 'description': '八字中食伤星缺失,子女缘分较晚或较少,可能需要通过其他方式增加子女运'
681
+ }
682
+ elif total == 1:
683
+ return {
684
+ 'level': '子女缘正常',
685
+ 'score': 60,
686
+ 'description': '食伤星数量适中,子女缘分正常,通常有1-2个孩子'
687
+ }
688
+ elif total == 2:
689
+ return {
690
+ 'level': '子女缘佳',
691
+ 'score': 75,
692
+ 'description': '食伤星充足,子女缘好,与孩子的关系融洽'
693
+ }
694
+ else:
695
+ return {
696
+ 'level': '子女缘旺',
697
+ 'score': 85,
698
+ 'description': '食伤星旺盛,子女多或与子女关系非常密切,但也可能为子女操心较多'
699
+ }
700
+
701
+ def _judge_children_marriage_impact(
702
+ self, shishen: int, shangguan: int,
703
+ hour_stem_god: str, hour_branch_god: str
704
+ ) -> Dict[str, Any]:
705
+ """判断子女因素对婚姻的影响"""
706
+ impacts = []
707
+ impact_score = 50 # 50=中性
708
+
709
+ # 女命伤官克夫
710
+ if self.gender == 'female' and shangguan >= 2:
711
+ impacts.append('伤官过多,在照顾孩子的同时容易与丈夫产生摩擦')
712
+ impact_score -= 15
713
+
714
+ # 女命伤官见官
715
+ has_guan = any('官' in g and '杀' not in g for g in self.stem_gods + self.branch_gods if g and g != '--')
716
+ if self.gender == 'female' and shangguan >= 1 and has_guan:
717
+ impacts.append('伤官见官:母亲角色与妻子角色可能产生冲突')
718
+ impact_score -= 10
719
+
720
+ # 食伤泄身太过
721
+ if shishen + shangguan >= 3:
722
+ impacts.append('食伤过旺泄身:为子女付出太多,忽略了自己和婚姻')
723
+ impact_score -= 10
724
+
725
+ # 食神制杀(可能是好的)
726
+ has_sha = any('杀' in g for g in self.stem_gods + self.branch_gods if g and g != '--')
727
+ if shishen >= 1 and has_sha:
728
+ impacts.append('食神制杀:孩子的存在反而能缓和夫妻间的紧张关系')
729
+ impact_score += 10
730
+
731
+ # 时柱吉凶
732
+ favorable = ['正财', '正官', '食神', '正印']
733
+ unfavorable = ['劫财', '伤官', '七杀']
734
+ if any(f in hour_stem_god for f in favorable) or any(f in hour_branch_god for f in favorable):
735
+ impacts.append('子女宫吉神坐守,孩子是家庭的正向力量')
736
+ impact_score += 10
737
+ if any(u in hour_stem_god for u in unfavorable) or any(u in hour_branch_god for u in unfavorable):
738
+ impacts.append('子女宫有凶神,孩子可能是家庭压力的来源之一')
739
+ impact_score -= 10
740
+
741
+ impact_score = max(0, min(100, impact_score))
742
+
743
+ if impact_score >= 60:
744
+ assessment = '子女因素对婚姻有正面影响'
745
+ elif impact_score >= 40:
746
+ assessment = '子女因素对婚姻影响中性'
747
+ else:
748
+ assessment = '子女因素可能增加婚姻压力'
749
+
750
+ return {
751
+ 'score': impact_score,
752
+ 'assessment': assessment,
753
+ 'factors': impacts
754
+ }
755
+
756
+ def _analyze_children_palace(self, hour_stem_god: str, hour_branch_god: str) -> Dict[str, Any]:
757
+ """分析子女宫(时柱)"""
758
+ # 时支是否被冲
759
+ hour_clashed = self.ZHI_CLASH.get(self.hour_zhi) in [self.year_zhi, self.month_zhi, self.day_zhi]
760
+
761
+ notes = []
762
+ if hour_clashed:
763
+ notes.append('时柱被冲,与子女的关系可能有波折,或子女远离身边')
764
+
765
+ # 时柱藏干与日主的关系
766
+ hour_hidden = self.ZHI_HIDDEN_STEMS.get(self.hour_zhi, [])
767
+ day_el = self.GAN_ELEMENT.get(self.day_gan, '')
768
+ for h in hour_hidden:
769
+ h_el = self.GAN_ELEMENT.get(h, '')
770
+ if self._element_conquers(day_el, h_el):
771
+ notes.append(f'日主({self.day_gan})克时支藏干({h}),管教子女较严')
772
+ break
773
+ if self._element_conquers(h_el, day_el):
774
+ notes.append(f'时支藏干({h})克日主({self.day_gan}),子女可能叛逆')
775
+ break
776
+
777
+ return {
778
+ 'hour_pillar': self.hour_gan + self.hour_zhi,
779
+ 'hour_stem_god': hour_stem_god,
780
+ 'hour_branch_god': hour_branch_god,
781
+ 'hour_clashed': hour_clashed,
782
+ 'notes': notes
783
+ }
784
+
785
+ def _predict_parenting_style(self) -> str:
786
+ """预测育儿风格(冷读法)"""
787
+ day_el = self.GAN_ELEMENT.get(self.day_gan, '')
788
+
789
+ styles = {
790
+ '木': '你在教育孩子上偏向"成长型"——你相信每个孩子都有自己的节奏,但有时候你的耐心会被消磨',
791
+ '火': '你对孩子的教育充满热情,但有时候会太着急——你希望孩子能快速成长,可能无意中给了太多压力',
792
+ '土': '你是那种"默默付出"型的家长——你给孩子很多安全感,但有时候会过度保护',
793
+ '金': '你对孩子要求比较高,规矩比较多——你觉得这是为他们好,但孩子可能有时候觉得喘不过气',
794
+ '水': '你在教育上比较灵活,善于理解孩子的想法——但有时候会因为太"理解"而忽略了该坚持的原则',
795
+ }
796
+
797
+ return styles.get(day_el, '你的育儿风格比较随和,会根据孩子的特点调整方式')
798
+
799
+ def _children_cold_reading(
800
+ self, total: int, marriage_impact: Dict, affinity: Dict
801
+ ) -> str:
802
+ """子女与婚姻关系的冷读"""
803
+ if total == 0:
804
+ if self.gender == 'female':
805
+ return (
806
+ '你的命盘中食伤星较弱——如果你目前没有孩子,'
807
+ '你可能在"要不要孩子"这个问题上思考了很久。'
808
+ '没有孩子的绊系让你在婚姻决策上更自由,'
809
+ '但你是不是也偶尔会想:如果有了孩子,一切会不会不一样?'
810
+ )
811
+ return '你的命盘中食伤星较弱,在子女问题上需要更多耐心和准备。'
812
+
813
+ if marriage_impact['score'] < 40:
814
+ return (
815
+ '你的命盘显示,孩子在你的婚姻中扮演了一个很复杂的角色——'
816
+ '你爱孩子,但有时候你会觉得"如果不是因为孩子,我可能早就......"。'
817
+ '这个想法让你内疚,但它确实存在。你需要知道的是,'
818
+ '这不代表你是一个不好的父母,而是你的婚姻本身需要被正视。'
819
+ '孩子不应该成为你留在不快乐关系中的唯一理由。'
820
+ )
821
+
822
+ if marriage_impact['score'] >= 60:
823
+ return (
824
+ '在你的命盘中,子女宫和婚姻宫的关系是相对和谐的——'
825
+ '孩子的存在其实可以成为你们关系的润滑剂。'
826
+ '但你需要注意的是,不要把所有注意力都放在孩子身上,'
827
+ '而忽略了你和伴侣之间的情感连接。'
828
+ )
829
+
830
+ return (
831
+ '你和孩子的缘分还不错——他们在你的生命中既是牵挂也是力量。'
832
+ '在当前的感情困境中,孩子是你考虑的重要因素之一,'
833
+ '但请记住:一个幸福的你,才是给孩子最好的礼物。'
834
+ )
835
+
836
+ # ==================== 5. 2026流年影响 ====================
837
+
838
+ def analyze_annual_impact(self, year: int = 2026) -> Dict[str, Any]:
839
+ """
840
+ 分析特定年份(默认2026丙午年)对婚姻的影响
841
+
842
+ 2026年: 丙午年(火年)
843
+ - 丙=阳火, 午=马(火)
844
+ - 天干丙火,地支午火 → 火势极旺
845
+ """
846
+ # 2026年天干地支
847
+ year_gan = '丙'
848
+ year_zhi = '午'
849
+
850
+ if year != 2026:
851
+ # 简化处理:只精确支持2026年
852
+ return {
853
+ 'year': year,
854
+ 'note': '目前仅支持2026年详细分析'
855
+ }
856
+
857
+ impacts = []
858
+ overall_score = 50 # 50=中性
859
+
860
+ # 1. 流年地支冲日支(婚姻宫)
861
+ if self.ZHI_CLASH.get(year_zhi) == self.day_zhi:
862
+ impacts.append({
863
+ 'type': 'marriage_palace_clash',
864
+ 'severity': 'high',
865
+ 'detail': f'2026午年冲你的婚姻宫({self.day_zhi}),今年感情可能有大的变动',
866
+ 'advice': '冲不一定是坏事,可能是"打破僵局"的契机,但需要做好心理准备'
867
+ })
868
+ overall_score -= 25
869
+
870
+ # 2. 流年地支合日支
871
+ if self.ZHI_COMBINE.get(year_zhi) == self.day_zhi:
872
+ impacts.append({
873
+ 'type': 'marriage_palace_combine',
874
+ 'severity': 'positive',
875
+ 'detail': f'2026午年与婚姻宫({self.day_zhi})相合,有利于感情修复',
876
+ 'advice': '这是一个修复关系的好窗口,如果想挽回,今年努力会有效果'
877
+ })
878
+ overall_score += 15
879
+
880
+ # 3. 流年地支是否为桃花位
881
+ peach_from_year = self.PEACH_BLOSSOM_TABLE.get(self.year_zhi)
882
+ peach_from_day = self.PEACH_BLOSSOM_TABLE.get(self.day_zhi)
883
+ if year_zhi == peach_from_year or year_zhi == peach_from_day:
884
+ impacts.append({
885
+ 'type': 'peach_blossom_year',
886
+ 'severity': 'mixed',
887
+ 'detail': '2026年是你的桃花年,异性缘上升',
888
+ 'advice': '单身利于脱单;已婚需注意婚外诱惑'
889
+ })
890
+
891
+ # 4. 流年天干与日主的关系
892
+ day_element = self.GAN_ELEMENT.get(self.day_gan, '')
893
+ year_element = self.GAN_ELEMENT.get(year_gan, '') # 丙=火
894
+
895
+ if self._element_conquers(year_element, day_element):
896
+ impacts.append({
897
+ 'type': 'annual_pressure',
898
+ 'severity': 'medium',
899
+ 'detail': f'流年丙火克日主{self.day_gan}({day_element}),今年外部压力较大',
900
+ 'advice': '压力来自外部环境,不完全是感情问题,需要区分来源'
901
+ })
902
+ overall_score -= 10
903
+ elif self._element_conquers(day_element, year_element):
904
+ impacts.append({
905
+ 'type': 'annual_control',
906
+ 'severity': 'positive',
907
+ 'detail': f'日主{self.day_gan}({day_element})克流年丙火,今年你有掌控感',
908
+ 'advice': '今年你在关系中相对主动,适合做出决策'
909
+ })
910
+ overall_score += 10
911
+
912
+ # 5. 流年十神分析(需要根据日主判断丙火对应的十神)
913
+ year_ten_god = self._determine_ten_god(year_gan)
914
+ if year_ten_god:
915
+ god_impact = self._analyze_annual_ten_god(year_ten_god)
916
+ if god_impact:
917
+ impacts.append(god_impact)
918
+ if god_impact['severity'] == 'high':
919
+ overall_score -= 15
920
+ elif god_impact['severity'] == 'positive':
921
+ overall_score += 10
922
+
923
+ overall_score = max(0, min(100, overall_score))
924
+
925
+ if overall_score >= 60:
926
+ assessment = '2026年对你的婚姻关系相对有利,是修复和决策的好时机'
927
+ elif overall_score >= 40:
928
+ assessment = '2026年婚姻运势平稳,维持现状或做小幅调整都可以'
929
+ else:
930
+ assessment = '2026年婚姻宫受到冲击,可能是关系中的关键转折年'
931
+
932
+ return {
933
+ 'year': 2026,
934
+ 'year_ganzhi': '丙午',
935
+ 'year_element': '火',
936
+ 'overall_score': overall_score,
937
+ 'assessment': assessment,
938
+ 'impacts': impacts,
939
+ 'cold_reading': self._annual_cold_reading(impacts, overall_score)
940
+ }
941
+
942
+ def _determine_ten_god(self, gan: str) -> str:
943
+ """根据日主确定某天干对应的十神(简化版)"""
944
+ day_el = self.GAN_ELEMENT.get(self.day_gan, '')
945
+ day_yy = self.GAN_YIN_YANG.get(self.day_gan, '')
946
+ target_el = self.GAN_ELEMENT.get(gan, '')
947
+ target_yy = self.GAN_YIN_YANG.get(gan, '')
948
+
949
+ if not day_el or not target_el:
950
+ return ''
951
+
952
+ # 同我
953
+ if target_el == day_el:
954
+ return '比肩' if target_yy == day_yy else '劫财'
955
+ # 生我
956
+ if self._element_generates(target_el, day_el):
957
+ return '偏印' if target_yy == day_yy else '正印'
958
+ # 我生
959
+ if self._element_generates(day_el, target_el):
960
+ return '食神' if target_yy == day_yy else '伤官'
961
+ # 我克
962
+ if self._element_conquers(day_el, target_el):
963
+ return '偏财' if target_yy == day_yy else '正财'
964
+ # 克我
965
+ if self._element_conquers(target_el, day_el):
966
+ return '七杀' if target_yy == day_yy else '正官'
967
+
968
+ return ''
969
+
970
+ def _element_generates(self, el1: str, el2: str) -> bool:
971
+ """检查五行相生: el1 是否生 el2"""
972
+ generates = {
973
+ '木': '火', '火': '土', '土': '金', '金': '水', '水': '木'
974
+ }
975
+ return generates.get(el1) == el2
976
+
977
+ def _analyze_annual_ten_god(self, ten_god: str) -> Optional[Dict]:
978
+ """分析流年十神对婚姻的影响"""
979
+ if self.gender == 'female':
980
+ if ten_god == '正官':
981
+ return {
982
+ 'type': 'annual_ten_god',
983
+ 'ten_god': ten_god,
984
+ 'severity': 'positive',
985
+ 'detail': '2026年流年正官透出(女命正官=丈夫),丈夫星活跃',
986
+ 'advice': '今年丈夫在你生活中的存在感会变强,适合重新审视关系'
987
+ }
988
+ if ten_god == '七杀':
989
+ return {
990
+ 'type': 'annual_ten_god',
991
+ 'ten_god': ten_god,
992
+ 'severity': 'high',
993
+ 'detail': '2026年流年七杀透出(女命七杀=第二段感情),感情复杂化',
994
+ 'advice': '可能出现新的感情对象或旧情复燃,需要保持清醒'
995
+ }
996
+ if ten_god == '伤官':
997
+ return {
998
+ 'type': 'annual_ten_god',
999
+ 'ten_god': ten_god,
1000
+ 'severity': 'high',
1001
+ 'detail': '2026年流年伤官透出(女命伤官克夫),与丈夫冲突加剧',
1002
+ 'advice': '今年特别需要控制情绪,避免因口舌之争导致关系破裂'
1003
+ }
1004
+ else: # male
1005
+ if ten_god == '正财':
1006
+ return {
1007
+ 'type': 'annual_ten_god',
1008
+ 'ten_god': ten_god,
1009
+ 'severity': 'positive',
1010
+ 'detail': '2026年流年正财透出(男命正财=妻子),婚姻运势上升',
1011
+ 'advice': '今年有利于婚姻修复和感情投入'
1012
+ }
1013
+ if ten_god == '劫财':
1014
+ return {
1015
+ 'type': 'annual_ten_god',
1016
+ 'ten_god': ten_god,
1017
+ 'severity': 'high',
1018
+ 'detail': '2026年流年劫财透出(男命劫财夺妻),需防第三者',
1019
+ 'advice': '今年需警惕朋友圈中的异性关系'
1020
+ }
1021
+
1022
+ return None
1023
+
1024
+ def _annual_cold_reading(self, impacts: List, score: int) -> str:
1025
+ """流年冷读"""
1026
+ if score < 35:
1027
+ return (
1028
+ '2026丙午年,火势极旺——你可能已经感觉到了,今年的情绪比往年更剧烈。'
1029
+ '你的婚姻宫在今年受到了冲击,这意味着一些一直被忽视的问题,'
1030
+ '今年可能会浮上��面。但请不要恐慌——冲击也是契机,'
1031
+ '它在逼迫你正视那些你一直不愿意面对的真相。'
1032
+ )
1033
+ elif score < 50:
1034
+ return (
1035
+ '2026年对你的感情来说是一个"过渡期"——不会有太大的惊喜,'
1036
+ '但也不会太平静。你可能会在今年下半年的某个时刻,'
1037
+ '突然对自己的关系有一个新的认识。留意那个瞬间。'
1038
+ )
1039
+ else:
1040
+ return (
1041
+ '2026年的星象对你的感情关系来说是相对温和的——'
1042
+ '如果你有修复关系的打算,今年是一个不错的窗口。'
1043
+ '但温和不代表可以放松,恰恰是在平静的时期,'
1044
+ '最适合做出清醒的判断。'
1045
+ )
1046
+
1047
+ # ==================== 6. 冷读钩子生成 ====================
1048
+
1049
+ def generate_cold_reading_hooks(self) -> List[Dict[str, Any]]:
1050
+ """
1051
+ 生成冷读法钩子 — 用于 AI prompt 的情绪共鸣锚点
1052
+ 基于命盘真实数据,但用模糊而精准的语言
1053
+ """
1054
+ hooks = []
1055
+ day_element = self.GAN_ELEMENT.get(self.day_gan, '')
1056
+
1057
+ # Hook 1: 基于日主五行的情感模式
1058
+ emotion_patterns = {
1059
+ '木': {
1060
+ 'title': '你的感情像一棵树',
1061
+ 'hook': '你在感情中很执着——你对不对的人,一旦认定了就很难放手。你可能已经在这段关系里"扎根"太久了,即使知道土壤可能不太对。',
1062
+ 'resonance': 'high'
1063
+ },
1064
+ '火': {
1065
+ 'title': '你的爱燃烧得太快',
1066
+ 'hook': '你爱一个人的时候,那种热烈是很难藏住的。但你有没有发现,你的热情总是来得快去得也快?不是你不够深情,而是你燃烧得太猛烈了。',
1067
+ 'resonance': 'high'
1068
+ },
1069
+ '土': {
1070
+ 'title': '你扛得太多了',
1071
+ 'hook': '在这段关系里,你是不是那个一直在"忍"的人?你把很多委屈都埋在心里,因为你觉得忍一忍就过去了。但今天你来到这里,说明你已经快忍不住了。',
1072
+ 'resonance': 'very_high'
1073
+ },
1074
+ '金': {
1075
+ 'title': '你的标准不允许你将就',
1076
+ 'hook': '你心里有一条线——低于这条线的,你不愿意接受。别人可能觉得你太挑剔,但你知道那不是挑剔,那是你对自己和对方的尊重。问题是,你的伴侣知道这条线在哪里吗?',
1077
+ 'resonance': 'high'
1078
+ },
1079
+ '水': {
1080
+ 'title': '你的心像一面湖',
1081
+ 'hook': '表面上你看起来很平静——甚至你的朋友可能都不知道你在经历什么。但在深处,你的情绪翻涌得比谁都厉害。你是不是经常在深夜的时候,一个人想很多很多?',
1082
+ 'resonance': 'very_high'
1083
+ },
1084
+ }
1085
+
1086
+ pattern = emotion_patterns.get(day_element)
1087
+ if pattern:
1088
+ hooks.append({
1089
+ 'category': 'emotion_pattern',
1090
+ 'title': pattern['title'],
1091
+ 'content': pattern['hook'],
1092
+ 'resonance_level': pattern['resonance'],
1093
+ 'basis': f'日主{self.day_gan}({day_element})五行特质'
1094
+ })
1095
+
1096
+ # Hook 2: 基于婚姻宫的关系动态
1097
+ palace_zhi = self.day_zhi
1098
+ if palace_zhi in ['子', '午', '卯', '酉']:
1099
+ hooks.append({
1100
+ 'category': 'relationship_dynamic',
1101
+ 'title': '你们之间有过很好的时候',
1102
+ 'content': (
1103
+ '婚姻宫坐桃花位,说明你和伴侣之间曾经是有吸引力的——'
1104
+ '你们不是那种没感情凑合的关系。正因为曾经有过很美好的感觉,'
1105
+ '现在的落差才让你这么痛苦。你是不是经常想起以前的好时光,'
1106
+ '然后问自己:"到底是从什么时候开始变的?"'
1107
+ ),
1108
+ 'resonance_level': 'very_high',
1109
+ 'basis': f'日支{palace_zhi}为桃花位'
1110
+ })
1111
+ elif palace_zhi in ['辰', '戌', '丑', '未']:
1112
+ hooks.append({
1113
+ 'category': 'relationship_dynamic',
1114
+ 'title': '你选择了责任',
1115
+ 'content': (
1116
+ '你的婚姻宫坐在四墓库之一——你在选择伴侣的时候,'
1117
+ '可能更看重的是"靠谱"和"稳定",而不是心动。'
1118
+ '这没有错,但你是不是有时候会想:如果当初选了那个让你心动的人,会怎样?'
1119
+ ),
1120
+ 'resonance_level': 'high',
1121
+ 'basis': f'日支{palace_zhi}为四墓库'
1122
+ })
1123
+ else:
1124
+ hooks.append({
1125
+ 'category': 'relationship_dynamic',
1126
+ 'title': '你一直在寻找平衡',
1127
+ 'content': (
1128
+ '你的婚姻宫格局显示,你在关系中一直在寻找一种平衡——'
1129
+ '付出和回报的平衡、独立和依赖的平衡。'
1130
+ '你不是不愿意付出,而是你需要感受到对方也在付出。'
1131
+ '这种平衡一旦被打破,你就会开始怀疑一切。'
1132
+ ),
1133
+ 'resonance_level': 'high',
1134
+ 'basis': f'日支{palace_zhi}为四长生'
1135
+ })
1136
+
1137
+ # Hook 3: 基于十神格局的决策风格
1138
+ all_gods_str = ' '.join(self.stem_gods + self.branch_gods)
1139
+ if '伤' in all_gods_str and self.gender == 'female':
1140
+ hooks.append({
1141
+ 'category': 'decision_style',
1142
+ 'title': '你比自己以为的更勇敢',
1143
+ 'content': (
1144
+ '你的命盘里有伤官星——这代表你骨子里有一种"不认命"的劲。'
1145
+ '你来做这个分析,不是因为你软弱需要指导,'
1146
+ '而是因为你够清醒,想要做出一个理性的判断。'
1147
+ '很多人连面对的勇气都没有,你已经迈出了第一步。'
1148
+ ),
1149
+ 'resonance_level': 'very_high',
1150
+ 'basis': '命局有伤官星'
1151
+ })
1152
+ elif '印' in all_gods_str:
1153
+ hooks.append({
1154
+ 'category': 'decision_style',
1155
+ 'title': '你需要的不是答案',
1156
+ 'content': (
1157
+ '你的命盘中印星较明显——你其实是一个很有想法的人,'
1158
+ '你来这里不是因为不知道答案,而是想确认一下自己的感觉对不对。'
1159
+ '你心里可能已经有了一个倾向,只是还不够确定。'
1160
+ '你需要的不是别人告诉你怎么做,而是一面镜子。'
1161
+ ),
1162
+ 'resonance_level': 'high',
1163
+ 'basis': '命局有印星'
1164
+ })
1165
+ else:
1166
+ hooks.append({
1167
+ 'category': 'decision_style',
1168
+ 'title': '你的直觉比你想的准',
1169
+ 'content': (
1170
+ '你来做这个分析,说明你内心已经有了某种预感。'
1171
+ '命理能做的,只是把你模糊的感觉具象化,用数据和结构告诉你:'
1172
+ '你的直觉没有错。接下来要做的,是信任自己。'
1173
+ ),
1174
+ 'resonance_level': 'high',
1175
+ 'basis': '通用决策风格分析'
1176
+ })
1177
+
1178
+ return hooks
1179
+
1180
+
1181
+ # ==================== 测试函数 ====================
1182
+
1183
+ def test_love_clarity_analyzer():
1184
+ """测试函数"""
1185
+ test_bazi = {
1186
+ 'gender': 'female',
1187
+ 'solar_date': '1992-08-15',
1188
+ 'bazi_chart': {
1189
+ 'year': {'gan': '壬', 'zhi': '申'},
1190
+ 'month': {'gan': '戊', 'zhi': '申'},
1191
+ 'day': {'gan': '丙', 'zhi': '午'}, # 日刃格!
1192
+ 'hour': {'gan': '癸', 'zhi': '巳'}
1193
+ },
1194
+ 'ten_gods': {
1195
+ 'heavenly_stems': ['偏官', '偏印', '--', '正官'],
1196
+ 'earthly_branches': ['偏官', '偏印', '劫财', '偏印']
1197
+ }
1198
+ }
1199
+
1200
+ analyzer = LoveClarityAnalyzer(test_bazi)
1201
+ result = analyzer.analyze_all()
1202
+
1203
+ import json
1204
+ print(json.dumps(result, ensure_ascii=False, indent=2))
1205
+
1206
+
1207
+ if __name__ == '__main__':
1208
+ test_love_clarity_analyzer()