【源码阅读/Vue Flask前后端】简历数据查询功能

news2025/4/1 8:42:29

目录

  • 一、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 results
    except 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': '获取简历文件失败'
            }), 500
        return jsonify(result), 200
    except 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-pagination
    v-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.value
  const end = start + pageSize.value
  return allResumeList.value.slice(start, end)
})

根据当前分页参数计算当前页显示的数据
核心方法
数据获取

const fetchResumeData = async () => {
  loading.value = true
  try {
    const response = await axios.get('http://10.1.108.220:18000/resume/resume-files')
    allResumeList.value = response.data
    total.value = response.data.length
    todayNew.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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2324927.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue背景介绍+声明式渲染+数据响应式

一、Vue背景 1. 为什么学Vue 1.前后端开发就业必备技能 2.岗位多&#xff0c;绝⼤互联⽹公司都在使⽤Vue&#xff0c;还可以助⼒SpringBoot、C等项⽬开发 3.提⾼开发效率 更少的时间,干更多的活,提高项目开发速度 原生JS做法 Vue做法 总而言之: 使用Vue能够赋能、提升就业竞争…

HarmonyOS NEXT 鸿蒙中手写和使用第三方仓库封装Logger打印工具

应用场景 在鸿蒙开发中&#xff0c;我们在很多时候调试代码都需要用到日志打印工具&#xff0c;但无论是hilog还是console.log,都用起来相对麻烦&#xff0c;而且需要手动将对象转换为JSON字符串的方式才能打印&#xff0c;并且在控制台日志中输出的格式也非常丑。所以下面我们…

批量合并 PDF 文档,支持合并成单个文档,也支持按文件夹合并 PDF 文档

在日常工作中&#xff0c;合并多个 PDF 文档为一个文件是非常常见的需求。通过合并 PDF&#xff0c;不仅能够更方便地进行管理&#xff0c;还能在特定场景下&#xff08;如批量打印&#xff09;提高效率。那么&#xff0c;当我们需要批量合并多个 PDF 文件时&#xff0c;是否有…

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学习

前言&#xff1a;这学期劳动课选了虚拟现实&#xff0c;其中老师算挺认真的&#xff0c;当然对一些不感兴趣的同学来说是一种折磨&#xff0c;我对这个unity的学习以及后续的虚幻引擎刚开始连基础的概念都没有&#xff0c;后面渐渐也是滋生了一些兴趣&#xff0c;用这篇博客记录…

一文详解QT环境搭建:ubuntu20.4安装配置Qt5

随着软件开发技术的不断进步&#xff0c;跨平台应用程序的需求日益增长&#xff0c;开发者们面临着如何在不同操作系统之间保持代码的一致性和效率的问题。Qt作为一个成熟的跨平台C框架&#xff0c;在这方面提供了卓越的支持&#xff0c;不仅简化了GUI应用程序的创建过程&#…

【IDEA的个性化配置】

目录&#xff1a; 一&#xff1a;隐藏项目路径二&#xff1a;禁用斜体注释三&#xff1a;重新Maven构建未完待续... 一&#xff1a;隐藏项目路径 &#x1f60a;在IDEA左侧的Project目录中&#xff0c;项目名称后面显示了项目的文件路径地址&#xff0c;如果不喜欢可以隐藏&…

【Kafka】分布式消息队列的核心奥秘

文章目录 一、Kafka 的基石概念​主题&#xff08;Topic&#xff09;​分区&#xff08;Partition&#xff09;​生产者&#xff08;Producer&#xff09;​消费者&#xff08;Consumer&#xff09;​ 二、Kafka 的架构探秘​Broker 集群​副本机制​ 三、Kafka 的卓越特性​高…

自动化发布工具CI/CD实践Jenkins部署与配置教程

1. 前言背景 其实一直想把jenkins 的笔记整理下&#xff0c;介于公司这次升级jenkins2.0 &#xff0c;根据自己部署的一些经验&#xff0c;我把它整理成笔记。 之前我们的jenkins1.0 时代 还一直停留在 free style 或者 maven 风格的项目&#xff0c;随着项目的日益增多&#x…

什么是SQL作业

SQL作业是在数据库服务器上按特定时间或间隔自动执行的计划任务或流程&#xff0c;这些作业由Microsoft SQL Server中的SQL Server代理管理&#xff0c;对于自动执行日常任务&#xff08;如数据库系统中的备份、数据导入和报告生成&#xff09;以及确保及时准确地处理和更新数据…

Android实践开发制作小猴子摘桃小游戏

Android实践制作小猴子摘桃小游戏 实践素材项目源文件获取&#xff1a;Android可能存在版本差异项目如果不能正确运行&#xff0c;可以使用里面的素材自己构建项目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 中&#xff0c;bucket 是一个重要的概念…

VsCode启用右括号自动跳过(自动重写) - 自录制gif演示

VsCode启用右括号自动跳过(自动重写) - 自录制gif演示 前言 不知道大家在编程时候的按键习惯是怎样的。输入完左括号后编辑器一般会自动补全右括号&#xff0c;输入完左括号的内容后&#xff0c;是按→跳过右括号还是按)跳过右括号呢&#xff1f; for (int i 0; i < a.s…

[Linux]在vim中批量注释与批量取消注释

1.在vim中批量注释的步骤&#xff1a; 1.在normal模式下按Ctrl v &#xff0c;进入V-BLOCK模式 2.按 J 键 或 K 键选择要注释的内容&#xff0c;J向上K向下 我们给第5&#xff0c;6&#xff0c;7行进行注释 3.按住shift i进入插入模式&#xff0c;输入 // 4.点击ESC键&…

NC,GFS、ICON 数据气象信息可视化--降雨量的实现

随着气象数据的快速发展和应用&#xff0c;气象信息的可视化成为了一项不可或缺的技术手段。它不仅能帮助气象专家快速解读数据&#xff0c;还能为公众提供直观的天气预报信息。今天&#xff0c;我们将从降雨量的可视化出发&#xff0c;带大家一起了解如何实现气象数据的可视化…

LLM之RAG实战(五十二)| 如何使用混合搜索优化RAG 检索

在RAG项目中&#xff0c;大模型生成的参考内容&#xff08;专业术语称为块&#xff09;来自前一步的检索&#xff0c;检索的内容在很大程度上直接决定了生成的效果&#xff0c;因此检索对于RAG项目至关重要&#xff0c;最常用的检索方法是关键字搜索和语义搜索。本文将分别介绍…

[操作系统,学习记录]3.进程(2)

1.fork(); 玩法一&#xff1a;通过返回值if&#xff0c;else去执行不同的代码片段 玩法二&#xff1a;if&#xff0c;else然后调用execve函数去执行新的程序 2.进程终止&#xff1a; 退出码&#xff0c;子进程通过exit/return返回&#xff0c;父进程wait/waitpid等待而得&am…

26考研——排序_选择排序_选择排序的基本思想 简单选择排序(8)

408答疑 文章目录 四、选择排序选择排序的基本思想简单选择排序定义算法思想性能分析空间效率时间效率稳定性 适用性 九、参考资料鲍鱼科技课件26王道考研书 四、选择排序 选择排序的基本思想 每一趟&#xff08;如第 i i i 趟&#xff09;在剩下 n − i 1 n-i1 n−i1&…

PPT——组合SCI论文图片

SCI论文中对于图的排版常常是最头疼的事情&#xff0c;通常需要几个图组合在一起&#xff0c;并且如何控制图中的字体一致也是麻烦事。 保持这个大图里面的一致&#xff0c;转头一看跟其他图又不一致了。最近跟我的博导学了一手&#xff0c;今天就来记录一下吧。主要用到的软件…

Tabby 一:如何在Mac配置保姆级教程(本地模型替换hugging face下载)

1. brew安装 mac需要先安装brew&#xff0c;如果本地已经安装过brew这一步可以忽略&#xff0c;遇到问题可以自己ai问 /bin/bash -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 可能遇到source .zprofile失败&#xff0c;因为…