project-progress-modal.html 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <!-- 弹窗遮罩 -->
  2. <div class="modal-overlay" *ngIf="visible" (click)="onClose()">
  3. <!-- 弹窗内容 -->
  4. <div class="modal-content" (click)="onContentClick($event)">
  5. <!-- 标题栏 -->
  6. <div class="modal-header">
  7. <h2 class="modal-title">
  8. <span class="icon">📊</span>
  9. 项目进度详情
  10. </h2>
  11. <button class="close-btn" (click)="onClose()" aria-label="关闭">
  12. <span>✕</span>
  13. </button>
  14. </div>
  15. <!-- 项目基本信息 -->
  16. <div class="project-info" *ngIf="summary">
  17. <div class="info-row">
  18. <span class="label">项目名称:</span>
  19. <span class="value">{{ summary.projectName }}</span>
  20. </div>
  21. <div class="info-row">
  22. <span class="label">空间总数:</span>
  23. <span class="value">{{ summary.totalSpaces }} 个</span>
  24. </div>
  25. <div class="info-row">
  26. <span class="label">已完成空间:</span>
  27. <span class="value">{{ summary.spacesWithDeliverables }} / {{ summary.totalSpaces }}</span>
  28. </div>
  29. </div>
  30. <!-- 整体进度 -->
  31. <div class="overall-progress" *ngIf="summary">
  32. <div class="progress-header">
  33. <span class="label">整体完成率</span>
  34. <span class="percentage" [style.color]="getOverallProgressColor()">
  35. {{ summary.overallCompletionRate }}%
  36. </span>
  37. <span class="status-badge" [style.background-color]="getOverallProgressColor()">
  38. {{ getOverallStatusLabel() }}
  39. </span>
  40. </div>
  41. <div class="progress-bar-container">
  42. <div class="progress-bar-bg">
  43. <div
  44. class="progress-bar-fill"
  45. [style.width.%]="summary.overallCompletionRate"
  46. [style.background-color]="getOverallProgressColor()">
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. <!-- 文件统计 -->
  52. <div class="file-stats" *ngIf="summary">
  53. <div class="stats-title">交付文件统计</div>
  54. <div class="stats-grid">
  55. <div class="stat-item">
  56. <span class="stat-icon">🏗️</span>
  57. <span class="stat-label">白模</span>
  58. <span class="stat-value">{{ summary.totalByType.whiteModel }}</span>
  59. </div>
  60. <div class="stat-item">
  61. <span class="stat-icon">🎨</span>
  62. <span class="stat-label">软装</span>
  63. <span class="stat-value">{{ summary.totalByType.softDecor }}</span>
  64. </div>
  65. <div class="stat-item">
  66. <span class="stat-icon">🖼️</span>
  67. <span class="stat-label">渲染</span>
  68. <span class="stat-value">{{ summary.totalByType.rendering }}</span>
  69. </div>
  70. <div class="stat-item">
  71. <span class="stat-icon">✨</span>
  72. <span class="stat-label">后期</span>
  73. <span class="stat-value">{{ summary.totalByType.postProcess }}</span>
  74. </div>
  75. </div>
  76. <div class="stats-total">
  77. 总计:<strong>{{ summary.totalDeliverableFiles }}</strong> 个文件
  78. </div>
  79. </div>
  80. <!-- ✅ 应用方案:未完成任务汇总(按设计师分组)- 仅显示当前项目 -->
  81. <div class="incomplete-tasks-summary" *ngIf="summary">
  82. <div class="summary-header">
  83. <div class="summary-title-section">
  84. <span class="summary-icon">⚠️</span>
  85. <h3 class="summary-title">未完成任务汇总</h3>
  86. <span class="summary-badge" *ngIf="hasIncompleteTasks()">{{ getTotalIncompleteTasks() }} 个任务</span>
  87. <span class="summary-badge success" *ngIf="!hasIncompleteTasks()">全部完成</span>
  88. </div>
  89. <div class="summary-subtitle">
  90. 当前项目:{{ summary.projectName }} - 按设计师分组查看未完成任务
  91. </div>
  92. </div>
  93. <!-- 有未完成任务时显示 -->
  94. <div class="designer-tasks-list" *ngIf="hasIncompleteTasks()">
  95. <div
  96. *ngFor="let designerGroup of getIncompleteTasksByDesigner()"
  97. class="designer-group"
  98. [class.unassigned]="designerGroup.designerName === '未分配'">
  99. <div class="designer-header">
  100. <div class="designer-info">
  101. <span class="designer-icon">👤</span>
  102. <span class="designer-name" [class.unassigned-text]="designerGroup.designerName === '未分配'">
  103. {{ designerGroup.designerName }}
  104. </span>
  105. <span class="task-count-badge">{{ designerGroup.taskCount }} 个未完成</span>
  106. </div>
  107. </div>
  108. <div class="tasks-list">
  109. <div
  110. *ngFor="let task of designerGroup.tasks"
  111. class="task-item">
  112. <span class="task-phase-badge" [style.background-color]="getPhaseProgressColor(0)">
  113. {{ task.phaseLabel }}
  114. </span>
  115. <span class="task-space-name">{{ task.spaceName }}</span>
  116. </div>
  117. </div>
  118. </div>
  119. </div>
  120. <!-- 全部完成时显示 -->
  121. <div class="all-completed-message" *ngIf="!hasIncompleteTasks()">
  122. <span class="success-icon-large">✅</span>
  123. <div class="message-content">
  124. <h4>恭喜!所有任务已完成</h4>
  125. <p>该项目所有空间的交付任务均已完成,无需跟进。</p>
  126. </div>
  127. </div>
  128. <div class="summary-footer" *ngIf="getUnassignedTaskCount() > 0">
  129. <span class="warning-icon">⚠️</span>
  130. <span class="warning-text">
  131. 有 {{ getUnassignedTaskCount() }} 个任务未分配负责人,请及时分配
  132. </span>
  133. </div>
  134. </div>
  135. <!-- 各阶段进度详情 -->
  136. <div class="phase-progress" *ngIf="summary">
  137. <div class="section-title">各阶段进度明细</div>
  138. <div class="phase-list">
  139. <div
  140. *ngFor="let phase of getPhases()"
  141. class="phase-item"
  142. [class.expanded]="isPhaseExpanded(phase.name)">
  143. <!-- 阶段概览(可点击展开/收起) -->
  144. <div class="phase-overview" (click)="togglePhase(phase.name)">
  145. <div class="phase-header">
  146. <span class="phase-icon">{{ PHASE_INFO[phase.name].icon }}</span>
  147. <span class="phase-label">{{ phase.info.phaseLabel }}</span>
  148. <span class="phase-progress-badge" [style.background-color]="getPhaseProgressColor(phase.info.completionRate)">
  149. {{ phase.info.completionRate }}%
  150. </span>
  151. <span class="expand-icon">{{ isPhaseExpanded(phase.name) ? '▼' : '▶' }}</span>
  152. </div>
  153. <div class="phase-summary">
  154. <span class="summary-text">
  155. 已完成 {{ phase.info.completedSpaces }} / {{ phase.info.requiredSpaces }} 个空间
  156. ({{ phase.info.totalFiles }} 个文件)
  157. </span>
  158. </div>
  159. <!-- 阶段进度条 -->
  160. <div class="phase-progress-bar">
  161. <div class="progress-bar-bg">
  162. <div
  163. class="progress-bar-fill"
  164. [style.width.%]="phase.info.completionRate"
  165. [style.background-color]="getPhaseProgressColor(phase.info.completionRate)">
  166. </div>
  167. </div>
  168. </div>
  169. </div>
  170. <!-- 未完成空间详情(展开时显示) -->
  171. <div class="phase-details" *ngIf="isPhaseExpanded(phase.name)">
  172. <div class="details-header">
  173. <span class="details-title">未完成空间列表</span>
  174. <span class="details-count">({{ phase.info.incompleteSpaces.length }} 个)</span>
  175. </div>
  176. <div class="incomplete-spaces" *ngIf="phase.info.incompleteSpaces.length > 0">
  177. <div
  178. *ngFor="let space of phase.info.incompleteSpaces"
  179. class="space-item"
  180. [class.no-assignee]="!space.assignee || space.assignee === '未分配'">
  181. <span class="space-icon">📦</span>
  182. <span class="space-name">{{ space.spaceName }}</span>
  183. <!-- ✅ 优化:右侧显示设计师名字 -->
  184. <span class="assignee-wrapper">
  185. <!-- 有设计师且不是"未分配"时显示 -->
  186. <span class="assignee" *ngIf="space.assignee && space.assignee !== '未分配'">
  187. <span class="assignee-icon">👤</span>
  188. <span class="assignee-name">{{ space.assignee }}</span>
  189. </span>
  190. <!-- 没有设计师或为"未分配"时显示 -->
  191. <span class="assignee unassigned-badge" *ngIf="!space.assignee || space.assignee === '未分配'">
  192. <span class="warning-icon-small">⚠️</span>
  193. <span>未分配</span>
  194. </span>
  195. </span>
  196. </div>
  197. </div>
  198. <div class="no-incomplete" *ngIf="phase.info.incompleteSpaces.length === 0">
  199. <span class="success-icon">✅</span>
  200. <span>所有空间已完成此阶段交付</span>
  201. </div>
  202. </div>
  203. </div>
  204. </div>
  205. </div>
  206. <!-- 操作按钮 -->
  207. <div class="modal-footer">
  208. <button class="btn btn-secondary" (click)="onClose()">
  209. 关闭
  210. </button>
  211. <button class="btn btn-primary" (click)="onReportIssue()">
  212. <span class="btn-icon">🐛</span>
  213. 提交问题
  214. </button>
  215. </div>
  216. </div>
  217. </div>