Skip to content

Commit 44e772f

Browse files
committed
feat: file relate kb
1 parent a3c6d68 commit 44e772f

File tree

7 files changed

+50
-26
lines changed

7 files changed

+50
-26
lines changed

client/src/pages/api/plugins/file/read.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
2626

2727
const encoding = jschardet.detect(buffer)?.encoding;
2828

29-
res.setHeader('encoding', encoding);
30-
res.setHeader('Content-Type', file.contentType);
29+
res.setHeader('Content-Type', `${file.contentType}; charset=${encoding}`);
3130
res.setHeader('Cache-Control', 'public, max-age=3600');
3231
res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(file.filename)}"`);
3332

client/src/pages/api/plugins/file/upload.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,30 @@ class UploadModel {
3838
}).any();
3939

4040
async doUpload(req: NextApiRequest, res: NextApiResponse) {
41-
return new Promise<{ files: FileType[] }>((resolve, reject) => {
41+
return new Promise<{ files: FileType[]; metadata: Record<string, any> }>((resolve, reject) => {
4242
// @ts-ignore
4343
this.uploader(req, res, (error) => {
4444
if (error) {
4545
return reject(error);
4646
}
4747

4848
resolve({
49-
// @ts-ignore
50-
files: req.files?.map((file) => ({
51-
...file,
52-
originalname: decodeURIComponent(file.originalname)
53-
}))
49+
files:
50+
// @ts-ignore
51+
req.files?.map((file) => ({
52+
...file,
53+
originalname: decodeURIComponent(file.originalname)
54+
})) || [],
55+
metadata: (() => {
56+
if (!req.body?.metadata) return {};
57+
try {
58+
return JSON.parse(req.body.metadata);
59+
} catch (error) {
60+
console.log(error);
61+
62+
return {};
63+
}
64+
})()
5465
});
5566
});
5667
});
@@ -64,7 +75,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
6475
await connectToDatabase();
6576
const { userId } = await authUser({ req, authToken: true });
6677

67-
const { files = [] } = await upload.doUpload(req, res);
78+
const { files, metadata } = await upload.doUpload(req, res);
6879

6980
const gridFs = new GridFSStorage('dataset', userId);
7081

@@ -74,8 +85,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
7485
path: file.path,
7586
filename: file.originalname,
7687
metadata: {
88+
...metadata,
7789
contentType: file.mimetype,
78-
encoding: file.encoding,
7990
userId
8091
}
8192
})

client/src/pages/api/plugins/kb/delete.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { authUser } from '@/service/utils/auth';
55
import { PgClient } from '@/service/pg';
66
import { Types } from 'mongoose';
77
import { PgTrainingTableName } from '@/constants/plugin';
8+
import { GridFSStorage } from '@/service/lib/gridfs';
89

910
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
1011
try {
@@ -21,24 +22,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
2122

2223
await connectToDatabase();
2324

24-
// delete all pg data
25-
await PgClient.delete(PgTrainingTableName, {
26-
where: [['user_id', userId], 'AND', ['kb_id', id]]
27-
});
28-
2925
// delete training data
3026
await TrainingData.deleteMany({
3127
userId,
3228
kbId: id
3329
});
3430

35-
// delete related app
36-
await App.updateMany(
37-
{
38-
userId
39-
},
40-
{ $pull: { 'chat.relatedKbs': new Types.ObjectId(id) } }
41-
);
31+
// delete all pg data
32+
await PgClient.delete(PgTrainingTableName, {
33+
where: [['user_id', userId], 'AND', ['kb_id', id]]
34+
});
35+
36+
// delete related files
37+
const gridFs = new GridFSStorage('dataset', userId);
38+
await gridFs.deleteFilesByKbId(id);
4239

4340
// delete kb data
4441
await KB.findOneAndDelete({

client/src/pages/kb/detail/components/Import/FileSelect.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import dynamic from 'next/dynamic';
1919
import MyTooltip from '@/components/MyTooltip';
2020
import { FetchResultItem, DatasetItemType } from '@/types/plugin';
2121
import { getErrText } from '@/utils/tools';
22+
import { useUserStore } from '@/store/user';
2223

2324
const UrlFetchModal = dynamic(() => import('./UrlFetchModal'));
2425
const CreateFileModal = dynamic(() => import('./CreateFileModal'));
@@ -54,6 +55,7 @@ const FileSelect = ({
5455
showCreateFile = true,
5556
...props
5657
}: Props) => {
58+
const { kbDetail } = useUserStore();
5759
const { Loading: FileSelectLoading } = useLoading();
5860
const { t } = useTranslation();
5961

@@ -109,7 +111,7 @@ const FileSelect = ({
109111
}
110112
return '';
111113
})(),
112-
uploadFiles([file], (percent) => {
114+
uploadFiles([file], { kbId: kbDetail._id }, (percent) => {
113115
if (percent < 100) {
114116
setSelectingText(
115117
t('file.Uploading', { name: file.name.slice(0, 20), percent }) || ''

client/src/pages/kb/list/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const Kb = () => {
3131
const { toast } = useToast();
3232
const { openConfirm, ConfirmModal } = useConfirm({
3333
title: '删除提示',
34-
content: '确认删除该知识库?'
34+
content: '确认删除该知识库?知识库相关的文件、记录将永久删除,无法恢复!'
3535
});
3636
const { myKbList, loadKbList, setKbList } = useUserStore();
3737

client/src/service/lib/gridfs.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export class GridFSStorage {
7979
return Promise.reject(`file not found`);
8080
}
8181

82-
if (String(file.metadata?.userId) !== this.uid) {
82+
if (file.metadata?.userId !== this.uid) {
8383
return Promise.reject(ERROR_ENUM.unAuthFile);
8484
}
8585

@@ -100,6 +100,16 @@ export class GridFSStorage {
100100
return true;
101101
}
102102

103+
async deleteFilesByKbId(kbId: string) {
104+
if (!kbId) return;
105+
const bucket = this.GridFSBucket();
106+
const files = await bucket
107+
.find({ ['metadata.kbId']: kbId, ['metadata.userId']: this.uid }, { projection: { _id: 1 } })
108+
.toArray();
109+
110+
return Promise.all(files.map((file) => this.delete(String(file._id))));
111+
}
112+
103113
async download(id: string) {
104114
await this.findAndAuthFile(id);
105115

client/src/utils/file.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ import { uploadImg, postUploadFiles } from '@/api/system';
77
/**
88
* upload file to mongo gridfs
99
*/
10-
export const uploadFiles = (files: File[], percentListen?: (percent: number) => void) => {
10+
export const uploadFiles = (
11+
files: File[],
12+
metadata: Record<string, any> = {},
13+
percentListen?: (percent: number) => void
14+
) => {
1115
const form = new FormData();
16+
form.append('metadata', JSON.stringify(metadata));
1217
files.forEach((file) => {
1318
form.append('file', file, encodeURIComponent(file.name));
1419
});

0 commit comments

Comments
 (0)