百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python + Flask 做个接口-员工带薪年假查询

zhezhongyun 2025-08-06 23:59 53 浏览

学Python有一段时间了,但接口还没去做过。也就是前端html,css,javascripts,后端就用Python。

先看效果图:





安装Python 和Flask这些我跳过,自行安装。

总体目录结构:


app.py代码如下:

一:导入必要的python库,记的要有app = Flask(__name__)

from flask import Flask, render_template, jsonify, request
import pyodbc
from datetime import datetime as dt
import pandas as pd

app = Flask(__name__)

二:先配置连接到后端数据库的连接信息

# 定义数据库连接信息
server = '0.0.0.0\sql2008' #IP地址
database = 'XXXX' # 数据库名
username = 'sa'
password = ''
# 连接Microsoft SQL Server数据库
try:
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=' + server + ';DATABASE=' + database + ';UID=' + username + ';PWD=' + password)
print('数据库连接成功!')
except Exception as e:
print('数据库连接失败'+e)
conn.close()

三:从数据库中获取数据的接口

# 按钮“查询”的触发函数
@app.route('/api/data', methods=['GET'])
def get_data():
as_year = request.args.get('as_year')
as_empid = request.args.get('as_empid')
# print(as_year + as_empid)
if as_year and as_empid:
data = onclick(as_year, as_empid)
return jsonify(data)
else:
return jsonify({"error": "Missing as_year or as_empid parameters"}), 400

def onclick(as_year,as_empid):
"显示查询年假表格数据"
# 表查询语句 中文显示会乱码的要convert 成navrchar(12)类型
ls_year = as_year
today = str(dt.today().date())
# print(today)
Enddate = dt.strptime(ls_year + '-12-31', "%Y-%m-%d")
Empid = as_empid
sql_cmd = (f"SELECT emp_id as 工号 from 表名" where 条件)
data = pd.read_sql(sql_cmd, conn)
# print(data)
return data.to_dict(orient='records')

四:最后给flask配置一个主页的路由。

# API路由
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)

五:index.html 代码

