2026-09-10 用户确认 F01–F12、原型通过,并要求按四阶段建议推进。原型验收:#1 评论 7498。阶段 4;覆盖 F12 收尾。
基于各工单已有响应式基础,完成整条学习流程在两类浏览器的交互一致性、主题与字号偏好。
前置:#9, #12, #13。状态:待验收(2026-09-15,提交 e069894,PR #34;契约见评论 8081,实施证据见最新评论)。前置尚未通过时不得标进行中;每单完成停在待验收,由用户验收后关闭。技术验证可与不依赖其结论的工作分工,但不提前冻结未验证契约。
通用 Element Plus 表单与可访问性模式;阅读与复习定制组件。
沿用已验收两端原型,重要差异补局部设计。
后端不为建表/API 单独画页面原型;先写数据、接口、状态、隔离与幂等契约。学习端采用 #1 已验收 v1,未做的 LinguaCafe 对照不标完成。
预计 3~5 人日(8 小时/人日),包含本单设计、前后端实现、相关测试、修正和文档;是规划估算,不是交付日期或 AI 运行时间。仅 F 范围,X 系列不纳入。数据变更先在隔离测试库验证迁移/回退,保留既有数据和原型。
实施时按影响更新 Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;需求变化更新 Product-Requirements-Overview,交付单补实际部署恢复文档。Wiki 先写再回读同步;结束评论记录测试、未验证内容、提交及 revision。工单正文保留基线,重要变化追加评论。
Gitea MCP 指向其他站点,沿用目标 git.ilapage.cn API 回退;凭据仅进入进程。
用户 2026-09-15 指示「做 #14,都按你说的来做」,授权按本契约实施。覆盖 F12 收尾,前置 #9、#12、#13 均已验收关闭。分支 feat/14-responsive-display 从 main 5f86f17 创建。
feat/14-responsive-display
5f86f17
用带触摸的 390×844 移动视口逐个打开登录/书库/导入/书籍/阅读/查词面板/生词本/复习/进度:每个页面 scrollWidth 都等于 innerWidth,没有溢出元素。说明前几单的响应式基础成立,本单不重做已完成的部分,只补缺口并把已成立的性质固化成自动化移动测试。真机手感(长按选择、手柄拖动)无法由本机自动化产生,按 D9 记录为待人工确认的证据缺口,不用窄屏桌面冒充真机。
scrollWidth
innerWidth
theme ∈ {浅色, 深色, 跟随系统},默认跟随系统。用 html[data-theme] 标记,同时切换 Element Plus 官方暗色类 html.dark 并引入 element-plus/theme-chalk/dark/css-vars.css;style.css 现有的 116 处硬编码颜色收敛为约 20 个语义变量(背景、表面、文本、次要文本、边框、主色、提示、状态色等),暗色只覆盖变量,不改组件结构。跟随系统时监听 prefers-color-scheme 实时变化。含中文衬线字体与 Element Plus 组件在深色下的可读性。
theme ∈ {浅色, 深色, 跟随系统}
html[data-theme]
html.dark
element-plus/theme-chalk/dark/css-vars.css
style.css
prefers-color-scheme
三档「标准 / 大 / 特大」(1.0 / 1.15 / 1.3),经 CSS 变量 --reader-font-scale 作用于阅读面:章节正文、释义面板正文与例句、复习卡的词与释义。不做全局 UI 缩放,避免侧栏与按钮在窄屏被挤坏;这是有意的边界,会写入文档。
--reader-font-scale
保存在本机 localStorage,键为 lexgo-learner-display:<账号 id>,按账号隔离:切换账号立刻换成该账号自己的偏好或默认值,A 的深色不会带给 B。未登录的登录页使用系统默认。不跨设备同步(属范围外,明确记录)。这直接对应验收标准「字号和基础明暗主题可保存,账号切换不串偏好」。
localStorage
lexgo-learner-display:<账号 id>
学习端站点头部统一放一个「显示」控件(下拉/弹层,含主题与字号两组单选),当前值可见、可键盘操作、移动端可点开。七个页面各加一处引用,不重构现有头部结构。
按「账号+章节」保存滚动比例,并同时保存当时的 content_sha256:章节就绪后恢复到上次位置;正文版本变化后不恢复(避免把新内容的读者丢到旧偏移);同账号其他章节互不影响。本机行为,不跨设备。
content_sha256
空格
Enter
1
2
3
Esc
LookupPanel
不引入任何会阻止默认行为的触摸处理(现状即如此,本单保持)。新增带 hasTouch 的移动 e2e:触摸滑动必须真的滚动页面、不得误开释义面板;pointerup 与 selectionchange 的既有设计不变。长按原生选择的手感仍需真机确认。
hasTouch
pointerup
selectionchange
PWA、离线能力、自定义配色/复杂主题、全局 UI 缩放、偏好跨设备同步、阅读位置跨设备同步、真机自动化(记录为待人工确认)。
isMobile
纯前端与文档改动,无迁移:回退到上一提交即可;本单不触碰后端与数据库。
Gitea MCP 仍指向其他站点,沿用目标站点 API 回退;凭据仅从既有安全配置读入进程。
用户 2026-09-15 指示「做 #14,都按你说的来做」,按契约评论 8081 实施。分支 feat/14-responsive-display 从 main 5f86f17 创建,功能提交 e069894 已推送;PR #34 未合并,工单不关闭,停在待用户验收。
e069894
:root
1/2/3
npx vitest --run
vue-tsc --build
pnpm run build
playwright test
pnpm test
pnpm lint
python -m unittest discover -s tests
harness.py check --strict
sync --check
LEXGO_TEST_DB_NAME=lexgo_test_issue13 python scripts/server.py test-integration
--project=mobile
--bg: var(--brand-panel-text)
outline-style: none
e2e/theme.spec.ts
onMounted(load)
a4fd3873678017ea046a6e708141d7f8140edcef
5a44b1713b3fd2374baa78314872539f3e2e23ab
e6255c24e7b966573a9851b1e2356e370d3daef1
912089b338bf3c978add09069e39e7fb19c94240
591ce1b3b16af9401062af925ba159ebdc4b8c6a
AGENTS.md
README.md
纯前端与文档改动,无 schema 变化、无接口变化:git revert 到 5f86f17 或恢复上一版学习端构建即可。
git revert
附件:移动端八个界面与深色/特大/滚动截图、桌面主题浅深两态、复习键盘流程,以及真实链路的阅读位置、深色特大与复习键盘截图;本会话模型不能读取图片,断言来自程序化检查。
审核对象:提交 e069894(PR #34)。只读审阅代码与测试差异,没有重跑测试。契约 D1~D11(评论 8081)逐条核对如下。
stores/preferences.ts
readPreference
displayKey
watch(() => session.user?.id, ...)
load
FONT_SCALES
applyPreference
readingPosition.ts
readPosition
parsed.sha !== sha
ReaderView.vue
restorePosition
status==='ready'
reviewShortcuts.ts
ignoresShortcut
preventDefault
touchmove
git show --stat
learner/
server/
评论里如实记录了实施中踩到并修掉的 4 个问题,我抽查了其中两个最容易被掩盖的:
html[data-theme='dark']
var()
button, a[href], [role="button"]
这种「先如实报告自己犯过的错,再给出修复依据」的记录方式值得肯定,比只报喜不报错更可信。
达标,可以进入用户验收。 这单的验收标准本身就要求「真机结果单独记录」,pi 也确实把「模拟触摸视口」和「真实手机」分得很清楚,没有像业务规则明确禁止的那样拿窄屏当真机;D1 的现状复测(先证明前几单的响应式基础已经成立,再补自动化用例固化,而不是不问就重做)也是合理的效率判断,没有虚报工作量。
本次审核只读代码,没有重跑 learner 的 vitest/E2E(含新增的 mobile/theme/keyboard 专项用例);pi 报告的 147 项单测、23 项 E2E 等结果未被本次复核重复验证。真机(长按选择、手柄拖动、软键盘、安全区)仍是待人工确认的已知缺口,这一点工单本身已如实标注,不需要我重复提示。
Gitea MCP 仍指向其他站点,本次沿用已记录的目标站点 API 回退;凭据只从 ~/.claude/gitea.env 安全配置读入进程。
~/.claude/gitea.env
用户于 2026-09-15 明确回复「#14 通过验收」。
20e13e9
9f6485206c60c737b386fdf2f2946adf606d53e7
b61d9e1b0d9ae9fc24cb026580149f2b582a2526
358d7720d952a49b6827a96173a4f63387ac6989
5cf8e02e2248e93b1255ad85fb41153984c84cd1
单元工单关闭;#16 的 #14 复选框同步勾选。
No dependencies set.
The note is not visible to the blocked user.
来源与目标
2026-09-10 用户确认 F01–F12、原型通过,并要求按四阶段建议推进。原型验收:#1 评论 7498。阶段 4;覆盖 F12 收尾。
基于各工单已有响应式基础,完成整条学习流程在两类浏览器的交互一致性、主题与字号偏好。
验收标准
依赖与执行
前置:#9, #12, #13。状态:待验收(2026-09-15,提交 e069894,PR #34;契约见评论 8081,实施证据见最新评论)。前置尚未通过时不得标进行中;每单完成停在待验收,由用户验收后关闭。技术验证可与不依赖其结论的工作分工,但不提前冻结未验证契约。
参考模块与设计证据
通用 Element Plus 表单与可访问性模式;阅读与复习定制组件。
沿用已验收两端原型,重要差异补局部设计。
后端不为建表/API 单独画页面原型;先写数据、接口、状态、隔离与幂等契约。学习端采用 #1 已验收 v1,未做的 LinguaCafe 对照不标完成。
工作量、范围与风险
预计 3~5 人日(8 小时/人日),包含本单设计、前后端实现、相关测试、修正和文档;是规划估算,不是交付日期或 AI 运行时间。仅 F 范围,X 系列不纳入。数据变更先在隔离测试库验证迁移/回退,保留既有数据和原型。
文档与证据
实施时按影响更新 Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;需求变化更新 Product-Requirements-Overview,交付单补实际部署恢复文档。Wiki 先写再回读同步;结束评论记录测试、未验证内容、提交及 revision。工单正文保留基线,重要变化追加评论。
Gitea MCP 指向其他站点,沿用目标 git.ilapage.cn API 回退;凭据仅进入进程。
#14 方案确认与实施启动(2026-09-15)
用户 2026-09-15 指示「做 #14,都按你说的来做」,授权按本契约实施。覆盖 F12 收尾,前置 #9、#12、#13 均已验收关闭。分支
feat/14-responsive-display从 main5f86f17创建。D1 先测现状(已完成,事实而非假设)
用带触摸的 390×844 移动视口逐个打开登录/书库/导入/书籍/阅读/查词面板/生词本/复习/进度:每个页面
scrollWidth都等于innerWidth,没有溢出元素。说明前几单的响应式基础成立,本单不重做已完成的部分,只补缺口并把已成立的性质固化成自动化移动测试。真机手感(长按选择、手柄拖动)无法由本机自动化产生,按 D9 记录为待人工确认的证据缺口,不用窄屏桌面冒充真机。D2 主题偏好
theme ∈ {浅色, 深色, 跟随系统},默认跟随系统。用html[data-theme]标记,同时切换 Element Plus 官方暗色类html.dark并引入element-plus/theme-chalk/dark/css-vars.css;style.css现有的 116 处硬编码颜色收敛为约 20 个语义变量(背景、表面、文本、次要文本、边框、主色、提示、状态色等),暗色只覆盖变量,不改组件结构。跟随系统时监听prefers-color-scheme实时变化。含中文衬线字体与 Element Plus 组件在深色下的可读性。D3 字号偏好
三档「标准 / 大 / 特大」(1.0 / 1.15 / 1.3),经 CSS 变量
--reader-font-scale作用于阅读面:章节正文、释义面板正文与例句、复习卡的词与释义。不做全局 UI 缩放,避免侧栏与按钮在窄屏被挤坏;这是有意的边界,会写入文档。D4 偏好的保存与账号隔离
保存在本机
localStorage,键为lexgo-learner-display:<账号 id>,按账号隔离:切换账号立刻换成该账号自己的偏好或默认值,A 的深色不会带给 B。未登录的登录页使用系统默认。不跨设备同步(属范围外,明确记录)。这直接对应验收标准「字号和基础明暗主题可保存,账号切换不串偏好」。D5 偏好入口
学习端站点头部统一放一个「显示」控件(下拉/弹层,含主题与字号两组单选),当前值可见、可键盘操作、移动端可点开。七个页面各加一处引用,不重构现有头部结构。
D6 保留阅读位置
按「账号+章节」保存滚动比例,并同时保存当时的
content_sha256:章节就绪后恢复到上次位置;正文版本变化后不恢复(避免把新内容的读者丢到旧偏移);同账号其他章节互不影响。本机行为,不跨设备。D7 键盘操作与焦点
空格/Enter显示答案,1认识/答对,2不认识/答错,3再学一次;只在事件目标不是输入框、文本域、下拉或按钮时生效,避免与按钮原生按键重复触发;界面显示快捷键提示。Esc关闭释义面板;LookupPanel自身的 Esc 继续只关面板。D8 触摸与滚动
不引入任何会阻止默认行为的触摸处理(现状即如此,本单保持)。新增带
hasTouch的移动 e2e:触摸滑动必须真的滚动页面、不得误开释义面板;pointerup与selectionchange的既有设计不变。长按原生选择的手感仍需真机确认。D9 范围外
PWA、离线能力、自定义配色/复杂主题、全局 UI 缩放、偏好跨设备同步、阅读位置跨设备同步、真机自动化(记录为待人工确认)。
D10 验证与文档
isMobile+hasTouch):8 个界面无横向溢出、每页都有可返回的入口、复习键盘流程、触摸滚动不误触、主题切换在刷新后保持且账号间不串、阅读位置恢复。D11 回退
纯前端与文档改动,无迁移:回退到上一提交即可;本单不触碰后端与数据库。
Gitea MCP 仍指向其他站点,沿用目标站点 API 回退;凭据仅从既有安全配置读入进程。
#14 实施完成,待用户验收(2026-09-15)
用户 2026-09-15 指示「做 #14,都按你说的来做」,按契约评论 8081 实施。分支
feat/14-responsive-display从 main5f86f17创建,功能提交e069894已推送;PR #34 未合并,工单不关闭,停在待用户验收。实现与差异
style.css收敛为语义调色板(:root的 53 个变量是文件内仅有的颜色字面量),html[data-theme]覆盖取值,html.dark映射 Element Plus 暗色变量并引入其暗色样式表;跟随系统时监听系统配色变化。--reader-font-scale只作用于阅读面,不做全局缩放。lexgo-learner-display:<账号 id>,切换账号换成该账号偏好或默认,退出回默认;非法/旧格式回退默认。不跨设备同步。content_sha256;正文换新版本后不恢复,等待可滚动后再应用(约 1 秒内放弃)。空格/Enter显示答案、1/2/3评分,输入控件内不触发、聚焦按钮的按键交给浏览器;Esc关闭释义面板;焦点环覆盖自定义元素。实际验证
npx vitest --run/vue-tsc --build/pnpm run build/playwright testpnpm test/pnpm lintpython -m unittest discover -s tests/harness.py check --strict/sync --checkLEXGO_TEST_DB_NAME=lexgo_test_issue13 python scripts/server.py test-integration--project=mobile本单自己踩到并修掉的问题(如实记录)
:root自身的定义也被替换,产生--bg: var(--brand-panel-text)这类自引用,所有颜色静默失效;几何断言与属性断言全部照常通过,只有焦点环探针暴露了它(outline-style: none而宽度仍是 medium 的 3px)。修好后补了e2e/theme.spec.ts:逐个读回 16 个变量,断言深浅两套都解析成非空值、背景不透明、正文与背景不同色。onMounted(load)改成只注册滚动监听,导致阅读器不再加载章节,被既有单测当场拦下。未验证与边界
hasTouch的模拟设备,不用模拟结果冒充真机(#4、#11 起就记录该缺口,本单未能消除)。文档
a4fd3873678017ea046a6e708141d7f8140edcef5a44b1713b3fd2374baa78314872539f3e2e23abe6255c24e7b966573a9851b1e2356e370d3daef1912089b338bf3c978add09069e39e7fb19c94240591ce1b3b16af9401062af925ba159ebdc4b8c6async --check通过,4 个变更页逐字节正文比对一致;仓库根AGENTS.md与README.md已同步口径与进度回退
纯前端与文档改动,无 schema 变化、无接口变化:
git revert到5f86f17或恢复上一版学习端构建即可。Gitea MCP 仍指向其他站点,沿用目标站点 API 回退;凭据仅从既有安全配置读入进程。
附件:移动端八个界面与深色/特大/滚动截图、桌面主题浅深两态、复习键盘流程,以及真实链路的阅读位置、深色特大与复习键盘截图;本会话模型不能读取图片,断言来自程序化检查。
#14 代码审核:达标(2026-09-15,Claude Code)
审核对象:提交
e069894(PR #34)。只读审阅代码与测试差异,没有重跑测试。契约 D1~D11(评论 8081)逐条核对如下。逐条核对
stores/preferences.ts的readPreference对损坏/旧格式/非法值一律回退默认而不是抛错或半应用;displayKey按账号 id 建立独立存储键;watch(() => session.user?.id, ...)在账号切换时立即重新load。这几点都是容易做漏的边界,代码里都处理了。达标。FONT_SCALES只通过--reader-font-scale一个 CSS 变量输出,applyPreference没有触碰任何布局相关的变量,符合「只作用阅读面、不做全局缩放」的边界。达标。readingPosition.ts的readPosition显式比较parsed.sha !== sha才拒绝,ReaderView.vue的restorePosition用 sha 和status==='ready'双重把关;恢复逻辑改成轮询等待页面可滚动(最多 20×50ms ≈ 1s 后放弃),而不是单个定时器賭时机。达标。reviewShortcuts.ts的ignoresShortcut精确区分「按钮只吃 Space/Enter」和「数字键永远归复习」,这正是 pi 自己发现并修复的冲突点;代码注释把原因写清楚了,不是含糊带过。达标。preventDefault/touchmove拦截,移动端 e2e 用真实触摸事件验证滑动能滚动、不误开面板。达标。git show --stat确认改动全部在learner/与文档,没有server/目录改动。达标。对自查缺陷记录的复核
评论里如实记录了实施中踩到并修掉的 4 个问题,我抽查了其中两个最容易被掩盖的:
style.css的:root块(53 个变量)与html[data-theme='dark']覆盖块,两处全部是字面量十六进制颜色,没有找到自引用的var()。深色覆盖块的取值与浅色一一对应、无遗漏。确认已修复。ignoresShortcut的实现与描述一致——button, a[href], [role="button"]只拦截 Space/Enter,数字键不受影响。确认已修复。这种「先如实报告自己犯过的错,再给出修复依据」的记录方式值得肯定,比只报喜不报错更可信。
结论
达标,可以进入用户验收。 这单的验收标准本身就要求「真机结果单独记录」,pi 也确实把「模拟触摸视口」和「真实手机」分得很清楚,没有像业务规则明确禁止的那样拿窄屏当真机;D1 的现状复测(先证明前几单的响应式基础已经成立,再补自动化用例固化,而不是不问就重做)也是合理的效率判断,没有虚报工作量。
本次审核只读代码,没有重跑 learner 的 vitest/E2E(含新增的 mobile/theme/keyboard 专项用例);pi 报告的 147 项单测、23 项 E2E 等结果未被本次复核重复验证。真机(长按选择、手柄拖动、软键盘、安全区)仍是待人工确认的已知缺口,这一点工单本身已如实标注,不需要我重复提示。
Gitea MCP 仍指向其他站点,本次沿用已记录的目标站点 API 回退;凭据只从
~/.claude/gitea.env安全配置读入进程。#14 验收通过(2026-09-15)
用户于 2026-09-15 明确回复「#14 通过验收」。
e069894;验收文档提交20e13e9已推送。9f6485206c60c737b386fdf2f2946adf606d53e7、Architectureb61d9e1b0d9ae9fc24cb026580149f2b582a2526、Product-Requirements358d7720d952a49b6827a96173a4f63387ac6989、Project-Profile5cf8e02e2248e93b1255ad85fb41153984c84cd1。sync --check通过,并对 4 个变更页做逐字节正文比对(全部一致)。站点对整页批量回读仍返回 HTTP 429,沿用「revision 级 check + 变更页正文比对」。5f86f17或恢复上一版学习端构建即可。hasTouch模拟设备,未用模拟结果冒充真机);未做 Safari/Firefox 验证。缺陷 #32(编辑正文回到曾用版本返回 500)已定位、方案待用户确认,尚未排期。单元工单关闭;#16 的 #14 复选框同步勾选。