import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { FmodeObject, FmodeParse } from 'fmode-ng/parse'; import { ProductSpaceService, Project } from '../../services/product-space.service'; const Parse = FmodeParse.with('nova'); @Component({ selector: 'app-team-assign', standalone: true, imports: [CommonModule, FormsModule], templateUrl: './team-assign.component.html', styleUrls: ['./team-assign.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class TeamAssignComponent implements OnInit { @Input() project: FmodeObject | null = null; @Input() canEdit: boolean = true; // 可选:未传入时默认允许编辑 @Input() currentUser: FmodeObject | null = null; // 可选:未传入时为 null // 项目组(Department)列表 departments: FmodeObject[] = []; selectedDepartment: FmodeObject | null = null; // 项目组成员(Profile)列表 departmentMembers: FmodeObject[] = []; selectedDesigner: FmodeObject | null = null; // 已分配的项目团队成员 projectTeams: FmodeObject[] = []; // 设计师分配对话框 showAssignDialog: boolean = false; assigningDesigner: FmodeObject | null = null; selectedSpaces: string[] = []; editingTeam: FmodeObject | null = null; // 当前正在编辑的团队对象 // 加载状态 loadingMembers: boolean = false; loadingTeams: boolean = false; loadingSpaces: boolean = false; saving: boolean = false; // 空间数据 projectSpaces: Project[] = []; constructor( private productSpaceService: ProductSpaceService, private cdr: ChangeDetectorRef ) {} async ngOnInit() { await this.loadData(); } async loadData() { if (!this.project) return; try { // 初始化已选择的项目组与设计师(若项目已有) const department = this.project.get('department'); if (department) { this.selectedDepartment = department; await this.loadDepartmentMembers(department); } const assignee = this.project.get('assignee'); if (assignee) { this.selectedDesigner = assignee; } // 加载项目组列表 const deptQuery = new Parse.Query('Department'); deptQuery.include('leader'); deptQuery.equalTo('type', 'project'); deptQuery.equalTo('company', localStorage.getItem('company')); deptQuery.notEqualTo('isDeleted', true); deptQuery.ascending('name'); this.departments = await deptQuery.find(); // 加载项目团队 await this.loadProjectTeams(); // 加载项目空间 await this.loadProjectSpaces(); } catch (err) { console.error('加载团队分配数据失败:', err); } finally { this.cdr.markForCheck(); } } async loadProjectSpaces(): Promise { if (!this.project) return; try { this.loadingSpaces = true; const projectId = this.project.id || ''; this.projectSpaces = await this.productSpaceService.getProjectProductSpaces(projectId); } catch (err) { console.error('加载项目空间失败:', err); } finally { this.loadingSpaces = false; this.cdr.markForCheck(); } } async loadProjectTeams() { if (!this.project) return; try { this.loadingTeams = true; const query = new Parse.Query('ProjectTeam'); query.equalTo('project', this.project.toPointer()); query.include('profile'); query.notEqualTo('isDeleted', true); this.projectTeams = await query.find(); } catch (err) { console.error('加载项目团队失败:', err); } finally { this.loadingTeams = false; } } async selectDepartment(department: FmodeObject) { this.selectedDepartment = department; this.selectedDesigner = null; this.departmentMembers = []; await this.loadDepartmentMembers(department); } async loadDepartmentMembers(department: FmodeObject) { const departmentId = department?.id; if (!departmentId) return []; try { this.loadingMembers = true; const query = new Parse.Query('Profile'); query.equalTo('department', departmentId); query.equalTo('roleName', '组员'); query.notEqualTo('isDeleted', true); query.ascending('name'); this.departmentMembers = await query.find(); // 将组长置顶展示 const leader = department?.get('leader'); if (leader) { this.departmentMembers.unshift(leader); } return this.departmentMembers; } catch (err) { console.error('加载项目组成员失败:', err); } finally { this.loadingMembers = false; } return []; } selectDesigner(designer: FmodeObject) { // 检查是否已分配 const isAssigned = this.projectTeams.some(team => team.get('profile')?.id === designer.id); if (isAssigned) { alert('该设计师已分配到此项目'); return; } this.assigningDesigner = designer; this.selectedSpaces = []; // 如果只有一个空间,默认选中 if (this.projectSpaces.length === 1) { const only = this.projectSpaces[0]; this.selectedSpaces = [only.name]; } this.showAssignDialog = true; } editAssignedDesigner(team: FmodeObject) { const designer = team.get('profile'); if (!designer) return; this.assigningDesigner = designer; this.editingTeam = team; const currentSpaces = team.get('data')?.spaces || []; this.selectedSpaces = [...currentSpaces]; this.showAssignDialog = true; } toggleSpaceSelection(spaceName: string) { const index = this.selectedSpaces.indexOf(spaceName); if (index > -1) { this.selectedSpaces.splice(index, 1); } else { this.selectedSpaces.push(spaceName); } } async confirmAssignDesigner() { if (!this.assigningDesigner || !this.project) return; if (this.selectedSpaces.length === 0) { alert('请至少选择一个空间场景'); return; } try { this.saving = true; if (this.editingTeam) { // 更新现有团队成员的空间分配 const data = this.editingTeam.get('data') || {}; data.spaces = this.selectedSpaces; data.updatedAt = new Date(); data.updatedBy = this.currentUser?.id; this.editingTeam.set('data', data); await this.editingTeam.save(); alert('更新成功'); } else { // 创建新的 ProjectTeam const ProjectTeam = Parse.Object.extend('ProjectTeam'); const team = new ProjectTeam(); team.set('project', this.project.toPointer()); team.set('profile', this.assigningDesigner.toPointer()); team.set('role', '组员'); team.set('data', { spaces: this.selectedSpaces, assignedAt: new Date(), assignedBy: this.currentUser?.id }); await team.save(); // 加入群聊(静默执行) await this.addMemberToGroupChat(this.assigningDesigner.get('userId')); alert('分配成功'); } await this.loadProjectTeams(); this.showAssignDialog = false; this.assigningDesigner = null; this.selectedSpaces = []; this.editingTeam = null; } catch (err) { console.error(this.editingTeam ? '更新失败:' : '分配设计师失败:', err); alert(this.editingTeam ? '更新失败' : '分配失败'); } finally { this.saving = false; } } cancelAssignDialog() { this.showAssignDialog = false; this.assigningDesigner = null; this.selectedSpaces = []; this.editingTeam = null; } async addMemberToGroupChat(userId: string) { if (!userId) return; try { const groupChat = (this as any).groupChat; if (!groupChat) return; const chatId = groupChat.get('chat_id'); if (!chatId) return; if (typeof (window as any).ww !== 'undefined') { await (window as any).ww.updateEnterpriseChat({ chatId: chatId, userIdsToAdd: [userId] }); } } catch (err) { console.warn('添加群成员失败:', err); } } getMemberSpaces(team: FmodeObject): string { const spaces = team.get('data')?.spaces || []; return spaces.join('、') || '未分配'; } getDesignerWorkload(designer: FmodeObject): string { return '3个项目'; } }