mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-05 14:47:38 +00:00
Optimize the project structure and introduce DDD design (#394)
This commit is contained in:
5
projects/app/src/web/core/api/ai.ts
Normal file
5
projects/app/src/web/core/api/ai.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
||||
import type { CreateQuestionGuideParams } from '@/global/core/api/aiReq.d';
|
||||
|
||||
export const postQuestionGuide = (data: CreateQuestionGuideParams, cancelToken: AbortController) =>
|
||||
POST<string[]>('/core/ai/agent/createQuestionGuide', data, { cancelToken });
|
57
projects/app/src/web/core/api/app.ts
Normal file
57
projects/app/src/web/core/api/app.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
|
||||
import type { AppSchema } from '@/types/mongoSchema';
|
||||
import type { AppListItemType, AppUpdateParams } from '@/types/app';
|
||||
import { RequestPaging } from '@/types/index';
|
||||
import { addDays } from 'date-fns';
|
||||
import type { GetAppChatLogsParams } from '@/global/core/api/appReq.d';
|
||||
import type { CreateAppParams } from '@/types/app';
|
||||
|
||||
/**
|
||||
* 获取模型列表
|
||||
*/
|
||||
export const getMyModels = () => GET<AppListItemType[]>('/app/myApps');
|
||||
|
||||
/**
|
||||
* 创建一个模型
|
||||
*/
|
||||
export const postCreateApp = (data: CreateAppParams) => POST<string>('/app/create', data);
|
||||
|
||||
/**
|
||||
* 根据 ID 删除模型
|
||||
*/
|
||||
export const delModelById = (id: string) => DELETE(`/app/del?appId=${id}`);
|
||||
|
||||
/**
|
||||
* 根据 ID 获取模型
|
||||
*/
|
||||
export const getModelById = (id: string) => GET<AppSchema>(`/app/detail?appId=${id}`);
|
||||
|
||||
/**
|
||||
* 根据 ID 更新模型
|
||||
*/
|
||||
export const putAppById = (id: string, data: AppUpdateParams) =>
|
||||
PUT(`/app/update?appId=${id}`, data);
|
||||
|
||||
/* 共享市场 */
|
||||
/**
|
||||
* 获取共享市场模型
|
||||
*/
|
||||
export const getShareModelList = (data: { searchText?: string } & RequestPaging) =>
|
||||
POST(`/app/share/getModels`, data);
|
||||
|
||||
/**
|
||||
* 收藏/取消收藏模型
|
||||
*/
|
||||
export const triggerModelCollection = (appId: string) =>
|
||||
POST<number>(`/app/share/collection?appId=${appId}`);
|
||||
|
||||
// ====================== data
|
||||
export const getAppTotalUsage = (data: { appId: string }) =>
|
||||
POST<{ date: String; total: number }[]>(`/app/data/totalUsage`, {
|
||||
...data,
|
||||
start: addDays(new Date(), -13),
|
||||
end: addDays(new Date(), 1)
|
||||
}).then((res) => (res.length === 0 ? [{ date: new Date(), total: 0 }] : res));
|
||||
|
||||
// =================== chat logs
|
||||
export const getAppChatLogs = (data: GetAppChatLogsParams) => POST(`/app/getChatLogs`, data);
|
45
projects/app/src/web/core/api/chat.ts
Normal file
45
projects/app/src/web/core/api/chat.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
|
||||
import type { ChatHistoryItemType } from '@/types/chat';
|
||||
import type { InitChatResponse } from '@/global/core/api/chatRes.d';
|
||||
import type { RequestPaging } from '@/types';
|
||||
import type { Props as UpdateHistoryProps } from '@/pages/api/chat/history/updateChatHistory';
|
||||
import type { AdminUpdateFeedbackParams } from '@/global/core/api/chatReq.d';
|
||||
|
||||
/**
|
||||
* 获取初始化聊天内容
|
||||
*/
|
||||
export const getInitChatSiteInfo = (data: { appId: string; chatId?: string }) =>
|
||||
GET<InitChatResponse>(`/chat/init`, data);
|
||||
|
||||
/**
|
||||
* 获取历史记录
|
||||
*/
|
||||
export const getChatHistory = (data: RequestPaging & { appId?: string }) =>
|
||||
POST<ChatHistoryItemType[]>('/chat/history/getHistory', data);
|
||||
|
||||
/**
|
||||
* 删除一条历史记录
|
||||
*/
|
||||
export const delChatHistoryById = (chatId: string) => DELETE(`/chat/removeHistory`, { chatId });
|
||||
/**
|
||||
* clear all history by appid
|
||||
*/
|
||||
export const clearChatHistoryByAppId = (appId: string) => DELETE(`/chat/removeHistory`, { appId });
|
||||
|
||||
/**
|
||||
* 删除一句对话
|
||||
*/
|
||||
export const delChatRecordById = (data: { chatId: string; contentId: string }) =>
|
||||
DELETE(`/chat/delChatRecordByContentId`, data);
|
||||
|
||||
/**
|
||||
* 修改历史记录: 标题/置顶
|
||||
*/
|
||||
export const putChatHistory = (data: UpdateHistoryProps) =>
|
||||
PUT('/chat/history/updateChatHistory', data);
|
||||
|
||||
export const userUpdateChatFeedback = (data: { chatItemId: string; userFeedback?: string }) =>
|
||||
POST('/chat/feedback/userUpdate', data);
|
||||
|
||||
export const adminUpdateChatFeedback = (data: AdminUpdateFeedbackParams) =>
|
||||
POST('/chat/feedback/adminUpdate', data);
|
123
projects/app/src/web/core/api/dataset.ts
Normal file
123
projects/app/src/web/core/api/dataset.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
||||
import type { DatasetItemType, DatasetsItemType, DatasetPathItemType } from '@/types/core/dataset';
|
||||
import type {
|
||||
DatasetUpdateParams,
|
||||
CreateDatasetParams,
|
||||
SearchTestProps,
|
||||
GetFileListProps,
|
||||
UpdateFileProps,
|
||||
MarkFileUsedProps,
|
||||
PushDataProps,
|
||||
UpdateDatasetDataPrams,
|
||||
GetDatasetDataListProps
|
||||
} from '@/global/core/api/datasetReq.d';
|
||||
import type { SearchTestResponseType, PushDataResponse } from '@/global/core/api/datasetRes.d';
|
||||
import { KbTypeEnum } from '@/constants/dataset';
|
||||
import type { DatasetFileItemType } from '@/types/core/dataset/file';
|
||||
import type { GSFileInfoType } from '@/types/common/file';
|
||||
import type { QuoteItemType } from '@/types/chat';
|
||||
import { getToken } from '@/utils/user';
|
||||
import download from 'downloadjs';
|
||||
import type { DatasetDataItemType } from '@/types/core/dataset/data';
|
||||
|
||||
/* ======================== dataset ======================= */
|
||||
export const getDatasets = (data: { parentId?: string; type?: `${KbTypeEnum}` }) =>
|
||||
GET<DatasetsItemType[]>(`/core/dataset/list`, data);
|
||||
|
||||
/**
|
||||
* get type=dataset list
|
||||
*/
|
||||
export const getAllDataset = () => GET<DatasetsItemType[]>(`/core/dataset/allDataset`);
|
||||
|
||||
export const getDatasetPaths = (parentId?: string) =>
|
||||
GET<DatasetPathItemType[]>('/core/dataset/paths', { parentId });
|
||||
|
||||
export const getDatasetById = (id: string) => GET<DatasetItemType>(`/core/dataset/detail?id=${id}`);
|
||||
|
||||
export const postCreateDataset = (data: CreateDatasetParams) =>
|
||||
POST<string>(`/core/dataset/create`, data);
|
||||
|
||||
export const putDatasetById = (data: DatasetUpdateParams) => PUT(`/core/dataset/update`, data);
|
||||
|
||||
export const delDatasetById = (id: string) => DELETE(`/core/dataset/delete?id=${id}`);
|
||||
|
||||
export const postSearchText = (data: SearchTestProps) =>
|
||||
POST<SearchTestResponseType>(`/core/dataset/searchTest`, data);
|
||||
|
||||
/* ============================= file ==================================== */
|
||||
export const getDatasetFiles = (data: GetFileListProps) =>
|
||||
POST<DatasetFileItemType[]>(`/core/dataset/file/list`, data);
|
||||
export const delDatasetFileById = (params: { fileId: string; kbId: string }) =>
|
||||
DELETE(`/core/dataset/file/delById`, params);
|
||||
export const getFileInfoById = (fileId: string) =>
|
||||
GET<GSFileInfoType>(`/core/dataset/file/detail`, { fileId });
|
||||
export const delDatasetEmptyFiles = (kbId: string) =>
|
||||
DELETE(`/core/dataset/file/delEmptyFiles`, { kbId });
|
||||
|
||||
export const updateDatasetFile = (data: UpdateFileProps) => PUT(`/core/dataset/file/update`, data);
|
||||
|
||||
export const putMarkFilesUsed = (data: MarkFileUsedProps) =>
|
||||
PUT(`/core/dataset/file/markUsed`, data);
|
||||
|
||||
/* =============================== data ==================================== */
|
||||
|
||||
/* kb data */
|
||||
export const getDatasetDataList = (data: GetDatasetDataListProps) =>
|
||||
POST(`/core/dataset/data/getDataList`, data);
|
||||
|
||||
/**
|
||||
* export and download data
|
||||
*/
|
||||
export const exportDatasetData = (data: { kbId: string }) =>
|
||||
fetch(`/api/core/dataset/data/exportAll?kbId=${data.kbId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
token: getToken()
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) {
|
||||
const data = await res.json();
|
||||
throw new Error(data?.message || 'Export failed');
|
||||
}
|
||||
return res.blob();
|
||||
})
|
||||
.then((blob) => download(blob, 'dataset.csv', 'text/csv'));
|
||||
|
||||
/**
|
||||
* 获取模型正在拆分数据的数量
|
||||
*/
|
||||
export const getTrainingData = (data: { kbId: string; init: boolean }) =>
|
||||
POST<{
|
||||
qaListLen: number;
|
||||
vectorListLen: number;
|
||||
}>(`/core/dataset/data/getTrainingData`, data);
|
||||
|
||||
/* get length of system training queue */
|
||||
export const getTrainingQueueLen = () => GET<number>(`/core/dataset/data/getQueueLen`);
|
||||
|
||||
export const getDatasetDataItemById = (dataId: string) =>
|
||||
GET<QuoteItemType>(`/core/dataset/data/getDataById`, { dataId });
|
||||
|
||||
/**
|
||||
* push data to training queue
|
||||
*/
|
||||
export const postChunks2Dataset = (data: PushDataProps) =>
|
||||
POST<PushDataResponse>(`/core/dataset/data/pushData`, data);
|
||||
|
||||
/**
|
||||
* insert one data to dataset (immediately insert)
|
||||
*/
|
||||
export const postData2Dataset = (data: { kbId: string; data: DatasetDataItemType }) =>
|
||||
POST<string>(`/core/dataset/data/insertData`, data);
|
||||
|
||||
/**
|
||||
* 更新一条数据
|
||||
*/
|
||||
export const putDatasetDataById = (data: UpdateDatasetDataPrams) =>
|
||||
PUT('/core/dataset/data/updateData', data);
|
||||
/**
|
||||
* 删除一条知识库数据
|
||||
*/
|
||||
export const delOneDatasetDataById = (dataId: string) =>
|
||||
DELETE(`/core/dataset/data/delDataById?dataId=${dataId}`);
|
119
projects/app/src/web/core/store/chat.ts
Normal file
119
projects/app/src/web/core/store/chat.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
import { ChatHistoryItemType } from '@/types/chat';
|
||||
import type { InitChatResponse } from '@/global/core/api/chatRes.d';
|
||||
import { delChatHistoryById, getChatHistory, clearChatHistoryByAppId } from '@/web/core/api/chat';
|
||||
|
||||
type State = {
|
||||
history: ChatHistoryItemType[];
|
||||
loadHistory: (data: { appId?: string }) => Promise<null>;
|
||||
delHistory(history: string): Promise<void>;
|
||||
clearHistory(appId: string): Promise<void>;
|
||||
updateHistory: (history: ChatHistoryItemType) => void;
|
||||
chatData: InitChatResponse;
|
||||
setChatData: (e: InitChatResponse | ((e: InitChatResponse) => InitChatResponse)) => void;
|
||||
lastChatAppId: string;
|
||||
setLastChatAppId: (id: string) => void;
|
||||
lastChatId: string;
|
||||
setLastChatId: (id: string) => void;
|
||||
};
|
||||
|
||||
const defaultChatData: InitChatResponse = {
|
||||
chatId: '',
|
||||
appId: '',
|
||||
app: {
|
||||
name: 'FastGPT',
|
||||
avatar: '/icon/logo.svg',
|
||||
intro: '',
|
||||
canUse: false
|
||||
},
|
||||
title: '新对话',
|
||||
variables: {},
|
||||
history: []
|
||||
};
|
||||
|
||||
export const useChatStore = create<State>()(
|
||||
devtools(
|
||||
persist(
|
||||
immer((set, get) => ({
|
||||
lastChatAppId: '',
|
||||
setLastChatAppId(id: string) {
|
||||
set((state) => {
|
||||
state.lastChatAppId = id;
|
||||
});
|
||||
},
|
||||
lastChatId: '',
|
||||
setLastChatId(id: string) {
|
||||
set((state) => {
|
||||
state.lastChatId = id;
|
||||
});
|
||||
},
|
||||
history: [],
|
||||
async loadHistory({ appId }) {
|
||||
const oneHistory = get().history[0];
|
||||
if (oneHistory && oneHistory.appId === appId) return null;
|
||||
const data = await getChatHistory({
|
||||
appId,
|
||||
pageNum: 1,
|
||||
pageSize: 20
|
||||
});
|
||||
set((state) => {
|
||||
state.history = data;
|
||||
});
|
||||
return null;
|
||||
},
|
||||
async delHistory(chatId) {
|
||||
set((state) => {
|
||||
state.history = state.history.filter((item) => item.chatId !== chatId);
|
||||
});
|
||||
await delChatHistoryById(chatId);
|
||||
},
|
||||
async clearHistory(appId) {
|
||||
set((state) => {
|
||||
state.history = [];
|
||||
});
|
||||
await clearChatHistoryByAppId(appId);
|
||||
},
|
||||
updateHistory(history) {
|
||||
const index = get().history.findIndex((item) => item.chatId === history.chatId);
|
||||
set((state) => {
|
||||
const newHistory = (() => {
|
||||
if (index > -1) {
|
||||
return [
|
||||
history,
|
||||
...get().history.slice(0, index),
|
||||
...get().history.slice(index + 1)
|
||||
];
|
||||
} else {
|
||||
return [history, ...state.history];
|
||||
}
|
||||
})();
|
||||
|
||||
state.history = newHistory;
|
||||
});
|
||||
},
|
||||
chatData: defaultChatData,
|
||||
setChatData(e = defaultChatData) {
|
||||
if (typeof e === 'function') {
|
||||
set((state) => {
|
||||
state.chatData = e(state.chatData);
|
||||
});
|
||||
} else {
|
||||
set((state) => {
|
||||
state.chatData = e;
|
||||
});
|
||||
}
|
||||
}
|
||||
})),
|
||||
{
|
||||
name: 'chatStore',
|
||||
partialize: (state) => ({
|
||||
lastChatAppId: state.lastChatAppId,
|
||||
lastChatId: state.lastChatId
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
110
projects/app/src/web/core/store/dataset.ts
Normal file
110
projects/app/src/web/core/store/dataset.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import type { SearchTestItemType } from '@/types/core/dataset';
|
||||
import type { DatasetItemType, DatasetsItemType } from '@/types/core/dataset';
|
||||
import { getAllDataset, getDatasets, getDatasetById, putDatasetById } from '@/web/core/api/dataset';
|
||||
import { defaultKbDetail } from '@/constants/dataset';
|
||||
import type { DatasetUpdateParams } from '@/global/core/api/datasetReq.d';
|
||||
|
||||
type State = {
|
||||
allDatasets: DatasetsItemType[];
|
||||
loadAllDatasets: () => Promise<DatasetsItemType[]>;
|
||||
myKbList: DatasetsItemType[];
|
||||
loadKbList: (parentId?: string) => Promise<any>;
|
||||
setKbList(val: DatasetsItemType[]): void;
|
||||
kbDetail: DatasetItemType;
|
||||
getKbDetail: (id: string, init?: boolean) => Promise<DatasetItemType>;
|
||||
updateDataset: (data: DatasetUpdateParams) => Promise<any>;
|
||||
|
||||
kbTestList: SearchTestItemType[];
|
||||
pushKbTestItem: (data: SearchTestItemType) => void;
|
||||
delKbTestItemById: (id: string) => void;
|
||||
updateKbItemById: (data: SearchTestItemType) => void;
|
||||
};
|
||||
|
||||
export const useDatasetStore = create<State>()(
|
||||
devtools(
|
||||
persist(
|
||||
immer((set, get) => ({
|
||||
allDatasets: [],
|
||||
async loadAllDatasets() {
|
||||
const res = await getAllDataset();
|
||||
set((state) => {
|
||||
state.allDatasets = res;
|
||||
});
|
||||
return res;
|
||||
},
|
||||
myKbList: [],
|
||||
async loadKbList(parentId = '') {
|
||||
const res = await getDatasets({ parentId });
|
||||
set((state) => {
|
||||
state.myKbList = res;
|
||||
});
|
||||
return res;
|
||||
},
|
||||
setKbList(val) {
|
||||
set((state) => {
|
||||
state.myKbList = val;
|
||||
});
|
||||
},
|
||||
kbDetail: defaultKbDetail,
|
||||
async getKbDetail(id: string, init = false) {
|
||||
if (id === get().kbDetail._id && !init) return get().kbDetail;
|
||||
|
||||
const data = await getDatasetById(id);
|
||||
|
||||
set((state) => {
|
||||
state.kbDetail = data;
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
async updateDataset(data) {
|
||||
if (get().kbDetail._id === data.id) {
|
||||
set((state) => {
|
||||
state.kbDetail = {
|
||||
...state.kbDetail,
|
||||
...data
|
||||
};
|
||||
});
|
||||
}
|
||||
set((state) => {
|
||||
state.myKbList = state.myKbList = state.myKbList.map((item) =>
|
||||
item._id === data.id
|
||||
? {
|
||||
...item,
|
||||
...data,
|
||||
tags: data.tags?.split(' ') || []
|
||||
}
|
||||
: item
|
||||
);
|
||||
});
|
||||
await putDatasetById(data);
|
||||
},
|
||||
kbTestList: [],
|
||||
pushKbTestItem(data) {
|
||||
set((state) => {
|
||||
state.kbTestList = [data, ...state.kbTestList].slice(0, 500);
|
||||
});
|
||||
},
|
||||
delKbTestItemById(id) {
|
||||
set((state) => {
|
||||
state.kbTestList = state.kbTestList.filter((item) => item.id !== id);
|
||||
});
|
||||
},
|
||||
updateKbItemById(data: SearchTestItemType) {
|
||||
set((state) => {
|
||||
state.kbTestList = state.kbTestList.map((item) => (item.id === data.id ? data : item));
|
||||
});
|
||||
}
|
||||
})),
|
||||
{
|
||||
name: 'kbStore',
|
||||
partialize: (state) => ({
|
||||
kbTestList: state.kbTestList
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
137
projects/app/src/web/core/store/shareChat.ts
Normal file
137
projects/app/src/web/core/store/shareChat.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
import type { ChatSiteItemType, ShareChatHistoryItemType, ShareChatType } from '@/types/chat';
|
||||
import { HUMAN_ICON } from '@/constants/chat';
|
||||
|
||||
type State = {
|
||||
shareChatData: ShareChatType;
|
||||
setShareChatData: (e: ShareChatType | ((e: ShareChatType) => ShareChatType)) => void;
|
||||
shareChatHistory: ShareChatHistoryItemType[];
|
||||
saveChatResponse: (e: {
|
||||
chatId: string;
|
||||
prompts: ChatSiteItemType[];
|
||||
variables: Record<string, any>;
|
||||
shareId: string;
|
||||
}) => void;
|
||||
delOneShareHistoryByChatId: (chatId: string) => void;
|
||||
delShareChatHistoryItemById: (e: { chatId: string; contentId?: string; index: number }) => void;
|
||||
delManyShareChatHistoryByShareId: (shareId?: string) => void;
|
||||
};
|
||||
|
||||
export const defaultHistory: ShareChatHistoryItemType = {
|
||||
chatId: `${Date.now()}`,
|
||||
updateTime: new Date(),
|
||||
title: '新对话',
|
||||
shareId: '',
|
||||
chats: []
|
||||
};
|
||||
const defaultShareChatData: ShareChatType = {
|
||||
userAvatar: HUMAN_ICON,
|
||||
app: {
|
||||
name: '',
|
||||
avatar: '/icon/logo.svg',
|
||||
intro: ''
|
||||
},
|
||||
history: defaultHistory
|
||||
};
|
||||
|
||||
export const useShareChatStore = create<State>()(
|
||||
devtools(
|
||||
persist(
|
||||
immer((set, get) => ({
|
||||
shareChatData: defaultShareChatData,
|
||||
setShareChatData(e) {
|
||||
const val = (() => {
|
||||
if (typeof e === 'function') {
|
||||
return e(get().shareChatData);
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
})();
|
||||
set((state) => {
|
||||
state.shareChatData = val;
|
||||
// update history
|
||||
state.shareChatHistory = state.shareChatHistory.map((item) =>
|
||||
item.chatId === val.history.chatId ? val.history : item
|
||||
);
|
||||
});
|
||||
},
|
||||
shareChatHistory: [],
|
||||
saveChatResponse({ chatId, prompts, variables, shareId }) {
|
||||
const chatHistory = get().shareChatHistory.find((item) => item.chatId === chatId);
|
||||
|
||||
const historyList = (() => {
|
||||
if (chatHistory) {
|
||||
return get().shareChatHistory.map((item) =>
|
||||
item.chatId === chatId
|
||||
? {
|
||||
...item,
|
||||
title: prompts[prompts.length - 2]?.value,
|
||||
updateTime: new Date(),
|
||||
chats: chatHistory.chats.concat(prompts).slice(-50),
|
||||
variables
|
||||
}
|
||||
: item
|
||||
);
|
||||
}
|
||||
return get().shareChatHistory.concat({
|
||||
chatId,
|
||||
shareId,
|
||||
title: prompts[prompts.length - 2]?.value,
|
||||
updateTime: new Date(),
|
||||
chats: prompts,
|
||||
variables
|
||||
});
|
||||
})();
|
||||
|
||||
// @ts-ignore
|
||||
historyList.sort((a, b) => new Date(b.updateTime) - new Date(a.updateTime));
|
||||
|
||||
set((state) => {
|
||||
state.shareChatHistory = historyList.slice(0, 100);
|
||||
});
|
||||
},
|
||||
delOneShareHistoryByChatId(chatId: string) {
|
||||
set((state) => {
|
||||
state.shareChatHistory = state.shareChatHistory.filter(
|
||||
(item) => item.chatId !== chatId
|
||||
);
|
||||
});
|
||||
},
|
||||
delShareChatHistoryItemById({ chatId, contentId }) {
|
||||
set((state) => {
|
||||
// update history store
|
||||
const newHistoryList = state.shareChatHistory.map((item) =>
|
||||
item.chatId === chatId
|
||||
? {
|
||||
...item,
|
||||
chats: item.chats.filter((item) => item.dataId !== contentId)
|
||||
}
|
||||
: item
|
||||
);
|
||||
state.shareChatHistory = newHistoryList;
|
||||
});
|
||||
},
|
||||
delManyShareChatHistoryByShareId(shareId?: string) {
|
||||
set((state) => {
|
||||
if (shareId) {
|
||||
state.shareChatHistory = state.shareChatHistory.filter(
|
||||
(item) => item.shareId !== shareId
|
||||
);
|
||||
} else {
|
||||
state.shareChatHistory = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
})),
|
||||
{
|
||||
name: 'shareChatStore',
|
||||
partialize: (state) => ({
|
||||
shareChatHistory: state.shareChatHistory
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
53
projects/app/src/web/core/utils/dataset.ts
Normal file
53
projects/app/src/web/core/utils/dataset.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { postCreateTrainingBill } from '@/web/common/api/bill';
|
||||
import { postChunks2Dataset } from '@/web/core/api/dataset';
|
||||
import { TrainingModeEnum } from '@/constants/plugin';
|
||||
import type { DatasetDataItemType } from '@/types/core/dataset/data';
|
||||
import { delay } from '@/utils/tools';
|
||||
|
||||
export async function chunksUpload({
|
||||
kbId,
|
||||
mode,
|
||||
chunks,
|
||||
prompt,
|
||||
rate = 150,
|
||||
onUploading
|
||||
}: {
|
||||
kbId: string;
|
||||
mode: `${TrainingModeEnum}`;
|
||||
chunks: DatasetDataItemType[];
|
||||
prompt?: string;
|
||||
rate?: number;
|
||||
onUploading?: (insertLen: number, total: number) => void;
|
||||
}) {
|
||||
// create training bill
|
||||
const billId = await postCreateTrainingBill({ name: 'dataset.Training Name' });
|
||||
|
||||
async function upload(data: DatasetDataItemType[]) {
|
||||
return postChunks2Dataset({
|
||||
kbId,
|
||||
data,
|
||||
mode,
|
||||
prompt,
|
||||
billId
|
||||
});
|
||||
}
|
||||
|
||||
let successInsert = 0;
|
||||
let retryTimes = 10;
|
||||
for (let i = 0; i < chunks.length; i += rate) {
|
||||
try {
|
||||
const { insertLen } = await upload(chunks.slice(i, i + rate));
|
||||
onUploading && onUploading(i + rate, chunks.length);
|
||||
successInsert += insertLen;
|
||||
} catch (error) {
|
||||
if (retryTimes === 0) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
await delay(1000);
|
||||
retryTimes--;
|
||||
i -= rate;
|
||||
}
|
||||
}
|
||||
|
||||
return { insertLen: successInsert };
|
||||
}
|
Reference in New Issue
Block a user