日期: 2025-10-24 任务: 在Admin项目管理中增强设计师分配功能 状态: 🚧 进行中
designer-team-assignment-modal组件文件: src/app/pages/admin/project-management/project-management.html
在操作列添加新按钮:
<button mat-icon-button class="action-btn" color="accent"
title="分配设计师"
(click)="openTeamAssignmentModal(project)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
<circle cx="9" cy="7" r="4"></circle>
<path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
</svg>
</button>
文件: src/app/pages/admin/project-management/project-management.ts
添加:
DesignerTeamAssignmentModalComponentopenTeamAssignmentModal(project)方法closeTeamAssignmentModal()方法confirmTeamAssignment(result)方法新增接口:
export interface WorkflowAssignment {
workflowType: 'space' | 'modeling' | 'furnishing' | 'rendering' | 'postprocessing';
workflowName: string;
assignedDesigners: string[]; // Designer IDs
productIds?: string[]; // 关联的产品/空间ID
estimatedHours?: number;
deadline?: Date;
}
export interface EnhancedDesignerAssignmentData {
projectId: string;
primaryTeamId: string;
workflowAssignments: WorkflowAssignment[];
crossTeamCollaborators: string[];
notes?: string;
}
文件: src/app/pages/designer/project-detail/components/designer-team-assignment-modal/designer-team-assignment-modal.component.html
在弹窗中添加新的"工序分工"部分:
<!-- 工序分工部分 -->
@if (internalSelectedTeamId && showWorkflowAssignment) {
<div class="workflow-assignment-section">
<h3>工序分工</h3>
<div class="workflow-grid">
<div class="workflow-item" *ngFor="let workflow of workflowTypes">
<div class="workflow-header">
<h4>{{ workflow.name }}</h4>
<span class="assigned-count">已分配: {{ getWorkflowAssignedCount(workflow.type) }}人</span>
</div>
<div class="designer-assignment">
<div class="designer-chips">
@for (designerId of getWorkflowAssignedDesigners(workflow.type); track designerId) {
<div class="designer-chip">
{{ getDesignerById(designerId)?.name }}
<button class="remove-chip" (click)="removeWorkflowDesigner(workflow.type, designerId)">×</button>
</div>
}
</div>
<button class="add-designer-btn" (click)="openDesignerSelector(workflow.type)">
+ 添加设计师
</button>
</div>
</div>
</div>
</div>
}
目标: 修改designer-calendar.component,使其显示类似iOS日历的月视图
参考图片要求:
实现方案:
创建新的月历组件或修改现有组件:
<div class="month-calendar">
<div class="calendar-header">
<button (click)="previousMonth()">‹</button>
<span class="month-year">{{ currentMonth }} {{ currentYear }}</span>
<button (click)="nextMonth()">›</button>
</div>
<div class="calendar-grid">
<div class="weekday-header" *ngFor="let day of weekDays">{{ day }}</div>
<div class="calendar-day"
*ngFor="let date of calendarDates"
[class.weekend]="isWeekend(date)"
[class.busy]="isDesignerBusy(date)"
[class.review]="isReviewDate(date)"
[class.available]="isAvailable(date)"
[class.today]="isToday(date)"
(click)="selectDate(date)">
<span class="date-number">{{ date.getDate() }}</span>
@if (hasEvents(date)) {
<div class="event-dots">
<span class="dot" *ngFor="let event of getDateEvents(date)"></span>
</div>
}
</div>
</div>
<!-- 选中日期的详情 -->
@if (selectedDate) {
<div class="date-details">
<h4>{{ selectedDate | date:'yyyy-MM-dd' }}</h4>
<div class="events-list">
<div class="event-item" *ngFor="let event of selectedDateEvents">
{{ event.description }}
</div>
</div>
</div>
}
</div>
查询项目团队成员:
async loadProjectTeamMembers(projectId: string): Promise<Designer[]> {
const query = new Parse.Query('ProjectTeam');
query.equalTo('project', { __type: 'Pointer', className: 'Project', objectId: projectId });
query.include('profile');
query.notEqualTo('isDeleted', true);
const teamMembers = await query.find();
return teamMembers.map(member => {
const profile = member.get('profile');
return {
id: profile.id,
name: profile.get('name'),
teamId: member.get('team')?.id,
teamName: member.get('team')?.get('name'),
// ... 其他字段
};
});
}
查询工序分配:
async loadWorkflowAssignments(projectId: string): Promise<WorkflowAssignment[]> {
const query = new Parse.Query('ProjectWorkflowAssignment');
query.equalTo('project', { __type: 'Pointer', className: 'Project', objectId: projectId });
query.include(['assignedTo', 'product']);
const assignments = await query.find();
return assignments.map(assignment => ({
workflowType: assignment.get('workflowType'),
workflowName: assignment.get('workflowName'),
assignedDesigners: assignment.get('assignedTo').map(d => d.id),
productIds: assignment.get('products')?.map(p => p.id),
}));
}
保存分配结果:
async saveTeamAssignment(projectId: string, data: EnhancedDesignerAssignmentData): Promise<void> {
// 1. 更新ProjectTeam表
for (const designerId of data.selectedDesigners) {
const ProjectTeam = Parse.Object.extend('ProjectTeam');
const teamMember = new ProjectTeam();
teamMember.set('project', { __type: 'Pointer', className: 'Project', objectId: projectId });
teamMember.set('profile', { __type: 'Pointer', className: 'Profile', objectId: designerId });
teamMember.set('role', 'member');
await teamMember.save();
}
// 2. 保存工序分配
for (const workflow of data.workflowAssignments) {
const WorkflowAssignment = Parse.Object.extend('ProjectWorkflowAssignment');
const assignment = new WorkflowAssignment();
assignment.set('project', { __type: 'Pointer', className: 'Project', objectId: projectId });
assignment.set('workflowType', workflow.workflowType);
assignment.set('workflowName', workflow.workflowName);
assignment.set('assignedTo', workflow.assignedDesigners.map(id => ({
__type: 'Pointer',
className: 'Profile',
objectId: id
})));
await assignment.save();
}
}
┌─────────────┬──────────────────────────────┐
│ 工序分工 │ │
├─────────────┼──────────────────────────────┤
│ 🏠 空间设计 │ [张三] [李四] [+ 添加] │
│ 🔨 建模制作 │ [王五] [+ 添加] │
│ 🪑 软装搭配 │ [赵六] [+ 添加] │
│ 🎨 效果渲染 │ [+ 添加] │
│ ✨ 后期处理 │ [+ 添加] │
└─────────────┴──────────────────────────────┘
2025年 10月
一 二 三 四 五 六 日
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
图例:
🟢 空闲可分配
🔴 已占用
🟡 对图日期
🔵 当前选中
可能需要新增表:
TABLE(ProjectWorkflowAssignment, "项目工序分配表") {
FIELD(objectId, String)
FIELD(project, Pointer→Project)
FIELD(company, Pointer→Company)
FIELD(workflowType, String) // "space" | "modeling" | "furnishing" | "rendering" | "postprocessing"
FIELD(workflowName, String)
FIELD(assignedTo, Array<Pointer→Profile>)
FIELD(products, Array<Pointer→Product>) // 关联的空间产品
FIELD(estimatedHours, Number)
FIELD(deadline, Date)
FIELD(isDeleted, Boolean)
FIELD(createdAt, Date)
FIELD(updatedAt, Date)
}
designer-team-assignment-modal组件isDeleted开发者: Claude AI 预计完成时间: 2025-10-24