import { Injectable } from '@angular/core'; import { AdminDataService } from './admin-data.service'; import { FmodeObject } from 'fmode-ng/core'; /** * 项目管理数据服务 */ @Injectable({ providedIn: 'root' }) export class ProjectService { constructor(private adminData: AdminDataService) {} /** * 查询项目列表 */ async findProjects(options?: { status?: string; keyword?: string; skip?: number; limit?: number; }): Promise { return await this.adminData.findAll('Project', { include: ['customer', 'assignee'], skip: options?.skip || 0, limit: options?.limit || 20, descending: 'updatedAt', additionalQuery: query => { if (options?.status) { query.equalTo('status', options.status); } if (options?.keyword) { const kw = options.keyword.trim(); if (kw) { // 搜索项目标题 query.matches('title', new RegExp(kw, 'i')); } } } }); } /** * 统计项目数量 */ async countProjects(status?: string): Promise { return await this.adminData.count('Project', query => { if (status) { query.equalTo('status', status); } }); } /** * 根据ID获取项目 */ async getProject(objectId: string): Promise { return await this.adminData.getById('Project', objectId, [ 'customer', 'assignee' ]); } /** * 创建项目 */ async createProject(data: { title: string; customerId?: string; assigneeId?: string; status?: string; currentStage?: string; deadline?: Date; data?: any; }): Promise { const projectData: any = { title: data.title, status: data.status || '待分配', currentStage: data.currentStage || '订单分配' }; // 设置客户指针 if (data.customerId) { projectData.customer = { __type: 'Pointer', className: 'ContactInfo', objectId: data.customerId }; } // 设置负责人指针 if (data.assigneeId) { projectData.assignee = { __type: 'Pointer', className: 'Profile', objectId: data.assigneeId }; } if (data.deadline) { projectData.deadline = data.deadline; } if (data.data) { projectData.data = data.data; } const project = this.adminData.createObject('Project', projectData); return await this.adminData.save(project); } /** * 更新项目 */ async updateProject( objectId: string, updates: { title?: string; customerId?: string; assigneeId?: string; status?: string; currentStage?: string; deadline?: Date; data?: any; } ): Promise { const project = await this.getProject(objectId); if (!project) { return null; } if (updates.title !== undefined) { project.set('title', updates.title); } if (updates.customerId !== undefined) { project.set('customer', { __type: 'Pointer', className: 'ContactInfo', objectId: updates.customerId }); } if (updates.assigneeId !== undefined) { project.set('assignee', { __type: 'Pointer', className: 'Profile', objectId: updates.assigneeId }); } if (updates.status !== undefined) { project.set('status', updates.status); } if (updates.currentStage !== undefined) { project.set('currentStage', updates.currentStage); } if (updates.deadline !== undefined) { project.set('deadline', updates.deadline); } if (updates.data !== undefined) { const currentData = project.get('data') || {}; project.set('data', { ...currentData, ...updates.data }); } return await this.adminData.save(project); } /** * 删除项目(软删除) */ async deleteProject(objectId: string): Promise { const project = await this.getProject(objectId); if (!project) { return false; } await this.adminData.softDelete(project); return true; } /** * 批量删除项目 */ async deleteProjects(objectIds: string[]): Promise { const projects = await Promise.all( objectIds.map(id => this.getProject(id)) ); const validProjects = projects.filter((p): p is FmodeObject => p !== null); if (validProjects.length === 0) { return 0; } await this.adminData.softDeleteBatch(validProjects); return validProjects.length; } /** * 转换为JSON */ toJSON(project: FmodeObject): any { const json = this.adminData.toJSON(project); // 处理关联对象 if (json.customer && typeof json.customer === 'object') { json.customerName = json.customer.name || ''; json.customerId = json.customer.objectId; } if (json.assignee && typeof json.assignee === 'object') { json.assigneeName = json.assignee.name || ''; json.assigneeId = json.assignee.objectId; } return json; } /** * 批量转换 */ toJSONArray(projects: FmodeObject[]): any[] { return projects.map(p => this.toJSON(p)); } }