You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress对接Google Calendar实现简易班次预约系统的方案咨询

极简班次预约工具实现方案

前期准备

  • 开通Google Cloud账号,创建新项目后启用Google Calendar API,生成服务账号密钥(JSON格式),记录服务账号对应的邮箱地址
  • 打开你要同步的目标Google Calendar的日历设置,在共享权限中添加上述服务账号邮箱,授予编辑权限,否则无法写入预约事件
  • 记录目标日历的ID,后续API调用会用到
  • 确认WordPress站点的时区与Google Calendar的时区保持一致,避免出现时间偏移问题

核心功能实现

所有代码可以直接写在当前主题的functions.php文件中,或者单独封装为自定义插件使用。

1. 接入Google Calendar API

引入Google官方API客户端,你可以通过Composer安装,也可以直接引入官方打包好的phar文件。封装获取日历忙碌时段的函数:

function get_google_busy_slots($start_time, $end_time) {
    // 加载服务账号密钥
    $client = new Google_Client();
    $client->setApplicationName('Shift Booking');
    $client->setScopes(Google_Service_Calendar::CALENDAR);
    $client->setAuthConfig('你的服务账号密钥文件路径');
    $service = new Google_Service_Calendar($client);
    
    // 查询忙碌时段
    $freebusy_req = new Google_Service_Calendar_FreeBusyRequest();
    $freebusy_req->setTimeMin($start_time->format(DateTime::RFC3339));
    $freebusy_req->setTimeMax($end_time->format(DateTime::RFC3339));
    $item = new Google_Service_Calendar_FreeBusyRequestItem();
    $item->setId('你的目标日历ID');
    $freebusy_req->setItems([$item]);
    $response = $service->freebusy->query($freebusy_req);
    
    $calendars = $response->getCalendars();
    $busy_slots = $calendars['你的目标日历ID']->getBusy();
    return $busy_slots;
}

2. 生成可用班次列表

封装函数生成指定天数内的可选班次:

function get_available_shifts($days = 14) {
    $now = new DateTime();
    $end_date = (clone $now)->modify("+{$days} days");
    $busy_slots = get_google_busy_slots($now, $end_date);
    $available = [];
    
    for ($i = 0; $i < $days; $i++) {
        $current_date = (clone $now)->modify("+{$i} days");
        $weekday = $current_date->format('N');
        // 判断是工作日还是周末,设置对应时段
        if ($weekday >=1 && $weekday <=5) {
            $shift_start = (clone $current_date)->setTime(17,0,0);
            $shift_end = (clone $current_date)->setTime(20,0,0);
        } else {
            $shift_start = (clone $current_date)->setTime(10,0,0);
            $shift_end = (clone $current_date)->setTime(13,0,0);
        }
        // 排除已过去的时段
        if ($shift_start < $now) continue;
        // 检查是否和忙碌时段重叠
        $is_busy = false;
        foreach ($busy_slots as $slot) {
            $b_start = new DateTime($slot->start);
            $b_end = new DateTime($slot->end);
            if (($shift_start < $b_end) && ($shift_end > $b_start)) {
                $is_busy = true;
                break;
            }
        }
        if (!$is_busy) {
            $available[] = [
                'start' => $shift_start->format('Y-m-d H:i:s'),
                'end' => $shift_end->format('Y-m-d H:i:s'),
                'label' => $shift_start->format('Y-m-d H:i') . ' - ' . $shift_end->format('H:i')
            ];
        }
    }
    return $available;
}

3. 注册预约短代码

注册短代码用于前端展示预约界面,不需要自定义页面模板的话直接在任意页面插入短代码即可使用:

add_shortcode('booking_shift', 'render_booking_shift');
function render_booking_shift() {
    if (!is_user_logged_in()) {
        return '<p>请先登录后再进行预约</p>';
    }
    $shifts = get_available_shifts();
    if (empty($shifts)) {
        return '<p>当前暂无可用班次,请稍后再试</p>';
    }
    // 输出预约表单
    $html = '<form method="post" action="' . admin_url('admin-post.php') . '">';
    $html .= wp_nonce_field('booking_shift_action', 'booking_nonce', true, false);
    $html .= '<input type="hidden" name="action" value="submit_booking">';
    $html .= '<label>选择可用班次:</label>';
    $html .= '<select name="selected_shift" required>';
    foreach ($shifts as $index => $shift) {
        $html .= '<option value="'.$index.'">'.$shift['label'].'</option>';
    }
    $html .= '</select>';
    $html .= '<button type="submit">确认预约</button>';
    $html .= '</form>';
    return $html;
}

4. 处理预约提交逻辑

绑定钩子处理表单提交,自动同步事件到Google Calendar:

add_action('admin_post_submit_booking', 'handle_booking_submit');
add_action('admin_post_nopriv_submit_booking', 'handle_booking_submit');
function handle_booking_submit() {
    // 校验登录状态和请求合法性
    if (!is_user_logged_in() || !wp_verify_nonce($_POST['booking_nonce'], 'booking_shift_action')) {
        wp_redirect(wp_get_referer() . '?booking_status=error');
        exit;
    }
    // 获取可用班次列表,校验选中班次合法性
    $shifts = get_available_shifts();
    $selected_index = intval($_POST['selected_shift']);
    if (!isset($shifts[$selected_index])) {
        wp_redirect(wp_get_referer() . '?booking_status=invalid');
        exit;
    }
    $selected_shift = $shifts[$selected_index];
    $current_user = wp_get_current_user();
    $event_name = $current_user->display_name; // 直接取用户资料的全名,用户无法修改
    
    // 调用Google Calendar API插入事件
    $client = new Google_Client();
    $client->setAuthConfig('你的服务账号密钥文件路径');
    $client->setScopes(Google_Service_Calendar::CALENDAR);
    $service = new Google_Service_Calendar($client);
    
    $event = new Google_Service_Calendar_Event([
        'summary' => $event_name,
        'start' => ['dateTime' => (new DateTime($selected_shift['start']))->format(DateTime::RFC3339)],
        'end' => ['dateTime' => (new DateTime($selected_shift['end']))->format(DateTime::RFC3339)],
        'transparency' => 'opaque' // 标记为忙碌状态
    ]);
    
    try {
        $service->events->insert('你的目标日历ID', $event);
        wp_redirect(wp_get_referer() . '?booking_status=success');
    } catch (Exception $e) {
        wp_redirect(wp_get_referer() . '?booking_status=fail');
    }
    exit;
}

可选调整

  • 如果需要用日历组件展示班次,可在短代码输出部分引入轻量日历JS库,将可用班次标注为可点击选项,无需用户下拉选择
  • 可在页面中添加状态判断,根据URL的booking_status参数展示对应成功/失败提示
  • 可添加用户预约次数限制,避免恶意占用班次

内容的提问来源于stack exchange,提问作者user17604307

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:06:05