python+flask+html实现智能局域网wifi员工签到系统代码

代码语言:python

所属分类:其他

代码描述:python+flask+html实现智能局域网wifi员工签到系统代码,通过arp获取设备ip与MAC地址,然后备注每个设备,每天一旦设备连接,自动记录打卡。

代码标签: python flask html 智能 局域网 wifi 员工 签到 系统 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

import sqlite3
import subprocess
import re
import os
import locale
import threading
import time
from datetime import datetime
import calendar
from flask import Flask, jsonify, request, render_template_string

# ==============================================================================
# 1. 应用程序设置与数据库初始化
# ==============================================================================

app = Flask(__name__)
DB_NAME = 'attendance_app_v3.db'  # 使用新版本数据库文件名以避免冲突

def get_db_connection():
    """创建并返回数据库连接"""
    conn = sqlite3.connect(DB_NAME, check_same_thread=False)
    conn.row_factory = sqlite3.Row
    return conn

def init_db():
    """初始化数据库,创建表结构"""
    conn = get_db_connection()
    cursor = conn.cursor()
    # 员工表:存储MAC地址与姓名的对应关系
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS employees (
            mac_address TEXT PRIMARY KEY,
            name TEXT NOT NULL UNIQUE
        )
    ''')
    # 考勤表:记录每日的签到信息
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS attendance (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            mac_address TEXT NOT NULL,
            check_in_time TEXT NOT NULL,
            check_in_date TEXT NOT NULL,
            name TEXT NOT NULL,
            UNIQUE(mac_address, check_in_date) -- 确保每人每天只有一条签到记录
        )
    ''')
    conn.commit()
    conn.close()
    print("数据库已成功初始化。")

# ==============================================================================
# 2. 后端核心逻辑 (设备扫描与智能签到) - 已修复
# ==============================================================================

def scan_network():
    """
    执行 'arp -a' 命令扫描局域网设备。
    返回一个包含所有检测到的MAC地址的集合。
    注意:'arp -a' 的输出格式可能因操作系统而异。
    """
    online_macs = set()
    try:
        # 使用 'arp -a' 命令获取ARP缓存表
        command = "arp -a"
        output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
        
        # 使用系统首选编码解码命令输出
        encoding = locale.getpreferredencoding()
        output_str = output.decode(encoding, errors='ignore')
        
        # 正则表达式匹配MAC地址 (xx:xx:xx:xx:xx:xx or xx-xx-xx-xx-xx-xx)
        mac_pattern = re.compile(r'([0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2})')
        found_macs = mac_pattern.findall(output_str)
        
        # 格式化MAC地址为大写,并使用冒号作为分隔符
        online_macs = {mac.upper().replace('-', ':') for mac in found_macs}
        
    except Exception as e:
        print(f"扫描网络时发生错误: {e}")
        
    return online_macs

def background_attendance_logger():
    """
    后台线程任务:定时扫描网络,并为在线的、尚未签到的注册员工自动签到。
    【已修复】采用无状态逻辑,更稳定可靠。
    """
    print("后台智能签到线程已启动...")
    while True:
        with app.app_context():
            try:
                # 1. 获取当前所有在线的MAC地址
                current_online_macs = scan_network()
                if not current_online_macs:
                    time.sleep(60) # 如果未扫描到设备,等待下一次扫描
                    continue

                # 2. 获取所有已注册的员工信息
                conn = get_db_connection()
                cursor = conn.cursor()
                cursor.execute("SELECT mac_address, name FROM employees")
                registered_employees = {row['mac_address']: row['name'] for row in cursor.fetchall()}
                
                # 3. 找出当前在线的注册员工
                online_registered_macs = set(registered_employees.keys()) & current_online_macs

                if online_registered_macs:
                    today_str = datetime.now().strftime('%Y-%m-%d')
                    
                    # 4. 获取今天已经签到过的员工
                    cursor.execute("SELECT mac_address FROM attendance WHERE check_in_date = ?", (today_str,))
                    already_checked_in_macs = {row['mac_address'] for row in cursor.fetchall()}
                    
                    # 5. 筛选出需要签到的员工 (在线、已注册但今天尚未签到)
                    macs_to_check_in = online_registered_macs - already_checked_in_macs

                    if macs_to_check_in:
                        print(f"检测到 {len(macs_to_check_in)} 名员工需要签到: {macs_to_check_in}")
                        for mac in macs_to_check_in:
                            name = registered_employees[mac]
                            check_in_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                            cursor.execute(
                                "INSERT INTO attendance (mac_address, check_in_time, check_in_date, name) VALUES (?, ?, ?, ?)",
                                (mac, check_in_time, today_str, name)
                            )
                            print(f"【自动签到】员工 '{name}' ({mac}) 已于 {check_in_time} 签到。")
                        conn.commit()
                
                conn.close()

            except Exception as e:
                print(f"后台签到线程运行时出错: {e}")

        # 每 60 秒执行一次扫描
        time.sleep(60)


# ==============================================================================
# 3. Flask 路由 (Web API 接口)
# ============================.........完整代码请登录后点击上方下载按钮下载查看

网友评论0