UI优化更新:面试模拟、简历面试、项目库、求职策略等多个页面改进
主要更新: - 面试模拟页:移除上滑查看评价,添加渐进式评分(72→81→89) - 简历面试页:添加岗位头像、标签背景、面试题加粗等视觉优化 - 项目库页:添加"我完成的项目库"板块,增加hover效果 - 求职策略详情页:优化圆柱体和矩形对齐,添加CSV岗位数据,调整批次文字位置 - 企业岗位列表页:添加返回按钮功能 - 全局:统一岗位级别术语(普通岗/技术骨干岗/储备干部岗) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,61 @@
|
||||
.company-jobs-list-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
/* 返回按钮样式 */
|
||||
.back-button-wrapper {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px; /* 与岗位卡片左对齐 */
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #4e5969;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:hover {
|
||||
background-color: #f7f8fa;
|
||||
border-color: #2c7aff;
|
||||
color: #2c7aff;
|
||||
transform: translateX(-2px);
|
||||
box-shadow: 0 4px 8px rgba(44, 122, 255, 0.15);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98) translateX(-2px);
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.back-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-list-page-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
padding-top: 60px;
|
||||
|
||||
.jobs-list-margin {
|
||||
> li {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useState, useCallback } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import JobList from "@/pages/CompanyJobsPage/components/JobList";
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
import { getJobsList } from "@/services";
|
||||
@@ -8,10 +9,16 @@ import "./index.css";
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
const CompanyJobsListPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const [jobs, setJobs] = useState([]);
|
||||
const [listPage, setListPage] = useState(1);
|
||||
const [listHasMore, setListHasMore] = useState(true);
|
||||
|
||||
// 返回到企业内推岗位页面
|
||||
const handleBack = () => {
|
||||
navigate("/company-jobs");
|
||||
};
|
||||
|
||||
const fetchJobs = useCallback(async () => {
|
||||
const res = await getJobsList({
|
||||
page: listPage,
|
||||
@@ -33,14 +40,24 @@ const CompanyJobsListPage = () => {
|
||||
}, [listPage]);
|
||||
|
||||
return (
|
||||
<InfiniteScroll
|
||||
loadMore={fetchJobs}
|
||||
hasMore={listHasMore}
|
||||
empty={jobs.length === 0}
|
||||
className="company-jobs-list-page-wrapper"
|
||||
>
|
||||
<JobList data={jobs} className="jobs-list-margin" />
|
||||
</InfiniteScroll>
|
||||
<div className="company-jobs-list-page">
|
||||
{/* 返回按钮 */}
|
||||
<div className="back-button-wrapper">
|
||||
<button className="back-button" onClick={handleBack}>
|
||||
<span className="back-icon">←</span>
|
||||
<span className="back-text">返回</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<InfiniteScroll
|
||||
loadMore={fetchJobs}
|
||||
hasMore={listHasMore}
|
||||
empty={jobs.length === 0}
|
||||
className="company-jobs-list-page-wrapper"
|
||||
>
|
||||
<JobList data={jobs} className="jobs-list-margin" />
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
background-color: #f2f3f5;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/background.png");
|
||||
background-size: auto;
|
||||
background-position: top right;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
@@ -61,6 +65,8 @@
|
||||
.file-icon {
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
filter: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
@@ -103,6 +109,21 @@
|
||||
color: #2c7aff;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #ffffff;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
background-color: #2c7aff;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(44, 122, 255, 0.3);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: 0 1px 4px rgba(44, 122, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,10 +63,7 @@ export default ({ visible, onClose, data, directToResume = false }) => {
|
||||
setResumeModalShow(true);
|
||||
};
|
||||
|
||||
const onSearch = (value) => {
|
||||
// todo
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
// 选择简历投递
|
||||
const userResumesClick = async (item) => {
|
||||
@@ -157,12 +154,7 @@ export default ({ visible, onClose, data, directToResume = false }) => {
|
||||
<div className="job-info-modal-content">
|
||||
{resumeModalShow ? (
|
||||
<>
|
||||
<InputSearch
|
||||
className="job-info-modal-search"
|
||||
onSearch={onSearch}
|
||||
searchButton
|
||||
placeholder="搜索简历"
|
||||
/>
|
||||
|
||||
{
|
||||
<InfiniteScroll
|
||||
loadMore={queryResumeList}
|
||||
@@ -178,7 +170,7 @@ export default ({ visible, onClose, data, directToResume = false }) => {
|
||||
<li
|
||||
key={item.id}
|
||||
className="list-item"
|
||||
onClick={() => userResumesClick(item)}
|
||||
onClick={(e) => userResumesBtnClick(e, item)}
|
||||
>
|
||||
<div className="list-item-info">
|
||||
<img src={FILEICON} className="file-icon" />
|
||||
@@ -195,9 +187,12 @@ export default ({ visible, onClose, data, directToResume = false }) => {
|
||||
</div>
|
||||
<div
|
||||
className="info-btn"
|
||||
onClick={(e) => userResumesBtnClick(e, item)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
userResumesClick(item);
|
||||
}}
|
||||
>
|
||||
简历详情
|
||||
投递
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -24,6 +24,14 @@
|
||||
background-color: #e5f1ff;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/jobs_page_left_list_item_bg.png");
|
||||
background-size: 100% 100%;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #4080ff;
|
||||
box-shadow: 0 4px 12px rgba(44, 127, 255, 0.15);
|
||||
transform: translateY(-2px);
|
||||
background-color: #d9e9ff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
@@ -115,6 +123,13 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: #0056b3;
|
||||
box-shadow: 0 2px 6px rgba(0, 119, 255, 0.3);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
> i {
|
||||
width: 12px;
|
||||
|
||||
@@ -1,374 +1,433 @@
|
||||
.company-jobs-page-wrapper {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.company-jobs-page {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.company-jobs-page-spin {
|
||||
margin: 200px 500px;
|
||||
}
|
||||
|
||||
.company-jobs-page-title {
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
margin-bottom: 20px;
|
||||
color: #1d2129;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 10px;
|
||||
width: 32px;
|
||||
height: 3px;
|
||||
background-image: url("@/assets/images/Common/title_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-left {
|
||||
width: 570px;
|
||||
height: 860px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
.company-jobs-page-left-list-wrapper {
|
||||
width: 100%;
|
||||
height: 760px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-wrapper {
|
||||
width: 572px;
|
||||
height: 860px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.company-jobs-page-interview-expand {
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.company-jobs-page-interview {
|
||||
width: 100%;
|
||||
height: 504px;
|
||||
margin-bottom: 20px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
background-color: #ffffff;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
|
||||
.company-jobs-page-interview-list {
|
||||
width: 540px;
|
||||
height: 90%;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.company-jobs-page-interview-item {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e5e6eb;
|
||||
margin-bottom: 20px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
list-style: none;
|
||||
background-color: #e5f1ff;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/jobs_page_left_list_item_bg.png");
|
||||
background-size: 100% 100%;
|
||||
|
||||
.company-jobs-page-interview-item-info {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.company-jobs-page-interview-item-info-position {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
margin-bottom: 5px;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-info-tags {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.company-jobs-page-interview-item-info-tag {
|
||||
background-color: #ffffff;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 5px;
|
||||
padding: 1px 8px;
|
||||
color: #4e5969;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border-radius: 2px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-info-salary {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 22px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: #ff7d00;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-btn-wrapper {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
position: relative;
|
||||
border: 1px solid #94bfff;
|
||||
border-radius: 4px;
|
||||
background-color: #e8f3ff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
|
||||
> span {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: #4e5969;
|
||||
}
|
||||
.company-jobs-page-interview-item-btn {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: #4e5969;
|
||||
}
|
||||
.company-jobs-page-interview-item-btn-active {
|
||||
color: #2c7aff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-wrapper-close {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
bottom: 20px;
|
||||
right: 0;
|
||||
width: 96px;
|
||||
height: 66px;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process_wrapper_close_bg.png");
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
|
||||
.company-jobs-page-process-wrapper-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.company-jobs-page-process-content {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-wrapper-expand {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 572px;
|
||||
height: 340px;
|
||||
background-image: linear-gradient(270deg, #e6f2ff, #ffffff);
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
|
||||
.company-jobs-page-process-wrapper-title {
|
||||
width: 100%;
|
||||
padding-bottom: 40px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
margin-bottom: 20px;
|
||||
color: #1d2129;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 4px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/close_icon.png");
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 40px;
|
||||
width: 32px;
|
||||
height: 3px;
|
||||
background-image: url("@/assets/images/Common/title_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-content {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 80px 20px;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.company-jobs-page-process-item-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
|
||||
> p {
|
||||
width: 84px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: -40px;
|
||||
transform: translateX(-50%);
|
||||
color: #4e5969;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-item-round-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process_dot.png");
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: -40px;
|
||||
transform: translateX(-50%);
|
||||
width: 132px;
|
||||
height: 25px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 68px;
|
||||
height: 0px;
|
||||
border: 1px dashed #c9cdd4;
|
||||
}
|
||||
}
|
||||
.icon1 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process1.png");
|
||||
}
|
||||
.icon2 {
|
||||
&::before {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process2.png");
|
||||
}
|
||||
}
|
||||
.icon3 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process3.png");
|
||||
> p {
|
||||
bottom: -20px;
|
||||
}
|
||||
}
|
||||
.icon4 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process4.png");
|
||||
margin: 0 48px;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: -68px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 68px;
|
||||
height: 0px;
|
||||
border: 1px dashed #c9cdd4;
|
||||
}
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -68px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 68px;
|
||||
height: 0px;
|
||||
border: 1px dashed #c9cdd4;
|
||||
}
|
||||
}
|
||||
.icon5 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process5.png");
|
||||
> p {
|
||||
bottom: -20px;
|
||||
}
|
||||
}
|
||||
.icon6 {
|
||||
&::before {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process6.png");
|
||||
}
|
||||
}
|
||||
.icon7 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process7.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.company-jobs-page-wrapper {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.company-jobs-page {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.company-jobs-page-spin {
|
||||
margin: 200px 500px;
|
||||
}
|
||||
|
||||
.company-jobs-page-title {
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
margin-bottom: 20px;
|
||||
color: #1d2129;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 10px;
|
||||
width: 32px;
|
||||
height: 6px;
|
||||
background-image: url("@/assets/images/Common/title_icon.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-left {
|
||||
width: 570px;
|
||||
height: 860px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
.company-jobs-page-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.company-jobs-page-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
color: #1d2129;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.view-all-jobs-btn {
|
||||
padding: 6px 16px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #2c7aff;
|
||||
border-radius: 4px;
|
||||
color: #2c7aff;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
margin-left: 20px;
|
||||
|
||||
&:hover {
|
||||
background-color: #2c7aff;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 2px 4px rgba(44, 122, 255, 0.2);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-left-list-wrapper {
|
||||
width: 100%;
|
||||
height: 760px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-wrapper {
|
||||
width: 572px;
|
||||
height: 860px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.company-jobs-page-interview-expand {
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.company-jobs-page-interview {
|
||||
width: 100%;
|
||||
height: 860px;
|
||||
margin-bottom: 20px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
background-color: #ffffff;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
|
||||
.company-jobs-page-interview-list {
|
||||
width: 540px;
|
||||
height: 760px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.company-jobs-page-interview-item {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e5e6eb;
|
||||
margin-bottom: 20px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
list-style: none;
|
||||
background-color: #e5f1ff;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/jobs_page_left_list_item_bg.png");
|
||||
background-size: 100% 100%;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border-color: #4080ff;
|
||||
box-shadow: 0 4px 12px rgba(44, 127, 255, 0.15);
|
||||
transform: translateY(-2px);
|
||||
background-color: #d9e9ff;
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-info {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.company-jobs-page-interview-item-info-position {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
margin-bottom: 5px;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-info-tags {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.company-jobs-page-interview-item-info-tag {
|
||||
background-color: #ffffff;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 5px;
|
||||
padding: 1px 8px;
|
||||
color: #4e5969;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border-radius: 2px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-info-salary {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 22px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: #ff7d00;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-interview-item-btn-wrapper {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
position: relative;
|
||||
border: 1px solid #94bfff;
|
||||
border-radius: 4px;
|
||||
background-color: #e8f3ff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
|
||||
> span {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: #4e5969;
|
||||
}
|
||||
.company-jobs-page-interview-item-btn {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: #4e5969;
|
||||
}
|
||||
.company-jobs-page-interview-item-btn-active {
|
||||
color: #2c7aff;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: #1967d2;
|
||||
text-decoration: underline;
|
||||
transform: translateX(2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-wrapper-close {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 96px;
|
||||
height: 66px;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process_wrapper_close_bg.png");
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
|
||||
.company-jobs-page-process-wrapper-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.company-jobs-page-process-content {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-wrapper-expand {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 572px;
|
||||
height: 340px;
|
||||
background-image: linear-gradient(270deg, #e6f2ff, #ffffff);
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
|
||||
.company-jobs-page-process-wrapper-title {
|
||||
width: 100%;
|
||||
padding-bottom: 40px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
margin-bottom: 20px;
|
||||
color: #1d2129;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 4px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/close_icon.png");
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 40px;
|
||||
width: 32px;
|
||||
height: 3px;
|
||||
background-image: url("@/assets/images/Common/title_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-content {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 80px 20px;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.company-jobs-page-process-item-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
|
||||
> p {
|
||||
width: 84px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: -40px;
|
||||
transform: translateX(-50%);
|
||||
color: #4e5969;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-page-process-item-round-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process_dot.png");
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: -40px;
|
||||
transform: translateX(-50%);
|
||||
width: 132px;
|
||||
height: 25px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 68px;
|
||||
height: 0px;
|
||||
border: 1px dashed #c9cdd4;
|
||||
}
|
||||
}
|
||||
.icon1 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process1.png");
|
||||
}
|
||||
.icon2 {
|
||||
&::before {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process2.png");
|
||||
}
|
||||
}
|
||||
.icon3 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process3.png");
|
||||
> p {
|
||||
bottom: -20px;
|
||||
}
|
||||
}
|
||||
.icon4 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process4.png");
|
||||
margin: 0 48px;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: -68px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 68px;
|
||||
height: 0px;
|
||||
border: 1px dashed #c9cdd4;
|
||||
}
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -68px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 68px;
|
||||
height: 0px;
|
||||
border: 1px dashed #c9cdd4;
|
||||
}
|
||||
}
|
||||
.icon5 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process5.png");
|
||||
> p {
|
||||
bottom: -20px;
|
||||
}
|
||||
}
|
||||
.icon6 {
|
||||
&::before {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process6.png");
|
||||
}
|
||||
}
|
||||
.icon7 {
|
||||
background-image: url("@/assets/images/CompanyJobsPage/process7.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,9 +178,28 @@ const CompanyJobsPage = () => {
|
||||
<>
|
||||
<div
|
||||
className="company-jobs-page-left"
|
||||
onClick={handleJobWrapperClick}
|
||||
>
|
||||
<p className="company-jobs-page-title">企业内推岗位库</p>
|
||||
<div className="company-jobs-page-header">
|
||||
<p className="company-jobs-page-title">
|
||||
<img
|
||||
src="https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_icon/recuUY5w4Kcw4H.png"
|
||||
alt="icon"
|
||||
style={{
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
marginRight: '8px',
|
||||
verticalAlign: 'middle'
|
||||
}}
|
||||
/>
|
||||
企业内推岗位库
|
||||
</p>
|
||||
<button
|
||||
className="view-all-jobs-btn"
|
||||
onClick={handleJobWrapperClick}
|
||||
>
|
||||
查看全部岗位
|
||||
</button>
|
||||
</div>
|
||||
<InfiniteScroll
|
||||
loadMore={fetchJobsList}
|
||||
hasMore={jobsListHasMore}
|
||||
@@ -191,13 +210,21 @@ const CompanyJobsPage = () => {
|
||||
</div>
|
||||
<div className="company-jobs-page-interview-wrapper">
|
||||
<div
|
||||
className={`${
|
||||
isExpand
|
||||
? "company-jobs-page-interview"
|
||||
: "company-jobs-page-interview company-jobs-page-interview-expand"
|
||||
}`}
|
||||
className="company-jobs-page-interview"
|
||||
>
|
||||
<p className="company-jobs-page-title">内推岗位面试</p>
|
||||
<p className="company-jobs-page-title">
|
||||
<img
|
||||
src="https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_icon/recuUY5wqNngw9.png"
|
||||
alt="icon"
|
||||
style={{
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
marginRight: '8px',
|
||||
verticalAlign: 'middle'
|
||||
}}
|
||||
/>
|
||||
岗位面试状态
|
||||
</p>
|
||||
<InfiniteScroll
|
||||
loadMore={fetchInterviewsData}
|
||||
hasMore={interviewsHasMore}
|
||||
|
||||
@@ -1,77 +1,195 @@
|
||||
.homework-page-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
|
||||
.homework-page-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
|
||||
.homework-page-content-list {
|
||||
width: 1120px;
|
||||
height: 360px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px 15px;
|
||||
|
||||
.homework-page-content-list-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #000;
|
||||
}
|
||||
.homework-page-content-list-class {
|
||||
height: 280px;
|
||||
margin-top: 20px;
|
||||
overflow-x: auto;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.homework-page-content-list-content-item {
|
||||
flex-shrink: 0;
|
||||
width: 164px;
|
||||
height: 100%;
|
||||
margin-right: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.homework-page-content-list-content-item-icon {
|
||||
width: 164px;
|
||||
height: 184px;
|
||||
}
|
||||
|
||||
.homework-page-content-list-content-item-name {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
.homework-page-content-list-content-item-btn {
|
||||
cursor: pointer;
|
||||
width: 109px;
|
||||
height: 32px;
|
||||
background-color: #2c7aff;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.homework-page-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
|
||||
.homework-page-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
|
||||
.homework-page-content-list {
|
||||
width: 1120px;
|
||||
min-height: 360px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px 15px;
|
||||
position: relative;
|
||||
overflow: hidden; /* 重要:隐藏溢出内容 */
|
||||
|
||||
.homework-page-content-list-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #000;
|
||||
}
|
||||
.homework-page-content-list-class {
|
||||
width: calc(100% + 30px); /* 扩展到padding外 */
|
||||
height: 300px;
|
||||
margin-top: 20px;
|
||||
margin-left: -15px;
|
||||
margin-right: -15px;
|
||||
padding: 0 15px;
|
||||
padding-bottom: 10px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
gap: 20px;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #c9cdd4;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: #86909c;
|
||||
}
|
||||
}
|
||||
|
||||
.homework-page-content-list-content-item {
|
||||
flex: 0 0 164px;
|
||||
width: 164px;
|
||||
height: 260px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.homework-page-content-list-content-item-icon {
|
||||
width: 164px;
|
||||
height: 184px;
|
||||
}
|
||||
|
||||
.homework-page-content-list-content-item-name {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0 5px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.homework-page-content-list-content-item-btn {
|
||||
cursor: pointer;
|
||||
width: 109px;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.completed {
|
||||
background: linear-gradient(135deg, #2c7aff 0%, #4096ff 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(44, 122, 255, 0.2);
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #4096ff 0%, #69b1ff 100%);
|
||||
box-shadow: 0 4px 8px rgba(44, 122, 255, 0.3);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: #f5f5f5;
|
||||
color: #c9cdd4;
|
||||
border: 1px solid #e5e6eb;
|
||||
cursor: not-allowed;
|
||||
|
||||
&:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* iframe页面样式 */
|
||||
.homework-page-iframe-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
|
||||
.homework-page-iframe-header {
|
||||
height: 60px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
|
||||
.homework-page-return-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
background: linear-gradient(135deg, #2c7aff 0%, #4096ff 100%);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #4096ff 0%, #69b1ff 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(44, 122, 255, 0.3);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.homework-page-iframe-title {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
}
|
||||
|
||||
.homework-page-iframe-content {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Tooltip } from "@arco-design/web-react";
|
||||
import { IconArrowLeft } from "@arco-design/web-react/icon";
|
||||
import { mockData } from "@/data/mockData";
|
||||
import ICON1 from "@/assets/images/HomeworkPage/homework_page_icon1.png";
|
||||
import ICON2 from "@/assets/images/HomeworkPage/homework_page_icon2.png";
|
||||
@@ -5,27 +8,114 @@ import "./index.css";
|
||||
|
||||
const HomeworkPage = () => {
|
||||
const { homework } = mockData;
|
||||
const scrollContainerRef = useRef(null);
|
||||
const [showIframe, setShowIframe] = useState(false);
|
||||
|
||||
// 调试:打印课程数量
|
||||
console.log('作业数据:', homework);
|
||||
if (homework && homework[0]) {
|
||||
console.log('复合能力培养课程数量:', homework[0].list.length);
|
||||
}
|
||||
|
||||
// 添加鼠标滚轮横向滚动支持(更丝滑的滚动)
|
||||
useEffect(() => {
|
||||
const container = scrollContainerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
let animationId = null;
|
||||
let targetScrollLeft = container.scrollLeft;
|
||||
|
||||
// 平滑滚动动画
|
||||
const smoothScroll = () => {
|
||||
const currentScrollLeft = container.scrollLeft;
|
||||
const diff = targetScrollLeft - currentScrollLeft;
|
||||
|
||||
if (Math.abs(diff) > 0.5) {
|
||||
container.scrollLeft = currentScrollLeft + diff * 0.15; // 缓动系数
|
||||
animationId = requestAnimationFrame(smoothScroll);
|
||||
} else {
|
||||
container.scrollLeft = targetScrollLeft;
|
||||
if (animationId) {
|
||||
cancelAnimationFrame(animationId);
|
||||
animationId = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 鼠标滚轮横向滚动
|
||||
const handleWheel = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// 计算滚动距离,使用较小的值让滚动更平滑
|
||||
const scrollAmount = e.deltaY * 0.8;
|
||||
targetScrollLeft = container.scrollLeft + scrollAmount;
|
||||
|
||||
// 限制滚动范围
|
||||
targetScrollLeft = Math.max(0, Math.min(targetScrollLeft, container.scrollWidth - container.clientWidth));
|
||||
|
||||
// 如果没有正在进行的动画,启动平滑滚动
|
||||
if (!animationId) {
|
||||
animationId = requestAnimationFrame(smoothScroll);
|
||||
}
|
||||
};
|
||||
|
||||
container.addEventListener('wheel', handleWheel, { passive: false });
|
||||
|
||||
return () => {
|
||||
container.removeEventListener('wheel', handleWheel);
|
||||
if (animationId) {
|
||||
cancelAnimationFrame(animationId);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleClickBtn = (sectionId, itemId) => {
|
||||
// 只有复合能力培养的第一个项目(展会策划教学)可以点击
|
||||
if (sectionId === 1 && itemId === 1) {
|
||||
window.open("https://du9uay.github.io/zhanhui/", "_blank");
|
||||
// 只有复合能力培养的第72个项目(展会策划教学)可以点击
|
||||
if (sectionId === 1 && itemId === 72) {
|
||||
setShowIframe(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 判断是否应该显示灰色图片和禁用按钮
|
||||
const isDisabled = (sectionId, itemId) => {
|
||||
// 只有复合能力培养的第一个项目是启用状态
|
||||
return !(sectionId === 1 && itemId === 1);
|
||||
// 只有复合能力培养的展会策划教学(第72个)是启用状态
|
||||
return !(sectionId === 1 && itemId === 72);
|
||||
};
|
||||
|
||||
// 如果显示iframe,渲染全页面的iframe
|
||||
if (showIframe) {
|
||||
return (
|
||||
<div className="homework-page-iframe-wrapper">
|
||||
<div className="homework-page-iframe-header">
|
||||
<button
|
||||
className="homework-page-return-btn"
|
||||
onClick={() => setShowIframe(false)}
|
||||
>
|
||||
<IconArrowLeft style={{ marginRight: '8px' }} />
|
||||
返回课后作业
|
||||
</button>
|
||||
<span className="homework-page-iframe-title">展会策划教学</span>
|
||||
</div>
|
||||
<iframe
|
||||
src="https://du9uay.github.io/zhanhui/"
|
||||
className="homework-page-iframe-content"
|
||||
title="展会策划教学"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 正常渲染作业列表
|
||||
return (
|
||||
<div className="homework-page-wrapper">
|
||||
<ul className="homework-page-content">
|
||||
{homework.map((item) => (
|
||||
<li key={item.id} className="homework-page-content-list">
|
||||
<p className="homework-page-content-list-title">{item.name}</p>
|
||||
<ul className="homework-page-content-list-class">
|
||||
<ul
|
||||
className="homework-page-content-list-class"
|
||||
ref={item.id === 1 ? scrollContainerRef : null}
|
||||
>
|
||||
{item.list.map((contentItem) => (
|
||||
<li
|
||||
key={contentItem.id}
|
||||
@@ -35,25 +125,19 @@ const HomeworkPage = () => {
|
||||
alt="icon"
|
||||
src={ICON1}
|
||||
className="homework-page-content-list-content-item-icon"
|
||||
style={{
|
||||
filter: isDisabled(item.id, contentItem.id) ? "grayscale(100%)" : "none",
|
||||
opacity: isDisabled(item.id, contentItem.id) ? 0.6 : 1
|
||||
}}
|
||||
/>
|
||||
<p className="homework-page-content-list-content-item-name">
|
||||
{contentItem.name}
|
||||
</p>
|
||||
<Tooltip content={contentItem.name} position="top">
|
||||
<p className="homework-page-content-list-content-item-name">
|
||||
{contentItem.name}
|
||||
</p>
|
||||
</Tooltip>
|
||||
<div
|
||||
className={`homework-page-content-list-content-item-btn ${
|
||||
isDisabled(item.id, contentItem.id) ? "disabled" : ""
|
||||
isDisabled(item.id, contentItem.id) ? "disabled" : "completed"
|
||||
}`}
|
||||
onClick={() => !isDisabled(item.id, contentItem.id) && handleClickBtn(item.id, contentItem.id)}
|
||||
style={{
|
||||
cursor: isDisabled(item.id, contentItem.id) ? "not-allowed" : "pointer",
|
||||
opacity: isDisabled(item.id, contentItem.id) ? 0.5 : 1
|
||||
}}
|
||||
>
|
||||
完成作业
|
||||
已完成
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
height: 860px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
background-color: #f2f3f5;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
gap: 20px;
|
||||
|
||||
.interview-rating-header {
|
||||
width: 100%;
|
||||
@@ -28,69 +30,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
.interview-rating-video-content {
|
||||
.interview-rating-video-section {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.interview-rating-video {
|
||||
width: 100%;
|
||||
height: 670px;
|
||||
height: 450px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background-color: #000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
> video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
> img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
.interview-rating-slide {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
background-color: #e8f3ff;
|
||||
margin-top: 60px;
|
||||
|
||||
> i {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-size: 100% 100%;
|
||||
margin: 0 5px;
|
||||
background-image: url("@/assets/images/InterviewSimulationPage/slide_up_icon.png");
|
||||
}
|
||||
> span {
|
||||
font-size: 14px;
|
||||
color: #2c7aff;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 滑动后 */
|
||||
.interview-evaluation-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
/* 面试评分图表区域 */
|
||||
|
||||
.interview-rating-header {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.interview-evaluation-charts-wrapper {
|
||||
width: 100%;
|
||||
height: 660px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
flex-shrink: 0;
|
||||
.interview-evaluation-charts-wrapper {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.charts-content {
|
||||
width: 100%;
|
||||
@@ -180,36 +165,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
.interview-evaluation-text-wrapper {
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
.interview-evaluation-text-wrapper {
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
|
||||
.interview-rating-text {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
background-color: #f2f3f5;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
color: #1d2129;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.interview-rating-text {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
background-color: #f2f3f5;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
color: #1d2129;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.interview-rating-wrapper2 {
|
||||
padding: 0px;
|
||||
border-radius: 0;
|
||||
overflow: auto;
|
||||
background-color: #f2f3f5;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,7 @@ import ScoreChart from "../ScoreChart";
|
||||
import RadarChart from "../RadarChart";
|
||||
import "./index.css";
|
||||
|
||||
// 滑动阈值(向上滑动超过这个距离触发切换)
|
||||
const SWIPE_THRESHOLD = 100;
|
||||
export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
const [isSlide, setIsSlide] = useState(false);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [startY, setStartY] = useState(0);
|
||||
const [currentY, setCurrentY] = useState(0);
|
||||
const slideRef = useRef(null);
|
||||
|
||||
// 根据选中项目获取对应的视频URL
|
||||
const getVideoUrl = () => {
|
||||
switch(selectedItem) {
|
||||
@@ -19,6 +11,12 @@ export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJSOKoqAm.mov";
|
||||
case "未来的自己":
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJT02CMM5.mp4";
|
||||
case "第一次线下面试模拟":
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJSOKoqAm.mov"; // 使用相同视频作为示例
|
||||
case "第二次线下面试模拟":
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJT02CMM5.mp4"; // 使用相同视频作为示例
|
||||
case "第三次线下面试模拟":
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/video/teach_sys/interview_offline_vedio/recuUpJSOKoqAm.mov"; // 使用相同视频作为示例
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@@ -26,7 +24,9 @@ export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
|
||||
// 判断是否是锁定的面试模拟项目
|
||||
const isLockedItem = () => {
|
||||
return selectedItem?.includes("线下面试模拟");
|
||||
return selectedItem === "第一次线下面试模拟" ||
|
||||
selectedItem === "第二次线下面试模拟" ||
|
||||
selectedItem === "第三次线下面试模拟";
|
||||
};
|
||||
|
||||
// 根据选中项目获取评价数据
|
||||
@@ -42,11 +42,47 @@ export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
|
||||
沟通表达上,候选人语言表达流畅自然,逻辑思维清晰有条理,能够积极主动地与面试官互动。在面对开放性问题时展现出良好的思维发散能力,回答层次分明,重点突出,表现出强烈的学习意愿和职业发展规划意识。整体表现超出预期,具备优秀的职场素养。`
|
||||
};
|
||||
} else if (selectedItem === "第一次线下面试模拟") {
|
||||
return {
|
||||
totalScore: 72,
|
||||
professionalScore: 28.0,
|
||||
performanceScore: 44.0,
|
||||
radarData: [7, 6, 7, 7],
|
||||
radarData2: [6, 6, 5, 6],
|
||||
title: "初次模拟评价",
|
||||
content: `在专业能力方面,候选人对基础知识有一定了解,但在深入问题上表现不够自信。回答问题时思路基本清晰,但缺乏具体案例支撑。对行业动态的了解较为表面,需要加强专业知识的深度学习。在描述项目经验时,表达略显生疏,未能充分展现个人价值。
|
||||
|
||||
沟通表达上,候选人表现出一定的紧张情绪,语速较快,有时会出现词不达意的情况。逻辑性有待加强,回答问题时容易偏离主题。肢体语言不够自然,眼神交流不足。建议多进行面试练习,提升表达的流畅度和自信心。整体来看,还有较大的提升空间。`
|
||||
};
|
||||
} else if (selectedItem === "第二次线下面试模拟") {
|
||||
return {
|
||||
totalScore: 81,
|
||||
professionalScore: 32.5,
|
||||
performanceScore: 48.5,
|
||||
radarData: [8, 7, 8, 8],
|
||||
radarData2: [7, 7, 6, 7],
|
||||
title: "进步明显评价",
|
||||
content: `在专业能力方面,候选人相比第一次有明显进步,对专业知识的理解更加深入。能够结合实际案例阐述观点,展现出一定的实践经验。对于技术问题的回答更有条理,能够抓住问题的关键点。行业认知有所提升,能够说出一些前沿趋势。
|
||||
|
||||
沟通表达上,紧张情绪明显缓解,语速适中,表达更加清晰。逻辑结构有所改善,能够按照"总-分-总"的结构组织答案。肢体语言更加自然,与面试官的互动增多。自信心有所提升,敢于表达自己的观点。但在一些压力问题上仍需加强应对能力。`
|
||||
};
|
||||
} else if (selectedItem === "第三次线下面试模拟") {
|
||||
return {
|
||||
totalScore: 89,
|
||||
professionalScore: 36.5,
|
||||
performanceScore: 52.5,
|
||||
radarData: [9, 8, 9, 9],
|
||||
radarData2: [8, 8, 7, 8],
|
||||
title: "接近优秀评价",
|
||||
content: `在专业能力方面,候选人展现出扎实的专业功底,能够深入浅出地解释复杂概念。项目经验描述详实,能够清楚说明技术难点和解决方案。对行业发展有独到见解,能够将理论与实践很好地结合。专业深度和广度都达到了较高水平。
|
||||
|
||||
沟通表达上,表现自然从容,完全没有紧张感。语言组织能力强,逻辑清晰,重点突出。能够根据面试官的反应及时调整表达方式,展现出良好的沟通技巧。肢体语言得体,眼神交流充分,整体气场稳定。已经基本具备了通过正式面试的能力,继续保持即可。`
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
totalScore: 85,
|
||||
professionalScore: 38.0,
|
||||
performanceScore: 50.0,
|
||||
professionalScore: 34.0,
|
||||
performanceScore: 51.0,
|
||||
radarData: [9, 8, 9, 9],
|
||||
title: "基础面试评价",
|
||||
content: `在专业能力方面,候选人对 [岗位相关专业知识] 有基本掌握,能够清晰回答与过往项目经验相关的问题,例如在描述 [具体项目] 时,能准确说明自己承担的职责和达成的成果,体现出一定的实践操作能力。但在深入探讨 [某一专业难点] 时,表述略显浅显,对行业前沿动态的了解不够全面,专业深度有提升空间。
|
||||
@@ -56,164 +92,37 @@ export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理触摸/鼠标开始
|
||||
const handleStart = (clientY) => {
|
||||
setIsDragging(true);
|
||||
setStartY(clientY);
|
||||
setCurrentY(clientY);
|
||||
if (slideRef.current) {
|
||||
slideRef.current.style.transition = "none";
|
||||
}
|
||||
// 判断是否应该显示评价内容
|
||||
const shouldShowEvaluation = () => {
|
||||
return selectedItem === "求职面试初体验" ||
|
||||
selectedItem === "未来的自己" ||
|
||||
selectedItem === "第一次线下面试模拟" ||
|
||||
selectedItem === "第二次线下面试模拟" ||
|
||||
selectedItem === "第三次线下面试模拟";
|
||||
};
|
||||
|
||||
// 处理触摸/鼠标移动
|
||||
const handleMove = (clientY) => {
|
||||
if (!isDragging) return;
|
||||
|
||||
setCurrentY(clientY);
|
||||
const diffY = startY - clientY; // 正值表示向上滑动,负值表示向下滑动
|
||||
|
||||
if (isSlide) {
|
||||
// 在评价界面时,只允许向下滑动
|
||||
if (diffY < 0) {
|
||||
const translateY = Math.min(Math.abs(diffY), 150);
|
||||
if (slideRef.current) {
|
||||
slideRef.current.style.transform = `translateY(${translateY}px)`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 在视频界面时,只允许向上滑动,且只对懵懂初试的项目生效
|
||||
if (diffY > 0 && (selectedItem === "求职面试初体验" || selectedItem === "未来的自己")) {
|
||||
const translateY = Math.min(diffY, 150);
|
||||
if (slideRef.current) {
|
||||
slideRef.current.style.transform = `translateY(-${translateY}px)`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 处理触摸/鼠标结束
|
||||
const handleEnd = () => {
|
||||
if (!isDragging) return;
|
||||
|
||||
setIsDragging(false);
|
||||
const diffY = startY - currentY;
|
||||
|
||||
// 恢复位置
|
||||
if (slideRef.current) {
|
||||
slideRef.current.style.transition = "transform 0.3s ease";
|
||||
slideRef.current.style.transform = "";
|
||||
}
|
||||
|
||||
// 检查滑动方向和阈值
|
||||
if (isSlide) {
|
||||
// 在评价界面时,向下滑动返回视频界面
|
||||
if (diffY < -SWIPE_THRESHOLD) {
|
||||
handleSwipeDown();
|
||||
}
|
||||
} else {
|
||||
// 在视频界面时,向上滑动到评价界面
|
||||
if (diffY > SWIPE_THRESHOLD) {
|
||||
handleSwipeUp();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 向上滑动事件处理
|
||||
const handleSwipeUp = () => {
|
||||
// 只有懵懂初试的项目可以上滑查看评价
|
||||
if (selectedItem === "求职面试初体验" || selectedItem === "未来的自己") {
|
||||
console.log("触发向上滑动切换");
|
||||
setIsSlide(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 向下滑动事件处理
|
||||
const handleSwipeDown = () => {
|
||||
console.log("触发向下滑动返回");
|
||||
setIsSlide(false);
|
||||
};
|
||||
|
||||
// 鼠标事件处理
|
||||
const handleMouseDown = (e) => {
|
||||
handleStart(e.clientY);
|
||||
};
|
||||
|
||||
const handleMouseMove = (e) => {
|
||||
if (isDragging) {
|
||||
e.preventDefault();
|
||||
handleMove(e.clientY);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
handleEnd();
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
handleEnd();
|
||||
};
|
||||
|
||||
// 触摸事件处理
|
||||
const handleTouchStart = (e) => {
|
||||
handleStart(e.touches[0].clientY);
|
||||
};
|
||||
|
||||
const handleTouchMove = (e) => {
|
||||
if (isDragging) {
|
||||
e.preventDefault();
|
||||
handleMove(e.touches[0].clientY);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
handleEnd();
|
||||
};
|
||||
|
||||
// 添加全局事件监听
|
||||
useEffect(() => {
|
||||
const handleGlobalMouseMove = (e) => handleMouseMove(e);
|
||||
const handleGlobalMouseUp = () => handleMouseUp();
|
||||
|
||||
if (isDragging) {
|
||||
document.addEventListener("mousemove", handleGlobalMouseMove);
|
||||
document.addEventListener("mouseup", handleGlobalMouseUp);
|
||||
document.body.style.cursor = "grabbing";
|
||||
document.body.style.userSelect = "none";
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousemove", handleGlobalMouseMove);
|
||||
document.removeEventListener("mouseup", handleGlobalMouseUp);
|
||||
document.body.style.cursor = "";
|
||||
document.body.style.userSelect = "";
|
||||
};
|
||||
}, [isDragging]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`interview-rating-wrapper ${
|
||||
isSlide ? "interview-rating-wrapper2" : ""
|
||||
}`}
|
||||
>
|
||||
{isSlide ? (
|
||||
<div
|
||||
className="interview-evaluation-wrapper"
|
||||
ref={slideRef}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchMove={handleTouchMove}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
style={{
|
||||
cursor: "grab",
|
||||
userSelect: "none",
|
||||
WebkitUserSelect: "none",
|
||||
touchAction: "pan-x",
|
||||
}}
|
||||
>
|
||||
<div className="interview-rating-wrapper">
|
||||
{/* 视频播放器区域 */}
|
||||
<div className="interview-rating-video-section">
|
||||
<div className="interview-rating-header">
|
||||
<span className="interview-rating-header-title">
|
||||
钢铁是怎样炼成的
|
||||
</span>
|
||||
</div>
|
||||
<div className="interview-rating-video">
|
||||
{isLockedItem() ? (
|
||||
<img src="/线下面试模拟锁定.png" alt="线下面试模拟锁定" style={{width: "100%", height: "100%", objectFit: "cover"}} />
|
||||
) : (
|
||||
<video src={getVideoUrl()} controls></video>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 评价内容区域 - 仅在特定项目时显示 */}
|
||||
{shouldShowEvaluation() && (
|
||||
<>
|
||||
{/* 面试评分区域 */}
|
||||
<div className="interview-evaluation-charts-wrapper">
|
||||
<div className="interview-rating-header">
|
||||
<span className="interview-rating-header-title">面试评分</span>
|
||||
@@ -241,16 +150,30 @@ export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
className="radar-chart"
|
||||
data={getEvaluationData().radarData}
|
||||
indicator={[
|
||||
{ name: "{a|核心知识掌握}\\n{b|与精准应用}", max: 10 },
|
||||
{ name: "{a|问题分析、方案设计}\\n{b|与成果表达}", max: 10 },
|
||||
{ name: "{a|产业认知与行业}\\n{b|趋势洞察}", max: 10 },
|
||||
{ name: "{a|企业工作流}\\n{b|理解与实践}", max: 10 },
|
||||
{ name: "核心知识掌握与精准应用", max: 10 },
|
||||
{ name: "问题分析方案设计与成果表达", max: 10 },
|
||||
{ name: "产业认知与行业趋势洞察", max: 10 },
|
||||
{ name: "企业工作流理解与实践", max: 10 },
|
||||
]}
|
||||
/>
|
||||
<RadarChart className="radar-chart" />
|
||||
<RadarChart
|
||||
className="radar-chart"
|
||||
data={getEvaluationData().radarData2 || [7, 8, 6, 7]}
|
||||
indicator={[
|
||||
{ name: "沟通表达与逻辑思维", max: 10 },
|
||||
{ name: "团队协作与责任意识", max: 10 },
|
||||
{ name: "学习能力与适应能力", max: 10 },
|
||||
{ name: "职业素养与发展潜力", max: 10 },
|
||||
]}
|
||||
lineClolr="#FFE4D9"
|
||||
areaColor="#FFD4C1"
|
||||
areaBorderColor="#FFB89A"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 基础面试评价区域 */}
|
||||
<div className="interview-evaluation-text-wrapper">
|
||||
<div className="interview-rating-header">
|
||||
<span className="interview-rating-header-title">{getEvaluationData().title}</span>
|
||||
@@ -259,42 +182,7 @@ export default ({ selectedItem = "求职面试初体验" }) => {
|
||||
{getEvaluationData().content}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className="interview-rating-video-content"
|
||||
ref={slideRef}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchMove={handleTouchMove}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
style={{
|
||||
cursor: "grab",
|
||||
userSelect: "none",
|
||||
WebkitUserSelect: "none",
|
||||
touchAction: "pan-x",
|
||||
}}
|
||||
>
|
||||
<div className="interview-rating-header">
|
||||
<span className="interview-rating-header-title">
|
||||
钢铁是怎样炼成的
|
||||
</span>
|
||||
</div>
|
||||
<div className="interview-rating-video">
|
||||
{isLockedItem() ? (
|
||||
<img src="/线下面试模拟锁定.png" alt="线下面试模拟锁定" style={{width: "100%", height: "100%", objectFit: "cover"}} />
|
||||
) : (
|
||||
<video src={getVideoUrl()} controls></video>
|
||||
)}
|
||||
</div>
|
||||
<div className="interview-rating-slide">
|
||||
<i />
|
||||
<span>上滑查看评价</span>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -18,22 +18,19 @@
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
line-height: 20px;
|
||||
color: #1d2129;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 5px;
|
||||
width: 31px;
|
||||
height: 3px;
|
||||
background-image: url("@/assets/images/Common/title_icon.png");
|
||||
background-size: 100% 100%;
|
||||
.mock-interview-title-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { Timeline } from "@arco-design/web-react";
|
||||
import IconFont from "@/components/IconFont";
|
||||
import "./index.css";
|
||||
|
||||
const TimelineItem = Timeline.Item;
|
||||
@@ -14,7 +15,10 @@ export default ({ onItemSelect }) => {
|
||||
|
||||
return (
|
||||
<div className="mock-interview-wrapper">
|
||||
<p className="mock-interview-title">面试模拟</p>
|
||||
<p className="mock-interview-title">
|
||||
<IconFont className="mock-interview-title-icon" src="recuUY5uwYg4km" />
|
||||
<span>面试模拟</span>
|
||||
</p>
|
||||
<ul className="mock-interview-list">
|
||||
<li className="mock-interview-item">
|
||||
<p className="mock-interview-item-title">
|
||||
@@ -33,7 +37,24 @@ export default ({ onItemSelect }) => {
|
||||
onClick={() => handleItemClick("求职面试初体验")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>求职面试初体验</p>
|
||||
<p>
|
||||
求职面试初体验
|
||||
<span style={{
|
||||
marginLeft: '8px',
|
||||
padding: '2px 8px',
|
||||
background: 'linear-gradient(135deg, #5DADE2 0%, #2874A6 100%)',
|
||||
borderRadius: '12px',
|
||||
color: '#ffffff',
|
||||
fontSize: '12px',
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'italic',
|
||||
letterSpacing: '1px',
|
||||
textTransform: 'uppercase',
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
demo
|
||||
</span>
|
||||
</p>
|
||||
<div className="time-line-item-info">
|
||||
初次接触面试环境,体验真实面试流程,了解自身在面试中的基本表现和待提升的方面
|
||||
</div>
|
||||
@@ -48,7 +69,24 @@ export default ({ onItemSelect }) => {
|
||||
onClick={() => handleItemClick("未来的自己")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>未来的自己</p>
|
||||
<p>
|
||||
未来的自己
|
||||
<span style={{
|
||||
marginLeft: '8px',
|
||||
padding: '2px 8px',
|
||||
background: 'linear-gradient(135deg, #5DADE2 0%, #2874A6 100%)',
|
||||
borderRadius: '12px',
|
||||
color: '#ffffff',
|
||||
fontSize: '12px',
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'italic',
|
||||
letterSpacing: '1px',
|
||||
textTransform: 'uppercase',
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
demo
|
||||
</span>
|
||||
</p>
|
||||
<div className="time-line-item-info">
|
||||
经过系统训练后的面试表现,展示个人成长和进步,体现出更强的职场竞争力和专业素养
|
||||
</div>
|
||||
@@ -98,30 +136,6 @@ export default ({ onItemSelect }) => {
|
||||
<p>第三次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第四次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第四次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第四次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第四次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
<TimelineItem
|
||||
lineType="dashed"
|
||||
dot={<div className={`time-line-dot-icon ${selectedItem === "第五次线下面试模拟" ? "time-line-dot-icon-active" : ""}`} />}
|
||||
>
|
||||
<div
|
||||
className={`time-line-item ${selectedItem === "第五次线下面试模拟" ? "time-line-item-active" : ""}`}
|
||||
onClick={() => handleItemClick("第五次线下面试模拟")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<p>第五次线下面试模拟</p>
|
||||
</div>
|
||||
</TimelineItem>
|
||||
</Timeline>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,69 +1,125 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useRef, useEffect } from "react";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
export default function RadarChart({
|
||||
data = [4200, 3000, 20000, 35000, 50000, 18000],
|
||||
data = [5, 8, 5, 8],
|
||||
value = null,
|
||||
indicator = [
|
||||
{ name: "Sales", max: 6500 },
|
||||
{ name: "Administration", max: 16000 },
|
||||
{ name: "Information Technology", max: 30000 },
|
||||
{ name: "Customer Support", max: 38000 },
|
||||
{ name: "Development", max: 52000 },
|
||||
{ name: "Marketing", max: 25000 },
|
||||
],
|
||||
className = "",
|
||||
lineClolr = "#DCDFFF",
|
||||
areaColor = "#CCCDFC",
|
||||
areaBorderColor = "#BDB5FF",
|
||||
}) {
|
||||
const chartRef = useRef(null);
|
||||
const chartInstance = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartRef.current) return;
|
||||
chartInstance.current = echarts.init(chartRef.current);
|
||||
|
||||
const option = {
|
||||
radar: {
|
||||
const option = {
|
||||
tooltip: { show: false },
|
||||
grid: { show: false },
|
||||
radar: [
|
||||
{
|
||||
center: ["50%", "55%"],
|
||||
indicator,
|
||||
radius: "65%", // 默认 65%,调大即可把文字整体外推
|
||||
nameGap: 20, // 再额外增加 6-12px 间距
|
||||
splitArea: { show: false }, // 关键:不显示花纹
|
||||
shape: "circle", // 设置雷达图外圈为圆形
|
||||
// 网格线样式配置
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: lineClolr, // 网格线颜色
|
||||
width: 2,
|
||||
type: "solid", // 线条类型:solid, dashed, dotted
|
||||
},
|
||||
},
|
||||
splitArea: { show: false },
|
||||
axisName: {
|
||||
color: "#4E5969",
|
||||
fontSize: 12,
|
||||
align: "center", // 水平居中
|
||||
verticalAlign: "middle", // 垂直居中
|
||||
lineHeight: 14, // 与富文本行高一致
|
||||
rich: {
|
||||
a: { fontSize: 12, color: "#4E5969" },
|
||||
b: { fontSize: 12, color: "#4E5969" },
|
||||
formatter: function(value) {
|
||||
// 移除富文本标记,只返回纯文本
|
||||
return value.replace(/{[ab]\|([^}]+)}/g, '$1').replace(/\n/g, '');
|
||||
},
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#E5E6EB",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "radar",
|
||||
data: [{ value: data }],
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: "radar",
|
||||
radarIndex: 0,
|
||||
data: [{
|
||||
value: value || data,
|
||||
label: {
|
||||
// 关键:显示数值
|
||||
show: true,
|
||||
formatter: "{c}", // 取当前轴值
|
||||
show: false, // 关键:隐藏雷达图内的标签
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false, // 确保 hover 时也不显示
|
||||
},
|
||||
fontSize: 12,
|
||||
color: "#333",
|
||||
},
|
||||
areaStyle: {}, // 关键:显示面积
|
||||
symbol: "none", // 关键:隐藏所有交点
|
||||
},
|
||||
],
|
||||
};
|
||||
chartInstance.current.setOption(option);
|
||||
areaStyle: {
|
||||
color: areaColor, // 面积填充颜色
|
||||
}, // 关键:显示面积
|
||||
lineStyle: {
|
||||
color: areaBorderColor, // 连接线颜色(边框颜色)
|
||||
width: 3, // 连接线宽度
|
||||
type: "solid", // 线条类型
|
||||
},
|
||||
symbol: "circle", // 显示端点
|
||||
symbolSize: 6, // 端点大小
|
||||
itemStyle: {
|
||||
color: "#fff", // 端点颜色
|
||||
borderColor: areaColor, // 端点边框颜色
|
||||
borderWidth: 2, // 端点边框宽度
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartRef.current) return;
|
||||
|
||||
// 如果实例不存在,则初始化
|
||||
if (!chartInstance.current) {
|
||||
chartInstance.current = echarts.init(chartRef.current);
|
||||
}
|
||||
|
||||
// 设置或更新配置,使用 notMerge: false 来避免重新触发动画
|
||||
chartInstance.current.setOption(option, {
|
||||
notMerge: false,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
});
|
||||
|
||||
const handleResize = () => {
|
||||
chartInstance.current?.resize();
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
// 自适应
|
||||
const resize = () => chartInstance.current?.resize();
|
||||
window.addEventListener("resize", resize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize);
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
}, [data, value, indicator]);
|
||||
|
||||
// 组件卸载时清理
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, [data, indicator, className]);
|
||||
}, []);
|
||||
|
||||
return <div ref={chartRef} className={className} />;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
export default function RadarChart({
|
||||
data = [4200, 3000, 20000, 35000, 50000, 18000],
|
||||
indicator = [
|
||||
{ name: "Sales", max: 6500 },
|
||||
{ name: "Administration", max: 16000 },
|
||||
{ name: "Information Technology", max: 30000 },
|
||||
{ name: "Customer Support", max: 38000 },
|
||||
{ name: "Development", max: 52000 },
|
||||
{ name: "Marketing", max: 25000 },
|
||||
],
|
||||
className = "",
|
||||
}) {
|
||||
const chartRef = useRef(null);
|
||||
const chartInstance = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartRef.current) return;
|
||||
chartInstance.current = echarts.init(chartRef.current);
|
||||
|
||||
const option = {
|
||||
radar: {
|
||||
indicator,
|
||||
radius: "65%", // 默认 65%,调大即可把文字整体外推
|
||||
nameGap: 20, // 再额外增加 6-12px 间距
|
||||
splitArea: { show: false }, // 关键:不显示花纹
|
||||
axisName: {
|
||||
color: "#4E5969",
|
||||
fontSize: 12,
|
||||
align: "center", // 水平居中
|
||||
verticalAlign: "middle", // 垂直居中
|
||||
lineHeight: 14, // 与富文本行高一致
|
||||
rich: {
|
||||
a: { fontSize: 12, color: "#4E5969" },
|
||||
b: { fontSize: 12, color: "#4E5969" },
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "radar",
|
||||
data: [{ value: data }],
|
||||
label: {
|
||||
// 关键:显示数值
|
||||
show: true,
|
||||
formatter: "{c}", // 取当前轴值
|
||||
fontSize: 12,
|
||||
color: "#333",
|
||||
},
|
||||
areaStyle: {}, // 关键:显示面积
|
||||
symbol: "none", // 关键:隐藏所有交点
|
||||
},
|
||||
],
|
||||
};
|
||||
chartInstance.current.setOption(option);
|
||||
|
||||
// 自适应
|
||||
const resize = () => chartInstance.current?.resize();
|
||||
window.addEventListener("resize", resize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize);
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, [data, indicator, className]);
|
||||
|
||||
return <div ref={chartRef} className={className} />;
|
||||
}
|
||||
@@ -1,19 +1,14 @@
|
||||
import { useRef, useEffect, useState } from "react";
|
||||
import { useRef, useEffect } from "react";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const screenWidth = window.screen.width;
|
||||
|
||||
const ScoreChart = ({
|
||||
className = "",
|
||||
value = 70, // 当前得分(0-100)
|
||||
colors = [
|
||||
[1 / 6, "#FF4C3C"],
|
||||
[2 / 6, "#FF8855"],
|
||||
[3 / 6, "#FFBA62"],
|
||||
[4 / 6, "#A5CC58"],
|
||||
[5 / 6, "#66B86F"],
|
||||
[1, "#49AB55"],
|
||||
],
|
||||
colors = new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||
// 渐变色配置
|
||||
{ offset: 0, color: "#2C7FFF" }, // 起始颜色(左端)
|
||||
{ offset: 1, color: "#2CA9FF" }, // 结束颜色(右端)
|
||||
]),
|
||||
}) => {
|
||||
const chartRef = useRef(null);
|
||||
const chartInstance = useRef(null);
|
||||
@@ -24,56 +19,90 @@ const ScoreChart = ({
|
||||
useEffect(() => {
|
||||
if (!chartRef.current) return;
|
||||
|
||||
// 销毁旧实例
|
||||
if (chartInstance.current) chartInstance.current.dispose();
|
||||
|
||||
// 新建实例
|
||||
chartInstance.current = echarts.init(chartRef.current);
|
||||
// 如果实例不存在,则初始化
|
||||
if (!chartInstance.current) {
|
||||
chartInstance.current = echarts.init(chartRef.current);
|
||||
}
|
||||
|
||||
const option = {
|
||||
series: [
|
||||
{
|
||||
type: "gauge",
|
||||
center: ["50%", "80%"],
|
||||
startAngle: 180,
|
||||
endAngle: 360,
|
||||
min: 0,
|
||||
max: 120,
|
||||
splitNumber: 10,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 15,
|
||||
max: 100,
|
||||
radius: "100%",
|
||||
splitNumber: 5,
|
||||
itemStyle: {
|
||||
color: "#FFAB91",
|
||||
},
|
||||
progress: {
|
||||
show: true,
|
||||
width: 20,
|
||||
roundCap: true, // 开启圆角
|
||||
itemStyle: {
|
||||
color: colors,
|
||||
},
|
||||
},
|
||||
pointer: {
|
||||
length: "60%",
|
||||
itemStyle: { color: "auto" },
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 20,
|
||||
},
|
||||
},
|
||||
axisTick: { show: false },
|
||||
splitLine: { show: false },
|
||||
axisLabel: { show: false },
|
||||
detail: {
|
||||
fontSize: 20,
|
||||
offsetCenter: [0, "60%"],
|
||||
valueAnimation: true,
|
||||
formatter: "{value}.00\n总评分",
|
||||
color: "inherit",
|
||||
anchor: {
|
||||
show: false,
|
||||
},
|
||||
radius: "100%",
|
||||
data: [{ value }],
|
||||
title: {
|
||||
show: false,
|
||||
},
|
||||
detail: {
|
||||
valueAnimation: true,
|
||||
lineHeight: 40,
|
||||
borderRadius: 8,
|
||||
offsetCenter: [0, "-15%"],
|
||||
fontSize: 24,
|
||||
formatter: "{value}.00 ",
|
||||
color: "#1D2129",
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
chartInstance.current.setOption(option);
|
||||
// 设置或更新配置,避免重新触发动画
|
||||
chartInstance.current.setOption(option, {
|
||||
notMerge: false,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
});
|
||||
|
||||
// 监听窗口变化
|
||||
window.addEventListener("resize", resize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize);
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, [value, colors]);
|
||||
|
||||
// 组件卸载时清理
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <div ref={chartRef} className={className} />;
|
||||
};
|
||||
|
||||
export default ScoreChart;
|
||||
export default ScoreChart;
|
||||
@@ -0,0 +1,79 @@
|
||||
import { useRef, useEffect, useState } from "react";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const screenWidth = window.screen.width;
|
||||
|
||||
const ScoreChart = ({
|
||||
className = "",
|
||||
value = 70, // 当前得分(0-100)
|
||||
colors = [
|
||||
[1 / 6, "#FF4C3C"],
|
||||
[2 / 6, "#FF8855"],
|
||||
[3 / 6, "#FFBA62"],
|
||||
[4 / 6, "#A5CC58"],
|
||||
[5 / 6, "#66B86F"],
|
||||
[1, "#49AB55"],
|
||||
],
|
||||
}) => {
|
||||
const chartRef = useRef(null);
|
||||
const chartInstance = useRef(null);
|
||||
|
||||
// 图表自适应容器
|
||||
const resize = () => chartInstance.current?.resize();
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartRef.current) return;
|
||||
|
||||
// 销毁旧实例
|
||||
if (chartInstance.current) chartInstance.current.dispose();
|
||||
|
||||
// 新建实例
|
||||
chartInstance.current = echarts.init(chartRef.current);
|
||||
|
||||
const option = {
|
||||
series: [
|
||||
{
|
||||
type: "gauge",
|
||||
min: 0,
|
||||
max: 120,
|
||||
splitNumber: 10,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 15,
|
||||
color: colors,
|
||||
},
|
||||
},
|
||||
pointer: {
|
||||
length: "60%",
|
||||
itemStyle: { color: "auto" },
|
||||
},
|
||||
axisTick: { show: false },
|
||||
splitLine: { show: false },
|
||||
axisLabel: { show: false },
|
||||
detail: {
|
||||
fontSize: 20,
|
||||
offsetCenter: [0, "60%"],
|
||||
valueAnimation: true,
|
||||
formatter: "{value}.00\n总评分",
|
||||
color: "inherit",
|
||||
},
|
||||
radius: "100%",
|
||||
data: [{ value }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
chartInstance.current.setOption(option);
|
||||
|
||||
// 监听窗口变化
|
||||
window.addEventListener("resize", resize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize);
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, [value, colors]);
|
||||
|
||||
return <div ref={chartRef} className={className} />;
|
||||
};
|
||||
|
||||
export default ScoreChart;
|
||||
@@ -5,17 +5,17 @@
|
||||
|
||||
.target-position-content {
|
||||
width: 914px;
|
||||
height: 346px;
|
||||
margin-top: 150px;
|
||||
height: 450px;
|
||||
margin-top: 50px;
|
||||
margin-left: 50px;
|
||||
position: relative;
|
||||
|
||||
.batch-icon {
|
||||
width: 190px;
|
||||
width: 340px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
left: -40px;
|
||||
top: -30px;
|
||||
background-image: url("@/assets/images/JobStrategyDetailPage/batch.png");
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
@@ -27,70 +27,219 @@
|
||||
font-size: 19px;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
|
||||
&:nth-child(1) {
|
||||
margin-top: 60px; /* 第一批次文字下移到圆柱体中心 */
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-top: 25px; /* 第二批次保持原位 */
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
margin-top: 25px; /* 第三批次保持原位 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.batch-content {
|
||||
width: 702px;
|
||||
height: 102px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
left: 189px;
|
||||
background-size: 100% 100%;
|
||||
left: 299px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding-left: 60px;
|
||||
padding-left: 25px;
|
||||
padding-right: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border-radius: 8px;
|
||||
scroll-behavior: smooth;
|
||||
/* 移除背景图片,使用CSS渐变 */
|
||||
|
||||
/* 自定义滚动条样式 */
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: rgba(233, 226, 255, 0.1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(233, 226, 255, 0.5);
|
||||
border-radius: 3px;
|
||||
transition: background 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(233, 226, 255, 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
/* Firefox滚动条 */
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(233, 226, 255, 0.5) rgba(233, 226, 255, 0.1);
|
||||
|
||||
.avatar-wrapper {
|
||||
width: 78px;
|
||||
height: 78px;
|
||||
margin-top: -15px;
|
||||
width: 85px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 20px;
|
||||
margin-right: 15px;
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-3px);
|
||||
|
||||
.student-avatar {
|
||||
box-shadow: 0 6px 16px rgba(44, 127, 255, 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
/* 仅在悬停岗位名称时显示气泡 */
|
||||
.student-name:hover + .position-tooltip {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translate(-50%, -8px);
|
||||
}
|
||||
|
||||
.student-avatar {
|
||||
position: relative;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
border: 2px solid #ffffff;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.student-name {
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 0;
|
||||
width: 78px;
|
||||
height: 30px;
|
||||
border-radius: 57px;
|
||||
border: 1px solid #ffffff;
|
||||
margin-top: 8px;
|
||||
width: 85px;
|
||||
height: 24px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.8);
|
||||
text-align: center;
|
||||
color: #1d2129;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 30px;
|
||||
background-color: #fefcfc;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 气泡提示框 */
|
||||
.position-tooltip {
|
||||
position: absolute;
|
||||
bottom: 35px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
color: #ffffff;
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* 气泡箭头 */
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 6px 6px 0 6px;
|
||||
border-color: rgba(0, 0, 0, 0.85) transparent transparent transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.batch-content1 {
|
||||
top: 2px;
|
||||
background-image: url("@/assets/images/JobStrategyDetailPage/batch1.png");
|
||||
top: 5px;
|
||||
/* 统一渐变样式 - E9E2FF从左到右缓慢淡化 */
|
||||
background: linear-gradient(to right,
|
||||
#E9E2FF 0%,
|
||||
rgba(233, 226, 255, 0.95) 10%,
|
||||
rgba(233, 226, 255, 0.9) 20%,
|
||||
rgba(233, 226, 255, 0.85) 30%,
|
||||
rgba(233, 226, 255, 0.75) 40%,
|
||||
rgba(233, 226, 255, 0.65) 50%,
|
||||
rgba(233, 226, 255, 0.5) 60%,
|
||||
rgba(233, 226, 255, 0.35) 70%,
|
||||
rgba(233, 226, 255, 0.2) 80%,
|
||||
rgba(233, 226, 255, 0.1) 90%,
|
||||
rgba(233, 226, 255, 0) 100%);
|
||||
border: 2px solid #ffffff;
|
||||
}
|
||||
|
||||
.batch-content2 {
|
||||
top: 123px;
|
||||
background-image: url("@/assets/images/JobStrategyDetailPage/batch2.png");
|
||||
top: 140px;
|
||||
/* 统一渐变样式 - E9E2FF从左到右缓慢淡化 */
|
||||
background: linear-gradient(to right,
|
||||
#E9E2FF 0%,
|
||||
rgba(233, 226, 255, 0.95) 10%,
|
||||
rgba(233, 226, 255, 0.9) 20%,
|
||||
rgba(233, 226, 255, 0.85) 30%,
|
||||
rgba(233, 226, 255, 0.75) 40%,
|
||||
rgba(233, 226, 255, 0.65) 50%,
|
||||
rgba(233, 226, 255, 0.5) 60%,
|
||||
rgba(233, 226, 255, 0.35) 70%,
|
||||
rgba(233, 226, 255, 0.2) 80%,
|
||||
rgba(233, 226, 255, 0.1) 90%,
|
||||
rgba(233, 226, 255, 0) 100%);
|
||||
border: 2px solid #ffffff;
|
||||
}
|
||||
|
||||
.batch-content3 {
|
||||
top: 242px;
|
||||
background-image: url("@/assets/images/JobStrategyDetailPage/batch3.png");
|
||||
top: 275px;
|
||||
/* 统一渐变样式 - E9E2FF从左到右缓慢淡化 */
|
||||
background: linear-gradient(to right,
|
||||
#E9E2FF 0%,
|
||||
rgba(233, 226, 255, 0.95) 10%,
|
||||
rgba(233, 226, 255, 0.9) 20%,
|
||||
rgba(233, 226, 255, 0.85) 30%,
|
||||
rgba(233, 226, 255, 0.75) 40%,
|
||||
rgba(233, 226, 255, 0.65) 50%,
|
||||
rgba(233, 226, 255, 0.5) 60%,
|
||||
rgba(233, 226, 255, 0.35) 70%,
|
||||
rgba(233, 226, 255, 0.2) 80%,
|
||||
rgba(233, 226, 255, 0.1) 90%,
|
||||
rgba(233, 226, 255, 0) 100%);
|
||||
border: 2px solid #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,114 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Avatar } from "@arco-design/web-react";
|
||||
import Locked from "@/components/Locked";
|
||||
import jobLevelData from "@/data/joblevel.json";
|
||||
import "./index.css";
|
||||
|
||||
export default ({ locked = false }) => {
|
||||
const batch1Ref = useRef(null);
|
||||
const batch2Ref = useRef(null);
|
||||
const batch3Ref = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
// 添加鼠标滚轮事件监听,实现横向滚动
|
||||
const handleWheel = (e, ref) => {
|
||||
if (ref.current && ref.current.contains(e.target)) {
|
||||
e.preventDefault();
|
||||
ref.current.scrollLeft += e.deltaY;
|
||||
}
|
||||
};
|
||||
|
||||
const batch1El = batch1Ref.current;
|
||||
const batch2El = batch2Ref.current;
|
||||
const batch3El = batch3Ref.current;
|
||||
|
||||
const wheel1Handler = (e) => handleWheel(e, batch1Ref);
|
||||
const wheel2Handler = (e) => handleWheel(e, batch2Ref);
|
||||
const wheel3Handler = (e) => handleWheel(e, batch3Ref);
|
||||
|
||||
if (batch1El) batch1El.addEventListener('wheel', wheel1Handler, { passive: false });
|
||||
if (batch2El) batch2El.addEventListener('wheel', wheel2Handler, { passive: false });
|
||||
if (batch3El) batch3El.addEventListener('wheel', wheel3Handler, { passive: false });
|
||||
|
||||
return () => {
|
||||
if (batch1El) batch1El.removeEventListener('wheel', wheel1Handler);
|
||||
if (batch2El) batch2El.removeEventListener('wheel', wheel2Handler);
|
||||
if (batch3El) batch3El.removeEventListener('wheel', wheel3Handler);
|
||||
};
|
||||
}, []);
|
||||
// 根据岗位名称获取头像
|
||||
const getPositionAvatar = (positionName) => {
|
||||
const jobData = jobLevelData.data;
|
||||
for (const [key, levelData] of Object.entries(jobData)) {
|
||||
const found = levelData.list.find(item => item.position_name === positionName);
|
||||
if (found) {
|
||||
return found.img;
|
||||
}
|
||||
}
|
||||
return "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_teacher-avatar/recuUpSO4gUtJz.png"; // 默认头像
|
||||
};
|
||||
|
||||
// 定义三个批次的岗位数据
|
||||
const batchPositions = {
|
||||
batch1: [
|
||||
"二次元周边店店员",
|
||||
"会展执行助理",
|
||||
"会展讲解员",
|
||||
"会展营销",
|
||||
"商业会展执行专员",
|
||||
"景区运营专员",
|
||||
"文旅运营总监助理",
|
||||
"品牌策划运营专员",
|
||||
"品牌推广专员",
|
||||
"ip运营",
|
||||
"文创产品设计师助理",
|
||||
"新媒体运营专员",
|
||||
"网络运营专员",
|
||||
"社群运营",
|
||||
"直播助理"
|
||||
],
|
||||
batch2: [
|
||||
"宠物店店长",
|
||||
"宠物营养师",
|
||||
"二次元周边选品专员",
|
||||
"二次元周边店店长",
|
||||
"会展策划师",
|
||||
"漫展策划师",
|
||||
"活动执行",
|
||||
"活动策划师",
|
||||
"酒店运营专员",
|
||||
"餐厅运营经理",
|
||||
"露营地运营专员",
|
||||
"旅游规划师",
|
||||
"文旅项目投资拓展管培生",
|
||||
"民宿管家",
|
||||
"民宿客房管家",
|
||||
"民宿运营专员",
|
||||
"品牌公关",
|
||||
"IP运营总监助理",
|
||||
"品牌公关管培生",
|
||||
"直播中控",
|
||||
"SEO专员",
|
||||
"SEM专员",
|
||||
"赛事经纪"
|
||||
],
|
||||
batch3: [
|
||||
"酒店餐饮主管",
|
||||
"客房经理",
|
||||
"酒店大堂副理",
|
||||
"旅游计调专员",
|
||||
"文创产品策划师",
|
||||
"文创产品设计师",
|
||||
"赛事礼仪",
|
||||
"赛事编辑",
|
||||
"艺人经纪人",
|
||||
"演出执行经理",
|
||||
"场馆运营人员"
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="target-position-wrapper">
|
||||
<div className="target-position-content">
|
||||
@@ -11,19 +117,51 @@ export default ({ locked = false }) => {
|
||||
<span>第二批次</span>
|
||||
<span>第三批次</span>
|
||||
</div>
|
||||
<div className="batch-content batch-content1">
|
||||
<div className="avatar-wrapper">
|
||||
<Avatar className="student-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
src="//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp"
|
||||
/>
|
||||
</Avatar>
|
||||
<span className="student-name">张三</span>
|
||||
</div>
|
||||
<div className="batch-content batch-content1" ref={batch1Ref}>
|
||||
{batchPositions.batch1.map((position, index) => (
|
||||
<div key={index} className="avatar-wrapper">
|
||||
<div className="student-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
src={getPositionAvatar(position)}
|
||||
/>
|
||||
</div>
|
||||
<span className="student-name">{position}</span>
|
||||
{/* 完整名称的气泡提示 */}
|
||||
<div className="position-tooltip">{position}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="batch-content batch-content2" ref={batch2Ref}>
|
||||
{batchPositions.batch2.map((position, index) => (
|
||||
<div key={index} className="avatar-wrapper">
|
||||
<div className="student-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
src={getPositionAvatar(position)}
|
||||
/>
|
||||
</div>
|
||||
<span className="student-name">{position}</span>
|
||||
{/* 完整名称的气泡提示 */}
|
||||
<div className="position-tooltip">{position}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="batch-content batch-content3" ref={batch3Ref}>
|
||||
{batchPositions.batch3.map((position, index) => (
|
||||
<div key={index} className="avatar-wrapper">
|
||||
<div className="student-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
src={getPositionAvatar(position)}
|
||||
/>
|
||||
</div>
|
||||
<span className="student-name">{position}</span>
|
||||
{/* 完整名称的气泡提示 */}
|
||||
<div className="position-tooltip">{position}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="batch-content batch-content2"></div>
|
||||
<div className="batch-content batch-content3"></div>
|
||||
|
||||
{locked && (
|
||||
<Locked text="该板块将在「垂直能力提升」阶段开放,完成线上1V1求职策略定制后解锁" />
|
||||
|
||||
@@ -4,75 +4,203 @@
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
|
||||
/* 返回按钮样式 */
|
||||
.back-button-wrapper {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 30px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e5e6eb;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #4e5969;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:hover {
|
||||
background-color: #f7f8fa;
|
||||
border-color: #2c7aff;
|
||||
color: #2c7aff;
|
||||
transform: translateX(-2px);
|
||||
box-shadow: 0 4px 8px rgba(44, 122, 255, 0.15);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98) translateX(-2px);
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.back-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.job-strategy-detail-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 16px;
|
||||
background-image: linear-gradient(180deg, #d7e5ff, #eff4fb);
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
border: 2px solid #fff;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.job-strategy-detail-header {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 310px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 25px;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
z-index: 5;
|
||||
|
||||
.nav-item {
|
||||
color: #86909c;
|
||||
background-color: #f4f7f9;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
width: 140px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 0 12px;
|
||||
|
||||
&:hover {
|
||||
background-color: #e8f3ff;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 优先目标岗位图标 */
|
||||
.target-icon {
|
||||
background-image: url("https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_icon/recuUY5qlmzVhH.png");
|
||||
}
|
||||
|
||||
/* 曲线就业方案图标 */
|
||||
.curved-icon {
|
||||
background-image: url("https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_icon/recuVUShwMZfFm.png");
|
||||
}
|
||||
}
|
||||
|
||||
.item-active {
|
||||
background-color: #0077ff !important;
|
||||
color: #fff !important;
|
||||
|
||||
/* 选中状态的优先目标岗位图标 */
|
||||
.target-icon {
|
||||
background-image: url("https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_icon/recuUY5s6knA9u.png");
|
||||
}
|
||||
|
||||
/* 选中状态的曲线就业方案图标 */
|
||||
.curved-icon {
|
||||
background-image: url("https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/teach_sys_icon/recuVUSJS109uJ.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-strategy-detail-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 80px);
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
margin-top: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.job-strategy-detail-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
border-radius: 16px;
|
||||
background-image: linear-gradient(180deg, #d7e5ff, #eff4fb);
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
border: 2px solid #fff;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.job-strategy-detail-header {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
width: 310px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 25px;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
|
||||
> div {
|
||||
color: #4e5969;
|
||||
color: #86909c;
|
||||
background-color: #f4f7f9;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: 32px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 12px;
|
||||
width: 140px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.item-active {
|
||||
background-color: #f2f3f5;
|
||||
border-radius: 100px;
|
||||
color: #2c7aff;
|
||||
color: #fff;
|
||||
background-color: #0077ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-strategy-detail-content {
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
margin-top: 50px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
.slide-wrapper {
|
||||
width: 123px;
|
||||
height: 125px;
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
top: 20px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-image: url("@/assets/images/JobStrategyDetailPage/slide_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.slide-text {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
color: #0275f2;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
78
src/pages/JobStrategyDetailPage/index.css.bak
Normal file
78
src/pages/JobStrategyDetailPage/index.css.bak
Normal file
@@ -0,0 +1,78 @@
|
||||
.job-strategy-detail-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
|
||||
.job-strategy-detail-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
|
||||
.job-strategy-detail-header {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
> div {
|
||||
color: #4e5969;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: 32px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 12px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item-active {
|
||||
background-color: #f2f3f5;
|
||||
border-radius: 100px;
|
||||
color: #2c7aff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-strategy-detail-content {
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
.slide-wrapper {
|
||||
width: 123px;
|
||||
height: 125px;
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
top: 20px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-image: url("@/assets/images/JobStrategyDetailPage/slide_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.slide-text {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
color: #0275f2;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import TargetPosition from "./components/TargetPosition";
|
||||
import CurvedEmployment from "./components/CurvedEmployment";
|
||||
import "./index.css";
|
||||
@@ -7,165 +8,50 @@ import "./index.css";
|
||||
const SWIPE_THRESHOLD = 120;
|
||||
const JobStrategyDetailPage = () => {
|
||||
const [activeItem, setActiveItem] = useState("1");
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [startX, setStartX] = useState(0);
|
||||
const [currentX, setCurrentX] = useState(0);
|
||||
const slideWrapperRef = useRef(null);
|
||||
const [hasSwiped, setHasSwiped] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// 处理鼠标/触摸开始
|
||||
const handleStart = (clientX) => {
|
||||
setIsDragging(true);
|
||||
setStartX(clientX);
|
||||
setCurrentX(clientX);
|
||||
setHasSwiped(false);
|
||||
// 返回上一页
|
||||
const handleBack = () => {
|
||||
navigate(-1);
|
||||
};
|
||||
|
||||
// 处理鼠标/触摸移动
|
||||
const handleMove = (clientX) => {
|
||||
if (!isDragging) return;
|
||||
|
||||
setCurrentX(clientX);
|
||||
const diffX = clientX - startX;
|
||||
|
||||
// 添加视觉反馈
|
||||
if (slideWrapperRef.current) {
|
||||
slideWrapperRef.current.style.transform = `translateX(${diffX}px)`;
|
||||
slideWrapperRef.current.style.transition = "none";
|
||||
}
|
||||
};
|
||||
|
||||
// 处理鼠标/触摸结束
|
||||
const handleEnd = () => {
|
||||
if (!isDragging) return;
|
||||
|
||||
setIsDragging(false);
|
||||
const diffX = currentX - startX;
|
||||
|
||||
// 恢复原始位置
|
||||
if (slideWrapperRef.current) {
|
||||
slideWrapperRef.current.style.transform = "";
|
||||
slideWrapperRef.current.style.transition = "transform 0.3s ease";
|
||||
}
|
||||
|
||||
// 检查是否达到滑动阈值
|
||||
if (Math.abs(diffX) > SWIPE_THRESHOLD) {
|
||||
if (diffX < 0) {
|
||||
// 左滑
|
||||
handleSwipeLeft();
|
||||
} else {
|
||||
// 右滑
|
||||
handleSwipeRight();
|
||||
}
|
||||
setHasSwiped(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 左滑事件处理
|
||||
const handleSwipeLeft = () => {
|
||||
console.log("触发左滑事件");
|
||||
setActiveItem("2");
|
||||
};
|
||||
|
||||
// 鼠标事件
|
||||
const handleMouseDown = (e) => {
|
||||
handleStart(e.clientX);
|
||||
};
|
||||
|
||||
const handleMouseMove = (e) => {
|
||||
if (isDragging) {
|
||||
e.preventDefault();
|
||||
handleMove(e.clientX);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
handleEnd();
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
handleEnd();
|
||||
};
|
||||
|
||||
// 触摸事件
|
||||
const handleTouchStart = (e) => {
|
||||
handleStart(e.touches[0].clientX);
|
||||
};
|
||||
|
||||
const handleTouchMove = (e) => {
|
||||
if (isDragging) {
|
||||
e.preventDefault();
|
||||
handleMove(e.touches[0].clientX);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
handleEnd();
|
||||
};
|
||||
|
||||
// 添加全局事件监听
|
||||
useEffect(() => {
|
||||
const handleGlobalMouseMove = (e) => handleMouseMove(e);
|
||||
const handleGlobalMouseUp = () => handleMouseUp();
|
||||
|
||||
if (isDragging) {
|
||||
document.addEventListener("mousemove", handleGlobalMouseMove);
|
||||
document.addEventListener("mouseup", handleGlobalMouseUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousemove", handleGlobalMouseMove);
|
||||
document.removeEventListener("mouseup", handleGlobalMouseUp);
|
||||
};
|
||||
}, [isDragging]);
|
||||
|
||||
return (
|
||||
<div className="job-strategy-detail-page">
|
||||
<div className="job-strategy-detail-body">
|
||||
<div className="job-strategy-detail-wrapper">
|
||||
{/* 返回按钮 */}
|
||||
<div className="back-button-wrapper">
|
||||
<button className="back-button" onClick={handleBack}>
|
||||
<span className="back-icon">←</span>
|
||||
<span className="back-text">返回</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 顶部导航栏 */}
|
||||
<div className="job-strategy-detail-header">
|
||||
<div
|
||||
className={` ${activeItem === "1" ? "item-active" : ""}`}
|
||||
className={`nav-item ${activeItem === "1" ? "item-active" : ""}`}
|
||||
onClick={() => setActiveItem("1")}
|
||||
>
|
||||
优先目标岗位
|
||||
<span className="nav-icon target-icon"></span>
|
||||
<span className="nav-text">优先目标岗位</span>
|
||||
</div>
|
||||
<div
|
||||
className={` ${activeItem === "2" ? "item-active" : ""}`}
|
||||
className={`nav-item ${activeItem === "2" ? "item-active" : ""}`}
|
||||
onClick={() => setActiveItem("2")}
|
||||
>
|
||||
"曲线就业"方案
|
||||
<span className="nav-icon curved-icon"></span>
|
||||
<span className="nav-text">曲线就业方案</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="job-strategy-detail-content"
|
||||
ref={slideWrapperRef}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchMove={handleTouchMove}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
style={{
|
||||
cursor: isDragging ? "grabbing" : "grab",
|
||||
userSelect: "none",
|
||||
WebkitUserSelect: "none",
|
||||
touchAction: "pan-y",
|
||||
}}
|
||||
>
|
||||
{activeItem === "1" && (
|
||||
<>
|
||||
<TargetPosition locked={true} />
|
||||
<div className="slide-wrapper">
|
||||
<div className="slide-text">左滑查看曲线就业方案</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeItem === "2" && <CurvedEmployment locked={true} />}
|
||||
|
||||
{/* 内容区域 */}
|
||||
<div className="job-strategy-detail-content">
|
||||
{activeItem === "1" && <TargetPosition locked={false} />}
|
||||
{activeItem === "2" && <CurvedEmployment locked={false} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default JobStrategyDetailPage;
|
||||
export default JobStrategyDetailPage;
|
||||
@@ -11,7 +11,7 @@ const ProfileCard = () => {
|
||||
<Avatar className="profile-card-user-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
src="//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp"
|
||||
src={studentInfo?.avatar || "//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp"}
|
||||
/>
|
||||
</Avatar>
|
||||
<div className="profile-card-user-name">
|
||||
|
||||
@@ -1,18 +1,54 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import "./index.css";
|
||||
|
||||
const Portfolio = () => {
|
||||
const [iframeSrc, setIframeSrc] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
// 添加时间戳参数来破坏缓存
|
||||
const timestamp = new Date().getTime();
|
||||
setIframeSrc(`https://du9uay.github.io/personal-resume-wenlv/?t=${timestamp}`);
|
||||
}, []);
|
||||
|
||||
const handleRefresh = () => {
|
||||
// 手动刷新iframe内容
|
||||
const timestamp = new Date().getTime();
|
||||
setIframeSrc(`https://du9uay.github.io/personal-resume-wenlv/?t=${timestamp}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="user-portfolio-page">
|
||||
<iframe
|
||||
src="https://du9uay.github.io/personal-resume-wenlv/"
|
||||
<button
|
||||
onClick={handleRefresh}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100vh",
|
||||
position: "absolute",
|
||||
top: "10px",
|
||||
right: "10px",
|
||||
zIndex: 1000,
|
||||
padding: "8px 16px",
|
||||
backgroundColor: "#3491fa",
|
||||
color: "white",
|
||||
border: "none",
|
||||
display: "block"
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
fontSize: "14px"
|
||||
}}
|
||||
title="个人简历"
|
||||
/>
|
||||
>
|
||||
刷新页面
|
||||
</button>
|
||||
{iframeSrc && (
|
||||
<iframe
|
||||
key={iframeSrc} // 使用key强制重新渲染iframe
|
||||
src={iframeSrc}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100vh",
|
||||
border: "none",
|
||||
display: "block"
|
||||
}}
|
||||
title="个人简历"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,21 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.project-cases-modal-category-tag {
|
||||
display: inline-block;
|
||||
border: 1px solid #4080ff;
|
||||
background-color: #ffffff;
|
||||
height: 22px;
|
||||
border-radius: 3px;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
color: #4080ff;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.project-cases-modal-title {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
|
||||
@@ -20,6 +20,9 @@ export default ({ visible, onClose, data }) => {
|
||||
<Modal visible={visible} onClose={handleCloseModal}>
|
||||
<div className="project-cases-modal">
|
||||
<i className="close-icon" onClick={handleCloseModal} />
|
||||
{data?.category && (
|
||||
<span className="project-cases-modal-category-tag">{data.category}</span>
|
||||
)}
|
||||
<p className="project-cases-modal-title">{data?.title}</p>
|
||||
<ul className="project-cases-modal-list">
|
||||
{/* 项目概述 */}
|
||||
@@ -35,7 +38,7 @@ export default ({ visible, onClose, data }) => {
|
||||
<ul className="project-cases-modal-horizontal-list">
|
||||
{data?.applicablePositions?.map((pos, index) => (
|
||||
<li key={index} className="high-count-list-item">
|
||||
<span className={pos.level === '初级' ? 'low' : pos.level === '中级' ? 'medium' : 'high'}>
|
||||
<span className={pos.level === '普通岗' ? 'low' : pos.level === '技术骨干岗' ? 'medium' : 'high'}>
|
||||
{pos.level}
|
||||
</span>
|
||||
<p>{pos.position}</p>
|
||||
|
||||
@@ -1,111 +1,177 @@
|
||||
.project-library-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
.project-library-wrapper {
|
||||
width: 100%;
|
||||
height: 790px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.project-library-search-area {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
|
||||
.ser-portfolio-searc {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border: 1px solid #2c7aff;
|
||||
|
||||
span {
|
||||
background-color: #fff;
|
||||
}
|
||||
input {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.project-library-list {
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px 0;
|
||||
|
||||
.project-library-item:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.project-library-item {
|
||||
flex-shrink: 0;
|
||||
width: 340px;
|
||||
height: 82px;
|
||||
box-sizing: border-box;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
background-color: #f7f8fa;
|
||||
border: 1px solid #e5e6eb;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.project-library-item-title {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
border: 1px solid #2c7aff;
|
||||
background-color: #e8f3ff;
|
||||
height: 20px;
|
||||
border-radius: 2px;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
color: #2c7aff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
|
||||
> p {
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
> span {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #2c7aff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.project-library-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
.project-library-wrapper {
|
||||
width: 1120px;
|
||||
/* height: 790px; */
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
.project-library-title {
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
margin-bottom: 20px;
|
||||
color: #1d2129;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
padding-bottom: 10px;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 10px;
|
||||
width: 32px;
|
||||
height: 6px;
|
||||
background-image: url("@/assets/images/Common/title_icon.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.project-library-search-area {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
|
||||
.ser-portfolio-searc {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border: 1px solid #2c7aff;
|
||||
|
||||
span {
|
||||
background-color: #fff;
|
||||
}
|
||||
input {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.project-library-list {
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px 0;
|
||||
|
||||
.project-library-item:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.project-library-item {
|
||||
flex-shrink: 0;
|
||||
width: 340px;
|
||||
height: 100px;
|
||||
box-sizing: border-box;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
background-color: #e5f1ff;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/jobs_page_left_list_item_bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
border: 1px solid #e5e6eb;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border-color: #4080ff;
|
||||
box-shadow: 0 4px 12px rgba(44, 127, 255, 0.2);
|
||||
transform: translateY(-2px);
|
||||
background-color: #f0f7ff;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.project-library-item-title {
|
||||
display: inline-block;
|
||||
border: 1px solid #4080ff;
|
||||
background-color: #ffffff;
|
||||
min-height: 22px;
|
||||
height: 22px;
|
||||
border-radius: 3px;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
color: #4080ff;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 22px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin: 0 0 4px 0;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
|
||||
> p {
|
||||
width: 80%;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
line-height: 1.5;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
> span {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #2c7aff;
|
||||
flex-shrink: 0;
|
||||
margin-left: 10px;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.my-project-library {
|
||||
margin-top: 20px;
|
||||
|
||||
.project-library-empty {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
color: #86909c;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
111
src/pages/ProjectLibraryPage/index.css.bak
Normal file
111
src/pages/ProjectLibraryPage/index.css.bak
Normal file
@@ -0,0 +1,111 @@
|
||||
.project-library-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
.project-library-wrapper {
|
||||
width: 100%;
|
||||
height: 790px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.project-library-search-area {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
|
||||
.ser-portfolio-searc {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border: 1px solid #2c7aff;
|
||||
|
||||
span {
|
||||
background-color: #fff;
|
||||
}
|
||||
input {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.project-library-list {
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px 0;
|
||||
|
||||
.project-library-item:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.project-library-item {
|
||||
flex-shrink: 0;
|
||||
width: 340px;
|
||||
height: 82px;
|
||||
box-sizing: border-box;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
background-color: #f7f8fa;
|
||||
border: 1px solid #e5e6eb;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.project-library-item-title {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
border: 1px solid #2c7aff;
|
||||
background-color: #e8f3ff;
|
||||
height: 20px;
|
||||
border-radius: 2px;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
color: #2c7aff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
|
||||
> p {
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
> span {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #2c7aff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +1,101 @@
|
||||
import { useState } from "react";
|
||||
import { Input } from "@arco-design/web-react";
|
||||
import toast from "@/components/Toast";
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
import ProjectCasesModal from "./components/ProjectCasesModal";
|
||||
import { getProjectsList, getProjectsdetail } from "@/services/projectLibrary";
|
||||
import "./index.css";
|
||||
|
||||
const InputSearch = Input.Search;
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
const ProjectLibrary = () => {
|
||||
const [modalData, setModalData] = useState(undefined);
|
||||
const [projectList, setProjectList] = useState([]);
|
||||
const [projectCasesModalVisible, setProjectCasesModalVisible] =
|
||||
useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
|
||||
const onSearch = (value) => {
|
||||
setProjectList([]);
|
||||
setHasMore(true);
|
||||
setPage(1);
|
||||
fetchProjects(value, 1);
|
||||
};
|
||||
|
||||
const handleProjectClick = async (item) => {
|
||||
if (item?.id) {
|
||||
const res = await getProjectsdetail(item.id);
|
||||
if (res.success) {
|
||||
setModalData(res.data);
|
||||
setProjectCasesModalVisible(true);
|
||||
} else {
|
||||
toast.error(res.message);
|
||||
}
|
||||
} else {
|
||||
toast.error("加载数据失败,请刷新重试");
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setProjectCasesModalVisible(false);
|
||||
setModalData(undefined);
|
||||
};
|
||||
|
||||
const fetchProjects = async (searchValue = "", pageNum) => {
|
||||
try {
|
||||
const res = await getProjectsList({
|
||||
search: searchValue,
|
||||
page: pageNum ?? page,
|
||||
pageSize: PAGE_SIZE,
|
||||
});
|
||||
if (res.success) {
|
||||
setProjectList((prevList) => {
|
||||
const newList = [...prevList, ...res.data];
|
||||
if (res.total === newList?.length) {
|
||||
setHasMore(false);
|
||||
} else {
|
||||
setPage((prevPage) => prevPage + 1);
|
||||
}
|
||||
return newList;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch projects:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="project-library-page">
|
||||
<div className="project-library-wrapper">
|
||||
<div className="project-library-search-area">
|
||||
<InputSearch
|
||||
className="ser-portfolio-search"
|
||||
onSearch={onSearch}
|
||||
searchButton="搜索"
|
||||
/>
|
||||
</div>
|
||||
<InfiniteScroll
|
||||
loadMore={fetchProjects}
|
||||
hasMore={hasMore}
|
||||
empty={projectList.length === 0}
|
||||
className="project-library-list"
|
||||
>
|
||||
{projectList.map((item) => (
|
||||
<li className="project-library-item" key={item.id}>
|
||||
<p className="project-library-item-title">{item.description}</p>
|
||||
<div>
|
||||
<p>{item.name}</p>
|
||||
<span onClick={() => handleProjectClick(item)}>详情 ></span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
<ProjectCasesModal
|
||||
data={modalData}
|
||||
visible={projectCasesModalVisible}
|
||||
onClose={handleCloseModal}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProjectLibrary;
|
||||
import { useState } from "react";
|
||||
import toast from "@/components/Toast";
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
import ProjectCasesModal from "./components/ProjectCasesModal";
|
||||
import { getProjectsList, getProjectsdetail } from "@/services/projectLibrary";
|
||||
import "./index.css";
|
||||
|
||||
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
const ProjectLibrary = () => {
|
||||
const [modalData, setModalData] = useState(undefined);
|
||||
const [projectList, setProjectList] = useState([]);
|
||||
const [projectCasesModalVisible, setProjectCasesModalVisible] =
|
||||
useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
|
||||
|
||||
|
||||
const handleProjectClick = async (item) => {
|
||||
if (item?.id) {
|
||||
const res = await getProjectsdetail(item.id);
|
||||
if (res.success) {
|
||||
setModalData(res.data);
|
||||
setProjectCasesModalVisible(true);
|
||||
} else {
|
||||
toast.error(res.message);
|
||||
}
|
||||
} else {
|
||||
toast.error("加载数据失败,请刷新重试");
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setProjectCasesModalVisible(false);
|
||||
setModalData(undefined);
|
||||
};
|
||||
|
||||
const fetchProjects = async (pageNum) => {
|
||||
try {
|
||||
const res = await getProjectsList({
|
||||
page: pageNum ?? page,
|
||||
pageSize: PAGE_SIZE,
|
||||
});
|
||||
if (res.success) {
|
||||
setProjectList((prevList) => {
|
||||
const newList = [...prevList, ...res.data];
|
||||
if (res.total === newList?.length) {
|
||||
setHasMore(false);
|
||||
} else {
|
||||
setPage((prevPage) => prevPage + 1);
|
||||
}
|
||||
return newList;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch projects:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="project-library-page">
|
||||
<div className="project-library-wrapper">
|
||||
<p className="project-library-title">文旅班级项目库</p>
|
||||
<InfiniteScroll
|
||||
loadMore={fetchProjects}
|
||||
hasMore={hasMore}
|
||||
empty={projectList.length === 0}
|
||||
className="project-library-list"
|
||||
>
|
||||
{projectList.map((item) => (
|
||||
<li className="project-library-item" key={item.id}>
|
||||
<p className="project-library-item-title">{item.description}</p>
|
||||
<div>
|
||||
<p>{item.name}</p>
|
||||
<span onClick={() => handleProjectClick(item)}>详情 ></span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
|
||||
{/* 我的项目库板块 */}
|
||||
<div className="project-library-wrapper my-project-library">
|
||||
<p className="project-library-title">我完成的项目库</p>
|
||||
<div className="project-library-empty">
|
||||
<p>暂无项目</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ProjectCasesModal
|
||||
data={modalData}
|
||||
visible={projectCasesModalVisible}
|
||||
onClose={handleCloseModal}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProjectLibrary;
|
||||
|
||||
@@ -1,289 +1,369 @@
|
||||
.resume-interview-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
.resume-interview-spin,
|
||||
.empty-data {
|
||||
margin: auto;
|
||||
}
|
||||
.resume-interview-navigation {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
z-index: 10;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
||||
|
||||
.active {
|
||||
color: #2c7aff !important;
|
||||
background-color: #f2f3f5;
|
||||
}
|
||||
|
||||
.navigation-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
/* 隐藏滚动条但保留滚动功能 */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-navigation-item {
|
||||
margin-right: 12px;
|
||||
min-width: fit-content;
|
||||
white-space: nowrap;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 100px;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
color: #4e5969;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: #f7f8fa;
|
||||
color: #2c7aff;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-content-wrapper {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 56px 20px 20px 20px;
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
.resume-interview-content-item-wrapper:nth-child(2n) {
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/bg_2.png") !important;
|
||||
|
||||
&::after {
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/icon_2.png") !important;
|
||||
}
|
||||
|
||||
.job-item {
|
||||
> span {
|
||||
border: 1px solid #8d4eda !important;
|
||||
background-color: #f5e8ff !important;
|
||||
color: #8d4eda !important;
|
||||
}
|
||||
}
|
||||
|
||||
.resumes-list {
|
||||
background-image: linear-gradient(
|
||||
180deg,
|
||||
#dcdffb 0%,
|
||||
#dcdffb4d 30%
|
||||
) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-content-item-wrapper {
|
||||
width: 100%;
|
||||
height: 326px;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
border: 2px solid #fff;
|
||||
padding: 16px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/bg_1.png");
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 132px;
|
||||
height: 132px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/icon_1.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 24px;
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.item-subtitle {
|
||||
font-size: 14px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
color: #86909c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-content-wrapper {
|
||||
width: 100%;
|
||||
height: 212px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.jobs-list {
|
||||
width: 664px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 20px 15px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.job-item:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.job-item-change {
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
right: -12px;
|
||||
width: 62px;
|
||||
height: 66px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/change_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
.job-item {
|
||||
width: 311px;
|
||||
height: 80px;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
background-color: #f7f8fa;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid #e5e8ed;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
> span {
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 0 4px;
|
||||
margin-bottom: 5px;
|
||||
color: #3491fa;
|
||||
background-color: #e8f7ff;
|
||||
border: 1px solid #3491fa;
|
||||
}
|
||||
|
||||
.job-name {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
> p {
|
||||
width: 239px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #1d2129;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
> span {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #2c7aff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-results {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #86909c;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.resumes-list {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 408px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
border: 1px solid #ffffff;
|
||||
opacity: 0.91;
|
||||
background-image: linear-gradient(180deg, #d2e5fc 0%, #d2e5fc80 50%);
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.resume-item {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
> p {
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
color: #1d2129;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.resume-interview-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
.resume-interview-spin,
|
||||
.empty-data {
|
||||
margin: auto;
|
||||
}
|
||||
.resume-interview-navigation-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
background-color: #ffffff;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.08);
|
||||
|
||||
.nav-scroll-btn {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 56px;
|
||||
width: 40px;
|
||||
background: linear-gradient(to right, rgba(255,255,255,1), rgba(255,255,255,0.8));
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
color: #4e5969;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(to right, rgba(255,255,255,1), rgba(255,255,255,0.95));
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
&.nav-scroll-btn-left {
|
||||
left: 0;
|
||||
background: linear-gradient(to right, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
&.nav-scroll-btn-right {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, rgba(255,255,255,1), rgba(255,255,255,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-navigation {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
scrollbar-width: none; /* Firefox - 隐藏滚动条 */
|
||||
-ms-overflow-style: none; /* IE and Edge - 隐藏滚动条 */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera - 隐藏滚动条 */
|
||||
}
|
||||
|
||||
.navigation-tabs {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 20px;
|
||||
padding-right: 60px; /* 增加右侧内边距,确保最后一个按钮完全显示 */
|
||||
min-width: 100%;
|
||||
width: max-content;
|
||||
box-sizing: content-box; /* 确保padding不影响width计算 */
|
||||
}
|
||||
|
||||
.resume-interview-navigation-item {
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
min-width: max-content;
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 100px;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
color: #4e5969;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
list-style: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #f7f8fa;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #2c7aff !important;
|
||||
background-color: #f2f3f5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-content-wrapper {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 80px 20px 20px 20px; /* 增加顶部内边距,在导航栏和内容之间添加间隔 */
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
|
||||
.resume-interview-content-item-wrapper {
|
||||
width: 100%;
|
||||
height: 326px;
|
||||
box-sizing: border-box;
|
||||
background-color: #E8F0FF;
|
||||
border-radius: 8px;
|
||||
border: 2px solid #fff;
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: -20px;
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/icon_1.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 24px;
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.item-subtitle {
|
||||
font-size: 14px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
color: #86909c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-content-wrapper {
|
||||
width: 100%;
|
||||
height: 212px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.jobs-list {
|
||||
width: 664px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
rgba(255, 255, 255, 0.3) 0%,
|
||||
rgba(255, 255, 255, 0.6) 100%
|
||||
);
|
||||
opacity: 0.9;
|
||||
border: 1px solid #ffffff;
|
||||
box-sizing: border-box;
|
||||
padding: 20px 15px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.job-item:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.job-item-change {
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
right: -12px;
|
||||
width: 62px;
|
||||
height: 66px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/change_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
.job-item {
|
||||
width: 311px;
|
||||
height: 80px;
|
||||
box-sizing: border-box;
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/bg_1.png");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
margin-bottom: 5px;
|
||||
border: 2px solid #ffffff;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.job-avatar-wrapper {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 10px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.job-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.job-avatar-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.job-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
|
||||
.job-level-tag {
|
||||
width: auto;
|
||||
height: 16px;
|
||||
object-fit: contain;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.job-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
> p {
|
||||
flex: 1;
|
||||
color: #1d2129;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.job-arrow {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #3491fa;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-results {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #86909c;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.resumes-list {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 408px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background-color: #ffffff;
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
border: 1px solid #ffffff;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.resume-item {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
background-color: #EFF6FF;
|
||||
background-image: url("@/assets/images/CompanyJobsPage/jobs_page_left_list_item_bg.png");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 12px;
|
||||
gap: 8px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: #E1EFFF;
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.question-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
> p {
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
color: #1d2129;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
289
src/pages/ResumeInterviewPage/index.css.bak
Normal file
289
src/pages/ResumeInterviewPage/index.css.bak
Normal file
@@ -0,0 +1,289 @@
|
||||
.resume-interview-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
.resume-interview-spin,
|
||||
.empty-data {
|
||||
margin: auto;
|
||||
}
|
||||
.resume-interview-navigation {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
z-index: 10;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
||||
|
||||
.active {
|
||||
color: #2c7aff !important;
|
||||
background-color: #f2f3f5;
|
||||
}
|
||||
|
||||
.navigation-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
/* 隐藏滚动条但保留滚动功能 */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-navigation-item {
|
||||
margin-right: 12px;
|
||||
min-width: fit-content;
|
||||
white-space: nowrap;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 100px;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
color: #4e5969;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: #f7f8fa;
|
||||
color: #2c7aff;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-content-wrapper {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 56px 20px 20px 20px;
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
.resume-interview-content-item-wrapper:nth-child(2n) {
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/bg_2.png") !important;
|
||||
|
||||
&::after {
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/icon_2.png") !important;
|
||||
}
|
||||
|
||||
.job-item {
|
||||
> span {
|
||||
border: 1px solid #8d4eda !important;
|
||||
background-color: #f5e8ff !important;
|
||||
color: #8d4eda !important;
|
||||
}
|
||||
}
|
||||
|
||||
.resumes-list {
|
||||
background-image: linear-gradient(
|
||||
180deg,
|
||||
#dcdffb 0%,
|
||||
#dcdffb4d 30%
|
||||
) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.resume-interview-content-item-wrapper {
|
||||
width: 100%;
|
||||
height: 326px;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
border: 2px solid #fff;
|
||||
padding: 16px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/bg_1.png");
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 132px;
|
||||
height: 132px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/icon_1.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 24px;
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.item-subtitle {
|
||||
font-size: 14px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
color: #86909c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-content-wrapper {
|
||||
width: 100%;
|
||||
height: 212px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.jobs-list {
|
||||
width: 664px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 20px 15px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.job-item:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.job-item-change {
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
right: -12px;
|
||||
width: 62px;
|
||||
height: 66px;
|
||||
background-image: url("@/assets/images/ResumeInterviewPage/change_icon.png");
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
.job-item {
|
||||
width: 311px;
|
||||
height: 80px;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
background-color: #f7f8fa;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid #e5e8ed;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
> span {
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 0 4px;
|
||||
margin-bottom: 5px;
|
||||
color: #3491fa;
|
||||
background-color: #e8f7ff;
|
||||
border: 1px solid #3491fa;
|
||||
}
|
||||
|
||||
.job-name {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
> p {
|
||||
width: 239px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #1d2129;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
> span {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #2c7aff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-results {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #86909c;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.resumes-list {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 408px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
border: 1px solid #ffffff;
|
||||
opacity: 0.91;
|
||||
background-image: linear-gradient(180deg, #d2e5fc 0%, #d2e5fc80 50%);
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
|
||||
.resume-item {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
> p {
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
color: #1d2129;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,11 @@ import toast from "@/components/Toast";
|
||||
import InterviewQuestionsModal from "./components/InterviewQuestionsModal";
|
||||
import ResumeInfoModal from "@/pages/CompanyJobsPage/components/ResumeInfoModal";
|
||||
import { getPageData } from "@/services/resumeInterview";
|
||||
import jobLevelData from "@/data/joblevel.json";
|
||||
import TagHigh from "@/assets/images/ResumeInterviewPage/Tag.png";
|
||||
import TagMiddle from "@/assets/images/ResumeInterviewPage/Tag2.png";
|
||||
import TagOrdinary from "@/assets/images/ResumeInterviewPage/Tag3.png";
|
||||
import QuestionIcon from "@/assets/images/ResumeInterviewPage/question_icon2.png";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
@@ -15,7 +20,50 @@ const ResumeInterviewPage = () => {
|
||||
const [resumeModalData, setResumeModalData] = useState(undefined);
|
||||
const [pageData, setPageData] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [showLeftBtn, setShowLeftBtn] = useState(false);
|
||||
const [showRightBtn, setShowRightBtn] = useState(true);
|
||||
const sectionsRef = useRef({});
|
||||
const navRef = useRef(null);
|
||||
|
||||
// 获取岗位头像和级别信息
|
||||
const getPositionInfo = (positionTitle) => {
|
||||
const jobData = jobLevelData.data;
|
||||
let positionInfo = null;
|
||||
let levelName = "";
|
||||
let levelKey = "";
|
||||
|
||||
// 遍历所有级别查找匹配的岗位
|
||||
for (const [key, levelData] of Object.entries(jobData)) {
|
||||
const found = levelData.list.find(item => item.position_name === positionTitle);
|
||||
if (found) {
|
||||
positionInfo = found;
|
||||
levelName = levelData.name;
|
||||
levelKey = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据级别返回对应的标签图片
|
||||
let tagImage = "";
|
||||
switch(levelKey) {
|
||||
case "high":
|
||||
tagImage = TagHigh;
|
||||
break;
|
||||
case "middle":
|
||||
tagImage = TagMiddle;
|
||||
break;
|
||||
case "ordinary":
|
||||
default:
|
||||
tagImage = TagOrdinary;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
avatar: positionInfo?.img || null,
|
||||
levelName: levelName || "普通岗",
|
||||
tagImage: tagImage
|
||||
};
|
||||
};
|
||||
|
||||
// 导航到指定行业段落
|
||||
const handleNavClick = (industryId) => {
|
||||
@@ -114,28 +162,76 @@ const ResumeInterviewPage = () => {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, [pageData?.industries]);
|
||||
|
||||
// 监听数据变化,更新滚动按钮状态
|
||||
useEffect(() => {
|
||||
if (pageData?.industries && navRef.current) {
|
||||
setTimeout(() => {
|
||||
checkScrollButtons();
|
||||
}, 100);
|
||||
}
|
||||
}, [pageData?.industries]);
|
||||
|
||||
// 检查滚动按钮的显示状态
|
||||
const checkScrollButtons = () => {
|
||||
if (!navRef.current) return;
|
||||
const { scrollLeft, scrollWidth, clientWidth } = navRef.current;
|
||||
setShowLeftBtn(scrollLeft > 5); // 添加5px的容差
|
||||
setShowRightBtn(scrollLeft < scrollWidth - clientWidth - 5); // 添加5px的容差,确保能滚动到最后
|
||||
};
|
||||
|
||||
// 左右滚动函数
|
||||
const scrollNav = (direction) => {
|
||||
if (!navRef.current) return;
|
||||
const scrollAmount = 200; // 每次滚动的距离
|
||||
navRef.current.scrollTo({
|
||||
left: navRef.current.scrollLeft + (direction === 'left' ? -scrollAmount : scrollAmount),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
};
|
||||
|
||||
// 添加鼠标滚轮横向滚动功能
|
||||
useEffect(() => {
|
||||
const navigation = document.querySelector('.resume-interview-navigation');
|
||||
if (!navigation) return;
|
||||
// 延迟执行以确保DOM已经渲染
|
||||
const timer = setTimeout(() => {
|
||||
const navigation = navRef.current;
|
||||
if (!navigation) return;
|
||||
|
||||
const handleWheel = (e) => {
|
||||
const tabs = navigation.querySelector('.navigation-tabs');
|
||||
if (!tabs) return;
|
||||
|
||||
// 检查是否在导航栏区域
|
||||
if (e.currentTarget === navigation || navigation.contains(e.target)) {
|
||||
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
|
||||
const handleWheel = (e) => {
|
||||
// 检查是否鼠标在导航栏上
|
||||
if (navigation.contains(e.target)) {
|
||||
// 阻止默认垂直滚动
|
||||
e.preventDefault();
|
||||
tabs.scrollLeft += e.deltaY * 0.5; // 减慢滚动速度使其更平滑
|
||||
e.stopPropagation();
|
||||
|
||||
// 转换为横向滚动
|
||||
const delta = e.deltaY || e.deltaX;
|
||||
navigation.scrollLeft += delta;
|
||||
|
||||
// 更新按钮状态
|
||||
checkScrollButtons();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
navigation.addEventListener('wheel', handleWheel, { passive: false });
|
||||
return () => navigation.removeEventListener('wheel', handleWheel);
|
||||
}, []);
|
||||
const handleScroll = () => {
|
||||
checkScrollButtons();
|
||||
};
|
||||
|
||||
// 使用捕获阶段以确保事件被正确处理
|
||||
window.addEventListener('wheel', handleWheel, { passive: false, capture: true });
|
||||
navigation.addEventListener('scroll', handleScroll);
|
||||
|
||||
// 初始检查
|
||||
checkScrollButtons();
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('wheel', handleWheel, { capture: true });
|
||||
navigation.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, 100);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [pageData]);
|
||||
|
||||
return (
|
||||
<div className="resume-interview-page">
|
||||
@@ -143,21 +239,39 @@ const ResumeInterviewPage = () => {
|
||||
<Spin size={80} className="resume-interview-spin" />
|
||||
) : pageData ? (
|
||||
<>
|
||||
<ul className="resume-interview-navigation">
|
||||
<div className="navigation-tabs">
|
||||
{pageData.industries.map((industry) => (
|
||||
<li
|
||||
key={industry.id}
|
||||
className={`resume-interview-navigation-item ${
|
||||
activeIndustry === industry.id ? "active" : ""
|
||||
}`}
|
||||
onClick={() => handleNavClick(industry.id)}
|
||||
>
|
||||
{industry.name}
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
</ul>
|
||||
<div className="resume-interview-navigation-wrapper">
|
||||
{showLeftBtn && (
|
||||
<button
|
||||
className="nav-scroll-btn nav-scroll-btn-left"
|
||||
onClick={() => scrollNav('left')}
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
)}
|
||||
<ul className="resume-interview-navigation" ref={navRef}>
|
||||
<div className="navigation-tabs">
|
||||
{pageData.industries.map((industry) => (
|
||||
<li
|
||||
key={industry.id}
|
||||
className={`resume-interview-navigation-item ${
|
||||
activeIndustry === industry.id ? "active" : ""
|
||||
}`}
|
||||
onClick={() => handleNavClick(industry.id)}
|
||||
>
|
||||
{industry.name}
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
</ul>
|
||||
{showRightBtn && (
|
||||
<button
|
||||
className="nav-scroll-btn nav-scroll-btn-right"
|
||||
onClick={() => scrollNav('right')}
|
||||
>
|
||||
›
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<ul className="resume-interview-content-wrapper">
|
||||
{pageData.industries.map((item) => (
|
||||
<li
|
||||
@@ -169,19 +283,39 @@ const ResumeInterviewPage = () => {
|
||||
<p className="item-subtitle">简历与面试题</p>
|
||||
<div className="item-content-wrapper">
|
||||
<ul className="jobs-list">
|
||||
{filterPositions(item.positions).map((position) => (
|
||||
<li
|
||||
className="job-item job-item-change"
|
||||
key={position.id}
|
||||
onClick={() => handlePositionClick(position, item)}
|
||||
>
|
||||
<span>{position.level}</span>
|
||||
<div className="job-name">
|
||||
<p>{position.title}</p>
|
||||
<span>详情 ></span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
{filterPositions(item.positions).map((position) => {
|
||||
const positionInfo = getPositionInfo(position.title);
|
||||
return (
|
||||
<li
|
||||
className="job-item job-item-change"
|
||||
key={position.id}
|
||||
onClick={() => handlePositionClick(position, item)}
|
||||
>
|
||||
<div className="job-avatar-wrapper">
|
||||
{positionInfo.avatar ? (
|
||||
<img
|
||||
src={positionInfo.avatar}
|
||||
alt={position.title}
|
||||
className="job-avatar"
|
||||
/>
|
||||
) : (
|
||||
<div className="job-avatar-placeholder" />
|
||||
)}
|
||||
</div>
|
||||
<div className="job-info">
|
||||
<img
|
||||
src={positionInfo.tagImage}
|
||||
alt={positionInfo.levelName}
|
||||
className="job-level-tag"
|
||||
/>
|
||||
<div className="job-name">
|
||||
<p>岗位名称:{position.title}</p>
|
||||
<span className="job-arrow">›</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
<ul className="resumes-list">
|
||||
{item.questions.map((question) => (
|
||||
@@ -192,6 +326,11 @@ const ResumeInterviewPage = () => {
|
||||
handleQuestionClick({ ...item, questions: question.subQuestions || [question] })
|
||||
}
|
||||
>
|
||||
<img
|
||||
src={QuestionIcon}
|
||||
alt="question"
|
||||
className="question-icon"
|
||||
/>
|
||||
<p>{question.question}</p>
|
||||
</li>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user