feat: 2026-07-12~13 全量更新 - AI对话链路改造+H5 v4/v5+坐席端v5+上下文感知诊断+知识库迭代3
## H5 员工端 v4 (2026-07-13 00:48 已部署)
- 人工按钮三态文案统一为"人工坐席"
- 按钮位置移至发送键和语音按钮上方(垂直堆叠)
- 点按钮直接调 store.shakeAgent(),删除 CallAgentModal 弹窗动画
- 截图快捷键提示改为"截图->粘贴:Alt+Shift+A-Ctrl+V ---> Ctrl+V"
- 移动端隐藏截图提示(CSS 媒体查询)
- AI转人工提示改为"已为您呼叫人工坐席,请稍等!"
- 坐席接入提示改为"坐席正在查看您的信息,请等待处理回复!"
- 删除"摇铃呼叫坐席"入口和文案
- 删除孤儿组件 MessageList.vue + shake 动画 CSS
## H5 员工端 v5 (2026-07-13 02:08 已部署)
- RightPanel v2.1:删除"软件安装"和"资源权限"标签页
- 移除标签栏,智能推荐(DynamicRecommend)直接展示
- 删除 SoftwareDownloads/ApprovalLinks 引用和相关 CSS
## AI 对话链路全栈改造 Phase 1-6 (已部署)
- Phase 1: Dify JSON输出 + 后端blocking解析 + 双WS推送 + 错误降级
- Phase 2: 关键词收窄(~25强意图词) + 两级分类Prompt + 删除前端checkApprovalIntent
- Phase 3: WS扩展(ai_thinking+dynamic_recommend) + ai_structured气泡 + RightPanel v2 + 选项回传
- Phase 4: VisionService接入 + 图片消息融合(5秒窗口) + 降级策略
- Phase 5: 坐席端ai_thinking指示器 + ai_structured/byod_card渲染 + handleNewMessage修复
- Phase 6: diagnosis_stage(6值) + response_time_ms计时 + 慢响应告警(>10s)
## 坐席端 v5 (2026-07-13 01:38 已部署)
- ai_structured/byod_card 只读渲染
- AI思考指示器 UI
- handleNewMessage 透传 msg_type/extra_data 修复
- 布局优化v2.0: QuickReplyBar L1+L2悬浮 + ReplyBox左右分区 + 右栏260/560px切换
- 键盘快捷键v2.3: 纯数字路由 + ESC分层撤销 + Shift+Space用event.code
## 上下文感知智能诊断闭环 (2026-07-12 已部署)
- 三层诊断(API→Script→AI) + 三段排队(VIP→info_locked→not locked)
- 答题插队 + 五场景关闭
- 迁移052(6表+6列) + queue_service + quiz_service + closing_service
- H5前端: QueueWaiting + RightPanel双Tab + InputBar三态 + ResolveConfirmCard
- 坐席前端: pending_close结单流程 + 信息锁定(Dify步骤完成+有效回答率≥70%)
## 知识库迭代3 (2026-07-12 已部署)
- 分诊交互(H5+坐席+Dify独立应用)
- 拓扑预览(ECharts只读)
- 代答排除(4种匹配器: keyword/regex/intent/category)
- 迁移051 + 44文件43测试通过
## 后端变更
- 6个Python文件改造(h5_ai_task.py/h5.py/ai_service.py/closing_service.py等)
- funny_phrase_service.py: shake/connected/keyword 默认文案更新
- session_service.py: 企微消息文案同步
- 新增: queue.py/quiz.py/triage.py/exclusion_rules.py 等API端点
- 新增: diagnostic.py/quiz.py/triage_session.py 等模型
- 新增: closing_service/queue_service/quiz_service/triage_service 等服务
## 文档更新
- CHANGELOG.md: 新增 [未发布] 区全部变更记录
- 项目管理主文档 v2.5: 新增v0.7.3版本 + 已完成看板 + 最近搞定
- 版本记录: 新增v0.7.3条目
- AI对话链路实施计划: Phase 1-6 全部标记✅已实施
- 新增架构图/时序图/类图(mermaid)
## 部署路径修正
- 服务器项目根路径: /opt/wecom-it-desk/
- 所有前端dist均为ro bind mount,只能在宿主机源路径操作
- 服务器nginx /h5/ 是静态文件服务(非proxy_pass)
- elFinder上传二进制不可靠(MD5不匹配),改用base64分块上传
This commit is contained in:
@@ -21,7 +21,7 @@ import {
|
||||
shake,
|
||||
getApprovalLinks,
|
||||
getSoftwareDownloads,
|
||||
detectApprovalIntent,
|
||||
// v2.0: detectApprovalIntent 已移除(审批意图识别统一由后端处理)
|
||||
leaveAsParticipant as leaveAsParticipantApi,
|
||||
type UserInfo,
|
||||
type ConversationInfo,
|
||||
@@ -35,6 +35,8 @@ import {
|
||||
type ParticipantItem,
|
||||
} from '@/api/conversation'
|
||||
import { useEmployeeStore } from '@/stores/employee'
|
||||
// v2.0: 导入 WS 发送函数(用于选项选择回传)
|
||||
import { sendWsMessage } from '@/composables/useH5WebSocket'
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// 本地缓存配置
|
||||
@@ -186,6 +188,29 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
/** 参与者面板是否展开 */
|
||||
const participantPanelVisible = ref<boolean>(false)
|
||||
|
||||
// ==========================================================================
|
||||
// v2.0 新增:动态推荐状态(侧边栏卡片推送)
|
||||
// ==========================================================================
|
||||
/**
|
||||
* 动态推荐卡片列表(由后端 WS dynamic_recommend 推送)
|
||||
* 做什么:存储 AI 推荐的审批/操作入口卡片,供 RightPanel 的 DynamicRecommend 组件渲染
|
||||
* 为什么:审批卡片从聊天流移到侧边栏,与文字回复强关联但不打断对话
|
||||
* 最多保留 3 张,超过时移除最旧的
|
||||
*/
|
||||
const dynamicRecommendations = ref<Array<{
|
||||
recommend_id: string
|
||||
card_type: string
|
||||
title: string
|
||||
description: string
|
||||
approval_type?: string
|
||||
confidence: number
|
||||
message_id: string
|
||||
conversation_id: string
|
||||
}>>([])
|
||||
|
||||
/** 动态推荐未查看数量(用于 Badge 红点提示) */
|
||||
const unreadRecommendCount = ref<number>(0)
|
||||
|
||||
// ==========================================================================
|
||||
// 流式 AI 回复(打字机)临时状态 — 改造方案 A
|
||||
// ==========================================================================
|
||||
@@ -453,11 +478,9 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
return
|
||||
}
|
||||
|
||||
// 异步检测审批意图(不阻塞消息发送流程)
|
||||
// 员工发消息 → 消息正常发送 → 异步检测审批意图 → 如果命中则在消息列表中插入审批卡片
|
||||
checkApprovalIntent(content).catch((err) => {
|
||||
console.warn('[Store] 审批意图检测异常:', err)
|
||||
})
|
||||
// v2.0 改造(2026-07-13):删除前端 checkApprovalIntent 异步调用
|
||||
// 审批意图识别已统一由后端 process_h5_ai_reply → get_structured_reply 处理
|
||||
// 结果通过 WS dynamic_recommend 推送到侧边栏,不再由前端独立调用
|
||||
|
||||
// ========================================================================
|
||||
// 步骤1:乐观更新 - 立即添加临时消息到列表
|
||||
@@ -743,7 +766,8 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
|
||||
// 如果已分配坐席,更新话术内容
|
||||
if (data.assign_result === 'assigned' && data.assigned_agent_id) {
|
||||
systemMsg.content = `${data.funny_phrase}\n\n🎉 坐席已为您服务,请稍候...`
|
||||
// 2026-07-12 改造:去掉 🎉 emoji,文案与后端 funny_phrases.connected 保持一致
|
||||
systemMsg.content = `${data.funny_phrase}\n\n坐席正在查看您的信息,请等待处理回复!`
|
||||
// 更新会话状态
|
||||
if (currentConversation.value) {
|
||||
currentConversation.value.status = 'serving'
|
||||
@@ -782,41 +806,10 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步检测审批意图
|
||||
* 调用后端 /approval/detect-intent 接口,后端先用关键词预过滤,
|
||||
* 命中后调 Dify 做意图识别。如果检测到审批意图(is_approval_request === true),
|
||||
* 在消息列表中插入一条审批卡片消息(不阻塞消息发送流程)。
|
||||
*
|
||||
* @param text 用户输入的消息文本
|
||||
*/
|
||||
async function checkApprovalIntent(text: string): Promise<void> {
|
||||
try {
|
||||
const response = await detectApprovalIntent(text)
|
||||
console.log('[Store] 审批意图检测结果:', response)
|
||||
|
||||
if (response.is_approval_request) {
|
||||
// 在消息列表中插入审批卡片消息(作为消息流内联卡片,不是弹窗)
|
||||
const approvalCardMessage: Message = {
|
||||
message_id: `approval_card_${Date.now()}`,
|
||||
conversation_id: currentConversation.value?.conversation_id || '',
|
||||
message_type: 'system',
|
||||
msg_type: 'approval_card',
|
||||
content: '',
|
||||
sender_name: '',
|
||||
created_at: new Date().toISOString(),
|
||||
extra_data: {
|
||||
approval_type: response.approval_type,
|
||||
confidence: response.confidence,
|
||||
},
|
||||
}
|
||||
messages.value.push(approvalCardMessage)
|
||||
console.log('[Store] 已插入审批卡片消息, approval_type:', response.approval_type)
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[Store] 审批意图检测失败:', error)
|
||||
}
|
||||
}
|
||||
// v2.0 改造(2026-07-13):checkApprovalIntent() 已删除
|
||||
// 审批意图识别统一由后端 process_h5_ai_reply → get_structured_reply 处理
|
||||
// 结果通过 WS dynamic_recommend 推送到侧边栏 DynamicRecommend 组件
|
||||
// 前端不再独立调用 /approval/detect-intent 接口
|
||||
|
||||
/** 关闭审批卡片弹窗(兼容旧调用,新流程中审批卡片为内联消息,无需关闭) */
|
||||
function closeApprovalCard(): void {
|
||||
@@ -1072,6 +1065,7 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
ai_reply_count: number
|
||||
can_call_agent: boolean
|
||||
conversation_status: string
|
||||
extra_data?: Record<string, any> // v2.0: 结构化消息的 options/action
|
||||
}): void {
|
||||
if (currentConversation.value?.conversation_id !== data.conversation_id) return
|
||||
|
||||
@@ -1084,6 +1078,8 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
sender_name: data.sender_name || 'Duckula(达寇拉)',
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'sent',
|
||||
// v2.0: 传递结构化数据(options 按钮列表、action 卡片信息)
|
||||
extra_data: data.extra_data || undefined,
|
||||
}
|
||||
|
||||
// 用真实消息替换占位气泡(若存在)
|
||||
@@ -1158,8 +1154,148 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
streamingAiMessageId.value = null
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// v2.0 新增:AI 思考指示器 + 动态推荐 + 选项回传
|
||||
// ==========================================================================
|
||||
|
||||
/**
|
||||
* 取消流式气泡(WS 断连时调用)
|
||||
* 处理 WS ai_thinking 消息(v2.0 新增)
|
||||
* 做什么:在消息列表中创建/更新一个"正在思考..."的 AI 占位气泡
|
||||
* 为什么:blocking 模式下 Dify 返回需要 3-8 秒,需要即时反馈让用户知道 AI 在工作
|
||||
*
|
||||
* @param data - { conversation_id, status? }
|
||||
* - status 未定义:首次思考指示,创建占位气泡显示"正在思考..."
|
||||
* - status = "still_thinking":15 秒后更新为"仍在思考..."
|
||||
*/
|
||||
function handleAiThinking(data: { conversation_id: string; status?: string }): void {
|
||||
if (currentConversation.value?.conversation_id !== data.conversation_id) return
|
||||
|
||||
// 如果已有占位气泡(streamingAiMessageId 或 thinking 气泡),更新文字
|
||||
const thinkingId = streamingAiMessageId.value
|
||||
const idx = thinkingId
|
||||
? messages.value.findIndex(m => m.message_id === thinkingId)
|
||||
: -1
|
||||
|
||||
const thinkingText = data.status === 'still_thinking'
|
||||
? '仍在思考中,请稍候...'
|
||||
: '正在思考...'
|
||||
|
||||
if (idx !== -1) {
|
||||
// 更新已有占位气泡的文字
|
||||
messages.value[idx].content = thinkingText
|
||||
} else {
|
||||
// 创建新的占位气泡
|
||||
const tempId = `ai_thinking_${data.conversation_id}_${Date.now()}`
|
||||
streamingAiMessageId.value = tempId
|
||||
messages.value.push({
|
||||
message_id: tempId,
|
||||
conversation_id: data.conversation_id,
|
||||
message_type: 'ai',
|
||||
msg_type: 'text',
|
||||
content: thinkingText,
|
||||
sender_name: 'Duckula(达寇拉)',
|
||||
created_at: new Date().toISOString(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 WS dynamic_recommend 消息(v2.0 新增)
|
||||
* 做什么:将 AI 推荐的操作卡片数据存入 dynamicRecommendations,
|
||||
* RightPanel 的 DynamicRecommend 组件会响应式渲染
|
||||
* 为什么:审批/操作入口从聊天流移到侧边栏,与文字回复强关联但不打断对话
|
||||
*
|
||||
* @param data - 推荐卡片数据 { recommend_id, card_type, title, description, ... }
|
||||
*/
|
||||
function handleDynamicRecommend(data: {
|
||||
recommend_id: string
|
||||
card_type: string
|
||||
title: string
|
||||
description: string
|
||||
approval_type?: string
|
||||
confidence: number
|
||||
message_id: string
|
||||
conversation_id: string
|
||||
}): void {
|
||||
// 添加到推荐列表(最多 3 张,超过时移除最旧的)
|
||||
dynamicRecommendations.value.push(data)
|
||||
if (dynamicRecommendations.value.length > 3) {
|
||||
dynamicRecommendations.value.shift()
|
||||
}
|
||||
// 增加未读计数(用于 Badge 红点提示)
|
||||
unreadRecommendCount.value += 1
|
||||
console.log('[Store] 动态推荐已接收:', data.title, '未读:', unreadRecommendCount.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除未读推荐计数(用户查看侧边栏推荐时调用)
|
||||
*/
|
||||
function clearUnreadRecommend(): void {
|
||||
unreadRecommendCount.value = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定的推荐卡片(用户点击 × 关闭时调用)
|
||||
*/
|
||||
function removeRecommend(recommendId: string): void {
|
||||
const idx = dynamicRecommendations.value.findIndex(r => r.recommend_id === recommendId)
|
||||
if (idx !== -1) {
|
||||
dynamicRecommendations.value.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送选项选择(v2.0 新增)
|
||||
* 做什么:用户点击聊天气泡中的选项按钮后,通过 WS 发送 option_select 消息
|
||||
* 后端接收后转化为 Dify user message,继续对话
|
||||
* 为什么:实现交互式排查的闭环——AI 提问 → 用户点选项 → AI 继续推理
|
||||
*
|
||||
* @param optionValue - 选项的 value 字段(如 "has_code")
|
||||
* @param optionLabel - 选项的 label 字段(如 "有错误代码"),作为用户消息显示
|
||||
*/
|
||||
function sendOptionSelect(optionValue: string, optionLabel: string): void {
|
||||
const convId = currentConversation.value?.conversation_id
|
||||
if (!convId) return
|
||||
|
||||
// 1. 在消息列表中显示用户的选择(作为员工消息)
|
||||
const employeeStore = useEmployeeStore()
|
||||
messages.value.push({
|
||||
message_id: `option_select_${Date.now()}`,
|
||||
conversation_id: convId,
|
||||
message_type: 'employee',
|
||||
msg_type: 'text',
|
||||
content: optionLabel,
|
||||
sender_name: employeeStore.employeeName || '我',
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'sent',
|
||||
})
|
||||
|
||||
// 2. 通过 WS 发送 option_select 消息(v2.0 已接入)
|
||||
// 后端接收后转化为 Dify user message,继续对话
|
||||
// WS 消息格式:{ type: "option_select", data: { conversation_id, option_value, option_label } }
|
||||
const sent = sendWsMessage({
|
||||
type: 'option_select',
|
||||
data: {
|
||||
conversation_id: convId,
|
||||
option_value: optionValue,
|
||||
option_label: optionLabel,
|
||||
},
|
||||
})
|
||||
|
||||
if (!sent) {
|
||||
// WS 未连接,降级为普通消息发送(HTTP API)
|
||||
console.warn('[Store] WS 未连接,选项选择降级为 HTTP 消息发送')
|
||||
// 通过现有的 sendMessage API 发送,后端会走正常 AI 回复流程
|
||||
sendMessage({ content: optionLabel, msg_type: 'text' }).catch((err: unknown) => {
|
||||
console.error('[Store] 选项选择 HTTP 降级发送失败:', err)
|
||||
})
|
||||
}
|
||||
|
||||
console.log('[Store] 选项选择已发送:', optionValue, optionLabel)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消流式占位气泡
|
||||
* 做什么:若 WS 在流式推送中途断开,移除未完成的占位气泡,
|
||||
* 交由 3 秒轮询兜底重新拉取完整 AI 消息
|
||||
* 为什么:避免断连后留下半成品打字气泡
|
||||
@@ -1173,6 +1309,184 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
streamingAiMessageId.value = null
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// 新增:排队/关闭机制 WS 事件处理
|
||||
// ==========================================================================
|
||||
|
||||
/** 排队位置更新数据(来自 WS queue_position_update 事件) */
|
||||
const queuePositionData = ref<{
|
||||
position: number
|
||||
segment: string
|
||||
ahead_count: number
|
||||
queue_priority: number
|
||||
} | null>(null)
|
||||
|
||||
/** 坐席结单请求(来自 WS pending_close_request 事件) */
|
||||
const pendingCloseRequest = ref<{
|
||||
conversation_id: string
|
||||
resolve_summary: string
|
||||
agent_name: string
|
||||
} | null>(null)
|
||||
|
||||
/** 会话已关闭信息(来自 WS conversation_resolved 事件) */
|
||||
const resolvedInfo = ref<{
|
||||
conversation_id: string
|
||||
resolved_by: string
|
||||
resolved_method: string
|
||||
resolve_summary: string
|
||||
} | null>(null)
|
||||
|
||||
/**
|
||||
* 处理排队位置更新事件
|
||||
* WS event: queue_position_update
|
||||
*/
|
||||
function handleQueuePositionUpdate(data: {
|
||||
conversation_id: string
|
||||
position: number
|
||||
segment: string
|
||||
ahead_count: number
|
||||
queue_priority: number
|
||||
}): void {
|
||||
if (currentConversation.value?.conversation_id !== data.conversation_id) return
|
||||
queuePositionData.value = {
|
||||
position: data.position,
|
||||
segment: data.segment,
|
||||
ahead_count: data.ahead_count,
|
||||
queue_priority: data.queue_priority,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理会话关闭事件
|
||||
* WS event: conversation_resolved
|
||||
*/
|
||||
function handleConversationResolved(data: {
|
||||
conversation_id: string
|
||||
status: string
|
||||
resolved_by: string
|
||||
resolved_method: string
|
||||
resolve_summary: string
|
||||
}): void {
|
||||
if (currentConversation.value?.conversation_id !== data.conversation_id) return
|
||||
|
||||
// 更新会话状态
|
||||
if (currentConversation.value) {
|
||||
currentConversation.value.status = 'resolved'
|
||||
}
|
||||
|
||||
resolvedInfo.value = {
|
||||
conversation_id: data.conversation_id,
|
||||
resolved_by: data.resolved_by,
|
||||
resolved_method: data.resolved_method,
|
||||
resolve_summary: data.resolve_summary || '',
|
||||
}
|
||||
|
||||
// 清除结单请求卡片
|
||||
pendingCloseRequest.value = null
|
||||
|
||||
// 添加系统消息
|
||||
const resolveMsg: Message = {
|
||||
message_id: `resolve_${data.conversation_id}_${Date.now()}`,
|
||||
conversation_id: data.conversation_id,
|
||||
message_type: 'system',
|
||||
msg_type: 'text',
|
||||
content: getResolveMessageText(data.resolved_method),
|
||||
sender_name: '系统',
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'sent',
|
||||
}
|
||||
messages.value.push(resolveMsg)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理坐席结单请求
|
||||
* WS event: pending_close_request
|
||||
*/
|
||||
function handlePendingCloseRequest(data: {
|
||||
conversation_id: string
|
||||
resolve_summary: string
|
||||
agent_name: string
|
||||
}): void {
|
||||
if (currentConversation.value?.conversation_id !== data.conversation_id) return
|
||||
|
||||
// 更新会话状态为 pending_close
|
||||
if (currentConversation.value) {
|
||||
currentConversation.value.status = 'waiting' as any // pending_close 映射
|
||||
}
|
||||
|
||||
pendingCloseRequest.value = {
|
||||
conversation_id: data.conversation_id,
|
||||
resolve_summary: data.resolve_summary || '',
|
||||
agent_name: data.agent_name || '坐席',
|
||||
}
|
||||
|
||||
// 添加系统消息提示
|
||||
const systemMsg: Message = {
|
||||
message_id: `pending_close_${data.conversation_id}_${Date.now()}`,
|
||||
conversation_id: data.conversation_id,
|
||||
message_type: 'system',
|
||||
msg_type: 'text',
|
||||
content: `📋 ${data.agent_name || '坐席'}发起了结单请求,请确认`,
|
||||
sender_name: '系统',
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'sent',
|
||||
}
|
||||
messages.value.push(systemMsg)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理诊断答题答案附加到上下文
|
||||
* WS event: quiz_diagnostic_answer
|
||||
*/
|
||||
function handleQuizDiagnosticAnswer(data: {
|
||||
question: string
|
||||
selected_answer: string
|
||||
conversation_id: string
|
||||
}): void {
|
||||
// 添加系统消息,告知用户诊断信息已传递
|
||||
const systemMsg: Message = {
|
||||
message_id: `quiz_diag_${data.conversation_id}_${Date.now()}`,
|
||||
conversation_id: data.conversation_id,
|
||||
message_type: 'system',
|
||||
msg_type: 'text',
|
||||
content: `📝 诊断信息已传递给坐席:${data.question} → ${data.selected_answer}`,
|
||||
sender_name: '系统',
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'sent',
|
||||
}
|
||||
messages.value.push(systemMsg)
|
||||
}
|
||||
|
||||
/** 清除结单请求(确认或拒绝后调用) */
|
||||
function clearPendingCloseRequest(): void {
|
||||
pendingCloseRequest.value = null
|
||||
}
|
||||
|
||||
/** 清除关闭信息(重开会话后调用) */
|
||||
function clearResolvedInfo(): void {
|
||||
resolvedInfo.value = null
|
||||
queuePositionData.value = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关闭方式生成系统消息文本
|
||||
*/
|
||||
function getResolveMessageText(resolvedMethod: string): string {
|
||||
if (resolvedMethod === 'ai_self') {
|
||||
return '✅ 问题已解决,会话已关闭。24小时内可重新打开。'
|
||||
}
|
||||
if (resolvedMethod === 'agent_confirm') {
|
||||
return '✅ 坐席已结单,会话已关闭。24小时内可重新打开。'
|
||||
}
|
||||
if (resolvedMethod === 'employee_initiative') {
|
||||
return '✅ 会话已关闭。24小时内可重新打开。'
|
||||
}
|
||||
if (resolvedMethod === 'system_timeout') {
|
||||
return '⏰ 会话因长时间无响应已自动关闭。24小时内可重新打开。'
|
||||
}
|
||||
return '✅ 会话已关闭。24小时内可重新打开。'
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化应用
|
||||
* 1. 获取用户信息
|
||||
@@ -1325,7 +1639,7 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
stopPolling,
|
||||
shakeAgent,
|
||||
fetchApprovalLinks,
|
||||
checkApprovalIntent,
|
||||
// v2.0: checkApprovalIntent 已删除(审批意图识别统一由后端处理)
|
||||
closeApprovalCard,
|
||||
showApprovalCard,
|
||||
fetchSoftwareDownloads,
|
||||
@@ -1347,5 +1661,25 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
handleAiReply,
|
||||
handleAiReplyFailed,
|
||||
cancelStreamingBubble,
|
||||
|
||||
// v2.0 新增:AI 思考指示器 + 动态推荐 + 选项回传
|
||||
handleAiThinking,
|
||||
handleDynamicRecommend,
|
||||
clearUnreadRecommend,
|
||||
removeRecommend,
|
||||
sendOptionSelect,
|
||||
dynamicRecommendations,
|
||||
unreadRecommendCount,
|
||||
|
||||
// 排队/关闭机制 WS 事件处理
|
||||
queuePositionData,
|
||||
pendingCloseRequest,
|
||||
resolvedInfo,
|
||||
handleQueuePositionUpdate,
|
||||
handleConversationResolved,
|
||||
handlePendingCloseRequest,
|
||||
handleQuizDiagnosticAnswer,
|
||||
clearPendingCloseRequest,
|
||||
clearResolvedInfo,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user