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

200 lines
6.1 KiB
TypeScript
Raw Normal View History

2024-12-30 08:26:40 +08:00
import { Injectable } from '@nestjs/common';
import { BaseService } from '../base/base.service';
2025-01-22 18:56:27 +08:00
import { UserProfile, db, ObjectType, Prisma, VisitType } from '@nice/common';
2024-12-30 08:26:40 +08:00
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) {
2025-01-22 18:56:27 +08:00
const { postId, messageId } = args.data;
2025-01-24 00:19:02 +08:00
const clientIp = (args.data.meta as any)?.ip;
2024-12-30 08:26:40 +08:00
const visitorId = args.data.visitorId || staff?.id;
let result;
const existingVisit = await db.visit.findFirst({
where: {
2024-12-31 15:57:32 +08:00
type: args.data.type,
2025-01-24 00:19:02 +08:00
OR: [
{
AND: [
{ OR: [{ postId }, { messageId }] },
{ visitorId: visitorId || null },
],
},
{
AND: [
{ OR: [{ postId }, { messageId }] },
{ visitorId: null },
{ meta: { path: ['ip'], equals: clientIp } },
],
},
],
2024-12-30 08:26:40 +08:00
},
});
if (!existingVisit) {
result = await super.create(args);
2024-12-31 15:57:32 +08:00
} else if (args.data.type === VisitType.READED) {
2024-12-30 08:26:40 +08:00
result = await super.update({
where: { id: existingVisit.id },
data: {
...args.data,
views: existingVisit.views + 1,
},
});
2025-01-24 00:19:02 +08:00
} 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,
},
});
}
}
2024-12-30 08:26:40 +08:00
}
2025-01-24 15:06:57 +08:00
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,
});
}
2025-01-26 15:28:34 +08:00
if (args.data.type === VisitType.HATE) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: postId,
visitType: VisitType.HATE,
});
}
2025-01-24 00:19:02 +08:00
}
2024-12-30 08:26:40 +08:00
return result;
}
async createMany(args: Prisma.VisitCreateManyArgs, staff?: UserProfile) {
const data = Array.isArray(args.data) ? args.data : [args.data];
2024-12-31 15:57:32 +08:00
const updatePromises: any[] = [];
const createData: Prisma.VisitCreateManyInput[] = [];
2024-12-30 08:26:40 +08:00
await Promise.all(
data.map(async (item) => {
2025-01-22 18:56:27 +08:00
if (staff && !item.visitorId) item.visitorId = staff.id;
const { postId, messageId, visitorId } = item;
2024-12-30 08:26:40 +08:00
const existingVisit = await db.visit.findFirst({
where: {
visitorId,
2025-01-22 18:56:27 +08:00
OR: [{ postId }, { messageId }],
2024-12-30 08:26:40 +08:00
},
});
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
}
2025-01-24 17:39:41 +08:00
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,
});
}
2025-01-26 16:10:31 +08:00
if (args.where.type === VisitType.HATE) {
EventBus.emit('updateVisitCount', {
objectType: ObjectType.POST,
id: args?.where?.postId as string,
visitType: VisitType.HATE,
});
}
2025-01-24 17:39:41 +08:00
}
return superDetele;
}
2024-12-30 08:26:40 +08:00
}