文章目录[隐藏]
WordPress网站员工排班与考勤管理应用开发详细教程
引言:为什么选择WordPress开发企业应用?
在当今数字化时代,企业管理系统正逐渐从传统的桌面软件转向基于Web的解决方案。WordPress作为全球最流行的内容管理系统,不仅适用于博客和内容网站,其强大的扩展性和灵活性也使其成为开发企业级应用的理想平台。通过WordPress开发员工排班与考勤管理系统,企业可以享受以下优势:
- 成本效益:相比定制开发或购买专业软件,基于WordPress的解决方案成本更低
- 易于维护:WordPress拥有庞大的开发者社区和丰富的文档资源
- 高度可定制:可以根据企业具体需求进行灵活调整
- 集成能力:可与现有WordPress网站无缝集成,无需额外登录系统
本教程将详细指导您如何通过WordPress代码二次开发,创建一个功能完整的员工排班与考勤管理应用。
第一部分:开发环境准备与项目规划
1.1 开发环境搭建
在开始开发之前,我们需要准备合适的开发环境:
// 推荐开发环境配置
- WordPress版本:5.8或更高
- PHP版本:7.4或更高
- MySQL版本:5.6或更高
- 本地开发环境:XAMPP、MAMP或Local by Flywheel
- 代码编辑器:VS Code、PHPStorm或Sublime Text
1.2 创建自定义插件
为了避免主题更新导致功能丢失,我们将创建一个独立的插件:
<?php
/**
* Plugin Name: 员工排班与考勤管理系统
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站添加员工排班与考勤管理功能
* Version: 1.0.0
* Author: 您的姓名
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('EMP_SCHEDULE_VERSION', '1.0.0');
define('EMP_SCHEDULE_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('EMP_SCHEDULE_PLUGIN_URL', plugin_dir_url(__FILE__));
1.3 数据库表设计
我们需要创建几个数据库表来存储员工、排班和考勤数据:
// 在插件激活时创建数据库表
register_activation_hook(__FILE__, 'emp_schedule_create_tables');
function emp_schedule_create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 员工信息表
$employees_table = $wpdb->prefix . 'emp_employees';
$sql1 = "CREATE TABLE IF NOT EXISTS $employees_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
employee_id varchar(50) NOT NULL,
full_name varchar(100) NOT NULL,
department varchar(100),
position varchar(100),
hire_date date,
status varchar(20) DEFAULT 'active',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY employee_id (employee_id)
) $charset_collate;";
// 排班表
$schedules_table = $wpdb->prefix . 'emp_schedules';
$sql2 = "CREATE TABLE IF NOT EXISTS $schedules_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
employee_id mediumint(9) NOT NULL,
schedule_date date NOT NULL,
shift_start time NOT NULL,
shift_end time NOT NULL,
shift_type varchar(50),
notes text,
created_by bigint(20),
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY employee_date (employee_id, schedule_date)
) $charset_collate;";
// 考勤记录表
$attendance_table = $wpdb->prefix . 'emp_attendance';
$sql3 = "CREATE TABLE IF NOT EXISTS $attendance_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
employee_id mediumint(9) NOT NULL,
attendance_date date NOT NULL,
check_in datetime,
check_out datetime,
status varchar(50),
late_minutes int(11) DEFAULT 0,
overtime_minutes int(11) DEFAULT 0,
notes text,
verified_by bigint(20),
verified_at datetime,
PRIMARY KEY (id),
UNIQUE KEY employee_date (employee_id, attendance_date)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql1);
dbDelta($sql2);
dbDelta($sql3);
}
第二部分:员工管理模块开发
2.1 员工信息管理界面
创建员工管理后台页面,允许管理员添加、编辑和删除员工信息:
// 添加管理菜单
add_action('admin_menu', 'emp_schedule_admin_menu');
function emp_schedule_admin_menu() {
// 主菜单
add_menu_page(
'员工排班与考勤系统',
'员工考勤',
'manage_options',
'emp-schedule',
'emp_schedule_dashboard_page',
'dashicons-calendar-alt',
30
);
// 子菜单
add_submenu_page(
'emp-schedule',
'员工管理',
'员工管理',
'manage_options',
'emp-employees',
'emp_employees_page'
);
add_submenu_page(
'emp-schedule',
'排班管理',
'排班管理',
'manage_options',
'emp-schedules',
'emp_schedules_page'
);
add_submenu_page(
'emp-schedule',
'考勤记录',
'考勤记录',
'manage_options',
'emp-attendance',
'emp_attendance_page'
);
add_submenu_page(
'emp-schedule',
'报表统计',
'报表统计',
'manage_options',
'emp-reports',
'emp_reports_page'
);
}
// 员工管理页面
function emp_employees_page() {
global $wpdb;
// 处理表单提交
if (isset($_POST['add_employee'])) {
// 验证和清理数据
$employee_data = array(
'user_id' => intval($_POST['user_id']),
'employee_id' => sanitize_text_field($_POST['employee_id']),
'full_name' => sanitize_text_field($_POST['full_name']),
'department' => sanitize_text_field($_POST['department']),
'position' => sanitize_text_field($_POST['position']),
'hire_date' => sanitize_text_field($_POST['hire_date']),
'status' => sanitize_text_field($_POST['status'])
);
$table_name = $wpdb->prefix . 'emp_employees';
$wpdb->insert($table_name, $employee_data);
echo '<div class="notice notice-success"><p>员工添加成功!</p></div>';
}
// 获取员工列表
$employees_table = $wpdb->prefix . 'emp_employees';
$employees = $wpdb->get_results("SELECT * FROM $employees_table ORDER BY id DESC");
?>
<div class="wrap">
<h1 class="wp-heading-inline">员工管理</h1>
<a href="#add-employee-form" class="page-title-action">添加新员工</a>
<hr class="wp-header-end">
<!-- 员工列表 -->
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>员工ID</th>
<th>姓名</th>
<th>部门</th>
<th>职位</th>
<th>入职日期</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php if ($employees): ?>
<?php foreach ($employees as $employee): ?>
<tr>
<td><?php echo esc_html($employee->employee_id); ?></td>
<td><?php echo esc_html($employee->full_name); ?></td>
<td><?php echo esc_html($employee->department); ?></td>
<td><?php echo esc_html($employee->position); ?></td>
<td><?php echo esc_html($employee->hire_date); ?></td>
<td>
<span class="status-badge status-<?php echo esc_attr($employee->status); ?>">
<?php
$status_labels = array(
'active' => '在职',
'inactive' => '离职',
'on_leave' => '休假'
);
echo isset($status_labels[$employee->status]) ? $status_labels[$employee->status] : $employee->status;
?>
</span>
</td>
<td>
<a href="?page=emp-employees&action=edit&id=<?php echo $employee->id; ?>" class="button button-small">编辑</a>
<a href="?page=emp-employees&action=delete&id=<?php echo $employee->id; ?>" class="button button-small button-link-delete" onclick="return confirm('确定要删除此员工吗?')">删除</a>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="7" style="text-align:center;">暂无员工数据</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<!-- 添加员工表单 -->
<h2 id="add-employee-form">添加新员工</h2>
<form method="post" action="">
<table class="form-table">
<tr>
<th scope="row"><label for="employee_id">员工编号</label></th>
<td><input type="text" id="employee_id" name="employee_id" required class="regular-text"></td>
</tr>
<tr>
<th scope="row"><label for="full_name">姓名</label></th>
<td><input type="text" id="full_name" name="full_name" required class="regular-text"></td>
</tr>
<tr>
<th scope="row"><label for="department">部门</label></th>
<td>
<select id="department" name="department" class="regular-text">
<option value="">选择部门</option>
<option value="技术部">技术部</option>
<option value="市场部">市场部</option>
<option value="销售部">销售部</option>
<option value="人事部">人事部</option>
<option value="财务部">财务部</option>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="position">职位</label></th>
<td><input type="text" id="position" name="position" class="regular-text"></td>
</tr>
<tr>
<th scope="row"><label for="hire_date">入职日期</label></th>
<td><input type="date" id="hire_date" name="hire_date" class="regular-text"></td>
</tr>
<tr>
<th scope="row"><label for="status">状态</label></th>
<td>
<select id="status" name="status" class="regular-text">
<option value="active">在职</option>
<option value="inactive">离职</option>
<option value="on_leave">休假</option>
</select>
</td>
</tr>
</table>
<?php submit_button('添加员工', 'primary', 'add_employee'); ?>
</form>
</div>
<style>
.status-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
font-weight: bold;
}
.status-active {
background-color: #d4edda;
color: #155724;
}
.status-inactive {
background-color: #f8d7da;
color: #721c24;
}
.status-on_leave {
background-color: #fff3cd;
color: #856404;
}
</style>
<?php
}
2.2 员工数据导入导出功能
为了方便批量管理员工信息,我们添加导入导出功能:
// 添加上传处理功能
function emp_handle_employee_import() {
if (isset($_POST['import_employees']) && isset($_FILES['import_file'])) {
$file = $_FILES['import_file'];
if ($file['error'] === UPLOAD_ERR_OK) {
$file_type = wp_check_filetype($file['name']);
if ($file_type['ext'] === 'csv') {
$handle = fopen($file['tmp_name'], 'r');
$header = fgetcsv($handle); // 跳过标题行
global $wpdb;
$table_name = $wpdb->prefix . 'emp_employees';
$imported = 0;
$skipped = 0;
while (($data = fgetcsv($handle)) !== FALSE) {
if (count($data) >= 6) {
$employee_data = array(
'employee_id' => sanitize_text_field($data[0]),
'full_name' => sanitize_text_field($data[1]),
'department' => sanitize_text_field($data[2]),
'position' => sanitize_text_field($data[3]),
'hire_date' => sanitize_text_field($data[4]),
'status' => sanitize_text_field($data[5])
);
// 检查员工ID是否已存在
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name WHERE employee_id = %s",
$employee_data['employee_id']
));
if (!$existing) {
$wpdb->insert($table_name, $employee_data);
$imported++;
} else {
$skipped++;
}
}
}
fclose($handle);
echo '<div class="notice notice-success"><p>导入完成!成功导入 ' . $imported . ' 条记录,跳过 ' . $skipped . ' 条重复记录。</p></div>';
} else {
echo '<div class="notice notice-error"><p>请上传CSV格式的文件。</p></div>';
}
}
}
}
// 导出功能
function emp_export_employees_csv() {
if (isset($_GET['export_employees']) && $_GET['export_employees'] === '1') {
global $wpdb;
$table_name = $wpdb->prefix . 'emp_employees';
$employees = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=employees_' . date('Y-m-d') . '.csv');
$output = fopen('php://output', 'w');
// 添加BOM头,确保Excel正确识别UTF-8编码
fwrite($output, "xEFxBBxBF");
// 写入标题行
fputcsv($output, array('员工编号', '姓名', '部门', '职位', '入职日期', '状态'));
// 写入数据
foreach ($employees as $employee) {
fputcsv($output, array(
$employee['employee_id'],
$employee['full_name'],
$employee['department'],
$employee['position'],
$employee['hire_date'],
$employee['status']
));
}
fclose($output);
exit;
}
}
add_action('admin_init', 'emp_export_employees_csv');
第三部分:排班管理模块开发
3.1 排班日历视图
创建一个直观的日历界面来管理员工排班:
// 排班管理页面
function emp_schedules_page() {
global $wpdb;
// 获取当前月份
$current_month = isset($_GET['month']) ? $_GET['month'] : date('Y-m');
?>
<div class="wrap">
<h1 class="wp-heading-inline">排班管理</h1>
<a href="#add-schedule-form" class="page-title-action">添加排班</a>
<hr class="wp-header-end">
<!-- 月份导航 -->
<div class="month-navigation">
<?php
$prev_month = date('Y-m', strtotime($current_month . ' -1 month'));
$next_month = date('Y-m', strtotime($current_month . ' +1 month'));
?>
<a href="?page=emp-schedules&month=<?php echo $prev_month; ?>" class="button">← 上月</a>
<h2 style="display:inline-block; margin:0 20px;"><?php echo date('Y年m月', strtotime($current_month)); ?></h2>
<a href="?page=emp-schedules&month=<?php echo $next_month; ?>" class="button">下月 →</a>
</div>
<!-- 排班日历 -->
<div class="schedule-calendar">
<?php
// 生成日历
$year = date('Y', strtotime($current_month));
$month = date('m', strtotime($current_month));
$first_day = mktime(0, 0, 0, $month, 1, $year);
$days_in_month = date('t', $first_day);
$first_day_of_week = date('w', $first_day);
// 获取员工列表
$employees_table = $wpdb->prefix . 'emp_employees';
// 获取排班数据
$schedules_table = $wpdb->prefix . 'emp_schedules';
$schedules = $wpdb->get_results($wpdb->prepare(
"SELECT s.*, e.full_name
FROM $schedules_table s
LEFT JOIN $employees_table e ON s.employee_id = e.id
WHERE YEAR(schedule_date) = %d AND MONTH(schedule_date) = %d
ORDER BY schedule_date, shift_start",
$year, $month
));
// 按日期组织排班数据
$schedule_by_date = array();
foreach ($schedules as $schedule) {
$date = $schedule->schedule_date;
if (!isset($schedule_by_date[$date])) {
$schedule_by_date[$date] = array();
}
$schedule_by_date[$date][] = $schedule;
}
?>
<table class="widefat fixed schedule-calendar-table">
<thead>
<tr>
<th>周日</th>
<th>周一</th>
<th>周二</th>
<th>周三</th>
<th>周四</th>
<th>周五</th>
<th>周六</th>
</tr>
</thead>
<tbody>
<?php
$day_count = 1;
echo '<tr>';
// 填充第一个星期前的空白
for ($i = 0; $i < $first_day_of_week; $i++) {
echo '<td class="empty-day"></td>';
$day_count++;
}
// 填充日期
for ($day = 1; $day <= $days_in_month; $day++) {
$current_date = sprintf('%04d-%02d-%02d', $year, $month, $day);
$is_today = ($current_date == date('Y-m-d')) ? 'today' : '';
echo '<td class="calendar-day ' . $is_today . '">';
echo '<div class="day-number">' . $day . '</div>';
// 显示当天的排班
if (isset($schedule_by_date[$current_date])) {
echo '<div class="day-schedules">';
foreach ($schedule_by_date[$current_date] as $schedule) {
echo '<div class="schedule-item" data-id="' . $schedule->id . '">';
echo '<span class="employee-name">' . esc_html($schedule->full_name) . '</span>';
echo '<span class="shift-time">' . date('H:i', strtotime($schedule->shift_start)) . '-' . date('H:i', strtotime($schedule->shift_end)) . '</span>';
echo '</div>';
}
echo '</div>';
}
echo '</td>';
// 换行
if ($day_count % 7 == 0 && $day != $days_in_month) {
echo '</tr><tr>';
}
$day_count++;
}
// 填充最后一个星期后的空白
while ($day_count % 7 != 1) {
echo '<td class="empty-day"></td>';
$day_count++;
}
echo '</tr>';
?>
</tbody>
</table>
</div>
<!-- 添加排班表单 -->
<h2 id="add-schedule-form">添加排班</h2>
<form method="post" action="">
<table class="form-table">
<tr>
<th scope="row"><label for="employee_id">员工</label></th>
<td>
<select id="employee_id" name="employee_id" required class="regular-text">
<option value="">选择员工</option>
<?php foreach ($employees as $employee): ?>
<option value="<?php echo $employee->id; ?>">
<?php echo esc_html($employee->full_name . ' (' . $employee->employee_id . ')'); ?>
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="schedule_date">日期</label></th>
<td><input type="date" id="schedule_date" name="schedule_date" required class="regular-text" value="<?php echo date('Y-m-d'); ?>"></td>
</tr>
<tr>
<th scope="row"><label for="shift_start">上班时间</label></th>
<td><input type="time" id="shift_start" name="shift_start" required class="regular-text" value="09:00"></td>
</tr>
<tr>
<th scope="row"><label for="shift_end">下班时间</label></th>
<td><input type="time" id="shift_end" name="shift_end" required class="regular-text" value="18:00"></td>
</tr>
<tr>
<th scope="row"><label for="shift_type">班次类型</label></th>
<td>
<select id="shift_type" name="shift_type" class="regular-text">
<option value="normal">正常班</option>
<option value="morning">早班</option>
<option value="night">晚班</option>
<option value="overtime">加班</option>
<option value="weekend">周末班</option>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="notes">备注</label></th>
<td><textarea id="notes" name="notes" rows="3" class="regular-text"></textarea></td>
</tr>
</table>
<?php submit_button('添加排班', 'primary', 'add_schedule'); ?>
</form>
</div>
<style>
.schedule-calendar-table {
border-collapse: collapse;
margin: 20px 0;
}
.schedule-calendar-table th {
background-color: #f1f1f1;
text-align: center;
padding: 10px;
border: 1px solid #ddd;
}
.calendar-day {
height: 120px;
vertical-align: top;
border: 1px solid #ddd;
padding: 5px;
position: relative;
}
.calendar-day.today {
background-color: #e6f7ff;
}
.day-number {
font-weight: bold;
margin-bottom: 5px;
}
.day-schedules {
max-height: 90px;
overflow-y: auto;
}
.schedule-item {
background-color: #f0f8ff;
border-left: 3px solid #1890ff;
padding: 3px 5px;
margin-bottom: 3px;
font-size: 12px;
border-radius: 2px;
}
.schedule-item .employee-name {
display: block;
font-weight: bold;
}
.schedule-item .shift-time {
color: #666;
font-size: 11px;
}
.empty-day {
background-color: #f9f9f9;
border: 1px solid #ddd;
}
.month-navigation {
margin: 20px 0;
text-align: center;
}
</style>
<?php
}
3.2 批量排班功能
为了方便批量设置排班,我们添加批量排班功能:
// 批量排班功能
function emp_batch_schedule_form() {
?>
<div class="batch-schedule-form" style="margin: 20px 0; padding: 20px; background: #f9f9f9; border: 1px solid #ddd;">
<h3>批量排班设置</h3>
<form method="post" action="">
<table class="form-table">
<tr>
<th scope="row"><label for="batch_employees">选择员工</label></th>
<td>
<select id="batch_employees" name="batch_employees[]" multiple class="regular-text" style="height: 150px;">
<?php
global $wpdb;
$employees_table = $wpdb->prefix . 'emp_employees';
$employees = $wpdb->get_results("SELECT id, full_name, employee_id FROM $employees_table WHERE status = 'active' ORDER BY full_name");
foreach ($employees as $employee) {
echo '<option value="' . $employee->id . '">' . esc_html($employee->full_name . ' (' . $employee->employee_id . ')') . '</option>';
}
?>
</select>
<p class="description">按住Ctrl键可多选</p>
</td>
</tr>
<tr>
<th scope="row"><label for="batch_start_date">开始日期</label></th>
<td><input type="date" id="batch_start_date" name="batch_start_date" required class="regular-text" value="<?php echo date('Y-m-d'); ?>"></td>
</tr>
<tr>
<th scope="row"><label for="batch_end_date">结束日期</label></th>
<td><input type="date" id="batch_end_date" name="batch_end_date" required class="regular-text" value="<?php echo date('Y-m-d', strtotime('+7 days')); ?>"></td>
</tr>
<tr>
<th scope="row"><label for="batch_weekdays">工作日</label></th>
<td>
<label><input type="checkbox" name="batch_weekdays[]" value="1" checked> 周一</label>
<label><input type="checkbox" name="batch_weekdays[]" value="2" checked> 周二</label>
<label><input type="checkbox" name="batch_weekdays[]" value="3" checked> 周三</label>
<label><input type="checkbox" name="batch_weekdays[]" value="4" checked> 周四</label>
<label><input type="checkbox" name="batch_weekdays[]" value="5" checked> 周五</label>
<label><input type="checkbox" name="batch_weekdays[]" value="6"> 周六</label>
<label><input type="checkbox" name="batch_weekdays[]" value="0"> 周日</label>
</td>
</tr>
<tr>
<th scope="row"><label for="batch_shift_start">上班时间</label></th>
<td><input type="time" id="batch_shift_start" name="batch_shift_start" required class="regular-text" value="09:00"></td>
</tr>
<tr>
<th scope="row"><label for="batch_shift_end">下班时间</label></th>
<td><input type="time" id="batch_shift_end" name="batch_shift_end" required class="regular-text" value="18:00"></td>
</tr>
<tr>
<th scope="row"><label for="batch_shift_type">班次类型</label></th>
<td>
<select id="batch_shift_type" name="batch_shift_type" class="regular-text">
<option value="normal">正常班</option>
<option value="morning">早班</option>
<option value="night">晚班</option>
</select>
</td>
</tr>
</table>
<?php submit_button('批量设置排班', 'primary', 'batch_schedule'); ?>
</form>
</div>
<?php
}
// 处理批量排班
function emp_process_batch_schedule() {
if (isset($_POST['batch_schedule'])) {
global $wpdb;
$employees = $_POST['batch_employees'];
$start_date = $_POST['batch_start_date'];
$end_date = $_POST['batch_end_date'];
$weekdays = isset($_POST['batch_weekdays']) ? $_POST['batch_weekdays'] : array();
$shift_start = $_POST['batch_shift_start'];
$shift_end = $_POST['batch_shift_end'];
$shift_type = $_POST['batch_shift_type'];
$schedules_table = $wpdb->prefix . 'emp_schedules';
$current_user_id = get_current_user_id();
$start = new DateTime($start_date);
$end = new DateTime($end_date);
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end->modify('+1 day'));
$added_count = 0;
foreach ($period as $date) {
$weekday = $date->format('w'); // 0=周日, 1=周一...
if (in_array($weekday, $weekdays)) {
$schedule_date = $date->format('Y-m-d');
foreach ($employees as $employee_id) {
// 检查是否已有排班
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $schedules_table
WHERE employee_id = %d AND schedule_date = %s",
$employee_id, $schedule_date
));
if (!$existing) {
$wpdb->insert($schedules_table, array(
'employee_id' => $employee_id,
'schedule_date' => $schedule_date,
'shift_start' => $shift_start,
'shift_end' => $shift_end,
'shift_type' => $shift_type,
'created_by' => $current_user_id
));
$added_count++;
}
}
}
}
echo '<div class="notice notice-success"><p>批量排班完成!成功添加 ' . $added_count . ' 条排班记录。</p></div>';
}
}
第四部分:考勤管理模块开发
4.1 考勤打卡功能
创建员工考勤打卡界面:
// 添加快捷码支持
add_shortcode('emp_attendance_check', 'emp_attendance_check_shortcode');
function emp_attendance_check_shortcode() {
if (!is_user_logged_in()) {
return '<p>请先登录系统。</p>';
}
$user_id = get_current_user_id();
$today = date('Y-m-d');
// 获取员工信息
global $wpdb;
$employees_table = $wpdb->prefix . 'emp_employees';
$employee = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $employees_table WHERE user_id = %d",
$user_id
));
if (!$employee) {
return '<p>您不是注册员工,无法使用考勤功能。</p>';
}
// 获取今日排班
$schedules_table = $wpdb->prefix . 'emp_schedules';
$schedule = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $schedules_table
WHERE employee_id = %d AND schedule_date = %s",
$employee->id, $today
));
// 获取今日考勤记录
$attendance_table = $wpdb->prefix . 'emp_attendance';
$attendance = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $attendance_table
WHERE employee_id = %d AND attendance_date = %s",
$employee->id, $today
));
ob_start();
?>
<div class="emp-attendance-check">
<div class="attendance-header">
<h2>员工考勤打卡</h2>
<div class="employee-info">
<p><strong>员工:</strong> <?php echo esc_html($employee->full_name); ?></p>
<p><strong>日期:</strong> <?php echo date('Y年m月d日'); ?></p>
<p><strong>时间:</strong> <span id="current-time"><?php echo date('H:i:s'); ?></span></p>
</div>
</div>
<?php if ($schedule): ?>
<div class="schedule-info">
<h3>今日排班信息</h3>
<p><strong>上班时间:</strong> <?php echo date('H:i', strtotime($schedule->shift_start)); ?></p>
<p><strong>下班时间:</strong> <?php echo date('H:i', strtotime($schedule->shift_end)); ?></p>
<p><strong>班次类型:</strong> <?php echo esc_html($schedule->shift_type); ?></p>
</div>
<?php else: ?>
<div class="notice notice-warning">
<p>今日无排班安排。</p>
</div>
<?php endif; ?>
<div class="attendance-actions">
<?php if (!$attendance || !$attendance->check_in): ?>
<form method="post" action="" class="checkin-form">
<input type="hidden" name="action" value="check_in">
<input type="hidden" name="employee_id" value="<?php echo $employee->id; ?>">
<button type="submit" class="button button-primary button-large" name="check_in">
<span class="dashicons dashicons-clock"></span> 上班打卡
</button>
<p class="description">上班时间: <?php echo $schedule ? date('H:i', strtotime($schedule->shift_start)) : '无排班'; ?></p>
</form>
<?php elseif ($attendance && $attendance->check_in && !$attendance->check_out): ?>
<div class="checked-in-info">
<p class="checked-in-time">上班打卡时间: <?php echo date('H:i:s', strtotime($attendance->check_in)); ?></p>
<?php
// 计算是否迟到
if ($schedule) {
$check_in_time = strtotime($attendance->check_in);
