Files
wecom_it_smart_desk/docs/openapi.json
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

1 line
163 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"openapi":"3.1.0","info":{"title":"企微IT智能服务台","description":"基于企微自建应用消息API的IT服务坐席系统","version":"1.0.0"},"paths":{"/wecom/callback":{"get":{"tags":["企微回调"],"summary":"Verify Url","description":"验证企微回调URL有效性。\n\n企微管理后台配置回调URL时,会发送 GET 请求验证。\n验证流程:\n1. 验证签名 SHA1(sort(token, timestamp, nonce, echostr))\n2. 解密 echostr\n3. 返回解密后的明文\n\nArgs:\n msg_signature: 企微签名\n timestamp: 时间戳\n nonce: 随机数\n echostr: 加密的验证字符串\n\nReturns:\n str: 解密后的 echostr 明文","operationId":"verify_url_wecom_callback_get","parameters":[{"name":"msg_signature","in":"query","required":true,"schema":{"type":"string","description":"企微签名","title":"Msg Signature"},"description":"企微签名"},{"name":"timestamp","in":"query","required":true,"schema":{"type":"string","description":"时间戳","title":"Timestamp"},"description":"时间戳"},{"name":"nonce","in":"query","required":true,"schema":{"type":"string","description":"随机数","title":"Nonce"},"description":"随机数"},{"name":"echostr","in":"query","required":true,"schema":{"type":"string","description":"加密的验证字符串","title":"Echostr"},"description":"加密的验证字符串"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["企微回调"],"summary":"Receive Message","description":"接收企微推送的消息。\n\n企微将员工发送的消息通过此接口推送过来。\n处理流程:\n1. 读取 XML 请求体\n2. 解密消息(验证签名 + AES 解密)\n3. 解析消息内容\n4. 路由到 MessageRouter 处理\n5. 返回 \"success\" 字符串(企微要求)\n\n重构说明:使用 dependencies 模块提供的共享服务实例,\n不再手动创建/关闭 Redis、WecomService、AIService。\n\n企微推送的消息格式(加密后):\n<xml>\n <ToUserName><![CDATA[corp_id]]></ToUserName>\n <AgentID>1000002</AgentID>\n <Encrypt><![CDATA[加密内容]]></Encrypt>\n</xml>\n\nArgs:\n request: FastAPI 请求对象(读取 XML 请求体)\n msg_signature: 企微签名\n timestamp: 时间戳\n nonce: 随机数\n\nReturns:\n str: \"success\" 字符串(企微要求的固定响应)","operationId":"receive_message_wecom_callback_post","parameters":[{"name":"msg_signature","in":"query","required":true,"schema":{"type":"string","description":"企微签名","title":"Msg Signature"},"description":"企微签名"},{"name":"timestamp","in":"query","required":true,"schema":{"type":"string","description":"时间戳","title":"Timestamp"},"description":"时间戳"},{"name":"nonce","in":"query","required":true,"schema":{"type":"string","description":"随机数","title":"Nonce"},"description":"随机数"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations":{"get":{"tags":["会话管理"],"summary":"List Conversations","description":"坐席获取会话列表(全局可见)。\n\n返回所有活跃会话,每个会话增加字段:\n- is_mine: 是否为当前坐席的会话\n- assigned_agent_name: 分配的坐席姓名(其他坐席会话显示用)\n- can_grab: 是否可以接手(其他坐席已接单的会话为 True)\n\n排序规则:紧急→举手→需介入→活跃→已结单。\n\nArgs:\n status: 按状态过滤(可选)\n agent_id: 按坐席ID过滤(可选)\n page: 页码\n page_size: 每页数量\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含会话列表和总数","operationId":"list_conversations_conversations_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按状态过滤: ai_handling/queued/serving/resolved","title":"Status"},"description":"按状态过滤: ai_handling/queued/serving/resolved"},{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按坐席ID过滤","title":"Agent Id"},"description":"按坐席ID过滤"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码(从1开始)","default":1,"title":"Page"},"description":"页码(从1开始)"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页数量","default":50,"title":"Page Size"},"description":"每页数量"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}":{"get":{"tags":["会话管理"],"summary":"Get Conversation","description":"获取会话详情。\n\nArgs:\n conversation_id: 会话ID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含会话详情","operationId":"get_conversation_conversations__conversation_id__get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/assign":{"post":{"tags":["会话管理"],"summary":"Assign Conversation","description":"坐席接单(接入会话)。\n\n坐席点击\"接单\"按钮时调用,将会话状态从 queued 改为 serving。\n\nArgs:\n conversation_id: 会话ID\n body: 接单请求体(包含 agent_id\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"assign_conversation_conversations__conversation_id__assign_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationAssign"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/resolve":{"post":{"tags":["会话管理"],"summary":"Resolve Conversation","description":"结单。\n\n坐席点击\"结单\"按钮时调用,将会话状态改为 resolved。\n\n权限控制:只有主责坐席(assigned_agent_id)才能结单。\n协作坐席和其他坐席不能结单。\n\nArgs:\n conversation_id: 会话ID\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"resolve_conversation_conversations__conversation_id__resolve_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/pin":{"post":{"tags":["会话管理"],"summary":"Toggle Pin","description":"切换会话置顶状态。\n\n每次调用切换当前状态:置顶→取消置顶,取消置顶→置顶。\n\nArgs:\n conversation_id: 会话ID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"toggle_pin_conversations__conversation_id__pin_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/todo":{"post":{"tags":["会话管理"],"summary":"Toggle Todo","description":"切换会话代办状态。\n\n每次调用切换当前状态:代办→取消代办,取消代办→代办。\n\nArgs:\n conversation_id: 会话ID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"toggle_todo_conversations__conversation_id__todo_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/transfer":{"post":{"tags":["会话管理"],"summary":"Transfer Conversation","description":"转接会话到另一个坐席。\n\n第一步简化版:只更换坐席,不做转接通知。\n\nArgs:\n conversation_id: 会话ID\n body: 转接请求体(包含 target agent_id\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"transfer_conversation_conversations__conversation_id__transfer_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationAssign"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/grab":{"post":{"tags":["会话管理"],"summary":"Grab Conversation","description":"接手其他坐席的会话(抢单)。\n\n接手后原坐席自动释放,会话 assigned_agent_id 切换为当前坐席。\n验证规则:\n1. 会话必须已分配给其他坐席(不能接手自己的,不能接手未分配的)\n2. 当前坐席未满负荷\n3. 会话状态为 serving\n\nArgs:\n conversation_id: 会话ID\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含接手后的会话信息","operationId":"grab_conversation_conversations__conversation_id__grab_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/invite":{"post":{"tags":["会话管理"],"summary":"Invite Collaborator","description":"坐席A邀请坐席B加入会话协作。\n\n校验规则:\n1. 当前坐席必须是主责坐席或已加入的协作坐席\n2. 被邀请坐席存在且在线\n3. 被邀请坐席不是主责坐席,也不在协作列表中(防止重复邀请)\n4. 会话必须为 serving(已结单的不能摇人)\n\n副作用:\n- WebSocket 推送给被邀请坐席(collaborator_invited 定向通知)\n- WebSocket 广播给所有坐席(collaborator_joined 刷新列表)\n\nArgs:\n conversation_id: 会话ID\n body: 邀请请求(含 agent_id\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"invite_collaborator_conversations__conversation_id__invite_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationInvite"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/leave":{"post":{"tags":["会话管理"],"summary":"Leave Collaboration","description":"坐席退出协作。\n\n校验规则:\n1. 当前坐席必须在协作列表中\n2. 当前坐席不能是主责坐席(主责坐席不能\"退出\",只能转接或结单)\n\n副作用:\n- WebSocket 广播给所有坐席(collaborator_left 刷新列表)\n\nArgs:\n conversation_id: 会话ID\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"leave_collaboration_conversations__conversation_id__leave_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/invite-participant":{"post":{"tags":["会话管理"],"summary":"Invite Participant","description":"坐席邀请员工/部门加入会话(P0-09 邀请发起)。\n\n权限:只有主责坐席可以发起邀请。\n副作用:\n- 向被邀请人发送企微卡片通知(含「加入会话」按钮)\n- 在会话中创建系统消息\n- WebSocket 广播参与者变更\n\nArgs:\n conversation_id: 会话ID\n body: 邀请请求(含被邀请人列表 + 历史共享模式)\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"invite_participant_conversations__conversation_id__invite_participant_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteParticipantRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/join":{"post":{"tags":["会话管理"],"summary":"Join Conversation","description":"被邀请人通过链接加入会话(P0-10 加入会话)。\n\n校验:该员工必须在 participants 列表中(被邀请过才能加入)。\n副作用:\n- 更新参与者的 joined 状态\n- 在会话中创建系统消息\n- WebSocket 广播参与者变更\n\nArgs:\n conversation_id: 会话ID\n body: 加入请求(含 employee_id\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"join_conversation_conversations__conversation_id__join_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinConversationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/participants/{user_id}":{"delete":{"tags":["会话管理"],"summary":"Remove Participant","description":"移除参与者(P0-11 参与者管理)。\n\n权限:只有主责坐席可以移除参与者。\n副作用:\n- 在会话中创建系统消息\n- WebSocket 广播参与者变更\n\nArgs:\n conversation_id: 会话ID\n user_id: 被移除的员工UserID\n db: 数据库会话\n current_agent: 当前坐席(认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"remove_participant_conversations__conversation_id__participants__user_id__delete","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/leave-participant":{"post":{"tags":["会话管理"],"summary":"Leave As Participant","description":"参与者主动退出会话。\n\n副作用:\n- 在会话中创建系统消息\n- WebSocket 广播参与者变更\n\nArgs:\n conversation_id: 会话ID\n body: 退出请求(含 employee_id\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"leave_as_participant_conversations__conversation_id__leave_participant_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinConversationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/messages":{"get":{"tags":["消息管理"],"summary":"List Messages","description":"获取会话消息列表(分页)。\n\n支持向上加载历史消息(通过 before 参数指定消息ID)。\n默认返回最新的 limit 条消息。\n\nArgs:\n conversation_id: 会话ID\n limit: 每页消息数量\n before: 加载此消息ID之前的消息(向上翻页)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含消息列表和是否还有更多消息","operationId":"list_messages_conversations__conversation_id__messages_get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页消息数量","default":50,"title":"Limit"},"description":"每页消息数量"},{"name":"before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"加载此消息ID之前的消息(向上翻页)","title":"Before"},"description":"加载此消息ID之前的消息(向上翻页)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["消息管理"],"summary":"Send Message","description":"坐席发送消息。\n\n流程:\n1. 校验会话存在且未结单\n2. 将消息存入 messages 表\n3. 调用企微 API 发送消息给员工\n4. 更新会话的最后消息信息\n\nArgs:\n conversation_id: 会话ID\n body: 消息请求体(包含 content 和 msg_type\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含发送的消息对象","operationId":"send_message_conversations__conversation_id__messages_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/messages/poll":{"get":{"tags":["消息管理"],"summary":"Poll Messages","description":"坐席轮询新消息。\n\n前端每 3-5 秒调用一次,获取上次轮询后的新消息。\n\nArgs:\n conversation_id: 会话ID\n after_message_id: 上次轮询的最后一消息ID(返回此之后的消息)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含新消息列表","operationId":"poll_messages_conversations__conversation_id__messages_poll_get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"after_message_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"返回此消息ID之后的新消息","title":"After Message Id"},"description":"返回此消息ID之后的新消息"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/messages/{message_id}/recall":{"post":{"tags":["消息管理"],"summary":"Recall Message","description":"撤回消息(2分钟内)。\n\n仅可撤回2分钟内坐席自己发送的消息。\n\nP0-2 安全修复(2026-06-14 评审):\n 此前完全无鉴权,任意 HTTP 客户端可调用此端点修改任意消息。\n 现在依赖 get_current_agent 校验登录态,再校验 message.sender_id\n 是否等于当前坐席的 user_id,防止越权撤回他人消息。\n\nArgs:\n message_id: 消息ID\n agent: 当前坐席(鉴权依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"recall_message_messages__message_id__recall_post","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/messages/{message_id}":{"delete":{"tags":["消息管理"],"summary":"Delete Message","description":"删除坐席自己发送的消息。\n\nP0-3 安全修复(2026-06-14 评审):\n 此前完全无鉴权,任意 HTTP 客户端可删除任意消息。\n 现在依赖 get_current_agent 校验登录态,再校验消息是否属于当前坐席,\n 防止越权删除他人/会话历史。\n\nArgs:\n message_id: 消息ID\n agent: 当前坐席(鉴权依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"delete_message_messages__message_id__delete","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/mark-read":{"post":{"tags":["消息管理"],"summary":"Mark Read","description":"标记会话中所有员工未读消息为已读。\n\nP0-4 安全修复(2026-06-14 评审):\n 此前完全无鉴权,任意 HTTP 客户端可标记任意会话为已读,\n 会破坏\"未读消息数\"业务统计。\n 现在依赖 get_current_agent 校验登录态,再校验当前坐席是会话的\n 主责或协作坐席才允许标记,防止越权篡改未读状态。\nP2-3 修复:原 `.where(Message.is_read == False)` 是 Python 表达式比较\n 永远为 False(不抛错但实际未过滤),SQLAlchemy 也会当成赋值表达式\n 处理;改为 `is_(False)` 走 SQL 否定。\n\nArgs:\n conversation_id: 会话ID\n agent: 当前坐席(鉴权依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"mark_read_conversations__conversation_id__mark_read_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/messages/image":{"post":{"tags":["消息管理"],"summary":"Upload Image","description":"上传图片文件。\n\n文件大小限制:10MB\n\nArgs:\n file: 图片文件\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含文件URL和元数据","operationId":"upload_image_messages_image_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_image_messages_image_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/messages/file":{"post":{"tags":["消息管理"],"summary":"Upload Message File","description":"上传普通文件。\n\n文件大小限制:10MB\n\nArgs:\n file: 文件\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含文件URL和元数据","operationId":"upload_message_file_messages_file_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_message_file_messages_file_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/login":{"post":{"tags":["坐席管理"],"summary":"Agent Login","description":"坐席登录。\n\n第一步使用简单的用户名密码登录。\n登录成功后生成 token 存入 RedisTTL 8小时)。\n\n流程:\n1. 查找坐席记录(按 user_id),不存在则自动创建\n2. 生成随机 token\n3. token 存 Rediskey: agent:token:{token}, value: user_id\n4. 更新坐席状态为 online\n5. 返回坐席信息和 token\n\nArgs:\n body: 登录请求体(包含 user_id 和 name\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含坐席信息和 token","operationId":"agent_login_agents_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentLogin"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/me":{"get":{"tags":["坐席管理"],"summary":"Get Agent Me","description":"获取当前坐席信息。\n\n需要在请求头中携带有效的 token。\n\nArgs:\n agent: 当前坐席(通过认证依赖注入)\n\nReturns:\n Dict: 统一响应格式,包含坐席信息","operationId":"get_agent_me_agents_me_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/me/status":{"put":{"tags":["坐席管理"],"summary":"Update Agent Status","description":"更新坐席状态。\n\n坐席可以切换为 online/busy/offline。\n- online: 在线,可以接收新会话\n- busy: 忙碌,不接收新会话但继续处理已有的\n- offline: 离线,不接收任何会话\n\nArgs:\n body: 状态更新请求体\n agent: 当前坐席\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的坐席信息","operationId":"update_agent_status_agents_me_status_put","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents":{"get":{"tags":["坐席管理"],"summary":"List Agents","description":"获取坐席列表。\n\n用于转接选择时展示可用的坐席列表。\n\nArgs:\n status: 按状态过滤(可选)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含坐席列表","operationId":"list_agents_agents_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按状态过滤: online/busy/offline","title":"Status"},"description":"按状态过滤: online/busy/offline"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/otp-bind":{"post":{"tags":["坐席管理"],"summary":"Bind Agent Otp","description":"为当前坐席生成 OTP 密钥和二维码。\n\n生成 TOTP 密钥,生成 otpauth:// URI 用于扫码绑定 Google Authenticator。\n返回二维码(base64编码)和密钥,供用户手动输入备用。\n\nReturns:\n Dict: 二维码图片(base64)和密钥","operationId":"bind_agent_otp_agents_otp_bind_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/otp-verify":{"post":{"tags":["坐席管理"],"summary":"Verify Agent Otp","description":"验证并启用 OTP。\n\n用户输入 OTP 码验证成功后,启用 OTP。\n首次验证成功后 otp_enabled 设为 1。\n\nArgs:\n body.otp_code: 用户输入的 OTP 码(必填)\n\nReturns:\n Dict: 验证结果","operationId":"verify_agent_otp_agents_otp_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentLogin"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/otp-unbind":{"post":{"tags":["坐席管理"],"summary":"Unbind Agent Otp","description":"解绑 OTP。\n\n解绑后 mfa_secret 和 mfa_enabled 都清空。\n需要管理员操作。\n\nReturns:\n Dict: 解绑结果","operationId":"unbind_agent_otp_agents_otp_unbind_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents/password":{"post":{"tags":["坐席管理"],"summary":"Update Agent Password","description":"修改坐席本地密码。\n\n可选功能,允许坐席设置本地密码作为备用认证方式。\n企微验证失败时,可使用本地密码认证。\n\nP0-#5 新增端点。\n\nArgs:\n body.new_password: 新密码(6-128位)\n\nReturns:\n Dict: 修改结果","operationId":"update_agent_password_agents_password_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPasswordUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/quick-replies":{"get":{"tags":["快速回复"],"summary":"List Quick Replies","description":"获取快速回复模板列表。\n\n支持按分类过滤,按 sort_order 排序。\n坐席端可见性规则:\n- 有认证:返回 approved + 自己的 pending_review\n- 无认证:只返回 approved\n\nArgs:\n category: 按分类过滤(可选)\n db: 数据库会话\n agent: 当前坐席(可选认证)\n\nReturns:\n Dict: 统一响应格式,包含模板列表","operationId":"list_quick_replies_quick_replies_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按分类过滤: 账号/网络/软件/硬件/通用","title":"Category"},"description":"按分类过滤: 账号/网络/软件/硬件/通用"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["快速回复"],"summary":"Create Quick Reply","description":"创建快速回复模板。\n\nArgs:\n body: 创建请求体(包含 category、title、content、variables、sort_order\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含创建的模板","operationId":"create_quick_reply_quick_replies_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickReplyCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/quick-replies/{template_id}":{"put":{"tags":["快速回复"],"summary":"Update Quick Reply","description":"更新快速回复模板。\n\n只更新传入的字段(部分更新)。\n\nArgs:\n template_id: 模板ID\n body: 更新请求体(所有字段可选)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的模板","operationId":"update_quick_reply_quick_replies__template_id__put","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickReplyUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["快速回复"],"summary":"Delete Quick Reply","description":"删除快速回复模板。\n\n第一步使用物理删除。\n\nArgs:\n template_id: 模板ID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"delete_quick_reply_quick_replies__template_id__delete","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/oauth/authorize":{"get":{"tags":["H5用户端"],"summary":"Get Oauth Authorize Url","description":"获取企微OAuth2授权URL。\n\n前端调用此接口获取完整的企微OAuth2授权链接,\n然后跳转到该链接进行静默授权。\n\n授权流程:\n1. 前端请求此接口获取授权URL\n2. 前端跳转到授权URL\n3. 企微自动重定向到 redirect_uri?code=CODE&state=STATE\n4. 前端拿到code,调用 POST /api/h5/oauth/callback\n\nArgs:\n request: FastAPI Request 对象(用于 UA 检测)\n redirect_uri: 自定义回调地址(可选)\n request_host: 请求的 Host 头(自动获取,用于构造默认回调地址)\n\nReturns:\n Dict: 统一响应格式,包含 authorize_url 字段","operationId":"get_oauth_authorize_url_h5_oauth_authorize_get","parameters":[{"name":"redirect_uri","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"OAuth2回调地址(可选,默认使用请求来源域名/h5/)","title":"Redirect Uri"},"description":"OAuth2回调地址(可选,默认使用请求来源域名/h5/)"},{"name":"Host","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/oauth/callback":{"post":{"tags":["H5用户端"],"summary":"Oauth Callback","description":"企微 OAuth2 授权回调。\n\nH5 页面通过企微 OAuth2 静默授权获取 code,后端用 code 换取员工身份。\n成功后生成 Bearer Token 存入 Redis,返回 token + 员工信息。\n\n重构说明:不再手动创建/关闭 Redis 和 WecomService,改用 DI 注入共享实例。\n\n流程:\n1. 前端跳转企微授权页面\n2. 企微回调到 H5 页面并携带 code\n3. H5 前端将 code 发给后端\n4. 后端用 code 调用企微 API 换取员工 UserID\n5. 后端获取员工详细信息(姓名、部门、岗位等)\n6. 生成 Bearer Token 存入 Redis\n7. 返回 token + 员工信息\n\nArgs:\n request: FastAPI Request 对象(用于 UA 检测)\n body: OAuth2 回调请求体(包含 code\n db: 数据库会话\n redis_client: 共享 Redis 客户端(DI 注入)\n wecom_service: 共享企微服务(DI 注入)\n\nReturns:\n Dict: 统一响应格式,包含 token 和员工信息","operationId":"oauth_callback_h5_oauth_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthCallbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/mock-login":{"post":{"tags":["H5用户端"],"summary":"Mock Login","description":"Mock 登录(测试阶段使用,跳过企微 OAuth2)。\n\n仅当后端配置 MOCK_LOGIN_ENABLED=true 时可用。\n直接通过员工 ID 生成 Bearer Token,并存入 Redis。\n返回格式与 OAuth2 回调完全一致。\n\nArgs:\n body: 请求体 { employee_id: str, employee_name: str }\n redis_client: 共享 Redis 客户端(DI 注入)\n\nReturns:\n Dict: 统一响应格式,包含 token 和员工信息","operationId":"mock_login_h5_mock_login_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/me":{"get":{"tags":["H5用户端"],"summary":"Get Current Employee Info","description":"获取当前登录员工的详细信息。\n\n需要在请求头中携带有效的 Bearer token。\n优先从 Redis 缓存读取,缓存不存在则调用企微API获取。\n\n重构说明:不再手动创建/关闭 Redis 和 WecomService,改用 DI 注入共享实例。\n\nArgs:\n employee_id: 员工企微 UserID(通过认证依赖注入)\n db: 数据库会话\n redis_client: 共享 Redis 客户端(DI 注入)\n wecom_service: 共享企微服务(DI 注入)\n\nReturns:\n Dict: 统一响应格式,包含员工详细信息","operationId":"get_current_employee_info_h5_me_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/user":{"get":{"tags":["H5用户端"],"summary":"Get Current User","description":"获取当前用户信息。\n\n通过 Bearer Token 认证后获取员工信息。\n\nArgs:\n employee_id: 员工企微 UserID(通过认证依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含员工信息","operationId":"get_current_user_h5_user_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/current":{"get":{"tags":["H5用户端"],"summary":"Get Current Conversation","description":"获取当前用户的活跃会话。\n\n查找员工当前状态为 ai_handling、queued 或 serving 的会话。\n如果没有活跃会话,返回空数据。\n\nArgs:\n employee_id: 员工企微 UserID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含会话信息","operationId":"get_current_conversation_h5_conversations_current_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/current/messages":{"post":{"tags":["H5用户端"],"summary":"H5 Send Message","description":"H5 用户发送消息(含 AI 回复与计数)。\n\n重构说明:AI 调用逻辑已统一至 AIHandler,此接口仅负责:\n1. 会话管理(查找/创建)\n2. 消息持久化\n3. 根据 AIHandler 返回结果更新会话状态和计数\n4. 返回响应\n\nArgs:\n body: 消息请求体(包含 content\n employee_id: 员工企微 UserID\n db: 数据库会话\n ai_handler: AI 处理器(DI 注入,统一 AI 调用逻辑)\n\nReturns:\n Dict: 统一响应格式,包含用户消息和 AI 回复","operationId":"h5_send_message_h5_conversations_current_messages_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/current/messages/poll":{"get":{"tags":["H5用户端"],"summary":"H5 Poll Messages","description":"H5 用户轮询新消息。\n\n前端定时调用获取坐席回复的新消息。\n\nArgs:\n after_message_id: 上次轮询的最后一消息ID\n employee_id: 员工企微 UserID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含新消息列表","operationId":"h5_poll_messages_h5_conversations_current_messages_poll_get","parameters":[{"name":"after_message_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"返回此消息ID之后的新消息","title":"After Message Id"},"description":"返回此消息ID之后的新消息"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/current/shake":{"post":{"tags":["H5用户端"],"summary":"Shake","description":"举手(敲桌子呼叫坐席)。\n\n前端按钮从「摇人🔔」改为「敲桌子👊👊」,后端端点保持不变。\n\n重构说明:不再手动创建/关闭 Redis 和 WecomService,改用 DI 注入共享实例。\n\n流程:\n1. 查找或创建会话\n2. 设置举手标记\n3. 获取趣味话术\n4. 发送系统消息\n5. 通过企微 API 发送话术给员工\n6. 返回会话信息和话术\n\nArgs:\n body: 举手请求体(包含 employee_id 和 employee_name\n db: 数据库会话\n wecom_service: 共享企微服务(DI 注入)\n\nReturns:\n Dict: 统一响应格式,包含会话信息和趣味话术","operationId":"shake_h5_conversations_current_shake_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShakeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/approval-links":{"get":{"tags":["H5用户端"],"summary":"Get Approval Links","description":"获取审批流程链接。\n\n从 approval_links 表读取,支持按分类过滤。\n用于 H5 用户端 AI 助手面板。\n\nArgs:\n category: 按分类过滤(可选)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含审批链接列表","operationId":"get_approval_links_h5_approval_links_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按分类过滤: IT/HR/行政/财务","title":"Category"},"description":"按分类过滤: IT/HR/行政/财务"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/software-downloads":{"get":{"tags":["H5用户端"],"summary":"Get Software Downloads","description":"获取软件下载列表。\n\n从 software_downloads 表读取,支持按分类过滤。\n用于 H5 用户端 AI 助手面板。\n\nArgs:\n category: 按分类过滤(可选)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含软件下载列表","operationId":"get_software_downloads_h5_software_downloads_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按分类过滤: 办公/开发/安全/工具","title":"Category"},"description":"按分类过滤: 办公/开发/安全/工具"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/{conversation_id}/join":{"post":{"tags":["H5用户端"],"summary":"H5 Join Conversation","description":"H5员工加入会话(带认证)。\n\n做什么:被邀请人点击企微卡片链接后,通过此接口加入会话\n为什么:需要验证请求者身份,防止冒充其他员工加入会话\n认证:Bearer Token → employee_id,与请求体中的 employee_id 校验一致性\n\n副作用:\n- 更新参与者的 joined 状态\n- 在会话中创建系统消息\n- WebSocket 广播参与者变更\n\nArgs:\n conversation_id: 会话ID\n employee_id: 当前登录员工ID(从 Token 认证获取)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"h5_join_conversation_h5_conversations__conversation_id__join_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/{conversation_id}/leave-participant":{"post":{"tags":["H5用户端"],"summary":"H5 Leave Participant","description":"H5员工退出会话(带认证)。\n\n做什么:参与者主动退出会话\n为什么:需要验证请求者身份,防止冒充其他员工退出\n认证:Bearer Token → employee_id\n\n副作用:\n- 在会话中创建系统消息\n- WebSocket 广播参与者变更\n\nArgs:\n conversation_id: 会话ID\n employee_id: 当前登录员工ID(从 Token 认证获取)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的会话信息","operationId":"h5_leave_participant_h5_conversations__conversation_id__leave_participant_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/h5/conversations/{conversation_id}/participants":{"get":{"tags":["H5用户端"],"summary":"H5 Get Participants","description":"获取会话参与者列表(带认证 + 参与者权限校验)。\n\n做什么:返回指定会话的所有参与者信息\n为什么:H5员工端需要查看参与者面板\n认证:Bearer Token → employee_id\n权限:仅会话发起人(employee_id)或已加入的参与者可查看,防止越权读取他会话信息\n\nP0 安全修复(2026-06-14 评审):\n 此前仅校验\"用户已登录\",未校验\"是否属于本会话\",存在数据泄露风险——\n 任意已登录员工可枚举 conversation_id 读取其他会话的参与者名单。\n\nArgs:\n conversation_id: 会话ID\n employee_id: 当前登录员工ID(从 Token 认证获取)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含参与者列表\n\nRaises:\n ERR_CONVERSATION_NOT_FOUND: 会话不存在\n AppException(4003): 当前员工不是会话发起人/参与者","operationId":"h5_get_participants_h5_conversations__conversation_id__participants_get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent-notes/{employee_id}":{"get":{"tags":["坐席备注"],"summary":"List Agent Notes","description":"获取员工的所有备注。\n\n通过员工ID查找其所有会话的备注。\n用于坐席端用户信息面板展示。\n\nArgs:\n employee_id: 员工企微 UserID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含备注列表","operationId":"list_agent_notes_agent_notes__employee_id__get","parameters":[{"name":"employee_id","in":"path","required":true,"schema":{"type":"string","title":"Employee Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent-notes":{"post":{"tags":["坐席备注"],"summary":"Create Agent Note","description":"添加坐席备注。\n\nArgs:\n body: 备注请求体(包含 conversation_id, agent_id, content\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含创建的备注","operationId":"create_agent_note_agent_notes_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent-notes/{note_id}":{"put":{"tags":["坐席备注"],"summary":"Update Agent Note","description":"更新坐席备注。\n\nArgs:\n note_id: 备注ID\n body: 更新请求体(包含 content\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的备注","operationId":"update_agent_note_agent_notes__note_id__put","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Note Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["坐席备注"],"summary":"Delete Agent Note","description":"删除坐席备注。\n\nArgs:\n note_id: 备注ID\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"delete_agent_note_agent_notes__note_id__delete","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Note Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/system/emergency-mode":{"get":{"tags":["系统管理"],"summary":"Get Emergency Mode","description":"查询应急模式状态。\n\n返回当前应急模式的开关状态。\n应急模式开启时,智能服务台降级,引导员工使用企微原生「员工服务」通道。\n\nReturns:\n Dict: 统一响应格式\n data.emergency_mode: bool — 是否启用应急模式\n data.employee_service_guide: str — 开启时的引导文案(仅开启时返回)","operationId":"get_emergency_mode_system_emergency_mode_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"put":{"tags":["系统管理"],"summary":"Toggle Emergency Mode","description":"切换应急模式开关(仅限坐席/管理员操作)。\n\n开启应急模式后:\n- H5 用户端页面显示引导文案,提示走企微原生「员工服务」\n- 坐席工作台顶部显示醒目的应急模式横幅\n\n关闭应急模式后恢复正常服务。\n\nArgs:\n body: 请求体,包含 emergency_mode: bool\n\nReturns:\n Dict: 统一响应格式\n data.emergency_mode: bool — 切换后的状态","operationId":"toggle_emergency_mode_system_emergency_mode_put","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/wingman/draft":{"post":{"tags":["AI Wingman"],"summary":"Generate Draft","description":"生成 AI 草稿回复。\n\n基于当前会话的消息历史,让 Wingman Agent 生成坐席可以采纳的草稿回复。\n\nArgs:\n conversation_id: 会话ID\n agent: 当前坐席(通过认证依赖注入)\n db: 数据库会话\n wingman_service: Wingman 服务实例\n\nReturns:\n Dict: 统一响应格式,包含草稿内容、置信度和推理说明","operationId":"generate_draft_conversations__conversation_id__wingman_draft_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/wingman/summary":{"post":{"tags":["AI Wingman"],"summary":"Generate Summary","description":"生成会话自动摘要。\n\n基于完整对话生成结构化摘要,包含问题、原因、解决方案。\n通常在结单时调用。\n\nArgs:\n conversation_id: 会话ID\n agent: 当前坐席\n db: 数据库会话\n wingman_service: Wingman 服务实例\n\nReturns:\n Dict: 统一响应格式,包含问题、原因、解决方案","operationId":"generate_summary_conversations__conversation_id__wingman_summary_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conversations/{conversation_id}/wingman/tags":{"post":{"tags":["AI Wingman"],"summary":"Suggest Tags","description":"生成自动标签建议。\n\n基于对话内容建议标签分类,包含标签列表、分类和优先级。\n\nArgs:\n conversation_id: 会话ID\n agent: 当前坐席\n db: 数据库会话\n wingman_service: Wingman 服务实例\n\nReturns:\n Dict: 统一响应格式,包含建议标签、分类和优先级","operationId":"suggest_tags_conversations__conversation_id__wingman_tags_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todo-items":{"get":{"tags":["待办事项","待办事项"],"summary":"List Todo Items","description":"获取当前坐席待办列表。\n\n支持按状态和优先级过滤。","operationId":"list_todo_items_todo_items_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"priority","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todo-items/{item_id}":{"get":{"tags":["待办事项","待办事项"],"summary":"Get Todo Item","description":"获取待办事项详情。","operationId":"get_todo_item_todo_items__item_id__get","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todo-items/{item_id}/status":{"put":{"tags":["待办事项","待办事项"],"summary":"Update Todo Item Status","description":"更新待办事项状态。","operationId":"update_todo_item_status_todo_items__item_id__status_put","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoStatusUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/troubleshooting-templates":{"get":{"tags":["排查模板","排查模板"],"summary":"List Troubleshooting Templates","description":"获取排查模板列表。\n\n支持按分类过滤。","operationId":"list_troubleshooting_templates_troubleshooting_templates_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["排查模板","排查模板"],"summary":"Create Troubleshooting Template","description":"新增排查模板(管理员)。","operationId":"create_troubleshooting_template_troubleshooting_templates_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TroubleshootingTemplateCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/troubleshooting-templates/{template_id}":{"get":{"tags":["排查模板","排查模板"],"summary":"Get Troubleshooting Template","description":"获取排查模板详情。","operationId":"get_troubleshooting_template_troubleshooting_templates__template_id__get","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["排查模板","排查模板"],"summary":"Update Troubleshooting Template","description":"修改排查模板(管理员)。","operationId":"update_troubleshooting_template_troubleshooting_templates__template_id__put","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TroubleshootingTemplateUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["排查模板","排查模板"],"summary":"Delete Troubleshooting Template","description":"删除排查模板(管理员)。","operationId":"delete_troubleshooting_template_troubleshooting_templates__template_id__delete","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/employees/{employee_id}/it-level":{"put":{"tags":["员工管理","员工管理"],"summary":"Update Employee It Level","description":"更新员工IT技能等级。\n\n坐席可以手动调整员工的IT技能等级,等级来源标记为 manual。\n更新后等级立即生效,并记录来源以便追溯。\n\nArgs:\n employee_id: 员工ID\n request: 等级更新请求\n\nReturns:\n 更新结果","operationId":"update_employee_it_level_employees__employee_id__it_level_put","parameters":[{"name":"employee_id","in":"path","required":true,"schema":{"type":"string","title":"Employee Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItLevelUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/upload":{"post":{"tags":["文件上传"],"summary":"Upload File","description":"上传文件到服务器。\n\n处理流程:\n1. 校验文件扩展名(白名单)\n2. 校验文件大小(图片10MB,其他20MB)\n3. 按日期目录存储文件\n4. 返回文件访问URL\n\nArgs:\n file: FastAPI UploadFile 对象\n\nReturns:\n Dict: 统一响应格式,包含文件URL、文件名、文件大小、文件类型","operationId":"upload_file_upload_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Employee-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Employee-Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_file_upload_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/media/{year}/{month}/{day}/{filename}":{"get":{"tags":["文件上传"],"summary":"Serve Media File","description":"提供上传文件的静态访问。\n\n开发环境使用 FastAPI 直接返回文件;\n生产环境建议 Nginx 配置 location /api/media/ 直接代理到 uploads 目录。\n\nArgs:\n year: 年份(路径参数)\n month: 月份(路径参数)\n day: 日期(路径参数)\n filename: 文件名(路径参数)\n\nReturns:\n FileResponse: 文件响应","operationId":"serve_media_file_media__year___month___day___filename__get","parameters":[{"name":"year","in":"path","required":true,"schema":{"type":"string","title":"Year"}},{"name":"month","in":"path","required":true,"schema":{"type":"string","title":"Month"}},{"name":"day","in":"path","required":true,"schema":{"type":"string","title":"Day"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/dashboard/overview":{"get":{"tags":["管理后台"],"summary":"Get Dashboard Overview","description":"获取仪表盘统计数据。\n\n返回在线坐席数、今日会话数、待审核数、集成健康状态等。\n\nArgs:\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含仪表盘数据","operationId":"get_dashboard_overview_admin_dashboard_overview_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/configs":{"get":{"tags":["管理后台"],"summary":"Get Configs","description":"获取全部配置项(按功能分组)。\n\nArgs:\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含配置分组列表","operationId":"get_configs_admin_configs_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/configs/{key}":{"put":{"tags":["管理后台"],"summary":"Update Config","description":"更新单个配置项(同时记录变更日志)。\n\nArgs:\n key: 配置键\n body: 更新请求体\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含变更信息","operationId":"update_config_admin_configs__key__put","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/configs/{key}/history":{"get":{"tags":["管理后台"],"summary":"Get Config History","description":"获取指定配置项的变更历史。\n\nArgs:\n key: 配置键\n limit: 返回条数上限\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含变更历史列表","operationId":"get_config_history_admin_configs__key__history_get","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"返回条数上限","default":20,"title":"Limit"},"description":"返回条数上限"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/agents":{"get":{"tags":["管理后台"],"summary":"List Admin Agents","description":"获取坐席列表(管理视图,含角色/技能标签)。\n\nArgs:\n status: 按状态筛选(可选)\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含坐席列表","operationId":"list_admin_agents_admin_agents_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按状态筛选: online/offline/busy","title":"Status"},"description":"按状态筛选: online/offline/busy"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["管理后台"],"summary":"Create Agent","description":"添加坐席。\n\nArgs:\n body: 创建请求体\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含创建的坐席信息","operationId":"create_agent_admin_agents_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/agents/{agent_id}":{"put":{"tags":["管理后台"],"summary":"Update Agent","description":"编辑坐席(角色/技能标签/负载上限)。\n\nArgs:\n agent_id: 坐席ID\n body: 更新请求体\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的坐席信息","operationId":"update_agent_admin_agents__agent_id__put","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["管理后台"],"summary":"Delete Agent","description":"移除坐席。\n\nArgs:\n agent_id: 坐席ID\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"delete_agent_admin_agents__agent_id__delete","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/agents/{agent_id}/otp-unbind":{"post":{"tags":["管理后台"],"summary":"Admin Unbind Agent Otp","description":"强制解绑坐席的OTP。\n\nArgs:\n agent_id: 坐席ID\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"admin_unbind_agent_otp_admin_agents__agent_id__otp_unbind_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations":{"get":{"tags":["管理后台"],"summary":"Get Integrations","description":"获取集成系统列表及配置状态。\n\nArgs:\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含集成系统列表","operationId":"get_integrations_admin_integrations_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/{integration_id}":{"put":{"tags":["管理后台"],"summary":"Update Integration","description":"更新集成配置(支持 url_key 和 access_key 两种模式)。\n\n- url_key 模式(Dify / RAGFlow):传入 api_url + api_key\n- access_key 模式(火绒安全):传入 access_key_id + access_key_secret + base_url\n\nArgs:\n integration_id: 集成系统ID(如 dify/ragflow/huorong\n body: 更新请求体\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的集成信息","operationId":"update_integration_admin_integrations__integration_id__put","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"string","title":"Integration Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/quick-replies/pending":{"get":{"tags":["管理后台"],"summary":"List Pending Quick Replies","description":"获取待审核快速回复模板列表。\n\nArgs:\n category: 按分类筛选(可选)\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含待审核模板列表","operationId":"list_pending_quick_replies_admin_quick_replies_pending_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按分类筛选","title":"Category"},"description":"按分类筛选"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/quick-replies/{template_id}/review":{"put":{"tags":["管理后台"],"summary":"Review Quick Reply","description":"审核快速回复模板(通过/驳回)。\n\nArgs:\n template_id: 模板ID\n body: 审核请求体\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含审核结果","operationId":"review_quick_reply_admin_quick_replies__template_id__review_put","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickReplyReviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/assignment-mode":{"get":{"tags":["管理后台"],"summary":"Get Assignment Mode","description":"获取当前分配模式。\n\nArgs:\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含分配模式信息","operationId":"get_assignment_mode_admin_assignment_mode_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["管理后台"],"summary":"Update Assignment Mode","description":"切换分配模式(阶段一仅允许手动接单)。\n\nArgs:\n body: 更新请求体\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含更新后的分配模式","operationId":"update_assignment_mode_admin_assignment_mode_put","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentModeUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/monitor/sessions":{"get":{"tags":["管理后台"],"summary":"Get Monitor Sessions","description":"获取实时会话列表(Demo预览)。\n\nArgs:\n status: 按会话状态筛选(可选)\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含会话监控数据","operationId":"get_monitor_sessions_admin_monitor_sessions_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按会话状态筛选","title":"Status"},"description":"按会话状态筛选"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/search":{"get":{"tags":["管理后台"],"summary":"Global Search","description":"搜索配置项、坐席、快速回复。\n\nArgs:\n q: 搜索关键词\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含搜索结果","operationId":"global_search_admin_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"搜索关键词","title":"Q"},"description":"搜索关键词"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/huorong/test":{"post":{"tags":["管理后台"],"summary":"Test Huorong Connection","description":"测试火绒API连接。\n\n使用当前保存的 AccessKey 配置调用火绒 _list 接口验证连接。\n仅请求1条数据,最小化对火绒系统的影响。\n失败时返回调试信息帮助排查凭据问题。\n\nArgs:\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 包含 success(bool) 和 message(str),失败时含 debug 信息","operationId":"test_huorong_connection_admin_integrations_huorong_test_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/huorong/terminals":{"get":{"tags":["管理后台"],"summary":"List Huorong Terminals","description":"查询火绒终端列表。\n\n代理火绒 /api/clnts/_list 接口,返回终端基本信息。\n\nArgs:\n group_id: 分组ID(可选)\n page: 页码\n per_page: 每页条数\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 终端列表数据","operationId":"list_huorong_terminals_admin_integrations_huorong_terminals_get","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"分组ID","title":"Group Id"},"description":"分组ID"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页条数","default":20,"title":"Per Page"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/huorong/terminals/{client_id}":{"get":{"tags":["管理后台"],"summary":"Get Huorong Terminal Detail","description":"查询火绒终端详细信息。\n\n代理火绒 /api/clnts/_info2 接口,返回终端硬件/软件/资产/网络配置。\n\nArgs:\n client_id: 终端唯一ID\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 终端详细信息","operationId":"get_huorong_terminal_detail_admin_integrations_huorong_terminals__client_id__get","parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/huorong/leaks":{"get":{"tags":["管理后台"],"summary":"List Huorong Leaks","description":"查询火绒高危漏洞终端。\n\n代理火绒 /api/clnts/_leak 接口。\n\nArgs:\n group_id: 分组ID(可选)\n page: 页码\n per_page: 每页条数\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 漏洞终端列表","operationId":"list_huorong_leaks_admin_integrations_huorong_leaks_get","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"分组ID","title":"Group Id"},"description":"分组ID"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页条数","default":20,"title":"Per Page"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/huorong/virus-events":{"get":{"tags":["管理后台"],"summary":"List Huorong Virus Events","description":"查询火绒病毒事件统计。\n\n代理火绒 /api/clnts/_virus_events 接口。\n火绒API要求 type 参数: 0=按client_id查, 1=按group_id查, 2=查全部。\n\nArgs:\n client_id: 终端IDtype=0时需提供)\n group_id: 分组IDtype=1时需提供)\n query_type: 查询类型,默认2(全部)\n page: 页码\n per_page: 每页条数\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 病毒事件统计数据","operationId":"list_huorong_virus_events_admin_integrations_huorong_virus_events_get","parameters":[{"name":"client_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"终端IDtype=0时需提供)","title":"Client Id"},"description":"终端IDtype=0时需提供)"},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"分组IDtype=1时需提供)","title":"Group Id"},"description":"分组IDtype=1时需提供)"},{"name":"query_type","in":"query","required":false,"schema":{"type":"integer","maximum":2,"minimum":0,"description":"查询类型: 0=按终端ID, 1=按分组ID, 2=全部","default":2,"title":"Query Type"},"description":"查询类型: 0=按终端ID, 1=按分组ID, 2=全部"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页条数","default":20,"title":"Per Page"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/lianruan/test":{"post":{"tags":["管理后台"],"summary":"Test Lianruan Connection","description":"测试联软API连接。\n\n通过获取Token验证:IP白名单 + 账号密码 + Token。\n\nArgs:\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 包含 success(bool) 和 message(str)","operationId":"test_lianruan_connection_admin_integrations_lianruan_test_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/lianruan/terminals":{"get":{"tags":["管理后台"],"summary":"Query Lianruan Terminals","description":"查询联软终端设备(核心映射接口)。\n\n⭐ strusername 参数可直接按员工账号查终端!这是联软最大的优势。\n\nArgs:\n strusername: 员工账号(映射金钥匙)\n strdevname: 计算机名\n strdevip: IP地址\n page: 页码\n per_page: 每页条数\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 终端列表数据","operationId":"query_lianruan_terminals_admin_integrations_lianruan_terminals_get","parameters":[{"name":"strusername","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"员工账号(核心映射字段)","title":"Strusername"},"description":"员工账号(核心映射字段)"},{"name":"strdevname","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"计算机名","title":"Strdevname"},"description":"计算机名"},{"name":"strdevip","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IP地址","title":"Strdevip"},"description":"IP地址"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页条数","default":20,"title":"Per Page"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/audit/conversations":{"get":{"tags":["管理后台"],"summary":"List Audit Conversations","description":"获取会话审计列表(支持分页+多条件筛选)。","operationId":"list_audit_conversations_admin_audit_conversations_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按状态筛选","title":"Status"},"description":"按状态筛选"},{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按坐席筛选","title":"Agent Id"},"description":"按坐席筛选"},{"name":"keyword","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按员工姓名/消息摘要搜索","title":"Keyword"},"description":"按员工姓名/消息摘要搜索"},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"开始日期 YYYY-MM-DD","title":"Date From"},"description":"开始日期 YYYY-MM-DD"},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"结束日期 YYYY-MM-DD","title":"Date To"},"description":"结束日期 YYYY-MM-DD"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页条数","default":20,"title":"Page Size"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/audit/conversations/{conversation_id}":{"get":{"tags":["管理后台"],"summary":"Get Audit Conversation Detail","description":"获取会话审计详情(含消息列表)。","operationId":"get_audit_conversation_detail_admin_audit_conversations__conversation_id__get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/agent-performance":{"get":{"tags":["管理后台"],"summary":"Get Agent Performance","description":"获取坐席绩效统计。","operationId":"get_agent_performance_admin_agent_performance_get","parameters":[{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"开始日期 YYYY-MM-DD","title":"Date From"},"description":"开始日期 YYYY-MM-DD"},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"结束日期 YYYY-MM-DD","title":"Date To"},"description":"结束日期 YYYY-MM-DD"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/system-logs":{"get":{"tags":["管理后台"],"summary":"Get System Logs","description":"获取系统日志(配置变更日志)。","operationId":"get_system_logs_admin_system_logs_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"每页条数","default":50,"title":"Page Size"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/lianruan/terminals/{devname}/detail":{"get":{"tags":["管理后台"],"summary":"Get Lianruan Terminal Detail","description":"查询联软终端详细信息(极详细)。\n\n比火绒_info2更丰富,含逻辑磁盘使用率、显示器、内存条详情。\n\nArgs:\n devname: 计算机名\n admin: 管理员\n db: 数据库会话\n\nReturns:\n Dict: 终端详细信息","operationId":"get_lianruan_terminal_detail_admin_integrations_lianruan_terminals__devname__detail_get","parameters":[{"name":"devname","in":"path","required":true,"schema":{"type":"string","title":"Devname"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/ragflow/test":{"post":{"tags":["管理后台"],"summary":"Test Ragflow Connection","description":"测试 RAGFlow API 连接。","operationId":"test_ragflow_connection_admin_integrations_ragflow_test_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/ragflow/datasets":{"get":{"tags":["管理后台"],"summary":"List Ragflow Datasets","description":"列出 RAGFlow 知识库(数据集)。","operationId":"list_ragflow_datasets_admin_integrations_ragflow_datasets_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"每页条数","default":20,"title":"Page Size"},"description":"每页条数"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/integrations/ragflow/retrieval":{"post":{"tags":["管理后台"],"summary":"Ragflow Retrieval","description":"RAGFlow 知识检索测试。","operationId":"ragflow_retrieval_admin_integrations_ragflow_retrieval_post","parameters":[{"name":"question","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"查询问题","title":"Question"},"description":"查询问题"},{"name":"dataset_ids","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"数据集ID列表(逗号分隔)","title":"Dataset Ids"},"description":"数据集ID列表(逗号分隔)"},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"返回结果数量","default":5,"title":"Top K"},"description":"返回结果数量"},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/portal/roles":{"get":{"tags":["统一入口"],"summary":"Get User Roles","description":"获取当前用户的角色信息。\n\n返回用户的基本信息和角色列表,用于路由选择页展示。\n\nArgs:\n current_user: 当前用户(通过认证依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含用户信息和角色列表","operationId":"get_user_roles_portal_roles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/portal/switch-role":{"post":{"tags":["统一入口"],"summary":"Switch Role","description":"切换当前角色。\n\n更新 Redis Token 中的 current_role 字段,返回目标角色的入口 URL。\n\nArgs:\n body: 切换角色请求\n current_user: 当前用户(通过认证依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含切换后的角色和重定向 URL","operationId":"switch_role_portal_switch_role_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchRoleRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"HTTPBearer":[]}]}},"/portal/entry/{role_name}":{"get":{"tags":["统一入口"],"summary":"Get Role Entry","description":"获取角色对应的入口 URL。\n\nArgs:\n role_name: 角色标识\n current_user: 当前用户(通过认证依赖注入)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含角色信息和入口 URL","operationId":"get_role_entry_portal_entry__role_name__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"role_name","in":"path","required":true,"schema":{"type":"string","title":"Role Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/roles":{"get":{"tags":["角色管理"],"summary":"Get Roles","description":"获取所有角色列表。\n\n返回角色列表,包含每个角色的用户数量统计。\n\nArgs:\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含角色列表","operationId":"get_roles_admin_roles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/roles/assign":{"post":{"tags":["角色管理"],"summary":"Assign Role","description":"手动分配角色。\n\n为指定用户分配角色,记录分配者和分配原因。\n安全限制:禁止管理员给自己分配角色。\n\nArgs:\n body: 分配角色请求\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"assign_role_admin_roles_assign_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/roles/revoke":{"post":{"tags":["角色管理"],"summary":"Revoke Role","description":"撤销角色。\n\n撤销指定用户的角色。\n安全限制:禁止管理员撤销自己的角色。\n\nArgs:\n body: 撤销角色请求\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"revoke_role_admin_roles_revoke_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRevokeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/roles/mapping-rules":{"get":{"tags":["角色管理"],"summary":"Get Mapping Rules","description":"获取所有角色映射规则。\n\nArgs:\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含映射规则列表","operationId":"get_mapping_rules_admin_roles_mapping_rules_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["角色管理"],"summary":"Create Mapping Rule","description":"创建角色映射规则。\n\nArgs:\n body: 创建映射规则请求\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含新创建的规则 ID","operationId":"create_mapping_rule_admin_roles_mapping_rules_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleMappingRuleRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/roles/mapping-rules/{rule_id}":{"delete":{"tags":["角色管理"],"summary":"Delete Mapping Rule","description":"删除角色映射规则。\n\nArgs:\n rule_id: 规则 ID\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式","operationId":"delete_mapping_rule_admin_roles_mapping_rules__rule_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/roles/permissions/matrix":{"get":{"tags":["角色管理"],"summary":"Get Permissions Matrix","description":"获取 RBAC 完整权限矩阵(管理后台可视化用)。\n\n返回 5 角色预置的 permissions JSON,前端用此数据渲染\n角色 × 资源 × 操作 × 范围 的可读表格。\n\nArgs:\n admin: 管理员(权限校验)\n db: 数据库会话\n\nReturns:\n Dict: 统一响应格式,包含完整权限矩阵","operationId":"get_permissions_matrix_admin_roles_permissions_matrix_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/roles/permissions/check":{"get":{"tags":["角色管理"],"summary":"Check My Permission","description":"检查当前管理员是否拥有指定权限(给前端按钮级控制用)。\n\n永远返回 true(因为 require_admin 已确保是 admin)。\n此端点存在是为了给前端一个统一入口,实际权限由后端强制。\n未来扩展:可加 current_user 参数(非 admin 角色也能调)。\n\nArgs:\n resource: 资源\n action: 操作\n scope: 数据范围\n\nReturns:\n Dict: 统一响应格式,包含 has_permission 字段","operationId":"check_my_permission_admin_roles_permissions_check_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"resource","in":"query","required":true,"schema":{"type":"string","description":"资源","title":"Resource"},"description":"资源"},{"name":"action","in":"query","required":true,"schema":{"type":"string","description":"操作","title":"Action"},"description":"操作"},{"name":"scope","in":"query","required":false,"schema":{"type":"string","description":"数据范围","default":"own","title":"Scope"},"description":"数据范围"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/security/comparison/summary":{"get":{"tags":["终端安全对比","终端安全对比"],"summary":"Get Comparison Summary","description":"获取比对汇总数据","operationId":"get_comparison_summary_security_comparison_summary_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareSummaryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/security/comparison/no-huorong":{"get":{"tags":["终端安全对比","终端安全对比"],"summary":"Get No Huorong Devices","description":"获取未安装火绒的电脑清单","operationId":"get_no_huorong_devices_security_comparison_no_huorong_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NoHuorongDevice"},"title":"Response Get No Huorong Devices Security Comparison No Huorong Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/security/comparison/trigger":{"post":{"tags":["终端安全对比","终端安全对比"],"summary":"Trigger Comparison","description":"手动触发比对并推送企微消息","operationId":"trigger_comparison_security_comparison_trigger_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/security/comparison/tasks":{"get":{"tags":["终端安全对比","终端安全对比"],"summary":"List Tasks","description":"列出所有定时任务","operationId":"list_tasks_security_comparison_tasks_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskConfigResponse"},"title":"Response List Tasks Security Comparison Tasks Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["终端安全对比","终端安全对比"],"summary":"Create Task","description":"创建定时任务","operationId":"create_task_security_comparison_tasks_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskConfigRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/security/comparison/tasks/{task_id}":{"delete":{"tags":["终端安全对比","终端安全对比"],"summary":"Delete Task","description":"删除定时任务","operationId":"delete_task_security_comparison_tasks__task_id__delete","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/approval/templates":{"get":{"tags":["审批流程"],"summary":"Get Approval Templates","description":"获取所有审批模板列表","operationId":"get_approval_templates_approval_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApprovalTemplateResponse"},"type":"array","title":"Response Get Approval Templates Approval Templates Get"}}}}}}},"/approval/templates/{template_id}":{"get":{"tags":["审批流程"],"summary":"Get Approval Template","description":"获取指定审批模板详情","operationId":"get_approval_template_approval_templates__template_id__get","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/approval/jump":{"post":{"tags":["审批流程"],"summary":"Create Approval Jump","description":"生成跳转审批链接(模板124跳转方式)","operationId":"create_approval_jump_approval_jump_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalJumpRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalJumpResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/approval/submit":{"post":{"tags":["审批流程"],"summary":"Submit Approval","description":"API提交审批(模板122 API方式)","operationId":"submit_approval_approval_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalSubmitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/approval/keywords":{"get":{"tags":["审批流程"],"summary":"Get Approval Keywords","description":"获取所有审批关键词(用于前端关键词检测)","operationId":"get_approval_keywords_approval_keywords_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/wecom/jsapi-config":{"get":{"tags":["企微JS-SDK"],"summary":"Get Jsapi Config","description":"获取企微 JS-SDK 鉴权配置。\n\n供前端 wx.config 和 wx.agentConfig 使用。\n\nReturns:\n {\n \"code\": 0,\n \"data\": {\n \"corp_id\": \"wwa8c87970b2011f41\",\n \"agent_id\": \"1000133\",\n \"timestamp\": 1718500000,\n \"nonce_str\": \"5K8264ILTKCH...\",\n \"signature\": \"f7c8e9...\"\n }\n }","operationId":"get_jsapi_config_wecom_jsapi_config_get","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","description":"当前页面 URL(不含 # 及其后)","title":"Url"},"description":"当前页面 URL(不含 # 及其后)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wecom/check-role":{"get":{"tags":["企微JS-SDK"],"summary":"Check Emergency Role","description":"检测当前账号在应急页场景下的角色。\n\n实现方式(优先级递减):\n1. 企微通讯录标签检测(若配置 WECOM_AGENT_TAG_ID)\n2. 后台硬编码名单(若配置 WECOM_AGENT_USERIDS 环境变量)\n3. 默认 \"user\" (兜底)\n\nArgs:\n userid: 企微 userid(从 wx.agentConfig 拿)\n\nReturns:\n {\n \"code\": 0,\n \"data\": {\n \"role\": \"user\" | \"agent\",\n \"userid\": \"...\",\n \"method\": \"tag\" | \"hardcoded\" | \"default\"\n }\n }","operationId":"check_emergency_role_wecom_check_role_get","parameters":[{"name":"userid","in":"query","required":true,"schema":{"type":"string","description":"企微 userid","title":"Userid"},"description":"企微 userid"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth_qrcode/create":{"post":{"tags":["扫码登录","扫码登录"],"summary":"Create Qrcode","description":"创建扫码登录票据。\n\n无需鉴权(用户尚未登录,正在登录页)。\n返回 ticket + 企微 OAuth2 授权 URL,前端渲染二维码。\n\nReturns:\n Dict: 统一响应格式,data 字段是 QrcodeCreateResponse","operationId":"create_qrcode_auth_qrcode_create_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth_qrcode/poll/{ticket}":{"get":{"tags":["扫码登录","扫码登录"],"summary":"Poll Qrcode","description":"轮询扫码状态。\n\n无需鉴权(浏览器未登录态访问)。\n\n状态机:\n - waiting: ticket 有效,等待扫码\n - scanned: 已扫码,等待 confirm\n - confirmed: 已确认,返回 token\n - expired: ticket 过期/不存在\n\nReturns:\n Dict: 统一响应格式,data 字段是 QrcodePollResponse","operationId":"poll_qrcode_auth_qrcode_poll__ticket__get","parameters":[{"name":"ticket","in":"path","required":true,"schema":{"type":"string","description":"扫码登录票据","title":"Ticket"},"description":"扫码登录票据"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth_qrcode/scan":{"get":{"tags":["扫码登录","扫码登录"],"summary":"Scan Qrcode","description":"处理企微 OAuth2 扫码回调。\n\n企微 OAuth2 标准回调走 **GET** 带 query 参数 `?code=xxx&state=<ticket>`,\n本端点同时支持 GET 和 POST(POST 兼容内部调用 / 旧前端代码)。\n\nGET 模式 (企微 OAuth2 标准回调):\n - ticket ← query.state\n - code ← query.code\n - 自动 302 跳转到 /itdesk/ 或 /itadmin/ 或 /itagent/(按角色)\nPOST 模式 (内部调用):\n - ticket ← body.ticket\n - code ← body.code\n\n无需鉴权(此端点被企微服务器回调,带 code + ticket)。\n用 code 换取企微 userid,然后写 Redis scan:{ticket} 等待 confirm 端点。\n\ndev 模式: code 形如 \"dev:dev-user-001\",跳过企微 API 调用。","operationId":"scan_qrcode_auth_qrcode_scan_get","parameters":[{"name":"ticket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"扫码登录票据(企微 OAuth state 参数)","title":"Ticket"},"description":"扫码登录票据(企微 OAuth state 参数)"},{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"企微 OAuth 授权码","title":"Code"},"description":"企微 OAuth 授权码"}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/QrcodeScanRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["扫码登录","扫码登录"],"summary":"Scan Qrcode","description":"处理企微 OAuth2 扫码回调。\n\n企微 OAuth2 标准回调走 **GET** 带 query 参数 `?code=xxx&state=<ticket>`,\n本端点同时支持 GET 和 POST(POST 兼容内部调用 / 旧前端代码)。\n\nGET 模式 (企微 OAuth2 标准回调):\n - ticket ← query.state\n - code ← query.code\n - 自动 302 跳转到 /itdesk/ 或 /itadmin/ 或 /itagent/(按角色)\nPOST 模式 (内部调用):\n - ticket ← body.ticket\n - code ← body.code\n\n无需鉴权(此端点被企微服务器回调,带 code + ticket)。\n用 code 换取企微 userid,然后写 Redis scan:{ticket} 等待 confirm 端点。\n\ndev 模式: code 形如 \"dev:dev-user-001\",跳过企微 API 调用。","operationId":"scan_qrcode_auth_qrcode_scan_get","parameters":[{"name":"ticket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"扫码登录票据(企微 OAuth state 参数)","title":"Ticket"},"description":"扫码登录票据(企微 OAuth state 参数)"},{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"企微 OAuth 授权码","title":"Code"},"description":"企微 OAuth 授权码"}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/QrcodeScanRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth_qrcode/confirm":{"post":{"tags":["扫码登录","扫码登录"],"summary":"Confirm Qrcode","description":"处理当前已登录坐席的扫码确认授权。\n\n需要鉴权: 只有已登录的坐席/管理员能确认授权。\n把扫码用户身份变成可登录 Token(roles=['agent']),\n写 Redis confirm:{ticket},前端 poll 拿到后跳坐席主页。\n\notp_code: admin 场景下可选,Phase 1.1 仅记录日志,\n 真实 OTP 校验留给 Phase 2.1(参考 agents.py:272-274 的 totp.verify)。\n\nArgs:\n body: 包含 ticket 和 otp_code(可选)\n current_user: 当前已登录用户(由 get_current_user 注入)\n redis_client: Redis 客户端\n\nReturns:\n Dict: 统一响应格式,data 字段是 QrcodeConfirmResponse","operationId":"confirm_qrcode_auth_qrcode_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QrcodeConfirmRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/high-risk/demo/{category}":{"post":{"tags":["高危操作"],"summary":"演示高危操作 OTP 守卫","description":"展示 5 类高危操作(role_change / config_change / data_export / account_disable / account_create_reset)的 OTP 守卫流程。<br><br>调用此端点时,如果当前管理员 30 分钟内没在 /api/auth/otp-verify 过 OTP,会返回错误码 2001,前端应弹 OTP 输入框 → 调 /api/auth/otp-verify → 重试。","operationId":"demo_high_risk_op_admin_high_risk_demo__category__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Demo High Risk Op Admin High Risk Demo Category Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/high-risk/whitelist":{"get":{"tags":["高危操作"],"summary":"获取高危操作白名单","description":"返回 5 类高危操作的元数据,供前端文档化展示。","operationId":"get_whitelist_admin_high_risk_whitelist_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Whitelist Admin High Risk Whitelist Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/high-risk/check":{"get":{"tags":["高危操作"],"summary":"检查当前管理员 OTP 验证状态","description":"查询当前管理员是否在 30 分钟内通过过 OTP。前端在弹 OTP 输入框前先调一次此端点,如果已验证就不弹。","operationId":"check_otp_status_admin_high_risk_check_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Check Otp Status Admin High Risk Check Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/mfa/status":{"get":{"tags":["MFA二次认证","MFA二次认证"],"summary":"Get Mfa Status","description":"查询当前用户的 MFA 绑定状态。\n\n前端路由守卫使用:\n - bound=false → 强制走绑定流程\n - bound=true → 跳到\"输入 OTP 验证\"或继续业务\n\nReturns:\n success_response({bound, enabled, last_verified_at})","operationId":"get_mfa_status_mfa_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/mfa/bind/start":{"post":{"tags":["MFA二次认证","MFA二次认证"],"summary":"Bind Start","description":"生成 TOTP 密钥和二维码。\n\n行为:\n - 生成 32 位 base32 secret\n - 把 secret 写入 agents.mfa_secret(mfa_enabled=False,mfa_bound_at=None)\n - 返回 otpauth URI + base64 二维码 PNG(给前端展示)\n\n重复调用策略:\n - 如果已经 enabled=True → 拒绝,要求先 disable 再重新绑定\n - 如果只是 secret 存在但 enabled=False → 复用旧 secret(支持\"刷新二维码\")\n\nReturns:\n success_response({secret, otpauth_url, qr_code_base64})","operationId":"bind_start_mfa_bind_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/mfa/bind/confirm":{"post":{"tags":["MFA二次认证","MFA二次认证"],"summary":"Bind Confirm","description":"用 6 位 OTP 码确认绑定,启用 MFA。\n\n行为:\n - 用 mfa_secret 校验 otp_code(valid_window=1)\n - 校验通过 → mfa_enabled=True, mfa_bound_at=now(), mfa_last_verified_at=now()\n - 校验失败 → 抛 AppException(E_INVALID_PARAMETER)\n\nReturns:\n success_response({success: true})","operationId":"bind_confirm_mfa_bind_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MFABindConfirmRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/mfa/verify":{"post":{"tags":["MFA二次认证","MFA二次认证"],"summary":"Verify Mfa","description":"校验 6 位码,在 Redis 写 30 分钟复用标记。\n\n行为:\n - 校验通过 → mfa:verified:{employee_id}=1 TTL 1800s\n + 更新 mfa_last_verified_at\n - 校验失败 → verified=false(不抛异常,前端可以重试)\n\nReturns:\n success_response({verified, expires_in})","operationId":"verify_mfa_mfa_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MFAVerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/mfa/disable":{"post":{"tags":["MFA二次认证","MFA二次认证"],"summary":"Disable Mfa","description":"关闭 MFA(清空 secret + disabled 标记)。\n\n安全要求: 必须先校验当前 OTP,防止误操作或被劫持后恶意关闭。\n\nReturns:\n success_response({success: true})","operationId":"disable_mfa_mfa_disable_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MFADisableRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/admin/mfa/reset/{employee_id}":{"post":{"tags":["MFA管理(管理员)","MFA管理(管理员)"],"summary":"Admin Reset Mfa","description":"管理员重置指定员工的 MFA 绑定(无 OTP 验证)。\n\n使用场景:\n - 员工丢手机/换手机 → 管理员后台\"重置 MFA\"按钮\n\n鉴权:校验 current_user 是否拥有 admin 角色。\n\nReturns:\n success_response({success: true})","operationId":"admin_reset_mfa_admin_mfa_reset__employee_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"employee_id","in":"path","required":true,"schema":{"type":"string","title":"Employee Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth_wecom/sso/init":{"get":{"tags":["企微SSO","企微 SSO"],"summary":"Sso Init","description":"初始化 SSO: 生成 state,302 跳转到企微 OAuth2 授权页。\n\nArgs:\n next: 登录成功后跳转路径,如 /itdesk/ /itagent/ /itadmin/","operationId":"sso_init_auth_wecom_sso_init_get","parameters":[{"name":"next","in":"query","required":false,"schema":{"type":"string","description":"登录后跳转路径","default":"/itdesk/","title":"Next"},"description":"登录后跳转路径"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth_wecom/sso/callback":{"get":{"tags":["企微SSO","企微 SSO"],"summary":"Sso Callback","description":"企微 OAuth 回调: 用 code 换 userid → 查 role → 生成 token → 跳 next。","operationId":"sso_callback_auth_wecom_sso_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","description":"企微 OAuth2 授权 code","title":"Code"},"description":"企微 OAuth2 授权 code"},{"name":"state","in":"query","required":true,"schema":{"type":"string","description":"防 CSRF state","title":"State"},"description":"防 CSRF state"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth_wecom/sso/verify":{"get":{"tags":["企微SSO","企微 SSO"],"summary":"Sso Verify","description":"前端用 SSO token 换用户身份(token 一次性使用,用完删除)。","operationId":"sso_verify_auth_wecom_sso_verify_get","parameters":[{"name":"sso_token","in":"query","required":true,"schema":{"type":"string","description":"SSO token","title":"Sso Token"},"description":"SSO token"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/audit-logs":{"get":{"tags":["审计日志","审计日志"],"summary":"Get Audit Logs","description":"查询审计日志(分页)。\n\n权限: 需要 audit_log:read:all (admin / auditor 角色拥有)\n\nReturns:\n Dict: 统一响应格式,包含 items/total/page/page_size","operationId":"get_audit_logs_admin_audit_logs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"employee_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按操作人过滤","title":"Employee Id"},"description":"按操作人过滤"},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按操作类型过滤","title":"Action"},"description":"按操作类型过滤"},{"name":"resource","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"按资源类型过滤","title":"Resource"},"description":"按资源类型过滤"},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"起始时间(ISO8601)","title":"From"},"description":"起始时间(ISO8601)"},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"结束时间(ISO8601)","title":"To"},"description":"结束时间(ISO8601)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"页码","default":1,"title":"Page"},"description":"页码"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"每页条数","default":50,"title":"Page Size"},"description":"每页条数"}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/UserInfo"}],"title":"Admin"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/test-ping":{"get":{"tags":["诊断"],"summary":"Test Ping","description":"简单测试 — 不依赖数据库和 Redis","operationId":"test_ping_test_ping_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/test-error":{"get":{"tags":["诊断"],"summary":"Test Error","description":"测试异常处理 — 故意抛出异常","operationId":"test_error_test_error_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"tags":["系统"],"summary":"Health Check","description":"健康检查端点。\n\n返回服务运行状态,用于:\n- Docker 健康检查\n- 负载均衡探针\n- 监控系统检测服务是否存活","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/ready":{"get":{"tags":["系统"],"summary":"Readiness Check","description":"就绪检查端点。\n\n检查服务依赖(DB + Redis),不调用企微 API(避免阻塞)。\n用于 K8s readinessProbe。","operationId":"readiness_check_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/metrics":{"get":{"tags":["系统"],"summary":"Metrics","description":"指标端点。\n\n返回服务运行指标,用于 Prometheus 采集。","operationId":"metrics_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/version":{"get":{"tags":["系统"],"summary":"Version","description":"版本信息端点。\n\n返回服务版本信息。","operationId":"version_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AgentCreateRequest":{"properties":{"user_id":{"type":"string","maxLength":64,"minLength":1,"title":"User Id","description":"企微用户ID"},"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name","description":"坐席姓名"},"role":{"type":"string","title":"Role","description":"角色: admin=组长, agent=坐席","default":"agent"},"skill_tags":{"items":{"type":"string"},"type":"array","title":"Skill Tags","description":"技能标签列表"},"max_load":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Max Load","description":"最大同时服务数","default":5}},"type":"object","required":["user_id","name"],"title":"AgentCreateRequest","description":"创建坐席请求 Schema。\n\nAttributes:\n user_id: 企微用户ID\n name: 坐席姓名\n role: 角色(admin=组长, agent=坐席)\n skill_tags: 技能标签列表\n max_load: 最大同时服务数"},"AgentLogin":{"properties":{"user_id":{"type":"string","maxLength":64,"minLength":1,"title":"User Id","description":"企微用户ID"},"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name","description":"坐席姓名"},"otp_code":{"anyOf":[{"type":"string","maxLength":6,"minLength":6},{"type":"null"}],"title":"Otp Code","description":"OTP动态码(6位数字)"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password","description":"本地密码(可选)"}},"type":"object","required":["user_id","name"],"title":"AgentLogin","description":"坐席登录请求 Schema。\n\n第一步使用简单的用户名密码登录。\nuser_id 对应企微通讯录中的 UserID。\nadmin 角色需要 OTP 二次验证。\n可选本地密码认证(企微验证失败时的备用认证)。\n\nP0-#5 改动:\n- 新增 password 字段:本地密码(可选)\n- 企微主路径优先 → 本地 password 双因子(新增)\n\nAttributes:\n user_id: 企微用户ID\n name: 坐席姓名\n otp_code: OTP 动态码(admin 角色必填)\n password: 本地密码(企微验证失败时的备用认证)"},"AgentPasswordUpdate":{"properties":{"old_password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Password","description":"旧密码(验证用)"},"new_password":{"type":"string","maxLength":128,"minLength":6,"title":"New Password","description":"新密码"}},"type":"object","required":["new_password"],"title":"AgentPasswordUpdate","description":"坐席修改密码请求 Schema"},"AgentStatusUpdate":{"properties":{"status":{"type":"string","title":"Status","description":"坐席状态: online/offline/busy"}},"type":"object","required":["status"],"title":"AgentStatusUpdate","description":"坐席状态更新请求 Schema。\n\n坐席上线、离线、设为忙碌时使用。\n\nAttributes:\n status: 新的坐席状态"},"AgentUpdateRequest":{"properties":{"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"角色: admin=组长, agent=坐席"},"skill_tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Skill Tags","description":"技能标签列表"},"max_load":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Max Load","description":"最大同时服务数"}},"type":"object","title":"AgentUpdateRequest","description":"更新坐席请求 Schema。\n\n所有字段可选,只更新传入的字段。\n\nAttributes:\n role: 角色\n skill_tags: 技能标签列表\n max_load: 最大同时服务数"},"ApprovalJumpRequest":{"properties":{"template_id":{"type":"string","title":"Template Id"},"employee_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Employee Id"}},"type":"object","required":["template_id"],"title":"ApprovalJumpRequest","description":"跳转审批请求"},"ApprovalJumpResponse":{"properties":{"url":{"type":"string","title":"Url"},"template_name":{"type":"string","title":"Template Name"}},"type":"object","required":["url","template_name"],"title":"ApprovalJumpResponse","description":"跳转审批响应"},"ApprovalSubmitRequest":{"properties":{"template_id":{"type":"string","title":"Template Id"},"employee_id":{"type":"string","title":"Employee Id"},"content":{"type":"object","title":"Content"}},"type":"object","required":["template_id","employee_id","content"],"title":"ApprovalSubmitRequest","description":"API提交审批请求"},"ApprovalSubmitResponse":{"properties":{"sp_no":{"type":"string","title":"Sp No"},"template_name":{"type":"string","title":"Template Name"}},"type":"object","required":["sp_no","template_name"],"title":"ApprovalSubmitResponse","description":"API提交审批响应"},"ApprovalTemplateResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type"},"keywords":{"items":{"type":"string"},"type":"array","title":"Keywords"}},"type":"object","required":["id","name","type","keywords"],"title":"ApprovalTemplateResponse","description":"审批模板响应"},"AssignmentModeUpdateRequest":{"properties":{"mode":{"type":"string","title":"Mode","description":"分配模式ID"}},"type":"object","required":["mode"],"title":"AssignmentModeUpdateRequest","description":"分配模式更新请求 Schema。\n\nAttributes:\n mode: 要切换的分配模式ID"},"Body_upload_file_upload_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"上传的文件(图片或文档)"}},"type":"object","required":["file"],"title":"Body_upload_file_upload_post"},"Body_upload_image_messages_image_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_image_messages_image_post"},"Body_upload_message_file_messages_file_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_message_file_messages_file_post"},"CompareSummaryResponse":{"properties":{"lianruan_count":{"type":"integer","title":"Lianruan Count"},"huorong_count":{"type":"integer","title":"Huorong Count"},"no_huorong_count":{"type":"integer","title":"No Huorong Count"},"compliance_rate":{"type":"string","title":"Compliance Rate"},"generated_at":{"type":"string","title":"Generated At"}},"type":"object","required":["lianruan_count","huorong_count","no_huorong_count","compliance_rate","generated_at"],"title":"CompareSummaryResponse","description":"比对汇总响应"},"ConfigUpdateRequest":{"properties":{"value":{"type":"string","minLength":1,"title":"Value","description":"新的配置值"}},"type":"object","required":["value"],"title":"ConfigUpdateRequest","description":"配置更新请求 Schema。\n\nAttributes:\n value: 新的配置值"},"ConversationAssign":{"properties":{"agent_id":{"type":"string","maxLength":64,"minLength":1,"title":"Agent Id","description":"坐席ID"}},"type":"object","required":["agent_id"],"title":"ConversationAssign","description":"坐席接单请求 Schema。\n\nAttributes:\n agent_id: 接单的坐席ID"},"ConversationInvite":{"properties":{"agent_id":{"type":"string","maxLength":64,"minLength":1,"title":"Agent Id","description":"被邀请的坐席ID"}},"type":"object","required":["agent_id"],"title":"ConversationInvite","description":"摇人邀请请求 Schema。\n\nAttributes:\n agent_id: 被邀请的坐席ID"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IntegrationUpdateRequest":{"properties":{"api_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Url","description":"API 地址(Dify/RAGFlow 模式)"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key","description":"API KeyDify/RAGFlow 模式)"},"access_key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Key Id","description":"AccessKey ID(火绒模式)"},"access_key_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Key Secret","description":"AccessKey Secret(火绒模式)"},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url","description":"内网 Base URL(火绒/联软模式)"},"api_account":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Account","description":"API账号(联软模式)"},"api_password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Password","description":"API密码(联软模式)"},"validate_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Validate Key","description":"验证密钥(联软模式,可选)"}},"type":"object","title":"IntegrationUpdateRequest","description":"集成系统配置更新请求 Schema。\n\n支持三种模式:\n- url_key 模式(Dify / RAGFlow):传入 api_url + api_key\n- access_key 模式(火绒安全):传入 access_key_id + access_key_secret + base_url\n- account_password 模式(联软LV7000):传入 api_account + api_password + base_url + validate_key(可选)\n\nAttributes:\n # url_key 模式\n api_url: API 地址(可选,火绒/联软模式不需要)\n api_key: API Key(可选,火绒/联软模式不需要)\n\n # access_key 模式(火绒)\n access_key_id: AccessKey ID(可选)\n access_key_secret: AccessKey Secret(可选)\n base_url: 内网 Base URL(可选)\n\n # account_password 模式(联软)\n api_account: API账号(可选,联软模式)\n api_password: API密码(可选,联软模式)\n validate_key: 验证密钥(可选,联软模式)"},"InviteParticipantRequest":{"properties":{"participants":{"items":{"$ref":"#/components/schemas/ParticipantInfo"},"type":"array","maxItems":20,"minItems":1,"title":"Participants","description":"被邀请人列表"},"history_mode":{"type":"string","title":"History Mode","description":"历史消息共享模式: recent10/all/none","default":"recent10"}},"type":"object","required":["participants"],"title":"InviteParticipantRequest","description":"邀请员工/部门加入会话请求 Schema。\n\nAttributes:\n participants: 被邀请人列表\n history_mode: 历史消息共享模式 — recent10(最近10条)/ all(全部)/ none(不共享)"},"ItLevelUpdateRequest":{"properties":{"it_level":{"type":"string","title":"It Level","description":"IT技能等级: bronze/silver/gold/platinum/diamond/star/king"},"source":{"type":"string","title":"Source","description":"等级来源: system/manual/assessment","default":"manual"}},"type":"object","required":["it_level"],"title":"ItLevelUpdateRequest","description":"IT技能等级更新请求 Schema。"},"JoinConversationRequest":{"properties":{"employee_id":{"type":"string","maxLength":64,"minLength":1,"title":"Employee Id","description":"企微员工UserID"}},"type":"object","required":["employee_id"],"title":"JoinConversationRequest","description":"被邀请人加入会话请求 Schema。\n\nAttributes:\n employee_id: 被邀请人的企微UserID"},"MFABindConfirmRequest":{"properties":{"otp_code":{"type":"string","maxLength":6,"minLength":6,"title":"Otp Code","description":"6 位 OTP 动态码"}},"type":"object","required":["otp_code"],"title":"MFABindConfirmRequest","description":"POST /api/auth/otp-verify 请求体。\n\nAttributes:\n otp_code: 用户输入的 6 位 OTP 码"},"MFADisableRequest":{"properties":{"otp_code":{"type":"string","maxLength":6,"minLength":6,"title":"Otp Code","description":"6 位 OTP 动态码"}},"type":"object","required":["otp_code"],"title":"MFADisableRequest","description":"POST /api/auth/otp-unbind 请求体。\n\nAttributes:\n otp_code: 用户输入的 6 位 OTP 码(防止误操作)"},"MFAVerifyRequest":{"properties":{"otp_code":{"type":"string","maxLength":6,"minLength":6,"title":"Otp Code","description":"6 位 OTP 动态码"}},"type":"object","required":["otp_code"],"title":"MFAVerifyRequest","description":"POST /api/auth/otp-verify 请求体。\n\nAttributes:\n otp_code: 用户输入的 6 位 OTP 码"},"MessageCreate":{"properties":{"content":{"type":"string","minLength":1,"title":"Content","description":"消息内容"},"msg_type":{"type":"string","title":"Msg Type","description":"消息类型: text/image/file","default":"text"},"media_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Media Url","description":"媒体文件URL(图片/文件消息时使用)"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Name","description":"文件名"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size","description":"文件大小(字节)"},"reply_to_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reply To Id","description":"引用回复:被回复的消息ID"}},"type":"object","required":["content"],"title":"MessageCreate","description":"创建消息请求 Schema。\n\n坐席发送消息时使用。\n支持文本消息和文件/图片消息。\n\nAttributes:\n content: 消息内容(文本消息为正文,文件消息为文件URL或描述)\n msg_type: 消息类型(默认 text,支持 image/file\n media_url: 媒体文件URL(图片/文件消息时使用)\n file_name: 文件名(文件消息时使用)\n file_size: 文件大小(字节,文件消息时使用)"},"NoHuorongDevice":{"properties":{"hostname":{"type":"string","title":"Hostname"},"ip":{"type":"string","title":"Ip"},"useraccount":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Useraccount"},"dept":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dept"},"last_login":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Login"},"osver":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Osver"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","required":["hostname","ip"],"title":"NoHuorongDevice","description":"未安装火绒设备"},"OAuthCallbackRequest":{"properties":{"code":{"type":"string","minLength":1,"title":"Code","description":"企微OAuth2授权码"}},"type":"object","required":["code"],"title":"OAuthCallbackRequest","description":"OAuth2 回调请求 Schema。\n\nH5页面通过企微OAuth2授权后,将code传给后端换取员工身份。\n\nAttributes:\n code: 企微OAuth2授权码"},"ParticipantInfo":{"properties":{"id":{"type":"string","maxLength":64,"minLength":1,"title":"Id","description":"企微员工UserID或部门ID"},"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name","description":"姓名或部门名称"},"department":{"type":"string","maxLength":256,"title":"Department","description":"部门(仅员工类型)","default":""},"type":{"type":"string","title":"Type","description":"类型: employee/department","default":"employee"},"avatar":{"type":"string","maxLength":512,"title":"Avatar","description":"头像URL","default":""},"joined":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Joined","description":"是否已加入"},"joined_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Joined At","description":"加入时间(ISO格式)"}},"type":"object","required":["id","name"],"title":"ParticipantInfo","description":"被邀请人信息。\n\nAttributes:\n id: 企微员工UserID 或部门ID\n name: 姓名 或 部门名称\n department: 部门(仅员工类型有)\n type: 类型 — employee(个人)或 department(部门)\n avatar: 头像URL(从企微通讯录或employees表获取)\n joined: 是否已加入(邀请后、点击加入前为 False)\n joined_at: 加入时间(ISO 格式字符串)"},"QrcodeConfirmRequest":{"properties":{"ticket":{"type":"string","minLength":1,"title":"Ticket","description":"扫码登录票据"},"otp_code":{"anyOf":[{"type":"string","maxLength":6,"minLength":6},{"type":"null"}],"title":"Otp Code","description":"OTP 动态码(管理员可选,普通坐席留空)"}},"type":"object","required":["ticket"],"title":"QrcodeConfirmRequest","description":"扫码登录确认请求体。\n\nAttributes:\n ticket: 扫码登录票据(UUID)\n otp_code: OTP 动态码(管理员场景下可选,普通坐席可空)"},"QrcodeScanRequest":{"properties":{"ticket":{"type":"string","minLength":1,"title":"Ticket","description":"扫码登录票据"},"code":{"type":"string","minLength":1,"title":"Code","description":"企微 OAuth2 授权 code"}},"type":"object","required":["ticket","code"],"title":"QrcodeScanRequest","description":"扫码登录扫码请求体。\n\nAttributes:\n ticket: 扫码登录票据(UUID)\n code: 企微 OAuth2 授权回调 code"},"QuickReplyCreate":{"properties":{"category":{"type":"string","maxLength":64,"title":"Category","description":"分类","default":"通用"},"title":{"type":"string","maxLength":128,"minLength":1,"title":"Title","description":"模板标题"},"content":{"type":"string","minLength":1,"title":"Content","description":"模板内容"},"variables":{"items":{"type":"string"},"type":"array","title":"Variables","description":"可用变量列表"},"sort_order":{"type":"integer","title":"Sort Order","description":"排序权重","default":0}},"type":"object","required":["title","content"],"title":"QuickReplyCreate","description":"创建快速回复模板请求 Schema。\n\nAttributes:\n category: 分类(账号/网络/软件/硬件/通用)\n title: 模板标题\n content: 模板内容(支持 {employee_name} 等变量)\n variables: 可用变量列表\n sort_order: 排序权重"},"QuickReplyReviewRequest":{"properties":{"action":{"type":"string","title":"Action","description":"审核动作: approve/reject"},"reason":{"type":"string","title":"Reason","description":"审核原因/意见","default":""}},"type":"object","required":["action"],"title":"QuickReplyReviewRequest","description":"快速回复审核请求 Schema。\n\nAttributes:\n action: 审核动作(approve=通过, reject=驳回)\n reason: 审核原因/意见(驳回时建议填写)"},"QuickReplyUpdate":{"properties":{"category":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Category","description":"分类"},"title":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Title","description":"模板标题"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content","description":"模板内容"},"variables":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Variables","description":"可用变量列表"},"sort_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sort Order","description":"排序权重"}},"type":"object","title":"QuickReplyUpdate","description":"更新快速回复模板请求 Schema。\n\n所有字段可选,只更新传入的字段。\n\nAttributes:\n category: 分类\n title: 模板标题\n content: 模板内容\n variables: 可用变量列表\n sort_order: 排序权重"},"RoleAssignRequest":{"properties":{"employee_id":{"type":"string","maxLength":100,"minLength":1,"title":"Employee Id","description":"企微 UserID"},"role_name":{"type":"string","maxLength":50,"minLength":1,"title":"Role Name","description":"角色标识"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason","description":"分配原因"}},"type":"object","required":["employee_id","role_name"],"title":"RoleAssignRequest","description":"角色分配请求 Schema。\n\nAttributes:\n employee_id: 企微 UserID\n role_name: 角色标识(user/agent/admin\n reason: 分配原因(可选)"},"RoleMappingRuleRequest":{"properties":{"role_name":{"type":"string","maxLength":50,"minLength":1,"title":"Role Name","description":"目标角色标识"},"source_type":{"type":"string","maxLength":50,"minLength":1,"title":"Source Type","description":"来源类型"},"source_value":{"type":"string","maxLength":200,"minLength":1,"title":"Source Value","description":"来源值"},"priority":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Priority","description":"优先级(0-100","default":0},"is_active":{"type":"boolean","title":"Is Active","description":"是否启用","default":true}},"type":"object","required":["role_name","source_type","source_value"],"title":"RoleMappingRuleRequest","description":"角色映射规则创建/更新请求 Schema。\n\nAttributes:\n role_name: 目标角色标识(user/agent/admin\n source_type: 来源类型(wecom_tag/ehr_position\n source_value: 来源值(标签名/岗位关键词)\n priority: 优先级(数值越大优先级越高)\n is_active: 是否启用"},"RoleRevokeRequest":{"properties":{"employee_id":{"type":"string","maxLength":100,"minLength":1,"title":"Employee Id","description":"企微 UserID"},"role_name":{"type":"string","maxLength":50,"minLength":1,"title":"Role Name","description":"角色标识"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason","description":"撤销原因"}},"type":"object","required":["employee_id","role_name"],"title":"RoleRevokeRequest","description":"角色撤销请求 Schema。\n\nAttributes:\n employee_id: 企微 UserID\n role_name: 角色标识(user/agent/admin\n reason: 撤销原因(可选)"},"ShakeRequest":{"properties":{"employee_id":{"type":"string","maxLength":64,"minLength":1,"title":"Employee Id","description":"企微员工UserID"},"employee_name":{"type":"string","maxLength":128,"title":"Employee Name","description":"员工姓名","default":""}},"type":"object","required":["employee_id"],"title":"ShakeRequest","description":"摇人请求 Schema。\n\n用户点击H5页面摇人按钮时发送的请求。\n\nAttributes:\n employee_id: 企微员工UserID\n employee_name: 员工姓名"},"SwitchRoleRequest":{"properties":{"new_role":{"type":"string","maxLength":50,"minLength":1,"title":"New Role","description":"目标角色标识"}},"type":"object","required":["new_role"],"title":"SwitchRoleRequest","description":"角色切换请求 Schema。\n\nAttributes:\n new_role: 目标角色标识"},"TaskConfigRequest":{"properties":{"name":{"type":"string","title":"Name"},"cron":{"type":"string","title":"Cron"},"recipients":{"items":{"type":"string"},"type":"array","title":"Recipients"},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name","cron","recipients"],"title":"TaskConfigRequest","description":"任务配置请求"},"TaskConfigResponse":{"properties":{"task_id":{"type":"string","title":"Task Id"},"name":{"type":"string","title":"Name"},"cron":{"type":"string","title":"Cron"},"recipients":{"items":{"type":"string"},"type":"array","title":"Recipients"},"enabled":{"type":"boolean","title":"Enabled"},"last_run":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Run"},"next_run":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Run"}},"type":"object","required":["task_id","name","cron","recipients","enabled"],"title":"TaskConfigResponse","description":"任务配置响应"},"TodoStatusUpdateRequest":{"properties":{"status":{"type":"string","title":"Status","description":"新状态: pending/processing/resolved"}},"type":"object","required":["status"],"title":"TodoStatusUpdateRequest","description":"更新待办状态请求 Schema。"},"TroubleshootingTemplateCreateRequest":{"properties":{"name":{"type":"string","maxLength":256,"minLength":1,"title":"Name","description":"模板名称"},"category":{"type":"string","title":"Category","description":"分类: vpn/email/system/account","default":"system"},"path_steps":{"items":{"type":"object"},"type":"array","title":"Path Steps","description":"排障步骤路径"},"flowchart":{"type":"object","title":"Flowchart","description":"流程图定义"},"is_active":{"type":"boolean","title":"Is Active","description":"是否启用","default":true}},"type":"object","required":["name"],"title":"TroubleshootingTemplateCreateRequest","description":"创建排查模板请求 Schema。"},"TroubleshootingTemplateUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Name","description":"模板名称"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"分类"},"path_steps":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Path Steps","description":"排障步骤路径"},"flowchart":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Flowchart","description":"流程图定义"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active","description":"是否启用"}},"type":"object","title":"TroubleshootingTemplateUpdateRequest","description":"更新排查模板请求 Schema。"},"UserInfo":{"properties":{"employee_id":{"type":"string","title":"Employee Id"},"name":{"type":"string","title":"Name"},"department":{"type":"string","title":"Department"},"avatar":{"type":"string","title":"Avatar"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"current_role":{"type":"string","title":"Current Role"},"login_source":{"type":"string","title":"Login Source"}},"type":"object","required":["employee_id","name","department","avatar","roles","current_role","login_source"],"title":"UserInfo"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}