App Inventor 2 考勤系统完整教程

基于GPS电子围栏实现自动打卡,支持手动打卡、历史记录查询、月度报表。

一、系统设计

1.1 功能模块

考勤系统
├── 打卡模块
│   ├── 手动打卡(按钮)
│   ├── 自动打卡(电子围栏)
│   └── 打卡验证(位置校验)
├── 记录模块
│   ├── 今日打卡状态
│   ├── 历史记录查询
│   └── 月度统计
└── 管理模块
    ├── 设置公司位置
    └── 设置打卡范围

1.2 数据结构(网络微数据库)

标签设计:
"checkin_张三_2026-03-26"  → "09:02:35"   (上班时间)
"checkout_张三_2026-03-26" → "18:15:22"   (下班时间)
"userlist"                 → ["张三","李四","王五"]
"company_location"         → "39.9042,116.4074,200"  (纬度,经度,半径)

二、核心代码

2.1 初始化与登录

初始化全局变量 当前用户 = ""
初始化全局变量 公司纬度 = 39.9042
初始化全局变量 公司经度 = 116.4074
初始化全局变量 打卡半径 = 200    // 米
初始化全局变量 已打卡上班 = 假
初始化全局变量 已打卡下班 = 假

当 Screen1.初始化 时
  // 从本地微数据库读取上次登录用户
  初始化局部变量 保存用户 = 调用 微数据库1.获取值("last_user", "")
  如果 保存用户 ≠ "" 则
    设置 全局变量 当前用户 = 保存用户
    调用 进入主界面()
  否则
    调用 显示登录界面()

// 登录
当 按钮_登录.被点击 时
  初始化局部变量 用户名 = 文本输入框_用户名.文本
  初始化局部变量 密码 = 文本输入框_密码.文本
  
  如果 用户名 ≠ "" 且 密码 ≠ "" 则
    // 从网络微数据库验证
    调用 网络微数据库1.获取值(合并字符串("user_", 用户名), "")
    设置 全局变量 当前用户 = 用户名

2.2 手动打卡

当 按钮_打卡.被点击 时
  // 检查位置权限
  如果 位置传感器1.可用 = 假 则
    调用 对话框1.显示消息对话框("请开启位置权限", "提示", "确定")
    返回
  
  // 获取当前位置
  初始化局部变量 当前纬度 = 位置传感器1.纬度
  初始化局部变量 当前经度 = 位置传感器1.经度
  
  // 计算与公司的距离
  初始化局部变量 距离 = 调用 计算距离(
    当前纬度, 当前经度,
    全局变量 公司纬度, 全局变量 公司经度
  )
  
  如果 距离 <= 全局变量 打卡半径 则
    调用 执行打卡()
  否则
    调用 对话框1.显示消息对话框(
      合并字符串("❌ 不在打卡范围内\n距公司:", 四舍五入(距离), "米"),
      "打卡失败", "确定")

// 执行打卡
定义 执行打卡()
  初始化局部变量 今日 = 调用 计时器1.格式化日期时间(调用 计时器1.现在, "yyyy-MM-dd")
  初始化局部变量 时间 = 调用 计时器1.格式化日期时间(调用 计时器1.现在, "HH:mm:ss")
  初始化局部变量 小时 = 转换为数字(截取文本(时间, 1, 2))
  
  如果 全局变量 已打卡上班 = 假 则
    // 上班打卡
    调用 网络微数据库1.存储值(
      合并字符串("checkin_", 全局变量 当前用户, "_", 今日),
      时间
    )
    设置 全局变量 已打卡上班 = 真
    设置 标签_上班时间.文本 = 合并字符串("上班:", 时间)
    
    // 判断是否迟到(9点后算迟到)
    如果 小时 >= 9 则
      设置 标签_状态.文本 = "⚠️ 迟到"
      设置 标签_状态.背景颜色 = 橙色
    否则
      设置 标签_状态.文本 = "✅ 正常"
      设置 标签_状态.背景颜色 = 绿色
  
  否则如果 全局变量 已打卡下班 = 假 则
    // 下班打卡
    调用 网络微数据库1.存储值(
      合并字符串("checkout_", 全局变量 当前用户, "_", 今日),
      时间
    )
    设置 全局变量 已打卡下班 = 真
    设置 标签_下班时间.文本 = 合并字符串("下班:", 时间)
    调用 对话框1.显示消息对话框("✅ 下班打卡成功!", "提示", "确定")
  
  否则
    调用 对话框1.显示消息对话框("今日已完成打卡", "提示", "确定")

2.3 自动打卡(电子围栏)

初始化全局变量 上次围栏状态 = "外"

