|
|
@@ -0,0 +1,292 @@
|
|
|
+import { DataSource } from 'typeorm';
|
|
|
+import { EmploymentOrder, OrderPerson, OrderPersonAsset, AssetType, AssetFileType } from '../../src/entities';
|
|
|
+import { OrderStatus, WorkStatus } from '@d8d/allin-enums';
|
|
|
+import { File } from '@d8d/file-module';
|
|
|
+
|
|
|
+/**
|
|
|
+ * 订单模块测试数据工厂类
|
|
|
+ * 用于生成测试数据,避免测试代码中的重复
|
|
|
+ */
|
|
|
+export class OrderTestDataFactory {
|
|
|
+ /**
|
|
|
+ * 创建测试用工订单数据
|
|
|
+ */
|
|
|
+ static createEmploymentOrderData(overrides: Partial<EmploymentOrder> = {}): Partial<EmploymentOrder> {
|
|
|
+ const timestamp = Math.floor(Math.random() * 100000);
|
|
|
+ return {
|
|
|
+ orderName: `测试订单_${timestamp}`,
|
|
|
+ platformId: 1,
|
|
|
+ companyId: 1,
|
|
|
+ channelId: 1,
|
|
|
+ expectedStartDate: new Date('2025-01-01'),
|
|
|
+ orderStatus: OrderStatus.DRAFT,
|
|
|
+ workStatus: WorkStatus.NOT_WORKING,
|
|
|
+ ...overrides
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在数据库中创建测试用工订单
|
|
|
+ */
|
|
|
+ static async createTestEmploymentOrder(
|
|
|
+ dataSource: DataSource,
|
|
|
+ overrides: Partial<EmploymentOrder> = {}
|
|
|
+ ): Promise<EmploymentOrder> {
|
|
|
+ const orderData = this.createEmploymentOrderData(overrides);
|
|
|
+ const orderRepository = dataSource.getRepository(EmploymentOrder);
|
|
|
+ const order = new EmploymentOrder(orderData);
|
|
|
+ return await orderRepository.save(order);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建测试订单人员数据
|
|
|
+ */
|
|
|
+ static createOrderPersonData(
|
|
|
+ orderId: number,
|
|
|
+ personId: number,
|
|
|
+ overrides: Partial<OrderPerson> = {}
|
|
|
+ ): Partial<OrderPerson> {
|
|
|
+ return {
|
|
|
+ orderId,
|
|
|
+ personId,
|
|
|
+ joinDate: new Date('2025-01-15'),
|
|
|
+ salaryDetail: 5000.00,
|
|
|
+ ...overrides
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在数据库中创建测试订单人员
|
|
|
+ */
|
|
|
+ static async createTestOrderPerson(
|
|
|
+ dataSource: DataSource,
|
|
|
+ orderId: number,
|
|
|
+ personId: number,
|
|
|
+ overrides: Partial<OrderPerson> = {}
|
|
|
+ ): Promise<OrderPerson> {
|
|
|
+ const personData = this.createOrderPersonData(orderId, personId, overrides);
|
|
|
+ const personRepository = dataSource.getRepository(OrderPerson);
|
|
|
+ const person = new OrderPerson(personData);
|
|
|
+ return await personRepository.save(person);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建测试订单人员资产数据
|
|
|
+ */
|
|
|
+ static createOrderPersonAssetData(
|
|
|
+ orderId: number,
|
|
|
+ personId: number,
|
|
|
+ fileId: number,
|
|
|
+ overrides: Partial<OrderPersonAsset> = {}
|
|
|
+ ): Partial<OrderPersonAsset> {
|
|
|
+ const timestamp = Math.floor(Math.random() * 100000);
|
|
|
+ return {
|
|
|
+ orderId,
|
|
|
+ personId,
|
|
|
+ fileId,
|
|
|
+ assetType: AssetType.DISABILITY_CERT,
|
|
|
+ assetFileType: AssetFileType.IMAGE,
|
|
|
+ ...overrides
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在数据库中创建测试订单人员资产
|
|
|
+ */
|
|
|
+ static async createTestOrderPersonAsset(
|
|
|
+ dataSource: DataSource,
|
|
|
+ orderId: number,
|
|
|
+ personId: number,
|
|
|
+ fileId: number,
|
|
|
+ overrides: Partial<OrderPersonAsset> = {}
|
|
|
+ ): Promise<OrderPersonAsset> {
|
|
|
+ const assetData = this.createOrderPersonAssetData(orderId, personId, fileId, overrides);
|
|
|
+ const assetRepository = dataSource.getRepository(OrderPersonAsset);
|
|
|
+ const asset = new OrderPersonAsset(assetData);
|
|
|
+ return await assetRepository.save(asset);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建测试文件数据
|
|
|
+ * 注意:这里只是创建File实体的数据,实际文件上传需要调用文件模块的API
|
|
|
+ */
|
|
|
+ static createFileData(overrides: Partial<File> = {}): Partial<File> {
|
|
|
+ const timestamp = Math.floor(Math.random() * 100000);
|
|
|
+ return {
|
|
|
+ name: `test_file_${timestamp}.jpg`, // 注意:File实体使用name字段,不是filename
|
|
|
+ type: 'image/jpeg',
|
|
|
+ size: 1024,
|
|
|
+ path: `test/${timestamp}_test_file.jpg`,
|
|
|
+ uploadUserId: 1,
|
|
|
+ uploadTime: new Date(),
|
|
|
+ createdAt: new Date(),
|
|
|
+ updatedAt: new Date(),
|
|
|
+ ...overrides
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在数据库中创建测试文件
|
|
|
+ * 注意:需要文件模块的File实体已注册到DataSource中
|
|
|
+ */
|
|
|
+ static async createTestFile(
|
|
|
+ dataSource: DataSource,
|
|
|
+ overrides: Partial<File> = {}
|
|
|
+ ): Promise<File> {
|
|
|
+ const fileData = this.createFileData(overrides);
|
|
|
+ const fileRepository = dataSource.getRepository(File);
|
|
|
+ const file = fileRepository.create(fileData);
|
|
|
+ return await fileRepository.save(file);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建完整的测试订单环境(包含订单、人员、资产、文件)
|
|
|
+ */
|
|
|
+ static async createCompleteOrderEnvironment(
|
|
|
+ dataSource: DataSource,
|
|
|
+ options: {
|
|
|
+ orderOverrides?: Partial<EmploymentOrder>;
|
|
|
+ personId?: number;
|
|
|
+ personOverrides?: Partial<OrderPerson>;
|
|
|
+ fileOverrides?: Partial<File>;
|
|
|
+ assetOverrides?: Partial<OrderPersonAsset>;
|
|
|
+ } = {}
|
|
|
+ ): Promise<{
|
|
|
+ order: EmploymentOrder;
|
|
|
+ orderPerson: OrderPerson;
|
|
|
+ file: File;
|
|
|
+ orderPersonAsset: OrderPersonAsset;
|
|
|
+ }> {
|
|
|
+ // 创建订单
|
|
|
+ const order = await this.createTestEmploymentOrder(dataSource, options.orderOverrides);
|
|
|
+
|
|
|
+ // 创建文件
|
|
|
+ const file = await this.createTestFile(dataSource, options.fileOverrides);
|
|
|
+
|
|
|
+ // 创建订单人员
|
|
|
+ const personId = options.personId || 1;
|
|
|
+ const orderPerson = await this.createTestOrderPerson(
|
|
|
+ dataSource,
|
|
|
+ order.id,
|
|
|
+ personId,
|
|
|
+ options.personOverrides
|
|
|
+ );
|
|
|
+
|
|
|
+ // 创建订单人员资产
|
|
|
+ const orderPersonAsset = await this.createTestOrderPersonAsset(
|
|
|
+ dataSource,
|
|
|
+ order.id,
|
|
|
+ personId,
|
|
|
+ file.id,
|
|
|
+ options.assetOverrides
|
|
|
+ );
|
|
|
+
|
|
|
+ return { order, orderPerson, file, orderPersonAsset };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建批量添加人员的测试数据
|
|
|
+ */
|
|
|
+ static createBatchAddPersonsData(
|
|
|
+ orderId: number,
|
|
|
+ count: number = 3
|
|
|
+ ): Array<{ personId: number; joinDate: string; salaryDetail: number }> {
|
|
|
+ const persons: Array<{ personId: number; joinDate: string; salaryDetail: number }> = [];
|
|
|
+
|
|
|
+ for (let i = 1; i <= count; i++) {
|
|
|
+ persons.push({
|
|
|
+ personId: i,
|
|
|
+ joinDate: `2025-01-${10 + i}`,
|
|
|
+ salaryDetail: 4000 + i * 500
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return persons;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建不同订单状态的测试数据
|
|
|
+ */
|
|
|
+ static createOrderWithStatus(
|
|
|
+ status: OrderStatus,
|
|
|
+ overrides: Partial<EmploymentOrder> = {}
|
|
|
+ ): Partial<EmploymentOrder> {
|
|
|
+ const baseData = this.createEmploymentOrderData(overrides);
|
|
|
+ const result: Partial<EmploymentOrder> = {
|
|
|
+ ...baseData,
|
|
|
+ orderStatus: status
|
|
|
+ };
|
|
|
+
|
|
|
+ if (status === OrderStatus.IN_PROGRESS) {
|
|
|
+ result.actualStartDate = new Date();
|
|
|
+ } else if (status === OrderStatus.COMPLETED) {
|
|
|
+ result.actualStartDate = new Date('2025-01-01');
|
|
|
+ result.actualEndDate = new Date('2025-12-31');
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建不同工作状态的测试数据
|
|
|
+ */
|
|
|
+ static createOrderWithWorkStatus(
|
|
|
+ workStatus: WorkStatus,
|
|
|
+ overrides: Partial<EmploymentOrder> = {}
|
|
|
+ ): Partial<EmploymentOrder> {
|
|
|
+ const baseData = this.createEmploymentOrderData(overrides);
|
|
|
+ return {
|
|
|
+ ...baseData,
|
|
|
+ workStatus,
|
|
|
+ ...(workStatus === WorkStatus.WORKING && { actualStartDate: new Date() }),
|
|
|
+ ...(workStatus === WorkStatus.RESIGNED && {
|
|
|
+ actualStartDate: new Date('2025-01-01'),
|
|
|
+ actualEndDate: new Date('2025-06-30')
|
|
|
+ })
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建不同资产类型的测试数据
|
|
|
+ */
|
|
|
+ static createAssetWithType(
|
|
|
+ orderId: number,
|
|
|
+ assetType: AssetType,
|
|
|
+ assetFileType: AssetFileType,
|
|
|
+ overrides: Partial<OrderPersonAsset> = {}
|
|
|
+ ): Partial<OrderPersonAsset> {
|
|
|
+ return {
|
|
|
+ orderId,
|
|
|
+ personId: 1,
|
|
|
+ fileId: 1,
|
|
|
+ assetType,
|
|
|
+ assetFileType,
|
|
|
+ ...overrides
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成随机ID(用于测试中的personId等)
|
|
|
+ */
|
|
|
+ static generateRandomId(min: number = 1, max: number = 1000): number {
|
|
|
+ return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成随机日期字符串(YYYY-MM-DD格式)
|
|
|
+ */
|
|
|
+ static generateRandomDate(startYear: number = 2024, endYear: number = 2025): string {
|
|
|
+ const year = Math.floor(Math.random() * (endYear - startYear + 1)) + startYear;
|
|
|
+ const month = Math.floor(Math.random() * 12) + 1;
|
|
|
+ const day = Math.floor(Math.random() * 28) + 1; // 简单处理,避免日期无效
|
|
|
+ return `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成随机金额(保留2位小数)
|
|
|
+ */
|
|
|
+ static generateRandomAmount(min: number = 1000, max: number = 10000): number {
|
|
|
+ const amount = Math.random() * (max - min) + min;
|
|
|
+ return Math.round(amount * 100) / 100;
|
|
|
+ }
|
|
|
+}
|