docs: R4 WCD 生产任务契约(designData→词云)与路线文档
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## 项目概览
|
||||
|
||||
智绘微刻(Smart-Engraving)微信小程序:词云生成 + 个性化激光雕刻定制。基于 **Taro 3.6.31 + React 18 + TypeScript**,SCSS 变量驱动主题,构建产物运行在微信小程序(webpack5 编译到 `dist/`)。
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
npm install # 安装依赖
|
||||
npm run dev:weapp # 微信小程序开发模式(watch,配合微信开发者工具)
|
||||
npm run build:weapp # 生产构建;也是提交前 / 验收的标准验证命令
|
||||
npm run dev:h5 # H5 预览调试(H5 下事件用 onClick,见下文)
|
||||
node --test tools/homeTopMask.test.mjs # 运行 node:test 单测(目前唯一测试,无需 jest)
|
||||
```
|
||||
|
||||
没有配置 lint/test 脚本。提交前验证 = `npm run build:weapp` 通过(见 `docs/parallel-development-guide.md` §6)。
|
||||
|
||||
## 数据访问层(核心架构,务必先读)
|
||||
|
||||
页面**不得**直接读写 Storage 或直接发请求。所有数据操作取道两个聚合入口,二者都只 re-export、不堆业务:
|
||||
|
||||
- `../../utils/store`(DA 层,本地 Storage,按域拆文件):页面从 `src/utils/store/index.ts` 导入 `getDesignList()`、`addAddress()`、`designToOrder()` 等。
|
||||
- `../../utils/api`(HTTP 层,按域拆文件):页面从 `src/utils/api/index.ts` 导入 `login()`、`fetchProducts()` 等。
|
||||
|
||||
每个域文件(`store/keys|user|design|address|order|theme.ts`、`api/auth|user|product|address|design|order|upload.ts`)按领域职责划分,新增逻辑加到对应域文件里(不要新建 `xxx2.ts`),新文件需在聚合入口显式 re-export。后端替换 = 把 `store/<domain>.ts` 的函数换成 `api/<domain>.ts` 的 HTTP 调用,页面层零改动。
|
||||
|
||||
**openid 作用域隔离**(`store/keys.ts`):storage key 形如 `${scope}_${openid}`,通过 `key(scope)`(当前用户)与 `keyFor(scope, openid)`(指定用户)生成,实现多用户数据隔离。
|
||||
|
||||
类型统一放 `src/types/index.ts` 或 `src/types/<domain>.ts`,不要散落在页面里。
|
||||
|
||||
## 协作约定(R0–R4 并行路线)
|
||||
|
||||
仓库按四人并行开发组织,主干为 `master`,禁止直接推主干,合入走 PR。每人一条端到端路线(前端 + 后端、同名分支):
|
||||
|
||||
| 路线 | 分支 | 页面归属 | 数据域 |
|
||||
|---|---|---|---|
|
||||
| R1 商品目录 | `feat/r1-catalog` | `index`、`shop`、`shop/detail`、`product` | `api/product` |
|
||||
| R2 地址+设计清单 | `feat/r2-address-design` | `address`、`designList` | `store/design`、`store/address`、`api/address`、`api/design` |
|
||||
| R3 订单+支付占位 | `feat/r3-order-pay` | `checkout`、`orders`、`orderDetail` | `store/order`、`api/order` |
|
||||
| R4 上传+词云+线稿 | `feat/r4-upload-wordcloud` | `wordcloud`、`diy/stickerEdit` | `api/upload` |
|
||||
|
||||
`store/index.ts` 与 `api/index.ts` 由 R0(本分支 `feat/r0-dev-foundation`)维护,**只加不删、不堆业务**。完整规则见 `docs/team-collaboration-guide.md` 与 `docs/parallel-development-guide.md`(含合并顺序:R1 → R2/R4 → R3)。
|
||||
|
||||
## 主题系统
|
||||
|
||||
`ThemeMode`:`light` / `dark` / `auto`(`store/theme.ts`)。`ThemeContext`(`src/context/ThemeContext.tsx`)产出最终生效的 `resolvedTheme: 'light' | 'dark'`。
|
||||
|
||||
- 页面根节点 `className={theme-${resolvedTheme}}`;所有颜色/字号来自 `app.scss` 里的 CSS 变量(浅色 `:root` + `.theme-dark`),**禁止在页面里硬编码颜色/字号/组件形态**,token 语义见 `DESIGN.md`,落地规则见 `设计变更文档.md`。
|
||||
- 每个页面都挂 `<ThemedPageMeta />`(`PageMeta + NavigationBar`),按 `resolvedTheme` 强制覆盖顶部/状态栏颜色;`useStatusBar(resolvedTheme)` 在页面显示时再同步一次。`app.config.ts` 里的 `darkmode: true` 只作为系统主题探测通道(`onThemeChange`/`getAppBaseInfo`),窗口颜色不依赖它。
|
||||
- 自定义 tabBar 无法继承 React Context,通过 `Taro.eventCenter` 订阅 `themeChange` 事件 (`THEME_CHANGE_EVENT`) 同步主题。
|
||||
- 图标一律用 `src/icon/` 下的 PNG/SVG,**禁止用 emoji 当图标**。
|
||||
|
||||
## 事件与生命周期(重要兼容坑)
|
||||
|
||||
- **一律用 `onTap`,不要用 `onClick`**。微信基础库 3.17.0 + Taro React 下动态更新 handler 会触发 `TaroElement.removeEventListener(undefined)`,报 `Cannot read properties of undefined (reading '_num')`。仅在 H5 构建里可用 `onClick`。
|
||||
- 页面显示刷新用 `useDidShow`(`@tarojs/taro`),不要手动覆盖 `page.onShow`(热更新会重复叠加导致异常)。
|
||||
|
||||
## 请求与登录
|
||||
|
||||
- `src/utils/request.ts`:`BASE_URL = https://wxbackend.tokenleaping.com`;后端统一响应 `{ code, message, data }`,`code === 0` 成功;token 存 `smart_access_token`,走 `Authorization: Bearer`。HTTP 401 会自动触发一次会话续登(`app.tsx` 注册的 `refreshSession`),失败则清 token 并调 `onUnauthorized`。
|
||||
- `session.ts` 的 `refreshSession`:`wx.login` 换新 code → `/api/auth/login` 续签 → `/api/users/me` 校验 openid 与本地账号一致才放行(防串号)。`mock_*` 开头的 openid 是历史残留,`isMockOpenid` 会识别并拒绝。
|
||||
- 登录态校验有缓存(`src/utils/authState.ts`),`LoginGuard` 监听 `authStateChanged`/`tabBarChange`/`themeChange` 事件自动刷新。
|
||||
|
||||
## 静态资源与 OSS
|
||||
|
||||
- 产品大图已迁到阿里云 OSS(bucket `wordcloudwechat`,杭州),包体积需保持在微信 2MB 限制内(当前 `dist/` 约 1MB)。
|
||||
- 基址在根目录 `.env` 的 `OSS_BASE_URL`(git 忽略),由 `config/index.js` 注入为 `__OSS_BASE_URL__` 常量。
|
||||
- 所有资源路径经 `assetUrl()`(`src/utils/asset.ts`)处理:`/img/*` 大图拼 OSS 远程地址,`/icon/*` 小图标与 `src/icon`、`theme.json` 通过 `config/index.js` 的 copy patterns 打包进 `dist/`。
|
||||
- 商品/品类配置集中在 `src/utils/productConfig.ts`(`PRODUCTS` 数组 + icon 映射 + `tone` 主题色),遮罩尺寸说明见 `docs/mask-config-guide.md`。
|
||||
|
||||
## 页面结构说明
|
||||
|
||||
路由与 tabBar 见 `src/app.config.ts`(全局 `navigationStyle: custom`,5 个 tab 的自定义 tabBar)。几个非平凡的页面:
|
||||
|
||||
- `pages/shop/index`:单页双容器——2 列商品网格 + 固定 overlay 沉浸式详情(滚动视差、产品 `tone` 主题色联动),点击卡片在当前页内过渡,不跳转;底部 CTA 跳 `/pages/product/index?id=xxx` 衔接购买链路。
|
||||
- `pages/diy/index`:DIY 工作台(贴纸拖拽/缩放/碰撞检测),后续 `diy/stickerEdit` 为贴纸编辑画板。
|
||||
- 共享组件在 `src/components/`(`ThemedPageMeta`、`ScrollTopMask`、`TopBarGradient`、`BottomActionBar`、`LoginGuard`、`LoginModal` 等)。
|
||||
|
||||
## 已知遗留问题
|
||||
|
||||
README「已知遗留问题」表记载(改动相关页面时注意):
|
||||
|
||||
- checkout 页在设计中新增地址后无法及时同步(design 数据写入与读取生命周期不一致)。
|
||||
- `diy/stickerEdit` 页面无法运行:Canvas 2D `createImage` 在部分基础库版本返回 `undefined`,且线稿 AI 接口未接入。
|
||||
Reference in New Issue
Block a user