Files
wushu/ht/api.php
2026-03-30 07:32:12 +08:00

327 lines
11 KiB
PHP

<?php
header('Content-Type: application/json; charset=UTF-8');
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once('../../includes/common.php');
$debug_info = [];
$debug_info['current_dir'] = __DIR__;
$debug_info['current_file'] = __FILE__;
$debug_info['require_path'] = '../../includes/common.php';
$debug_info['file_exists'] = file_exists('../../includes/common.php') ? 'yes' : 'no';
$debug_info['parent_dir'] = dirname(__DIR__);
$debug_info['DB_isset'] = isset($DB) ? 'yes' : 'no';
if (isset($DB)) {
$debug_info['DB_methods'] = get_class_methods($DB);
}
if (isset($_GET['api'])) {
$api = $_GET['api'];
if ($api === 'captcha') {
session_start();
$num1 = mt_rand(1, 10);
$num2 = mt_rand(1, 10);
$answer = $num1 + $num2;
$captcha_key = 'captcha_' . session_id();
$_SESSION[$captcha_key] = (string)$answer;
echo json_encode([
'ok' => true,
'num1' => $num1,
'num2' => $num2
], JSON_UNESCAPED_UNICODE);
exit;
}
if ($api === 'categories') {
try {
$categories = [];
$debug_info['DB_findAll_exists'] = method_exists($DB, 'findAll') ? 'yes' : 'no';
if ($DB && method_exists($DB, 'findAll')) {
$categories = $DB->findAll('category', '*', null, 'sid asc');
$debug_info['categories_count'] = count($categories);
}
if (empty($categories)) {
$categories = [
['catename' => '唐诗'],
['catename' => '宋词'],
['catename' => '元曲'],
['catename' => '诗词句'],
['catename' => '现代诗']
];
$debug_info['used_fallback'] = 'yes';
}
echo json_encode([
'ok' => true,
'categories' => $categories,
'debug' => $debug_info
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
$debug_info['exception'] = $e->getMessage();
echo json_encode([
'ok' => true,
'categories' => [
['catename' => '唐诗'],
['catename' => '宋词'],
['catename' => '元曲'],
['catename' => '诗词句'],
['catename' => '现代诗']
],
'debug' => $debug_info
], JSON_UNESCAPED_UNICODE);
}
exit;
}
if ($api === 'check-name') {
if (!isset($_POST['name'])) {
echo json_encode(['ok' => false, 'error' => '缺少name参数']);
exit;
}
try {
$name = trim($_POST['name']);
$exists = false;
$similar_count = 0;
$max_similarity = 0;
$threshold = isset($_POST['threshold']) ? intval($_POST['threshold']) : 80;
$threshold = max(0, min(100, $threshold));
if ($DB && method_exists($DB, 'findAll')) {
$tables_to_check = ['site', 'apply'];
foreach ($tables_to_check as $table) {
$all_records = $DB->findAll($table, 'name');
if ($all_records) {
foreach ($all_records as $record) {
$db_name = trim($record['name']);
if ($db_name === $name) {
$exists = true;
$max_similarity = 100;
$similar_count = 1;
break 2;
}
$similarity = calculateSimilarity($name, $db_name);
if ($similarity >= $threshold) {
$similar_count++;
if ($similarity > $max_similarity) {
$max_similarity = $similarity;
}
}
}
}
}
}
if ($max_similarity >= $threshold) {
$exists = true;
}
echo json_encode([
'ok' => true,
'exists' => $exists,
'similar_count' => $similar_count,
'max_similarity' => $max_similarity,
'threshold' => $threshold
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode([
'ok' => true,
'exists' => false,
'similar_count' => 0,
'max_similarity' => 0,
'threshold' => 80
], JSON_UNESCAPED_UNICODE);
}
exit;
}
if ($api === 'submit') {
$submit_debug = [];
session_start();
$client_ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$rate_limit_key = 'submit_rate_' . $client_ip;
if (!isset($_SESSION[$rate_limit_key])) {
$_SESSION[$rate_limit_key] = [];
}
$current_time = time();
$_SESSION[$rate_limit_key] = array_filter($_SESSION[$rate_limit_key], function($time) use ($current_time) {
return ($current_time - $time) < 60;
});
if (count($_SESSION[$rate_limit_key]) >= 3) {
echo json_encode(['ok' => false, 'error' => '提交过于频繁,请稍后再试']);
exit;
}
$img = isset($_POST['img']) ? trim($_POST['img']) : '';
$isFlutter = strpos($img, 'Flutter') !== false;
$required = ['name', 'catename', 'url', 'keywords', 'introduce'];
if (!$isFlutter) {
$required[] = 'captcha';
}
foreach ($required as $field) {
if (!isset($_POST[$field]) || empty(trim($_POST[$field]))) {
echo json_encode(['ok' => false, 'error' => "缺少必填字段:{$field}"]);
exit;
}
}
if (!$isFlutter) {
$captcha = trim($_POST['captcha']);
$captcha_key = 'captcha_' . session_id();
if (!isset($_SESSION[$captcha_key]) || $_SESSION[$captcha_key] != $captcha) {
echo json_encode(['ok' => false, 'error' => '验证码错误,请重新输入']);
exit;
}
unset($_SESSION[$captcha_key]);
}
try {
$name = trim($_POST['name']);
$threshold = isset($_POST['threshold']) ? intval($_POST['threshold']) : 80;
$threshold = max(0, min(100, $threshold));
$similar_exists = false;
if ($DB && method_exists($DB, 'findAll')) {
$tables_to_check = ['site', 'apply'];
foreach ($tables_to_check as $table) {
$all_records = $DB->findAll($table, 'name');
if ($all_records) {
foreach ($all_records as $record) {
$db_name = trim($record['name']);
if ($db_name === $name) {
$similar_exists = true;
break 2;
}
$similarity = calculateSimilarity($name, $db_name);
if ($similarity >= $threshold) {
$similar_exists = true;
break 2;
}
}
}
}
}
if ($similar_exists) {
echo json_encode(['ok' => false, 'error' => '该诗词已存在!']);
exit;
}
$catename = trim($_POST['catename']);
$url = trim($_POST['url']);
$keywords = trim($_POST['keywords']);
$introduce = trim($_POST['introduce']);
$img = isset($_POST['img']) ? trim($_POST['img']) : 'default';
$submit_debug['input_data'] = [
'name' => $name,
'catename' => $catename,
'url' => $url,
'keywords' => $keywords,
'introduce' => $introduce,
'img' => $img
];
$data = [
'name' => $name,
'img' => $img,
'catename' => $catename,
'url' => $url,
'keywords' => $keywords,
'introduce' => $introduce,
'reject' => 0,
'create_time' => date('Y-m-d H:i:s'),
'update_time' => date('Y-m-d H:i:s')
];
$submit_debug['insert_data'] = $data;
$submit_debug['DB_insert_exists'] = method_exists($DB, 'insert') ? 'yes' : 'no';
$result = false;
$db_error = '';
if ($DB && method_exists($DB, 'insert')) {
$result = $DB->insert('apply', $data);
$submit_debug['insert_result'] = $result;
if (method_exists($DB, 'error')) {
$db_error = $DB->error();
$submit_debug['db_error'] = $db_error;
}
if (method_exists($DB, 'lastInsertId')) {
$submit_debug['last_insert_id'] = $DB->lastInsertId();
}
}
if ($result) {
$_SESSION[$rate_limit_key][] = $current_time;
echo json_encode([
'ok' => true,
'message' => '✅ 提交成功!等待审核',
'debug' => $submit_debug
], JSON_UNESCAPED_UNICODE);
} else {
echo json_encode([
'ok' => false,
'error' => '❌ 数据库写入失败:无法插入数据',
'debug' => $submit_debug
], JSON_UNESCAPED_UNICODE);
}
} catch (Exception $e) {
$submit_debug['exception'] = $e->getMessage();
$submit_debug['trace'] = $e->getTraceAsString();
echo json_encode([
'ok' => false,
'error' => $e->getMessage(),
'debug' => $submit_debug
], JSON_UNESCAPED_UNICODE);
}
exit;
}
}
function calculateSimilarity($str1, $str2) {
$str1 = preg_replace('/[^\p{L}\p{N}\s]/u', '', $str1);
$str2 = preg_replace('/[^\p{L}\p{N}\s]/u', '', $str2);
$str1 = preg_replace('/\s+/', '', $str1);
$str2 = preg_replace('/\s+/', '', $str2);
$len1 = mb_strlen($str1, 'UTF-8');
$len2 = mb_strlen($str2, 'UTF-8');
if ($len1 === 0 || $len2 === 0) {
return 0;
}
$maxLen = max($len1, $len2);
$distance = levenshtein($str1, $str2);
if ($distance === 0) {
return 100;
}
$similarity = round((1 - $distance / $maxLen) * 100, 2);
return max(0, min(100, $similarity));
}
echo json_encode(['ok' => false, 'error' => '无效的API请求']);