模板里怎么添加ai对话功能?

Tanmer

发布于:2025-08-14

1️⃣ Ai对话对应 HTML代码片段

<div id="js--ai-search-completion-container"
     data-controller="ai-search-completion"
     data-ai-search-completion-hidden-class="hidden opacity-0"
     data-ai-search-completion-url-value="/-/ai-search-completion"
     data-ai-search-completion-auto-submit-value="true"
     data-ai-search-completion-messages-value='{"thinking":"AI 正在思考...","completed":"AI 已完成","canceled":"已取消回答"}'>

  <!-- 消息显示容器 -->
  <div data-ai-search-completion-target="messages" class="chat-container overflow-y-auto gap-2 ai-response prose scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100">
  </div>

  <!-- 用户消息模板 -->
  <template data-ai-search-completion-target="userMessageTemplate">
    <div class="flex gap-3 justify-end items-start">
      <div class="text-right">
        <div class="inline-block p-3 max-w-xs break-words rounded-xl rounded-br-none bg-base-200 text-base-content ai-user-message">
        </div>
        <div class="mt-2 text-sm font-medium text-base-content/80">{{ current_user.name }}</div>
      </div>
      <img src="{{ current_user.image | default: avatar }}" class="w-10 h-10 rounded-full" />
    </div>
  </template>

  <!-- AI 消息模板 -->
  <template data-ai-search-completion-target="assistantMessageTemplate">
    <div class="flex gap-3 items-start">
      <div class="avatar avatar-online avatar-placeholder">
        <div class="w-10 rounded-full bg-neutral text-neutral-content">
          <span class="text-xl">AI</span>
        </div>
      </div>
      <div class="flex-1 min-w-0">
        <div class="p-3 break-words rounded-xl rounded-bl-none text-info-content bg-info w-fit max-w-3/4 ai-assistant-message chat-bubble prose ProseMirror">
        </div>
        <div class="mt-1 text-sm font-medium text-base-content/80">{{ site.settings.robot_name }}</div>
      </div>
    </div>
  </template>

  <!-- 错误显示 -->
  <div data-ai-search-completion-target="error" class="hidden text-red-500 opacity-100 transition-opacity duration-300"></div>

  <!-- 输入框 -->
  <textarea data-ai-search-completion-target="input"
            autocomplete="off"
            class="flex-1 p-2 mr-4 rounded-md border-0 bg-base-300 sm:min-h-20 text-base-content/50 input input-bordered focus:outline-none focus:ring-0 placeholder:text-base-content/60"
            placeholder="请输入你的问题…"></textarea>

  <!-- 发送按钮 -->
  <button data-ai-search-completion-target="send"
          type="button"
          class="text-base btn btn-primary">
    <i class="ri-send-plane-2-fill"></i>
  </button>

  <!-- 可选重试按钮模板(JS 中动态创建) -->
  <button data-ai-search-completion-target="retryButton" class="hidden"></button>
</div>

2️⃣ Stimulus Targets 与 HTML 属性对应表

Target 名称

对应 HTML 属性

作用

备注

messages

data-ai-search-completion-target="messages"

聊天消息显示容器

显示 AI 与用户聊天记录

userMessageTemplate

data-ai-search-completion-target="userMessageTemplate"

用户消息模板

<template> 定义用户消息气泡,用于动态追加用户消息

assistantMessageTemplate

data-ai-search-completion-target="assistantMessageTemplate"

AI 消息模板

<template> 定义 AI 消息气泡,用于动态追加 AI 消息

error

data-ai-search-completion-target="error"

错误消息显示容器

显示网络或系统错误,可隐藏/显示

input

data-ai-search-completion-target="input"

用户输入框

用户输入聊天内容或搜索关键词

send

data-ai-search-completion-target="send"

发送按钮

点击触发 #sendUserMessage()

retryButton

data-ai-search-completion-target="retryButton"

AI 消息重试按钮

用于 AI 响应出错时,用户点击重新发送消息。可以自定义按钮,也可以由 JS 创建默认按钮


3️⃣ Stimulus Values 对应 HTML 属性

Stimulus Value

类型

HTML 属性写法

说明

url

String

data-ai-search-completion-url-value="/-/ai-search-completion"

AI 消息请求的接口 URL,sendMessage 会向这个地址发送请求。必须以完整路径写入。

timeout

Number

data-ai-search-completion-timeout-value="30"

超时时间(秒),超过这个时间未返回结果会显示“响应超时,请重试”。可选。

autoSubmit

Boolean

data-ai-search-completion-auto-submit-value="true"

是否开启自动提交,当 messageValue 变化时自动发送。默认 false

message

String

data-ai-search-completion-message-value=""

页面加载或外部触发的初始消息,例如跳转搜索页携带的关键词。通常为空,由 JS 更新。

messages

Object

data-ai-search-completion-messages-value='{"thinking":"AI 正在思考...","completed":"已完成回答","canceled":"已取消回答"}'

用于显示默认文本,如 AI 正在思考、已完成、已取消等状态提示。


4️⃣ Stimulus Classes

Class 名称

HTML 属性

作用

hidden

data-ai-search-completion-hidden-class

用于隐藏元素,例如错误信息容器


5️⃣ 流程概览

  1. 用户在 data-ai-search-completion-target="input"输入消息 → 按回车或点击 data-ai-search-completion-target="send"

  2. 调用 #sendUserMessage() → 清空输入框 → 调用 sendMessage(message)

  3. sendMessage 使用 EventSourceurl 发送消息

  4. SSE 流式返回:

    • status=streaming → 实时更新 AI 消息内容

    • status=completed → AI 消息完成,追加 messagesValue.completed 提示

    • status=error → 显示错误消息 + 重试按钮

  5. 页面消息追加使用 userMessageTemplateTargetassistantMessageTemplateTarget


6️⃣ 历史会话消息获取

后端 Liquid 获取示例

{% assign chat_messages = site.chat_messages | order_by: '-created_at' | limit: 10 %}
<div class="overflow-y-auto gap-2 ai-response prose scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100">
  {% for message in chat_messages reversed %}
    {% if message.role == 'user' %}
      <div class="ai-user-message">{{ message.content }}</div>
    {% else %}
      <div class="ai-assistant-message">{{ message.content }}</div>
    {% endif %}
  {% endfor %}
</div>

实践要点:

  • 使用 reversed 将时间倒序的数据正序显示(旧消息在上)。


7️⃣页面初始化或外部触发初始消息

<script>
(function () {
  setTimeout(function () {
    const aiSearchCompletion = document.getElementById('js--ai-search-completion');
    if(aiSearchCompletion){
      aiSearchCompletion.dataset.aiSearchCompletionMessageValue = "{{ search.keywords | escape_once }}";
      setTimeout(function () {
        const messagesElement = document.querySelector('[data-ai-search-completion-target="messages"]');
        if(messagesElement){
          messagesElement.scrollIntoView({ block: 'end', behavior: 'auto' });
        }
      }, 1000);
    }
  }, 1000);
})();
</script>

实践要点:

  • data-ai-search-completion-message-value 用于初始化页面消息,或者外部 JS 触发发送初始查询。也可以在元素上直接设置data-ai-search-completion-message-value

  • 结合 Stimulus Controller 的 messageValueChanged() 可以在页面加载时自动提交消息。


提交反馈