nestapp/src/modules/database/utils.ts
2025-06-02 19:21:24 +08:00

83 lines
2.6 KiB
TypeScript

import { isArray, isNil } from 'lodash';
import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';
import { OrderQueryType, PaginateOptions, PaginateReturn } from '@/modules/database/types';
export const paginate = async <T extends ObjectLiteral>(
qb: SelectQueryBuilder<T>,
options: PaginateOptions,
): Promise<PaginateReturn<T>> => {
const limit = isNil(options.limit) || options.limit < 1 ? 1 : options.limit;
const page = isNil(options.page) || options.page < 1 ? 1 : options.page;
const start = page >= 1 ? page - 1 : 0;
const totalItems = await qb.getCount();
qb.take(limit).skip(start * limit);
const items = await qb.getMany();
const totalPages =
totalItems % limit === 0
? Math.floor(totalItems / limit)
: Math.floor(totalItems / limit) + 1;
const remainder = totalItems % limit === 0 ? limit : totalItems % limit;
const itemCount = page < totalPages ? limit : remainder;
return {
items,
meta: {
totalItems,
itemCount,
perPage: limit,
totalPages,
currentPage: page,
},
};
};
export function treePaginate<T extends ObjectLiteral>(
options: PaginateOptions,
data: T[],
): PaginateReturn<T> {
const { page, limit } = options;
let items: T[] = [];
const totalItems = data.length;
const totalRst = totalItems / limit;
const totalPages =
totalRst > Math.floor(totalRst) ? Math.floor(totalRst) + 1 : Math.floor(totalRst);
let itemCount = 0;
if (page <= totalPages) {
itemCount = page === totalPages ? totalItems - (totalPages - 1) * limit : limit;
const start = (page - 1) * limit;
items = data.slice(start, start + itemCount);
}
return {
meta: {
itemCount,
totalItems,
perPage: limit,
totalPages,
currentPage: page,
},
items,
};
}
export const getOrderByQuery = <T extends ObjectLiteral>(
qb: SelectQueryBuilder<T>,
alias: string,
orderBy?: OrderQueryType,
) => {
if (isNil(orderBy)) {
return qb;
}
if (typeof orderBy === 'string') {
return qb.orderBy(`${alias}.${orderBy}`, 'DESC');
}
if (isArray(orderBy)) {
for (const item of orderBy) {
typeof item === 'string'
? qb.addOrderBy(`${alias}.${item}`, 'DESC')
: qb.addOrderBy(`${alias}.${item.name}`, item.order);
}
return qb;
}
return qb.orderBy(`${alias}.${(orderBy as any).name}`, (orderBy as any).order);
};