133 lines
2.9 KiB
TypeScript
133 lines
2.9 KiB
TypeScript
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 },
|
||
});
|
||
}
|
||
}
|