浏览代码

docs(readme): 补全四大板块——技术栈/目录结构与用途/编码规范/构建与本地运行

- 技术栈表补全(TS strict/Vite/axios 统一封装/pnpm/ESLint+Prettier)
- 目录结构补 composables/types 层 + 逐目录用途约束表
- 编码规范拆为 §3.1~3.6:结构铁律/接口与响应契约/路由与鉴权/可复用资产与惯例/质量门禁/Git 纪律
- 补构建与本地运行(dev/build/环境变量)
Q 4 天之前
父节点
当前提交
4dc53d2d65
共有 1 个文件被更改,包括 94 次插入 和 27 次删除
  1. 94 27
      README.md

+ 94 - 27
README.md

@@ -1,49 +1,116 @@
 # PC 端前端(管理/运营)
 
-> Vue3 管理端,承载**教务域重写** + **教学 admin 复用**两块页面。统一走 nginx 入口 + 统一 Go 后端 SSO。本文档描述工程结构约定;接口契约与角色权限见 `../unified/`、`../academic/05-architecture/`、`../teaching/05-architecture/`。
+> Vue3 管理端,承载**教务域重写** + **教学 admin 复用**两块页面,统一走 nginx 入口 + 统一 Go 后端 SSO。
+> 本文档覆盖四块:**技术栈 / 目录结构与用途 / 编码规范 / 构建**。接口契约与角色权限见工作区文档库 `unified/`、`academic/05-architecture/`、`teaching/05-architecture/`(本仓库不复制契约原文)。
 
 ## 定位
 
-单一 Vue3 项目(`frontend-pc`),面向登录角色中的 **超管/教务/财务/老师(管理侧)** 等 PC 端角色(**市场角色登录入口暂禁用**——不建市场端入口/路由,后续启用时再单独拍板)。学生/家长日常操作走 `../frontend-mobile`。
+单一 Vue3 项目,面向登录角色中的 **超管/教务/财务/老师(管理侧)** 等 PC 端角色(**市场角色登录入口暂禁用**——不建市场端入口/路由,后续启用时再单独拍板)。学生/家长日常操作走移动端仓库 `DEV-MERGE-LEGACY-MOBILE-FRONTEND-2026`。
 
-## 技术栈(与规划对齐)
+## 1. 技术栈
 
-| 关注点 | 选型 | 依据 |
+| 关注点 | 选型 | 说明 / 依据 |
 |---|---|---|
-| 框架 | Vue 3 + TypeScript + Vite | 与教学 admin 现有栈一致,复用成本低 |
-| UI | Element Plus | 管理端组件库 |
-| 状态 | Pinia | 登录态 / 角色 / institution/campus 作用域 |
-| 路由 | Vue Router(按端 + 角色权限码守卫) | 7 角色,权限码来自统一 RBAC |
-| 接口封装 | 统一 `{code, data, message}` 信封 | 以教学 code 体系为基线(对齐清单 §2) |
-| 鉴权 | SSO(OIDC)token;菜单/按钮按权限码显隐 | 统一 identity 签发 |
+| 框架 | **Vue 3**(`<script setup>` + Composition API) | 与教学 admin 现有栈一致,复用成本低 |
+| 语言 | **TypeScript**(strict) | 接口契约类型化;统一信封 `R<T>` 泛型 |
+| 构建 | **Vite** | dev HMR + 产物构建;主 chunk < 1024KB(质量门禁) |
+| UI | **Element Plus**(含 `el-config-provider` 中文 locale) | 管理端组件库;locale 双注入(见编码规范 §3.4) |
+| 状态 | **Pinia** | `login`(token/角色)+ `scope`(institution/campus 作用域) |
+| 路由 | **Vue Router 4** | 按端组织 + 角色/权限码守卫 |
+| HTTP | **axios**(统一封装于 `src/api/`) | 统一 `{code, data, message}` 信封处理;拦截器只注入 token/trace,**不** reject 业务错误 |
+| 鉴权 | SSO(最小可行)token:access 30min + refresh 30 天 | 统一 identity 签发(ADR-014);菜单/按钮按权限码显隐 |
+| 包管理 | **pnpm**(lockfile 入库) | 与移动端同栈,依赖可对齐 |
+| 代码风格 | ESLint + Prettier(vue3 官方推荐配置) | 提交前 lint |
 
