feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复

== 已部署上线 (9项) ==
- 代办事项真实数据源集成 (企微审批API 8bug修复链)
- H5/坐席端 Logo样式统一+绿色背景
- 视频引导页修复 (localStorage key v2)
- 坐席端 v9 Vue版本修复 (ElMessage._context)
- 截图按钮 v10 修复 (getDisplayMedia user gesture)
- 扫码样式恢复+H5扫码登录跳转修复
- H5截图快捷键提示

== 代码完成待部署 (3项) ==
- 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查)
- 会议室预定-小鱼易联终端 (40文件, 40/40测试通过)
- IT资产升级审批推送 (asset_service.py)

== 需求文档 (2项) ==
- 坐席端AI辅助消息框-PRD (4项新功能确认)
- 坐席端布局优化建议 v2.0 (7天计划)

== 新增文档 ==
- 日报-2026-07-11.md
- 知识迭代Bug修复报告-20260711.md
- 会议室预定-部署指南.md
- CHANGELOG.md 更新

== 测试 ==
- test_todo_integration.py: 40/40
- test_meetingroom.py: 40/40
- test_bugfix_ki_suggestions.py: 21/21
This commit is contained in:
Simon
2026-07-11 23:13:10 +08:00
parent 3d152fc8eb
commit bea288e414
928 changed files with 85169 additions and 54205 deletions
+103 -298
View File
@@ -1,321 +1,126 @@
%% 坐席端截图+拍照功能 — 类图
%% 文件: docs/03-技术架构/class-diagram.mermaid
classDiagram
direction TB
%% ── 枚举 ──────────────────────────────────────────
class AudienceEnum {
<<enumeration>>
employee_quick_reply
engineer_workguide
%% ===== 类型定义 =====
class PendingImage {
+id: string
+blob: Blob
+previewUrl: string
+source: "screenshot" | "camera"
+createdAt: number
}
class SuggestionStatusEnum {
<<enumeration>>
pending
queued
approved
rejected
applied
graph_synced
expired
class SelectionBox {
+x: number
+y: number
+w: number
+h: number
}
class GraphSyncStatusEnum {
<<enumeration>>
pending
synced
failed
class EditHistoryEntry {
+imageData: ImageData
+timestamp: number
}
class SourceTypeEnum {
<<enumeration>>
annotation
conversation
ai_uncertain
manual
document_ragflow
class ScreenshotToolConfig {
+name: ScreenshotTool
+icon: string
+label: string
}
class RelationTypeEnum {
<<enumeration>>
LEADS_TO
RELATES_TO
CAN_JUMP_TO
%% ===== Composables =====
class useScreenCapture {
-isCapturing: Ref~boolean~
+isScreenCaptureSupported() boolean
+captureScreen() Promise~Blob | null~
+captureScreenAsCanvas() Promise~HTMLCanvasElement | null~
}
%% ── PostgreSQL 模型 ───────────────────────────────
class KnowledgeSuggestion {
+str id
+str suggestion_type
+SuggestionStatusEnum status
+str title
+str content
+str category
+List~str~ tags
+SourceTypeEnum source_type
+List~str~ source_data
+str reason
+str reject_reason
+str reviewer_id
+datetime reviewed_at
+datetime created_at
+datetime updated_at
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
+dict graph_meta
+GraphSyncStatusEnum graph_sync_status
+bool source_failed
+datetime queued_at
+datetime applied_at
class useCamera {
-isActive: Ref~boolean~
-error: Ref~CameraError | null~
-stream: MediaStream | null
+startCamera(facingMode?) Promise~boolean~
+stopCamera() void
+captureFrame() Promise~Blob | null~
+switchCamera() Promise~boolean~
}
class KnowledgeBase {
+str id
+str category
+str title
+str content
+List~str~ tags
+int view_count
+int use_count
+GraphSyncStatusEnum graph_sync_status
+str graph_node_uuid
+datetime created_at
+datetime updated_at
class usePendingImages {
-images: Ref~PendingImage[]~
+addImage(blob: Blob, source: string) void
+removeImage(id: string) void
+clearAll() void
+hasImages: ComputedRef~boolean~
+count: ComputedRef~number~
}
class Conversation {
+str id
+str employee_id
+str status
+str session_type
+datetime created_at
%% ===== 组件 =====
class ScreenCapture {
+props: screenshotCanvas: HTMLCanvasElement
+emit: confirm(blob: Blob)
+emit: cancel()
-box: Ref~SelectionBox~
-currentTool: Ref~ScreenshotTool~
-currentColor: Ref~string~
-history: EditHistoryEntry[]
-historyIndex: number
+startSelect(e: MouseEvent) void
+onMove(e: MouseEvent) void
+startResize(dir: string, e: MouseEvent) void
+drawMosaic(x1, y1, x2, y2) void
+drawArrow(x1, y1, x2, y2) void
+drawText(x, y, text) void
+undo() void
+confirm() void
+cancel() void
}
%% ── Neo4j 图节点模型 ──────────────────────────────
class IssueNode {
+str uuid
+str name
+str category
+datetime created_at
+datetime updated_at
+str source_suggestion_id
class CameraCapture {
+props: modelValue: boolean
+emit: confirm(blob: Blob)
+emit: cancel()
+emit: update:modelValue(boolean)
-videoRef: Ref~HTMLVideoElement~
-capturedImage: Ref~string | null~
-cameraError: Ref~CameraError | null~
+startCamera() void
+capture() void
+retake() void
+confirm() void
+close() void
}
class ActionNode {
+str uuid
+str name
+str description
+datetime created_at
+str source_suggestion_id
class PendingImagePreview {
+props: images: PendingImage[]
+emit: remove(id: string)
}
class InfoNode {
+str uuid
+str name
+str value
+List~str~ modifiers
+datetime created_at
class ReplyBox {
-pendingImages: usePendingImages
-showScreenCapture: Ref~boolean~
-showCameraDialog: Ref~boolean~
-screenshotCanvas: Ref~HTMLCanvasElement | null~
+handleScreenshot() Promise~void~
+handleCamera() void
+onScreenCaptureConfirm(blob: Blob) void
+onCameraConfirm(blob: Blob) void
+onCameraCancel() void
+removePendingImage(id: string) void
+handleSend() Promise~void~
+sendPendingImages(convId: string) Promise~void~
}
class RelationEdge {
+str from_uuid
+str to_uuid
+RelationTypeEnum type
+int order
+float weight
}
%% ── Pydantic Schema ───────────────────────────────
class KnowledgeSuggestionCreate {
+str suggestion_type
+str title
+str content
+str category
+List~str~ tags
+SourceTypeEnum source_type
+List~str~ source_data
+str reason
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
+dict graph_meta
}
class KnowledgeSuggestionResponse {
+str id
+str suggestion_type
+SuggestionStatusEnum status
+str title
+str content
+str category
+List~str~ tags
+SourceTypeEnum source_type
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
+dict graph_meta
+GraphSyncStatusEnum graph_sync_status
+bool source_failed
+datetime queued_at
+datetime applied_at
+datetime created_at
}
class KnowledgeSuggestionApprove {
<<request>>
}
class KnowledgeSuggestionReject {
<<request>>
+str reject_reason
}
class KnowledgeSuggestionRewrite {
<<request>>
+str title
+str content
+str category
+List~str~ tags
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
}
class VisionRequest {
<<request>>
+str conversation_id
+bytes image_file
}
class VisionResponse {
+str description
+float confidence
+dict metadata
}
class RagflowIngestionRequest {
<<request>>
+str file_name
+bytes file_data
+str category_hint
}
class RagflowIngestionResponse {
+str task_id
+str status
+List~KnowledgeSuggestionResponse~ suggestions
}
%% ── 服务类 ────────────────────────────────────────
class KnowledgeIterationService {
-str ai_api_url
-str ai_api_key
+analyze_and_generate_suggestions(db, days) dict
-_analyze_annotation_data(db, days) dict
-_analyze_conversation_data(db, days) dict
-_generate_update_suggestion(db, source_type, source_data, reason) KnowledgeSuggestion
-_generate_new_faq_suggestion(db, source_type, source_data, reason) KnowledgeSuggestion
-_check_existing_suggestion(db, source_id) bool
-_auto_tag_audience(db, source_type, source_data) AudienceEnum
+approve_suggestion(db, suggestion_id, reviewer_id) KnowledgeSuggestion
+reject_suggestion(db, suggestion_id, reviewer_id, reason) KnowledgeSuggestion
+rewrite_suggestion(db, suggestion_id, reviewer_id, data) KnowledgeSuggestion
+queue_suggestion(db, suggestion_id) KnowledgeSuggestion
+dequeue_approve(db, suggestion_id, reviewer_id) KnowledgeSuggestion
+sync_to_neo4j(neo4j_client, suggestion) bool
+get_suggestion_stats(db) dict
+get_queue_stats(db) dict
}
class WingmanService {
-str api_url
-str api_key
-int timeout
-httpx.AsyncClient _client
+generate_draft(conversation_id, messages, db) dict
+generate_summary(conversation_id, messages) dict
+suggest_tags(conversation_id, messages, existing_tags) dict
+generate_knowledge_suggestion(context_messages) dict
-_build_context_messages(messages, system_prompt) list
-_call_wingman_api(context_messages) str
-_parse_json_response(content, default) dict
-_estimate_confidence(content) float
+close()
}
class Neo4jClient {
-str uri
-str user
-str password
-str database
-AsyncDriver _driver
+initialize()
+close()
+create_issue_node(issue) IssueNode
+create_action_node(action) ActionNode
+create_relation(from_uuid, to_uuid, rel) RelationEdge
+merge_issue(name, category, props) IssueNode
+merge_action(name, props) ActionNode
+find_issue_by_name(name) IssueNode
+find_related_issues(uuid, rel_type) List~IssueNode~
+execute_write_query(cypher, params) result
+execute_read_query(cypher, params) result
+health_check() bool
}
class VisionService {
-str dify_vision_api_url
-str dify_vision_api_key
-str local_vision_model
+analyze_screenshot(image_bytes, conversation_id) VisionResponse
-_preprocess_image(image_bytes) bytes
-_call_vision_workflow(processed_image) dict
+inject_to_conversation_context(description, conversation_id)
}
class RagflowIngestionService {
-RagflowClient client
+upload_and_process(file_data, file_name, category_hint) RagflowIngestionResponse
+poll_processing_status(task_id) str
+create_suggestions_from_result(result) List~KnowledgeSuggestion~
}
%% ── 关系 ──────────────────────────────────────────
KnowledgeSuggestion ..> AudienceEnum : uses
KnowledgeSuggestion ..> SuggestionStatusEnum : uses
KnowledgeSuggestion ..> SourceTypeEnum : uses
KnowledgeSuggestion ..> RelationTypeEnum : uses
KnowledgeSuggestion ..> GraphSyncStatusEnum : uses
KnowledgeBase ..> GraphSyncStatusEnum : uses
KnowledgeIterationService --> WingmanService : 调用 AI 生成
KnowledgeIterationService --> Neo4jClient : 写图同步
KnowledgeIterationService --> KnowledgeSuggestion : 管理
KnowledgeIterationService --> KnowledgeBase : 落库
KnowledgeSuggestionCreate --> KnowledgeSuggestion : 创建
KnowledgeSuggestionResponse --> KnowledgeSuggestion : 返回
KnowledgeSuggestionApprove --> KnowledgeSuggestion : 状态变更
KnowledgeSuggestionReject --> KnowledgeSuggestion : 状态变更
KnowledgeSuggestionRewrite --> KnowledgeSuggestion : 内容更新
IssueNode <--> RelationEdge : 关联
ActionNode <--> RelationEdge : 关联
Neo4jClient --> IssueNode : CRUD
Neo4jClient --> ActionNode : CRUD
Neo4jClient --> RelationEdge : 管理
VisionService --> WingmanService : 复用 _call_wingman_api 范式
RagflowIngestionService --> KnowledgeSuggestion : 产出
%% ===== 关系 =====
ReplyBox --> useScreenCapture : 调用截图
ReplyBox --> useCamera : 调用拍照
ReplyBox --> usePendingImages : 管理待发送图片
ReplyBox --> ScreenCapture : 挂载截图编辑器
ReplyBox --> CameraCapture : 挂载拍照弹窗
ReplyBox --> PendingImagePreview : 挂载预览条
ScreenCapture --> SelectionBox : 选区状态
ScreenCapture --> EditHistoryEntry : 撤销历史
CameraCapture --> useCamera : 摄像头逻辑
PendingImagePreview --> PendingImage : 渲染缩略图
usePendingImages --> PendingImage : 管理队列