From 6fd49b09554c2ff8e5be5fc8b24d2fa478de17a7 Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Sat, 10 Jun 2023 14:01:00 +0800 Subject: [PATCH] perf: ui --- .gitignore | 1 - .husky/pre-commit | 6 + client/src/components/Layout/navbar.tsx | 55 +++--- client/src/constants/theme.ts | 4 + client/src/constants/user.ts | 5 + client/src/pages/api/openapi/kb/pushData.ts | 16 +- client/src/pages/chat/components/History.tsx | 19 +-- client/src/pages/kb/components/KbList.tsx | 8 +- .../src/pages/model/components/ModelList.tsx | 161 ++++++++++-------- client/src/styles/reset.scss | 2 +- package.json | 3 +- 11 files changed, 161 insertions(+), 119 deletions(-) create mode 100755 .husky/pre-commit diff --git a/.gitignore b/.gitignore index 5de60dd48..2892820b1 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,4 @@ next-env.d.ts platform.json testApi/ local/ -.husky/ dist/ \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..12cc5e1ce --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +if command -v npx >/dev/null 2>&1; then + npx lint-staged +fi \ No newline at end of file diff --git a/client/src/components/Layout/navbar.tsx b/client/src/components/Layout/navbar.tsx index 75114791e..88e648b30 100644 --- a/client/src/components/Layout/navbar.tsx +++ b/client/src/components/Layout/navbar.tsx @@ -27,7 +27,7 @@ const Navbar = ({ unread }: { unread: number }) => { activeLink: ['/chat'] }, { - label: '我的应用', + label: '应用', icon: 'model', link: `/model?modelId=${lastModelId}`, activeLink: ['/model'] @@ -39,7 +39,7 @@ const Navbar = ({ unread }: { unread: number }) => { activeLink: ['/kb'] }, { - label: '应用市场', + label: '市场', icon: 'appStore', link: '/model/share', activeLink: ['/model/share'] @@ -61,14 +61,15 @@ const Navbar = ({ unread }: { unread: number }) => { ); const itemStyles: any = { - mb: 3, + my: 3, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', - w: '60px', - h: '45px', + w: '54px', + h: '54px', + borderRadius: 'md', _hover: { color: '#ffffff' } @@ -79,7 +80,7 @@ const Navbar = ({ unread }: { unread: number }) => { flexDirection={'column'} alignItems={'center'} pt={6} - backgroundColor={'#465069'} + backgroundImage={'linear-gradient(to bottom right,#465069,#000000)'} h={'100%'} w={'100%'} boxShadow={'4px 0px 4px 0px rgba(43, 45, 55, 0.01)'} @@ -99,30 +100,26 @@ const Navbar = ({ unread }: { unread: number }) => { {/* 导航列表 */} {navbarList.map((item) => ( - - - - - + + + {item.label} + + ))} {unread > 0 && ( diff --git a/client/src/constants/theme.ts b/client/src/constants/theme.ts index c8db64557..bf9d192db 100644 --- a/client/src/constants/theme.ts +++ b/client/src/constants/theme.ts @@ -232,6 +232,10 @@ export const theme = extendTheme({ xl: '1800px', '2xl': '2100px' }, + active: { + activeBlueGradient: 'linear-gradient(120deg, #d6e8ff 0%, #f0f7ff 100%)', + hoverBlueGradient: 'linear-gradient(60deg, #f0f7ff 0%, #d6e8ff 100%)' + }, components: { Modal: ModalTheme, Button, diff --git a/client/src/constants/user.ts b/client/src/constants/user.ts index c4edb6c1c..4386331e2 100644 --- a/client/src/constants/user.ts +++ b/client/src/constants/user.ts @@ -40,3 +40,8 @@ export const InformTypeMap = { label: '系统通知' } }; + +export enum MyModelsTypeEnum { + my = 'my', + collection = 'collection' +} diff --git a/client/src/pages/api/openapi/kb/pushData.ts b/client/src/pages/api/openapi/kb/pushData.ts index bcffda278..fab40ba25 100644 --- a/client/src/pages/api/openapi/kb/pushData.ts +++ b/client/src/pages/api/openapi/kb/pushData.ts @@ -7,6 +7,7 @@ import { withNextCors } from '@/service/utils/tools'; import { TrainingModeEnum } from '@/constants/plugin'; import { startQueue } from '@/service/utils/tools'; import { PgClient } from '@/service/pg'; +import { modelToolMap } from '@/utils/plugin'; type DateItemType = { a: string; q: string; source?: string }; @@ -21,6 +22,11 @@ export type Response = { insertLen: number; }; +const modeMaxToken = { + [TrainingModeEnum.index]: 700, + [TrainingModeEnum.qa]: 3300 +}; + export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse) { try { const { kbId, data, mode, prompt } = req.body as Props; @@ -68,7 +74,15 @@ export async function pushDataToKb({ data.forEach((item) => { const text = item.q + item.a; - if (!set.has(text)) { + + // count token + const token = modelToolMap['gpt-3.5-turbo'].countTokens({ + messages: [{ obj: 'System', value: item.q }] + }); + + if (mode === TrainingModeEnum.qa && token > modeMaxToken[TrainingModeEnum.qa]) { + console.log('q is too long'); + } else if (!set.has(text)) { filterData.push(item); set.add(text); } diff --git a/client/src/pages/chat/components/History.tsx b/client/src/pages/chat/components/History.tsx index b5521c752..9a000be7a 100644 --- a/client/src/pages/chat/components/History.tsx +++ b/client/src/pages/chat/components/History.tsx @@ -146,31 +146,26 @@ const PcSliderBar = ({ )} )} - {/* chat history */} - + {history.map((item) => ( { if (item._id === chatId) return; diff --git a/client/src/pages/kb/components/KbList.tsx b/client/src/pages/kb/components/KbList.tsx index 5f10d71d9..f9b254786 100644 --- a/client/src/pages/kb/components/KbList.tsx +++ b/client/src/pages/kb/components/KbList.tsx @@ -87,7 +87,7 @@ const KbList = ({ kbId }: { kbId: string }) => { /> - + {kbs.map((item) => ( { mb={[2, 0]} cursor={'pointer'} transition={'background-color .2s ease-in'} - borderLeft={['', '5px solid transparent']} _hover={{ - backgroundColor: ['', '#dee0e3'] + backgroundImage: ['', theme.active.hoverBlueGradient] }} {...(kbId === item._id ? { - backgroundColor: '#eff0f1', - borderLeftColor: 'myBlue.600 !important' + backgroundImage: `${theme.active.activeBlueGradient} !important` } : {})} onClick={() => { diff --git a/client/src/pages/model/components/ModelList.tsx b/client/src/pages/model/components/ModelList.tsx index 3bf74cb78..8fa9a36af 100644 --- a/client/src/pages/model/components/ModelList.tsx +++ b/client/src/pages/model/components/ModelList.tsx @@ -1,5 +1,15 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { Box, Flex, useTheme, Input, IconButton, Tooltip } from '@chakra-ui/react'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; +import { + Box, + Flex, + Input, + IconButton, + Tooltip, + Tabs, + TabList, + Tab, + useTheme +} from '@chakra-ui/react'; import { AddIcon } from '@chakra-ui/icons'; import { useRouter } from 'next/router'; import MyIcon from '@/components/Icon'; @@ -9,8 +19,15 @@ import { useToast } from '@/hooks/useToast'; import { useQuery } from '@tanstack/react-query'; import { useUserStore } from '@/store/user'; import Avatar from '@/components/Avatar'; +import { MyModelsTypeEnum } from '@/constants/user'; const ModelList = ({ modelId }: { modelId: string }) => { + const tabs = useRef([ + { label: '我的', value: MyModelsTypeEnum.my }, + { label: '收藏', value: MyModelsTypeEnum.collection } + ]); + const [currentTab, setCurrentTab] = useState(MyModelsTypeEnum.my); + const theme = useTheme(); const router = useRouter(); const { toast } = useToast(); @@ -42,29 +59,23 @@ const ModelList = ({ modelId }: { modelId: string }) => { setIsLoading(false); }, [myModels.length, refreshModel, router, setIsLoading, toast]); - const models = useMemo( - () => - [ - { - label: '我的', - list: myModels.filter((item) => - new RegExp(searchText, 'ig').test(item.name + item.systemPrompt) - ) - }, - { - label: '收藏', - list: myCollectionModels.filter((item) => - new RegExp(searchText, 'ig').test(item.name + item.systemPrompt) - ) - } - ].filter((item) => item.list.length > 0), - [myCollectionModels, myModels, searchText] - ); - - const totalModels = useMemo( - () => models.reduce((sum, item) => sum + item.list.length, 0), - [models] - ); + const currentModels = useMemo(() => { + const map = { + [MyModelsTypeEnum.my]: { + list: myModels.filter((item) => + new RegExp(searchText, 'ig').test(item.name + item.systemPrompt) + ), + emptyText: '还没有 AI 应用~\n快来创建一个吧' + }, + [MyModelsTypeEnum.collection]: { + list: myCollectionModels.filter((item) => + new RegExp(searchText, 'ig').test(item.name + item.systemPrompt) + ), + emptyText: '收藏的 AI 应用为空~\n快去市场找一个吧' + } + }; + return map[currentTab]; + }, [currentTab, myCollectionModels, myModels, searchText]); return ( { /> - - {models.map((item) => ( - - - {item.label} - - {item.list.map((item) => ( - { - if (item._id === modelId) return; - router.push(`/model?modelId=${item._id}`); - }} + + + item.value === currentTab)} + onChange={(i) => setCurrentTab(tabs.current[i].value)} + > + + {tabs.current.map((item) => ( + - - - - {item.name} - - - {item.systemPrompt || '这个 应用 没有设置提示词~'} - - - + {item.label} + ))} - + + + + + {currentModels.list.map((item) => ( + { + if (item._id === modelId) return; + router.push(`/model?modelId=${item._id}`); + }} + > + + + + {item.name} + + + {item.systemPrompt || '这个 应用 没有设置提示词~'} + + + ))} - - {!isFetching && totalModels === 0 && ( + {!isFetching && currentModels.list.length === 0 && ( - 还没有 AI 应用~ + {currentModels.emptyText} )} diff --git a/client/src/styles/reset.scss b/client/src/styles/reset.scss index 8de5ad988..13864a54d 100644 --- a/client/src/styles/reset.scss +++ b/client/src/styles/reset.scss @@ -44,7 +44,7 @@ svg { div { &::-webkit-scrollbar-thumb { background: transparent !important; - transition: 1s; + transition: background 1s; } &:hover { &::-webkit-scrollbar-thumb { diff --git a/package.json b/package.json index 8df2a2fd9..63f578a58 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,13 @@ "prepare": "husky install", "format": "prettier --config \"./.prettierrc.js\" --write \"./**/src/**/*.{ts,tsx,scss}\"" }, - "dependencies": {}, "devDependencies": { "husky": "^8.0.3", "lint-staged": "^13.2.1", "prettier": "^2.8.7" }, "lint-staged": { - "./**/*.{ts,tsx,scss}": "npm run format" + "./**/**/*.{ts,tsx,scss}": "npm run format" }, "engines": { "node": ">=18.0.0"