-## 目录结构约定
+## 2. 目录结构与用途
 
 ```
-frontend-pc/
-├── README.md            ← 本文件
+.
+├── README.md              ← 本文件
+├── package.json / pnpm-lock.yaml
+├── vite.config.ts         ← Vite 配置(proxy /api → 后端;chunk 拆分)
+├── tsconfig.json
+├── .env.example           ← 环境变量模板(VITE_API_BASE 等;实际 .env.* 走 .gitignore)
 └── src/
-    ├── views/           # 页面:按域分子目录(academic / teaching / org / system)
-    ├── components/      # 复用组件(表格/表单/作用域选择器 institution·campus)
-    ├── api/             # 接口封装:统一信封 + 错误码处理;按域分子目录
-    ├── router/          # 路由:按端组织 + 角色/权限码守卫
-    └── store/           # Pinia:login(token/角色)、scope(institution/campus)
+    ├── main.ts            ← 装配:Element Plus 双 locale 注入 + Pinia + Router + 作用域/权限守卫挂载
+    ├── views/             ← 页面:按域分子目录(见用途表)
+    │   ├── academic/      ←   教务域(排班/费用/打卡/充值/报课)——**新写**(旧 jQuery 视图全部重写)
+    │   ├── teaching/      ←   教学 admin(备课/题库/组卷/练习分析)——**按现有 Vue3 逐步迁入**
+    │   ├── org/           ←   机构/校区/班级/成员管理
+    │   └── system/        ←   系统(用户/角色/字典/任务监控/日志)
+    ├── components/        ← 复用组件:表格/表单/作用域选择器(institution·campus 联动)/Badge 色板
+    ├── api/               ← 接口封装:统一信封 + 错误码处理;按域分子目录(academic/teaching/org/…)
+    ├── router/            ← 路由:按端组织 + 角色/权限码守卫
+    ├── store/             ← Pinia:login(token/角色)、scope(institution/campus)
+    ├── composables/       ← 可组合逻辑:useListPage(列表页规范)等
+    └── types/             ← 契约类型:R<T> 信封、角色/权限码、各域 DTO
 ```
 
-## 结构铁律
+**目录用途约定**:
 
-1. **作用域(institution/campus)是全局状态**:所有业务页面查询必须带作用域,由 store 统一注入,禁止页面各自拼 `schoolid/campusid`(对齐清单 §3:消灭控制器隐式参数)。
+| 目录 | 用途 | 约束 |
+|---|---|---|
+| `src/views/{域}/` | 页面层,只放视图与页面级状态 | 禁止散写 fetch/axios;只经 `src/api/` |
+| `src/components/` | 跨页面复用组件 | 零业务耦合(作用域感知组件除外,从 store 读) |
+| `src/api/{域}/` | 接口封装(一域一目录,一资源一文件) | 统一信封处理收口在此;返回类型化 DTO |
+| `src/router/` | 路由与守卫 | 权限码驱动;不写 `role == N` 硬编码 |
+| `src/store/` | 全局状态(登录态/作用域) | 唯一 token 存取点(禁 localStorage 散写) |
+| `src/composables/` | 可组合逻辑 | 列表页一律复用 `useListPage<T>` |
+| `src/types/` | 契约类型 | 与后端 DTO camelCase 对齐;`R<T>` 泛型 |
+
+## 3. 编码规范
+
+### 3.1 结构铁律
+
+1. **作用域(institution/campus)是全局状态**:所有业务页面查询必须带作用域,由 `store/scope` 统一注入,禁止页面各自拼 `schoolid/campusid`(对齐清单 §3:消灭控制器隐式参数)。
 2. **权限码驱动显隐**:菜单/按钮/路由守卫读统一 RBAC 权限码,不写 `role == N` 硬编码(对齐清单 §3 超管判据收敛)。
 3. **教务域页面为新写**(旧 DataTables/视图 jQuery 全部重写);**教学 admin 页面按现有 Vue3 逐步迁入**,契约不变。
 4. 接口调用只经 `src/api/`,禁止页面里散写 fetch/axios。
 
