From c331d0864411996ba09026a5cda2c8873cba675e Mon Sep 17 00:00:00 2001 From: wangdl Date: Wed, 27 May 2026 22:47:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=9F=A5=E8=AF=86=E7=82=B9=E8=BD=AF?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20+=20=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DELETE /knowledge-items/:id 软删除(设 deletedAt) - POST /knowledge-items/batch-delete 批量软删除 - softDelete 校验归属权 + 自动更新父KB的itemCount Co-Authored-By: Claude Opus 4.7 --- .../knowledge-items.controller.ts | 18 ++++++++++++++- .../knowledge-items.repository.ts | 15 ++++++++++++ .../knowledge-items.service.ts | 23 ++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/modules/knowledge-items/knowledge-items.controller.ts b/src/modules/knowledge-items/knowledge-items.controller.ts index 464c43c..b3ad39f 100644 --- a/src/modules/knowledge-items/knowledge-items.controller.ts +++ b/src/modules/knowledge-items/knowledge-items.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, Post, Patch, Body, Param, Query } from '@nestjs/common'; +import { Controller, Get, Post, Patch, Delete, Body, Param, Query, HttpCode, HttpStatus } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'; import { KnowledgeItemsService } from './knowledge-items.service'; import { CurrentUser } from '../../common/decorators/current-user.decorator'; @@ -32,4 +32,20 @@ export class KnowledgeItemsController { async update(@Param('id') id: string, @Body() body: any) { return this.service.update(id, body); } + + @Delete(':id') + @HttpCode(HttpStatus.OK) + @ApiOperation({ summary: '软删除知识点' }) + async delete(@CurrentUser() user: UserPayload, @Param('id') id: string) { + await this.service.softDelete(id, String(user?.id || 'anonymous')); + return { success: true, message: '已删除' }; + } + + @Post('batch-delete') + @HttpCode(HttpStatus.OK) + @ApiOperation({ summary: '批量软删除知识点' }) + async batchDelete(@CurrentUser() user: UserPayload, @Body() body: { ids: string[] }) { + const count = await this.service.batchSoftDelete(body.ids || [], String(user?.id || 'anonymous')); + return { success: true, message: `已删除 ${count} 个知识点`, count }; + } } diff --git a/src/modules/knowledge-items/knowledge-items.repository.ts b/src/modules/knowledge-items/knowledge-items.repository.ts index 64d557a..5d47693 100644 --- a/src/modules/knowledge-items/knowledge-items.repository.ts +++ b/src/modules/knowledge-items/knowledge-items.repository.ts @@ -50,4 +50,19 @@ export class KnowledgeItemsRepository { data: dto, }); } + + async softDelete(id: string) { + const item = await this.prisma.knowledgeItem.update({ + where: { id }, + data: { deletedAt: new Date() }, + }); + + // 更新知识库 itemCount + await this.prisma.knowledgeBase.update({ + where: { id: item.knowledgeBaseId }, + data: { itemCount: { decrement: 1 } }, + }); + + return item; + } } diff --git a/src/modules/knowledge-items/knowledge-items.service.ts b/src/modules/knowledge-items/knowledge-items.service.ts index 7575b97..f6c8975 100644 --- a/src/modules/knowledge-items/knowledge-items.service.ts +++ b/src/modules/knowledge-items/knowledge-items.service.ts @@ -1,4 +1,4 @@ -import { Injectable, NotFoundException } from '@nestjs/common'; +import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/common'; import { KnowledgeItemsRepository } from './knowledge-items.repository'; @Injectable() @@ -24,4 +24,25 @@ export class KnowledgeItemsService { if (!item) throw new NotFoundException('知识点不存在'); return item; } + + async softDelete(id: string, userId: string) { + const item = await this.repository.findById(id); + if (!item) throw new NotFoundException('知识点不存在'); + if (item.userId !== userId) throw new ForbiddenException('无权操作'); + return this.repository.softDelete(id); + } + + async batchSoftDelete(ids: string[], userId: string) { + if (!ids.length) return 0; + let count = 0; + for (const id of ids) { + try { + await this.softDelete(id, userId); + count++; + } catch { + // 跳过不存在的或无权操作的 + } + } + return count; + } }