【源码阅读/Vue Flask前后端】简历数据查询功能
目录
- 一、Flask后端部分
- model
- Service
- route
- 二、Vue前端部分
- index.js
- main.vue
- 功能界面
- template
- script
- style
一般就是三个层面,model层面用来建立数据库的字段,service用来对model进行操作,写一些数据库操作的代码,route就是具体的功能了,其中会包含一些数据库service层的函数
一、Flask后端部分
model
# 创建基础模型类
Base = declarative_base()# 创建数据库连接
engine = create_engine('sqlite:data/hyq/code/llf/yuanshenqidong/backend/app/models/test.db')
Session = sessionmaker(bind=engine)
class ExternalResume(Base):__tablename__ = 'external_resume'uuid = Column(String(255), primary_key=True, unique=True)person_id = Column(Integer, ForeignKey('person.person_id'))name = Column(String(255), nullable=False)gender = Column(String(255))age = Column(Integer)brith_date = Column(DateTime)email = Column(String(255))phone = Column(String(255))educational_background = Column(String(255))work_experience = Column(String(255))project_experience = Column(String(255))skill = Column(String(255))research_achievement = Column(String(255))award = Column(String(255))person = relationship("Person", back_populates="external_resume")
tablename = ‘external_resume’ 指定了数据库中对应的表名
类继承自 Base,这是 SQLAlchemy 的声明性基类
person = relationship(“Person”, back_populates=“external_resume”):定义了与 Person 模型的双向关系
declarative_base() 是 SQLAlchemy 提供的一个工厂函数,用于创建所有模型类的基类
继承自这个 Base 的类会被 SQLAlchemy 自动识别为数据库模型
create_engine() 创建了一个数据库引擎实例
注意 SQLite 的连接字符串是三个斜杠 (sqlite:///) 后接文件路径
sessionmaker 创建了一个会话工厂类
bind=engine 将这个会话工厂绑定到之前创建的数据库引擎
之后可以通过 Session() 来创建实际的数据库会话实例,用于执行数据库操作

将不同的模型分类到 model.py 和 newmodel.py 中,便于管理。通过 init.py 统一导出,使外部代码可以方便地导入所有模型。
潜在问题
User 类重复
model.py 和 newmodel.py 都定义了 User 类,可能会导致冲突。
如果两个 User 是不同的模型,应该重命名其中一个(如 NewUser)。
如果相同,应该统一放在一个文件中。
Session 可能混淆
Session 是 SQLAlchemy 的会话类,但通常建议命名为 DBSession 或类似名称,避免与标准库的 session 混淆。
Base 的导出
Base 是 SQLAlchemy 的基类,通常不需要在 all 中导出,除非外部代码需要直接访问它(如创建表)。
Service
def get_all_resume_data():"""查询数据库中所有简历数据返回:List[Dict]: 包含所有简历数据的列表,每个简历是一个字典"""try:with Session() as session:resumes = session.query(ExternalResume).all()results=[]for resume in resumes:resume_dict = {'name': resume.name,'gender': resume.gender,'age': resume.age,'birth_date': resume.brith_date.strftime('%Y-%m-%d') if resume.brith_date else None,'email': resume.email,'phone': resume.phone,'educational_background': resume.educational_background,'work_experience': resume.work_experience,'project_experience': resume.project_experience,'skill': resume.skill,'research_achievement': resume.research_achievement,'award': resume.award}results.append(resume_dict)print(resume_dict)print(f"成功查询到 {len(results)} 条简历记录")return resultsexcept Exception as e:print(f"查询数据库时发生错误: {str(e)}")return []
with Session():
使用上下文管理器创建数据库会话,确保会话在使用后自动关闭。(这个写法很像打开文件)
session.query(ExternalResume).all():
查询 ExternalResume 表的所有记录,返回一个包含所有简历对象的列表。对象列表,遍历每一个对象,并获取数据库对象的属性
在返回的时候,也构造类似的数据,列表中是字典,每个字典对应着数据库中的一行,键是每一行的属性。字典列表。
route
# 查询知识库
@resume_bp.route('/resume-files', methods=['GET'])
def get_resume_files():try:result = get_all_resume_data()if result is None:return jsonify({'error': '获取简历文件失败'}), 500return jsonify(result), 200except Exception as e:print(f"获取简历文件时出错: {str(e)}")return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500
字典列表是可以直接用jsonify加工成json数据的,然后回传给前端
jsonify 是 Flask 框架中一个非常实用的函数,用于将 Python 数据结构转换为 JSON 格式的 HTTP 响应。
二、Vue前端部分
前端部分主要为三部分,一个是路由.js文件,一个main.vue主界面,还有一个我们的功能界面
index.js
import RecruitmentView from '@/views/RecruitmentView.vue'
import AbilityView from '@/views/AbilityView.vue'
用于导入页面文件

const routes = [{ path: '/main', component: Main },{ path: '/', component: Login },{ path: '/register', component: Register },{ path: '/modify', component: Modify },{path: '/recruitment',name: 'recruitment',component: RecruitmentView},{path: '/ability',name: 'ability',component: AbilityView},
];
routes 是一个数组,定义了应用程序的所有路由规则。
每个路由规则是一个对象,包含:
path: URL 路径(就是浏览器访问的地址)
component: 对应的 Vue 组件(页面)
const router = createRouter({history: createWebHistory(),routes
});export default router;
使用 createRouter 创建路由实例。
history: 使用 createWebHistory() 创建基于 HTML5 History API 的路由模式(干净的 URL,无 #)
routes: 传入上面定义的路由配置
导出创建的路由实例,以便在 Vue 应用程序的主文件(通常是 main.js 或 app.js)中使用。
main.vue
<el-button class="aside-btn upload-file-btn" type="primary" :icon="Plus":class="{ 'icon-only': isCollapsed }"@click="goToRecruitmentPage">{{ isCollapsed ? '' : '人才招聘分析' }}</el-button>
type=“primary”:
设置按钮类型为 primary(主按钮,通常是蓝色)
:icon=“Plus”:
动态绑定图标属性,使用 Element Plus 的 Plus(加号)图标
需要从 Element Plus 导入 Plus 图标:import { Plus } from ‘@element-plus/icons-vue’
:class=“{ ‘icon-only’: isCollapsed }”:
动态绑定 class,当 isCollapsed 为 true 时,添加 icon-only 类
这通常用于侧边栏折叠时只显示图标不显示文字的场景
@click=“goToRecruitmentPage”:
点击事件绑定,点击按钮时调用 goToRecruitmentPage 方法
goToRecruitmentPage() {// 使用 Vue Router 进行页面跳转this.$router.push('/recruitment');},
在script的methods下完成跳转
.push() 方法:
Vue Router 的核心导航方法
作用:向浏览器的历史记录栈添加一个新记录,并跳转到指定路由
等效于用户点击 的效果

功能界面
template
整体结构,分为三行
<div class="recruitment-container"><el-row :gutter="20"><!-- 三个主要部分 --><el-col :span="24">标题和总览卡片</el-col><div v-show="showAnalysis">数据分析图表区域</div><el-col :span="24">表格区域</el-col></el-row>
</div>

标题和总览区域
<el-card class="overview-card" shadow="hover"><div class="dashboard-header"><h2>人才池运营看板</h2><div class="header-actions"><el-button type="primary" @click="showAnalysis = !showAnalysis":icon="showAnalysis ? 'Close' : 'DataAnalysis'" >{{ showAnalysis ? '关闭分析' : '数据分析' }}</el-button></div><div class="total-stats"><div class="stat-item"><div class="stat-value">{{ total }}</div><div class="stat-label">简历总数</div></div><div class="stat-item"><div class="stat-value">{{ todayNew }}</div><div class="stat-label">今日新增</div></div></div></div>
</el-card>
使用 el-card 创建卡片式布局
包含:
主标题 “人才池运营看板”
一个切换按钮,用于显示/隐藏分析图表区域
两个统计数字:简历总数和今日新增简历
卡片式布局,应该就是标签并排着一个一个
数据分析图表区域 (条件渲染)
<div v-show="showAnalysis" class="analysis-container"><el-row :gutter="20"><el-col :span="24"><!-- 技术栈分布图表 --><el-card class="chart-card" shadow="hover"><template #header><span class="chart-title">技术栈分布</span></template><div ref="skillChart" class="chart-container skill-chart"></div></el-card><!-- 学历分布图表 --><el-card class="chart-card" shadow="hover"><template #header><span class="chart-title">学历分布</span></template><div ref="educationChart" class="chart-container education-chart"></div></el-card></el-col></el-row>
</div>
使用 v-show 控制显示/隐藏
包含两个图表卡片:
技术栈分布图表
学历分布图表
使用 ref 属性为图表容器注册引用,便于后续用 ECharts 等库渲染图表
表格区域
<el-card class="table-card" shadow="hover"><el-table :data="resumeList" stripe v-loading="loading"height="calc(100vh - 600px)"><!-- 多个表格列 --><el-table-column prop="name" label="姓名" /><el-table-column prop="gender" label="性别" /><!-- 其他列... --><!-- 特殊处理的列 --><el-table-column prop="skill" label="技能"><template #default="scope"><el-tag v-for="skill in scope.row.skill?.split(',')">{{ skill.trim() }}</el-tag></template></el-table-column><!-- 长文本使用 tooltip 显示 --><el-table-column prop="work_experience" label="工作经验"><template #default="scope"><el-tooltip :content="scope.row.work_experience"><div class="truncate">{{ scope.row.work_experience }}</div></el-tooltip></template></el-table-column></el-table><!-- 分页组件 --><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize"@size-change="handleSizeChange"@current-change="handleCurrentChange"/>
</el-card>

script
导入依赖
import { ref, onMounted, computed, watch, nextTick } from 'vue'
import axios from 'axios'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import { DataAnalysis, Close } from '@element-plus/icons-vue'
Vue 相关:Composition API 的核心方法
Axios:用于 HTTP 请求
Element Plus:消息提示组件和图标
ECharts:数据可视化图表库
响应式数据
const allResumeList = ref([]) // 所有简历数据
const currentPage = ref(1) // 当前页码
const pageSize = ref(10) // 每页条数
const loading = ref(false) // 加载状态
const total = ref(0) // 数据总数
const todayNew = ref(0) // 今日新增简历数
const showAnalysis = ref(false) // 是否显示分析图表
const analysisType = ref('skill') // 当前分析维度
// 图表 DOM 引用
const skillChart = ref(null)
const educationChart = ref(null)
// 图表实例
let skillChartInstance = null
let educationChartInstance = null
计算属性
const resumeList = computed(() => {const start = (currentPage.value - 1) * pageSize.valueconst end = start + pageSize.valuereturn allResumeList.value.slice(start, end)
})
根据当前分页参数计算当前页显示的数据
核心方法
数据获取
const fetchResumeData = async () => {loading.value = truetry {const response = await axios.get('http://10.1.108.220:18000/resume/resume-files')allResumeList.value = response.datatotal.value = response.data.lengthtodayNew.value = Math.floor(Math.random() * 10) // 模拟数据if (response.data.length === 0) {ElMessage.warning('暂无简历数据')} else {ElMessage.success('数据加载成功')}} catch (error) {ElMessage.error('获取数据失败')} finally {loading.value = false}
}

当点击事件发生的时候,就获取简历数据
返回值
return {resumeList,currentPage,pageSize,total,loading,handleSizeChange,handleCurrentChange,skillChart,educationChart,todayNew,showAnalysis,DataAnalysis,Close
}
暴露给模板使用的所有变量和方法
style
相关文章:
【源码阅读/Vue Flask前后端】简历数据查询功能
目录 一、Flask后端部分modelServiceroute 二、Vue前端部分index.js main.vue功能界面templatescriptstyle 一般就是三个层面,model层面用来建立数据库的字段,service用来对model进行操作,写一些数据库操作的代码,route就是具体的…...
Vue背景介绍+声明式渲染+数据响应式
一、Vue背景 1. 为什么学Vue 1.前后端开发就业必备技能 2.岗位多,绝⼤互联⽹公司都在使⽤Vue,还可以助⼒SpringBoot、C等项⽬开发 3.提⾼开发效率 更少的时间,干更多的活,提高项目开发速度 原生JS做法 Vue做法 总而言之: 使用Vue能够赋能、提升就业竞争…...
HarmonyOS NEXT 鸿蒙中手写和使用第三方仓库封装Logger打印工具
应用场景 在鸿蒙开发中,我们在很多时候调试代码都需要用到日志打印工具,但无论是hilog还是console.log,都用起来相对麻烦,而且需要手动将对象转换为JSON字符串的方式才能打印,并且在控制台日志中输出的格式也非常丑。所以下面我们…...
如何使用 CSS 的backdrop - filter属性实现背景模糊等特效,有哪些兼容性问题?
大白话如何使用 CSS 的backdrop - filter属性实现背景模糊等特效,有哪些兼容性问题? 嘿,朋友!今天咱们来聊聊 CSS 里超酷的 backdrop-filter 属性,它能让你轻松实现背景模糊等超炫特效。咱们先看看这属性到底是啥&…...
批量合并 PDF 文档,支持合并成单个文档,也支持按文件夹合并 PDF 文档
在日常工作中,合并多个 PDF 文档为一个文件是非常常见的需求。通过合并 PDF,不仅能够更方便地进行管理,还能在特定场景下(如批量打印)提高效率。那么,当我们需要批量合并多个 PDF 文件时,是否有…...
rbpf虚拟机-汇编和反汇编器
文章目录 一、概述二、主要功能三、关键函数解析3.1 汇编器3.1.1 parse -转换为Instruction列表3.1.2 assemble_internal-转换为Insn 3.2 反汇编器3.2.1 to_insn_vec-转换为机器指令 四、总结 Welcome to Code Blocks blog 本篇文章主要介绍了 [rbpf虚拟机-汇编和反汇编器] ❤…...
虚拟现实--->unity学习
前言:这学期劳动课选了虚拟现实,其中老师算挺认真的,当然对一些不感兴趣的同学来说是一种折磨,我对这个unity的学习以及后续的虚幻引擎刚开始连基础的概念都没有,后面渐渐也是滋生了一些兴趣,用这篇博客记录…...
一文详解QT环境搭建:ubuntu20.4安装配置Qt5
随着软件开发技术的不断进步,跨平台应用程序的需求日益增长,开发者们面临着如何在不同操作系统之间保持代码的一致性和效率的问题。Qt作为一个成熟的跨平台C框架,在这方面提供了卓越的支持,不仅简化了GUI应用程序的创建过程&#…...
Gateway实战(三)、断言-时间、Cookie信息
spring cloud-Gateway实战三、断言 断言一)、时间断言相关1、适用场景2、Demo案例二)、断言- Cookie信息1、用户身份验证与会话管理场景及Demo案例2、A/B测试及Demo案例断言 简单了解: 断言是一种在程序设计中用于检查程序状态或条件的机制,在gateway网关里,断言的作用是…...
PyTorch中的Tensor
PyTorch中的Tensor 是核心数据结构,类似于 NumPy 的多维数组,但具备 GPU 加速和自动求导等深度学习特性。 一、基本概念 核心数据结构 Tensor 是存储和操作数据的基础单元,支持标量(0D)、向量(1D&am…...
C++11大数加减
C11大数加减 // 20190412.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include "pch.h" #include <iostream> #include <algorithm> // sort find find_if #include <string> #include <vector> using names…...
OpenGL —— 基于Qt的视频播放器 - ffmpeg硬解码,QOpenGL渲染yuv420p或nv12视频(附源码)
🔔 OpenGL 相关技术、疑难杂症文章合集(掌握后可自封大侠 ⓿_⓿)(记得收藏,持续更新中…) 运行效果...
【IDEA的个性化配置】
目录: 一:隐藏项目路径二:禁用斜体注释三:重新Maven构建未完待续... 一:隐藏项目路径 😊在IDEA左侧的Project目录中,项目名称后面显示了项目的文件路径地址,如果不喜欢可以隐藏&…...
Vue 类与样式
数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute,我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易…...
【Kafka】分布式消息队列的核心奥秘
文章目录 一、Kafka 的基石概念主题(Topic)分区(Partition)生产者(Producer)消费者(Consumer) 二、Kafka 的架构探秘Broker 集群副本机制 三、Kafka 的卓越特性高…...
自动化发布工具CI/CD实践Jenkins部署与配置教程
1. 前言背景 其实一直想把jenkins 的笔记整理下,介于公司这次升级jenkins2.0 ,根据自己部署的一些经验,我把它整理成笔记。 之前我们的jenkins1.0 时代 还一直停留在 free style 或者 maven 风格的项目,随着项目的日益增多&#x…...
python中的demjson包介绍
demjson是Python中的一个第三方模块库,专门用于编码和解码JSON数据。以下是关于demjson包的详细介绍: 一、主要功能 编码与解码: demjson提供了将Python对象(如字典、列表等)编码成JSON字符串的功能。同时,…...
什么是SQL作业
SQL作业是在数据库服务器上按特定时间或间隔自动执行的计划任务或流程,这些作业由Microsoft SQL Server中的SQL Server代理管理,对于自动执行日常任务(如数据库系统中的备份、数据导入和报告生成)以及确保及时准确地处理和更新数据…...
Android实践开发制作小猴子摘桃小游戏
Android实践制作小猴子摘桃小游戏 实践素材项目源文件获取:Android可能存在版本差异项目如果不能正确运行,可以使用里面的素材自己构建项目Android实践制作小猴子摘桃小游戏Android实践制作小猴子摘桃小游戏https://mp.weixin.qq.com/s/jNU_hVfj9xklsil…...
springboot整合couchbase(集群)
springboot整合couchbase 1、Couchbase1.1、介绍1.2、Bucket1.3、Couchbase SDK 2、(key,value)写入couchbase集群2.1、总体图2.2、依赖2.3、CouchbaseConfig 配置文件2.4、代码使用 1、Couchbase 1.1、介绍 1.2、Bucket 在 Couchbase 中,bucket 是一个重要的概念…...
VsCode启用右括号自动跳过(自动重写) - 自录制gif演示
VsCode启用右括号自动跳过(自动重写) - 自录制gif演示 前言 不知道大家在编程时候的按键习惯是怎样的。输入完左括号后编辑器一般会自动补全右括号,输入完左括号的内容后,是按→跳过右括号还是按)跳过右括号呢? for (int i 0; i < a.s…...
[Linux]在vim中批量注释与批量取消注释
1.在vim中批量注释的步骤: 1.在normal模式下按Ctrl v ,进入V-BLOCK模式 2.按 J 键 或 K 键选择要注释的内容,J向上K向下 我们给第5,6,7行进行注释 3.按住shift i进入插入模式,输入 // 4.点击ESC键&…...
NC,GFS、ICON 数据气象信息可视化--降雨量的实现
随着气象数据的快速发展和应用,气象信息的可视化成为了一项不可或缺的技术手段。它不仅能帮助气象专家快速解读数据,还能为公众提供直观的天气预报信息。今天,我们将从降雨量的可视化出发,带大家一起了解如何实现气象数据的可视化…...
LLM之RAG实战(五十二)| 如何使用混合搜索优化RAG 检索
在RAG项目中,大模型生成的参考内容(专业术语称为块)来自前一步的检索,检索的内容在很大程度上直接决定了生成的效果,因此检索对于RAG项目至关重要,最常用的检索方法是关键字搜索和语义搜索。本文将分别介绍…...
探索Scala基础:融合函数式与面向对象编程的强大语言
Scala作为一门在现代编程领域备受瞩目的编程语言,融合了函数式编程和面向对象编程的特性,运行于Java虚拟机(JVM)之上,与Java有着良好的互操作性。它简洁、高效且表达力强,适用于各种规模和类型的软件开发项…...
Selenium文件上传
在 Web 自动化测试中,文件上传是一项常见的任务。不同的网站和前端技术可能导致上传方式有所不同,因此需要采用不同的方法进行处理。 方法 1:使用 send_keys() 直接上传(最常用) 适用场景: 页面中 有标准的 <input type="file"> 标签。 不需要弹出 Wind…...
Java多线程与高并发专题——Condition 和 wait/notify的关系
引入 上一篇关于Condition,我们对Condition有了进一步了解,在之前生产/消费者模式一文,我们讲过如何用 Condition 和 wait/notify 来实现生产者/消费者模式,其中的精髓就在于用Condition 和 wait/notify 来实现简易版阻塞队列&am…...
mysql-分区和性能
mysql自身只支持表的横向分区。 常听到开发人员说“”对表做个分区“,然后数据的查询就会快了。这是真的吗?实际上可能跟根本感觉不到查询速度的提升,甚至会发现查询速度急剧下降。因此,在合理使用分区之前,必须了解分…...
使用matlab进行分位数回归
对于使用MATLAB、R语言或者STATA执行带有虚拟变量的分位数回归,这三个工具都带有强大的分析功能。在核心观点上,首先需要理解分位数回归的基本原理、其次要掌握如何在各个统计软件中实现该分析、最后,需要熟悉虚拟变量在模型中的应用并合理加…...
[操作系统,学习记录]3.进程(2)
1.fork(); 玩法一:通过返回值if,else去执行不同的代码片段 玩法二:if,else然后调用execve函数去执行新的程序 2.进程终止: 退出码,子进程通过exit/return返回,父进程wait/waitpid等待而得&am…...
