From 24ffe99f24d653464411ad4ade40117b9cf4fa85 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: Tue, 26 Aug 2025 11:40:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BA=86=E5=90=84=E4=B8=AA=E9=A1=B5=E9=9D=A2=E7=9A=84=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/InfiniteScroll/index.jsx | 2 +- src/components/Layout/index_new.jsx | 0 src/pages/CompanyJobsPage/index.css | 4 + src/pages/CompanyJobsPage/index.jsx | 254 ++++++++++++------------ src/pages/ResumeInterviewPage/index.css | 5 + src/pages/ResumeInterviewPage/index.jsx | 136 ++++++------- src/services/personalProfile.js | 6 +- 7 files changed, 209 insertions(+), 198 deletions(-) delete mode 100644 src/components/Layout/index_new.jsx diff --git a/src/components/InfiniteScroll/index.jsx b/src/components/InfiniteScroll/index.jsx index 85fd763..6f30da2 100644 --- a/src/components/InfiniteScroll/index.jsx +++ b/src/components/InfiniteScroll/index.jsx @@ -92,7 +92,7 @@ const InfiniteScroll = ({ {/* 滚动加载指示器 */} {loading && hasMore && (
- + 加载中...
)} diff --git a/src/components/Layout/index_new.jsx b/src/components/Layout/index_new.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/CompanyJobsPage/index.css b/src/pages/CompanyJobsPage/index.css index 0181d75..32d8946 100644 --- a/src/pages/CompanyJobsPage/index.css +++ b/src/pages/CompanyJobsPage/index.css @@ -11,6 +11,10 @@ align-items: center; position: relative; + .company-jobs-page-spin { + margin: 200px 500px; + } + .company-jobs-page-title { width: 100%; height: 42px; diff --git a/src/pages/CompanyJobsPage/index.jsx b/src/pages/CompanyJobsPage/index.jsx index 9b04e73..a1bc801 100644 --- a/src/pages/CompanyJobsPage/index.jsx +++ b/src/pages/CompanyJobsPage/index.jsx @@ -1,11 +1,16 @@ import { useState, useEffect } from "react"; import { useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; +import { Spin, Empty } from "@arco-design/web-react"; import { mapJobList, mapInterviewList } from "@/utils/dataMapper"; import InfiniteScroll from "@/components/InfiniteScroll"; import toast from "@/components/Toast"; import JobList from "./components/JobList"; -import { getCompanyJobsPageData, getJobsList, getInterviewsList } from "@/services"; +import { + getCompanyJobsPageData, + getJobsList, + getInterviewsList, +} from "@/services"; import "./index.css"; const PAGE_SIZE = 10; @@ -31,7 +36,7 @@ const CompanyJobsPage = () => { const res = await getCompanyJobsPageData({ studentId: studentInfo?.id, }); - + if (res?.success) { // 设置岗位数据 if (res.data?.jobs) { @@ -42,32 +47,34 @@ const CompanyJobsPage = () => { setJobsListPage(2); // 下次从第2页开始 } } - + // 设置面试数据 if (res.data?.interviews && studentInfo?.id) { - const mappedInterviews = mapInterviewList(res.data.interviews.list || []); + const mappedInterviews = mapInterviewList( + res.data.interviews.list || [] + ); setInterviews(mappedInterviews); setInterviewsHasMore(res.data.interviews.hasMore); if (mappedInterviews.length > 0) { setInterviewsPage(2); // 下次从第2页开始 } } - + setInitialDataLoaded(true); } } catch (error) { - console.error('Failed to fetch initial page data:', error); + console.error("Failed to fetch initial page data:", error); // 如果聚合接口失败,回退到原来的方式 setInitialDataLoaded(true); // 显示错误信息给用户 if (toast && toast.error) { - toast.error('加载数据失败,请刷新重试'); + toast.error("加载数据失败,请刷新重试"); } } finally { setLoading(false); } }; - + fetchInitialData(); }, [studentInfo?.id]); @@ -77,7 +84,7 @@ const CompanyJobsPage = () => { if (!initialDataLoaded || (interviewsPage === 1 && interviews.length > 0)) { return; } - + if (studentInfo?.id) { const res = await getInterviewsList({ page: interviewsPage, @@ -89,9 +96,13 @@ const CompanyJobsPage = () => { const mappedInterviews = mapInterviewList(res.data || []); setInterviews((prevList) => { // 去重处理:过滤掉已存在的数据 - const existingIds = new Set(prevList.map(interview => interview.id)); - const newInterviews = mappedInterviews.filter(interview => !existingIds.has(interview.id)); - + const existingIds = new Set( + prevList.map((interview) => interview.id) + ); + const newInterviews = mappedInterviews.filter( + (interview) => !existingIds.has(interview.id) + ); + const newList = [...prevList, ...newInterviews]; if (res.total <= newList?.length) { setInterviewsHasMore(false); @@ -115,12 +126,12 @@ const CompanyJobsPage = () => { if (!initialDataLoaded || (jobsListPage === 1 && jobs.length > 0)) { return; } - + // 防止重复请求 if (jobsListPage === 1 && jobs.length === 0) { return; // 初始数据应该通过聚合接口加载 } - + try { const res = await getJobsList({ page: jobsListPage, @@ -132,9 +143,9 @@ const CompanyJobsPage = () => { const mappedJobs = mapJobList(res.data); setJobs((prevList) => { // 去重处理:过滤掉已存在的数据 - const existingIds = new Set(prevList.map(job => job.id)); - const newJobs = mappedJobs.filter(job => !existingIds.has(job.id)); - + const existingIds = new Set(prevList.map((job) => job.id)); + const newJobs = mappedJobs.filter((job) => !existingIds.has(job.id)); + const newList = [...prevList, ...newJobs]; if (res.total <= newList?.length) { setJobsListHasMore(false); @@ -156,118 +167,117 @@ const CompanyJobsPage = () => { navigate("/company-jobs-list"); }; - if (loading && jobs.length === 0 && interviews.length === 0) { - return ( -
-

正在加载数据...

-
- ); - } - return (
-
-

企业内推岗位库

- - - -
-
-
-

内推岗位面试

- + ) : ( + <> +
- {interviews.map((item) => ( -
  • -
    -

    - {item.position} -

    - {item.job?.tags?.length > 0 ? ( -
      - {item.job.tags.map((tag) => ( -
    • - {tag} -
    • - ))} -
    - ) : null} - - {item.job?.salary || "面议"} - -
    -
    - {item.interviewTime} -
    企业内推岗位库

    + + + +
    +
    +
    +

    内推岗位面试

    + + {interviews.map((item) => ( +
  • - {item.statusText} -
  • -
    - - ))} - -
    -
    -
    -
    setIsExpand(!isExpand)} - > - 岗位陪跑流程 -
    -
    -
    -

    内推岗位简历投递

    +
    +

    + {item.position} +

    + {item.job?.tags?.length > 0 ? ( +
      + {item.job.tags.map((tag) => ( +
    • + {tag} +
    • + ))} +
    + ) : null} + + {item.job?.salary || "面议"} + +
    +
    + {item.interviewTime} +
    + {item.statusText} +
    +
    + + ))} + +
    -
    -
    -

    岗位简历接收

    +
    +
    setIsExpand(!isExpand)} + > + 岗位陪跑流程 +
    +
    +
    +

    内推岗位简历投递

    +
    +
    +
    +

    岗位简历接收

    +
    +
    +

    面试时间地点确定

    +
    +
    +

    参与企业面试

    +
    +
    +
    +

    企业offer发送

    +
    +
    -
    -

    面试时间地点确定

    -
    -
    -

    参与企业面试

    -
    -
    -
    -

    企业offer发送

    -
    -
    -
    + + )}
    ); diff --git a/src/pages/ResumeInterviewPage/index.css b/src/pages/ResumeInterviewPage/index.css index 2756e3a..24e7fae 100644 --- a/src/pages/ResumeInterviewPage/index.css +++ b/src/pages/ResumeInterviewPage/index.css @@ -3,7 +3,12 @@ height: 100%; box-sizing: border-box; position: relative; + display: flex; + .resume-interview-spin, + .empty-data { + margin: auto; + } .resume-interview-navigation { position: fixed; top: 0; diff --git a/src/pages/ResumeInterviewPage/index.jsx b/src/pages/ResumeInterviewPage/index.jsx index 325133b..a76086f 100644 --- a/src/pages/ResumeInterviewPage/index.jsx +++ b/src/pages/ResumeInterviewPage/index.jsx @@ -1,4 +1,5 @@ import { useRef, useState, useEffect } from "react"; +import { Spin, Empty } from "@arco-design/web-react"; import toast from "@/components/Toast"; import InterviewQuestionsModal from "./components/InterviewQuestionsModal"; import ResumeInfoModal from "@/pages/CompanyJobsPage/components/ResumeInfoModal"; @@ -110,79 +111,74 @@ const ResumeInterviewPage = () => { return () => window.removeEventListener("scroll", handleScroll); }, [pageData?.industries]); - if (loading) { - return ( -
    -
    加载中...
    -
    - ); - } - - if (!pageData) { - return ( -
    -
    加载失败,请刷新重试
    -
    - ); - } - return (
    -
      -
      - {pageData.industries.map((industry) => ( -
    • handleNavClick(industry.id)} - > - {industry.name} -
    • - ))} -
      -
    -
      - {pageData.industries.map((item) => ( -
    • (sectionsRef.current[item.id] = el)} - > -

      {item.name}

      -

      简历与面试题

      -
      -
        - {filterPositions(item.positions).map((position) => ( -
      • handlePositionClick(position, item)} - > - {position.level} -
        -

        {position.name}

        - 详情 > -
        -
      • - ))} -
      -
        - {item.questions.map((question) => ( -
      • handleQuestionClick({ ...item, question })} - > -

        {question.question}

        -
      • - ))} -
      + {loading ? ( + + ) : pageData ? ( + <> +
        +
        + {pageData.industries.map((industry) => ( +
      • handleNavClick(industry.id)} + > + {industry.name} +
      • + ))}
        - - ))} -
      +
    +
      + {pageData.industries.map((item) => ( +
    • (sectionsRef.current[item.id] = el)} + > +

      {item.name}

      +

      简历与面试题

      +
      +
        + {filterPositions(item.positions).map((position) => ( +
      • handlePositionClick(position, item)} + > + {position.level} +
        +

        {position.name}

        + 详情 > +
        +
      • + ))} +
      +
        + {item.questions.map((question) => ( +
      • + handleQuestionClick({ ...item, question }) + } + > +

        {question.question}

        +
      • + ))} +
      +
      +
    • + ))} +
    + + ) : ( + + )} +