playEdu自定义接口需要满足的格式

二次开发playEdu时,自定义API接口前台react接收报错

奇怪的是,报错中已包含了正确的返回值

怀疑是返回值格式不符合react要求,找到react中定义接口请求参数的代码:src\api\internal\httpClient.ts

TypeScript 复制代码
import axios, { Axios, AxiosResponse } from "axios";
import { message } from "antd";
import { getToken, clearToken } from "../../utils/index";

const GoLogin = () => {
  clearToken();
  window.location.href = "/login";
};

const GoError = (code: number) => {
  // window.location.href = "/error?code=" + code;
};

export class HttpClient {
  axios: Axios;

  constructor(url: string) {
    this.axios = axios.create({
      baseURL: url,
      timeout: 15000,
      withCredentials: false,
      headers: {
        Accept: "application/json",
      },
    });

    //拦截器注册
    this.axios.interceptors.request.use(
      (config) => {
        const token = getToken();
        token && (config.headers.Authorization = "Bearer " + token);
        return config;
      },
      (err) => {
        return Promise.reject(err);
      }
    );

    this.axios.interceptors.response.use(
      (response: AxiosResponse) => {
        let code = response.data.code; //业务返回代码
        let msg = response.data.msg; //错误消息

        if (code === 0) {
          return Promise.resolve(response);
        } else if (code === 404) {
          message.error(msg);
          // 跳转到404页面
          GoError(404);
        } else if (code === 403) {
          message.error(msg);
          // 跳转到无权限页面
          GoError(403);
        } else if (code === 429) {
          message.error(msg);
          // 跳转到429页面
          GoError(429);
        } else if (code === 500) {
          message.error(msg);
          // 跳转到500异常页面
          GoError(500);
        } else {
          GoError(code);
          message.error(msg);
        }
        return Promise.reject(response);
      },
      // 当http的状态码非0
      (error) => {
        let status = error.response.status;
        if (status === 401) {
          message.error("请重新登录");
          GoLogin();
        } else if (status === 404) {
          // 跳转到404页面
          GoError(404);
        } else if (status === 403) {
          // 跳转到无权限页面
          GoError(403);
        } else if (status === 429) {
          // 跳转到429页面
          GoError(429);
        } else if (status === 500) {
          // 跳转到500异常页面
          GoError(500);
        } else {
          GoError(status);
        }
        return Promise.reject(error.response);
      }
    );
  }

  get(url: string, params: object) {
    return new Promise((resolve, reject) => {
      this.axios
        .get(url, {
          params: params,
        })
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err.data);
        });
    });
  }

  destroy(url: string) {
    return new Promise((resolve, reject) => {
      this.axios
        .delete(url)
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err.data);
        });
    });
  }

  post(url: string, params: object) {
    return new Promise((resolve, reject) => {
      this.axios
        .post(url, params)
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err.data);
        });
    });
  }

  put(url: string, params: object) {
    return new Promise((resolve, reject) => {
      this.axios
        .put(url, params)
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err.data);
        });
    });
  }

  request(config: object) {
    return new Promise((resolve, reject) => {
      this.axios
        .request(config)
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err.data);
        });
    });
  }
}

const APP_URL = import.meta.env.VITE_APP_URL || "";

const client = new HttpClient(APP_URL);

export default client;

虽然我的判断正确,但是我肉眼没有找到具体代码行的证据,绕了几个弯子,在代码中加入debugger单步执行也没有找到原因。

这个过程中我了解了vscode中前台单步调试方法,在需要调试的位置加入一行debugger; 谷歌浏览器访问开发页面,当谷歌执行到debugger;代码就会暂停执行,等待用户调试。

把上述代码交给deepseek,得到答案:

问题分析

在你的拦截器代码中:

typescript

复制代码
this.axios.interceptors.response.use(
  (response: AxiosResponse) => {
    let code = response.data.code; //业务返回代码
    let msg = response.data.msg; //错误消息

    if (code === 0) {
      return Promise.resolve(response);  // ✅ 只有 code === 0 才成功
    } else {
      // 其他所有情况都进入 reject
      return Promise.reject(response);   // ❌ 这就是问题所在!
    }
  }
);

问题根源

  1. 你的接口返回的业务码不是 0

  2. 即使 HTTP 状态码是 200,只要业务码 code !== 0,拦截器就会 Promise.reject(response)

  3. 这导致正确的数据进入了错误处理流程

这个问题是因为java编写的自定义后台api接口返回值格式不规范:

java 复制代码
@BackendPermission(slug = BPermissionConstant.USER_LEARN)
@GetMapping("/progress")
@Log(title = "学员-学习任务完成度", businessType = BusinessTypeConstant.GET)
public ResponseEntity<List<StudentProgressDTO>> getAllStudentProgress() {
    List<StudentProgressDTO> progressList = progressService.getAllStudentProgress();
    return ResponseEntity.ok(progressList);
}

按照规范正确的写法:

java 复制代码
@BackendPermission(slug = BPermissionConstant.USER_LEARN)
@GetMapping("/progress")
@Log(title = "学员-学习任务完成度", businessType = BusinessTypeConstant.GET)
public JsonResponse getAllStudentProgress() {
    List<StudentProgressDTO> progressList = progressService.getAllStudentProgress();
    return JsonResponse.data(progressList);
}

以下是返回值格式定义:

java 复制代码
package xyz.playedu.common.types;

import lombok.Data;

@Data
public class JsonResponse {

    private Integer code;
    private String msg;
    private Object data;

    public JsonResponse(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
相关推荐
IT_陈寒3 分钟前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
xingpanvip4 分钟前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua
@PHARAOH16 分钟前
WHAT - GitLens supercharged 插件
前端
TT模板36 分钟前
苹果cms整合西瓜播放器XGplayer插件支持跳过片头尾
前端·html5
Wect1 小时前
React 性能优化精讲
前端·react.js·性能优化
追风筝的人er2 小时前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
前端·vue.js·后端
无敌的黑星星2 小时前
Java8 CompletableFuture 实战指南
linux·前端·python
雁鸣零落2 小时前
如何在 Chrome 中查看其他浏览器的书签?书签空间订阅与侧边栏只读切换指南
前端·chrome·edge浏览器
hpoenixf3 小时前
一天上线 + 零返工:我如何给复杂前端需求建立“安全感”
前端
广州华水科技3 小时前
单北斗GNSS变形监测系统在水利工程安全保障中的应用与优势分析
前端