s6-chat-interface.md
3.14 KB
S6: 聊天界面 — 气泡 + 输入框 + 流式渲染
目标
在 aichat.html 的主区域(#chatArea)实现完整的聊天界面:
- 用户消息气泡(右侧蓝色)
- AI 消息气泡(左侧灰色)
- 底部输入框 + 发送按钮
- 流式渲染:SSE 实时推送 AI 回复,逐词显示
- Enter 发送 / Shift+Enter 换行
- Loading 指示器(AI 思考中)
- 自动滚动到底部
- 切换到不同会话时加载历史消息
涉及文件
templates/aichat.html— 唯一修改文件
依赖(已验证)
local_db.py: conversations/messages 表 ✓, conv_list/msg_list/msg_add 等函数 ✓app.py:- /api/conversations ✓
- /api/conversations//messages GET ✓
- /api/conversations//messages POST ✓
- /api/conversations//stream SSE ✓
- /chat → aichat.html ✓
数据流
用户输入 → POST /api/conversations/<id>/messages → 保存 user msg
→ call_hermes()
→ 保存 assistant msg
→ 返回 JSON
或者:用户输入 → GET /api/conversations/<id>/stream?message=xxx
→ SSE text/event-stream
→ 前端逐 chunk 渲染
→ [DONE] 后追加到消息列表
两者都可用。POST 模式适合简单场景,SSE 适合流式。同时支持。
步骤
- CSS: 添加消息气泡样式(user/assistant)、输入区域样式、loading 动画
- HTML: 替换 #chatArea 的 .empty-state 为 .messages-container + .input-area
- JS: 实现
selectConversation(id)加载历史消息 - JS: 实现
sendMessage()— SSE 流式发送 + 渲染 - JS: 实现流式 chunk 渲染、完成标记、自动滚动
- JS: Enter 发送 / Shift+Enter 换行
验证命令
# 1. 页面能打开
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/chat
# 2. 关键 JS 函数存在
curl -s http://127.0.0.1:5000/chat | grep "function sendMessage"
curl -s http://127.0.0.1:5000/chat | grep "function selectConversation"
# 3. JS 无转义错误
curl -s http://127.0.0.1:5000/chat | python3 -c "
import sys; html=sys.stdin.read()
assert \"style=\\\\\\\\'\" not in html, 'STYLE BACKSLASH BUG'
assert \"\\\\\\\\\\\\\\\\\\\\\\\"'\" not in html, 'TRIPLE ESCAPE BUG'
print('JS CLEAN')
"
# 4. 关键 DOM 元素存在
curl -s http://127.0.0.1:5000/chat | grep 'id="msgList"'
curl -s http://127.0.0.1:5000/chat | grep 'id="msgInput"'
curl -s http://127.0.0.1:5000/chat | grep 'id="sendBtn"'
# 5. 无 onclick 转义陷阱
curl -s http://127.0.0.1:5000/chat | python3 -c "
import sys; html=sys.stdin.read()
assert 'toggleContent(' not in html, 'ONCLICK ESCAPE BUG'
assert '\\\\\\'' not in html, 'BACKSLASH SINGLE QUOTE'
print('ONCLICK CLEAN')
"
# 6. smoketest
cd ~/wechat-viewer && python3 test_smoke.py
风险
- SSE 实现需注意连接断开后的清理
- 消息气泡中 Markdown/代码块渲染(基础实现即可,不做复杂格式化)
- 自动滚动需在流式刷新时保持体验
- 不要用
\\'转义 onclick(直接使用 data 属性 + addEventListener 或避免引号嵌套)