| 
					
				 | 
			
			
				@@ -4242,4 +4242,193 @@ export class ProjectDetail implements OnInit, OnDestroy { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       minute: '2-digit' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // ============ 空间管理相关方法 ============ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 添加新空间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  addSpace(processId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const spaceName = this.newSpaceName[processId]?.trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!spaceName) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 生成新的空间ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const spaceId = `space_${Date.now()}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 添加到spaces数组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const newSpace: DeliverySpace = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      id: spaceId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      name: spaceName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      isExpanded: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      order: process.spaces.length + 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    process.spaces.push(newSpace); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化content数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    process.content[spaceId] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      images: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      progress: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      status: 'pending', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      notes: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      lastUpdated: new Date() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 清空输入框并隐藏 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.newSpaceName[processId] = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.showAddSpaceInput[processId] = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.log(`已添加空间: ${spaceName} 到流程 ${process.name}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 取消添加空间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cancelAddSpace(processId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.newSpaceName[processId] = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.showAddSpaceInput[processId] = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 获取指定流程的活跃空间列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getActiveProcessSpaces(processId: string): DeliverySpace[] { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process) return []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return process.spaces.sort((a, b) => a.order - b.order); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 切换空间展开状态 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  toggleSpace(processId: string, spaceId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const space = process.spaces.find(s => s.id === spaceId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (space) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      space.isExpanded = !space.isExpanded; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 获取空间进度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getSpaceProgress(processId: string, spaceId: string): number { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process || !process.content[spaceId]) return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return process.content[spaceId].progress || 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 删除空间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  removeSpace(processId: string, spaceId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 从spaces数组中移除 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const spaceIndex = process.spaces.findIndex(s => s.id === spaceId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (spaceIndex > -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const spaceName = process.spaces[spaceIndex].name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      process.spaces.splice(spaceIndex, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 清理content数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (process.content[spaceId]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 释放图片URL资源 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        process.content[spaceId].images.forEach(img => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (img.url && img.url.startsWith('blob:')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            URL.revokeObjectURL(img.url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete process.content[spaceId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      console.log(`已删除空间: ${spaceName} 从流程 ${process.name}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 触发空间文件输入 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  triggerSpaceFileInput(processId: string, spaceId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const inputId = `spaceFileInput_${processId}_${spaceId}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const input = document.getElementById(inputId) as HTMLInputElement; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (input) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      input.click(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 处理空间文件拖拽 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  onSpaceFileDrop(event: DragEvent, processId: string, spaceId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    event.preventDefault(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    event.stopPropagation(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const files = event.dataTransfer?.files; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!files || files.length === 0) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.handleSpaceFiles(Array.from(files), processId, spaceId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 处理空间文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  private handleSpaceFiles(files: File[], processId: string, spaceId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process || !process.content[spaceId]) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    files.forEach(file => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (/\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const imageItem = this.makeImageItem(file); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        process.content[spaceId].images.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          id: imageItem.id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          name: imageItem.name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          url: imageItem.url, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          size: this.formatFileSize(file.size), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          reviewStatus: 'pending' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 更新进度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.updateSpaceProgress(processId, spaceId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 获取空间图片列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getSpaceImages(processId: string, spaceId: string): Array<{ id: string; name: string; url: string; size?: string; reviewStatus?: 'pending' | 'approved' | 'rejected' }> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process || !process.content[spaceId]) return []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return process.content[spaceId].images || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 获取空间备注 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getSpaceNotes(processId: string, spaceId: string): string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process || !process.content[spaceId]) return ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return process.content[spaceId].notes || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 更新空间备注 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  updateSpaceNotes(processId: string, spaceId: string, notes: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process || !process.content[spaceId]) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    process.content[spaceId].notes = notes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    process.content[spaceId].lastUpdated = new Date(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.log(`已更新空间备注: ${processId}/${spaceId}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 更新空间进度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  private updateSpaceProgress(processId: string, spaceId: string): void { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const process = this.deliveryProcesses.find(p => p.id === processId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!process || !process.content[spaceId]) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const content = process.content[spaceId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const imageCount = content.images.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 根据图片数量和状态计算进度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (imageCount === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      content.progress = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      content.status = 'pending'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (imageCount < 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      content.progress = Math.min(imageCount * 30, 90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      content.status = 'in_progress'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      content.progress = 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      content.status = 'completed'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    content.lastUpdated = new Date(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |