|
|
4 dni temu | |
|---|---|---|
| .gitignore | 4 dni temu | |
| README.md | 4 dni temu |
单仓多端,按角色分包:
teacher/student/parent三端共享packages/shared(身份/登录态、通用组件、接口封装)。 本文档覆盖四块:技术栈 / 目录结构与用途 / 编码规范 / 构建。接口契约见工作区文档库unified/、academic/05-architecture/、teaching/05-architecture/(本仓库不复制契约原文)。
一个移动端仓服务三个角色端:
| 端 | 主要场景 | 主要域 |
|---|---|---|
| 老师端 | 打卡、查看/批改练习、备课查看 | 教务(打卡)+ 教学(练习/备课) |
| 学生端 | 做题、查看练习记录与分析 | 教学 |
| 家长端 | 绑定孩子、查看孩子练习/费用 | 教务(bindchild 绑定、费用)+ 教学(练习) |
三端底层用户统一(canonical_user_id + 7 角色),故共用 shared 的 SSO 接入与登录态,仅按角色分包差异视图。
| 关注点 | 选型 | 说明 / 依据 |
|---|---|---|
| 框架 | 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 |
.
├── 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)
目录用途约定:
| 目录 | 用途 | 约束 |
|---|---|---|
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 免构建、类型直达) |
packages/shared/src/identity;三端不得各自实现登录(对齐"底层用户统一")。bindchild 为事实源(对齐清单 §6):家长端进入时按绑定关系拉取孩子数据,不本地存绑定快照。views/ + router),但共用 shared/components 与 shared/api;角色差异用权限码判断,不写 role == N 硬编码。shared/api/,三端 views 内不散写请求。pnpm build 通过后方可提交(跨端回归门禁)。code」信封 {code, data, message, total?, success};判成功读 code === 200,错误文案读 message,不靠拦截器 reject、不靠 HTTP status。1xxx 认证/权限 · 2xxx 参数 · 3xxx 数据 · 4xxx 依赖 · 5xxx 系统;1001/1002 走 identity 统一刷新/重登流程(并发只刷一次)。camelCase;组件 PascalCase;组合式函数 useXxx。shared";shared/identity(SSO 接入、token 存取/刷新/吊销)三端共用一份。useListPage<T> + 列表组件(分页/下拉刷新收口);Badge 色板纯数据零 Vue 依赖(年级学段色系/科目首字简称)。| 门禁 | 命令 | 基线 |
|---|---|---|
| 类型检查 | vue-tsc --noEmit(各端 + shared) |
0 错误 |
| 构建 | pnpm -r build(三端) |
各端主 chunk < 1024KB |
| Lint | pnpm -r lint |
0 错误 |
| 跨端回归 | 改 shared 后三端全量 build | 全绿方可提交 |
git push 前必须经用户确认(逐次确认)。feat: / fix: / chore: / docs: / refactor:);影响 shared 的提交在正文标注 affects: student,parent,teacher。.env 走 .gitignore,仅 .env.example 入库)。pnpm install # 工作区安装
pnpm --filter student dev # 单端开发(student / parent / teacher)
pnpm -r build # 三端全量构建 → apps/*/dist/(部署经 nginx 按端分发)
环境变量(各端 .env.example 入库,实际 .env.* 不入库):VITE_API_BASE(后端 base)、VITE_WECHAT_APPID(家长端微信入口)。
academic/05-architecture/ 与 teaching/05-architecture/;学生端契约兼容基线见 unified/00-planning/cross-system-reconciliation.md §5。