本文目录导读:

我来给你介绍几种 PHP 排班通知的实现方案,根据你的需求复杂度来选择:
简单轮班制(最基础)
<?php
class SimpleShiftScheduler {
private $employees = ['张三', '李四', '王五', '赵六'];
private $shifts = ['早班', '中班', '晚班'];
public function generateWeeklySchedule($startDate) {
$schedule = [];
$shiftIndex = 0;
$employeeIndex = 0;
for ($i = 0; $i < 7; $i++) {
$date = date('Y-m-d', strtotime("$startDate + $i days"));
$schedule[$date] = [
'employee' => $this->employees[$employeeIndex % count($this->employees)],
'shift' => $this->shifts[$shiftIndex % count($this->shifts)]
];
$shiftIndex++;
$employeeIndex = (int)($shiftIndex / 2);
}
return $schedule;
}
}
数据库驱动排班系统
<?php
class DatabaseScheduler {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
// 生成排班表
public function generateSchedule($startDate, $endDate, $shiftPattern = [0,1,2,0,1,2]) {
$sql = "INSERT INTO schedules (employee_id, shift_date, shift_type, created_at) VALUES (?, ?, ?, NOW())";
$stmt = $this->pdo->prepare($sql);
$employees = $this->getAvailableEmployees();
$currentDate = $startDate;
while ($currentDate <= $endDate) {
foreach ($employees as $key => $employee) {
$shiftIndex = date('N', strtotime($currentDate)) - 1;
$shiftType = $this->getShiftType($employee['id'], $currentDate);
// 检查是否有请假或不可用
if (!$this->isEmployeeAvailable($employee['id'], $currentDate)) {
continue;
}
// 分配班次
$stmt->execute([
$employee['id'],
$currentDate,
$shiftType
]);
}
$currentDate = date('Y-m-d', strtotime($currentDate . ' +1 day'));
}
return $this->getSchedule($startDate, $endDate);
}
// 发送排班通知
public function sendScheduleNotification($scheduleId) {
$schedule = $this->getScheduleById($scheduleId);
if (!$schedule) {
return ['success' => false, 'message' => '排班记录不存在'];
}
// 获取员工联系方式
$employee = $this->getEmployeeContact($schedule['employee_id']);
// 发送短信通知
$smsResult = $this->sendSMSNotification(
$employee['phone'],
"您的排班通知:{$schedule['shift_date']} {$schedule['shift_type']},请准时到岗"
);
// 发送邮件通知(可选)
if (!empty($employee['email'])) {
$this->sendEmailNotification(
$employee['email'],
'排班通知',
$this->formatEmailContent($schedule)
);
}
return ['success' => true];
}
// 批量发送通知
public function sendBulkNotifications($date) {
$schedules = $this->getSchedulesByDate($date);
$results = [];
foreach ($schedules as $schedule) {
$results[] = [
'employee' => $schedule['employee_name'],
'result' => $this->sendScheduleNotification($schedule['id'])
];
}
return $results;
}
private function sendSMSNotification($phone, $message) {
// 使用短信服务商API,如阿里云、腾讯云等
$api = new SmsService();
return $api->send($phone, $message);
}
private function sendEmailNotification($email, $subject, $content) {
// 使用PHP Mailer或第三方邮件服务
$mail = new PHPMailer();
$mail->addAddress($email);
$mail->Subject = $subject;
$mail->Body = $content;
return $mail->send();
}
}
高级智能排班(带规则约束)
<?php
class SmartScheduler {
private $rules = [];
private $employeeAvailability = [];
// 添加排班规则
public function addRule($ruleName, $callback) {
$this->rules[$ruleName] = $callback;
}
// 设置员工可用时间
public function setEmployeeAvailability($employeeId, $availability) {
$this->employeeAvailability[$employeeId] = $availability;
}
// 生成最优排班方案
public function generateOptimalSchedule($startDate, $days, $shiftsPerDay) {
$schedule = [];
$allEmployees = $this->getAllEmployees();
for ($i = 0; $i < $days; $i++) {
$date = date('Y-m-d', strtotime("$startDate + $i days"));
$dailySchedule = [];
for ($shift = 0; $shift < $shiftsPerDay; $shift++) {
$candidates = $this->findCandidates($date, $shift, $allEmployees);
if ($candidates) {
// 按优先级选择最佳人选
$selected = $this->selectBestCandidate($candidates, [
'date' => $date,
'shift' => $shift,
'schedule' => $schedule
]);
$dailySchedule[] = [
'date' => $date,
'shift' => $shift,
'employee' => $selected,
'status' => 'confirmed'
];
}
}
$schedule[] = $dailySchedule;
}
return $schedule;
}
private function findCandidates($date, $shift, $employees) {
$candidates = [];
foreach ($employees as $employee) {
// 检查员工是否可用
if (!$this->isAvailable($employee['id'], $date, $shift)) {
continue;
}
// 检查连续工作天数
if ($this->hasOverwork($employee['id'], $date)) {
continue;
}
// 计算推荐分数
$score = $this->calculateScore($employee, $date, $shift);
$candidates[] = array_merge($employee, ['score' => $score]);
}
// 按分数排序
usort($candidates, function($a, $b) {
return $b['score'] <=> $a['score'];
});
return $candidates;
}
private function calculateScore($employee, $date, $shift) {
$score = 100; // 基础分
// 根据历史出勤率加分
$attendanceRate = $this->getAttendanceRate($employee['id']);
$score += $attendanceRate * 10;
// 技能匹配加分
if ($this->hasRequiredSkill($employee['id'], $shift)) {
$score += 20;
}
// 连续工作扣分
$consecutiveDays = $this->getConsecutiveWorkDays($employee['id']);
$score -= $consecutiveDays * 5;
// 加班扣分
if ($this->isOvertime($employee['id'], $date)) {
$score -= 15;
}
// 员工偏好加分
$preference = $this->getShiftPreference($employee['id']);
if ($preference == $shift) {
$score += 10;
}
return $score;
}
private function isAvailable($employeeId, $date, $shift) {
// 检查员工是否被设置为不可用
if (!isset($this->employeeAvailability[$employeeId])) {
return true;
}
$availability = $this->employeeAvailability[$employeeId];
$dayOfWeek = date('N', strtotime($date));
return isset($availability[$dayOfWeek][$shift])
&& $availability[$dayOfWeek][$shift] === true;
}
}
发送通知的完整实现
<?php
class ScheduleNotifier {
private $scheduleData;
public function __construct($scheduleData) {
$this->scheduleData = $scheduleData;
}
public function notifyViaMultipleChannels() {
$notifications = [];
foreach ($this->scheduleData as $schedule) {
$channels = $this->getPreferredChannels($schedule['employee_id']);
foreach ($channels as $channel) {
$result = $this->sendViaChannel($channel, $schedule);
$notifications[] = [
'employee' => $schedule['employee_name'],
'channel' => $channel,
'status' => $result ? 'success' : 'failed',
'timestamp' => date('Y-m-d H:i:s')
];
}
}
return $notifications;
}
private function sendViaChannel($channel, $schedule) {
$message = $this->formatScheduleMessage($schedule);
switch ($channel) {
case 'wechat':
return $this->sendWechatMessage($schedule['wechat_id'], $message);
case 'sms':
return $this->sendSMS($schedule['phone'], $message);
case 'email':
return $this->sendEmail($schedule['email'], '排班通知', $message);
case 'app_notification':
return $this->sendAppNotification($schedule['user_id'], $message);
default:
return false;
}
}
private function formatScheduleMessage($schedule) {
return sprintf(
"【排班通知】%s\n员工:%s\n班次:%s\n时间:%s-%s\n备注:%s\n请准时到岗,如有问题请提前联系管理人员。",
$schedule['shift_date'],
$schedule['employee_name'],
$schedule['shift_type'],
$schedule['start_time'],
$schedule['end_time'],
$schedule['remarks'] ?? '无'
);
}
// 微信通知(通过企业微信/公众号)
private function sendWechatMessage($openId, $message) {
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
$data = [
'touser' => $openId,
'template_id' => 'YOUR_TEMPLATE_ID',
'data' => [
'content' => ['value' => $message]
]
];
return $this->curlPost($url, json_encode($data));
}
// 手机短信
private function sendSMS($phone, $message) {
// 使用阿里云短信或腾讯云短信
$config = [
'access_key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET',
'sign_name' => '你的签名',
'template_code' => 'SMS_12345678'
];
$sms = new AliyunSms();
return $sms->send($phone, $message, $config);
}
// 邮件通知
private function sendEmail($to, $subject, $content) {
$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'your-email@example.com';
$mail->Password = 'your-password';
$mail->setFrom('from@example.com', '排班系统');
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->Body = $content;
return $mail->send();
}
// APP推送(使用极光推送等)
private function sendAppNotification($userId, $message) {
$jpush = new JPush('app_key', 'master_secret');
return $jpush->push()
->setPlatform('ios', 'android')
->addAlias($userId)
->setNotificationAlert($message)
->send();
}
}
使用示例
<?php
// 初始化排班系统
$scheduler = new SmartScheduler();
// 设置规则
$scheduler->addRule('max_consecutive_days', function($employeeId) {
// 最多连续工作5天
return $this->getConsecutiveWorkDays($employeeId) < 5;
});
// 设置员工可用时间
$scheduler->setEmployeeAvailability(1, [
1 => [true, true, true], // 周一所有班次
2 => [true, false, true], // 周二中班不排
// ...
]);
// 生成下周排班
$startDate = date('Y-m-d', strtotime('next Monday'));
$schedule = $scheduler->generateOptimalSchedule($startDate, 7, 3);
// 发送通知
$notifier = new ScheduleNotifier($schedule);
$results = $notifier->notifyViaMultipleChannels();
// 记录日志
foreach ($results as $result) {
echo "通知 {$result['employee']} 成功,渠道:{$result['channel']}\n";
}
推荐使用第三方案例
如果你不想从零开发,可以查看这些开源项目:
- SimpleSchedule - 轻量级排班系统
- ShiftScheduler - 支持多种班次类型
- SmartRota - 智能排班+通知
需要完整项目代码或者有其他功能需求(比如请假管理、调班申请等),我可以帮你进一步完善!
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播