Initial commit: 教务系统在线平台

- 包含4个产业方向的前端项目:智能开发、智能制造、大健康、财经商贸
- 已清理node_modules、.yoyo等大文件,项目大小从2.6GB优化至631MB
- 配置完善的.gitignore文件

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
KQL
2025-12-12 18:16:55 +08:00
commit a7242f0c69
2932 changed files with 2303533 additions and 0 deletions

View File

@@ -0,0 +1,273 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import Modal from "@/components/Modal";
import PDFICON from "@/assets/images/Common/pdf_icon.png";
import FileIcon from "@/components/FileIcon";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import ImagePreviewModal from "../ImagePreviewModal";
import { getCompoundUnits, getVerticalUnits } from "@/data/projectUnitsMapping";
import "./index.css";
export default ({ visible, onClose, data }) => {
const navigate = useNavigate();
const [previewVisible, setPreviewVisible] = useState(false);
const [previewIndex, setPreviewIndex] = useState(0);
const handleCloseModal = () => {
onClose();
};
// 处理岗位点击,跳转到简历与面试题页面
const handlePositionClick = (positionName) => {
// 关闭当前模态框
onClose();
// 跳转到简历与面试题页面,并传递岗位名称参数
navigate('/resume-interview', { state: { selectedPosition: positionName } });
};
// 处理图片点击预览
const handleImageClick = (index) => {
setPreviewIndex(index);
setPreviewVisible(true);
};
// 处理单元点击跳转到课程直播间
const handleUnitClick = (unitName, isCompound) => {
console.log('Unit clicked:', unitName, 'isCompound:', isCompound);
// 关闭当前模态框
onClose();
// 构建URL参数
const params = new URLSearchParams();
params.append('courseTitle', unitName);
// 根据单元类型设置课程类型
if (isCompound) {
params.append('courseType', 'compound-skill');
} else {
params.append('courseType', 'vertical-skill');
}
console.log('Navigate to live with params:', params.toString());
// 跳转到课程直播间
navigate(`/live?${params.toString()}`);
};
// 将换行符转换为Markdown格式
const formatMarkdownContent = (content) => {
if (!content) return "";
// 将 \\n 替换为实际的换行符
return content.replace(/\\n/g, '\n');
};
return (
<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?.name || data?.title}</p>
<ul className="project-cases-modal-list">
{/* 项目概述 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">项目概述</p>
<p className="project-cases-modal-item-text">
{data?.description || data?.overview || "暂无项目概述"}
</p>
</li>
{/* 如果有sections数据结构优先使用sections */}
{data?.sections ? (
<>
{data.sections.map((section, index) => (
<li key={index} className="project-cases-modal-item">
<p className="project-cases-modal-item-title">{section.title}</p>
<div className="project-cases-modal-markdown-content">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{formatMarkdownContent(section.content)}</ReactMarkdown>
</div>
</li>
))}
{/* 项目图片展示 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">项目效果图</p>
{data?.images && data.images.length > 0 ? (
<div className="project-cases-modal-images">
{data.images.map((image, index) => {
const imageUrl = typeof image === 'string' ? image : image.url;
const imageTitle = typeof image === 'string' ? `${index + 1}` : image.title;
return (
<div key={index} className="project-cases-modal-image-wrapper">
<img
src={imageUrl}
alt={imageTitle}
className="project-cases-modal-image"
onClick={() => handleImageClick(index)}
onError={(e) => {
e.target.style.display = 'none';
e.target.nextSibling.style.display = 'none';
if (e.target.parentElement) {
const placeholder = document.createElement('div');
placeholder.style.width = '100%';
placeholder.style.height = '200px';
placeholder.style.display = 'flex';
placeholder.style.alignItems = 'center';
placeholder.style.justifyContent = 'center';
placeholder.style.backgroundColor = '#f5f5f5';
placeholder.style.borderRadius = '8px';
placeholder.style.color = '#999';
placeholder.style.fontSize = '14px';
placeholder.textContent = '暂无项目效果图';
e.target.parentElement.appendChild(placeholder);
}
}}
/>
<span className="project-cases-modal-image-title">
{imageTitle}
</span>
</div>
);
})}
</div>
) : (
<p className="project-cases-modal-item-text">暂无项目效果图</p>
)}
</li>
</>
) : (
<>
{/* 原有的数据结构保持不变 */}
{/* 适用岗位 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">适用岗位</p>
<ul className="project-cases-modal-horizontal-list">
{data?.applicablePositions?.map((pos, index) => (
<li
key={index}
className="high-count-list-item"
onClick={() => handlePositionClick(pos.position)}
style={{ cursor: 'pointer' }}
>
<span className={pos.level === '普通岗' ? 'low' : pos.level === '技术骨干岗' ? 'medium' : 'high'}>
{pos.level}
</span>
<p>{pos.position}</p>
</li>
)) || (
<li className="high-count-list-item">
<span className="medium">暂无</span>
<p>适用岗位信息</p>
</li>
)}
</ul>
</li>
{/* 对应单元 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">对应单元</p>
{/* 复合能力课 */}
<div className="unit-category-section">
<p className="unit-category-subtitle">必修课</p>
<ul className="project-cases-modal-horizontal-list">
{getCompoundUnits(data?.title).map((unit, index) => (
<li
key={`compound-${index}`}
className="class-list-item clickable-unit"
onClick={() => handleUnitClick(unit, true)}
style={{ cursor: 'pointer' }}
>
<div className="class-list-item-title">
<i />
<span>{unit}</span>
</div>
</li>
))}
{getCompoundUnits(data?.title).length === 0 && (
<li className="class-list-item">
<div className="class-list-item-title">
<i />
<span>暂无复合能力课信息</span>
</div>
</li>
)}
</ul>
</div>
{/* 垂直能力课 */}
<div className="unit-category-section">
<p className="unit-category-subtitle">选修课</p>
<ul className="project-cases-modal-horizontal-list">
{getVerticalUnits(data?.title).map((unit, index) => (
<li
key={`vertical-${index}`}
className="class-list-item clickable-unit"
onClick={() => handleUnitClick(unit, false)}
style={{ cursor: 'pointer' }}
>
<div className="class-list-item-title">
<i />
<span>{unit}</span>
</div>
</li>
))}
{getVerticalUnits(data?.title).length === 0 && (
<li className="class-list-item">
<div className="class-list-item-title">
<i />
<span>暂无垂直能力课信息</span>
</div>
</li>
)}
</ul>
</div>
</li>
{/* 项目整体流程介绍 - Markdown格式 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">项目整体流程介绍</p>
<div className="project-cases-modal-markdown-content">
{data?.process ? (
<ReactMarkdown remarkPlugins={[remarkGfm]}>{formatMarkdownContent(data.process)}</ReactMarkdown>
) : (
<p className="project-cases-modal-item-text">暂无项目流程介绍</p>
)}
</div>
</li>
{/* 项目案例关键技术点 - Markdown格式 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">项目案例关键技术点</p>
<div className="project-cases-modal-markdown-content">
{data?.keyPoints ? (
<ReactMarkdown remarkPlugins={[remarkGfm]}>{formatMarkdownContent(data.keyPoints)}</ReactMarkdown>
) : (
<p className="project-cases-modal-item-text">暂无关键技术点</p>
)}
</div>
</li>
{/* 附件板块 */}
<li className="project-cases-modal-item">
<p className="project-cases-modal-item-title">附件</p>
<p className="project-cases-modal-item-text">暂无附件</p>
</li>
</>
)}
</ul>
</div>
{/* 图片预览Modal */}
{data?.images && (
<ImagePreviewModal
visible={previewVisible}
onClose={() => setPreviewVisible(false)}
images={data.images}
initialIndex={previewIndex}
/>
)}
</Modal>
);
};

