|
|
@@ -1,6 +1,7 @@
|
|
|
# 移动端前端(老师 / 学生 / 家长)
|
|
|
|
|
|
-> 单一 Vue 项目,**按角色分包**:`teacher` / `student` / `parent` 三端共享 `shared/`(身份/登录态、通用组件、接口封装)。本文档描述工程结构约定;接口契约见 `../unified/`、`../academic/05-architecture/`、`../teaching/05-architecture/`。
|
|
|
+> 单仓多端,**按角色分包**:`teacher` / `student` / `parent` 三端共享 `packages/shared`(身份/登录态、通用组件、接口封装)。
|
|
|
+> 本文档覆盖四块:**技术栈 / 目录结构与用途 / 编码规范 / 构建**。接口契约见工作区文档库 `unified/`、`academic/05-architecture/`、`teaching/05-architecture/`(本仓库不复制契约原文)。
|
|
|
|
|
|
## 定位
|
|
|
|
|
|
@@ -12,47 +13,113 @@
|
|
|
| 学生端 | 做题、查看练习记录与分析 | 教学 |
|
|
|
| 家长端 | 绑定孩子、查看孩子练习/费用 | 教务(bindchild 绑定、费用)+ 教学(练习) |
|
|
|
|
|
|
-三端**底层用户统一**(canonical_user_id + 7 角色),故共用 `shared/` 的 SSO 接入与登录态,仅按角色分包差异视图。
|
|
|
+三端**底层用户统一**(canonical_user_id + 7 角色),故共用 `shared` 的 SSO 接入与登录态,仅按角色分包差异视图。
|
|
|
|
|
|
-## 技术栈(与规划对齐)
|
|
|
+## 1. 技术栈
|
|
|
|
|
|
-| 关注点 | 选型 | 依据 |
|
|
|
+| 关注点 | 选型 | 说明 / 依据 |
|
|
|
|---|---|---|
|
|
|
-| 框架 | Vue 3 + TypeScript + Vite | 与 PC 端同栈,组件/工具可复用 |
|
|
|
-| UI | 移动端 UI 组件库(Vant 系,落地时定) | 移动交互 |
|
|
|
-| 状态 | Pinia | 登录态 / 角色 / institution·campus 作用域 |
|
|
|
-| 接口封装 | 统一 `{code, data, message}` 信封 | 以教学 code 体系为基线(对齐清单 §2) |
|
|
|
-| 鉴权 | SSO(OIDC)token;家长端走微信 per-campus 授权 | 统一 identity 签发;教务微信免登收敛 |
|
|
|
+| 框架 | **Vue 3**(`<script setup>` + Composition API) | 与 PC 端同栈,组件/工具/类型可复用 |
|
|
|
+| 语言 | **TypeScript**(strict) | 契约类型化;`R<T>` 信封泛型与 PC 端一致 |
|
|
|
+| 构建 | **Vite**(每端独立入口) | 按端分包产物;主 chunk < 1024KB |
|
|
|
+| UI | **Vant 4** | 移动交互组件库(默认中文 locale);如混用 Element Plus 组件需双 locale 注入 |
|
|
|
+| 状态 | **Pinia** | 登录态/角色/institution·campus 作用域(shared 内建) |
|
|
|
+| 路由 | **Vue Router 4**(每端独立路由表) | 角色差异用权限码判断 |
|
|
|
+| HTTP | **axios**(统一封装于 `shared/api`) | 统一 `{code, data, message}` 信封处理 |
|
|
|
+| 鉴权 | SSO(最小可行)token + **微信 per-campus 授权**(家长端主入口) | 统一 identity 签发(ADR-014);多 appid 按 campus 绑定 |
|
|
|
+| 工作区 | **pnpm monorepo**(workspaces) | `packages/shared` + `apps/{student,parent,teacher}` |
|
|
|
+| 代码风格 | ESLint + Prettier | 提交前 lint |
|
|
|
|
|
|
-## 目录结构约定
|
|
|
+## 2. 目录结构与用途
|
|
|
|
|
|
```
|
|
|
-frontend-mobile/
|
|
|
-├── README.md ← 本文件
|
|
|
-└── src/
|
|
|
- ├── shared/ # 三端共享
|
|
|
- │ ├── identity/ # SSO 接入:token 存取、刷新/吊销、微信授权(per-campus appid)
|
|
|
- │ ├── components/ # 通用组件(作用域感知、列表、表单)
|
|
|
- │ └── api/ # 接口封装:统一信封 + 错误码;按域分子目录
|
|
|
- ├── teacher/ # 老师端:views/ + 路由
|
|
|
- ├── student/ # 学生端:views/ + 路由
|
|
|
- └── parent/ # 家长端:views/ + 路由
|
|
|
+.
|
|
|
+├── README.md ← 本文件
|
|
|
+├── package.json ← 根(workspaces 声明 + 公共脚本/依赖)
|
|
|
+├── pnpm-workspace.yaml ← pnpm 工作区(packages/* + apps/*)
|
|
|
+├── tsconfig.base.json ← TS 公共配置(apps/* 继承 + paths 指 shared 源码)
|
|
|
+├── .env.example ← 环境变量模板(各端 VITE_API_BASE / VITE_WECHAT_* 等)
|
|
|
+├── packages/
|
|
|
+│ └── shared/ ← 三端共享(唯一登录态/SSO 实现,见铁律 1)
|
|
|
+│ ├── src/
|
|
|
+│ │ ├── identity/ ← SSO 接入:token 存取、静默刷新/吊销、微信 per-campus 授权
|
|
|
+│ │ ├── api/ ← 接口封装:统一信封 + 错误码;按域分子目录(academic/teaching/…)
|
|
|
+│ │ ├── components/← 通用组件(作用域感知、列表、表单、Badge 色板)
|
|
|
+│ │ ├── types/ ← 契约类型:R<T>、角色/权限码、各域 DTO
|
|
|
+│ │ └── composables/← 可组合逻辑:useListPage 等
|
|
|
+│ └── package.json ← 包名 @unified/shared;main 指向 src(按源码消费,免构建)
|
|
|
+└── apps/
|
|
|
+ ├── student/ ← 学生端:src/{views,router,api 域扩展}/ + main.ts(独立 Vite 入口)
|
|
|
+ ├── parent/ ← 家长端:同上(微信授权主入口 + bindchild 绑定流)
|
|
|
+ └── teacher/ ← 老师端:同上(规划待建,结构对齐 student/parent)
|
|
|
```
|
|
|
|
|
|
-## 结构铁律
|
|
|
+**目录用途约定**:
|
|
|
|
|
|
-1. **登录态/SSO 只有一份**,放 `shared/identity`;三端不得各自实现登录(对齐"底层用户统一")。
|
|
|
-2. **家长↔学生绑定以教务侧 `bindchild` 为事实源**(对齐清单 §6):家长端进入时按绑定关系拉取孩子数据。
|
|
|
-3. **三端路由独立**(各自 `views/`),但共用 `shared/components` 与 `shared/api`;角色差异用权限码判断,不写 `role == N` 硬编码。
|
|
|
+| 目录 | 用途 | 约束 |
|
|
|
+|---|---|---|
|
|
|
+| `packages/shared` | 三端共享层:SSO/登录态、接口封装、通用组件、契约类型 | **唯一** token 存取与 SSO 实现点;零端差异逻辑 |
|
|
|
+| `apps/{端}/src/views` | 该端页面 | 只经 `shared/api` 发起请求;不实现登录 |
|
|
|
+| `apps/{端}/src/router` | 该端独立路由 + 权限码守卫 | 角色差异用权限码,不写 `role == N` |
|
|
|
+| `apps/{端}/.env*` | 该端构建变量(API base、微信 appid 映射) | 只 `.env.example` 入库 |
|
|
|
+| `tsconfig.base.json` | 公共 TS 配置 | apps 经 `paths` 直指 `@unified/shared` 源码(dev 免构建、类型直达) |
|
|
|
+
|
|
|
+## 3. 编码规范
|
|
|
+
|
|
|
+### 3.1 结构铁律
|
|
|
+
|
|
|
+1. **登录态/SSO 只有一份**,放 `packages/shared/src/identity`;三端不得各自实现登录(对齐"底层用户统一")。
|
|
|
+2. **家长↔学生绑定以教务侧 `bindchild` 为事实源**(对齐清单 §6):家长端进入时按绑定关系拉取孩子数据,不本地存绑定快照。
|
|
|
+3. **三端路由独立**(各自 `views/` + router),但共用 `shared/components` 与 `shared/api`;角色差异用权限码判断,不写 `role == N` 硬编码。
|
|
|
4. 接口调用只经 `shared/api/`,三端 `views` 内不散写请求。
|
|
|
+5. **shared 改动影响三端**:改 shared 必须三端各自 `pnpm build` 通过后方可提交(跨端回归门禁)。
|
|
|
+
|
|
|
+### 3.2 接口与响应契约
|
|
|
+
|
|
|
+- 统一「**HTTP 恒 200 + body `code`**」信封 `{code, data, message, total?, success}`;判成功读 `code === 200`,错误文案读 `message`,不靠拦截器 reject、不靠 HTTP status。
|
|
|
+- 错误码分段(与后端/PC 端一致):`1xxx` 认证/权限 · `2xxx` 参数 · `3xxx` 数据 · `4xxx` 依赖 · `5xxx` 系统;`1001/1002` 走 identity 统一刷新/重登流程(并发只刷一次)。
|
|
|
+- AI 类异步结果(批改/分析):**派发成功 ≠ 完成**,轮询任务终态或业务表,前端展示"处理中"态而非静默。
|
|
|
+- 命名:入参/出参 `camelCase`;组件 `PascalCase`;组合式函数 `useXxx`。
|
|
|
+
|
|
|
+### 3.3 鉴权与微信授权
|
|
|
+
|
|
|
+- 家长端主入口 = 微信 per-campus 授权(campus → appid 映射由后端下发);老师/学生端账密 + 微信绑定。
|
|
|
+- token 刷新单例:并发过期只触发一次 refresh(Promise 复用),成功后重放原请求。
|
|
|
+- 授权失败/未绑定时引导到对应端登录页,不白屏。
|
|
|
+
|
|
|
+### 3.4 可复用资产与惯例(源自教务 Go 重构实战)
|
|
|
|
|
|
-## 可复用资产(源自教务 Go 重构实战)
|
|
|
+- **三端复用模式**:与教务重构一致采用"移动教师/移动家长 Vant + 共享 `shared`";`shared/identity`(SSO 接入、token 存取/刷新/吊销)三端共用一份。
|
|
|
+- **locale**:Vant 4 默认中文,不动;如混用 Element Plus 组件需命令式 + 声明式双注入。
|
|
|
+- **列表页规范**:`useListPage<T>` + 列表组件(分页/下拉刷新收口);Badge 色板纯数据零 Vue 依赖(年级学段色系/科目首字简称)。
|
|
|
+- **脱敏展示**:手机号/身份证按后端已脱敏值展示,前端不再二次处理(源头脱敏)。
|
|
|
+
|
|
|
+### 3.5 质量门禁
|
|
|
+
|
|
|
+| 门禁 | 命令 | 基线 |
|
|
|
+|---|---|---|
|
|
|
+| 类型检查 | `vue-tsc --noEmit`(各端 + shared) | 0 错误 |
|
|
|
+| 构建 | `pnpm -r build`(三端) | 各端主 chunk < 1024KB |
|
|
|
+| Lint | `pnpm -r lint` | 0 错误 |
|
|
|
+| 跨端回归 | 改 shared 后三端全量 build | 全绿方可提交 |
|
|
|
+
|
|
|
+### 3.6 Git 与提交规范
|
|
|
+
|
|
|
+- **工程纪律**:本地 commit 可执行;**脚手架搭建与 `git push` 前必须经用户确认**(逐次确认)。
|
|
|
+- 提交信息:conventional commits(`feat:` / `fix:` / `chore:` / `docs:` / `refactor:`);影响 shared 的提交在正文标注 `affects: student,parent,teacher`。
|
|
|
+- 提交前自检:三端 build 通过;敏感值未入库(`.env` 走 .gitignore,仅 `.env.example` 入库)。
|
|
|
+
|
|
|
+## 4. 构建与本地运行
|
|
|
+
|
|
|
+```bash
|
|
|
+pnpm install # 工作区安装
|
|
|
+pnpm --filter student dev # 单端开发(student / parent / teacher)
|
|
|
+pnpm -r build # 三端全量构建 → apps/*/dist/(部署经 nginx 按端分发)
|
|
|
+```
|
|
|
|
|
|
-- **三端复用**:与教务重构一致采用"移动教师/移动家长 Vant + 共享 `shared`"模式;`shared/identity`(SSO 接入、token 存取/刷新/吊销)三端共用一份。
|
|
|
-- **locale**:Vant4 默认中文,不动;如混用 Element Plus 组件需命令式+声明式双注入。
|
|
|
-- **响应封装**:统一「HTTP 恒 200 + body `code`」,判成功读 `code===200`、错误文案读 `data.msg`。
|
|
|
-- 建议 pnpm monorepo 与 `../frontend-pc` 共用 `shared`(types/http/色板/列表规范);移植清单见 `../unified/00-planning/experience-impact-analysis.md` §4。
|
|
|
+**环境变量**(各端 `.env.example` 入库,实际 `.env.*` 不入库):`VITE_API_BASE`(后端 base)、`VITE_WECHAT_APPID`(家长端微信入口)。
|
|
|
|
|
|
-## 与文档目录的关系
|
|
|
+## 5. 与文档目录的关系
|
|
|
|
|
|
-- 本目录**只放移动端代码**;家长绑定、费用、练习契约见 `../academic/05-architecture/` 与 `../teaching/05-architecture/`;学生端契约兼容基线见 `../unified/00-planning/cross-system-reconciliation.md` §5。
|
|
|
+- 本仓库**只放移动端代码**;家长绑定、费用、练习契约见工作区文档库 `academic/05-architecture/` 与 `teaching/05-architecture/`;学生端契约兼容基线见 `unified/00-planning/cross-system-reconciliation.md` §5。
|
|
|
+- 与 PC 端仓库共享编码惯例(统一信封/脱敏/权限码/commit 规范),差异仅在 UI 库(Vant)与 monorepo 形态。
|