feat: harden CMPP delivery and platform workflows

This commit is contained in:
hectorzhao
2026-07-20 18:07:29 +08:00
parent 80fb5a8f53
commit f02c33cbb7
61 changed files with 1834 additions and 281 deletions
@@ -45,6 +45,11 @@ export class DictionariesController {
return this.dictionaries.createPhoneCarrierRule(body);
}
@Delete('phone-carrier-rules/:id')
deletePhoneCarrierRule(@Param('id') id: string) {
return this.dictionaries.deletePhoneCarrierRule(id);
}
@Get('sensitive-words')
listSensitiveWords(@Query('keyword') keyword?: string, @Query('status') status?: string) {
return this.dictionaries.listSensitiveWords({ keyword, status });
+28 -9
View File
@@ -1,4 +1,4 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { BadRequestException, ConflictException, Injectable } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
@@ -145,6 +145,10 @@ export class DictionariesService {
});
}
deletePhoneCarrierRule(id: string) {
return this.prisma.phoneCarrierRule.delete({ where: { id } });
}
listSensitiveWords(query: DictionaryListQuery = {}) {
return this.prisma.sensitiveWord.findMany({
where: {
@@ -191,13 +195,13 @@ export class DictionariesService {
}
async createGlobalBlacklist(data: CreateBlacklistDto) {
const created = await this.prisma.globalBlacklist.create({
data: {
phoneNumber: data.phoneNumber,
reason: data.reason,
status: data.status ?? 'active',
},
});
const created = await this.createBlacklistOrConflict(() => this.prisma.globalBlacklist.create({
data: {
phoneNumber: data.phoneNumber,
reason: data.reason,
status: data.status ?? 'active',
},
}), 'global');
await this.writeOperationLog(data.operatorId, 'global_blacklist.create', 'global_blacklist', created.id, {
phoneNumber: data.phoneNumber,
reason: data.reason,
@@ -252,7 +256,7 @@ export class DictionariesService {
reason: data.reason,
status: data.status ?? 'active',
};
const created = await this.prisma.enterpriseBlacklist.create({ data: createData });
const created = await this.createBlacklistOrConflict(() => this.prisma.enterpriseBlacklist.create({ data: createData }), 'enterprise');
await this.writeOperationLog(data.operatorId, 'enterprise_blacklist.create', 'enterprise_blacklist', created.id, {
tenantId: data.tenantId,
applicationId: data.applicationId,
@@ -269,6 +273,21 @@ export class DictionariesService {
return updated;
}
private async createBlacklistOrConflict<T>(operation: () => Promise<T>, scope: 'global' | 'enterprise') {
try {
return await operation();
} catch (error) {
if ((error as { code?: string }).code !== 'P2002') throw error;
throw new ConflictException({
code: 'BLACKLIST_DUPLICATE',
field: 'phoneNumber',
message: scope === 'global'
? '该手机号已存在于全局黑名单;停用或逻辑删除后请恢复原记录'
: '该手机号已存在于当前应用黑名单;停用或逻辑删除后请恢复原记录',
});
}
}
async listDrainageFields() {
const fields = await this.prisma.drainageField.findMany({
include: { _count: { select: { channelReportFields: true, commonReportFields: true } } },