2026-07-11 23:13:10 +08:00
|
|
|
%% 坐席端截图+拍照功能 — 类图
|
|
|
|
|
%% 文件: docs/03-技术架构/class-diagram.mermaid
|
|
|
|
|
|
2026-07-09 11:50:19 +08:00
|
|
|
classDiagram
|
2026-07-11 23:13:10 +08:00
|
|
|
%% ===== 类型定义 =====
|
|
|
|
|
class PendingImage {
|
|
|
|
|
+id: string
|
|
|
|
|
+blob: Blob
|
|
|
|
|
+previewUrl: string
|
|
|
|
|
+source: "screenshot" | "camera"
|
|
|
|
|
+createdAt: number
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
class SelectionBox {
|
|
|
|
|
+x: number
|
|
|
|
|
+y: number
|
|
|
|
|
+w: number
|
|
|
|
|
+h: number
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
class EditHistoryEntry {
|
|
|
|
|
+imageData: ImageData
|
|
|
|
|
+timestamp: number
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
class ScreenshotToolConfig {
|
|
|
|
|
+name: ScreenshotTool
|
|
|
|
|
+icon: string
|
|
|
|
|
+label: string
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
%% ===== Composables =====
|
|
|
|
|
class useScreenCapture {
|
|
|
|
|
-isCapturing: Ref~boolean~
|
|
|
|
|
+isScreenCaptureSupported() boolean
|
|
|
|
|
+captureScreen() Promise~Blob | null~
|
|
|
|
|
+captureScreenAsCanvas() Promise~HTMLCanvasElement | null~
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
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~
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
class usePendingImages {
|
|
|
|
|
-images: Ref~PendingImage[]~
|
|
|
|
|
+addImage(blob: Blob, source: string) void
|
|
|
|
|
+removeImage(id: string) void
|
|
|
|
|
+clearAll() void
|
|
|
|
|
+hasImages: ComputedRef~boolean~
|
|
|
|
|
+count: ComputedRef~number~
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
%% ===== 组件 =====
|
|
|
|
|
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
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
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
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
class PendingImagePreview {
|
|
|
|
|
+props: images: PendingImage[]
|
|
|
|
|
+emit: remove(id: string)
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
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~
|
2026-07-09 11:50:19 +08:00
|
|
|
}
|
|
|
|
|
|
2026-07-11 23:13:10 +08:00
|
|
|
%% ===== 关系 =====
|
|
|
|
|
ReplyBox --> useScreenCapture : 调用截图
|
|
|
|
|
ReplyBox --> useCamera : 调用拍照
|
|
|
|
|
ReplyBox --> usePendingImages : 管理待发送图片
|
|
|
|
|
ReplyBox --> ScreenCapture : 挂载截图编辑器
|
|
|
|
|
ReplyBox --> CameraCapture : 挂载拍照弹窗
|
|
|
|
|
ReplyBox --> PendingImagePreview : 挂载预览条
|
|
|
|
|
ScreenCapture --> SelectionBox : 选区状态
|
|
|
|
|
ScreenCapture --> EditHistoryEntry : 撤销历史
|
|
|
|
|
CameraCapture --> useCamera : 摄像头逻辑
|
|
|
|
|
PendingImagePreview --> PendingImage : 渲染缩略图
|
|
|
|
|
usePendingImages --> PendingImage : 管理队列
|