feat: 优化班级排名展示并集成Lottie动画
- 限制班级排名详情页只展示前10名学员 - 替换面试状态数据为文旅产业15个岗位数据 - 将面试状态展开动画从静态图片改为Lottie动画 - 添加5个面试状态的Lottie动画文件 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1
public/lottie/interview-status/1-off_初筛未通过.json
Normal file
1
public/lottie/interview-status/1-off_初筛未通过.json
Normal file
File diff suppressed because one or more lines are too long
1
public/lottie/interview-status/2-off_面试未通过.json
Normal file
1
public/lottie/interview-status/2-off_面试未通过.json
Normal file
File diff suppressed because one or more lines are too long
1
public/lottie/interview-status/3-off_未参与面试.json
Normal file
1
public/lottie/interview-status/3-off_未参与面试.json
Normal file
File diff suppressed because one or more lines are too long
1
public/lottie/interview-status/4-off_拒绝Offer.json
Normal file
1
public/lottie/interview-status/4-off_拒绝Offer.json
Normal file
File diff suppressed because one or more lines are too long
1
public/lottie/interview-status/4-on_收到Offer.json
Normal file
1
public/lottie/interview-status/4-on_收到Offer.json
Normal file
File diff suppressed because one or more lines are too long
@@ -24,15 +24,15 @@ const ClassRankModal = ({ visible, onClose }) => {
|
||||
rankings[0] || null, // 第1名
|
||||
rankings[2] || null, // 第3名
|
||||
];
|
||||
// 获取第4名及以后的数据
|
||||
const restRankings = rankings.slice(3);
|
||||
// 获取第4-10名的数据(只展示前10名)
|
||||
const restRankings = rankings.slice(3, 10);
|
||||
|
||||
return (
|
||||
<Modal visible={visible} onClose={onClose}>
|
||||
<div className="class-rank-modal">
|
||||
<div className="class-rank-modal-header">
|
||||
<h2 className="class-rank-modal-title">
|
||||
<span>班级排名</span>
|
||||
<span>班级排名(前10名)</span>
|
||||
</h2>
|
||||
<i className="close-icon" onClick={onClose} />
|
||||
</div>
|
||||
|
||||
@@ -1,57 +1,77 @@
|
||||
[
|
||||
{
|
||||
"查询岗位名称": "HR人事专员",
|
||||
"阶段日期": "面试未通过:2025/8/22 14:12",
|
||||
"面试状态": "面试未通过,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "商业会展执行专员",
|
||||
"阶段日期": "2025/7/30",
|
||||
"面试状态": "拒绝Offer"
|
||||
"阶段日期": "Offer已拒绝:2025/7/30 09:45",
|
||||
"面试状态": "Offer已拒绝,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "活动策划师",
|
||||
"阶段日期": "2025/7/26",
|
||||
"面试状态": "收到Offer"
|
||||
"阶段日期": "Offer已拒绝:2025/7/16 14:33",
|
||||
"面试状态": "Offer已拒绝,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "SEO专员",
|
||||
"阶段日期": "2025/7/28",
|
||||
"面试状态": "拒绝Offer"
|
||||
"阶段日期": "Offer已拒绝:2025/7/28 17:01",
|
||||
"面试状态": "Offer已拒绝,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "新媒体运营专员",
|
||||
"阶段日期": "2025/7/31",
|
||||
"面试状态": "拒绝Offer"
|
||||
"阶段日期": "Offer已拒绝:2025/7/31 14:38",
|
||||
"面试状态": "Offer已拒绝,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "ip运营",
|
||||
"阶段日期": "2025/7/10",
|
||||
"面试状态": "收到Offer"
|
||||
"阶段日期": "Offer已拒绝:2025/7/10 11:13",
|
||||
"面试状态": "Offer已拒绝,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "二次元周边店店长",
|
||||
"阶段日期": "2025/6/27",
|
||||
"面试状态": "HR初筛未通过"
|
||||
"阶段日期": "简历未通过:2025/6/27 15:45",
|
||||
"面试状态": "简历未通过,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "社群运营",
|
||||
"阶段日期": "2025/7/23",
|
||||
"面试状态": "收到Offer"
|
||||
"阶段日期": "简历未通过:2025/7/23 11:10",
|
||||
"面试状态": "简历未通过,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "品牌推广专员",
|
||||
"阶段日期": "面试未通过:2025/8/2 13:32",
|
||||
"面试状态": "面试未通过,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "会展策划师",
|
||||
"阶段日期": "回复截至2025-09-12",
|
||||
"面试状态": "等待HR通知"
|
||||
"阶段日期": "Offer已接收:2025/9/11 16:39",
|
||||
"面试状态": "Offer已接收,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "客服",
|
||||
"阶段日期": "2025/8/2",
|
||||
"面试状态": "未参与面试"
|
||||
"阶段日期": "Offer已拒绝:2025/8/2 09:31",
|
||||
"面试状态": "Offer已拒绝,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "境外展会操作助理",
|
||||
"阶段日期": "面试未通过:2025/8/9 12:01",
|
||||
"面试状态": "面试未通过,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "海外活动策划专员",
|
||||
"阶段日期": "2025/9/2",
|
||||
"面试状态": "等待回复"
|
||||
"阶段日期": "面试未通过:2025/7/17 20:18",
|
||||
"面试状态": "面试未通过,岗位内推结束"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "品牌公关",
|
||||
"阶段日期": "面试完成2025-09-02",
|
||||
"面试状态": "面试完成"
|
||||
"阶段日期": "面试日期:2025/9/7 18:35",
|
||||
"面试状态": "面试日期已确定,等待面试"
|
||||
},
|
||||
{
|
||||
"查询岗位名称": "景区运营专员",
|
||||
"阶段日期": "面试未通过:2025/8/12 14:53",
|
||||
"面试状态": "面试未通过,岗位内推结束"
|
||||
}
|
||||
]
|
||||
@@ -40,7 +40,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
.animation-container {
|
||||
.lottie-container {
|
||||
width: 100%;
|
||||
height: 136px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
transform: scale(0.9);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.interview-status-animation-wrapper.expanding .lottie-container {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
/* 保留原有的图片样式作为后备方案 */
|
||||
.image-container {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
display: flex;
|
||||
@@ -51,11 +67,14 @@
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.interview-status-animation-wrapper.expanding .animation-container {
|
||||
.interview-status-animation-wrapper.expanding .image-container {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.animation-container svg {
|
||||
.status-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@@ -2,27 +2,25 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import lottie from 'lottie-web';
|
||||
import './index.css';
|
||||
|
||||
// 状态动画映射
|
||||
const statusAnimationMap = {
|
||||
'HR初筛未通过': () => import('@/assets/animations/interviewStatus/1-off_初筛未通过.json'),
|
||||
'HR评估中': () => import('@/assets/animations/interviewStatus/1-on_hr评估中.json'),
|
||||
'面试未通过': () => import('@/assets/animations/interviewStatus/2-off_面试未通过.json'),
|
||||
'到场面试': () => import('@/assets/animations/interviewStatus/2-on_到场面试.json'),
|
||||
'收到通知': () => import('@/assets/animations/interviewStatus/2-on_收到通知.json'),
|
||||
'等待面试': () => import('@/assets/animations/interviewStatus/2-wati_等待面试.json'),
|
||||
'未参与面试': () => import('@/assets/animations/interviewStatus/3-off_未参与面试.json'),
|
||||
'等待HR通知': () => import('@/assets/animations/interviewStatus/3-wati_等待HR通知.json'),
|
||||
'拒绝Offer': () => import('@/assets/animations/interviewStatus/4-off_拒绝Offer.json'),
|
||||
'收到Offer': () => import('@/assets/animations/interviewStatus/4-on_收到Offer.json'),
|
||||
'等待回复': () => import('@/assets/animations/interviewStatus/4-wati_等待回复.json'),
|
||||
// 状态到lottie动画文件的映射
|
||||
const statusLottieMap = {
|
||||
'Offer已拒绝,岗位内推结束': '/lottie/interview-status/4-off_拒绝Offer.json',
|
||||
'Offer已接收,岗位内推结束': '/lottie/interview-status/4-on_收到Offer.json',
|
||||
'Offer已接受,岗位内推结束': '/lottie/interview-status/4-on_收到Offer.json',
|
||||
'已收到Offer,请于2天内答复': '/lottie/interview-status/4-on_收到Offer.json',
|
||||
'面试日期已确定,等待面试': '/lottie/interview-status/4-on_收到Offer.json',
|
||||
'简历未通过,岗位内推结束': '/lottie/interview-status/1-off_初筛未通过.json',
|
||||
'未参与面试,岗位内推结束': '/lottie/interview-status/3-off_未参与面试.json',
|
||||
'面试未通过,岗位内推结束': '/lottie/interview-status/2-off_面试未通过.json',
|
||||
// 兼容其他可能的状态文本
|
||||
'岗位内推结束': '/lottie/interview-status/1-off_初筛未通过.json', // 默认动画
|
||||
};
|
||||
|
||||
export default ({ statusText, isOpen }) => {
|
||||
const animationContainer = useRef(null);
|
||||
const lottieInstance = useRef(null);
|
||||
const [animationData, setAnimationData] = useState(null);
|
||||
export default ({ statusText, isOpen, stageDate }) => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [animationClass, setAnimationClass] = useState('');
|
||||
const lottieContainer = useRef(null);
|
||||
const lottieInstance = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
@@ -38,47 +36,87 @@ export default ({ statusText, isOpen }) => {
|
||||
}
|
||||
}, [isOpen, isVisible]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && statusText) {
|
||||
// 加载对应的动画数据
|
||||
const loadAnimation = statusAnimationMap[statusText];
|
||||
if (loadAnimation) {
|
||||
loadAnimation().then(module => {
|
||||
setAnimationData(module.default);
|
||||
});
|
||||
// 获取对应的lottie动画路径
|
||||
const getLottiePath = (status, stageDate) => {
|
||||
// 首先尝试精确匹配
|
||||
if (statusLottieMap[status]) {
|
||||
return statusLottieMap[status];
|
||||
}
|
||||
|
||||
// 如果精确匹配失败,尝试模糊匹配
|
||||
if (status && status.includes('简历未通过')) {
|
||||
return statusLottieMap['简历未通过,岗位内推结束'];
|
||||
}
|
||||
if (status && status.includes('未参与面试')) {
|
||||
return statusLottieMap['未参与面试,岗位内推结束'];
|
||||
}
|
||||
if (status && status.includes('面试未通过')) {
|
||||
return statusLottieMap['面试未通过,岗位内推结束'];
|
||||
}
|
||||
if (status && status.includes('Offer已拒绝')) {
|
||||
return statusLottieMap['Offer已拒绝,岗位内推结束'];
|
||||
}
|
||||
if (status && (status.includes('Offer已接受') || status.includes('Offer已接收'))) {
|
||||
return statusLottieMap['Offer已接收,岗位内推结束'];
|
||||
}
|
||||
if (status && status.includes('面试日期已确定')) {
|
||||
return statusLottieMap['面试日期已确定,等待面试'];
|
||||
}
|
||||
if (status && status.includes('已收到Offer')) {
|
||||
return statusLottieMap['已收到Offer,请于2天内答复'];
|
||||
}
|
||||
|
||||
// 对于通用的"岗位内推结束"状态,根据阶段日期判断具体原因
|
||||
if (status === '岗位内推结束' && stageDate) {
|
||||
if (stageDate.includes('简历未通过')) {
|
||||
return statusLottieMap['简历未通过,岗位内推结束'];
|
||||
}
|
||||
if (stageDate.includes('未参与面试')) {
|
||||
return statusLottieMap['未参与面试,岗位内推结束'];
|
||||
}
|
||||
if (stageDate.includes('面试未通过')) {
|
||||
return statusLottieMap['面试未通过,岗位内推结束'];
|
||||
}
|
||||
}
|
||||
}, [isOpen, statusText]);
|
||||
|
||||
// 默认返回通用动画
|
||||
return statusLottieMap['岗位内推结束'];
|
||||
};
|
||||
|
||||
// 加载lottie动画
|
||||
useEffect(() => {
|
||||
if (animationData && animationContainer.current && isVisible) {
|
||||
// 清除之前的动画实例
|
||||
if (isVisible && lottieContainer.current) {
|
||||
// 清理之前的动画实例
|
||||
if (lottieInstance.current) {
|
||||
lottieInstance.current.destroy();
|
||||
}
|
||||
|
||||
// 创建新的动画实例
|
||||
const lottiePath = getLottiePath(statusText, stageDate);
|
||||
|
||||
// 加载新的lottie动画
|
||||
lottieInstance.current = lottie.loadAnimation({
|
||||
container: animationContainer.current,
|
||||
container: lottieContainer.current,
|
||||
renderer: 'svg',
|
||||
loop: true,
|
||||
autoplay: true,
|
||||
animationData: animationData
|
||||
path: lottiePath
|
||||
});
|
||||
|
||||
return () => {
|
||||
if (lottieInstance.current) {
|
||||
lottieInstance.current.destroy();
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [animationData, isVisible]);
|
||||
|
||||
// 清理函数
|
||||
return () => {
|
||||
if (lottieInstance.current) {
|
||||
lottieInstance.current.destroy();
|
||||
lottieInstance.current = null;
|
||||
}
|
||||
};
|
||||
}, [isVisible, statusText, stageDate]);
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<div className={`interview-status-animation-wrapper ${animationClass}`}>
|
||||
<div className="animation-container" ref={animationContainer} />
|
||||
<div className="lottie-container" ref={lottieContainer} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
1613
网页未导入数据/岗位面试状态(全产业).json
Normal file
1613
网页未导入数据/岗位面试状态(全产业).json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user