-## 可复用资产(源自教务 Go 重构实战)
+### 3.2 接口与响应契约
+
+- 统一「**HTTP 恒 200 + body `code`**」信封 `{code, data, message, total?, success}`;判成功读 `code === 200`,错误文案读 `message`,**不靠**拦截器 reject、**不靠** HTTP status(源自教务 Go 重构在产验证)。
+- 错误码分段(与后端一致):`1xxx` 认证/权限 · `2xxx` 参数 · `3xxx` 数据 · `4xxx` 依赖 · `5xxx` 系统;`1001/1002` 统一跳登录(refresh 失败才跳,access 过期先静默 refresh)。
+- 分页:请求 `page`/`pageSize`(上限 200);列表读**顶层** `total`。
+- 命名:入参/出参 `camelCase`;组件 `PascalCase`;组合式函数 `useXxx`。
+
+### 3.3 路由与鉴权
+
+- 路由守卫顺序:登录态(access 有效?)→ 刷新(过期且有 refresh 则静默换)→ 角色/权限码 → 作用域就绪(scope 已注入)。
+- 刷新单例:并发 401/过期只触发一次 refresh(Promise 复用),成功后重放原请求。
+- 敏感操作(充值/退款/改密)二次确认 + 操作留痕(后端审计)。
+
+### 3.4 可复用资产与惯例(源自教务 Go 重构实战)
+
+- **列表页规范**:`useListPage<T>` + `ListPage.vue`(分页/筛选/批量操作收口);年级 `<GradeBadge>`(数字=年级 id + 学段色系)、科目 `<SubjectBadge>`(首字简称 + 独立色系)——色板纯数据零 Vue 依赖,新增列表页一律复用。
+- **locale 双注入**:Element Plus 默认英文,需 `app.use(ElementPlus, {locale: zhCn})`(命令式 ElMessageBox/Notification)+ `<el-config-provider :locale>`(声明式)**双注入**,单用其一必有遗漏;locale 引 `element-plus/es/locale/lang/zh-cn`。
+- **脱敏展示**:手机号/身份证按后端已脱敏值展示,前端不再二次处理(源头脱敏)。
+
+### 3.5 质量门禁
+
+| 门禁 | 命令 | 基线 |
+|---|---|---|
+| 类型检查 | `vue-tsc --noEmit` | 0 错误 |
+| 构建 | `pnpm build`(vite) | 主 chunk < 1024KB |
+| Lint | `pnpm lint`(eslint + prettier) | 0 错误 |
+
+### 3.6 Git 与提交规范
+
+- **工程纪律**:本地 commit 可执行;**脚手架搭建与 `git push` 前必须经用户确认**(逐次确认)。
+- 提交信息:conventional commits(`feat:` / `fix:` / `chore:` / `docs:` / `refactor:`)。
+- 提交前自检:`vue-tsc` + `pnpm build` 通过;敏感值未入库(`.env` 走 .gitignore,仅 `.env.example` 入库)。
+
+## 4. 构建与本地运行
+
+```bash
+pnpm install          # 依赖(pnpm 10.x;lockfile 入库)
+pnpm dev              # 本地开发(vite dev,/api 代理到后端 dev 地址)
+pnpm build            # 产物 → dist/(部署经 nginx)
+```
 
-- **列表页规范**:`useListPage<T>` + `ListPage.vue`;年级 `<GradeBadge>`(数字=年级 id + 学段色系)、科目 `<SubjectBadge>`(首字简称 + 独立色系)——色板纯数据零 Vue 依赖,新增列表页一律复用。
-- **locale 双注入**:Element Plus 默认英文,需 `app.use(ElementPlus,{locale:zhCn})`(命令式 ElMessageBox/Notification)+ `<el-config-provider :locale>`(声明式)双注入,单用其一必有遗漏;locale 引 `element-plus/es/locale/lang/zh-cn`。
-- **响应封装**:统一「HTTP 恒 200 + body `code`」,判成功读 `code===200`、错误文案读 `data.msg`,不靠拦截器 reject。
-- 建议采用 **pnpm monorepo + `shared` 包**(types/http 分层),与 `../frontend-mobile` 共用;按包拷贝 + 改 API base 即可移植(详见 `../unified/00-planning/experience-impact-analysis.md` §4)。
+**环境变量**(`.env.example` 入库,实际 `.env.*` 不入库):`VITE_API_BASE`(后端 base,dev 走 vite proxy 时可省)。
 
-## 与文档目录的关系
+## 5. 与文档目录的关系
 
-- 本目录**只放前端代码**;接口契约、端点清单、错误码见 `../academic/05-architecture/` 与 `../teaching/05-architecture/`;前端策略(重写 vs 复用)见 `../unified/00-planning/cross-system-reconciliation.md` §5。
+- 本仓库**只放前端代码**;接口契约、端点清单、错误码见工作区文档库 `academic/05-architecture/` 与 `teaching/05-architecture/`;前端策略(重写 vs 复用)见 `unified/00-planning/cross-system-reconciliation.md` §5。
+- 与移动端仓库共享编码惯例(统一信封/脱敏/权限码/commit 规范),差异仅在 UI 库与路由形态。