112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
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<M>(this: new (...args: any[]) => M, obj: M): M {
|
|
return plainToClass(this, obj);
|
|
}
|
|
|
|
public static toPagination<M>(
|
|
{ data, meta }: Paginated<M>,
|
|
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<T>(
|
|
queryFilters: any,
|
|
filterableColumns: {
|
|
[key in Column<T> | (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;
|
|
}
|
|
}
|