forked from admin/deShanXiao
114 lines
3.1 KiB
TypeScript
114 lines
3.1 KiB
TypeScript
import { getConnection, Between, Brackets } from "typeorm";
|
||
import { Request } from "express";
|
||
|
||
type paginationType<T> = {
|
||
list: T[];
|
||
total: number;
|
||
pageSize: number;
|
||
pageNumber: number;
|
||
};
|
||
|
||
const filterKeys = ["pwd"];
|
||
const DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
||
|
||
export default async function getBuilderPagination<T>(
|
||
entity: Function,
|
||
req: Request,
|
||
queryParams?: { [key: string]: any }
|
||
): Promise<paginationType<T>> {
|
||
try {
|
||
// 获取分页参数
|
||
const { pageSize, pageNumber } = getPaginationParams(req);
|
||
const repository = getConnection().manager.getRepository(entity);
|
||
const alias = "entity";
|
||
|
||
// 创建 QueryBuilder
|
||
const queryBuilder = repository.createQueryBuilder(alias);
|
||
// 处理查询参数
|
||
if (queryParams) {
|
||
Object.entries(queryParams).forEach(([key, value]) => {
|
||
if (!["pageSize", "pageNumber"].includes(key)) {
|
||
// 新增非空条件处理
|
||
if (value === "NOT_EMPTY") {
|
||
queryBuilder.andWhere(
|
||
new Brackets((qb) => {
|
||
qb.where(`${alias}.${key} IS NOT NULL`).andWhere(
|
||
`${alias}.${key} != ''`
|
||
);
|
||
})
|
||
);
|
||
}
|
||
// 处理日期范围
|
||
else if (typeof value === "string" && DATE_REGEX.test(value)) {
|
||
const start = new Date(`${value}T00:00:00`);
|
||
const end = new Date(`${value}T23:59:59`);
|
||
queryBuilder.andWhere(
|
||
new Brackets((qb) =>
|
||
qb
|
||
.where(`${alias}.${key} >= :start`, { start })
|
||
.andWhere(`${alias}.${key} <= :end`, { end })
|
||
)
|
||
);
|
||
}
|
||
// 处理普通参数
|
||
else if (value !== undefined) {
|
||
// 处理数组参数(如?status=1,2,3)
|
||
if (typeof value === "string" && value.includes(",")) {
|
||
queryBuilder.andWhere(`${alias}.${key} IN (:...${key})`, {
|
||
[key]: value.split(","),
|
||
});
|
||
}
|
||
// 处理普通值
|
||
else {
|
||
queryBuilder.andWhere(`${alias}.${key} = :${key}`, {
|
||
[key]: value,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// 添加排序
|
||
queryBuilder.orderBy(`${alias}.createDate`, "DESC");
|
||
|
||
// 执行分页查询
|
||
const [list, total] = await queryBuilder
|
||
.skip((pageNumber - 1) * pageSize)
|
||
.take(pageSize)
|
||
.getManyAndCount();
|
||
|
||
// 过滤敏感字段
|
||
const filteredList = list.map((item: any) => {
|
||
const filtered = { ...item };
|
||
filterKeys.forEach((key) => delete filtered[key]);
|
||
return filtered;
|
||
});
|
||
|
||
return {
|
||
list: filteredList,
|
||
total,
|
||
pageSize,
|
||
pageNumber,
|
||
};
|
||
} catch (err) {
|
||
throw new Error(`分页查询出错: ${err.message}`);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取分页参数
|
||
*/
|
||
function getPaginationParams(req: Request): {
|
||
pageSize: number;
|
||
pageNumber: number;
|
||
} {
|
||
const { pageSize = 10, pageNumber = 1 } =
|
||
req.method === "GET" ? req.query : req.body;
|
||
|
||
return {
|
||
pageSize: Math.max(1, parseInt(pageSize as string, 10)),
|
||
pageNumber: Math.max(1, parseInt(pageNumber as string, 10)),
|
||
};
|
||
}
|