1 line
163 KiB
JSON
1 line
163 KiB
JSON
{"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 存入 Redis(TTL 8小时)。\n\n流程:\n1. 查找坐席记录(按 user_id),不存在则自动创建\n2. 生成随机 token\n3. token 存 Redis(key: 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: 终端ID(type=0时需提供)\n group_id: 分组ID(type=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":"终端ID(type=0时需提供)","title":"Client Id"},"description":"终端ID(type=0时需提供)"},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"分组ID(type=1时需提供)","title":"Group Id"},"description":"分组ID(type=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/mfa/verify 过 OTP,会返回错误码 2001,前端应弹 OTP 输入框 → 调 /api/mfa/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 Key(Dify/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/mfa/bind/confirm 请求体。\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/mfa/disable 请求体。\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/mfa/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"}}}} |