From a06598c8a65e82b495fec5729a85edbe617ac824 Mon Sep 17 00:00:00 2001 From: jesse-ux Date: Thu, 22 Oct 2026 03:57:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(chart):=20Yogini=20=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E6=9D=A1=E7=95=99=E5=9C=A8=E6=A0=8F=E5=86=85=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E8=A1=A5=E4=B8=8A=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 两个选项分掉右栏宽度,点选区域至少 44px。同一提交写上设计、文案、更新日志和真人步骤。 Co-Authored-By: Grok (agent loop) Co-authored-by: Cursor --- CHANGELOG.md | 5 +++ .../PROGRESS-chart-dasha-yogini-20261021.md | 38 +++++++++++++++++++ docs/testing/chart-dasha-switch-20261021.md | 9 +++++ frontend/DESIGN.md | 10 +++-- frontend/docs/VOICE.md | 1 + frontend/src/app/globals.css | 13 +++++++ .../tests/chart-dasha-switch-layout.test.ts | 20 ++++++++++ 7 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 docs/tasks/PROGRESS-chart-dasha-yogini-20261021.md create mode 100644 docs/testing/chart-dasha-switch-20261021.md create mode 100644 frontend/tests/chart-dasha-switch-layout.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a9c7826..9939b1bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # 印度占星 Skill 更新日志 +## 2026-10-22 — 星盘大运右栏可以切到 Yogini + +- 大运页左栏仍是 Vimshottari。右栏默认 Chara,可以切到 Yogini。点开当前大运能看到小运。Yogini 的小运下面写「小运未经外部软件核对。」 +- Skill 版本不变。 + ## 2026-10-21 — 导出弹窗:没有英文时顶部提示一次,选中态用主题色 - 英文版不可用时,打开导出弹窗在顶部提示一次,弹窗里不再留那行说明。英文可用时,「建议选 English」仍在语言选项下面。 diff --git a/docs/tasks/PROGRESS-chart-dasha-yogini-20261021.md b/docs/tasks/PROGRESS-chart-dasha-yogini-20261021.md new file mode 100644 index 00000000..8b740c21 --- /dev/null +++ b/docs/tasks/PROGRESS-chart-dasha-yogini-20261021.md @@ -0,0 +1,38 @@ +# 进度:星盘大运右栏加上 Yogini(2026-10-22) + +分支 `codex/chart-dasha-yogini-20261021`。起点 `28dd8df333370dd7f6c2ed56656f9e83f978382f`(已含 #86、#87)。没有 push。 + +## 提交 + +| 步 | SHA | 说明 | +| --- | --- | --- | +| T1 | `6eeb98c7745f134d0609e0cacd1bb27bbc9c7502` | 小运按比例单列,大运函数输出不变 | +| T2 | `3490e89403f3fcfe99a1d91260e8b4320cb0193e` | 只在接口返回的副本上挂小运 | +| T3 | `85567071c74f6460ec917aebc1011f429b346269` | 三张公开名人盘对照 PyJHora,小运做内部核对 | +| T4 | `7a296c7348abb73295b186ac0ed80ee376f15a01` | 按需取 Yogini,缓存按体系分开 | +| T5 | `5ebbd57b041b65c8a6e28ba8be168d57c57b8497` | 按轨道合并,刷新保留已到的轨 | +| T6 | `7b1070f86d1911f7b693724ce580c944dd751e61` | 右栏 Chara / Yogini 切换 | +| T7 | 本文件所在提交 | 切换条样式、DESIGN、VOICE、CHANGELOG、真人清单 | + +## 对照 + +PyJHora `4.8.7`。Presley、Spears、Einstein 三张公开盘走 `compute_chart` 再 `_compute_dasha_system`。大运主星顺序一致,起止日误差都在 1 天以内。没有改算法,没有放宽误差,没有换样本。 + +小运不跟 PyJHora 比。时长 = 大运 `full_years` × 子运年数 ÷ 36,从该大运自己的 Yogini 起轮转 8 位。页面写「小运未经外部软件核对。」 + +完整解读仍直接调用 `calculate_yogini_dasha`。接口行去掉 `antardasha` 之后与完整解读的大运行逐字段相同;完整解读的行没有 `antardasha`。Ashtottari 与 `scripts/jyotish_api_server.py` 没有改。 + +## 测试 + +- `tests/test_yogini_seed_profile.py` + `tests/test_dasha_api_engine_parity.py`:15 passed,0 failed,0 skipped(`-rs` 没有 skip)。其中种子 5,接口对照 10。 +- `frontend/tests/chart-dasha-yogini.test.ts`:4 passed,0 failed。 +- `frontend/tests/chart-page-hook.test.ts`:28 passed,0 failed。 +- `frontend/tests/chart-page-view.test.tsx`:28 passed,0 failed。 +- `frontend/tests/chart-view-route.test.ts`:12 passed,0 failed。 +- `frontend/tests/chart-view-zero-year.test.ts`:4 passed,0 failed。 +- `frontend/tests/chart-planet-glyphs.test.tsx`:13 passed,0 failed。 +- `frontend/tests/chart-dasha-switch-layout.test.ts`:1 passed,0 failed。 +- `tsc --noEmit`:0 错。 +- `npm run lint`:0 error,122 条既有 warning。 + +没有跑 Python 快速门、全量 `npm test`、`next build`。这三件留给验收。没有新增 BUG。真人清单只写步骤。 diff --git a/docs/testing/chart-dasha-switch-20261021.md b/docs/testing/chart-dasha-switch-20261021.md new file mode 100644 index 00000000..5bd16412 --- /dev/null +++ b/docs/testing/chart-dasha-switch-20261021.md @@ -0,0 +1,9 @@ +# 星盘大运切换(真人) + +桌面和手机各做一遍。不要在这份清单上写「已通过」。 + +1. 打开星盘页,点「大运」。左栏是 Vimshottari。右栏默认是 Chara,能看到「现在」卡。 +2. 右栏切到 Yogini。等这一栏出来后,点开当前大运,能看到小运。列表下面有一句「小运未经外部软件核对。」 +3. 再切回 Chara。Chara 仍在,左栏 Vimshottari 没有被换掉。Chara 下面没有那句小运核对说明。 +4. 看「现在」卡:大运、小运、小运剩余都在。 +5. 把窗口收到手机宽度(约 375px)。两栏改成上下排。右栏的 Chara / Yogini 切换不把页面撑出横向滚动,两个选项都能点到。 diff --git a/frontend/DESIGN.md b/frontend/DESIGN.md index 18caeaf7..41ee861e 100644 --- a/frontend/DESIGN.md +++ b/frontend/DESIGN.md @@ -1110,7 +1110,7 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 独立 route `/chart`,不进 `page.tsx`。外壳先画、主盘先到、其余 tab 按需。不扣点、不调模型。盘面从现有路径复用 `VedicChartSvg`,不搬家。 -`/chart` 是静态壳:首字节不取决于引擎。进页只请求 `/api/chart`。分盘(`/api/varga_full`,D2–D60 一次取齐)、大运 Chara(`/api/dasha/chara`)、西洋(`/api/western`)、Bhava(`/api/bhava_chalit`)、行运(按当天日期的 `/api/chart`)在用户点到对应 tab / 盘型时才请求。月亮盘从已到的 D1 投影,不发请求。未点的不发请求。 +`/chart` 是静态壳:首字节不取决于引擎。进页只请求 `/api/chart`。分盘(`/api/varga_full`,D2–D60 一次取齐)、大运 Chara(`/api/dasha/chara`,点开大运 Tab 才请求)、Yogini(`/api/dasha`,缓存范围 `dasha:yogini`,只在右栏切到 Yogini 时请求)、西洋(`/api/western`)、Bhava(`/api/bhava_chalit`)、行运(按当天日期的 `/api/chart`)在用户点到对应 tab / 盘型 / 大运体系时才请求。月亮盘从已到的 D1 投影,不发请求。未点的不发请求。 **七政四余 2026-09-28 起不在星盘页展示**(TASK-chart-types D1):Tab、组件、懒加载层与契约字段已删,后端 `/api/qizheng`、引擎与 vendor 保留,以后作对话里的补充。 @@ -1213,9 +1213,13 @@ D40 / D45 / D60 的表格上方,出生时间不是「已校正」时多一句 0 年大运照实显示,不改引擎。某段 Chara 的 `duration_years` 为 0 时,这一段标注「0 年」,起止落在同一天,不占时间轴,也不展开子运;子运区写「本段时长为 0,不展开」。前一段的结束日就是下一段的开始日。 -### 大运 Tab(2026-09-25) +### 大运 Tab(2026-09-25;右栏切换 2026-10-22) -每条轨道自上而下是「现在」卡、时间条、可折叠大运列表。≥1024 时 Vimshottari 在左、Chara 在右;更窄则上下排。底部仍是那句双轨说明。 +每条轨道自上而下是「现在」卡、时间条、可折叠大运列表。左栏固定 Vimshottari。右栏在 Chara 与 Yogini 之间切换,默认 Chara。切换条在右栏卡片里,两个选项各至少 44px,横排分掉这一栏的宽度,不另开横向滚动。≥1024 时两栏并排;更窄则上下排,切换条跟着右栏走,不另加断点。底部仍是那句双轨说明。 + +点「大运」只取 Chara(`/api/dasha/chara`)。切到 Yogini 才请求 `/api/dasha`,缓存范围是 `dasha:yogini`,和 Chara 不是同一条缓存。回来时只换当前这一轨,已经拿到的另一轨还在。刷新本命盘也保留已经到达的大运轨。 + +Yogini 还在取时,右栏用和 Chara 相同的轨道等待(`OrbitWaiting`),读屏是「这一栏还没拿到。」失败只写在右栏,左栏 Vimshottari 不动。再点当前这个失败的选项会再请求一次。Yogini 列表下面固定一句「小运未经外部软件核对。」Chara 与 Vimshottari 不写这句。 「现在」卡三行:大运、小运、小运剩余 N 个月。月份按排盘所用的 `asOf` 到当前小运结束日的整月数,结束日当天不往下减。没有落入的时段写「未落入已返回的时段」,没有小运写「—」。 diff --git a/frontend/docs/VOICE.md b/frontend/docs/VOICE.md index 6385ccb4..fc1c8d2d 100644 --- a/frontend/docs/VOICE.md +++ b/frontend/docs/VOICE.md @@ -220,6 +220,7 @@ Jyotisha 的可见文案是产品的一部分。正确性红线(真实性、 - 星历这一天没取到:「这一天的星历没取到,点日期再试一次。」 - 0 年大运不展开:「本段时长为 0,不展开。」时长本身写「0 年」。这一行是灰色,不能点开。 - 大运「现在」卡只报三件事:大运名称、小运名称、`小运剩余 N 个月`。没有落入已返回的时段时,大运写「未落入已返回的时段」,小运和小运剩余写「—」。不解释吉凶。 +- Yogini 的小运列表下面固定写「小运未经外部软件核对。」Chara 和 Vimshottari 不写这句。 - 西洋盘要点只报位置,例如:`上升 处女 21°40′`、`太阳 双子 23°48′`、`月亮 双鱼 10°55′`、`元素最多 土`、`星群 摩羯`。同一星座少于 3 颗就不写星群。点中的行星没有主要相位时,相位表写「没有主要相位」。 没有出生资料时,标题是「还没有星盘资料」,按钮是「去填写出生资料」。资料读不出来、已采用时间缺时区、时区没有对上,正文仍用各自的原句,只共用这颗按钮。 diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 7f4501cb..41155422 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -6067,6 +6067,19 @@ button.synastry-dd-add { border-radius: 0 0 var(--radius-md) var(--radius-md); } font-size: var(--type-title-md); font-weight: 500; } +.chart-page-dasha-switch { + display: flex; + gap: var(--space-3); + margin: 0 0 var(--space-3); + border-bottom: 1px solid var(--color-border); + overflow-x: hidden; +} +.chart-page-dasha-switch .chart-page-tab { + flex: 1 1 0; + min-width: 44px; + min-height: 44px; + text-align: center; +} .chart-page-planet-card p { margin: 0 0 var(--space-2); font-size: var(--type-body-sm); } .chart-page-symbol { color: var(--color-ink-tertiary); } .chart-page-dasha-now { diff --git a/frontend/tests/chart-dasha-switch-layout.test.ts b/frontend/tests/chart-dasha-switch-layout.test.ts new file mode 100644 index 00000000..a610d1b7 --- /dev/null +++ b/frontend/tests/chart-dasha-switch-layout.test.ts @@ -0,0 +1,20 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +import { cssDeclarations } from "./css-contract-test-support.ts"; + +const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); + +test("the dasha switch stays inside the column and keeps a 44px hit area", () => { + const row = cssDeclarations(".chart-page-dasha-switch", globalStyles); + assert.match(row, /display:\s*flex/); + assert.match(row, /overflow-x:\s*hidden/); + assert.doesNotMatch(row, /overflow-x:\s*auto/); + const option = cssDeclarations(".chart-page-dasha-switch .chart-page-tab", globalStyles); + assert.match(option, /min-height:\s*44px/); + assert.match(option, /min-width:\s*44px/); + assert.match(option, /flex:\s*1 1 0/); + assert.match(globalStyles, /@media \(min-width: 1024px\)/); + assert.match(globalStyles, /\.chart-page-dasha-columns/); +});