feat: 模型数据管理
This commit is contained in:
parent
713332522f
commit
f32c557bdd
@ -41,6 +41,7 @@
|
|||||||
"react-hook-form": "^7.43.1",
|
"react-hook-form": "^7.43.1",
|
||||||
"react-markdown": "^8.0.5",
|
"react-markdown": "^8.0.5",
|
||||||
"react-syntax-highlighter": "^15.5.0",
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
|
"redis": "^4.6.5",
|
||||||
"rehype-katex": "^6.0.2",
|
"rehype-katex": "^6.0.2",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remark-math": "^5.1.1",
|
"remark-math": "^5.1.1",
|
||||||
|
|||||||
95
pnpm-lock.yaml
generated
95
pnpm-lock.yaml
generated
@ -47,6 +47,7 @@ specifiers:
|
|||||||
react-hook-form: ^7.43.1
|
react-hook-form: ^7.43.1
|
||||||
react-markdown: ^8.0.5
|
react-markdown: ^8.0.5
|
||||||
react-syntax-highlighter: ^15.5.0
|
react-syntax-highlighter: ^15.5.0
|
||||||
|
redis: ^4.6.5
|
||||||
rehype-katex: ^6.0.2
|
rehype-katex: ^6.0.2
|
||||||
remark-gfm: ^3.0.1
|
remark-gfm: ^3.0.1
|
||||||
remark-math: ^5.1.1
|
remark-math: ^5.1.1
|
||||||
@ -87,6 +88,7 @@ dependencies:
|
|||||||
react-hook-form: registry.npmmirror.com/react-hook-form/7.43.1_react@18.2.0
|
react-hook-form: registry.npmmirror.com/react-hook-form/7.43.1_react@18.2.0
|
||||||
react-markdown: registry.npmmirror.com/react-markdown/8.0.5_pmekkgnqduwlme35zpnqhenc34
|
react-markdown: registry.npmmirror.com/react-markdown/8.0.5_pmekkgnqduwlme35zpnqhenc34
|
||||||
react-syntax-highlighter: registry.npmmirror.com/react-syntax-highlighter/15.5.0_react@18.2.0
|
react-syntax-highlighter: registry.npmmirror.com/react-syntax-highlighter/15.5.0_react@18.2.0
|
||||||
|
redis: registry.npmmirror.com/redis/4.6.5
|
||||||
rehype-katex: registry.npmmirror.com/rehype-katex/6.0.2
|
rehype-katex: registry.npmmirror.com/rehype-katex/6.0.2
|
||||||
remark-gfm: registry.npmmirror.com/remark-gfm/3.0.1
|
remark-gfm: registry.npmmirror.com/remark-gfm/3.0.1
|
||||||
remark-math: registry.npmmirror.com/remark-math/5.1.1
|
remark-math: registry.npmmirror.com/remark-math/5.1.1
|
||||||
@ -4504,6 +4506,72 @@ packages:
|
|||||||
version: 2.11.6
|
version: 2.11.6
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/@redis/bloom/1.2.0_@redis+client@1.5.6:
|
||||||
|
resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@redis/bloom/-/bloom-1.2.0.tgz}
|
||||||
|
id: registry.npmmirror.com/@redis/bloom/1.2.0
|
||||||
|
name: '@redis/bloom'
|
||||||
|
version: 1.2.0
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': registry.npmmirror.com/@redis/client/1.5.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/@redis/client/1.5.6:
|
||||||
|
resolution: {integrity: sha512-dFD1S6je+A47Lj22jN/upVU2fj4huR7S9APd7/ziUXsIXDL+11GPYti4Suv5y8FuXaN+0ZG4JF+y1houEJ7ToA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@redis/client/-/client-1.5.6.tgz}
|
||||||
|
name: '@redis/client'
|
||||||
|
version: 1.5.6
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
dependencies:
|
||||||
|
cluster-key-slot: registry.npmmirror.com/cluster-key-slot/1.1.2
|
||||||
|
generic-pool: registry.npmmirror.com/generic-pool/3.9.0
|
||||||
|
yallist: registry.npmmirror.com/yallist/4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/@redis/graph/1.1.0_@redis+client@1.5.6:
|
||||||
|
resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@redis/graph/-/graph-1.1.0.tgz}
|
||||||
|
id: registry.npmmirror.com/@redis/graph/1.1.0
|
||||||
|
name: '@redis/graph'
|
||||||
|
version: 1.1.0
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': registry.npmmirror.com/@redis/client/1.5.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/@redis/json/1.0.4_@redis+client@1.5.6:
|
||||||
|
resolution: {integrity: sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@redis/json/-/json-1.0.4.tgz}
|
||||||
|
id: registry.npmmirror.com/@redis/json/1.0.4
|
||||||
|
name: '@redis/json'
|
||||||
|
version: 1.0.4
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': registry.npmmirror.com/@redis/client/1.5.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/@redis/search/1.1.2_@redis+client@1.5.6:
|
||||||
|
resolution: {integrity: sha512-/cMfstG/fOh/SsE+4/BQGeuH/JJloeWuH+qJzM8dbxuWvdWibWAOAHHCZTMPhV3xIlH4/cUEIA8OV5QnYpaVoA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@redis/search/-/search-1.1.2.tgz}
|
||||||
|
id: registry.npmmirror.com/@redis/search/1.1.2
|
||||||
|
name: '@redis/search'
|
||||||
|
version: 1.1.2
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': registry.npmmirror.com/@redis/client/1.5.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/@redis/time-series/1.0.4_@redis+client@1.5.6:
|
||||||
|
resolution: {integrity: sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@redis/time-series/-/time-series-1.0.4.tgz}
|
||||||
|
id: registry.npmmirror.com/@redis/time-series/1.0.4
|
||||||
|
name: '@redis/time-series'
|
||||||
|
version: 1.0.4
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': registry.npmmirror.com/@redis/client/1.5.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/@rushstack/eslint-patch/1.2.0:
|
registry.npmmirror.com/@rushstack/eslint-patch/1.2.0:
|
||||||
resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz}
|
resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz}
|
||||||
name: '@rushstack/eslint-patch'
|
name: '@rushstack/eslint-patch'
|
||||||
@ -5562,6 +5630,13 @@ packages:
|
|||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/cluster-key-slot/1.1.2:
|
||||||
|
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz}
|
||||||
|
name: cluster-key-slot
|
||||||
|
version: 1.1.2
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/color-convert/1.9.3:
|
registry.npmmirror.com/color-convert/1.9.3:
|
||||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz}
|
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz}
|
||||||
name: color-convert
|
name: color-convert
|
||||||
@ -6799,6 +6874,13 @@ packages:
|
|||||||
version: 1.2.3
|
version: 1.2.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/generic-pool/3.9.0:
|
||||||
|
resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/generic-pool/-/generic-pool-3.9.0.tgz}
|
||||||
|
name: generic-pool
|
||||||
|
version: 3.9.0
|
||||||
|
engines: {node: '>= 4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/gensync/1.0.0-beta.2:
|
registry.npmmirror.com/gensync/1.0.0-beta.2:
|
||||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz}
|
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz}
|
||||||
name: gensync
|
name: gensync
|
||||||
@ -9367,6 +9449,19 @@ packages:
|
|||||||
picomatch: registry.npmmirror.com/picomatch/2.3.1
|
picomatch: registry.npmmirror.com/picomatch/2.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/redis/4.6.5:
|
||||||
|
resolution: {integrity: sha512-O0OWA36gDQbswOdUuAhRL6mTZpHFN525HlgZgDaVNgCJIAZR3ya06NTESb0R+TUZ+BFaDpz6NnnVvoMx9meUFg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/redis/-/redis-4.6.5.tgz}
|
||||||
|
name: redis
|
||||||
|
version: 4.6.5
|
||||||
|
dependencies:
|
||||||
|
'@redis/bloom': registry.npmmirror.com/@redis/bloom/1.2.0_@redis+client@1.5.6
|
||||||
|
'@redis/client': registry.npmmirror.com/@redis/client/1.5.6
|
||||||
|
'@redis/graph': registry.npmmirror.com/@redis/graph/1.1.0_@redis+client@1.5.6
|
||||||
|
'@redis/json': registry.npmmirror.com/@redis/json/1.0.4_@redis+client@1.5.6
|
||||||
|
'@redis/search': registry.npmmirror.com/@redis/search/1.1.2_@redis+client@1.5.6
|
||||||
|
'@redis/time-series': registry.npmmirror.com/@redis/time-series/1.0.4_@redis+client@1.5.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/refractor/3.6.0:
|
registry.npmmirror.com/refractor/3.6.0:
|
||||||
resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/refractor/-/refractor-3.6.0.tgz}
|
resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/refractor/-/refractor-3.6.0.tgz}
|
||||||
name: refractor
|
name: refractor
|
||||||
|
|||||||
@ -2,6 +2,9 @@ import { GET, POST, DELETE, PUT } from './request';
|
|||||||
import type { ModelSchema } from '@/types/mongoSchema';
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
import { ModelUpdateParams } from '@/types/model';
|
import { ModelUpdateParams } from '@/types/model';
|
||||||
import { TrainingItemType } from '../types/training';
|
import { TrainingItemType } from '../types/training';
|
||||||
|
import { PagingData } from '@/types';
|
||||||
|
import { RequestPaging } from '../types/index';
|
||||||
|
import { Obj2Query } from '@/utils/tools';
|
||||||
|
|
||||||
export const getMyModels = () => GET<ModelSchema[]>('/model/list');
|
export const getMyModels = () => GET<ModelSchema[]>('/model/list');
|
||||||
|
|
||||||
@ -16,13 +19,30 @@ export const putModelById = (id: string, data: ModelUpdateParams) =>
|
|||||||
PUT(`/model/update?modelId=${id}`, data);
|
PUT(`/model/update?modelId=${id}`, data);
|
||||||
|
|
||||||
export const postTrainModel = (id: string, form: FormData) =>
|
export const postTrainModel = (id: string, form: FormData) =>
|
||||||
POST(`/model/train?modelId=${id}`, form, {
|
POST(`/model/train/train?modelId=${id}`, form, {
|
||||||
headers: {
|
headers: {
|
||||||
'content-type': 'multipart/form-data'
|
'content-type': 'multipart/form-data'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const putModelTrainingStatus = (id: string) => PUT(`/model/putTrainStatus?modelId=${id}`);
|
export const putModelTrainingStatus = (id: string) =>
|
||||||
|
PUT(`/model/train/putTrainStatus?modelId=${id}`);
|
||||||
|
|
||||||
export const getModelTrainings = (id: string) =>
|
export const getModelTrainings = (id: string) =>
|
||||||
GET<TrainingItemType[]>(`/model/getTrainings?modelId=${id}`);
|
GET<TrainingItemType[]>(`/model/train/getTrainings?modelId=${id}`);
|
||||||
|
|
||||||
|
/* 模型 data */
|
||||||
|
|
||||||
|
type GetModelDataListProps = RequestPaging & {
|
||||||
|
modelId: string;
|
||||||
|
};
|
||||||
|
export const getModelDataList = (props: GetModelDataListProps) =>
|
||||||
|
GET(`/model/data/getModelData?${Obj2Query(props)}`);
|
||||||
|
|
||||||
|
export const postModelData = (data: { modelId: string; data: { q: string; a: string }[] }) =>
|
||||||
|
POST(`/model/data/pushModelData`, data);
|
||||||
|
|
||||||
|
export const putModelDataById = (data: { modelId: string; answer: string }) =>
|
||||||
|
PUT('/model/data/putModelData', data);
|
||||||
|
export const DelOneModelData = (modelId: string) =>
|
||||||
|
DELETE(`/model/data/delModelDataById?modelId=${modelId}`);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import type { ServiceName } from '@/types/mongoSchema';
|
import type { ServiceName, ModelDataType, ModelSchema } from '@/types/mongoSchema';
|
||||||
import { ModelSchema } from '../types/mongoSchema';
|
|
||||||
|
|
||||||
export enum ChatModelNameEnum {
|
export enum ChatModelNameEnum {
|
||||||
GPT35 = 'gpt-3.5-turbo',
|
GPT35 = 'gpt-3.5-turbo',
|
||||||
@ -76,6 +75,12 @@ export const formatModelStatus = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ModelDataStatusMap: Record<ModelDataType, string> = {
|
||||||
|
0: '训练完成',
|
||||||
|
1: '等待训练',
|
||||||
|
2: '训练中'
|
||||||
|
};
|
||||||
|
|
||||||
export const defaultModel: ModelSchema = {
|
export const defaultModel: ModelSchema = {
|
||||||
_id: '',
|
_id: '',
|
||||||
userId: '',
|
userId: '',
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export const usePaging = <T = any>({
|
|||||||
pageSize = 10,
|
pageSize = 10,
|
||||||
params = {}
|
params = {}
|
||||||
}: {
|
}: {
|
||||||
api: (data: any) => Promise<PagingData<T>>;
|
api: (data: any) => any;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
params?: Record<string, any>;
|
params?: Record<string, any>;
|
||||||
}) => {
|
}) => {
|
||||||
@ -30,7 +30,7 @@ export const usePaging = <T = any>({
|
|||||||
setRequesting(true);
|
setRequesting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await api({
|
const res: PagingData<T> = await api({
|
||||||
pageNum: num,
|
pageNum: num,
|
||||||
pageSize,
|
pageSize,
|
||||||
...params
|
...params
|
||||||
|
|||||||
@ -14,6 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
pageNum: string;
|
pageNum: string;
|
||||||
pageSize: string;
|
pageSize: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { authorization } = req.headers;
|
const { authorization } = req.headers;
|
||||||
|
|
||||||
pageNum = +pageNum;
|
pageNum = +pageNum;
|
||||||
@ -41,7 +42,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
.limit(pageSize);
|
.limit(pageSize);
|
||||||
|
|
||||||
jsonRes(res, {
|
jsonRes(res, {
|
||||||
data
|
data: {
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
data,
|
||||||
|
total: await ModelData.countDocuments({
|
||||||
|
modelId,
|
||||||
|
userId
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
jsonRes(res, {
|
jsonRes(res, {
|
||||||
|
|||||||
86
src/pages/model/components/ModelDataCard.tsx
Normal file
86
src/pages/model/components/ModelDataCard.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import React, { useEffect, useCallback, useState } from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
TableContainer,
|
||||||
|
Table,
|
||||||
|
Thead,
|
||||||
|
Tbody,
|
||||||
|
Tr,
|
||||||
|
Th,
|
||||||
|
Td,
|
||||||
|
IconButton,
|
||||||
|
Flex,
|
||||||
|
Button
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
|
import { ModelDataSchema } from '@/types/mongoSchema';
|
||||||
|
import { ModelDataStatusMap } from '@/constants/model';
|
||||||
|
import { usePaging } from '@/hooks/usePaging';
|
||||||
|
import ScrollData from '@/components/ScrollData';
|
||||||
|
import { getModelDataList } from '@/api/model';
|
||||||
|
import { DeleteIcon } from '@chakra-ui/icons';
|
||||||
|
|
||||||
|
const ModelDataCard = ({ model }: { model: ModelSchema }) => {
|
||||||
|
const {
|
||||||
|
nextPage,
|
||||||
|
isLoadAll,
|
||||||
|
requesting,
|
||||||
|
data: dataList,
|
||||||
|
total
|
||||||
|
} = usePaging<ModelDataSchema>({
|
||||||
|
api: getModelDataList,
|
||||||
|
pageSize: 10,
|
||||||
|
params: {
|
||||||
|
modelId: model._id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Flex>
|
||||||
|
<Box fontWeight={'bold'} fontSize={'lg'} flex={1}>
|
||||||
|
模型数据: {total}组
|
||||||
|
</Box>
|
||||||
|
<Button size={'sm'}>导入</Button>
|
||||||
|
</Flex>
|
||||||
|
<ScrollData
|
||||||
|
flex={'1 0 0'}
|
||||||
|
h={0}
|
||||||
|
px={6}
|
||||||
|
mt={3}
|
||||||
|
isLoadAll={isLoadAll}
|
||||||
|
requesting={requesting}
|
||||||
|
nextPage={nextPage}
|
||||||
|
fontSize={'xs'}
|
||||||
|
whiteSpace={'pre-wrap'}
|
||||||
|
>
|
||||||
|
<TableContainer mt={4}>
|
||||||
|
<Table variant={'simple'}>
|
||||||
|
<Thead>
|
||||||
|
<Tr>
|
||||||
|
<Th>Question</Th>
|
||||||
|
<Th>Text</Th>
|
||||||
|
<Th>Status</Th>
|
||||||
|
<Th></Th>
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
<Tbody>
|
||||||
|
{dataList.map((item) => (
|
||||||
|
<Tr key={item._id}>
|
||||||
|
<Td>{item.q}</Td>
|
||||||
|
<Td>{item.a}</Td>
|
||||||
|
<Td>{ModelDataStatusMap[item.status]}</Td>
|
||||||
|
<Td>
|
||||||
|
<IconButton icon={<DeleteIcon />} aria-label={'delete'} />
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</ScrollData>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModelDataCard;
|
||||||
@ -11,13 +11,26 @@ import {
|
|||||||
SliderFilledTrack,
|
SliderFilledTrack,
|
||||||
SliderThumb,
|
SliderThumb,
|
||||||
SliderMark,
|
SliderMark,
|
||||||
Tooltip
|
Tooltip,
|
||||||
|
Button
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||||
import type { ModelSchema } from '@/types/mongoSchema';
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
import { UseFormReturn } from 'react-hook-form';
|
import { UseFormReturn } from 'react-hook-form';
|
||||||
|
import { modelList } from '@/constants/model';
|
||||||
|
import { formatPrice } from '@/utils/user';
|
||||||
|
import { useConfirm } from '@/hooks/useConfirm';
|
||||||
|
|
||||||
const ModelEditForm = ({ formHooks }: { formHooks: UseFormReturn<ModelSchema> }) => {
|
const ModelEditForm = ({
|
||||||
|
formHooks,
|
||||||
|
handleDelModel
|
||||||
|
}: {
|
||||||
|
formHooks: UseFormReturn<ModelSchema>;
|
||||||
|
handleDelModel: () => void;
|
||||||
|
}) => {
|
||||||
|
const { openConfirm, ConfirmChild } = useConfirm({
|
||||||
|
content: '确认删除该模型?'
|
||||||
|
});
|
||||||
const { register, setValue, getValues } = formHooks;
|
const { register, setValue, getValues } = formHooks;
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
|
|
||||||
@ -29,7 +42,7 @@ const ModelEditForm = ({ formHooks }: { formHooks: UseFormReturn<ModelSchema> })
|
|||||||
</Flex>
|
</Flex>
|
||||||
<FormControl mt={4}>
|
<FormControl mt={4}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 50px'} w={0}>
|
<Box flex={'0 0 80px'} w={0}>
|
||||||
名称:
|
名称:
|
||||||
</Box>
|
</Box>
|
||||||
<Input
|
<Input
|
||||||
@ -39,7 +52,36 @@ const ModelEditForm = ({ formHooks }: { formHooks: UseFormReturn<ModelSchema> })
|
|||||||
></Input>
|
></Input>
|
||||||
</Flex>
|
</Flex>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl mt={4}>
|
<Flex alignItems={'center'} mt={4}>
|
||||||
|
<Box flex={'0 0 80px'} w={0}>
|
||||||
|
底层模型:
|
||||||
|
</Box>
|
||||||
|
<Box>{getValues('service.modelName')}</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex alignItems={'center'} mt={4}>
|
||||||
|
<Box flex={'0 0 80px'} w={0}>
|
||||||
|
价格:
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
{formatPrice(
|
||||||
|
modelList.find((item) => item.model === getValues('service.modelName'))?.price || 0,
|
||||||
|
1000
|
||||||
|
)}
|
||||||
|
元/1K tokens(包括上下文和回答)
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex mt={5} alignItems={'center'}>
|
||||||
|
<Box flex={'0 0 80px'}>删除:</Box>
|
||||||
|
<Button
|
||||||
|
colorScheme={'gray'}
|
||||||
|
variant={'outline'}
|
||||||
|
size={'sm'}
|
||||||
|
onClick={openConfirm(handleDelModel)}
|
||||||
|
>
|
||||||
|
删除模型
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
{/* <FormControl mt={4}>
|
||||||
<Box mb={1}>介绍:</Box>
|
<Box mb={1}>介绍:</Box>
|
||||||
<Textarea
|
<Textarea
|
||||||
rows={5}
|
rows={5}
|
||||||
@ -47,7 +89,7 @@ const ModelEditForm = ({ formHooks }: { formHooks: UseFormReturn<ModelSchema> })
|
|||||||
{...register('intro')}
|
{...register('intro')}
|
||||||
placeholder={'模型的介绍,仅做展示,不影响模型的效果'}
|
placeholder={'模型的介绍,仅做展示,不影响模型的效果'}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl> */}
|
||||||
</Card>
|
</Card>
|
||||||
<Card p={4}>
|
<Card p={4}>
|
||||||
<Box fontWeight={'bold'}>模型效果</Box>
|
<Box fontWeight={'bold'}>模型效果</Box>
|
||||||
@ -202,6 +244,7 @@ const ModelEditForm = ({ formHooks }: { formHooks: UseFormReturn<ModelSchema> })
|
|||||||
</Flex>
|
</Flex>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Card> */}
|
</Card> */}
|
||||||
|
<ConfirmChild />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,36 +11,34 @@ import { getChatSiteId } from '@/api/chat';
|
|||||||
import type { ModelSchema } from '@/types/mongoSchema';
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
import { Card, Box, Flex, Button, Tag, Grid } from '@chakra-ui/react';
|
import { Card, Box, Flex, Button, Tag, Grid } from '@chakra-ui/react';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { useConfirm } from '@/hooks/useConfirm';
|
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { formatModelStatus, ModelStatusEnum, modelList, defaultModel } from '@/constants/model';
|
import { formatModelStatus, ModelStatusEnum, modelList, defaultModel } from '@/constants/model';
|
||||||
import { useGlobalStore } from '@/store/global';
|
import { useGlobalStore } from '@/store/global';
|
||||||
import { useScreen } from '@/hooks/useScreen';
|
import { useScreen } from '@/hooks/useScreen';
|
||||||
import ModelEditForm from './components/ModelEditForm';
|
import ModelEditForm from './components/ModelEditForm';
|
||||||
import Icon from '@/components/Iconfont';
|
// import Icon from '@/components/Iconfont';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import dynamic from 'next/dynamic';
|
// import dynamic from 'next/dynamic';
|
||||||
|
import ModelDataCard from './components/ModelDataCard';
|
||||||
|
|
||||||
const Training = dynamic(() => import('./components/Training'));
|
// const Training = dynamic(() => import('./components/Training'));
|
||||||
|
|
||||||
const ModelDetail = ({ modelId }: { modelId: string }) => {
|
const ModelDetail = ({ modelId }: { modelId: string }) => {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { isPc, media } = useScreen();
|
const { isPc, media } = useScreen();
|
||||||
const { setLoading } = useGlobalStore();
|
const { setLoading } = useGlobalStore();
|
||||||
const { openConfirm, ConfirmChild } = useConfirm({
|
|
||||||
content: '确认删除该模型?'
|
|
||||||
});
|
|
||||||
const SelectFileDom = useRef<HTMLInputElement>(null);
|
const SelectFileDom = useRef<HTMLInputElement>(null);
|
||||||
const [model, setModel] = useState<ModelSchema>(defaultModel);
|
const [model, setModel] = useState<ModelSchema>(defaultModel);
|
||||||
const formHooks = useForm<ModelSchema>({
|
const formHooks = useForm<ModelSchema>({
|
||||||
defaultValues: model
|
defaultValues: model
|
||||||
});
|
});
|
||||||
|
|
||||||
const canTrain = useMemo(() => {
|
// const canTrain = useMemo(() => {
|
||||||
const openai = modelList.find((item) => item.model === model?.service.modelName);
|
// const openai = modelList.find((item) => item.model === model?.service.modelName);
|
||||||
return openai && openai.trainName;
|
// return openai && openai.trainName;
|
||||||
}, [model]);
|
// }, [model]);
|
||||||
|
|
||||||
/* 加载模型数据 */
|
/* 加载模型数据 */
|
||||||
const loadModel = useCallback(async () => {
|
const loadModel = useCallback(async () => {
|
||||||
@ -250,79 +248,15 @@ const ModelDetail = ({ modelId }: { modelId: string }) => {
|
|||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
<Grid mt={5} gridTemplateColumns={media('1fr 1fr', '1fr')} gridGap={5}>
|
<Grid mt={5} gridTemplateColumns={media('1fr 1fr', '1fr')} gridGap={5}>
|
||||||
<ModelEditForm formHooks={formHooks} />
|
<ModelEditForm formHooks={formHooks} handleDelModel={handleDelModel} />
|
||||||
|
|
||||||
{canTrain && (
|
{/* {canTrain && (
|
||||||
<Card p={4}>
|
<Card p={4}>
|
||||||
<Training model={model} />
|
<Training model={model} />
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)} */}
|
||||||
|
<Card p={4} height={'400px'} gridColumnStart={1} gridColumnEnd={3}>
|
||||||
<Card p={4}>
|
{model._id && <ModelDataCard model={model} />}
|
||||||
<Box fontWeight={'bold'} fontSize={'lg'}>
|
|
||||||
神奇操作
|
|
||||||
</Box>
|
|
||||||
<Flex mt={5} alignItems={'center'}>
|
|
||||||
<Box flex={'0 0 80px'}>模型微调:</Box>
|
|
||||||
<Button
|
|
||||||
size={'sm'}
|
|
||||||
onClick={() => {
|
|
||||||
SelectFileDom.current?.click();
|
|
||||||
}}
|
|
||||||
title={!canTrain ? '模型不支持微调' : ''}
|
|
||||||
isDisabled={!canTrain}
|
|
||||||
>
|
|
||||||
上传数据集
|
|
||||||
</Button>
|
|
||||||
<Flex
|
|
||||||
as={'a'}
|
|
||||||
href="/TrainingTemplate.jsonl"
|
|
||||||
download
|
|
||||||
ml={5}
|
|
||||||
cursor={'pointer'}
|
|
||||||
alignItems={'center'}
|
|
||||||
color={'blue.500'}
|
|
||||||
>
|
|
||||||
<Icon name={'icon-yunxiazai'} color={'#3182ce'} />
|
|
||||||
下载模板
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
{/* 提示 */}
|
|
||||||
<Box mt={3} py={3} color={'blackAlpha.600'}>
|
|
||||||
<Box as={'li'} lineHeight={1.9}>
|
|
||||||
暂时需要使用自己的openai key
|
|
||||||
</Box>
|
|
||||||
<Box as={'li'} lineHeight={1.9}>
|
|
||||||
可以使用
|
|
||||||
<Box
|
|
||||||
as={'span'}
|
|
||||||
fontWeight={'bold'}
|
|
||||||
textDecoration={'underline'}
|
|
||||||
color={'blackAlpha.800'}
|
|
||||||
mx={2}
|
|
||||||
cursor={'pointer'}
|
|
||||||
onClick={() => router.push('/data/list')}
|
|
||||||
>
|
|
||||||
数据拆分
|
|
||||||
</Box>
|
|
||||||
功能,从任意文本中提取数据集。
|
|
||||||
</Box>
|
|
||||||
<Box as={'li'} lineHeight={1.9}>
|
|
||||||
每行包括一个 prompt 和一个 completion
|
|
||||||
</Box>
|
|
||||||
<Box as={'li'} lineHeight={1.9}>
|
|
||||||
prompt 必须以 {'</s>'} 结尾
|
|
||||||
</Box>
|
|
||||||
<Box as={'li'} lineHeight={1.9}>
|
|
||||||
completion 开头必须有一个空格,必须以 {'</s>'} 结尾
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<Flex mt={5} alignItems={'center'}>
|
|
||||||
<Box flex={'0 0 80px'}>删除模型:</Box>
|
|
||||||
<Button colorScheme={'red'} size={'sm'} onClick={openConfirm(handleDelModel)}>
|
|
||||||
删除模型
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
@ -330,7 +264,6 @@ const ModelDetail = ({ modelId }: { modelId: string }) => {
|
|||||||
<Box position={'absolute'} w={0} h={0} overflow={'hidden'}>
|
<Box position={'absolute'} w={0} h={0} overflow={'hidden'}>
|
||||||
<input ref={SelectFileDom} type="file" accept=".jsonl" onChange={startTraining} />
|
<input ref={SelectFileDom} type="file" accept=".jsonl" onChange={startTraining} />
|
||||||
</Box>
|
</Box>
|
||||||
<ConfirmChild />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { generateQA } from './events/generateQA';
|
import { generateQA } from './events/generateQA';
|
||||||
import { generateAbstract } from './events/generateAbstract';
|
import { generateAbstract } from './events/generateAbstract';
|
||||||
|
import { connectRedis } from './redis';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接 MongoDB 数据库
|
* 连接 MongoDB 数据库
|
||||||
@ -28,6 +29,7 @@ export async function connectToDatabase(): Promise<void> {
|
|||||||
|
|
||||||
generateQA();
|
generateQA();
|
||||||
generateAbstract();
|
generateAbstract();
|
||||||
|
// connectRedis();
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './models/authCode';
|
export * from './models/authCode';
|
||||||
|
|||||||
74
src/service/redis.ts
Normal file
74
src/service/redis.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { createClient, SchemaFieldTypes } from 'redis';
|
||||||
|
|
||||||
|
export const connectRedis = async () => {
|
||||||
|
// 断开了,重连
|
||||||
|
if (global.redisClient && !global.redisClient.isOpen) {
|
||||||
|
await global.redisClient.disconnect();
|
||||||
|
} else if (global.redisClient) {
|
||||||
|
// 没断开,不再连接
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
global.redisClient = createClient({
|
||||||
|
url: 'redis://:121914yu@120.76.193.200:8100'
|
||||||
|
});
|
||||||
|
|
||||||
|
global.redisClient.on('error', (err) => {
|
||||||
|
console.log('Redis Client Error', err);
|
||||||
|
global.redisClient = null;
|
||||||
|
});
|
||||||
|
global.redisClient.on('end', () => {
|
||||||
|
global.redisClient = null;
|
||||||
|
});
|
||||||
|
global.redisClient.on('ready', () => {
|
||||||
|
console.log('redis connected');
|
||||||
|
});
|
||||||
|
|
||||||
|
await global.redisClient.connect();
|
||||||
|
|
||||||
|
// 0 - 测试库,1 - 正式
|
||||||
|
await global.redisClient.select(0);
|
||||||
|
|
||||||
|
// 创建索引
|
||||||
|
await global.redisClient.ft.create(
|
||||||
|
'vec:question',
|
||||||
|
{
|
||||||
|
'$.vector': SchemaFieldTypes.VECTOR,
|
||||||
|
'$.modelId': {
|
||||||
|
type: SchemaFieldTypes.TEXT,
|
||||||
|
AS: 'modelId'
|
||||||
|
},
|
||||||
|
'$.userId': {
|
||||||
|
type: SchemaFieldTypes.TEXT,
|
||||||
|
AS: 'userId'
|
||||||
|
},
|
||||||
|
'$.status': {
|
||||||
|
type: SchemaFieldTypes.NUMERIC,
|
||||||
|
AS: 'status'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ON: 'JSON',
|
||||||
|
PREFIX: 'fastgpt:modeldata'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// await global.redisClient.json.set('fastgpt:modeldata:1', '$', {
|
||||||
|
// vector: [],
|
||||||
|
// modelId: 'daf',
|
||||||
|
// userId: 'adfd',
|
||||||
|
// q: 'fasf',
|
||||||
|
// a: 'afasf',
|
||||||
|
// status: 0,
|
||||||
|
// createTime: new Date()
|
||||||
|
// });
|
||||||
|
// const value = await global.redisClient.get('fastgpt:modeldata:1');
|
||||||
|
|
||||||
|
// console.log(value);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error, '==');
|
||||||
|
global.redisClient = null;
|
||||||
|
return Promise.reject('redis 连接失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
@ -1,7 +1,9 @@
|
|||||||
import type { Mongoose } from 'mongoose';
|
import type { Mongoose } from 'mongoose';
|
||||||
|
import type { RedisClientType } from 'redis';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var mongodb: Mongoose | string | null;
|
var mongodb: Mongoose | string | null;
|
||||||
|
var redisClient: RedisClientType | null;
|
||||||
var generatingQA: boolean;
|
var generatingQA: boolean;
|
||||||
var generatingAbstract: boolean;
|
var generatingAbstract: boolean;
|
||||||
var QRCode: any;
|
var QRCode: any;
|
||||||
|
|||||||
3
src/types/mongoSchema.d.ts
vendored
3
src/types/mongoSchema.d.ts
vendored
@ -51,11 +51,12 @@ export interface ModelPopulate extends ModelSchema {
|
|||||||
userId: UserModelSchema;
|
userId: UserModelSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ModelDataType = 0 | 1 | 2;
|
||||||
export interface ModelDataSchema {
|
export interface ModelDataSchema {
|
||||||
_id: string;
|
_id: string;
|
||||||
q: string;
|
q: string;
|
||||||
a: string;
|
a: string;
|
||||||
status: 0 | 1 | 2;
|
status: ModelDataType;
|
||||||
createTime: Date;
|
createTime: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user