123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- 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<void> {
- 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个项目';
- }
- }
|