fix: reject CMPP daily limit synchronously

This commit is contained in:
hectorzhao
2026-07-22 17:09:44 +08:00
parent 66bc230d7e
commit 55019443c0
7 changed files with 112 additions and 20 deletions
+28 -10
View File
@@ -2028,9 +2028,12 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
throw new BadRequestException('CMPP account is invalid');
}
const dailyQuota = await this.tryReserveDailySendQuota(application.id, phoneNumbers.length);
const dailyLimitFailure = dailyQuota.reserved
const dailyLimitRejection = dailyQuota.reserved
? undefined
: `应用当日发送上限${dailyQuota.dailyLimit}条,本次${phoneNumbers.length}条超出剩余配额`;
: {
code: 'DAILY_LIMIT',
reason: `应用当日发送上限${dailyQuota.dailyLimit}条,本次${phoneNumbers.length}条超出剩余配额`,
};
const submitGroupMessageId = `MSG-${randomUUID()}`;
const submissions = phoneNumbers.map((phoneNumber, index) => ({
@@ -2045,11 +2048,12 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
...data,
phoneNumber: submission.phoneNumber,
phoneNumbers: undefined,
}, submission.messageId, submitGroupMessageId, dailyLimitFailure))));
}, submission.messageId, submitGroupMessageId, dailyLimitRejection))));
}
const first = results[0];
return {
...first,
result: dailyLimitRejection ? 8 : undefined,
phoneCount: results.length,
messages: results.map((result, index) => ({
phoneNumber: phoneNumbers[index],
@@ -2065,7 +2069,7 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
data: GatewayInboundSubmitDto & { phoneNumber: string },
messageId: string,
submitGroupMessageId: string,
dailyLimitFailure?: string,
synchronousRejection?: { code: string; reason: string },
) {
const application = await this.findInboundApplication(data.account);
if (!application) {
@@ -2098,7 +2102,9 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
sourceType: 'cmpp',
content: data.content,
phoneTotal: 1,
status: 'validating',
status: synchronousRejection ? 'rejected' : 'validating',
auditStatus: synchronousRejection ? 'rejected' : undefined,
rejectReason: synchronousRejection?.reason,
progressTotal: 1,
},
});
@@ -2110,7 +2116,7 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
sourceIp: data.remoteIp,
userAgent: 'cmpp-gateway',
payloadSummary: { phoneTotal: 1, contentLength: [...data.content].length, account: data.account },
status: 'accepted',
status: synchronousRejection ? 'rejected' : 'accepted',
},
});
const message = await this.prisma.smsMessageRecord.create({
@@ -2130,10 +2136,24 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
cmppSubmitGroupMessageId: submitGroupMessageId,
clientSrcId,
applicationExtension: application.cmppApplicationExtension,
status: 'validating',
status: synchronousRejection ? 'rejected' : 'validating',
errorCode: synchronousRejection?.code,
errorMessage: synchronousRejection?.reason,
},
});
if (synchronousRejection) {
return {
accepted: false,
tenantId: application.tenantId,
applicationId: application.id,
taskId: task.id,
messageId: message.messageId,
messageRecordId: message.id,
status: 'rejected',
};
}
const reject = async (code: string, reason: string) => {
await this.prisma.smsBatchTask.update({
where: { id: task.id },
@@ -2203,9 +2223,7 @@ export class SendChainService implements OnModuleInit, OnModuleDestroy {
});
await this.enqueueBatchTask(task.id);
};
if (dailyLimitFailure) {
await reject('DAILY_LIMIT', dailyLimitFailure);
} else if (application.status !== 'active' || application.tenant.status !== 'active') {
if (application.status !== 'active' || application.tenant.status !== 'active') {
await reject('ACCOUNT', '企业或短信应用已停用');
} else if (!application.interfaceEnabled) {
await reject('INTERFACE', '短信应用 CMPP 接口已停用');