docs(tasks): chart dasha Yogini switch brief (agent loop, issue #88)
Product decided 1A 2A: Yogini sub-periods proportional with internal checks (majors still matched against PyJHora); Ashtottari leaves this ticket because its start table disagrees with PyJHora on 8 of 12 nakshatras and will get its own issue. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9812f31737
commit
8c63f31f12
@@ -515,3 +515,4 @@
|
||||
| `TASK-chart-ascendant-slash-20261021.md` | — | #87 上升状态格「不适用」改「/」+ 悬停 / 点按说明;报告上升行同改并在表下加说明(推翻 10-15 口径) | 待领取(等 #86 合入) | `codex/chart-ascendant-slash-20261021` |
|
||||
| `TASK-report-export-dialog-polish-20261021.md` | — | #90 导出弹窗:英文不可用说明改顶部浮层(每次打开一次);选中态描边 / 圆点 / 勾选框用主题色、底色中性(推翻 DESIGN「Selected states use canvas-muted + ink」,BUG-1078 主语保留) | 待领取(可与 #89 并行) | `codex/report-export-dialog-polish-20261021` |
|
||||
| `TASK-report-english-han-leak-20261021.md` | `PROGRESS-report-english-han-leak-20261021.md` | #89 个人报告英文版约 4 成整份丢弃:漏译汉字源头补英文孪生字段、修吃空格;200 张固定种子回归 + 快速门 smoke(复发自 BUG-1272);中文逐字节不变 | 待领取(最先做;#91/#92 在后) | `codex/report-english-han-leak-20261021` |
|
||||
| `TASK-chart-dasha-yogini-20261021.md` | — | #88 星盘页大运右栏切换 Chara / Yogini,Yogini 补小运(按比例,内部核对,页面注明未经外部软件核对);Ashtottari 另立单(起运表与 PyJHora 8/12 宿不一致) | 待领取(等 #86、#87 合入) | `codex/chart-dasha-yogini-20261021` |
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# 任务书:星盘页大运右栏可切换,加 Yogini(含小运)(2026-10-21,issue #88)
|
||||
|
||||
> 产品 2026-10-21 已决定 **Ashtottari 不在本单**(见 P2 与「另行处理」)。
|
||||
|
||||
## 基线
|
||||
|
||||
- 写单时 `origin/staging` = `bd3ce0e7b`(此后 `308ca2a65` 只加了 #87 任务书)。**开工时以 #86、#87 合入后的 `origin/staging` 为准**;任一未合入就不开工,回报「等 #86 / #87」。
|
||||
- 执行方:**Grok(Windows + Docker)**。分支 `codex/chart-dasha-yogini-20261021`,工作树 `.worktrees/chart-dasha-yogini-20261021`,**只推这个分支**,不推 staging、不推 main。
|
||||
- 关联:BUG-1196、BUG-1262(Yogini 顺序与出生余额)、BUG-1341(`/api/dasha` 改走引擎模块)、BUG-1344(PyJHora 大运对照的来源)。
|
||||
|
||||
### 与 #86、#87 的文件重叠
|
||||
|
||||
| 文件 | #86 | #87 | 本单 |
|
||||
| --- | --- | --- | --- |
|
||||
| `frontend/src/components/chart-page/chart-page-view.tsx` | 出生资料行(页头 `birthline` 一带)、人名切换 | — | `ChartDashaTab` 的入参(等待 / 失败按层传) |
|
||||
| `frontend/src/hooks/use-chart-page.ts` | 可能(切换人物时) | — | `mergeLayer`、`missing` 判定 |
|
||||
| `frontend/tests/chart-page-hook.test.ts` | 可能 | 旧缓存时 `>不适用<` 断言改成 `/` | 新层的 429 / 失败 / 合并用例 |
|
||||
| `frontend/tests/chart-page-view.test.tsx` | 可能 | — | 大运 Tab 渲染用例 |
|
||||
| `frontend/src/app/globals.css`、`frontend/DESIGN.md` | 是 | 是 | 是(大运切换条、§大运 Tab) |
|
||||
|
||||
`chart-vedic-tab.tsx`、`scripts/pl9_reader_export.py`(#87)本单不碰。#86 写单时没有任务书在 staging 上,开工时用 `git log -p origin/staging -- <上表文件>` 看它们实际改了什么,在其上改,不得回退。
|
||||
|
||||
## 现状实证(按符号定位)
|
||||
|
||||
| # | 事实 | 位置 |
|
||||
| --- | --- | --- |
|
||||
| 1 | `/api/dasha` 对非 Vimshottari 体系调 `dasha_registry.compute_dasha`,响应只带 `periods` 和 `algorithm_label / algorithm_note / profile`。小运放进每个大运行的 `antardasha` 字段就会原样透出,**不需要改 `jyotish_api_server.py`** | `scripts/jyotish_api_server.py` `_compute_dasha_system`;`scripts/dasha_registry.py` `compute_dasha` yogini 分支 |
|
||||
| 2 | Yogini 只有大运。行字段 `yogini / planet / full_years / years / start_date / end_date / unclipped_start_date / cycle_number`;第一段 `start_date` 已裁到出生时刻,未裁起点在 `unclipped_start_date`;年长 365.25 天;至少 3 轮(24 段) | `scripts/yogini_dasha.py` `_calculate_moon_balanced_yogini` |
|
||||
| 3 | 完整解读也调 `calculate_yogini_dasha`(`jyotish_engine.cmd_full_reading`),`test_dasha_api_engine_parity.py::test_api_major_periods_match_full_reading_modules` 断言接口 `periods` 与完整解读模块行逐字段相等 | `scripts/jyotish_engine.py`(`from yogini_dasha import calculate_yogini_dasha`);同名测试 |
|
||||
| 4 | PyJHora 4.8.7 的 Yogini 小运是 8 等分(`yogini.get_dhasa_bhukthi` 里 `parent_years / n`),与产品定的按比例算法不同,所以小运不与 PyJHora 对照(P1)。Yogini **大运**写单时实测与 PyJHora 主星顺序一致、起点误差 ≤1 天(虚构盘、Presley、Spears 等 4 张,各 24 段) | PyJHora `jhora/horoscope/dhasa/graha/yogini.py` |
|
||||
| 5 | 前端 Chara 按需层链路:`CHART_VIEW_LAYERS`(`chart-view-engine.ts`)→ `parseChartViewLayers`(`app/api/chart-view/route.ts`)→ `assembleChartView` 按层并发调引擎(`chart-view-load.ts`)→ `buildChartView` / `charaTrack`(`chart-view-mapper.ts`)→ `chartViewOkSchema.dasha` 与 `layerFailures`(`chart-view-contract.ts`,轨道 `id` 是 `z.enum(["vimshottari","chara"])`)→ `useChartPage.requestLayer` / `mergeLayer`(`hooks/use-chart-page.ts`)→ `ChartPageView.selectTab("dasha")` 请求 `chara`(`components/chart-page/chart-page-view.tsx`)→ `ChartDashaTab` 右栏写死 `view.dasha.chara`,等待态 `OrbitWaiting`(`components/chart-page/chart-dasha-tab.tsx`) | 各文件按符号 |
|
||||
| 6 | 照抄 Chara 会踩的三个坑:① 引擎缓存键 `chartViewEngineCacheKey` 只含 path 不含 body;Yogini 走 `/api/dasha`,将来其他体系也走同一 path,**不带 `cacheScope` 就会串缓存**(`chartViewEngineCachePath(path, cacheScope)`,行运层已这样做);② `mergeLayer` 对 `chara` 整个替换 `dasha` 对象(`{ dasha: incoming.dasha }`),新层这样写会把已到的 Chara 冲掉;③ `secondary-page-data.ts` 的 `refreshChartPage` 合并旧快照时只保留 `dasha.chara`,新轨道会在刷新后丢失 | `chart-view-engine.ts` `chartViewEngineCacheKey`;`use-chart-page.ts` `mergeLayer`;`secondary-page-data.ts` `refreshChartPage` |
|
||||
| 7 | DESIGN.md 现有约定:大运 Tab「≥1024 时 Vimshottari 在左、Chara 在右;更窄则上下排」(`.chart-page-dasha-columns`);按需层「失败移除等待,再点该 Tab / chip 清失败并重试」 | `frontend/DESIGN.md` §大运 Tab、§按需层 |
|
||||
|
||||
## 根因
|
||||
|
||||
不是 bug,是缺口:页面只接了 Chara 一个按需层,Yogini 引擎没有小运。
|
||||
|
||||
## 决策记录(产品负责人 2026-10-21)
|
||||
|
||||
| # | 决定 |
|
||||
| --- | --- |
|
||||
| K1 | 左栏固定 Vimshottari 不变。右栏顶部加体系切换:**Chara / Yogini**,默认 Chara |
|
||||
| K2 | Yogini 和 Chara 一样能点开大运看小运;「现在」卡显示大运、小运、小运剩余 |
|
||||
| K3 | (原「Ashtottari 只在适用时出现」)随 P2 移出本单 |
|
||||
| K4 | 数据走现有 `POST /api/dasha {dasha:"yogini"}`;Yogini 小运在 `scripts/yogini_dasha.py` 新增;不改冻结文件 `jyotish_api_server.py` |
|
||||
| K5 | 核对(按 P1 调整):Yogini **大运**与 PyJHora 对照,≥3 张公开名人盘,主星顺序一致、起止日误差 ≤1 天;Yogini **小运**做内部自洽核对(见 T3)。PyJHora 只作测试参照,不进运行代码。对不上就停下报告,不得放宽误差;对不上则 Yogini 不上页面 |
|
||||
| K6 | 前端照 Chara 按需层加 `yogini` 层;切到 Yogini 时才请求;失败只在右栏显示失败句,可重试;等待态沿用 `OrbitWaiting`,不新增加载动画 |
|
||||
| K7 | 合同测试 fixture 取自真实 `/api/dasha` 响应(golden),不得手造 |
|
||||
| K8 | 手机宽度两栏上下排,切换条横向不溢出 |
|
||||
| K9 | 改了 Python,验收跑 Python 快速门全量 |
|
||||
| K10 | 不在本单:Ashtottari、Kalachakra、Narayana、星座类体系 |
|
||||
| P1 = A | Yogini 小运**按比例**:时长 = 大运年数 × 子运年数 ÷ 36,从该大运的 Yogini 起依次轮转 8 位;首个大运按出生时已走过的比例裁掉前面的部分。小运不与 PyJHora 对照(PyJHora 是等分)。页面在 Yogini 小运处注明「小运未经外部软件核对。」 |
|
||||
| P2 = A | **Ashtottari 不在本单**。切换只有 Chara / Yogini。Ashtottari 的起运表与适用口径另立 issue(见「另行处理」) |
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. **不改 `scripts/jyotish_api_server.py`**(`git diff origin/staging -- scripts/jyotish_api_server.py` 必须为空);`tests/test_api_server_growth_contract.py` 照常通过。
|
||||
2. **不碰 Ashtottari**:`scripts/ashtottari_dasha.py`、`scripts/ashtottari_rule_profiles.py`、`dasha_registry.compute_dasha` 的 ashtottari 分支、完整解读里的 Ashtottari 段一律不改。
|
||||
3. PyJHora 只在测试里出现;`tests/test_runtime_jhora_import_scan.py` 必须通过;`scripts/**` 不得 `import jhora`。
|
||||
4. 对照测试必须**真跑**:工作树 `.venv` 按 `requirements-reference-engines.txt` 装 PyJHora 4.8.7;新对照用例 `pytest -rs` 不得出现 skip。跳过不算通过。
|
||||
5. 对照测试走**接口路径**(`_compute_dasha_system` 或 `compute_dasha`),不直接调模块。
|
||||
6. **停止条件**:Yogini 大运对照不过(主星顺序不同,或任一起止日误差 >1 天),或 T3 的内部核对不过,停下,在 PROGRESS 写清哪张盘、哪一段、差多少,回报;不得放宽误差、不得换样本凑通过、不得改 PyJHora 调用参数迎合引擎。此时 Yogini 不上页面。
|
||||
7. 不改完整解读(`cmd_full_reading`)的 Yogini 输出:小运只挂在接口返回的副本上;虚构盘完整解读逐字段不变(PROGRESS 附 diff 结论)。
|
||||
8. 前端 fixture 只来自真实 `/api/dasha` 响应,文件头写 `sourceCommand`(命令、盘、岁差、交点);不得手写形状。
|
||||
9. 改既有断言写「原值 / 新值 / 原因」三栏;测试总数不得少于开工基线。
|
||||
10. 不改数据库、不改 `.gitea/`、不升级依赖(PyJHora 只装进工作树 `.venv`,不改 `requirements*.txt`)。
|
||||
11. 隐私:fixture、测试、文档只用公开名人盘或虚构盘。
|
||||
|
||||
## 任务分解
|
||||
|
||||
| # | 内容 | 验收标准 | Grok 自跑 | Claude 验收 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| T1 | `scripts/yogini_dasha.py` 新增独立函数(如 `yogini_antardashas(major_row, *, birth_dt, year_days)`):从该大运自己的 Yogini 起依次 8 位;时长 = 大运 `full_years` × 子运年数 ÷ 36;从 `unclipped_start_date` 起排,结束于出生前的小运丢掉,跨出生的那段起点裁到出生(保留 `unclipped_start_date`);最后一段收尾到大运 `end_date`。`calculate_yogini_dasha` 输出不变 | 新单测(沿用 `test_yogini_seed_profile.py` 的盘):见 T3 内部核对 | `tests/test_yogini_seed_profile.py` + 新单测 | 复验 + 快速门 |
|
||||
| T2 | `dasha_registry.compute_dasha` 的 yogini 分支:对大运行做深拷贝并挂 `antardasha`(字段 `level / planet / yogini / lord / years / start_date / end_date`,跨出生那段加 `unclipped_start_date`) | 虚构盘、Spears 接口响应有小运;完整解读 Yogini 模块与改前逐字段相同 | 同 T3 | 复验 |
|
||||
| T3 | 核对(K5、P1、红线 4–6),写进 `tests/test_dasha_api_engine_parity.py`:**① 大运对照**:≥3 张公开盘(候选 Presley、Spears、Einstein、Trump,盘数据已在 `tests/smoke_test_runner.py` / 本测试文件里),接口大运对 PyJHora `yogini.get_dhasa_bhukthi(..., dhasa_level_index=1)`,主星顺序一致,起点(用 `unclipped_start_date`)误差 ≤1 天。**② 小运内部核对**(同几张盘的全部大运):每个大运的小运时长之和与大运(裁后)时长相差 ≤1 天;小运主星从该大运自己的 Yogini 起按 Goel Table I 轮转;首个大运第一条小运起点等于大运裁后起点(出生时刻),其余大运第一条小运起点等于大运起点;相邻小运首尾相接;未裁的首个大运按比例时长与公式一致。**③ 既有断言**:`test_api_major_periods_match_full_reading_modules` 对 yogini 由 `result["periods"] == engine_rows` 改为去掉 `antardasha` 后相等(三栏) | `pytest -rs` 0 skip;全部通过或按红线 6 停止 | 必跑 | 复验(本机已装 PyJHora 4.8.7) |
|
||||
| T4 | 前端数据层:`CHART_VIEW_LAYERS` 加 `yogini`;`assembleChartView` 调 `/api/dasha`,body 为 `followUp` + `dasha: "yogini"`,**`cacheScope` 取体系名**(`"dasha:yogini"`);`chartViewDashaTrackSchema.id` 加 `yogini`,`chartViewOkSchema.dasha` 与 `layerFailures` 加 `yogini`;`chart-view-mapper.ts` 照 `charaTrack` 写 `yoginiTrack`:大运 / 小运日期直接用引擎值(`derived: false`),大运标签「<Yogini 名> / <行星中文>」(例「Pingala / 太阳」),小运同样格式;`antardashaNote` = 「小运未经外部软件核对。」(放在 `labels.ts`,在轨道列表下与其他轨道的说明句同一位置,`.chart-page-note`)。**可推广要求**:大运层的「层名 → 引擎体系键 → 缓存 scope → 轨道键」写成一张表(一处常量),加第二个 `/api/dasha` 体系时只加一行 + 一个映射函数,不改 hook 与合并逻辑 | golden 测试:Yogini 真实响应映射后过 `chartViewOkSchema`;缓存测试:同一人先取 Chara 再取 Yogini、再换一个 `/api/dasha` 体系键(测试里传参),各拿各的数据 | 改到的测试文件 | 全量 `npm test` |
|
||||
| T5 | `use-chart-page.ts`:`mergeLayer` 对大运层只替换各自那条轨道(`dasha: { ...current.dasha, [轨道]: incoming.dasha[轨道] }`,Chara 也改成这样),不再整体替换 `dasha`;`requestLayer` 中 Yogini 以 periods 为空判失败;`secondary-page-data.ts` `refreshChartPage` 按 T4 那张表保留所有已到的大运轨道,不再只写 `chara` | hook 测试:先到 Chara 再到 Yogini,Chara 仍在;反过来亦然;Yogini 429 只在 Yogini 层失败;D1 刷新后 Yogini 轨道仍在 | 改到的测试文件 | 全量 |
|
||||
| T6 | 页面:`ChartDashaTab` 右栏顶部切换条(Chara / Yogini,默认 Chara,`role="tablist"` 或分段按钮,当前项样式沿用页面 Tab 下划线语言);进大运 Tab 仍只请求 Chara;切到 Yogini 才请求 `yogini`;等待 `OrbitWaiting`;失败只在右栏显示 `chartLayerFailureCopy` 的句子,再点当前选项重试(与 DESIGN.md 按需层重试一致,不另加按钮);左栏 Vimshottari 不受影响;`chart-page-view.tsx` 把按层的等待 / 失败传进 `ChartDashaTab` | 渲染测试:默认 Chara;切到 Yogini 只发 yogini 层;右栏失败时左栏正常;再点 Yogini 重新请求;Yogini「现在」卡有大运 / 小运 / 小运剩余;Yogini 轨道下有「小运未经外部软件核对。」,Chara、Vimshottari 下没有 | 改到的测试文件 | 全量 + `next build` |
|
||||
| T7 | 样式与文档:切换条在 375px 不横向溢出(两个短标签,不用横向滚动;点击区 ≥44px);≥1024 两栏、更窄上下排沿用 `.chart-page-dasha-columns`;DESIGN.md §大运 Tab 改写(右栏可切换、Yogini 小运说明句、失败与重试、按需请求列表加 `/api/dasha` Yogini);`frontend/docs/VOICE.md` 若有大运 Tab 文案表则补这句;CHANGELOG;PROGRESS;真机清单 `docs/testing/chart-dasha-switch-20261021.md`(电脑与手机各打开大运 Tab,切两种体系、展开当前大运看小运、核对「现在」卡、手机看切换条不溢出) | 样式断言测试;文档齐 | — | 复验;`/` 仍 Static、首屏 gzip ±2% |
|
||||
|
||||
### 按源码文本断言、需要同轮跟改的测试(AGENTS §7.8,开工时再 grep 一遍)
|
||||
|
||||
| 测试 | 断言的内容 |
|
||||
| --- | --- |
|
||||
| `frontend/tests/chart-view-route.test.ts` | `loadSource` 匹配 `/api/dasha/chara`;`CHART_VIEW_LAYERS` 全层组装;`body.dasha.chara.title` |
|
||||
| `frontend/tests/chart-page-hook.test.ts` | 按层 429 循环(层名列表带三栏注释,加层再写三栏);引擎桩按 path 分派(`/api/dasha` 要按 body 的 `dasha` 分派) |
|
||||
| `frontend/tests/chart-page-view.test.tsx` | 大运 Tab 含「Chara Dasha(kn_rao 变体)」;chara 失败 / 等待;「现在」卡数量 = 2、时间条段数 = 两条轨道段数之和(默认 Chara 时应不变) |
|
||||
| `frontend/tests/chart-view-zero-year.test.ts` | `ChartDashaTab` 渲染 Chara 0 年段、段数 |
|
||||
| `frontend/tests/secondary-page-entry.test.ts` | `use-chart-page.ts` 源码文本(`useState<ChartViewResponse \| null>(() => viewMatchingSubject(subjectId))`) |
|
||||
| `frontend/tests/chart-profile-update-consistency.test.ts`、`chart-view-engine.test.ts` | 缓存键、`chartViewOkSchema` |
|
||||
| `tests/test_chart_page_vedic_tables_contract.py` | 用 golden 跑 `buildChartView`(`chara: null`,新增入参要兼容) |
|
||||
| `tests/test_dasha_api_engine_parity.py` | `periods == engine_rows`、未实现键报错 |
|
||||
| `tests/run_all.py`「Yogini Dasha 8 periods」、`tests/test_yogini_seed_profile.py`、`tests/test_full_reading_conditional_dashas.py`、`tests/test_report_longform_*` | Yogini 模块输出(完整解读不变则不应变红) |
|
||||
|
||||
## 让步顺序
|
||||
|
||||
1. 时间不够:T1–T3(Python + 核对)单独提交先推分支,前端后补;不得先上前端、后补核对。
|
||||
2. T4 的「可推广表」若与现有类型冲突难以收敛,可先只做 Yogini,但 T5 的「按轨道合并、刷新保留全部大运轨道」不让步。
|
||||
3. 核对不过:按红线 6 停,Yogini 不上页面,本单只交已完成的前端重构部分须经 Claude 确认后再推。
|
||||
|
||||
## 开工前置命令
|
||||
|
||||
```bash
|
||||
git fetch origin --prune
|
||||
git log --oneline -30 origin/staging # 确认 #86、#87 已合入;没合入就回报「等 #86 / #87」
|
||||
git worktree add -b codex/chart-dasha-yogini-20261021 .worktrees/chart-dasha-yogini-20261021 origin/staging
|
||||
cd .worktrees/chart-dasha-yogini-20261021
|
||||
.venv/Scripts/python -m pip install -r requirements-reference-engines.txt # 只装进工作树 .venv
|
||||
.venv/Scripts/python -c "import importlib.metadata as m; print(m.version('PyJHora'))" # 必须 4.8.7
|
||||
.venv/Scripts/python -m pytest tests/test_dasha_api_engine_parity.py tests/test_yogini_seed_profile.py -rs -q # 记基线
|
||||
grep -rn "chara" frontend/src/lib/chart-view-*.ts frontend/src/hooks/use-chart-page.ts frontend/src/lib/secondary-page-data.ts frontend/src/components/chart-page/
|
||||
grep -rln "chart-dasha-tab\|use-chart-page\|chart-view-load\|chart-view-contract\|chart-view-mapper\|CHART_VIEW_LAYERS\|dasha/chara" frontend/tests tests
|
||||
git log -p origin/staging -- frontend/src/components/chart-page/chart-page-view.tsx frontend/src/hooks/use-chart-page.ts | head -200 # 看 #86/#87 改了什么
|
||||
grep -o "BUG-1[0-9]\{3\}" docs/BUG_HISTORY.md | sort -u | tail -3
|
||||
```
|
||||
|
||||
验收分工:Grok 自跑 `tsc --noEmit`、`npm run lint`、改到的前端测试文件、改到的 Python 测试文件(含 T3,`-rs` 无 skip);Claude 验收时跑前端全量 `npm test`、Python 快速门 `run_quality_gate.py --profile quick`、`npm run build`(`/` 仍 Static、首屏 gzip ±2%),并复跑 T3。本单不动数据库,不要求 `test:db`。执行方不得在真机清单里写「已通过」。
|
||||
|
||||
## 另行处理(不在本单)
|
||||
|
||||
- **Ashtottari** 的起运表与「本盘是否适用」口径另立 issue,由 Claude 起草给产品负责人确认后再提。写单时已确认的问题:接口用的旧白名单起运星在 12 个月宿里有 8 个与 PyJHora 不一致、白名单索引 20 的注释错一位、三套适用口径在 10 张公开盘上结论互不相同、接口从不传规则族、现有对照测试绕过接口路径。
|
||||
- **完整解读 / 报告里的 Ashtottari 段目前可能是错的**(与接口共用同一函数、同一白名单)。本单不碰,留给上述 issue。
|
||||
|
||||
## BUG 编号
|
||||
|
||||
本单是功能缺口,原则上不新增 BUG;执行中若发现并修了 bug 才记。编号取开工时 `docs/BUG_HISTORY.md` 最大号 +1。该文件自 `400af57e8` 起整段重复了一遍,取最大号务必用 `grep -o "BUG-1[0-9]\{3\}" docs/BUG_HISTORY.md | sort -u | tail -1`,不要按行号或首次出现取。#85 占用 BUG-1404~1408。
|
||||
Reference in New Issue
Block a user