feat: 更新企业内推岗位功能
- 删除岗位陪跑流程图标和弹窗组件 - 导入企业内推岗位库.json新数据源(39个岗位) - 实现岗位按截止时间降序排序 - 添加过期岗位判断逻辑,过期岗位显示已过期且无法投递 - 更新岗位卡片显示截止时间格式(YYYY-MM-DD) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,135 +1,65 @@
|
||||
// 导入JSON数据
|
||||
import companyJobsData from './companyJobs.json';
|
||||
import companyJobsNewData from './companyJobsNew.json';
|
||||
import calendarCoursesData from './calendarCourses.json';
|
||||
import aiCoursesData from '../../网页未导入数据/文旅产业/ai课程表.json';
|
||||
import marketingCoursesData from './marketingCourses.json';
|
||||
|
||||
// 转换函数:将JSON数据转换为页面所需格式
|
||||
const transformCompanyJobs = (jobsData) => {
|
||||
return jobsData.map((job, index) => ({
|
||||
id: index + 1,
|
||||
company: job["公司介绍"] ? job["公司介绍"].split('。')[0].substring(0, 20) + '...' : `公司${index + 1}`,
|
||||
position: job["内推岗位名称"],
|
||||
salary: job["薪资"],
|
||||
status: "available",
|
||||
jobType: job["岗位标签"] === "实习" ? "internship" : "fulltime",
|
||||
remainingPositions: parseInt(job["招聘人数"]) || 1,
|
||||
applicationStatus: ["not_applied", "applied", "interview_success", "interview_failed"][Math.floor(Math.random() * 4)],
|
||||
tags: job["职位标签"] || [],
|
||||
deadline: job["截止时间"],
|
||||
type: job["岗位相关标签"] || "专业相关岗位",
|
||||
jobCategory: job["岗位相关标签"] || "专业相关岗位", // 岗位相关标签
|
||||
location: job["工作地点"], // 工作地点
|
||||
education: job["学历要求"], // 学历要求
|
||||
benefits: job["福利标签"] || [], // 福利标签
|
||||
isRecommended: Math.random() > 0.7,
|
||||
details: {
|
||||
location: job["工作地点"],
|
||||
experience: "1-3年",
|
||||
education: job["学历要求"],
|
||||
positions: job["招聘人数"],
|
||||
description: job["职位描述"],
|
||||
requirements: job["任职要求"] ? job["任职要求"].split(/[;;。\n]/).filter(r => r.trim()) : [],
|
||||
benefits: job["福利标签"] || [],
|
||||
companyInfo: job["公司介绍"]
|
||||
}
|
||||
}));
|
||||
};
|
||||
// 获取今天的日期(只保留日期部分)
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
// 转换函数:将日历课程JSON数据转换为日历事件格式
|
||||
const transformCalendarCourses = (coursesData) => {
|
||||
return coursesData
|
||||
.filter(course => course["❌课程状态"] !== "休息" && course["日期"])
|
||||
.map((course, index) => {
|
||||
// 解析日期
|
||||
const dateStr = course["日期"];
|
||||
const [year, month, day] = dateStr.split('/').map(Number);
|
||||
const courseDate = new Date(year, month - 1, day);
|
||||
return jobsData
|
||||
.map((job, index) => {
|
||||
// 处理截止时间格式(2025/8/28 -> Date对象)
|
||||
const deadlineParts = job["截止时间"].split('/');
|
||||
const deadlineDate = new Date(
|
||||
parseInt(deadlineParts[0]),
|
||||
parseInt(deadlineParts[1]) - 1,
|
||||
parseInt(deadlineParts[2])
|
||||
);
|
||||
deadlineDate.setHours(0, 0, 0, 0);
|
||||
|
||||
// 获取课程名称(优先级从高到低)
|
||||
const courseName = course["复合技能阶段"] ||
|
||||
course["公开课"] ||
|
||||
course["垂直方向阶段(方向二:商业活动策划)"] ||
|
||||
course["1V1 规划阶段"] ||
|
||||
course["模拟面试实战练习阶段"] ||
|
||||
"未命名课程";
|
||||
|
||||
// 解析上课时间
|
||||
const timeStr = course["上课时间"] || "20:00-21:00";
|
||||
let startTime = "20:00";
|
||||
let endTime = "21:00";
|
||||
|
||||
// 特殊处理1V1规划课程的时间
|
||||
if (course["1V1 规划阶段"]) {
|
||||
startTime = "14:00";
|
||||
endTime = "16:00";
|
||||
} else {
|
||||
// 处理时间格式,确保有效
|
||||
if (timeStr && timeStr.includes('-')) {
|
||||
const timeParts = timeStr.split('-').map(t => t ? t.trim() : '');
|
||||
if (timeParts[0]) startTime = timeParts[0];
|
||||
if (timeParts[1]) endTime = timeParts[1];
|
||||
} else if (timeStr) {
|
||||
// 如果没有'-',假设是开始时间
|
||||
startTime = timeStr.trim();
|
||||
// 自动计算结束时间(加1小时)
|
||||
const [hour, minute] = startTime.split(':');
|
||||
const endHour = parseInt(hour) + 1;
|
||||
endTime = `${endHour.toString().padStart(2, '0')}:${minute || '00'}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 构建完整的时间戳
|
||||
const startDateTime = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')} ${startTime}`;
|
||||
const endDateTime = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')} ${endTime}`;
|
||||
|
||||
// 确定课程类型和颜色
|
||||
let type = 'class';
|
||||
let color = '#3b82f6'; // 默认蓝色
|
||||
|
||||
if (course["公开课"]) {
|
||||
type = 'public-course';
|
||||
color = '#f59e0b'; // 橙色
|
||||
} else if (course["1V1 规划阶段"]) {
|
||||
type = 'one-on-one';
|
||||
color = '#ec4899'; // 粉色
|
||||
} else if (course["模拟面试实战练习阶段"]) {
|
||||
type = 'interview';
|
||||
color = '#3b82f6'; // 蓝色
|
||||
} else if (course["复合技能阶段"]) {
|
||||
type = 'compound-skill';
|
||||
color = '#667eea'; // 紫色
|
||||
} else if (course["垂直方向阶段(方向二:商业活动策划)"]) {
|
||||
type = 'vertical-skill';
|
||||
color = '#22c55e'; // 绿色
|
||||
}
|
||||
|
||||
// 确定课程状态
|
||||
let status = 'upcoming';
|
||||
const now = new Date();
|
||||
if (courseDate < now) {
|
||||
status = 'completed';
|
||||
} else if (courseDate.toDateString() === now.toDateString()) {
|
||||
status = 'ongoing';
|
||||
}
|
||||
// 判断岗位是否已过期
|
||||
const isExpired = deadlineDate < today;
|
||||
|
||||
return {
|
||||
id: index + 1,
|
||||
title: courseName,
|
||||
fullTitle: courseName,
|
||||
teacher: course["❌导师姓名查询"] || "待定",
|
||||
unit: course["❌查询单元名称"] || "",
|
||||
startTime: startDateTime,
|
||||
endTime: endDateTime,
|
||||
type: type,
|
||||
color: color,
|
||||
textColor: '#1d2129',
|
||||
description: `${courseName} - ${course["❌导师姓名查询"] || "待定"}老师`,
|
||||
status: course["❌课程状态"] || status,
|
||||
weekday: course["星期"],
|
||||
location: course["上课地点"] || "线上",
|
||||
originalDate: course["日期"]
|
||||
company: job["公司介绍"] ? job["公司介绍"].split('。')[0].substring(0, 20) + '...' : `公司${index + 1}`,
|
||||
position: job["内推岗位名称"],
|
||||
salary: job["薪资"],
|
||||
status: isExpired ? "expired" : "available",
|
||||
jobType: job["岗位标签"] === "实习" ? "internship" : "fulltime",
|
||||
remainingPositions: parseInt(job["招聘人数"]) || 1,
|
||||
applicationStatus: isExpired ? "expired" : "not_applied",
|
||||
tags: job["职位标签"] || [],
|
||||
deadline: `${deadlineParts[0]}-${deadlineParts[1].padStart(2, '0')}-${deadlineParts[2].padStart(2, '0')}`, // 格式化为 YYYY-MM-DD
|
||||
deadlineDate: deadlineDate, // 用于排序
|
||||
isExpired: isExpired, // 标记是否过期
|
||||
type: job["岗位相关标签"] || "专业相关岗位",
|
||||
jobCategory: job["岗位相关标签"] || "专业相关岗位",
|
||||
location: job["工作地点"],
|
||||
education: job["学历要求"],
|
||||
benefits: job["福利标签"] || [],
|
||||
isRecommended: Math.random() > 0.7,
|
||||
details: {
|
||||
location: job["工作地点"],
|
||||
experience: "1-3年",
|
||||
education: job["学历要求"],
|
||||
positions: job["招聘人数"],
|
||||
description: job["职位描述"],
|
||||
requirements: job["任职要求"] ? job["任职要求"].split(/[;;。
|
||||
]/).filter(r => r.trim()) : [],
|
||||
benefits: job["福利标签"] || [],
|
||||
companyInfo: job["公司介绍"]
|
||||
}
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
// 按截止时间降序排序(最晚的在前)
|
||||
return b.deadlineDate - a.deadlineDate;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2185,7 +2115,7 @@ export const mockData = {
|
||||
companyJobs: {
|
||||
title: "企业内推岗位",
|
||||
subtitle: "基于AI智能匹配的企业内推岗位推荐系统",
|
||||
companyPositions: transformCompanyJobs(companyJobsData),
|
||||
companyPositions: transformCompanyJobs(companyJobsNewData),
|
||||
},
|
||||
|
||||
// 用户简历数据
|
||||
|
||||
@@ -169,6 +169,23 @@
|
||||
background-size: 100% 100%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: #f2f3f5;
|
||||
color: #c9cdd4;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #f2f3f5;
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
> i {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company-jobs-info-deadline {
|
||||
|
||||
@@ -32,6 +32,12 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
||||
const handleDeliverClick = async (e, item) => {
|
||||
e.stopPropagation(); // 阻止冒泡到li的点击事件
|
||||
|
||||
// 检查岗位是否已过期
|
||||
if (item.isExpired || item.status === 'expired') {
|
||||
toast.error('该岗位已过期,无法投递');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取岗位详情然后打开投递弹窗
|
||||
const res = await getJobsDetail(item.id);
|
||||
if (res.success) {
|
||||
@@ -147,11 +153,12 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
||||
{item?.salary}
|
||||
</p>
|
||||
<button
|
||||
className="company-jobs-btn"
|
||||
className={`company-jobs-btn ${(item.isExpired || item.status === 'expired') ? 'disabled' : ''}`}
|
||||
onClick={(e) => handleDeliverClick(e, item)}
|
||||
disabled={item.isExpired || item.status === 'expired'}
|
||||
>
|
||||
<i />
|
||||
<span>投递</span>
|
||||
<span>{(item.isExpired || item.status === 'expired') ? '已过期' : '投递'}</span>
|
||||
</button>
|
||||
{item?.deadline && (
|
||||
<p className="company-jobs-info-deadline">
|
||||
|
||||
@@ -17,7 +17,6 @@ const PAGE_SIZE = 10;
|
||||
|
||||
const CompanyJobsPage = () => {
|
||||
const studentInfo = useSelector((state) => state.student.studentInfo);
|
||||
const [isExpand, setIsExpand] = useState(false); // 是否展开
|
||||
const [jobs, setJobs] = useState([]);
|
||||
const [jobsListPage, setJobsListPage] = useState(1);
|
||||
const [jobsListHasMore, setJobsListHasMore] = useState(true);
|
||||
@@ -272,37 +271,6 @@ const CompanyJobsPage = () => {
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => setIsExpand(!isExpand)}
|
||||
className={
|
||||
isExpand
|
||||
? "company-jobs-page-process-wrapper-expand"
|
||||
: "company-jobs-page-process-wrapper-close"
|
||||
}
|
||||
>
|
||||
<div className="company-jobs-page-process-wrapper-title">
|
||||
岗位陪跑流程
|
||||
</div>
|
||||
<div className="company-jobs-page-process-content">
|
||||
<div className="company-jobs-page-process-item-icon icon1">
|
||||
<p>内推岗位简历投递</p>
|
||||
</div>
|
||||
<div className="company-jobs-page-process-item-round-dot icon2" />
|
||||
<div className="company-jobs-page-process-item-icon icon3">
|
||||
<p>岗位简历接收</p>
|
||||
</div>
|
||||
<div className="company-jobs-page-process-item-icon icon4">
|
||||
<p>面试时间地点确定</p>
|
||||
</div>
|
||||
<div className="company-jobs-page-process-item-icon icon5">
|
||||
<p>参与企业面试</p>
|
||||
</div>
|
||||
<div className="company-jobs-page-process-item-round-dot icon6" />
|
||||
<div className="company-jobs-page-process-item-icon icon7">
|
||||
<p>企业offer发送</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
1124
网页未导入数据/文旅产业/企业内推岗位库.json
Normal file
1124
网页未导入数据/文旅产业/企业内推岗位库.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user