import { Component, OnInit, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { DepartmentService } from '../services/department.service'; import { EmployeeService } from '../services/employee.service'; import { FmodeObject } from 'fmode-ng/core'; interface Department { id: string; name: string; leader: FmodeObject; leaderName: string; leaderId?: string; type: string; memberCount: number; createdAt?: Date; } interface Employee { id: string; name: string; roleName: string; } @Component({ selector: 'app-departments', standalone: true, imports: [CommonModule, FormsModule], templateUrl: './departments.html', styleUrls: ['./departments.scss'] }) export class Departments implements OnInit { // 数据 departments = signal([]); employees = signal([]); // 可选择的组长列表 loading = signal(false); // 筛选 keyword = signal(''); // 侧边面板 showPanel = false; panelMode: 'add' | 'detail' | 'edit' = 'add'; currentDepartment: Department | null = null; formModel: Partial = {}; // 统计 total = signal(0); constructor( private departmentService: DepartmentService, private employeeService: EmployeeService ) {} ngOnInit(): void { this.loadDepartments(); this.loadLeaders(); } async loadDepartments(): Promise { this.loading.set(true); try { const depts = await this.departmentService.findDepartments({ type: 'project' }); const deptList: Department[] = await Promise.all( depts.map(async d => { const json = this.departmentService.toJSON(d); const memberCount = await this.departmentService.countDepartmentMembers(json.objectId); return { id: json.objectId, name: json.name || '未命名项目组', leader: d?.get("leader"), leaderName: d?.get("leader")?.get("name") || '未分配', leaderId: d?.get("leader").id, type: json.type || 'project', memberCount, createdAt: json.createdAt?.iso || json.createdAt }; }) ); this.departments.set(deptList); this.total.set(deptList.length); } catch (error) { console.error('加载项目组失败:', error); } finally { this.loading.set(false); } } async loadLeaders(): Promise { try { // 加载所有可以担任组长的员工(组长角色) const leaders = await this.employeeService.findEmployees({ roleName: '组长' }); this.employees.set( leaders.map(l => { const json = this.employeeService.toJSON(l); return { id: json.objectId, name: json.name, roleName: json.roleName }; }) ); } catch (error) { console.error('加载组长列表失败:', error); } } get filtered() { const kw = this.keyword().trim().toLowerCase(); if (!kw) return this.departments(); return this.departments().filter( d => d.name.toLowerCase().includes(kw) || d.leaderName.toLowerCase().includes(kw) ); } resetFilters() { this.keyword.set(''); } // 新建项目组 addDepartment() { this.formModel = { name: '', leaderId: undefined, type: 'project' }; this.currentDepartment = null; this.panelMode = 'add'; this.showPanel = true; } // 查看详情 viewDepartment(dept: Department) { this.currentDepartment = dept; this.panelMode = 'detail'; this.showPanel = true; } // 编辑 editDepartment(dept: Department) { this.currentDepartment = dept; this.formModel = { ...dept }; this.panelMode = 'edit'; this.showPanel = true; } // 关闭面板 closePanel() { this.showPanel = false; this.panelMode = 'add'; this.currentDepartment = null; this.formModel = {}; } // 保存新增 async saveDepartment() { const name = (this.formModel.name || '').trim(); if (!name) { window?.fmode?.alert('请输入项目组名称'); return; } if (!this.formModel.leaderId) { window?.fmode?.alert('请选择组长'); return; } try { await this.departmentService.createDepartment({ name, leaderId: this.formModel.leaderId, type: 'project' }); await this.loadDepartments(); this.closePanel(); } catch (error) { console.error('创建项目组失败:', error); window?.fmode?.alert('创建项目组失败,请重试'); } } // 提交编辑 async updateDepartment() { if (!this.currentDepartment) return; const name = (this.formModel.name || '').trim(); if (!name) { window?.fmode?.alert('请输入项目组名称'); return; } if (!this.formModel.leaderId) { window?.fmode?.alert('请选择组长'); return; } try { await this.departmentService.updateDepartment(this.currentDepartment.id, { name, leaderId: this.formModel.leaderId }); await this.loadDepartments(); this.closePanel(); } catch (error) { console.error('更新项目组失败:', error); window?.fmode?.alert('更新项目组失败,请重试'); } } // 删除 async deleteDepartment(dept: Department) { if (!await window?.fmode?.confirm(`确定要删除项目组 "${dept.name}" 吗?`)) { return; } try { await this.departmentService.deleteDepartment(dept.id); await this.loadDepartments(); } catch (error) { console.error('删除项目组失败:', error); window?.fmode?.alert('删除项目组失败,请重试'); } } // 导出 exportDepartments() { const header = ['项目组名称', '组长', '成员数', '创建时间']; const rows = this.filtered.map(d => [ d.name, d.leaderName, String(d.memberCount), d.createdAt instanceof Date ? d.createdAt.toISOString().slice(0, 10) : String(d.createdAt || '') ]); this.downloadCSV('项目组列表.csv', [header, ...rows]); } private downloadCSV(filename: string, rows: (string | number)[][]) { const escape = (val: string | number) => { const s = String(val ?? ''); if (/[",\n]/.test(s)) return '"' + s.replace(/"/g, '""') + '"'; return s; }; const csv = rows.map(r => r.map(escape).join(',')).join('\n'); const blob = new Blob(['\ufeff', csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } }