签入版本
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# Service 层
|
||||
|
||||
Service 层是业务逻辑层,负责实现具体的业务规则。简单 CRUD 模块继承 `BaseService` 基类,只需声明差异点即可获得完整的增删改查能力。
|
||||
|
||||
## 文件位置
|
||||
|
||||
```
|
||||
src/modules/system/position/service.py
|
||||
```
|
||||
|
||||
## 完整代码
|
||||
|
||||
```python
|
||||
"""
|
||||
岗位管理服务模块
|
||||
=============================================================
|
||||
|
||||
该模块实现了岗位管理相关的所有业务逻辑。
|
||||
"""
|
||||
|
||||
from src.common.base_service import BaseService
|
||||
from src.core.exceptions import BizError
|
||||
from src.modules.system.position.schema import PositionForm, PositionStatusForm
|
||||
from src.modules.system.position.repository import PositionRepository
|
||||
from src.modules.system.user.repository import UserRepository
|
||||
|
||||
|
||||
class PositionService(BaseService):
|
||||
"""
|
||||
岗位服务类
|
||||
|
||||
继承 BaseService 获得标准 CRUD 能力,并扩展删除前用户引用校验。
|
||||
"""
|
||||
repository = PositionRepository
|
||||
form = PositionForm
|
||||
status_form = PositionStatusForm
|
||||
model_name = "岗位"
|
||||
|
||||
@classmethod
|
||||
def before_delete(cls, ids):
|
||||
"""
|
||||
删除前校验钩子
|
||||
|
||||
检查岗位是否仍被用户引用,若被引用则拒绝删除。
|
||||
|
||||
Args:
|
||||
ids: 待删除的岗位ID列表
|
||||
|
||||
Raises:
|
||||
BizError: 岗位被用户引用时抛出
|
||||
"""
|
||||
for pid in ids:
|
||||
if UserRepository.count_by({'position_id': pid}) > 0:
|
||||
raise BizError(f"岗位ID {pid} 已被用户引用,无法删除")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 模块级代理函数:保持 router 调用兼容
|
||||
# ============================================================
|
||||
|
||||
get_position_page = PositionService.get_page
|
||||
get_position_detail = PositionService.get_detail
|
||||
get_info = PositionService.get_info
|
||||
add_position = PositionService.add
|
||||
update_position = PositionService.update
|
||||
delete_positions = PositionService.remove
|
||||
update_position_status = PositionService.update_status
|
||||
get_position_list = PositionService.get_list
|
||||
```
|
||||
|
||||
## 代码解析
|
||||
|
||||
### 必须声明的属性
|
||||
|
||||
```python
|
||||
repository = PositionRepository # 关联的 Repository 类
|
||||
form = PositionForm # 新增/更新表单校验类
|
||||
status_form = PositionStatusForm # 状态更新表单校验类
|
||||
model_name = "岗位" # 业务对象名称,用于错误提示
|
||||
```
|
||||
|
||||
### 表单校验
|
||||
|
||||
`BaseService` 通过 `form` 和 `status_form` 属性自动执行表单校验:
|
||||
|
||||
- `add()` / `update()` 时使用 `form` 校验
|
||||
- `update_status()` 时使用 `status_form` 校验
|
||||
- 校验失败自动抛出 `BizError`
|
||||
|
||||
### 生命周期钩子
|
||||
|
||||
`BaseService` 提供以下钩子方法,子类可按需覆盖:
|
||||
|
||||
| 钩子 | 触发时机 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `before_add(form)` | 新增操作前 | 可返回额外写入字段 |
|
||||
| `after_add(obj)` | 新增操作后 | 用于缓存清理等 |
|
||||
| `before_update(form, obj)` | 更新操作前 | 可返回额外更新字段 |
|
||||
| `after_update(obj)` | 更新操作后 | 用于缓存清理等 |
|
||||
| `before_delete(ids)` | 删除操作前 | 抛出 BizError 中止删除 |
|
||||
| `after_delete(count)` | 删除操作后 | 记录审计日志等 |
|
||||
| `_enrich_page_records(records)` | 分页富化时 | 追加关联数据 |
|
||||
| `_detail_dict(obj)` | 详情序列化时 | 自定义返回字段 |
|
||||
|
||||
### 模块级代理函数
|
||||
|
||||
```python
|
||||
# 模块级代理函数:保持 router 调用兼容
|
||||
get_position_page = PositionService.get_page
|
||||
get_position_detail = PositionService.get_detail
|
||||
add_position = PositionService.add
|
||||
update_position = PositionService.update
|
||||
delete_positions = PositionService.remove
|
||||
update_position_status = PositionService.update_status
|
||||
get_position_list = PositionService.get_list
|
||||
```
|
||||
|
||||
模块级代理函数将 Service 类方法暴露为模块级函数,供 Router 层调用。Router 层直接导入函数,不依赖 Service 实例。
|
||||
|
||||
## 基类提供的通用方法
|
||||
|
||||
| 方法 | 说明 |
|
||||
|:----|:----|
|
||||
| `get_page(params)` | 分页查询(params 包含 pageNo/pageSize 及筛选条件) |
|
||||
| `get_detail(id)` | 查询详情(返回字典) |
|
||||
| `get_info(id)` | 查询模型对象(内部使用) |
|
||||
| `add(data)` | 新增记录(含表单校验 + 钩子) |
|
||||
| `update(data)` | 更新记录(含表单校验 + 存在性校验 + 钩子) |
|
||||
| `remove(ids)` | 批量软删除(逗号分隔 ID 字符串) |
|
||||
| `update_status(data)` | 更新状态(含状态表单校验) |
|
||||
| `get_list(params)` | 无分页列表查询(用于下拉选择) |
|
||||
|
||||
## 开发要点
|
||||
|
||||
1. **必须声明 `repository`**:基类所有数据访问方法依赖此属性
|
||||
2. **声明 `form` 和 `status_form`**:用于自动表单校验
|
||||
3. **声明 `model_name`**:用于错误提示信息
|
||||
4. **删除前校验用 `before_delete` 钩子**:抛出 BizError 中止操作
|
||||
5. **必须创建模块级代理函数**:供 Router 层调用
|
||||
6. **Service 层不直接读取 request**:参数通过函数传入(dict 类型)
|
||||
|
||||
## 总结
|
||||
|
||||
Service 层继承 `BaseService` 获得通用 CRUD 能力,只需声明差异点(`repository`/`form`/`model_name`)并覆写钩子方法。必须创建模块级代理函数供 Router 层调用,Service 层不直接读取 request,入参为数据字典,出参为纯数据,业务失败通过 `raise BizError` 表达。
|
||||
Reference in New Issue
Block a user