fix: paginate operational list pages

This commit is contained in:
hectorzhao
2026-07-28 23:20:13 +08:00
parent 87c5b1eccc
commit b8560372cc
40 changed files with 1208 additions and 422 deletions
+147 -6
View File
@@ -122,6 +122,8 @@ export interface TemplateListQuery {
applicationKeyword?: string;
nameKeyword?: string;
contentKeyword?: string;
page?: number;
pageSize?: number;
}
export interface ApplicationListQuery {
@@ -131,6 +133,8 @@ export interface ApplicationListQuery {
applicationKeyword?: string;
status?: string;
includeConnections?: boolean;
page?: number;
pageSize?: number;
}
export interface SignatureListQuery {
@@ -141,6 +145,8 @@ export interface SignatureListQuery {
applicationKeyword?: string;
signatureKeyword?: string;
drainageKeyword?: string;
page?: number;
pageSize?: number;
}
export interface GatewayDownstreamConnectionEventDto {
@@ -205,7 +211,15 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
ipAllowlist: true,
httpConfig: true,
},
omit: {
secretHash: true,
passwordCipher: true,
},
orderBy: { createdAt: 'desc' },
...(query.page && query.pageSize ? {
skip: (query.page - 1) * query.pageSize,
take: query.pageSize,
} : {}),
});
if (!query.includeConnections) {
return applications;
@@ -243,6 +257,34 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
|| left.id.localeCompare(right.id));
}
async listApplicationsPage(query: ApplicationListQuery) {
const page = Math.max(1, Math.floor(Number(query.page) || 1));
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(query.pageSize) || 10)));
const where: Prisma.SmsApplicationWhereInput = {
tenantId: query.tenantId,
status: query.status && query.status !== 'all' ? query.status : { not: 'deleted' },
tenant: query.enterpriseKeyword ? { name: { contains: query.enterpriseKeyword } } : undefined,
name: query.applicationKeyword ? { contains: query.applicationKeyword } : undefined,
OR: query.keyword ? [
{ name: { contains: query.keyword } },
{ tenant: { name: { contains: query.keyword } } },
] : undefined,
};
const [items, total] = await Promise.all([
this.listApplications({ ...query, page, pageSize }),
this.prisma.smsApplication.count({ where }),
]);
return { items, total, page, pageSize };
}
listApplicationOptions(tenantId?: string) {
return this.prisma.smsApplication.findMany({
where: { tenantId, status: { not: 'deleted' } },
select: { id: true, tenantId: true, name: true, status: true },
orderBy: [{ name: 'asc' }, { id: 'asc' }],
});
}
async getApplication(applicationId: string, tenantId?: string) {
const application = await this.prisma.smsApplication.findUnique({
where: { id: applicationId },
@@ -905,6 +947,10 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
reportTasks: { include: { channel: true, drainageInfo: true } },
},
orderBy: { createdAt: 'desc' },
...(query.page && query.pageSize ? {
skip: (query.page - 1) * query.pageSize,
take: query.pageSize,
} : {}),
});
const applicationIds = signatures.map((signature) => signature.applicationId).filter((id): id is string => Boolean(id));
const routes = applicationIds.length ? await this.prisma.channelRouteRule.findMany({
@@ -979,9 +1025,60 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
});
}
async listClientSignatures(tenantId?: string, signatureId?: string) {
async listSignaturesPage(query: SignatureListQuery) {
const page = Math.max(1, Math.floor(Number(query.page) || 1));
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(query.pageSize) || 10)));
const where: Prisma.SmsSignatureWhereInput = {
tenantId: query.tenantId,
auditStatus: query.status && query.status !== 'all' ? query.status : { not: 'deleted' },
tenant: query.enterpriseKeyword ? { name: { contains: query.enterpriseKeyword } } : undefined,
application: query.applicationKeyword ? { name: { contains: query.applicationKeyword } } : undefined,
name: query.signatureKeyword ? { contains: query.signatureKeyword } : undefined,
drainageItems: query.drainageKeyword ? {
some: {
auditStatus: { not: 'deleted' },
OR: [
{ siteName: { contains: query.drainageKeyword } },
{ url: { contains: query.drainageKeyword } },
{ remark: { contains: query.drainageKeyword } },
],
},
} : undefined,
OR: query.keyword ? [
{ name: { contains: query.keyword } },
{ purpose: { contains: query.keyword } },
{ tenant: { name: { contains: query.keyword } } },
{ application: { name: { contains: query.keyword } } },
] : undefined,
};
const [items, total] = await Promise.all([
this.listSignatures({ ...query, page, pageSize }),
this.prisma.smsSignature.count({ where }),
]);
return { items, total, page, pageSize };
}
listSignatureOptions(tenantId?: string) {
return this.prisma.smsSignature.findMany({
where: { tenantId, auditStatus: { not: 'deleted' } },
select: { id: true, tenantId: true, applicationId: true, name: true, auditStatus: true },
orderBy: [{ name: 'asc' }, { id: 'asc' }],
});
}
async listClientSignatures(tenantId?: string, signatureId?: string, query: { keyword?: string; applicationId?: string; status?: string; page?: number; pageSize?: number } = {}) {
const signatures = await this.prisma.smsSignature.findMany({
where: { id: signatureId, tenantId, auditStatus: { notIn: ['deleted', 'disabled'] } },
where: {
id: signatureId,
tenantId,
applicationId: query.applicationId,
auditStatus: query.status || { notIn: ['deleted', 'disabled'] },
OR: query.keyword?.trim() ? [
{ name: { contains: query.keyword.trim() } },
{ purpose: { contains: query.keyword.trim() } },
{ application: { name: { contains: query.keyword.trim() } } },
] : undefined,
},
select: {
id: true,
tenantId: true,
@@ -1020,6 +1117,8 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
_count: { select: { reportMaterials: true } },
},
orderBy: { updatedAt: 'desc' },
skip: query.page && query.pageSize ? (query.page - 1) * query.pageSize : undefined,
take: query.pageSize,
});
return signatures.map((signature) => {
const stored = isRecord(signature.drainageInfo) ? signature.drainageInfo : {};
@@ -1056,9 +1155,22 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
return signature;
}
async getClientSignatureWorkspace(tenantId?: string) {
const [items, statusCounts] = await Promise.all([
this.listClientSignatures(tenantId),
async getClientSignatureWorkspace(tenantId?: string, query: { keyword?: string; applicationId?: string; status?: string; page?: number; pageSize?: number } = {}) {
const page = Math.max(1, Math.floor(Number(query.page) || 1));
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(query.pageSize) || 10)));
const filteredWhere: Prisma.SmsSignatureWhereInput = {
tenantId,
applicationId: query.applicationId,
auditStatus: query.status || { notIn: ['deleted', 'disabled'] },
OR: query.keyword?.trim() ? [
{ name: { contains: query.keyword.trim() } },
{ purpose: { contains: query.keyword.trim() } },
{ application: { name: { contains: query.keyword.trim() } } },
] : undefined,
};
const [items, total, statusCounts] = await Promise.all([
this.listClientSignatures(tenantId, undefined, { ...query, page, pageSize }),
this.prisma.smsSignature.count({ where: filteredWhere }),
this.prisma.smsSignature.groupBy({
by: ['auditStatus'],
where: { tenantId, auditStatus: { notIn: ['deleted', 'disabled'] } },
@@ -1073,7 +1185,7 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
summary[item.auditStatus as keyof Omit<typeof summary, 'total'>] = count;
}
}
return { items, summary };
return { items, summary, total, page, pageSize };
}
async listClientDrainageInfos(tenantId?: string, itemId?: string) {
@@ -1464,9 +1576,38 @@ export class SmsConfigService implements OnModuleInit, OnModuleDestroy {
},
include: { variables: true, application: true, tenant: true, signature: true },
orderBy: { createdAt: 'desc' },
...(query.page && query.pageSize ? {
skip: (query.page - 1) * query.pageSize,
take: query.pageSize,
} : {}),
});
}
async listTemplatesPage(query: TemplateListQuery) {
const page = Math.max(1, Math.floor(Number(query.page) || 1));
const pageSize = Math.min(100, Math.max(1, Math.floor(Number(query.pageSize) || 10)));
const where: Prisma.SmsTemplateWhereInput = {
tenantId: query.tenantId,
auditStatus: query.status && query.status !== 'all' ? query.status : { not: 'deleted' },
tenant: query.enterpriseKeyword ? { name: { contains: query.enterpriseKeyword } } : undefined,
application: query.applicationKeyword ? { name: { contains: query.applicationKeyword } } : undefined,
name: query.nameKeyword ? { contains: query.nameKeyword } : undefined,
content: query.contentKeyword ? { contains: query.contentKeyword } : undefined,
OR: query.keyword ? [
{ name: { contains: query.keyword } },
{ content: { contains: query.keyword } },
{ category: { contains: query.keyword } },
{ application: { name: { contains: query.keyword } } },
{ tenant: { name: { contains: query.keyword } } },
] : undefined,
};
const [items, total] = await Promise.all([
this.listTemplates({ ...query, page, pageSize }),
this.prisma.smsTemplate.count({ where }),
]);
return { items, total, page, pageSize };
}
listClientTemplates(tenantId: string | undefined, includeHistory = false) {
return this.listTemplates({ tenantId, status: includeHistory ? 'all' : 'approved' });
}