diff --git a/src/components/Layout/index.jsx b/src/components/Layout/index.jsx
index 5f87092..996f98e 100644
--- a/src/components/Layout/index.jsx
+++ b/src/components/Layout/index.jsx
@@ -9,7 +9,9 @@ import "./index.css";
const Layout = ({ children }) => {
const dispatch = useDispatch();
const [isCollapsed, setIsCollapsed] = useState(true);
- const loading = useSelector((state) => state.loading.value);
+ const globalLoading = useSelector(
+ (state) => state?.loading?.effect?.globalLoading
+ );
const studentInfo = useSelector((state) => state.student.studentInfo);
const queryLoginStudentInfo = async () => {
@@ -27,7 +29,7 @@ const Layout = ({ children }) => {
return (
-
+
{children}
diff --git a/src/pages/CompanyJobsPage/index.jsx b/src/pages/CompanyJobsPage/index.jsx
index c4ff752..f1f93aa 100644
--- a/src/pages/CompanyJobsPage/index.jsx
+++ b/src/pages/CompanyJobsPage/index.jsx
@@ -57,7 +57,8 @@ const CompanyJobsPage = () => {
pageSize: PAGE_SIZE,
isActive: true,
});
- if (res.success) {
+
+ if (res?.success) {
const mappedJobs = mapJobList(res.data);
setJobs((prevList) => {
const newList = [...prevList, ...mappedJobs];
diff --git a/src/services/api.js b/src/services/api.js
index 35c94da..b248fd1 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -1,211 +1,464 @@
-import request from '@/utils/request';
+import request from "@/utils/request";
// Student API
export const studentAPI = {
// Get current logged-in student
- getCurrentStudent: () => request.get('/api/students/me'),
-
+ getCurrentStudent: async () =>
+ request({
+ url: "/api/students/me",
+ method: "GET",
+ }),
+
// Get student list
- getList: (params) => request.get('/api/students', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/students",
+ method: "GET",
+ params,
+ }),
+
// Get student detail
- getDetail: (id) => request.get(`/api/students/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/students/${id}`,
+ method: "GET",
+ }),
+
// Create student
- create: (data) => request.post('/api/students', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/students",
+ method: "POST",
+ data,
+ }),
+
// Update student
- update: (id, data) => request.put(`/api/students/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/students/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Get student progress
- getProgress: (id) => request.get(`/api/students/${id}/progress`),
+ getProgress: async (id) =>
+ request({
+ url: `/api/students/${id}/progress`,
+ method: "GET",
+ }),
};
// Course API
export const courseAPI = {
// Get course list
- getList: (params) => request.get('/api/courses', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/courses",
+ method: "GET",
+ params,
+ }),
+
// Get course detail
- getDetail: (id) => request.get(`/api/courses/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/courses/${id}`,
+ method: "GET",
+ }),
+
// Create course
- create: (data) => request.post('/api/courses', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/courses",
+ method: "POST",
+ data,
+ }),
+
// Update course
- update: (id, data) => request.put(`/api/courses/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/courses/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Enroll student in course
- enroll: (courseId, studentId) =>
- request.post(`/api/courses/${courseId}/enroll`, { studentId }),
-
+ enroll: async (courseId, studentId) =>
+ request({
+ url: `/api/courses/${courseId}/enroll`,
+ method: "POST",
+ data: { studentId },
+ }),
+
// Update enrollment progress
- updateEnrollment: (courseId, enrollmentId, data) =>
- request.put(`/api/courses/${courseId}/enrollment/${enrollmentId}`, data),
-
+ updateEnrollment: async (courseId, enrollmentId, data) =>
+ request({
+ url: `/api/courses/${courseId}/enrollment/${enrollmentId}`,
+ method: "PUT",
+ data,
+ }),
+
// Get course students
- getStudents: (id) => request.get(`/api/courses/${id}/students`),
+ getStudents: async (id) =>
+ request({
+ url: `/api/courses/${id}/students`,
+ method: "GET",
+ }),
};
// Job API
export const jobAPI = {
// Get job list
- getList: (params) => request.get('/api/jobs', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/jobs",
+ method: "GET",
+ params,
+ }),
+
// Get job detail
- getDetail: (id) => request.get(`/api/jobs/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/jobs/${id}`,
+ method: "GET",
+ }),
+
// Create job
- create: (data) => request.post('/api/jobs', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/jobs",
+ method: "POST",
+ data,
+ }),
+
// Update job
- update: (id, data) => request.put(`/api/jobs/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/jobs/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Get recommended jobs for student
- getRecommended: (studentId) => request.get(`/api/jobs/recommend/${studentId}`),
+ getRecommended: async (studentId) =>
+ request({
+ url: `/api/jobs/recommend/${studentId}`,
+ method: "GET",
+ }),
};
// Company API
export const companyAPI = {
// Get company list
- getList: (params) => request.get('/api/companies', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/companies",
+ method: "GET",
+ params,
+ }),
+
// Get company detail
- getDetail: (id) => request.get(`/api/companies/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/companies/${id}`,
+ method: "GET",
+ }),
+
// Create company
- create: (data) => request.post('/api/companies', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/companies",
+ method: "POST",
+ data,
+ }),
+
// Update company
- update: (id, data) => request.put(`/api/companies/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/companies/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Get company jobs
- getJobs: (id) => request.get(`/api/companies/${id}/jobs`),
+ getJobs: async (id) =>
+ request({
+ url: `/api/companies/${id}/jobs`,
+ method: "GET",
+ }),
};
// Resume API
export const resumeAPI = {
// Get resume list
- getList: (params) => request.get('/api/resumes', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/resumes",
+ method: "GET",
+ params,
+ }),
+
// Get resume detail
- getDetail: (id) => request.get(`/api/resumes/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/resumes/${id}`,
+ method: "GET",
+ }),
+
// Create resume
- create: (data) => request.post('/api/resumes', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/resumes",
+ method: "POST",
+ data,
+ }),
+
// Update resume
- update: (id, data) => request.put(`/api/resumes/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/resumes/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Delete resume
- delete: (id) => request.delete(`/api/resumes/${id}`),
-
+ delete: async (id) =>
+ request({
+ url: `/api/resumes/${id}`,
+ method: "DELETE",
+ }),
+
// Get student's active resume
- getStudentActive: (studentId) =>
- request.get(`/api/resumes/student/${studentId}/active`),
+ getStudentActive: async (studentId) =>
+ request({
+ url: `/api/resumes/student/${studentId}/active`,
+ method: "GET",
+ }),
};
// Interview API
export const interviewAPI = {
// Get interview list
- getList: (params) => request.get('/api/interviews', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/interviews",
+ method: "GET",
+ params,
+ }),
+
// Get interview detail
- getDetail: (id) => request.get(`/api/interviews/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/interviews/${id}`,
+ method: "GET",
+ }),
+
// Schedule interview
- schedule: (data) => request.post('/api/interviews', data),
-
+ schedule: async (data) =>
+ request({
+ url: "/api/interviews",
+ method: "POST",
+ data,
+ }),
+
// Update interview
- update: (id, data) => request.put(`/api/interviews/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/interviews/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Cancel interview
- cancel: (id, reason) =>
- request.post(`/api/interviews/${id}/cancel`, { reason }),
-
+ cancel: async (id, reason) =>
+ request({
+ url: `/api/interviews/${id}/cancel`,
+ method: "POST",
+ data: { reason },
+ }),
+
// Submit feedback
- submitFeedback: (id, data) =>
- request.post(`/api/interviews/${id}/feedback`, data),
-
+ submitFeedback: async (id, data) =>
+ request({
+ url: `/api/interviews/${id}/feedback`,
+ method: "POST",
+ data,
+ }),
+
// Get student interview history
- getStudentHistory: (studentId) =>
- request.get(`/api/interviews/student/${studentId}/history`),
+ getStudentHistory: async (studentId) =>
+ request({
+ url: `/api/interviews/student/${studentId}/history`,
+ method: "GET",
+ }),
};
// Class API
export const classAPI = {
// Get class list
- getList: (params) => request.get('/api/classes', { params }),
-
+ getList: async (params) =>
+ request({
+ url: "/api/classes",
+ method: "GET",
+ params,
+ }),
+
// Get class detail
- getDetail: (id) => request.get(`/api/classes/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/classes/${id}`,
+ method: "GET",
+ }),
+
// Create class
- create: (data) => request.post('/api/classes', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/classes",
+ method: "POST",
+ data,
+ }),
+
// Update class
- update: (id, data) => request.put(`/api/classes/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/classes/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Get class students
- getStudents: (id) => request.get(`/api/classes/${id}/students`),
-
+ getStudents: async (id) =>
+ request({
+ url: `/api/classes/${id}/students`,
+ method: "GET",
+ }),
+
// Add student to class
- addStudent: (classId, studentId) =>
- request.post(`/api/classes/${classId}/students`, { studentId }),
-
+ addStudent: async (classId, studentId) =>
+ request({
+ url: `/api/classes/${classId}/students`,
+ method: "POST",
+ data: { studentId },
+ }),
+
// Remove student from class
- removeStudent: (classId, studentId) =>
- request.delete(`/api/classes/${classId}/students/${studentId}`),
-
+ removeStudent: async (classId, studentId) =>
+ request({
+ url: `/api/classes/${classId}/students/${studentId}`,
+ method: "DELETE",
+ }),
+
// Get class statistics
- getStats: (id) => request.get(`/api/classes/${id}/stats`),
+ getStats: async (id) =>
+ request({
+ url: `/api/classes/${id}/stats`,
+ method: "GET",
+ }),
};
// Learning Stage API
export const stageAPI = {
// Get all stages
- getList: () => request.get('/api/stages'),
-
+ getList: async () =>
+ request({
+ url: "/api/stages",
+ method: "GET",
+ }),
+
// Get stage detail
- getDetail: (id) => request.get(`/api/stages/${id}`),
-
+ getDetail: async (id) =>
+ request({
+ url: `/api/stages/${id}`,
+ method: "GET",
+ }),
+
// Create stage
- create: (data) => request.post('/api/stages', data),
-
+ create: async (data) =>
+ request({
+ url: "/api/stages",
+ method: "POST",
+ data,
+ }),
+
// Update stage
- update: (id, data) => request.put(`/api/stages/${id}`, data),
-
+ update: async (id, data) =>
+ request({
+ url: `/api/stages/${id}`,
+ method: "PUT",
+ data,
+ }),
+
// Delete stage
- delete: (id) => request.delete(`/api/stages/${id}`),
-
+ delete: async (id) =>
+ request({
+ url: `/api/stages/${id}`,
+ method: "DELETE",
+ }),
+
// Get stage courses
- getCourses: (id) => request.get(`/api/stages/${id}/courses`),
-
+ getCourses: async (id) =>
+ request({
+ url: `/api/stages/${id}/courses`,
+ method: "GET",
+ }),
+
// Get stage students
- getStudents: (id) => request.get(`/api/stages/${id}/students`),
-
+ getStudents: async (id) =>
+ request({
+ url: `/api/stages/${id}/students`,
+ method: "GET",
+ }),
+
// Advance student to next stage
- advanceStudent: (stageId, studentId) =>
- request.post(`/api/stages/${stageId}/advance/${studentId}`),
+ advanceStudent: async (stageId, studentId) =>
+ request({
+ url: `/api/stages/${stageId}/advance/${studentId}`,
+ method: "POST",
+ }),
};
// Auth API
export const authAPI = {
// Login
- login: (data) => request.post('/api/auth/login', data),
-
+ login: async (data) =>
+ request({
+ url: "/api/auth/login",
+ method: "POST",
+ data,
+ }),
+
// Register
- register: (data) => request.post('/api/auth/register', data),
-
+ register: async (data) =>
+ request({
+ url: "/api/auth/register",
+ method: "POST",
+ data,
+ }),
+
// Logout
- logout: () => request.post('/api/auth/logout'),
-
+ logout: async () =>
+ request({
+ url: "/api/auth/logout",
+ method: "POST",
+ }),
+
// Get current user
- getCurrentUser: () => request.get('/api/auth/me'),
+ getCurrentUser: async () =>
+ request({
+ url: "/api/auth/me",
+ method: "GET",
+ }),
};
// Health Check
export const healthAPI = {
- check: () => request.get('/health'),
- checkDB: () => request.get('/health/db'),
-};
\ No newline at end of file
+ check: async () =>
+ request({
+ url: "/health",
+ method: "GET",
+ }),
+ checkDB: async () =>
+ request({
+ url: "/health/db",
+ method: "GET",
+ }),
+};
diff --git a/src/services/companyJobs.js b/src/services/companyJobs.js
index b23c6d5..d4b308a 100644
--- a/src/services/companyJobs.js
+++ b/src/services/companyJobs.js
@@ -2,9 +2,17 @@ import request from "@/utils/request";
// 获取企业内推岗位
export async function getJobsList(params) {
- return request.get("/api/jobs", { params });
+ return request({
+ url: `/api/jobs`,
+ method: "GET",
+ params,
+ });
}
// 获取企业内推岗位面试
export async function getInterviewsList(params) {
- return request.get("/api/interviews", { params });
+ return request({
+ url: `/api/interviews`,
+ method: "GET",
+ params,
+ });
}
diff --git a/src/services/dashboard.js b/src/services/dashboard.js
index 5dc7e5f..7c705b4 100644
--- a/src/services/dashboard.js
+++ b/src/services/dashboard.js
@@ -1,14 +1,23 @@
import request from "@/utils/request";
// 获取主页信息
export async function getDashboardStatistics(studentId) {
- return request.get(`/api/dashboard/stats/${studentId}`);
+ return request({
+ url: `/api/dashboard/stats/${studentId}`,
+ method: "GET",
+ });
}
// 获取学习进度
export async function getLearningProgressSummary(studentId) {
- return request.get(`/api/dashboard/learning-summary/${studentId}`);
+ return request({
+ url: `/api/dashboard/learning-summary/${studentId}`,
+ method: "GET",
+ });
}
// 获取班级排名
export async function getClassRanking(classId) {
- return request.get(`/api/rankings/class/${classId}`);
+ return request({
+ url: `/api/rankings/class/${classId}`,
+ method: "GET",
+ });
}
diff --git a/src/services/global.js b/src/services/global.js
index f7e056b..c122f35 100644
--- a/src/services/global.js
+++ b/src/services/global.js
@@ -2,5 +2,9 @@ import request from "@/utils/request";
// 获取当前登录学生信息
export async function getLoginStudentInfo() {
- return request.get("/api/students/me");
+ return request({
+ url: `/api/students/me`,
+ method: "GET",
+ namespace: "globalLoading",
+ });
}
diff --git a/src/services/index.js b/src/services/index.js
index d40f283..59893b4 100644
--- a/src/services/index.js
+++ b/src/services/index.js
@@ -1,3 +1,4 @@
+// 此处是已经调试的api
import {
getDashboardStatistics,
getLearningProgressSummary,
diff --git a/src/services/personalProfile.js b/src/services/personalProfile.js
index 7fa6bff..f389ecc 100644
--- a/src/services/personalProfile.js
+++ b/src/services/personalProfile.js
@@ -2,5 +2,8 @@ import request from "@/utils/request";
// 获取当前登录学生学习进度
export async function getLoginStudentProgress(id) {
- return request.get(`/api/students/${id}/progress`);
+ return request({
+ url: `/api/students/${id}/progress`,
+ method: "GET",
+ });
}
diff --git a/src/services/projectLibrary.js b/src/services/projectLibrary.js
index f5f2c14..2f1b33f 100644
--- a/src/services/projectLibrary.js
+++ b/src/services/projectLibrary.js
@@ -1,5 +1,9 @@
import request from "@/utils/request";
// 获取项目列表
export async function getProjectsList(params) {
- return request.get(`/api/projects`, { params });
+ return request({
+ url: `/api/projects`,
+ method: "GET",
+ params,
+ });
}
diff --git a/src/store/slices/loadingSlice.js b/src/store/slices/loadingSlice.js
index 0bab42c..833ef8a 100644
--- a/src/store/slices/loadingSlice.js
+++ b/src/store/slices/loadingSlice.js
@@ -1,25 +1,31 @@
+// 导入 Redux Toolkit 的 createSlice
import { createSlice } from "@reduxjs/toolkit";
-// 创建slice
+// 定义初始状态
+const initialState = {
+ effect: {}, // 全局加载状态对象
+};
+
+// 创建 loading slice
const loadingSlice = createSlice({
- name: "loading",
- initialState: {
- value: false,
- },
+ name: "loading", // slice 名称
+ initialState,
reducers: {
- // 设置loading状态为true
- setLoadingTrue: (state) => {
- state.value = true;
+ // 显示全局加载状态
+ showGlobalLoading: (state, action) => {
+ const { namespace } = action.payload;
+ state.effect[namespace] = true;
},
- // 设置loading状态为false
- setLoadingFalse: (state) => {
- state.value = false;
+ // 隐藏全局加载状态
+ hideGlobalLoading: (state, action) => {
+ const { namespace } = action.payload;
+ state.effect[namespace] = false;
},
},
});
-// 导出actions
-export const { setLoadingTrue, setLoadingFalse } = loadingSlice.actions;
+// 导出 action creators
+export const { showGlobalLoading, hideGlobalLoading } = loadingSlice.actions;
-// 导出reducer
+// 导出 reducer
export default loadingSlice.reducer;
diff --git a/src/utils/request.js b/src/utils/request.js
index 117dd6d..d4e2ca4 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -1,9 +1,24 @@
// 引入axios
import axios from "axios";
+import store from "@/store/index";
+import {
+ showGlobalLoading,
+ hideGlobalLoading,
+} from "@/store/slices/loadingSlice";
+const baseURL = import.meta.env.VITE_API_BASE_URL || "http://localhost:3000";
+// 全局加载状态loading,基于redux
+const handleGlobalLoading = (namespace, type) => {
+ if (!namespace) return;
+ store.dispatch(
+ type === "show"
+ ? showGlobalLoading({ namespace })
+ : hideGlobalLoading({ namespace })
+ );
+};
// 创建axios实例
-const service = axios.create({
- baseURL: import.meta.env.VITE_API_BASE_URL || "http://localhost:3000", // 基础URL
+const axiosInstance = axios.create({
+ baseURL, // 基础URL
timeout: 10000, // 请求超时时间
headers: {
"Content-Type": "application/json;charset=utf-8",
@@ -11,12 +26,12 @@ const service = axios.create({
});
// 请求拦截器
-service.interceptors.request.use(
+axiosInstance.interceptors.request.use(
(config) => {
// 开发阶段使用固定的 x-user-id
// 这个ID对应种子数据中的开发默认用户
config.headers["x-user-id"] = "dev-user-id";
-
+
// 后续对接飞书后使用token
// const token = localStorage.getItem("token");
// if (token) {
@@ -30,11 +45,11 @@ service.interceptors.request.use(
);
// 响应拦截器
-service.interceptors.response.use(
+axiosInstance.interceptors.response.use(
(response) => {
// 处理响应数据
const res = response.data;
-
+
// 后端统一返回格式 {success, data, message}
if (res.success !== undefined) {
if (res.success) {
@@ -50,17 +65,38 @@ service.interceptors.response.use(
return Promise.reject(new Error(res.message || "请求失败"));
}
}
-
+
// 兼容直接返回数据的情况
return res;
},
(error) => {
// 处理响应错误
console.error("请求错误:", error);
- const message = error.response?.data?.message || error.message || "网络错误";
+ const message =
+ error.response?.data?.message || error.message || "网络错误";
return Promise.reject(new Error(message));
}
);
// 导出请求方法
-export default service;
+export default function request({
+ url,
+ apiUrl,
+ namespace,
+ method = "get",
+ data,
+ params,
+ headers = {},
+}) {
+ handleGlobalLoading(namespace, "show");
+ // 返回Promise对象
+ return axiosInstance({
+ method,
+ url: `${apiUrl ? apiUrl : baseURL}${url}`,
+ data,
+ params,
+ headers,
+ }).finally(() => {
+ handleGlobalLoading(namespace, "hide");
+ });
+}