diff --git a/packages/server/src/services/document.service.ts b/packages/server/src/services/document.service.ts index af3b3bc7..65d54a87 100644 --- a/packages/server/src/services/document.service.ts +++ b/packages/server/src/services/document.service.ts @@ -385,6 +385,7 @@ export class DocumentService { } const auths = await this.documentAuthorityRepo.find({ documentId }); await this.documentAuthorityRepo.remove(auths); + await this.viewService.deleteViews(documentId); return this.documentRepo.remove(document); } @@ -609,27 +610,33 @@ export class DocumentService { const records = await this.viewService.getUserRecentVisitedDocuments(user.id); const documentIds = records.map((r) => r.documentId); const visitedAtMap = records.reduce((a, c) => { - return (a[c.documentId] = c.visitedAt); + a[c.documentId] = c.visitedAt; + return a; }, {}); - const documents = await this.documentRepo.findByIds(documentIds); - const docs = documents.filter((doc) => !doc.isWikiHome).map((doc) => instanceToPlain(doc)); + const ret = await Promise.all( + documentIds.map(async (documentId) => { + const doc = await this.findById(documentId); - const res = await Promise.all( - docs.map(async (doc) => { - const views = await this.viewService.getDocumentTotalViews(doc.id); - return { ...doc, views, visitedAt: visitedAtMap[doc.id] } as IDocument & { views: number; visitedAt: Date }; + if (!doc) { + return null; + } + + const [views, createUser] = await Promise.all([ + await this.viewService.getDocumentTotalViews(documentId), + doc && doc.createUserId ? await this.userService.findById(doc.createUserId) : null, + ]); + + return { + ...instanceToPlain(doc), + views, + visitedAt: visitedAtMap[documentId], + createUser, + }; }) ); - const withCreateUserRes = await Promise.all( - res.map(async (doc) => { - const createUser = await this.userService.findById(doc.createUserId); - return { createUser, ...doc }; - }) - ); - - return withCreateUserRes; + return ret.filter(Boolean); } /** diff --git a/packages/server/src/services/view.service.ts b/packages/server/src/services/view.service.ts index dfc5edcb..daba9912 100644 --- a/packages/server/src/services/view.service.ts +++ b/packages/server/src/services/view.service.ts @@ -1,4 +1,5 @@ import { ViewEntity } from '@entities/view.entity'; +import { ONE_DAY } from '@helpers/log.helper'; import { parseUserAgent } from '@helpers/ua.helper'; import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; @@ -30,6 +31,11 @@ export class ViewService { return ret; } + async deleteViews(documentId) { + const records = await this.viewRepo.find({ documentId }); + await this.viewRepo.remove(records); + } + async getDocumentTotalViews(documentId) { const [, total] = await this.viewRepo.findAndCount({ documentId }); return total; @@ -61,14 +67,41 @@ export class ViewService { visitedAt: Date; }> > { - const [ret] = await this.viewRepo.findAndCount({ - where: { userId }, - take: 20, - order: { createdAt: 'DESC' }, + const now = Date.now(); + const queryBuilder = this.viewRepo.createQueryBuilder('view'); + + queryBuilder.where('view.userId=:userId', { userId }).andWhere('view.createdAt BETWEEN :start AND :end', { + start: new Date(now - 3 * ONE_DAY), + end: new Date(now), }); - return ret.map((item) => ({ - documentId: item.documentId, - visitedAt: item.createdAt, - })); + + const ret = await queryBuilder.getMany(); + + const map = {}; + + ret.forEach((item) => { + const key = item.documentId; + if (!map[key]) { + map[key] = item; + } + const mapItem = map[key]; + const isGreaterThan = new Date(mapItem.createdAt).valueOf() < new Date(item.createdAt).valueOf(); + if (isGreaterThan) { + map[key] = item; + } + }); + + const res = Object.keys(map).map((documentId) => { + return { + documentId, + visitedAt: map[documentId].createdAt, + }; + }); + + res.sort((a, b) => { + return -new Date(a.visitedAt).valueOf() + new Date(b.visitedAt).valueOf(); + }); + + return res.slice(0, 20); } }