View File

@@ -0,0 +1,241 @@
import json
# 读取大健康项目案例数据
with open('网页未导入数据/大健康产业/大健康项目案例.json', 'r', encoding='utf-8') as f:
health_data = json.load(f)
# 为getMockProjectsList创建项目列表数据 - 使用正确的字段名
projects_list = []
# 为getMockProjectDetail创建详情数据
projects_detail = []
# 为projectUnitsMapping创建单元映射
units_mapping = {}
for idx, item in enumerate(health_data, 1):
# 提取岗位列表(字符串数组)
positions = []
if item.get("适用岗位"):
positions = [pos.strip() for pos in item["适用岗位"].split(",")]
# 获取方向(类别)
direction = item.get("所属垂直方向", "健康管理")
# 获取单元(取第一个复合能力课或垂直能力课)
unit = ""
if item.get("对应单元名称(复合能力课)"):
units = item["对应单元名称(复合能力课)"].split(",")
if units:
unit = units[0].strip()
elif item.get("对应单元名称(垂直能力课)"):
units = item["对应单元名称(垂直能力课)"].split(",")
if units:
unit = units[0].strip()
# 创建列表项 - 使用正确的字段名
list_item = {
"id": idx,
"name": item["案例名称"], # 使用name而不是title
"description": direction, # 简短描述用方向名
"positions": positions, # 字符串数组,不是对象数组
"unit": unit,
"direction": direction,
"category": direction # 使用方向作为分类
}
projects_list.append(list_item)
# 创建详情项 - 保持原有结构
# 先加载岗位等级映射
position_level_map = {}
with open('网页未导入数据/大健康产业/大健康岗位简历.json', 'r', encoding='utf-8') as level_f:
resume_data = json.load(level_f)
for resume_item in resume_data:
position_name = resume_item.get('岗位名称', '')
level_label = resume_item.get('岗位等级标签', '')
if position_name and level_label:
position_level_map[position_name] = level_label
# 提取岗位详情(包含正确级别)
positions_detail = []
for pos in positions:
# 从映射中获取正确的级别
level = position_level_map.get(pos, "技术骨干岗") # 默认为技术骨干岗
# 将"基础岗"映射为"普通岗"以保持原有样式
if level == "基础岗":
level = "普通岗"
positions_detail.append({
"level": level,
"position": pos
})
# 从项目内容中提取各个部分
content = item.get("项目案例内容", "")
# 提取项目概述
overview = ""
if "# 一、项目概述" in content:
overview_start = content.index("# 一、项目概述") + len("# 一、项目概述")
overview_end = content.find("# 二、", overview_start) if "# 二、" in content[overview_start:] else len(content)
overview = content[overview_start:overview_end].strip()
# 提取项目流程
process = ""
if "# 二、项目整体流程介绍" in content:
process_start = content.index("# 二、项目整体流程介绍") + len("# 二、项目整体流程介绍")
process_end = content.find("# 三、", process_start) if "# 三、" in content[process_start:] else len(content)
process = content[process_start:process_end].strip()
# 提取关键技术点
keyPoints = ""
if "# 三、项目" in content:
tech_start = content.index("# 三、项目")
keyPoints = content[tech_start:].strip()
detail_item = {
"id": idx,
"name": item["案例名称"],
"positions": positions_detail,
"unit": unit,
"category": direction,
"applicablePositions": positions_detail,
"description": overview[:500] + "..." if len(overview) > 500 else overview,
"process": process,
"keyPoints": keyPoints,
"images": []
}
projects_detail.append(detail_item)
# 创建单元映射
compound_units = [u.strip() for u in item.get("对应单元名称(复合能力课)", "").split(",") if u.strip()]
vertical_units = [u.strip() for u in item.get("对应单元名称(垂直能力课)", "").split(",") if u.strip()]
units_mapping[item["案例名称"]] = {
"compoundUnits": compound_units,
"verticalUnits": vertical_units
}
# 生成projectLibraryMock.js - 保持原有结构
mock_js_content = f"""// 项目列表Mock数据
export const getMockProjectsList = (params = {{}}) => {{
const {{ search = "", page = 1, pageSize = 10 }} = params;
// 完整项目列表数据 - 大健康产业
const projects = {json.dumps(projects_list, ensure_ascii=False, indent=4)};
// 搜索过滤
let filteredProjects = projects;
if (search) {{
filteredProjects = projects.filter(project =>
project.name.includes(search) ||
project.description.includes(search) ||
project.positions.some(pos => pos.includes(search)) ||
project.category.includes(search)
);
}}
// 分页
const start = (page - 1) * pageSize;
const end = start + pageSize;
const paginatedProjects = filteredProjects.slice(start, end);
return {{
success: true,
data: paginatedProjects,
total: filteredProjects.length,
page,
pageSize
}};
}};
// 项目详情Mock数据 - 大健康产业
export const getMockProjectDetail = (id) => {{
// 直接根据ID返回对应项目的详情
const projects = {json.dumps(projects_detail, ensure_ascii=False, indent=4)};
const project = projects.find(p => p.id === parseInt(id));
if (project) {{
return {{
success: true,
data: project
}};
}}
return {{
success: false,
message: '项目不存在'
}};
}};
export default {{
getMockProjectsList,
getMockProjectDetail
}};
"""
# 生成projectUnitsMapping.js
mapping_js_content = f"""// 项目案例对应单元映射数据 - 大健康产业
export const projectUnitsMapping = {json.dumps(units_mapping, ensure_ascii=False, indent=2)};
// 获取项目的复合能力课程
export const getCompoundUnits = (projectTitle) => {{
if (!projectTitle) return [];
// 直接匹配
if (projectUnitsMapping[projectTitle]) {{
return projectUnitsMapping[projectTitle].compoundUnits || [];
}}
// 尝试去除后缀后匹配(如"详情"
const cleanTitle = projectTitle.replace(/详情$/, '');
if (projectUnitsMapping[cleanTitle]) {{
return projectUnitsMapping[cleanTitle].compoundUnits || [];
}}
return [];
}};
// 获取项目的垂直能力课程
export const getVerticalUnits = (projectTitle) => {{
if (!projectTitle) return [];
// 直接匹配
if (projectUnitsMapping[projectTitle]) {{
return projectUnitsMapping[projectTitle].verticalUnits || [];
}}
// 尝试去除后缀后匹配(如"详情"
const cleanTitle = projectTitle.replace(/详情$/, '');
if (projectUnitsMapping[cleanTitle]) {{
return projectUnitsMapping[cleanTitle].verticalUnits || [];
}}
return [];
}};
// 获取项目的所有对应单元
export const getProjectUnits = (projectTitle) => {{
const mapping = projectUnitsMapping[projectTitle];
if (!mapping) return [];
return [...mapping.compoundUnits, ...mapping.verticalUnits];
}};
"""
# 写入文件
with open('src/mocks/projectLibraryMock.js', 'w', encoding='utf-8') as f:
f.write(mock_js_content)
with open('src/data/projectUnitsMapping.js', 'w', encoding='utf-8') as f:
f.write(mapping_js_content)
print(f"成功转换 {len(health_data)} 个大健康项目案例")
print("数据结构:")
print(f"- id: 数字ID")
print(f"- name: 项目名称")
print(f"- description: 简短描述(方向)")
print(f"- positions: 岗位字符串数组")
print(f"- unit: 对应单元")
print(f"- direction: 所属方向")
print(f"- category: 分类")

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,282 @@
// 项目案例对应单元映射数据 - 大健康产业
export const projectUnitsMapping = {
"老年健康管理与营养照护综合服务优化项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务"
],
"verticalUnits": [
"健康检查与智慧养老服务",
"慢性病管理",
"健康管理基础",
"健康政策与法规解读"
]
},
"东阿阿胶品牌运营与网络营销项目": {
"compoundUnits": [
"AI人工智能在大健康产业的应用"
],
"verticalUnits": [
"健康运动与社群运营",
"新媒体运营基础"
]
},
"采耳社群运营与品牌推广项目": {
"compoundUnits": [
"AI人工智能在大健康产业的应用"
],
"verticalUnits": [
"健康运动与社群运营",
"新媒体运营基础"
]
},
"药品供应链优化与精细化管理项目": {
"compoundUnits": [
"药品生产/经营的质量管理体系解读"
],
"verticalUnits": [
"GMP与药品生产规范"
]
},
"阿司匹林片生产工艺优化与质量控制体系建设项目": {
"compoundUnits": [
"基础制药工艺",
"药品生产/经营的质量管理体系解读"
],
"verticalUnits": [
"智能制药设备应用",
"药品生产工艺设计",
"药品生产工艺",
"药品生产实战",
"典型制药设备及智能化控制"
]
},
"中年高管心血管风险健康咨询干预项目": {
"compoundUnits": [
"健康管理基础",
"AI人工智能在大健康产业的应用"
],
"verticalUnits": [
"慢性病管理",
"健康管理基础",
"健康政策与法规解读",
"健康数据分析基础"
]
},
"学校健康体检服务质量管理与影像诊断优化项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务",
"医疗认知"
],
"verticalUnits": [
"慢性病管理",
"健康管理基础",
"健康政策与法规解读",
"健康数据分析基础"
]
},
"创新型残疾儿童功能恢复与康复服务项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务"
],
"verticalUnits": [
"康复治疗",
"健康咨询及客户转化",
"健康管理基础"
]
},
"某产妇产后康复全流程项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务"
],
"verticalUnits": [
"康复治疗",
"健康咨询及客户转化",
"健康管理基础"
]
},
"腓肠肌(小腿肚)Ⅱ级拉伤运动康复项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务"
],
"verticalUnits": [
"康复治疗",
"健康咨询及客户转化",
"健康管理基础"
]
},
"卒中后言语失用与非流利性失语康复治疗项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务"
],
"verticalUnits": [
"康复治疗",
"健康咨询及客户转化",
"健康管理基础"
]
},
"社区慢性病患者管理与健康促进项目": {
"compoundUnits": [
"健康管理基础",
"常见护理实务"
],
"verticalUnits": [
"慢性病管理",
"健康管理基础",
"健康政策与法规解读"
]
},
"定制化职场女性轻医美美肤方案": {
"compoundUnits": [
"健康管理基础",
"AI人工智能在大健康产业的应用",
"医疗认知"
],
"verticalUnits": [
"慢性病管理",
"健康管理基础",
"健康政策与法规解读"
]
},
"轻医美面部年轻化与精致化调整项目": {
"compoundUnits": [
"健康管理基础",
"AI人工智能在大健康产业的应用",
"医疗认知"
],
"verticalUnits": [
"慢性病管理",
"健康管理基础",
"健康政策与法规解读"
]
},
"初三学生中考前焦虑心理辅导项目": {
"compoundUnits": [
"健康管理基础",
"AI人工智能在大健康产业的应用",
"医疗认知"
],
"verticalUnits": [
"慢性病管理",
"健康管理基础",
"健康政策与法规解读"
]
},
"阿莫西林胶囊制剂生产工艺优化项目": {
"compoundUnits": [
"基础制药工艺",
"药品生产/经营的质量管理体系解读",
"基础药品认知",
"药品生产法规"
],
"verticalUnits": [
"药品生产工艺设计",
"药品生产工艺"
]
},
"维生素C原料药生产质量控制项目": {
"compoundUnits": [
"药品生产/经营的质量管理体系解读",
"药品生产法规"
],
"verticalUnits": [
"药品质量管理体系",
"药品质量管理",
"GMP与药品生产规范"
]
},
"甲硝唑质量检测项目": {
"compoundUnits": [
"药品生产/经营的质量管理体系解读",
"检验检测原理与设备操作"
],
"verticalUnits": [
"药品质量管理体系",
"药品质量管理",
"GMP与药品生产规范"
]
},
"某品牌5%葡萄糖注射液抽检工作方案": {
"compoundUnits": [
"药品生产/经营的质量管理体系解读",
"检验检测原理与设备操作"
],
"verticalUnits": [
"药品质量管理体系",
"药品质量管理",
"GMP与药品生产规范"
]
},
"新型抗肝癌药物药效验证项目": {
"compoundUnits": [
"药品生产/经营的质量管理体系解读",
"检验检测原理与设备操作"
],
"verticalUnits": [
"药品质量管理体系",
"药品质量管理",
"GMP与药品生产规范"
]
},
"老年人免疫力与心血管保健品临床试验项目": {
"compoundUnits": [
"药品生产/经营的质量管理体系解读",
"检验检测原理与设备操作"
],
"verticalUnits": [
"药物分析",
"药品分析技术",
"药品质量管理"
]
}
};
// 获取项目的复合能力课程
export const getCompoundUnits = (projectTitle) => {
if (!projectTitle) return [];
// 直接匹配
if (projectUnitsMapping[projectTitle]) {
return projectUnitsMapping[projectTitle].compoundUnits || [];
}
// 尝试去除后缀后匹配(如"详情"
const cleanTitle = projectTitle.replace(/详情$/, '');
if (projectUnitsMapping[cleanTitle]) {
return projectUnitsMapping[cleanTitle].compoundUnits || [];
}
return [];
};
// 获取项目的垂直能力课程
export const getVerticalUnits = (projectTitle) => {
if (!projectTitle) return [];
// 直接匹配
if (projectUnitsMapping[projectTitle]) {
return projectUnitsMapping[projectTitle].verticalUnits || [];
}
// 尝试去除后缀后匹配(如"详情"
const cleanTitle = projectTitle.replace(/详情$/, '');
if (projectUnitsMapping[cleanTitle]) {
return projectUnitsMapping[cleanTitle].verticalUnits || [];
}
return [];
};
// 获取项目的所有对应单元
export const getProjectUnits = (projectTitle) => {
const mapping = projectUnitsMapping[projectTitle];
if (!mapping) return [];
return [...mapping.compoundUnits, ...mapping.verticalUnits];
};