327 lines
11 KiB
PHP
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请求']);
|