Files
djangoadmin-wiki/DjangoAdmin_Django_AntdVue/zh/volume4/integration/api-contract.md
T
2026-09-12 23:12:15 +08:00

4.4 KiB
Raw Blame History

接口响应规范

:::tip 说明 后端所有接口统一返回 R.ok() / R.failed() 格式的 JSON 响应,前端通过 VAxios 的 transformRequestData 拦截器统一解包处理。 :::

响应格式

成功响应

{
 "code": 0,
 "data": { "id": 1, "name": "测试岗位", "status": 1 },
 "msg": "操作成功",
 "ok": true
}

失败响应

{
 "code": 1,
 "data": null,
 "msg": "岗位名称不能重复",
 "ok": false
}

分页响应

{
    "code": 0,
    "data": {
        "records": [
            { "id": 1, "name": "案例1", "status": 1 },
            { "id": 2, "name": "案例2", "status": 2 }
        ],
        "total": 100,
        "size": 10,
        "current": 1,
        "pages": 10
    },
    "msg": "操作成功",
    "ok": true
}

后端实现

位于 utils/R.py:

from django.http import JsonResponse

def ok(data=None, msg="操作成功", code=0, **kwargs):
    response_body = {"code": code, "data": data, "msg": msg, "ok": True}
    if kwargs:
        response_body.update(kwargs)
    return JsonResponse(data=response_body)

def failed(msg="操作失败", code=1, data=None, **kwargs):
    response_body = {"code": code, "data": data, "msg": msg, "ok": False}
    if kwargs:
        response_body.update(kwargs)
    return JsonResponse(data=response_body)

使用示例

# 成功
return R.ok(data=user_info)
return R.ok(data=page_data)  # 分页
return R.ok(msg="添加成功")

# 失败
return R.failed(msg="用户名已存在")
return R.failed("参数错误")

前端拦截器

VAxios 的 transformRequestData 统一解包响应:

// src/utils/http/axios/index.ts
transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
    const { code, data, msg } = res.data;

    // 业务成功(code === 0):直接返回 data
    if (code === ResultEnum.SUCCESS) {
        return data;
    }

    // 业务失败(code === 1):弹出错误提示
    if (code === ResultEnum.ERROR) {
        ElMessage.error(msg);
        throw new Error(msg);
    }

    // 登录超时(code === 401):弹出确认框,跳转登录页
    if (code === ResultEnum.TIMEOUT) {
        ElMessageBox.confirm('登录身份已失效,请重新登录!', '提示', {
            confirmButtonText: '确定',
            showCancelButton: false,
            type: 'warning',
        }).then(() => {
            storage.clear();
            window.location.href = '/login';
        });
        throw new Error(msg);
    }
},

解包后调用方拿到的是 data 字段内容:

// 普通接口:data 就是业务数据
const result = await exampleAdd(formData);
// result = undefined (add 接口无返回数据)

// 分页接口:data 包含 records、total 等
const result = await getExamplePage(params);
// result = { records: [...], total: 100, size: 10, current: 1, pages: 10 }

字段说明

字段 类型 说明
code number 业务码:0=成功,1=失败,401=登录超时
data any 业务数据
total number 分页总数(仅分页接口)
msg string 提示消息
ok boolean 业务是否成功

错误码规范

code 说明 前端行为
0 成功 返回 data
1 业务失败 ElMessage.error(msg) + throw
401 未登录或 Token 过期 弹出确认框 → 跳转登录页

HTTP 状态码始终为 200,业务成功/失败通过 code 字段区分。

前端错误展示

业务错误通过 ElMessage.error 弹出提示,无需组件手动处理:

// 组件中直接调用,错误由拦截器处理
try {
    await positionAdd(formData);
    message('操作成功');
} catch (e) {
    // 拦截器已弹出 ElMessage.error,此处可选处理
}

:::tip 温馨提示 HTTP 状态码始终为 200,业务成功/失败通过 code 字段区分。这避免了 HTTP 状态码与业务状态码的混淆。前端拦截器统一处理错误提示,业务代码只需处理成功逻辑。 :::

总结

接口响应规范统一使用 R.ok()/R.failed() 格式,code=0 表示成功返回 data,code=1 表示失败弹出 msg,code=401 表示登录超时跳转登录页。前端 VAxios 的 transformRequestData 拦截器统一解包,调用方直接使用业务数据。