博客评论限流5/min,添加前端错误处理
This commit is contained in:
@@ -3,23 +3,25 @@ import {
|
|||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
|
Ip,
|
||||||
Param,
|
Param,
|
||||||
ParseUUIDPipe,
|
ParseUUIDPipe,
|
||||||
Post,
|
Post,
|
||||||
Request,
|
Req,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { BlogService } from './blog.service';
|
import { BlogService } from './blog.service';
|
||||||
import { OptionalAuthGuard } from 'src/auth/strategies/OptionalAuthGuard';
|
import { OptionalAuthGuard } from 'src/auth/strategies/OptionalAuthGuard';
|
||||||
import { UserService } from 'src/user/user.service';
|
import { UserService } from 'src/user/user.service';
|
||||||
import { createBlogCommentDto } from './dto/create.blogcomment.dto';
|
import { createBlogCommentDto } from './dto/create.blogcomment.dto';
|
||||||
|
import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
|
||||||
|
|
||||||
@Controller('blog')
|
@Controller('blog')
|
||||||
export class BlogController {
|
export class BlogController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly blogService: BlogService,
|
private readonly blogService: BlogService,
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
getBlogs() {
|
getBlogs() {
|
||||||
@@ -54,25 +56,22 @@ export class BlogController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 该接口允许匿名评论,但仍需验证userId合法性
|
// 该接口允许匿名评论,但仍需验证userId合法性
|
||||||
@UseGuards(OptionalAuthGuard)
|
@UseGuards(ThrottlerGuard, OptionalAuthGuard)
|
||||||
|
@Throttle({ default: { limit: 5, ttl: 60000 } })
|
||||||
@Post(':id/comment')
|
@Post(':id/comment')
|
||||||
async createBlogComment(
|
async createBlogComment(
|
||||||
@Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
|
@Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
|
||||||
@Body() commentData: createBlogCommentDto,
|
@Body() commentData: createBlogCommentDto,
|
||||||
@Request() req,
|
@Req() req,
|
||||||
|
@Ip() ip,
|
||||||
) {
|
) {
|
||||||
const { userId } = req.user || {};
|
const { userId } = req.user || {};
|
||||||
const blog = await this.blogService.findById(id);
|
const blog = await this.blogService.findById(id);
|
||||||
if (!blog) throw new BadRequestException('文章不存在');
|
if (!blog) throw new BadRequestException('文章不存在');
|
||||||
|
|
||||||
const user = userId ? await this.userService.findOne({ userId }) : null;
|
const user = userId ? await this.userService.findById(userId) : null;
|
||||||
|
|
||||||
// 获取IP归属地
|
// 获取IP归属地
|
||||||
const ip =
|
|
||||||
req.ip ||
|
|
||||||
req.socket.remoteAddress ||
|
|
||||||
req.headers['x-forwarded-for'] ||
|
|
||||||
'未知';
|
|
||||||
let address = '未知';
|
let address = '未知';
|
||||||
if (!['::1'].includes(ip)) {
|
if (!['::1'].includes(ip)) {
|
||||||
const addressRes = await (
|
const addressRes = await (
|
||||||
|
|||||||
@@ -32,12 +32,20 @@ export function BlogCommentTool({ blogId, onInsertComment, replayTarget, handleC
|
|||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
if (comment.trim().length === 0) return;
|
if (comment.trim().length === 0) return;
|
||||||
const res = await BlogApi.createComment(blogId, comment, replayTarget ? replayTarget.id : undefined);
|
|
||||||
if (res) {
|
try {
|
||||||
toast.success('发布成功');
|
const res = await BlogApi.createComment(blogId, comment, replayTarget ? replayTarget.id : undefined);
|
||||||
setComment('');
|
if (res) {
|
||||||
onInsertComment(res);
|
toast.success('发布成功');
|
||||||
handleClearReplayTarget();
|
setComment('');
|
||||||
|
onInsertComment(res);
|
||||||
|
handleClearReplayTarget();
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.statusCode === 429) {
|
||||||
|
return toast.error('操作太频繁了,稍后再试吧')
|
||||||
|
}
|
||||||
|
toast.error('发布失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user