You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python操作的MySQL考勤数据库中实现签退动作?

RFID签到签退系统签退逻辑实现方案

我正在做一个学校项目,通过RFID读卡器读取RFID卡片,将签到(check_in)和签退(check_out)时间存储到MySQL数据库中。目前已实现签到功能,但无法完成“查询用户当日已有记录并自动添加签退动作”的逻辑。

数据库表结构

create table attendance_check(
   id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
   date_id DATE NOT NULL DEFAULT CURRENT_DATE,  
   user_id INT UNSIGNED NOT NULL,
   name VARCHAR(255) NOT NULL,
   clock_id TIME NOT NULL DEFAULT CURRENT_TIME,
   Action VARCHAR(255) NOT NULL,
   PRIMARY KEY ( id )
);

Action字段用于记录"in"(签到)和"out"(签退),date_id默认取当前日期,clock_id默认取当前时间。

当前实现代码

while True:
    lcd.clear()
    lcd.message('Place Card to\nrecord attendance')
    id, text = reader.read()

    cursor.execute("Select id, name FROM users WHERE rfid_uid="+str(id))
    result = cursor.fetchone()
    lcd.clear()
    name = result[1]
    number = result [0]
    action1 = "in"
    action2 = "out"
    if cursor.rowcount >= 1:
      lcd.message("Welcome " + name)
      add = ("INSERT INTO attendance_check (user_id, name, Action) VALUES (%s, %s, %s)")
      date = (numar, nume, action1)  # 注:此处变量名应为number和name,属于笔误
      cursor.execute(add, date)
      db.commit()
    else:
      lcd.message("User does not exist.")
    time.sleep(2)

签退逻辑实现方案

核心解决思路是:每次读取RFID后,先查询用户当日最新的操作状态,如果是"in"则插入"out"记录,如果是"out"或无当日记录则插入"in"记录。修改后的代码如下:

import time
# 假设reader、cursor、db、lcd已完成初始化

while True:
    lcd.clear()
    lcd.message('Place Card to\nrecord attendance')
    id, text = reader.read()

    # 1. 查询用户信息
    cursor.execute("SELECT id, name FROM users WHERE rfid_uid = %s", (str(id),))
    result = cursor.fetchone()
    lcd.clear()
    
    if not result:
        lcd.message("User does not exist.")
        time.sleep(2)
        continue
    
    user_id = result[0]
    user_name = result[1]

    # 2. 查询用户当日最新的签到记录
    cursor.execute("""
        SELECT Action 
        FROM attendance_check 
        WHERE user_id = %s AND date_id = CURRENT_DATE 
        ORDER BY clock_id DESC 
        LIMIT 1
    """, (user_id,))
    latest_action = cursor.fetchone()

    # 3. 判断要执行的动作
    if not latest_action or latest_action[0] == "out":
        current_action = "in"
        lcd.message(f"Welcome {user_name}\nChecked In")
    else:
        current_action = "out"
        lcd.message(f"Goodbye {user_name}\nChecked Out")

    # 4. 插入新的记录
    insert_sql = """
        INSERT INTO attendance_check (user_id, name, Action) 
        VALUES (%s, %s, %s)
    """
    cursor.execute(insert_sql, (user_id, user_name, current_action))
    db.commit()
    time.sleep(2)

关键修改说明

  • 用参数化查询替换字符串拼接,避免SQL注入风险(原代码存在注入隐患)
  • 新增当日记录查询逻辑:按clock_id倒序取最新一条记录,精准判断用户当前状态
  • 修正原代码中的变量名笔误
  • 根据状态动态设置动作,并给出对应的LCD提示

内容的提问来源于stack exchange,提问作者user21192515

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:41:43