feat: 数据集管理

This commit is contained in:
archer
2023-03-25 22:13:15 +08:00
parent 0cee404c7f
commit 02cee35a45
20 changed files with 285 additions and 86 deletions

View File

@@ -1,21 +1,15 @@
{"prompt":"什么是死锁?如何避免死锁?\n\n###\n\n","completion":" 死锁是指两个或多个进程在执行过程中,由于互相等待对方释放资源而造成的一种僵局。避免死锁的常用方法包括:破坏互斥条件、破坏请求和保持条件、破坏不剥夺条件、破坏循环等待条件。###"}
{"prompt":"什么是虚拟内存?\n\n###\n\n","completion":" 虚拟内存是指一种计算机内存管理技术,它使得操作系统可以将进程所使用的虚拟地址空间映射到物理内存中,从而可以让多个进程共享物理内存。当物理内存不足时,操作系统会将一部分不常用的内存页面暂时存储到硬盘上,这样就可以释放出更多的物理内存供其他进程使用。###"}
{"prompt":"什么是分页和分段?有什么区别?\n\n###\n\n","completion":" 分页和分段是虚拟内存管理中常用的两种技术。分页是将虚拟地址空间划分为固定大小的页面,而分段则是将虚拟地址空间划分为不同大小的段。区别在于,分页的页面大小是固定的,而分段的段大小是可变的;另外,分页是为了实现虚拟内存,而分段则是为了实现逻辑地址空间的管理。###"}
{"prompt":"什么是lru算法\n\n###\n\n","completion":" lru算法是一种页面置换算法它的全称是least recently used即最近最少使用算法。lru算法的基本思想是在物理内存中维护一个页面访问历史记录当需要替换一页时选择最近最少被访问的页面进行替换。###"}
{"prompt":"什么是文件系统?\n\n###\n\n","completion":" 文件系统是一种用于管理计算机存储设备上文件和目录的组织方式。文件系统通常包括存储管理、目录管理、文件访问控制、文件系统维护等功能。常见的文件系统包括fat、ntfs、ext等。###"}
{"prompt":"什么是并发和并行?\n\n###\n\n","completion":" 并发是指多个任务交替执行的情况,而并行是指多个任务同时执行的情况。并发的实现方式是通过时间分片技术,而并行的实现方式是通过多核处理器等硬件设备。###"}
{"prompt":"什么是系统调用?\n\n###\n\n","completion":" 系统调用是操作系统中的一种机制,它允许用户空间程序请求操作系统内核提供一些服务,如读写文件、创建进程等。系统调用通常是通过软中断实现的###"}
{"prompt":"什么是进程间通信?\n\n###\n\n","completion":" 进程间通信是指不同进程之间进行数据交换和通信的机制,常见的方式有管道、共享内存、消息队列、信号量等。###"}
{"prompt":"什么是文件描述符?\n\n###\n\n","completion":" 文件描述符是一个非负整数它是操作系统内核为了管理打开的文件而维护的一种抽象概念。应用程序使用文件描述符来访问文件或其他i\/o设备###"}
{"prompt":"什么是中断? \n\n###\n\n","completion":" 中断是指计算机硬件或软件在执行程序时,暂停当前程序的执行,转而去执行另一个程序或处理器所需的其他任务的过程。中断可以是外部中断、内部中断或软中断。###"}
{"prompt":"什么是页表?\n\n###\n\n","completion":" 页表是一种数据结构,它用于将虚拟地址转换为物理地址。在虚拟内存中,每个进程都有自己的页表,它描述了虚拟地址空间中每个页面对应的物理地址。 ###"}
{"prompt":"什么是僵尸进程?\n\n###\n\n","completion":" 僵尸进程是指一个已经完成执行但其父进程还没有对其进行善后处理的进程,它会一直占用系统资源,直到其父进程将其处理为止。###"}
{"prompt":"什么是守护进程? \n\n###\n\n","completion":" 守护进程是一种在后台运行的特殊进程,它通常用于提供某种服务或执行某种系统任务。守护进程通常不与任何用户界面交互,也不会终止,直到操作系统关机或重启。###"}
{"prompt":"计算机操作系统是什么?\n\n###\n\n","completion":" 计算机操作系统是一种控制计算机硬件和协调应用程序运行的系统软件。###"}
{"prompt":"什么是进程?\n\n###\n\n","completion":" 进程是一个正在执行中的程序实例,它包括了程序计数器、堆栈、数据区等信息。###"}
{"prompt":"什么是线程?\n\n###\n\n","completion":" 线程是操作系统能够进行运算调度的最小单位,它是进程的一个执行流程,共享进程的地址空间。###"}
{"prompt":"什么是虚拟内存?\n\n###\n\n","completion":" 虚拟内存是一种计算机系统内存管理技术,它使得应用程序认为它拥有连续的可用的内存,而实际上它通常是被分成多个物理内存碎片。###"}
{"prompt":"什么是死锁?\n\n###\n\n","completion":" 死锁是指两个或多个进程在执行过程中,因争夺资源而造成的一种互相等待的现象,导致所有进程都无法继续执行。###"}
{"prompt":"什么是缓存?\n\n###\n\n","completion":" 缓存是指在计算机中暂存数据的高速存储器,它可以提高计算机对数据的访问速度,避免频繁地访问较慢的主存储器。###"}
{"prompt":"什么是文件系统?\n\n###\n\n","completion":" 文件系统是计算机中用来管理和组织文件的一种机制,它通过一系列的数据结构来描述文件和目录的组织方式,以及文件如何存储和访问。###"}
{"prompt":"什么是调度算法?\n\n###\n\n","completion":" 调度算法是指操作系统中用来决定进程或线程在cpu上执行顺序的一种算法它的目标是最大化系统吞吐量、最小化响应时间或最大化资源利用率等。###"}
{"prompt":"什么是百度plato</s>","completion":" 百度PLATO是一种聊天机器人发布于2021年10月参数量为百亿是GPT-3的1/17。</s>"}
{"prompt":"与百度plato相比chatgpt有哪些优点</s>","completion":" 与百度PLATO相比ChatGPT体现出耐心、体贴和妥当被网友们普遍称赞。ChatGPT可以用于个性化聊天机器人例如生成一个很相似的数字人提供一位温柔健谈的朋友指导语言学习等。</s>"}
{"prompt":"replika是什么</s>","completion":" Replika是一个产品使用ChatGPT的技术可以根据自己的需求生成一个虚拟女友、男友或单纯的朋友。目前还引起了不少有关性骚扰、家暴、隐私等问题的争议。</s>"}
{"prompt":"聊天机器人可以用于哪些场景?</s>","completion":" 聊天机器人可以用于很多陪伴的场景,例如亲人去世、抑郁症或自闭症患者、语言学习、小朋友、养老院或独居在家的老人等。</s>"}
{"prompt":"有人反对使用聊天机器人解决孤独困境,为什么?</s>","completion":" 有人反对使用聊天机器人解决孤独困境,认为孤独困境应该用人与人真正的交往解决,机器是冰冷的。</s>"}
{"prompt":"什么聊天机器人仍然需要解决当下的需求?</s>","completion":" 在社会结构性的困局还没有解开时,长夜漫漫的独身打工人、养老院里卧床的老人、父母在外留守在家的儿童,当下的需求仍需要解决。</s>"}
{"prompt":"ai在未来会被戴上什么样的帽子</s>","completion":" AI在未来各个场景下都会被戴上一个很虚无的帽子“机器是冰冷的”、“没有灵魂”、“它并不是真正在思考”。</s>"}
{"prompt":"怎么回答“ai是否真正思考”的问题</s>","completion":" 引用乔姆斯基老爷子的那句名言“思考是人类特性。AI有天会思考吗那就像是在问潜水艇会不会游泳一样。”</s>"}
{"prompt":"聊天机器人与人类完成任务的方式有何不同?</s>","completion":" 聊天机器人与人类完成任务的方式不同,但并不重要。它们能跟人一样完成任务,这是最重要的。</s>"}
{"prompt":"聊天机器人的发展前景如何?</s>","completion":" 聊天机器人的发展前景广阔,可以应用于很多领域,例如客服、教育、医疗等。</s>"}
{"prompt":"什么是百度plato</s>","completion":" 百度PLATO是一种聊天机器人发布于2021年10月参数量为百亿是GPT-3的1/17。</s>"}
{"prompt":"与百度plato相比chatgpt有哪些优点</s>","completion":" 与百度PLATO相比ChatGPT体现出耐心、体贴和妥当被网友们普遍称赞。ChatGPT还可以用于很多陪伴的场景如亲人去世、抑郁症或自闭症患者、语言学习、小朋友、养老院或独居在家的老人等。</s>"}
{"prompt":"replika是什么产品</s>","completion":" Replika是一个产品用的是ChatGPT的技术。用户可以根据自己的需求生成一个虚拟女友、男友或单纯的朋友。目前还引起了不少有关性骚扰、家暴、隐私等问题的争议。</s>"}
{"prompt":"聊天机器人能够解决哪些现实问题?</s>","completion":" 聊天机器人能够解决现代人面临的孤独困境,如长夜漫漫的独身打工人、养老院里卧床的老人、父母在外留守在家的儿童等。</s>"}
{"prompt":"有人反对使用聊天机器人解决孤独困境,为什么?</s>","completion":" 有人反对使用聊天机器人解决孤独困境,认为孤独困境应该用人与人真正的交往解决,机器是冰冷的。</s>"}

