170 lines
5.6 KiB
TypeScript
170 lines
5.6 KiB
TypeScript
import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
|
|
import { ApiTags } from '@nestjs/swagger';
|
|
import { CurrentSessionUserId } from '../auth/current-session-user.decorator';
|
|
import { SendChainService } from '../send-chain/send-chain.service';
|
|
import {
|
|
BatchReviewSmsTasksDto,
|
|
CreateRiskRuleDto,
|
|
ReviewSmsTaskDto,
|
|
RiskReviewService,
|
|
} from './risk-review.service';
|
|
import {
|
|
CreatePhoneFrequencyWhitelistDto,
|
|
PhoneFrequencyService,
|
|
UpdatePhoneFrequencyWhitelistDto,
|
|
} from './phone-frequency.service';
|
|
|
|
@ApiTags('risk-review')
|
|
@Controller('admin/risk-review')
|
|
export class AdminRiskReviewController {
|
|
constructor(
|
|
private readonly riskReview: RiskReviewService,
|
|
private readonly sendChain: SendChainService,
|
|
private readonly phoneFrequency: PhoneFrequencyService,
|
|
) {}
|
|
|
|
@Get('rules')
|
|
listRules(@Query('applicationId') applicationId?: string) {
|
|
return this.riskReview.listRules(applicationId);
|
|
}
|
|
|
|
@Post('rules')
|
|
createRule(@Body() body: CreateRiskRuleDto) {
|
|
return this.riskReview.createRule(body);
|
|
}
|
|
|
|
@Put('rules/:id')
|
|
updateRule(@Param('id') ruleId: string, @Body() body: Partial<CreateRiskRuleDto>) {
|
|
return this.riskReview.updateRule(ruleId, body);
|
|
}
|
|
|
|
@Get('hits')
|
|
listHits(@Query('tenantId') tenantId?: string, @Query('taskId') taskId?: string) {
|
|
return this.riskReview.listHits(tenantId, taskId);
|
|
}
|
|
|
|
@Get('phone-frequency-hits')
|
|
listPhoneFrequencyHits(
|
|
@Query('tenantId') tenantId?: string,
|
|
@Query('applicationId') applicationId?: string,
|
|
@Query('phoneNumber') phoneNumber?: string,
|
|
@Query('status') status?: 'active' | 'expired' | 'released',
|
|
@Query('createdAtFrom') createdAtFrom?: string,
|
|
@Query('createdAtTo') createdAtTo?: string,
|
|
@Query('page') page?: string,
|
|
@Query('pageSize') pageSize?: string,
|
|
) {
|
|
return this.phoneFrequency.listHits({
|
|
tenantId,
|
|
applicationId,
|
|
phoneNumber,
|
|
status,
|
|
createdAtFrom,
|
|
createdAtTo,
|
|
page: Number(page ?? 1),
|
|
pageSize: Number(pageSize ?? 20),
|
|
});
|
|
}
|
|
|
|
@Post('phone-frequency-hits/:id/release')
|
|
releasePhoneFrequencyHit(
|
|
@Param('id') hitId: string,
|
|
@Body() body: { reason?: string },
|
|
@CurrentSessionUserId() reviewerId?: string,
|
|
) {
|
|
return this.phoneFrequency.releaseHit(hitId, reviewerId, body.reason);
|
|
}
|
|
|
|
@Get('phone-frequency-whitelist')
|
|
listPhoneFrequencyWhitelist(
|
|
@Query('phoneNumber') phoneNumber?: string,
|
|
@Query('keyword') keyword?: string,
|
|
@Query('status') status?: 'active' | 'inactive' | 'deleted',
|
|
@Query('updatedAtFrom') updatedAtFrom?: string,
|
|
@Query('updatedAtTo') updatedAtTo?: string,
|
|
@Query('page') page?: string,
|
|
@Query('pageSize') pageSize?: string,
|
|
) {
|
|
return this.phoneFrequency.listWhitelist({
|
|
phoneNumber,
|
|
keyword,
|
|
status,
|
|
updatedAtFrom,
|
|
updatedAtTo,
|
|
page: Number(page ?? 1),
|
|
pageSize: Number(pageSize ?? 20),
|
|
});
|
|
}
|
|
|
|
@Post('phone-frequency-whitelist')
|
|
createPhoneFrequencyWhitelist(
|
|
@Body() body: CreatePhoneFrequencyWhitelistDto,
|
|
@CurrentSessionUserId() operatorId?: string,
|
|
) {
|
|
return this.phoneFrequency.createWhitelist(body, operatorId);
|
|
}
|
|
|
|
@Put('phone-frequency-whitelist/:id')
|
|
updatePhoneFrequencyWhitelist(
|
|
@Param('id') id: string,
|
|
@Body() body: UpdatePhoneFrequencyWhitelistDto,
|
|
@CurrentSessionUserId() operatorId?: string,
|
|
) {
|
|
return this.phoneFrequency.updateWhitelist(id, body, operatorId);
|
|
}
|
|
|
|
@Delete('phone-frequency-whitelist/:id')
|
|
deletePhoneFrequencyWhitelist(
|
|
@Param('id') id: string,
|
|
@Body() body: { reason?: string },
|
|
@CurrentSessionUserId() operatorId?: string,
|
|
) {
|
|
return this.phoneFrequency.deleteWhitelist(id, operatorId, body.reason);
|
|
}
|
|
|
|
@Get('tasks')
|
|
listTasks(@Query('tenantId') tenantId?: string, @Query('status') status?: string, @Query('submittedAtFrom') submittedAtFrom?: string, @Query('submittedAtTo') submittedAtTo?: string) {
|
|
return this.riskReview.listTasks(tenantId, status, submittedAtFrom, submittedAtTo);
|
|
}
|
|
|
|
@Get('tasks/pending')
|
|
listPendingTasks() {
|
|
return this.riskReview.listPendingTasks();
|
|
}
|
|
|
|
@Get('tasks/:id/messages')
|
|
listTaskMessages(
|
|
@Param('id') taskId: string,
|
|
@Query('phone') phone?: string,
|
|
@Query('page') page?: string,
|
|
@Query('pageSize') pageSize?: string,
|
|
) {
|
|
return this.riskReview.listTaskMessages(taskId, phone, Number(page ?? 1), Number(pageSize ?? 20));
|
|
}
|
|
|
|
@Post('tasks/:id/approve')
|
|
async approveTask(@Param('id') taskId: string, @Body() body: ReviewSmsTaskDto, @CurrentSessionUserId() reviewerId?: string) {
|
|
const review = { ...body, reviewerId };
|
|
const task = await this.riskReview.approveTask(taskId, review);
|
|
await this.sendChain.handleReviewDecision(taskId, 'approved', body.reason ?? '运营审核通过');
|
|
return task;
|
|
}
|
|
|
|
@Post('tasks/batch/reject')
|
|
async rejectTasks(@Body() body: BatchReviewSmsTasksDto, @CurrentSessionUserId() reviewerId?: string) {
|
|
const tasks = await this.riskReview.rejectTasks({ ...body, reviewerId });
|
|
const reason = body.reason?.trim() ?? '';
|
|
for (const task of tasks) {
|
|
await this.sendChain.handleReviewDecision(task.id, 'rejected', reason);
|
|
}
|
|
return tasks;
|
|
}
|
|
|
|
@Post('tasks/:id/reject')
|
|
async rejectTask(@Param('id') taskId: string, @Body() body: ReviewSmsTaskDto, @CurrentSessionUserId() reviewerId?: string) {
|
|
const task = await this.riskReview.rejectTask(taskId, { ...body, reviewerId });
|
|
await this.sendChain.handleReviewDecision(taskId, 'rejected', body.reason ?? task.rejectReason ?? '运营审核驳回');
|
|
return task;
|
|
}
|
|
}
|