# 部门员工服务 **本文引用的文件** - [backend/app/services/department_service.py](file://backend/app/services/department_service.py) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/models/finance.py](file://backend/app/models/finance.py) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py) - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py) - [backend/app/core/database.py](file://backend/app/core/database.py) - [backend/app/core/security.py](file://backend/app/core/security.py) - [backend/app/core/config.py](file://backend/app/core/config.py) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向“部门与员工服务”的开发与运维,围绕 DepartmentService 与 StaffService 的实现架构进行系统化说明。内容涵盖: - 部门管理:树形结构管理、层级关系维护、增删改查与有效性校验 - 员工管理:信息维护、职位与职称字段、基本工资与绩效系数、状态管理 - 数据模型关系映射:部门与员工的外键约束、索引与级联策略 - 高级能力:树形查询、分页与统计、权限控制、事务处理 - 实际业务场景示例与最佳实践 ## 项目结构 后端采用 FastAPI + SQLAlchemy Async 异步 ORM 架构,服务层位于 app/services,API 路由位于 app/api/v1,数据模型位于 app/models,配置与安全位于 app/core。 ```mermaid graph TB subgraph "API 层" A1["/api/v1/departments.py"] A2["/api/v1/staff.py"] end subgraph "服务层" S1["services/department_service.py"] S2["services/staff_service.py"] end subgraph "模型层" M1["models/models.py"] M2["models/finance.py"] end subgraph "基础设施" C1["core/config.py"] C2["core/database.py"] C3["core/security.py"] end A1 --> S1 A2 --> S2 S1 --> M1 S2 --> M1 M1 --> C2 M2 --> C2 C1 --> C2 C1 --> C3 ``` 图表来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L1-L108) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L1-L150) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L1-L112) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L114) - [backend/app/models/finance.py](file://backend/app/models/finance.py#L45-L74) - [backend/app/core/config.py](file://backend/app/core/config.py#L9-L47) - [backend/app/core/database.py](file://backend/app/core/database.py#L9-L39) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) 章节来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L1-L108) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L1-L150) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L1-L112) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L114) - [backend/app/core/database.py](file://backend/app/core/database.py#L9-L39) ## 核心组件 - DepartmentService:提供科室列表、树形结构、按编码/ID 查询、创建、更新、删除等能力;自动计算层级并校验删除前置条件(无子部门) - StaffService:提供员工列表、按工号/ID 查询、创建、更新、删除、按科室查询在职员工等能力 - 数据模型 Department/Staff:定义字段、枚举、索引与关系;Department 与 Staff 通过外键建立一对多关系 - API 路由:提供 REST 接口,绑定权限装饰器,调用服务层并返回统一响应格式 - 安全与配置:JWT 认证、权限校验、数据库连接池与事务管理 章节来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L13-L150) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L13-L112) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L114) - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L19-L107) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L20-L123) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110) - [backend/app/core/database.py](file://backend/app/core/database.py#L28-L39) ## 架构总览 部门与员工服务遵循“API → 服务 → 模型 → 数据库”的分层架构,配合统一响应体与权限控制,确保数据一致性与安全性。 ```mermaid sequenceDiagram participant Client as "客户端" participant API as "FastAPI 路由" participant Service as "服务层" participant DB as "数据库" Client->>API : "HTTP 请求" API->>API : "权限校验(Active/Manager)" API->>Service : "调用服务方法(参数校验)" Service->>DB : "SQL 查询/写入(异步)" DB-->>Service : "结果集/受影响行" Service-->>API : "领域对象/聚合" API-->>Client : "统一响应体(code,message,data,total/page/page_size)" ``` 图表来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L19-L107) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L20-L123) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L16-L111) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L16-L101) - [backend/app/core/database.py](file://backend/app/core/database.py#L28-L39) ## 详细组件分析 ### 部门服务 DepartmentService - 列表查询:支持按类型与启用状态过滤、分页与总数统计 - 树形结构:手动构建树,避免懒加载导致的 N+1 问题 - 创建逻辑:根据父级计算层级 level,插入后刷新实体 - 删除逻辑:先检查是否存在子部门,避免破坏树形结构 - 更新与查询:按 ID/编码查询,支持部分字段更新 ```mermaid classDiagram class DepartmentService { +get_list(db, dept_type, is_active, page, page_size) tuple +get_by_id(db, dept_id) Department? +get_by_code(db, code) Department? +create(db, dept_data) Department +update(db, dept_id, dept_data) Department? +delete(db, dept_id) bool +get_tree(db, dept_type) DepartmentTree[] } class Department { +id : int +name : string +code : string +dept_type : DeptType +parent_id : int? +level : int +sort_order : int +is_active : bool +description : string? +children : Department[] +staff : Staff[] } DepartmentService --> Department : "读写/树构建" ``` 图表来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L13-L150) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L85) 章节来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L16-L149) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L85) ### 员工服务 StaffService - 列表查询:支持按科室、状态、关键词搜索;预加载部门关系 - 详情查询:按 ID 查询并注入部门名称 - 创建/更新/删除:基础 CRUD;删除不涉及子记录级联 - 按科室查询:筛选在职员工 ```mermaid classDiagram class StaffService { +get_list(db, department_id, status, keyword, page, page_size) tuple +get_by_id(db, staff_id) Staff? +get_by_employee_id(db, employee_id) Staff? +create(db, staff_data) Staff +update(db, staff_id, staff_data) Staff? +delete(db, staff_id) bool +get_by_department(db, department_id) Staff[] } class Staff { +id : int +employee_id : string +name : string +department_id : int +position : string +title : string? +phone : string? +email : string? +base_salary : float +performance_ratio : float +status : StaffStatus +hire_date : datetime? +department : Department +assessments : Assessment[] +salary_records : SalaryRecord[] } StaffService --> Staff : "读写/关联查询" ``` 图表来源 - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L13-L112) - [backend/app/models/models.py](file://backend/app/models/models.py#L88-L114) 章节来源 - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L16-L111) - [backend/app/models/models.py](file://backend/app/models/models.py#L88-L114) ### 数据模型与关系映射 - Department 与 Staff:一对多外键关联,Department 作为父表,Staff 通过 department_id 关联 - 索引:部门表对类型与父级建立索引;员工表对部门与状态建立索引 - 枚举:科室类型、员工状态、考核状态、指标类型等 - 财务模型:DepartmentFinance 与 Department 建立一对多关系,用于科室财务核算 ```mermaid erDiagram DEPARTMENTS { int id PK string name string code UK enum dept_type int parent_id FK int level int sort_order bool is_active text description datetime created_at datetime updated_at } STAFF { int id PK string employee_id UK string name int department_id FK string position string title string phone string email numeric base_salary numeric performance_ratio enum status datetime hire_date datetime created_at datetime updated_at } DEPARTMENTS ||--o{ STAFF : "拥有" ``` 图表来源 - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L114) 章节来源 - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L114) ### API 路由与权限控制 - 部门路由:列表、树形、详情、创建、更新、删除;创建/更新/删除需管理员或经理权限 - 员工路由:列表、详情、创建、更新、删除、按科室查询;创建/更新/删除需管理员或经理权限 - 统一响应:code/message/data/total/page/page_size - 权限装饰器:get_current_active_user 与 get_current_manager_user ```mermaid sequenceDiagram participant Client as "客户端" participant DeptAPI as "部门路由" participant StaffAPI as "员工路由" participant Sec as "安全模块" participant Svc as "服务层" Client->>DeptAPI : "POST /api/v1/departments" DeptAPI->>Sec : "get_current_manager_user()" Sec-->>DeptAPI : "用户(管理员/经理)" DeptAPI->>Svc : "DepartmentService.create()" Svc-->>DeptAPI : "Department" DeptAPI-->>Client : "统一响应" Client->>StaffAPI : "POST /api/v1/staff" StaffAPI->>Sec : "get_current_manager_user()" Sec-->>StaffAPI : "用户(管理员/经理)" StaffAPI->>Svc : "StaffService.create()" Svc-->>StaffAPI : "Staff" StaffAPI-->>Client : "统一响应" ``` 图表来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L67-L80) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L81) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110) 章节来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L19-L107) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L20-L123) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110) ### 处理流程与算法 #### 部门树形构建流程 ```mermaid flowchart TD Start(["进入 get_tree"]) --> Query["查询所有部门并排序"] Query --> BuildMap["构建 id->DepartmentTree 映射"] BuildMap --> Iterate["遍历部门构造树节点"] Iterate --> HasParent{"存在父节点?"} HasParent --> |是| AppendChild["加入父节点 children"] HasParent --> |否| AddRoot["加入根节点列表"] AppendChild --> Next["下一个部门"] AddRoot --> Next Next --> Done(["返回根节点树"]) ``` 图表来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L113-L149) 章节来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L113-L149) #### 删除部门前置校验流程 ```mermaid flowchart TD Start(["进入 delete"]) --> Load["按 ID 加载部门"] Load --> Exists{"是否存在?"} Exists --> |否| Fail["返回 False"] Exists --> |是| CountChildren["统计子部门数量"] CountChildren --> HasChild{"是否有子部门?"} HasChild --> |是| Block["返回 False(不可删除)"] HasChild --> |否| Remove["删除部门并返回 True"] ``` 图表来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L96-L110) 章节来源 - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L96-L110) ## 依赖分析 - 服务层依赖模型层(ORM 映射)与数据库会话(异步) - API 层依赖服务层与安全模块(权限校验) - 配置模块提供数据库 URL、JWT 参数与分页默认值 - 数据库模块提供异步引擎与会话生命周期(commit/rollback/close) ```mermaid graph LR API_D["/api/v1/departments.py"] --> SVC_D["services/department_service.py"] API_S["/api/v1/staff.py"] --> SVC_S["services/staff_service.py"] SVC_D --> MODELS["models/models.py"] SVC_S --> MODELS MODELS --> DB["core/database.py"] API_D --> SEC["core/security.py"] API_S --> SEC CFG["core/config.py"] --> DB CFG --> SEC ``` 图表来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L1-L108) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L1-L124) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L1-L150) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L1-L112) - [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438) - [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) - [backend/app/core/config.py](file://backend/app/core/config.py#L1-L47) 章节来源 - [backend/app/core/database.py](file://backend/app/core/database.py#L9-L39) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) - [backend/app/core/config.py](file://backend/app/core/config.py#L9-L47) ## 性能考虑 - 异步数据库:使用 AsyncSession 提升并发吞吐 - 分页与统计:列表查询先统计总数再分页,避免全量扫描 - 关系预加载:员工列表预加载部门关系,减少 N+1 查询 - 索引优化:部门类型与父级、员工部门与状态建立索引 - 事务边界:每个请求会话在依赖中 commit/rollback,异常自动回滚 - 连接池:配置池大小与溢出,避免高并发下的连接争用 章节来源 - [backend/app/core/database.py](file://backend/app/core/database.py#L9-L39) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py#L26-L49) - [backend/app/models/models.py](file://backend/app/models/models.py#L82-L85) - [backend/app/models/models.py](file://backend/app/models/models.py#L112-L114) ## 故障排查指南 - 404 未找到:查询员工或部门不存在时返回 404 - 400 编码冲突:创建部门/员工时编码或工号重复 - 400 无法删除:删除部门时存在子部门 - 403 权限不足:非管理员/经理用户尝试创建/更新/删除 - 500 服务器错误:数据库异常触发回滚并抛出 章节来源 - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L62-L107) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L75-L108) - [backend/app/core/security.py](file://backend/app/core/security.py#L94-L110) - [backend/app/core/database.py](file://backend/app/core/database.py#L34-L36) ## 结论 DepartmentService 与 StaffService 通过清晰的分层与严格的权限控制,实现了部门与员工的基础管理能力,并以树形结构与分页查询满足了常见的组织管理需求。结合模型层的索引与关系设计,以及异步数据库与事务管理,系统具备良好的扩展性与稳定性。建议后续在批量导入导出、数据同步与审计日志方面继续完善。 ## 附录 ### 统一响应体与分页 - 响应体包含 code、message、data、total、page、page_size - 分页参数默认值与最大值由配置提供 章节来源 - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L49-L60) - [backend/app/core/config.py](file://backend/app/core/config.py#L31-L33) ### 数据模型枚举参考 - 科室类型:临床、医技、护理、行政、财务、后勤等 - 员工状态:在职、休假、离职、退休 - 考核状态:草稿、已提交、已审核、已确认、已驳回 - 指标类型:质量、数量、效率、服务、成本 章节来源 - [backend/app/models/models.py](file://backend/app/models/models.py#L16-L52) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L12-L45)