79 lines
3.1 KiB
HTML
79 lines
3.1 KiB
HTML
<!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>
|