import { HttpStatus } from '@nestjs/common'; import { plainToClass, plainToInstance } from 'class-transformer'; import { FilterOperator, FilterSuffix, Paginated } from 'nestjs-paginate'; import { Column } from 'nestjs-paginate/lib/helper'; import { SystemLang } from '../lang/system.lang'; export default class AppResponse { public static toResponse( data: any, options?: { message?: string; status_code?: number; bonus?: any }, ) { return { message: options?.message || (!Boolean(data) ? SystemLang.getText('messages', 'default_action') : SystemLang.getText('messages', 'success')), status_code: options?.status_code || (!Boolean(data) ? HttpStatus.BAD_REQUEST : 200), data: data, timestamp: new Date().toISOString(), ...(options?.bonus || {}), }; } public static plainToInStance(this: new (...args: any[]) => M, obj: M): M { return plainToClass(this, obj); } public static toPagination( { data, meta }: Paginated, transform = true, dtoClass?: new () => M, ) { let transformedData: any[] = data; if (transform && dtoClass) { transformedData = plainToInstance(dtoClass, data); } const currentPage = meta.currentPage ?? 1; const itemsPerPage = meta.itemsPerPage ?? 0; const totalItems = meta.totalItems ?? 0; const totalPages = meta.totalPages ?? 0; return this.toResponse(transformedData, { bonus: { current_page: currentPage, from: currentPage * itemsPerPage - (itemsPerPage - 1), to: currentPage * itemsPerPage > totalItems ? totalItems : currentPage * itemsPerPage, last_page: totalPages, per_page: itemsPerPage, total: totalItems, }, }); } public static processFilters( queryFilters: any, filterableColumns: { [key in Column | (string & {})]?: | (FilterOperator | FilterSuffix)[] | true; }, ): any { if (!queryFilters) return {}; const processedFilters = { ...queryFilters }; for (const key in queryFilters) { const value = queryFilters[key]; if (filterableColumns[key]) { const columnConfig = filterableColumns[key]; if (Array.isArray(columnConfig)) { for (const operator of columnConfig) { if ( operator === FilterOperator.ILIKE && !value.startsWith('$ilike') ) { processedFilters[key] = `$ilike:%${value}%`; // Thêm ký tự đại diện % break; } if (operator === FilterOperator.LTE && !value.startsWith('$lte')) { processedFilters[key] = `$lte:${value}`; break; } if (operator === FilterOperator.GTE && !value.startsWith('$gte')) { processedFilters[key] = `$gte:${value}`; break; } if (operator === FilterOperator.EQ && !value.startsWith('$eq')) { processedFilters[key] = `$eq:${value}`; break; } } } // Nếu cột chỉ có giá trị `true` (mặc định EQ) else if (columnConfig === true && !value.startsWith('$eq')) { processedFilters[key] = `$eq:${value}`; } } } return processedFilters; } }