<!DOCTYPE html>
<html
lang="zh-CN">
<head>
<meta
charset="UTF-8">
<meta
name="viewport" content="width=device-width, initial-scale=1.0">
<title>
年度带薪年假查询</title>
<script
src="
https://cdn.tailwindcss.com"
></script>
<link
href="
https://cdn.jsdelivr.net/npm/font-awesome@
4.7.0/css/font-awesome.min.css"
rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3874c8',
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style
type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.fixed-bottom-right {
position: fixed;
right: 1rem;
bottom: 1rem;
}
.header-height {
height: 50px;
}
.table-shadow {
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
}
</style>
</head>
<body
class="bg-gray-50 min-h-screen flex flex-col">
<!-- 头部 -->
<header class="bg-primary header-height text-white flex items-center justify-between px-4 shadow-lg z-10">
<h1
class="text-xl font-bold">年度带薪年假查询</h1>
<button
id="menu-toggle" class="p-2 rounded-full hover:bg-primary-700 transition-colors">
<i
class="fa fa-bars text-xl"></i>
</button>
</header>
<!-- 主内容区 -->
<main class="flex-1 p-4 md:p-6">
<!-- 查询条件区域 -->
<div class="bg-white rounded-lg shadow-md p-4 mb-4">
<h2
class="text-lg font-semibold mb-4 text-gray-700">查询条件</h2>
<div
class="flex flex-col md:flex-row gap-4">
<div
class="flex-1">
<label
for="as_year" class="block text-sm font-medium text-gray-700 mb-1">输入年度</label>
<input
type="text" id="as_year" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition">
</div>
<div
class="flex-1">
<label
for="as_empid" class="block text-sm font-medium text-gray-700 mb-1">请输入工号</label>
<input
type="text" id="as_empid" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition">
</div>
<div
class="flex items-end">
<button
id="query-btn" class="w-full md:w-auto bg-primary hover:bg-primary/90 text-white font-medium py-2 px-4 rounded-md transition duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary">
<i
class="fa fa-search mr-2"></i>查询
</button>
</div>
</div>
</div>
<!-- 结果展示区域 -->
<div class="bg-white rounded-lg shadow-md p-4">
<h2
class="text-lg font-semibold mb-4 text-gray-700">查询结果</h2>
<!-- 加载状态 -->
<div id="loading" class="hidden flex justify-center items-center py-16">
<div
class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary"></div>
</div>
<!-- 表格容器 -->
<div id="table-container" class="hidden overflow-x-auto">
<table
class="min-w-full divide-y divide-gray-200 table-shadow">
<thead
class="bg-gray-50">
<tr>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">工号</th>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">姓名</th>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">入职日期</th>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">雇佣状态</th>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">可休时数</th>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">工龄</th>
<th
scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">己休时数</th>
</tr>
</thead>
<tbody
id="result-body" class="bg-white divide-y divide-gray-200">
<!-- 结果将在这里动态生成 -->
</tbody>
</table>
<!-- 分页控件 -->
<div id="pagination" class="flex items-center justify-between px-4 py-3 sm:px-6 mt-4">
<div
class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<p
class="text-sm text-gray-700">
显示第 <span id="page-range" class="font-medium">1-2</span> 条,共 <span id="total-count" class="font-medium">2</span>
</p>
</div>
<div>
<nav
class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
<a
href="#" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
<span
class="sr-only">上一页</span>
<i
class="fa fa-chevron-left"></i>
</a>
<a
href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-primary text-sm font-medium text-white hover:bg-primary/90">
1
</a>
<a
href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50">
2
</a>
<span
class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700">
...
</span>
<a
href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50">
4
</a>
<a
href="#" class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
<span
class="sr-only">下一页</span>
<i
class="fa fa-chevron-right"></i>
</a>
</nav>
</div>
</div>
</div>
</div>
<!-- 空状态 -->
<div id="empty-state" class="hidden flex flex-col items-center justify-center py-16">
<i
class="fa fa-search text-6xl text-gray-300 mb-4"></i>
<p
class="text-gray-500">请输入查询条件并点击查询按钮</p>
</div>
<!-- 错误状态 -->
<div id="error-state" class="hidden bg-red-50 border-l-4 border-red-400 p-4 my-4">
<div
class="flex">
<div
class="flex-shrink-0">
<i
class="fa fa-exclamation-triangle text-red-500"></i>
</div>
<div
class="ml-3">
<p
id="error-message" class="text-sm text-red-700"></p>
</div>
</div>
</div>
<!-- 无结果状态 -->
<div id="no-result" class="hidden flex flex-col items-center justify-center py-16">
<i
class="fa fa-folder-open-o text-6xl text-gray-300 mb-4"></i>
<p
class="text-gray-500">没有找到匹配的记录</p>
</div>
</div>
</main>
<!-- 页脚 -->
<footer class="bg-white border-t border-gray-200 py-4 px-6">
<div
class="text-center text-gray-500 text-sm">
<span
id="footer-text"></span>
</div>
</footer>
<!-- 侧边栏 -->
<div id="right-drawer" class="fixed inset-y-0 right-0 w-64 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-20 lg:hidden">
<div
class="p-4">
<div
class="flex justify-between items-center mb-4">
<h3
class="text-lg font-semibold text-gray-700">菜单</h3>
<button
id="close-drawer" class="p-1 rounded-full hover:bg-gray-100 transition-colors">
<i
class="fa fa-times"></i>
</button>
</div>
<nav
class="space-y-2">
<a
href="#" class="block px-4 py-2 rounded-md text-base font-medium text-gray-700 hover:bg-gray-50">首页</a>
<a
href="#" class="block px-4 py-2 rounded-md text-base font-medium text-gray-700 hover:bg-gray-50">报表管理</a>
<a
href="#" class="block px-4 py-2 rounded-md text-base font-medium text-gray-700 hover:bg-gray-50">员工管理</a>
<a
href="#" class="block px-4 py-2 rounded-md text-base font-medium text-gray-700 hover:bg-gray-50">系统设置</a>
</nav>
</div>
</div>
<!-- 遮罩层 -->
<div id="overlay" class="fixed inset-0 bg-black bg-opacity-50 z-10 hidden transition-opacity duration-300"></div>
<script>
// 侧边栏控制
const menuToggle = document.getElementById('menu-toggle');
const rightDrawer = document.getElementById('right-drawer');
const closeDrawer = document.getElementById('close-drawer');
const overlay = document.getElementById('overlay');

