v3.1 + 批次0: 智能回复重构基线 - ApprovalMatcher + 关键词降级 + 文档速修 + v4.0任务书面化
This commit is contained in:
@@ -211,6 +211,63 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
/** 动态推荐未查看数量(用于 Badge 红点提示) */
|
||||
const unreadRecommendCount = ref<number>(0)
|
||||
|
||||
// ==========================================================================
|
||||
// 资产推荐卡片(v3.0 新增,由 WS asset_recommend 事件推送)
|
||||
// ==========================================================================
|
||||
/**
|
||||
* 资产推荐卡片列表(由后端 asset_recommend_service 推送)
|
||||
* 做什么:存储 L1/L2/L3 分层推荐卡片,供 DynamicRecommend 组件渲染
|
||||
* 数据结构:{ id, layer, layer_label, source, title, description, items, ... }
|
||||
*/
|
||||
const assetRecommendations = ref<Array<{
|
||||
id: string
|
||||
layer: string
|
||||
layer_label: string
|
||||
source: string
|
||||
title: string
|
||||
description?: string
|
||||
icon?: string
|
||||
items?: Array<{
|
||||
label: string
|
||||
type: string
|
||||
url?: string
|
||||
value?: string
|
||||
copyable?: boolean
|
||||
approval_type?: string
|
||||
}>
|
||||
action_url?: string
|
||||
confidence?: number
|
||||
relevance?: string
|
||||
}>>([])
|
||||
|
||||
/**
|
||||
* 处理资产推荐卡片(v3.0 新增)
|
||||
* 做什么:将后端推送的资产推荐数据存入 assetRecommendations
|
||||
*/
|
||||
function handleAssetRecommend(data: {
|
||||
recommends: Array<any>
|
||||
layered?: boolean
|
||||
push_type?: string
|
||||
}): void {
|
||||
if (!data.recommends || data.recommends.length === 0) return
|
||||
|
||||
// 添加到推荐列表(最多 5 张,超过时移除最旧的)
|
||||
assetRecommendations.value.push(...data.recommends)
|
||||
if (assetRecommendations.value.length > 5) {
|
||||
assetRecommendations.value.splice(0, assetRecommendations.value.length - 5)
|
||||
}
|
||||
// 增加未读计数
|
||||
unreadRecommendCount.value += data.recommends.length
|
||||
console.log('[Store] 资产推荐已接收:', data.recommends.length, '条, 未读:', unreadRecommendCount.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有资产推荐
|
||||
*/
|
||||
function clearAssetRecommend(): void {
|
||||
assetRecommendations.value = []
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// 流式 AI 回复(打字机)临时状态 — 改造方案 A
|
||||
// ==========================================================================
|
||||
@@ -361,7 +418,8 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
conversation_id: data.conversation_id,
|
||||
message_type: (data.sender_type || 'system') as MessageType,
|
||||
msg_type: (data.msg_type || 'text') as MsgContentType,
|
||||
content: data.content,
|
||||
// ★ 防御性类型保护:确保 content 始终是 String
|
||||
content: typeof data.content === 'string' ? data.content : (data.content ? JSON.stringify(data.content) : ''),
|
||||
sender_name: data.sender_name || '',
|
||||
created_at: new Date().toISOString(),
|
||||
})
|
||||
@@ -574,6 +632,22 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
currentConversation.value.ai_substantive_reply_count = resp.ai_reply_count ?? 0
|
||||
}
|
||||
|
||||
// 关键修复:如果发送消息前没有活跃会话(currentConversation 为 null),
|
||||
// 说明这是第一条消息创建了新会话。此时必须重新获取会话信息,
|
||||
// 否则 currentConversation.value?.conversation_id 为 undefined,
|
||||
// 所有后续 WS 事件(ai_reply / ai_thinking / dynamic_recommend 等)
|
||||
// 都会因 conversation_id 不匹配(undefined !== actual_id)被静默丢弃。
|
||||
if (!currentConversation.value && resp.user_message?.conversation_id) {
|
||||
console.log('[Store] 发送消息后 currentConversation 为 null,重新获取会话信息...')
|
||||
await fetchCurrentConversation()
|
||||
if (currentConversation.value) {
|
||||
// 获取到新会话后,同步状态
|
||||
currentConversation.value.can_call_agent = resp.can_call_agent ?? false
|
||||
currentConversation.value.ai_substantive_reply_count = resp.ai_reply_count ?? 0
|
||||
console.log('[Store] 新会话已获取:', currentConversation.value.conversation_id)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
'[Store] 消息发送成功, AI回复计数:',
|
||||
resp.ai_reply_count,
|
||||
@@ -1074,7 +1148,9 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
conversation_id: data.conversation_id,
|
||||
message_type: (data.sender_type || 'ai') as MessageType,
|
||||
msg_type: (data.msg_type || 'text') as MsgContentType,
|
||||
content: data.content,
|
||||
// ★ 防御性类型保护:确保 content 始终是 String
|
||||
// 后端可能因 Dify 返回异常导致 content 为对象,此时转为 JSON 字符串
|
||||
content: typeof data.content === 'string' ? data.content : (data.content ? JSON.stringify(data.content) : ''),
|
||||
sender_name: data.sender_name || 'Duckula(达寇拉)',
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'sent',
|
||||
@@ -1671,6 +1747,11 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
dynamicRecommendations,
|
||||
unreadRecommendCount,
|
||||
|
||||
// v3.0 新增:资产推荐(分层展示)
|
||||
handleAssetRecommend,
|
||||
clearAssetRecommend,
|
||||
assetRecommendations,
|
||||
|
||||
// 排队/关闭机制 WS 事件处理
|
||||
queuePositionData,
|
||||
pendingCloseRequest,
|
||||
|
||||
Reference in New Issue
Block a user