-优化了 Data、Scene 和 Team组件的逻辑,使用 currentIodMessage 替代复杂的条件判断- 改进了 IodRelevant 组件的动画和数据处理方式 - 调整了 Message 组件以支持数联网搜索功能 - 重构了 PlaygroundIodProvider,简化了上下文类型和数据处理 - 更新了数据库相关操作,使用新的 HistoryMessage 类型 - 新增了 IodDb 类来管理数联网连接配置
151 lines
5.1 KiB
TypeScript
151 lines
5.1 KiB
TypeScript
import React, { useMemo } from "react"
|
||
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
|
||
import { Card, Skeleton } from "antd"
|
||
import { IodRegistryEntry } from "@/types/iod.ts"
|
||
import { useIodPlaygroundContext } from "@/components/Option/Playground/PlaygroundIod.tsx"
|
||
|
||
const defaultData: IodRegistryEntry[] = [
|
||
{
|
||
name: "绿色化工工艺项目",
|
||
description:
|
||
"基于生物基原料,采用repeal2.0可降解材料技术,开发新型环保材料。",
|
||
doId: "CSTR:13552.11.01.61.2021.742"
|
||
},
|
||
{
|
||
name: "智能农业解决方案",
|
||
description: "利用物联网技术,实现精准农业管理,提高农作物产量。",
|
||
doId: "CSTR:14542.11.01.61.2031.528"
|
||
},
|
||
{
|
||
name: "新能源汽车电池技术",
|
||
description: "研发高能量密度、长寿命的新型电池材料,推动电动汽车发展。",
|
||
doId: "CSTR:147842.11.04.91.2031.680"
|
||
},
|
||
{
|
||
name: "碳捕集与封存技术",
|
||
description: "开发高效的碳捕集技术,减少工业排放,助力碳中和目标。",
|
||
doId: "CSTR:14242.19.11.61.2131.428"
|
||
}
|
||
]
|
||
|
||
type HeaderProps = {
|
||
title: string
|
||
showButton?: boolean
|
||
onClick?: () => void
|
||
}
|
||
const Header: React.FC<HeaderProps> = ({
|
||
title,
|
||
showButton = true,
|
||
onClick
|
||
}) => (
|
||
<DataNavigation
|
||
Header={
|
||
<div className="flex items-center text-[#4ab01a] gap-1">
|
||
<svg
|
||
className="icon"
|
||
viewBox="0 0 1025 1024"
|
||
version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
p-id="6235"
|
||
width="18"
|
||
height="18">
|
||
<path
|
||
d="M980.34571 1.143792c-4.850903 0-9.824354 0.888481-14.797806 2.930966L229.773215 299.724504H20.428686c-11.233669 0-20.424853 9.446494-20.424853 21.180572V702.584302c0 11.74429 9.191184 21.180572 20.424853 21.180573h129.820365c-4.728353 14.808018-7.271248 30.51473-7.271248 46.46654 0 84.119757 68.678568 152.543014 153.176184 152.543014 70.721053 0 130.330986-47.998404 147.93721-112.847312l521.569043 209.59984c4.983664 1.919936 9.957116 2.930966 14.808019 2.930967 21.568645 0 40.839493-18.127057 40.839493-42.371358V43.525362C1021.195415 19.270849 1002.047116 1.143792 980.34571 1.143792zM296.153987 831.250663c-33.833769 0-61.274559-27.308028-61.274558-61.009035 0-14.297397 4.983664-27.951411 14.042086-38.807221l108.374269 43.525362c-2.553107 31.403211-28.972654 56.290895-61.141797 56.290894z m633.12959 74.550713L263.984844 638.501326l-16.462431-6.638077H91.915671V391.626129h155.606742l16.462431-6.638077 665.298733-267.30005v788.113374z m0 0"
|
||
fill="#4ab01a"
|
||
p-id="6236"></path>
|
||
</svg>
|
||
{title}
|
||
</div>
|
||
}
|
||
showButton={showButton}
|
||
onClick={onClick}
|
||
/>
|
||
)
|
||
|
||
type MainProps = {
|
||
loading: boolean
|
||
data: IodRegistryEntry[]
|
||
truncate?: boolean
|
||
}
|
||
const Main: React.FC<MainProps> = ({ data, loading, truncate = true }) => (
|
||
<div className="space-y-1.5 flex-1 overflow-y-auto">
|
||
{data.map((item, index) => {
|
||
return (
|
||
<Card
|
||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]"
|
||
key={item.doId}>
|
||
{loading ? (
|
||
<Skeleton title={false} active />
|
||
) : (
|
||
<div className="flex flex-col gap-0.5">
|
||
<h3
|
||
className={`text-base font-medium mb-1 text-[#222222] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||
title={item.name}>
|
||
{item.name}
|
||
</h3>
|
||
<p
|
||
className={`text-sm text-[#383838] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||
title={item.doId}>
|
||
数字对象标识:{item.doId}
|
||
</p>
|
||
<p
|
||
className={`text-[#828282] text-xs break-all ${truncate ? "truncate" : ""}`}
|
||
title={item.description}>
|
||
{item.description}
|
||
</p>
|
||
</div>
|
||
)}
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
)
|
||
|
||
type Props = {
|
||
className?: string
|
||
}
|
||
export const PlaygroundScene: React.FC<Props> = ({ className }) => {
|
||
const { iodLoading } = useMessageOption()
|
||
|
||
const {
|
||
setShowPlayground,
|
||
setDetailHeader,
|
||
setDetailMain,
|
||
currentIodMessage
|
||
} = useIodPlaygroundContext()
|
||
|
||
const data = useMemo<IodRegistryEntry[]>(() => {
|
||
return currentIodMessage
|
||
? currentIodMessage.scenario?.data ?? []
|
||
: defaultData
|
||
}, [currentIodMessage])
|
||
|
||
const title = useMemo(() => {
|
||
return currentIodMessage ? "推荐场景" : "热点场景"
|
||
}, [currentIodMessage])
|
||
|
||
const showMore = () => {
|
||
setShowPlayground(false)
|
||
setDetailHeader(
|
||
<Header
|
||
title={title}
|
||
showButton={false}
|
||
onClick={() => setShowPlayground(false)}
|
||
/>
|
||
)
|
||
setDetailMain(<Main loading={iodLoading && Boolean(currentIodMessage)} data={data} truncate={false} />)
|
||
}
|
||
|
||
return (
|
||
<Card className={`${className}`} hoverable>
|
||
<div className="h-full flex flex-col gap-2 relative">
|
||
{/* 数据导航 */}
|
||
<Header title={title} onClick={showMore} />
|
||
|
||
{/* 数据列表 */}
|
||
<Main loading={iodLoading && Boolean(currentIodMessage)} data={data.slice(0, 3)} />
|
||
</div>
|
||
</Card>
|
||
)
|
||
}
|