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

基于NodeJS、HBS、JS实现SQLite考勤打卡状态更新功能需求

没问题,我来帮你搞定这个打卡功能的数据库更新逻辑!下面是适配你技术栈的完整实现步骤:

实现从按钮点击到SQLite数据库更新的完整流程

1. 先搞定后端依赖与数据库初始化

首先确保你的项目里安装了必要的包:

npm install express express-handlebars sqlite3

然后在你的主Node.js文件(比如app.js)里完成基础配置与数据库连接:

const express = require('express');
const sqlite3 = require('sqlite3').verbose();
const exphbs = require('express-handlebars');

const app = express();
const port = 3000;

// 配置Handlebars模板引擎
app.engine('hbs', exphbs({ extname: '.hbs' }));
app.set('view engine', 'hbs');

// 解析前端发送的JSON/表单数据
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 连接SQLite数据库
const db = new sqlite3.Database('./db.development.sqlite', (err) => {
  if (err) {
    console.error(err.message);
  }
  console.log('已连接到开发数据库');
});

// 确保Clock_in表存在(如果还没创建的话)
db.run(`CREATE TABLE IF NOT EXISTS Clock_in (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id TEXT NOT NULL,
  is_present BOOLEAN NOT NULL,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`);

2. 编写后端API路由处理打卡请求

添加两个POST路由来分别处理IN/OUT的状态更新:

// 处理IN按钮请求:标记用户为在场(TRUE)
app.post('/clock-in', (req, res) => {
  const { userId } = req.body;
  if (!userId) {
    return res.status(400).json({ success: false, message: '用户ID不能为空' });
  }

  // 用INSERT OR REPLACE实现"有则更新,无则插入"的逻辑
  db.run(`INSERT OR REPLACE INTO Clock_in (user_id, is_present)
          VALUES (?, ?)`, [userId, 1], (err) => {
    if (err) {
      return res.status(500).json({ success: false, message: err.message });
    }
    res.json({ success: true, message: '已标记为在场' });
  });
});

// 处理OUT按钮请求:标记用户为缺勤(FALSE)
app.post('/clock-out', (req, res) => {
  const { userId } = req.body;
  if (!userId) {
    return res.status(400).json({ success: false, message: '用户ID不能为空' });
  }

  db.run(`INSERT OR REPLACE INTO Clock_in (user_id, is_present)
          VALUES (?, ?)`, [userId, 0], (err) => {
    if (err) {
      return res.status(500).json({ success: false, message: err.message });
    }
    res.json({ success: true, message: '已标记为缺勤' });
  });
});

// 启动本地服务器
app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

如果你的需求是每次点击都新增一条打卡记录(而非覆盖旧记录),把INSERT OR REPLACE改成INSERT INTO即可。

3. 前端Handlebars模板与按钮事件绑定

在你的Handlebars视图文件(比如views/index.hbs)里添加按钮并编写点击事件:

<!DOCTYPE html>
<html>
<head>
  <title>员工打卡系统</title>
</head>
<body>
  <h1>打卡操作</h1>
  <button id="clockInBtn">IN</button>
  <button id="clockOutBtn">OUT</button>

  <script>
    // 替换为实际用户ID,也可以从后端模板动态渲染:{{userId}}
    const currentUserId = 'employee_001';

    // IN按钮点击逻辑
    document.getElementById('clockInBtn').addEventListener('click', async () => {
      try {
        const response = await fetch('/clock-in', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ userId: currentUserId })
        });
        const result = await response.json();
        alert(result.message);
      } catch (err) {
        console.error('IN操作失败:', err);
        alert('IN请求失败,请重试');
      }
    });

    // OUT按钮点击逻辑
    document.getElementById('clockOutBtn').addEventListener('click', async () => {
      try {
        const response = await fetch('/clock-out', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ userId: currentUserId })
        });
        const result = await response.json();
        alert(result.message);
      } catch (err) {
        console.error('OUT操作失败:', err);
        alert('OUT请求失败,请重试');
      }
    });
  </script>
</body>
</html>

4. 测试功能

  1. 启动服务器:node app.js
  2. 访问http://localhost:3000
  3. 点击IN/OUT按钮,用SQLite可视化工具(比如DB Browser for SQLite)打开db.development.sqlite,就能看到Clock_in表的is_present字段被正确更新为1(TRUE)或0(FALSE)

小提醒

如果你的项目有用户认证,可以从session中自动获取当前用户ID,不用硬编码,这样更安全灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:27:44