提交文件

This commit is contained in:
2026-02-28 15:16:15 +08:00
parent 1a4e50e0a4
commit 44f250f58e
159 changed files with 61268 additions and 0 deletions

View File

@@ -0,0 +1,437 @@
# 前端开发指南
<cite>
**本文引用的文件**
- [package.json](file://frontend/package.json)
- [vite.config.js](file://frontend/vite.config.js)
- [main.js](file://frontend/src/main.js)
- [App.vue](file://frontend/src/App.vue)
- [router/index.js](file://frontend/src/router/index.js)
- [stores/index.js](file://frontend/src/stores/index.js)
- [stores/user.js](file://frontend/src/stores/user.js)
- [stores/app.js](file://frontend/src/stores/app.js)
- [views/Layout.vue](file://frontend/src/views/Layout.vue)
- [views/Login.vue](file://frontend/src/views/Login.vue)
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue)
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue)
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue)
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue)
- [api/request.js](file://frontend/src/api/request.js)
- [api/auth.js](file://frontend/src/api/auth.js)
- [api/index.js](file://frontend/src/api/index.js)
- [assets/main.scss](file://frontend/src/assets/main.scss)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本指南面向医院绩效系统的前端开发团队,围绕 Vue 3 Composition API 的使用、组件架构设计与状态管理策略展开同时覆盖路由配置、API 调用封装、UI 组件设计规范、Element Plus 组件库使用、样式定制与响应式布局、组件开发最佳实践、代码组织结构、构建与部署流程,以及开发环境配置、热重载与生产构建优化、常见问题与性能优化建议。
## 项目结构
前端采用 Vite + Vue 3 + Pinia + Element Plus 技术栈,目录组织遵循按功能域划分的模块化思路:
- 根级配置package.json、vite.config.js
- 应用入口main.js、App.vue
- 路由src/router/index.js
- 状态管理src/stores 下的用户与应用状态
- 视图层src/views 下按业务域划分的页面组件
- API 层src/api 下按领域划分的接口模块与统一请求封装
- 样式src/assets/main.scss 提供全局样式与主题变量
```mermaid
graph TB
A["main.js<br/>应用入口"] --> B["App.vue<br/>根组件"]
A --> C["router/index.js<br/>路由配置"]
A --> D["stores/*<br/>Pinia 状态"]
B --> E["views/Layout.vue<br/>布局容器"]
E --> F["views/Login.vue<br/>登录页"]
E --> G["views/Dashboard.vue<br/>工作台"]
E --> H["views/basic/Departments.vue<br/>基础数据-科室"]
E --> I["views/assessment/Assessments.vue<br/>考核管理"]
E --> J["views/reports/Reports.vue<br/>统计报表"]
A --> K["api/request.js<br/>HTTP 封装"]
K --> L["api/auth.js<br/>认证接口"]
K --> M["api/index.js<br/>接口聚合导出"]
A --> N["assets/main.scss<br/>全局样式"]
```
图表来源
- [main.js](file://frontend/src/main.js#L1-L24)
- [App.vue](file://frontend/src/App.vue#L1-L17)
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
章节来源
- [package.json](file://frontend/package.json#L1-L27)
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
- [main.js](file://frontend/src/main.js#L1-L24)
- [App.vue](file://frontend/src/App.vue#L1-L17)
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
- [stores/index.js](file://frontend/src/stores/index.js#L1-L3)
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
## 核心组件
- 应用入口与插件注册:在入口文件中完成 Element Plus 国际化、图标全局注册、Pinia、路由挂载与全局样式引入。
- 根组件:通过 Config Provider 统一语言包,简化多组件国际化使用。
- 路由系统:采用 History 模式,定义登录页与主框架嵌套路由,含面包屑标题与全局前置守卫。
- 状态管理:使用 Pinia 定义用户与应用状态,支持登录态持久化、菜单树与侧边栏状态。
- API 层:统一 Axios 实例,拦截器处理鉴权头、错误提示与路由跳转;接口模块按领域拆分并聚合导出。
- 视图组件:采用 Composition API 编写,结合 Element Plus 组件实现表单、表格、对话框、图表等。
章节来源
- [main.js](file://frontend/src/main.js#L1-L24)
- [App.vue](file://frontend/src/App.vue#L1-L17)
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
## 架构总览
系统采用“视图层-状态层-接口层-基础设施层”的分层架构:
- 视图层:页面组件负责交互与展示,使用 Composition API 管理本地状态与生命周期。
- 状态层Pinia Store 管理跨组件共享的状态与业务逻辑。
- 接口层Axios 封装统一处理请求/响应拦截,接口模块按领域拆分。
- 基础设施Vite 构建工具、Element Plus UI 库、SCSS 全局样式。
```mermaid
graph TB
subgraph "视图层"
V1["views/Login.vue"]
V2["views/Layout.vue"]
V3["views/Dashboard.vue"]
V4["views/basic/Departments.vue"]
V5["views/assessment/Assessments.vue"]
V6["views/reports/Reports.vue"]
end
subgraph "状态层"
S1["stores/user.js"]
S2["stores/app.js"]
end
subgraph "接口层"
I1["api/request.js"]
I2["api/auth.js"]
I3["api/index.js"]
end
subgraph "基础设施"
B1["main.js"]
B2["router/index.js"]
B3["assets/main.scss"]
end
V1 --> S1
V2 --> S2
V3 --> I1
V4 --> I1
V5 --> I1
V6 --> I1
S1 --> I2
I1 --> I3
B1 --> V1
B1 --> V2
B1 --> V3
B1 --> V4
B1 --> V5
B1 --> V6
B1 --> B2
B1 --> B3
```
图表来源
- [main.js](file://frontend/src/main.js#L1-L24)
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
## 详细组件分析
### 路由与导航
- 路由模式History 模式,便于 SEO 与语义化 URL。
- 导航守卫:在进入非登录页时校验本地 token未登录自动跳转登录页。
- 嵌套路由Layout 作为父路由,子路由承载各业务页面,支持面包屑标题动态设置。
- 动态导入:路由组件懒加载,提升首屏性能。
```mermaid
sequenceDiagram
participant U as "用户"
participant R as "路由守卫"
participant L as "登录页"
participant H as "主页"
U->>R : 访问任意受保护路径
R->>R : 读取 localStorage 中 token
alt 无 token
R-->>U : 跳转到 /login
U->>L : 渲染登录页
else 有 token
R-->>U : 放行
U->>H : 进入主框架
end
```
图表来源
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
章节来源
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
### 状态管理Pinia
- 用户状态登录、获取当前用户信息、登出token 持久化至 localStorage。
- 应用状态:侧边栏折叠状态、科室树加载;用于菜单渲染与布局切换。
```mermaid
classDiagram
class UserStore {
+string token
+object userInfo
+login(username,password) Promise~boolean~
+getUserInfo() Promise~object|null~
+logout() void
}
class AppStore {
+boolean collapsed
+array departmentTree
+toggleSidebar() void
+loadDepartmentTree() Promise~void~
}
class ApiAuth {
+login(data) Promise
+getCurrentUser() Promise
}
UserStore --> ApiAuth : "调用"
```
图表来源
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
章节来源
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [stores/index.js](file://frontend/src/stores/index.js#L1-L3)
### API 调用封装
- Axios 实例baseURL 指向 /api/v1统一超时与 Content-Type。
- 请求拦截:自动附加 Authorization 头Bearer token
- 响应拦截统一错误码判断、错误消息提示、401 自动清理 token 并跳转登录。
- 接口模块按领域拆分auth、department、staff、indicator、assessment、salary、stats、template并在 index.js 聚合导出。
```mermaid
flowchart TD
Start(["发起请求"]) --> AddToken["从 localStorage 读取 token 并注入 Authorization"]
AddToken --> SendReq["发送请求"]
SendReq --> Resp{"响应状态"}
Resp --> |code!=200| ShowErr["提示错误消息"]
Resp --> |401| ClearToken["清除 token 并跳转登录"]
Resp --> |其他错误| ShowNetErr["提示网络错误"]
Resp --> |成功| ReturnRes["返回响应数据"]
ShowErr --> End(["结束"])
ClearToken --> End
ShowNetErr --> End
ReturnRes --> End
```
图表来源
- [api/request.js](file://frontend/src/api/request.js#L14-L63)
章节来源
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
### 登录页与布局
- 登录页:表单校验、加载态、错误提示、默认账号演示、登录成功跳转。
- 布局:侧边栏菜单、顶部导航、面包屑、内容区过渡动画、用户下拉菜单、退出登录。
```mermaid
sequenceDiagram
participant U as "用户"
participant L as "Login.vue"
participant S as "UserStore"
participant R as "Router"
participant A as "Auth API"
U->>L : 输入用户名/密码并点击登录
L->>L : 表单校验
L->>S : 调用 login(username,password)
S->>A : 调用登录接口
A-->>S : 返回 token
S-->>L : 返回 true
L->>R : 跳转到 /
R-->>U : 渲染 Layout
```
图表来源
- [views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)
- [stores/user.js](file://frontend/src/stores/user.js#L10-L20)
- [api/auth.js](file://frontend/src/api/auth.js#L4-L11)
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
章节来源
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
### 工作台Dashboard
- 统计卡片:在职员工、已考核人数、平均得分、奖金总额。
- 关键指标仪表盘:四个 KPI 指标仪表图联动。
- 图表区域:科室排名对比、收支趋势、绩效趋势、绩效分布饼图。
- 预警提示:低分员工、未完成考核科室、异常数据。
- 员工排名TOP 10 展示与奖金格式化。
章节来源
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
- [assets/main.scss](file://frontend/src/assets/main.scss#L95-L179)
### 基础数据-科室管理
- 查询条件:关键词、科室类型、分页。
- 表格字段:编码、名称、类型、层级、状态、创建时间。
- 操作:编辑、删除、状态开关。
- 新增/编辑弹窗:表单校验、树形上级选择、提交。
- 数据加载:分页查询、科室树加载。
章节来源
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
### 考核管理
- 查询条件:科室树选择、考核周期、状态筛选。
- 表格字段:姓名、科室、周期、总分、加权得分、状态、创建时间。
- 操作:查看详情、提交、审核通过/驳回、确认。
- 批量创建:选择科室、周期、指标集合进行批量生成。
章节来源
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
### 统计报表
- 筛选条件:统计周期(月)。
- 统计概览:在职员工、已考核人数、平均得分、奖金总额。
- 图表:科室绩效对比柱状图、绩效分布饼图。
- 数据表格:科室统计与员工排名 TOP 20。
章节来源
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
## 依赖关系分析
- 依赖安装Vue 3、Vue Router、Pinia、Axios、Element Plus、图标库、ECharts、Day.js。
- 开发依赖:@vitejs/plugin-vue、vite、sass。
- 构建与运行dev/build/preview 脚本,代理 /api 到后端 8000 端口。
```mermaid
graph LR
P["package.json"] --> V["vue@^3.4.15"]
P --> VR["vue-router@^4.2.5"]
P --> PN["pinia@^2.1.7"]
P --> AX["axios@^1.6.5"]
P --> EP["element-plus@^2.5.3"]
P --> IC["@element-plus/icons-vue@^2.3.1"]
P --> EC["echarts@^5.4.3"]
P --> DJ["dayjs@^1.11.10"]
P --> VP["@vitejs/plugin-vue@^5.0.3"]
P --> VT["vite@^5.0.11"]
P --> SA["sass@^1.70.0"]
```
图表来源
- [package.json](file://frontend/package.json#L11-L25)
章节来源
- [package.json](file://frontend/package.json#L1-L27)
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
## 性能考虑
- 路由懒加载:使用动态导入减少首屏体积。
- 组件懒加载:路由组件按需加载。
- 图表性能ECharts 初始化与 resize 事件绑定,避免重复初始化;图表容器尺寸固定,减少重排。
- 状态持久化:用户 token 存储于 localStorage减少重复登录开销。
- 请求缓存:可结合业务场景在 Store 层增加简单缓存策略(如最近一次查询结果)。
- 构建优化:生产构建开启压缩与 Tree Shaking按需引入 Element Plus 组件与图标以减小体积。
## 故障排查指南
- 登录失败/401检查后端认证接口是否返回 token确认请求拦截器是否正确注入 Authorization。
- 路由跳转异常:确认路由守卫逻辑与 token 存储位置一致。
- 图表不显示:确认容器元素存在且具备宽高,窗口 resize 事件触发图表 resize。
- 样式冲突:检查全局样式与组件 scoped 样式的优先级,避免覆盖 Element Plus 默认样式。
- 代理无效:确认 vite 代理配置指向正确的后端地址与端口。
章节来源
- [api/request.js](file://frontend/src/api/request.js#L14-L63)
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
- [assets/main.scss](file://frontend/src/assets/main.scss#L181-L186)
## 结论
本指南基于现有代码梳理了前端架构与实现细节,建议在后续迭代中持续完善:
- 在 Store 中增加更细粒度的错误状态与加载状态管理。
- 对高频接口增加缓存策略与防抖。
- 逐步引入 TypeScript 以提升类型安全。
- 增加单元测试与端到端测试覆盖关键流程。
## 附录
### 开发环境配置与热重载
- 启动命令npm run dev
- 端口5173
- 代理:/api -> http://localhost:8000
- 热重载Vite 默认启用,修改代码自动刷新
章节来源
- [vite.config.js](file://frontend/vite.config.js#L12-L20)
- [package.json](file://frontend/package.json#L6-L10)
### 生产构建与部署
- 构建命令npm run build
- 预览命令npm run preview
- 部署建议:将 dist 目录部署至 Nginx/Apache确保静态资源路径正确后端提供 /api/v1 接口。
章节来源
- [package.json](file://frontend/package.json#L6-L10)
### Element Plus 使用与样式定制
- 全局注册:在入口文件注册 Element Plus 与图标组件。
- 国际化:通过 Config Provider 与 zhCN 语言包统一界面语言。
- 主题变量:在全局样式中定义颜色与间距变量,供组件样式复用。
- 响应式布局:利用 Element Plus Grid 与 Flex 布局实现自适应。
章节来源
- [main.js](file://frontend/src/main.js#L3-L21)
- [App.vue](file://frontend/src/App.vue#L2-L8)
- [assets/main.scss](file://frontend/src/assets/main.scss#L14-L61)