123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- <div class="designer-assignment-container">
- <div class="section-header">
- <h3>设计师分配</h3>
- <div class="assignment-summary">
- @if (selectedTeamId) {
- <span class="team-info">主要团队:{{ getSelectedTeam()?.name }}</span>
- @if (assignmentData.crossTeamCollaborators.length > 0) {
- <span class="cross-team-info">跨组合作:{{ assignmentData.crossTeamCollaborators.length }}人</span>
- }
- }
- </div>
- </div>
- <!-- 精美的设计师分配选择框 -->
- <div class="designer-selection-dropdown">
- <div class="dropdown-header" (click)="openTeamAssignmentModal()">
- <div class="dropdown-content">
- @if (selectedTeamId) {
- <div class="selected-team-info">
- <div class="team-name">{{ getSelectedTeam()?.name }}</div>
- <div class="team-summary">
- 已分配 {{ getTotalAssignedDesigners() }} 名设计师
- @if (assignmentData.crossTeamCollaborators.length > 0) {
- ,跨组合作 {{ assignmentData.crossTeamCollaborators.length }} 人
- }
- </div>
- </div>
- } @else {
- <div class="placeholder-text">
- <span class="placeholder-icon">👥</span>
- <span>点击选择项目组并分配设计师</span>
- </div>
- }
- </div>
- <div class="dropdown-arrow">
- <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
- <path d="M4 6l4 4 4-4H4z"/>
- </svg>
- </div>
- </div>
- </div>
- <!-- 设计师组分配弹窗 -->
- @if (showTeamAssignmentModal) {
- <app-designer-team-assignment-modal
- [visible]="showTeamAssignmentModal"
- [projectTeams]="projectTeams"
- [quotationItems]="quotationItems"
- [selectedTeamId]="selectedTeamId"
- [selectedDesigners]="assignmentData.quotationAssignments"
- [crossTeamCollaborators]="assignmentData.crossTeamCollaborators"
- (close)="closeTeamAssignmentModal()"
- (confirm)="onModalAssignmentConfirm($event)"
- ></app-designer-team-assignment-modal>
- }
- <!-- 设计师详细日历弹窗 -->
- @if (showDesignerCalendar && selectedDesignerForCalendar) {
- <div class="calendar-modal-overlay" (click)="closeDesignerCalendar()">
- <div class="calendar-modal-container" (click)="$event.stopPropagation()">
- <div class="calendar-modal-header">
- <h3>{{ selectedDesignerForCalendar.name }} - 详细日历</h3>
- <button class="close-btn" (click)="closeDesignerCalendar()">
- <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
- <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"/>
- </svg>
- </button>
- </div>
- <div class="calendar-modal-body">
- <!-- 这里可以集成具体的日历组件 -->
- <div class="designer-calendar-placeholder">
- <p>设计师详细日历功能正在开发中...</p>
- <div class="designer-info-summary">
- <h4>{{ selectedDesignerForCalendar.name }}</h4>
- <p>团队:{{ selectedDesignerForCalendar.teamName }}</p>
- <p>状态:{{ getDesignerStatusText(selectedDesignerForCalendar.status) }}</p>
- <p>工作量:{{ selectedDesignerForCalendar.workload }}%</p>
- @if (selectedDesignerForCalendar.idleDays > 0) {
- <p>已闲置:{{ selectedDesignerForCalendar.idleDays }} 天</p>
- }
- @if (selectedDesignerForCalendar.reviewDates && selectedDesignerForCalendar.reviewDates.length > 0) {
- <p>对图日期:{{ selectedDesignerForCalendar.reviewDates.join(', ') }}</p>
- }
- </div>
- </div>
- </div>
- </div>
- </div>
- }
- <!-- 自动分配建议 -->
- @if (selectedTeamId && getAutoAssignmentSuggestion()) {
- <div class="auto-suggestion">
- <div class="suggestion-header">
- <span class="suggestion-icon">💡</span>
- <span>分配建议</span>
- </div>
- <p>{{ getAutoAssignmentSuggestion() }}</p>
- </div>
- }
- <!-- 报价项目分配 -->
- @if (selectedTeamId && quotationItems.length > 0) {
- <div class="quotation-assignment-section">
- <h4>报价项目分配</h4>
- <div class="assignment-grid">
- @for (assignment of assignmentData.quotationAssignments; track assignment.quotationItemId) {
- <div class="assignment-card">
- <div class="assignment-header">
- <h5>{{ assignment.quotationItemName }}</h5>
- <div class="assigned-count">
- 已分配:{{ assignment.assignedDesigners.length }}人
- </div>
- </div>
-
- <div class="designer-selection">
- <div class="available-designers">
- <h6>团队成员</h6>
- <div class="designer-list">
- @for (designer of getSelectedTeam()?.members; track designer.id) {
- <div
- class="designer-item"
- [class.assigned]="assignment.assignedDesigners.includes(designer.id)"
- (click)="onDesignerClick(designer)"
- >
- <div class="designer-avatar">
- @if (designer.avatar) {
- <img [src]="designer.avatar" [alt]="designer.name" />
- } @else {
- <div class="avatar-placeholder">{{ designer.name.charAt(0) }}</div>
- }
- </div>
-
- <div class="designer-info">
- <div class="designer-name">
- {{ designer.name }}
- @if (designer.isTeamLeader) {
- <span class="leader-badge">组长</span>
- }
- </div>
- <div class="designer-status">
- <span
- class="status-dot"
- [style.background-color]="getDesignerStatusColor(designer.status)"
- ></span>
- <span class="status-text">{{ getDesignerStatusText(designer.status) }}</span>
- @if (designer.idleDays > 0) {
- <span class="idle-days">{{ designer.idleDays }}天未接单</span>
- }
- </div>
- <div class="workload-bar">
- <div class="workload-fill" [style.width.%]="designer.workload"></div>
- <span class="workload-text">{{ designer.workload }}%</span>
- </div>
- </div>
-
- <div class="assignment-actions">
- @if (assignment.assignedDesigners.includes(designer.id)) {
- <button
- class="remove-btn"
- (click)="removeDesignerFromQuotation(assignment.quotationItemId, designer.id); $event.stopPropagation()"
- >
- 移除
- </button>
- } @else {
- <button
- class="assign-btn"
- (click)="assignDesignerToQuotation(assignment.quotationItemId, designer.id); $event.stopPropagation()"
- >
- 分配
- </button>
- }
- </div>
- </div>
- }
- </div>
- </div>
- </div>
- </div>
- }
- </div>
- </div>
- }
- <!-- 跨组合作 -->
- @if (selectedTeamId) {
- <div class="cross-team-section">
- <div class="section-title">
- <h4>跨组合作</h4>
- <button
- class="toggle-btn"
- (click)="showCrossTeamSelection = !showCrossTeamSelection"
- >
- @if (showCrossTeamSelection) {
- <span>收起</span>
- } @else {
- <span>添加跨组合作</span>
- }
- </button>
- </div>
- <!-- 已选择的跨组合作设计师 -->
- @if (assignmentData.crossTeamCollaborators.length > 0) {
- <div class="selected-collaborators">
- <h5>已选择的跨组合作设计师</h5>
- <div class="collaborator-list">
- @for (designerId of assignmentData.crossTeamCollaborators; track designerId) {
- <div class="collaborator-item">
- @if (getDesignerById(designerId); as designer) {
- <div class="designer-info">
- <span class="designer-name">{{ designer.name }}</span>
- <span class="team-name">{{ designer.teamName }}</span>
- </div>
- <button
- class="remove-collaborator-btn"
- (click)="removeCrossTeamCollaborator(designerId)"
- >
- ×
- </button>
- }
- </div>
- }
- </div>
- </div>
- }
- <!-- 跨组设计师选择 -->
- @if (showCrossTeamSelection) {
- <div class="cross-team-selection">
- <h5>选择其他组设计师</h5>
- <div class="cross-team-grid">
- @for (team of projectTeams; track team.id) {
- @if (team.id !== selectedTeamId) {
- <div class="cross-team-group">
- <h6>{{ team.name }}</h6>
- <div class="designer-list">
- @for (designer of team.members; track designer.id) {
- <div
- class="designer-item"
- [class.selected]="assignmentData.crossTeamCollaborators.includes(designer.id)"
- (click)="onDesignerClick(designer)"
- >
- <div class="designer-info">
- <span class="designer-name">{{ designer.name }}</span>
- <div class="designer-status">
- <span
- class="status-dot"
- [style.background-color]="getDesignerStatusColor(designer.status)"
- ></span>
- <span class="status-text">{{ getDesignerStatusText(designer.status) }}</span>
- </div>
- </div>
- <div class="selection-actions">
- @if (assignmentData.crossTeamCollaborators.includes(designer.id)) {
- <button
- class="remove-btn"
- (click)="removeCrossTeamCollaborator(designer.id); $event.stopPropagation()"
- >
- 移除
- </button>
- } @else {
- <button
- class="add-btn"
- (click)="addCrossTeamCollaborator(designer.id); $event.stopPropagation()"
- >
- 添加
- </button>
- }
- </div>
- </div>
- }
- </div>
- </div>
- }
- }
- </div>
- </div>
- }
- </div>
- }
- <!-- 备注 -->
- <div class="notes-section">
- <label for="assignmentNotes">分配备注</label>
- <textarea
- id="assignmentNotes"
- [(ngModel)]="assignmentData.notes"
- (ngModelChange)="emitAssignmentChange()"
- placeholder="请输入分配相关的备注信息..."
- class="notes-textarea"
- rows="3"
- ></textarea>
- </div>
- <!-- 分配总结 -->
- <div class="assignment-summary-section">
- <h4>分配总结</h4>
- <div class="summary-content">
- @if (selectedTeamId) {
- <div class="summary-item">
- <span class="label">主要团队:</span>
- <span class="value">{{ getSelectedTeam()?.name }}</span>
- </div>
- }
-
- @if (assignmentData.quotationAssignments.length > 0) {
- <div class="summary-item">
- <span class="label">项目分配:</span>
- <div class="assignment-list">
- @for (assignment of assignmentData.quotationAssignments; track assignment.quotationItemId) {
- @if (assignment.assignedDesigners.length > 0) {
- <div class="assignment-summary-item">
- <span class="project-name">{{ assignment.quotationItemName }}</span>
- <span class="assigned-designers">
- @for (designerId of assignment.assignedDesigners; track designerId) {
- <span class="designer-tag">{{ getDesignerById(designerId)?.name }}</span>
- }
- </span>
- </div>
- }
- }
- </div>
- </div>
- }
-
- @if (assignmentData.crossTeamCollaborators.length > 0) {
- <div class="summary-item">
- <span class="label">跨组合作:</span>
- <div class="collaborator-tags">
- @for (designerId of assignmentData.crossTeamCollaborators; track designerId) {
- <span class="collaborator-tag">{{ getDesignerById(designerId)?.name }}</span>
- }
- </div>
- </div>
- }
- </div>
- </div>
- </div>
|