Files
wushu/ht/index.php
2026-03-30 06:42:59 +08:00

373 lines
17 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>诗词收录 - 古诗词鉴赏平台</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="header">
<h1>📜 诗词收录</h1>
<p>收录经典诗词,传承中华文化</p>
</div>
<div class="card">
<div id="alert" class="alert"></div>
<form id="submitForm">
<div class="form-group">
<label for="name">参考语句 <span class="required">*</span></label>
<div class="input-wrapper">
<input type="text" id="name" name="name" class="form-control" placeholder="请输入参考语句(如:纤云弄巧,飞星传恨)" required>
<span class="icon" id="nameIcon"></span>
</div>
<div class="threshold-wrapper">
<label for="threshold">相似度阈值 (%)</label>
<input type="number" id="threshold" name="threshold" class="form-control threshold-input" value="80" min="0" max="100" step="1">
<button type="button" class="btn btn-secondary" onclick="checkName()">🔍 检测是否存在</button>
</div>
<div id="similarityInfo" class="similarity-info"></div>
</div>
<div class="form-group">
<label for="catename">分类 <span class="required">*</span></label>
<select id="catename" name="catename" class="form-control" required>
<option value="">请选择分类</option>
</select>
</div>
<div class="form-group">
<label for="url">诗人和标题 <span class="required">*</span></label>
<input type="text" id="url" name="url" class="form-control" placeholder="请输入诗人和标题(如:李白 静夜思)" required>
</div>
<div class="form-group">
<label for="keywords">关键词 <span class="required">*</span></label>
<input type="text" id="keywords" name="keywords" class="form-control" placeholder="请输入关键词,用逗号分隔(如:思乡,月亮,唐诗)" required>
</div>
<div class="form-group">
<label for="img">平台(可选)</label>
<input type="text" id="img" name="img" class="form-control" placeholder="请输入平台名称(如:安卓 Flutter">
</div>
<div class="form-group">
<label for="introduce">诗词介绍 <span class="required">*</span></label>
<textarea id="introduce" name="introduce" class="form-control" placeholder="请输入诗词详细介绍..." required></textarea>
</div>
<div class="form-group">
<label for="captcha">人机验证 <span class="required">*</span></label>
<div class="captcha-wrapper">
<div class="captcha-question" id="captchaQuestion"></div>
<input type="text" id="captcha" name="captcha" class="form-control captcha-input" placeholder="请输入答案" required>
<button type="button" class="btn btn-secondary refresh-btn" onclick="generateCaptcha()">🔄 刷新</button>
</div>
</div>
<button type="submit" id="submitBtn" class="btn btn-primary btn-block">
<span class="loading" id="loading"></span>
<span id="btnText">📝 提交收录</span>
</button>
</form>
<div class="debug-section">
<h3>🔧 开发者调试工具</h3>
<button class="debug-btn" onclick="fillTestData()">填充测试数据</button>
<button class="debug-btn" onclick="clearForm()">清空表单</button>
<button class="debug-btn" onclick="toggleDebugLog()">显示/隐藏日志</button>
<div id="debugLog" class="debug-log"></div>
</div>
</div>
</div>
<div id="resultModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<span id="modalIcon"></span>
<h2 id="modalTitle"></h2>
</div>
<div class="modal-body">
<p id="modalMessage"></p>
</div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="closeModal()">确定</button>
</div>
</div>
</div>
<script>
let nameChecked = false;
let nameExists = false;
async function generateCaptcha() {
try {
const response = await fetch('api.php?api=captcha');
const data = await response.json();
if (data.ok) {
document.getElementById('captchaQuestion').textContent = `${data.num1} + ${data.num2} = ?`;
document.getElementById('captcha').value = '';
}
} catch (error) {
addLog('获取验证码失败: ' + error.message);
}
}
function showModal(type, title, message) {
const modal = document.getElementById('resultModal');
const icon = document.getElementById('modalIcon');
const modalTitle = document.getElementById('modalTitle');
const modalMessage = document.getElementById('modalMessage');
icon.textContent = type === 'success' ? '✅' : '❌';
modalTitle.textContent = title;
modalMessage.textContent = message;
modal.classList.add('show');
}
function closeModal() {
const modal = document.getElementById('resultModal');
modal.classList.remove('show');
}
function showAlert(message, type = 'info') {
const alert = document.getElementById('alert');
alert.className = `alert alert-${type} show`;
alert.innerHTML = `<span>${type === 'success' ? '✅' : type === 'error' ? '❌' : ''}</span> ${message}`;
if (type !== 'error') {
setTimeout(() => alert.classList.remove('show'), 5000);
}
}
function addLog(message) {
const log = document.getElementById('debugLog');
const time = new Date().toLocaleTimeString();
const item = document.createElement('div');
item.className = 'log-item';
item.innerHTML = `<span class="log-time">[${time}]</span>${message}`;
log.appendChild(item);
log.scrollTop = log.scrollHeight;
}
function toggleDebugLog() {
document.getElementById('debugLog').classList.toggle('show');
}
async function loadCategories() {
try {
addLog('正在加载分类数据...');
const response = await fetch('api.php?api=categories');
addLog('API响应状态: ' + response.status);
const data = await response.json();
addLog('API返回数据: ' + JSON.stringify(data));
if (data.debug) {
addLog('🔍 调试信息:');
Object.entries(data.debug).forEach(([key, value]) => {
addLog(` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`);
});
}
if (data.ok && data.categories && data.categories.length > 0) {
const select = document.getElementById('catename');
select.innerHTML = '<option value="">请选择分类</option>';
data.categories.forEach(cat => {
const option = document.createElement('option');
option.value = cat.catename;
option.textContent = cat.catename;
select.appendChild(option);
});
addLog(`✅ 分类加载成功,共 ${data.categories.length} 个分类`);
} else {
addLog('⚠️ 分类加载失败或无数据');
}
} catch (error) {
addLog('❌ 分类加载异常: ' + error.message);
}
}
async function checkName() {
const name = document.getElementById('name').value.trim();
const icon = document.getElementById('nameIcon');
const input = document.getElementById('name');
const similarityInfo = document.getElementById('similarityInfo');
const threshold = parseInt(document.getElementById('threshold').value) || 80;
if (!name) {
icon.className = 'icon';
input.className = 'form-control';
similarityInfo.innerHTML = '';
nameChecked = false;
nameExists = false;
return;
}
try {
addLog(`检查名称: ${name}, 阈值: ${threshold}%`);
const formData = new FormData();
formData.append('name', name);
formData.append('threshold', threshold);
const response = await fetch('api.php?api=check-name', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.ok) {
nameChecked = true;
nameExists = data.exists;
if (data.exists) {
icon.className = 'icon error';
icon.textContent = '❌';
input.className = 'form-control invalid';
let infoHtml = `<div class="similarity-item error">`;
infoHtml += `<span class="similarity-label">⚠️ 发现相似内容</span>`;
if (data.similar_count > 0) {
infoHtml += `<span class="similarity-count">相似 ${data.similar_count} 条</span>`;
}
if (data.max_similarity > 0) {
infoHtml += `<span class="similarity-percent">最高相似度 ${data.max_similarity}%</span>`;
}
infoHtml += `</div>`;
similarityInfo.innerHTML = infoHtml;
addLog(`名称已存在,相似度 ${data.max_similarity}%,相似 ${data.similar_count} 条`);
} else {
icon.className = 'icon success';
icon.textContent = '✅';
input.className = 'form-control valid';
let infoHtml = `<div class="similarity-item success">`;
infoHtml += `<span class="similarity-label">✅ 未发现相似内容</span>`;
if (data.max_similarity > 0) {
infoHtml += `<span class="similarity-percent">最高相似度 ${data.max_similarity}%</span>`;
}
infoHtml += `</div>`;
similarityInfo.innerHTML = infoHtml;
addLog('名称可用');
}
}
} catch (error) {
addLog('检查名称异常: ' + error.message);
}
}
function fillTestData() {
document.getElementById('name').value = '将进酒';
document.getElementById('url').value = '李白 将进酒';
document.getElementById('keywords').value = '豪放,饮酒,唐诗';
document.getElementById('img').value = 'iOS Swift';
document.getElementById('introduce').value = '《将进酒》是唐代大诗人李白沿用乐府古题创作的七言歌行。此诗思想内容非常深沉,艺术表现非常成熟,在同题作品中影响最大。诗人豪饮高歌,借酒消愁,抒发了忧愤深广的人生感慨。';
addLog('测试数据已填充');
checkName();
}
function clearForm() {
document.getElementById('submitForm').reset();
document.getElementById('nameIcon').className = 'icon';
document.getElementById('name').className = 'form-control';
document.getElementById('alert').classList.remove('show');
nameChecked = false;
nameExists = false;
addLog('表单已清空');
}
function setLoading(loading) {
const btn = document.getElementById('submitBtn');
const loadingEl = document.getElementById('loading');
const btnText = document.getElementById('btnText');
btn.disabled = loading;
loadingEl.classList.toggle('show', loading);
btnText.textContent = loading ? '提交中...' : '📝 提交收录';
}
document.getElementById('name').addEventListener('blur', checkName);
document.getElementById('name').addEventListener('input', () => {
nameChecked = false;
document.getElementById('nameIcon').className = 'icon';
document.getElementById('name').className = 'form-control';
});
document.getElementById('submitForm').addEventListener('submit', async (e) => {
e.preventDefault();
const name = document.getElementById('name').value.trim();
const catename = document.getElementById('catename').value;
const url = document.getElementById('url').value;
const keywords = document.getElementById('keywords').value;
const introduce = document.getElementById('introduce').value;
if (!nameChecked) {
await checkName();
}
if (nameExists) {
showAlert('该诗词名称已存在,请更换一个', 'error');
addLog('提交被阻止:名称已存在');
return;
}
const confirmMessage = `确认提交以下信息?\n\n诗词名称${name}\n分类${catename}\n诗人和标题${url}\n关键词${keywords}\n诗词介绍${introduce.substring(0, 50)}${introduce.length > 50 ? '...' : ''}`;
if (!confirm(confirmMessage)) {
addLog('用户取消提交');
return;
}
setLoading(true);
showAlert('正在提交...', 'info');
addLog('开始提交表单...');
try {
const formData = new FormData(e.target);
const response = await fetch('api.php?api=submit', {
method: 'POST',
body: formData
});
const data = await response.json();
addLog('API返回数据: ' + JSON.stringify(data));
if (data.debug) {
addLog('🔍 提交调试信息:');
Object.entries(data.debug).forEach(([key, value]) => {
addLog(` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`);
});
}
if (data.ok) {
showModal('success', '提交成功', data.message);
clearForm();
generateCaptcha();
addLog('提交成功');
} else {
showModal('error', '提交失败', data.error);
addLog('提交失败: ' + data.error);
}
} catch (error) {
showAlert('提交失败,请稍后重试', 'error');
addLog('提交异常: ' + error.message);
} finally {
setLoading(false);
}
});
document.addEventListener('DOMContentLoaded', () => {
loadCategories();
generateCaptcha();
addLog('页面加载完成');
});
</script>
</body>
</html>