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:
Simon
2026-07-11 23:13:10 +08:00
parent 3d152fc8eb
commit bea288e414
928 changed files with 85169 additions and 54205 deletions
+71 -25
View File
@@ -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,