Some checks failed
Deploy API Server / build-and-deploy (push) Failing after 11s
Schema 新增: - coverType/coverIcon/coverColor(封面类型/系统图标/颜色) - visibility(private/public) - isPinned(置顶) - ownerType(user/official) - isVerified(认证标识) - KnowledgeBaseSubscription 表 API 新增: - POST /knowledge-bases/:id/pin(切换置顶) - PATCH /knowledge-bases/:id/visibility(切换公开/私有) - POST /knowledge-bases/:id/subscribe(订阅) - DELETE /knowledge-bases/:id/subscribe(取消订阅) - GET /knowledge-bases/subscribed(已订阅列表) - GET /knowledge-bases/discover(发现公开库) 增强: - findAll 支持 visibility/ownerType 筛选 + 置顶优先排序 - findOne 公开库允许任何人查看 - update 支持所有新字段 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
157 lines
4.1 KiB
TypeScript
157 lines
4.1 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
|
|
|
@Injectable()
|
|
export class KnowledgeBaseRepository {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async create(userId: string, dto: {
|
|
title: string;
|
|
description?: string;
|
|
coverKey?: string;
|
|
coverType?: string;
|
|
coverIcon?: string;
|
|
coverColor?: string;
|
|
visibility?: string;
|
|
}) {
|
|
return this.prisma.knowledgeBase.create({
|
|
data: {
|
|
userId,
|
|
title: dto.title,
|
|
description: dto.description ?? '',
|
|
coverKey: dto.coverKey ?? null,
|
|
coverType: dto.coverType ?? 'custom',
|
|
coverIcon: dto.coverIcon ?? null,
|
|
coverColor: dto.coverColor ?? null,
|
|
visibility: dto.visibility ?? 'private',
|
|
status: 'active',
|
|
itemCount: 0,
|
|
},
|
|
});
|
|
}
|
|
|
|
async findById(id: string) {
|
|
return this.prisma.knowledgeBase.findUnique({ where: { id } });
|
|
}
|
|
|
|
async findAllByUserId(
|
|
userId: string,
|
|
opts?: {
|
|
page?: number;
|
|
limit?: number;
|
|
visibility?: string;
|
|
ownerType?: string;
|
|
},
|
|
) {
|
|
const page = opts?.page ?? 1;
|
|
const limit = opts?.limit ?? 20;
|
|
const where: any = { userId, deletedAt: null };
|
|
if (opts?.visibility) where.visibility = opts.visibility;
|
|
if (opts?.ownerType) where.ownerType = opts.ownerType;
|
|
return this.prisma.knowledgeBase.findMany({
|
|
where,
|
|
orderBy: [{ isPinned: 'desc' }, { updatedAt: 'desc' }],
|
|
skip: (page - 1) * limit,
|
|
take: limit,
|
|
});
|
|
}
|
|
|
|
async findAllPublic(opts?: { page?: number; limit?: number; search?: string }) {
|
|
const page = opts?.page ?? 1;
|
|
const limit = opts?.limit ?? 20;
|
|
const where: any = { visibility: 'public', deletedAt: null };
|
|
if (opts?.search) {
|
|
where.OR = [
|
|
{ title: { contains: opts.search } },
|
|
{ description: { contains: opts.search } },
|
|
];
|
|
}
|
|
return this.prisma.knowledgeBase.findMany({
|
|
where,
|
|
orderBy: [{ isPinned: 'desc' }, { updatedAt: 'desc' }],
|
|
skip: (page - 1) * limit,
|
|
take: limit,
|
|
});
|
|
}
|
|
|
|
async countByUserId(userId: string) {
|
|
return this.prisma.knowledgeBase.count({
|
|
where: { userId, deletedAt: null },
|
|
});
|
|
}
|
|
|
|
async update(id: string, dto: {
|
|
title?: string;
|
|
description?: string;
|
|
coverKey?: string;
|
|
coverType?: string;
|
|
coverIcon?: string;
|
|
coverColor?: string;
|
|
visibility?: string;
|
|
isPinned?: boolean;
|
|
}) {
|
|
return this.prisma.knowledgeBase.update({
|
|
where: { id },
|
|
data: dto,
|
|
});
|
|
}
|
|
|
|
async togglePin(id: string, isPinned: boolean) {
|
|
return this.prisma.knowledgeBase.update({
|
|
where: { id },
|
|
data: { isPinned },
|
|
});
|
|
}
|
|
|
|
async setVisibility(id: string, visibility: string) {
|
|
return this.prisma.knowledgeBase.update({
|
|
where: { id },
|
|
data: { visibility },
|
|
});
|
|
}
|
|
|
|
async softDelete(id: string) {
|
|
await this.prisma.knowledgeBase.update({
|
|
where: { id },
|
|
data: { deletedAt: new Date() },
|
|
});
|
|
return true;
|
|
}
|
|
|
|
// ── Subscription ──
|
|
|
|
async subscribe(userId: string, knowledgeBaseId: string) {
|
|
return this.prisma.knowledgeBaseSubscription.create({
|
|
data: { userId, knowledgeBaseId },
|
|
});
|
|
}
|
|
|
|
async unsubscribe(userId: string, knowledgeBaseId: string) {
|
|
await this.prisma.knowledgeBaseSubscription.deleteMany({
|
|
where: { userId, knowledgeBaseId },
|
|
});
|
|
return true;
|
|
}
|
|
|
|
async findSubscribed(userId: string, opts?: { page?: number; limit?: number }) {
|
|
const page = opts?.page ?? 1;
|
|
const limit = opts?.limit ?? 20;
|
|
return this.prisma.knowledgeBase.findMany({
|
|
where: {
|
|
subscriptions: { some: { userId } },
|
|
deletedAt: null,
|
|
},
|
|
orderBy: { updatedAt: 'desc' },
|
|
skip: (page - 1) * limit,
|
|
take: limit,
|
|
});
|
|
}
|
|
|
|
async isSubscribed(userId: string, knowledgeBaseId: string): Promise<boolean> {
|
|
const sub = await this.prisma.knowledgeBaseSubscription.findUnique({
|
|
where: { userId_knowledgeBaseId: { userId, knowledgeBaseId } },
|
|
});
|
|
return !!sub;
|
|
}
|
|
}
|