import { GenericCrudService } from '@d8d/shared-crud'; import { DataSource, Repository, DataSourceOptions, In, Not } from 'typeorm'; import { EmploymentOrder } from '../entities/employment-order.entity'; import { OrderPerson } from '../entities/order-person.entity'; import { OrderPersonAsset } from '../entities/order-person-asset.entity'; import { AssetType, AssetFileType } from '../schemas/order.schema'; import { FileService, File } from '@d8d/file-module'; import { OrderStatus, WorkStatus } from '@d8d/allin-enums'; export class OrderService extends GenericCrudService { private readonly orderPersonRepository: Repository; private readonly orderPersonAssetRepository: Repository; private readonly fileRepository: Repository; private fileService: FileService; constructor(dataSource: DataSource) { super(dataSource, EmploymentOrder); this.orderPersonRepository = dataSource.getRepository(OrderPerson); this.orderPersonAssetRepository = dataSource.getRepository(OrderPersonAsset); this.fileRepository = dataSource.getRepository(File); this.fileService = new FileService(dataSource); } /** * 创建订单 - 覆盖父类方法,添加验证和业务逻辑 */ async create(data: Partial, userId?: string | number): Promise { // 验证枚举值 if (data.orderStatus && !Object.values(OrderStatus).includes(data.orderStatus)) { throw new Error('订单状态无效'); } if (data.workStatus && !Object.values(WorkStatus).includes(data.workStatus)) { throw new Error('工作状态无效'); } // 设置默认值 const orderData = { ...data, orderStatus: data.orderStatus || OrderStatus.DRAFT, workStatus: data.workStatus || WorkStatus.NOT_WORKING, }; return super.create(orderData, userId); } /** * 更新订单 - 覆盖父类方法,添加验证 */ async update(id: number, data: Partial, userId?: string | number): Promise { // 验证枚举值 if (data.orderStatus && !Object.values(OrderStatus).includes(data.orderStatus)) { throw new Error('订单状态无效'); } if (data.workStatus && !Object.values(WorkStatus).includes(data.workStatus)) { throw new Error('工作状态无效'); } return super.update(id, data, userId); } /** * 分页查询订单 - 自定义方法,返回源服务的格式 */ async findAll(query: { orderName?: string; platformId?: number; companyId?: number; channelId?: number; orderStatus?: OrderStatus; startDate?: string; endDate?: string; page?: number; limit?: number; }): Promise<{ data: any[]; total: number }> { const { orderName, platformId, companyId, channelId, orderStatus, startDate, endDate, page = 1, limit = 10 } = query; const queryBuilder = this.repository.createQueryBuilder('order'); // 构建查询条件 if (orderName) { queryBuilder.andWhere('order.orderName LIKE :orderName', { orderName: `%${orderName}%` }); } if (platformId) { queryBuilder.andWhere('order.platformId = :platformId', { platformId }); } if (companyId) { queryBuilder.andWhere('order.companyId = :companyId', { companyId }); } if (channelId) { queryBuilder.andWhere('order.channelId = :channelId', { channelId }); } if (orderStatus) { queryBuilder.andWhere('order.orderStatus = :orderStatus', { orderStatus }); } // 日期范围查询 - 基于createTime字段 if (startDate) { queryBuilder.andWhere('order.createTime >= :startDate', { startDate: `${startDate}T00:00:00Z` }); } if (endDate) { queryBuilder.andWhere('order.createTime <= :endDate', { endDate: `${endDate}T23:59:59Z` }); } // 获取总数 const total = await queryBuilder.getCount(); // 获取数据 const data = await queryBuilder .skip((page - 1) * limit) .take(limit) .orderBy('order.createTime', 'DESC') .getMany(); // 获取每个订单的人员数量 const orderIds = data.map(order => order.id); let personCounts: Array<{ orderId: number; count: number }> = []; if (orderIds.length > 0) { const personCountQuery = await this.orderPersonRepository .createQueryBuilder('orderPerson') .select('orderPerson.orderId', 'orderId') .addSelect('COUNT(orderPerson.id)', 'count') .where('orderPerson.orderId IN (:...orderIds)', { orderIds }) .groupBy('orderPerson.orderId') .getRawMany(); personCounts = personCountQuery.map(item => ({ orderId: item.orderId, count: parseInt(item.count) })); } // 格式化返回数据 const formattedData = data.map(order => { const personCount = personCounts.find(pc => pc.orderId === order.id)?.count || 0; return { id: order.id, orderName: order.orderName, platformId: order.platformId, companyId: order.companyId, channelId: order.channelId, expectedStartDate: order.expectedStartDate, actualStartDate: order.actualStartDate, actualEndDate: order.actualEndDate, orderStatus: order.orderStatus, workStatus: order.workStatus, createTime: order.createTime, updateTime: order.updateTime, personCount }; }); return { data: formattedData, total }; } /** * 查询单个订单详情 - 自定义方法 */ async findOne(id: number): Promise { const order = await this.repository.findOne({ where: { id }, relations: ['orderPersons', 'orderPersons.person'] }); if (!order) { return null; } // 获取订单人员详情(这里简化处理,实际可能需要关联更多信息) const orderPersons = order.orderPersons || []; return { id: order.id, orderName: order.orderName, platformId: order.platformId, companyId: order.companyId, channelId: order.channelId, expectedStartDate: order.expectedStartDate, actualStartDate: order.actualStartDate, actualEndDate: order.actualEndDate, orderStatus: order.orderStatus, workStatus: order.workStatus, createTime: order.createTime, updateTime: order.updateTime, orderPersons: orderPersons.map(person => ({ id: person.id, // 注意:schema期望id字段,不是opId orderId: person.orderId, personId: person.personId, joinDate: person.joinDate, leaveDate: person.leaveDate, workStatus: person.workStatus, salaryDetail: person.salaryDetail, // 残疾人员的详细信息 person: person.person ? { id: person.person.id, name: person.person.name, gender: person.person.gender, disabilityType: person.person.disabilityType, phone: person.person.phone, // 可以根据需要添加更多字段 } : null })) }; } /** * 订单激活 - 自定义业务方法 */ async activateOrder(orderId: number): Promise { const queryRunner = this.dataSource.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); try { // 查询订单 const order = await queryRunner.manager.findOne(EmploymentOrder, { where: { id: orderId } }); if (!order) { throw new Error(`订单ID ${orderId} 不存在`); } if (order.orderStatus !== OrderStatus.DRAFT) { throw new Error(`只有草稿状态的订单才能激活,当前订单状态为: ${order.orderStatus}`); } // 更新订单状态为已确认 order.orderStatus = OrderStatus.CONFIRMED; order.actualStartDate = new Date(); await queryRunner.manager.save(order); // 更新订单人员状态为待就业 await queryRunner.manager.update(OrderPerson, { orderId: orderId }, { workStatus: WorkStatus.PRE_WORKING } ); await queryRunner.commitTransaction(); return true; } catch (error) { await queryRunner.rollbackTransaction(); throw error; } finally { await queryRunner.release(); } } /** * 订单关闭 - 自定义业务方法 */ async closeOrder(orderId: number): Promise { const queryRunner = this.dataSource.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); try { // 查询订单 const order = await queryRunner.manager.findOne(EmploymentOrder, { where: { id: orderId } }); if (!order) { throw new Error(`订单ID ${orderId} 不存在`); } if (order.orderStatus !== OrderStatus.CONFIRMED && order.orderStatus !== OrderStatus.IN_PROGRESS) { throw new Error(`只有已确认或进行中的订单才能关闭,当前订单状态为: ${order.orderStatus}`); } // 更新订单状态为已完成 order.orderStatus = OrderStatus.COMPLETED; order.actualEndDate = new Date(); await queryRunner.manager.save(order); // 更新订单人员状态为已离职 await queryRunner.manager.update(OrderPerson, { orderId: orderId }, { workStatus: WorkStatus.RESIGNED, leaveDate: new Date() } ); await queryRunner.commitTransaction(); return true; } catch (error) { await queryRunner.rollbackTransaction(); throw error; } finally { await queryRunner.release(); } } /** * 批量添加人员到订单 - 自定义业务方法 */ async batchAddPersons(orderId: number, persons: Array<{ personId: number; joinDate: Date; salaryDetail: number; }>): Promise<{ success: boolean; message: string; addedCount: number }> { // 验证订单是否存在 const order = await this.repository.findOne({ where: { id: orderId } }); if (!order) { throw new Error(`订单ID ${orderId} 不存在`); } if (order.orderStatus === OrderStatus.COMPLETED || order.orderStatus === OrderStatus.CANCELLED) { throw new Error(`订单ID ${orderId} 已结束或已取消,无法添加人员`); } // 检查哪些人员已经在订单中 const existingPersons = await this.orderPersonRepository.find({ where: { orderId } }); const existingPersonIds = existingPersons.map(p => p.personId); // 过滤掉已存在的人员 const newPersons = persons.filter(p => !existingPersonIds.includes(p.personId)); if (newPersons.length === 0) { return { success: true, message: '所有人员都已在此订单中', addedCount: 0 }; } // 使用事务添加新人员 const queryRunner = this.dataSource.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); try { // 创建订单人员关联 const orderPersons = newPersons.map(person => { return queryRunner.manager.create(OrderPerson, { orderId: orderId, personId: person.personId, joinDate: person.joinDate, workStatus: WorkStatus.NOT_WORKING, salaryDetail: person.salaryDetail, }); }); await queryRunner.manager.save(orderPersons); await queryRunner.commitTransaction(); return { success: true, message: `成功添加 ${newPersons.length} 个人员到订单`, addedCount: newPersons.length }; } catch (error) { await queryRunner.rollbackTransaction(); throw error; } finally { await queryRunner.release(); } } /** * 验证文件ID是否存在 */ async validateFileId(fileId: number): Promise { try { const file = await this.fileRepository.findOne({ where: { id: fileId } }); return !!file; } catch (error) { console.error('验证文件ID失败:', error); return false; } } /** * 创建订单人员资产 - 自定义业务方法 */ async createOrderPersonAsset(data: { orderId: number; personId: number; assetType: AssetType; assetFileType: AssetFileType; fileId: number; relatedTime?: Date; }): Promise { // 验证文件ID是否存在 const fileExists = await this.validateFileId(data.fileId); if (!fileExists) { throw new Error('文件不存在'); } // 验证订单和人员关联是否存在 const orderPerson = await this.orderPersonRepository.findOne({ where: { orderId: data.orderId, personId: data.personId } }); if (!orderPerson) { throw new Error(`人员ID ${data.personId} 不在订单ID ${data.orderId} 中`); } // 创建资产记录 const asset = new OrderPersonAsset({ orderId: data.orderId, personId: data.personId, assetType: data.assetType, assetFileType: data.assetFileType, fileId: data.fileId, relatedTime: data.relatedTime || new Date() }); return await this.orderPersonAssetRepository.save(asset); } /** * 查询订单人员资产 - 自定义业务方法 */ async queryOrderPersonAsset(query: { orderId?: number; personId?: number; assetType?: string; assetFileType?: string; page?: number; limit?: number; }): Promise<{ data: OrderPersonAsset[]; total: number }> { const { orderId, personId, assetType, assetFileType, page = 1, limit = 10 } = query; const queryBuilder = this.orderPersonAssetRepository.createQueryBuilder('asset'); // 构建查询条件 if (orderId) { queryBuilder.andWhere('asset.orderId = :orderId', { orderId }); } if (personId) { queryBuilder.andWhere('asset.personId = :personId', { personId }); } if (assetType) { queryBuilder.andWhere('asset.assetType = :assetType', { assetType }); } if (assetFileType) { queryBuilder.andWhere('asset.assetFileType = :assetFileType', { assetFileType }); } // 获取总数 const total = await queryBuilder.getCount(); // 获取数据,加载文件关系 const data = await queryBuilder .leftJoinAndSelect('asset.file', 'file') .skip((page - 1) * limit) .take(limit) .orderBy('asset.updateTime', 'DESC') .getMany(); return { data, total }; } /** * 删除订单人员资产 - 自定义业务方法 */ async deleteOrderPersonAsset(id: number): Promise<{ success: boolean; message: string }> { const asset = await this.orderPersonAssetRepository.findOne({ where: { id } }); if (!asset) { throw new Error(`资产ID ${id} 不存在`); } await this.orderPersonAssetRepository.delete({ id }); return { success: true, message: `成功删除资产ID ${id}` }; } /** * 更新订单人员工作状态 - 自定义业务方法 */ async updatePersonWorkStatus(orderId: number, personId: number, workStatus: WorkStatus): Promise<{ success: boolean; message: string }> { // 验证订单是否存在 const order = await this.repository.findOne({ where: { id: orderId } }); if (!order) { throw new Error(`订单ID ${orderId} 不存在`); } // 验证工作状态是否有效 if (!Object.values(WorkStatus).includes(workStatus)) { throw new Error('工作状态无效'); } // 查找订单人员关联 const orderPerson = await this.orderPersonRepository.findOne({ where: { orderId, personId } }); if (!orderPerson) { throw new Error(`人员ID ${personId} 不在订单ID ${orderId} 中`); } // 更新工作状态 orderPerson.workStatus = workStatus; // 根据工作状态设置相关日期 if (workStatus === WorkStatus.WORKING && !orderPerson.actualStartDate) { orderPerson.actualStartDate = new Date(); } else if (workStatus === WorkStatus.RESIGNED && !orderPerson.leaveDate) { orderPerson.leaveDate = new Date(); } await this.orderPersonRepository.save(orderPerson); return { success: true, message: `成功更新人员 ${personId} 的工作状态为 ${workStatus}` }; } }