|
@@ -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();
|
|
|
+ }
|
|
|
}
|