doctor-mail/apps/server/src/models/visit/visit.service.ts

200 lines
6.1 KiB
TypeScript
Executable File
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 { Injectable } from '@nestjs/common';
import { BaseService } from '../base/base.service';
import { UserProfile, db, ObjectType, Prisma, VisitType } from '@nice/common';
import EventBus from '@server/utils/event-bus';
@Injectable()
export class VisitService extends BaseService<Prisma.VisitDelegate> {
constructor() {
super(db, ObjectType.VISIT);
}
async create(args: Prisma.VisitCreateArgs, staff?: UserProfile) {
const { postId, messageId } = args.data;
const clientIp = (args.data.meta as any)?.ip;
const visitorId = args.data.visitorId || staff?.id;
let result;
const existingVisit = await db.visit.findFirst({
where: {
type: args.data.type,
OR: [
{
AND: [
{ OR: [{ postId }, { messageId }] },
{ visitorId: visitorId || null },
],
},
{
AND: [
{ OR: [{ postId }, { messageId }] },
{ visitorId: null },
{ meta: { path: ['ip'], equals: clientIp } },
],
},
],
},
});
if (!existingVisit) {
result = await super.create(args);
} else if (args.data.type === VisitType.READED) {
result = await super.update({
where: { id: existingVisit.id },
data: {
...args.data,
views: existingVisit.views + 1,
},
});
} else if (args.data.type === VisitType.LIKE) {
if (!visitorId && existingVisit) {
const thirtyMinutesAgo = new Date(Date.now() - 30 * 60 * 1000);
if (existingVisit.updatedAt < thirtyMinutesAgo) {
// 如果上次更新时间超过30分钟增加view计数
result = await super.update({
where: { id: existingVisit.id },
data: {
...args.data,
views: existingVisit.views + 1,
},
});
}
}
}
if (postId) {
if (visitorId) {
EventBus.emit('updatePostState', {
id: postId,
});
}
if (args.data.type === VisitType.READED) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: postId,
visitType: VisitType.READED,
});
}
if (args.data.type === VisitType.LIKE) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: postId,
visitType: VisitType.LIKE,
});
}
if (args.data.type === VisitType.HATE) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: postId,
visitType: VisitType.HATE,
});
}
}
return result;
}
async createMany(args: Prisma.VisitCreateManyArgs, staff?: UserProfile) {
const data = Array.isArray(args.data) ? args.data : [args.data];
const updatePromises: any[] = [];
const createData: Prisma.VisitCreateManyInput[] = [];
await Promise.all(
data.map(async (item) => {
if (staff && !item.visitorId) item.visitorId = staff.id;
const { postId, messageId, visitorId } = item;
const existingVisit = await db.visit.findFirst({
where: {
visitorId,
OR: [{ postId }, { messageId }],
},
});
if (existingVisit) {
updatePromises.push(
super.update({
where: { id: existingVisit.id },
data: {
...item,
views: existingVisit.views + 1,
},
}),
);
} else {
createData.push(item);
}
}),
);
// Execute all updates in parallel
await Promise.all(updatePromises);
// Create new visits for those not existing
if (createData.length > 0) {
return super.createMany({
...args,
data: createData,
});
}
return { count: updatePromises.length }; // Return the number of updates if no new creates
}
async deleteMany(args: Prisma.VisitDeleteManyArgs, staff?: UserProfile) {
// const where = Array.isArray(args.where) ? args.where : [args.where];
// const updatePromises: any[] = [];
// const createData: Prisma.VisitCreateManyInput[] = [];
// super
// await Promise.all(
// data.map(async (item) => {
// if (staff && !item.visitorId) item.visitorId = staff.id;
// const { postId, messageId, visitorId } = item;
// const existingVisit = await db.visit.findFirst({
// where: {
// visitorId,
// OR: [{ postId }, { messageId }],
// },
// });
// if (existingVisit) {
// updatePromises.push(
// super.update({
// where: { id: existingVisit.id },
// data: {
// ...item,
// views: existingVisit.views + 1,
// },
// }),
// );
// } else {
// createData.push(item);
// }
// }),
// );
// // Execute all updates in parallel
// await Promise.all(updatePromises);
// // Create new visits for those not existing
// if (createData.length > 0) {
// return super.createMany({
// ...args,
// data: createData,
// });
// }
// return { count: updatePromises.length }; // Return the number of updates if no new creates
const superDetele = super.deleteMany(args, staff);
if (args?.where?.postId) {
if (args.where.type === VisitType.READED) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: args?.where?.postId as string,
visitType: VisitType.READED,
});
}
if (args.where.type === VisitType.LIKE) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: args?.where?.postId as string,
visitType: VisitType.LIKE,
});
}
if (args.where.type === VisitType.HATE) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: args?.where?.postId as string,
visitType: VisitType.HATE,
});
}
}
return superDetele;
}
}