fix: enforce application limits and signature format

This commit is contained in:
hectorzhao
2026-07-22 16:29:22 +08:00
parent cd085d2712
commit a09036c67b
20 changed files with 479 additions and 79 deletions
+18 -6
View File
@@ -385,7 +385,7 @@ export class SmsConfigService {
interfaceType,
cmppMaxConnections: getPositiveInteger(data.cmppMaxConnections, 1, 'cmppMaxConnections'),
cmppWindowSize: getPositiveInteger(data.cmppWindowSize, 16, 'cmppWindowSize'),
dailyLimit: data.dailyLimit,
dailyLimit: getPositiveInteger(data.dailyLimit, 100000, 'dailyLimit'),
customerUnitPrice: data.customerUnitPrice ?? 0,
queuePriority,
maxPhonesPerTask: data.maxPhonesPerTask ?? 1000000,
@@ -452,7 +452,7 @@ export class SmsConfigService {
interfaceType,
cmppMaxConnections: data.cmppMaxConnections === undefined ? undefined : getPositiveInteger(data.cmppMaxConnections, 1, 'cmppMaxConnections'),
cmppWindowSize: data.cmppWindowSize === undefined ? undefined : getPositiveInteger(data.cmppWindowSize, 16, 'cmppWindowSize'),
dailyLimit: data.dailyLimit,
dailyLimit: data.dailyLimit === undefined ? undefined : getPositiveInteger(data.dailyLimit, 100000, 'dailyLimit'),
customerUnitPrice: data.customerUnitPrice,
queuePriority,
maxPhonesPerTask: data.maxPhonesPerTask,
@@ -799,6 +799,7 @@ export class SmsConfigService {
}));
return {
...signature,
name: normalizeSmsSignature(signature.name),
drainageInfo: { ...legacyPayload, links: drainageLinks },
reportTargets: (() => {
const channels = routes.filter((route) => route.applicationId === signature.applicationId && route.group).flatMap((route) => route.group!.items.map((item) => item.channel)).filter((channel) => channel.status !== 'deleted');
@@ -894,7 +895,7 @@ export class SmsConfigService {
id: signature.id,
tenantId: signature.tenantId,
applicationId: signature.applicationId,
name: signature.name,
name: normalizeSmsSignature(signature.name),
purpose: signature.purpose,
auditStatus: signature.auditStatus,
reportStatus: signature.reportStatus,
@@ -977,11 +978,12 @@ export class SmsConfigService {
async createSignature(data: CreateSmsSignatureDto, options: CreateSmsSignatureOptions = {}) {
await this.validateSignatureReportValues(data.applicationId, data.drainageInfo);
const drainageInfo = await this.withReportRequirementSnapshot(data.applicationId, data.drainageInfo);
const name = validateCompleteSmsSignature(data.name);
const signature = await this.prisma.smsSignature.create({
data: {
tenantId: data.tenantId,
applicationId: data.applicationId,
name: data.name,
name,
purpose: data.purpose,
auditStatus: options.initialAuditStatus,
drainageInfo: drainageInfo as Prisma.InputJsonValue | undefined,
@@ -1011,8 +1013,9 @@ export class SmsConfigService {
const drainageInfo = data.drainageInfo
? await this.withReportRequirementSnapshot(applicationId, data.drainageInfo)
: undefined;
const name = data.name === undefined ? undefined : validateCompleteSmsSignature(data.name);
const materialChanged = (data.applicationId !== undefined && data.applicationId !== signature.applicationId)
|| (data.name !== undefined && normalizeSmsSignature(data.name) !== normalizeSmsSignature(signature.name))
|| (name !== undefined && name !== normalizeSmsSignature(signature.name))
|| (data.purpose !== undefined && data.purpose !== signature.purpose)
|| (data.drainageInfo !== undefined && JSON.stringify(data.drainageInfo) !== JSON.stringify(signature.drainageInfo ?? null));
const auditStatus = materialChanged && signature.auditStatus === 'approved' ? 'pending' : data.auditStatus;
@@ -1020,7 +1023,7 @@ export class SmsConfigService {
where: { id: signatureId },
data: {
applicationId: data.applicationId,
name: data.name,
name,
purpose: data.purpose,
auditStatus,
rejectReason: auditStatus === 'pending' ? null : undefined,
@@ -1728,6 +1731,15 @@ function normalizeSmsSignature(name: string) {
return innerName ? `${innerName}` : '';
}
function validateCompleteSmsSignature(name: string) {
const value = name.trim();
const match = value.match(/^【([^【】]+)】$/);
if (!match || match[1] !== match[1].trim()) {
throw new BadRequestException('短信签名必须包含完整中文黑括号,例如:【某某科技】');
}
return value;
}
function startOfToday() {
const date = new Date();
date.setHours(0, 0, 0, 0);