2026-06-14 14:00:24 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 安装程序数据库结构(ip_groups / ip_list / visitor_logs)
|
|
|
|
|
|
*/
|
|
|
|
|
|
class InstallSchema
|
|
|
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @return string[] 按顺序执行的 DDL(IF NOT EXISTS,可重复运行)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function statements()
|
|
|
|
|
|
{
|
|
|
|
|
|
return [
|
|
|
|
|
|
"CREATE TABLE IF NOT EXISTS `ip_groups` (
|
|
|
|
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
|
|
|
|
`name` varchar(100) NOT NULL COMMENT '组名',
|
|
|
|
|
|
`type` enum('black','white') NOT NULL COMMENT '类型:black为黑名单,white为白名单',
|
|
|
|
|
|
PRIMARY KEY (`id`)
|
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci",
|
|
|
|
|
|
|
|
|
|
|
|
"CREATE TABLE IF NOT EXISTS `ip_list` (
|
|
|
|
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
|
|
|
|
`group_id` int(11) NOT NULL COMMENT '所属组ID',
|
|
|
|
|
|
`ip_address` varchar(45) NOT NULL COMMENT 'IP地址',
|
|
|
|
|
|
PRIMARY KEY (`id`),
|
|
|
|
|
|
KEY `idx_group_ip` (`group_id`,`ip_address`)
|
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci",
|
|
|
|
|
|
|
|
|
|
|
|
"CREATE TABLE IF NOT EXISTS `cloak_site_domains` (
|
|
|
|
|
|
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
|
|
|
|
`hostname` varchar(255) NOT NULL COMMENT '站点域名',
|
|
|
|
|
|
`config_name` varchar(64) NOT NULL DEFAULT '' COMMENT '关联配置名',
|
|
|
|
|
|
`cf_zone_id` varchar(64) DEFAULT NULL COMMENT 'Cloudflare Zone ID',
|
|
|
|
|
|
`cf_nameservers` text DEFAULT NULL COMMENT 'Cloudflare NS JSON',
|
|
|
|
|
|
`cf_status` varchar(32) NOT NULL DEFAULT 'local' COMMENT 'Cloudflare 状态',
|
|
|
|
|
|
`cf_error` varchar(500) DEFAULT NULL COMMENT '最近错误',
|
|
|
|
|
|
`cf_checked_at` datetime DEFAULT NULL COMMENT '上次检测时间',
|
|
|
|
|
|
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
|
|
|
|
|
|
PRIMARY KEY (`id`),
|
|
|
|
|
|
UNIQUE KEY `uk_hostname` (`hostname`),
|
|
|
|
|
|
KEY `idx_config_name` (`config_name`)
|
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci",
|
|
|
|
|
|
|
2026-07-06 10:34:34 +08:00
|
|
|
|
"CREATE TABLE IF NOT EXISTS `cloak_config_domain` (
|
|
|
|
|
|
`config_name` varchar(64) NOT NULL COMMENT 'check_config 配置名',
|
|
|
|
|
|
`domain_id` int(11) UNSIGNED NOT NULL COMMENT 'cloak_site_domains.id',
|
|
|
|
|
|
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
|
|
|
|
|
|
PRIMARY KEY (`config_name`),
|
|
|
|
|
|
KEY `idx_domain_id` (`domain_id`)
|
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci",
|
|
|
|
|
|
|
2026-06-14 14:00:24 +08:00
|
|
|
|
"CREATE TABLE IF NOT EXISTS `visitor_logs` (
|
|
|
|
|
|
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
|
|
|
|
`campagin_id` varchar(20) NOT NULL COMMENT '策略ID',
|
|
|
|
|
|
`visit_md5_code` char(32) NOT NULL DEFAULT 'loss' COMMENT '客户端标记',
|
|
|
|
|
|
`domain` varchar(35) NOT NULL COMMENT '域名',
|
|
|
|
|
|
`visit_date` datetime NOT NULL COMMENT '访问日期',
|
|
|
|
|
|
`IP` varchar(150) NOT NULL COMMENT 'IP',
|
|
|
|
|
|
`country` varchar(10) DEFAULT NULL COMMENT '国家',
|
|
|
|
|
|
`result` char(5) DEFAULT NULL COMMENT '判断结果',
|
|
|
|
|
|
`reason` varchar(100) DEFAULT NULL COMMENT '判断理由',
|
|
|
|
|
|
`referer` text DEFAULT NULL COMMENT '来源',
|
|
|
|
|
|
`vtimes` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '第几次访问',
|
|
|
|
|
|
`client` varchar(20) DEFAULT NULL COMMENT '客户端',
|
|
|
|
|
|
`browser` varchar(20) DEFAULT NULL COMMENT '浏览器',
|
|
|
|
|
|
`device` varchar(300) DEFAULT NULL COMMENT '设备',
|
|
|
|
|
|
`page` text DEFAULT NULL COMMENT '浏览页面',
|
|
|
|
|
|
`fp_url` text DEFAULT NULL COMMENT '跳转页面',
|
|
|
|
|
|
`language` varchar(300) DEFAULT NULL COMMENT '语言',
|
|
|
|
|
|
`user_agent` text DEFAULT NULL COMMENT 'User-Agent 完整值',
|
|
|
|
|
|
`http_referer` text DEFAULT NULL COMMENT 'HTTP Referer 完整值',
|
|
|
|
|
|
`accept_language_raw` text DEFAULT NULL COMMENT 'Accept-Language 完整值',
|
|
|
|
|
|
`judge_timing` text DEFAULT NULL COMMENT '判定用时 JSON',
|
2026-06-14 18:30:06 +08:00
|
|
|
|
`fp_hdata` text DEFAULT NULL COMMENT '指纹 hdata 解码 JSON',
|
2026-06-15 16:53:05 +08:00
|
|
|
|
`api_by_request` text DEFAULT NULL COMMENT 'byApi 请求参数 JSON',
|
|
|
|
|
|
`api_by_response` text DEFAULT NULL COMMENT 'byApi 响应 JSON',
|
|
|
|
|
|
`api_risk_request` text DEFAULT NULL COMMENT 'byApiRisk 请求参数 JSON',
|
|
|
|
|
|
`api_risk_response` text DEFAULT NULL COMMENT 'byApiRisk 响应 JSON',
|
2026-06-15 22:42:59 +08:00
|
|
|
|
`is_simulation` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否模拟测试',
|
|
|
|
|
|
`sim_source_log_id` int(11) UNSIGNED DEFAULT NULL COMMENT '模拟重放来源日志 ID',
|
2026-06-14 14:00:24 +08:00
|
|
|
|
`add_time` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '日志记录时间',
|
|
|
|
|
|
PRIMARY KEY (`id`),
|
|
|
|
|
|
KEY `IP` (`IP`),
|
|
|
|
|
|
KEY `idx_visit_date` (`visit_date`),
|
|
|
|
|
|
KEY `idx_result` (`result`),
|
|
|
|
|
|
KEY `idx_domain_date` (`domain`, `visit_date`),
|
|
|
|
|
|
KEY `idx_country` (`country`)
|
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci",
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @param mysqli $conn 已连接目标库
|
|
|
|
|
|
* @return array{ok:bool,error?:string,tables?:string[]}
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function install($conn)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!$conn->set_charset('utf8mb4')) {
|
|
|
|
|
|
return ['ok' => false, 'error' => '设置字符集 utf8mb4 失败:' . $conn->error];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (self::statements() as $sql) {
|
|
|
|
|
|
if (!$conn->query($sql)) {
|
|
|
|
|
|
return [
|
|
|
|
|
|
'ok' => false,
|
|
|
|
|
|
'error' => $conn->error,
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
'ok' => true,
|
2026-07-06 10:34:34 +08:00
|
|
|
|
'tables' => ['ip_groups', 'ip_list', 'cloak_site_domains', 'cloak_config_domain', 'visitor_logs'],
|
2026-06-14 14:00:24 +08:00
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|