menuToggle.addEventListener('click', () => {


rightDrawer.classList.toggle('translate-x-full');

overlay.classList.toggle('hidden');

document.body.classList.toggle('overflow-hidden');

});

closeDrawer.addEventListener('click', () => {

rightDrawer.classList.add('translate-x-full');
overlay.classList.add('hidden');

document.body.classList.remove('overflow-hidden');

});
overlay.addEventListener('click', () => {
rightDrawer.classList.add('translate-x-full');
overlay.classList.add('hidden');

document.body.classList.remove('overflow-hidden');

});
// 设置页脚日期
document.getElementById('footer-text').textContent = new Date().getFullYear();
// 显示空状态
document.getElementById('empty-state').classList.remove('hidden');
document.getElementById('table-container').classList.add('hidden');
document.getElementById('error-state').classList.add('hidden');
document.getElementById('no-result').classList.add('hidden');
// 查询按钮点击事件
document.getElementById('query-btn').addEventListener('click', async function() {
// 获取输入值
const as_year = document.getElementById('as_year').value.trim();
const as_empid = document.getElementById('as_empid').value.trim();
// 简单验证
if (!as_year) {
showError('请输入年度');
return;
}
if (!as_empid) {
showError('请输入工号');
return;
}
// 显示加载状态
document.getElementById('empty-state').classList.add('hidden');
document.getElementById('table-container').classList.add('hidden');
document.getElementById('error-state').classList.add('hidden');
document.getElementById('no-result').classList.add('hidden');
document.getElementById('loading').classList.remove('hidden');
try {
// 调用真实的 API
await fetchApiData(as_year, as_empid);
} catch (error) {
showError(error.message);
} finally {
// 隐藏加载状态
document.getElementById('loading').classList.add('hidden');
}
});
// 调用真实的 API
async function fetchApiData(year, empId) {
const apiUrl = `
http://192.168.0.41:5000/api/data?as_year=${year}&as_empid=${empId}`;

try {
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
// 清空表格内容
const resultBody = document.getElementById('result-body');
resultBody.innerHTML = '';
// 如果有数据,填充表格
if (data.length > 0) {
data.forEach(item => {
const row = document.createElement('tr');
row.className = 'hover:bg-gray-50 transition';
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${item['工号']}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item['姓名']}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item['入职日期']}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item['雇佣状态']}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item['可休时数']}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item['工龄']}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item['己休时数']}</td>
`;
resultBody.appendChild(row);
});
// 显示表格
document.getElementById('table-container').classList.remove('hidden');
// 更新分页信息
document.getElementById('page-range').textContent = `1-${data.length}`;
document.getElementById('total-count').textContent = data.length;
} else {
// 显示无结果状态
document.getElementById('no-result').classList.remove('hidden');
}
} catch (error) {
throw error;
}
}
// 显示错误信息
function showError(message) {
document.getElementById('error-message').textContent = message;
document.getElementById('error-state').classList.remove('hidden');
}
</script>
</body>
</html>

六:启动后端服务器


出现这样表示成功了,

七:浏览器上输入http://192.168.0.41:5000 或 http://127.0.0.1:5000 ,就可以了。

#python自学# #pythonflask##flask框架有什么用#


相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...