diff --git a/.env.template b/.env.template index 0d1b43381..dad399c7c 100644 --- a/.env.template +++ b/.env.template @@ -5,4 +5,5 @@ MY_MAIL= MAILE_CODE= TOKEN_KEY= OPENAIKEY= -REDIS_URL= \ No newline at end of file +REDIS_URL= +OPENAPI_KEY= \ No newline at end of file diff --git a/public/TrainingTemplate.jsonl b/public/TrainingTemplate.jsonl deleted file mode 100644 index 3172d6c49..000000000 --- a/public/TrainingTemplate.jsonl +++ /dev/null @@ -1,15 +0,0 @@ -{"prompt":"什么是百度plato?","completion":" 百度PLATO是一种聊天机器人,发布于2021年10月,参数量为百亿,是GPT-3的1/17。"} -{"prompt":"与百度plato相比,chatgpt有哪些优点?","completion":" 与百度PLATO相比,ChatGPT体现出耐心、体贴和妥当,被网友们普遍称赞。ChatGPT可以用于个性化聊天机器人,例如生成一个很相似的数字人,提供一位温柔健谈的朋友,指导语言学习等。"} -{"prompt":"replika是什么?","completion":" Replika是一个产品,使用ChatGPT的技术,可以根据自己的需求生成一个虚拟女友、男友或单纯的朋友。目前还引起了不少有关性骚扰、家暴、隐私等问题的争议。"} -{"prompt":"聊天机器人可以用于哪些场景?","completion":" 聊天机器人可以用于很多陪伴的场景,例如亲人去世、抑郁症或自闭症患者、语言学习、小朋友、养老院或独居在家的老人等。"} -{"prompt":"有人反对使用聊天机器人解决孤独困境,为什么?","completion":" 有人反对使用聊天机器人解决孤独困境,认为孤独困境应该用人与人真正的交往解决,机器是冰冷的。"} -{"prompt":"为什么聊天机器人仍然需要解决当下的需求?","completion":" 在社会结构性的困局还没有解开时,长夜漫漫的独身打工人、养老院里卧床的老人、父母在外留守在家的儿童,当下的需求仍需要解决。"} -{"prompt":"ai在未来会被戴上什么样的帽子?","completion":" AI在未来各个场景下都会被戴上一个很虚无的帽子:“机器是冰冷的”、“没有灵魂”、“它并不是真正在思考”。"} -{"prompt":"怎么回答“ai是否真正思考”的问题?","completion":" 引用乔姆斯基老爷子的那句名言:“思考是人类特性。AI有天会思考吗?那就像是在问潜水艇会不会游泳一样。”"} -{"prompt":"聊天机器人与人类完成任务的方式有何不同?","completion":" 聊天机器人与人类完成任务的方式不同,但并不重要。它们能跟人一样完成任务,这是最重要的。"} -{"prompt":"聊天机器人的发展前景如何?","completion":" 聊天机器人的发展前景广阔,可以应用于很多领域,例如客服、教育、医疗等。"} -{"prompt":"什么是百度plato?","completion":" 百度PLATO是一种聊天机器人,发布于2021年10月,参数量为百亿,是GPT-3的1/17。"} -{"prompt":"与百度plato相比,chatgpt有哪些优点?","completion":" 与百度PLATO相比,ChatGPT体现出耐心、体贴和妥当,被网友们普遍称赞。ChatGPT还可以用于很多陪伴的场景,如亲人去世、抑郁症或自闭症患者、语言学习、小朋友、养老院或独居在家的老人等。"} -{"prompt":"replika是什么产品?","completion":" Replika是一个产品,用的是ChatGPT的技术。用户可以根据自己的需求生成一个虚拟女友、男友或单纯的朋友。目前还引起了不少有关性骚扰、家暴、隐私等问题的争议。"} -{"prompt":"聊天机器人能够解决哪些现实问题?","completion":" 聊天机器人能够解决现代人面临的孤独困境,如长夜漫漫的独身打工人、养老院里卧床的老人、父母在外留守在家的儿童等。"} -{"prompt":"有人反对使用聊天机器人解决孤独困境,为什么?","completion":" 有人反对使用聊天机器人解决孤独困境,认为孤独困境应该用人与人真正的交往解决,机器是冰冷的。"} diff --git a/public/js/iconfont.js b/public/js/iconfont.js deleted file mode 100644 index 4052f5de7..000000000 --- a/public/js/iconfont.js +++ /dev/null @@ -1 +0,0 @@ -window._iconfont_svg_string_3913924='',function(e){var t=(t=document.getElementsByTagName("script"))[t.length-1],c=t.getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var a,o,n,i,s,l=function(t,c){c.parentNode.insertBefore(t,c)};if(c&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}a=function(){var t,c=document.createElement("div");c.innerHTML=e._iconfont_svg_string_3913924,(c=c.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",c=c,(t=document.body).firstChild?l(c,t.firstChild):t.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),a()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(n=a,i=e.document,s=!1,d(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,h())})}function h(){s||(s=!0,n())}function d(){try{i.documentElement.doScroll("left")}catch(t){return void setTimeout(d,50)}h()}}(window); \ No newline at end of file diff --git a/public/trainData/4d89aa7a10c65cf0e3cec4300.jsonl b/public/trainData/4d89aa7a10c65cf0e3cec4300.jsonl deleted file mode 100644 index 7d7291975..000000000 --- a/public/trainData/4d89aa7a10c65cf0e3cec4300.jsonl +++ /dev/null @@ -1,21 +0,0 @@ -{"prompt": "什么是高潜公司\n\n###\n\n", "completion": " 高潜公司是指高潜力的公司,其所处的赛道有发展潜力和前景。###"} -{"prompt": "高潜公司的优势是什么\n\n###\n\n", "completion": " 高潜公司所处的整个行业和赛道有一定的增量空间,头部vc通过严格的筛选和加持为高潜公司背书,高潜公司的创始者一般都特别优秀。加入高潜公司可以获得很多机会来锻炼自己、强化自己的认知,快速成长、展现自己,并有可能成为公司扩张后的管理层###"} -{"prompt": "高潜公司的风险是什么\n\n###\n\n", "completion": " 高潜公司的高风险问题也很明显。一旦公司失败,很多边缘人就会被淘汰掉。但宏观来讲,只要赛道是有潜力的,即便这家公司失败了,也可以跳槽到成功的公司去。###"} -{"prompt": "高潜公司的例子有哪些\n\n###\n\n", "completion": " 很多高潜公司在做最近比较火的AIGC,包括去年的元宇宙,前两年比较火的新消费、企业服务和出海之类的。###"} -{"prompt": "为什么现在加入大厂的前景不广阔?\n\n###\n\n", "completion": " 今年的大形势之下,互联网大厂纷纷开始裁员、取消普调、晋升比例严重缩水,HC也急剧减少。###"} -{"prompt": "加入高潜公司可以获得什么样的机会?\n\n###\n\n", "completion": " 加入高潜公司可以获得很多机会来锻炼自己、强化自己的认知,快速成长、展现自己,并有可能成为公司扩张后的管理层。###"} -{"prompt": "什么是高潜公司?\n\n###\n\n", "completion": " 高潜公司的定义是“高潜力的公司”,所处的行业和赛道有发展潜力和前景,头部vc为其背书,创始者一般都特别优秀。###"} -{"prompt": "加入高潜公司有哪些优点\n\n###\n\n", "completion": " 加入高潜公司能够获得锻炼自己、强化认知的机会,快速成长、展现自己,在公司扩张后成为团队的管理层。同时,所处的行业还处于上升期,发展前景广阔。###"} -{"prompt": "高潜公司存在哪些风险?\n\n###\n\n", "completion": " 高潜公司存在高风险问题,一旦公司失败,很多边缘人就会被淘汰掉。但宏观来讲,只要赛道是有潜力的,即便这家公司失败了,也可以跳槽到成功的公司去。###"} -{"prompt": "高潜公司和互联网有什么相似之处?\n\n###\n\n", "completion": " 目前来说,高潜公司的风格大部分都比较像互联网大厂,有风格,但又没有那么内卷,因为大家每天都在开拓边疆,突破和探索市场的边界。同时,互联网产业的蓬勃发展也给其他行业,包括新能源汽车、新消费等,带来了用户增长和运营的经验###"} -{"prompt": "互联网大厂的制度和分工如何?\n\n###\n\n", "completion": " 目前的互联网大厂的制度和分工非常明确,基本是按照一些标准SOP做事。同时,由于已经没有用户增量了,内卷和向上管理的问题也比较严重。###"} -{"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": " 资本繁荣,无论中国还是美国,创业生态的崛起都是伴随着移动互联网的发展。中国这一代VC的崛起,主要是通过投资移动互联网项目所积累的战绩扩大了资金池,通过这些成本低、增长快、回报率高的项目,才有了底气去推动更多行业发展,尝试着投资toB和硬科技这类成本高、增长慢、回报率低、风险大的项目。###"} -{"prompt": "环境繁荣是指什么?\n\n###\n\n", "completion": " 环境繁荣是指互联网带动起经济发展后,各地政府也开始了对于创业进行培育,免费场地、巨额无偿补贴、各地送钱竞赛,大幅度降低了创业成本。###"} -{"prompt": "高潜公司对于追求长期创造价值的毕业生来说为什么是好的选择?\n\n###\n\n", "completion": " 因为在高潜公司,毕业生可以通过参与创业公司的发展,获得更多的机会和成长空间,而不是被固定在某个职位上。此外,高潜公司通常会注重团队建设和文化建设,能够提供更好的工作环境和发展机会。###"} -{"prompt": "如果想要寻找高潜公司,有哪些渠道可以利用?\n\n###\n\n", "completion": " 可以利用领英职场app和知潜微信小程序。领英职场app中入驻了很多高潜公司及高管,而知潜小程序现在也已经有100+高潜力创业公司入驻,都是经过筛选的、top VC投资过且赛道有前景的公司。此外,红杉和真格等VC机构自己的公众号也会经常披露投资的企业。###"} -{"prompt": "为什么现在更多优秀的人才会加入创业公司?\n\n###\n\n", "completion": " 因为在当前社会的大趋势下,创业公司成为了创新生态的重要组成部分。创业公司在创造价值和推动行业发展方面具有更大的空间和潜力,而且随着移动互联网的发展,创业公司的崛起也得到了资本和政策的支持。因此,更多优秀的人才选择加入创业公司,以实现自己的创业梦想和获得更好的发展机会。###"} -{"prompt": "高潜公司的优势在哪些方面?\n\n###\n\n", "completion": " 高潜公司在团队建设、文化建设和发展机会等方面具有优势。高潜公司通常会注重团队建设和文化建设,能够提供更好的工作环境和发展机会。同时,高潜公司的发展潜力和创新能力也很强,可以为毕业生提供更多的机会和成长空间。###"} \ No newline at end of file diff --git a/public/trainData/d95c4a3c319667d5f24955602.jsonl b/public/trainData/d95c4a3c319667d5f24955602.jsonl deleted file mode 100644 index 82ca08ff9..000000000 --- a/public/trainData/d95c4a3c319667d5f24955602.jsonl +++ /dev/null @@ -1,21 +0,0 @@ -{"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上执行顺序的一种算法,它的目标是最大化系统吞吐量、最小化响应时间或最大化资源利用率等。###"} diff --git a/src/api/openapi.ts b/src/api/openapi.ts new file mode 100644 index 000000000..1ee4919db --- /dev/null +++ b/src/api/openapi.ts @@ -0,0 +1,16 @@ +import { GET, POST, DELETE } from './request'; +import { UserOpenApiKey } from '@/types/openapi'; +/** + * crete a api key + */ +export const createAApiKey = () => POST('/openapi/postKey'); + +/** + * get api keys + */ +export const getApiKeys = () => GET('/openapi/getKeys'); + +/** + * delete api by id + */ +export const delApiById = (id: string) => DELETE(`/openapi/delKet?id=${id}`); diff --git a/src/components/Icon/icons/board.svg b/src/components/Icon/icons/board.svg new file mode 100644 index 000000000..74845c417 --- /dev/null +++ b/src/components/Icon/icons/board.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icon/chatting.svg b/src/components/Icon/icons/chatting.svg similarity index 100% rename from public/icon/chatting.svg rename to src/components/Icon/icons/chatting.svg diff --git a/src/components/Icon/icons/develop.svg b/src/components/Icon/icons/develop.svg new file mode 100644 index 000000000..442958b0f --- /dev/null +++ b/src/components/Icon/icons/develop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/icons/user.svg b/src/components/Icon/icons/user.svg new file mode 100644 index 000000000..b0068fb0d --- /dev/null +++ b/src/components/Icon/icons/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index aa69b3446..1e38406e8 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,7 +1,6 @@ import React from 'react'; import type { IconProps } from '@chakra-ui/react'; import { Icon } from '@chakra-ui/react'; -import dynamic from 'next/dynamic'; const map = { model: require('./icons/model.svg').default, @@ -10,7 +9,11 @@ const map = { menu: require('./icons/menu.svg').default, pay: require('./icons/pay.svg').default, copy: require('./icons/copy.svg').default, - chatSend: require('./icons/chatSend.svg').default + chatSend: require('./icons/chatSend.svg').default, + board: require('./icons/board.svg').default, + develop: require('./icons/develop.svg').default, + user: require('./icons/user.svg').default, + chatting: require('./icons/chatting.svg').default }; export type IconName = keyof typeof map; diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 358ee25db..3f3afdf44 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -16,27 +16,27 @@ const unShowLayoutRoute: { [key: string]: boolean } = { const navbarList = [ { label: '介绍', - icon: 'icon-gongzuotai-01', + icon: 'board', link: '/', activeLink: ['/'] }, { label: '模型', - icon: 'icon-moxing', + icon: 'model', link: '/model/list', activeLink: ['/model/list', '/model/detail'] }, - // { - // label: '数据', - // icon: 'icon-datafull', - // link: '/data/list', - // activeLink: ['/data/list', '/data/detail'] - // }, { label: '账号', - icon: 'icon-yonghu-yuan', + icon: 'user', link: '/number/setting', activeLink: ['/number/setting'] + }, + { + label: '开发', + icon: 'develop', + link: '/openapi', + activeLink: ['/openapi'] } ]; diff --git a/src/components/Layout/navbar.tsx b/src/components/Layout/navbar.tsx index 1fe0e006e..b904d97d5 100644 --- a/src/components/Layout/navbar.tsx +++ b/src/components/Layout/navbar.tsx @@ -2,8 +2,7 @@ import React from 'react'; import { Box, Flex } from '@chakra-ui/react'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import Icon from '../Iconfont'; - +import MyIcon from '../Icon'; export enum NavbarTypeEnum { normal = 'normal', small = 'small' @@ -66,20 +65,16 @@ const Navbar = ({ backgroundColor: 'transparent' })} > - {item.label} ))} - {/* 通知 icon */} - {/* - - */} ); }; diff --git a/src/components/Layout/navbarPhone.tsx b/src/components/Layout/navbarPhone.tsx index e4fa2897b..0e8091874 100644 --- a/src/components/Layout/navbarPhone.tsx +++ b/src/components/Layout/navbarPhone.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useRouter } from 'next/router'; -import Icon from '../Iconfont'; +import MyIcon from '../Icon'; import { Flex, Drawer, @@ -39,9 +39,8 @@ const NavbarPhone = ({ px={7} > - + - {/* */} @@ -74,11 +73,11 @@ const NavbarPhone = ({ backgroundColor: 'transparent' })} > - {item.label} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 67fbfefd5..61416d7d0 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -51,7 +51,6 @@ export default function App({ Component, pageProps }: AppProps) { /> - diff --git a/src/pages/api/openapi/delKet.ts b/src/pages/api/openapi/delKet.ts new file mode 100644 index 000000000..c9bf91b3b --- /dev/null +++ b/src/pages/api/openapi/delKet.ts @@ -0,0 +1,33 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction +import type { NextApiRequest, NextApiResponse } from 'next'; +import { jsonRes } from '@/service/response'; +import { connectToDatabase, OpenApi } from '@/service/mongo'; +import { authToken } from '@/service/utils/tools'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + const { id } = req.query as { id: string }; + const { authorization } = req.headers; + + if (!authorization) { + throw new Error('缺少登录凭证'); + } + + if (!id) { + throw new Error('缺少参数'); + } + + const userId = await authToken(authorization); + + await connectToDatabase(); + + await OpenApi.findOneAndRemove({ _id: id, userId }); + + jsonRes(res); + } catch (err) { + jsonRes(res, { + code: 500, + error: err + }); + } +} diff --git a/src/pages/api/openapi/getKeys.ts b/src/pages/api/openapi/getKeys.ts new file mode 100644 index 000000000..3a293590c --- /dev/null +++ b/src/pages/api/openapi/getKeys.ts @@ -0,0 +1,40 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction +import type { NextApiRequest, NextApiResponse } from 'next'; +import { jsonRes } from '@/service/response'; +import { connectToDatabase, OpenApi } from '@/service/mongo'; +import { authToken } from '@/service/utils/tools'; +import { UserOpenApiKey } from '@/types/openapi'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + const { authorization } = req.headers; + + if (!authorization) { + throw new Error('缺少登录凭证'); + } + + const userId = await authToken(authorization); + + await connectToDatabase(); + + const findResponse = await OpenApi.find({ userId }); + + // jus save four data + const apiKeys = findResponse.map((item) => { + const key = item.apiKey; + return { + id: item._id, + apiKey: `${key.substring(0, 2)}******${key.substring(key.length - 2)}` + }; + }); + + jsonRes(res, { + data: apiKeys + }); + } catch (err) { + jsonRes(res, { + code: 500, + error: err + }); + } +} diff --git a/src/pages/api/openapi/postKey.ts b/src/pages/api/openapi/postKey.ts new file mode 100644 index 000000000..4a199c508 --- /dev/null +++ b/src/pages/api/openapi/postKey.ts @@ -0,0 +1,43 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction +import type { NextApiRequest, NextApiResponse } from 'next'; +import { jsonRes } from '@/service/response'; +import { connectToDatabase, OpenApi } from '@/service/mongo'; +import { authToken } from '@/service/utils/tools'; +import { customAlphabet } from 'nanoid'; +const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890-', 20); + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + const { authorization } = req.headers; + + if (!authorization) { + throw new Error('缺少登录凭证'); + } + + const userId = await authToken(authorization); + + await connectToDatabase(); + + const count = await OpenApi.find({ userId }).countDocuments(); + + if (count >= 5) { + throw new Error('最多 5 组API Key'); + } + + const apiKey = `${userId}-${nanoid()}`; + + await OpenApi.create({ + userId, + apiKey + }); + + jsonRes(res, { + data: apiKey + }); + } catch (err) { + jsonRes(res, { + code: 500, + error: err + }); + } +} diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index 9cd93752e..4d2a29e90 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -519,11 +519,11 @@ const Chat = ({ chatId }: { chatId: string }) => { onClick={sendPrompt} > {isChatting ? ( - {''} ) : ( { + return ( + + ss + + ); +}; + +export default OpenApi; diff --git a/src/service/models/openapi.ts b/src/service/models/openapi.ts index a76a01424..1e2718f95 100644 --- a/src/service/models/openapi.ts +++ b/src/service/models/openapi.ts @@ -7,6 +7,10 @@ const OpenApiSchema = new Schema({ ref: 'user', required: true }, + apiKey: { + type: String, + required: true + }, createTime: { type: Date, default: () => new Date() diff --git a/src/service/mongo.ts b/src/service/mongo.ts index bf08865bb..0d6963603 100644 --- a/src/service/mongo.ts +++ b/src/service/mongo.ts @@ -42,3 +42,4 @@ export * from './models/pay'; export * from './models/data'; export * from './models/dataItem'; export * from './models/splitData'; +export * from './models/openapi'; diff --git a/src/types/mongoSchema.d.ts b/src/types/mongoSchema.d.ts index 1dff08734..f8ff8ee0e 100644 --- a/src/types/mongoSchema.d.ts +++ b/src/types/mongoSchema.d.ts @@ -154,4 +154,5 @@ export interface OpenApiSchema { userId: string; createTime: Date; lastUsedTime: Date; + apiKey: String; } diff --git a/src/types/openapi.d.ts b/src/types/openapi.d.ts new file mode 100644 index 000000000..6b7056d9b --- /dev/null +++ b/src/types/openapi.d.ts @@ -0,0 +1,4 @@ +export interface UserOpenApiKey { + id: string; + apiKey: string; +}