From e0e41d7e21eac8f1775810e87f1fe16ff6e319e3 Mon Sep 17 00:00:00 2001 From: zhaoweijie Date: Sat, 23 Aug 2025 20:11:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(components):=20=E6=96=B0=E5=A2=9E=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E7=BB=84=E4=BB=B6=E5=B9=B6=E4=BC=98=E5=8C=96=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Bell、Collect 和 NotCollect 图标组件 - 优化 History 组件,添加隐藏 logo 功能 - 调整 Message 组件样式,移除不必要的代码 - 更新 Scene 组件 Header 颜色 - 注释掉 tailwind.css 中的 arimo 字体权重 --- src/assets/icons/a.svg | 1 - src/assets/icons/b.svg | 1 - src/assets/icons/bulb.svg | 1 - src/assets/icons/c.svg | 1 - src/assets/icons/d.svg | 1 - src/assets/icons/e.svg | 1 - src/assets/icons/eye.svg | 1 - src/assets/icons/f.svg | 1 - src/assets/icons/rocket.svg | 1 - src/assets/tailwind.css | 2 +- src/components/Common/Playground/History.tsx | 33 ++++--- .../Common/Playground/IodRelevant.tsx | 2 +- src/components/Common/Playground/Message.tsx | 98 +++++++++---------- src/components/Common/Playground/Scene.tsx | 4 +- src/components/Icons/Bell.tsx | 26 +++++ src/components/Icons/Collect.tsx | 24 +++++ src/components/Icons/NotCollect.tsx | 23 +++++ src/components/Icons/Setting.tsx | 22 +++++ src/components/Icons/Share.tsx | 23 +++++ src/components/Layouts/Header.tsx | 82 +++++++++------- .../Option/Playground/PlaygroundEmpty.tsx | 3 +- .../Option/Playground/PlaygroundForm.tsx | 97 +++++++++--------- .../Option/Playground/PlaygroundIod.tsx | 38 ++++++- src/components/Option/Sidebar.tsx | 28 +++--- 24 files changed, 331 insertions(+), 183 deletions(-) delete mode 100644 src/assets/icons/a.svg delete mode 100644 src/assets/icons/b.svg delete mode 100644 src/assets/icons/bulb.svg delete mode 100644 src/assets/icons/c.svg delete mode 100644 src/assets/icons/d.svg delete mode 100644 src/assets/icons/e.svg delete mode 100644 src/assets/icons/eye.svg delete mode 100644 src/assets/icons/f.svg delete mode 100644 src/assets/icons/rocket.svg create mode 100644 src/components/Icons/Bell.tsx create mode 100644 src/components/Icons/Collect.tsx create mode 100644 src/components/Icons/NotCollect.tsx create mode 100644 src/components/Icons/Setting.tsx create mode 100644 src/components/Icons/Share.tsx diff --git a/src/assets/icons/a.svg b/src/assets/icons/a.svg deleted file mode 100644 index 27ce94d..0000000 --- a/src/assets/icons/a.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/b.svg b/src/assets/icons/b.svg deleted file mode 100644 index dad9420..0000000 --- a/src/assets/icons/b.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/bulb.svg b/src/assets/icons/bulb.svg deleted file mode 100644 index 18d1176..0000000 --- a/src/assets/icons/bulb.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/c.svg b/src/assets/icons/c.svg deleted file mode 100644 index f0fdfa0..0000000 --- a/src/assets/icons/c.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/d.svg b/src/assets/icons/d.svg deleted file mode 100644 index 7821513..0000000 --- a/src/assets/icons/d.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/e.svg b/src/assets/icons/e.svg deleted file mode 100644 index d6146cc..0000000 --- a/src/assets/icons/e.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/eye.svg b/src/assets/icons/eye.svg deleted file mode 100644 index 4ebe497..0000000 --- a/src/assets/icons/eye.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/f.svg b/src/assets/icons/f.svg deleted file mode 100644 index 880bc1d..0000000 --- a/src/assets/icons/f.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/icons/rocket.svg b/src/assets/icons/rocket.svg deleted file mode 100644 index 049fc99..0000000 --- a/src/assets/icons/rocket.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/tailwind.css b/src/assets/tailwind.css index 1ef50b0..dbbc8e8 100644 --- a/src/assets/tailwind.css +++ b/src/assets/tailwind.css @@ -6,7 +6,7 @@ .arimo { font-family: "Arimo", sans-serif; - font-weight: 500; + /*font-weight: 500;*/ font-style: normal; } diff --git a/src/components/Common/Playground/History.tsx b/src/components/Common/Playground/History.tsx index 0c57ebd..ccdeef1 100644 --- a/src/components/Common/Playground/History.tsx +++ b/src/components/Common/Playground/History.tsx @@ -1,12 +1,11 @@ import { Sidebar } from "@/components/Option/Sidebar.tsx" -import React, { useContext, useMemo, useState } from "react" +import React, { useContext, useMemo } from "react" import { useMessageOption } from "@/hooks/useMessageOption.tsx" import { useStoreChatModelSettings } from "@/store/model.tsx" import { Button, Card, Divider, - List, Menu, MenuProps, Popover, @@ -22,8 +21,7 @@ import { PlusOutlined, RightOutlined } from "@ant-design/icons" import { qaPrompt } from "@/libs/playground.tsx" import { ProviderIcons } from "@/components/Common/ProviderIcon.tsx" import { fetchChatModels } from "@/services/ollama.ts" -import logo from '@/assets/logo.png' - +import logo from "@/assets/logo.png" const ModelIcon = () => { return ( @@ -74,10 +72,14 @@ export const PlaygroundHistory = () => { children: qaPrompt.map((item) => { return { key: item.id, - label:
-

{item.icon}

- {item.title} -
, + label: ( +
+

+ {item.icon} +

+ {item.title} +
+ ) } }) } @@ -101,25 +103,26 @@ export const PlaygroundHistory = () => { } // 大模型 - const { - data: models, - isLoading: isModelsLoading, - refetch - } = useQuery({ + const { data: models, isLoading: isModelsLoading } = useQuery({ queryKey: ["fetchModel"], queryFn: () => fetchChatModels({ returnEmpty: true }), refetchIntervalInBackground: false, placeholderData: (prev) => prev }) + // 是否隐藏logo + const hideLogo = useMemo(() => { + return localStorage.getItem("hideLogo") === "true" + }, []) + return ( {/*Header*/}
- logo + {!hideLogo && logo}

数联网科创智能体

diff --git a/src/components/Common/Playground/IodRelevant.tsx b/src/components/Common/Playground/IodRelevant.tsx index 91073ff..578fad9 100644 --- a/src/components/Common/Playground/IodRelevant.tsx +++ b/src/components/Common/Playground/IodRelevant.tsx @@ -350,7 +350,7 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => { + className={`${className} translate-y-[-2px] !bg-[#d0e6ff] !shadow-md`}>
{/* 花瓣效果 */}
{ {/*
*/}
-
-
- {props.isBot ? ( - !props.botAvatar ? ( -
- ) : ( - props.botAvatar - ) - ) : !props.userAvatar ? ( -
- ) : ( - props.userAvatar - )} -
-
-
+
{props.isBot && @@ -102,7 +87,7 @@ export const PlaygroundMessage = (props: Props) => { return ( { })} ) : ( + //

+ // {props.message} + //

+ className={`bg-[#2563eb] font-normal rounded-tr-none + text-white px-4 py-2.5 rounded-2xl prose-lg dark:prose-invert whitespace-pre-line prose-p:leading-relaxed prose-pre:p-0 dark:prose-dark ${ + props.message_type && "italic dark:text-gray-400" + } flex flex-row-reverse`}> {props.message} - {/*{props.message}*/}

) ) : ( @@ -196,35 +187,42 @@ export const PlaygroundMessage = (props: Props) => { ]} /> )} - {props.isBot && props?.iodSources && Object.values(props?.iodSources).map(item => item.data).flat().length > 0 && ( - - {t("iodCitations")} -
- ), - children: ( -
- {Object.values(props?.iodSources).map(item => item.data).flat()?.map((source, index) => ( - - ))} -
- ) - } - ]} - /> - )} + {props.isBot && + props?.iodSources && + Object.values(props?.iodSources) + .map((item) => item.data) + .flat().length > 0 && ( + + {t("iodCitations")} +
+ ), + children: ( +
+ {Object.values(props?.iodSources) + .map((item) => item.data) + .flat() + ?.map((source, index) => ( + + ))} +
+ ) + } + ]} + /> + )} {!props.isProcessing && !editMode ? (
= ({ title, showButton = true, onClick }) => ( +
= ({ title, showButton = true, onClick }) => height="18"> {title} diff --git a/src/components/Icons/Bell.tsx b/src/components/Icons/Bell.tsx new file mode 100644 index 0000000..b6b301b --- /dev/null +++ b/src/components/Icons/Bell.tsx @@ -0,0 +1,26 @@ +import React from "react" + +export const BellIcon = React.forwardRef< + SVGSVGElement, + React.SVGProps +>((props, ref) => { + return ( + + + + + ) +}) diff --git a/src/components/Icons/Collect.tsx b/src/components/Icons/Collect.tsx new file mode 100644 index 0000000..a318f3d --- /dev/null +++ b/src/components/Icons/Collect.tsx @@ -0,0 +1,24 @@ +import React from "react" + +export const CollectIcon = React.forwardRef< + SVGSVGElement, + React.SVGProps +>((props, ref) => { + return ( + + + + ) +}) diff --git a/src/components/Icons/NotCollect.tsx b/src/components/Icons/NotCollect.tsx new file mode 100644 index 0000000..e705807 --- /dev/null +++ b/src/components/Icons/NotCollect.tsx @@ -0,0 +1,23 @@ +import React from "react" + +export const NotCollectIcon = React.forwardRef< + SVGSVGElement, + React.SVGProps +>((props, ref) => { + return ( + + + + ) +}) diff --git a/src/components/Icons/Setting.tsx b/src/components/Icons/Setting.tsx new file mode 100644 index 0000000..4b95026 --- /dev/null +++ b/src/components/Icons/Setting.tsx @@ -0,0 +1,22 @@ +import React from "react" + +export const SettingIcon = React.forwardRef< + SVGSVGElement, + React.SVGProps +>((props, ref) => { + return ( + + + + ) +}) diff --git a/src/components/Icons/Share.tsx b/src/components/Icons/Share.tsx new file mode 100644 index 0000000..d4b4d5c --- /dev/null +++ b/src/components/Icons/Share.tsx @@ -0,0 +1,23 @@ +import React from "react" + +export const ShareIcon = React.forwardRef< + SVGSVGElement, + React.SVGProps +>((props, ref) => { + return ( + + + + ) +}) diff --git a/src/components/Layouts/Header.tsx b/src/components/Layouts/Header.tsx index 22c1e80..701126b 100644 --- a/src/components/Layouts/Header.tsx +++ b/src/components/Layouts/Header.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useMemo } from "react" +import React, { useContext, useMemo, useState } from "react" import { HistoryContext } from "@/components/Layouts/Layout.tsx" import { PanelLeftIcon } from "lucide-react" import { Button, Tooltip } from "antd" @@ -7,27 +7,11 @@ import { useMessageOption } from "@/hooks/useMessageOption.tsx" import { useTranslation } from "react-i18next" import { NavLink, useLocation } from "react-router-dom" import logo from "@/assets/logo.png" - -interface SettingIconProps {} -const SettingIcon: React.FC = () => { - return ( - - - - ) -} +import { BellIcon } from "@/components/Icons/Bell.tsx" +import { ShareIcon } from "@/components/Icons/Share.tsx" +import { NotCollectIcon } from "@/components/Icons/NotCollect.tsx" +import { CollectIcon } from "@/components/Icons/Collect.tsx" +import { SettingIcon } from "@/components/Icons/Setting.tsx" type Props = { setOpenModelSettings: (open: boolean) => void @@ -49,6 +33,13 @@ export const Header: React.FC = ({ setOpenModelSettings }) => { const { t } = useTranslation(["option", "common", "settings"]) const { clearChat } = useMessageOption() + + // 是否隐藏logo + const hideLogo = useMemo(() => { + return localStorage.getItem("hideLogo") === "true" + }, []) + + const [collect, setCollect] = useState(false) return (
@@ -88,8 +79,11 @@ export const Header: React.FC = ({ setOpenModelSettings }) => {

- 数联网科创智能体 + className="!text-gray-500 dark:text-gray-400 flex items-center gap-2 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"> + {!hideLogo && logo} +

+ 数联网科创智能体 +

)} @@ -103,14 +97,11 @@ export const Header: React.FC = ({ setOpenModelSettings }) => { ${show ? "-top-[60px]" : "-top-[2px] delay-200"} `}> = ({ setOpenModelSettings }) => { p-id="9635">

- logo -

数联网科创智能体

+ {!hideLogo && logo} +

+ 数联网科创智能体 +

{/*设置框*/} -
+
+ {collect ? ( + + + ) : ( + + + )} + + + + - - + +
diff --git a/src/components/Option/Playground/PlaygroundEmpty.tsx b/src/components/Option/Playground/PlaygroundEmpty.tsx index 206cd32..d10c713 100644 --- a/src/components/Option/Playground/PlaygroundEmpty.tsx +++ b/src/components/Option/Playground/PlaygroundEmpty.tsx @@ -24,11 +24,12 @@ export const PlaygroundEmpty = () => {
{qaPrompt.map((item, index) => (
handleQuestion(item.title)}>
{item.icon}
-
+
{item.title}
diff --git a/src/components/Option/Playground/PlaygroundForm.tsx b/src/components/Option/Playground/PlaygroundForm.tsx index 9e2a0f9..f988ee6 100644 --- a/src/components/Option/Playground/PlaygroundForm.tsx +++ b/src/components/Option/Playground/PlaygroundForm.tsx @@ -18,7 +18,7 @@ import { defaultEmbeddingModelForRag } from "~/services/ollama" import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react" import { getVariable } from "@/utils/select-variable" import { useTranslation } from "react-i18next" -import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect" +// import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect" import { useSpeechRecognition } from "@/hooks/useSpeechRecognition" import { PiGlobe, PiNetwork } from "react-icons/pi" import { handleChatInputKeyDown } from "@/utils/key-down" @@ -369,11 +369,15 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { variant="filled" size="large" className="w-full mt-4 hover:!bg-[#0057ff1a]" - style={iodSearch ? { - color: "#0057ff", - background: "#0057ff0f", - border: "1px solid #0066ff26" - } : {}}> + style={ + iodSearch + ? { + color: "#0057ff", + background: "#0057ff0f", + border: "1px solid #0066ff26" + } + : {} + }> 数联网深度搜索{iodSearch ? ":开" : ""} @@ -381,34 +385,32 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
)}
-
+
{!selectedKnowledge && ( - + + )} {browserSupportsSpeechRecognition && ( - + )} - + {/**/} {!isSending ? ( - - - } + // icon={ + // + // + // + // } menu={{ items: [ { @@ -479,20 +484,6 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { ] }}>
- {sendWhenEnter ? ( - - - - - ) : null} {t("common:submit")}
diff --git a/src/components/Option/Playground/PlaygroundIod.tsx b/src/components/Option/Playground/PlaygroundIod.tsx index ae79040..901a795 100644 --- a/src/components/Option/Playground/PlaygroundIod.tsx +++ b/src/components/Option/Playground/PlaygroundIod.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useState } from "react" +import React, { createContext, useContext, useMemo, useState } from "react" import { AnimatePresence, motion } from "framer-motion" @@ -8,6 +8,8 @@ import { PlaygroundScene } from "@/components/Common/Playground/Scene.tsx" import { PlaygroundTeam } from "@/components/Common/Playground/Team.tsx" import { Card } from "antd" import { CloseOutlined } from "@ant-design/icons" +import { useMessageOption } from "@/hooks/useMessageOption.tsx" +import { Message } from "@/types/message.ts" // 定义 Context 类型 interface IodPlaygroundContextType { @@ -17,6 +19,7 @@ interface IodPlaygroundContextType { setDetailHeader: React.Dispatch> detailMain: React.ReactNode setDetailMain: React.Dispatch> + currentMessage: Message | null } // 创建 Context @@ -36,13 +39,41 @@ export const useIodPlaygroundContext = () => { } export const PlaygroundIod = () => { + const { messages, iodLoading, currentMessageId, iodSearch } = + useMessageOption() + const [showPlayground, setShowPlayground] = useState(true) const [detailHeader, setDetailHeader] = useState(<>) const [detailMain, setDetailMain] = useState(<>) + const currentMessage = useMemo(() => { + if (iodLoading) { + return null + } + + if (messages.length && iodSearch) { + // 如果不存在currentMessageId默认返回最后一个message + if (!currentMessageId) { + return messages.at(-1) + } + + const currentMessage = messages?.find( + (message) => message.id === currentMessageId + ) + if (currentMessage) { + return currentMessage + } + // 如果当前message不存在最后一个message + return messages.at(-1) + } + + return null + }, [currentMessageId, messages, iodLoading, iodSearch]) + return ( { const { showPlayground, detailMain, detailHeader, setShowPlayground } = useIodPlaygroundContext() - return ( {showPlayground ? ( @@ -80,7 +110,9 @@ const PlaygroundContent = () => { }} className="h-full grid grid-rows-12 gap-3">
- +
diff --git a/src/components/Option/Sidebar.tsx b/src/components/Option/Sidebar.tsx index d350976..fedbff6 100644 --- a/src/components/Option/Sidebar.tsx +++ b/src/components/Option/Sidebar.tsx @@ -1,21 +1,21 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" import { - PageAssitDatabase, + deleteByHistoryId, formatToChatHistory, formatToMessage, - deleteByHistoryId, - updateHistory, + getPromptById, + PageAssitDatabase, pinHistory, - getPromptById + updateHistory } from "@/db" -import { Empty, Skeleton, Dropdown, Menu, Tooltip } from "antd" +import { Dropdown, Empty, Menu, Skeleton, Tooltip } from "antd" import { - PencilIcon, - Trash2, + BotIcon, MoreVertical, + PencilIcon, PinIcon, PinOffIcon, - BotIcon + Trash2 } from "lucide-react" import { useNavigate } from "react-router-dom" import { useTranslation } from "react-i18next" @@ -24,7 +24,6 @@ import { getLastUsedChatSystemPrompt, lastUsedChatModelEnabled } from "@/services/model-settings" -import { useState } from "react" type Props = { onClose: () => void @@ -171,10 +170,9 @@ export const Sidebar = ({
{chat?.message_source === "copilot" && ( @@ -271,7 +269,9 @@ export const Sidebar = ({ trigger={["click"]} placement="bottomRight">