feat: 优化岗位系统功能和界面
- 添加已投递岗位展示功能,与企业岗位列表集成 - 修复简历版本选择独立状态管理bug - 统一岗位卡片和详情页面的标签样式 - 为未投递岗位添加剩余数量显示和警告图标 - 优化雷达图和仪表盘的显示效果 - 调整岗位详情弹窗的背景和宽度 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -74,13 +74,27 @@ const transformInterviewStatus = (statusData, jobsData) => {
|
|||||||
tags: matchedJob["职位标签"] || [],
|
tags: matchedJob["职位标签"] || [],
|
||||||
location: matchedJob["工作地点"],
|
location: matchedJob["工作地点"],
|
||||||
education: 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: "面议",
|
salary: "面议",
|
||||||
tags: [],
|
tags: [],
|
||||||
location: "待定",
|
location: "待定",
|
||||||
education: "待定",
|
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 generatePublicCourseLiveList = (calendarEvents) => {
|
||||||
// 定义公共课单元
|
// 课程到单元的映射关系
|
||||||
const publicUnits = {
|
const courseToUnitMapping = {
|
||||||
"终生学习系统课": {
|
// AI课程映射
|
||||||
unitId: "public-ai-learning",
|
"AI 学习路径与课程总览": "AI 入门与工具环境",
|
||||||
unitName: "终生学习系统课",
|
"AI 工具与环境初始化": "AI 入门与工具环境",
|
||||||
courses: []
|
"常见 AI 工具对比与选择方法": "AI 入门与工具环境",
|
||||||
},
|
"AI 辅助思维导图与可视化工具实践": "AI 入门与工具环境",
|
||||||
"营销能力课": {
|
"Obsidian × AI:双向链接与模板应用": "AI 入门与工具环境",
|
||||||
unitId: "public-marketing",
|
"Notion × AI:数据库与多视角管理": "AI 入门与工具环境",
|
||||||
unitName: "营销能力课",
|
"DuoduoNote × AI:多源视频高效采集": "AI 入门与工具环境",
|
||||||
courses: []
|
"AI 辅助卡片化写作与引用规范": "AI 入门与工具环境",
|
||||||
},
|
"API × AI 自动同步(Notion/Obsidian)": "AI 入门与工具环境",
|
||||||
"企业高管公开课": {
|
"AI 驱动的日程与任务管理": "AI 入门与工具环境",
|
||||||
unitId: "public-executive",
|
"RAG 与 AI 知识增强全景": "RAG 与检索增强",
|
||||||
unitName: "企业高管公开课",
|
"向量检索与阈值调优(Embedding 技术)": "RAG 与检索增强",
|
||||||
courses: []
|
"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课程
|
// 遍历日历事件,找出公开课和AI课程
|
||||||
calendarEvents.forEach(event => {
|
calendarEvents.forEach(event => {
|
||||||
// 处理type为'public-course'的课程或AI课程
|
// 处理type为'public-course'的课程或AI课程
|
||||||
@@ -452,44 +542,110 @@ const generatePublicCourseLiveList = (calendarEvents) => {
|
|||||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||||
const courseDay = new Date(courseDate.getFullYear(), courseDate.getMonth(), courseDate.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}`,
|
const unitName = courseToUnitMapping[event.title];
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
// 根据课程类型和讲师分类
|
if (unitName) {
|
||||||
if (event.type === 'ai-course') {
|
// 如果单元还不存在,创建它
|
||||||
publicUnits["终生学习系统课"].courses.push(courseData);
|
if (!publicUnits[unitName]) {
|
||||||
} else if (event.type === 'marketing-course' || event.teacher === "孙应战") {
|
publicUnits[unitName] = {
|
||||||
publicUnits["营销能力课"].courses.push(courseData);
|
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 {
|
} 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 = [];
|
const result = [];
|
||||||
if (publicUnits["终生学习系统课"].courses.length > 0) {
|
unitOrder.forEach(unitName => {
|
||||||
result.push(publicUnits["终生学习系统课"]);
|
if (publicUnits[unitName] && publicUnits[unitName].courses.length > 0) {
|
||||||
}
|
result.push(publicUnits[unitName]);
|
||||||
if (publicUnits["企业高管公开课"].courses.length > 0) {
|
}
|
||||||
result.push(publicUnits["企业高管公开课"]);
|
});
|
||||||
}
|
|
||||||
if (publicUnits["营销能力课"].courses.length > 0) {
|
// 添加任何未在顺序列表中的单元
|
||||||
result.push(publicUnits["营销能力课"]);
|
Object.keys(publicUnits).forEach(unitName => {
|
||||||
}
|
if (!unitOrder.includes(unitName) && publicUnits[unitName].courses.length > 0) {
|
||||||
|
result.push(publicUnits[unitName]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.job-info-modal-content {
|
.job-info-modal-content {
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
width: 844px;
|
width: 720px;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
background-color: #f2f3f5;
|
background-color: #f2f3f5;
|
||||||
background-image: url("@/assets/images/CompanyJobsPage/background.png");
|
background-image: url("@/assets/images/CompanyJobsPage/background.png");
|
||||||
background-size: auto;
|
background-size: 100% auto;
|
||||||
background-position: top right;
|
background-position: top center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -194,6 +194,45 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
|
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 {
|
.job-info-modal-content-position-info-num {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -221,14 +260,14 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.job-info-modal-info-tag {
|
.job-info-modal-info-tag {
|
||||||
background-color: #e5e6eb;
|
background-color: #ffffff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
padding: 1px 8px;
|
padding: 4px 12px;
|
||||||
color: #1d2129;
|
color: #86909c;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut
|
|||||||
const [resumeModalShow, setResumeModalShow] = useState(directToResume);
|
const [resumeModalShow, setResumeModalShow] = useState(directToResume);
|
||||||
const [resumeInfoModalShow, setResumeInfoModalShow] = useState(false);
|
const [resumeInfoModalShow, setResumeInfoModalShow] = useState(false);
|
||||||
const [resumeInfoData, setResumeInfoData] = useState(null);
|
const [resumeInfoData, setResumeInfoData] = useState(null);
|
||||||
|
const [currentResumeId, setCurrentResumeId] = useState(null); // 当前查看的简历ID
|
||||||
const [resumeList, setResumeList] = useState([]); // 简历列表
|
const [resumeList, setResumeList] = useState([]); // 简历列表
|
||||||
const [listPage, setListPage] = useState(1);
|
const [listPage, setListPage] = useState(1);
|
||||||
const [listHasMore, setListHasMore] = useState(true);
|
const [listHasMore, setListHasMore] = useState(true);
|
||||||
const [permissionModalVisible, setPermissionModalVisible] = useState(false);
|
const [permissionModalVisible, setPermissionModalVisible] = useState(false);
|
||||||
const [selectedVersion, setSelectedVersion] = useState("2"); // 默认选择个人修改版
|
const [selectedVersions, setSelectedVersions] = useState({}); // 每个简历的版本选择,使用简历ID作为key
|
||||||
|
|
||||||
// 处理directToResume参数变化
|
// 处理directToResume参数变化
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -84,12 +85,12 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut
|
|||||||
resumeTitle: item.title,
|
resumeTitle: item.title,
|
||||||
jobPosition: data?.position,
|
jobPosition: data?.position,
|
||||||
company: data?.company,
|
company: data?.company,
|
||||||
resumeVersion: selectedVersion // 添加版本信息
|
resumeVersion: selectedVersions[item.id] || "2" // 添加版本信息
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
// 投递成功,显示成功提示
|
// 投递成功,显示成功提示
|
||||||
const versionText = selectedVersion === "1" ? "原始版" : "个人修改版";
|
const versionText = (selectedVersions[item.id] || "2") === "1" ? "原始版" : "个人修改版";
|
||||||
toast.success(`简历"${item.title}"(${versionText})投递成功!`);
|
toast.success(`简历"${item.title}"(${versionText})投递成功!`);
|
||||||
|
|
||||||
// 关闭模态框
|
// 关闭模态框
|
||||||
@@ -148,13 +149,14 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut
|
|||||||
resumeTitle: item.title,
|
resumeTitle: item.title,
|
||||||
position: item.position,
|
position: item.position,
|
||||||
industry: item.industry,
|
industry: item.industry,
|
||||||
selectedVersion: selectedVersion,
|
selectedVersion: selectedVersions[item.id] || "2",
|
||||||
hasContent: !!positionTemplate?.content,
|
hasContent: !!positionTemplate?.content,
|
||||||
hasOriginal: !!positionTemplate?.content?.original,
|
hasOriginal: !!positionTemplate?.content?.original,
|
||||||
hasModified: !!positionTemplate?.content?.modified
|
hasModified: !!positionTemplate?.content?.modified
|
||||||
});
|
});
|
||||||
|
|
||||||
setResumeInfoData(resumeData);
|
setResumeInfoData(resumeData);
|
||||||
|
setCurrentResumeId(item.id); // 记录当前简历ID
|
||||||
setResumeInfoModalShow(true);
|
setResumeInfoModalShow(true);
|
||||||
} else {
|
} else {
|
||||||
toast.error('加载简历数据失败');
|
toast.error('加载简历数据失败');
|
||||||
@@ -198,9 +200,14 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut
|
|||||||
<div className="version-selector">
|
<div className="version-selector">
|
||||||
<Select
|
<Select
|
||||||
placeholder="选择版本"
|
placeholder="选择版本"
|
||||||
value={selectedVersion}
|
value={selectedVersions[item.id] || "2"}
|
||||||
style={{ width: 120, fontSize: '12px' }}
|
style={{ width: 120, fontSize: '12px' }}
|
||||||
onChange={(value) => setSelectedVersion(value)}
|
onChange={(value) => {
|
||||||
|
setSelectedVersions(prev => ({
|
||||||
|
...prev,
|
||||||
|
[item.id]: value
|
||||||
|
}));
|
||||||
|
}}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<Select.Option value="1">原始版</Select.Option>
|
<Select.Option value="1">原始版</Select.Option>
|
||||||
@@ -231,13 +238,22 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut
|
|||||||
</span>
|
</span>
|
||||||
{/* 岗位相关标签 */}
|
{/* 岗位相关标签 */}
|
||||||
{(data?.jobCategoryTag || data?.jobCategory) && (
|
{(data?.jobCategoryTag || data?.jobCategory) && (
|
||||||
<span className="job-category-tag">
|
<span
|
||||||
|
className="job-category-tag"
|
||||||
|
data-category={data?.jobCategoryTag || data?.jobCategory}
|
||||||
|
>
|
||||||
{data?.jobCategoryTag || data?.jobCategory}
|
{data?.jobCategoryTag || data?.jobCategory}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<span className="job-info-modal-content-position-info-num">
|
|
||||||
该岗位仅剩{data?.remainingPositions}人
|
{/* 岗位剩余量 - 仅未投递岗位显示 */}
|
||||||
</span>
|
{!data?.isDelivered && data?.remainingPositions && (
|
||||||
|
<span className="job-remaining-positions">
|
||||||
|
<i className="warning-icon">!</i>
|
||||||
|
岗位招聘数量仅剩{data?.remainingPositions}名
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
<span className="job-info-modal-content-position-info-salary">
|
<span className="job-info-modal-content-position-info-salary">
|
||||||
{data?.salary}
|
{data?.salary}
|
||||||
</span>
|
</span>
|
||||||
@@ -314,10 +330,11 @@ export default ({ visible, onClose, data, directToResume = false, hideDeliverBut
|
|||||||
<ResumeInfoModal
|
<ResumeInfoModal
|
||||||
visible={resumeInfoModalShow}
|
visible={resumeInfoModalShow}
|
||||||
data={resumeInfoData}
|
data={resumeInfoData}
|
||||||
initialVersion={selectedVersion}
|
initialVersion={selectedVersions[currentResumeId] || "2"}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setResumeInfoModalShow(false);
|
setResumeInfoModalShow(false);
|
||||||
setResumeInfoData(null);
|
setResumeInfoData(null);
|
||||||
|
setCurrentResumeId(null);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<PermissionModal
|
<PermissionModal
|
||||||
|
|||||||
@@ -73,6 +73,38 @@
|
|||||||
color: #86909c;
|
color: #86909c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.delivered {
|
||||||
|
background-color: #f7f8fa;
|
||||||
|
background-image: none;
|
||||||
|
border-color: #e5e6eb;
|
||||||
|
opacity: 0.9;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #c9cdd4;
|
||||||
|
box-shadow: none;
|
||||||
|
transform: none;
|
||||||
|
background-color: #f2f3f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-jobs-info-position {
|
||||||
|
color: #86909c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-jobs-info-tags {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-jobs-info-position-salary {
|
||||||
|
color: #c9cdd4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-jobs-info-category-tag {
|
||||||
|
opacity: 0.7;
|
||||||
|
background-color: #f2f3f5;
|
||||||
|
color: #86909c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -146,14 +178,14 @@
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
|
|
||||||
.company-jobs-info-tag {
|
.company-jobs-info-tag {
|
||||||
background-color: #fff;
|
background-color: #ffffff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
padding: 1px 8px;
|
padding: 4px 12px;
|
||||||
color: #4e5969;
|
color: #86909c;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,6 +261,25 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.delivered {
|
||||||
|
background-color: #f0f5ff;
|
||||||
|
color: #52c41a;
|
||||||
|
border: 1px solid #b7eb8f;
|
||||||
|
cursor: not-allowed;
|
||||||
|
pointer-events: none;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f0f5ff;
|
||||||
|
box-shadow: none;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> i {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.company-jobs-info-deadline {
|
.company-jobs-info-deadline {
|
||||||
|
|||||||
@@ -12,14 +12,47 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
|||||||
|
|
||||||
const handleJobClick = async (e, item) => {
|
const handleJobClick = async (e, item) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const res = await getJobsDetail(item.id);
|
|
||||||
if (res.success) {
|
// 如果是已投递的岗位,直接使用岗位本身的数据
|
||||||
// Mock数据已经是前端格式,不需要映射
|
if (item.isDelivered) {
|
||||||
setJobInfoData(res.data);
|
// 已投递岗位已经包含了所有必要的数据,需要转换为Modal期望的格式
|
||||||
setDirectToResume(false); // 点击岗位条目,显示详情
|
setJobInfoData({
|
||||||
|
id: item.originalInterviewId || item.id,
|
||||||
|
position: item.position,
|
||||||
|
salary: item.salary,
|
||||||
|
location: item.location,
|
||||||
|
education: item.education,
|
||||||
|
tags: item.tags,
|
||||||
|
jobCategory: item.jobCategory,
|
||||||
|
deadline: item.deadline,
|
||||||
|
welfare: item.welfare,
|
||||||
|
isDelivered: true,
|
||||||
|
interviewTime: item.interviewTime,
|
||||||
|
interviewStatus: item.interviewStatus,
|
||||||
|
// 将详细信息放在details对象中,以匹配Modal的期望格式
|
||||||
|
details: {
|
||||||
|
description: item.description || "",
|
||||||
|
requirements: item.requirements ?
|
||||||
|
(typeof item.requirements === 'string' ?
|
||||||
|
item.requirements.split(/\d+\.\s*/).filter(r => r.trim()) :
|
||||||
|
item.requirements) : [],
|
||||||
|
requirementsText: typeof item.requirements === 'string' ? item.requirements : "",
|
||||||
|
companyInfo: item.companyInfo || ""
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setDirectToResume(false);
|
||||||
setJobInfoModalVisible(true);
|
setJobInfoModalVisible(true);
|
||||||
} else {
|
} else {
|
||||||
toast.error(res.message);
|
// 未投递的岗位,从服务获取详情
|
||||||
|
const res = await getJobsDetail(item.id);
|
||||||
|
if (res.success) {
|
||||||
|
// Mock数据已经是前端格式,不需要映射
|
||||||
|
setJobInfoData(res.data);
|
||||||
|
setDirectToResume(false); // 点击岗位条目,显示详情
|
||||||
|
setJobInfoModalVisible(true);
|
||||||
|
} else {
|
||||||
|
toast.error(res.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,11 +150,11 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
|||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className={`company-jobs-page-left-list-item ${(item.isExpired || item.status === 'expired') ? 'expired' : ''}`}
|
className={`company-jobs-page-left-list-item ${(item.isExpired || item.status === 'expired') ? 'expired' : ''} ${item.isDelivered ? 'delivered' : ''}`}
|
||||||
style={{ backgroundColor }}
|
style={{ backgroundColor }}
|
||||||
onClick={(e) => handleJobClick(e, item)}
|
onClick={(e) => handleJobClick(e, item)}
|
||||||
>
|
>
|
||||||
<i className={`icon icon-${item?.jobType}`}></i>
|
|
||||||
<div className="company-jobs-info">
|
<div className="company-jobs-info">
|
||||||
<div className="company-jobs-info-position-wrapper">
|
<div className="company-jobs-info-position-wrapper">
|
||||||
<p className="company-jobs-info-position">{item?.position}</p>
|
<p className="company-jobs-info-position">{item?.position}</p>
|
||||||
@@ -144,21 +177,27 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<p className="company-jobs-info-position-count">
|
{!item.isDelivered && !item.isExpired && item.status !== 'expired' && (
|
||||||
岗位招聘数量仅剩{item?.remainingPositions}名
|
<p className="company-jobs-info-position-count">
|
||||||
</p>
|
岗位招聘数量仅剩{item?.remainingPositions}名
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="company-jobs-btn-wrapper">
|
<div className="company-jobs-btn-wrapper">
|
||||||
<p className="company-jobs-info-position-salary">
|
<p className="company-jobs-info-position-salary">
|
||||||
{item?.salary}
|
{item?.salary}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
className={`company-jobs-btn ${(item.isExpired || item.status === 'expired') ? 'disabled' : ''}`}
|
className={`company-jobs-btn ${(item.isExpired || item.status === 'expired') ? 'disabled' : item.isDelivered ? 'delivered' : ''}`}
|
||||||
onClick={(e) => handleDeliverClick(e, item)}
|
onClick={(e) => item.isDelivered ? e.stopPropagation() : handleDeliverClick(e, item)}
|
||||||
disabled={item.isExpired || item.status === 'expired'}
|
disabled={item.isExpired || item.status === 'expired' || item.isDelivered}
|
||||||
>
|
>
|
||||||
<i />
|
<i />
|
||||||
<span>{(item.isExpired || item.status === 'expired') ? '已过期' : '投递'}</span>
|
<span>{
|
||||||
|
(item.isExpired || item.status === 'expired') ? '已过期' :
|
||||||
|
item.isDelivered ? '已投递' :
|
||||||
|
'投递'
|
||||||
|
}</span>
|
||||||
</button>
|
</button>
|
||||||
{item?.deadline && (
|
{item?.deadline && (
|
||||||
<p className="company-jobs-info-deadline">
|
<p className="company-jobs-info-deadline">
|
||||||
@@ -175,6 +214,7 @@ export default ({ className = "", data = [], backgroundColor }) => {
|
|||||||
visible={jobInfoModalVisible}
|
visible={jobInfoModalVisible}
|
||||||
onClose={onClickJobInfoModalClose}
|
onClose={onClickJobInfoModalClose}
|
||||||
directToResume={directToResume}
|
directToResume={directToResume}
|
||||||
|
hideDeliverButton={jobInfoData?.isDelivered || false}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -45,25 +45,60 @@ const CompanyJobsPage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res?.success) {
|
if (res?.success) {
|
||||||
// 设置岗位数据
|
// 设置面试数据
|
||||||
if (res.data?.jobs) {
|
let interviewsData = [];
|
||||||
|
if (res.data?.interviews) {
|
||||||
// Mock数据已经是前端格式,直接使用不需要映射
|
// Mock数据已经是前端格式,直接使用不需要映射
|
||||||
const jobs = res.data.jobs.list || [];
|
interviewsData = res.data.interviews.list || [];
|
||||||
setJobs(jobs);
|
setInterviews(interviewsData);
|
||||||
setJobsListHasMore(res.data.jobs.hasMore);
|
setInterviewsHasMore(res.data.interviews.hasMore);
|
||||||
if (jobs.length > 0) {
|
if (interviewsData.length > 0) {
|
||||||
setJobsListPage(2); // 下次从第2页开始
|
setInterviewsPage(2); // 下次从第2页开始
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置面试数据
|
// 设置岗位数据 - 包含已投递的岗位
|
||||||
if (res.data?.interviews) {
|
if (res.data?.jobs) {
|
||||||
// Mock数据已经是前端格式,直接使用不需要映射
|
// Mock数据已经是前端格式,直接使用不需要映射
|
||||||
const interviews = res.data.interviews.list || [];
|
const jobsList = res.data.jobs.list || [];
|
||||||
setInterviews(interviews);
|
|
||||||
setInterviewsHasMore(res.data.interviews.hasMore);
|
// 从面试数据中提取已投递的岗位信息
|
||||||
if (interviews.length > 0) {
|
const deliveredJobs = interviewsData.map(interview => {
|
||||||
setInterviewsPage(2); // 下次从第2页开始
|
// 确保有完整的岗位数据
|
||||||
|
const jobData = interview.job || {};
|
||||||
|
return {
|
||||||
|
id: `delivered-${interview.id}`, // 使用特殊的ID标识已投递岗位
|
||||||
|
position: interview.position,
|
||||||
|
isDelivered: true, // 标记为已投递
|
||||||
|
interviewTime: interview.interviewTime,
|
||||||
|
interviewStatus: interview.statusText,
|
||||||
|
originalInterviewId: interview.id,
|
||||||
|
// 从job对象中提取所有必要字段
|
||||||
|
salary: jobData.salary || "面议",
|
||||||
|
tags: jobData.tags || [],
|
||||||
|
location: jobData.location || "待定",
|
||||||
|
education: jobData.education || "待定",
|
||||||
|
jobCategory: jobData.jobCategory || "专业相关岗位",
|
||||||
|
remainingPositions: jobData.remainingPositions || 5,
|
||||||
|
deadline: jobData.deadline || "2025-12-31",
|
||||||
|
jobType: jobData.jobType || "job",
|
||||||
|
requirements: jobData.requirements || "",
|
||||||
|
description: jobData.description || "",
|
||||||
|
welfare: jobData.welfare || [],
|
||||||
|
companyInfo: jobData.companyInfo || ""
|
||||||
|
};
|
||||||
|
}).filter(job => job.position); // 过滤掉没有岗位信息的项
|
||||||
|
|
||||||
|
// 分离未投递和已过期的岗位
|
||||||
|
const activeJobs = jobsList.filter(job => !job.isExpired && job.status !== 'expired');
|
||||||
|
const expiredJobs = jobsList.filter(job => job.isExpired || job.status === 'expired');
|
||||||
|
|
||||||
|
// 按照顺序合并:未投递 -> 已投递 -> 已过期
|
||||||
|
const allJobs = [...activeJobs, ...deliveredJobs, ...expiredJobs];
|
||||||
|
setJobs(allJobs);
|
||||||
|
setJobsListHasMore(res.data.jobs.hasMore);
|
||||||
|
if (allJobs.length > 0) {
|
||||||
|
setJobsListPage(2); // 下次从第2页开始
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,19 +14,57 @@ export default function RadarChart({
|
|||||||
lineClolr = "#DCDFFF",
|
lineClolr = "#DCDFFF",
|
||||||
areaColor = "#CCCDFC",
|
areaColor = "#CCCDFC",
|
||||||
areaBorderColor = "#BDB5FF",
|
areaBorderColor = "#BDB5FF",
|
||||||
|
isGreenTheme = false, // 新增参数:是否使用绿色主题
|
||||||
}) {
|
}) {
|
||||||
const chartRef = useRef(null);
|
const chartRef = useRef(null);
|
||||||
const chartInstance = useRef(null);
|
const chartInstance = useRef(null);
|
||||||
|
|
||||||
|
// 获取实际数据值
|
||||||
|
const actualData = value || data;
|
||||||
|
|
||||||
|
// 创建渐变色配置
|
||||||
|
const gradientColor = isGreenTheme ? {
|
||||||
|
type: 'radial',
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.5,
|
||||||
|
r: 0.5,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(34, 197, 94, 0.3)' // 绿色中心
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(34, 197, 94, 0.8)' // 绿色边缘
|
||||||
|
}]
|
||||||
|
} : {
|
||||||
|
type: 'radial',
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.5,
|
||||||
|
r: 0.5,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(189, 181, 255, 0.3)' // 紫色中心
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(189, 181, 255, 0.8)' // 紫色边缘
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为指标添加分数显示
|
||||||
|
const indicatorWithScore = indicator.map((item, index) => ({
|
||||||
|
...item,
|
||||||
|
name: item.name,
|
||||||
|
value: actualData[index] // 存储分数值
|
||||||
|
}));
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
tooltip: { show: false },
|
tooltip: { show: false },
|
||||||
grid: { show: false },
|
grid: { show: false },
|
||||||
radar: [
|
radar: [
|
||||||
{
|
{
|
||||||
center: ["50%", "50%"],
|
center: ["50%", "50%"],
|
||||||
indicator,
|
indicator: indicatorWithScore,
|
||||||
radius: "55%", // 调小半径以确保文字不超出容器
|
radius: "45%", // 调小半径以确保文字和分数不超出容器
|
||||||
nameGap: 8, // 调整文字与雷达图的间距
|
nameGap: 35, // 增大间距,让文字距离雷达图更远
|
||||||
shape: "circle", // 设置雷达图外圈为圆形
|
shape: "circle", // 设置雷达图外圈为圆形
|
||||||
// 网格线样式配置
|
// 网格线样式配置
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@@ -41,17 +79,40 @@ export default function RadarChart({
|
|||||||
color: "#4E5969",
|
color: "#4E5969",
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: "900", // 更粗的文字
|
fontWeight: "900", // 更粗的文字
|
||||||
lineHeight: 16,
|
lineHeight: 20,
|
||||||
formatter: function(value) {
|
align: 'center', // 文本居中对齐
|
||||||
// 已经包含换行符的直接返回
|
rich: {
|
||||||
|
score: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: isGreenTheme ? '#22c55e' : '#8b5cf6',
|
||||||
|
padding: [0, 0, 8, 0],
|
||||||
|
align: 'center',
|
||||||
|
lineHeight: 24
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#4E5969',
|
||||||
|
fontWeight: '900',
|
||||||
|
align: 'center',
|
||||||
|
lineHeight: 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatter: function(value, indicator) {
|
||||||
|
const index = indicatorWithScore.findIndex(item => item.name === value);
|
||||||
|
const score = actualData[index];
|
||||||
|
// 已经包含换行符的处理
|
||||||
if (value.includes('\n')) {
|
if (value.includes('\n')) {
|
||||||
return value;
|
const parts = value.split('\n');
|
||||||
|
return '{score|' + score + '}\n{name|' + parts.join('\n') + '}';
|
||||||
}
|
}
|
||||||
// 对较长的文本进行换行处理
|
// 对较长的文本进行换行处理
|
||||||
if (value.length > 8) {
|
if (value.length > 8) {
|
||||||
return value.substring(0, 8) + '\n' + value.substring(8);
|
const line1 = value.substring(0, 8);
|
||||||
|
const line2 = value.substring(8);
|
||||||
|
return '{score|' + score + '}\n{name|' + line1 + '\n' + line2 + '}';
|
||||||
}
|
}
|
||||||
return value;
|
return '{score|' + score + '}\n{name|' + value + '}';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@@ -78,10 +139,10 @@ export default function RadarChart({
|
|||||||
color: "#333",
|
color: "#333",
|
||||||
},
|
},
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
color: areaColor, // 面积填充颜色
|
color: gradientColor, // 使用渐变色
|
||||||
}, // 关键:显示面积
|
}, // 关键:显示面积
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
color: areaBorderColor, // 连接线颜色(边框颜色)
|
color: isGreenTheme ? '#22c55e' : areaBorderColor, // 连接线颜色(边框颜色)
|
||||||
width: 3, // 连接线宽度
|
width: 3, // 连接线宽度
|
||||||
type: "solid", // 线条类型
|
type: "solid", // 线条类型
|
||||||
},
|
},
|
||||||
@@ -89,7 +150,7 @@ export default function RadarChart({
|
|||||||
symbolSize: 6, // 端点大小
|
symbolSize: 6, // 端点大小
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: "#fff", // 端点颜色
|
color: "#fff", // 端点颜色
|
||||||
borderColor: areaColor, // 端点边框颜色
|
borderColor: isGreenTheme ? '#22c55e' : areaBorderColor, // 端点边框颜色
|
||||||
borderWidth: 2, // 端点边框宽度
|
borderWidth: 2, // 端点边框宽度
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ const ScoreChart = ({
|
|||||||
lineHeight: 40,
|
lineHeight: 40,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
offsetCenter: [0, "-15%"],
|
offsetCenter: [0, "-15%"],
|
||||||
fontSize: 24,
|
fontSize: 36,
|
||||||
|
fontWeight: "bold",
|
||||||
formatter: "{value}.00 ",
|
formatter: "{value}.00 ",
|
||||||
color: "#1D2129",
|
color: "#1D2129",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user