Skip to content

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 表达。

小蚂蚁云团队 · 提供技术支持