From d0075937e123364af2593880cff08d68b0ba27c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BA=BA=E7=BB=9D=E4=B8=8D=E4=B8=BA?= =?UTF-8?q?=E5=A5=B4?= Date: Fri, 22 Aug 2025 10:32:57 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E5=AF=B9=E6=8E=A5?= =?UTF-8?q?=E4=BA=86=E4=B8=80=E4=BA=9B=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/index.jsx | 4 +- src/components/Rank/index.jsx | 44 ++++++------------- .../components/QuickAccess/index.jsx | 23 ++++++++-- src/pages/Dashboard/index.jsx | 24 +++++++++- .../components/ProfileCard/index.jsx | 4 +- .../components/StudyStudes/index.jsx | 17 +++---- src/pages/PersonalProfile/index.jsx | 32 +++++++++++++- src/services/dashboard.js | 19 ++++---- src/services/index.js | 42 ++++++++++-------- src/services/personalProfile.js | 9 ++++ src/utils/request.js | 18 -------- 11 files changed, 141 insertions(+), 95 deletions(-) diff --git a/src/components/Layout/index.jsx b/src/components/Layout/index.jsx index 996f98e..3331a8d 100644 --- a/src/components/Layout/index.jsx +++ b/src/components/Layout/index.jsx @@ -16,7 +16,9 @@ const Layout = ({ children }) => { const queryLoginStudentInfo = async () => { const res = await getLoginStudentInfo(); - dispatch(setStudentInfo(res)); + if (res.success) { + dispatch(setStudentInfo(res.data)); + } }; // 初始化项目统一获取登录用户信息 diff --git a/src/components/Rank/index.jsx b/src/components/Rank/index.jsx index 1fdf5c0..eaeb98f 100644 --- a/src/components/Rank/index.jsx +++ b/src/components/Rank/index.jsx @@ -1,41 +1,23 @@ import { Avatar } from "@arco-design/web-react"; import "./index.css"; -const Rank = ({ className }) => { +const Rank = ({ className, data }) => { return (

班级排名

+ )} - {data?.details?.description && ( + {data?.description && (

岗位描述

-

- {data?.details?.description} -

+

{data?.description}

)} - {data?.details?.requirements?.length > 0 && ( + {data?.requirements && ( +
+

岗位要求

+

{data?.requirements}

+
+ )} + {/* {data?.details?.requirements?.length > 0 && (

岗位要求

    @@ -124,12 +129,12 @@ export default ({ visible, onClose, data }) => { ))}
- )} - {data?.details?.companyInfo && ( + )} */} + {data?.company?.industry && (

公司介绍

- {data?.details?.companyInfo} + {data?.company?.industry}

)} diff --git a/src/pages/CompanyJobsPage/components/JobList/index.jsx b/src/pages/CompanyJobsPage/components/JobList/index.jsx index 9871b01..3995ee7 100644 --- a/src/pages/CompanyJobsPage/components/JobList/index.jsx +++ b/src/pages/CompanyJobsPage/components/JobList/index.jsx @@ -1,17 +1,23 @@ import { useState } from "react"; -import { useNavigate } from "react-router-dom"; +import toast from "@/components/Toast"; import JobInfoModal from "../JobInfoModal"; +import { getJobsDetail } from "@/services"; +import { mapJob } from "@/utils/dataMapper"; import "./index.css"; export default ({ className = "", data = [], backgroundColor = "#FFFFFF" }) => { - const navigate = useNavigate(); const [jobInfoData, setJobInfoData] = useState(undefined); const [jobInfoModalVisible, setJobInfoModalVisible] = useState(false); - const handleJobClick = (e, item) => { + const handleJobClick = async (e, item) => { e.stopPropagation(); - setJobInfoModalVisible(true); - setJobInfoData(item); + const res = await getJobsDetail(item.id); + if (res.success) { + setJobInfoData(mapJob(res.data)); + setJobInfoModalVisible(true); + } else { + toast.error(res.message); + } }; const onClickJobInfoModalClose = () => { diff --git a/src/pages/Dashboard/index.jsx b/src/pages/Dashboard/index.jsx index 8c6ef95..60bb30c 100644 --- a/src/pages/Dashboard/index.jsx +++ b/src/pages/Dashboard/index.jsx @@ -6,7 +6,7 @@ import StudyStatus from "./components/StudyStatus"; import Rank from "@/components/Rank"; import StageProgress from "@/components/StageProgress"; import TaskList from "./components/TaskList"; -import { getClassRanking, getLearningProgressSummary } from "@/services"; +import { getClassRanking, getStudyRecordsProgress } from "@/services"; import "./index.css"; const Dashboard = () => { @@ -14,7 +14,7 @@ const Dashboard = () => { // 获取整体学习进度 const queryLearningProgressSummary = async () => { - const res = await getLearningProgressSummary({ period: "semester" }); + const res = await getStudyRecordsProgress(); console.log("learningProgressSummary", res); }; diff --git a/src/pages/PersonalProfile/index.jsx b/src/pages/PersonalProfile/index.jsx index 07489fb..3912a77 100644 --- a/src/pages/PersonalProfile/index.jsx +++ b/src/pages/PersonalProfile/index.jsx @@ -5,7 +5,7 @@ import Rank from "@/components/Rank"; import StageProgress from "@/components/StageProgress"; import StudyStudes from "./components/StudyStudes"; import { updateStudentInfo } from "@/store/slices/studentSlice"; -import { getClassRanking, getLearningProgressSummary } from "@/services"; +import { getClassRanking, getStudyRecordsProgress } from "@/services"; import "./index.css"; const PersonalProfile = () => { @@ -13,7 +13,7 @@ const PersonalProfile = () => { const [rankData, setRankData] = useState([]); // 班级排名数据 const queryLearningProgressSummary = async () => { - const res = await getLearningProgressSummary({ period: "semester" }); + const res = await getStudyRecordsProgress(); console.log("learningProgressSummary", res); }; diff --git a/src/services/companyJobs.js b/src/services/companyJobs.js index d4b308a..354f6d0 100644 --- a/src/services/companyJobs.js +++ b/src/services/companyJobs.js @@ -8,6 +8,15 @@ export async function getJobsList(params) { params, }); } + +// 获取企业内推岗位详情 +export async function getJobsDetail(id) { + return request({ + url: `/api/jobs/${id}`, + method: "GET", + }); +} + // 获取企业内推岗位面试 export async function getInterviewsList(params) { return request({ diff --git a/src/services/dashboard.js b/src/services/dashboard.js index aaa4d68..493b50a 100644 --- a/src/services/dashboard.js +++ b/src/services/dashboard.js @@ -1,11 +1,10 @@ import request from "@/utils/request"; -// 获取当前学生的学习进度汇总 -export async function getLearningProgressSummary(queryParams = {}) { +// 获取学生的整体学习进度 +export async function getStudyRecordsProgress() { return request({ - url: `/api/dashboard/learning-summary`, + url: `/api/study-records/progress`, method: "GET", - params: queryParams, namespace: "dashboardLoading", }); } diff --git a/src/services/index.js b/src/services/index.js index 9238453..8394cc8 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -1,11 +1,11 @@ // 统一的API服务接口 - 基于当前认证用户 import { - getLearningProgressSummary, + getStudyRecordsProgress, getMyTasks, getClassRanking, } from "./dashboard"; import { getProjectsList } from "./projectLibrary"; -import { getJobsList, getInterviewsList } from "./companyJobs"; +import { getJobsList, getJobsDetail, getInterviewsList } from "./companyJobs"; import { getLoginStudentInfo } from "./global"; import { getDashboardStatistics, @@ -19,7 +19,7 @@ export { // 仪表盘相关 getMyTasks, // 获取我的任务 getDashboardStatistics, // 获取当前学生仪表盘统计 - getLearningProgressSummary, // 获取当前学生学习进度汇总 + getStudyRecordsProgress, // 获取学生的整体学习进度 // 排名相关 getClassRanking, // 获取当前学生班级排名 @@ -35,6 +35,7 @@ export { // 求职相关 getJobsList, // 获取岗位列表 + getJobsDetail, // 岗位详情 getInterviewsList, // 获取面试列表 getResumesList, // 获取简历列表 getResumesDetail, // 获取简历详情 diff --git a/src/utils/dataMapper.js b/src/utils/dataMapper.js index 96e182d..2d2881b 100644 --- a/src/utils/dataMapper.js +++ b/src/utils/dataMapper.js @@ -3,12 +3,12 @@ // Map student data from backend to frontend format export const mapStudent = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, - name: backendData.realName, // realName -> name - studentId: backendData.studentNo, // studentNo -> studentId - gender: backendData.gender === 'MALE' ? '男' : '女', + name: backendData.realName, // realName -> name + studentId: backendData.studentNo, // studentNo -> studentId + gender: backendData.gender === "MALE" ? "男" : "女", school: backendData.school, major: backendData.major, enrollDate: backendData.enrollDate, @@ -34,7 +34,7 @@ export const mapStudentList = (backendList) => { // Map course data export const mapCourse = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, name: backendData.name, @@ -45,12 +45,15 @@ export const mapCourse = (backendData) => { credits: backendData.credits, hours: backendData.hours, isAiCourse: backendData.isAiCourse, - teacher: backendData.teacher ? { - id: backendData.teacher.id, - name: backendData.teacher.realName, - } : null, + teacher: backendData.teacher + ? { + id: backendData.teacher.id, + name: backendData.teacher.realName, + } + : null, stage: backendData.stage, - enrollmentCount: backendData.enrollmentCount || backendData._count?.enrollments || 0, + enrollmentCount: + backendData.enrollmentCount || backendData._count?.enrollments || 0, }; }; @@ -63,25 +66,26 @@ export const mapCourseList = (backendList) => { // Map job data export const mapJob = (backendData) => { if (!backendData) return null; - + // Format salary range - let salary = '面议'; + let salary = "面议"; if (backendData.salaryMin && backendData.salaryMax) { const min = Math.floor(backendData.salaryMin / 1000); const max = Math.floor(backendData.salaryMax / 1000); salary = `${min}K-${max}K`; } - + return { id: backendData.id, - position: backendData.title, // title -> position + company: backendData.company, + position: backendData.title, // title -> position description: backendData.description, requirements: backendData.requirements, responsibilities: backendData.responsibilities, - company: backendData.company?.name || '', + companyName: backendData.company?.name || "", companyId: backendData.companyId, type: mapJobType(backendData.type), - jobType: backendData.type === 'INTERNSHIP' ? 'internship' : 'fulltime', + jobType: backendData.type === "INTERNSHIP" ? "internship" : "fulltime", level: backendData.level, location: backendData.location, salary: salary, @@ -90,9 +94,9 @@ export const mapJob = (backendData) => { benefits: backendData.benefits || [], skills: backendData.skills || [], isActive: backendData.isActive, - status: backendData.isActive ? 'available' : 'closed', + status: backendData.isActive ? "available" : "closed", remainingPositions: backendData._count?.interviews || 5, // Mock remaining positions - applicationStatus: 'not_applied', // Default status + applicationStatus: "not_applied", // Default status tags: generateJobTags(backendData), deadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days from now }; @@ -107,11 +111,11 @@ export const mapJobList = (backendList) => { // Map job type const mapJobType = (type) => { const typeMap = { - 'FULLTIME': '全职', - 'PARTTIME': '兼职', - 'INTERNSHIP': '实习', - 'CONTRACT': '合同制', - 'REMOTE': '远程', + FULLTIME: "全职", + PARTTIME: "兼职", + INTERNSHIP: "实习", + CONTRACT: "合同制", + REMOTE: "远程", }; return typeMap[type] || type; }; @@ -119,21 +123,21 @@ const mapJobType = (type) => { // Generate job tags const generateJobTags = (job) => { const tags = []; - if (job.location) tags.push(job.location.split('市')[0] + '市'); - if (job.type === 'FULLTIME') tags.push('五险一金'); - if (job.benefits?.includes('双休')) tags.push('双休'); - if (job.benefits?.includes('弹性工作')) tags.push('弹性工作'); + if (job.location) tags.push(job.location.split("市")[0] + "市"); + if (job.type === "FULLTIME") tags.push("五险一金"); + if (job.benefits?.includes("双休")) tags.push("双休"); + if (job.benefits?.includes("弹性工作")) tags.push("弹性工作"); return tags.slice(0, 4); // Max 4 tags }; // Map company data export const mapCompany = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, name: backendData.name, - companyName: backendData.name, // Alias for compatibility + companyName: backendData.name, // Alias for compatibility description: backendData.description, industry: backendData.industry, scale: mapCompanyScale(backendData.scale), @@ -155,10 +159,10 @@ export const mapCompanyList = (backendList) => { // Map company scale const mapCompanyScale = (scale) => { const scaleMap = { - 'SMALL': '50人以下', - 'MEDIUM': '50-200人', - 'LARGE': '200-1000人', - 'ENTERPRISE': '1000人以上', + SMALL: "50人以下", + MEDIUM: "50-200人", + LARGE: "200-1000人", + ENTERPRISE: "1000人以上", }; return scaleMap[scale] || scale; }; @@ -166,7 +170,7 @@ const mapCompanyScale = (scale) => { // Map resume data export const mapResume = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, title: backendData.title, @@ -183,11 +187,11 @@ export const mapResume = (backendData) => { // Map interview data export const mapInterview = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, scheduledAt: backendData.scheduledAt, - interviewTime: new Date(backendData.scheduledAt).toLocaleString('zh-CN'), + interviewTime: new Date(backendData.scheduledAt).toLocaleString("zh-CN"), type: backendData.type, status: backendData.status, location: backendData.location, @@ -196,8 +200,8 @@ export const mapInterview = (backendData) => { result: backendData.result, student: backendData.student ? mapStudent(backendData.student) : null, job: backendData.job ? mapJob(backendData.job) : null, - company: backendData.job?.company?.name || '', - position: backendData.job?.title || '', + company: backendData.job?.company?.name || "", + position: backendData.job?.title || "", // Map status for frontend statusText: mapInterviewStatus(backendData.status, backendData.result), }; @@ -211,16 +215,16 @@ export const mapInterviewList = (backendList) => { // Map interview status const mapInterviewStatus = (status, result) => { - if (status === 'COMPLETED') { - if (result === 'PASS' || result === 'OFFER') return '面试成功'; - if (result === 'FAIL') return '面试失败'; - return '已完成'; + if (status === "COMPLETED") { + if (result === "PASS" || result === "OFFER") return "面试成功"; + if (result === "FAIL") return "面试失败"; + return "已完成"; } - + const statusMap = { - 'SCHEDULED': '待面试', - 'CANCELLED': '已取消', - 'NO_SHOW': '未到场', + SCHEDULED: "待面试", + CANCELLED: "已取消", + NO_SHOW: "未到场", }; return statusMap[status] || status; }; @@ -228,7 +232,7 @@ const mapInterviewStatus = (status, result) => { // Map enrollment data export const mapEnrollment = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, courseId: backendData.courseId, @@ -248,9 +252,9 @@ export const mapEnrollment = (backendData) => { // Map enrollment status const mapEnrollmentStatus = (status) => { const statusMap = { - 'NOT_STARTED': '未开始', - 'IN_PROGRESS': '学习中', - 'COMPLETED': '已完成', + NOT_STARTED: "未开始", + IN_PROGRESS: "学习中", + COMPLETED: "已完成", }; return statusMap[status] || status; }; @@ -258,19 +262,21 @@ const mapEnrollmentStatus = (status) => { // Map class data export const mapClass = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, name: backendData.name, - className: backendData.name, // Alias for compatibility + className: backendData.name, // Alias for compatibility description: backendData.description, startDate: backendData.startDate, endDate: backendData.endDate, isActive: backendData.isActive, - teacher: backendData.teacher ? { - id: backendData.teacher.id, - name: backendData.teacher.realName, - } : null, + teacher: backendData.teacher + ? { + id: backendData.teacher.id, + name: backendData.teacher.realName, + } + : null, studentCount: backendData._count?.students || 0, students: backendData.students ? mapStudentList(backendData.students) : [], }; @@ -279,7 +285,7 @@ export const mapClass = (backendData) => { // Map stage data export const mapStage = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, name: backendData.name, @@ -297,7 +303,7 @@ export const mapStage = (backendData) => { // Map learning record export const mapLearningRecord = (backendData) => { if (!backendData) return null; - + return { id: backendData.id, studentId: backendData.studentId, @@ -312,33 +318,35 @@ export const mapLearningRecord = (backendData) => { // Map profile data (for personal profile page) export const mapProfile = (studentData) => { if (!studentData) return null; - + const mapped = mapStudent(studentData); - + return { ...mapped, - avatar: '/api/placeholder/80/80', // Default avatar + avatar: "/api/placeholder/80/80", // Default avatar badges: { credits: 84, // Mock data, should come from backend classRank: 9, // Mock data, should come from backend - mbti: studentData.mbtiType || 'ENTP', + mbti: studentData.mbtiType || "ENTP", }, - courses: studentData.enrollments ? - studentData.enrollments.map(e => e.course?.name).filter(Boolean) : [], - mbtiReport: studentData.mbtiReport || generateMockMBTIReport(studentData.mbtiType), + courses: studentData.enrollments + ? studentData.enrollments.map((e) => e.course?.name).filter(Boolean) + : [], + mbtiReport: + studentData.mbtiReport || generateMockMBTIReport(studentData.mbtiType), }; }; // Generate mock MBTI report (temporary until backend provides) const generateMockMBTIReport = (type) => { return { - type: type || 'ENTP', - title: 'Personality Type', - description: 'Your personality type description', - characteristics: ['Creative', 'Analytical', 'Strategic'], - strengths: ['Problem-solving', 'Leadership', 'Innovation'], - recommendations: ['Focus on execution', 'Develop patience', 'Listen more'], - careerSuggestions: ['Product Manager', 'Consultant', 'Entrepreneur'], + type: type || "ENTP", + title: "Personality Type", + description: "Your personality type description", + characteristics: ["Creative", "Analytical", "Strategic"], + strengths: ["Problem-solving", "Leadership", "Innovation"], + recommendations: ["Focus on execution", "Develop patience", "Listen more"], + careerSuggestions: ["Product Manager", "Consultant", "Entrepreneur"], }; }; @@ -360,4 +368,4 @@ export default { mapStage, mapLearningRecord, mapProfile, -}; \ No newline at end of file +}; diff --git a/vite.config.js b/vite.config.js index 3516d09..4d093b7 100644 --- a/vite.config.js +++ b/vite.config.js @@ -57,6 +57,7 @@ export default defineConfig({ resolve: { alias: { "@": "/src", + "@/services": "/src/services", }, }, }); From bba32ca5fbacde2fb9e7e6bafcbf6a2174012734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BA=BA=E7=BB=9D=E4=B8=8D=E4=B8=BA?= =?UTF-8?q?=E5=A5=B4?= Date: Fri, 22 Aug 2025 13:28:30 +0800 Subject: [PATCH 3/4] =?UTF-8?q?style:=20=F0=9F=92=84=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=E5=87=A0=E5=A4=84=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/index.css | 5 +++-- src/pages/CompanyJobsPage/index.css | 1 - src/services/dashboard.js | 8 ++++---- src/services/personalProfile.js | 4 ++-- src/services/resumeInterview.js | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/Layout/index.css b/src/components/Layout/index.css index ac8e516..ccb87ee 100644 --- a/src/components/Layout/index.css +++ b/src/components/Layout/index.css @@ -1,7 +1,7 @@ /* 布局相关样式 */ .app-layout { display: flex; - min-height: 100vh; + height: 100vh; width: 100%; background-color: #f2f3f5; @@ -13,7 +13,8 @@ /* 主内容区域 */ .main-content { flex: 1; - overflow: hidden; + height: 100vh; + overflow-y: auto; transition: margin-left 0.3s ease; display: flex; flex-direction: column; diff --git a/src/pages/CompanyJobsPage/index.css b/src/pages/CompanyJobsPage/index.css index c39d7f4..b3f0295 100644 --- a/src/pages/CompanyJobsPage/index.css +++ b/src/pages/CompanyJobsPage/index.css @@ -1,6 +1,5 @@ .company-jobs-page-wrapper { width: 100%; - height: 100%; box-sizing: border-box; padding: 20px; position: relative; diff --git a/src/services/dashboard.js b/src/services/dashboard.js index 493b50a..4384db2 100644 --- a/src/services/dashboard.js +++ b/src/services/dashboard.js @@ -10,21 +10,21 @@ export async function getStudyRecordsProgress() { } // 获取我的任务 -export async function getMyTasks(queryParams = {}) { +export async function getMyTasks(params = {}) { return request({ url: `/api/tasks/my-tasks`, method: "GET", - params: queryParams, + params: params, namespace: "dashboardLoading", }); } // 获取当前学生班级排名 -export async function getClassRanking(queryParams = {}) { +export async function getClassRanking(params = {}) { return request({ url: `/api/rankings/class`, method: "GET", - params: queryParams, + params: params, namespace: "dashboardLoading", }); } diff --git a/src/services/personalProfile.js b/src/services/personalProfile.js index a30bf7a..69f438b 100644 --- a/src/services/personalProfile.js +++ b/src/services/personalProfile.js @@ -19,11 +19,11 @@ export async function getDashboardStatistics() { } // 获取当前学生班级排名 -export async function getClassRank(queryParams = {}) { +export async function getClassRank(params = {}) { return request({ url: `/api/rankings/class`, method: "GET", - params: queryParams, + params: params, namespace: "profileLoading", }); } diff --git a/src/services/resumeInterview.js b/src/services/resumeInterview.js index 9346fc7..05b5b23 100644 --- a/src/services/resumeInterview.js +++ b/src/services/resumeInterview.js @@ -3,9 +3,9 @@ import request from "@/utils/request"; // 获取简历列表 export async function getResumesList(params) { return request({ - url: `/api/resumes/`, + url: `/api/resumes`, method: "GET", - params, + params: params, }); } // 获取简历详情 From e24105b78bfe704af95248263029e640423c816e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BA=BA=E7=BB=9D=E4=B8=8D=E4=B8=BA?= =?UTF-8?q?=E5=A5=B4?= Date: Fri, 22 Aug 2025 14:04:04 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E7=AE=80=E5=8E=86?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/JobInfoModal/index.css | 7 +- .../components/JobInfoModal/index.jsx | 98 +++++++++++++------ src/pages/CompanyJobsPage/index.jsx | 45 +++++---- src/services/companyJobs.js | 16 +++ src/services/index.js | 10 +- src/services/resumeInterview.js | 16 --- 6 files changed, 118 insertions(+), 74 deletions(-) diff --git a/src/pages/CompanyJobsPage/components/JobInfoModal/index.css b/src/pages/CompanyJobsPage/components/JobInfoModal/index.css index 5197c1b..97e95ee 100644 --- a/src/pages/CompanyJobsPage/components/JobInfoModal/index.css +++ b/src/pages/CompanyJobsPage/components/JobInfoModal/index.css @@ -24,9 +24,14 @@ background-color: #fff; } } - + .empty-data-wrapper { + width: 100%; + min-height: 555px; + display: flex; + } .job-info-modal-user-resumes-list { width: 100%; + min-height: 555px; margin-top: 16px; display: grid; grid-template-columns: repeat(2, 1fr); /* 每行两列 */ diff --git a/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx b/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx index 8f0b1f4..a90ed43 100644 --- a/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx +++ b/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx @@ -1,24 +1,48 @@ import { useState } from "react"; +import { useSelector } from "react-redux"; import { Input } from "@arco-design/web-react"; import Modal from "@/components/Modal"; -import { mockData } from "@/data/mockData"; +import InfiniteScroll from "@/components/InfiniteScroll"; import ResumeInfoModal from "@/pages/CompanyJobsPage/components/ResumeInfoModal"; import FILEICON from "@/assets/images/CompanyJobsPage/file_icon.png"; +import { getResumesList } from "@/services"; import "./index.css"; const InputSearch = Input.Search; -const { userResumes } = mockData; +const PAGE_SIZE = 10; export default ({ visible, onClose, data }) => { - console.log(data); + const studentInfo = useSelector((state) => state.student.studentInfo); const [resumeModalShow, setResumeModalShow] = useState(false); const [resumeInfoModalShow, setResumeInfoModalShow] = useState(false); + const [resumeList, setResumeList] = useState([]); // 简历列表 + const [listPage, setListPage] = useState(1); + const [listHasMore, setListHasMore] = useState(true); const handleCloseModal = () => { setResumeModalShow(false); onClose(); }; + const queryResumeList = async () => { + const res = await getResumesList({ + page: listPage, + pageSize: PAGE_SIZE, + studentId: studentInfo?.id, + }); + if (res.success) { + setResumeList((prevList) => { + const newList = [...prevList, ...res.data]; + if (res.total === newList?.length) { + setListHasMore(false); + } else { + setListPage((prevPage) => prevPage + 1); + } + return newList; + }); + } + }; + // 点击立即投递 const handleClickDeliverBtn = (e) => { e.stopPropagation(); @@ -53,36 +77,46 @@ export default ({ visible, onClose, data }) => { searchButton placeholder="搜索简历" /> - -
    - {userResumes.map((item) => ( -
  • userResumesClick(item)} - > -
    - -
    -

    - {item.targetPosition} -

    - {item?.skills?.length > 0 && ( -

    - {item?.skills?.join("/")} -

    - )} -
    -
    -
    userResumesBtnClick(e, item)} + { + + {resumeList.map((item) => ( +
  • userResumesClick(item)} > - 简历详情 -
- - ))} - +
+ +
+

+ {item.title} +

+ {item?.skills?.length > 0 && ( +

+ {item?.skills?.join("/")} +

+ )} +
+
+
userResumesBtnClick(e, item)} + > + 简历详情 +
+ + ))} + + } ) : ( <> diff --git a/src/pages/CompanyJobsPage/index.jsx b/src/pages/CompanyJobsPage/index.jsx index 9da91e2..e66f380 100644 --- a/src/pages/CompanyJobsPage/index.jsx +++ b/src/pages/CompanyJobsPage/index.jsx @@ -2,9 +2,10 @@ import { useState } from "react"; import { useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import { mapJobList, mapInterviewList } from "@/utils/dataMapper"; +import InfiniteScroll from "@/components/InfiniteScroll"; +import toast from "@/components/Toast"; import JobList from "./components/JobList"; import { getJobsList, getInterviewsList } from "@/services"; -import InfiniteScroll from "@/components/InfiniteScroll"; import "./index.css"; const PAGE_SIZE = 10; @@ -22,30 +23,28 @@ const CompanyJobsPage = () => { // 获取面试信息 const fetchInterviewsData = async () => { - try { - if (studentInfo?.id) { - const res = await getInterviewsList({ - page: interviewsPage, - pageSize: PAGE_SIZE, - studentId: studentInfo?.id, - status: "SCHEDULED", + if (studentInfo?.id) { + const res = await getInterviewsList({ + page: interviewsPage, + pageSize: PAGE_SIZE, + studentId: studentInfo?.id, + status: "SCHEDULED", + }); + if (res.success) { + const mappedInterviews = mapInterviewList(res.data || []); + setInterviews((prevList) => { + const newList = [...prevList, ...mappedInterviews]; + if (res.total === newList?.length) { + setInterviewsHasMore(false); + } else { + setInterviewsPage((prevPage) => prevPage + 1); + } + return newList; }); - if (res.success) { - const mappedInterviews = mapInterviewList(res.data || []); - setInterviews((prevList) => { - const newList = [...prevList, ...mappedInterviews]; - if (res.total === newList?.length) { - setInterviewsHasMore(false); - } else { - setInterviewsPage((prevPage) => prevPage + 1); - } - return newList; - }); - } + } else { + setInterviews([]); + toast.error(res.message); } - } catch (error) { - console.error("Failed to fetch data:", error); - setInterviews([]); } }; diff --git a/src/services/companyJobs.js b/src/services/companyJobs.js index 354f6d0..3ea965e 100644 --- a/src/services/companyJobs.js +++ b/src/services/companyJobs.js @@ -25,3 +25,19 @@ export async function getInterviewsList(params) { params, }); } + +// 获取简历列表 +export async function getResumesList(params) { + return request({ + url: `/api/resumes`, + method: "GET", + params: params, + }); +} +// 获取简历详情 +export async function getResumesDetail(id) { + return request({ + url: `/api/resumes/${id}`, + method: "GET", + }); +} diff --git a/src/services/index.js b/src/services/index.js index 8394cc8..77a7098 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -5,7 +5,13 @@ import { getClassRanking, } from "./dashboard"; import { getProjectsList } from "./projectLibrary"; -import { getJobsList, getJobsDetail, getInterviewsList } from "./companyJobs"; +import { + getJobsList, + getJobsDetail, + getInterviewsList, + getResumesList, + getResumesDetail, +} from "./companyJobs"; import { getLoginStudentInfo } from "./global"; import { getDashboardStatistics, @@ -13,7 +19,7 @@ import { getClassRank, getMyRanking, } from "./personalProfile"; -import { getResumesList, getResumesDetail } from "./resumeInterview"; +import {} from "./resumeInterview"; export { // 仪表盘相关 diff --git a/src/services/resumeInterview.js b/src/services/resumeInterview.js index 05b5b23..075344e 100644 --- a/src/services/resumeInterview.js +++ b/src/services/resumeInterview.js @@ -1,17 +1 @@ import request from "@/utils/request"; - -// 获取简历列表 -export async function getResumesList(params) { - return request({ - url: `/api/resumes`, - method: "GET", - params: params, - }); -} -// 获取简历详情 -export async function getResumesDetail(id) { - return request({ - url: `/api/resumes/${id}`, - method: "GET", - }); -}