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
+76 -12
View File
@@ -7,11 +7,15 @@
# 生产基址(任务指定):http://yw-dify.dc.servyou-it.com/dify2openai/
#
# 返回结构(供 IntentRouter 使用):
# {"scenario_key": str|None, "confidence": float, "raw": str, "error": str}
# {"global_intent": str|None, "scenario_key": str|None, "confidence": float,
# "corrected_field": str|None, "old_value": str|None, "new_value": str|None,
# "supplement_field": str|None, "supplement_value": str|None,
# "raw": str, "error": str}
# global_intent ∈ {pause, resume_task, correct, supplement, None}
# scenario_key ∈ {password_reset, software_install, virus_dispose, terminal_locate}
#
# 降级:Dify 未配置或调用失败 → _fallback_intent 走关键词兜底(关键词取自
# app.services.automation.DEFAULT_SCENARIO_CONFIGS),保证无真实环境也能闭环。
# 降级:Dify 未配置或调用失败 → _fallback_intent 走关键词兜底(先匹配全局意图
# 关键词,未命中再匹配场景关键词),保证无真实环境也能闭环。
# =============================================================================
from __future__ import annotations
@@ -32,12 +36,28 @@ logger = logging.getLogger(__name__)
_DEFAULT_TIMEOUT = 30.0
# 意图识别提示词:要求模型仅输出 JSON
# 复杂场景重构:在现有4场景分类基础上,增加全局对话控制意图判断
_SYSTEM_PROMPT = (
"你是IT服务台意图分类器。根据用户诉求,判断其属于以下哪个场景之一"
"并仅输出一个 JSON 对象,不要输出任何额外文字:\n"
'{"scenario_key": "password_reset|software_install|virus_dispose|terminal_locate|unknown", '
'"confidence": 0.0~1.0}\n'
"场景说明:\n"
"你是IT服务台意图分类器。根据用户诉求,首先判断是否属于「全局对话控制意图」"
"如果不是全局控制意图,再判断其属于哪个IT场景。\n"
"仅输出一个 JSON 对象,不要输出任何额外文字:\n"
'{\n'
' "global_intent": "pause|resume_task|correct|supplement|null",\n'
' "scenario_key": "password_reset|software_install|virus_dispose|terminal_locate|unknown",\n'
' "confidence": 0.0~1.0,\n'
' "corrected_field": "字段名(仅correct时填写)",\n'
' "old_value": "旧值(仅correct时填写)",\n'
' "new_value": "新值(仅correct时填写)",\n'
' "supplement_field": "字段名(仅supplement时填写)",\n'
' "supplement_value": "补充值(仅supplement时填写)"\n'
'}\n'
"全局意图说明(优先判断,命中后 scenario_key 设为 unknown):\n"
"- pause: 用户要暂停/离开当前任务(如\"先去开会\"\"等会继续\"\"暂停\"\n"
"- resume_task: 用户要恢复之前暂停的任务(如\"继续\"\"继续刚才\"\"回来了\"\n"
"- correct: 用户要更正之前提供的信息(如\"刚才说错了\"\"不是xx是xx\"\"应该是\"\n"
"- supplement: 用户要补充额外信息(如\"再补充一下\"\"顺便说一下\"\"还有\"\n"
"- null: 不属于以上任何全局意图,走场景分类\n"
"场景说明(仅 global_intent 为 null 时判断):\n"
"- password_reset: 忘记/重置密码、账号密码相关\n"
"- software_install: 安装/下载软件\n"
"- virus_dispose: 病毒、木马、勒索、杀毒\n"
@@ -79,10 +99,12 @@ class DifyClient(BaseClient):
async def detect_intent(
self, description: str, employee_id: str = ""
) -> Dict[str, Any]:
"""调用 Dify 识别意图。
"""调用 Dify 识别意图(含全局意图判断)
Returns:
Dict: {scenario_key, confidence, raw, error}
Dict: {global_intent, scenario_key, confidence, corrected_field,
old_value, new_value, supplement_field, supplement_value,
raw, error}
"""
prompt = description or ""
body = {
@@ -114,11 +136,24 @@ class DifyClient(BaseClient):
choices = data.get("choices") or []
content = choices[0]["message"]["content"] if choices else ""
parsed = json.loads(content)
# 全局意图解析
global_intent_raw = parsed.get("global_intent")
global_intent: Optional[str] = None
if global_intent_raw and global_intent_raw != "null":
global_intent = global_intent_raw
scenario_key = parsed.get("scenario_key")
confidence = float(parsed.get("confidence", 0.0))
return {
"global_intent": global_intent,
"scenario_key": scenario_key if scenario_key != "unknown" else None,
"confidence": confidence,
"corrected_field": parsed.get("corrected_field"),
"old_value": parsed.get("old_value"),
"new_value": parsed.get("new_value"),
"supplement_field": parsed.get("supplement_field"),
"supplement_value": parsed.get("supplement_value"),
"raw": content,
"error": "",
}
@@ -132,10 +167,33 @@ class DifyClient(BaseClient):
def _fallback_intent(description: str) -> Dict[str, Any]:
"""关键词兜底(无 Dify / 解析失败时)。
关键词取自 DEFAULT_SCENARIO_CONFIGS 的 trigger_conditions.keywords
命中即返回该场景,置信度取 0.6(恰好达到阈值,可继续编排)
复杂场景重构:先做全局意图关键词匹配,命中则返回全局意图
命中则走原场景关键词匹配
"""
text = (description or "").lower()
# 1. 全局意图关键词兜底
try:
from app.constants import GLOBAL_INTENT_KEYWORDS
for intent, keywords in GLOBAL_INTENT_KEYWORDS.items():
if any(kw.lower() in text for kw in keywords):
return {
"global_intent": intent,
"scenario_key": None,
"confidence": 0.6,
"corrected_field": None,
"old_value": None,
"new_value": None,
"supplement_field": None,
"supplement_value": None,
"raw": "",
"error": "fallback",
}
except Exception: # noqa: BLE001
pass
# 2. 场景关键词兜底
scenario_key: Optional[str] = None
try: # 懒加载,避免循环依赖
from app.services.automation import DEFAULT_SCENARIO_CONFIGS
@@ -149,8 +207,14 @@ class DifyClient(BaseClient):
except Exception: # noqa: BLE001
pass
return {
"global_intent": None,
"scenario_key": scenario_key,
"confidence": 0.6 if scenario_key else 0.0,
"corrected_field": None,
"old_value": None,
"new_value": None,
"supplement_field": None,
"supplement_value": None,
"raw": "",
"error": "fallback",
}