feat: 创建博客支持slug字段了
This commit is contained in:
@@ -5,6 +5,9 @@ export class CreateBlogDto {
|
||||
@IsString()
|
||||
title: string;
|
||||
|
||||
@IsString()
|
||||
slug: string;// 允许空串,但如果为空则需要手动设置为null,防止数据库唯一键冲突
|
||||
|
||||
@IsString()
|
||||
description: string;
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ export class BlogService {
|
||||
.digest('hex');
|
||||
}
|
||||
}
|
||||
if (typeof blog.slug === 'string' && blog.slug.trim().length === 0) {
|
||||
blog.slug = null;
|
||||
}
|
||||
|
||||
const newBlog = this.blogRepository.create(blog);
|
||||
return this.blogRepository.save(newBlog);
|
||||
|
||||
@@ -27,12 +27,37 @@ export default function AddBlog({ children, onRefresh }: AddBlogProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [blog, setBlog] = useState({
|
||||
title: "",
|
||||
slug: "",
|
||||
description: "",
|
||||
contentUrl: "",
|
||||
permissions: [] as BlogPermission[],
|
||||
password: "",
|
||||
});
|
||||
|
||||
const handleCopyShareURL = () => {
|
||||
const slug = blog.slug.trim();
|
||||
if (slug.length === 0) {
|
||||
return toast.warning('请先填写Slug')
|
||||
}
|
||||
|
||||
let url = `${window.location.origin}/blog/${slug}`;
|
||||
|
||||
const password = blog.password.trim();
|
||||
if (blog.permissions.includes(BlogPermission.ByPassword)) {
|
||||
if (password.length === 0) {
|
||||
return toast.warning('开启了密码保护,但没有填写有效的密码,无法生成有效URL')
|
||||
} else {
|
||||
url += `?p=${blog.password.trim()}`;
|
||||
}
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(url).then(() => {
|
||||
toast.success('复制成功');
|
||||
}, () => {
|
||||
toast.error('复制失败,请手动复制');
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
const res = await AdminAPI.createBlog({
|
||||
@@ -44,6 +69,7 @@ export default function AddBlog({ children, onRefresh }: AddBlogProps) {
|
||||
toast.success("添加成功");
|
||||
setBlog({
|
||||
title: '',
|
||||
slug: '',
|
||||
description: '',
|
||||
contentUrl: '',
|
||||
permissions: [],
|
||||
@@ -92,6 +118,17 @@ export default function AddBlog({ children, onRefresh }: AddBlogProps) {
|
||||
onChange={(e) => setBlog({ ...blog, description: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="slug" className="text-right">
|
||||
Slug
|
||||
</Label>
|
||||
<Input
|
||||
id="slug"
|
||||
className="col-span-3"
|
||||
value={blog.slug}
|
||||
onChange={(e) => setBlog({ ...blog, slug: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="contentUrl" className="text-right">
|
||||
文章URL
|
||||
@@ -136,9 +173,14 @@ export default function AddBlog({ children, onRefresh }: AddBlogProps) {
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button type="button" variant='secondary' onClick={() => setOpen(false)}>取消</Button>
|
||||
<Button type="button" onClick={handleSubmit}>保存</Button>
|
||||
<DialogFooter >
|
||||
<div className="flex justify-between w-full">
|
||||
<Button type="button" variant='outline' onClick={handleCopyShareURL}>复制分享链接</Button>
|
||||
<div>
|
||||
<Button type="button" variant='secondary' onClick={() => setOpen(false)}>取消</Button>
|
||||
<Button type="button" onClick={handleSubmit}>保存</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { clientFetch } from "../client";
|
||||
import { Blog } from "@/lib/types/blog";
|
||||
import { BlogPermission } from "@/lib/types/Blog.Permission.enum";
|
||||
import { Role } from "@/lib/types/role";
|
||||
import { APIError } from "../common";
|
||||
|
||||
export interface UserEntity {
|
||||
userId: string;
|
||||
@@ -87,9 +88,28 @@ export async function updateResource(id: string, data: UpdateResourceParams) {
|
||||
interface CreateBlogParams {
|
||||
title: string;
|
||||
description: string;
|
||||
slug: string;
|
||||
contentUrl: string;
|
||||
permissions: BlogPermission[];
|
||||
password: string;
|
||||
}
|
||||
export async function createBlog(data: CreateBlogParams) {
|
||||
data.title = data.title.trim()
|
||||
data.description = data.description.trim()
|
||||
data.slug = data.slug.trim()
|
||||
data.contentUrl = data.contentUrl.trim()
|
||||
data.password = data.password.trim()
|
||||
|
||||
if (data.title.length === 0) {
|
||||
throw new APIError('标题不得为空')
|
||||
}
|
||||
if (data.description.length === 0) {
|
||||
throw new APIError('描述不得为空')
|
||||
}
|
||||
if (data.contentUrl.length === 0) {
|
||||
throw new APIError('文章链接不得为空')
|
||||
}
|
||||
|
||||
return clientFetch<Blog>('/api/admin/web/blog', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
|
||||
Reference in New Issue
Block a user