diff --git a/.ai-specs/coding-specs/2026-04-22-profile-page-static-design.md b/.ai-specs/coding-specs/2026-04-22-profile-page-static-design.md
deleted file mode 100644
index 586e17a..0000000
--- a/.ai-specs/coding-specs/2026-04-22-profile-page-static-design.md
+++ /dev/null
@@ -1,213 +0,0 @@
-# `pages/profile/index` 未登录态静态页面设计
-
-## 文档元信息
-
-- 日期:`2026-04-22`
-- 目标页面:`pages/profile/index`
-- 设计范围:`结构复刻 + 纯静态展示 + 未登录态`
-- 关联文档:`AGENTS.md`、`README.md`
-
-## 目标
-
-在不引入接口、store、页面跳转和新增组件的前提下,将 `pages/profile/index` 从占位页升级为一个可直接展示的个人中心静态页面。页面目标是复刻参考图的区块结构和信息层级,同时沿用仓库现有暖色、卡片化视觉语言,避免做截图级像素还原。
-
-## 范围与非目标
-
-### 本次范围
-
-- 仅修改 `pages/profile/index.js`、`pages/profile/index.wxml`、`pages/profile/index.wxss`
-- 页面首屏固定为未登录态
-- 页面包含 5 个区块:用户卡片、会员引导卡片、学习资产四宫格、最近记录空状态、其它功能列表
-- 页面内容使用静态 `data` 驱动
-- 按微信原生小程序常规写法实现,不新增通用组件
-
-### 非目标
-
-- 不接入 `stores/modules/session.js`
-- 不调用 `services/api/*` 或 `services/request/index.js`
-- 不新增图标图片资源、不新增字体资源
-- 不接按钮点击、页面跳转、分享能力、登录能力
-- 不处理已登录态、真实记录列表、真实资产计数
-
-## 方案选择
-
-### 备选方案
-
-1. 页面内一次性落地
-2. 先抽资产区和列表行为局部组件
-3. 强行复用现有 `components/base/app-button` 与 `components/biz/entry-card`
-
-### 最终选择
-
-采用“页面内一次性落地”方案。
-
-选择原因:
-
-- 当前目标是静态结构复刻,范围小,直接写在页面内更短更稳
-- 现有组件与目标结构不贴合,强复用会增加样式扭曲和模板复杂度
-- 通过结构化 `data` 和分区 class 命名,后续仍可平滑抽组件,不会锁死实现
-
-## 页面结构
-
-页面按纵向信息流组织,顺序固定如下:
-
-1. 用户卡片
-2. 会员引导卡片
-3. 学习资产四宫格
-4. 最近记录
-5. 其它功能
-
-各区块关系如下:
-
-```mermaid
-flowchart TD
- PAGE["profile-page 页面根容器"] --> USER["用户卡片
头像占位 / 登录文案 / 设置入口占位"]
- PAGE --> VIP["会员引导卡片
图标占位 / 说明文案 / CTA 按钮占位"]
- PAGE --> ASSET["学习资产四宫格
我的笔记 / 我的书架 / 我的收藏 / 浏览历史"]
- PAGE --> RECENT["最近记录卡片
标题 + 空状态文案"]
- PAGE --> MORE["其它功能列表
意见反馈 / 分享 APP / 关于我们 / 设置"]
-```
-
-## 数据模型
-
-页面 `data` 只承载静态展示信息,建议按 5 组对象/数组组织:
-
-```js
-{
- userCard: {
- avatarText: '?',
- title: '点击登录',
- subtitle: '登录后查看你的学习资产',
- settingsText: '设'
- },
- vipCard: {
- icon: '会员',
- title: '开通会员',
- subtitle: '解锁更多学习资料、AI 仪表与阅读辅助能力',
- actionText: '成为会员'
- },
- assetItems: [
- { key: 'notes', icon: '记', title: '我的笔记', count: 0 },
- { key: 'bookshelf', icon: '架', title: '我的书架', count: 0 },
- { key: 'favorites', icon: '藏', title: '我的收藏', count: 0 },
- { key: 'history', icon: '史', title: '浏览历史', count: 0 }
- ],
- recentRecord: {
- title: '最近记录',
- emptyTitle: '还没有回访记录',
- emptyDescription: '去典籍阅读或 AI 页完成一次学习,记录会出现在这里。'
- },
- moreItems: [
- { key: 'feedback', title: '意见反馈' },
- { key: 'share', title: '分享 APP' },
- { key: 'about', title: '关于我们' },
- { key: 'settings', title: '设置' }
- ]
-}
-```
-
-约束:
-
-- `assetItems` 和 `moreItems` 必须使用 `wx:for`
-- `key` 只用于渲染稳定性和后续扩展,不在本次承担业务逻辑
-- 所有文本先静态写入 `data`,避免模板中散落魔法字符串
-
-## WXML 结构边界
-
-WXML 只保留三级边界:
-
-- 页面根:`profile-page`
-- 区块卡片:`section-card`
-- 区块内部局部结构:`profile-header`、`vip-banner`、`asset-grid`、`recent-panel`、`menu-list`
-
-结构要求:
-
-- 顶部用户卡片和会员卡片为独立卡片,不合并
-- 资产区一行固定 4 列,每项包含图标容器、标题、数字
-- 最近记录固定为空状态,不渲染列表分支
-- 其它功能为纵向列表,每一行使用“左文案 + 右箭头占位”的标准结构
-
-## 样式策略
-
-页面视觉遵循“结构复刻,风格贴合仓库”的原则。
-
-### 页面级
-
-- 延续当前项目已有的米白到浅金渐变背景
-- 保持主内容纵向滚动,顶部和底部有稳定安全边距
-
-### 卡片级
-
-- 统一使用浅底、圆角、大留白、轻阴影
-- 卡片间距与首页的 `section-card` 节奏接近
-- 避免复杂装饰、绝对定位角标和图片背景
-
-### 文本级
-
-- 区块标题延续首页的 `Songti` / serif 风格
-- 正文、副文案、数字采用更轻的系统字体层级
-- 用户卡片标题突出,辅助说明弱化
-
-### 图标级
-
-- 本次不新增图片资源
-- 头像、会员、四宫格图标、右箭头均用字符或简单容器占位
-- 图标容器风格统一,避免每块都出现不同视觉语言
-
-## 行为与数据流
-
-本页当前没有真实行为流,只保留静态展示结构。
-
-```mermaid
-flowchart LR
- DATA["Page data 静态对象"] --> WXML["WXML 区块渲染"]
- WXML --> WXSS["WXSS 卡片与布局样式"]
- WXSS --> UI["未登录态个人中心静态页面"]
-```
-
-约束:
-
-- 不出现 `onLoad` 拉取数据逻辑
-- 不出现 `wx.navigateTo`、`wx.switchTab`、`wx.login`、`wx.getUserProfile`
-- 不出现依赖外部状态的分支渲染
-
-## 错误处理与边界
-
-由于本次没有网络请求和真实交互,错误处理重点放在布局稳定性:
-
-- `assetItems` 固定为 4 项;若后续数量变化,需要单独评估布局是否仍保持 4 列
-- 文案长度以当前中文文案为基准,样式需避免一行被异常挤压
-- 图标占位必须在没有外部资源时也能稳定渲染
-- 页面在微信常规设备宽度下不能出现卡片溢出、四宫格换行错位、列表箭头挤压
-
-## 测试与验收
-
-本次设计对应的最小验证范围:
-
-1. 页面整体包含 5 个区块,顺序与设计一致
-2. 学习资产区稳定为一行 4 列
-3. 最近记录展示为空状态,不出现列表分支
-4. 其它功能区展示 4 行静态入口
-5. 改动范围仅限 `pages/profile/index.*`,不新增业务组件、不接 API / store
-
-若补测试,优先补:
-
-- 页面 `data` 结构渲染测试
-- 四宫格与功能列表项数量断言
-- 关键标题文案存在性断言
-
-## 实施边界
-
-实施顺序固定为:
-
-1. 重写 `pages/profile/index.js` 中的静态数据
-2. 重写 `pages/profile/index.wxml` 的区块结构
-3. 重写 `pages/profile/index.wxss` 的整体布局与卡片样式
-4. 回查 `app.json` 中 `pages/profile/index` 路由已存在,无需新增注册
-
-禁止事项:
-
-- 不提前抽新组件
-- 不顺手接登录态
-- 不顺手接页面跳转
-- 不为“以后可能要用”增加额外抽象
diff --git a/.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-design.md b/.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-design.md
deleted file mode 100644
index ade8e15..0000000
--- a/.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-design.md
+++ /dev/null
@@ -1,255 +0,0 @@
-# `frontend` 老项目静态页面迁移设计
-
-## 文档元信息
-
-- 日期:`2026-04-23`
-- 目标仓库:`xuanzhi-wx`
-- 参考来源:`D:\Code3\wdp\xuanzhi\frontend`
-- 设计范围:`静态页面复刻 + 可点击导航 + 基础前端交互`
-- 关联文档:`AGENTS.md`、`README.md`、`.ai-specs/coding-specs/2026-04-22-profile-page-static-design.md`
-
-## 目标
-
-在不复刻旧项目接口、数据结构、状态管理、工程组织和业务逻辑的前提下,将 `frontend` 项目中的主要页面形态迁移到当前微信原生小程序仓库,形成一套:
-
-- 保持当前 `4 tab` 结构不变
-- 页面都能看得到并点得到
-- 只依赖静态 `data` 和页面内交互
-- 与当前项目目录职责一致
-
-的静态 UI/UX 壳层。
-
-## 范围与非目标
-
-### 本次范围
-
-- 完善现有主包页面:`pages/home/index`、`pages/library/index`、`pages/ai/index`、`pages/profile/index`、`pages/login/index`
-- 新增分包页面:
- - `packages/tcm/pages/*`
- - `packages/mingli/pages/*`
- - `packages/learning/pages/*`
-- 补齐从主包 `tab` 页进入新增分包页的静态导航入口
-- 在页面内保留纯前端交互:
- - 切换
- - 输入
- - 弹层
- - 抽屉
- - 静态结果展示
-- 新增纯静态数据与路由映射工具,服务页面渲染
-
-### 非目标
-
-- 不接入 `services/api/*`
-- 不复用旧项目的 `services/*`、`stores/*`、`composables/*`、`utils/*workflow*`
-- 不保留旧项目的 `bookId / recordId / passageId` 真实业务语义
-- 不实现真实登录、历史、搜索、收藏、书架、阅读进度、AI 回答、八字排盘
-- 不复制旧项目的页面目录命名和信息架构问题
-- 不新增底部 `tab`
-
-## 页面归属与路由设计
-
-### 总体原则
-
-- 主包继续承担 `tab` 与公共入口职责
-- 新增业务页优先进入分包
-- 已经存在的主包页面只做增强,不重复新建第二套首页或第二套我的页
-
-### 主包保留页面
-
-| 路由 | 角色 | 本次定位 |
-|:---|:---|:---|
-| `pages/home/index` | 首页 tab | 总入口页,承接中医域、易学域、学习中心入口 |
-| `pages/library/index` | 典籍 tab | 保留中医书城主体,补易学阁入口 |
-| `pages/ai/index` | AI tab | 保留中医 AI 主体,补命理解读和相关深入口 |
-| `pages/profile/index` | 我的 tab | 复刻静态个人页,并补学习中心、资产、历史等入口 |
-| `pages/login/index` | 登录页 | 改成纯静态登录展示页,不保留 mock 会话逻辑 |
-
-### 中医分包
-
-| 路由 | 对应旧页 | 定位 |
-|:---|:---|:---|
-| `packages/tcm/pages/ai-history/index` | `src/pages/tcm/ai-history/index.vue` | AI 历史静态页 |
-| `packages/tcm/pages/assets/index` | `src/pages/tcm/assets/index.vue` | 学习资产静态页 |
-| `packages/tcm/pages/bianzheng/index` | `src/pages/tcm/bianzheng/index.vue` | 辨证分析静态页 |
-| `packages/tcm/pages/book-detail/index` | `src/pages/tcm/book-detail/index.vue` | 典籍详情静态页 |
-| `packages/tcm/pages/search-books/index` | `src/pages/tcm/search-books/index.vue` | 搜索静态页 |
-| `packages/tcm/pages/section/index` | `src/pages/tcm/section/index.vue` | 阅读页静态壳 |
-| `packages/tcm/pages/placeholder/index` | `src/pages/tcm/placeholder/index.vue` | 占位说明页 |
-
-### 易学分包
-
-| 路由 | 对应旧页 | 定位 |
-|:---|:---|:---|
-| `packages/mingli/pages/hall/index` | `src/pages/mingli/books/index.vue` | 易学阁首页,重新命名为 `hall` |
-| `packages/mingli/pages/bazi/index` | `src/pages/bazi/index.vue` | 八字排盘静态页 |
-| `packages/mingli/pages/book-detail/index` | `src/pages/mingli/book-detail/index.vue` | 易学典籍详情静态页 |
-| `packages/mingli/pages/search-books/index` | `src/pages/mingli/search-books/index.vue` | 易学搜索静态页 |
-| `packages/mingli/pages/section/index` | `src/pages/mingli/section/index.vue` | 易学阅读静态页 |
-| `packages/mingli/pages/interpret/index` | `src/pages/mingli/interpret/index.vue` | 命理解读静态页 |
-
-### 学习中心分包
-
-| 路由 | 对应旧页 | 定位 |
-|:---|:---|:---|
-| `packages/learning/pages/center/index` | `src/pages/learning/index.vue` | 学习中心聚合页 |
-
-### 导航要求
-
-- 保持当前 `4 tab` 不变
-- 所有新增页面必须能从现有可见入口进入
-- 页面间只保留静态跳转链路,不建立真实业务流
-
-```mermaid
-flowchart TD
- HOME["pages/home/index"] --> TCM_BOOK_DETAIL["packages/tcm/pages/book-detail/index"]
- HOME --> TCM_SECTION["packages/tcm/pages/section/index"]
- HOME --> MINGLI_HALL["packages/mingli/pages/hall/index"]
- HOME --> BAZI["packages/mingli/pages/bazi/index"]
- HOME --> LEARNING["packages/learning/pages/center/index"]
-
- LIBRARY["pages/library/index"] --> TCM_SEARCH["packages/tcm/pages/search-books/index"]
- LIBRARY --> MINGLI_HALL
-
- AI["pages/ai/index"] --> TCM_AI_HISTORY["packages/tcm/pages/ai-history/index"]
- AI --> TCM_BIANZHENG["packages/tcm/pages/bianzheng/index"]
- AI --> MINGLI_INTERPRET["packages/mingli/pages/interpret/index"]
-
- PROFILE["pages/profile/index"] --> TCM_ASSETS["packages/tcm/pages/assets/index"]
- PROFILE --> TCM_AI_HISTORY
- PROFILE --> LEARNING
- PROFILE --> TCM_PLACEHOLDER["packages/tcm/pages/placeholder/index"]
-```
-
-## 静态数据与最小复用层
-
-### 目标
-
-定义当前项目自己的静态展示模型,只为支撑页面渲染,不兼容旧项目业务模型。
-
-### 允许新增的静态工具
-
-| 路径 | 职责 |
-|:---|:---|
-| `utils/static-ux/route-map.js` | 维护页面跳转路径常量 |
-| `utils/static-ux/shared.js` | 维护纯静态数据克隆、场景选择等无状态工具 |
-| `utils/static-ux/tcm.js` | 维护中医域静态页面数据工厂 |
-| `utils/static-ux/mingli.js` | 维护易学域与八字域静态页面数据工厂 |
-| `utils/static-ux/learning.js` | 维护学习中心聚合页静态数据工厂 |
-
-### 允许抽取的公共层级
-
-- 少量全局视觉 token 放入 `app.wxss`
-- 只抽纯静态、无业务含义的复用
-- 页面结构优先在页面内落地,避免过早抽组件
-
-### 禁止抽取的层级
-
-- `services/api/*`
-- `services/request/*`
-- `stores/*`
-- 旧项目的 `domain-*`、`standalone-storage*`、`workflow*`、`composables/*`
-- 与后端 response contract 强绑定的 model、mapper、adapter
-
-### 静态数据模型约束
-
-- 页面只消费最小展示字段
-- 字段名按当前项目需要重新定义
-- 同一视觉卡片可以和旧项目使用不同字段名
-- 所有展示数据都由当前仓库内静态工厂返回
-
-推荐数据形态:
-
-```js
-{
- card: { key, title, subtitle, icon, actionText },
- book: { key, title, subtitle, coverText, tags },
- section: { key, title, children },
- historyItem: { key, label, title, subtitle, meta },
- formPreset: { title, fields, examples, buttonText },
- resultPreset: { title, summary, highlights },
- baziPreset: { profile, pillars, summary, highlights }
-}
-```
-
-## 交互边界
-
-### 允许保留的前端交互
-
-- 页面跳转
-- tab / segment / 分类切换
-- 输入框、textarea、选项选中态
-- 抽屉、弹层、目录展开
-- 静态结果卡显示与隐藏
-- `wx.showToast` 占位提示
-
-### 明确禁止的交互
-
-- 真实登录态判断
-- mock session 写入
-- 本地持久化历史、收藏、书架、笔记
-- 按真实 ID 请求详情
-- 真实搜索过滤
-- 真实阅读器分页逻辑
-- 真实 AI 输出和引用结构
-- 真实八字计算或记录管理
-
-### 参数策略
-
-参数只允许承担静态场景切换,不承担业务身份标识。
-
-允许的参数示例:
-
-- `kind=notes|bookshelf|favorites|history`
-- `mode=qa|analysis|constitution`
-- `domain=tcm|mingli`
-- `scene=default|empty|result`
-
-禁止继续沿用的旧式业务参数语义:
-
-- `bookId`
-- `recordId`
-- `passageId`
-
-如果某个页面确实需要多个视觉场景,应使用当前项目自定义的轻量参数,例如:
-
-- `scene=classic-a`
-- `scene=record-preview`
-
-## 视觉风格约束
-
-- `tcm` 域沿用当前项目暖金、米白、浅棕的卡片化风格
-- `mingli / bazi` 域保留偏红棕的区分,但统一到当前小程序样式体系
-- 同域页面的标题、卡片、按钮、背景节奏必须一致
-- 不做截图级像素还原,优先保证结构、层级、节奏、交互反馈一致
-- 不擅自重做当前项目已经确定的 tab 结构和全局视觉方向
-
-## 实施边界
-
-### 实施顺序
-
-1. 更新 `app.json` 注册分包与页面路由
-2. 搭建 `utils/static-ux/*` 静态数据层
-3. 完善主包 4 个 tab 页和登录页的入口与静态结构
-4. 落地 `tcm` 分包静态页
-5. 落地 `mingli` 分包静态页
-6. 落地 `learning` 分包静态页
-7. 回查路由、入口、样式一致性与文档登记
-
-### 禁止事项
-
-- 不把旧项目目录整体照搬到当前仓库
-- 不为了复刻 UI 顺手补接口或 store
-- 不为了“以后可能会接后端”先设计复杂状态层
-- 不新建第二套首页、第二套我的页、第二套主导航
-
-## 验收标准
-
-1. 当前项目保留 `4 tab` 结构不变
-2. `frontend` 目标页面在当前仓库都有静态对应页
-3. 当前已经存在的主包页只做增强,不重复建页
-4. 所有新增页面都能从可见入口点进去
-5. 页面内主要操作都有静态反馈、切换或跳转结果
-6. 实现过程中不新增 API、request、store 依赖
-7. 实现过程中不复刻旧项目数据结构、工具链和目录组织
-8. `AGENTS.md` 的 `.ai-specs` 文档登记与本设计保持同步
-
diff --git a/.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-implementation-plan.md b/.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-implementation-plan.md
deleted file mode 100644
index 7d0e555..0000000
--- a/.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-implementation-plan.md
+++ /dev/null
@@ -1,1744 +0,0 @@
-# Frontend Static Page Migration Implementation Plan
-
-> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
-
-**Goal:** 在保持当前 `4 tab` 不变的前提下,把 `D:\Code3\wdp\xuanzhi\frontend` 的主要页面迁移为当前小程序仓库中的静态页面体系,做到页面可见、可点、可切换,但不接 API、store、旧数据结构和真实业务逻辑。
-
-**Architecture:** 先在 `app.json` 中注册 `tcm / mingli / learning` 分包,再建立 `utils/static-ux/*` 纯静态数据层,随后按“主包页 -> tcm 分包 -> mingli + learning 分包”的顺序落地页面。所有页面 `index.js` 统一暴露 `create*PageData` 工厂函数,Jest 直接验证页面数据和事件处理,页面间只通过当前仓库自定义的静态参数做场景切换。
-
-**Tech Stack:** 微信原生小程序、JavaScript、WXML、WXSS、Jest、TDesign(仅限当前仓库已存在组件)
-
----
-
-## File Structure
-
-- Modify: `app.json`
-- Modify: `app.wxss`
-- Create: `utils/static-ux/route-map.js`
-- Create: `utils/static-ux/shared.js`
-- Create: `utils/static-ux/tcm.js`
-- Create: `utils/static-ux/mingli.js`
-- Create: `utils/static-ux/learning.js`
-- Modify: `pages/home/index.js`
-- Modify: `pages/home/index.wxml`
-- Modify: `pages/home/index.wxss`
-- Modify: `pages/library/index.js`
-- Modify: `pages/library/index.wxml`
-- Modify: `pages/library/index.wxss`
-- Modify: `pages/ai/index.js`
-- Modify: `pages/ai/index.wxml`
-- Modify: `pages/ai/index.wxss`
-- Modify: `pages/profile/index.js`
-- Modify: `pages/profile/index.wxml`
-- Modify: `pages/profile/index.wxss`
-- Modify: `pages/login/index.js`
-- Modify: `pages/login/index.wxml`
-- Modify: `pages/login/index.wxss`
-- Create: `packages/tcm/pages/ai-history/index.js`
-- Create: `packages/tcm/pages/ai-history/index.json`
-- Create: `packages/tcm/pages/ai-history/index.wxml`
-- Create: `packages/tcm/pages/ai-history/index.wxss`
-- Create: `packages/tcm/pages/assets/index.js`
-- Create: `packages/tcm/pages/assets/index.json`
-- Create: `packages/tcm/pages/assets/index.wxml`
-- Create: `packages/tcm/pages/assets/index.wxss`
-- Create: `packages/tcm/pages/bianzheng/index.js`
-- Create: `packages/tcm/pages/bianzheng/index.json`
-- Create: `packages/tcm/pages/bianzheng/index.wxml`
-- Create: `packages/tcm/pages/bianzheng/index.wxss`
-- Create: `packages/tcm/pages/book-detail/index.js`
-- Create: `packages/tcm/pages/book-detail/index.json`
-- Create: `packages/tcm/pages/book-detail/index.wxml`
-- Create: `packages/tcm/pages/book-detail/index.wxss`
-- Create: `packages/tcm/pages/search-books/index.js`
-- Create: `packages/tcm/pages/search-books/index.json`
-- Create: `packages/tcm/pages/search-books/index.wxml`
-- Create: `packages/tcm/pages/search-books/index.wxss`
-- Create: `packages/tcm/pages/section/index.js`
-- Create: `packages/tcm/pages/section/index.json`
-- Create: `packages/tcm/pages/section/index.wxml`
-- Create: `packages/tcm/pages/section/index.wxss`
-- Create: `packages/tcm/pages/placeholder/index.js`
-- Create: `packages/tcm/pages/placeholder/index.json`
-- Create: `packages/tcm/pages/placeholder/index.wxml`
-- Create: `packages/tcm/pages/placeholder/index.wxss`
-- Create: `packages/mingli/pages/hall/index.js`
-- Create: `packages/mingli/pages/hall/index.json`
-- Create: `packages/mingli/pages/hall/index.wxml`
-- Create: `packages/mingli/pages/hall/index.wxss`
-- Create: `packages/mingli/pages/bazi/index.js`
-- Create: `packages/mingli/pages/bazi/index.json`
-- Create: `packages/mingli/pages/bazi/index.wxml`
-- Create: `packages/mingli/pages/bazi/index.wxss`
-- Create: `packages/mingli/pages/book-detail/index.js`
-- Create: `packages/mingli/pages/book-detail/index.json`
-- Create: `packages/mingli/pages/book-detail/index.wxml`
-- Create: `packages/mingli/pages/book-detail/index.wxss`
-- Create: `packages/mingli/pages/search-books/index.js`
-- Create: `packages/mingli/pages/search-books/index.json`
-- Create: `packages/mingli/pages/search-books/index.wxml`
-- Create: `packages/mingli/pages/search-books/index.wxss`
-- Create: `packages/mingli/pages/section/index.js`
-- Create: `packages/mingli/pages/section/index.json`
-- Create: `packages/mingli/pages/section/index.wxml`
-- Create: `packages/mingli/pages/section/index.wxss`
-- Create: `packages/mingli/pages/interpret/index.js`
-- Create: `packages/mingli/pages/interpret/index.json`
-- Create: `packages/mingli/pages/interpret/index.wxml`
-- Create: `packages/mingli/pages/interpret/index.wxss`
-- Create: `packages/learning/pages/center/index.js`
-- Create: `packages/learning/pages/center/index.json`
-- Create: `packages/learning/pages/center/index.wxml`
-- Create: `packages/learning/pages/center/index.wxss`
-- Create: `tests/static-ux-route-map.test.js`
-- Create: `tests/static-ux-domain-data.test.js`
-- Create: `tests/profile-page.test.js`
-- Create: `tests/profile-page-render.test.js`
-- Create: `tests/login-page.test.js`
-- Create: `tests/login-page-render.test.js`
-- Create: `tests/tcm-support-pages.test.js`
-- Create: `tests/tcm-reading-pages.test.js`
-- Create: `tests/mingli-learning-pages.test.js`
-- Modify: `tests/project-config.test.js`
-- Modify: `tests/home-page.test.js`
-- Modify: `tests/home-page-render.test.js`
-- Modify: `tests/library-page.test.js`
-- Modify: `tests/library-page-render.test.js`
-- Modify: `tests/ai-page.test.js`
-- Modify: `tests/ai-page-render.test.js`
-
-## Execution Notes
-
-- 工作区已经存在与本计划无关的改动;每一步只 `git add` 本任务涉及的文件。
-- 页面参数只允许使用 `scene / mode / kind / domain / keyword` 这类静态场景参数,不允许恢复 `bookId / recordId / passageId` 的真实业务语义。
-- 现有页面测试已经约束 `pages/home/index.wxss` 不能使用 `display: grid`、`gap:`、`width: fit-content`,实现时必须继续遵守。
-
-### Task 1: Register Subpackages And Static UX Foundation
-
-**Files:**
-- Modify: `app.json`
-- Modify: `tests/project-config.test.js`
-- Create: `utils/static-ux/route-map.js`
-- Create: `utils/static-ux/shared.js`
-- Create: `utils/static-ux/tcm.js`
-- Create: `utils/static-ux/mingli.js`
-- Create: `utils/static-ux/learning.js`
-- Create: `tests/static-ux-route-map.test.js`
-- Create: `tests/static-ux-domain-data.test.js`
-
-- [ ] **Step 1: Write the failing route and data-factory tests**
-
-```js
-// tests/static-ux-route-map.test.js
-const { ROUTES } = require('../utils/static-ux/route-map')
-
-describe('static route map', () => {
- test('exposes full route paths for all static migration pages', () => {
- expect(ROUTES.tabs.home).toBe('/pages/home/index')
- expect(ROUTES.tcm.aiHistory).toBe('/packages/tcm/pages/ai-history/index')
- expect(ROUTES.tcm.section).toBe('/packages/tcm/pages/section/index')
- expect(ROUTES.mingli.hall).toBe('/packages/mingli/pages/hall/index')
- expect(ROUTES.mingli.interpret).toBe('/packages/mingli/pages/interpret/index')
- expect(ROUTES.learning.center).toBe('/packages/learning/pages/center/index')
- })
-})
-```
-
-```js
-// tests/static-ux-domain-data.test.js
-const {
- createTcmHomeHubCards,
- createTcmAssetPageData
-} = require('../utils/static-ux/tcm')
-const {
- createMingliHallPageData,
- createBaziPageData
-} = require('../utils/static-ux/mingli')
-const { createLearningCenterPageData } = require('../utils/static-ux/learning')
-
-describe('static domain factories', () => {
- test('returns scene-safe static data for tcm, mingli and learning domains', () => {
- expect(createTcmHomeHubCards()).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ key: 'tcm-library', title: '中医馆' }),
- expect.objectContaining({ key: 'mingli-hall', title: '易学阁' })
- ])
- )
- expect(createTcmAssetPageData('notes')).toEqual(
- expect.objectContaining({
- title: '学习资产',
- activeKind: 'notes'
- })
- )
- expect(createMingliHallPageData()).toEqual(
- expect.objectContaining({
- title: '易学阁'
- })
- )
- expect(createBaziPageData('result')).toEqual(
- expect.objectContaining({
- title: '八字排盘',
- scene: 'result'
- })
- )
- expect(createLearningCenterPageData()).toEqual(
- expect.objectContaining({
- title: '学习中心'
- })
- )
- })
-})
-```
-
-```js
-// tests/project-config.test.js
-test('registers static migration subpackages in app config', () => {
- const appConfig = readJson('app.json')
-
- expect(appConfig.subPackages).toEqual(
- expect.arrayContaining([
- expect.objectContaining({
- root: 'packages/tcm',
- pages: expect.arrayContaining([
- 'pages/ai-history/index',
- 'pages/assets/index',
- 'pages/bianzheng/index',
- 'pages/book-detail/index',
- 'pages/search-books/index',
- 'pages/section/index',
- 'pages/placeholder/index'
- ])
- }),
- expect.objectContaining({
- root: 'packages/mingli',
- pages: expect.arrayContaining([
- 'pages/hall/index',
- 'pages/bazi/index',
- 'pages/book-detail/index',
- 'pages/search-books/index',
- 'pages/section/index',
- 'pages/interpret/index'
- ])
- }),
- expect.objectContaining({
- root: 'packages/learning',
- pages: ['pages/center/index']
- })
- ])
- )
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/project-config.test.js tests/static-ux-route-map.test.js tests/static-ux-domain-data.test.js`
-
-Expected: FAIL with `Cannot find module '../utils/static-ux/route-map'` and missing `packages/tcm` / `packages/mingli` / `packages/learning` registration assertions.
-
-- [ ] **Step 3: Write the minimal subpackage and static-ux implementation**
-
-```js
-// utils/static-ux/route-map.js
-const ROUTES = Object.freeze({
- tabs: {
- home: '/pages/home/index',
- library: '/pages/library/index',
- ai: '/pages/ai/index',
- profile: '/pages/profile/index',
- login: '/pages/login/index'
- },
- tcm: {
- aiHistory: '/packages/tcm/pages/ai-history/index',
- assets: '/packages/tcm/pages/assets/index',
- bianzheng: '/packages/tcm/pages/bianzheng/index',
- bookDetail: '/packages/tcm/pages/book-detail/index',
- searchBooks: '/packages/tcm/pages/search-books/index',
- section: '/packages/tcm/pages/section/index',
- placeholder: '/packages/tcm/pages/placeholder/index'
- },
- mingli: {
- hall: '/packages/mingli/pages/hall/index',
- bazi: '/packages/mingli/pages/bazi/index',
- bookDetail: '/packages/mingli/pages/book-detail/index',
- searchBooks: '/packages/mingli/pages/search-books/index',
- section: '/packages/mingli/pages/section/index',
- interpret: '/packages/mingli/pages/interpret/index'
- },
- learning: {
- center: '/packages/learning/pages/center/index'
- }
-})
-
-module.exports = {
- ROUTES
-}
-```
-
-```js
-// utils/static-ux/shared.js
-function cloneItem(item) {
- return { ...item }
-}
-
-function cloneList(items) {
- return items.map(cloneItem)
-}
-
-function resolveScene(rawScene, allowedScenes, fallbackScene) {
- return allowedScenes.includes(rawScene) ? rawScene : fallbackScene
-}
-
-function resolveKind(rawKind, allowedKinds, fallbackKind) {
- return allowedKinds.includes(rawKind) ? rawKind : fallbackKind
-}
-
-module.exports = {
- cloneItem,
- cloneList,
- resolveScene,
- resolveKind
-}
-```
-
-```js
-// utils/static-ux/tcm.js
-const { cloneList, resolveKind } = require('./shared')
-const { ROUTES } = require('./route-map')
-
-const TCM_HOME_HUB_CARDS = Object.freeze([
- { key: 'tcm-library', title: '中医馆', subtitle: '典籍与目录', route: ROUTES.tabs.library, badge: 'TCM' },
- { key: 'mingli-hall', title: '易学阁', subtitle: '命理与经典', route: ROUTES.mingli.hall, badge: 'NEW' },
- { key: 'bazi', title: '八字排盘', subtitle: '静态排盘结果', route: ROUTES.mingli.bazi, badge: 'BETA' },
- { key: 'learning-center', title: '学习中心', subtitle: '继续学习与回顾', route: ROUTES.learning.center, badge: 'GO' }
-])
-
-const TCM_ASSET_SURFACES = Object.freeze({
- notes: { title: '学习资产', activeKind: 'notes', kinds: ['notes', 'bookshelf', 'favorites', 'history'] },
- bookshelf: { title: '学习资产', activeKind: 'bookshelf', kinds: ['notes', 'bookshelf', 'favorites', 'history'] },
- favorites: { title: '学习资产', activeKind: 'favorites', kinds: ['notes', 'bookshelf', 'favorites', 'history'] },
- history: { title: '学习资产', activeKind: 'history', kinds: ['notes', 'bookshelf', 'favorites', 'history'] }
-})
-
-function createTcmHomeHubCards() {
- return cloneList(TCM_HOME_HUB_CARDS)
-}
-
-function createTcmAssetPageData(rawKind) {
- const activeKind = resolveKind(rawKind, ['notes', 'bookshelf', 'favorites', 'history'], 'notes')
- return {
- ...TCM_ASSET_SURFACES[activeKind],
- cards: createTcmHomeHubCards()
- }
-}
-
-module.exports = {
- createTcmHomeHubCards,
- createTcmAssetPageData
-}
-```
-
-```js
-// utils/static-ux/mingli.js
-const { cloneList, resolveScene } = require('./shared')
-const { ROUTES } = require('./route-map')
-
-const MINGLI_QUICK_CARDS = Object.freeze([
- { key: 'hall', title: '易学阁', subtitle: '总览入口', route: ROUTES.mingli.hall, icon: '阁' },
- { key: 'bazi', title: '八字排盘', subtitle: '静态排盘结果', route: ROUTES.mingli.bazi, icon: '盘' },
- { key: 'interpret', title: '命理解读', subtitle: '问题与解读', route: ROUTES.mingli.interpret, icon: '解' }
-])
-
-function createMingliHallPageData() {
- return {
- title: '易学阁',
- quickCards: cloneList(MINGLI_QUICK_CARDS)
- }
-}
-
-function createBaziPageData(rawScene) {
- const scene = resolveScene(rawScene, ['default', 'result'], 'default')
- return {
- title: '八字排盘',
- scene,
- quickCards: cloneList(MINGLI_QUICK_CARDS)
- }
-}
-
-module.exports = {
- createMingliHallPageData,
- createBaziPageData
-}
-```
-
-```js
-// utils/static-ux/learning.js
-function createLearningCenterPageData() {
- return {
- title: '学习中心',
- summaryCards: [
- { key: 'qa', value: 8, label: '问答' },
- { key: 'analysis', value: 5, label: '辨证' },
- { key: 'interpret', value: 6, label: '解读' },
- { key: 'bazi', value: 4, label: '排盘' }
- ]
- }
-}
-
-module.exports = {
- createLearningCenterPageData
-}
-```
-
-```json
-// app.json
-{
- "subPackages": [
- {
- "root": "packages/demo",
- "pages": ["pages/workbench/index"]
- },
- {
- "root": "packages/tcm",
- "pages": [
- "pages/ai-history/index",
- "pages/assets/index",
- "pages/bianzheng/index",
- "pages/book-detail/index",
- "pages/search-books/index",
- "pages/section/index",
- "pages/placeholder/index"
- ]
- },
- {
- "root": "packages/mingli",
- "pages": [
- "pages/hall/index",
- "pages/bazi/index",
- "pages/book-detail/index",
- "pages/search-books/index",
- "pages/section/index",
- "pages/interpret/index"
- ]
- },
- {
- "root": "packages/learning",
- "pages": ["pages/center/index"]
- }
- ]
-}
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/project-config.test.js tests/static-ux-route-map.test.js tests/static-ux-domain-data.test.js`
-
-Expected: PASS, with the new route map and subpackage assertions green.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add app.json utils/static-ux/route-map.js utils/static-ux/shared.js utils/static-ux/tcm.js utils/static-ux/mingli.js utils/static-ux/learning.js tests/project-config.test.js tests/static-ux-route-map.test.js tests/static-ux-domain-data.test.js
-git commit -m "feat: add static page route foundation"
-```
-
-### Task 2: Enhance Home Page As The Global Portal
-
-**Files:**
-- Modify: `app.wxss`
-- Modify: `pages/home/index.js`
-- Modify: `pages/home/index.wxml`
-- Modify: `pages/home/index.wxss`
-- Modify: `tests/home-page.test.js`
-- Modify: `tests/home-page-render.test.js`
-
-- [ ] **Step 1: Write the failing home-page portal tests**
-
-```js
-// tests/home-page.test.js
-test('adds direct portal cards for tcm, mingli, bazi and learning routes', () => {
- let capturedPageConfig
-
- global.Page = config => {
- capturedPageConfig = config
- }
-
- const homePageModule = require('../pages/home/index')
- const pageData = homePageModule.createHomePageData()
-
- expect(pageData.portalTitle).toBe('学习入口')
- expect(pageData.portalCards).toEqual([
- expect.objectContaining({ key: 'tcm-library', title: '中医馆' }),
- expect.objectContaining({ key: 'mingli-hall', title: '易学阁' }),
- expect.objectContaining({ key: 'bazi', title: '八字排盘' }),
- expect.objectContaining({ key: 'learning-center', title: '学习中心' })
- ])
-
- global.wx = {
- navigateTo: jest.fn()
- }
-
- capturedPageConfig.handlePortalTap({
- currentTarget: {
- dataset: {
- route: '/packages/mingli/pages/hall/index'
- }
- }
- })
-
- expect(global.wx.navigateTo).toHaveBeenCalledWith({
- url: '/packages/mingli/pages/hall/index'
- })
-})
-```
-
-```js
-// tests/home-page-render.test.js
-test('renders the portal section without forbidden grid or gap styles', () => {
- const wxml = fs.readFileSync(path.join(process.cwd(), 'pages/home/index.wxml'), 'utf8')
- const wxss = fs.readFileSync(path.join(process.cwd(), 'pages/home/index.wxss'), 'utf8')
-
- expect(wxml).toContain('{{portalTitle}}')
- expect(wxml).toContain('portal-grid')
- expect(wxml).toContain('bindtap="handlePortalTap"')
- expect(wxss).toContain('.portal-grid')
- expect(wxss).toContain('.portal-card')
- expect(wxss).not.toContain('display: grid')
- expect(wxss).not.toContain('gap:')
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/home-page.test.js tests/home-page-render.test.js`
-
-Expected: FAIL because `portalTitle`, `portalCards`, `handlePortalTap`, `.portal-grid`, and `.portal-card` do not exist yet.
-
-- [ ] **Step 3: Write the home portal implementation**
-
-```js
-// pages/home/index.js
-const { createTcmHomeHubCards } = require('../../utils/static-ux/tcm')
-
-function showNavigate(route) {
- if (typeof wx?.navigateTo === 'function') {
- wx.navigateTo({ url: route })
- }
-}
-
-function createHomePageData() {
- return {
- brandName: '玄知中医',
- greeting: '晚上好',
- subtitle: '今天想学点什么?从典籍、工具或养生主题开始。',
- searchPlaceholder: '搜索典籍、术语、AI问答...',
- searchBadge: 'AI',
- portalTitle: '学习入口',
- portalCards: createTcmHomeHubCards(),
- encyclopediaTitle: '中医百科',
- encyclopediaCards: [
- { key: 'classic', icon: '书', title: '经典书城' },
- { key: 'meridian', icon: '穴', title: '经络穴位', status: '待开放' },
- { key: 'disease', icon: '病', title: '疾病百科', status: '待开放' }
- ],
- toolsTitle: '学习工具',
- toolCards: [
- { key: 'qa', icon: '问', title: 'AI问答' },
- { key: 'formula', icon: '方', title: '方剂笔记' },
- { key: 'constitution', icon: '诊', title: '体质诊断' },
- { key: 'wellness', icon: '养', title: '智能饮片' }
- ],
- wellnessTitle: '养生调理',
- wellnessCards: [
- { key: 'constitution-check', icon: '🧬', title: 'AI体质检测', status: '待开放' },
- { key: 'medicated-diet', icon: '🍲', title: '药膳', status: '待开放' },
- { key: 'ingredient', icon: '🥬', title: '食材', status: '待开放' }
- ],
- classicsTitle: '热门典籍',
- classicsActionText: '进入书城',
- classicsBooks: [
- { key: 'huangdi-neijing-suwen', coverText: '黄', title: '黄帝内经素问' },
- { key: 'shang-han-lun', coverText: '伤', title: '伤寒论' },
- { key: 'wen-bing-tiao-bian', coverText: '温', title: '温病条辨' },
- { key: 'bencao-gangmu-bieming-lu', coverText: '本', title: '本草纲目别名录' }
- ]
- }
-}
-
-Page({
- data: createHomePageData(),
-
- handlePortalTap(event) {
- showNavigate(event.currentTarget.dataset.route)
- }
-})
-
-module.exports = {
- createHomePageData
-}
-```
-
-```xml
-
-
- {{portalTitle}}
-
-
- {{item.badge}}
- {{item.title}}
- {{item.subtitle}}
-
-
-
-```
-
-```css
-/* pages/home/index.wxss */
-.portal-grid {
- margin-top: 16rpx;
- overflow: hidden;
-}
-
-.portal-card {
- float: left;
- width: 48%;
- min-height: 156rpx;
- margin-right: 4%;
- margin-bottom: 16rpx;
- padding: 18rpx;
- border-radius: 24rpx;
- background: linear-gradient(180deg, rgba(255, 252, 246, 0.98), rgba(245, 236, 221, 0.92));
- border: 1rpx solid rgba(118, 83, 42, 0.08);
-}
-
-.portal-card:nth-child(2n) {
- margin-right: 0;
-}
-
-.portal-card__badge {
- display: inline-block;
- padding: 6rpx 14rpx;
- border-radius: 999rpx;
- background: rgba(111, 66, 22, 0.08);
- color: #8f5c1f;
- font-size: 18rpx;
-}
-
-.portal-card__title {
- display: block;
- margin-top: 16rpx;
- font-size: 30rpx;
- font-weight: 700;
- color: #2c2419;
-}
-
-.portal-card__subtitle {
- display: block;
- margin-top: 8rpx;
- font-size: 22rpx;
- line-height: 1.6;
- color: #7b6b57;
-}
-```
-
-```css
-/* app.wxss */
-.xz-page--warm {
- min-height: 100vh;
- background: linear-gradient(180deg, #f8edd6 0%, #f9f0de 24%, #f6ead4 100%);
-}
-
-.xz-page--mingli {
- min-height: 100vh;
- background: linear-gradient(180deg, #fbf6f3 0%, #f4ebe6 100%);
-}
-
-.xz-card {
- border-radius: 28rpx;
- border: 1rpx solid rgba(84, 58, 29, 0.08);
- box-shadow: 0 16rpx 36rpx rgba(84, 58, 29, 0.06);
-}
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/home-page.test.js tests/home-page-render.test.js`
-
-Expected: PASS, with `portalTitle`, `portalCards`, and `handlePortalTap` verified.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add app.wxss pages/home/index.js pages/home/index.wxml pages/home/index.wxss tests/home-page.test.js tests/home-page-render.test.js
-git commit -m "feat: add global portal section to home page"
-```
-
-### Task 3: Bridge Library And AI Tabs To New Static Domains
-
-**Files:**
-- Modify: `pages/library/index.js`
-- Modify: `pages/library/index.wxml`
-- Modify: `pages/library/index.wxss`
-- Modify: `pages/ai/index.js`
-- Modify: `pages/ai/index.wxml`
-- Modify: `pages/ai/index.wxss`
-- Modify: `tests/library-page.test.js`
-- Modify: `tests/library-page-render.test.js`
-- Modify: `tests/ai-page.test.js`
-- Modify: `tests/ai-page-render.test.js`
-
-- [ ] **Step 1: Write the failing bridge-entry tests**
-
-```js
-// tests/library-page.test.js
-test('adds a visible mingli-hall bridge entry to the library tab', () => {
- let capturedPageConfig
-
- global.Page = config => {
- capturedPageConfig = config
- }
-
- global.wx = {
- navigateTo: jest.fn(),
- showToast: jest.fn()
- }
-
- const libraryPageModule = require('../pages/library/index')
- const pageData = libraryPageModule.createLibraryPageData()
-
- expect(pageData.domainBridge).toEqual(
- expect.objectContaining({
- title: '进入易学阁',
- route: '/packages/mingli/pages/hall/index'
- })
- )
-
- capturedPageConfig.handleDomainBridgeTap()
-
- expect(global.wx.navigateTo).toHaveBeenCalledWith({
- url: '/packages/mingli/pages/hall/index'
- })
-})
-```
-
-```js
-// tests/ai-page.test.js
-test('adds a visible interpret entry and routes history to the tcm history page', () => {
- let capturedPageConfig
-
- global.Page = config => {
- capturedPageConfig = config
- }
-
- global.wx = {
- navigateTo: jest.fn(),
- showToast: jest.fn()
- }
-
- const aiPageModule = require('../pages/ai/index')
- const pageData = aiPageModule.createAiPageData()
-
- expect(pageData.secondaryEntries).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ key: 'ai-history', title: 'AI历史' }),
- expect.objectContaining({ key: 'mingli-interpret', title: '命理解读' })
- ])
- )
-
- capturedPageConfig.handleHistoryTap()
- capturedPageConfig.handleSecondaryEntryTap({
- currentTarget: {
- dataset: {
- route: '/packages/mingli/pages/interpret/index'
- }
- }
- })
-
- expect(global.wx.navigateTo).toHaveBeenNthCalledWith(1, {
- url: '/packages/tcm/pages/ai-history/index'
- })
- expect(global.wx.navigateTo).toHaveBeenNthCalledWith(2, {
- url: '/packages/mingli/pages/interpret/index'
- })
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/library-page.test.js tests/library-page-render.test.js tests/ai-page.test.js tests/ai-page-render.test.js`
-
-Expected: FAIL because `domainBridge`, `handleDomainBridgeTap`, `secondaryEntries`, and new navigation handlers are not implemented.
-
-- [ ] **Step 3: Write the bridge-entry implementation**
-
-```js
-// pages/library/index.js
-const { ROUTES } = require('../../utils/static-ux/route-map')
-// 继续复用当前文件里已经存在的 LIBRARY_CATEGORIES / getBooksByCategory / getCategoryById
-
-function createLibraryPageData(categoryId) {
- const activeCategory = getCategoryById(categoryId)
-
- return {
- title: '典籍',
- searchButtonText: '搜索',
- domainBridge: {
- title: '进入易学阁',
- subtitle: '查看命理经典与八字相关静态页面',
- route: ROUTES.mingli.hall
- },
- categories: LIBRARY_CATEGORIES.map(item => ({ ...item })),
- activeCategoryId: activeCategory.id,
- currentCategoryName: activeCategory.name,
- visibleBooks: getBooksByCategory(activeCategory.id)
- }
-}
-
-Page({
- data: createLibraryPageData(),
-
- handleDomainBridgeTap() {
- wx.navigateTo({
- url: ROUTES.mingli.hall
- })
- }
-})
-```
-
-```xml
-
-
- {{domainBridge.title}}
- {{domainBridge.subtitle}}
-
-```
-
-```css
-/* pages/library/index.wxss */
-.library-page__bridge {
- margin-bottom: 18rpx;
- padding: 20rpx 24rpx;
- border-radius: 24rpx;
- background: rgba(255, 250, 242, 0.94);
- border: 1rpx solid rgba(118, 83, 42, 0.08);
-}
-```
-
-```js
-// pages/ai/index.js
-const { ROUTES } = require('../../utils/static-ux/route-map')
-// 继续复用当前文件里已经存在的 AI_PAGE_BLUEPRINT / createPanelByKey
-
-function createAiPageData() {
- return {
- title: 'AI助手',
- historyText: '历史',
- disclaimerText: AI_PAGE_BLUEPRINT.disclaimerText,
- secondaryEntries: [
- { key: 'ai-history', title: 'AI历史', route: ROUTES.tcm.aiHistory },
- { key: 'mingli-interpret', title: '命理解读', route: ROUTES.mingli.interpret }
- ],
- activeTabKey: 'qa',
- tabs: AI_PAGE_BLUEPRINT.tabs.map(item => ({ ...item })),
- currentPanel: createPanelByKey('qa')
- }
-}
-
-Page({
- data: createAiPageData(),
-
- handleHistoryTap() {
- wx.navigateTo({
- url: ROUTES.tcm.aiHistory
- })
- },
-
- handleSecondaryEntryTap(event) {
- wx.navigateTo({
- url: event.currentTarget.dataset.route
- })
- }
-})
-```
-
-```xml
-
-
-
- {{item.title}}
-
-
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/library-page.test.js tests/library-page-render.test.js tests/ai-page.test.js tests/ai-page-render.test.js`
-
-Expected: PASS, with the new bridge entries and `wx.navigateTo` calls green.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add pages/library/index.js pages/library/index.wxml pages/library/index.wxss pages/ai/index.js pages/ai/index.wxml pages/ai/index.wxss tests/library-page.test.js tests/library-page-render.test.js tests/ai-page.test.js tests/ai-page-render.test.js
-git commit -m "feat: connect library and ai tabs to static domain pages"
-```
-
-### Task 4: Replace Profile And Login Placeholders With Static UX Pages
-
-**Files:**
-- Modify: `pages/profile/index.js`
-- Modify: `pages/profile/index.wxml`
-- Modify: `pages/profile/index.wxss`
-- Modify: `pages/login/index.js`
-- Modify: `pages/login/index.wxml`
-- Modify: `pages/login/index.wxss`
-- Create: `tests/profile-page.test.js`
-- Create: `tests/profile-page-render.test.js`
-- Create: `tests/login-page.test.js`
-- Create: `tests/login-page-render.test.js`
-
-- [ ] **Step 1: Write the failing profile and login tests**
-
-```js
-// tests/profile-page.test.js
-describe('profile page', () => {
- afterEach(() => {
- delete global.Page
- delete global.wx
- jest.resetModules()
- })
-
- test('exposes static profile sections and navigable shortcuts', () => {
- let capturedPageConfig
-
- global.Page = config => {
- capturedPageConfig = config
- }
-
- global.wx = {
- navigateTo: jest.fn()
- }
-
- const profilePageModule = require('../pages/profile/index')
- const pageData = profilePageModule.createProfilePageData()
-
- expect(pageData.userCard.title).toBe('点击登录')
- expect(pageData.assetItems).toHaveLength(4)
- expect(pageData.moreItems).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ key: 'learning-center', title: '学习中心' }),
- expect.objectContaining({ key: 'ai-history', title: 'AI历史' })
- ])
- )
-
- capturedPageConfig.handleMoreTap({
- currentTarget: {
- dataset: {
- route: '/packages/learning/pages/center/index'
- }
- }
- })
-
- expect(global.wx.navigateTo).toHaveBeenCalledWith({
- url: '/packages/learning/pages/center/index'
- })
- })
-})
-```
-
-```js
-// tests/login-page.test.js
-const fs = require('fs')
-const path = require('path')
-
-describe('login page', () => {
- afterEach(() => {
- delete global.Page
- jest.resetModules()
- })
-
- test('renders a static login surface without session-store wiring', () => {
- let capturedPageConfig
-
- global.Page = config => {
- capturedPageConfig = config
- }
-
- const loginPageModule = require('../pages/login/index')
- const pageData = loginPageModule.createLoginPageData()
- const source = fs.readFileSync(path.join(process.cwd(), 'pages/login/index.js'), 'utf8')
-
- expect(pageData.title).toBe('欢迎来到玄志')
- expect(pageData.actions).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ key: 'wechat', title: '微信授权登录' }),
- expect.objectContaining({ key: 'browse', title: '先看看静态页面' })
- ])
- )
- expect(source).not.toContain('sessionStore')
- expect(source).not.toContain('handleMockLogin')
- })
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/profile-page.test.js tests/profile-page-render.test.js tests/login-page.test.js tests/login-page-render.test.js`
-
-Expected: FAIL because `pages/profile/index.js` does not export `createProfilePageData`, `pages/login/index.js` still depends on session logic, and the new render assertions are missing.
-
-- [ ] **Step 3: Write the static profile and login implementation**
-
-```js
-// pages/profile/index.js
-const { ROUTES } = require('../../utils/static-ux/route-map')
-
-function createProfilePageData() {
- return {
- userCard: {
- avatarText: '?',
- title: '点击登录',
- subtitle: '登录后查看你的学习资产'
- },
- assetItems: [
- { key: 'notes', title: '我的笔记', count: 0, route: `${ROUTES.tcm.assets}?kind=notes` },
- { key: 'bookshelf', title: '我的书架', count: 0, route: `${ROUTES.tcm.assets}?kind=bookshelf` },
- { key: 'favorites', title: '我的收藏', count: 0, route: `${ROUTES.tcm.assets}?kind=favorites` },
- { key: 'history', title: '浏览历史', count: 0, route: `${ROUTES.tcm.assets}?kind=history` }
- ],
- moreItems: [
- { key: 'learning-center', title: '学习中心', route: ROUTES.learning.center },
- { key: 'ai-history', title: 'AI历史', route: ROUTES.tcm.aiHistory },
- { key: 'placeholder-about', title: '关于我们', route: `${ROUTES.tcm.placeholder}?kind=about` },
- { key: 'placeholder-settings', title: '设置', route: `${ROUTES.tcm.placeholder}?kind=settings` }
- ]
- }
-}
-
-Page({
- data: createProfilePageData(),
-
- handleAssetTap(event) {
- wx.navigateTo({ url: event.currentTarget.dataset.route })
- },
-
- handleMoreTap(event) {
- wx.navigateTo({ url: event.currentTarget.dataset.route })
- }
-})
-
-module.exports = {
- createProfilePageData
-}
-```
-
-```js
-// pages/login/index.js
-const { ROUTES } = require('../../utils/static-ux/route-map')
-
-function createLoginPageData() {
- return {
- title: '欢迎来到玄志',
- subtitle: '当前阶段先提供静态登录页,后续再接入新的认证方案。',
- actions: [
- { key: 'wechat', title: '微信授权登录', type: 'toast' },
- { key: 'browse', title: '先看看静态页面', type: 'route', route: ROUTES.tabs.home }
- ]
- }
-}
-
-function showComingSoon() {
- if (typeof wx?.showToast === 'function') {
- wx.showToast({
- title: '登录功能建设中',
- icon: 'none'
- })
- }
-}
-
-Page({
- data: createLoginPageData(),
-
- handleActionTap(event) {
- const { actionType, route } = event.currentTarget.dataset
-
- if (actionType === 'route') {
- wx.switchTab({ url: route })
- return
- }
-
- showComingSoon()
- }
-})
-
-module.exports = {
- createLoginPageData
-}
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/profile-page.test.js tests/profile-page-render.test.js tests/login-page.test.js tests/login-page-render.test.js`
-
-Expected: PASS, with `profile` shortcut routes and `login` static action data confirmed.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add pages/profile/index.js pages/profile/index.wxml pages/profile/index.wxss pages/login/index.js pages/login/index.wxml pages/login/index.wxss tests/profile-page.test.js tests/profile-page-render.test.js tests/login-page.test.js tests/login-page-render.test.js
-git commit -m "feat: add static profile and login pages"
-```
-
-### Task 5: Build TCM Support Pages
-
-**Files:**
-- Create: `packages/tcm/pages/ai-history/index.js`
-- Create: `packages/tcm/pages/ai-history/index.json`
-- Create: `packages/tcm/pages/ai-history/index.wxml`
-- Create: `packages/tcm/pages/ai-history/index.wxss`
-- Create: `packages/tcm/pages/assets/index.js`
-- Create: `packages/tcm/pages/assets/index.json`
-- Create: `packages/tcm/pages/assets/index.wxml`
-- Create: `packages/tcm/pages/assets/index.wxss`
-- Create: `packages/tcm/pages/bianzheng/index.js`
-- Create: `packages/tcm/pages/bianzheng/index.json`
-- Create: `packages/tcm/pages/bianzheng/index.wxml`
-- Create: `packages/tcm/pages/bianzheng/index.wxss`
-- Create: `packages/tcm/pages/placeholder/index.js`
-- Create: `packages/tcm/pages/placeholder/index.json`
-- Create: `packages/tcm/pages/placeholder/index.wxml`
-- Create: `packages/tcm/pages/placeholder/index.wxss`
-- Create: `tests/tcm-support-pages.test.js`
-
-- [ ] **Step 1: Write the failing TCM support-page tests**
-
-```js
-// tests/tcm-support-pages.test.js
-describe('tcm support pages', () => {
- afterEach(() => {
- delete global.Page
- delete global.wx
- jest.resetModules()
- })
-
- test('assets page switches by static kind and keeps route-only navigation', () => {
- let capturedPageConfig
-
- global.Page = config => {
- capturedPageConfig = config
- }
-
- const assetsPageModule = require('../packages/tcm/pages/assets/index')
- const pageData = assetsPageModule.createTcmAssetsPageData('favorites')
-
- expect(pageData.activeKind).toBe('favorites')
- expect(pageData.title).toBe('学习资产')
- expect(pageData.filterItems).toHaveLength(4)
- })
-
- test('ai history, bianzheng and placeholder pages expose scene-driven static data', () => {
- global.Page = () => {}
-
- const aiHistoryModule = require('../packages/tcm/pages/ai-history/index')
- const bianzhengModule = require('../packages/tcm/pages/bianzheng/index')
- const placeholderModule = require('../packages/tcm/pages/placeholder/index')
-
- expect(aiHistoryModule.createTcmAiHistoryPageData('empty')).toEqual(
- expect.objectContaining({ scene: 'empty', title: 'AI对话历史' })
- )
- expect(bianzhengModule.createTcmBianzhengPageData('result')).toEqual(
- expect.objectContaining({ scene: 'result', title: '辨证分析' })
- )
- expect(placeholderModule.createTcmPlaceholderPageData('membership')).toEqual(
- expect.objectContaining({ kind: 'membership' })
- )
- })
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/tcm-support-pages.test.js`
-
-Expected: FAIL because the `packages/tcm/pages/*` modules and `create*PageData` exports do not exist yet.
-
-- [ ] **Step 3: Write the TCM support pages**
-
-```js
-// packages/tcm/pages/assets/index.js
-const { createTcmAssetPageData } = require('../../../../utils/static-ux/tcm')
-const { resolveKind } = require('../../../../utils/static-ux/shared')
-
-function createTcmAssetsPageData(rawKind) {
- const data = createTcmAssetPageData(rawKind)
-
- return {
- ...data,
- filterItems: data.kinds.map(kind => ({
- key: kind,
- label: kind === 'notes' ? '笔记' : kind === 'bookshelf' ? '书架' : kind === 'favorites' ? '收藏' : '历史',
- route: `/packages/tcm/pages/assets/index?kind=${kind}`
- }))
- }
-}
-
-Page({
- data: createTcmAssetsPageData('notes'),
-
- onLoad(options) {
- this.setData(createTcmAssetsPageData(resolveKind(options.kind, ['notes', 'bookshelf', 'favorites', 'history'], 'notes')))
- }
-})
-
-module.exports = {
- createTcmAssetsPageData
-}
-```
-
-```js
-// packages/tcm/pages/ai-history/index.js
-const { resolveScene } = require('../../../../utils/static-ux/shared')
-
-function createTcmAiHistoryPageData(rawScene) {
- const scene = resolveScene(rawScene, ['default', 'empty'], 'default')
-
- return {
- title: 'AI对话历史',
- scene,
- groups:
- scene === 'empty'
- ? []
- : [
- { key: 'today', label: '今天', items: [{ key: 'qa-1', title: '什么是阴阳?', summary: '从阴阳对待看基础结构。' }] }
- ]
- }
-}
-
-Page({
- data: createTcmAiHistoryPageData('default'),
-
- onLoad(options) {
- this.setData(createTcmAiHistoryPageData(options.scene))
- }
-})
-
-module.exports = {
- createTcmAiHistoryPageData
-}
-```
-
-```js
-// packages/tcm/pages/bianzheng/index.js
-const { resolveScene } = require('../../../../utils/static-ux/shared')
-
-function createTcmBianzhengPageData(rawScene) {
- const scene = resolveScene(rawScene, ['default', 'result'], 'default')
-
- return {
- title: '辨证分析',
- scene,
- form: {
- mainSymptoms: '',
- tongue: '',
- pulse: '',
- constitution: '',
- duration: ''
- },
- result:
- scene === 'result'
- ? {
- title: '学习型辨证结果',
- summary: '以脾虚湿困作为静态展示结果,后续接真实逻辑时再替换。'
- }
- : null
- }
-}
-
-Page({
- data: createTcmBianzhengPageData('default'),
-
- onLoad(options) {
- this.setData(createTcmBianzhengPageData(options.scene))
- },
-
- handleSubmitTap() {
- this.setData(createTcmBianzhengPageData('result'))
- }
-})
-
-module.exports = {
- createTcmBianzhengPageData
-}
-```
-
-```js
-// packages/tcm/pages/placeholder/index.js
-function createTcmPlaceholderPageData(kind) {
- const activeKind = ['membership', 'feedback', 'share', 'about', 'settings'].includes(kind)
- ? kind
- : 'about'
-
- return {
- title: activeKind === 'membership' ? '开通会员' : activeKind === 'feedback' ? '意见反馈' : activeKind === 'share' ? '分享 APP' : activeKind === 'settings' ? '设置' : '关于我们',
- kind: activeKind,
- tips: [
- '本页当前只承接静态展示。',
- '后续接入真实逻辑时保持当前页面信息层级。',
- '不要把旧项目流程直接迁移过来。'
- ]
- }
-}
-
-Page({
- data: createTcmPlaceholderPageData('about'),
-
- onLoad(options) {
- this.setData(createTcmPlaceholderPageData(options.kind))
- }
-})
-
-module.exports = {
- createTcmPlaceholderPageData
-}
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/tcm-support-pages.test.js`
-
-Expected: PASS, with `scene` / `kind`-driven static data verified and no service layer required.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add packages/tcm/pages/ai-history packages/tcm/pages/assets packages/tcm/pages/bianzheng packages/tcm/pages/placeholder tests/tcm-support-pages.test.js
-git commit -m "feat: add tcm support pages"
-```
-
-### Task 6: Build TCM Reading, Search And Detail Pages
-
-**Files:**
-- Create: `packages/tcm/pages/book-detail/index.js`
-- Create: `packages/tcm/pages/book-detail/index.json`
-- Create: `packages/tcm/pages/book-detail/index.wxml`
-- Create: `packages/tcm/pages/book-detail/index.wxss`
-- Create: `packages/tcm/pages/search-books/index.js`
-- Create: `packages/tcm/pages/search-books/index.json`
-- Create: `packages/tcm/pages/search-books/index.wxml`
-- Create: `packages/tcm/pages/search-books/index.wxss`
-- Create: `packages/tcm/pages/section/index.js`
-- Create: `packages/tcm/pages/section/index.json`
-- Create: `packages/tcm/pages/section/index.wxml`
-- Create: `packages/tcm/pages/section/index.wxss`
-- Create: `tests/tcm-reading-pages.test.js`
-
-- [ ] **Step 1: Write the failing TCM reading-page tests**
-
-```js
-// tests/tcm-reading-pages.test.js
-describe('tcm reading pages', () => {
- afterEach(() => {
- delete global.Page
- delete global.wx
- jest.resetModules()
- })
-
- test('book detail, search and section pages use static scenes instead of business ids', () => {
- global.Page = () => {}
-
- const bookDetailModule = require('../packages/tcm/pages/book-detail/index')
- const searchModule = require('../packages/tcm/pages/search-books/index')
- const sectionModule = require('../packages/tcm/pages/section/index')
-
- expect(bookDetailModule.createTcmBookDetailPageData('classic-a')).toEqual(
- expect.objectContaining({ scene: 'classic-a', title: '典籍详情' })
- )
- expect(searchModule.createTcmSearchBooksPageData('keyword-demo')).toEqual(
- expect.objectContaining({ keyword: 'keyword-demo', title: '搜索典籍' })
- )
- expect(sectionModule.createTcmSectionPageData('reader-a')).toEqual(
- expect.objectContaining({ scene: 'reader-a', title: '典籍阅读' })
- )
- })
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/tcm-reading-pages.test.js`
-
-Expected: FAIL because the three reading-page modules do not exist yet.
-
-- [ ] **Step 3: Write the TCM reading-page implementation**
-
-```js
-// packages/tcm/pages/book-detail/index.js
-const { resolveScene } = require('../../../../utils/static-ux/shared')
-
-function createTcmBookDetailPageData(rawScene) {
- const scene = resolveScene(rawScene, ['classic-a', 'classic-b'], 'classic-a')
-
- return {
- title: '典籍详情',
- scene,
- book: {
- title: scene === 'classic-a' ? '黄帝内经素问' : '伤寒论',
- subtitle: '传世中医典籍 · 学习阅读入口'
- },
- catalog: [
- { key: 'chapter-1', title: '上古天真论', children: ['节录一', '节录二'] },
- { key: 'chapter-2', title: '四气调神大论', children: ['节录一', '节录二'] }
- ]
- }
-}
-
-Page({
- data: createTcmBookDetailPageData('classic-a'),
-
- onLoad(options) {
- this.setData(createTcmBookDetailPageData(options.scene))
- }
-})
-
-module.exports = {
- createTcmBookDetailPageData
-}
-```
-
-```js
-// packages/tcm/pages/search-books/index.js
-function createTcmSearchBooksPageData(keyword) {
- return {
- title: '搜索典籍',
- keyword: keyword || '',
- history: ['黄帝内经', '伤寒论', '温病条辨'],
- results:
- keyword && keyword.trim()
- ? [
- { key: 'result-1', title: '黄帝内经素问', subtitle: '书名命中' },
- { key: 'result-2', title: '黄帝内经灵枢', subtitle: '相关结果' }
- ]
- : []
- }
-}
-
-Page({
- data: createTcmSearchBooksPageData(''),
-
- onLoad(options) {
- this.setData(createTcmSearchBooksPageData(options.keyword || options.q))
- }
-})
-
-module.exports = {
- createTcmSearchBooksPageData
-}
-```
-
-```js
-// packages/tcm/pages/section/index.js
-const { resolveScene } = require('../../../../utils/static-ux/shared')
-
-function createTcmSectionPageData(rawScene) {
- const scene = resolveScene(rawScene, ['reader-a', 'reader-b'], 'reader-a')
-
- return {
- title: '典籍阅读',
- scene,
- toolbarVisible: false,
- settings: {
- fontScale: 1,
- lineMode: 'normal',
- bgMode: 'default'
- },
- passages:
- scene === 'reader-a'
- ? ['上古之人,其知道者,法于阴阳,和于术数。', '食饮有节,起居有常,不妄作劳。']
- : ['伤寒者,太阳病也。', '太阳之为病,脉浮,头项强痛而恶寒。']
- }
-}
-
-Page({
- data: createTcmSectionPageData('reader-a'),
-
- onLoad(options) {
- this.setData(createTcmSectionPageData(options.scene))
- },
-
- handleToolbarToggle() {
- this.setData({
- toolbarVisible: !this.data.toolbarVisible
- })
- }
-})
-
-module.exports = {
- createTcmSectionPageData
-}
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/tcm-reading-pages.test.js`
-
-Expected: PASS, with `scene`-based page data and reader toggles confirmed.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add packages/tcm/pages/book-detail packages/tcm/pages/search-books packages/tcm/pages/section tests/tcm-reading-pages.test.js
-git commit -m "feat: add tcm reading and search pages"
-```
-
-### Task 7: Build Mingli Domain And Learning Center Pages
-
-**Files:**
-- Create: `packages/mingli/pages/hall/index.js`
-- Create: `packages/mingli/pages/hall/index.json`
-- Create: `packages/mingli/pages/hall/index.wxml`
-- Create: `packages/mingli/pages/hall/index.wxss`
-- Create: `packages/mingli/pages/bazi/index.js`
-- Create: `packages/mingli/pages/bazi/index.json`
-- Create: `packages/mingli/pages/bazi/index.wxml`
-- Create: `packages/mingli/pages/bazi/index.wxss`
-- Create: `packages/mingli/pages/book-detail/index.js`
-- Create: `packages/mingli/pages/book-detail/index.json`
-- Create: `packages/mingli/pages/book-detail/index.wxml`
-- Create: `packages/mingli/pages/book-detail/index.wxss`
-- Create: `packages/mingli/pages/search-books/index.js`
-- Create: `packages/mingli/pages/search-books/index.json`
-- Create: `packages/mingli/pages/search-books/index.wxml`
-- Create: `packages/mingli/pages/search-books/index.wxss`
-- Create: `packages/mingli/pages/section/index.js`
-- Create: `packages/mingli/pages/section/index.json`
-- Create: `packages/mingli/pages/section/index.wxml`
-- Create: `packages/mingli/pages/section/index.wxss`
-- Create: `packages/mingli/pages/interpret/index.js`
-- Create: `packages/mingli/pages/interpret/index.json`
-- Create: `packages/mingli/pages/interpret/index.wxml`
-- Create: `packages/mingli/pages/interpret/index.wxss`
-- Create: `packages/learning/pages/center/index.js`
-- Create: `packages/learning/pages/center/index.json`
-- Create: `packages/learning/pages/center/index.wxml`
-- Create: `packages/learning/pages/center/index.wxss`
-- Create: `tests/mingli-learning-pages.test.js`
-
-- [ ] **Step 1: Write the failing mingli and learning tests**
-
-```js
-// tests/mingli-learning-pages.test.js
-describe('mingli and learning pages', () => {
- afterEach(() => {
- delete global.Page
- delete global.wx
- jest.resetModules()
- })
-
- test('hall, bazi, interpret and learning center pages expose static route-first surfaces', () => {
- global.Page = () => {}
-
- const hallModule = require('../packages/mingli/pages/hall/index')
- const baziModule = require('../packages/mingli/pages/bazi/index')
- const interpretModule = require('../packages/mingli/pages/interpret/index')
- const learningModule = require('../packages/learning/pages/center/index')
-
- expect(hallModule.createMingliHallPageData()).toEqual(
- expect.objectContaining({ title: '易学阁' })
- )
- expect(baziModule.createMingliBaziPageData('result')).toEqual(
- expect.objectContaining({ scene: 'result', title: '八字排盘' })
- )
- expect(interpretModule.createMingliInterpretPageData('result')).toEqual(
- expect.objectContaining({ scene: 'result', title: '命理解读' })
- )
- expect(learningModule.createLearningCenterPageData()).toEqual(
- expect.objectContaining({ title: '学习中心' })
- )
- })
-})
-```
-
-- [ ] **Step 2: Run the targeted tests to verify they fail**
-
-Run: `npm test -- tests/mingli-learning-pages.test.js`
-
-Expected: FAIL because the mingli and learning page modules do not exist yet.
-
-- [ ] **Step 3: Write the mingli and learning implementation**
-
-```js
-// packages/mingli/pages/hall/index.js
-const { createMingliHallPageData } = require('../../../../utils/static-ux/mingli')
-
-Page({
- data: createMingliHallPageData()
-})
-
-module.exports = {
- createMingliHallPageData
-}
-```
-
-```js
-// packages/mingli/pages/bazi/index.js
-const { resolveScene } = require('../../../../utils/static-ux/shared')
-
-function createMingliBaziPageData(rawScene) {
- const scene = resolveScene(rawScene, ['default', 'result'], 'default')
-
- return {
- title: '八字排盘',
- scene,
- form: {
- name: '张三',
- gender: '男',
- birthDate: '1990-01-01',
- birthTime: '08:30'
- },
- result:
- scene === 'result'
- ? {
- pillars: [
- { key: 'year', label: '年柱', value: '庚午' },
- { key: 'month', label: '月柱', value: '戊寅' },
- { key: 'day', label: '日柱', value: '甲辰' },
- { key: 'time', label: '时柱', value: '丁卯' }
- ]
- }
- : null
- }
-}
-
-Page({
- data: createMingliBaziPageData('default'),
-
- onLoad(options) {
- this.setData(createMingliBaziPageData(options.scene))
- },
-
- handleSubmitTap() {
- this.setData(createMingliBaziPageData('result'))
- }
-})
-
-module.exports = {
- createMingliBaziPageData
-}
-```
-
-```js
-// packages/mingli/pages/interpret/index.js
-const { resolveScene } = require('../../../../utils/static-ux/shared')
-
-function createMingliInterpretPageData(rawScene) {
- const scene = resolveScene(rawScene, ['default', 'result'], 'default')
-
- return {
- title: '命理解读',
- scene,
- question: '',
- result:
- scene === 'result'
- ? {
- title: '学习型解读',
- summary: '围绕日主与经典段落给出静态说明。'
- }
- : null
- }
-}
-
-Page({
- data: createMingliInterpretPageData('default'),
-
- onLoad(options) {
- this.setData(createMingliInterpretPageData(options.scene))
- },
-
- handleSubmitTap() {
- this.setData(createMingliInterpretPageData('result'))
- }
-})
-
-module.exports = {
- createMingliInterpretPageData
-}
-```
-
-```js
-// packages/learning/pages/center/index.js
-const { createLearningCenterPageData } = require('../../../../utils/static-ux/learning')
-
-Page({
- data: createLearningCenterPageData()
-})
-
-module.exports = {
- createLearningCenterPageData
-}
-```
-
-- [ ] **Step 4: Run the targeted tests to verify they pass**
-
-Run: `npm test -- tests/mingli-learning-pages.test.js`
-
-Expected: PASS, with the mingli and learning pages exposed as static route-first surfaces.
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add packages/mingli packages/learning tests/mingli-learning-pages.test.js
-git commit -m "feat: add mingli and learning static pages"
-```
-
-### Task 8: Full Verification And Integration Sweep
-
-**Files:**
-- Modify: any files required to fix failing tests or lint issues from prior tasks
-- Test: all touched files under `pages/`, `packages/`, `utils/static-ux/`, `tests/`, `app.json`, `app.wxss`
-
-- [ ] **Step 1: Run the focused render and data suites**
-
-Run: `npm test -- tests/home-page.test.js tests/home-page-render.test.js tests/library-page.test.js tests/library-page-render.test.js tests/ai-page.test.js tests/ai-page-render.test.js tests/profile-page.test.js tests/profile-page-render.test.js tests/login-page.test.js tests/login-page-render.test.js tests/tcm-support-pages.test.js tests/tcm-reading-pages.test.js tests/mingli-learning-pages.test.js tests/static-ux-route-map.test.js tests/static-ux-domain-data.test.js tests/project-config.test.js`
-
-Expected: PASS with all migration-related tests green.
-
-- [ ] **Step 2: Run the full repository test suite**
-
-Run: `npm test`
-
-Expected: PASS with zero failing Jest suites.
-
-- [ ] **Step 3: Run the repository linter**
-
-Run: `npm run lint`
-
-Expected: exit code `0` and no lint errors.
-
-- [ ] **Step 4: Perform the route and manual UX checklist**
-
-```text
-1. 打开首页,确认能看到并点击进入:中医馆、易学阁、八字排盘、学习中心。
-2. 打开典籍 tab,确认能进入中医搜索页和易学阁入口。
-3. 打开 AI tab,确认历史按钮进入中医 AI 历史页,命理解读入口可达。
-4. 打开我的 tab,确认资产、AI 历史、学习中心、占位说明页都可达。
-5. 打开 tcm 和 mingli 页,确认没有真实登录、接口、store、mock session 逻辑。
-6. 检查所有页面参数都只使用 scene / mode / kind / keyword 这类静态参数。
-```
-
-- [ ] **Step 5: Create the final feature commit**
-
-```bash
-git add app.json app.wxss pages/home pages/library pages/ai pages/profile pages/login packages/tcm packages/mingli packages/learning utils/static-ux tests/static-ux-route-map.test.js tests/static-ux-domain-data.test.js tests/home-page.test.js tests/home-page-render.test.js tests/library-page.test.js tests/library-page-render.test.js tests/ai-page.test.js tests/ai-page-render.test.js tests/profile-page.test.js tests/profile-page-render.test.js tests/login-page.test.js tests/login-page-render.test.js tests/tcm-support-pages.test.js tests/tcm-reading-pages.test.js tests/mingli-learning-pages.test.js tests/project-config.test.js
-git commit -m "feat: migrate frontend static pages into miniprogram"
-```
diff --git a/AGENTS.md b/AGENTS.md
index 71d2dfd..31964a9 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -107,9 +107,7 @@ flowchart LR
| 路径 | 用途 | 说明 |
|:---|:---|:---|
-| `.ai-specs/coding-specs/2026-04-22-profile-page-static-design.md` | `pages/profile/index` 未登录态静态页面设计 | 涉及本页结构复刻、静态数据组织、样式边界与验收范围时必读 |
-| `.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-design.md` | `frontend` 老项目静态页面迁移设计 | 涉及旧项目页面迁移、分包归属、静态数据边界、导航与交互约束时必读 |
-| `.ai-specs/coding-specs/2026-04-23-frontend-static-page-migration-implementation-plan.md` | `frontend` 老项目静态页面迁移实施计划 | 涉及实现顺序、文件落点、测试策略和分任务执行时必读 |
+
### 后端接口文档
D:\Code3\wdp\xuanzhi-service\.worktrees\feat-xuanzhi-service\server\.ai-specs\doc-dict 字典参考