feat: 添加WPS表单处理功能及相关测试

实现WPS表单Webhook接收端点,包括数据解析、验证和存储功能
添加数据库表创建脚本和测试用例
包含Webhook测试页面和日志功能
This commit is contained in:
2025-12-05 13:58:57 +08:00
parent 3f4c26b1fa
commit 5bbb0877d5
4 changed files with 785 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
-- 创建WPS表单数据表
CREATE TABLE IF NOT EXISTS wps_form_submissions (
id INT AUTO_INCREMENT PRIMARY KEY,
rid VARCHAR(50) NOT NULL COMMENT '表单提交ID',
form_id VARCHAR(50) NOT NULL COMMENT '表单ID',
form_title VARCHAR(255) NOT NULL COMMENT '表单标题',
creator_id VARCHAR(50) NOT NULL COMMENT '创建者ID',
create_time DATETIME NOT NULL COMMENT '创建时间',
update_time DATETIME NOT NULL COMMENT '更新时间',
nick_name VARCHAR(255) COMMENT '创建者昵称',
department VARCHAR(255) COMMENT '创建者部门',
mobile VARCHAR(20) COMMENT '请输入手机号',
name VARCHAR(255) COMMENT '怎么称呼您',
license_plate VARCHAR(20) COMMENT '车牌号',
date DATE COMMENT '日期',
time_slot VARCHAR(20) COMMENT '时间段',
car_type VARCHAR(50) COMMENT '车型',
wash_type VARCHAR(100) COMMENT '洗车类型',
wash_packages VARCHAR(255) COMMENT '洗车套餐',
wash_services TEXT COMMENT '洗车服务',
additional_services TEXT COMMENT '额外服务',
need_wax VARCHAR(10) COMMENT '是否需要打蜡',
wax_type VARCHAR(50) COMMENT '蜡的类型',
cleaning_needs TEXT COMMENT '清洁需求',
interior_cleaning VARCHAR(10) COMMENT '是否需要内饰清洁',
exterior_cleaning VARCHAR(10) COMMENT '是否需要外观清洁',
vip_member VARCHAR(10) COMMENT '是否为VIP会员',
vip_number VARCHAR(50) COMMENT 'VIP卡号',
payment_method VARCHAR(50) COMMENT '支付方式',
special_requests TEXT COMMENT '特殊要求',
technician VARCHAR(50) COMMENT '指定技师',
status VARCHAR(20) DEFAULT 'pending' COMMENT '状态',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
INDEX idx_rid (rid),
INDEX idx_license_plate (license_plate),
INDEX idx_date (date),
INDEX idx_mobile (mobile)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+124
View File
@@ -0,0 +1,124 @@
<?php
// 测试数据库连接和表创建功能
require_once 'config.php';
// 记录日志的函数
function log_test_message($message, $type = 'info') {
$log_file = 'test_db.log';
$timestamp = date('Y-m-d H:i:s');
$log_entry = "[$timestamp] [$type] $message\n";
file_put_contents($log_file, $log_entry, FILE_APPEND);
echo $log_entry;
}
echo "=== 测试数据库连接和表创建功能 ===\n";
// 测试数据库连接
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);
log_test_message("数据库连接成功");
} catch(PDOException $e) {
log_test_message("数据库连接失败: " . $e->getMessage(), 'error');
exit(1);
}
// 测试创建表
try {
$sql = "CREATE TABLE IF NOT EXISTS wps_form_submissions (
id INT AUTO_INCREMENT PRIMARY KEY,
rid VARCHAR(50) NOT NULL COMMENT '表单提交ID',
form_id VARCHAR(50) NOT NULL COMMENT '表单ID',
form_title VARCHAR(255) NOT NULL COMMENT '表单标题',
creator_id VARCHAR(50) NOT NULL COMMENT '创建者ID',
create_time DATETIME NOT NULL COMMENT '创建时间',
update_time DATETIME NOT NULL COMMENT '更新时间',
mobile VARCHAR(20) COMMENT '请输入手机号',
name VARCHAR(255) COMMENT '怎么称呼您',
license_plate VARCHAR(20) COMMENT '车牌号',
date DATE COMMENT '日期',
time_slot VARCHAR(20) COMMENT '时间段',
car_type VARCHAR(50) COMMENT '车型',
wash_type VARCHAR(100) COMMENT '洗车类型',
wash_packages VARCHAR(255) COMMENT '洗车套餐',
wash_services TEXT COMMENT '洗车服务',
additional_services TEXT COMMENT '额外服务',
need_wax VARCHAR(10) COMMENT '是否需要打蜡',
wax_type VARCHAR(50) COMMENT '蜡的类型',
cleaning_needs TEXT COMMENT '清洁需求',
interior_cleaning VARCHAR(10) COMMENT '是否需要内饰清洁',
exterior_cleaning VARCHAR(10) COMMENT '是否需要外观清洁',
vip_member VARCHAR(10) COMMENT '是否为VIP会员',
vip_number VARCHAR(50) COMMENT 'VIP卡号',
payment_method VARCHAR(50) COMMENT '支付方式',
special_requests TEXT COMMENT '特殊要求',
technician VARCHAR(50) COMMENT '指定技师',
status VARCHAR(20) DEFAULT 'pending' COMMENT '状态',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
INDEX idx_rid (rid),
INDEX idx_license_plate (license_plate),
INDEX idx_date (date),
INDEX idx_mobile (mobile)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
$pdo->exec($sql);
log_test_message("表创建成功");
} catch(PDOException $e) {
log_test_message("表创建失败: " . $e->getMessage(), 'error');
exit(1);
}
// 测试插入数据
try {
$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
) VALUES (
:rid, :form_id, :form_title, :creator_id, :create_time, :update_time,
:mobile, :name, :license_plate, :date, :time_slot, :car_type
)";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':rid', 'test_rid_' . time());
$stmt->bindValue(':form_id', 'test_form_id');
$stmt->bindValue(':form_title', '测试表单');
$stmt->bindValue(':creator_id', 'test_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(':mobile', '13800138000');
$stmt->bindValue(':name', '测试用户');
$stmt->bindValue(':license_plate', '京A12345');
$stmt->bindValue(':date', date('Y-m-d'));
$stmt->bindValue(':time_slot', '14:00-15:00');
$stmt->bindValue(':car_type', '轿车');
$stmt->execute();
$insert_id = $pdo->lastInsertId();
log_test_message("测试数据插入成功,ID: " . $insert_id);
} catch(PDOException $e) {
log_test_message("测试数据插入失败: " . $e->getMessage(), 'error');
exit(1);
}
// 测试查询数据
try {
$sql = "SELECT * FROM wps_form_submissions ORDER BY id DESC LIMIT 1";
$stmt = $pdo->query($sql);
$row = $stmt->fetch();
if ($row) {
log_test_message("测试数据查询成功");
log_test_message("查询结果: " . print_r($row, true));
} else {
log_test_message("测试数据查询失败: 没有找到数据", 'error');
}
} catch(PDOException $e) {
log_test_message("测试数据查询失败: " . $e->getMessage(), 'error');
exit(1);
}
echo "\n=== 所有测试完成 ===\n";
+263
View File
@@ -0,0 +1,263 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WPS表单Webhook测试</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.container {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #333;
text-align: center;
}
.test-section {
margin: 20px 0;
padding: 15px;
background-color: white;
border-radius: 4px;
border: 1px solid #ddd;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background-color: #45a049;
}
.response {
margin-top: 10px;
padding: 10px;
background-color: #f0f0f0;
border-radius: 4px;
white-space: pre-wrap;
font-family: monospace;
}
.log-section {
margin-top: 30px;
}
#log-content {
height: 300px;
overflow-y: auto;
background-color: #2d2d2d;
color: #f0f0f0;
padding: 10px;
border-radius: 4px;
font-family: monospace;
}
</style>
</head>
<body>
<div class="container">
<h1>WPS表单Webhook测试工具</h1>
<div class="test-section">
<h2>1. 验证请求测试</h2>
<p>模拟WPS表单的验证请求,Webhook应返回绑定码</p>
<button onclick="testVerification()">发送验证请求</button>
<div class="response" id="verification-response"></div>
</div>
<div class="test-section">
<h2>2. 表单数据测试</h2>
<p>模拟WPS表单发送数据,Webhook应接收并处理数据</p>
<button onclick="testFormData()">发送表单数据</button>
<div class="response" id="form-data-response"></div>
</div>
<div class="log-section">
<h2>3. Webhook日志</h2>
<button onclick="loadLog()">加载日志</button>
<button onclick="clearLog()">清空日志</button>
<div id="log-content"></div>
</div>
</div>
<script>
// Webhook URL
const webhookUrl = 'http://localhost:8000/webhook.php';
// 发送验证请求
async function testVerification() {
const responseDiv = document.getElementById('verification-response');
responseDiv.innerHTML = '发送中...';
try {
const response = await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: '' // 空请求体,模拟验证请求
});
const data = await response.json();
responseDiv.innerHTML = '响应: ' + JSON.stringify(data, null, 2);
} catch (error) {
responseDiv.innerHTML = '错误: ' + error.message;
}
}
// 发送表单数据
async function testFormData() {
const responseDiv = document.getElementById('form-data-response');
responseDiv.innerHTML = '发送中...';
// 模拟WPS实际表单数据格式
const formData = {
"rid": "lAFP6N1Tap",
"formId": "20251205123619412736007",
"formTitle": "张老师撸车(私家车库)预约撸车表单",
"aid": "20251205131620432762589",
"eventTs": Date.now(),
"messageTs": Date.now(),
"creatorId": "344573037",
"creatorName": "吴展鹏",
"event": "create_answer",
"version": 2,
"answerContents": [
{
"qid": "eo513g",
"type": "input",
"title": "怎么称呼您",
"value": "吴展鹏"
},
{
"qid": "xKFUcp",
"type": "input",
"title": "车型",
"value": "比亚迪宋PRODMi"
},
{
"qid": "NFJDDT",
"type": "input",
"title": "车牌号",
"value": "新AF10365-普通输入"
},
{
"qid": "t2u2i4",
"type": "licensePlate",
"title": "车牌号",
"value": "新AF10365-车牌专用"
},
{
"qid": "7jgfmh",
"type": "telphone",
"title": "请输入手机号",
"value": "18699627661"
},
{
"qid": "3j6opi",
"type": "select",
"title": "是否有车衣",
"value": ["否,无车衣"]
},
{
"qid": "ej48lk",
"type": "select",
"title": "有无自己撸车习惯",
"value": ["有"]
},
{
"qid": "1tnljp",
"type": "select",
"title": "撸车经验",
"value": ["我是老司机啦"]
},
{
"qid": "x02g35",
"type": "select",
"title": "洗车频率",
"value": ["每2周一次(每月1-2次)"]
},
{
"qid": "54dbo7",
"type": "select",
"title": "请选择年龄段",
"value": ["26~30"]
},
{
"qid": "rwxgkc",
"type": "autoNum",
"title": "自动编号",
"value": "zlslc202512002"
},
{
"qid": "r3ft9n",
"type": "input",
"title": "备注内容",
"value": "谢谢"
}
]
};
try {
const response = await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
});
const data = await response.json();
responseDiv.innerHTML = '响应: ' + JSON.stringify(data, null, 2);
} catch (error) {
responseDiv.innerHTML = '错误: ' + error.message;
}
}
// 加载日志
async function loadLog() {
const logContent = document.getElementById('log-content');
logContent.innerHTML = '加载中...';
try {
const response = await fetch('wps_form_webhook.log');
if (response.ok) {
const text = await response.text();
logContent.innerHTML = text;
} else {
logContent.innerHTML = '无法加载日志文件: ' + response.statusText;
}
} catch (error) {
logContent.innerHTML = '错误: ' + error.message;
}
}
// 清空日志
async function clearLog() {
const logContent = document.getElementById('log-content');
try {
const response = await fetch('webhook.php?action=clear_log', {
method: 'POST'
});
if (response.ok) {
logContent.innerHTML = '日志已清空';
} else {
logContent.innerHTML = '清空日志失败';
}
} catch (error) {
logContent.innerHTML = '错误: ' + error.message;
}
}
</script>
</body>
</html>
+359
View File
@@ -0,0 +1,359 @@
<?php
// WPS表单Webhook接收端点
// 设置响应头
header('Content-Type: application/json; charset=utf-8');
// 绑定码(根据WPS表单要求提供)
$bind_code = '20251205123619412736007';
// 日志文件路径
$log_file = '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;
}
}
// 字段对照表(根据提供的文档)
$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'),
'车牌号2' => array('7nAOz7', 'input'),
'车牌号' => array('NFJDDT', 'input'), // 注意:有两个车牌号字段,这里是第一个
'怎么称呼您' => array('eo513g', 'input'),
'车型' => array('xKFUcp', 'input'),
'车牌号' => array('t2u2i4', 'licensePlate'), // 注意:有两个车牌号字段,这里是第二个
'请输入手机号' => 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";
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;
}
// 处理实际的表单数据
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;
}
// 创建表(如果不存在)
create_wps_form_table($pdo);
// 准备SQL语句
$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,
wash_type, wash_packages, wash_services, additional_services, need_wax,
wax_type, cleaning_needs, interior_cleaning, exterior_cleaning, vip_member,
vip_number, payment_method, special_requests, technician, status
) VALUES (
:rid, :form_id, :form_title, :creator_id, :create_time, :update_time,
:mobile, :name, :license_plate, :date, :time_slot, :car_type,
:wash_type, :wash_packages, :wash_services, :additional_services, :need_wax,
:wax_type, :cleaning_needs, :interior_cleaning, :exterior_cleaning, :vip_member,
:vip_number, :payment_method, :special_requests, :technician, :status
)";
$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(':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']['怎么称呼您'] : '');
// 处理车牌号字段(优先使用licensePlate类型的)
$license_plate = '';
if (isset($form_data['answers_by_qid']['t2u2i4'])) {
$license_plate = $form_data['answers_by_qid']['t2u2i4'];
} elseif (isset($form_data['answers_by_title']['车牌号'])) {
$license_plate = $form_data['answers_by_title']['车牌号'];
}
$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(':wash_type', isset($form_data['answers_by_title']['洗车类型']) ? $form_data['answers_by_title']['洗车类型'] : '');
$stmt->bindValue(':wash_packages', isset($form_data['answers_by_title']['洗车套餐']) ? $form_data['answers_by_title']['洗车套餐'] : '');
$stmt->bindValue(':wash_services', isset($form_data['answers_by_title']['洗车服务']) ? $form_data['answers_by_title']['洗车服务'] : '');
$stmt->bindValue(':additional_services', isset($form_data['answers_by_title']['额外服务']) ? $form_data['answers_by_title']['额外服务'] : '');
$stmt->bindValue(':need_wax', isset($form_data['answers_by_title']['是否需要打蜡']) ? $form_data['answers_by_title']['是否需要打蜡'] : '');
$stmt->bindValue(':wax_type', isset($form_data['answers_by_title']['蜡的类型']) ? $form_data['answers_by_title']['蜡的类型'] : '');
$stmt->bindValue(':cleaning_needs', isset($form_data['answers_by_title']['清洁需求']) ? $form_data['answers_by_title']['清洁需求'] : '');
$stmt->bindValue(':interior_cleaning', isset($form_data['answers_by_title']['是否需要内饰清洁']) ? $form_data['answers_by_title']['是否需要内饰清洁'] : '');
$stmt->bindValue(':exterior_cleaning', isset($form_data['answers_by_title']['是否需要外观清洁']) ? $form_data['answers_by_title']['是否需要外观清洁'] : '');
$stmt->bindValue(':vip_member', isset($form_data['answers_by_title']['是否为VIP会员']) ? $form_data['answers_by_title']['是否为VIP会员'] : '');
$stmt->bindValue(':vip_number', isset($form_data['answers_by_title']['VIP卡号']) ? $form_data['answers_by_title']['VIP卡号'] : '');
$stmt->bindValue(':payment_method', isset($form_data['answers_by_title']['支付方式']) ? $form_data['answers_by_title']['支付方式'] : '');
$stmt->bindValue(':special_requests', isset($form_data['answers_by_title']['特殊要求']) ? $form_data['answers_by_title']['特殊要求'] : '');
$stmt->bindValue(':technician', 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;
}
}
// 创建WPS表单数据表
function create_wps_form_table($pdo) {
try {
$sql = "CREATE TABLE IF NOT EXISTS wps_form_submissions (
id INT AUTO_INCREMENT PRIMARY KEY,
rid VARCHAR(50) NOT NULL COMMENT '表单提交ID',
form_id VARCHAR(50) NOT NULL COMMENT '表单ID',
form_title VARCHAR(255) NOT NULL COMMENT '表单标题',
creator_id VARCHAR(50) NOT NULL COMMENT '创建者ID',
create_time DATETIME NOT NULL COMMENT '创建时间',
update_time DATETIME NOT NULL COMMENT '更新时间',
mobile VARCHAR(20) COMMENT '请输入手机号',
name VARCHAR(255) COMMENT '怎么称呼您',
license_plate VARCHAR(20) COMMENT '车牌号',
date DATE COMMENT '日期',
time_slot VARCHAR(20) COMMENT '时间段',
car_type VARCHAR(50) COMMENT '车型',
wash_type VARCHAR(100) COMMENT '洗车类型',
wash_packages VARCHAR(255) COMMENT '洗车套餐',
wash_services TEXT COMMENT '洗车服务',
additional_services TEXT COMMENT '额外服务',
need_wax VARCHAR(10) COMMENT '是否需要打蜡',
wax_type VARCHAR(50) COMMENT '蜡的类型',
cleaning_needs TEXT COMMENT '清洁需求',
interior_cleaning VARCHAR(10) COMMENT '是否需要内饰清洁',
exterior_cleaning VARCHAR(10) COMMENT '是否需要外观清洁',
vip_member VARCHAR(10) COMMENT '是否为VIP会员',
vip_number VARCHAR(50) COMMENT 'VIP卡号',
payment_method VARCHAR(50) COMMENT '支付方式',
special_requests TEXT COMMENT '特殊要求',
technician VARCHAR(50) COMMENT '指定技师',
status VARCHAR(20) DEFAULT 'pending' COMMENT '状态',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
INDEX idx_rid (rid),
INDEX idx_license_plate (license_plate),
INDEX idx_date (date),
INDEX idx_mobile (mobile)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
$pdo->exec($sql);
return true;
} catch (Exception $e) {
log_message("创建表失败: " . $e->getMessage(), 'error');
return false;
}
}
?>