View File

@@ -3,6 +3,7 @@ import { RequestPaging } from '../types/index';
import { Obj2Query } from '@/utils/tools';
import type { DataListItem } from '@/types/data';
import type { PagingData } from '../types/index';
import { DataItemSchema } from '@/types/mongoSchema';
export const getDataList = (data: RequestPaging) =>
GET<PagingData<DataListItem>>(`/data/getDataList?${Obj2Query(data)}`);
@@ -16,3 +17,9 @@ export const updateDataName = (dataId: string, name: string) =>
PUT(`/data/putDataName?dataId=${dataId}&name=${name}`);
export const delData = (dataId: string) => DELETE(`/data/delData?dataId=${dataId}`);
type GetDataItemsProps = RequestPaging & {
dataId: string;
};
export const getDataItems = (data: GetDataItemsProps) =>
GET<PagingData<DataItemSchema>>(`/data/getDataItems?${Obj2Query(data)}`);

View File

@@ -30,7 +30,7 @@ const navbarList = [
label: '数据',
icon: 'icon-datafull',
link: '/data/list',
activeLink: ['/data/list']
activeLink: ['/data/list', '/data/detail']
},
{
label: '账号',

View File

@@ -0,0 +1,50 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { connectToDatabase, DataItem } from '@/service/mongo';
import { authToken } from '@/service/utils/tools';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
let {
dataId,
pageNum = 1,
pageSize = 10
} = req.query as { dataId: string; pageNum: string; pageSize: string };
pageNum = +pageNum;
pageSize = +pageSize;
if (!dataId) {
throw new Error('参数错误');
}
await connectToDatabase();
const { authorization } = req.headers;
await authToken(authorization);
const dataItems = await DataItem.find({
dataId,
status: 0
})
.sort({ time: -1 }) // 按照创建时间倒序排列
.skip((pageNum - 1) * pageSize)
.limit(pageSize);
jsonRes(res, {
data: {
pageNum,
pageSize,
data: dataItems,
total: await DataItem.countDocuments({
dataId,
status: 0
})
}
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
}

View File

@@ -24,7 +24,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await connectToDatabase();
// 根据 id 获取用户账单
const datalist = await Data.aggregate<DataListItem>([
{
$match: {

View File

@@ -22,18 +22,20 @@ import { useMutation } from '@tanstack/react-query';
import { useToast } from '@/hooks/useToast';
import { useLoading } from '@/hooks/useLoading';
const fileExtension = '.txt,.doc,.docx,.pdf,.md';
const ImportDataModal = ({ dataId, onClose }: { dataId: string; onClose: () => void }) => {
const { openConfirm, ConfirmChild } = useConfirm({
content: '确认提交生成任务?该任务无法终止!'
});
const { toast } = useToast();
const { setIsLoading, Loading } = useLoading();
const { File, onOpen } = useSelectFile({ fileType: '.txt,.doc,.docx,.pdf', multiple: true });
const { File, onOpen } = useSelectFile({ fileType: fileExtension, multiple: true });
const { tabs, activeTab, setActiveTab } = useTabs({
tabs: [
{ id: 'text', label: '文本' },
{ id: 'doc', label: '文件' },
{ id: 'url', label: '链接' }
{ id: 'doc', label: '文件' }
// { id: 'url', label: '链接' }
]
});
@@ -76,14 +78,18 @@ const ImportDataModal = ({ dataId, onClose }: { dataId: string; onClose: () => v
e.map((file) => {
// @ts-ignore
const extension = file?.name?.split('.').pop().toLowerCase();
if (extension === 'txt') {
return readTxtContent(file);
} else if (extension === 'pdf') {
return readPdfContent(file);
} else if (extension === 'docx' || extension === 'doc') {
return readDocContent(file);
switch (extension) {
case 'txt':
case 'md':
return readTxtContent(file);
case 'pdf':
return readPdfContent(file);
case 'doc':
case 'docx':
return readDocContent(file);
default:
return '';
}
return '';
})
)
).join('\n');
@@ -137,6 +143,7 @@ const ImportDataModal = ({ dataId, onClose }: { dataId: string; onClose: () => v
{activeTab === 'doc' && (
<Flex
flexDirection={'column'}
p={2}
h={'100%'}
alignItems={'center'}
justifyContent={'center'}
@@ -145,7 +152,23 @@ const ImportDataModal = ({ dataId, onClose }: { dataId: string; onClose: () => v
borderRadius={'md'}
>
<Button onClick={onOpen}></Button>
{fileText && <Box mt={2}> {fileText.length} </Box>}
<Box mt={2}> {fileExtension} </Box>
{fileText && (
<>
<Box mt={2}> {fileText.length} </Box>
<Box
maxH={'300px'}
w={'100%'}
overflow={'auto'}
p={2}
backgroundColor={'blackAlpha.50'}
whiteSpace={'pre'}
fontSize={'xs'}
>
{fileText}
</Box>
</>
)}
</Flex>
)}
</Box>

View File

@@ -1,15 +0,0 @@
import React from 'react';
const DataDetail = ({ dataId }: { dataId: string }) => {
return <div>DataDetail</div>;
};
export default DataDetail;
export async function getServerSideProps(context: any) {
const dataId = context.query?.dataId || '';
return {
props: { dataId }
};
}

61
src/pages/data/detail.tsx Normal file
View File

@@ -0,0 +1,61 @@
import React from 'react';
import { Box, Card, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react';
import ScrollData from '@/components/ScrollData';
import { getDataItems } from '@/api/data';
import { usePaging } from '@/hooks/usePaging';
import type { DataItemSchema } from '@/types/mongoSchema';
const DataDetail = ({ dataName, dataId }: { dataName: string; dataId: string }) => {
const {
nextPage,
isLoadAll,
requesting,
data: dataItems
} = usePaging<DataItemSchema>({
api: getDataItems,
pageSize: 10,
params: {
dataId
}
});
return (
<Card py={4} h={'100%'} display={'flex'} flexDirection={'column'}>
<Box px={6} fontSize={'xl'} fontWeight={'bold'}>
{dataName}
</Box>
<ScrollData
flex={'1 0 0'}
h={0}
px={6}
mt={3}
isLoadAll={isLoadAll}
requesting={requesting}
nextPage={nextPage}
fontSize={'xs'}
>
{dataItems.map((item) => (
<Box key={item._id}>
{item.result.map((result, i) => (
<Box key={i} mb={3}>
<Box fontWeight={'bold'}>Q: {result.q}</Box>
<Box>A: {result.a}</Box>
</Box>
))}
</Box>
))}
</ScrollData>
</Card>
);
};
export default DataDetail;
export async function getServerSideProps(context: any) {
return {
props: {
dataName: context.query?.dataName || '',
dataId: context.query?.dataId || ''
}
};
}

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useCallback } from 'react';
import {
Card,
Box,
@@ -12,21 +12,30 @@ import {
Td,
TableContainer,
useDisclosure,
Input
Input,
Menu,
MenuButton,
MenuList,
MenuItem
} from '@chakra-ui/react';
import { getDataList, updateDataName, delData } from '@/api/data';
import { getDataList, updateDataName, delData, getDataItems } from '@/api/data';
import { usePaging } from '@/hooks/usePaging';
import type { DataListItem } from '@/types/data';
import ScrollData from '@/components/ScrollData';
import dayjs from 'dayjs';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import { useConfirm } from '@/hooks/useConfirm';
import { useRequest } from '@/hooks/useRequest';
import { DataItemSchema } from '@/types/mongoSchema';
const CreateDataModal = dynamic(() => import('./components/CreateDataModal'));
const ImportDataModal = dynamic(() => import('./components/ImportDataModal'));
export type ExportDataType = 'jsonl';
const DataList = () => {
const router = useRouter();
const {
nextPage,
isLoadAll,
@@ -58,13 +67,51 @@ const DataList = () => {
}
});
const { mutate: handleExportData, isLoading: isExporting } = useRequest({
mutationFn: async ({ data, type }: { data: DataListItem; type: ExportDataType }) => ({
type,
data: await getDataItems({ dataId: data._id, pageNum: 1, pageSize: data.totalData }).then(
(res) => res.data
)
}),
successToast: '导出数据集成功',
errorToast: '导出数据集异常',
onSuccess(res: { type: ExportDataType; data: DataItemSchema[] }) {
// 合并数据
const data = res.data.map((item) => item.result).flat();
let text = '';
// 生成 jsonl
data.forEach((item) => {
const result = JSON.stringify({
prompt: `${item.q.toLocaleLowerCase()}</s>`,
completion: ` ${item.a}</s>`
});
text += `${result}\n`;
});
// 去掉最后一个 \n
text = text.substring(0, text.length - 1);
// 导出为文件
const blob = new Blob([text], { type: 'application/json;charset=utf-8' });
// 创建下载链接
const downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.download = 'file.jsonl';
// 添加链接到页面并触发下载
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
});
return (
<Box display={['block', 'flex']} flexDirection={'column'} h={'100%'}>
<Card px={6} py={4}>
<Flex>
<Box flex={1} mr={1}>
<Box fontSize={'xl'} fontWeight={'bold'}>
</Box>
<Box fontSize={'xs'} color={'blackAlpha.600'}>
QA 使 QA
@@ -99,6 +146,7 @@ const DataList = () => {
<Tr key={item._id}>
<Td>
<Input
minW={'150px'}
placeholder="请输入数据集名称"
defaultValue={item.name}
size={'sm'}
@@ -118,7 +166,9 @@ const DataList = () => {
variant={'outline'}
colorScheme={'gray'}
mr={2}
onClick={() => setImportDataId(item._id)}
onClick={() =>
router.push(`/data/detail?dataId=${item._id}&dataName=${item.name}`)
}
>
</Button>
@@ -130,9 +180,17 @@ const DataList = () => {
>
</Button>
<Button mr={2} size={'sm'}>
</Button>
<Menu>
<MenuButton as={Button} mr={2} size={'sm'}>
</MenuButton>
<MenuList>
<MenuItem onClick={() => handleExportData({ data: item, type: 'jsonl' })}>
jsonl
</MenuItem>
</MenuList>
</Menu>
<Button
size={'sm'}
colorScheme={'red'}

View File

@@ -264,10 +264,10 @@ const ModelDetail = ({ modelId }: { modelId: string }) => {
onClick={() => {
SelectFileDom.current?.click();
}}
title={!canTrain ? '' : '模型不支持微调'}
title={!canTrain ? '模型不支持微调' : ''}
isDisabled={!canTrain}
>
</Button>
<Flex
as={'a'}
@@ -283,16 +283,30 @@ const ModelDetail = ({ modelId }: { modelId: string }) => {
</Flex>
</Flex>
{/* 提示 */}
<Box mt={3} py={3} color={'blackAlpha.500'}>
<Box mt={3} py={3} color={'blackAlpha.600'}>
<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 \n\n###\n\n prompt
prompt {'</s>'}
</Box>
<Box as={'li'} lineHeight={1.9}>
completion ###
completion {'</s>'}
</Box>
</Box>
<Flex mt={5} alignItems={'center'}>

View File

@@ -1,4 +1,5 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { AuthCodeSchema as AuthCodeType } from '@/types/mongoSchema';
const AuthCodeSchema = new Schema({
email: {
@@ -21,4 +22,5 @@ const AuthCodeSchema = new Schema({
}
});
export const AuthCode = models['auth_code'] || model('auth_code', AuthCodeSchema);
export const AuthCode: Model<AuthCodeType> =
models['auth_code'] || model('auth_code', AuthCodeSchema);

View File

@@ -1,5 +1,6 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { modelList } from '@/constants/model';
import { BillSchema as BillType } from '@/types/mongoSchema';
const BillSchema = new Schema({
userId: {
@@ -42,4 +43,4 @@ const BillSchema = new Schema({
}
});
export const Bill = models['bill'] || model('bill', BillSchema);
export const Bill: Model<BillType> = models['bill'] || model('bill', BillSchema);

View File

@@ -1,4 +1,5 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { ChatSchema as ChatType } from '@/types/mongoSchema';
const ChatSchema = new Schema({
userId: {
@@ -47,4 +48,4 @@ const ChatSchema = new Schema({
}
});
export const Chat = models['chat'] || model('chat', ChatSchema);
export const Chat: Model<ChatType> = models['chat'] || model('chat', ChatSchema);

View File

@@ -1,4 +1,5 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { DataItemSchema as Datatype } from '@/types/mongoSchema';
const DataSchema = new Schema({
userId: {
@@ -20,4 +21,4 @@ const DataSchema = new Schema({
}
});
export const Data = models['data'] || model('data', DataSchema);
export const Data: Model<Datatype> = models['data'] || model('data', DataSchema);

View File

@@ -1,4 +1,5 @@
import { Schema, model, models } from 'mongoose';
import type { DataItemSchema as DataItemType } from '@/types/mongoSchema';
import { Schema, model, models, Model } from 'mongoose';
const DataItemSchema = new Schema({
userId: {
@@ -45,4 +46,5 @@ const DataItemSchema = new Schema({
}
});
export const DataItem = models['dataItem'] || model('dataItem', DataItemSchema);
export const DataItem: Model<DataItemType> =
models['dataItem'] || model('dataItem', DataItemSchema);

View File

@@ -1,5 +1,5 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model as MongoModel } from 'mongoose';
import { ModelSchema as ModelType } from '@/types/mongoSchema';
const ModelSchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
@@ -95,4 +95,4 @@ const ModelSchema = new Schema({
}
});
export const Model = models['model'] || model('model', ModelSchema);
export const Model: MongoModel<ModelType> = models['model'] || model('model', ModelSchema);

View File

@@ -1,5 +1,5 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { PaySchema as PayType } from '@/types/mongoSchema';
const PaySchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
@@ -26,4 +26,4 @@ const PaySchema = new Schema({
}
});
export const Pay = models['pay'] || model('pay', PaySchema);
export const Pay: Model<PayType> = models['pay'] || model('pay', PaySchema);

View File

@@ -1,5 +1,5 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { TrainingSchema as TrainingType } from '@/types/mongoSchema';
const TrainingSChema = new Schema({
serviceName: {
// 模型厂商名
@@ -25,4 +25,5 @@ const TrainingSChema = new Schema({
}
});
export const Training = models['training'] || model('training', TrainingSChema);
export const Training: Model<TrainingType> =
models['training'] || model('training', TrainingSChema);

View File

@@ -1,7 +1,7 @@
import { Schema, model, models } from 'mongoose';
import { Schema, model, models, Model } from 'mongoose';
import { hashPassword } from '@/service/utils/tools';
import { PRICE_SCALE } from '@/constants/common';
import { UserModelSchema } from '@/types/mongoSchema';
const UserSchema = new Schema({
email: {
type: String,
@@ -38,4 +38,4 @@ const UserSchema = new Schema({
}
});
export const User = models['user'] || model('user', UserSchema);
export const User: Model<UserModelSchema> = models['user'] || model('user', UserSchema);

View File

@@ -16,4 +16,4 @@ export type PagingData<T> = {
total;
};
export type RequestPaging = { pageNum: number; pageSize: number };
export type RequestPaging = { pageNum: number; pageSize: number; [key]: any };