当 位置传感器1.位置改变 时(纬度, 经度, 高度, 速度)
  初始化局部变量 距离 = 调用 计算距离(
    纬度, 经度, 全局变量 公司纬度, 全局变量 公司经度
  )
  初始化局部变量 当前状态 = 如果 距离 <= 全局变量 打卡半径 则 "内" 否则 "外"
  
  // 进入围栏 → 自动上班打卡
  如果 当前状态 = "内" 且 全局变量 上次围栏状态 = "外" 且 全局变量 已打卡上班 = 假 则
    调用 执行打卡()
    调用 对话框1.显示消息对话框("📍 已自动上班打卡", "提示", "确定")
  
  // 离开围栏 → 自动下班打卡
  如果 当前状态 = "外" 且 全局变量 上次围栏状态 = "内" 且 全局变量 已打卡上班 = 真 且 全局变量 已打卡下班 = 假 则
    调用 执行打卡()
    调用 对话框1.显示消息对话框("🚶 已自动下班打卡", "提示", "确定")
  
  设置 全局变量 上次围栏状态 = 当前状态

2.4 查询历史记录

当 按钮_查询.被点击 时
  初始化局部变量 查询日期 = 日期选择器1.日期
  
  // 查询上班时间
  调用 网络微数据库1.获取值(
    合并字符串("checkin_", 全局变量 当前用户, "_", 查询日期),
    "未打卡"
  )

当 网络微数据库1.已获得值时(标签, 值)
  如果 以 "checkin_" 开头(标签) 则
    设置 标签_上班.文本 = 合并字符串("上班:", 值)
    // 继续查下班
    初始化局部变量 日期 = 截取文本(标签, 文本长度(全局变量 当前用户)+9+1, 文本长度(标签))
    调用 网络微数据库1.获取值(
      合并字符串("checkout_", 全局变量 当前用户, "_", 日期),
      "未打卡"
    )
  否则如果 以 "checkout_" 开头(标签) 则
    设置 标签_下班.文本 = 合并字符串("下班:", 值)

2.5 月度统计

当 按钮_月报.被点击 时
  初始化局部变量 年月 = "2026-03"
  初始化局部变量 出勤天数 = 0
  初始化局部变量 迟到次数 = 0
  
  // 遍历当月每天
  对于 日 从 1 到 31 步长 1
    初始化局部变量 日期 = 合并字符串(年月, "-", 调用 补零(日, 2))
    初始化局部变量 上班时间 = 调用 微数据库1.获取值(
      合并字符串("checkin_", 全局变量 当前用户, "_", 日期), ""
    )
    如果 上班时间 ≠ "" 则
      设置 出勤天数 = 出勤天数 + 1
      如果 转换为数字(截取文本(上班时间, 1, 2)) >= 9 则
        设置 迟到次数 = 迟到次数 + 1
  
  设置 标签_月报.文本 = 合并字符串(
    年月, " 考勤报告\n",
    "出勤:", 出勤天数, "天\n",
    "迟到:", 迟到次数, "次\n",
    "缺勤:", 31 - 出勤天数, "天"
  )

三、界面设计参考

┌─────────────────────────────────┐
│  考勤打卡  [张三]  [退出]        │
├─────────────────────────────────┤
│  📍 距公司:35米  ✅ 在范围内    │
├──────────────┬──────────────────┤
│ 上班:09:02  │ 下班:--:--      │
│ 状态:✅正常  │                  │
├──────────────┴──────────────────┤
│         [  立即打卡  ]           │
├─────────────────────────────────┤
│  [查询记录]  [月度报表]  [设置]  │
└─────────────────────────────────┘

四、常见问题

Q1:GPS定位慢怎么办?

  • 先用网络定位(快但精度低),再等GPS精确定位
  • 设置 位置传感器1.使用GPS = 真 同时启用网络定位

Q2:如何防止员工代打卡?

  • 结合人脸识别(使用百度AI人脸识别API)
  • 要求打卡时拍照上传
  • 记录打卡时的GPS精度,低精度打卡标记为异常

Q3:多人考勤数据如何管理?

  • 每人独立标签(checkin_用户名_日期
  • 管理员端查询所有人:遍历 userlist 列表

参考资料


文档版本:2026.03 | 作者:App Inventor 2 中文网 www.fun123.cn

参考资料与版权声明

原文来源

版权声明

本文档基于 MIT App Inventor 官方文档及社区资源整理,版权归原作者所有:
  • MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权
  • MIT App Inventor Community 帖子版权归原作者所有
本文档由 ai2claw 🐝 整理,仅供学习参考,如有侵权请联系删除。