Files
easygoadmin-wiki/EasyGoAdmin_Iris_NaiveVue/zh/api-spec/response.md
T
2026-10-20 21:19:44 +08:00

7.0 KiB
Raw Blame History

8.1 统一响应格式

:::tip 概述 所有接口返回统一的 JSON 结构,前端可据此判断请求结果。响应由 response\Result 类构造,保证全系统格式一致。 :::

响应结构

interface ApiResponse {
    code: number;   // 状态码:0=成功,其他=失败
    ok: boolean;    // 是否成功
    msg: string;    // 提示信息
    data: any;      // 响应数据
}

状态码定义

code 含义 ok 说明
0 成功 true 业务成功
1 业务失败 false 通用业务错误(参数错误、业务校验失败等)
401 未授权 false Token 缺失/无效/过期
403 禁止访问 false 权限不足
404 数据不存在 false 查询的记录不存在
422 参数验证失败 false Validate 校验不通过

成功响应

普通成功

{
    "code": 0,
    "ok": true,
    "msg": "操作成功",
    "data": {
        "id": 1,
        "username": "admin",
        "realname": "管理员",
        "createTime": "2026-01-01 00:00:00"
    }
}

带自定义消息

{
    "code": 0,
    "ok": true,
    "msg": "添加成功",
    "data": { "id": 42 }
}

data 为 null

{
    "code": 0,
    "ok": true,
    "msg": "修改成功",
    "data": null
}

data 为数组

{
    "code": 0,
    "ok": true,
    "msg": "操作成功",
    "data": [
        { "id": 1, "name": "选项一" },
        { "id": 2, "name": "选项二" }
    ]
}

分页响应

{
    "code": 0,
    "ok": true,
    "msg": "操作成功",
    "data": {
        "records": [
            { "id": 1, "username": "admin", "createTime": "2026-01-01 00:00:00" },
            { "id": 2, "username": "user1", "createTime": "2026-01-02 00:00:00" }
        ],
        "total": 100,
        "size": 20,
        "current": 1,
        "pages": 5
    }
}

分页参数

字段 类型 说明
records array 当前页数据列表
total number 总记录数
size number 每页条数
current number 当前页码
pages number 总页数(ceil(total / size))

失败响应

通用业务失败

{
    "code": 1,
    "ok": false,
    "msg": "用户名已存在",
    "data": null
}

参数验证失败

{
    "code": 1,
    "ok": false,
    "msg": "参数验证失败",
    "data": "用户名不能为空"
}

批量验证失败

{
    "code": 1,
    "ok": false,
    "msg": "参数验证失败",
    "data": [
        "用户名不能为空",
        "姓名不能为空"
    ]
}

数据不存在

{
    "code": 1,
    "ok": false,
    "msg": "数据不存在",
    "data": null
}

未授权(Token 问题)

{
    "code": 401,
    "ok": false,
    "msg": "token已过期",
    "data": null
}

权限不足

{
    "code": 403,
    "ok": false,
    "msg": "无访问权限",
    "data": null
}

字段说明

字段 类型 说明
code number 状态码,0=成功
ok boolean 是否成功
msg string 提示信息
data any 响应数据,失败时通常为 null 或错误详情

分页字段

字段 类型 说明
data.records array 分页数据列表
data.total number 总记录数
data.size number 每页条数
data.current number 当前页码
data.pages number 总页数

后端 Result 类

文件: extend/response/Result.php

方法清单

方法 说明 code ok
success($data, $msg) 成功响应 0 true
page($records, $total, $current, $size) 分页响应 0 true
fail($msg, $code, $data) 失败响应 1 false
unauthorized($msg) 未授权 401 false
forbidden($msg) 禁止访问 403 false
notFound($msg) 数据不存在 404 false
validateError($errors) 验证失败 422 false

使用示例

// Controller 中通过 BaseController 调用
$this->success($data, '操作成功');
$this->success(['id' => $id], '添加成功');
$this->fail('用户名已存在');
$this->fail('缺少id参数', 1);

// 直接调用 Result 类
\response\Result::success($data);
\response\Result::fail('错误信息');
\response\Result::unauthorized('未授权');
\response\Result::forbidden('无权限');
\response\Result::notFound('数据不存在');
\response\Result::validateError('用户名不能为空');

驼峰自动转换

响应数据自动从 snake_case 转为 camelCase:

数据库字段 响应字段
create_time createTime
user_name userName
is_delete isDelete
dept_id deptId

可通过 config/api.php 的 camel_snake_convert 配置关闭。

前端响应处理

Axios 响应拦截器

// src/utils/http/axios/index.ts

axios.interceptors.response.use(
    response => {
        const { code, data, msg } = response.data;

        // 成功
        if (code === 0) {
            return data;
        }

        // Token 过期
        if (code === 401) {
            localStorage.clear();
            router.push('/login');
            return Promise.reject(new Error(msg));
        }

        // 权限不足
        if (code === 403) {
            ElMessage.error(msg || '无访问权限');
            return Promise.reject(new Error(msg));
        }

        // 其他业务错误
        ElMessage.error(msg || '操作失败');
        return Promise.reject(new Error(msg));
    },
    error => {
        ElMessage.error('网络错误');
        return Promise.reject(error);
    }
);

处理分页数据

const fetchData = async () => {
    const res = await getUserPage({ pageNo: 1, pageSize: 20 });
    // res 已经是 data 部分(拦截器已解包)
    tableData.value = res.records;
    total.value = res.total;
};

处理导入结果

const handleImport = async (file) => {
    const res = await importUsers(file);
    // res = { count: 8, errors: [{ row: 3, reason: "..." }] }
    if (res.errors.length === 0) {
        ElMessage.success(`成功导入 ${res.count} 条`);
    } else {
        ElMessage.warning(`成功 ${res.count} 条,失败 ${res.errors.length} 条`);
    }
};

常见响应场景汇总

场景 code msg data
查询成功 0 操作成功 数据对象/数组
分页成功 0 操作成功 {records, total, size, current, pages}
新增成功 0 添加成功 {id: 42}
修改成功 0 修改成功 null
删除成功 0 删除成功 null
业务失败 1 具体错误信息 null
参数验证失败 1 参数验证失败 错误字符串或数组
Token 过期 401 token已过期 null
无权限 403 无访问权限 null
数据不存在 404 数据不存在 null