综合设计——多源异构数据采集与融合应用综合实践
职途启航
数据采集项目实践 | https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology |
---|---|
组名、项目简介 | 组名:数据矿工,项目需求:爬取招聘网站的求助信息、编辑信息匹配系统等,项目目标:根据求职者的个人信息为其推荐最合适的工作、根据全国各省的各行业信息为求职者提供合适的参考城市、项目开展技术路线:数据库操作:使用 pymysql 库与 MySQL 数据库进行交互,执行 SQL 查询和获取数据、Flask Web 框架:使用了 Flask 作为 Web 应用框架,用于创建 Web 服务和 API 端点 、WSGI 服务器 :pywsgi 作为 WSGI 服务器来运行 Flask 应用 |
团队成员学号 | 102202132、102202131、102202143、102202111、102202122、102202136 |
这个项目的目标 | 根据求职者的个人信息为其推荐最合适的工作 |
其他参考文献 | Flask Web框架官方文档 https://flask.palletsprojects.com/en/latest/ PyMySQL官方文档 https://github.com/PyMySQL/PyMySQL 讯飞星火大模型API文档 https://www.xfyun.cn/doc/spark/Web.html 数据库设计和优化 https://db-book.com/ 云服务器和数据库部署 https://cloud.tencent.com/ |
gitee地址:https://gitee.com/zheng-bingzhi/2022-level-data-collection/tree/master/职业规划与就业分析平台
1.项目概述
互联网的发展成就了众多招聘APP,这些APP为求职者提供了更多的就业选择,但随着行业的细分化,许多求职者甚至不清楚以自己的技能和工作经历适合什么工作岗位。俗话说良禽择木而栖,不同的城市主要的发展行业不同,这也就导致相同行业在不同城市的薪资待遇和发展前景截然不同,因此选择一个好城市也十分重要。本项目便是为求职者匹配合适的招聘信息和为求职者提供各省份间的各行业发展,为求职者提供参考。
2.成员分工
成员编号 | 角色 | 职责 |
---|---|---|
成员1 | 项目经理 & 前端开发 | - 项目整体规划与进度管理 - 团队协调与沟通保障 - 前端界面设计与开发 - 前后端数据交互协作 |
成员2 | 后端开发 & 数据采集分析师 | - 后端逻辑与API开发 - 数据库管理 - 参与数据采集,确保数据准确及时 - 与前端团队协作,保障数据正确展示 |
成员3 | 后端开发 | - 专注于后端服务开发 - 服务器端逻辑与数据库交互 - 与数据采集团队合作,优化数据处理 |
成员4 | 前端开发 & 数据采集分析师 | - 前端界面开发,保障美观与易用性 - 参与数据采集,确保数据展示准确 |
成员5 | 数据采集分析师 | - 从招聘网站爬取岗位、薪资、行业趋势等数据 - 数据清洗与分析 - 为智能推荐服务提供数据支持 |
成员6 | 数据采集分析师 | - 与成员5协作,负责数据采集与分析 - 确保数据质量与分析准确性 |
3.个人分工
负责项目整体规划和进度管理。
协调团队成员,确保沟通顺畅。
前端界面设计和开发,确保用户界面友好、响应迅速。
与后端开发团队协作,完成前后端数据交互。
3.1核心代码
3.1.1.FujianRecruitmentView.vue:
async fetchRecruitments() {
const savedRecruitments = localStorage.getItem('recruitments');
if (savedRecruitments) {
this.originalRecruitments = JSON.parse(savedRecruitments);
this.allRecruitments = this.setDefaultOccupationType([...this.originalRecruitments]);
this.allRecruitments.forEach(recruitment => {
recruitment.Location = recruitment.Location.trim();
recruitment.Occupation_Type = recruitment.Occupation_Type ? recruitment.Occupation_Type.trim() : '未知';
});
this.resetRecruitments();
} else {
try {
const response = await axios.get('http://81.70.22.101:5000/province-recruitment');
if (response.data.code === 200) {
this.originalRecruitments = response.data.data;
this.allRecruitments = this.setDefaultOccupationType([...this.originalRecruitments]);
this.allRecruitments.forEach(recruitment => {
recruitment.Location = recruitment.Location.trim();
recruitment.Occupation_Type = recruitment.Occupation_Type ? recruitment.Occupation_Type.trim() : '未知';
});
this.resetRecruitments();
} else {
console.error(response.data.message);
this.allRecruitments = [];
this.visibleRecruitments = [];
}
} catch (error) {
console.error('Error fetching recruitments:', error);
this.allRecruitments = [];
this.visibleRecruitments = [];
}
}
},
3.1.2.IntelligentRecommendationInputView.vue:
this.isLoading = true; // 开始加载
try {
// 发送获取匹配职位的 API 请求
const response1 = await axios.post('http://81.70.22.101:5000/api/recommend_career_advice', {
desired_position: this.formData.jobs.join(', '), // 转化成逗号分隔字符串
expected_salary: this.formData.salary,
resume: this.formData.bio,
requirements: this.formData.requirements,
work_experience: this.formData.experience
});
// 发送获取职业规划建议的 API 请求
const response2 = await axios.post('http://127.0.0.1:5000/recommend-career-advice', {
desired_position: this.formData.jobs.join(', '),
expected_salary: this.formData.salary,
resume: this.formData.bio,
requirements: this.formData.requirements,
work_experience: this.formData.experience
});
// 检查两个接口的响应状态
console.log('Response1:', response1);
console.log('Response2:', response2);
if (response1.data.code === 200 && response2.data.code === 200) {
// 将匹配职位和职业规划建议保存到 Vuex 中
this.$store.dispatch('saveRecommendedJobs', response1.data.data); // 保存职位数据
this.$store.dispatch('saveCareerAdvice', response2.data.data); // 保存职业规划数据
// 跳转到结果页面
console.log('Navigating to result page');
this.$router.push('/intelligent-recommendation-result');
} else {
this.errorMessage = response1.data.message || response2.data.message || '获取匹配职位失败';
}
3.1.3.IntelligentRecommendationResultView.vue:
<script>
import Header from "../components/Header.vue";
export default {
name: "IntelligentRecommendationResultView",
components: {
Header,
},
data() {
return {
// 从 Vuex 获取推荐职业数据
recommendedJobs: this.$store.state.recommendedJobs,
tabs: ["岗位现状", "职位面试", "就职方向", "人际沟通"],
activeTab: "岗位现状", // 默认选中的标签
currentContent: "", // 当前显示的文本内容
};
},
mounted() {
this.fetchTabContent();
},
methods: {
goToRecruitmentDetail(id) {
this.$router.push(`/recruitment-detail/${id}`);
},
changeTab(tab) {
this.activeTab = tab;
this.fetchTabContent();
},
fetchTabContent() {
// 获取职业规划建议内容
const careerAdvice = this.$store.state.careerAdvice;
switch (this.activeTab) {
case "岗位现状":
this.currentContent = careerAdvice.Current_Situation || "暂无内容";
break;
case "职位面试":
this.currentContent = careerAdvice.Interview_Advice || "暂无内容";
break;
case "就职方向":
this.currentContent = careerAdvice.Career_Direction || "暂无内容";
break;
case "人际沟通":
this.currentContent = careerAdvice.Communication_Skills || "暂无内容";
break;
default:
this.currentContent = "暂无内容";
}
},
},
};
</script>
3.1.4.NationalEmploymentView.vue:
// 监听地图点击事件
myChart.on('click', (params) => {
this.selectedProvince = params.name; // 获取点击的省份名称
this.navigateToProvincePage(this.selectedProvince, module);
});
},
// 导航到对应的省份页面并在新窗口中打开
navigateToProvincePage(provinceName, module) {
let url;
if (module === 'industryAverageSalary') {
url = `http://81.70.22.101:5000/${provinceName}`; // 行业平均工资页面
} else if (module === 'industryPopulationChange') {
url = `http://81.70.22.101:5000/api/${provinceName}`; // 行业人数变化页面
}
// 在新窗口中打开 URL
window.open(url, '_blank');
},
},
3.1.5.IntelligentRecommendationResultView.vue:
methods: {
async fetchJobDetail() {
try {
const recruitmentId = this.$route.params.id; // 使用 'id' 而不是 'recruitment_id'
const response = await axios.get('http://81.70.22.101:5000/recruitment-detail', {
params: {
id: recruitmentId // 传递正确的参数名
}
});
if (response.data.code === 200) {
this.jobDetail = response.data.data; // 赋值给 jobDetail
} else {
console.error('Error fetching job details:', response.data.message);
}
} catch (error) {
console.error('API request failed:', error);
}
},
goBack() {
this.$router.go(-1); // 返回上一页
},
prevImage() {
if (this.jobDetail.Company_Photo && this.jobDetail.Company_Photo.length > 0) {
this.currentImageIndex = (this.currentImageIndex - 1 + this.jobDetail.Company_Photo.length) % this.jobDetail.Company_Photo.length;
}
},
nextImage() {
if (this.jobDetail.Company_Photo && this.jobDetail.Company_Photo.length > 0) {
this.currentImageIndex = (this.currentImageIndex + 1) % this.jobDetail.Company_Photo.length;
}
}
4.收获
-
Vue3的深刻理解
通过项目实践,我对Vue3的响应式系统、组件化架构以及Composition API有了深刻的理解。这些知识让我能够构建高效、可维护的前端应用。 -
可视化应用的掌握
我学会了如何利用Vue3结合数据可视化库,如ECharts,来创建直观的图表和数据展示,这极大地增强了应用的交互性和信息传达效果。 -
前后端交互的实战经验
在项目中,我负责了前后端交互的实现,包括API的调用与测试。我使用了Axios进行HTTP请求,确保了数据的正确传输和处理。 -
API调用与测试
我亲自测试了API接口,确保了数据的正确传输和处理。通过编写单元测试和使用Postman等工具,我提高了API的稳定性和可靠性。 -
问题解决策略
面对技术难题,我学会了如何分析问题并找到解决方案。例如,在处理Vue3中的跨域问题时,我通过配置代理服务器和CORS策略,成功地解决了问题。 -
技术深化
通过这个项目,我对前端技术栈有了更深入的理解,包括HTML、CSS、JavaScript以及Vue3特有的功能,如Fragments、Teleport和Suspense。 -
时间管理与团队领导
在紧迫的项目期限内,我学会了如何合理分配时间和资源,确保项目按时完成。同时,我提升了自己的领导能力,包括激励团队成员、引导项目方向和维护团队士气。