feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复
== 已部署上线 (9项) == - 代办事项真实数据源集成 (企微审批API 8bug修复链) - H5/坐席端 Logo样式统一+绿色背景 - 视频引导页修复 (localStorage key v2) - 坐席端 v9 Vue版本修复 (ElMessage._context) - 截图按钮 v10 修复 (getDisplayMedia user gesture) - 扫码样式恢复+H5扫码登录跳转修复 - H5截图快捷键提示 == 代码完成待部署 (3项) == - 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查) - 会议室预定-小鱼易联终端 (40文件, 40/40测试通过) - IT资产升级审批推送 (asset_service.py) == 需求文档 (2项) == - 坐席端AI辅助消息框-PRD (4项新功能确认) - 坐席端布局优化建议 v2.0 (7天计划) == 新增文档 == - 日报-2026-07-11.md - 知识迭代Bug修复报告-20260711.md - 会议室预定-部署指南.md - CHANGELOG.md 更新 == 测试 == - test_todo_integration.py: 40/40 - test_meetingroom.py: 40/40 - test_bugfix_ki_suggestions.py: 21/21
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
shake,
|
||||
getApprovalLinks,
|
||||
getSoftwareDownloads,
|
||||
detectApprovalIntent,
|
||||
leaveAsParticipant as leaveAsParticipantApi,
|
||||
type UserInfo,
|
||||
type ConversationInfo,
|
||||
@@ -452,12 +453,11 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否包含审批关键词,如果包含则先弹出卡片
|
||||
const hasApprovalKeyword = checkApprovalKeywords(content)
|
||||
if (hasApprovalKeyword) {
|
||||
console.log('[Store] 检测到审批关键词,弹窗后仍发送消息')
|
||||
// 审批弹窗显示,但不阻止消息发送
|
||||
}
|
||||
// 异步检测审批意图(不阻塞消息发送流程)
|
||||
// 员工发消息 → 消息正常发送 → 异步检测审批意图 → 如果命中则在消息列表中插入审批卡片
|
||||
checkApprovalIntent(content).catch((err) => {
|
||||
console.warn('[Store] 审批意图检测异常:', err)
|
||||
})
|
||||
|
||||
// ========================================================================
|
||||
// 步骤1:乐观更新 - 立即添加临时消息到列表
|
||||
@@ -518,6 +518,10 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
...resp.user_message,
|
||||
status: 'sent',
|
||||
}
|
||||
// 新增:更新去重追踪,避免轮询时重复添加
|
||||
trackProcessedMessageId(resp.user_message.message_id)
|
||||
// 新增:更新 lastMessageId,防止轮询重复拉取刚发送的消息
|
||||
lastMessageId.value = resp.user_message.message_id
|
||||
console.log('[Store] 乐观更新成功:临时消息已替换为真实消息')
|
||||
|
||||
// 更新本地缓存
|
||||
@@ -528,6 +532,10 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
} else {
|
||||
// 防御性:找不到临时消息时直接添加
|
||||
messages.value.push({ ...resp.user_message, status: 'sent' })
|
||||
// 新增:更新去重追踪,避免轮询时重复添加
|
||||
trackProcessedMessageId(resp.user_message.message_id)
|
||||
// 新增:更新 lastMessageId,防止轮询重复拉取刚发送的消息
|
||||
lastMessageId.value = resp.user_message.message_id
|
||||
}
|
||||
|
||||
// 注意:AI 回复不再经 HTTP 同步返回(后端已改为 ai_reply: null),
|
||||
@@ -774,33 +782,71 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 审批关键词列表(静态配置,后续可从API获取)
|
||||
const APPROVAL_KEYWORDS = ['申请', '资源', '设备', '电脑', '笔记本']
|
||||
/**
|
||||
* 异步检测审批意图
|
||||
* 调用后端 /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)
|
||||
|
||||
/** 检查文本是否包含审批关键词,触发审批卡片弹窗 */
|
||||
function checkApprovalKeywords(text: string): boolean {
|
||||
const lowerText = text.toLowerCase()
|
||||
const hasKeyword = APPROVAL_KEYWORDS.some((kw) => lowerText.includes(kw))
|
||||
|
||||
if (hasKeyword) {
|
||||
approvalCardTriggerText.value = text
|
||||
approvalCardVisible.value = true
|
||||
console.log('[Store] 检测到审批关键词,触发卡片弹窗')
|
||||
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)
|
||||
}
|
||||
|
||||
return hasKeyword
|
||||
}
|
||||
|
||||
/** 关闭审批卡片弹窗 */
|
||||
/** 关闭审批卡片弹窗(兼容旧调用,新流程中审批卡片为内联消息,无需关闭) */
|
||||
function closeApprovalCard(): void {
|
||||
approvalCardVisible.value = false
|
||||
approvalCardTriggerText.value = ''
|
||||
}
|
||||
|
||||
/** 显示审批卡片弹窗(快捷按钮触发) */
|
||||
function showApprovalCard(triggerText: string = ''): void {
|
||||
approvalCardTriggerText.value = triggerText
|
||||
approvalCardVisible.value = true
|
||||
/**
|
||||
* 显示审批卡片(快捷按钮触发)
|
||||
* 新流程中审批卡片作为消息流内联卡片,此函数直接在消息列表中插入一条审批卡片消息。
|
||||
*
|
||||
* @param _triggerText 触发文本(可选,新流程中不再使用关键词匹配)
|
||||
*/
|
||||
function showApprovalCard(_triggerText: string = ''): void {
|
||||
// 插入一条审批卡片消息到消息列表(approval_type 为空时组件展示全部选项)
|
||||
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: '',
|
||||
confidence: 0,
|
||||
},
|
||||
}
|
||||
messages.value.push(approvalCardMessage)
|
||||
console.log('[Store] 手动插入审批卡片消息(快捷按钮触发)')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1279,7 +1325,7 @@ export const useConversationStore = defineStore('conversation', () => {
|
||||
stopPolling,
|
||||
shakeAgent,
|
||||
fetchApprovalLinks,
|
||||
checkApprovalKeywords,
|
||||
checkApprovalIntent,
|
||||
closeApprovalCard,
|
||||
showApprovalCard,
|
||||
fetchSoftwareDownloads,
|
||||
|
||||
Reference in New Issue
Block a user