我来帮你创建一个简单的PHP工时管理系统,这个系统将包含员工登录、工时打卡、工时记录和统计功能。

完整PHP工时管理系统
数据库结构
-- 创建数据库
CREATE DATABASE IF NOT EXISTS work_time_system;
USE work_time_system;
-- 员工表
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_code VARCHAR(20) UNIQUE NOT NULL,
name VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(100),
department VARCHAR(50),
position VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 打卡记录表
CREATE TABLE time_records (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_id INT,
work_date DATE NOT NULL,
check_in TIMESTAMP NOT NULL,
check_out TIMESTAMP,
work_hours DECIMAL(5,2),
status ENUM('正常', '迟到', '早退', '缺卡') DEFAULT '正常',
overtime_hours DECIMAL(5,2) DEFAULT 0,
remark TEXT,
FOREIGN KEY (employee_id) REFERENCES employees(id)
);
-- 请假记录表
CREATE TABLE leave_requests (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_id INT,
leave_type ENUM('事假', '病假', '年假', '调休') NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
reason TEXT,
status ENUM('待审批', '已批准', '已驳回') DEFAULT '待审批',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (employee_id) REFERENCES employees(id)
);
配置文件 (config.php)
<?php
// 数据库配置
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'work_time_system');
// 数据库连接
function db_connect() {
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
return $conn;
}
// 会话管理
session_start();
// 检查登录状态
function is_logged_in() {
return isset($_SESSION['employee_id']);
}
function require_login() {
if (!is_logged_in()) {
header('Location: login.php');
exit;
}
}
// 辅助函数
function redirect($url) {
header("Location: $url");
exit;
}
function sanitize($data) {
return htmlspecialchars(strip_tags(trim($data)));
}
?>
登录页面 (login.php)
<?php
require_once 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$employee_code = sanitize($_POST['employee_code']);
$password = $_POST['password'];
$conn = db_connect();
// 准备SQL语句
$stmt = $conn->prepare("SELECT id, employee_code, name, password FROM employees WHERE employee_code = ?");
$stmt->bind_param("s", $employee_code);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 1) {
$user = $result->fetch_assoc();
if (password_verify($password, $user['password'])) {
$_SESSION['employee_id'] = $user['id'];
$_SESSION['employee_name'] = $user['name'];
$_SESSION['employee_code'] = $user['employee_code'];
redirect('dashboard.php');
} else {
$error = "密码错误";
}
} else {
$error = "员工号不存在";
}
$stmt->close();
$conn->close();
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">员工登录 - 工时系统</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; display: flex; justify-content: center; align-items: center; height: 100vh; }
.login-container { background: white; padding: 40px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); width: 100%; max-width: 400px; }
h1 { text-align: center; margin-bottom: 30px; color: #333; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 5px; color: #555; }
input[type="text"], input[type="password"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; font-size: 16px; }
button { width: 100%; padding: 12px; background: #4CAF50; color: white; border: none; border-radius: 5px; font-size: 16px; cursor: pointer; }
button:hover { background: #45a049; }
.error { background: #f44336; color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; text-align: center; }
.register-link { text-align: center; margin-top: 15px; }
.register-link a { color: #4CAF50; text-decoration: none; }
</style>
</head>
<body>
<div class="login-container">
<h1>员工工时系统</h1>
<?php if (isset($error)): ?>
<div class="error"><?php echo $error; ?></div>
<?php endif; ?>
<form method="POST" action="">
<div class="form-group">
<label>员工号</label>
<input type="text" name="employee_code" required>
</div>
<div class="form-group">
<label>密码</label>
<input type="password" name="password" required>
</div>
<button type="submit">登 录</button>
<div class="register-link">
<a href="register.php">还没有账号?注册</a>
</div>
</form>
</div>
</body>
</html>
主页面 (dashboard.php)
<?php
require_once 'config.php';
require_login();
$conn = db_connect();
$employee_id = $_SESSION['employee_id'];
// 处理打卡操作
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
$today = date('Y-m-d');
if ($action === 'check_in') {
// 检查今天是否已经打卡
$check_sql = "SELECT id FROM time_records WHERE employee_id = ? AND work_date = ?";
$check_stmt = $conn->prepare($check_sql);
$check_stmt->bind_param("is", $employee_id, $today);
$check_stmt->execute();
$check_result = $check_stmt->get_result();
if ($check_result->num_rows === 0) {
// 正常上班时间为9:00
$check_in_time = date('Y-m-d H:i:s');
$hours = date('H');
$minutes = date('i');
$status = '正常';
if ($hours > 9 || ($hours == 9 && $minutes > 30)) {
$status = '迟到';
}
$insert_sql = "INSERT INTO time_records (employee_id, work_date, check_in, status) VALUES (?, ?, ?, ?)";
$insert_stmt = $conn->prepare($insert_sql);
$insert_stmt->bind_param("isss", $employee_id, $today, $check_in_time, $status);
$insert_stmt->execute();
$message = "上班打卡成功!";
} else {
$message = "今天已经打过卡了";
}
} elseif ($action === 'check_out') {
// 更新下班时间
$update_sql = "UPDATE time_records
SET check_out = ?,
work_hours = TIMESTAMPDIFF(MINUTE, check_in, NOW()) / 60
WHERE employee_id = ? AND work_date = ? AND check_out IS NULL";
$update_stmt = $conn->prepare($update_sql);
$check_out_time = date('Y-m-d H:i:s');
$update_stmt->bind_param("sis", $check_out_time, $employee_id, $today);
$update_stmt->execute();
if ($update_stmt->affected_rows > 0) {
$message = "下班打卡成功!";
} else {
$message = "没有找到有效的打卡记录";
}
}
}
// 获取今日打卡状态
$today = date('Y-m-d');
$today_record = null;
$sql = "SELECT * FROM time_records WHERE employee_id = ? AND work_date = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("is", $employee_id, $today);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$today_record = $result->fetch_assoc();
}
// 获取本月工时统计
$month_start = date('Y-m-01');
$month_end = date('Y-m-t');
$stats_sql = "SELECT
COUNT(*) as total_days,
SUM(work_hours) as total_hours,
AVG(work_hours) as avg_hours,
SUM(overtime_hours) as total_overtime,
SUM(status = '迟到') as late_days
FROM time_records
WHERE employee_id = ? AND work_date BETWEEN ? AND ?";
$stats_stmt = $conn->prepare($stats_sql);
$stats_stmt->bind_param("iss", $employee_id, $month_start, $month_end);
$stats_stmt->execute();
$stats = $stats_stmt->get_result()->fetch_assoc();
// 获取最近7天的记录
$week_sql = "SELECT * FROM time_records
WHERE employee_id = ? AND work_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
ORDER BY work_date DESC";
$week_stmt = $conn->prepare($week_sql);
$week_stmt->bind_param("i", $employee_id);
$week_stmt->execute();
$week_records = $week_stmt->get_result();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">工时管理系统 - 首页</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; }
.header { background: #333; color: white; padding: 15px 30px; display: flex; justify-content: space-between; align-items: center; }
.header h2 { font-size: 20px; }
.header .user-info { display: flex; align-items: center; }
.header .user-info span { margin-right: 20px; }
.header a, .header button { background: #4CAF50; color: white; padding: 8px 15px; border: none; border-radius: 4px; cursor: pointer; text-decoration: none; font-size: 14px; }
.header a:hover { background: #45a049; }
.container { margin: 20px auto; max-width: 1200px; padding: 0 20px; }
.welcome { background: #e3f2fd; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
.card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.card h3 { margin-bottom: 15px; color: #333; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; }
.stat-item { background: #f9f9f9; padding: 15px; border-radius: 8px; text-align: center; }
.stat-item .value { font-size: 24px; font-weight: bold; color: #333; }
.stat-item .label { color: #666; margin-top: 5px; }
.btn { padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; margin: 10px; }
.btn-green { background: #4CAF50; color: white; }
.btn-orange { background: #FF9800; color: white; }
.btn:hover { opacity: 0.9; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
th { background: #f2f2f2; }
.date-display { color: #666; margin-bottom: 20px; }
.message { background: #4CAF50; color: white; padding: 10px; border-radius: 5px; margin-bottom: 20px; text-align: center; }
.time-display { font-size: 24px; text-align: center; margin: 20px 0; }
.logout-btn { background: #f44336; margin-right: 10px; }
</style>
</head>
<body>
<div class="header">
<h2>工时管理系统</h2>
<div class="user-info">
<span>欢迎,<?php echo htmlspecialchars($_SESSION['employee_name']); ?></span>
<a href="logout.php" class="logout-btn">退出登录</a>
</div>
</div>
<div class="container">
<?php if (isset($message)): ?>
<div class="message"><?php echo $message; ?></div>
<?php endif; ?>
<div class="welcome">
<div class="time-display" id="current-time"></div>
<div class="date-display" id="current-date"></div>
<!-- 打卡区域 -->
<div style="text-align: center; margin-top: 20px;">
<?php if (!$today_record || empty($today_record['check_in'])): ?>
<form method="POST" action="" style="display: inline;">
<input type="hidden" name="action" value="check_in">
<button type="submit" class="btn btn-green">上班打卡</button>
</form>
<?php else: ?>
<p>✓ 今日已上班打卡:<?php echo date('Y-m-d H:i:s', strtotime($today_record['check_in'])); ?></p>
<?php if (empty($today_record['check_out'])): ?>
<form method="POST" action="" style="display: inline; margin-top: 10px;">
<input type="hidden" name="action" value="check_out">
<button type="submit" class="btn btn-orange">下班打卡</button>
</form>
<?php else: ?>
<p>✓ 今日已下班打卡:<?php echo date('Y-m-d H:i:s', strtotime($today_record['check_out'])); ?></p>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<!-- 本月统计 -->
<div class="card">
<h3>📊 本月统计</h3>
<div class="stats-grid">
<div class="stat-item">
<div class="value"><?php echo $stats['total_days'] ?? 0; ?></div>
<div class="label">工作天数</div>
</div>
<div class="stat-item">
<div class="value"><?php echo number_format(($stats['total_hours'] ?? 0), 2); ?>h</div>
<div class="label">总工时</div>
</div>
<div class="stat-item">
<div class="value"><?php echo number_format(($stats['avg_hours'] ?? 0), 2); ?>h</div>
<div class="label">平均工时</div>
</div>
<div class="stat-item">
<div class="value"><?php echo number_format(($stats['total_overtime'] ?? 0), 2); ?>h</div>
<div class="label">加班时间</div>
</div>
<div class="stat-item">
<div class="value"><?php echo $stats['late_days'] ?? 0; ?></div>
<div class="label">迟到次数</div>
</div>
</div>
</div>
<!-- 近7天记录 -->
<div class="card">
<h3>📋 最近7天打卡记录</h3>
<table>
<thead>
<tr>
<th>日期</th>
<th>上班时间</th>
<th>下班时间</th>
<th>工作时长</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<?php while ($record = $week_records->fetch_assoc()): ?>
<tr>
<td><?php echo $record['work_date']; ?></td>
<td><?php echo $record['check_in'] ? date('H:i:s', strtotime($record['check_in'])) : '--'; ?></td>
<td><?php echo $record['check_out'] ? date('H:i:s', strtotime($record['check_out'])) : '--'; ?></td>
<td><?php echo $record['work_hours'] ? round($record['work_hours'], 2) . 'h' : '--'; ?></td>
<td>
<?php
$status_color = $record['status'] == '正常' ? 'green' : 'orange';
echo "<span style='color: $status_color;'>{$record['status']}</span>";
?>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<!-- 功能链接 -->
<div class="card">
<h3>🔧 快捷操作</h3>
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<a href="leave_request.php" class="btn btn-green">申请请假</a>
<a href="attendance_report.php" class="btn btn-orange">考勤报表</a>
<a href="profile.php" class="btn" style="background: #2196F3; color: white;">个人信息</a>
</div>
</div>
</div>
<!-- JavaScript -->
<script>
// 实时时间显示
function updateTime() {
const now = new Date();
const timeElement = document.getElementById('current-time');
const dateElement = document.getElementById('current-date');
timeElement.textContent = now.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
dateElement.textContent = now.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
});
}
// 每秒更新时间
setInterval(updateTime, 1000);
updateTime();
</script>
</body>
</html>
退出登录 (logout.php)
<?php
session_start();
session_unset();
session_destroy();
header('Location: login.php');
exit;
?>
注册页面 (register.php)
<?php
require_once 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$employee_code = sanitize($_POST['employee_code']);
$name = sanitize($_POST['name']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
$email = sanitize($_POST['email']);
$department = sanitize($_POST['department']);
// 密码验证
if ($password !== $confirm_password) {
$error = "两次输入的密码不一致";
} elseif (strlen($password) < 6) {
$error = "密码长度至少6位";
} else {
$conn = db_connect();
// 检查员工号是否已存在
$check_sql = "SELECT id FROM employees WHERE employee_code = ?";
$check_stmt = $conn->prepare($check_sql);
$check_stmt->bind_param("s", $employee_code);
$check_stmt->execute();
$check_result = $check_stmt->get_result();
if ($check_result->num_rows > 0) {
$error = "员工号已存在";
} else {
// 密码加密
$hashed_password = password_hash($password, PASSWORD_BCRYPT);
// 插入新员工
$insert_sql = "INSERT INTO employees (employee_code, name, password, email, department)
VALUES (?, ?, ?, ?, ?)";
$insert_stmt = $conn->prepare($insert_sql);
$insert_stmt->bind_param("sssss", $employee_code, $name, $hashed_password, $email, $department);
if ($insert_stmt->execute()) {
$_SESSION['registration_success'] = true;
redirect('login.php');
} else {
$error = "注册失败,请稍后重试";
}
}
}
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">员工注册 - 工时系统</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; display: flex; justify-content: center; align-items: center; min-height: 100vh; }
.register-container { background: white; padding: 40px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); width: 100%; max-width: 500px; margin: 20px; }
h1 { text-align: center; margin-bottom: 30px; color: #333; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; color: #555; }
input[type="text"], input[type="password"], input[type="email"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; font-size: 16px; }
button { width: 100%; padding: 12px; background: #4CAF50; color: white; border: none; border-radius: 5px; font-size: 16px; cursor: pointer; }
button:hover { background: #45a049; }
.error { background: #f44336; color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; text-align: center; }
.back-link { text-align: center; margin-top: 15px; display: block; color: #4CAF50; text-decoration: none; }
</style>
</head>
<body>
<div class="register-container">
<h1>员工注册</h1>
<?php if (isset($error)): ?>
<div class="error"><?php echo $error; ?></div>
<?php endif; ?>
<form method="POST" action="">
<div class="form-group">
<label>员工号 *</label>
<input type="text" name="employee_code" required>
</div>
<div class="form-group">
<label>姓名 *</label>
<input type="text" name="name" required>
</div>
<div class="form-group">
<label>密码 * (至少6位)</label>
<input type="password" name="password" required minlength="6">
</div>
<div class="form-group">
<label>确认密码 *</label>
<input type="password" name="confirm_password" required>
</div>
<div class="form-group">
<label>邮箱</label>
<input type="email" name="email">
</div>
<div class="form-group">
<label>部门</label>
<input type="text" name="department" placeholder="如:技术部、市场部等">
</div>
<button type="submit">注 册</button>
<a href="login.php" class="back-link" style="color: #4CAF50;">已注册?返回登录</a>
</form>
</div>
</body>
</html>
请假申请页面 (leave_request.php)
<?php
require_once 'config.php';
require_login();
$conn = db_connect();
$employee_id = $_SESSION['employee_id'];
// 处理请假申请
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$leave_type = sanitize($_POST['leave_type']);
$start_date = sanitize($_POST['start_date']);
$end_date = sanitize($_POST['end_date']);
$reason = sanitize($_POST['reason']);
// 检查日期有效性
if ($start_date > $end_date) {
$error = "开始日期不能大于结束日期";
} else {
$insert_sql = "INSERT INTO leave_requests (employee_id, leave_type, start_date, end_date, reason)
VALUES (?, ?, ?, ?, ?)";
$stmt = $conn->prepare($insert_sql);
$stmt->bind_param("issss", $employee_id, $leave_type, $start_date, $end_date, $reason);
if ($stmt->execute()) {
$success = "请假申请已提交,等待审批";
} else {
$error = "提交失败,请稍后重试";
}
}
}
// 获取我的请假记录
$leave_sql = "SELECT * FROM leave_requests WHERE employee_id = ? ORDER BY created_at DESC";
$leave_stmt = $conn->prepare($leave_sql);
$leave_stmt->bind_param("i", $employee_id);
$leave_stmt->execute();
$leave_records = $leave_stmt->get_result();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">请假申请 - 工时系统</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; }
.header { background: #333; color: white; padding: 15px 30px; display: flex; justify-content: space-between; align-items: center; }
.header a { color: white; text-decoration: none; }
.container { margin: 20px auto; max-width: 1200px; padding: 0 20px; }
.card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; color: #555; }
input[type="text"], input[type="date"], select, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; font-size: 16px; }
textarea { height: 100px; }
button { padding: 12px 24px; background: #4CAF50; color: white; border: none; border-radius: 5px; font-size: 16px; cursor: pointer; }
button:hover { background: #45a049; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
th { background: #f2f2f2; }
.success { background: #4CAF50; color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; }
.error { background: #f44336; color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; }
.back-btn { display: inline-block; background: #333; color: white; padding: 10px 20px; border-radius: 5px; text-decoration: none; }
.status-pending { color: orange; }
.status-approved { color: green; }
.status-rejected { color: red; }
</style>
</head>
<body>
<div class="header">
<h2>请假管理</h2>
<a href="dashboard.php">← 返回首页</a>
</div>
<div class="container">
<?php if (isset($success)): ?>
<div class="success"><?php echo $success; ?></div>
<?php endif; ?>
<?php if (isset($error)): ?>
<div class="error"><?php echo $error; ?></div>
<?php endif; ?>
<!-- 请假申请表单 -->
<div class="card">
<h3>📝 申请请假</h3>
<form method="POST" action="">
<div class="form-group">
<label>请假类型</label>
<select name="leave_type" required>
<option value="">请选择类型</option>
<option value="事假">事假</option>
<option value="病假">病假</option>
<option value="年假">年假</option>
<option value="调休">调休</option>
</select>
</div>
<div class="form-group">
<label>开始日期</label>
<input type="date" name="start_date" required>
</div>
<div class="form-group">
<label>结束日期</label>
<input type="date" name="end_date" required>
</div>
<div class="form-group">
<label>请假原因</label>
<textarea name="reason" required></textarea>
</div>
<button type="submit">提交申请</button>
</form>
</div>
<!-- 我的请假记录 -->
<div class="card">
<h3>📋 我的请假记录</h3>
<table>
<thead>
<tr>
<th>类型</th>
<th>开始日期</th>
<th>结束日期</th>
<th>原因</th>
<th>状态</th>
<th>申请时间</th>
</tr>
</thead>
<tbody>
<?php while ($record = $leave_records->fetch_assoc()): ?>
<tr>
<td><?php echo $record['leave_type']; ?></td>
<td><?php echo $record['start_date']; ?></td>
<td><?php echo $record['end_date']; ?></td>
<td><?php echo htmlspecialchars($record['reason']); ?></td>
<td>
<?php
$status_class = strtolower($record['status']);
echo "<span class='status-$status_class'>{$record['status']}</span>";
?>
</td>
<td><?php echo $record['created_at']; ?></td>
</tr>
<?php endwhile; ?>
<?php if ($leave_records->num_rows === 0): ?>
<tr>
<td colspan="6" style="text-align: center; color: #999;">暂无请假记录</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</body>
</html>
考勤报表页面 (attendance_report.php)
<?php
require_once 'config.php';
require_login();
$conn = db_connect();
$employee_id = $_SESSION['employee_id'];
// 处理日期筛选
$selected_month = isset($_GET['month']) ? $_GET['month'] : date('Y-m');
$month_start = $selected_month . '-01';
$month_end = date('Y-m-t', strtotime($selected_month));
// 获取报表数据
$sql = "SELECT
work_date,
check_in,
check_out,
work_hours,
status,
overtime_hours
FROM time_records
WHERE employee_id = ? AND work_date BETWEEN ? AND ?
ORDER BY work_date DESC";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iss", $employee_id, $month_start, $month_end);
$stmt->execute();
$records = $stmt->get_result();
// 汇总统计
$summary_sql = "SELECT
COUNT(*) as total_days,
SUM(work_hours) as total_work_hours,
SUM(overtime_hours) as total_overtime,
AVG(work_hours) as avg_work_hours,
SUM(status = '迟到') as late_count,
SUM(status = '早退') as early_count
FROM time_records
WHERE employee_id = ? AND work_date BETWEEN ? AND ?";
$summary_stmt = $conn->prepare($summary_sql);
$summary_stmt->bind_param("iss", $employee_id, $month_start, $month_end);
$summary_stmt->execute();
$summary = $summary_stmt->get_result()->fetch_assoc();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">考勤报表 - 工时系统</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; }
.header { background: #333; color: white; padding: 15px 30px; display: flex; justify-content: space-between; align-items: center; }
.header a { color: white; text-decoration: none; }
.container { margin: 20px auto; max-width: 1400px; padding: 0 20px; }
.card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.month-selector { margin-bottom: 20px; }
select, button { padding: 10px; border: 1px solid #ddd; border-radius: 5px; font-size: 14px; }
button { background: #4CAF50; color: white; border: none; cursor: pointer; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit,
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播