首页 / 应用软件 / 详细教程,为WordPress网站开发员工排班与考勤管理应用

详细教程,为WordPress网站开发员工排班与考勤管理应用

WordPress网站员工排班与考勤管理应用开发详细教程

引言:为什么选择WordPress开发企业应用?

在当今数字化时代,企业管理系统正逐渐从传统的桌面软件转向基于Web的解决方案。WordPress作为全球最流行的内容管理系统,不仅适用于博客和内容网站,其强大的扩展性和灵活性也使其成为开发企业级应用的理想平台。通过WordPress开发员工排班与考勤管理系统,企业可以享受以下优势:

  1. 成本效益:相比定制开发或购买专业软件,基于WordPress的解决方案成本更低
  2. 易于维护:WordPress拥有庞大的开发者社区和丰富的文档资源
  3. 高度可定制:可以根据企业具体需求进行灵活调整
  4. 集成能力:可与现有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">&larr; 上月</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">下月 &rarr;</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);
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5204.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部