2026-03-27 22:20:25 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 15:21:21 +08:00
|
|
|
/** 推荐作品列表 */
|
|
|
|
|
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 } },
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 22:20:25 +08:00
|
|
|
/** 某用户的公开作品列表 */
|
|
|
|
|
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 };
|
|
|
|
|
}
|
|
|
|
|
}
|