Files
2026-05-15 17:08:05 +00:00

104 lines
5.3 KiB
JavaScript

(function() {
var chatCreated = false;
function createChat() {
if (chatCreated) return;
chatCreated = true;
const chat = document.createElement('div');
chat.id = 'ai-chat';
chat.style.cssText = 'display:none;position:fixed;bottom:20px;right:20px;width:460px;height:640px;background:#1e2130;border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,0.6);z-index:9999;flex-direction:column;overflow:hidden;border:1px solid #374151;';
chat.innerHTML = '<div style="background:#1a1f35;padding:14px 16px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #374151"><span style="color:#60a5fa;font-weight:bold;font-size:15px">🔍 YBIH 智能助手</span><button id="ai-chat-close" style="background:none;border:none;color:#aaa;font-size:20px;cursor:pointer">✕</button></div><div id="ai-messages" style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px"><div style="background:#2d3250;border-radius:12px;padding:12px;color:#94a3b8;font-size:13px">👋 你好!请输入问题搜索知识库。</div></div><div style="padding:12px;border-top:1px solid #374151;display:flex;gap:8px"><input id="ai-input" placeholder="输入问题..." style="flex:1;background:#2d3250;border:1px solid #374151;border-radius:8px;padding:10px 12px;color:#fff;font-size:14px;outline:none"/><button id="ai-send" style="background:#3b82f6;border:none;border-radius:8px;padding:10px 16px;color:#fff;cursor:pointer;font-size:14px;font-weight:bold">发送</button></div>';
document.body.appendChild(chat);
document.getElementById('ai-chat-close').onclick = function() { chat.style.display = 'none'; };
async function sendMessage() {
const input = document.getElementById('ai-input');
const q = input.value.trim();
if (!q) return;
input.value = '';
const messages = document.getElementById('ai-messages');
const userMsg = document.createElement('div');
userMsg.style.cssText = 'background:#3b82f6;border-radius:12px 12px 4px 12px;padding:10px 14px;color:#fff;font-size:14px;align-self:flex-end;max-width:85%;word-break:break-all';
userMsg.textContent = q;
messages.appendChild(userMsg);
const aiMsg = document.createElement('div');
aiMsg.style.cssText = 'background:#2d3250;border-radius:12px 12px 12px 4px;padding:14px;color:#e2e8f0;font-size:14px;max-width:100%';
aiMsg.innerHTML = '<span style="color:#94a3b8">⏳ 搜索中...</span>';
messages.appendChild(aiMsg);
messages.scrollTop = messages.scrollHeight;
try {
const res = await fetch('/aisearch?q=' + encodeURIComponent(q));
const data = await res.json();
let html = '';
if (data.sources && data.sources.length) {
const sorted = data.sources.slice().sort((a,b) => a.score - b.score);
html += '<div style="color:#64748b;font-size:12px;margin-bottom:8px">📄 相关文章(相关度从低到高)</div>';
for (const s of sorted) {
html += '<div style="margin-bottom:10px;padding:10px;background:#1e2130;border-radius:8px;border:1px solid #374151"><a href="'+s.url+'" target="_blank" style="color:#60a5fa;font-size:13px;font-weight:bold;text-decoration:none;display:block;margin-bottom:4px">'+s.title+'</a><div style="color:#94a3b8;font-size:12px;line-height:1.5">'+s.content+'</div><div style="color:#475569;font-size:11px;margin-top:4px">相关度 '+Math.round(s.score*100)+'%</div></div>';
}
}
html += '<div style="line-height:1.7;margin-top:14px;border-top:1px solid #374151;padding-top:12px;color:#e2e8f0;font-size:13px">' + (data.answer||'') + '</div>';
aiMsg.innerHTML = html;
} catch(err) {
aiMsg.innerHTML = '<span style="color:#ef4444">搜索失败: ' + err.message + '</span>';
}
messages.scrollTop = messages.scrollHeight;
}
document.getElementById('ai-send').onclick = sendMessage;
document.getElementById('ai-input').addEventListener('keydown', function(e) {
if (e.key === 'Enter') sendMessage();
});
}
// 在 document 级别捕获所有 keydown 事件
document.addEventListener('keydown', function(e) {
if (e.key !== 'Enter') return;
const t = e.target;
if (!t || (t.tagName !== 'INPUT' && t.tagName !== 'TEXTAREA')) return;
// 判断是搜索框(不是 ai-input 自己)
if (t.id === 'ai-input') return;
const q = t.value.trim();
if (!q) return;
e.preventDefault();
e.stopImmediatePropagation();
createChat();
t.value = '';
const chat = document.getElementById('ai-chat');
chat.style.display = 'flex';
chat.style.flexDirection = 'column';
document.getElementById('ai-input').value = q;
document.getElementById('ai-send').click();
}, true);
// 同时拦截 form submit
document.addEventListener('submit', function(e) {
const input = e.target.querySelector('input');
if (!input || input.id === 'ai-input') return;
const q = input.value.trim();
if (!q) return;
e.preventDefault();
e.stopImmediatePropagation();
createChat();
input.value = '';
const chat = document.getElementById('ai-chat');
chat.style.display = 'flex';
chat.style.flexDirection = 'column';
document.getElementById('ai-input').value = q;
document.getElementById('ai-send').click();
}, true);
})();