# Design Document: 任务分配与模板管理 ## Overview 本设计文档描述了标注平台的任务分配与模板管理功能的技术实现方案。该功能将完善现有平台的工作流程,实现从管理员(数据源)→ 任务派发 → 人员标注任务分配 → 数据收集 → 数据导出的完整闭环。 主要包含两大模块: - **任务分配系统**:支持管理员将任务分配给特定标注人员,标注人员只能看到分配给自己的任务 - **模板管理系统**:提供类似 LabelStudio 的模板选择界面和自定义 XML 配置编辑器 技术栈: - **前端**: React + TypeScript + Jotai + @humansignal/ui + Monaco Editor - **后端**: Python FastAPI + SQLite/MySQL - **编辑器**: Monaco Editor (XML 语法高亮) + @humansignal/editor (预览) ## Architecture ### System Architecture ```mermaid graph TB subgraph "Frontend (web/apps/lq_label)" A[React App] --> B[Layout Component] B --> C[User Management View] B --> D[Task Assignment View] B --> E[Template Manager View] B --> F[Config Editor View] B --> G[Export View] E --> H[Template Gallery] E --> I[Template Preview] F --> J[Monaco Editor] F --> K[Visual Builder] F --> L[Live Preview] A --> M[Jotai State Management] end subgraph "Backend (backend/)" N[FastAPI Server] --> O[User API] N --> P[Task Assignment API] N --> Q[Template API] N --> R[Export API] N --> S[Statistics API] O --> T[Database] P --> T Q --> T R --> T S --> T end A -->|HTTP/REST| N ``` ### Task Assignment Flow ```mermaid sequenceDiagram participant Admin as 管理员 participant Frontend as 前端 participant Backend as 后端 participant DB as 数据库 Admin->>Frontend: 选择任务 Admin->>Frontend: 点击分配按钮 Frontend->>Backend: GET /api/users?role=annotator Backend->>DB: 查询标注人员列表 DB-->>Backend: 返回用户列表 Backend-->>Frontend: 返回用户列表 Frontend->>Admin: 显示用户选择对话框 Admin->>Frontend: 选择用户并确认 Frontend->>Backend: PUT /api/tasks/{id}/assign Backend->>DB: 更新任务分配 DB-->>Backend: 确认更新 Backend-->>Frontend: 返回更新后的任务 Frontend->>Admin: 显示分配成功 ``` ### Template Selection Flow ```mermaid sequenceDiagram participant Admin as 管理员 participant Frontend as 前端 participant Editor as 编辑器 Admin->>Frontend: 创建项目 Frontend->>Admin: 显示模板选择界面 Admin->>Frontend: 选择模板类别 Frontend->>Admin: 显示模板列表 Admin->>Frontend: 选择具体模板 Frontend->>Editor: 加载模板配置 Editor->>Admin: 显示预览效果 Admin->>Frontend: 确认使用模板 Frontend->>Frontend: 填充配置到项目表单 ``` ## Components and Interfaces ### Frontend Components #### 1. UserManagementView **Location**: `web/apps/lq_label/src/views/user-management-view/` **Responsibility**: 用户管理界面,显示用户列表和任务统计 **Interface**: ```typescript interface UserManagementViewProps {} interface UserWithStats { id: string; username: string; email: string; role: 'admin' | 'annotator' | 'viewer'; created_at: string; task_stats: { assigned_count: number; completed_count: number; annotation_count: number; completion_rate: number; }; } ``` **Features**: - 用户列表展示(使用 DataTable) - 角色筛选 - 用户搜索 - 任务统计显示 #### 2. TaskAssignmentDialog **Location**: `web/apps/lq_label/src/components/task-assignment-dialog/` **Responsibility**: 任务分配对话框 **Interface**: ```typescript interface TaskAssignmentDialogProps { open: boolean; taskIds: string[]; onClose: () => void; onAssign: (userId: string) => Promise; } interface AssignableUser { id: string; username: string; email: string; current_task_count: number; } ``` **Features**: - 用户选择列表 - 当前工作量显示 - 批量分配支持 - 平均分配选项 #### 3. TemplateGallery **Location**: `web/apps/lq_label/src/components/template-gallery/` **Responsibility**: 模板选择画廊 **Interface**: ```typescript interface TemplateGalleryProps { onSelect: (template: Template) => void; selectedId?: string; } interface Template { id: string; name: string; category: TemplateCategory; description: string; config: string; preview_image?: string; tags: string[]; } type TemplateCategory = | 'image_classification' | 'object_detection' | 'image_segmentation' | 'text_classification' | 'ner' | 'text_labeling' | 'audio_transcription' | 'video_annotation'; ``` **Features**: - 分类筛选 - 模板搜索 - 模板预览卡片 - 选中状态显示 #### 4. ConfigEditor **Location**: `web/apps/lq_label/src/components/config-editor/` **Responsibility**: 标注配置编辑器(代码模式 + 可视化模式) **Interface**: ```typescript interface ConfigEditorProps { value: string; onChange: (value: string) => void; mode: 'code' | 'visual'; onModeChange: (mode: 'code' | 'visual') => void; previewData?: Record; } interface ValidationResult { valid: boolean; errors: Array<{ line: number; column: number; message: string; }>; } ``` **Features**: - Monaco Editor 集成(XML 语法高亮) - 实时语法验证 - 错误提示 - 模式切换 #### 5. VisualConfigBuilder **Location**: `web/apps/lq_label/src/components/visual-config-builder/` **Responsibility**: 可视化配置构建器 **Interface**: ```typescript interface VisualConfigBuilderProps { value: string; onChange: (value: string) => void; } interface ConfigComponent { type: string; name: string; icon: React.ReactNode; category: 'data' | 'annotation' | 'layout'; defaultProps: Record; } ``` **Features**: - 组件面板 - 拖拽构建 - 属性编辑面板 - 组件树视图 #### 6. ConfigPreview **Location**: `web/apps/lq_label/src/components/config-preview/` **Responsibility**: 配置预览面板 **Interface**: ```typescript interface ConfigPreviewProps { config: string; data?: Record; onError?: (error: string) => void; } ``` **Features**: - LabelStudio 编辑器集成 - 示例数据支持 - 错误显示 - 全屏模式 #### 7. DataExportDialog **Location**: `web/apps/lq_label/src/components/data-export-dialog/` **Responsibility**: 数据导出对话框 **Interface**: ```typescript interface DataExportDialogProps { open: boolean; projectId: string; onClose: () => void; } type ExportFormat = 'json' | 'csv' | 'coco' | 'yolo'; interface ExportOptions { format: ExportFormat; status_filter?: 'all' | 'completed' | 'pending' | 'in_progress'; include_metadata: boolean; } ``` **Features**: - 格式选择 - 状态筛选 - 进度显示 - 下载触发 #### 8. ProjectStatisticsPanel **Location**: `web/apps/lq_label/src/components/project-statistics-panel/` **Responsibility**: 项目统计面板 **Interface**: ```typescript interface ProjectStatisticsPanelProps { projectId: string; } interface ProjectStatistics { total_tasks: number; completed_tasks: number; in_progress_tasks: number; pending_tasks: number; total_items: number; annotated_items: number; completion_rate: number; user_stats: UserTaskStats[]; } interface UserTaskStats { user_id: string; username: string; assigned_tasks: number; completed_tasks: number; annotation_count: number; completion_rate: number; } ``` **Features**: - 项目级统计 - 人员级统计 - 进度条可视化 - 实时更新 ### Backend API Endpoints #### User API Extensions **Router**: `backend/routers/user.py` **New Endpoints**: ```python GET /api/users # List all users (admin only) GET /api/users/{id} # Get user by ID GET /api/users/{id}/stats # Get user task statistics GET /api/users/annotators # List annotators for assignment ``` **Models**: ```python class UserResponse(BaseModel): id: str username: str email: str role: str created_at: datetime class UserWithStatsResponse(UserResponse): task_stats: TaskStats class TaskStats(BaseModel): assigned_count: int completed_count: int annotation_count: int completion_rate: float ``` #### Task Assignment API **Router**: `backend/routers/task.py` (扩展) **New Endpoints**: ```python PUT /api/tasks/{id}/assign # Assign task to user POST /api/tasks/batch-assign # Batch assign tasks GET /api/tasks/my-tasks # Get current user's tasks ``` **Models**: ```python class TaskAssignRequest(BaseModel): user_id: str class BatchAssignRequest(BaseModel): task_ids: List[str] user_ids: List[str] mode: str = 'round_robin' # 'round_robin' | 'equal' ``` #### Template API **Router**: `backend/routers/template.py` **Endpoints**: ```python GET /api/templates # List all templates GET /api/templates/{id} # Get template by ID GET /api/templates/categories # List template categories POST /api/templates/validate # Validate XML config ``` **Models**: ```python class TemplateResponse(BaseModel): id: str name: str category: str description: str config: str preview_image: Optional[str] tags: List[str] class ConfigValidationRequest(BaseModel): config: str class ConfigValidationResponse(BaseModel): valid: bool errors: List[ValidationError] ``` #### Export API **Router**: `backend/routers/export.py` **Endpoints**: ```python POST /api/projects/{id}/export # Export project annotations GET /api/exports/{id}/status # Get export job status GET /api/exports/{id}/download # Download export file ``` **Models**: ```python class ExportRequest(BaseModel): format: str # 'json' | 'csv' | 'coco' | 'yolo' status_filter: Optional[str] include_metadata: bool = True class ExportResponse(BaseModel): export_id: str status: str download_url: Optional[str] ``` #### Statistics API **Router**: `backend/routers/statistics.py` **Endpoints**: ```python GET /api/projects/{id}/statistics # Get project statistics GET /api/statistics/overview # Get overall platform statistics ``` **Models**: ```python class ProjectStatisticsResponse(BaseModel): total_tasks: int completed_tasks: int in_progress_tasks: int pending_tasks: int total_items: int annotated_items: int completion_rate: float user_stats: List[UserTaskStats] ``` ## Data Models ### Database Schema Extensions ```sql -- 预设模板表 (可选,也可以使用静态配置) CREATE TABLE templates ( id TEXT PRIMARY KEY, name TEXT NOT NULL, category TEXT NOT NULL, description TEXT, config TEXT NOT NULL, preview_image TEXT, tags TEXT, -- JSON array created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 导出任务表 CREATE TABLE export_jobs ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, format TEXT NOT NULL, status TEXT DEFAULT 'pending', -- pending, processing, completed, failed file_path TEXT, error_message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, completed_at TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ); -- 任务分配历史表 (可选,用于追踪分配记录) CREATE TABLE task_assignments ( id TEXT PRIMARY KEY, task_id TEXT NOT NULL, assigned_to TEXT NOT NULL, assigned_by TEXT NOT NULL, assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE, FOREIGN KEY (assigned_to) REFERENCES users(id), FOREIGN KEY (assigned_by) REFERENCES users(id) ); ``` ### State Management (Jotai Atoms) **Location**: `web/apps/lq_label/src/atoms/` ```typescript // userAtoms.ts export const usersAtom = atom([]); export const annotatorsAtom = atom([]); export const userLoadingAtom = atom(false); // templateAtoms.ts export const templatesAtom = atom([]); export const selectedTemplateAtom = atom