报告开头改成重点摘要卡

新报告用围栏画出大运和事业、财富、婚恋,标题下写名字与日期。旧报告不变。

自测:pytest test_report_full_data_fix.py 10 通过;相关四份报告测试退出码 0;前端相关测试 147 通过、0 失败、0 取消;tsc 退出码 0;lint 0 error。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-10-13 21:45:43 +08:00
co-authored by Grok (agent loop)
parent 963276ca2f
commit 8883f8475f
20 changed files with 856 additions and 82 deletions
+75 -44
View File
@@ -1393,61 +1393,92 @@ def missing_field_count(packet: dict) -> int:
return len(fields)
def _iso_day(value: Any) -> str | None:
text = _date_text(value)
return text if re.fullmatch(r"\d{4}-\d{2}-\d{2}", text) else None
def _current_period_rows(packet: dict) -> dict[str, dict]:
"""Current MD/AD/PD rows already stored on the dasha timeline. No new dates."""
dasha = _dict(_timing(packet).get("dasha"))
current = _dict(dasha.get("current_dasha"))
md_row = current if current.get("lord") else {}
if not md_row:
for period in _list(dasha.get("timeline")):
if isinstance(period, dict) and period.get("is_current"):
md_row = period
break
ad_row: dict = {}
pd_row: dict = {}
for row in _list(md_row.get("antardasha_timeline")):
if isinstance(row, dict) and row.get("is_current"):
ad_row = row
for child in _list(row.get("pratyantar_dasha_timeline")):
if isinstance(child, dict) and child.get("is_current"):
pd_row = child
break
break
return {"md": md_row, "ad": ad_row, "pd": pd_row}
def _focus_fence(payload: dict) -> str:
try:
from report_focus_block import build_focus_fence
except ModuleNotFoundError: # pragma: no cover - package import compatibility
from scripts.report_focus_block import build_focus_fence
return build_focus_fence(payload)
def opening_focus_block(packet: dict) -> str:
"""Current MD/AD/PD plus career, wealth, and relationship house lords."""
"""Current MD/AD/PD plus career, wealth, and relationship house lords.
The reader draws the card from the fence. This function does not compute
a new dasha or house lord; missing dates stay null.
"""
language = _lang(packet)
lords = _current_lords(packet)
houses = _houses(packet)
planets = _planets(packet)
classification = _functional_classification(packet)
def lord_line(number: int, topic_zh: str, topic_en: str) -> str:
rows = _current_period_rows(packet)
periods = []
for level in ("md", "ad", "pd"):
row = rows[level]
lord = str(row.get("lord") or "").strip()
periods.append({
"level": level,
"lord": lord or None,
"start": _iso_day(row.get("start")),
"end": _iso_day(row.get("end")),
})
domains = []
for key, number in (("career", 10), ("wealth", 2), ("relationship", 7)):
house = _house_row(houses, number)
lord = str(house.get("lord") or "")
lord = str(house.get("lord") or "").strip()
row = planets.get(lord) if isinstance(planets.get(lord), dict) else {}
placed = row.get("house")
dignity = _dignity(row.get("status") or row.get("dignity"), language)
role = _role(classification.get(lord), language)
if language == "zh":
return (
f"- {topic_zh}第{number}宫主 {_planet(lord, language)} 落在第{placed if isinstance(placed, int) else '未列出'}宫,"
f"尊贵为{dignity},功能吉凶为{role}。"
)
return (
f"- {topic_en} house {number} lord {lord or 'not listed'} is in house "
f"{placed if isinstance(placed, int) else 'not listed'}, dignity {dignity}, functional nature {role}."
)
domains.append({
"key": key,
"house": number,
"lord": lord or None,
"placed": placed if isinstance(placed, int) else None,
"dignity": _dignity(row.get("status") or row.get("dignity"), language),
"role": _role(classification.get(lord), language),
})
if language == "zh":
lines = [
"重点:当前主运 MD {md},子运 AD {ad},次子运 PD {pd}。".format(
md=_planet(lords["md"], language),
ad=_planet(lords["ad"], language),
pd=_planet(lords["pd"], language),
),
"",
"## 重点",
lord_line(10, "事业", "Career"),
lord_line(2, "财富", "Resources"),
lord_line(7, "婚恋", "Relationship"),
"- 这段时间可能突出这些宫主所守护的主题,不是确定会发生的事。",
]
caveat = "这段时间可能突出这些宫主所守护的主题,不是确定会发生的事。"
heading = "## 重点"
else:
lines = [
"Focus: current Maha Dasha MD {md}, Antar Dasha AD {ad}, Pratyantar Dasha PD {pd}.".format(
md=lords["md"] or "not listed",
ad=lords["ad"] or "not listed",
pd=lords["pd"] or "not listed",
),
"",
"## Focus",
lord_line(10, "事业", "Career"),
lord_line(2, "财富", "Resources"),
lord_line(7, "婚恋", "Relationship"),
"- This period may bring those house-lord topics forward. It is not a certain event.",
]
return "\n".join(lines)
caveat = "This period may bring those house-lord topics forward. It is not a certain event."
heading = "## Focus"
fence = _focus_fence({
"version": 1,
"periods": periods,
"domains": domains,
"caveat": caveat,
})
return f"{heading}\n\n{fence}"
def _strength_snapshot(packet: dict) -> dict: