library-picturebook-activity/backend/src/public/gallery.service.ts

137 lines
3.7 KiB
TypeScript
Raw Normal View History

import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
@Injectable()
export class GalleryService {
constructor(private prisma: PrismaService) {}
/** 作品广场列表(已审核通过的公开作品) */
async getGalleryList(params: {
page?: number;
pageSize?: number;
tagId?: number;
category?: string;
sortBy?: string;
keyword?: string;
}) {
const { page = 1, pageSize = 12, tagId, category, sortBy = 'latest', keyword } = params;
const skip = (page - 1) * pageSize;
const where: any = {
status: 'published',
visibility: 'public',
isDeleted: 0,
};
if (keyword) {
where.OR = [
{ title: { contains: keyword } },
{ description: { contains: keyword } },
];
}
if (tagId) {
where.tags = { some: { tagId } };
}
if (category) {
where.tags = {
...where.tags,
some: { ...where.tags?.some, tag: { category } },
};
}
const orderBy: any = sortBy === 'hot'
? [{ likeCount: 'desc' }, { viewCount: 'desc' }]
: sortBy === 'views'
? { viewCount: 'desc' }
: { publishTime: 'desc' };
const [list, total] = await Promise.all([
this.prisma.userWork.findMany({
where,
skip,
take: pageSize,
orderBy,
include: {
creator: { select: { id: true, nickname: true, avatar: true } },
tags: { include: { tag: { select: { id: true, name: true } } } },
_count: { select: { pages: true, likes: true, comments: true } },
},
}),
this.prisma.userWork.count({ where }),
]);
return { list, total, page, pageSize };
}
/** 广场作品详情(增加浏览量) */
async getGalleryDetail(id: number) {
const work = await this.prisma.userWork.findFirst({
where: { id, status: 'published', visibility: 'public', isDeleted: 0 },
include: {
pages: { orderBy: { pageNo: 'asc' } },
creator: { select: { id: true, nickname: true, avatar: true, username: true } },
tags: { include: { tag: true } },
_count: { select: { pages: true, likes: true, favorites: true, comments: true } },
},
});
if (!work) throw new NotFoundException('作品不存在');
// 异步增加浏览量
this.prisma.userWork.update({
where: { id },
data: { viewCount: { increment: 1 } },
}).catch(() => {});
return work;
}
/** 推荐作品列表 */
async getRecommendedWorks(limit = 10) {
return this.prisma.userWork.findMany({
where: {
isRecommended: true,
status: 'published',
visibility: 'public',
isDeleted: 0,
},
take: limit,
orderBy: [{ likeCount: 'desc' }, { publishTime: 'desc' }],
include: {
creator: { select: { id: true, nickname: true, avatar: true } },
},
});
}
/** 某用户的公开作品列表 */
async getUserPublicWorks(userId: number, params: { page?: number; pageSize?: number }) {
const { page = 1, pageSize = 12 } = params;
const skip = (page - 1) * pageSize;
const where = {
userId,
status: 'published',
visibility: 'public',
isDeleted: 0,
};
const [list, total] = await Promise.all([
this.prisma.userWork.findMany({
where,
skip,
take: pageSize,
orderBy: { publishTime: 'desc' },
include: {
tags: { include: { tag: { select: { id: true, name: true } } } },
_count: { select: { pages: true, likes: true } },
},
}),
this.prisma.userWork.count({ where }),
]);
return { list, total, page, pageSize };
}
}