diff --git a/apps/server/src/auth/auth.service.ts b/apps/server/src/auth/auth.service.ts index a026ad6..6708806 100755 --- a/apps/server/src/auth/auth.service.ts +++ b/apps/server/src/auth/auth.service.ts @@ -169,12 +169,16 @@ export class AuthService { password, officerId, showname, - department: deptId && { - connect: { id: deptId }, - }, - domain: { - connect: deptId && { id: deptId }, - }, + department: deptId + ? { + connect: { id: deptId }, + } + : undefined, + domain: deptId + ? { + connect: { id: deptId }, + } + : undefined, // domainId: data.deptId, meta: { photoUrl, diff --git a/apps/server/src/models/post/utils.ts b/apps/server/src/models/post/utils.ts index 90906fd..9de3772 100644 --- a/apps/server/src/models/post/utils.ts +++ b/apps/server/src/models/post/utils.ts @@ -31,7 +31,6 @@ export async function setPostRelation(params: { visitorId: staff?.id, }, })) > 0; - const liked = (await db.visit.count({ where: { @@ -50,6 +49,24 @@ export async function setPostRelation(params: { }), }, })) > 0; + const hated = + (await db.visit.count({ + where: { + postId: data.id, + type: VisitType?.HATE, + ...(staff?.id + ? // 如果有 staff,查找对应的 visitorId + { visitorId: staff.id } + : // 如果没有 staff,查找相同 IP 且 visitorId 为 null 且 30 分钟内的记录 + { + visitorId: null, + meta: { path: ['ip'], equals: clientIp }, + updatedAt: { + gte: thirtyMinutesAgo, + }, + }), + }, + })) > 0; const readedCount = await db.visit.count({ where: { postId: data.id, @@ -61,6 +78,7 @@ export async function setPostRelation(params: { readed, readedCount, liked, + hated, commentsCount, }); // console.log('data', data); diff --git a/apps/server/src/models/visit/visit.service.ts b/apps/server/src/models/visit/visit.service.ts index 9847639..3d3a49a 100644 --- a/apps/server/src/models/visit/visit.service.ts +++ b/apps/server/src/models/visit/visit.service.ts @@ -78,6 +78,13 @@ export class VisitService extends BaseService { visitType: VisitType.LIKE, }); } + if (args.data.type === VisitType.HATE) { + EventBus.emit('updateVisitCount', { + objectType: ObjectType.POST, + id: postId, + visitType: VisitType.HATE, + }); + } } return result; } diff --git a/apps/web/src/app/auth/register.tsx b/apps/web/src/app/auth/register.tsx index 18253f2..3337d32 100644 --- a/apps/web/src/app/auth/register.tsx +++ b/apps/web/src/app/auth/register.tsx @@ -37,19 +37,20 @@ export const RegisterForm = ({ onSubmit, isLoading }: RegisterFormProps) => { layout="vertical" onFinish={onSubmit} scrollToFirstError> -
-
+
+
+ width: `100%`, + height: 210, + }} + />
-
+
{ noStyle label="部门" rules={[{ required: true, message: "请选择部门" }]}> - + + + +
-
- - - - - - - - - - - - - - - - - - - - ({ - validator(_, value) { - if ( - !value || - getFieldValue("password") === value - ) { - return Promise.resolve(); - } - return Promise.reject( - new Error("两次输入的密码不一致") - ); +
+
+ - - + ]} + name={"phoneNumber"} + label="手机号"> + + + + + + + + +
+
+ + + + + + + ({ + validator(_, value) { + if ( + !value || + getFieldValue("password") === value + ) { + return Promise.resolve(); + } + return Promise.reject( + new Error("两次输入的密码不一致") + ); + }, + }), + ]}> + + +
+ +
- -
-
-
-
- ); +
+ + +
+ + + + ); } diff --git a/apps/web/src/components/models/post/detail/PostCommentList.tsx b/apps/web/src/components/models/post/detail/PostCommentList.tsx index 0b9f005..e15b442 100644 --- a/apps/web/src/components/models/post/detail/PostCommentList.tsx +++ b/apps/web/src/components/models/post/detail/PostCommentList.tsx @@ -137,7 +137,7 @@ export default function PostCommentList() { } if (!items.length) { - return null + return null; } return ( @@ -177,11 +177,9 @@ export default function PostCommentList() { animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} className="flex flex-col items-center py-4 space-y-2"> - 已加载全部回复 - ) )} diff --git a/apps/web/src/components/models/post/detail/PostResources.tsx b/apps/web/src/components/models/post/detail/PostResources.tsx index e49abc4..328bae4 100644 --- a/apps/web/src/components/models/post/detail/PostResources.tsx +++ b/apps/web/src/components/models/post/detail/PostResources.tsx @@ -8,7 +8,10 @@ import { formatFileSize } from '@nice/utils'; export default function PostResources({ post }: { post: PostDto }) { const { resources } = useMemo(() => { if (!post?.resources) return { resources: [] }; - const isImage = (url: string) => /\.(png|jpg|jpeg|gif|webp)$/i.test(url); + + const isImage = (url: string) => + /\.(png|jpg|jpeg|gif|webp)$/i.test(url); + const sortedResources = post.resources .map((resource) => ({ ...resource, @@ -36,8 +39,7 @@ export default function PostResources({ post }: { post: PostDto }) { md={6} lg={6} xl={4} - className="relative" - > + className="relative">
(
+ className="flex items-center justify-between p-3 hover:bg-gray-50 rounded-md transition-colors duration-200">
- {getFileIcon(resource.url)} + + {getFileIcon(resource.url)} +

{resource.title || "未命名文件"}

- {resource.url.split(".").pop()?.toUpperCase()}文件 + {resource.url + .split(".") + .pop() + ?.toUpperCase()} + 文件 {resource.meta.size && @@ -100,8 +107,7 @@ export default function PostResources({ post }: { post: PostDto }) {
@@ -111,4 +117,4 @@ export default function PostResources({ post }: { post: PostDto }) { )}
); -} \ No newline at end of file +} diff --git a/packages/client/src/api/hooks/useVisitor.ts b/packages/client/src/api/hooks/useVisitor.ts index 2ff19ab..37ce83e 100644 --- a/packages/client/src/api/hooks/useVisitor.ts +++ b/packages/client/src/api/hooks/useVisitor.ts @@ -118,6 +118,21 @@ export function useVisitor() { })) ); + const hate = api.visitor.create.useMutation( + createOptimisticMutation((item) => ({ + ...item, + hates: (item.hates || 0) + 1, + hated: true, + })) + ); + const unHate = api.visitor.deleteMany.useMutation( + createOptimisticMutation((item) => ({ + ...item, + hates: item.hates - 1 || 0, + hated: false, + })) + ); + const addStar = api.visitor.create.useMutation( createOptimisticMutation((item) => ({ ...item, diff --git a/packages/common/prisma/schema.prisma b/packages/common/prisma/schema.prisma index 5f58649..9e49147 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") @@ -203,8 +203,9 @@ model Post { 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) + 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/common/src/enum.ts b/packages/common/src/enum.ts index 5a1b00b..035c58a 100755 --- a/packages/common/src/enum.ts +++ b/packages/common/src/enum.ts @@ -14,6 +14,7 @@ export enum VisitType { STAR = "star", READED = "read", LIKE = "like", + HATE = "hate", } export enum StorageProvider {