From d4679f3733a6cb166b15966c175f7e1650742a38 Mon Sep 17 00:00:00 2001 From: tone <3341154833@qq.com> Date: Sun, 22 Jun 2025 23:26:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=8D=9A=E5=AE=A2=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=97=B6=E7=9A=84=E6=9D=83=E9=99=90=E6=8C=87=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/admin-web-blog.controller.ts | 5 +- .../admin/dto/admin-web/create-blog.dto.ts | 9 ++- tone-page-server/src/blog/blog.service.ts | 13 +++- .../web/blog/components/AddBlog.tsx | 60 +++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/tone-page-server/src/admin/controller/web/admin-web-blog.controller.ts b/tone-page-server/src/admin/controller/web/admin-web-blog.controller.ts index 9140462..8e9aab6 100644 --- a/tone-page-server/src/admin/controller/web/admin-web-blog.controller.ts +++ b/tone-page-server/src/admin/controller/web/admin-web-blog.controller.ts @@ -1,4 +1,5 @@ import { + BadRequestException, Body, Controller, Delete, @@ -12,7 +13,9 @@ import { import { AuthGuard } from '@nestjs/passport'; import { CreateBlogDto } from 'src/admin/dto/admin-web/create-blog.dto'; import { Role } from 'src/auth/role.enum'; +import { BlogPermission } from 'src/blog/Blog.Permission.enum'; import { BlogService } from 'src/blog/blog.service'; +import { Blog } from 'src/blog/entity/Blog.entity'; import { Roles } from 'src/common/decorators/role.decorator'; import { RolesGuard } from 'src/common/guard/roles.guard'; @@ -20,7 +23,7 @@ import { RolesGuard } from 'src/common/guard/roles.guard'; @UseGuards(AuthGuard('jwt'), RolesGuard) @Roles(Role.Admin) export class AdminWebBlogController { - constructor(private readonly adminWebBlogService: BlogService) {} + constructor(private readonly adminWebBlogService: BlogService) { } @Get() async list() { diff --git a/tone-page-server/src/admin/dto/admin-web/create-blog.dto.ts b/tone-page-server/src/admin/dto/admin-web/create-blog.dto.ts index c4977ff..4481d72 100644 --- a/tone-page-server/src/admin/dto/admin-web/create-blog.dto.ts +++ b/tone-page-server/src/admin/dto/admin-web/create-blog.dto.ts @@ -1,4 +1,5 @@ -import { IsString } from 'class-validator'; +import { IsEnum, IsString } from 'class-validator'; +import { BlogPermission } from 'src/blog/Blog.Permission.enum'; export class CreateBlogDto { @IsString() @@ -9,4 +10,10 @@ export class CreateBlogDto { @IsString() contentUrl: string; + + @IsEnum(BlogPermission, { each: true, message: '请求类型错误' }) + permissions: BlogPermission[]; + + @IsString() + password: string;// 允许空串 } diff --git a/tone-page-server/src/blog/blog.service.ts b/tone-page-server/src/blog/blog.service.ts index 5e4718b..f96b3b3 100644 --- a/tone-page-server/src/blog/blog.service.ts +++ b/tone-page-server/src/blog/blog.service.ts @@ -3,6 +3,8 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Blog } from './entity/Blog.entity'; import { Repository } from 'typeorm'; import { BlogComment } from './entity/BlogComment.entity'; +import { BlogPermission } from './Blog.Permission.enum'; +import { createHash } from 'crypto'; @Injectable() export class BlogService { @@ -11,7 +13,7 @@ export class BlogService { private readonly blogRepository: Repository, @InjectRepository(BlogComment) private readonly blogCommentRepository: Repository, - ) {} + ) { } async list() { return this.blogRepository.find({ @@ -22,7 +24,14 @@ export class BlogService { }); } - async create(blog: Partial) { + async create(dto: Partial & { password: string }) { + const { password, ...blog } = dto; + if (blog.permissions.includes(BlogPermission.ByPassword)) { + if (password) { + blog.password_hash = createHash('sha256').update(`${password}`).digest('hex'); + } + } + const newBlog = this.blogRepository.create(blog); return this.blogRepository.save(newBlog); } diff --git a/tone-page-web/app/console/(with-menu)/web/blog/components/AddBlog.tsx b/tone-page-web/app/console/(with-menu)/web/blog/components/AddBlog.tsx index 3a09425..7b869e3 100644 --- a/tone-page-web/app/console/(with-menu)/web/blog/components/AddBlog.tsx +++ b/tone-page-web/app/console/(with-menu)/web/blog/components/AddBlog.tsx @@ -1,6 +1,7 @@ 'use client' import { Button } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, @@ -12,6 +13,7 @@ import { import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { AdminApi } from "@/lib/api"; +import { BlogPermission } from "@/lib/types/Blog.Permission.enum"; import { useState } from "react"; import { toast } from "sonner"; @@ -20,12 +22,29 @@ interface AddBlogProps { onRefresh: () => void; } +const blogPermissions = [ + { + permission: BlogPermission.Public, + localText: '公开可读', + }, + { + permission: BlogPermission.ByPassword, + localText: '受密码保护', + }, + { + permission: BlogPermission.List, + localText: '显示在列表中', + }, +] as const; + export default function AddBlog({ children, onRefresh }: AddBlogProps) { const [open, setOpen] = useState(false); const [blog, setBlog] = useState({ title: "", description: "", contentUrl: "", + permissions: [] as BlogPermission[], + password: "", }); const handleSubmit = async () => { @@ -41,6 +60,8 @@ export default function AddBlog({ children, onRefresh }: AddBlogProps) { title: '', description: '', contentUrl: '', + permissions: [], + password: '', }) } else { throw new Error(); @@ -93,6 +114,45 @@ export default function AddBlog({ children, onRefresh }: AddBlogProps) { onChange={(e) => setBlog({ ...blog, contentUrl: e.target.value })} /> +
+ +
+ { + blogPermissions.map((v, i) => ( +
+ { + setBlog({ + ...blog, + permissions: newChecked ? + [...blog.permissions, v.permission] : + [...blog.permissions].filter(p => p !== v.permission), + }) + }} /> + +
+ )) + } +
+
+ { + blog.permissions.includes(BlogPermission.ByPassword) && +
+ + setBlog({ ...blog, password: e.target.value })} + /> +
+ }