C#winform上下班打卡系统Demo

news2025/1/18 14:54:18

C# winform上下班打卡系统Demo

系统效果如图所示
在这里插入图片描述
7个label控件(lblUsername、lblLoggedInEmployeeId、lab_IP、lblCheckOutTime、lblCheckInTime、lab_starttime、lab_endtime)、3个按钮、1个dataGridView控件、2个groupBox控件

C#代码实现

using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class 员工打卡 : Form
    {
        private string loggedInUsername;
        private string loggedInEmployeeId;
        private string connectionString = "server=127.0.0.1;uid=sa;pwd=xyz@0123456;database=test";

        public 员工打卡(string username, string employeeId)
        {
            InitializeComponent();
            loggedInUsername = username;
            loggedInEmployeeId = employeeId;
            CheckTodaysPunchInRecord();
        }
        [DllImport("user32.dll")]
        public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]
        public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);

        // 禁用窗口大小改变
        private const uint SC_SIZE = 0xF000;
        private const uint MF_BYCOMMAND = 0x0000;
        private const uint MF_GRAYED = 0x0001;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            IntPtr hMenu = GetSystemMenu(this.Handle, false);
            if (hMenu != IntPtr.Zero)
            {
                EnableMenuItem(hMenu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
            }
        }
        private void 员工打卡_Load(object sender, EventArgs e)
        {

            lblUsername.Text = "当前登录用户:" + loggedInUsername;
            lblLoggedInEmployeeId.Text = "工号:" + loggedInEmployeeId.ToString();
            // 设置日期控件的显示格式为年-月-日
            startTime.Format = DateTimePickerFormat.Custom;
            startTime.CustomFormat = "yyyy-MM-dd";
            // 设置日期控件的显示格式为年-月-日
            endTime.Format = DateTimePickerFormat.Custom;
            endTime.CustomFormat = "yyyy-MM-dd";
            //不显示出dataGridView1的最后一行空白
            dataGridView1_Result.AllowUserToAddRows = false;
            // 设置数据和列名居中对齐
            dataGridView1_Result.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1_Result.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            // 设置列名加粗
            dataGridView1_Result.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font(dataGridView1_Result.ColumnHeadersDefaultCellStyle.Font, FontStyle.Bold);
            // 设置列宽自适应
            dataGridView1_Result.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            LoadData();
            GetIP();

        }
        private void GetIP()
        {
            // 获取本机IP地址
            IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in ipHost.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    lab_IP.Text = "IP地址:" + ip.ToString(); // 添加到label1的Text属性中
                }
            }
        }
        private void btnCheckIn_Click(object sender, EventArgs e)
        {
            if (IsPunchInRecordExists())
            {
                MessageBox.Show("你已打过上班卡。", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
                return;
            }

            DateTime currentTime = DateTime.Now;
            string punchInTime = currentTime.ToString("yyyy-MM-dd HH:mm:ss");
            string status = currentTime.TimeOfDay < new TimeSpan(8, 30, 0) ? "正常" : "迟到";

            InsertPunchInRecord(punchInTime, status);
            lblCheckInTime.Text = punchInTime;
            lblCheckInTime.Visible = true;
            // 刷新DataGridView显示最新打卡记录
            RefreshDataGridView();
        }

        private bool IsPunchInRecordExists()
        {
            DateTime currentDate = DateTime.Now.Date;
            string query = $"SELECT COUNT(*) FROM PunchIn WHERE emp_code='{loggedInEmployeeId}' AND punch_in_time >= '{currentDate}'";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    int count = (int)command.ExecuteScalar();
                    return count > 0;
                }
            }
        }

        private void RefreshDataGridView()
        {
            // 执行查询语句
           string query = $@"
                    SELECT 
                        a.id,
                        a1.username AS 用户名,
                        a.emp_code AS 工号,
                        CONVERT(VARCHAR(19), a.punch_in_time, 120) AS 上班打卡时间,
                        a.status AS 上班打卡状态,
                        CONVERT(VARCHAR(19), b.punch_out_time, 120) AS 下班打卡时间,
                        b.status AS 下班打卡状态
                    FROM 
                        (SELECT * FROM Employee) a1
                    LEFT JOIN 
                        PunchIn a ON a1.emp_code = a.emp_code
                    LEFT JOIN 
                        PunchOut b ON a.emp_code = b.emp_code 
                                 AND CONVERT(DATE, a.punch_in_time) = CONVERT(DATE, b.punch_out_time)
                                 AND b.punch_out_time = (
                                     SELECT MAX(punch_out_time)
                                     FROM PunchOut
                                     WHERE emp_code = a.emp_code 
                                       AND CONVERT(DATE, punch_out_time) = CONVERT(DATE, a.punch_in_time)
                                 )
                    WHERE 
                        a.emp_code = '{loggedInEmployeeId}' AND MONTH(a.punch_in_time) = MONTH(GETDATE()) AND YEAR(a.punch_in_time) = YEAR(GETDATE())
                    ORDER BY 
                        a.id, a.emp_code, a.punch_in_time";
            Console.WriteLine("执行的SQL语句是:" + query);
            // 执行查询并获取结果
            // 你可以使用适合你数据库的查询方法
            DataTable dataTable = ExecuteQuery(query);

            // 将查询结果绑定到DataGridView的数据源
            dataGridView1_Result.DataSource = dataTable;
        }

        private DataTable ExecuteQuery(string query)
        {
            // 创建连接和命令对象并执行查询
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();

                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    // 创建适配器并填充数据到DataTable
                    SqlDataAdapter adapter = new SqlDataAdapter(command);
                    DataTable dataTable = new DataTable();
                    adapter.Fill(dataTable);
                    return dataTable;
                }
            }
        }

        private void InsertPunchInRecord(string punchInTime, string status)
        {
            string query = $"INSERT INTO PunchIn (emp_code, punch_in_time, status) VALUES ('{loggedInEmployeeId}', '{punchInTime}', '{status}')";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    command.ExecuteNonQuery();
                }
            }
        }
        private void CheckTodaysPunchInRecord()
        {
            DateTime currentDate = DateTime.Now.Date;
            string query = $"SELECT punch_in_time FROM PunchIn WHERE emp_code='{loggedInEmployeeId}' AND punch_in_time >= '{currentDate}'";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    object result = command.ExecuteScalar();
                    if (result != null)
                    {
                        string punchInTime = ((DateTime)result).ToString("yyyy-MM-dd HH:mm:ss");
                        lblCheckInTime.Text = punchInTime;
                        lblCheckInTime.Visible = true;
                    }
                }
            }
        }
        private void btnCheckOut_Click(object sender, EventArgs e)
        {
            DateTime currentTime = DateTime.Now;
            string punchOutTime = currentTime.ToString("yyyy-MM-dd HH:mm:ss");

            if (IsInvalidPunchOutTime(currentTime))
            {
                MessageBox.Show("21点30到23:59:59点打下班卡无效。");
                return;
            }

            string status = currentTime.TimeOfDay < new TimeSpan(18, 0, 0) ? "早退" : "正常"; // 判断下班打卡时间是否在18:00之前

            InsertPunchOutRecord(punchOutTime, status);
            lblCheckOutTime.Text = punchOutTime;
            lblCheckOutTime.Visible = true;
            // 刷新DataGridView显示最新打卡记录
            RefreshDataGridView();
        }

        private bool IsInvalidPunchOutTime(DateTime currentTime)
        {
            TimeSpan startTime = new TimeSpan(21, 30, 0);
            TimeSpan endTime = new TimeSpan(23, 59, 59);
            TimeSpan currentTimeOfDay = currentTime.TimeOfDay;

            return currentTimeOfDay >= startTime && currentTimeOfDay <= endTime;
        }

        private void InsertPunchOutRecord(string punchOutTime, string status)
        {
            string query = $"INSERT INTO PunchOut (emp_code, punch_out_time, status) VALUES ('{loggedInEmployeeId}', '{punchOutTime}', '{status}')";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    command.ExecuteNonQuery();
                }
            }
        }

        private void btn_Serch_Click(object sender, EventArgs e)
        {
            // 获取所选时间范围
            DateTime startDate = startTime.Value.Date;
            DateTime endDate = endTime.Value.Date.AddDays(1).AddSeconds(-1);
            // 构建 SQL 查询语句
            string query = $@"
                    SELECT 
                        a.id,
                        a1.username AS 用户名,
                        a.emp_code AS 工号,
                        CONVERT(VARCHAR(19), a.punch_in_time, 120) AS 上班打卡时间,
                        a.status AS 上班打卡状态,
                        CONVERT(VARCHAR(19), b.punch_out_time, 120) AS 下班打卡时间,
                        b.status AS 下班打卡状态
                    FROM 
                        (SELECT * FROM Employee) a1
                    LEFT JOIN 
                        PunchIn a ON a1.emp_code = a.emp_code
                    LEFT JOIN 
                        PunchOut b ON a.emp_code = b.emp_code 
                                 AND CONVERT(DATE, a.punch_in_time) = CONVERT(DATE, b.punch_out_time)
                                 AND b.punch_out_time = (
                                     SELECT MAX(punch_out_time)
                                     FROM PunchOut
                                     WHERE emp_code = a.emp_code 
                                       AND CONVERT(DATE, punch_out_time) = CONVERT(DATE, a.punch_in_time)
                                 )
                    WHERE 
                        a.punch_in_time BETWEEN @StartDate AND @EndDate
                        AND a.emp_code = '{loggedInEmployeeId}'
                    ORDER BY 
                        a.id, a.emp_code, a.punch_in_time";

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    // 添加查询参数
                    command.Parameters.AddWithValue("@StartDate", startDate);
                    command.Parameters.AddWithValue("@EndDate", endDate);
                    Console.WriteLine("查询的SQL语句:" + query);
                    // 打开数据库连接
                    connection.Open();

                    // 创建数据适配器和数据表
                    SqlDataAdapter adapter = new SqlDataAdapter(command);
                    DataTable table = new DataTable();

                    // 填充数据表
                    adapter.Fill(table);

                    // 关闭数据库连接
                    connection.Close();

                    // 绑定数据表到 DataGridView 控件
                    dataGridView1_Result.DataSource = table;
                }
            }
        }

        private void LoadData()
        {
            // 获取所选时间范围
            DateTime startDate = startTime.Value.Date;
            DateTime endDate = endTime.Value.Date.AddDays(1).AddSeconds(-1);
            string query = $@"
                    SELECT 
                        a.id,
                        a1.username AS 用户名,
                        a.emp_code AS 工号,
                        CONVERT(VARCHAR(19), a.punch_in_time, 120) AS 上班打卡时间,
                        a.status AS 上班打卡状态,
                        CONVERT(VARCHAR(19), b.punch_out_time, 120) AS 下班打卡时间,
                        b.status AS 下班打卡状态
                    FROM 
                        (SELECT * FROM Employee) a1
                    LEFT JOIN 
                        PunchIn a ON a1.emp_code = a.emp_code
                    LEFT JOIN 
                        PunchOut b ON a.emp_code = b.emp_code 
                                 AND CONVERT(DATE, a.punch_in_time) = CONVERT(DATE, b.punch_out_time)
                                 AND b.punch_out_time = (
                                     SELECT MAX(punch_out_time)
                                     FROM PunchOut
                                     WHERE emp_code = a.emp_code 
                                       AND CONVERT(DATE, punch_out_time) = CONVERT(DATE, a.punch_in_time)
                                 )
                    WHERE 
                        a.punch_in_time BETWEEN @StartDate AND @EndDate
                        AND a.emp_code = '{loggedInEmployeeId}'
                    ORDER BY 
                        a.id, a.emp_code, a.punch_in_time";
            Console.WriteLine("开始时间:" + startDate);
            Console.WriteLine("结束时间:" + endDate);
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    // 添加查询参数
                    command.Parameters.AddWithValue("@StartDate", startDate);
                    command.Parameters.AddWithValue("@EndDate", endDate);
                    Console.WriteLine("一加载时获取数据查询的SQL语句:" + query);
                    // 打开数据库连接
                    connection.Open();

                    // 创建数据适配器和数据表
                    SqlDataAdapter adapter = new SqlDataAdapter(command);
                    DataTable table = new DataTable();

                    // 填充数据表
                    adapter.Fill(table);

                    // 关闭数据库连接
                    connection.Close();

                    // 绑定数据表到 DataGridView 控件
                    dataGridView1_Result.DataSource = table;
                }
            }
        }




    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1293755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1、初识 llvm源码编译 及virtualbox和ubuntu环境搭建

