Skip to content

开发规范 ​

统一响应结构 ​

所有 HTTP 接口都返回同一个结构 ResponseSchema,无论成功与否,前端都能用同一套逻辑解析:

json
{
  "code": 0,
  "msg": "操作成功",
  "data": { ... },
  "status_code": 200,
  "success": true
}

字段含义:

  • code:业务状态码,0 表示成功,非 0 表示业务失败(详见下文错误码)
  • msg:对用户的提示信息,失败时用于直接展示
  • data:业务数据,无数据时为空
  • status_code:HTTP 状态码
  • success:是否成功,与 code === 0 等价

约定与机制:

  • 后端统一用 SuccessResponse(data=..., msg=...) 返回成功,用 ErrorResponse 或抛出 CustomException 返回失败,不要在业务代码里直接拼 dict。
  • 响应体在输出时会自动完成两件事:字段名由 snake_case 转为小驼峰(如 dept_name → deptName),时间字段格式化为 YYYY-MM-DD HH:MM:SS。所以后端用 Python 习惯的蛇形命名,前端拿到的永远是驼峰命名。
  • 文件下载、流式响应(SSE)走独立的 UploadFileResponse / StreamResponse,不套 ResponseSchema。

业务状态码 ​

错误码集中在 framework/web/status_code.py 的 RET 枚举,分为三段区间:

区间含义示例
0 / 200 段成功OK=0、SUCCESS=200、CREATED=201
400–600HTTP 标准错误UNAUTHORIZED=401、FORBIDDEN=403、NOT_FOUND=404
4000+自定义业务码DATAEXIST=4003、PARAMERR=4103、令牌相关 4504/4505、权限相关 4512 等

约定:

  • code === 0 即成功,前端以此作为唯一判断依据,不要依赖 HTTP 200。
  • 抛出业务异常统一用 raise CustomException(code=RET.XXX.code, msg="可读的提示"),由全局异常处理器归一化为 ErrorResponse,避免把 Python 堆栈直接抛给前端。

异常处理约定 ​

全局异常处理器(framework/web/exception.py):业务异常通过 CustomException(code, msg) 抛出,框架统一捕获并返回 ErrorResponse,无需在 controller 中手动构造错误响应。

开发时只在真正需要区分业务语义时抛 CustomException,其余交给框架。

python
from app.framework.web.exception import CustomException
from app.framework.web.status_code import RET

if not exists:
    raise CustomException(code=RET.DATAERR.code, msg="数据不存在")

分页约定 ​

分页结果统一返回 PageResultSchema:

字段说明
pageNo当前页码(默认 1)
pageSize每页大小(默认 10)
total总记录数
hasNext是否有下一页
items当前页数据列表

关系型表的分页请使用 CRUDBase.page(数据库层 OFFSET/LIMIT);仅在数据源无法 SQL 分页(如内存列表、Redis 列表)时使用 PageUtil.paginate。

命名规范 ​

后端接口按模块组织,控制器使用 APIRouter(prefix="/xxx", tags=["模块-功能"]),并遵循固定的动作命名,便于前端和权限系统识别:

动作方法 + 路径说明
列表GET /list扁平列表
树 / 详情GET /tree、GET /get、GET /detail/{id}查询类
新增POST /create
修改PUT /update
删除DELETE /delete、DELETE /delete-list单删 / 批量删(ids 逗号分隔)
状态批量PATCH /status/batch启停等批量操作

命名规范与示例

对象规范示例
路由类XxxRouterDictTypeRouter
分页查询参数XxxQueryParam(@dataclass,用 Query)DictTypeQueryParam
响应模型XxxOutSchema(继承 CamelModel)DictTypeOutSchema
创建/更新模型XxxCreateSchema / XxxUpdateSchemaDictTypeCreateSchema
分页接口端点 /page,接收 XxxQueryParamGET /dict-type/page

接口声明示例:

python
@DictTypeRouter.get(
    "/get",
    summary="获取字典类型详情",
    response_model=ResponseSchema[DictTypeOutSchema],
)
async def get_type_detail_controller(
    id: Annotated[int, Query(description="字典类型ID")],
    auth: Annotated[AuthSchema, Depends(AuthPermission(["system:dict:query"]))],
) -> JSONResponse:
    result_dict = await DictTypeService(auth).detail(id=id)
    return SuccessResponse(data=result_dict, msg="获取字典类型详情成功")