feat: 完成 issue #77 [Ti-1] 前端对话组件集成
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>iAOP 对话助手</title>
|
||||
<style>
|
||||
/* iAOP 对话组件(issue #77):深色主题,对齐驾驶舱 */
|
||||
body { margin:0; font-family: "Microsoft YaHei", sans-serif; background:#0f172a; color:#e2e8f0; }
|
||||
#app { max-width: 720px; margin: 0 auto; padding: 16px; }
|
||||
h1 { font-size: 18px; color:#38bdf8; }
|
||||
#messages { height: 420px; overflow-y:auto; border:1px solid #1e293b; border-radius:8px;
|
||||
padding:12px; background:#111c33; }
|
||||
.msg { margin: 8px 0; }
|
||||
.msg .who { font-size:12px; color:#94a3b8; }
|
||||
.msg .text { display:inline-block; max-width:85%; padding:8px 12px; border-radius:8px; white-space:pre-wrap; }
|
||||
.user .text { background:#1d4ed8; }
|
||||
.bot .text { background:#1e293b; }
|
||||
.meta { font-size:11px; color:#64748b; margin-top:2px; }
|
||||
#panel { margin-top:10px; display:flex; gap:8px; }
|
||||
select, input { padding:8px; border-radius:6px; border:1px solid #334155; background:#0b1526; color:#e2e8f0; }
|
||||
input { flex:1; }
|
||||
button { padding:8px 16px; border:none; border-radius:6px; background:#0ea5e9; color:#fff; cursor:pointer; }
|
||||
button:disabled { opacity:.5; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<h1>iAOP 对话助手(Template-Ti 一期)</h1>
|
||||
<div id="messages"></div>
|
||||
<div id="panel">
|
||||
<select id="scenario">
|
||||
<option value="nl_query">自然语言查询</option>
|
||||
<option value="alarm_explain">报警解释</option>
|
||||
<option value="shift_handover">交接班摘要</option>
|
||||
</select>
|
||||
<input id="question" placeholder="请输入问题,如:氯气流量最近1小时趋势">
|
||||
<button id="send" onclick="send()">发送</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const el = id => document.getElementById(id);
|
||||
function addMsg(who, text, meta) {
|
||||
const box = el('messages');
|
||||
const div = document.createElement('div');
|
||||
div.className = 'msg ' + who;
|
||||
div.innerHTML = '<div class="who">' + (who === 'user' ? '我' : 'iAOP') + '</div>' +
|
||||
'<div class="text"></div>' + (meta ? '<div class="meta">' + meta + '</div>' : '');
|
||||
div.querySelector('.text').textContent = text;
|
||||
box.appendChild(div);
|
||||
box.scrollTop = box.scrollHeight;
|
||||
}
|
||||
async function send() {
|
||||
const question = el('question').value.trim();
|
||||
if (!question) return;
|
||||
const scenario = el('scenario').value;
|
||||
addMsg('user', question);
|
||||
el('question').value = ''; el('send').disabled = true;
|
||||
try {
|
||||
const resp = await fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ question, scenario })
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (data.error) addMsg('bot', '错误:' + data.error);
|
||||
else addMsg('bot', data.answer,
|
||||
'路由: ' + data.route + ' | 场景: ' + data.scenario +
|
||||
(data.needs_human ? ' | ⚠ 转人工确认' : ''));
|
||||
} catch (e) {
|
||||
addMsg('bot', '请求失败:' + e);
|
||||
} finally {
|
||||
el('send').disabled = false;
|
||||
}
|
||||
}
|
||||
el('question').addEventListener('keydown', e => { if (e.key === 'Enter') send(); });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user