|
@@ -732,234 +732,235 @@
|
|
<div class="empty-tip" style="color:#888;">暂无色彩分析结果</div>
|
|
<div class="empty-tip" style="color:#888;">暂无色彩分析结果</div>
|
|
}
|
|
}
|
|
</div>
|
|
</div>
|
|
- } @else if (stage === '建模') {
|
|
|
|
- <div class="upload-section">
|
|
|
|
- <div class="upload-header">
|
|
|
|
- <h4>上传白模图片</h4>
|
|
|
|
- <span class="hint">支持:JPG/PNG,不强制4K</span>
|
|
|
|
- </div>
|
|
|
|
- @if (canEditSection('delivery')) {
|
|
|
|
- <div class="upload-dropzone"
|
|
|
|
- (click)="whiteModelImages.length === 0 ? triggerFileInput('whiteModel') : null"
|
|
|
|
- (dragover)="whiteModelImages.length === 0 ? onDragOver($event) : null"
|
|
|
|
- (dragleave)="whiteModelImages.length === 0 ? onDragLeave($event) : null"
|
|
|
|
- (drop)="whiteModelImages.length === 0 ? onFileDrop($event, 'whiteModel') : null"
|
|
|
|
- [class.drag-over]="isDragOver && whiteModelImages.length === 0"
|
|
|
|
- [class.has-images]="whiteModelImages.length > 0">
|
|
|
|
- @if (whiteModelImages.length === 0) {
|
|
|
|
- <div class="upload-icon"></div>
|
|
|
|
- <div class="upload-text">点击此处或拖拽文件到此处上传</div>
|
|
|
|
- <div class="upload-hint">支持 JPG、PNG 格式,单个文件最大 10MB</div>
|
|
|
|
- } @else {
|
|
|
|
- <div class="uploaded-images-grid">
|
|
|
|
- @for (img of whiteModelImages; track img.id) {
|
|
|
|
- <div class="uploaded-image-item" (click)="previewImage(img)">
|
|
|
|
- <img [src]="img.url" [alt]="img.name" />
|
|
|
|
- <div class="image-overlay">
|
|
|
|
- <div class="image-name">{{ img.name }}</div>
|
|
|
|
- <div class="image-actions">
|
|
|
|
- <button class="preview-btn" (click)="$event.stopPropagation(); previewImage(img)">
|
|
|
|
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
- <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
|
|
- <circle cx="12" cy="12" r="3"></circle>
|
|
|
|
- </svg>
|
|
|
|
- </button>
|
|
|
|
- <button class="remove-btn" (click)="$event.stopPropagation(); removeWhiteModelImage(img.id)">
|
|
|
|
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
|
|
+ } @else if (stage === '建模' || stage === '软装' || stage === '渲染') {
|
|
|
|
+ <!-- 横向折叠面板布局 -->
|
|
|
|
+ <div class="delivery-execution-panel">
|
|
|
|
+ <div class="delivery-processes-container">
|
|
|
|
+ @for (process of deliveryProcesses; track process.name) {
|
|
|
|
+ @if ((stage === '建模' && process.type === 'modeling') ||
|
|
|
|
+ (stage === '软装' && process.type === 'softDecor') ||
|
|
|
|
+ (stage === '渲染' && process.type === 'rendering')) {
|
|
|
|
+ <div class="delivery-process-card" [class.expanded]="process.isExpanded">
|
|
|
|
+ <!-- 流程标题 -->
|
|
|
|
+ <div class="process-header" (click)="toggleProcess(process.id)">
|
|
|
|
+ <h4>{{ process.name }}</h4>
|
|
|
|
+ <div class="expand-icon" [class.rotated]="process.isExpanded">
|
|
|
|
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
+ <polyline points="6,9 12,15 18,9"></polyline>
|
|
|
|
+ </svg>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 空间列表 -->
|
|
|
|
+ <div class="spaces-list">
|
|
|
|
+ @for (space of process.spaces; track space.id) {
|
|
|
|
+ <div class="space-item"
|
|
|
|
+ [class.active]="space.isExpanded"
|
|
|
|
+ (click)="toggleSpace(process.id, space.id)">
|
|
|
|
+ <span class="space-name">{{ space.name }}</span>
|
|
|
|
+ @if (canEditSection('delivery')) {
|
|
|
|
+ <button class="remove-space-btn"
|
|
|
|
+ (click)="$event.stopPropagation(); removeSpace(process.id, space.id)"
|
|
|
|
+ title="删除空间">
|
|
|
|
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
</svg>
|
|
</svg>
|
|
</button>
|
|
</button>
|
|
- </div>
|
|
|
|
|
|
+ }
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <div class="add-more-btn" (click)="triggerFileInput('whiteModel')">
|
|
|
|
- <div class="add-icon">+</div>
|
|
|
|
- <div class="add-text">添加更多</div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <input type="file"
|
|
|
|
- id="whiteModelFileInput"
|
|
|
|
- accept="{{allowedImageTypes}}"
|
|
|
|
- multiple
|
|
|
|
- (change)="onWhiteModelSelected($event)"
|
|
|
|
- style="display: none;" />
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <div class="upload-actions">
|
|
|
|
- @if (canEditSection('delivery')) {
|
|
|
|
- <button class="primary-btn" [disabled]="whiteModelImages.length===0" (click)="confirmWhiteModelUpload()">确认上传</button>
|
|
|
|
- }
|
|
|
|
- @if (isTeamLeaderView()) { <button class="secondary-btn" (click)="syncUploadedImages('white')">同步图片信息</button> }
|
|
|
|
- @if (!canEditSection('delivery')) { <span class="desc">只读</span> }
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="model-check-section">
|
|
|
|
- <h4>模型差异检查清单</h4>
|
|
|
|
- <div class="checklist">
|
|
|
|
- @for (item of modelCheckItems; track item.id) {
|
|
|
|
- <div class="checklist-item">
|
|
|
|
- <label class="checklist-label">
|
|
|
|
- <input type="checkbox" class="custom-checkbox" [checked]="item.isPassed" (change)="updateModelCheckItem(item.id, $any($event.target).checked)" [disabled]="!canEditSection('delivery')">
|
|
|
|
- <span class="checklist-text">{{ item.name }}</span>
|
|
|
|
- </label>
|
|
|
|
- <span class="check-status">{{ item.isPassed ? '已通过' : '待处理' }}</span>
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- } @else if (stage === '软装') {
|
|
|
|
- <div class="softdecor-section">
|
|
|
|
- <h4>软装清单素材</h4>
|
|
|
|
- <div class="upload-section">
|
|
|
|
- <div class="upload-header">
|
|
|
|
- <h4>上传软装小图</h4>
|
|
|
|
- <span class="hint">建议 ≤1MB 的 JPG/PNG 小图</span>
|
|
|
|
- </div>
|
|
|
|
- @if (canEditSection('delivery')) {
|
|
|
|
- <div class="upload-dropzone"
|
|
|
|
- (click)="softDecorImages.length === 0 ? triggerFileInput('softDecor') : null"
|
|
|
|
- (dragover)="softDecorImages.length === 0 ? onDragOver($event) : null"
|
|
|
|
- (dragleave)="softDecorImages.length === 0 ? onDragLeave($event) : null"
|
|
|
|
- (drop)="softDecorImages.length === 0 ? onFileDrop($event, 'softDecor') : null"
|
|
|
|
- [class.drag-over]="isDragOver && softDecorImages.length === 0"
|
|
|
|
- [class.has-images]="softDecorImages.length > 0">
|
|
|
|
- @if (softDecorImages.length === 0) {
|
|
|
|
- <div class="upload-icon"></div>
|
|
|
|
- <div class="upload-text">点击此处或拖拽文件到此处上传</div>
|
|
|
|
- <div class="upload-hint">支持 JPG、PNG 格式,建议文件大小 ≤1MB</div>
|
|
|
|
- } @else {
|
|
|
|
- <div class="uploaded-images-grid">
|
|
|
|
- @for (img of softDecorImages; track img.id) {
|
|
|
|
- <div class="uploaded-image-item" (click)="previewImage(img)">
|
|
|
|
- <img [src]="img.url" [alt]="img.name" />
|
|
|
|
- <div class="image-overlay">
|
|
|
|
- <div class="image-name">{{ img.name }}</div>
|
|
|
|
- <div class="image-actions">
|
|
|
|
- <button class="preview-btn" (click)="$event.stopPropagation(); previewImage(img)">
|
|
|
|
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
- <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
|
|
- <circle cx="12" cy="12" r="3"></circle>
|
|
|
|
- </svg>
|
|
|
|
- </button>
|
|
|
|
- <button class="remove-btn" (click)="$event.stopPropagation(); removeSoftDecorImage(img.id)">
|
|
|
|
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
- <line x1="18" y1="6" x2="6" y2="18"></line>
|
|
|
|
- <line x1="6" y1="6" x2="18" y2="18"></line>
|
|
|
|
- </svg>
|
|
|
|
- </button>
|
|
|
|
- </div>
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ <!-- 添加空间按钮 -->
|
|
|
|
+ @if (canEditSection('delivery')) {
|
|
|
|
+ @if (showAddSpaceInput[process.id]) {
|
|
|
|
+ <div class="add-space-input">
|
|
|
|
+ <input type="text"
|
|
|
|
+ [(ngModel)]="newSpaceName[process.id]"
|
|
|
|
+ placeholder="输入空间名称"
|
|
|
|
+ (keyup.enter)="addSpace(process.id)"
|
|
|
|
+ (keyup.escape)="cancelAddSpace(process.id)"
|
|
|
|
+ #spaceInput>
|
|
|
|
+ <button class="confirm-btn" (click)="addSpace(process.id)">确认</button>
|
|
|
|
+ <button class="cancel-btn" (click)="cancelAddSpace(process.id)">取消</button>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
|
|
+ } @else {
|
|
|
|
+ <button class="add-space-btn" (click)="showAddSpaceForm(process.id)">
|
|
|
|
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
+ <line x1="12" y1="5" x2="12" y2="19"></line>
|
|
|
|
+ <line x1="5" y1="12" x2="19" y2="12"></line>
|
|
|
|
+ </svg>
|
|
|
|
+ 添加空间
|
|
|
|
+ </button>
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- <div class="add-more-btn" (click)="triggerFileInput('softDecor')">
|
|
|
|
- <div class="add-icon">+</div>
|
|
|
|
- <div class="add-text">添加更多</div>
|
|
|
|
- </div>
|
|
|
|
</div>
|
|
</div>
|
|
- }
|
|
|
|
- <input type="file"
|
|
|
|
- id="softDecorFileInput"
|
|
|
|
- accept="{{allowedImageTypes}}"
|
|
|
|
- multiple
|
|
|
|
- (change)="onSoftDecorSmallPicsSelected($event)"
|
|
|
|
- style="display: none;" />
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <div class="upload-actions">
|
|
|
|
- @if (canEditSection('delivery')) {
|
|
|
|
- <button class="primary-btn" [disabled]="softDecorImages.length===0" (click)="confirmSoftDecorUpload()">确认上传</button>
|
|
|
|
- }
|
|
|
|
- @if (isTeamLeaderView()) { <button class="secondary-btn" (click)="syncUploadedImages('soft')">同步图片信息</button> }
|
|
|
|
- @if (!canEditSection('delivery')) { <span class="desc">只读</span> }
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- } @else if (stage === '渲染') {
|
|
|
|
- <div class="render-progress-section">
|
|
|
|
- @if (isLoadingRenderProgress) {
|
|
|
|
- <div class="loading-state">
|
|
|
|
- <div class="loading-spinner"></div>
|
|
|
|
- <div>正在加载渲染进度...</div>
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- @if (errorLoadingRenderProgress) {
|
|
|
|
- <div class="error-state">
|
|
|
|
- <div>渲染进度加载失败</div>
|
|
|
|
- <button class="secondary-btn" (click)="retryLoadRenderProgress()">重试</button>
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- @if (!isLoadingRenderProgress && !errorLoadingRenderProgress && renderProgress) {
|
|
|
|
- <div class="progress-info" style="display:flex;gap:16px;align-items:center;margin:12px 0;">
|
|
|
|
- <span>状态:{{ renderProgress.status }}</span>
|
|
|
|
- <span>完成度:{{ renderProgress.completionRate }}%</span>
|
|
|
|
- <span>预计剩余:{{ renderProgress.estimatedTimeRemaining }} 小时</span>
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <div class="upload-section">
|
|
|
|
- <div class="upload-header">
|
|
|
|
- <h4>上传渲染大图</h4>
|
|
|
|
- <span class="hint">需满足4K标准(最长边 ≥ 4000px)</span>
|
|
|
|
- </div>
|
|
|
|
- @if (canEditSection('delivery')) {
|
|
|
|
- <div class="upload-dropzone"
|
|
|
|
- (click)="renderLargeImages.length === 0 ? triggerFileInput('render') : null"
|
|
|
|
- (dragover)="renderLargeImages.length === 0 ? onDragOver($event) : null"
|
|
|
|
- (dragleave)="renderLargeImages.length === 0 ? onDragLeave($event) : null"
|
|
|
|
- (drop)="renderLargeImages.length === 0 ? onFileDrop($event, 'render') : null"
|
|
|
|
- [class.drag-over]="isDragOver && renderLargeImages.length === 0"
|
|
|
|
- [class.has-images]="renderLargeImages.length > 0">
|
|
|
|
- @if (renderLargeImages.length === 0) {
|
|
|
|
- <div class="upload-icon"></div>
|
|
|
|
- <div class="upload-text">点击此处或拖拽文件到此处上传</div>
|
|
|
|
- <div class="upload-hint">支持 JPG、PNG 格式,需满足4K标准(最长边 ≥ 4000px)</div>
|
|
|
|
- } @else {
|
|
|
|
- <div class="uploaded-images-grid">
|
|
|
|
- @for (img of renderLargeImages; track img.id) {
|
|
|
|
- <div class="uploaded-image-item" (click)="previewImage(img)">
|
|
|
|
- <img [src]="img.url" [alt]="img.name" />
|
|
|
|
- <div class="image-overlay">
|
|
|
|
- <div class="image-name">{{ img.name }}</div>
|
|
|
|
- <div class="image-actions">
|
|
|
|
- <button class="preview-btn" (click)="$event.stopPropagation(); previewImage(img)">
|
|
|
|
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
- <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
|
|
- <circle cx="12" cy="12" r="3"></circle>
|
|
|
|
- </svg>
|
|
|
|
- </button>
|
|
|
|
- <button class="remove-btn" (click)="$event.stopPropagation(); removeRenderLargeImage(img.id)">
|
|
|
|
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
- <line x1="18" y1="6" x2="6" y2="18"></line>
|
|
|
|
- <line x1="6" y1="6" x2="18" y2="18"></line>
|
|
|
|
- </svg>
|
|
|
|
- </button>
|
|
|
|
|
|
+
|
|
|
|
+ <!-- 展开的内容区域 -->
|
|
|
|
+ @if (process.isExpanded) {
|
|
|
|
+ <div class="process-content">
|
|
|
|
+ @for (space of process.spaces; track space.id) {
|
|
|
|
+ @if (space.isExpanded) {
|
|
|
|
+ <div class="space-content">
|
|
|
|
+ <div class="space-content-header">
|
|
|
|
+ <h5>{{ space.name }} - {{ process.name }}</h5>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ @if (process.type === 'modeling') {
|
|
|
|
+ <!-- 建模内容 -->
|
|
|
|
+ <div class="modeling-content">
|
|
|
|
+ <div class="upload-section">
|
|
|
|
+ <div class="upload-header">
|
|
|
|
+ <h6>上传白模图片</h6>
|
|
|
|
+ <span class="hint">支持:JPG/PNG,不强制4K</span>
|
|
|
|
+ </div>
|
|
|
|
+ @if (canEditSection('delivery')) {
|
|
|
|
+ <div class="upload-dropzone"
|
|
|
|
+ (click)="!process.content[space.id]?.images || process.content[space.id].images.length === 0 ? triggerSpaceFileInput(process.id, space.id) : null"
|
|
|
|
+ [class.has-images]="(process.content[space.id]?.images?.length || 0) > 0">
|
|
|
|
+ @if (!process.content[space.id]?.images || process.content[space.id].images.length === 0) {
|
|
|
|
+ <div class="upload-icon"></div>
|
|
|
|
+ <div class="upload-text">点击此处上传白模图片</div>
|
|
|
|
+ <div class="upload-hint">支持 JPG、PNG 格式,单个文件最大 10MB</div>
|
|
|
|
+ } @else {
|
|
|
|
+ <div class="uploaded-images-grid">
|
|
|
|
+ @for (img of process.content[space.id].images; track img.id) {
|
|
|
|
+ <div class="uploaded-image-item" (click)="previewImage(img)">
|
|
|
|
+ <img [src]="img.url" [alt]="img.name" />
|
|
|
|
+ <div class="image-overlay">
|
|
|
|
+ <div class="image-name">{{ img.name }}</div>
|
|
|
|
+ <div class="image-actions">
|
|
|
|
+ <button class="preview-btn" (click)="$event.stopPropagation(); previewImage(img)">
|
|
|
|
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
|
|
+ <circle cx="12" cy="12" r="3"></circle>
|
|
|
|
+ </svg>
|
|
|
|
+ </button>
|
|
|
|
+ <button class="remove-btn" (click)="$event.stopPropagation(); removeSpaceImage(process.id, space.id, img.id)">
|
|
|
|
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
+ <line x1="18" y1="6" x2="6" y2="18"></line>
|
|
|
|
+ <line x1="6" y1="6" x2="18" y2="18"></line>
|
|
|
|
+ </svg>
|
|
|
|
+ </button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ <div class="add-more-btn" (click)="triggerSpaceFileInput(process.id, space.id)">
|
|
|
|
+ <div class="add-icon">+</div>
|
|
|
|
+ <div class="add-text">添加更多</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 模型检查清单 -->
|
|
|
|
+ <div class="model-check-section">
|
|
|
|
+ <h6>模型差异检查清单</h6>
|
|
|
|
+ <div class="checklist">
|
|
|
|
+ @for (item of modelCheckItems; track item.id) {
|
|
|
|
+ <div class="checklist-item">
|
|
|
|
+ <label class="checklist-label">
|
|
|
|
+ <input type="checkbox" class="custom-checkbox"
|
|
|
|
+ [checked]="item.isPassed"
|
|
|
|
+ (change)="updateModelCheckItem(item.id, $any($event.target).checked)"
|
|
|
|
+ [disabled]="!canEditSection('delivery')">
|
|
|
|
+ <span class="checklist-text">{{ item.name }}</span>
|
|
|
|
+ </label>
|
|
|
|
+ <span class="check-status">{{ item.isPassed ? '已通过' : '待处理' }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ } @else if (process.type === 'softDecor') {
|
|
|
|
+ <!-- 软装内容 -->
|
|
|
|
+ <div class="softdecor-content">
|
|
|
|
+ <div class="upload-section">
|
|
|
|
+ <div class="upload-header">
|
|
|
|
+ <h6>上传软装小图</h6>
|
|
|
|
+ <span class="hint">建议 ≤1MB 的 JPG/PNG 小图</span>
|
|
|
|
+ </div>
|
|
|
|
+ @if (canEditSection('delivery')) {
|
|
|
|
+ <div class="upload-dropzone"
|
|
|
|
+ (click)="!process.content[space.id]?.images || process.content[space.id].images.length === 0 ? triggerSpaceFileInput(process.id, space.id) : null"
|
|
|
|
+ [class.has-images]="(process.content[space.id]?.images?.length || 0) > 0">
|
|
|
|
+ @if (!process.content[space.id]?.images || process.content[space.id].images.length === 0) {
|
|
|
|
+ <div class="upload-icon"></div>
|
|
|
|
+ <div class="upload-text">点击此处上传软装图片</div>
|
|
|
|
+ <div class="upload-hint">支持 JPG、PNG 格式,建议文件大小 ≤1MB</div>
|
|
|
|
+ } @else {
|
|
|
|
+ <div class="uploaded-images-grid">
|
|
|
|
+ @for (img of process.content[space.id].images; track img.id) {
|
|
|
|
+ <div class="uploaded-image-item" (click)="previewImage(img)">
|
|
|
|
+ <img [src]="img.url" [alt]="img.name" />
|
|
|
|
+ <div class="image-overlay">
|
|
|
|
+ <div class="image-name">{{ img.name }}</div>
|
|
|
|
+ <div class="image-actions">
|
|
|
|
+ <button class="preview-btn" (click)="$event.stopPropagation(); previewImage(img)">
|
|
|
|
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
|
|
+ <circle cx="12" cy="12" r="3"></circle>
|
|
|
|
+ </svg>
|
|
|
|
+ </button>
|
|
|
|
+ <button class="remove-btn" (click)="$event.stopPropagation(); removeSpaceImage(process.id, space.id, img.id)">
|
|
|
|
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
|
|
+ <line x1="18" y1="6" x2="6" y2="18"></line>
|
|
|
|
+ <line x1="6" y1="6" x2="18" y2="18"></line>
|
|
|
|
+ </svg>
|
|
|
|
+ </button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ <div class="add-more-btn" (click)="triggerSpaceFileInput(process.id, space.id)">
|
|
|
|
+ <div class="add-icon">+</div>
|
|
|
|
+ <div class="add-text">添加更多</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ } @else if (process.type === 'rendering') {
|
|
|
|
+ <!-- 渲染内容 -->
|
|
|
|
+ <div class="rendering-content">
|
|
|
|
+ <div class="render-progress-info">
|
|
|
|
+ <h6>渲染进度</h6>
|
|
|
|
+ <div class="progress-details">
|
|
|
|
+ <div class="progress-item">
|
|
|
|
+ <span class="label">状态:</span>
|
|
|
|
+ <span class="value">{{ process.content[space.id]?.status || '待开始' }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="progress-item">
|
|
|
|
+ <span class="label">完成度:</span>
|
|
|
|
+ <span class="value">{{ process.content[space.id]?.progress || 0 }}%</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="progress-item">
|
|
|
|
+ <span class="label">更新时间:</span>
|
|
|
|
+ <span class="value">{{ process.content[space.id]?.lastUpdated || '暂无' }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ @if (process.content[space.id]?.notes) {
|
|
|
|
+ <div class="progress-notes">
|
|
|
|
+ <span class="label">备注:</span>
|
|
|
|
+ <span class="value">{{ process.content[space.id].notes }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ }
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <div class="add-more-btn" (click)="triggerFileInput('render')">
|
|
|
|
- <div class="add-icon">+</div>
|
|
|
|
- <div class="add-text">添加更多</div>
|
|
|
|
|
|
+ }
|
|
|
|
+ }
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <input type="file"
|
|
|
|
- id="renderFileInput"
|
|
|
|
- accept="{{allowedImageTypes}}"
|
|
|
|
- multiple
|
|
|
|
- (change)="onRenderLargePicsSelected($event)"
|
|
|
|
- style="display: none;" />
|
|
|
|
- </div>
|
|
|
|
- }
|
|
|
|
- <div class="upload-actions">
|
|
|
|
- @if (canEditSection('delivery')) {
|
|
|
|
- <button class="primary-btn" [disabled]="renderLargeImages.length===0" (click)="confirmRenderUpload()">确认上传</button>
|
|
|
|
|
|
+ }
|
|
|
|
+ </div>
|
|
}
|
|
}
|
|
- @if (isTeamLeaderView()) { <button class="secondary-btn" (click)="syncUploadedImages('render')">同步图片信息</button> }
|
|
|
|
- @if (!canEditSection('delivery')) { <span class="desc">只读</span> }
|
|
|
|
- </div>
|
|
|
|
|
|
+ }
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
} @else if (stage === '尾款结算') {
|
|
} @else if (stage === '尾款结算') {
|