很久没更新了&#xff0c;最近准备研究逆向和加固&#xff0c;于是跟着看雪hanbing老师学习彻底搞懂ollvm&#xff0c;终于把所有流程跑通了&#xff0c;中间遇到了太多的坑&#xff0c;所以必须记录一下&#xff0c;能避免自己和帮助他人最好。 环境搭建太重要了&#xff0c;…

c语言指针详解下

指针下 1 指针与字符串 int main01(){//指针与字符串char a[] "helloworld";//定义了一个字符数组,字符数组内容为helloworld\0//定义一个指针用来保存数组首元素的地址char * p a;printf("%s\n",p);//%s打印一个字符串,要的是首个字符的地址printf(…

使用Rust 构建C 组件

协议解析&#xff0c;这不就很快了&#xff0c;而且原生的标准库红黑树和avl 树支持&#xff0c;异步tokio 这些库&#xff0c;编写应用组件就很快了 rust 标准库不支持 unix 的消息队列&#xff0c;但是支持 shm 和 uds&#xff0c;后者从多方面考虑都比&#xff0c;消息队列更…

flutter添加全局水印

效果&#xff1a; 可以直接引用&#xff1a;disable_screenshots: ^0.2.0 但是有时候直接引用会报错&#xff0c;可以不引用插件直接把下面的源码工具类放在项目里面 工具类源码&#xff1a; import dart:io; import dart:math;import package:flutter/cupertino.dart; impor…

oomall课堂笔记

一、项目分层结构介绍 controller层&#xff08;控制器层&#xff09;&#xff1a; 作用&#xff1a;负责输出和输入&#xff0c;接收前端数据&#xff0c;把结果返回给前端。 1.处理用户请求&#xff0c;接收用户参数 2.调用service层处理业务&#xff0c;返回响应 servi…

uniapp 打开文件管理器上传(H5、微信小程序、android app三端)文件

H5跟安卓APP 手机打开的效果图&#xff1a; Vue页面&#xff1a; <template><view class"content"><button click"uploadFiles">点击上传</button></view> </template><script>export default {data() {return…

【Linux】已安装 powerlevel10k,报错 command not found: p10k

问题描述 在配置 zsh 时&#xff0c;已经安装了 powerlevel10k&#xff0c;但是当尝试启动 Powerlevel10k 配置向导时&#xff0c;出现了以下错误&#xff1a; p10k configure zsh: command not found: p10k原因分析 出现这个错误的原因是因为 zsh 终端还没有加载最新的配置…

Kafka性能调优:高吞吐、低延迟的数据流

Apache Kafka作为一种高性能、分布式流处理平台&#xff0c;对于实时数据的处理至关重要。本文将深入讨论Kafka性能调优的关键策略和技术&#xff0c;通过丰富的示例代码为大家提供实际操作指南&#xff0c;以构建高吞吐、低延迟的数据流系统。 Broker 配置的优化 首先&#…

[全志Tina/Linux]全志在线生成bootlogo工具

一、需求 由于全志的bootlogo文件要求使用bmp格式的32位RGBA图像&#xff0c;经测试在使用不同版本的ps软件修图时&#xff0c;导出的bootlogo.bmp经常无法被全志uboot识别&#xff0c;因此使用在线工具转换。 二、操作 1、登录工具网站 https://online-converting.com/ima…

C++面试宝典第3题:找不同的数

题目 封装两个函数&#xff0c;分别完成下面的编码任务。 &#xff08;1&#xff09;在一个整型数组中&#xff0c;数字都是两两相同&#xff0c;只有一个不同&#xff0c;请编写代码&#xff0c;最快找出这个不同的数字。 &#xff08;2&#xff09;在一个整型数组中&#xff…

力扣78. 子集(java 回溯解法)

Problem: 78. 子集 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 我们易知&#xff0c;本题目涉及到对元素的穷举&#xff0c;即我们可以使用回溯来实现。对于本题目我们应该较为注重回溯中的决策阶段&#xff1a; 由于涉及到对数组中元素的穷举&#xff0c;即在每…

1、Redis变慢原因排查(上)

感觉Redis变慢了&#xff0c;这些可能的原因你查了没 &#xff1f;(上) Redis 作为一款业内使用率最高的内存数据库&#xff0c;其拥有非常高的性能&#xff0c;单节点的QPS压测能达到18万以上。但也正因此如此&#xff0c;当应用访问 Redis 时&#xff0c;如果发现响应延迟变…

Docker架构及常用的命令

一、初识Docker 1、 docker是一个快速交付应用、运行应用的技术&#xff0c;具备下列优势&#xff1a; 可以将程序及其依赖、运行环境一起打包为一个镜像&#xff0c;可以迁移到任意Linux操作系统运行时利用沙箱机制形成隔离容器&#xff0c;各个应用互不干扰启动、移除都可以…

Redis保证高可用的三种方式

Redis保证高可用主要有三种方式&#xff1a;主从、哨兵、集群。 主从复制了解吗&#xff1f; Redis主从复制简图 主从复制&#xff0c;是指将一台 Redis 服务器的数据&#xff0c;复制到其他的 Redis 服务器。前者称为 主节点(master)&#xff0c;后者称为 从节点(slave)。且…

用Rust刷LeetCode之66 加一

66. 加一[1] 难度: 简单 func plusOne(digits []int) []int { length : len(digits) // 从最低位开始遍历&#xff0c;逐位加一 for i : length - 1; i > 0; i-- { if digits[i] < 9 { digits[i] return digits } d…

计算整数各位数字之和 C语言xdoj29

时间限制: 1 S 内存限制: 1000 Kb 问题描述: 假设n是一个由最多9位数字&#xff08;d9, …, d1&#xff09;组成的正整数。编写一个程序计算n的每一位数字之和 输入说明: 输入数据为一个正整数n 输出说明: 对整数n输出它的各位数字之和后换行 输入样例: …

排序算法——桶排序/基数排序/计数排序

桶排序 是计数排序的升级版。它利用了函数的映射关系&#xff0c;高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理&#xff1a; 假设输入数据服从均匀分布&#xff0c;将数据分到有限数量的桶里&#xff0c;每个桶再分别排序&#xff08;有可能再使…

C/C++,数字序列——计算伯努利数(Bernoulli Number)的计算方法与源程序

1 文本格式 typedef long long ll; const int maxn 10000; const int mod 1e9 7; ll B[maxn]; // 伯努利数 ll C[maxn][maxn]; // 组合数 ll inv[maxn]; // 逆元&#xff08;计算伯努利数&#xff09; void init() { // 预处理组合数 for (int i 0;…

PHPstudy小皮的数据库打开失败问题解决

如果你的MYSQL服务启动后停止&#xff0c;多次重启依然无法解决的情况下&#xff0c;大概率是和本地mysql冲突了 但是&#xff0c;千万不要卸载掉本地mysql&#xff0c;只需要在服务中停止本地mysql即可 将此服务关闭&#xff0c;小皮的mysql即可使用

AI助力智慧农业,基于DETR【DEtection TRansformer】模型开发构建田间作物场景下庄稼作物、杂草检测识别系统

智慧农业随着数字化信息化浪潮的演变有了新的定义&#xff0c;在前面的系列博文中&#xff0c;我们从一些现实世界里面的所见所想所感进行了很多对应的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《自建数据集&#xff0c;基于YOLOv7开发构建农田场景下杂草…