diff --git a/src/data/mockData.js b/src/data/mockData.js index 504f1af..adeadd8 100644 --- a/src/data/mockData.js +++ b/src/data/mockData.js @@ -74,13 +74,27 @@ const transformInterviewStatus = (statusData, jobsData) => { tags: matchedJob["职位标签"] || [], location: matchedJob["工作地点"], education: matchedJob["学历要求"], - companyInfo: matchedJob["公司介绍"] + companyInfo: matchedJob["公司介绍"], + jobCategory: matchedJob["岗位相关标签"] || "专业相关岗位", + remainingPositions: matchedJob["招聘人数"] ? parseInt(matchedJob["招聘人数"]) : 5, + deadline: matchedJob["截止时间"], + jobType: matchedJob["岗位标签"] === "就业" ? "job" : "internship", + requirements: matchedJob["任职要求"], + description: matchedJob["职位描述"], + welfare: matchedJob["福利标签"] || [] } : { salary: "面议", tags: [], location: "待定", education: "待定", - companyInfo: "" + companyInfo: "", + jobCategory: "专业相关岗位", + remainingPositions: 5, + deadline: "2025-12-31", + jobType: "job", + requirements: "", + description: "", + welfare: [] } }; }) @@ -422,27 +436,103 @@ const generateCourseLiveListFromCalendar = (calendarEvents) => { // 生成公共课程列表:从日历事件中提取公共课程 const generatePublicCourseLiveList = (calendarEvents) => { - // 定义公共课单元 - const publicUnits = { - "终生学习系统课": { - unitId: "public-ai-learning", - unitName: "终生学习系统课", - courses: [] - }, - "营销能力课": { - unitId: "public-marketing", - unitName: "营销能力课", - courses: [] - }, - "企业高管公开课": { - unitId: "public-executive", - unitName: "企业高管公开课", - courses: [] - } + // 课程到单元的映射关系 + const courseToUnitMapping = { + // AI课程映射 + "AI 学习路径与课程总览": "AI 入门与工具环境", + "AI 工具与环境初始化": "AI 入门与工具环境", + "常见 AI 工具对比与选择方法": "AI 入门与工具环境", + "AI 辅助思维导图与可视化工具实践": "AI 入门与工具环境", + "Obsidian × AI:双向链接与模板应用": "AI 入门与工具环境", + "Notion × AI:数据库与多视角管理": "AI 入门与工具环境", + "DuoduoNote × AI:多源视频高效采集": "AI 入门与工具环境", + "AI 辅助卡片化写作与引用规范": "AI 入门与工具环境", + "API × AI 自动同步(Notion/Obsidian)": "AI 入门与工具环境", + "AI 驱动的日程与任务管理": "AI 入门与工具环境", + "RAG 与 AI 知识增强全景": "RAG 与检索增强", + "向量检索与阈值调优(Embedding 技术)": "RAG 与检索增强", + "AI 混合检索:关键词 × 向量": "RAG 与检索增强", + "AI 重排与结果融合": "RAG 与检索增强", + "AI 评测集构建与标注规范": "RAG 与检索增强", + "AI 离线评测与迭代优化": "RAG 与检索增强", + "RAG 接入 AI 第二大脑": "RAG 与检索增强", + "AI 自动化思维:从事件风暴到数据流": "AI 自动化与任务编排", + "AI 错误处理与补偿机制": "AI 自动化与任务编排", + "AI 定时任务与数据抓取管线": "AI 自动化与任务编排", + "Dify:多工具 AI Agent 编排": "AI 自动化与任务编排", + "Dify × AI 应用评测与灰度发布": "AI 自动化与任务编排", + "MCP 工具集入门与 AI 场景": "AI 自动化与任务编排", + "MCP × AI 自动化融合案例": "AI 自动化与任务编排", + "AI 驱动的低代码平台实战(Zapier / Make)": "AI 自动化与任务编排", + "Agent 自动化:多任务协作与调度": "AI 自动化与任务编排", + "AI 项目骨架与协作(Trea/Claude/Copilot)": "AI 项目开发与前端交互", + "AI Agent 前端交互(对话与工具状态)": "AI 项目开发与前端交互", + "RAG × AI 前端展示(可引用回答)": "AI 项目开发与前端交互", + "前端触发 AI 自动化(Webhook 应用)": "AI 项目开发与前端交互", + "AI 应用部署与安全(Vercel/Netlify)": "AI 项目开发与前端交互", + "AI 性能优化与可访问性保障": "AI 项目开发与前端交互", + "AI 项目演示脚本与讲解录制": "AI 项目开发与前端交互", + "AI 应用问题排查与日志分析": "AI 项目开发与前端交互", + "项目协作与版本控制(GitHub / GitLab × AI)": "AI 项目开发与前端交互", + "数据可视化与仪表盘(Superset / PowerBI × AI)": "AI 项目开发与前端交互", + "AI大模型原理解析": "AI 大模型与核心原理", + "提示工程高级策略": "AI 大模型与核心原理", + "模型微调方法": "AI 大模型与核心原理", + "AI DevOps 与 MLOps": "AI 大模型与核心原理", + "向量数据库深度实践": "AI 大模型与核心原理", + "AI 安全与对抗样本": "AI 大模型与核心原理", + "AI 成本优化与算力管理": "AI 大模型与核心原理", + "AutoML 与 AutoAgent": "AI 大模型与核心原理", + "AI × 教育的应用": "AI 行业应用与综合实战", + "AI × 金融的应用": "AI 行业应用与综合实战", + "AI × 医疗的应用": "AI 行业应用与综合实战", + "AI × 制造业的应用": "AI 行业应用与综合实战", + "端到端 AI 应用开发": "AI 行业应用与综合实战", + "企业级 RAG 应用实战": "AI 行业应用与综合实战", + // 营销课程映射 + "PM产品经理思维": "必备营销技能", + "了解你的客户群体": "必备营销技能", + "营销与沟通": "必备营销技能", + "营销的模式": "必备营销技能", + "自我营销第一步:面试": "自我营销课", + "如何在职场中包装自己": "自我营销课", + // 企业高管公开课映射 + "如何进行有效的沟通与表达": "沟通与协作能力", + "高效团队协作与跨部门合作技巧": "沟通与协作能力", + "问题解决与批判性思维的培养": "问题解决与思维能力", + "创新思维与数字化转型中的机会": "问题解决与思维能力", + "企业文化与职场适应": "职场基础与个人发展", + "在企业中如何进行自我管理与自主学习": "职场基础与个人发展", + "情商管理与压力应对": "职场基础与个人发展", + "个人品牌与网络形象管理": "职场基础与个人发展", + "如何利用AI工具在企业中升职加薪": "职业发展与管理技能", + "目标管理与绩效提升的系统方法": "职业发展与管理技能", + "职场领导力与影响力的初步养成": "职业发展与管理技能", + "长期职业规划与可持续发展之路": "职业发展与管理技能" }; - // 导师头像映射 - // teacherAvatars已在文件顶部定义 + // 单元海报映射 + const unitPosters = { + "AI 入门与工具环境": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6sRee.jpg", + "RAG 与检索增强": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6zwRv.jpeg", + "AI 自动化与任务编排": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW7gMz6CiPN.jpeg", + "AI 项目开发与前端交互": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuW8VeXQDVI2.jpeg", + "AI 大模型与核心原理": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWnTJ2VZpoL.jpeg", + "AI 行业应用与综合实战": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWokg39Rmbf.jpeg", + "必备营销技能": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWokGcLVoRh.jpg", + "自我营销课": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWokT3zxfhR.jpeg", + "沟通与协作能力": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWolCj6ffh5.jpeg", + "问题解决与思维能力": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWolCCOVTt1.jpg", + "职场基础与个人发展": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWolCCOM6l0.jpeg", + "职业发展与管理技能": "https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/public_bg/recuWolCCOlOCz.jpg" + }; + + // 定义公共课单元 + const publicUnits = {}; + + // 导师头像映射已在文件顶部定义 + let globalCourseId = 1; + // 遍历日历事件,找出公开课和AI课程 calendarEvents.forEach(event => { // 处理type为'public-course'的课程或AI课程 @@ -452,44 +542,110 @@ const generatePublicCourseLiveList = (calendarEvents) => { const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const courseDay = new Date(courseDate.getFullYear(), courseDate.getMonth(), courseDate.getDate()); - const courseData = { - courseId: `public-${publicUnits["终生学习系统课"].courses.length + publicUnits["营销能力课"].courses.length + publicUnits["企业高管公开课"].courses.length + 1}`, - courseName: event.title, - teacherName: event.teacher, - teacherAvatar: teacherAvatars[event.teacher] || "", - date: event.startTime.split(' ')[0], - time: event.startTime.split(' ')[1] + ' - ' + event.endTime.split(' ')[1], - completed: courseDay < today, - current: courseDay.getTime() === today.getTime(), - upcoming: courseDay > today, - status: event.status, - location: "线上", - duration: "60分钟", - participants: 150 - }; + // 根据课程名称查找对应的单元 + const unitName = courseToUnitMapping[event.title]; - // 根据课程类型和讲师分类 - if (event.type === 'ai-course') { - publicUnits["终生学习系统课"].courses.push(courseData); - } else if (event.type === 'marketing-course' || event.teacher === "孙应战") { - publicUnits["营销能力课"].courses.push(courseData); + if (unitName) { + // 如果单元还不存在,创建它 + if (!publicUnits[unitName]) { + publicUnits[unitName] = { + unitId: `unit-${Object.keys(publicUnits).length + 1}`, + unitName: unitName, + unitPoster: unitPosters[unitName] || "", + courses: [] + }; + } + + const courseData = { + courseId: `public-${globalCourseId++}`, + courseName: event.title, + teacherName: event.teacher, + teacherAvatar: teacherAvatars[event.teacher] || "", + date: event.startTime.split(' ')[0], + time: event.startTime.split(' ')[1] + ' - ' + event.endTime.split(' ')[1], + completed: courseDay < today, + current: courseDay.getTime() === today.getTime(), + upcoming: courseDay > today, + status: event.status, + location: "线上", + duration: "60分钟", + participants: 150 + }; + + publicUnits[unitName].courses.push(courseData); } else { - publicUnits["企业高管公开课"].courses.push(courseData); + // 对于没有映射的课程,根据类型分配到默认单元 + let defaultUnit = "职场基础与个人发展"; + if (event.type === 'ai-course') { + defaultUnit = "AI 入门与工具环境"; + } else if (event.type === 'marketing-course') { + defaultUnit = "必备营销技能"; + } + + if (!publicUnits[defaultUnit]) { + publicUnits[defaultUnit] = { + unitId: `unit-${Object.keys(publicUnits).length + 1}`, + unitName: defaultUnit, + unitPoster: unitPosters[defaultUnit] || "", + courses: [] + }; + } + + const courseData = { + courseId: `public-${globalCourseId++}`, + courseName: event.title, + teacherName: event.teacher, + teacherAvatar: teacherAvatars[event.teacher] || "", + date: event.startTime.split(' ')[0], + time: event.startTime.split(' ')[1] + ' - ' + event.endTime.split(' ')[1], + completed: courseDay < today, + current: courseDay.getTime() === today.getTime(), + upcoming: courseDay > today, + status: event.status, + location: "线上", + duration: "60分钟", + participants: 150 + }; + + publicUnits[defaultUnit].courses.push(courseData); } } }); - // 转换为数组格式并过滤空单元,按顺序返回:终生学习系统课、企业高管公开课、营销能力课 + // 定义单元的优先级顺序 + const unitOrder = [ + // 终生学习系统 + "AI 入门与工具环境", + "RAG 与检索增强", + "AI 自动化与任务编排", + "AI 项目开发与前端交互", + "AI 大模型与核心原理", + "AI 行业应用与综合实战", + // 企业高管公开课 + "沟通与协作能力", + "问题解决与思维能力", + "职场基础与个人发展", + "职业发展与管理技能", + // 营销能力课 + "必备营销技能", + "自我营销课" + ]; + + // 按照定义的顺序返回有课程的单元 const result = []; - if (publicUnits["终生学习系统课"].courses.length > 0) { - result.push(publicUnits["终生学习系统课"]); - } - if (publicUnits["企业高管公开课"].courses.length > 0) { - result.push(publicUnits["企业高管公开课"]); - } - if (publicUnits["营销能力课"].courses.length > 0) { - result.push(publicUnits["营销能力课"]); - } + unitOrder.forEach(unitName => { + if (publicUnits[unitName] && publicUnits[unitName].courses.length > 0) { + result.push(publicUnits[unitName]); + } + }); + + // 添加任何未在顺序列表中的单元 + Object.keys(publicUnits).forEach(unitName => { + if (!unitOrder.includes(unitName) && publicUnits[unitName].courses.length > 0) { + result.push(publicUnits[unitName]); + } + }); + return result; }; diff --git a/src/pages/CompanyJobsPage/components/JobInfoModal/index.css b/src/pages/CompanyJobsPage/components/JobInfoModal/index.css index 8218e66..83a33d2 100644 --- a/src/pages/CompanyJobsPage/components/JobInfoModal/index.css +++ b/src/pages/CompanyJobsPage/components/JobInfoModal/index.css @@ -1,6 +1,6 @@ .job-info-modal-content { max-height: 80vh; - width: 844px; + width: 720px; position: relative; display: flex; flex-direction: column; @@ -8,8 +8,8 @@ justify-content: flex-start; background-color: #f2f3f5; background-image: url("@/assets/images/CompanyJobsPage/background.png"); - background-size: auto; - background-position: top right; + background-size: 100% auto; + background-position: top center; background-repeat: no-repeat; border-radius: 8px; box-sizing: border-box; @@ -194,6 +194,45 @@ white-space: nowrap; box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3); } + + /* 根据岗位相关标签内容设置不同颜色 */ + .job-category-tag[data-category="专业相关岗位"] { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + } + + .job-category-tag[data-category="非专业相关岗位"] { + background: linear-gradient(135deg, #ff6b6b 0%, #feca57 100%); + } + + .job-category-tag[data-category="人才出海岗位"] { + background: linear-gradient(135deg, #00d2ff 0%, #3a7bd5 100%); + } + + .job-remaining-positions { + display: inline-flex; + align-items: center; + margin-left: 8px; + color: #ff4d4f; + font-size: 12px; + font-weight: 600; + white-space: nowrap; + + .warning-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 14px; + height: 14px; + border-radius: 50%; + background-color: #ff4d4f; + color: #ffffff; + font-size: 10px; + font-weight: 700; + font-style: normal; + margin-right: 4px; + flex-shrink: 0; + } + } .job-info-modal-content-position-info-num { font-size: 14px; @@ -221,14 +260,14 @@ margin-top: 10px; .job-info-modal-info-tag { - background-color: #e5e6eb; + background-color: #ffffff; box-sizing: border-box; margin-bottom: 5px; - padding: 1px 8px; - color: #1d2129; + padding: 4px 12px; + color: #86909c; font-size: 12px; - font-weight: 600; - border-radius: 2px; + font-weight: 500; + border-radius: 4px; margin-right: 10px; } } diff --git a/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx b/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx index 4f8ae4a..0c8b6b3 100644 --- a/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx +++ b/src/pages/CompanyJobsPage/components/JobInfoModal/index.jsx @@ -18,11 +18,12 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut const [resumeModalShow, setResumeModalShow] = useState(directToResume); const [resumeInfoModalShow, setResumeInfoModalShow] = useState(false); const [resumeInfoData, setResumeInfoData] = useState(null); + const [currentResumeId, setCurrentResumeId] = useState(null); // 当前查看的简历ID const [resumeList, setResumeList] = useState([]); // 简历列表 const [listPage, setListPage] = useState(1); const [listHasMore, setListHasMore] = useState(true); const [permissionModalVisible, setPermissionModalVisible] = useState(false); - const [selectedVersion, setSelectedVersion] = useState("2"); // 默认选择个人修改版 + const [selectedVersions, setSelectedVersions] = useState({}); // 每个简历的版本选择,使用简历ID作为key // 处理directToResume参数变化 useEffect(() => { @@ -84,12 +85,12 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut resumeTitle: item.title, jobPosition: data?.position, company: data?.company, - resumeVersion: selectedVersion // 添加版本信息 + resumeVersion: selectedVersions[item.id] || "2" // 添加版本信息 }); if (result.success) { // 投递成功,显示成功提示 - const versionText = selectedVersion === "1" ? "原始版" : "个人修改版"; + const versionText = (selectedVersions[item.id] || "2") === "1" ? "原始版" : "个人修改版"; toast.success(`简历"${item.title}"(${versionText})投递成功!`); // 关闭模态框 @@ -148,13 +149,14 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut resumeTitle: item.title, position: item.position, industry: item.industry, - selectedVersion: selectedVersion, + selectedVersion: selectedVersions[item.id] || "2", hasContent: !!positionTemplate?.content, hasOriginal: !!positionTemplate?.content?.original, hasModified: !!positionTemplate?.content?.modified }); setResumeInfoData(resumeData); + setCurrentResumeId(item.id); // 记录当前简历ID setResumeInfoModalShow(true); } else { toast.error('加载简历数据失败'); @@ -198,9 +200,14 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut