文章目录
-
- 在当今数字营销时代,网站互动功能已成为提升用户参与度和转化率的关键因素。活动倒计时与预约提醒功能作为常见的互联网小工具,能够有效创造紧迫感,提高用户参与活动的积极性。对于电商网站,倒计时可以促进限时抢购;对于活动策划网站,预约提醒能确保参与者不会错过重要事件。 WordPress作为全球最流行的内容管理系统,其强大的可扩展性使得开发者可以通过代码二次开发实现各种定制功能。本教程将详细指导您如何为WordPress网站开发活动倒计时与预约提醒功能,无需依赖昂贵的插件,完全通过自主代码实现。
-
- 在开始开发之前,请确保您的WordPress环境满足以下条件: WordPress版本5.0或更高 PHP版本7.4或更高(推荐8.0+) MySQL 5.6或更高版本 已安装并激活一个支持子主题的WordPress主题
- 为了避免主题更新导致功能丢失,我们建议创建一个独立的功能插件: 在wp-content/plugins/目录下创建新文件夹event-countdown-manager 在该文件夹中创建主插件文件event-countdown-manager.php 添加插件头部信息: <?php /** * Plugin Name: 活动倒计时与预约提醒管理器 * Plugin URI: https://yourwebsite.com/ * Description: 为WordPress网站添加活动倒计时与预约提醒功能 * Version: 1.0.0 * Author: 您的名称 * License: GPL v2 or later * Text Domain: event-countdown-manager */
- 我们需要创建两个数据库表来存储活动信息和用户预约数据。在插件激活时创建这些表: // 创建数据库表 function ecm_create_database_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $events_table = $wpdb->prefix . 'ecm_events'; $bookings_table = $wpdb->prefix . 'ecm_bookings'; // 活动表SQL $events_sql = "CREATE TABLE IF NOT EXISTS $events_table ( event_id INT(11) NOT NULL AUTO_INCREMENT, event_title VARCHAR(255) NOT NULL, event_description TEXT, event_start DATETIME NOT NULL, event_end DATETIME NOT NULL, countdown_enabled TINYINT(1) DEFAULT 1, reminder_enabled TINYINT(1) DEFAULT 1, max_participants INT(11) DEFAULT 0, current_participants INT(11) DEFAULT 0, status ENUM('active', 'inactive', 'completed') DEFAULT 'active', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (event_id) ) $charset_collate;"; // 预约表SQL $bookings_sql = "CREATE TABLE IF NOT EXISTS $bookings_table ( booking_id INT(11) NOT NULL AUTO_INCREMENT, event_id INT(11) NOT NULL, user_id INT(11), user_name VARCHAR(255), user_email VARCHAR(255) NOT NULL, user_phone VARCHAR(50), reminder_sent TINYINT(1) DEFAULT 0, booking_time DATETIME DEFAULT CURRENT_TIMESTAMP, status ENUM('confirmed', 'pending', 'cancelled') DEFAULT 'confirmed', PRIMARY KEY (booking_id), FOREIGN KEY (event_id) REFERENCES $events_table(event_id) ON DELETE CASCADE ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($events_sql); dbDelta($bookings_sql); } register_activation_hook(__FILE__, 'ecm_create_database_tables');
-
- 为管理员添加活动管理界面: // 添加管理菜单 function ecm_add_admin_menu() { add_menu_page( '活动倒计时管理', '活动管理', 'manage_options', 'ecm-events', 'ecm_events_admin_page', 'dashicons-calendar-alt', 30 ); add_submenu_page( 'ecm-events', '添加新活动', '添加新活动', 'manage_options', 'ecm-add-event', 'ecm_add_event_page' ); add_submenu_page( 'ecm-events', '预约管理', '预约管理', 'manage_options', 'ecm-bookings', 'ecm_bookings_admin_page' ); } add_action('admin_menu', 'ecm_add_admin_menu');
- 创建活动列表显示与管理页面: function ecm_events_admin_page() { global $wpdb; $events_table = $wpdb->prefix . 'ecm_events'; // 处理删除操作 if (isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['event_id'])) { $event_id = intval($_GET['event_id']); $wpdb->delete($events_table, array('event_id' => $event_id)); echo '<div class="notice notice-success"><p>活动已删除</p></div>'; } // 获取所有活动 $events = $wpdb->get_results("SELECT * FROM $events_table ORDER BY event_start DESC"); ?> <div class="wrap"> <h1 class="wp-heading-inline">活动管理</h1> <a href="<?php echo admin_url('admin.php?page=ecm-add-event'); ?>" class="page-title-action">添加新活动</a> <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 (empty($events)): ?> <tr> <td colspan="7" style="text-align: center;">暂无活动</td> </tr> <?php else: ?> <?php foreach ($events as $event): ?> <tr> <td><?php echo $event->event_id; ?></td> <td><?php echo esc_html($event->event_title); ?></td> <td><?php echo date('Y-m-d H:i', strtotime($event->event_start)); ?></td> <td><?php echo date('Y-m-d H:i', strtotime($event->event_end)); ?></td> <td><?php echo $event->current_participants . '/' . $event->max_participants; ?></td> <td> <?php $status_labels = array( 'active' => '<span class="dashicons dashicons-yes-alt" style="color:green"></span> 进行中', 'inactive' => '<span class="dashicons dashicons-no" style="color:red"></span> 未激活', 'completed' => '<span class="dashicons dashicons-yes" style="color:blue"></span> 已结束' ); echo $status_labels[$event->status]; ?> </td> <td> <a href="<?php echo admin_url('admin.php?page=ecm-add-event&event_id=' . $event->event_id); ?>">编辑</a> | <a href="<?php echo admin_url('admin.php?page=ecm-events&action=delete&event_id=' . $event->event_id); ?>" onclick="return confirm('确定删除此活动吗?')">删除</a> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> <?php }
- 创建活动添加与编辑表单: function ecm_add_event_page() { global $wpdb; $events_table = $wpdb->prefix . 'ecm_events'; $event_id = isset($_GET['event_id']) ? intval($_GET['event_id']) : 0; $event = null; if ($event_id > 0) { $event = $wpdb->get_row($wpdb->prepare("SELECT * FROM $events_table WHERE event_id = %d", $event_id)); } // 处理表单提交 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ecm_event_nonce'])) { if (!wp_verify_nonce($_POST['ecm_event_nonce'], 'ecm_save_event')) { die('安全验证失败'); } $event_data = array( 'event_title' => sanitize_text_field($_POST['event_title']), 'event_description' => wp_kses_post($_POST['event_description']), 'event_start' => sanitize_text_field($_POST['event_start']), 'event_end' => sanitize_text_field($_POST['event_end']), 'countdown_enabled' => isset($_POST['countdown_enabled']) ? 1 : 0, 'reminder_enabled' => isset($_POST['reminder_enabled']) ? 1 : 0, 'max_participants' => intval($_POST['max_participants']), 'status' => sanitize_text_field($_POST['status']) ); if ($event_id > 0) { $wpdb->update($events_table, $event_data, array('event_id' => $event_id)); $message = '活动已更新'; } else { $wpdb->insert($events_table, $event_data); $event_id = $wpdb->insert_id; $message = '活动已创建'; } echo '<div class="notice notice-success"><p>' . $message . '</p></div>'; $event = $wpdb->get_row($wpdb->prepare("SELECT * FROM $events_table WHERE event_id = %d", $event_id)); } ?> <div class="wrap"> <h1><?php echo $event_id > 0 ? '编辑活动' : '添加新活动'; ?></h1> <form method="post" action=""> <?php wp_nonce_field('ecm_save_event', 'ecm_event_nonce'); ?> <table class="form-table"> <tr> <th><label for="event_title">活动标题</label></th> <td> <input type="text" id="event_title" name="event_title" class="regular-text" value="<?php echo $event ? esc_attr($event->event_title) : ''; ?>" required> </td> </tr> <tr> <th><label for="event_description">活动描述</label></th> <td> <?php $description = $event ? $event->event_description : ''; wp_editor($description, 'event_description', array( 'textarea_name' => 'event_description', 'media_buttons' => false, 'textarea_rows' => 5 )); ?> </td> </tr> <tr> <th><label for="event_start">开始时间</label></th> <td> <input type="datetime-local" id="event_start" name="event_start" value="<?php echo $event ? date('Y-m-dTH:i', strtotime($event->event_start)) : ''; ?>" required> </td> </tr> <tr> <th><label for="event_end">结束时间</label></th> <td> <input type="datetime-local" id="event_end" name="event_end" value="<?php echo $event ? date('Y-m-dTH:i', strtotime($event->event_end)) : ''; ?>" required> </td> </tr> <tr> <th>功能设置</th> <td> <label> <input type="checkbox" name="countdown_enabled" value="1" <?php echo ($event && $event->countdown_enabled) ? 'checked' : ''; ?>> 启用倒计时 </label> <br> <label> <input type="checkbox" name="reminder_enabled" value="1" <?php echo ($event && $event->reminder_enabled) ? 'checked' : ''; ?>> 启用预约提醒 </label> </td> </tr> <tr> <th><label for="max_participants">最大参与人数</label></th> <td> <input type="number" id="max_participants" name="max_participants" min="0" value="<?php echo $event ? $event->max_participants : '0'; ?>"> <p class="description">0表示不限制人数</p> </td> </tr> <tr> <th><label for="status">状态</label></th> <td> <select id="status" name="status"> <option value="active" <?php echo ($event && $event->status == 'active') ? 'selected' : ''; ?>>进行中</option> <option value="inactive" <?php echo ($event && $event->status == 'inactive') ? 'selected' : ''; ?>>未激活</option> <option value="completed" <?php echo ($event && $event->status == 'completed') ? 'selected' : ''; ?>>已结束</option> </select> </td> </tr> </table> <p class="submit"> <input type="submit" class="button button-primary" value="保存活动"> <a href="<?php echo admin_url('admin.php?page=ecm-events'); ?>" class="button">返回列表</a> </p> </form> </div> <?php }
-
- 创建短代码以便在文章或页面中插入倒计时: // 注册倒计时短代码 function ecm_countdown_shortcode($atts) { global $wpdb; $atts = shortcode_atts(array( 'event_id' => 0, 'title' => '活动倒计时', 'show_description' => true, 'style' => 'default' ), $atts); $event_id = intval($atts['event_id']); $events_table = $wpdb->prefix . 'ecm_events'; if ($event_id === 0) { // 获取最近的活动 $event = $wpdb->get_row("SELECT * FROM $events_table WHERE status = 'active' AND event_end > NOW() ORDER BY event_start LIMIT 1"); } else { $event = $wpdb->get_row($wpdb->prepare("SELECT * FROM $events_table WHERE event_id = %d", $event_id)); } if (!$event || $event->countdown_enabled != 1) { return '<p>暂无活动或倒计时未启用</p>'; } // 生成唯一ID用于JavaScript $countdown_id = 'ecm-countdown-' . uniqid(); ob_start(); ?> <div class="ecm-countdown-container ecm-style-<?php echo esc_attr($atts['style']); ?>" id="<?php echo $countdown_id; ?>"> <div class="ecm-countdown-header"> <h3><?php echo esc_html($atts['title']); ?></h3> <h4><?php echo esc_html($event->event_title); ?></h4> </div> <?php if ($atts['show_description'] && !empty($event->event_description)): ?> <div class="ecm-countdown-description"> <?php echo wpautop($event->event_description); ?> </div> <?php endif; ?> <div class="ecm-countdown-timer"> <div class="ecm-countdown-item"> <span class="ecm-countdown-number ecm-days">00</span> <span class="ecm-countdown-label">天</span> </div> <div class="ecm-countdown-separator">:</div> <div class="ecm-countdown-item"> <span class="ecm-countdown-number ecm-hours">00</span> <span class="ecm-countdown-label">时</span> </div> <div class="ecm-countdown-separator">:</div> <div class="ecm-countdown-item"> <span class="ecm-countdown-number ecm-minutes">00</span> <span class="ecm-countdown-label">分</span> </div> <div class="ecm-countdown-separator">:</div> <div class="ecm-countdown-item"> <span class="ecm-countdown-number ecm-seconds">00</span> <span class="ecm-countdown-label">秒</span> </div> </div> <div class="ecm-countdown-message"></div> <?php if ($event->reminder_enabled): ?> <div class="ecm-reminder-section"> <button class="ecm-reminder-btn" data-event-id="<?php echo $event->event_id; ?>"> 设置活动提醒 </button> </div> <?php endif; ?>
- 继续在短代码函数中添加JavaScript代码: <script> (function() { var countdownElement = document.getElementById('<?php echo $countdown_id; ?>'); var eventEndTime = new Date('<?php echo $event->event_end; ?>').getTime(); function updateCountdown() { var now = new Date().getTime(); var timeRemaining = eventEndTime - now; if (timeRemaining < 0) { countdownElement.querySelector('.ecm-countdown-message').innerHTML = '<p class="ecm-countdown-ended">活动已结束</p>'; countdownElement.querySelector('.ecm-countdown-timer').style.display = 'none'; return; } var days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24)); var hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); var minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60)); var seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000); // 更新显示 countdownElement.querySelector('.ecm-days').textContent = days.toString().padStart(2, '0'); countdownElement.querySelector('.ecm-hours').textContent = hours.toString().padStart(2, '0'); countdownElement.querySelector('.ecm-minutes').textContent = minutes.toString().padStart(2, '0'); countdownElement.querySelector('.ecm-seconds').textContent = seconds.toString().padStart(2, '0'); // 动态样式变化 if (days === 0 && hours < 24) { countdownElement.classList.add('ecm-countdown-urgent'); } if (days === 0 && hours < 1) { countdownElement.classList.add('ecm-countdown-critical'); } } // 初始更新 updateCountdown(); // 每秒更新 var countdownInterval = setInterval(updateCountdown, 1000); // 预约提醒按钮事件 var reminderBtn = countdownElement.querySelector('.ecm-reminder-btn'); if (reminderBtn) { reminderBtn.addEventListener('click', function() { var eventId = this.getAttribute('data-event-id'); ecmShowReminderModal(eventId); }); } })(); </script> <div class="ecm-reminder-modal" style="display: none;"> <div class="ecm-modal-content"> <span class="ecm-close-modal">×</span> <h3>设置活动提醒</h3> <form id="ecm-reminder-form"> <input type="hidden" name="event_id" value="<?php echo $event->event_id; ?>"> <div class="ecm-form-group"> <label for="ecm-user-name">姓名</label> <input type="text" id="ecm-user-name" name="user_name" required> </div> <div class="ecm-form-group"> <label for="ecm-user-email">邮箱</label> <input type="email" id="ecm-user-email" name="user_email" required> </div> <div class="ecm-form-group"> <label for="ecm-user-phone">手机号(可选)</label> <input type="tel" id="ecm-user-phone" name="user_phone"> </div> <div class="ecm-form-group"> <label> <input type="checkbox" name="email_reminder" checked> 通过邮件提醒 </label> </div> <button type="submit" class="ecm-submit-btn">确认预约</button> </form> </div> </div> </div> <style> .ecm-countdown-container { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; padding: 30px; color: white; text-align: center; margin: 20px 0; box-shadow: 0 10px 30px rgba(0,0,0,0.2); } .ecm-countdown-header h3 { margin: 0 0 10px 0; font-size: 24px; } .ecm-countdown-header h4 { margin: 0 0 20px 0; font-size: 20px; opacity: 0.9; } .ecm-countdown-timer { display: flex; justify-content: center; align-items: center; margin: 30px 0; font-family: 'Courier New', monospace; } .ecm-countdown-item { display: flex; flex-direction: column; align-items: center; margin: 0 10px; } .ecm-countdown-number { font-size: 48px; font-weight: bold; background: rgba(255,255,255,0.1); padding: 10px 20px; border-radius: 10px; min-width: 80px; display: inline-block; } .ecm-countdown-label { margin-top: 5px; font-size: 14px; opacity: 0.8; } .ecm-countdown-separator { font-size: 36px; margin: 0 5px; opacity: 0.7; } .ecm-countdown-urgent .ecm-countdown-number { background: rgba(255,193,7,0.2); color: #ffc107; } .ecm-countdown-critical .ecm-countdown-number { background: rgba(220,53,69,0.2); color: #dc3545; animation: pulse 1s infinite; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.7; } 100% { opacity: 1; } } .ecm-reminder-btn { background: white; color: #667eea; border: none; padding: 12px 30px; border-radius: 50px; font-size: 16px; font-weight: bold; cursor: pointer; transition: all 0.3s ease; } .ecm-reminder-btn:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0,0,0,0.3); } .ecm-reminder-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; justify-content: center; align-items: center; z-index: 10000; } .ecm-modal-content { background: white; padding: 30px; border-radius: 10px; width: 90%; max-width: 500px; position: relative; color: #333; } .ecm-close-modal { position: absolute; top: 15px; right: 20px; font-size: 24px; cursor: pointer; } .ecm-form-group { margin-bottom: 20px; } .ecm-form-group label { display: block; margin-bottom: 5px; font-weight: bold; } .ecm-form-group input[type="text"], .ecm-form-group input[type="email"], .ecm-form-group input[type="tel"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; font-size: 16px; } .ecm-submit-btn { background: #667eea; color: white; border: none; padding: 12px 30px; border-radius: 5px; font-size: 16px; cursor: pointer; width: 100%; } .ecm-submit-btn:hover { background: #5a67d8; } </style> <?php return ob_get_clean(); } add_shortcode('event_countdown', 'ecm_countdown_shortcode');
- 在插件中注册全局JavaScript函数: // 添加前端脚本 function ecm_enqueue_frontend_scripts() { wp_enqueue_style('ecm-frontend-style', plugins_url('css/ecm-frontend.css', __FILE__)); wp_enqueue_script('ecm-frontend-script', plugins_url('js/ecm-frontend.js', __FILE__), array('jquery'), '1.0.0', true); wp_localize_script('ecm-frontend-script', 'ecm_ajax', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('ecm_ajax_nonce') )); } add_action('wp_enqueue_scripts', 'ecm_enqueue_frontend_scripts'); 创建JavaScript文件 js/ecm-frontend.js: // 显示预约提醒模态框 function ecmShowReminderModal(eventId) { var modal = document.createElement('div'); modal.className = 'ecm-reminder-modal'; modal.innerHTML = ` <div class="ecm-modal-content"> <span class="ecm-close-modal" onclick="this.parentElement.parentElement.remove()">×</span> <h3>设置活动提醒</h3> <form id="ecm-reminder-form"> <input type="hidden" name="event_id" value="${eventId}"> <div class="ecm-form-group"> <label for="ecm-user-name">姓名</label> <input type="text" id="ecm-user-name" name="user_name" required> </div> <div class="ecm-form-group"> <label for="ecm-user-email">邮箱</label> <input type="email" id="ecm-user-email" name="user_email" required> </div> <div class="ecm-form-group"> <label for="ecm-user-phone">手机号(可选)</label> <input type="tel" id="ecm-user-email" name="user_phone"> </div> <div class="ecm-form-group"> <label> <input type="checkbox" name="email_reminder" checked> 通过邮件提醒 </label> </div> <button type="submit" class="ecm-submit-btn">确认预约</button> </form> </div> `; document.body.appendChild(modal); // 表单提交处理 modal.querySelector('#ecm-reminder-form').addEventListener('submit', function(e) { e.preventDefault(); ecmSubmitReminder(this); }); // 点击模态框外部关闭 modal.addEventListener('click', function(e) { if (e.target === this) { this.remove(); } }); } // 提交预约提醒 function ecmSubmitReminder(form) { var formData = new FormData(form); var submitBtn = form.querySelector('.ecm-submit-btn'); var originalText = submitBtn.textContent; submitBtn.textContent = '提交中...'; submitBtn.disabled = true; // 添加AJAX请求 formData.append('action', 'ecm_submit_reminder'); formData.append('nonce', ecm_ajax.nonce); fetch(ecm_ajax.ajax_url, { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { form.innerHTML = ` <div class="ecm-success-message"> <div style="text-align: center; padding: 20px;"> <div style="font-size: 48px; color: #28a745;">✓</div> <h3>预约成功!</h3> <p>${data.message}</p> <button onclick="this.closest('.ecm-reminder-modal').remove()" class="ecm-submit-btn" style="margin-top: 20px;"> 关闭 </button> </div> </div> `; } else { alert('错误:' + data.message); submitBtn.textContent = originalText; submitBtn.disabled = false; } }) .catch(error => { console.error('Error:', error); alert('提交失败,请稍后重试'); submitBtn.textContent = originalText; submitBtn.disabled = false; }); }
-
- 创建AJAX处理函数: // 处理预约表单提交 function ecm_handle_reminder_submission() { // 验证nonce if (!wp_verify_nonce($_POST['nonce'], 'ecm_ajax_nonce')) { wp_die('安全验证失败'); } global $wpdb; $events_table = $wpdb->prefix . 'ecm_events'; $bookings_table = $wpdb->prefix . 'ecm_bookings'; $event_id = intval($_POST['event_id']); $user_name = sanitize_text_field($_POST['user_name']); $user_email = sanitize_email($_POST['user_email']); $user_phone = sanitize_text_field($_POST['user_phone']); // 验证数据 if (empty($user_name) || empty($user_email)) { wp_send_json_error(array('message' => '请填写必填字段')); } if (!is_email($user_email)) { wp_send_json_error(array('message' => '邮箱格式不正确')); } // 检查活动是否存在且可预约 $event = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $events_table WHERE event_id = %d AND status = 'active' AND reminder_enabled = 1", $event_id )); if (!$event) { wp_send_json_error(array('message' => '活动不存在或已结束预约')); } // 检查是否已满员 if ($event->max_participants > 0 && $event->current_participants >= $event->max_participants) { wp_send_json_error(array('message' => '活动人数已满')); } // 检查是否已预约 $existing_booking = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $bookings_table WHERE event_id = %d AND user_email = %s AND status != 'cancelled'", $event_id, $user_email )); if ($existing_booking > 0) { wp_send_json_error(array('message' => '您已经预约过此活动')); } // 获取当前用户ID(如果已登录) $user_id = is_user_logged_in() ? get_current_user_id() : 0; // 插入预约记录 $booking_data = array( 'event_id' => $event_id, 'user_id' => $user_id, 'user_name' => $user_name, 'user_email' => $user_email, 'user_phone' => $user_phone, 'status' => 'confirmed' ); $result = $wpdb->insert($bookings_table, $booking_data); if ($result) { // 更新活动参与人数 $wpdb->query($wpdb->prepare( "UPDATE $events_table SET current_participants = current_participants + 1 WHERE event_id = %d", $event_id )); // 发送确认邮件 if (isset($_POST['email_reminder'])) { ecm_send_confirmation_email($user_email, $user_name, $event); } wp_send_json_success(array( 'message' => '预约成功!活动开始前您将收到提醒。' )); } else { wp_send_json_error(array('message' => '预约失败,请稍后重试')); } } add_action('wp_ajax_ecm_submit_reminder', 'ecm_handle_reminder_submission'); add_action('wp_ajax_nopriv_ecm_submit_reminder', 'ecm_handle_reminder_submission');
- // 发送确认邮件 function ecm_send_confirmation_email($user_email, $user_name, $event) { $subject = '活动预约确认:' . $event->event_title; $message = ' <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>活动预约确认</title> <style> body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; } .container { max-width: 600px; margin: 0 auto; padding: 20px; } .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 10px 10px 0 0; } .content { background: #f9f9f9; padding: 30px; border-radius: 0 0 10px 10px; } .event-info { background: white; padding: 20px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #667eea; }
在当今数字营销时代,网站互动功能已成为提升用户参与度和转化率的关键因素。活动倒计时与预约提醒功能作为常见的互联网小工具,能够有效创造紧迫感,提高用户参与活动的积极性。对于电商网站,倒计时可以促进限时抢购;对于活动策划网站,预约提醒能确保参与者不会错过重要事件。
WordPress作为全球最流行的内容管理系统,其强大的可扩展性使得开发者可以通过代码二次开发实现各种定制功能。本教程将详细指导您如何为WordPress网站开发活动倒计时与预约提醒功能,无需依赖昂贵的插件,完全通过自主代码实现。
在开始开发之前,请确保您的WordPress环境满足以下条件:
- WordPress版本5.0或更高
- PHP版本7.4或更高(推荐8.0+)
- MySQL 5.6或更高版本
- 已安装并激活一个支持子主题的WordPress主题
为了避免主题更新导致功能丢失,我们建议创建一个独立的功能插件:
- 在
wp-content/plugins/目录下创建新文件夹event-countdown-manager - 在该文件夹中创建主插件文件
event-countdown-manager.php - 添加插件头部信息:
<?php
/**
* Plugin Name: 活动倒计时与预约提醒管理器
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站添加活动倒计时与预约提醒功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: event-countdown-manager
*/
我们需要创建两个数据库表来存储活动信息和用户预约数据。在插件激活时创建这些表:
// 创建数据库表
function ecm_create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$events_table = $wpdb->prefix . 'ecm_events';
$bookings_table = $wpdb->prefix . 'ecm_bookings';
// 活动表SQL
$events_sql = "CREATE TABLE IF NOT EXISTS $events_table (
event_id INT(11) NOT NULL AUTO_INCREMENT,
event_title VARCHAR(255) NOT NULL,
event_description TEXT,
event_start DATETIME NOT NULL,
event_end DATETIME NOT NULL,
countdown_enabled TINYINT(1) DEFAULT 1,
reminder_enabled TINYINT(1) DEFAULT 1,
max_participants INT(11) DEFAULT 0,
current_participants INT(11) DEFAULT 0,
status ENUM('active', 'inactive', 'completed') DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (event_id)
) $charset_collate;";
// 预约表SQL
$bookings_sql = "CREATE TABLE IF NOT EXISTS $bookings_table (
booking_id INT(11) NOT NULL AUTO_INCREMENT,
event_id INT(11) NOT NULL,
user_id INT(11),
user_name VARCHAR(255),
user_email VARCHAR(255) NOT NULL,
user_phone VARCHAR(50),
reminder_sent TINYINT(1) DEFAULT 0,
booking_time DATETIME DEFAULT CURRENT_TIMESTAMP,
status ENUM('confirmed', 'pending', 'cancelled') DEFAULT 'confirmed',
PRIMARY KEY (booking_id),
FOREIGN KEY (event_id) REFERENCES $events_table(event_id) ON DELETE CASCADE
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($events_sql);
dbDelta($bookings_sql);
}
register_activation_hook(__FILE__, 'ecm_create_database_tables');
为管理员添加活动管理界面:
// 添加管理菜单
function ecm_add_admin_menu() {
add_menu_page(
'活动倒计时管理',
'活动管理',
'manage_options',
'ecm-events',
'ecm_events_admin_page',
'dashicons-calendar-alt',
30
);
add_submenu_page(
'ecm-events',
'添加新活动',
'添加新活动',
'manage_options',
'ecm-add-event',
'ecm_add_event_page'
);
add_submenu_page(
'ecm-events',
'预约管理',
'预约管理',
'manage_options',
'ecm-bookings',
'ecm_bookings_admin_page'
);
}
add_action('admin_menu', 'ecm_add_admin_menu');
创建活动列表显示与管理页面:
function ecm_events_admin_page() {
global $wpdb;
$events_table = $wpdb->prefix . 'ecm_events';
// 处理删除操作
if (isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['event_id'])) {
$event_id = intval($_GET['event_id']);
$wpdb->delete($events_table, array('event_id' => $event_id));
echo '<div class="notice notice-success"><p>活动已删除</p></div>';
}
// 获取所有活动
$events = $wpdb->get_results("SELECT * FROM $events_table ORDER BY event_start DESC");
?>
<div class="wrap">
<h1 class="wp-heading-inline">活动管理</h1>
<a href="<?php echo admin_url('admin.php?page=ecm-add-event'); ?>" class="page-title-action">添加新活动</a>
<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 (empty($events)): ?>
<tr>
<td colspan="7" style="text-align: center;">暂无活动</td>
</tr>
<?php else: ?>
<?php foreach ($events as $event): ?>
<tr>
<td><?php echo $event->event_id; ?></td>
<td><?php echo esc_html($event->event_title); ?></td>
<td><?php echo date('Y-m-d H:i', strtotime($event->event_start)); ?></td>
<td><?php echo date('Y-m-d H:i', strtotime($event->event_end)); ?></td>
<td><?php echo $event->current_participants . '/' . $event->max_participants; ?></td>
<td>
<?php
$status_labels = array(
'active' => '<span class="dashicons dashicons-yes-alt" style="color:green"></span> 进行中',
'inactive' => '<span class="dashicons dashicons-no" style="color:red"></span> 未激活',
'completed' => '<span class="dashicons dashicons-yes" style="color:blue"></span> 已结束'
);
echo $status_labels[$event->status];
?>
</td>
<td>
<a href="<?php echo admin_url('admin.php?page=ecm-add-event&event_id=' . $event->event_id); ?>">编辑</a> |
<a href="<?php echo admin_url('admin.php?page=ecm-events&action=delete&event_id=' . $event->event_id); ?>" onclick="return confirm('确定删除此活动吗?')">删除</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php
}
创建活动添加与编辑表单:
function ecm_add_event_page() {
global $wpdb;
$events_table = $wpdb->prefix . 'ecm_events';
$event_id = isset($_GET['event_id']) ? intval($_GET['event_id']) : 0;
$event = null;
if ($event_id > 0) {
$event = $wpdb->get_row($wpdb->prepare("SELECT * FROM $events_table WHERE event_id = %d", $event_id));
}
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ecm_event_nonce'])) {
if (!wp_verify_nonce($_POST['ecm_event_nonce'], 'ecm_save_event')) {
die('安全验证失败');
}
$event_data = array(
'event_title' => sanitize_text_field($_POST['event_title']),
'event_description' => wp_kses_post($_POST['event_description']),
'event_start' => sanitize_text_field($_POST['event_start']),
'event_end' => sanitize_text_field($_POST['event_end']),
'countdown_enabled' => isset($_POST['countdown_enabled']) ? 1 : 0,
'reminder_enabled' => isset($_POST['reminder_enabled']) ? 1 : 0,
'max_participants' => intval($_POST['max_participants']),
'status' => sanitize_text_field($_POST['status'])
);
if ($event_id > 0) {
$wpdb->update($events_table, $event_data, array('event_id' => $event_id));
$message = '活动已更新';
} else {
$wpdb->insert($events_table, $event_data);
$event_id = $wpdb->insert_id;
$message = '活动已创建';
}
echo '<div class="notice notice-success"><p>' . $message . '</p></div>';
$event = $wpdb->get_row($wpdb->prepare("SELECT * FROM $events_table WHERE event_id = %d", $event_id));
}
?>
<div class="wrap">
<h1><?php echo $event_id > 0 ? '编辑活动' : '添加新活动'; ?></h1>
<form method="post" action="">
<?php wp_nonce_field('ecm_save_event', 'ecm_event_nonce'); ?>
<table class="form-table">
<tr>
<th><label for="event_title">活动标题</label></th>
<td>
<input type="text" id="event_title" name="event_title" class="regular-text"
value="<?php echo $event ? esc_attr($event->event_title) : ''; ?>" required>
</td>
</tr>
<tr>
<th><label for="event_description">活动描述</label></th>
<td>
<?php
$description = $event ? $event->event_description : '';
wp_editor($description, 'event_description', array(
'textarea_name' => 'event_description',
'media_buttons' => false,
'textarea_rows' => 5
));
?>
</td>
</tr>
<tr>
<th><label for="event_start">开始时间</label></th>
<td>
<input type="datetime-local" id="event_start" name="event_start"
value="<?php echo $event ? date('Y-m-dTH:i', strtotime($event->event_start)) : ''; ?>" required>
</td>
</tr>
<tr>
<th><label for="event_end">结束时间</label></th>
<td>
<input type="datetime-local" id="event_end" name="event_end"
value="<?php echo $event ? date('Y-m-dTH:i', strtotime($event->event_end)) : ''; ?>" required>
</td>
</tr>
<tr>
<th>功能设置</th>
<td>
<label>
<input type="checkbox" name="countdown_enabled" value="1"
<?php echo ($event && $event->countdown_enabled) ? 'checked' : ''; ?>>
启用倒计时
</label>
<br>
<label>
<input type="checkbox" name="reminder_enabled" value="1"
<?php echo ($event && $event->reminder_enabled) ? 'checked' : ''; ?>>
启用预约提醒
</label>
</td>
</tr>
<tr>
<th><label for="max_participants">最大参与人数</label></th>
<td>
<input type="number" id="max_participants" name="max_participants" min="0"
value="<?php echo $event ? $event->max_participants : '0'; ?>">
<p class="description">0表示不限制人数</p>
</td>
</tr>
<tr>
<th><label for="status">状态</label></th>
<td>
<select id="status" name="status">
<option value="active" <?php echo ($event && $event->status == 'active') ? 'selected' : ''; ?>>进行中</option>
<option value="inactive" <?php echo ($event && $event->status == 'inactive') ? 'selected' : ''; ?>>未激活</option>
<option value="completed" <?php echo ($event && $event->status == 'completed') ? 'selected' : ''; ?>>已结束</option>
</select>
</td>
</tr>
</table>
<p class="submit">
<input type="submit" class="button button-primary" value="保存活动">
<a href="<?php echo admin_url('admin.php?page=ecm-events'); ?>" class="button">返回列表</a>
</p>
</form>
</div>
<?php
}
创建短代码以便在文章或页面中插入倒计时:
// 注册倒计时短代码
function ecm_countdown_shortcode($atts) {
global $wpdb;
$atts = shortcode_atts(array(
'event_id' => 0,
'title' => '活动倒计时',
'show_description' => true,
'style' => 'default'
), $atts);
$event_id = intval($atts['event_id']);
$events_table = $wpdb->prefix . 'ecm_events';
if ($event_id === 0) {
// 获取最近的活动
$event = $wpdb->get_row("SELECT * FROM $events_table WHERE status = 'active' AND event_end > NOW() ORDER BY event_start LIMIT 1");
} else {
$event = $wpdb->get_row($wpdb->prepare("SELECT * FROM $events_table WHERE event_id = %d", $event_id));
}
if (!$event || $event->countdown_enabled != 1) {
return '<p>暂无活动或倒计时未启用</p>';
}
// 生成唯一ID用于JavaScript
$countdown_id = 'ecm-countdown-' . uniqid();
ob_start();
?>
<div class="ecm-countdown-container ecm-style-<?php echo esc_attr($atts['style']); ?>" id="<?php echo $countdown_id; ?>">
<div class="ecm-countdown-header">
<h3><?php echo esc_html($atts['title']); ?></h3>
<h4><?php echo esc_html($event->event_title); ?></h4>
</div>
<?php if ($atts['show_description'] && !empty($event->event_description)): ?>
<div class="ecm-countdown-description">
<?php echo wpautop($event->event_description); ?>
</div>
<?php endif; ?>
<div class="ecm-countdown-timer">
<div class="ecm-countdown-item">
<span class="ecm-countdown-number ecm-days">00</span>
<span class="ecm-countdown-label">天</span>
</div>
<div class="ecm-countdown-separator">:</div>
<div class="ecm-countdown-item">
<span class="ecm-countdown-number ecm-hours">00</span>
<span class="ecm-countdown-label">时</span>
</div>
<div class="ecm-countdown-separator">:</div>
<div class="ecm-countdown-item">
<span class="ecm-countdown-number ecm-minutes">00</span>
<span class="ecm-countdown-label">分</span>
</div>
<div class="ecm-countdown-separator">:</div>
<div class="ecm-countdown-item">
<span class="ecm-countdown-number ecm-seconds">00</span>
<span class="ecm-countdown-label">秒</span>
</div>
</div>
<div class="ecm-countdown-message"></div>
<?php if ($event->reminder_enabled): ?>
<div class="ecm-reminder-section">
<button class="ecm-reminder-btn" data-event-id="<?php echo $event->event_id; ?>">
设置活动提醒
</button>
</div>
<?php endif; ?>
继续在短代码函数中添加JavaScript代码:
<script>
(function() {
var countdownElement = document.getElementById('<?php echo $countdown_id; ?>');
var eventEndTime = new Date('<?php echo $event->event_end; ?>').getTime();
function updateCountdown() {
var now = new Date().getTime();
var timeRemaining = eventEndTime - now;
if (timeRemaining < 0) {
countdownElement.querySelector('.ecm-countdown-message').innerHTML =
'<p class="ecm-countdown-ended">活动已结束</p>';
countdownElement.querySelector('.ecm-countdown-timer').style.display = 'none';
return;
}
var days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));
var hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);
// 更新显示
countdownElement.querySelector('.ecm-days').textContent = days.toString().padStart(2, '0');
countdownElement.querySelector('.ecm-hours').textContent = hours.toString().padStart(2, '0');
countdownElement.querySelector('.ecm-minutes').textContent = minutes.toString().padStart(2, '0');
countdownElement.querySelector('.ecm-seconds').textContent = seconds.toString().padStart(2, '0');
// 动态样式变化
if (days === 0 && hours < 24) {
countdownElement.classList.add('ecm-countdown-urgent');
}
if (days === 0 && hours < 1) {
countdownElement.classList.add('ecm-countdown-critical');
}
}
// 初始更新
updateCountdown();
// 每秒更新
var countdownInterval = setInterval(updateCountdown, 1000);
// 预约提醒按钮事件
var reminderBtn = countdownElement.querySelector('.ecm-reminder-btn');
if (reminderBtn) {
reminderBtn.addEventListener('click', function() {
var eventId = this.getAttribute('data-event-id');
ecmShowReminderModal(eventId);
});
}
})();
</script>
<div class="ecm-reminder-modal" style="display: none;">
<div class="ecm-modal-content">
<span class="ecm-close-modal">×</span>
<h3>设置活动提醒</h3>
<form id="ecm-reminder-form">
<input type="hidden" name="event_id" value="<?php echo $event->event_id; ?>">
<div class="ecm-form-group">
<label for="ecm-user-name">姓名</label>
<input type="text" id="ecm-user-name" name="user_name" required>
</div>
<div class="ecm-form-group">
<label for="ecm-user-email">邮箱</label>
<input type="email" id="ecm-user-email" name="user_email" required>
</div>
<div class="ecm-form-group">
<label for="ecm-user-phone">手机号(可选)</label>
<input type="tel" id="ecm-user-phone" name="user_phone">
</div>
<div class="ecm-form-group">
<label>
<input type="checkbox" name="email_reminder" checked>
通过邮件提醒
</label>
</div>
<button type="submit" class="ecm-submit-btn">确认预约</button>
</form>
</div>
</div>
</div>
<style>
.ecm-countdown-container {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
padding: 30px;
color: white;
text-align: center;
margin: 20px 0;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
.ecm-countdown-header h3 {
margin: 0 0 10px 0;
font-size: 24px;
}
.ecm-countdown-header h4 {
margin: 0 0 20px 0;
font-size: 20px;
opacity: 0.9;
}
.ecm-countdown-timer {
display: flex;
justify-content: center;
align-items: center;
margin: 30px 0;
font-family: 'Courier New', monospace;
}
.ecm-countdown-item {
display: flex;
flex-direction: column;
align-items: center;
margin: 0 10px;
}
.ecm-countdown-number {
font-size: 48px;
font-weight: bold;
background: rgba(255,255,255,0.1);
padding: 10px 20px;
border-radius: 10px;
min-width: 80px;
display: inline-block;
}
.ecm-countdown-label {
margin-top: 5px;
font-size: 14px;
opacity: 0.8;
}
.ecm-countdown-separator {
font-size: 36px;
margin: 0 5px;
opacity: 0.7;
}
.ecm-countdown-urgent .ecm-countdown-number {
background: rgba(255,193,7,0.2);
color: #ffc107;
}
.ecm-countdown-critical .ecm-countdown-number {
background: rgba(220,53,69,0.2);
color: #dc3545;
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
.ecm-reminder-btn {
background: white;
color: #667eea;
border: none;
padding: 12px 30px;
border-radius: 50px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
}
.ecm-reminder-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
.ecm-reminder-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 10000;
}
.ecm-modal-content {
background: white;
padding: 30px;
border-radius: 10px;
width: 90%;
max-width: 500px;
position: relative;
color: #333;
}
.ecm-close-modal {
position: absolute;
top: 15px;
right: 20px;
font-size: 24px;
cursor: pointer;
}
.ecm-form-group {
margin-bottom: 20px;
}
.ecm-form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.ecm-form-group input[type="text"],
.ecm-form-group input[type="email"],
.ecm-form-group input[type="tel"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
.ecm-submit-btn {
background: #667eea;
color: white;
border: none;
padding: 12px 30px;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
width: 100%;
}
.ecm-submit-btn:hover {
background: #5a67d8;
}
</style>
<?php
return ob_get_clean();
}
add_shortcode('event_countdown', 'ecm_countdown_shortcode');
在插件中注册全局JavaScript函数:
// 添加前端脚本
function ecm_enqueue_frontend_scripts() {
wp_enqueue_style('ecm-frontend-style', plugins_url('css/ecm-frontend.css', __FILE__));
wp_enqueue_script('ecm-frontend-script', plugins_url('js/ecm-frontend.js', __FILE__), array('jquery'), '1.0.0', true);
wp_localize_script('ecm-frontend-script', 'ecm_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ecm_ajax_nonce')
));
}
add_action('wp_enqueue_scripts', 'ecm_enqueue_frontend_scripts');
创建JavaScript文件 js/ecm-frontend.js:
// 显示预约提醒模态框
function ecmShowReminderModal(eventId) {
var modal = document.createElement('div');
modal.className = 'ecm-reminder-modal';
modal.innerHTML = `
<div class="ecm-modal-content">
<span class="ecm-close-modal" onclick="this.parentElement.parentElement.remove()">×</span>
<h3>设置活动提醒</h3>
<form id="ecm-reminder-form">
<input type="hidden" name="event_id" value="${eventId}">
<div class="ecm-form-group">
<label for="ecm-user-name">姓名</label>
<input type="text" id="ecm-user-name" name="user_name" required>
</div>
<div class="ecm-form-group">
<label for="ecm-user-email">邮箱</label>
<input type="email" id="ecm-user-email" name="user_email" required>
</div>
<div class="ecm-form-group">
<label for="ecm-user-phone">手机号(可选)</label>
<input type="tel" id="ecm-user-email" name="user_phone">
</div>
<div class="ecm-form-group">
<label>
<input type="checkbox" name="email_reminder" checked>
通过邮件提醒
</label>
</div>
<button type="submit" class="ecm-submit-btn">确认预约</button>
</form>
</div>
`;
document.body.appendChild(modal);
// 表单提交处理
modal.querySelector('#ecm-reminder-form').addEventListener('submit', function(e) {
e.preventDefault();
ecmSubmitReminder(this);
});
// 点击模态框外部关闭
modal.addEventListener('click', function(e) {
if (e.target === this) {
this.remove();
}
});
}
// 提交预约提醒
function ecmSubmitReminder(form) {
var formData = new FormData(form);
var submitBtn = form.querySelector('.ecm-submit-btn');
var originalText = submitBtn.textContent;
submitBtn.textContent = '提交中...';
submitBtn.disabled = true;
// 添加AJAX请求
formData.append('action', 'ecm_submit_reminder');
formData.append('nonce', ecm_ajax.nonce);
fetch(ecm_ajax.ajax_url, {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
form.innerHTML = `
<div class="ecm-success-message">
<div style="text-align: center; padding: 20px;">
<div style="font-size: 48px; color: #28a745;">✓</div>
<h3>预约成功!</h3>
<p>${data.message}</p>
<button onclick="this.closest('.ecm-reminder-modal').remove()"
class="ecm-submit-btn" style="margin-top: 20px;">
关闭
</button>
</div>
</div>
`;
} else {
alert('错误:' + data.message);
submitBtn.textContent = originalText;
submitBtn.disabled = false;
}
})
.catch(error => {
console.error('Error:', error);
alert('提交失败,请稍后重试');
submitBtn.textContent = originalText;
submitBtn.disabled = false;
});
}
创建AJAX处理函数:
// 处理预约表单提交
function ecm_handle_reminder_submission() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'ecm_ajax_nonce')) {
wp_die('安全验证失败');
}
global $wpdb;
$events_table = $wpdb->prefix . 'ecm_events';
$bookings_table = $wpdb->prefix . 'ecm_bookings';
$event_id = intval($_POST['event_id']);
$user_name = sanitize_text_field($_POST['user_name']);
$user_email = sanitize_email($_POST['user_email']);
$user_phone = sanitize_text_field($_POST['user_phone']);
// 验证数据
if (empty($user_name) || empty($user_email)) {
wp_send_json_error(array('message' => '请填写必填字段'));
}
if (!is_email($user_email)) {
wp_send_json_error(array('message' => '邮箱格式不正确'));
}
// 检查活动是否存在且可预约
$event = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $events_table WHERE event_id = %d AND status = 'active' AND reminder_enabled = 1",
$event_id
));
if (!$event) {
wp_send_json_error(array('message' => '活动不存在或已结束预约'));
}
// 检查是否已满员
if ($event->max_participants > 0 && $event->current_participants >= $event->max_participants) {
wp_send_json_error(array('message' => '活动人数已满'));
}
// 检查是否已预约
$existing_booking = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $bookings_table WHERE event_id = %d AND user_email = %s AND status != 'cancelled'",
$event_id, $user_email
));
if ($existing_booking > 0) {
wp_send_json_error(array('message' => '您已经预约过此活动'));
}
// 获取当前用户ID(如果已登录)
$user_id = is_user_logged_in() ? get_current_user_id() : 0;
// 插入预约记录
$booking_data = array(
'event_id' => $event_id,
'user_id' => $user_id,
'user_name' => $user_name,
'user_email' => $user_email,
'user_phone' => $user_phone,
'status' => 'confirmed'
);
$result = $wpdb->insert($bookings_table, $booking_data);
if ($result) {
// 更新活动参与人数
$wpdb->query($wpdb->prepare(
"UPDATE $events_table SET current_participants = current_participants + 1 WHERE event_id = %d",
$event_id
));
// 发送确认邮件
if (isset($_POST['email_reminder'])) {
ecm_send_confirmation_email($user_email, $user_name, $event);
}
wp_send_json_success(array(
'message' => '预约成功!活动开始前您将收到提醒。'
));
} else {
wp_send_json_error(array('message' => '预约失败,请稍后重试'));
}
}
add_action('wp_ajax_ecm_submit_reminder', 'ecm_handle_reminder_submission');
add_action('wp_ajax_nopriv_ecm_submit_reminder', 'ecm_handle_reminder_submission');
// 发送确认邮件
function ecm_send_confirmation_email($user_email, $user_name, $event) {
$subject = '活动预约确认:' . $event->event_title;
$message = '
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>活动预约确认</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 10px 10px 0 0; }
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 10px 10px; }
.event-info { background: white; padding: 20px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #667eea; }
// 发送确认邮件
function ecm_send_confirmation_email($user_email, $user_name, $event) {
$subject = '活动预约确认:' . $event->event_title;
$message = '
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>活动预约确认</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 10px 10px 0 0; }
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 10px 10px; }
.event-info { background: white; padding: 20px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #667eea; }


