Initial commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
(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);
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user