feat: complete reporting and filing workflows
This commit is contained in:
@@ -12,6 +12,16 @@ export class AdminSendChainController {
|
||||
return this.sendChain.listBatchTasks(tenantId, status);
|
||||
}
|
||||
|
||||
@Get('batch-tasks/:id/messages')
|
||||
listBatchTaskMessages(
|
||||
@Param('id') taskId: string,
|
||||
@Query('phone') phone?: string,
|
||||
@Query('page') page?: string,
|
||||
@Query('pageSize') pageSize?: string,
|
||||
) {
|
||||
return this.sendChain.listAdminBatchTaskMessages(taskId, phone, Number(page), Number(pageSize));
|
||||
}
|
||||
|
||||
@Get('messages')
|
||||
listMessages(
|
||||
@Query('tenantId') tenantId?: string,
|
||||
|
||||
@@ -128,6 +128,7 @@ function createPrismaMock() {
|
||||
create: jest.fn().mockImplementation(({ data }) => Promise.resolve({ ...message, ...data })),
|
||||
createMany: jest.fn().mockResolvedValue({ count: 2 }),
|
||||
findMany: jest.fn().mockResolvedValue([{ id: 'record-1', batchTaskId: 'task-1' }]),
|
||||
count: jest.fn().mockResolvedValue(1),
|
||||
findUnique: jest.fn().mockResolvedValue(message),
|
||||
findFirst: jest.fn().mockResolvedValue(message),
|
||||
update: jest.fn().mockImplementation(({ data }) => Promise.resolve({ ...message, ...data })),
|
||||
@@ -790,6 +791,35 @@ describe('SendChainService', () => {
|
||||
expect(prisma.smsMessageRecord.findMany).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('paginates the real phone list for an admin batch task', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsBatchTask.findFirst.mockResolvedValue({ id: 'task-1', sourceType: 'client' });
|
||||
prisma.smsMessageRecord.findMany.mockResolvedValue([
|
||||
{ id: 'record-1', phoneNumber: '13800000001', province: '上海', carrier: 'mobile', status: 'delivered' },
|
||||
]);
|
||||
prisma.smsMessageRecord.count.mockResolvedValue(21);
|
||||
|
||||
await expect(service.listAdminBatchTaskMessages('task-1', '138', 2, 20)).resolves.toEqual({
|
||||
items: [expect.objectContaining({ phoneNumber: '13800000001' })],
|
||||
total: 21,
|
||||
page: 2,
|
||||
pageSize: 20,
|
||||
});
|
||||
expect(prisma.smsMessageRecord.findMany).toHaveBeenCalledWith({
|
||||
where: { batchTaskId: 'task-1', phoneNumber: { contains: '138' } },
|
||||
select: {
|
||||
id: true,
|
||||
phoneNumber: true,
|
||||
province: true,
|
||||
carrier: true,
|
||||
status: true,
|
||||
},
|
||||
orderBy: [{ queuedAt: 'asc' }, { id: 'asc' }],
|
||||
skip: 20,
|
||||
take: 20,
|
||||
});
|
||||
});
|
||||
|
||||
it('terminates non-final tasks by canceling unsubmitted messages', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsBatchTask.findUnique.mockResolvedValue({ id: 'task-1', status: 'sending' });
|
||||
|
||||
@@ -599,6 +599,39 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
|
||||
return this.listMessages({ tenantId, taskId });
|
||||
}
|
||||
|
||||
async listAdminBatchTaskMessages(taskId: string, phone?: string, page = 1, pageSize = 20) {
|
||||
const task = await this.prisma.smsBatchTask.findFirst({
|
||||
where: { id: taskId, sourceType: 'client' },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!task) {
|
||||
throw new NotFoundException('SMS batch task not found');
|
||||
}
|
||||
const normalizedPage = Math.max(1, Math.floor(Number(page) || 1));
|
||||
const normalizedPageSize = Math.min(100, Math.max(1, Math.floor(Number(pageSize) || 20)));
|
||||
const where: Prisma.SmsMessageRecordWhereInput = {
|
||||
batchTaskId: taskId,
|
||||
...(phone?.trim() ? { phoneNumber: { contains: phone.trim() } } : {}),
|
||||
};
|
||||
const [items, total] = await Promise.all([
|
||||
this.prisma.smsMessageRecord.findMany({
|
||||
where,
|
||||
select: {
|
||||
id: true,
|
||||
phoneNumber: true,
|
||||
province: true,
|
||||
carrier: true,
|
||||
status: true,
|
||||
},
|
||||
orderBy: [{ queuedAt: 'asc' }, { id: 'asc' }],
|
||||
skip: (normalizedPage - 1) * normalizedPageSize,
|
||||
take: normalizedPageSize,
|
||||
}),
|
||||
this.prisma.smsMessageRecord.count({ where }),
|
||||
]);
|
||||
return { items, total, page: normalizedPage, pageSize: normalizedPageSize };
|
||||
}
|
||||
|
||||
listMessages(query: {
|
||||
tenantId?: string;
|
||||
applicationId?: string;
|
||||
|
||||
Reference in New Issue
Block a user