From 5695c59a0136626e4f619be4720a03055da39456 Mon Sep 17 00:00:00 2001 From: longdayi <13477510+longdayilongdayi@user.noreply.gitee.com> Date: Sun, 26 Jan 2025 19:36:54 +0800 Subject: [PATCH 1/2] 01261936 --- .../models/post/detail/PostCommentEditor.tsx | 8 +++++--- .../models/post/detail/PostHeader/Content.tsx | 3 +-- .../models/post/detail/PostResources.tsx | 20 ++++++++++++------- .../post/editor/form/LetterBasicForm.tsx | 2 +- packages/common/prisma/schema.prisma | 20 +++++++++---------- packages/utils/src/index.ts | 7 ++++++- 6 files changed, 36 insertions(+), 24 deletions(-) diff --git a/apps/web/src/components/models/post/detail/PostCommentEditor.tsx b/apps/web/src/components/models/post/detail/PostCommentEditor.tsx index 1cebbdd..f33d545 100644 --- a/apps/web/src/components/models/post/detail/PostCommentEditor.tsx +++ b/apps/web/src/components/models/post/detail/PostCommentEditor.tsx @@ -9,6 +9,7 @@ import toast from "react-hot-toast"; import { isContentEmpty } from "./utils"; import { SendOutlined } from "@ant-design/icons"; import { TusUploader } from "@web/src/components/common/uploader/TusUploader"; +import { useEntity } from '../../../../../../../packages/client/src/api/hooks/useEntity'; const { TabPane } = Tabs; @@ -17,8 +18,8 @@ export default function PostCommentEditor() { const [content, setContent] = useState(""); const [isPreview, setIsPreview] = useState(false); const [fileIds, setFileIds] = useState([]); - const { create } = usePost(); - + // const { create } = usePost(); + const {create}=useEntity("post") const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (isContentEmpty(content)) { @@ -30,7 +31,7 @@ export default function PostCommentEditor() { await create.mutateAsync({ data: { type: PostType.POST_COMMENT, - + parentId: post?.id, content: content, resources: { @@ -38,6 +39,7 @@ export default function PostCommentEditor() { fileId: id, })), }, + }, }); toast.success("发布成功!"); diff --git a/apps/web/src/components/models/post/detail/PostHeader/Content.tsx b/apps/web/src/components/models/post/detail/PostHeader/Content.tsx index 0dd9ac6..cc75d39 100644 --- a/apps/web/src/components/models/post/detail/PostHeader/Content.tsx +++ b/apps/web/src/components/models/post/detail/PostHeader/Content.tsx @@ -1,7 +1,6 @@ import { useContext } from "react"; import { useState, useRef, useEffect } from "react"; import { PostDetailContext } from "../context/PostDetailContext"; -import { motion } from "framer-motion"; import { StatsSection } from "./StatsSection"; import PostResources from "../PostResources"; @@ -10,7 +9,7 @@ export default function Content() { const [isExpanded, setIsExpanded] = useState(false); const contentWrapperRef = useRef(null); const [shouldCollapse, setShouldCollapse] = useState(false); - const maxHeight = 125; + useEffect(() => { if (contentWrapperRef.current) { const shouldCollapse = contentWrapperRef.current.scrollHeight > 150; diff --git a/apps/web/src/components/models/post/detail/PostResources.tsx b/apps/web/src/components/models/post/detail/PostResources.tsx index 328bae4..306bfb8 100644 --- a/apps/web/src/components/models/post/detail/PostResources.tsx +++ b/apps/web/src/components/models/post/detail/PostResources.tsx @@ -4,7 +4,9 @@ import { DownloadOutlined } from "@ant-design/icons"; import { PostDto } from "@nice/common"; import { env } from "@web/src/env"; import { getFileIcon } from "./utils"; -import { formatFileSize } from '@nice/utils'; +import { formatFileSize, getCompressedImageUrl } from '@nice/utils'; + + export default function PostResources({ post }: { post: PostDto }) { const { resources } = useMemo(() => { if (!post?.resources) return { resources: [] }; @@ -12,13 +14,16 @@ export default function PostResources({ post }: { post: PostDto }) { const isImage = (url: string) => /\.(png|jpg|jpeg|gif|webp)$/i.test(url); - const sortedResources = post.resources - .map((resource) => ({ + const sortedResources = post.resources.map(resource => { + const original = `http://${env.SERVER_IP}/uploads/${resource.url}` + const isImg = isImage(resource.url) + return { ...resource, - url: `http://${env.SERVER_IP}/uploads/${resource.url}`, - isImage: isImage(resource.url), - })) - .sort((a, b) => (a.isImage === b.isImage ? 0 : a.isImage ? -1 : 1)); + url: isImg ? getCompressedImageUrl(original) : original, + originalUrl: original, + isImage: isImg + } + }).sort((a, b) => a.isImage === b.isImage ? 0 : a.isImage ? -1 : 1) return { resources: sortedResources }; }, [post]); @@ -46,6 +51,7 @@ export default function PostResources({ post }: { post: PostDto }) { src={resource.url} alt={resource.title} preview={{ + src: resource.originalUrl, mask: (
点击预览 diff --git a/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx b/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx index d3b6cd2..dc1fb14 100644 --- a/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx +++ b/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx @@ -93,7 +93,7 @@ export function LetterBasicForm() { {/* Footer Actions */} -
+
是否公开 diff --git a/packages/common/prisma/schema.prisma b/packages/common/prisma/schema.prisma index 9e49147..e36573e 100644 --- a/packages/common/prisma/schema.prisma +++ b/packages/common/prisma/schema.prisma @@ -70,11 +70,11 @@ model TermAncestry { } model Staff { - id String @id @default(cuid()) - showname String? @map("showname") - username String @unique @map("username") - avatar String? @map("avatar") - password String? @map("password") + id String @id @default(cuid()) + showname String? @map("showname") + username String @unique @map("username") + avatar String? @map("avatar") + password String? @map("password") phoneNumber String? @unique @map("phone_number") @@ -196,16 +196,16 @@ model Post { domainId String? @map("domain_id") terms Term[] @relation("post_term") // 日期时间类型字段 - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @map("updated_at") + createdAt DateTime? @default(now()) @map("created_at") + updatedAt DateTime? @map("updated_at") deletedAt DateTime? @map("deleted_at") // 删除时间,可为空 // 关系类型字段 authorId String? @map("author_id") author Staff? @relation("post_author", fields: [authorId], references: [id]) // 帖子作者,关联 Staff 模型 visits Visit[] // 访问记录,关联 Visit 模型 - views Int @default(0) - likes Int @default(0) - hates Int @default(0) + views Int? @default(0) + likes Int? @default(0) + hates Int? @default(0) receivers Staff[] @relation("post_receiver") parentId String? @map("parent_id") parent Post? @relation("PostChildren", fields: [parentId], references: [id]) // 父级帖子,关联 Post 模型 diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 51f2b94..b08b0b5 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -27,5 +27,10 @@ export const formatFileSize = (bytes: number) => { if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`; }; - +// 压缩图片路径生成函数 +export const getCompressedImageUrl = (originalUrl: string): string => { + const cleanUrl = originalUrl.split(/[?#]/)[0] // 移除查询参数和哈希 + const lastSlashIndex = cleanUrl.lastIndexOf('/') + return `${cleanUrl.slice(0, lastSlashIndex)}/compressed/${cleanUrl.slice(lastSlashIndex + 1).replace(/\.[^.]+$/, '.webp')}` +} export * from "./types" \ No newline at end of file From 150f2964919102cb4724af1cebc240aaf768e248 Mon Sep 17 00:00:00 2001 From: longdayi <13477510+longdayilongdayi@user.noreply.gitee.com> Date: Sun, 26 Jan 2025 19:39:02 +0800 Subject: [PATCH 2/2] 01261939 --- packages/client/src/api/hooks/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/api/hooks/index.ts b/packages/client/src/api/hooks/index.ts index 9f4f998..3c543ed 100644 --- a/packages/client/src/api/hooks/index.ts +++ b/packages/client/src/api/hooks/index.ts @@ -9,3 +9,4 @@ export * from "./useTaxonomy" export * from "./useVisitor" export * from "./useMessage" export * from "./usePost" +export * from "./useEntity" \ No newline at end of file