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 适合流式。同时支持。

步骤

  1. CSS: 添加消息气泡样式(user/assistant)、输入区域样式、loading 动画
  2. HTML: 替换 #chatArea 的 .empty-state 为 .messages-container + .input-area
  3. JS: 实现 selectConversation(id) 加载历史消息
  4. JS: 实现 sendMessage() — SSE 流式发送 + 渲染
  5. JS: 实现流式 chunk 渲染、完成标记、自动滚动
  6. 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 或避免引号嵌套)