doctor-mail/apps/server/src/models/post/utils.ts

133 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
db,
Post,
PostState,
PostType,
UserProfile,
VisitType,
} from '@nice/common';
export async function setPostRelation(params: {
data: Post;
staff?: UserProfile;
}) {
const { data, staff } = params;
// 在函数开始时计算一次时间
const thirtyMinutesAgo = new Date(Date.now() - 30 * 60 * 1000);
const clientIp = (data?.meta as any)?.ip;
const commentsCount = await db.post.count({
where: {
parentId: data.id,
type: PostType.POST_COMMENT,
},
});
const readed =
(await db.visit.count({
where: {
postId: data.id,
type: VisitType.READED,
visitorId: staff?.id,
},
})) > 0;
const liked = await db.visit.count({
where: {
postId: data.id,
type: VisitType?.LIKE,
...(staff?.id
? // 如果有 staff查找对应的 visitorId
{ visitorId: staff.id }
: // 如果没有 staff查找相同 IP 且 visitorId 为 null 且 30 分钟内的记录
{
visitorId: null,
meta: { path: ['ip'], equals: clientIp },
updatedAt: {
gte: thirtyMinutesAgo,
},
}),
},
});
const readedCount = await db.visit.count({
where: {
postId: data.id,
type: VisitType.READED,
},
});
Object.assign(data, {
readed,
readedCount,
liked,
// limitedComments,
commentsCount,
// trouble
});
}
export function getClientIp(req: any): string {
let ip =
req.ip ||
(Array.isArray(req.headers['x-forwarded-for'])
? req.headers['x-forwarded-for'][0]
: req.headers['x-forwarded-for']) ||
req.socket.remoteAddress;
// 如果是 IPv4-mapped IPv6 地址,转换为 IPv4
if (typeof ip === 'string' && ip.startsWith('::ffff:')) {
ip = ip.substring(7);
}
return ip || '';
}
export async function updatePostState(id: string) {
const post = await db.post.findUnique({
where: {
id: id,
},
select: {
id: true,
state: true,
receivers: {
select: {
id: true,
},
},
},
});
if (post?.state === PostState.COMPLETED) {
return;
}
const postReceiverIds = post.receivers
.map((receiver) => receiver.id)
.filter(Boolean);
const receiverViews = await db.visit.count({
where: {
postId: id,
type: VisitType.READED,
visitorId: {
in: postReceiverIds,
},
},
});
if (receiverViews > 0 && post.state === PostState.PENDING) {
await db.post.update({
where: { id },
data: { state: PostState.PROCESSING },
});
}
const receiverComments = await db.post.count({
where: {
parentId: id,
type: PostType.POST_COMMENT,
authorId: {
in: postReceiverIds,
},
},
});
if (receiverComments > 0) {
await db.post.update({
where: { id },
data: { state: PostState.COMPLETED },
});
}
}