refactor(iod): 重构数联网相关组件和逻辑

-优化了 Data、Scene 和 Team组件的逻辑,使用 currentIodMessage 替代复杂的条件判断- 改进了 IodRelevant 组件的动画和数据处理方式
- 调整了 Message 组件以支持数联网搜索功能
- 重构了 PlaygroundIodProvider,简化了上下文类型和数据处理
- 更新了数据库相关操作,使用新的 HistoryMessage 类型
- 新增了 IodDb 类来管理数联网连接配置
This commit is contained in:
zhaoweijie
2025-08-24 19:00:49 +08:00
parent f9763778fa
commit 2b4885ae2d
20 changed files with 415 additions and 399 deletions

View File

@@ -11,8 +11,7 @@ const defaultData: IodRegistryEntry[] = [
{
name: "固态电池固体电解质材料数据集",
doId: "CSTR:16666.11.nbsdc.9bjqrscd",
description:
"国家基础学科公共科学数据中心"
description: "国家基础学科公共科学数据中心"
},
{
name: "固体颗粒物与流体耦合",
@@ -98,31 +97,22 @@ type Props = {
className?: string
}
export const PlaygroundData: React.FC<Props> = ({ className }) => {
const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption()
const { iodLoading } = useMessageOption()
const { setShowPlayground, setDetailHeader, setDetailMain } =
useIodPlaygroundContext()
const {
setShowPlayground,
setDetailHeader,
setDetailMain,
currentIodMessage
} = useIodPlaygroundContext()
const data = useMemo<IodRegistryEntry[]>(() => {
// 确保loading状态时数据大于3
if (iodLoading) {
return defaultData
}
if (messages.length && iodSearch) {
const currentMessage = messages?.find(
(message) => message.id === currentMessageId
)
return currentMessage?.iodSources.data.data ?? []
}
return defaultData
}, [currentMessageId, messages, iodLoading, iodSearch])
return currentIodMessage ? currentIodMessage.data?.data ?? [] : defaultData
}, [currentIodMessage])
const title = useMemo(() => {
return messages.length > 0 ? "推荐数据" : "热点数据"
}, [messages])
return currentIodMessage ? "推荐数据" : "热点数据"
}, [currentIodMessage])
const showMore = () => {
setShowPlayground(false)
@@ -133,7 +123,7 @@ export const PlaygroundData: React.FC<Props> = ({ className }) => {
onClick={() => setShowPlayground(false)}
/>
)
setDetailMain(<Main loading={iodLoading} data={data} truncate={false} />)
setDetailMain(<Main loading={iodLoading && Boolean(currentIodMessage)} data={data} truncate={false} />)
}
return (
@@ -142,7 +132,7 @@ export const PlaygroundData: React.FC<Props> = ({ className }) => {
{/* 数据导航 */}
<Header title={title} onClick={showMore} />
{/* 数据列表 */}
<Main loading={iodLoading} data={data.slice(0, 3)} />
<Main loading={iodLoading && Boolean(currentIodMessage)} data={data.slice(0, 3)} />
</div>
</Card>
)

View File

@@ -10,6 +10,7 @@ import { DatasetIcon } from "@/components/Icons/Dataset.tsx"
import { TechCompanyIcon } from "@/components/Icons/TechCompany.tsx"
import { ResearchInstitutesIcon } from "@/components/Icons/ResearchInstitutes.tsx"
import { NSDCIcon } from "@/components/Icons/NSDC.tsx"
import { useIodPlaygroundContext } from "@/components/Option/Playground/PlaygroundIod.tsx"
const rotate = keyframes`
0% {
@@ -32,8 +33,8 @@ const breathe = keyframes`
}
`
// 花瓣
const CircleElement = styled.div<{ delay: number; playing: boolean }>`
// 花瓣 /* ${(props) => (props.playing ? "running" : "paused")}; */
const CircleElement = styled.div<{ delay: number }>`
position: absolute;
width: 300px;
height: 160px;
@@ -46,7 +47,7 @@ const CircleElement = styled.div<{ delay: number; playing: boolean }>`
${rotate} 6s linear infinite,
${breathe} 2s infinite alternate;
animation-delay: ${(props) => props.delay}s;
animation-play-state: ${(props) => (props.playing ? "running" : "paused")};
animation-play-state: running;
animation-duration: 3s; /* 添加动画总持续时间 */
animation-fill-mode: forwards; /* 保持动画结束时的状态 */
`
@@ -221,24 +222,19 @@ type Props = {
className?: string
}
export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption()
const { iodLoading, iodSearch } = useMessageOption()
const { currentIodMessage } = useIodPlaygroundContext()
const showSearchData = useMemo(() => {
return iodSearch && messages.length > 0 && !iodLoading
}, [iodSearch, messages, iodLoading])
return currentIodMessage && !iodLoading
}, [currentIodMessage, iodLoading])
const data = useMemo(() => {
const currentMessage = messages?.find(
(message) => message.id === currentMessageId
)
const loading = (iodSearch && iodLoading)
const text = loading ? '正' : '已'
const text2 = loading ? '进行' : '完成'
const text3 = loading ? '……' : ''
const loading = iodSearch && iodLoading
const text = loading ? "正" : "已"
const text2 = loading ? "进行" : "完成"
const text3 = loading ? "……" : ""
const duration = loading ? 2.5 : 0
return [
@@ -256,7 +252,12 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
</span>
<span className="text-[#f00000]">
<CountUp decimals={1} end={53.7} duration={duration} separator="," />
<CountUp
decimals={1}
end={53.7}
duration={duration}
separator=","
/>
</span>
{text2}{text3}
@@ -268,7 +269,7 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<span className="text-green-700">
{" "}
<CountUp
end={currentMessage?.iodSources.data.total ?? 0}
end={currentIodMessage?.data.total ?? 0}
duration={2.5}
separator=","
/>
@@ -288,9 +289,14 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<CountUp end={138} duration={duration} separator="," />
</span>
<span className="text-[#f00000]">
<CountUp end={18.3} decimals={1} duration={duration} separator="," />
<CountUp
end={18.3}
decimals={1}
duration={duration}
separator=","
/>
</span>
{text2}{text3}
@@ -302,7 +308,7 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<span className="text-green-700">
{" "}
<CountUp
end={currentMessage?.iodSources.scenario.total ?? 0}
end={currentIodMessage?.scenario.total ?? 0}
duration={2.5}
separator=","
/>
@@ -324,7 +330,13 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<span className="text-[#f00000]">
{" "}
<CountUp end={2.1} decimals={1} duration={duration} separator="," />
<CountUp
end={2.1}
decimals={1}
duration={duration}
separator=","
/>
</span>
<span className="text-[#f00000]">
@@ -340,7 +352,7 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<span className="text-green-700">
{" "}
<CountUp
end={currentMessage?.iodSources.organization.total ?? 0}
end={currentIodMessage?.organization.total ?? 0}
duration={2.5}
separator=","
/>
@@ -353,7 +365,7 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
)
}
]
}, [messages, iodLoading])
}, [showSearchData, iodLoading])
return (
<Card
@@ -365,9 +377,9 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<div
className={`absolute inset-0 pointer-events-none z-0 overflow-hidden ${showSearchData ? "" : ""}`}>
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-64 h-64">
<CircleElement delay={0} playing={true} />
<CircleElement delay={1} playing={true} />
<CircleElement delay={2} playing={true} />
<CircleElement delay={0} />
<CircleElement delay={1} />
<CircleElement delay={2} />
</div>
</div>
@@ -376,16 +388,14 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
<h2 className="text-xl font-semibold text-[#1a3c87] flex justify-center items-center">
<div className="flex items-center gap-2">
<SearchIcon />
{messages.length > 0
? "科创数联网深度搜索"
: "科创数联网连接资源"}
{currentIodMessage ? "科创数联网深度搜索" : "科创数联网连接资源"}
</div>
{/*<button className="bg-[#2563eb1a] text-[#08307f] font-medium py-1 px-3 rounded-full text-sm hover:bg-[#2563eb1a] transition-colors float-right">*/}
{/* {data.length}个结果*/}
{/*</button>*/}
</h2>
<p className="text-sm text-[#1a3c87] mt-1 text-center">
{messages.length > 0
{currentIodMessage
? "下面是在科创数联网上进行深度搜索得到的相关数据、场景和团队"
: "下面是科创数联网连接的数据、场景和团队"}
</p>
@@ -393,7 +403,7 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
{/* Content */}
<div className="space-y-2 flex-1 overflow-y-auto">
{messages.length ? (
{currentIodMessage ? (
<AnimatePresence mode="wait">
<motion.div
key="search-results"
@@ -422,16 +432,16 @@ export const PlaygroundIodRelevant: React.FC<Props> = ({ className }) => {
/>
)}
</div>
<p
<div
className={`text-gray-700 ${showSearchData ? "text-sm" : "text-lg"}`}>
{item.title}
</p>
</div>
</div>
{item.description && (
<div className="flex-1">
<p className="text-xs text-gray-500 mt-1 pl-7">
<div className="text-xs text-gray-500 mt-1 pl-7">
{item.description}
</p>
</div>
</div>
)}
</div>

View File

@@ -25,8 +25,10 @@ import { GenerationInfo } from "./GenerationInfo"
import { parseReasoning } from "@/libs/reasoning"
import { humanizeMilliseconds } from "@/utils/humanize-milliseconds"
import { AllIodRegistryEntry } from "@/types/iod.ts"
import { PiNetwork } from "react-icons/pi"
type Props = {
id?: string
message: string
message_type?: string
hideCopy?: boolean
@@ -50,9 +52,11 @@ type Props = {
generationInfo?: any
isStreaming: boolean
reasoningTimeTaken?: number
iodSearch?: boolean
setCurrentMessageId: (id: string) => void
}
export const PlaygroundMessage = (props: Props) => {
export const PlaygroundMessage: React.FC<Props> = (props) => {
const [isBtnPressed, setIsBtnPressed] = React.useState(false)
const [editMode, setEditMode] = React.useState(false)
@@ -258,6 +262,18 @@ export const PlaygroundMessage = (props: Props) => {
)}
{props.isBot && (
<>
{/*数联网搜索*/}
{props.iodSearch && (
<Tooltip title="数联网信息">
<button
onClick={() => props.setCurrentMessageId(props.id)}
aria-label="数联网信息"
className="flex items-center justify-center w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500">
<PiNetwork className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
</button>
</Tooltip>
)}
{!props.hideCopy && (
<Tooltip title={t("copyToClipboard")}>
<button

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useState } from "react"
import React, { useMemo } from "react"
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
import { Card, Drawer, Skeleton } from "antd"
import { Card, Skeleton } from "antd"
import { IodRegistryEntry } from "@/types/iod.ts"
import { useIodPlaygroundContext } from "@/components/Option/Playground/PlaygroundIod.tsx"
@@ -33,7 +33,11 @@ type HeaderProps = {
showButton?: boolean
onClick?: () => void
}
const Header: React.FC<HeaderProps> = ({ title, showButton = true, onClick }) => (
const Header: React.FC<HeaderProps> = ({
title,
showButton = true,
onClick
}) => (
<DataNavigation
Header={
<div className="flex items-center text-[#4ab01a] gap-1">
@@ -97,36 +101,28 @@ const Main: React.FC<MainProps> = ({ data, loading, truncate = true }) => (
</div>
)
type Props = {
className?: string
}
export const PlaygroundScene: React.FC<Props> = ({ className }) => {
const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption()
const { iodLoading } = useMessageOption()
const { setShowPlayground, setDetailHeader, setDetailMain } =
useIodPlaygroundContext()
const {
setShowPlayground,
setDetailHeader,
setDetailMain,
currentIodMessage
} = useIodPlaygroundContext()
const data = useMemo<IodRegistryEntry[]>(() => {
// 确保loading状态时数据大于3
if (iodLoading) {
return defaultData
}
if (messages.length && iodSearch) {
const currentMessage = messages?.find(
(message) => message.id === currentMessageId
)
return currentMessage?.iodSources.scenario.data ?? []
}
return defaultData
}, [currentMessageId, messages, iodLoading])
return currentIodMessage
? currentIodMessage.scenario?.data ?? []
: defaultData
}, [currentIodMessage])
const title = useMemo(() => {
return messages.length > 0 ? "推荐场景" : "热点场景"
}, [messages])
return currentIodMessage ? "推荐场景" : "热点场景"
}, [currentIodMessage])
const showMore = () => {
setShowPlayground(false)
@@ -137,19 +133,17 @@ export const PlaygroundScene: React.FC<Props> = ({ className }) => {
onClick={() => setShowPlayground(false)}
/>
)
setDetailMain(<Main loading={iodLoading} data={data} truncate={false} />)
setDetailMain(<Main loading={iodLoading && Boolean(currentIodMessage)} data={data} truncate={false} />)
}
return (
<Card
className={`${className}`}
hoverable>
<Card className={`${className}`} hoverable>
<div className="h-full flex flex-col gap-2 relative">
{/* 数据导航 */}
<Header title={title} onClick={showMore} />
{/* 数据列表 */}
<Main loading={iodLoading} data={data.slice(0, 3)} />
<Main loading={iodLoading && Boolean(currentIodMessage)} data={data.slice(0, 3)} />
</div>
</Card>
)

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from "react"
import React, { useMemo } from "react"
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
import { Card, Skeleton } from "antd"
import { IodRegistryEntry } from "@/types/iod.ts"
@@ -17,11 +17,10 @@ const defaultData: IodRegistryEntry[] = [
doId: "91320507MAEKWL5Y2L"
},
{
name: "伊利诺伊大学香槟分校UIUC",
description: "创建于1867年坐落于伊利诺伊州双子城厄巴纳香槟市",
doId: "bdware.org/uiuc",
},
doId: "bdware.org/uiuc"
}
]
type HeaderProps = {
@@ -113,31 +112,24 @@ type Props = {
className?: string
}
export const PlaygroundTeam: React.FC<Props> = ({ className }) => {
const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption()
const { iodLoading } = useMessageOption()
const { setShowPlayground, setDetailHeader, setDetailMain } =
useIodPlaygroundContext()
const {
setShowPlayground,
setDetailHeader,
setDetailMain,
currentIodMessage
} = useIodPlaygroundContext()
const data = useMemo<IodRegistryEntry[]>(() => {
// 确保loading状态时数据大于3
if (iodLoading) {
return defaultData
}
if (messages.length && iodSearch) {
const currentMessage = messages?.find(
(message) => message.id === currentMessageId
)
return currentMessage?.iodSources.organization.data ?? []
}
return defaultData
}, [currentMessageId, messages, iodLoading])
return currentIodMessage
? currentIodMessage.organization?.data ?? []
: defaultData
}, [currentIodMessage])
const title = useMemo(() => {
return messages.length > 0 ? "推荐团队" : "热点团队"
}, [messages])
return currentIodMessage ? "推荐团队" : "热点团队"
}, [currentIodMessage])
const showMore = () => {
setShowPlayground(false)
@@ -148,17 +140,18 @@ export const PlaygroundTeam: React.FC<Props> = ({ className }) => {
onClick={() => setShowPlayground(false)}
/>
)
setDetailMain(<Main loading={iodLoading} data={data} truncate={false} flat={false} />)
setDetailMain(
<Main loading={iodLoading && Boolean(currentIodMessage)} data={data} truncate={false} flat={false} />
)
}
return (
<Card className={`${className}`} hoverable>
<div className="h-full flex flex-col gap-2 relative">
{/* 数据导航 */}
<Header title={title} onClick={showMore} />
{/* 数据列表 */}
<Main loading={iodLoading} data={data.slice(0, 3)} />
<Main loading={iodLoading && Boolean(currentIodMessage)} data={data.slice(0, 3)} />
</div>
</Card>
)

View File

@@ -1,15 +1,13 @@
import { Form, Image, Input, Modal, Tooltip, message } from "antd"
import { Share } from "lucide-react"
import { useState } from "react"
import type { Message } from "~/store/option"
import Markdown from "./Markdown"
import { Form, Image, Input, message, Modal } from "antd"
import React from "react"
import Markdown from "./Markdown"
import { useMutation } from "@tanstack/react-query"
import { getPageShareUrl } from "~/services/ollama"
import { cleanUrl } from "~/libs/clean-url"
import { getTitleById, getUserId, saveWebshare } from "@/db"
import { useTranslation } from "react-i18next"
import fetcher from "@/libs/fetcher"
import { Message } from "@/types/message.ts"
type Props = {
messages: Message[]

View File

@@ -11,7 +11,8 @@ export const PlaygroundChat = () => {
regenerateLastMessage,
isSearchingInternet,
editMessage,
ttsEnabled
ttsEnabled,
setCurrentMessageId,
} = useMessageOption()
const [isSourceOpen, setIsSourceOpen] = React.useState(false)
const [source, setSource] = React.useState<any>(null)
@@ -27,6 +28,7 @@ export const PlaygroundChat = () => {
{messages.map((message, index) => (
<PlaygroundMessage
key={index}
id={message.id}
isBot={message.isBot}
message={message.message}
name={message.name}
@@ -49,6 +51,8 @@ export const PlaygroundChat = () => {
generationInfo={message?.generationInfo}
isStreaming={streaming}
reasoningTimeTaken={message?.reasoning_time_taken}
setCurrentMessageId={setCurrentMessageId}
iodSearch={message.iodSearch}
/>
))}
</div>

View File

@@ -218,7 +218,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
{
key: 0,
label: (
<p
<div
onClick={() => {
setIodSearch(true)
}}>
@@ -227,13 +227,13 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
<PiNetwork className="h-5 w-5" />
</p>
<p className="text-[#00000080]"></p>
</p>
</div>
)
},
{
key: 1,
label: (
<p
<div
onClick={() => {
setIodSearch(false)
}}>
@@ -242,7 +242,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
<PiNetwork className="h-5 w-5" />
</p>
<p className="text-[#00000080]"></p>
</p>
</div>
)
}
]
@@ -397,7 +397,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
className={`!px-[5px] flex items-center justify-center dark:text-gray-300 ${
chatMode === "rag" ? "hidden" : "block"
}`}>
<ImageIcon stroke-width={1} className="h-5 w-5" />
<ImageIcon strokeWidth={1} className="h-5 w-5" />
</Button>
</Tooltip>
)}
@@ -420,12 +420,12 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
}}
className={`flex items-center justify-center dark:text-gray-300 !px-[5px]`}>
{!isListening ? (
<MicIcon stroke-width={1} className="h-5 w-5" />
<MicIcon strokeWidth={1} className="h-5 w-5" />
) : (
<div className="relative">
<span className="animate-ping absolute inline-flex h-3 w-3 rounded-full bg-red-400 opacity-75"></span>
<MicIcon
stroke-width={1}
strokeWidth={1}
className="h-5 w-5"
/>
</div>

View File

@@ -9,7 +9,7 @@ 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"
import { AllIodRegistryEntry } from "@/types/iod.ts"
// 定义 Context 类型
interface IodPlaygroundContextType {
@@ -19,7 +19,7 @@ interface IodPlaygroundContextType {
setDetailHeader: React.Dispatch<React.SetStateAction<React.ReactNode>>
detailMain: React.ReactNode
setDetailMain: React.Dispatch<React.SetStateAction<React.ReactNode>>
currentIodMessage: Message | null
currentIodMessage?: AllIodRegistryEntry
}
// 创建 Context
@@ -41,36 +41,34 @@ export const useIodPlaygroundContext = () => {
const PlaygroundIodProvider: React.FC<{ children: React.ReactNode }> = ({
children
}) => {
const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption()
const { messages, iodLoading, currentMessageId } = useMessageOption()
const [showPlayground, setShowPlayground] = useState<boolean>(true)
const [detailHeader, setDetailHeader] = useState(<></>)
const [detailMain, setDetailMain] = useState(<></>)
const currentIodMessage = useMemo<Message | null>(() => {
if (iodLoading) {
return null
const currentIodMessage = useMemo<AllIodRegistryEntry | undefined>(() => {
console.log('messages', messages)
console.log("currentMessageId", currentMessageId)
console.log("iodLoading", iodLoading)
// loading 返回 undefined是为了避免数据不足三个的情况
if (iodLoading || !messages.length) {
return undefined
}
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)
// 如果不存在currentMessageId默认返回最后一个message
if (!currentMessageId) {
const lastMessage = messages.at(-1)
// 如果最后一次message没有开启数联网搜索则返回undefined
return lastMessage?.iodSearch ? lastMessage.iodSources : undefined
}
return null
}, [currentMessageId, messages, iodLoading, iodSearch])
const currentMessage = messages?.find(
(message) => message.id === currentMessageId
)
console.log("currentMessage", currentMessage)
return currentMessage?.iodSearch ? currentMessage.iodSources : undefined
}, [currentMessageId, messages, iodLoading])
return (
<PlaygroundContext.Provider
@@ -154,7 +152,6 @@ const PlaygroundContent = () => {
)
}
export const PlaygroundIod = () => {
return (
<div className="w-[36%] h-full pt-16 pr-5 pb-0">

View File

@@ -1,25 +0,0 @@
import { PencilIcon } from "lucide-react"
import { useMessage } from "../../../hooks/useMessage"
import { useTranslation } from 'react-i18next';
export const PlaygroundNewChat = () => {
const { setHistory, setMessages, setHistoryId } = useMessage()
const { t } = useTranslation('optionChat')
const handleClick = () => {
setHistoryId(null)
setMessages([])
setHistory([])
}
return (
<button
onClick={handleClick}
className="flex w-full border bg-transparent hover:bg-gray-200 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 focus:ring-offset-gray-100 rounded-md p-2 dark:border-gray-800">
<PencilIcon className="mx-3 h-5 w-5" aria-hidden="true" />
<span className="inline-flex font-semibol text-white text-sm">
{t('newChat')}
</span>
</button>
)
}

View File

@@ -1,41 +1,20 @@
import { useTranslation } from "react-i18next"
import TextArea from "antd/es/input/TextArea"
import { useEffect, useState } from "react"
import { IodDb } from "@/db/iod.ts"
import { useState } from "react"
export const IodApp = () => {
const { t } = useTranslation("settings")
const db = IodDb.getInstance()
const [connectVal, setConnectVal] = useState<string>('')
const [connection, setConnection] = useState(JSON.stringify(db.getIodConnection(), null, 2))
const setConnectValWrap = (val: string) => {
localStorage.setItem("iod-connect", val)
setConnectVal(val)
db.insertIodConnection(JSON.parse(val))
setConnection(val)
}
useEffect(() => {
const val = localStorage.getItem("iod-connect")
const defaultVal = {
gatewayUrl: "tcp://reg01.public.internetofdata.cn:21037",
registry: "data/Registry",
localRepository: "data/Repository",
doBrowser: "http://021.node.internetapi.cn:21030/SCIDE/SCManager"
}
if (!val) {
localStorage.setItem(
"iod-connect",
JSON.stringify(defaultVal)
)
setConnectVal(JSON.stringify(defaultVal, null, 2))
return
}
try {
const val = localStorage.getItem("iod-connect")
setConnectVal(JSON.stringify(JSON.parse(val), null, 2))
} catch (e) {
setConnectVal(JSON.stringify(defaultVal, null, 2))
}
}, [])
return (
<dl className="flex flex-col space-y-6 text-sm">
@@ -47,7 +26,7 @@ export const IodApp = () => {
</div>
<div className="flex flex-col gap-3">
<span className="text-gray-700 dark:text-neutral-50"></span>
<TextArea rows={6} placeholder="请输入数联网连接配置" value={connectVal} onChange={(e) => setConnectValWrap(e.target.value)} />
<TextArea rows={6} placeholder="请输入数联网连接配置" value={connection} onChange={(e) => setConnectValWrap(e.target.value)} />
</div>
</dl>
)