314 lines
13 KiB
PHP
314 lines
13 KiB
PHP
<?php
|
||
// WPS表单Webhook接收端点
|
||
|
||
// 设置响应头
|
||
header('Content-Type: application/json; charset=utf-8');
|
||
|
||
// 绑定码(根据WPS表单要求提供)
|
||
$bind_code = '20251205123619412736007';
|
||
|
||
// 日志文件路径
|
||
$log_file = 'log/wps_form_webhook.log';
|
||
|
||
// 加载数据库配置
|
||
require_once 'config.php';
|
||
|
||
// 数据库连接函数
|
||
function get_db_connection() {
|
||
global $host, $username, $password, $database;
|
||
try {
|
||
$pdo = new PDO("mysql:host=$host;dbname=$database;charset=utf8mb4", $username, $password);
|
||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||
return $pdo;
|
||
} catch(PDOException $e) {
|
||
log_message("数据库连接失败: " . $e->getMessage(), 'error');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 字段对照表(根据WPS表单实际字段)
|
||
$field_mapping = array(
|
||
// 题目标题 => array(qid, type)
|
||
'日期' => array('0AmAeI', 'date'),
|
||
'单选项' => array('y0Rvqm', 'select'),
|
||
'图片和附件' => array('FOS5GT', 'file'),
|
||
'等级' => array('0wJSrH', 'star'),
|
||
'填写ID' => array('vwS7ci', 'input'),
|
||
'提交时间' => array('yjbQYS', 'date'),
|
||
'答题时间(秒)' => array('AA2kq8', 'input'),
|
||
'车牌号' => array('t2u2i4', 'licensePlate'), // 只使用这个车牌号字段(qid: t2u2i4, type: licensePlate)
|
||
'车牌号2' => array('7nAOz7', 'input'), // 不使用
|
||
'车牌号(普通)' => array('NFJDDT', 'input'), // 不使用
|
||
'怎么称呼您' => array('eo513g', 'input'),
|
||
'车型' => array('xKFUcp', 'input'),
|
||
'请输入手机号' => array('7jgfmh', 'input'),
|
||
'是否有车衣' => array('3j6opi', 'select'),
|
||
'有无自己撸车习惯' => array('ej48lk', 'select'),
|
||
'撸车经验' => array('1tnljp', 'select'),
|
||
'洗车频率' => array('x02g35', 'select'),
|
||
'请选择年龄段' => array('54dbo7', 'select'),
|
||
'提交者' => array('T9OiCe', 'contact'),
|
||
'自动编号' => array('rwxgkc', 'autoNum'),
|
||
'备注内容' => array('r3ft9n', 'input')
|
||
);
|
||
|
||
// 反向映射:qid => array(title, type)
|
||
$qid_mapping = array();
|
||
foreach ($field_mapping as $title => $info) {
|
||
$qid = $info[0];
|
||
$type = $info[1];
|
||
$qid_mapping[$qid] = array('title' => $title, 'type' => $type);
|
||
}
|
||
|
||
// 记录日志的函数
|
||
function log_message($message, $type = 'info') {
|
||
global $log_file;
|
||
$timestamp = date('Y-m-d H:i:s');
|
||
$log_entry = "[$timestamp] [$type] $message\n";
|
||
|
||
// 检查日志目录是否存在,如果不存在则创建
|
||
$log_dir = dirname($log_file);
|
||
if (!is_dir($log_dir)) {
|
||
mkdir($log_dir, 0755, true);
|
||
}
|
||
|
||
file_put_contents($log_file, $log_entry, FILE_APPEND);
|
||
}
|
||
|
||
// 获取请求方法
|
||
$method = $_SERVER['REQUEST_METHOD'];
|
||
|
||
// 获取请求数据
|
||
$request_body = file_get_contents('php://input');
|
||
|
||
// 记录所有请求
|
||
log_message("收到请求 - 方法: $method");
|
||
log_message("请求内容: $request_body");
|
||
|
||
// 处理验证请求
|
||
if ($method == 'POST') {
|
||
// 尝试解析请求体
|
||
$data = json_decode($request_body, true);
|
||
|
||
// 如果解析失败,可能是验证请求
|
||
if ($data === null) {
|
||
// 返回绑定码进行验证
|
||
log_message("返回绑定码进行验证");
|
||
echo json_encode(array('bind_code' => $bind_code));
|
||
exit;
|
||
}
|
||
|
||
// 检查是否是绑定验证请求
|
||
if (isset($data['event']) && $data['event'] === 'bind') {
|
||
log_message("收到绑定验证请求");
|
||
echo json_encode(array('bind_code' => $bind_code));
|
||
exit;
|
||
}
|
||
|
||
// 处理实际的表单数据
|
||
log_message("处理表单数据");
|
||
log_message("原始表单数据: " . print_r($data, true), 'data');
|
||
|
||
// 解析WPS表单数据结构
|
||
$form_data = array(
|
||
'rid' => isset($data['rid']) ? $data['rid'] : '',
|
||
'form_id' => isset($data['formId']) ? $data['formId'] : '',
|
||
'form_title' => isset($data['formTitle']) ? $data['formTitle'] : '',
|
||
'aid' => isset($data['aid']) ? $data['aid'] : '',
|
||
'event_ts' => isset($data['eventTs']) ? $data['eventTs'] : 0,
|
||
'message_ts' => isset($data['messageTs']) ? $data['messageTs'] : 0,
|
||
'creator_id' => isset($data['creatorId']) ? $data['creatorId'] : '',
|
||
'creator_name' => isset($data['creatorName']) ? $data['creatorName'] : '',
|
||
'event' => isset($data['event']) ? $data['event'] : '',
|
||
'version' => isset($data['version']) ? $data['version'] : 1,
|
||
'answers' => array()
|
||
);
|
||
|
||
// 解析表单字段
|
||
if (isset($data['answerContents']) && is_array($data['answerContents'])) {
|
||
foreach ($data['answerContents'] as $content) {
|
||
$qid = isset($content['qid']) ? $content['qid'] : '';
|
||
$type = isset($content['type']) ? $content['type'] : '';
|
||
$title = isset($content['title']) ? $content['title'] : '';
|
||
$value = isset($content['value']) ? $content['value'] : '';
|
||
|
||
// 将数组值转换为字符串,便于处理
|
||
if (is_array($value)) {
|
||
$value = implode(', ', $value);
|
||
}
|
||
|
||
$field = array(
|
||
'qid' => $qid,
|
||
'type' => $type,
|
||
'title' => $title,
|
||
'value' => $value
|
||
);
|
||
|
||
$form_data['answers'][] = $field;
|
||
|
||
// 按标题索引存储,便于直接访问
|
||
if (!empty($title)) {
|
||
$form_data['answers_by_title'][$title] = $value;
|
||
}
|
||
|
||
// 按qid索引存储,便于精确访问
|
||
if (!empty($qid)) {
|
||
$form_data['answers_by_qid'][$qid] = $value;
|
||
}
|
||
|
||
// 使用字段对照表检查并标准化字段
|
||
if (!empty($qid) && isset($qid_mapping[$qid])) {
|
||
$standard_title = $qid_mapping[$qid]['title'];
|
||
$standard_type = $qid_mapping[$qid]['type'];
|
||
|
||
// 存储标准化字段
|
||
$form_data['standardized_answers'][$standard_title] = array(
|
||
'qid' => $qid,
|
||
'type' => $standard_type,
|
||
'title' => $title, // 保留原始标题
|
||
'value' => $value,
|
||
'standard_title' => $standard_title
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
log_message("解析后的表单数据: " . print_r($form_data, true), 'data');
|
||
|
||
// 在这里可以添加数据处理逻辑,例如:
|
||
// 1. 将数据保存到数据库
|
||
// 2. 发送通知
|
||
// 3. 其他业务逻辑
|
||
|
||
// 示例:访问特定字段
|
||
|
||
// 通过标题访问
|
||
if (isset($form_data['answers_by_title']['怎么称呼您'])) {
|
||
$name = $form_data['answers_by_title']['怎么称呼您'];
|
||
log_message("客户姓名: $name");
|
||
}
|
||
|
||
// 注意:由于有两个"车牌号"字段,通过标题访问可能获取到任意一个
|
||
// 建议使用qid或标准化字段访问
|
||
if (isset($form_data['answers_by_title']['车牌号'])) {
|
||
$license_plate = $form_data['answers_by_title']['车牌号'];
|
||
log_message("车牌号(通过标题): $license_plate");
|
||
}
|
||
|
||
// 通过qid精确访问特定的车牌号字段
|
||
if (isset($form_data['answers_by_qid']['t2u2i4'])) {
|
||
$license_plate_standard = $form_data['answers_by_qid']['t2u2i4'];
|
||
log_message("车牌号(通过qid t2u2i4 - 标准): $license_plate_standard");
|
||
}
|
||
|
||
// 通过标准化字段访问
|
||
if (isset($form_data['standardized_answers']['怎么称呼您'])) {
|
||
$name_standard = $form_data['standardized_answers']['怎么称呼您']['value'];
|
||
log_message("客户姓名(标准化): $name_standard");
|
||
}
|
||
|
||
if (isset($form_data['standardized_answers']['车型'])) {
|
||
$car_model = $form_data['standardized_answers']['车型']['value'];
|
||
log_message("车型: $car_model");
|
||
}
|
||
|
||
if (isset($form_data['standardized_answers']['请输入手机号'])) {
|
||
$phone = $form_data['standardized_answers']['请输入手机号']['value'];
|
||
log_message("手机号: $phone");
|
||
}
|
||
|
||
// 返回成功响应
|
||
$response = array(
|
||
'code' => 200,
|
||
'message' => '数据接收成功',
|
||
'received_at' => date('Y-m-d H:i:s'),
|
||
'processed_fields' => count($form_data['answers'])
|
||
);
|
||
|
||
// 将数据存储到数据库
|
||
store_form_data_to_db($form_data);
|
||
|
||
log_message("返回成功响应");
|
||
echo json_encode($response);
|
||
} else {
|
||
// 处理非POST请求
|
||
log_message("不支持的请求方法: $method", 'error');
|
||
http_response_code(405); // 方法不允许
|
||
echo json_encode(array('error' => '只支持POST请求'));
|
||
}
|
||
|
||
log_message("请求处理完成\n" . str_repeat('-', 50) . "\n");
|
||
|
||
// 将表单数据存储到数据库
|
||
function store_form_data_to_db($form_data) {
|
||
try {
|
||
$pdo = get_db_connection();
|
||
if (!$pdo) {
|
||
return false;
|
||
}
|
||
|
||
// 准备SQL语句(只包含实际WPS表单存在的字段)
|
||
$sql = "INSERT INTO wps_form_submissions (
|
||
rid, form_id, form_title, creator_id, create_time, update_time,
|
||
mobile, name, license_plate, date, time_slot, car_type,
|
||
has_car_coat, car_wash_habit, car_wash_experience, wash_frequency,
|
||
age_group, remarks, auto_number, status, updated_at
|
||
) VALUES (
|
||
:rid, :form_id, :form_title, :creator_id, :create_time, :update_time,
|
||
:mobile, :name, :license_plate, :date, :time_slot, :car_type,
|
||
:has_car_coat, :car_wash_habit, :car_wash_experience, :wash_frequency,
|
||
:age_group, :remarks, :auto_number, :status, :updated_at
|
||
)";
|
||
|
||
$stmt = $pdo->prepare($sql);
|
||
|
||
// 绑定参数
|
||
$stmt->bindValue(':rid', $form_data['rid']);
|
||
$stmt->bindValue(':form_id', $form_data['form_id']);
|
||
$stmt->bindValue(':form_title', $form_data['form_title']);
|
||
$stmt->bindValue(':creator_id', $form_data['creator_id']);
|
||
$stmt->bindValue(':create_time', date('Y-m-d H:i:s'));
|
||
$stmt->bindValue(':update_time', date('Y-m-d H:i:s'));
|
||
$stmt->bindValue(':updated_at', date('Y-m-d H:i:s'));
|
||
|
||
// 绑定表单字段值(只绑定实际存在的字段)
|
||
$stmt->bindValue(':mobile', isset($form_data['answers_by_title']['请输入手机号']) ? $form_data['answers_by_title']['请输入手机号'] : '');
|
||
$stmt->bindValue(':name', isset($form_data['answers_by_title']['怎么称呼您']) ? $form_data['answers_by_title']['怎么称呼您'] : '');
|
||
|
||
// 处理车牌号字段(只使用qid为t2u2i4、type为licensePlate的车牌号字段)
|
||
$license_plate = '';
|
||
if (isset($form_data['answers_by_qid']['t2u2i4'])) {
|
||
$license_plate = $form_data['answers_by_qid']['t2u2i4'];
|
||
}
|
||
$stmt->bindValue(':license_plate', $license_plate);
|
||
|
||
// 日期处理
|
||
$date = isset($form_data['answers_by_title']['日期']) ? $form_data['answers_by_title']['日期'] : '';
|
||
$stmt->bindValue(':date', $date ? date('Y-m-d', strtotime($date)) : null);
|
||
|
||
// 绑定实际存在的其他字段
|
||
$stmt->bindValue(':time_slot', isset($form_data['answers_by_title']['单选项']) ? $form_data['answers_by_title']['单选项'] : '');
|
||
$stmt->bindValue(':car_type', isset($form_data['answers_by_title']['车型']) ? $form_data['answers_by_title']['车型'] : '');
|
||
$stmt->bindValue(':has_car_coat', isset($form_data['answers_by_title']['是否有车衣']) ? $form_data['answers_by_title']['是否有车衣'] : '');
|
||
$stmt->bindValue(':car_wash_habit', isset($form_data['answers_by_title']['有无自己撸车习惯']) ? $form_data['answers_by_title']['有无自己撸车习惯'] : '');
|
||
$stmt->bindValue(':car_wash_experience', isset($form_data['answers_by_title']['撸车经验']) ? $form_data['answers_by_title']['撸车经验'] : '');
|
||
$stmt->bindValue(':wash_frequency', isset($form_data['answers_by_title']['洗车频率']) ? $form_data['answers_by_title']['洗车频率'] : '');
|
||
$stmt->bindValue(':age_group', isset($form_data['answers_by_title']['请选择年龄段']) ? $form_data['answers_by_title']['请选择年龄段'] : '');
|
||
$stmt->bindValue(':remarks', isset($form_data['answers_by_title']['备注内容']) ? $form_data['answers_by_title']['备注内容'] : '');
|
||
$stmt->bindValue(':auto_number', isset($form_data['answers_by_title']['自动编号']) ? $form_data['answers_by_title']['自动编号'] : '');
|
||
$stmt->bindValue(':status', 'pending');
|
||
|
||
// 执行SQL
|
||
$stmt->execute();
|
||
|
||
log_message("表单数据成功存储到数据库,插入ID: " . $pdo->lastInsertId());
|
||
return true;
|
||
} catch (Exception $e) {
|
||
log_message("数据存储失败: " . $e->getMessage(), 'error');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
?>
|