Explorar o código

feat:delivery-rebuild

0235711 hai 16 horas
pai
achega
261ef1daa3

+ 0 - 1
src/modules/project/pages/project-detail/stages/components/ai-design-analysis/ai-design-analysis.component.ts

@@ -324,7 +324,6 @@ export class AiDesignAnalysisComponent implements OnInit {
       const response = await this.designAnalysisAIService.chatWithAI({
         userMessage: content,
         conversationHistory: history,
-        context: this.aiDesignAnalysisResult,
         onContentStream: (streamContent) => {
           const aiMsgIndex = this.aiChatMessages.findIndex(m => m.id === aiMsgId);
           if (aiMsgIndex !== -1) {

+ 1 - 1
src/modules/project/pages/project-detail/stages/components/space-requirement-item/space-requirement-item.component.ts

@@ -145,7 +145,7 @@ export class SpaceRequirementItemComponent implements OnInit {
 
   // File Inputs
   triggerFileClick(elementId: string) {
-    const element = document.getElementById(elementId) as HTMLInputElement;
+    const element = window.document.getElementById(elementId) as HTMLInputElement;
     if (element) {
       element.click();
     }

+ 91 - 264
src/modules/project/pages/project-detail/stages/stage-delivery-new.component.html

@@ -29,40 +29,26 @@
   }
 
   @if (!loading) {
-    <!-- 🆕 空间列表(可折叠展开,显示4个阶段) -->
+    <!-- 🆕 空间列表(智能网格视图) -->
     @if (projectProducts.length > 0) {
       <div class="spaces-list-section">
         @for (space of projectProducts; track space.id) {
           <div class="space-card">
-            <!-- 空间头部(显示空间名和四个阶段名称) -->
+            <!-- 空间头部 -->
             <div class="space-header" (click)="toggleSpaceExpansion(space.id)">
-              <!-- 空间名称 -->
-              <div class="space-name-section">
+              <div class="space-title">
                 {{ getSpaceDisplayName(space) }}
-                <!-- 完成进度显示 -->
-                <span class="completion-badge">
-                  {{ getCompletedStagesCount(space.id) }}/4
-                </span>
-              </div>
-
-              <!-- 四个阶段名称(横向排列) -->
-              <div class="stage-names-row">
-                @for (type of deliveryTypes; track type.id) {
-                  <div class="stage-name-item"
-                       [class.has-files]="getSpaceStageFileCount(space.id, type.id) > 0">
-                    <span class="stage-label">{{ type.name }}</span>
-                    @if (getSpaceStageFileCount(space.id, type.id) > 0) {
-                      <span class="mini-badge">{{ getSpaceStageFileCount(space.id, type.id) }}</span>
-                    }
-                  </div>
+                @if (space.area) {
+                   <span class="space-badge">{{ space.area }}㎡</span>
                 }
               </div>
-
-              <!-- 展开/收起图标 -->
-              <div class="expand-icon" [class.expanded]="isSpaceExpanded(space.id)">
-                <svg width="28" height="28" viewBox="0 0 24 24" fill="currentColor">
-                  <path d="M7 10l5 5 5-5z"/>
-                </svg>
+              <div class="space-header-right">
+                <span class="progress-text">{{ getCompletedStagesCount(space.id) }}/4 完成</span>
+                <div class="expand-icon" [class.expanded]="isSpaceExpanded(space.id)">
+                  <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
+                    <path d="M7 10l5 5 5-5z"/>
+                  </svg>
+                </div>
               </div>
             </div>
 
@@ -83,180 +69,98 @@
                           <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
                         </svg>
                       </div>
-                      <h3>拖拽到 {{ getSpaceDisplayName(space) }}</h3>
-                      <p>AI将自动分析图片并智能分类到合适的阶段</p>
+                      <h3>拖拽到此处</h3>
+                      <p>AI自动归类</p>
                     </div>
                   </div>
                 }
                 
-                <!-- 4个阶段区域(横向排列,每个阶段独立显示) -->
-                <div class="stages-container">
+                <!-- 4个阶段网格(2x2布局) -->
+                <div class="stages-grid">
                   @for (type of deliveryTypes; track type.id) {
-                    <div class="stage-section"
-                         [class.has-files]="getSpaceStageFileCount(space.id, type.id) > 0">
-                      <!-- 阶段头部 -->
-                      <div class="stage-header" 
-                           [class.clickable]="getSpaceStageFileCount(space.id, type.id) > 0"
-                           (click)="getSpaceStageFileCount(space.id, type.id) > 0 ? openStageGallery(space.id, type.id, $event) : null">
-                        <div class="stage-title">
-                          <span class="stage-name">{{ type.name }}</span>
-                          @if (getSpaceStageFileCount(space.id, type.id) > 0) {
-                            <span class="file-count-badge">{{ getSpaceStageFileCount(space.id, type.id) }}</span>
-                          }
-                        </div>
+                    <div class="stage-item"
+                         [class.completed]="getSpaceStageFileCount(space.id, type.id) > 0"
+                         [class.pending]="getSpaceStageFileCount(space.id, type.id) === 0"
+                         [class.drag-over]="isDragOver && selectedSpaceId === space.id && selectedStageType === type.id"
+                         (dragover)="onDragOver($event, space.id, type.id)"
+                         (dragleave)="onDragLeave($event)"
+                         (drop)="onDrop($event, space.id, type.id)">
+
+                      <!-- 阶段标题与状态 -->
+                      <div class="stage-label">
+                        <span>{{ type.name }}</span>
                         @if (getSpaceStageFileCount(space.id, type.id) > 0) {
-                          <div class="view-all-hint">
-                            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
-                              <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
-                            </svg>
-                            <span>查看全部</span>
-                          </div>
+                          <span class="status-icon icon-check">✓</span>
                         }
                       </div>
 
-                      <!-- 阶段内容区域 -->
-                      <div class="stage-body"
-                           (dragover)="onDragOver($event, space.id, type.id)"
-                           (dragleave)="onDragLeave($event)"
-                           (drop)="onDrop($event, space.id, type.id)"
-                           [class.drag-over]="isDragOver && selectedSpaceId === space.id && selectedStageType === type.id"
-                           (click)="selectSpaceAndStage(space.id, type.id)">
-
-                        <!-- 拖拽提示覆盖层 -->
-                        @if (isDragOver && selectedSpaceId === space.id && selectedStageType === type.id) {
-                          <div class="drag-overlay">
-                            <div class="drag-hint">
-                              <div class="drag-icon">
-                                <svg width="32" height="32" viewBox="0 0 24 24" fill="currentColor">
-                                  <path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/>
-                                </svg>
-                              </div>
-                              <p>释放上传</p>
+                      <!-- 文件预览或上传操作 -->
+                      @if (getSpaceStageFileCount(space.id, type.id) > 0) {
+                        <div class="preview-strip">
+                          <!-- 显示前2张图片 -->
+                          @for (file of getProductDeliveryFiles(space.id, type.id) | slice:0:2; track file.id) {
+                            <div class="mini-thumb-wrapper" (click)="previewFile(file); $event.stopPropagation()">
+                              @if (isImageFile(file.name)) {
+                                <img [src]="file.url" class="mini-thumb" (error)="onImageError($event)" />
+                              } @else {
+                                <div class="mini-thumb file-icon">
+                                  <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
+                                    <path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/>
+                                  </svg>
+                                </div>
+                              }
                             </div>
-                          </div>
-                        }
-
-                        <!-- 文件上传按钮 -->
-                        @if (canEdit && getSpaceStageFileCount(space.id, type.id) === 0) {
-                          <div class="upload-zone-compact">
-                            <input
-                              type="file"
-                              multiple
-                              (change)="uploadDeliveryFile($event, space.id, type.id)"
-                              [accept]="'image/*,.pdf,.dwg,.dxf,.skp,.max'"
-                              [disabled]="uploadingDeliveryFiles"
-                              hidden
-                              #fileInput />
-
-                            <button class="upload-btn-compact" (click)="fileInput.click(); $event.stopPropagation()" [disabled]="uploadingDeliveryFiles">
-                              <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
-                                <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
+                          }
+                          <!-- 添加按钮/查看更多 -->
+                          <div class="add-box" (click)="openStageGallery(space.id, type.id, $event)">
+                            @if (canEdit) {
+                              <span>+</span>
+                            } @else {
+                              <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
+                                <path d="M5 10h14v2H5z"/> <!-- Simple view icon or dots -->
+                                <circle cx="12" cy="12" r="2"/>
+                                <circle cx="19" cy="12" r="2"/>
+                                <circle cx="5" cy="12" r="2"/>
                               </svg>
-                              <span>上传{{ type.name }}</span>
-                            </button>
-                          </div>
-                        }
-
-                        <!-- 文件预览(缩略图) -->
-                        @if (getSpaceStageFileCount(space.id, type.id) > 0) {
-                          <div class="files-preview">
-                            @for (file of getProductDeliveryFiles(space.id, type.id).slice(0, 4); track file.id) {
-                              <div class="file-thumbnail" (click)="previewFile(file); $event.stopPropagation()">
-                                @if (isImageFile(file.name)) {
-                                  <img [src]="file.url" [alt]="file.name" class="thumbnail-img" (error)="onImageError($event)" />
-                                } @else {
-                                  <div class="thumbnail-placeholder">
-                                    <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
-                                      <path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/>
-                                    </svg>
-                                  </div>
-                                }
-                                <!-- 快捷发送图片按钮 -->
-                                @if (canEdit && isImageFile(file.name)) {
-                                  <button class="send-image-btn" (click)="sendSingleImage(space.id, type.id, file.url, $event); $event.stopPropagation()" title="发送图片(普通点击:选择话术 | Shift+点击:直接发送)">
-                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
-                                      <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
-                                    </svg>
-                                  </button>
-                                }
-                                @if (canEdit) {
-                                  <button class="delete-thumbnail-btn" (click)="deleteDeliveryFile(space.id, type.id, file.id); $event.stopPropagation()">
-                                    <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
-                                      <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
-                                    </svg>
-                                  </button>
-                                }
-                              </div>
-                            }
-                            @if (getSpaceStageFileCount(space.id, type.id) > 4) {
-                              <div class="more-files-indicator">
-                                +{{ getSpaceStageFileCount(space.id, type.id) - 4 }}
-                              </div>
                             }
                           </div>
-
-                          <!-- 添加更多文件和发送消息按钮 -->
-                          @if (canEdit) {
-                            <div class="add-more-files">
-                              <input
+                        </div>
+                      } @else {
+                        <!-- 空状态:点击上传 -->
+                        @if (canEdit) {
+                           <div class="upload-action" (click)="fileInput.click(); $event.stopPropagation()">
+                             <input
                                 type="file"
                                 multiple
                                 (change)="uploadDeliveryFile($event, space.id, type.id)"
                                 [accept]="'image/*,.pdf,.dwg,.dxf,.skp,.max'"
                                 [disabled]="uploadingDeliveryFiles"
                                 hidden
-                                #fileInputMore />
-                              <button class="add-more-btn" (click)="fileInputMore.click(); $event.stopPropagation()" [disabled]="uploadingDeliveryFiles">
-                                <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
-                                  <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
-                                </svg>
-                                添加文件
-                              </button>
-                              <button class="send-message-btn" (click)="openMessageModalWithFiles(space.id, type.id); $event.stopPropagation()">
-                                <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
-                                  <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
-                                </svg>
-                                发送消息
-                              </button>
-                            </div>
-                          }
+                                #fileInput />
+                             <span>📤 点击上传</span>
+                           </div>
+                        } @else {
+                           <div class="empty-action">
+                             <span>暂无文件</span>
+                           </div>
                         }
-
-                        <!-- 空状态提示 -->
-                        @if (getSpaceStageFileCount(space.id, type.id) === 0 && !canEdit) {
-                          <div class="empty-stage-hint">
-                            <svg width="32" height="32" viewBox="0 0 24 24" fill="currentColor" opacity="0.3">
-                              <path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/>
-                            </svg>
-                            <p>暂无文件</p>
-                          </div>
-                        }
-                      </div>
+                      }
                     </div>
                   }
                 </div>
 
-                <!-- 统一的交付执行清单确认按钮(在所有阶段下方) -->
+                <!-- 交付执行清单确认按钮 -->
                 <div class="space-confirm-section">
                   @if (!isSpaceConfirmed(space.id)) {
                     <button
                       class="confirm-space-btn"
                       (click)="confirmSpace(space.id)"
                       [disabled]="saving || getSpaceTotalFileCount(space.id) === 0">
-                      <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
-                        <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
-                      </svg>
-                      <span>交付执行清单确认</span>
+                      <span>确认清单</span>
                     </button>
                   } @else {
                     <div class="confirmed-info">
-                      <div class="confirmed-header">
-                        <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
-                          <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
-                        </svg>
-                        <span class="confirmed-text">已确认</span>
-                      </div>
-                      <div class="confirmed-details">{{ getSpaceConfirmationText(space.id) }}</div>
+                      <span class="confirmed-text">✓ 已确认</span>
                     </div>
                   }
                 </div>
@@ -271,18 +175,17 @@
     @if (projectProducts.length === 0 && !loading) {
       <div class="no-products-state">
         <div class="state-icon">
-          <svg class="icon" width="64" height="64" viewBox="0 0 24 24">
+          <svg class="icon" width="48" height="48" viewBox="0 0 24 24">
             <path fill="currentColor" d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2Z"/>
           </svg>
         </div>
-        <h3>暂无项目空间</h3>
-        <p>请先在方案深化阶段添加项目空间</p>
+        <p>暂无项目空间</p>
       </div>
     }
   }
 </div>
 
-<!-- 拖拽上传弹窗(增强版,支持AI识别和多空间选择) -->
+<!-- 拖拽上传弹窗 -->
 <app-drag-upload-modal
   [visible]="showDragUploadModal"
   [droppedFiles]="dragUploadFiles"
@@ -305,13 +208,9 @@
       <div class="gallery-header">
         <div class="gallery-title">
           <h3>{{ currentStageGallery.stageName }} - {{ currentStageGallery.spaceName }}</h3>
-          <p>{{ currentStageGallery.files.length }} 个文件</p>
+          <p>{{ currentStageGallery.files.length }} 个文件</p>
         </div>
-        <button class="close-btn" (click)="closeStageGallery()">
-          <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
-            <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
-          </svg>
-        </button>
+        <button class="close-btn" (click)="closeStageGallery()">×</button>
       </div>
       
       <!-- 图片网格 -->
@@ -324,38 +223,30 @@
                   <img [src]="file.url" [alt]="file.name" class="gallery-image" (error)="onImageError($event)" />
                 } @else {
                   <div class="file-placeholder">
-                    <svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
+                    <svg width="32" height="32" viewBox="0 0 24 24" fill="currentColor">
                       <path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/>
                     </svg>
                   </div>
                 }
                 <div class="image-info">
                   <div class="file-name" [title]="file.name">{{ file.name }}</div>
-                  <div class="file-size">{{ formatFileSize(file.size) }}</div>
                 </div>
                 @if (canEdit) {
-                  <button class="delete-image-btn" (click)="deleteDeliveryFile(currentStageGallery!.spaceId, currentStageGallery!.stageId, file.id); $event.stopPropagation()">
-                    <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
-                      <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
-                    </svg>
-                  </button>
+                  <button class="delete-image-btn" (click)="deleteDeliveryFile(currentStageGallery!.spaceId, currentStageGallery!.stageId, file.id); $event.stopPropagation()">×</button>
                 }
               </div>
             }
           </div>
         } @else {
           <div class="empty-gallery">
-            <svg width="64" height="64" viewBox="0 0 24 24" fill="currentColor" opacity="0.3">
-              <path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
-            </svg>
-            <p>该阶段暂无文件</p>
+            <p>暂无文件</p>
           </div>
         }
       </div>
       
       <!-- 模态框底部 -->
       <div class="gallery-footer">
-        @if (canEdit && currentStageGallery.files.length > 0) {
+        @if (canEdit) {
           <div class="gallery-actions">
             <input
               type="file"
@@ -366,14 +257,10 @@
               hidden
               #galleryFileInput />
             <button class="add-files-btn" (click)="galleryFileInput.click()" [disabled]="uploadingDeliveryFiles">
-              <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
-                <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
-              </svg>
               添加更多文件
             </button>
           </div>
         }
-        <button class="close-gallery-btn" (click)="closeStageGallery()">关闭</button>
       </div>
     </div>
   </div>
@@ -389,7 +276,7 @@
   (created)="onRevisionTaskCreated($event)">
 </app-revision-task-modal>
 
-<!-- 改图工单列表(全屏显示) -->
+<!-- 改图工单列表 -->
 @if (showRevisionTaskList) {
   <div class="revision-list-fullscreen">
     <app-revision-task-list
@@ -411,81 +298,21 @@
         <h4>发送消息</h4>
         <button class="close-btn" (click)="closeMessageModal()">×</button>
       </div>
-      
       <div class="modal-body">
-        <!-- 阶段信息 -->
-        <div class="stage-info-section">
-          <div class="info-item">
-            <span class="label">空间:</span>
-            <span class="value">{{ messageModalConfig.spaceName }}</span>
-          </div>
-          <div class="info-item">
-            <span class="label">阶段:</span>
-            <span class="value">{{ messageModalConfig.stageName }}</span>
-          </div>
-          @if (messageModalConfig.imageUrls.length > 0) {
-            <div class="info-item">
-              <span class="label">图片:</span>
-              <span class="value">{{ messageModalConfig.imageUrls.length }} 张</span>
-            </div>
-          }
-        </div>
-        
-        <!-- 预设话术 -->
-        <div class="template-section">
-          <label class="section-label">选择话术(可选):</label>
-          <div class="template-options">
-            @for (template of deliveryMessageService.getStageTemplates(messageModalConfig.stage); track template) {
-              <button class="template-option" 
-                      [class.active]="selectedTemplate === template"
-                      (click)="selectTemplate(template)">
-                {{ template }}
-              </button>
-            }
-          </div>
-        </div>
-        
-        <!-- 自定义消息 -->
-        <div class="custom-message-section">
-          <label class="section-label">自定义消息:</label>
-          <textarea 
+         <!-- 简化版消息发送界面,适配侧边栏 -->
+         <div class="info-item">
+            <span class="label">发送图片:</span>
+            <span class="value">{{ messageModalConfig.imageUrls.length }} 张</span>
+         </div>
+         <textarea 
             [(ngModel)]="customMessage" 
-            placeholder="输入自定义消息,如不填写将使用选中的话术..."
-            rows="4"
-            maxlength="500"></textarea>
-          <div class="char-count">{{ customMessage.length }}/500</div>
-        </div>
-        
-        <!-- 预览图片(如果有) -->
-        @if (messageModalConfig.imageUrls.length > 0) {
-          <div class="preview-images-section">
-            <label class="section-label">将发送的图片:</label>
-            <div class="preview-images-grid">
-              @for (url of messageModalConfig.imageUrls.slice(0, 6); track url) {
-                <img [src]="url" class="preview-img" />
-              }
-              @if (messageModalConfig.imageUrls.length > 6) {
-                <div class="more-images">
-                  +{{ messageModalConfig.imageUrls.length - 6 }}
-                </div>
-              }
-            </div>
-          </div>
-        }
+            placeholder="输入消息..."
+            rows="3"
+            style="width:100%;margin-top:10px;padding:8px;border:1px solid #e2e8f0;border-radius:6px;"></textarea>
       </div>
-      
       <div class="modal-footer">
         <button class="btn-cancel" (click)="closeMessageModal()">取消</button>
-        <button class="btn-send" 
-                (click)="sendMessage()" 
-                [disabled]="sendingMessage || (!customMessage.trim() && !selectedTemplate && messageModalConfig.imageUrls.length === 0)">
-          @if (sendingMessage) {
-            <span class="spinner-small"></span>
-            <span>发送中...</span>
-          } @else {
-            <span>发送</span>
-          }
-        </button>
+        <button class="btn-send" (click)="sendMessage()" [disabled]="sendingMessage">发送</button>
       </div>
     </div>
   </div>

+ 365 - 1990
src/modules/project/pages/project-detail/stages/stage-delivery-new.component.scss

@@ -1,2187 +1,562 @@
 .stage-delivery-container {
-  padding: 20px;
-  background-color: #f5f7fa;
+  padding: 12px;
+  background-color: #eef0f4;
   min-height: 100vh;
-  
-  // 🔥 企业微信端响应式:减小padding
-  @media screen and (max-width: 768px) {
-    padding: 12px !important;
-  }
-  
+
   @media screen and (max-width: 480px) {
-    padding: 8px !important;
+    padding: 8px;
   }
-  
-  // 改图工单工具栏
+
+  // Revision Toolbar
   .revision-toolbar {
     display: flex;
-    gap: 12px;
-    margin-bottom: 20px;
-    
-    // 🔥 企业微信端响应式
-    @media screen and (max-width: 768px) {
-      gap: 8px !important;
-      margin-bottom: 12px !important;
-    }
-    
+    gap: 8px;
+    margin-bottom: 12px;
+
     button {
-      padding: 10px 16px;
+      padding: 8px 12px;
       border: none;
-      border-radius: 8px;
-      font-size: 14px;
+      border-radius: 6px;
+      font-size: 13px;
       font-weight: 500;
       cursor: pointer;
-      transition: all 0.2s;
       display: flex;
       align-items: center;
-      gap: 8px;
-      
-      // 🔥 企业微信端响应式
-      @media screen and (max-width: 768px) {
-        padding: 8px 12px !important;
-        font-size: 13px !important;
-        
-        span {
-          display: none !important; // 隐藏文字,只显示图标
-        }
-      }
-      
-      svg {
-        flex-shrink: 0;
-        
-        // 🔥 企业微信端响应式
-        @media screen and (max-width: 768px) {
-          width: 16px !important;
-          height: 16px !important;
-        }
-      }
+      gap: 6px;
+      transition: all 0.2s;
     }
-    
+
     .btn-create-revision {
       background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
       color: white;
-      box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
-      
+      box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
+
       &:hover {
         transform: translateY(-1px);
-        box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
-      }
-      
-      &:active {
-        transform: translateY(0);
       }
     }
-    
+
     .btn-view-revisions {
       background: white;
       color: #4f46e5;
       border: 1px solid #e5e7eb;
       position: relative;
-      
-      &:hover {
-        background: #f9fafb;
-        border-color: #4f46e5;
-      }
-      
+
       .task-count-badge {
         position: absolute;
         top: -6px;
         right: -6px;
-        min-width: 20px;
-        height: 20px;
-        padding: 0 6px;
         background: #ef4444;
         color: white;
         border-radius: 10px;
-        font-size: 11px;
-        font-weight: 600;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        box-shadow: 0 2px 4px rgba(239, 68, 68, 0.3);
+        padding: 2px 6px;
+        font-size: 10px;
+        font-weight: 700;
       }
     }
   }
 
-  // 加载状态
+  // Loading State
   .loading-state {
     display: flex;
     flex-direction: column;
     align-items: center;
     justify-content: center;
-    padding: 60px 20px;
+    padding: 40px 20px;
     
     .spinner {
-      width: 48px;
-      height: 48px;
-      border: 4px solid #e0e0e0;
+      width: 32px; height: 32px;
+      border: 3px solid #e2e8f0;
       border-top-color: #667eea;
       border-radius: 50%;
       animation: spin 0.8s linear infinite;
     }
     
-    p {
-      margin-top: 16px;
-      color: #64748b;
-      font-size: 14px;
-    }
+    p { margin-top: 12px; font-size: 13px; color: #64748b; }
   }
 
-  @keyframes spin {
-    to { transform: rotate(360deg); }
-  }
+  @keyframes spin { to { transform: rotate(360deg); } }
 
-  // ==================== 🆕 空间列表样式 ====================
+  // ==================== 🆕 Spaces List (Smart Grid) ====================
   .spaces-list-section {
     display: flex;
     flex-direction: column;
-    gap: 24px;
+    gap: 12px;
 
-    // 空间卡片
     .space-card {
       background: white;
-      border-radius: 16px;
-      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
-      overflow: hidden;
-      transition: all 0.3s ease;
-
-      &:hover {
-        box-shadow: 0 4px 16px rgba(102, 126, 234, 0.15);
-      }
-    }
-
-    // 空间头部(显示空间名和四个阶段名称)
-    .space-header {
-      display: flex;
-      align-items: center;
-      gap: 20px;
-      padding: 20px 28px;
-      background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
-      border: 2px solid #e2e8f0;
-      cursor: pointer;
-      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
       border-radius: 12px;
-      position: relative;
+      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
       overflow: hidden;
-      
-      // 🔥 企业微信端响应式:改为竖向布局
-      @media screen and (max-width: 768px) {
-        flex-direction: column !important;
-        align-items: stretch !important;
-        gap: 12px !important;
-        padding: 12px 16px 48px 16px !important; // 底部留空间给展开图标
-      }
-
-      // 顶部装饰条
-      &::before {
-        content: '';
-        position: absolute;
-        top: 0;
-        left: 0;
-        right: 0;
-        height: 4px;
-        background: linear-gradient(90deg, #667eea 0%, #764ba2 50%, #667eea 100%);
-        background-size: 200% 100%;
-        transition: all 0.3s ease;
-      }
+      transition: box-shadow 0.2s;
 
       &:hover {
-        border-color: #667eea;
-        box-shadow: 0 8px 24px rgba(102, 126, 234, 0.15);
-        transform: translateY(-2px);
-
-        &::before {
-          animation: shimmer 2s linear infinite;
-        }
-
-        .expand-icon {
-          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-          color: white;
-          transform: scale(1.1);
-        }
+        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
       }
 
-      // 空间名称区域
-      .space-name-section {
+      // Header
+      .space-header {
         display: flex;
+        justify-content: space-between;
         align-items: center;
-        gap: 12px;
-        flex-shrink: 0;
-        min-width: 100px;
-        font-size: 18px;
-        font-weight: 700;
-        color: #1e293b;
-        padding-right: 20px;
-        border-right: 2px solid #e2e8f0;
-        letter-spacing: 0.3px;
-        
-        // 🔥 企业微信端响应式
-        @media screen and (max-width: 768px) {
-          flex-direction: row !important;
-          justify-content: space-between !important;
-          min-width: auto !important;
-          font-size: 16px !important;
-          padding-right: 0 !important;
-          border-right: none !important;
-          border-bottom: 1px solid #e2e8f0 !important;
-          padding-bottom: 8px !important;
+        padding: 14px 16px;
+        cursor: pointer;
+        background: white;
+        border-bottom: 1px solid transparent;
+        transition: all 0.2s;
+
+        &:hover {
+          background: #f9fafb;
         }
 
-        .completion-badge {
-          display: inline-flex;
+        .space-title {
+          font-size: 16px;
+          font-weight: 700;
+          color: #1e293b;
+          display: flex;
           align-items: center;
-          justify-content: center;
-          padding: 4px 10px;
-          background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
-          color: white;
-          font-size: 13px;
-          font-weight: 600;
-          border-radius: 12px;
-          box-shadow: 0 2px 6px rgba(82, 196, 26, 0.3);
-          animation: pulse-badge 2s ease-in-out infinite;
-          
-          // 🔥 企业微信端响应式
-          @media screen and (max-width: 768px) {
-            padding: 3px 8px !important;
-            font-size: 12px !important;
+          gap: 6px;
+
+          .space-badge {
+            font-size: 10px;
+            padding: 2px 6px;
+            background: #e0e7ff;
+            color: #6366f1;
+            border-radius: 4px;
+            font-weight: 500;
           }
         }
-      }
-
-      // 四个阶段名称横向排列
-      .stage-names-row {
-        flex: 1;
-        display: grid;
-        grid-template-columns: repeat(4, 1fr);
-        gap: 12px;
-        padding: 0 8px;
-        
-        // 🔥 企业微信端响应式:改为2列
-        @media screen and (max-width: 768px) {
-          grid-template-columns: repeat(2, 1fr) !important;
-          gap: 8px;
-          padding: 0;
-        }
 
-        .stage-name-item {
+        .space-header-right {
           display: flex;
           align-items: center;
-          justify-content: center;
           gap: 8px;
-          padding: 12px 16px;
-          background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
-          border: 2px solid #e2e8f0;
-          border-radius: 10px;
-          transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-          position: relative;
-          overflow: hidden;
-
-          // 底部装饰条
-          &::after {
-            content: '';
-            position: absolute;
-            bottom: 0;
-            left: 0;
-            right: 0;
-            height: 3px;
-            background: linear-gradient(90deg, #cbd5e1 0%, #94a3b8 100%);
-            transition: all 0.3s ease;
-          }
 
-          .stage-label {
-            font-size: 15px;
-            font-weight: 600;
-            color: #475569;
-            letter-spacing: 0.3px;
-            transition: all 0.3s ease;
-          }
-
-          .mini-badge {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            min-width: 24px;
-            height: 24px;
-            padding: 0 8px;
-            background: linear-gradient(135deg, #cbd5e1 0%, #94a3b8 100%);
-            color: white;
-            border-radius: 12px;
+          .progress-text {
             font-size: 12px;
-            font-weight: 700;
-            box-shadow: 0 2px 6px rgba(148, 163, 184, 0.3);
-            transition: all 0.3s ease;
-          }
-
-          // 有文件的阶段样式
-          &.has-files {
-            background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
-            border-color: #6ee7b7;
-            box-shadow: 0 2px 8px rgba(16, 185, 129, 0.15);
-
-            &::after {
-              background: linear-gradient(90deg, #10b981 0%, #059669 100%);
-            }
-
-            .stage-label {
-              color: #047857;
-              font-weight: 700;
-            }
-
-            .mini-badge {
-              background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-              box-shadow: 0 2px 8px rgba(16, 185, 129, 0.4);
-              animation: pulse-badge 2s ease-in-out infinite;
-            }
+            color: #64748b;
           }
 
-          // 悬停效果(仅在未展开时)
-          &:hover {
-            transform: translateY(-2px);
-            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
-            border-color: #667eea;
-
-            &::after {
-              background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
-            }
-
-            .stage-label {
-              color: #667eea;
+          .expand-icon {
+            color: #94a3b8;
+            transition: transform 0.3s;
+            display: flex;
+            
+            &.expanded {
+              transform: rotate(180deg);
             }
           }
         }
       }
 
-      // 展开/收起图标
-      .expand-icon {
-        flex-shrink: 0;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        width: 44px;
-        height: 44px;
-        background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
-        border: 2px solid #cbd5e1;
-        border-radius: 50%;
-        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
-        
-        // 🔥 企业微信端响应式:移到右下角
-        @media screen and (max-width: 768px) {
-          position: absolute !important;
-          bottom: 12px !important;
-          right: 50% !important;
-          transform: translateX(50%) !important;
-          width: 32px !important;
-          height: 32px !important;
-        }
-
-        svg {
-          transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-          color: #64748b;
-        }
-
-        &.expanded svg {
-          transform: rotate(180deg);
-        }
-      }
-    }
-
-    // 空间内容(展开时显示)
-    .space-content {
-      padding: 24px;
-      animation: slideDown 0.3s ease-out;
-      position: relative;
-      transition: all 0.3s ease;
-      
-      // 🔥 企业微信端响应式
-      @media screen and (max-width: 768px) {
-        padding: 12px !important;
-      }
-      
-      @media screen and (max-width: 480px) {
-        padding: 8px !important;
-      }
-      
-      // 🔥 空间拖拽状态
-      &.space-drag-over {
-        background: rgba(102, 126, 234, 0.05);
-        border-radius: 16px;
-        box-shadow: inset 0 0 0 3px rgba(102, 126, 234, 0.3);
-      }
+      // Content
+      .space-content {
+        padding: 12px;
+        border-top: 1px solid #f1f5f9;
+        position: relative;
+        animation: slideDown 0.3s ease-out;
 
-      // 🆕 四个阶段区域容器(横向排列)
-      .stages-container {
-        display: grid;
-        grid-template-columns: repeat(4, 1fr);
-        gap: 16px;
-        margin-bottom: 32px;
-        
-        // 🔥 企业微信端响应式:改为2列
-        @media screen and (max-width: 768px) {
-          grid-template-columns: repeat(2, 1fr) !important;
-          gap: 12px !important;
-          margin-bottom: 16px;
+        &.space-drag-over {
+          background: #f8fafc;
         }
-        
-        // 🔥 极窄屏幕:改为单列
-        @media screen and (max-width: 480px) {
-          grid-template-columns: 1fr !important;
-          gap: 10px !important;
-        }
-
-        // 单个阶段区域
-        .stage-section {
-          background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
-          border: 2px solid #e2e8f0;
-          border-radius: 16px;
-          overflow: hidden;
-          transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
-          position: relative;
-
-          // 顶部装饰条
-          &::before {
-            content: '';
-            position: absolute;
-            top: 0;
-            left: 0;
-            right: 0;
-            height: 4px;
-            background: linear-gradient(90deg, #cbd5e1 0%, #94a3b8 100%);
-            transition: all 0.3s ease;
-          }
 
-          &:hover {
-            border-color: #667eea;
-            box-shadow: 0 8px 24px rgba(102, 126, 234, 0.15);
-            transform: translateY(-4px);
-
-            &::before {
-              background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
-            }
-          }
-
-          // 有文件的阶段
-          &.has-files {
-            background: linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 100%);
-            border-color: #86efac;
-
-            &::before {
-              background: linear-gradient(90deg, #10b981 0%, #059669 100%);
-            }
-
-            .stage-header {
-              background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
-
-              .stage-name {
-                color: #065f46;
-              }
-
-              .file-count-badge {
-                background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-                box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
-              }
+        // Drag Overlay
+        .space-drag-overlay {
+          position: absolute;
+          inset: 0;
+          background: rgba(255, 255, 255, 0.9);
+          z-index: 10;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          
+          .space-drag-hint {
+            text-align: center;
+            color: #6366f1;
+            .space-drag-icon { 
+               margin: 0 auto 8px; 
+               width: 48px; height: 48px; 
+               background: #e0e7ff; 
+               border-radius: 50%; 
+               display: flex; align-items: center; justify-content: center;
             }
+            h3 { margin: 0; font-size: 16px; }
+            p { margin: 4px 0 0; font-size: 12px; color: #64748b; }
           }
+        }
 
-          // 阶段头部
-          .stage-header {
-            background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
-            padding: 12px 16px;
-            border-bottom: 1px solid #e2e8f0;
-            transition: all 0.3s ease;
-
-            .stage-title {
-              display: flex;
-              align-items: center;
-              justify-content: space-between;
-              gap: 8px;
-
-              .stage-name {
-                font-size: 15px;
-                font-weight: 700;
-                color: #475569;
-                letter-spacing: 0.3px;
-                transition: all 0.3s ease;
-              }
-
-              .file-count-badge {
-                display: inline-flex;
-                align-items: center;
-                justify-content: center;
-                min-width: 24px;
-                height: 24px;
-                padding: 0 8px;
-                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-                color: white;
-                border-radius: 12px;
-                font-size: 12px;
-                font-weight: 700;
-                box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
-                transition: all 0.3s ease;
-              }
-            }
-          }
+        // Grid Layout (2 Columns)
+        .stages-grid {
+          display: grid;
+          grid-template-columns: repeat(2, 1fr);
+          gap: 10px;
 
-          // 阶段内容区域
-          .stage-body {
-            padding: 16px;
-            min-height: 200px;
+          .stage-item {
+            background: #f9fafb;
+            border: 1px solid #e2e8f0;
+            border-radius: 8px;
+            padding: 10px;
             display: flex;
             flex-direction: column;
-            align-items: center;
-            justify-content: center;
+            gap: 8px;
             position: relative;
-            cursor: pointer;
-            transition: all 0.3s ease;
-
-            &:hover {
-              background: rgba(102, 126, 234, 0.02);
+            transition: all 0.2s;
+            min-height: 80px;
+
+            // Pending State
+            &.pending {
+              border-style: dashed;
+              border-color: #cbd5e1;
+              &:hover {
+                background: #f5f7ff;
+                border-color: #6366f1;
+              }
             }
 
-            // 拖拽状态
-            &.drag-over {
-              background: rgba(102, 126, 234, 0.08);
-              border: 2px dashed #667eea;
-              border-radius: 12px;
+            // Completed State
+            &.completed {
+              background: white;
+              border-color: #86efac; // Greenish border
+              box-shadow: 0 2px 4px rgba(16, 185, 129, 0.05);
             }
 
-            // 拖拽提示覆盖层
-            .drag-overlay {
-              position: absolute;
-              top: 0;
-              left: 0;
-              right: 0;
-              bottom: 0;
-              background: rgba(102, 126, 234, 0.12);
-              backdrop-filter: blur(4px);
-              display: flex;
-              align-items: center;
-              justify-content: center;
-              z-index: 10;
-              border-radius: 12px;
-              animation: dragOverlay 0.3s ease-out;
-
-              .drag-hint {
-                text-align: center;
-                color: #667eea;
-
-                .drag-icon {
-                  margin-bottom: 8px;
-                  opacity: 0.9;
-
-                  svg {
-                    animation: bounce 1s ease-in-out infinite;
-                    color: #667eea;
-                  }
-                }
-
-                p {
-                  margin: 0;
-                  font-size: 13px;
-                  font-weight: 600;
-                  color: #667eea;
-                }
-              }
+            // Drag Over State
+            &.drag-over {
+              background: #e0e7ff;
+              border-color: #6366f1;
+              border-style: dashed;
+              box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
             }
 
-            // 紧凑型上传区域(无文件时显示)
-            .upload-zone-compact {
+            .stage-label {
+              font-size: 13px;
+              font-weight: 600;
+              color: #334155;
               display: flex;
-              flex-direction: column;
+              justify-content: space-between;
               align-items: center;
-              justify-content: center;
-              gap: 12px;
-              padding: 20px;
 
-              .upload-btn-compact {
-                display: flex;
-                align-items: center;
-                gap: 8px;
-                padding: 12px 24px;
-                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+              .status-icon {
+                width: 16px; height: 16px;
+                border-radius: 50%;
+                background: #10b981;
                 color: white;
-                border: none;
-                border-radius: 10px;
-                font-size: 14px;
-                font-weight: 600;
-                cursor: pointer;
-                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-                box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
-
-                &:hover:not(:disabled) {
-                  transform: translateY(-2px);
-                  box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4);
-                  background: linear-gradient(135deg, #5568d3 0%, #6a3f8f 100%);
-                }
-
-                &:active:not(:disabled) {
-                  transform: translateY(0);
-                }
-
-                &:disabled {
-                  opacity: 0.5;
-                  cursor: not-allowed;
-                }
-
-                svg {
-                  width: 20px;
-                  height: 20px;
-                }
+                font-size: 10px;
+                display: flex; align-items: center; justify-content: center;
               }
             }
 
-            // 文件预览(缩略图网格)
-            .files-preview {
-              display: grid;
-              grid-template-columns: repeat(2, 1fr);
-              gap: 8px;
-              width: 100%;
-              padding: 8px;
+            // Previews
+            .preview-strip {
+              display: flex;
+              gap: 6px;
+              margin-top: auto;
 
-              .file-thumbnail {
-                position: relative;
-                width: 100%;
-                aspect-ratio: 1;
-                background: white;
-                border: 2px solid #e2e8f0;
-                border-radius: 8px;
+              .mini-thumb-wrapper {
+                width: 36px; height: 36px;
+                border-radius: 4px;
                 overflow: hidden;
+                border: 1px solid #e2e8f0;
+                background: white;
                 cursor: pointer;
-                transition: all 0.3s ease;
-                box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
-
-                &:hover {
-                  border-color: #667eea;
-                  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
-                  transform: scale(1.05);
-
-                  .delete-thumbnail-btn {
-                    opacity: 1;
-                  }
-                }
-
-                .thumbnail-img {
-                  width: 100%;
-                  height: 100%;
-                  object-fit: cover;
-                }
-
-                .thumbnail-placeholder {
-                  display: flex;
-                  align-items: center;
-                  justify-content: center;
-                  width: 100%;
-                  height: 100%;
-                  color: #cbd5e1;
-                  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
-
-                  svg {
-                    width: 28px;
-                    height: 28px;
-                  }
-                }
-
-                .delete-thumbnail-btn {
-                  position: absolute;
-                  top: 4px;
-                  right: 4px;
-                  width: 24px;
-                  height: 24px;
-                  display: flex;
-                  align-items: center;
-                  justify-content: center;
-                  background: rgba(239, 68, 68, 0.95);
-                  color: white;
-                  border: none;
-                  border-radius: 6px;
-                  cursor: pointer;
-                  opacity: 0;
-                  transition: all 0.3s ease;
-                  box-shadow: 0 2px 6px rgba(239, 68, 68, 0.4);
-
-                  &:hover {
-                    background: rgba(220, 38, 38, 1);
-                    transform: scale(1.1);
-                  }
-
-                  svg {
-                    width: 12px;
-                    height: 12px;
-                  }
-                }
+                flex-shrink: 0;
                 
-                .send-image-btn {
-                  position: absolute;
-                  bottom: 4px;
-                  right: 4px;
-                  width: 28px;
-                  height: 28px;
-                  display: flex;
-                  align-items: center;
-                  justify-content: center;
-                  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-                  color: white;
-                  border: none;
-                  border-radius: 6px;
-                  cursor: pointer;
-                  opacity: 0;
-                  transition: all 0.3s ease;
-                  box-shadow: 0 2px 8px rgba(16, 185, 129, 0.4);
-
-                  &:hover {
-                    background: linear-gradient(135deg, #059669 0%, #047857 100%);
-                    transform: scale(1.1);
-                    box-shadow: 0 4px 12px rgba(16, 185, 129, 0.6);
-                  }
-
-                  svg {
-                    width: 14px;
-                    height: 14px;
-                  }
+                .mini-thumb {
+                  width: 100%; height: 100%; object-fit: cover;
                 }
                 
-                &:hover {
-                  .send-image-btn {
-                    opacity: 1;
-                  }
+                .file-icon {
+                  display: flex; align-items: center; justify-content: center;
+                  color: #94a3b8;
                 }
               }
 
-              .more-files-indicator {
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
-                border: 2px dashed #cbd5e1;
-                border-radius: 8px;
-                font-size: 14px;
-                font-weight: 700;
-                color: #64748b;
+              .add-box {
+                width: 36px; height: 36px;
+                border-radius: 4px;
+                border: 1px dashed #cbd5e1;
+                display: flex; align-items: center; justify-content: center;
+                color: #94a3b8;
+                font-size: 16px;
                 cursor: pointer;
-                transition: all 0.3s ease;
-
+                background: white;
+                
                 &:hover {
-                  background: linear-gradient(135deg, #e0e7ff 0%, #ddd6fe 100%);
-                  border-color: #667eea;
-                  color: #667eea;
+                  border-color: #6366f1;
+                  color: #6366f1;
                 }
               }
             }
 
-            // 添加更多文件按钮
-            .add-more-files {
-              display: flex;
-              justify-content: center;
-              gap: 8px;
-              padding: 8px 0 0;
-
-              .add-more-btn, .send-message-btn {
-                display: flex;
-                align-items: center;
-                gap: 6px;
-                padding: 8px 16px;
-                border: 2px solid #e2e8f0;
-                border-radius: 8px;
-                font-size: 13px;
-                font-weight: 600;
-                cursor: pointer;
-                transition: all 0.3s ease;
-
-                &:disabled {
-                  opacity: 0.5;
-                  cursor: not-allowed;
-                }
-
-                svg {
-                  width: 16px;
-                  height: 16px;
-                }
-              }
-              
-              .add-more-btn {
-                background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
-                color: #475569;
-
-                &:hover:not(:disabled) {
-                  background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);
-                  border-color: #667eea;
-                  color: #667eea;
-                  transform: translateY(-1px);
-                  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.15);
-                }
-              }
-              
-              .send-message-btn {
-                background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-                color: white;
-                border-color: #10b981;
-
-                &:hover {
-                  background: linear-gradient(135deg, #059669 0%, #047857 100%);
-                  border-color: #047857;
-                  transform: translateY(-1px);
-                  box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
-                }
-              }
+            // Empty Actions
+            .upload-action {
+               margin-top: auto;
+               height: 36px;
+               display: flex;
+               align-items: center;
+               justify-content: center;
+               gap: 4px;
+               font-size: 12px;
+               color: #6366f1;
+               background: white;
+               border: 1px solid #e0e7ff;
+               border-radius: 4px;
+               cursor: pointer;
+               transition: all 0.2s;
+
+               &:hover {
+                 background: #6366f1;
+                 color: white;
+               }
             }
-
-            // 空状态提示
-            .empty-stage-hint {
+            
+            .empty-action {
+              margin-top: auto;
+              height: 36px;
               display: flex;
-              flex-direction: column;
               align-items: center;
               justify-content: center;
-              padding: 20px;
-              color: #cbd5e1;
-
-              svg {
-                margin-bottom: 8px;
-              }
-
-              p {
-                margin: 0;
-                font-size: 13px;
-                font-weight: 500;
-                color: #94a3b8;
-              }
+              font-size: 12px;
+              color: #94a3b8;
             }
           }
         }
-      }
-
-      // 🆕 整体空间拖拽覆盖层
-      .space-drag-overlay {
-        position: absolute;
-        top: 0;
-        left: 0;
-        right: 0;
-        bottom: 0;
-        background: rgba(102, 126, 234, 0.15);
-        backdrop-filter: blur(8px);
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        z-index: 50;
-        border-radius: 16px;
-        animation: spaceOverlayFadeIn 0.3s ease-out;
 
-        .space-drag-hint {
-          text-align: center;
-          padding: 40px;
-          background: rgba(255, 255, 255, 0.95);
-          border-radius: 20px;
-          box-shadow: 0 20px 60px rgba(102, 126, 234, 0.4);
-          border: 3px solid rgba(102, 126, 234, 0.3);
-          max-width: 400px;
-          animation: spaceHintBounce 0.5s ease-out;
+        // Confirm Section
+        .space-confirm-section {
+          margin-top: 16px;
+          display: flex;
+          justify-content: center;
+          border-top: 1px solid #f1f5f9;
+          padding-top: 16px;
 
-          .space-drag-icon {
-            margin: 0 auto 20px;
-            width: 80px;
-            height: 80px;
-            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-            border-radius: 50%;
+          .confirm-space-btn {
+            width: 100%;
+            padding: 10px;
+            background: #10b981;
+            color: white;
+            border: none;
+            border-radius: 8px;
+            font-weight: 600;
+            cursor: pointer;
             display: flex;
             align-items: center;
             justify-content: center;
-            animation: iconPulse 2s ease-in-out infinite;
-            box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
-
-            svg {
-              color: white;
-              width: 40px;
-              height: 40px;
-              filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
+            gap: 8px;
+            
+            &:hover:not(:disabled) {
+              background: #059669;
+            }
+            &:disabled {
+              opacity: 0.5;
+              cursor: not-allowed;
             }
           }
 
-          h3 {
-            margin: 0 0 12px 0;
-            font-size: 24px;
-            font-weight: 700;
-            color: #475569;
-            letter-spacing: 0.5px;
-          }
-
-          p {
-            margin: 0;
-            font-size: 16px;
-            color: #64748b;
-            line-height: 1.6;
-            font-weight: 500;
+          .confirmed-info {
+            display: flex;
+            align-items: center;
+            gap: 6px;
+            color: #059669;
+            font-weight: 600;
+            font-size: 14px;
+            padding: 8px 16px;
+            background: #ecfdf5;
+            border-radius: 8px;
           }
         }
       }
+    }
+  }
 
-      // 统一的空间确认按钮区域
-      .space-confirm-section {
-        display: flex;
-        justify-content: center;
-        padding: 32px 0 0;
-        margin-top: 32px;
-        border-top: 2px solid #e2e8f0;
-        position: relative;
-
-        // 装饰性渐变背景
-        &::before {
-          content: '';
-          position: absolute;
-          top: -2px;
-          left: 50%;
-          transform: translateX(-50%);
-          width: 200px;
-          height: 2px;
-          background: linear-gradient(90deg, transparent 0%, #667eea 50%, transparent 100%);
-        }
-
-        .confirm-space-btn {
-          display: flex;
-          align-items: center;
-          gap: 12px;
-          padding: 18px 56px;
-          background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-          color: white;
-          border: none;
-          border-radius: 16px;
-          font-size: 18px;
-          font-weight: 700;
-          cursor: pointer;
-          transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-          box-shadow: 0 8px 24px rgba(16, 185, 129, 0.35);
-          letter-spacing: 0.5px;
-          position: relative;
-          overflow: hidden;
-
-          // 按钮光泽效果
-          &::before {
-            content: '';
-            position: absolute;
-            top: 0;
-            left: -100%;
-            width: 100%;
-            height: 100%;
-            background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
-            transition: left 0.5s ease;
-          }
-
-          &:hover:not(:disabled) {
-            transform: translateY(-4px) scale(1.02);
-            box-shadow: 0 12px 32px rgba(16, 185, 129, 0.45);
-            background: linear-gradient(135deg, #059669 0%, #047857 100%);
-
-            &::before {
-              left: 100%;
-            }
-          }
-
-          &:active:not(:disabled) {
-            transform: translateY(-2px) scale(1);
-          }
-
-          &:disabled {
-            opacity: 0.5;
-            cursor: not-allowed;
-            background: linear-gradient(135deg, #94a3b8 0%, #64748b 100%);
-          }
-
-          svg {
-            width: 24px;
-            height: 24px;
-            filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
-          }
-        }
-
-        .confirmed-info {
-          display: flex;
-          flex-direction: column;
-          align-items: center;
-          gap: 12px;
-          padding: 24px 48px;
-          background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
-          border: 3px solid #6ee7b7;
-          border-radius: 16px;
-          box-shadow: 0 6px 20px rgba(16, 185, 129, 0.25);
-          position: relative;
-          overflow: hidden;
-
-          // 装饰性背景图案
-          &::before {
-            content: '';
-            position: absolute;
-            top: -50%;
-            right: -50%;
-            width: 200%;
-            height: 200%;
-            background: radial-gradient(circle, rgba(255, 255, 255, 0.3) 0%, transparent 70%);
-            animation: rotate 20s linear infinite;
-          }
-
-          .confirmed-header {
-            display: flex;
-            align-items: center;
-            gap: 12px;
-            position: relative;
-            z-index: 1;
-
-            svg {
-              width: 32px;
-              height: 32px;
-              color: #059669;
-              filter: drop-shadow(0 2px 4px rgba(5, 150, 105, 0.3));
-              animation: pulse 2s ease-in-out infinite;
-            }
-
-            .confirmed-text {
-              font-size: 22px;
-              font-weight: 700;
-              color: #059669;
-              letter-spacing: 0.5px;
-              text-shadow: 0 1px 2px rgba(5, 150, 105, 0.2);
-            }
-          }
-
-          .confirmed-details {
-            font-size: 14px;
-            font-weight: 500;
-            color: #047857;
-            text-align: center;
-            line-height: 1.6;
-            position: relative;
-            z-index: 1;
-            background: rgba(255, 255, 255, 0.5);
-            padding: 8px 16px;
-            border-radius: 8px;
-          }
-        }
-      }
-    }
-  }
-
-  // 没有场景时的提示
+  // Empty State
   .no-products-state {
     display: flex;
     flex-direction: column;
     align-items: center;
-    justify-content: center;
-    padding: 80px 20px;
-    
-    .state-icon {
-      color: #cbd5e1;
-      margin-bottom: 20px;
-      
-      svg {
-        width: 64px;
-        height: 64px;
-      }
-    }
-    
-    h3 {
-      margin: 0 0 12px;
-      font-size: 20px;
-      font-weight: 600;
-      color: #475569;
-    }
-    
-    p {
-      margin: 0;
-      font-size: 15px;
-      color: #94a3b8;
-      text-align: center;
-    }
-  }
-
-  // ==================== 动画效果 ====================
-
-  // 空间内容展开动画
-  @keyframes slideDown {
-    from {
-      opacity: 0;
-      transform: translateY(-10px);
-    }
-    to {
-      opacity: 1;
-      transform: translateY(0);
-    }
-  }
-
-  // 拖拽覆盖层动画
-  @keyframes dragOverlay {
-    from {
-      opacity: 0;
-      transform: scale(0.95);
-    }
-    to {
-      opacity: 1;
-      transform: scale(1);
-    }
-  }
-
-  // 拖拽提示动画
-  @keyframes dragHint {
-    from {
-      opacity: 0;
-      transform: translateY(10px) scale(0.9);
-    }
-    to {
-      opacity: 1;
-      transform: translateY(0) scale(1);
-    }
-  }
-
-  // 弹跳动画
-  @keyframes bounce {
-    0%, 20%, 50%, 80%, 100% {
-      transform: translateY(0);
-    }
-    40% {
-      transform: translateY(-8px);
-    }
-    60% {
-      transform: translateY(-4px);
-    }
-  }
-
-  // 脉冲动画(用于确认图标)
-  @keyframes pulse {
-    0%, 100% {
-      transform: scale(1);
-      opacity: 1;
-    }
-    50% {
-      transform: scale(1.1);
-      opacity: 0.8;
-    }
-  }
-
-  // 旋转动画(用于装饰背景)
-  @keyframes rotate {
-    from {
-      transform: rotate(0deg);
-    }
-    to {
-      transform: rotate(360deg);
-    }
-  }
-
-  // 渐入动画
-  @keyframes fadeIn {
-    from {
-      opacity: 0;
-    }
-    to {
-      opacity: 1;
-    }
-  }
-
-  // 从下方滑入动画
-  @keyframes slideUp {
-    from {
-      opacity: 0;
-      transform: translateY(20px);
-    }
-    to {
-      opacity: 1;
-      transform: translateY(0);
-    }
-  }
-
-  // 缩放进入动画
-  @keyframes scaleIn {
-    from {
-      opacity: 0;
-      transform: scale(0.9);
-    }
-    to {
-      opacity: 1;
-      transform: scale(1);
-    }
-  }
-
-  // 光泽扫过动画(用于空间头部)
-  @keyframes shimmer {
-    0% {
-      background-position: 200% 0;
-    }
-    100% {
-      background-position: -200% 0;
-    }
-  }
-
-  // 徽章脉冲动画
-  @keyframes pulse-badge {
-    0%, 100% {
-      transform: scale(1);
-      box-shadow: 0 2px 8px rgba(16, 185, 129, 0.4);
-    }
-    50% {
-      transform: scale(1.05);
-      box-shadow: 0 4px 12px rgba(16, 185, 129, 0.6);
-    }
-  }
-
-  // 🆕 空间拖拽动画
-  @keyframes spaceOverlayFadeIn {
-    from {
-      opacity: 0;
-      backdrop-filter: blur(0px);
-    }
-    to {
-      opacity: 1;
-      backdrop-filter: blur(8px);
-    }
-  }
-
-  @keyframes spaceHintBounce {
-    from {
-      opacity: 0;
-      transform: scale(0.8) translateY(20px);
-    }
-    to {
-      opacity: 1;
-      transform: scale(1) translateY(0);
-    }
-  }
+    padding: 60px 20px;
+    color: #94a3b8;
 
-  @keyframes iconPulse {
-    0%, 100% {
-      transform: scale(1);
-      box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
-    }
-    50% {
-      transform: scale(1.1);
-      box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6);
+    .state-icon {
+      width: 64px; height: 64px;
+      background: #f1f5f9;
+      border-radius: 50%;
+      display: flex; align-items: center; justify-content: center;
+      margin-bottom: 16px;
     }
+    p { margin: 0; font-size: 14px; }
   }
 }
 
-// 阶段头部点击样式
-.stage-header {
-  &.clickable {
-    cursor: pointer;
-    transition: all 0.2s ease;
-    
-    &:hover {
-      background: rgba(59, 130, 246, 0.05);
-      
-      .view-all-hint {
-        opacity: 1;
-        transform: translateY(0);
-      }
-    }
-  }
-  
-  .view-all-hint {
-    display: flex;
-    align-items: center;
-    gap: 4px;
-    font-size: 12px;
-    color: #3b82f6;
-    opacity: 0;
-    transform: translateY(-4px);
-    transition: all 0.2s ease;
-    
-    svg {
-      flex-shrink: 0;
-    }
-  }
+@keyframes slideDown {
+  from { opacity: 0; transform: translateY(-8px); }
+  to { opacity: 1; transform: translateY(0); }
 }
 
-// 阶段图片库模态框
-.stage-gallery-modal-overlay {
+// Modals (Simplified)
+.stage-gallery-modal-overlay, .message-modal-overlay {
   position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.6);
+  inset: 0;
+  background: rgba(0, 0, 0, 0.5);
+  z-index: 100;
   display: flex;
   align-items: center;
   justify-content: center;
-  z-index: 1000;
-  backdrop-filter: blur(4px);
+  padding: 20px;
 }
 
-.stage-gallery-modal {
+.stage-gallery-modal, .message-modal-box {
   background: white;
-  border-radius: 16px;
-  width: 90vw;
-  max-width: 1200px;
-  height: 80vh;
-  max-height: 800px;
+  border-radius: 12px;
+  width: 100%;
+  max-width: 400px;
+  max-height: 80vh;
   display: flex;
   flex-direction: column;
-  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 10px 25px rgba(0,0,0,0.2);
   overflow: hidden;
-}
 
-.gallery-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 24px 28px;
-  border-bottom: 1px solid #e2e8f0;
-  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
-  
-  .gallery-title {
-    h3 {
-      margin: 0;
-      font-size: 20px;
-      font-weight: 600;
-      color: #1e293b;
-    }
-    
-    p {
-      margin: 4px 0 0 0;
-      font-size: 14px;
-      color: #64748b;
-    }
-  }
-  
-  .close-btn {
-    background: none;
-    border: none;
-    cursor: pointer;
-    padding: 8px;
-    border-radius: 8px;
-    color: #64748b;
-    transition: all 0.2s ease;
+  .gallery-header, .modal-header {
+    padding: 16px;
+    border-bottom: 1px solid #e2e8f0;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .gallery-title h3, h4 { margin: 0; font-size: 16px; font-weight: 700; }
+    p { margin: 4px 0 0; font-size: 12px; color: #64748b; }
     
-    &:hover {
-      background: rgba(248, 113, 113, 0.1);
-      color: #ef4444;
+    .close-btn {
+      background: none; border: none; font-size: 24px; color: #94a3b8; cursor: pointer;
+      &:hover { color: #ef4444; }
     }
   }
-}
 
-.gallery-content {
-  flex: 1;
-  overflow-y: auto;
-  padding: 24px 28px;
-}
+  .gallery-content, .modal-body {
+    flex: 1;
+    overflow-y: auto;
+    padding: 16px;
 
-.images-grid {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
-  gap: 20px;
-}
+    // Gallery Grid
+    .images-grid {
+      display: grid;
+      grid-template-columns: repeat(3, 1fr);
+      gap: 8px;
 
-.image-item {
-  position: relative;
-  background: #f8fafc;
-  border-radius: 12px;
-  overflow: hidden;
-  cursor: pointer;
-  transition: all 0.3s ease;
-  border: 2px solid transparent;
-  
-  &:hover {
-    transform: translateY(-4px);
-    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
-    border-color: #3b82f6;
-    
-    .delete-image-btn {
-      opacity: 1;
+      .image-item {
+        position: relative;
+        aspect-ratio: 1;
+        border-radius: 6px;
+        overflow: hidden;
+        background: #f8fafc;
+        border: 1px solid #e2e8f0;
+
+        img { width: 100%; height: 100%; object-fit: cover; }
+        .file-placeholder {
+           width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #cbd5e1;
+        }
+        .image-info { 
+           position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.6); color: white; font-size: 10px; padding: 2px 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 
+        }
+        .delete-image-btn {
+           position: absolute; top: 2px; right: 2px; width: 16px; height: 16px; background: rgba(239,68,68,0.9); color: white; border: none; border-radius: 50%; font-size: 12px; display: flex; align-items: center; justify-content: center; cursor: pointer;
+        }
+      }
     }
   }
-  
-  .gallery-image {
-    width: 100%;
-    height: 150px;
-    object-fit: cover;
-    display: block;
-  }
-  
-  .file-placeholder {
-    width: 100%;
-    height: 150px;
+
+  .gallery-footer, .modal-footer {
+    padding: 12px 16px;
+    border-top: 1px solid #e2e8f0;
     display: flex;
-    align-items: center;
-    justify-content: center;
-    background: #f1f5f9;
-    color: #94a3b8;
-  }
-  
-  .image-info {
-    padding: 12px;
-    background: white;
-    
-    .file-name {
-      font-size: 13px;
-      font-weight: 500;
-      color: #1e293b;
-      margin-bottom: 4px;
-      white-space: nowrap;
-      overflow: hidden;
-      text-overflow: ellipsis;
+    justify-content: flex-end;
+    gap: 8px;
+
+    .add-files-btn {
+      display: flex; align-items: center; gap: 6px;
+      background: #6366f1; color: white; border: none; padding: 8px 12px; border-radius: 6px; cursor: pointer; font-size: 13px;
     }
-    
-    .file-size {
-      font-size: 12px;
-      color: #64748b;
+    .close-gallery-btn, .btn-cancel {
+       background: white; border: 1px solid #e2e8f0; color: #64748b; padding: 8px 12px; border-radius: 6px; cursor: pointer; font-size: 13px;
     }
-  }
-  
-  .delete-image-btn {
-    position: absolute;
-    top: 8px;
-    right: 8px;
-    background: rgba(239, 68, 68, 0.9);
-    color: white;
-    border: none;
-    border-radius: 6px;
-    padding: 6px;
-    cursor: pointer;
-    opacity: 0;
-    transition: all 0.2s ease;
-    
-    &:hover {
-      background: #dc2626;
-      transform: scale(1.1);
+    .btn-send {
+       background: #10b981; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 13px;
+       &:disabled { opacity: 0.5; }
     }
   }
 }
 
-.empty-gallery {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  height: 300px;
-  color: #94a3b8;
-  
-  p {
-    margin-top: 16px;
-    font-size: 16px;
-  }
+// Revision list
+.revision-list-fullscreen {
+  position: fixed;
+  inset: 0;
+  z-index: 200;
+  background: white;
 }
 
-.gallery-footer {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 20px 28px;
-  border-top: 1px solid #e2e8f0;
-  background: #f8fafc;
-  
-  .gallery-actions {
-    display: flex;
-    gap: 12px;
-  }
-  
-  .add-files-btn {
-    display: flex;
-    align-items: center;
-    gap: 8px;
-    background: #3b82f6;
-    color: white;
-    border: none;
-    border-radius: 8px;
-    padding: 10px 16px;
-    font-size: 14px;
-    font-weight: 500;
-    cursor: pointer;
-    transition: all 0.2s ease;
-    
-    &:hover:not(:disabled) {
-      background: #2563eb;
-      transform: translateY(-1px);
-    }
-    
-    &:disabled {
-      opacity: 0.5;
-      cursor: not-allowed;
-    }
-  }
-  
-  .close-gallery-btn {
-    background: #6b7280;
-    color: white;
-    border: none;
-    border-radius: 8px;
-    padding: 10px 20px;
-    font-size: 14px;
-    font-weight: 500;
-    cursor: pointer;
-    transition: all 0.2s ease;
-    
-    &:hover {
-      background: #4b5563;
-    }
-  }
+// ==================== 动画效果 ====================
+
+// 拖拽覆盖层动画
+@keyframes dragOverlay {
+  from { opacity: 0; transform: scale(0.95); }
+  to { opacity: 1; transform: scale(1); }
 }
 
-// 响应式设计 - 阶段图片库
-@media (max-width: 768px) {
-  .stage-gallery-modal {
-    width: 95vw;
-    height: 90vh;
-    margin: 20px;
-  }
-  
-  .gallery-header {
-    padding: 16px 20px;
-    
-    .gallery-title h3 {
-      font-size: 18px;
-    }
-  }
-  
-  .gallery-content {
-    padding: 16px 20px;
-  }
-  
-  .images-grid {
-    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
-    gap: 12px;
-  }
-  
-  .image-item {
-    .gallery-image,
-    .file-placeholder {
-      height: 120px;
-    }
-  }
-  
-  .gallery-footer {
-    padding: 16px 20px;
-    flex-direction: column;
-    gap: 12px;
-    
-    .gallery-actions {
-      width: 100%;
-      justify-content: center;
-    }
-  }
+// 拖拽提示动画
+@keyframes dragHint {
+  from { opacity: 0; transform: translateY(10px) scale(0.9); }
+  to { opacity: 1; transform: translateY(0) scale(1); }
 }
 
-// 全屏工单列表
-.revision-list-fullscreen {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  z-index: 2100;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  animation: fadeIn 0.2s ease;
-  pointer-events: auto;
-  
-  app-revision-task-list {
-    width: 90%;
-    max-width: 1200px;
-    height: 85vh;
-    background: white;
-    border-radius: 16px;
-    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
-    overflow: hidden;
-    animation: slideUp 0.3s ease;
-  }
+// 弹跳动画
+@keyframes bounce {
+  0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
+  40% { transform: translateY(-8px); }
+  60% { transform: translateY(-4px); }
+}
+
+// 脉冲动画(用于确认图标)
+@keyframes pulse {
+  0%, 100% { transform: scale(1); opacity: 1; }
+  50% { transform: scale(1.1); opacity: 0.8; }
 }
 
+// 旋转动画(用于装饰背景)
+@keyframes rotate {
+  from { transform: rotate(0deg); }
+  to { transform: rotate(360deg); }
+}
+
+// 渐入动画
 @keyframes fadeIn {
   from { opacity: 0; }
   to { opacity: 1; }
 }
 
+// 从下方滑入动画
 @keyframes slideUp {
-  from {
-    opacity: 0;
-    transform: translateY(20px);
-  }
-  to {
-    opacity: 1;
-    transform: translateY(0);
-  }
+  from { opacity: 0; transform: translateY(20px); }
+  to { opacity: 1; transform: translateY(0); }
 }
 
-// 消息发送弹窗
-.message-modal-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  z-index: 2300;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  animation: fadeIn 0.2s ease;
-  pointer-events: auto;
+// 缩放进入动画
+@keyframes scaleIn {
+  from { opacity: 0; transform: scale(0.9); }
+  to { opacity: 1; transform: scale(1); }
 }
 
-.message-modal-box {
-  background: white;
-  border-radius: 16px;
-  width: 90%;
-  max-width: 600px;
-  max-height: 85vh;
-  display: flex;
-  flex-direction: column;
-  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
-  animation: slideUp 0.3s ease;
-  
-  .modal-header {
-    padding: 20px 24px;
-    border-bottom: 1px solid #e5e7eb;
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    
-    h4 {
-      margin: 0;
-      font-size: 18px;
-      font-weight: 600;
-      color: #1f2937;
-    }
-    
-    .close-btn {
-      padding: 4px;
-      background: transparent;
-      border: none;
-      cursor: pointer;
-      color: #6b7280;
-      font-size: 28px;
-      line-height: 1;
-      
-      &:hover {
-        color: #1f2937;
-      }
-    }
-  }
-  
-  .modal-body {
-    flex: 1;
-    overflow-y: auto;
-    padding: 24px;
-    
-    .section-label {
-      display: block;
-      margin-bottom: 12px;
-      font-size: 14px;
-      font-weight: 600;
-      color: #374151;
-    }
-    
-    .stage-info-section {
-      background: #f9fafb;
-      border-radius: 12px;
-      padding: 16px;
-      margin-bottom: 20px;
-      
-      .info-item {
-        display: flex;
-        align-items: center;
-        margin-bottom: 8px;
-        
-        &:last-child {
-          margin-bottom: 0;
-        }
-        
-        .label {
-          font-size: 13px;
-          font-weight: 600;
-          color: #6b7280;
-          width: 60px;
-        }
-        
-        .value {
-          font-size: 14px;
-          color: #1f2937;
-          font-weight: 500;
-        }
-      }
-    }
-    
-    .template-section {
-      margin-bottom: 20px;
-      
-      .template-options {
-        display: flex;
-        flex-direction: column;
-        gap: 8px;
-        
-        .template-option {
-          padding: 12px 16px;
-          background: white;
-          border: 2px solid #e5e7eb;
-          border-radius: 10px;
-          text-align: left;
-          font-size: 14px;
-          line-height: 1.6;
-          color: #374151;
-          cursor: pointer;
-          transition: all 0.2s;
-          
-          &:hover {
-            background: #f9fafb;
-            border-color: #10b981;
-          }
-          
-          &.active {
-            background: #ecfdf5;
-            border-color: #10b981;
-            color: #065f46;
-            font-weight: 500;
-          }
-        }
-      }
-    }
-    
-    .custom-message-section {
-      margin-bottom: 20px;
-      
-      textarea {
-        width: 100%;
-        padding: 12px;
-        border: 2px solid #e5e7eb;
-        border-radius: 10px;
-        font-size: 14px;
-        font-family: inherit;
-        line-height: 1.6;
-        resize: vertical;
-        
-        &:focus {
-          outline: none;
-          border-color: #10b981;
-          box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
-        }
-      }
-      
-      .char-count {
-        margin-top: 4px;
-        font-size: 12px;
-        color: #9ca3af;
-        text-align: right;
-      }
-    }
-    
-    .preview-images-section {
-      margin-bottom: 20px;
-      
-      .preview-images-grid {
-        display: grid;
-        grid-template-columns: repeat(3, 1fr);
-        gap: 8px;
-        
-        .preview-img {
-          width: 100%;
-          aspect-ratio: 1;
-          object-fit: cover;
-          border-radius: 8px;
-          border: 2px solid #e5e7eb;
-        }
-        
-        .more-images {
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          aspect-ratio: 1;
-          background: #f9fafb;
-          border: 2px dashed #d1d5db;
-          border-radius: 8px;
-          font-size: 14px;
-          font-weight: 600;
-          color: #6b7280;
-        }
-      }
-    }
-  }
-  
-  .modal-footer {
-    padding: 16px 24px;
-    border-top: 1px solid #e5e7eb;
-    display: flex;
-    gap: 12px;
-    justify-content: flex-end;
-    
-    button {
-      padding: 10px 24px;
-      border: none;
-      border-radius: 10px;
-      font-size: 14px;
-      font-weight: 600;
-      cursor: pointer;
-      transition: all 0.2s;
-      display: flex;
-      align-items: center;
-      gap: 8px;
-      
-      &:disabled {
-        opacity: 0.5;
-        cursor: not-allowed;
-      }
-    }
-    
-    .btn-cancel {
-      background: white;
-      color: #6b7280;
-      border: 2px solid #d1d5db;
-      
-      &:hover:not(:disabled) {
-        background: #f9fafb;
-        border-color: #9ca3af;
-      }
-    }
-    
-    .btn-send {
-      background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-      color: white;
-      
-      &:hover:not(:disabled) {
-        background: linear-gradient(135deg, #059669 0%, #047857 100%);
-        box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
-      }
-      
-      .spinner-small {
-        width: 16px;
-        height: 16px;
-        border: 2px solid rgba(255, 255, 255, 0.3);
-        border-top-color: white;
-        border-radius: 50%;
-        animation: spin 0.6s linear infinite;
-      }
-    }
-  }
+// 🆕 空间拖拽动画
+@keyframes spaceOverlayFadeIn {
+  from { opacity: 0; backdrop-filter: blur(0px); }
+  to { opacity: 1; backdrop-filter: blur(8px); }
+}
 
-  // ==================== 🔥 企业微信端响应式适配 ====================
-  @media screen and (max-width: 768px) {
-    padding: 12px;
-    
-    // 工具栏优化
-    .revision-toolbar {
-      gap: 8px;
-      margin-bottom: 12px;
-      
-      button {
-        padding: 8px 12px;
-        font-size: 13px;
-        
-        svg {
-          width: 16px;
-          height: 16px;
-        }
-        
-        span {
-          display: none; // 隐藏文字,只显示图标
-        }
-      }
-      
-      .btn-view-revisions {
-        .task-count-badge {
-          top: -4px;
-          right: -4px;
-          min-width: 18px;
-          height: 18px;
-          font-size: 10px;
-        }
-      }
-    }
-    
-    // 空间卡片优化
-    .spaces-list-section {
-      gap: 16px;
-      
-      .space-card {
-        border-radius: 12px;
-        
-        .space-header {
-          flex-direction: column;
-          gap: 12px;
-          padding: 12px 16px;
-          align-items: stretch;
-          
-          &::before {
-            height: 3px;
-          }
-          
-          // 空间名称区域
-          .space-name-section {
-            flex-direction: row;
-            justify-content: space-between;
-            min-width: auto;
-            font-size: 16px;
-            padding-right: 0;
-            border-right: none;
-            border-bottom: 1px solid #e2e8f0;
-            padding-bottom: 8px;
-            
-            .completion-badge {
-              padding: 3px 8px;
-              font-size: 12px;
-              border-radius: 10px;
-            }
-          }
-          
-          // 四个阶段名称改为2x2网格
-          .stage-names-row {
-            grid-template-columns: repeat(2, 1fr);
-            gap: 8px;
-            padding: 0;
-            
-            .stage-name-item {
-              padding: 8px 12px;
-              border-radius: 8px;
-              
-              &::after {
-                height: 2px;
-              }
-              
-              .stage-label {
-                font-size: 13px;
-              }
-              
-              .mini-badge {
-                min-width: 20px;
-                height: 20px;
-                padding: 0 6px;
-                font-size: 11px;
-                border-radius: 10px;
-              }
-            }
-          }
-          
-          // 展开图标
-          .expand-icon {
-            position: absolute;
-            top: 12px;
-            right: 16px;
-            width: 32px;
-            height: 32px;
-            
-            svg {
-              width: 20px;
-              height: 20px;
-            }
-          }
-        }
-        
-        // 空间内容区域优化
-        .space-content {
-          padding: 12px;
-          
-          // 阶段容器改为2列布局
-          .stages-container {
-            grid-template-columns: repeat(2, 1fr);
-            gap: 12px;
-            margin-bottom: 16px;
-            
-            .stage-section {
-              border-radius: 12px;
-              
-              &::before {
-                height: 3px;
-              }
-              
-              .stage-header {
-                padding: 10px 12px;
-                
-                .stage-title {
-                  gap: 6px;
-                  
-                  .stage-name {
-                    font-size: 13px;
-                  }
-                  
-                  .file-count-badge {
-                    min-width: 20px;
-                    height: 20px;
-                    padding: 0 6px;
-                    font-size: 11px;
-                    border-radius: 10px;
-                  }
-                }
-                
-                .view-all-hint {
-                  font-size: 11px;
-                  gap: 4px;
-                  
-                  svg {
-                    width: 14px;
-                    height: 14px;
-                  }
-                }
-              }
-              
-              .stage-body {
-                padding: 12px;
-                min-height: 150px;
-                
-                .upload-zone-compact {
-                  padding: 12px;
-                  gap: 8px;
-                  
-                  .upload-btn-compact {
-                    padding: 10px 16px;
-                    font-size: 12px;
-                    border-radius: 8px;
-                    
-                    svg {
-                      width: 16px;
-                      height: 16px;
-                    }
-                  }
-                  
-                  .upload-hint {
-                    font-size: 11px;
-                  }
-                }
-                
-                // 文件预览网格
-                .files-preview-grid {
-                  grid-template-columns: repeat(2, 1fr);
-                  gap: 8px;
-                  
-                  .file-preview-item {
-                    .file-thumbnail {
-                      height: 80px;
-                      border-radius: 8px;
-                    }
-                    
-                    .file-name {
-                      font-size: 11px;
-                      padding: 4px 6px;
-                    }
-                    
-                    .btn-remove-file {
-                      width: 24px;
-                      height: 24px;
-                      top: 4px;
-                      right: 4px;
-                      
-                      svg {
-                        width: 14px;
-                        height: 14px;
-                      }
-                    }
-                  }
-                }
-                
-                // 加载状态
-                .stage-uploading {
-                  padding: 12px;
-                  
-                  .uploading-spinner {
-                    width: 32px;
-                    height: 32px;
-                    border-width: 3px;
-                  }
-                  
-                  p {
-                    font-size: 12px;
-                  }
-                }
-              }
-            }
-          }
-          
-          // 空间拖拽提示
-          .space-drag-overlay {
-            .space-drag-hint {
-              padding: 16px;
-              
-              .space-drag-icon svg {
-                width: 36px;
-                height: 36px;
-              }
-              
-              h3 {
-                font-size: 14px;
-                margin: 8px 0 4px;
-              }
-              
-              p {
-                font-size: 11px;
-              }
-            }
-          }
-        }
-      }
-    }
-    
-    // 确认状态卡片优化
-    .confirmation-card {
-      padding: 12px;
-      border-radius: 12px;
-      
-      .confirmation-header {
-        gap: 8px;
-        
-        .confirmation-icon svg {
-          width: 32px;
-          height: 32px;
-        }
-        
-        .confirmation-text {
-          h3 {
-            font-size: 15px;
-          }
-          
-          p {
-            font-size: 12px;
-          }
-        }
-      }
-    }
-    
-    // 空状态优化
-    .empty-state {
-      padding: 24px 16px;
-      
-      .empty-icon svg {
-        width: 48px;
-        height: 48px;
-      }
-      
-      h3 {
-        font-size: 15px;
-      }
-      
-      p {
-        font-size: 12px;
-      }
-    }
-  }
-  
-  // ==================== 🔥 极窄屏幕(<480px)单列布局 ====================
-  @media screen and (max-width: 480px) {
-    padding: 8px;
-    
-    .spaces-list-section {
-      gap: 12px;
-      
-      .space-card {
-        .space-content {
-          padding: 8px;
-          
-          // 阶段容器改为单列布局
-          .stages-container {
-            grid-template-columns: 1fr;
-            gap: 10px;
-            
-            .stage-section {
-              .stage-body {
-                min-height: 120px;
-                
-                .files-preview-grid {
-                  grid-template-columns: repeat(2, 1fr);
-                  gap: 6px;
-                  
-                  .file-preview-item {
-                    .file-thumbnail {
-                      height: 70px;
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
+@keyframes spaceHintBounce {
+  from { opacity: 0; transform: scale(0.8) translateY(20px); }
+  to { opacity: 1; transform: scale(1) translateY(0); }
+}
+
+@keyframes iconPulse {
+  0%, 100% { transform: scale(1); box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4); }
+  50% { transform: scale(1.1); box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6); }
 }

+ 16 - 3
src/modules/project/pages/project-detail/stages/stage-delivery.component.ts

@@ -369,9 +369,22 @@ export class StageDeliveryComponent implements OnInit, OnDestroy {
       // 如果没有currentUser,尝试获取
       if (!this.currentUser && this.cid) {
         console.log('👤 获取当前用户...');
-        // @ts-ignore - WxworkAuth type issue with fmode-ng
-        const wxwork = new WxworkAuth({ cid: this.cid, appId: 'crm' });
-        this.currentUser = await wxwork.currentProfile();
+        try {
+          // @ts-ignore - WxworkAuth type issue with fmode-ng
+          const wxwork = new WxworkAuth({ cid: this.cid, appId: 'crm' });
+          this.currentUser = await wxwork.currentProfile();
+        } catch (e) {
+          console.error('⚠️ WxworkAuth获取用户失败,尝试使用Parse.User.current()或忽略:', e);
+          // 尝试降级获取
+          try {
+            const user = Parse.User.current();
+            if (user) {
+              this.currentUser = await (user as any).fetch();
+            }
+          } catch (ex) {
+            console.warn('无法获取当前用户');
+          }
+        }
 
         const role = this.currentUser?.get('roleName') || '';
         // ⭐ 修复:使用模糊匹配判断权限(与订单分配阶段对齐)

+ 338 - 0
src/test/delivery-design-cards.html

@@ -0,0 +1,338 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>交付执行 - 方案A:空间进度卡片</title>
+    <style>
+        :root {
+            --primary: #6366f1;
+            --primary-light: #e0e7ff;
+            --success: #10b981;
+            --success-light: #d1fae5;
+            --warning: #f59e0b;
+            --warning-light: #fef3c7;
+            --gray-50: #f9fafb;
+            --gray-100: #f3f4f6;
+            --gray-200: #e5e7eb;
+            --gray-500: #6b7280;
+            --gray-700: #374151;
+            --gray-900: #111827;
+        }
+
+        * { box-sizing: border-box; margin: 0; padding: 0; }
+        body {
+            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+            background-color: #f3f4f6;
+            color: var(--gray-900);
+            padding: 20px;
+        }
+
+        .container {
+            max-width: 1200px;
+            margin: 0 auto;
+        }
+
+        .header {
+            margin-bottom: 24px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+
+        .header h1 { font-size: 24px; font-weight: 700; }
+        .header-stats { display: flex; gap: 16px; }
+        .stat-item {
+            background: white;
+            padding: 8px 16px;
+            border-radius: 8px;
+            box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+            font-size: 14px;
+            color: var(--gray-500);
+        }
+        .stat-value { font-weight: 700; color: var(--primary); margin-left: 4px; }
+
+        /* Space List */
+        .space-list {
+            display: flex;
+            flex-direction: column;
+            gap: 16px;
+        }
+
+        /* Space Card */
+        .space-card {
+            background: white;
+            border-radius: 12px;
+            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+            overflow: hidden;
+            border: 1px solid var(--gray-200);
+        }
+
+        .space-header {
+            padding: 16px 24px;
+            background: linear-gradient(to right, #fff, var(--gray-50));
+            border-bottom: 1px solid var(--gray-200);
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+
+        .space-info { display: flex; align-items: center; gap: 12px; }
+        .space-name { font-size: 18px; font-weight: 600; }
+        .space-meta { color: var(--gray-500); font-size: 13px; }
+        
+        .progress-bar-container {
+            width: 200px;
+            height: 8px;
+            background: var(--gray-200);
+            border-radius: 4px;
+            overflow: hidden;
+        }
+        .progress-bar {
+            height: 100%;
+            background: var(--success);
+            width: 50%; /* Demo value */
+        }
+
+        .space-body {
+            padding: 20px 24px;
+            display: grid;
+            grid-template-columns: repeat(4, 1fr);
+            gap: 20px;
+        }
+
+        /* Stage Column */
+        .stage-col {
+            display: flex;
+            flex-direction: column;
+            gap: 12px;
+        }
+
+        .stage-header-text {
+            font-size: 14px;
+            font-weight: 600;
+            color: var(--gray-700);
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+        .file-count {
+            font-size: 12px;
+            padding: 2px 8px;
+            background: var(--gray-100);
+            border-radius: 12px;
+            color: var(--gray-500);
+        }
+
+        /* Stage Box States */
+        .stage-box {
+            border: 2px dashed var(--gray-200);
+            border-radius: 8px;
+            min-height: 120px;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            transition: all 0.2s;
+            position: relative;
+            background: var(--gray-50);
+        }
+
+        .stage-box:hover {
+            border-color: var(--primary);
+            background: var(--primary-light);
+            cursor: pointer;
+        }
+
+        /* State: Empty */
+        .stage-box.empty {
+            color: var(--gray-500);
+        }
+        .upload-hint { font-size: 13px; margin-top: 8px; }
+        .icon-upload { font-size: 24px; color: var(--gray-400); }
+
+        /* State: Has Files */
+        .stage-box.filled {
+            border-style: solid;
+            border-color: var(--gray-200);
+            background: white;
+            padding: 8px;
+            display: grid;
+            grid-template-columns: repeat(2, 1fr);
+            grid-template-rows: repeat(2, 1fr);
+            gap: 4px;
+            align-content: start;
+            justify-items: stretch;
+        }
+        
+        .stage-box.filled img {
+            width: 100%;
+            height: 50px;
+            object-fit: cover;
+            border-radius: 4px;
+        }
+
+        .add-more-btn {
+            position: absolute;
+            bottom: 8px;
+            right: 8px;
+            background: rgba(255,255,255,0.9);
+            border: 1px solid var(--gray-200);
+            border-radius: 4px;
+            padding: 4px 8px;
+            font-size: 12px;
+            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
+        }
+
+        /* State: Completed/Verified */
+        .stage-status {
+            margin-top: 4px;
+            font-size: 12px;
+            text-align: center;
+        }
+        .status-tag {
+            display: inline-block;
+            padding: 2px 6px;
+            border-radius: 4px;
+        }
+        .status-pending { color: var(--warning); background: var(--warning-light); }
+        .status-done { color: var(--success); background: var(--success-light); }
+        
+        /* Drag Overlay Mock */
+        .drag-overlay {
+            position: absolute;
+            inset: 0;
+            background: rgba(99, 102, 241, 0.1);
+            border: 2px solid var(--primary);
+            border-radius: 8px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: var(--primary);
+            font-weight: 600;
+            opacity: 0;
+            pointer-events: none;
+        }
+        .stage-box:hover .drag-overlay { opacity: 1; }
+
+        @media (max-width: 768px) {
+            .space-body {
+                grid-template-columns: 1fr;
+            }
+        }
+    </style>
+</head>
+<body>
+
+<div class="container">
+    <div class="header">
+        <h1>交付执行看板</h1>
+        <div class="header-stats">
+            <div class="stat-item">总空间 <span class="stat-value">4</span></div>
+            <div class="stat-item">整体进度 <span class="stat-value">35%</span></div>
+        </div>
+    </div>
+
+    <div class="space-list">
+        
+        <!-- Space 1: Active -->
+        <div class="space-card">
+            <div class="space-header">
+                <div class="space-info">
+                    <span class="space-name">客厅 (Living Room)</span>
+                    <span class="space-meta">35㎡ · 现代简约</span>
+                </div>
+                <div class="progress-bar-container">
+                    <div class="progress-bar" style="width: 50%"></div>
+                </div>
+            </div>
+            <div class="space-body">
+                <!-- Stage 1: Verified -->
+                <div class="stage-col">
+                    <div class="stage-header-text">白模阶段 <span class="file-count">4</span></div>
+                    <div class="stage-box filled">
+                        <img src="https://placehold.co/100x100/e0e7ff/6366f1?text=WM1" alt="thumb">
+                        <img src="https://placehold.co/100x100/e0e7ff/6366f1?text=WM2" alt="thumb">
+                        <img src="https://placehold.co/100x100/e0e7ff/6366f1?text=WM3" alt="thumb">
+                        <div style="background:#f3f4f6;border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:12px;">+1</div>
+                    </div>
+                    <div class="stage-status"><span class="status-tag status-done">✓ 已确认</span></div>
+                </div>
+
+                <!-- Stage 2: In Progress -->
+                <div class="stage-col">
+                    <div class="stage-header-text">软装阶段 <span class="file-count">2</span></div>
+                    <div class="stage-box filled">
+                        <img src="https://placehold.co/100x100/fce7f3/ec4899?text=SD1" alt="thumb">
+                        <img src="https://placehold.co/100x100/fce7f3/ec4899?text=SD2" alt="thumb">
+                        <div class="drag-overlay">拖拽上传</div>
+                    </div>
+                    <div class="stage-status"><span class="status-tag status-pending">● 进行中</span></div>
+                </div>
+
+                <!-- Stage 3: Empty (Next) -->
+                <div class="stage-col">
+                    <div class="stage-header-text">渲染阶段 <span class="file-count">0</span></div>
+                    <div class="stage-box empty">
+                        <span class="icon-upload">📷</span>
+                        <span class="upload-hint">点击或拖拽上传</span>
+                    </div>
+                    <div class="stage-status"><span style="color:#9ca3af;font-size:12px;">未开始</span></div>
+                </div>
+
+                <!-- Stage 4: Empty -->
+                <div class="stage-col">
+                    <div class="stage-header-text">后期阶段 <span class="file-count">0</span></div>
+                    <div class="stage-box empty">
+                        <span class="icon-upload">✨</span>
+                        <span class="upload-hint">等待渲染完成</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- Space 2: Empty -->
+        <div class="space-card">
+            <div class="space-header">
+                <div class="space-info">
+                    <span class="space-name">主卧 (Master Bedroom)</span>
+                    <span class="space-meta">22㎡ · 现代简约</span>
+                </div>
+                <div class="progress-bar-container">
+                    <div class="progress-bar" style="width: 0%"></div>
+                </div>
+            </div>
+            <div class="space-body">
+                <div class="stage-col">
+                    <div class="stage-header-text">白模阶段 <span class="file-count">0</span></div>
+                    <div class="stage-box empty">
+                        <span class="icon-upload">🧊</span>
+                        <span class="upload-hint">上传白模文件</span>
+                    </div>
+                </div>
+                <div class="stage-col">
+                    <div class="stage-header-text">软装阶段 <span class="file-count">0</span></div>
+                    <div class="stage-box empty" style="opacity:0.5">
+                        <span class="upload-hint">待白模确认</span>
+                    </div>
+                </div>
+                <div class="stage-col">
+                    <div class="stage-header-text">渲染阶段 <span class="file-count">0</span></div>
+                    <div class="stage-box empty" style="opacity:0.5">
+                        <span class="upload-hint">待软装确认</span>
+                    </div>
+                </div>
+                <div class="stage-col">
+                    <div class="stage-header-text">后期阶段 <span class="file-count">0</span></div>
+                    <div class="stage-box empty" style="opacity:0.5">
+                        <span class="upload-hint">待渲染确认</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+    </div>
+</div>
+
+</body>
+</html>

+ 255 - 0
src/test/delivery-design-matrix.html

@@ -0,0 +1,255 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>交付执行 - 方案B:矩阵表格视图</title>
+    <style>
+        :root {
+            --primary: #4f46e5;
+            --gray-100: #f3f4f6;
+            --gray-200: #e5e7eb;
+            --gray-300: #d1d5db;
+            --gray-600: #4b5563;
+            --gray-900: #111827;
+        }
+        body {
+            font-family: sans-serif;
+            background: #f9fafb;
+            padding: 40px;
+            color: var(--gray-900);
+        }
+        .container {
+            max-width: 1200px;
+            margin: 0 auto;
+            background: white;
+            border-radius: 16px;
+            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+            overflow: hidden;
+        }
+        .header {
+            padding: 24px;
+            border-bottom: 1px solid var(--gray-200);
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+        }
+        .table-wrapper {
+            width: 100%;
+            overflow-x: auto;
+        }
+        table {
+            width: 100%;
+            border-collapse: collapse;
+            min-width: 800px;
+        }
+        th {
+            text-align: left;
+            padding: 16px 24px;
+            background: var(--gray-100);
+            font-weight: 600;
+            font-size: 14px;
+            color: var(--gray-600);
+        }
+        td {
+            padding: 16px 24px;
+            border-top: 1px solid var(--gray-200);
+            vertical-align: top;
+        }
+        
+        /* Space Row Header */
+        .space-cell {
+            width: 200px;
+        }
+        .space-name { font-weight: 700; font-size: 16px; display: block; }
+        .space-meta { font-size: 13px; color: #9ca3af; margin-top: 4px; }
+
+        /* Stage Cells */
+        .stage-cell {
+            width: 200px;
+            position: relative;
+        }
+        
+        .cell-content {
+            border: 1px solid transparent;
+            border-radius: 8px;
+            padding: 12px;
+            transition: all 0.2s;
+            min-height: 80px;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+        }
+        
+        /* Hover State */
+        .cell-content:hover {
+            background: #feffff;
+            border-color: var(--primary);
+            box-shadow: 0 4px 12px rgba(0,0,0,0.05);
+        }
+        
+        /* Status Indicators */
+        .status-dot {
+            width: 8px;
+            height: 8px;
+            border-radius: 50%;
+            display: inline-block;
+            margin-right: 6px;
+        }
+        .dot-gray { background: #d1d5db; }
+        .dot-green { background: #10b981; }
+        .dot-blue { background: #3b82f6; }
+
+        .status-text { font-size: 13px; font-weight: 500; }
+        
+        /* File Preview in Cell */
+        .file-preview-row {
+            display: flex;
+            gap: 4px;
+            margin-top: 8px;
+        }
+        .file-thumb {
+            width: 32px;
+            height: 32px;
+            border-radius: 4px;
+            object-fit: cover;
+            background: #e5e7eb;
+        }
+        .more-files {
+            width: 32px;
+            height: 32px;
+            border-radius: 4px;
+            background: #f3f4f6;
+            font-size: 10px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: #6b7280;
+        }
+
+        /* Action Buttons (Show on Hover) */
+        .cell-actions {
+            margin-top: 8px;
+            display: none;
+        }
+        .cell-content:hover .cell-actions {
+            display: flex;
+            gap: 8px;
+        }
+        
+        .btn-xs {
+            padding: 4px 8px;
+            font-size: 12px;
+            border-radius: 4px;
+            border: 1px solid var(--gray-300);
+            background: white;
+            cursor: pointer;
+        }
+        .btn-primary-xs {
+            background: var(--primary);
+            color: white;
+            border: none;
+        }
+
+        /* Empty State */
+        .empty-state {
+            text-align: center;
+            color: #9ca3af;
+            font-size: 13px;
+        }
+    </style>
+</head>
+<body>
+
+<div class="container">
+    <div class="header">
+        <h2>交付进度矩阵</h2>
+        <button class="btn-xs" style="padding: 8px 16px;">批量导出</button>
+    </div>
+    <div class="table-wrapper">
+        <table>
+            <thead>
+                <tr>
+                    <th>空间名称</th>
+                    <th>白模 (White Model)</th>
+                    <th>软装 (Soft Decor)</th>
+                    <th>渲染 (Rendering)</th>
+                    <th>后期 (Post Process)</th>
+                </tr>
+            </thead>
+            <tbody>
+                <!-- Row 1 -->
+                <tr>
+                    <td class="space-cell">
+                        <span class="space-name">客厅</span>
+                        <span class="space-meta">Living Room</span>
+                    </td>
+                    <td class="stage-cell">
+                        <div class="cell-content">
+                            <div><span class="status-dot dot-green"></span><span class="status-text">已确认 (4)</span></div>
+                            <div class="file-preview-row">
+                                <img src="https://placehold.co/40" class="file-thumb">
+                                <img src="https://placehold.co/40" class="file-thumb">
+                                <span class="more-files">+2</span>
+                            </div>
+                            <div class="cell-actions">
+                                <button class="btn-xs">查看</button>
+                                <button class="btn-xs">补传</button>
+                            </div>
+                        </div>
+                    </td>
+                    <td class="stage-cell">
+                        <div class="cell-content">
+                            <div><span class="status-dot dot-blue"></span><span class="status-text">待审核 (2)</span></div>
+                            <div class="file-preview-row">
+                                <img src="https://placehold.co/40" class="file-thumb">
+                                <img src="https://placehold.co/40" class="file-thumb">
+                            </div>
+                            <div class="cell-actions">
+                                <button class="btn-xs">查看</button>
+                                <button class="btn-xs btn-primary-xs">上传</button>
+                            </div>
+                        </div>
+                    </td>
+                    <td class="stage-cell">
+                        <div class="cell-content">
+                            <div class="empty-state">
+                                <div>- 暂无文件 -</div>
+                            </div>
+                            <div class="cell-actions" style="justify-content: center;">
+                                <button class="btn-xs btn-primary-xs">上传渲染图</button>
+                            </div>
+                        </div>
+                    </td>
+                    <td class="stage-cell">
+                        <div class="cell-content">
+                             <div class="empty-state">-</div>
+                        </div>
+                    </td>
+                </tr>
+                
+                <!-- Row 2 -->
+                <tr>
+                    <td class="space-cell">
+                        <span class="space-name">主卧</span>
+                        <span class="space-meta">Master Bedroom</span>
+                    </td>
+                    <td class="stage-cell">
+                        <div class="cell-content">
+                            <div class="empty-state">未开始</div>
+                            <div class="cell-actions" style="justify-content: center;">
+                                <button class="btn-xs btn-primary-xs">上传白模</button>
+                            </div>
+                        </div>
+                    </td>
+                    <td class="stage-cell"><div class="cell-content"><div class="empty-state">-</div></div></td>
+                    <td class="stage-cell"><div class="cell-content"><div class="empty-state">-</div></div></td>
+                    <td class="stage-cell"><div class="cell-content"><div class="empty-state">-</div></div></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+</body>
+</html>

+ 199 - 0
src/test/delivery-design-tasks.html

@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>交付执行 - 方案C:任务清单视图</title>
+    <style>
+        :root {
+            --primary: #3b82f6;
+            --bg: #f8fafc;
+            --card-bg: #ffffff;
+            --text-main: #1e293b;
+            --text-sub: #64748b;
+            --border: #e2e8f0;
+        }
+        body {
+            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+            background: var(--bg);
+            padding: 40px 20px;
+            color: var(--text-main);
+        }
+        .layout {
+            max-width: 800px;
+            margin: 0 auto;
+            display: grid;
+            gap: 32px;
+        }
+
+        .section-title {
+            font-size: 18px;
+            font-weight: 700;
+            margin-bottom: 16px;
+            display: flex;
+            align-items: center;
+            gap: 8px;
+        }
+        .badge {
+            background: #ef4444;
+            color: white;
+            font-size: 12px;
+            padding: 2px 8px;
+            border-radius: 10px;
+        }
+
+        /* Task Card */
+        .task-card {
+            background: var(--card-bg);
+            border: 1px solid var(--border);
+            border-radius: 12px;
+            padding: 16px 20px;
+            margin-bottom: 12px;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            transition: transform 0.2s, box-shadow 0.2s;
+        }
+        .task-card:hover {
+            transform: translateY(-2px);
+            box-shadow: 0 4px 12px rgba(0,0,0,0.05);
+            border-color: var(--primary);
+        }
+
+        .task-left {
+            display: flex;
+            align-items: center;
+            gap: 16px;
+        }
+        .task-icon {
+            width: 40px;
+            height: 40px;
+            background: #eff6ff;
+            color: var(--primary);
+            border-radius: 8px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-size: 20px;
+        }
+        .task-info h4 {
+            margin: 0;
+            font-size: 16px;
+            font-weight: 600;
+        }
+        .task-info p {
+            margin: 4px 0 0;
+            font-size: 14px;
+            color: var(--text-sub);
+        }
+
+        .task-actions {
+            display: flex;
+            gap: 12px;
+        }
+        .btn {
+            padding: 8px 16px;
+            border-radius: 6px;
+            font-size: 14px;
+            font-weight: 500;
+            cursor: pointer;
+            border: none;
+            display: flex;
+            align-items: center;
+            gap: 6px;
+        }
+        .btn-primary {
+            background: var(--primary);
+            color: white;
+        }
+        .btn-primary:hover { background: #2563eb; }
+        
+        .btn-outline {
+            background: transparent;
+            border: 1px solid var(--border);
+            color: var(--text-sub);
+        }
+        .btn-outline:hover { border-color: var(--text-sub); color: var(--text-main); }
+
+        /* Section: Completed */
+        .completed-section { opacity: 0.7; }
+        .completed-section .task-card { background: #f1f5f9; border-color: transparent; }
+        .completed-section .task-icon { background: #dcfce7; color: #166534; }
+
+    </style>
+</head>
+<body>
+
+<div class="layout">
+
+    <!-- Pending Section -->
+    <div>
+        <div class="section-title">
+            待处理任务 <span class="badge">3</span>
+        </div>
+
+        <!-- Task 1 -->
+        <div class="task-card">
+            <div class="task-left">
+                <div class="task-icon">📷</div>
+                <div class="task-info">
+                    <h4>上传渲染图</h4>
+                    <p>客厅 (Living Room) · 渲染阶段</p>
+                </div>
+            </div>
+            <div class="task-actions">
+                <button class="btn btn-primary">📤 立即上传</button>
+            </div>
+        </div>
+
+        <!-- Task 2 -->
+        <div class="task-card">
+            <div class="task-left">
+                <div class="task-icon">🧊</div>
+                <div class="task-info">
+                    <h4>上传白模文件</h4>
+                    <p>主卧 (Master Bedroom) · 白模阶段</p>
+                </div>
+            </div>
+            <div class="task-actions">
+                <button class="btn btn-primary">📤 立即上传</button>
+            </div>
+        </div>
+
+         <!-- Task 3 -->
+         <div class="task-card">
+            <div class="task-left">
+                <div class="task-icon">✨</div>
+                <div class="task-info">
+                    <h4>确认后期图</h4>
+                    <p>餐厅 (Dining Room) · 后期阶段</p>
+                </div>
+            </div>
+            <div class="task-actions">
+                <button class="btn btn-outline">👀 查看详情</button>
+            </div>
+        </div>
+    </div>
+
+    <!-- Completed Section -->
+    <div class="completed-section">
+        <div class="section-title">已完成</div>
+
+        <div class="task-card">
+            <div class="task-left">
+                <div class="task-icon">✓</div>
+                <div class="task-info">
+                    <h4 style="text-decoration: line-through;">上传白模文件</h4>
+                    <p>客厅 (Living Room) · 白模阶段 · 已确认</p>
+                </div>
+            </div>
+            <div class="task-actions">
+                <button class="btn btn-outline">查看文件</button>
+            </div>
+        </div>
+    </div>
+
+</div>
+
+</body>
+</html>

+ 186 - 0
src/test/sidebar-v2-compact.html

@@ -0,0 +1,186 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>侧边栏 - 方案C:极简状态条</title>
+    <style>
+        body {
+            font-family: sans-serif;
+            background: #f8fafc;
+            margin: 0; padding: 12px;
+            max-width: 400px;
+            margin: 0 auto;
+            border: 1px solid #eee;
+        }
+        
+        .space-block {
+            background: white;
+            border-radius: 8px;
+            padding: 12px;
+            margin-bottom: 12px;
+            box-shadow: 0 1px 2px rgba(0,0,0,0.05);
+        }
+        
+        .space-head {
+            font-weight: bold;
+            margin-bottom: 12px;
+            font-size: 15px;
+            display: flex;
+            justify-content: space-between;
+        }
+        
+        /* Compact 4-Step Bar */
+        .status-bar-container {
+            display: flex;
+            gap: 8px;
+        }
+        
+        .status-pill {
+            flex: 1;
+            background: #f1f5f9;
+            border-radius: 6px;
+            padding: 8px 4px;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            font-size: 11px;
+            color: #64748b;
+            cursor: pointer;
+            border: 1px solid transparent;
+            position: relative;
+        }
+        
+        .status-pill:hover {
+            background: #eef2ff;
+            color: #4f46e5;
+        }
+        
+        .status-pill.done {
+            background: #ecfdf5;
+            color: #059669;
+            border-color: #a7f3d0;
+        }
+        
+        .status-pill.active {
+            background: white;
+            border-color: #6366f1;
+            color: #6366f1;
+            box-shadow: 0 2px 4px rgba(99,102,241,0.1);
+        }
+        
+        .pill-icon { font-size: 16px; margin-bottom: 2px; }
+        
+        .count-bubble {
+            position: absolute;
+            top: -4px; right: -4px;
+            background: #ef4444;
+            color: white;
+            font-size: 9px;
+            width: 14px; height: 14px;
+            border-radius: 50%;
+            display: flex; align-items: center; justify-content: center;
+        }
+
+        /* Expanded Panel for Active Stage */
+        .active-stage-panel {
+            margin-top: 12px;
+            border-top: 1px dashed #e2e8f0;
+            padding-top: 12px;
+        }
+        
+        .panel-header {
+            font-size: 13px;
+            color: #475569;
+            margin-bottom: 8px;
+            font-weight: 600;
+            display: flex;
+            justify-content: space-between;
+        }
+        
+        .upload-box-rect {
+            border: 2px dashed #cbd5e1;
+            border-radius: 6px;
+            height: 60px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: #94a3b8;
+            font-size: 12px;
+            gap: 6px;
+            cursor: pointer;
+        }
+        .upload-box-rect:hover {
+            border-color: #6366f1;
+            color: #6366f1;
+            background: #eef2ff;
+        }
+
+    </style>
+</head>
+<body>
+
+<div class="space-block">
+    <div class="space-head">
+        <span>客厅</span>
+        <span style="color:#999;font-weight:normal;font-size:12px;">35㎡</span>
+    </div>
+    
+    <!-- 4 Steps Horizontal -->
+    <div class="status-bar-container">
+        <div class="status-pill done">
+            <span class="pill-icon">🧊</span>
+            白模
+            <div class="count-bubble" style="background:#10b981">4</div>
+        </div>
+        <div class="status-pill active">
+            <span class="pill-icon">🛋️</span>
+            软装
+            <div class="count-bubble">0</div>
+        </div>
+        <div class="status-pill">
+            <span class="pill-icon">📷</span>
+            渲染
+        </div>
+        <div class="status-pill">
+            <span class="pill-icon">✨</span>
+            后期
+        </div>
+    </div>
+
+    <!-- Active Panel (shows because Soft Decor is clicked) -->
+    <div class="active-stage-panel">
+        <div class="panel-header">软装阶段 - 待上传</div>
+        <div class="upload-box-rect">
+            <span>📤 点击上传软装方案</span>
+        </div>
+    </div>
+</div>
+
+<div class="space-block">
+    <div class="space-head">
+        <span>主卧</span>
+    </div>
+    <div class="status-bar-container">
+        <div class="status-pill">
+            <span class="pill-icon">🧊</span>
+            白模
+        </div>
+        <div class="status-pill">
+            <span class="pill-icon">🛋️</span>
+            软装
+        </div>
+        <div class="status-pill">
+            <span class="pill-icon">📷</span>
+            渲染
+        </div>
+        <div class="status-pill">
+            <span class="pill-icon">✨</span>
+            后期
+        </div>
+    </div>
+</div>
+
+</body>
+</html>

+ 288 - 0
src/test/sidebar-v2-grid.html

@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>侧边栏 - 方案A:智能网格视图</title>
+    <style>
+        :root {
+            --primary: #6366f1;
+            --primary-bg: #e0e7ff;
+            --success: #10b981;
+            --text-main: #1f2937;
+            --text-sub: #6b7280;
+            --border: #e5e7eb;
+            --bg: #f3f4f6;
+        }
+        body {
+            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+            background-color: #eef0f4;
+            margin: 0;
+            padding: 0;
+            /* 模拟企业微信侧边栏宽度 */
+            max-width: 400px;
+            margin: 0 auto;
+            min-height: 100vh;
+            border-left: 1px solid #ddd;
+            border-right: 1px solid #ddd;
+        }
+
+        /* 模拟顶部导航 */
+        .mock-header {
+            background: white;
+            padding: 12px 16px;
+            border-bottom: 1px solid var(--border);
+            position: sticky;
+            top: 0;
+            z-index: 10;
+        }
+        .stage-stepper {
+            display: flex;
+            justify-content: space-between;
+            font-size: 12px;
+            color: var(--text-sub);
+            margin-bottom: 8px;
+        }
+        .step { position: relative; text-align: center; }
+        .step.active { color: var(--primary); font-weight: 600; }
+        .step-circle { 
+            width: 20px; height: 20px; background: #ddd; border-radius: 50%; margin: 0 auto 4px; 
+            display: flex; align-items: center; justify-content: center; font-size: 10px; color: white;
+        }
+        .step.active .step-circle { background: var(--primary); }
+
+        /* Content Area */
+        .content { padding: 12px; display: flex; flex-direction: column; gap: 12px; }
+
+        /* Space Card */
+        .space-card {
+            background: white;
+            border-radius: 12px;
+            padding: 16px;
+            box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+        }
+
+        .space-header {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            margin-bottom: 12px;
+        }
+        .space-title {
+            font-size: 16px;
+            font-weight: 700;
+            color: var(--text-main);
+            display: flex;
+            align-items: center;
+            gap: 6px;
+        }
+        .space-badge {
+            font-size: 10px;
+            padding: 2px 6px;
+            background: var(--primary-bg);
+            color: var(--primary);
+            border-radius: 4px;
+        }
+        .progress-text {
+            font-size: 12px;
+            color: var(--text-sub);
+        }
+
+        /* 2x2 Grid for Stages */
+        .stages-grid {
+            display: grid;
+            grid-template-columns: 1fr 1fr;
+            gap: 10px;
+        }
+
+        .stage-item {
+            background: #f9fafb;
+            border: 1px solid var(--border);
+            border-radius: 8px;
+            padding: 10px;
+            display: flex;
+            flex-direction: column;
+            gap: 8px;
+            position: relative;
+            transition: all 0.2s;
+        }
+
+        /* Empty State / Action Needed */
+        .stage-item.pending {
+            border-style: dashed;
+            border-color: #cbd5e1;
+        }
+        .stage-item.pending:hover {
+            border-color: var(--primary);
+            background: #f5f7ff;
+        }
+
+        /* Completed State */
+        .stage-item.completed {
+            background: white;
+            border-color: var(--success);
+            box-shadow: 0 2px 4px rgba(16,185,129,0.1);
+        }
+
+        .stage-label {
+            font-size: 13px;
+            font-weight: 600;
+            color: var(--text-main);
+            display: flex;
+            justify-content: space-between;
+        }
+        
+        .status-icon {
+            width: 16px; height: 16px;
+            border-radius: 50%;
+            display: flex; align-items: center; justify-content: center;
+            font-size: 10px;
+        }
+        .icon-check { background: var(--success); color: white; }
+        .icon-wait { background: #e5e7eb; color: #9ca3af; }
+
+        /* File Previews within grid */
+        .preview-strip {
+            display: flex;
+            gap: 4px;
+            height: 40px;
+        }
+        .mini-thumb {
+            width: 40px;
+            height: 40px;
+            border-radius: 4px;
+            background: #eee;
+            object-fit: cover;
+        }
+        .add-box {
+            width: 40px;
+            height: 40px;
+            border-radius: 4px;
+            border: 1px dashed #ccc;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: #999;
+            font-size: 18px;
+            cursor: pointer;
+        }
+        .add-box:hover {
+            border-color: var(--primary);
+            color: var(--primary);
+        }
+
+        /* Upload Action Area (for empty stages) */
+        .upload-action {
+            height: 40px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            gap: 6px;
+            font-size: 12px;
+            color: var(--primary);
+            background: white;
+            border-radius: 4px;
+            cursor: pointer;
+            border: 1px solid #e0e7ff;
+        }
+        .upload-action:hover {
+            background: var(--primary);
+            color: white;
+        }
+
+    </style>
+</head>
+<body>
+
+<div class="mock-header">
+    <div class="stage-stepper">
+        <div class="step"><div class="step-circle">1</div>订单</div>
+        <div class="step"><div class="step-circle">2</div>需求</div>
+        <div class="step active"><div class="step-circle">3</div>交付</div>
+        <div class="step"><div class="step-circle">4</div>售后</div>
+    </div>
+</div>
+
+<div class="content">
+    
+    <!-- Space 1: Living Room -->
+    <div class="space-card">
+        <div class="space-header">
+            <div class="space-title">客厅 <span class="space-badge">35㎡</span></div>
+            <span class="progress-text">2/4 完成</span>
+        </div>
+        
+        <div class="stages-grid">
+            <!-- Stage 1: Done -->
+            <div class="stage-item completed">
+                <div class="stage-label">
+                    白模
+                    <span class="status-icon icon-check">✓</span>
+                </div>
+                <div class="preview-strip">
+                    <img src="https://placehold.co/40" class="mini-thumb">
+                    <img src="https://placehold.co/40" class="mini-thumb">
+                    <div class="add-box">+</div>
+                </div>
+            </div>
+
+            <!-- Stage 2: Done -->
+            <div class="stage-item completed">
+                <div class="stage-label">
+                    软装
+                    <span class="status-icon icon-check">✓</span>
+                </div>
+                <div class="preview-strip">
+                    <img src="https://placehold.co/40/pink/white" class="mini-thumb">
+                    <div class="add-box">+</div>
+                </div>
+            </div>
+
+            <!-- Stage 3: Pending (Action Needed) -->
+            <div class="stage-item pending">
+                <div class="stage-label">
+                    渲染
+                    <span class="status-icon icon-wait">!</span>
+                </div>
+                <div class="upload-action">
+                    <span>📤 点击上传</span>
+                </div>
+            </div>
+
+            <!-- Stage 4: Locked/Pending -->
+            <div class="stage-item pending" style="opacity: 0.6;">
+                <div class="stage-label">
+                    后期
+                </div>
+                <div class="upload-action" style="cursor: not-allowed; border: none; background: transparent; color: #999;">
+                    <span>等待渲染</span>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Space 2: Master Bedroom -->
+    <div class="space-card">
+        <div class="space-header">
+            <div class="space-title">主卧 <span class="space-badge">22㎡</span></div>
+            <span class="progress-text">0/4 完成</span>
+        </div>
+        
+        <div class="stages-grid">
+            <div class="stage-item pending">
+                <div class="stage-label">白模</div>
+                <div class="upload-action"><span>📤 上传白模</span></div>
+            </div>
+            <div class="stage-item pending">
+                <div class="stage-label">软装</div>
+                <div class="upload-action"><span>📤 上传软装</span></div>
+            </div>
+            <div class="stage-item pending" style="opacity: 0.5"><div class="stage-label">渲染</div></div>
+            <div class="stage-item pending" style="opacity: 0.5"><div class="stage-label">后期</div></div>
+        </div>
+    </div>
+
+</div>
+
+</body>
+</html>

+ 176 - 0
src/test/sidebar-v2-list.html

@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>侧边栏 - 方案B:垂直列表详情</title>
+    <style>
+        :root {
+            --primary: #6366f1;
+            --text-dark: #111827;
+            --text-gray: #6b7280;
+            --border: #e5e7eb;
+            --bg-card: #ffffff;
+        }
+        body {
+            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+            background-color: #f3f4f6;
+            margin: 0; padding: 0;
+            max-width: 400px;
+            margin: 0 auto;
+            border-left: 1px solid #ddd;
+            border-right: 1px solid #ddd;
+            min-height: 100vh;
+        }
+
+        .space-container {
+            background: white;
+            margin-bottom: 8px;
+            border-bottom: 1px solid var(--border);
+        }
+
+        .space-title-bar {
+            padding: 16px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            font-weight: 700;
+            color: var(--text-dark);
+            background: white;
+            cursor: pointer;
+        }
+        .toggle-icon {
+            transition: transform 0.2s;
+        }
+        .space-title-bar.active .toggle-icon {
+            transform: rotate(180deg);
+        }
+
+        .stage-list {
+            display: block; /* Expanded by default in this demo */
+            padding: 0 16px 16px;
+        }
+
+        .stage-row {
+            display: flex;
+            gap: 12px;
+            padding: 12px 0;
+            border-top: 1px solid #f3f4f6;
+        }
+
+        .stage-icon {
+            width: 36px; height: 36px;
+            background: #f3f4f6;
+            border-radius: 8px;
+            display: flex; align-items: center; justify-content: center;
+            font-size: 18px;
+            flex-shrink: 0;
+        }
+        .stage-info {
+            flex: 1;
+            display: flex;
+            flex-direction: column;
+            gap: 4px;
+        }
+        .stage-name { font-size: 14px; font-weight: 600; }
+        .stage-desc { font-size: 12px; color: var(--text-gray); }
+
+        .stage-action {
+            display: flex;
+            align-items: center;
+        }
+
+        /* Button Styles */
+        .btn-upload {
+            padding: 6px 12px;
+            background: var(--primary);
+            color: white;
+            border: none;
+            border-radius: 6px;
+            font-size: 12px;
+            cursor: pointer;
+        }
+        .btn-view {
+            padding: 6px 12px;
+            background: white;
+            border: 1px solid var(--border);
+            color: var(--text-dark);
+            border-radius: 6px;
+            font-size: 12px;
+            cursor: pointer;
+        }
+
+        /* File Thumbs Row */
+        .file-row {
+            margin-top: 8px;
+            display: flex;
+            gap: 6px;
+            overflow-x: auto;
+            padding-bottom: 4px;
+        }
+        .file-row img {
+            width: 48px; height: 48px; border-radius: 4px; object-fit: cover;
+            border: 1px solid #eee;
+        }
+    </style>
+</head>
+<body>
+
+<!-- Space 1 -->
+<div class="space-container">
+    <div class="space-title-bar active">
+        <span>客厅 (Living Room)</span>
+        <span class="toggle-icon">▼</span>
+    </div>
+    <div class="stage-list">
+        
+        <!-- Stage: White Model -->
+        <div class="stage-row">
+            <div class="stage-icon">🧊</div>
+            <div class="stage-info">
+                <div class="stage-name">白模阶段 <span style="color:green;font-size:10px;background:#d1fae5;padding:1px 4px;border-radius:4px;">已完成</span></div>
+                <div class="file-row">
+                    <img src="https://placehold.co/50">
+                    <img src="https://placehold.co/50">
+                    <img src="https://placehold.co/50">
+                </div>
+            </div>
+            <div class="stage-action">
+                <button class="btn-view">管理</button>
+            </div>
+        </div>
+
+        <!-- Stage: Soft Decor -->
+        <div class="stage-row">
+            <div class="stage-icon">🛋️</div>
+            <div class="stage-info">
+                <div class="stage-name">软装阶段</div>
+                <div class="stage-desc">等待上传软装方案</div>
+            </div>
+            <div class="stage-action">
+                <button class="btn-upload">上传</button>
+            </div>
+        </div>
+
+        <!-- Stage: Rendering -->
+        <div class="stage-row">
+            <div class="stage-icon">📷</div>
+            <div class="stage-info">
+                <div class="stage-name">渲染阶段</div>
+                <div class="stage-desc">未开始</div>
+            </div>
+        </div>
+
+    </div>
+</div>
+
+<!-- Space 2 -->
+<div class="space-container">
+    <div class="space-title-bar">
+        <span>主卧 (Master Bedroom)</span>
+        <span class="toggle-icon" style="transform: rotate(0deg);">▶</span>
+    </div>
+</div>
+
+</body>
+</html>