feat(iod): 重构数联网搜索功能
- 新增数联网设置页面 - 优化数联网搜索结果展示 - 添加数据集、科创场景和科技企业等不同类型的搜索结果 - 重构搜索结果卡片组件,支持加载状态和不同展示模式 - 更新数联网搜索相关的国际化文案
This commit is contained in:
@@ -11,6 +11,11 @@ export const PageAssistProvider = ({
|
||||
const [controller, setController] = React.useState<AbortController | null>(
|
||||
null
|
||||
)
|
||||
|
||||
const [iodLoading, setIodLoading] = React.useState<boolean>(false)
|
||||
const [currentMessageId, setCurrentMessageId] = React.useState<string>('')
|
||||
|
||||
|
||||
const [embeddingController, setEmbeddingController] =
|
||||
React.useState<AbortController | null>(null)
|
||||
|
||||
@@ -20,6 +25,12 @@ export const PageAssistProvider = ({
|
||||
messages,
|
||||
setMessages,
|
||||
|
||||
iodLoading,
|
||||
setIodLoading,
|
||||
|
||||
currentMessageId,
|
||||
setCurrentMessageId,
|
||||
|
||||
controller,
|
||||
setController,
|
||||
|
||||
|
||||
@@ -1,57 +1,99 @@
|
||||
import React from "react"
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
|
||||
import { Card, Drawer, List } from "antd"
|
||||
import { useCallback, useState } from "react"
|
||||
import { Card, Drawer, Skeleton } from "antd"
|
||||
import { useMessageOption } from "@/hooks/useMessageOption.tsx"
|
||||
import { IodRegistryEntry } from "@/types/iod.ts"
|
||||
|
||||
export const PlaygroundData = () => {
|
||||
// 模拟数据
|
||||
const data: {
|
||||
title: string
|
||||
description: string
|
||||
time: string
|
||||
metadata?: string
|
||||
}[] = [
|
||||
{
|
||||
title: "2019-2024年黄海清浅海域中河湖代数生物物种数据集",
|
||||
description:
|
||||
"数字对象标识: CSTR:13452.11.01.11.2021.242 国家海洋科学数据中心",
|
||||
time: "包括2019年8月,2021年8月和2024年6月",
|
||||
metadata: "热 榜 第2"
|
||||
},
|
||||
{
|
||||
title: "祁连山老虎沟大本营10米气象每日值数据集(V1.0)(2018-2023)",
|
||||
description:
|
||||
"中国科学院西北生态环境资源研究院,2021年8月3日发布,2021年8月3日20:48更新",
|
||||
time: "包括2019年8月,2021年8月和2024年6月",
|
||||
metadata: "热 榜 第2"
|
||||
},
|
||||
{
|
||||
title: "李嘉图为研究老虎沟大本营2014-2018年...",
|
||||
description:
|
||||
"中国科学院西北生态环境资源研究院,2021年8月3日发布,2021年8月3日20:48更新",
|
||||
time: "包括2019年8月,2021年8月和2024年6月",
|
||||
metadata: "热 榜 第2"
|
||||
},
|
||||
{
|
||||
title: "青海玉树B1区俄日矿勘探数据2017-2023",
|
||||
description:
|
||||
"数字中国集团,CSTR:3260.11.1528414774204895456,DT2023年地质勘探补充调查",
|
||||
time: "包括2019年8月,2021年8月和2024年6月",
|
||||
metadata: "热 榜 第2"
|
||||
}
|
||||
]
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
data.push({
|
||||
title: "中国资源环境网",
|
||||
description: "中国资源环境网,2021年8月3日发布,2021年8月3日20:48更新",
|
||||
time: "包括2019年8月,2021年8月和2024年6月"
|
||||
})
|
||||
const defaultData: IodRegistryEntry[] = [
|
||||
{
|
||||
name: "2019-2024年黄海清浅海域中河湖代数生物物种数据集",
|
||||
doId: "CSTR:13452.11.01.11.2021.242",
|
||||
description:
|
||||
"数字对象标识: CSTR:13452.11.01.11.2021.242 国家海洋科学数据中心"
|
||||
},
|
||||
{
|
||||
name: "祁连山老虎沟大本营10米气象每日值数据集(V1.0)(2018-2023)",
|
||||
doId: "CSTR:13452.11.01.11.2021.343",
|
||||
description: "黄海清浅海域中河湖代数生物物种数据集"
|
||||
},
|
||||
{
|
||||
name: "李嘉图为研究老虎沟大本营2014-2018年",
|
||||
doId: "CSTR:3260.11.1528414789920489545",
|
||||
description:
|
||||
"中国科学院西北生态环境资源研究院,2021年8月3日发布,2021年8月3日20:48更新"
|
||||
},
|
||||
{
|
||||
name: "青海玉树B1区俄日矿勘探数据2017-2023",
|
||||
doId: "CSTR:3260.11.152841477420489545",
|
||||
description:
|
||||
"数字中国集团,CSTR:3260.11.1528414774204895456,DT2023年地质勘探补充调查"
|
||||
}
|
||||
]
|
||||
|
||||
type ShowCardProps = {
|
||||
loading: boolean
|
||||
record: IodRegistryEntry
|
||||
truncate?: boolean
|
||||
}
|
||||
|
||||
const ShowCard: React.FC<ShowCardProps> = ({
|
||||
loading,
|
||||
record,
|
||||
truncate = true
|
||||
}) => (
|
||||
<Card className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
{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={record.name}>
|
||||
{record.name}
|
||||
</h3>
|
||||
<p
|
||||
className={`text-sm text-[#383838] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||||
title={record.doId}>
|
||||
数字对象标识:{record.doId}
|
||||
</p>
|
||||
<p
|
||||
className={`text-[#828282] text-xs break-all ${truncate ? "truncate" : ""}`}
|
||||
title={record.description}>
|
||||
{record.description}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
export const PlaygroundData = () => {
|
||||
const { messages, iodLoading, currentMessageId, iodSearch } = useMessageOption()
|
||||
|
||||
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])
|
||||
|
||||
const title = useMemo(() => {
|
||||
return messages.length > 0 ? "推荐数据" : "热点数据"
|
||||
}, [messages])
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const showDrawer = () => {
|
||||
if (iodLoading) {
|
||||
return
|
||||
}
|
||||
setOpen(true)
|
||||
}
|
||||
|
||||
@@ -67,7 +109,7 @@ export const PlaygroundData = () => {
|
||||
{/* 数据导航 */}
|
||||
<DataNavigation
|
||||
Header={
|
||||
<div className="flex items-center gap-0.5 text-[#3480e3]">
|
||||
<div className="flex items-center gap-0.5 text-[#3581e3]">
|
||||
<svg
|
||||
className="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
@@ -79,9 +121,9 @@ export const PlaygroundData = () => {
|
||||
<path
|
||||
d="M877.714286 54.857143H754.285714V9.142857c0-5.028571-4.114286-9.142857-9.142857-9.142857h-64c-5.028571 0-9.142857 4.114286-9.142857 9.142857v45.714286H498.285714V9.142857c0-5.028571-4.114286-9.142857-9.142857-9.142857h-64c-5.028571 0-9.142857 4.114286-9.142857 9.142857v45.714286H292.571429c-20.228571 0-36.571429 16.342857-36.571429 36.571428v137.142858h-109.714286c-20.228571 0-36.571429 16.342857-36.571428 36.571428v722.285714c0 20.228571 16.342857 36.571429 36.571428 36.571429h585.142857c20.228571 0 36.571429-16.342857 36.571429-36.571429v-109.714285h109.714286c20.228571 0 36.571429-16.342857 36.571428-36.571429V91.428571c0-20.228571-16.342857-36.571429-36.571428-36.571428zM685.714286 941.714286H192V310.857143h249.142857v198.857143c0 25.257143 20.457143 45.714286 45.714286 45.714285h198.857143v386.285715z m0-459.428572H514.285714V310.857143h0.228572L685.714286 482.057143v0.228571z m146.285714 313.142857h-64V448L548.571429 228.571429H338.285714v-91.428572h77.714286v36.571429c0 5.028571 4.114286 9.142857 9.142857 9.142857h64c5.028571 0 9.142857-4.114286 9.142857-9.142857v-36.571429h173.714286v36.571429c0 5.028571 4.114286 9.142857 9.142857 9.142857h64c5.028571 0 9.142857-4.114286 9.142857-9.142857v-36.571429h77.714286v658.285714z"
|
||||
p-id="3573"
|
||||
fill="#3480e3"></path>
|
||||
fill="#3581e3"></path>
|
||||
</svg>
|
||||
相关数据
|
||||
{title}
|
||||
</div>
|
||||
}
|
||||
onClick={showDrawer}
|
||||
@@ -89,59 +131,23 @@ export const PlaygroundData = () => {
|
||||
|
||||
{/* 数据列表 */}
|
||||
<div className="space-y-1.5 flex-1 overflow-y-auto">
|
||||
{data.slice(0, 3).map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="text-base font-medium mb-1 text-[#222222] line-clamp-2">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm text-[#383838] line-clamp-2">
|
||||
{item.description}
|
||||
</p>
|
||||
<p className="text-[#828282] text-xs truncate">{item.time}</p>
|
||||
{item.metadata && (
|
||||
<div>
|
||||
<span className="inline-block text-[#D90000] bg-[#eb1c1c30] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
{item.metadata}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
{data.slice(0, 3).map((item, index) => {
|
||||
return (
|
||||
<ShowCard key={item.doId} loading={iodLoading} record={item} />
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 抽屉 */}
|
||||
<Drawer
|
||||
title="相关数据"
|
||||
title={title}
|
||||
closable={{ "aria-label": "Close Button" }}
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
width="33.33%">
|
||||
<div className="grid grid-cols-1 gap-3 overflow-y-auto">
|
||||
{data.slice(0, 3).map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
hoverable
|
||||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="text-base font-medium mb-1 text-[#222222]">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm text-[#383838]">{item.description}</p>
|
||||
<p className="text-[#828282] text-xs">{item.time}</p>
|
||||
{item.metadata && (
|
||||
<div>
|
||||
<span className="inline-block text-[#D90000] bg-[#eb1c1c30] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
{item.metadata}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
{data.map((item, index) => (
|
||||
<ShowCard key={item.doId} loading={iodLoading} record={item} truncate={false} />
|
||||
))}
|
||||
</div>
|
||||
</Drawer>
|
||||
|
||||
@@ -67,7 +67,7 @@ export const PlaygroundHistory = () => {
|
||||
return [
|
||||
{
|
||||
key: "qaPrompt",
|
||||
label: "热门搜索",
|
||||
label: "热点问题",
|
||||
type: "group" as const,
|
||||
children: qaPrompt.map((item) => {
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from "react"
|
||||
import { Button, Card } from "antd"
|
||||
import React, { useMemo } from "react"
|
||||
import { Card } from "antd"
|
||||
|
||||
// 使用 CSS-in-JS 方式
|
||||
import styled, { keyframes } from 'styled-components'
|
||||
import styled, { keyframes } from "styled-components"
|
||||
|
||||
const rotate = keyframes`
|
||||
0% {
|
||||
@@ -25,20 +25,22 @@ const breathe = keyframes`
|
||||
}
|
||||
`
|
||||
|
||||
const CircleElement = styled.div<{ delay: number }>`
|
||||
const CircleElement = styled.div<{ delay: number; playing: boolean }>`
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
height: 160px;
|
||||
background: #3b82f6; // blue-500
|
||||
background: #3b82f6; // blue-500
|
||||
opacity: 0.2;
|
||||
border-radius: 50%;
|
||||
top: 55%;
|
||||
left: 50%;
|
||||
animation: ${rotate} 6s linear infinite, ${breathe} 2s infinite alternate;
|
||||
animation-delay: ${props => props.delay}s;
|
||||
animation:
|
||||
${rotate} 6s linear infinite,
|
||||
${breathe} 2s infinite alternate;
|
||||
animation-delay: ${(props) => props.delay}s;
|
||||
animation-play-state: ${(props) => (props.playing ? "running" : "paused")};
|
||||
`
|
||||
|
||||
|
||||
const SuccessIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
@@ -64,13 +66,13 @@ const LoadingIcon = () => {
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="8408"
|
||||
p-id="29588"
|
||||
width="18"
|
||||
height="18">
|
||||
<path
|
||||
d="M512 128C299.936 128 128 296.672 128 504.736c0 130.784 67.904 245.984 170.976 313.536l35.52-52.256C248.576 709.696 192 613.696 192 504.736c0-173.376 143.264-313.92 320-313.92s320 140.544 320 313.92c0 98.112-45.856 185.696-117.696 243.296l-73.792-72.416V864h192l-72.768-71.36C843.072 723.52 896 620.16 896 504.704 896 296.672 724.064 128 512 128z"
|
||||
fill="#52c41a"
|
||||
p-id="8409"></path>
|
||||
d="M483.712 888.064a52.437333 52.437333 0 1 1 52.48 52.352 52.394667 52.394667 0 0 1-52.48-52.352z m-235.434667-53.76a65.578667 65.578667 0 1 1 46.421334 19.242667 65.962667 65.962667 0 0 1-46.378667-19.242667z m499.584-16.597333a41.984 41.984 0 0 1 59.264-59.434667 42.282667 42.282667 0 0 1 0 59.434667 41.941333 41.941333 0 0 1-59.264 0zM112.853333 546.602667a81.92 81.92 0 1 1 81.92 81.92 81.834667 81.834667 0 0 1-81.92-81.877334z m731.008 0a33.536 33.536 0 1 1 33.493334 33.578666 33.578667 33.578667 0 0 1-33.450667-33.536zM222.208 377.6a102.4 102.4 0 1 1 72.533333 29.866667 102.869333 102.869333 0 0 1-72.533333-29.824z m536.32-53.504a26.666667 26.666667 0 1 1 18.816 7.936 26.368 26.368 0 0 1-18.773333-7.893333zM414.378667 205.184a121.642667 121.642667 0 1 1 121.813333 121.6A121.728 121.728 0 0 1 414.378667 205.226667z"
|
||||
p-id="29589"
|
||||
fill="#4284f6"></path>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -94,60 +96,110 @@ const SearchIcon = () => {
|
||||
}
|
||||
|
||||
export const PlaygroundIodRelevant: React.FC = () => {
|
||||
const data = [
|
||||
{
|
||||
title: <p>已在<span className="text-[#9d0000]">29个科学数据中心</span>的<span className="text-[#9d0000]">50万个科学数据集</span>中进行搜索</p>,
|
||||
description: <p>已发现<span className="text-green-700"> 4个 </span>数据集</p>,
|
||||
status: "success"
|
||||
},
|
||||
{
|
||||
title: <p>已在<span className="text-[#9d0000]">100万篇论文</span>、<span className="text-[#9d0000]">2800个科创场景</span>中进行搜索</p>,
|
||||
description: "已发现4个数据集",
|
||||
status: "success"
|
||||
},
|
||||
{
|
||||
title: <p>正在<span className="text-[#9d0000]">1000位智库专家</span>、<span className="text-[#9d0000]">12万个创新机构</span>中进行搜索</p>,
|
||||
status: "loading"
|
||||
}
|
||||
]
|
||||
const { messages, iodLoading, currentMessageId, iodSearch } =
|
||||
useMessageOption()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
data.push({
|
||||
title: <p>正在<span className="text-[#9d0000]">1000位智库专家</span>、<span className="text-[#9d0000]">12万个创新机构</span>中进行搜索{i}</p>,
|
||||
description: "已发现4个数据集",
|
||||
status: "success"
|
||||
})
|
||||
}
|
||||
const showDescription = useMemo(() => {
|
||||
return iodSearch && messages.length > 0 && !iodLoading
|
||||
}, [iodSearch, messages, iodLoading])
|
||||
|
||||
const data = useMemo(() => {
|
||||
const currentMessage = messages?.find(
|
||||
(message) => message.id === currentMessageId
|
||||
)
|
||||
return [
|
||||
{
|
||||
title: (
|
||||
<p className="font-extrabold">
|
||||
已连接<span className="text-[#f00000]"> 11家 </span>
|
||||
国家科学数据中心的
|
||||
<span className="text-[#f00000]"> 500000+个 </span>科学数据集中
|
||||
</p>
|
||||
),
|
||||
description: showDescription ? (
|
||||
<p>
|
||||
已发现
|
||||
<span className="text-green-700">
|
||||
{" "}
|
||||
{currentMessage?.iodSources.data.total}个{" "}
|
||||
</span>
|
||||
数据集
|
||||
</p>
|
||||
) : (
|
||||
""
|
||||
)
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<p className="font-extrabold">
|
||||
已连接<span className="text-[#f00000]"> 1000000+篇 </span>论文和
|
||||
<span className="text-[#f00000]"> 50000+个 </span>科创场景
|
||||
</p>
|
||||
),
|
||||
description: showDescription ? (
|
||||
<p>
|
||||
已发现
|
||||
<span className="text-green-700">
|
||||
{" "}
|
||||
{currentMessage?.iodSources.scenario.total}个{" "}
|
||||
</span>
|
||||
科创场景
|
||||
</p>
|
||||
) : (
|
||||
""
|
||||
)
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<p className="font-extrabold">
|
||||
已连接<span className="text-[#f00000]"> 1000+位 </span>智库专家
|
||||
<span className="text-[#f00000]"> 763家 </span>高校和科研机构和
|
||||
<span className="text-[#f00000]"> 21000+家 </span>科技企业
|
||||
</p>
|
||||
),
|
||||
description: showDescription ? (
|
||||
<p>
|
||||
已发现
|
||||
<span className="text-green-700">
|
||||
{" "}
|
||||
{currentMessage?.iodSources.organization.total}个{" "}
|
||||
</span>
|
||||
科技企业
|
||||
</p>
|
||||
) : (
|
||||
""
|
||||
)
|
||||
}
|
||||
]
|
||||
}, [messages, iodLoading])
|
||||
|
||||
return (
|
||||
<Card
|
||||
hoverable
|
||||
variant="outlined"
|
||||
className="flex flex-col h-full [&_.ant-card-body]:h-full [&_.ant-card-body]:!p-[20px] translate-y-[-2px] !bg-[#f0f9ff]"
|
||||
>
|
||||
className="flex flex-col h-full [&_.ant-card-body]:h-full [&_.ant-card-body]:!p-[20px] translate-y-[-2px] !bg-[#f0f9ff]">
|
||||
<div className="h-full flex flex-col relative">
|
||||
{/* 花瓣效果 */}
|
||||
<div className="absolute inset-0 pointer-events-none z-0 overflow-hidden">
|
||||
<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} />
|
||||
<CircleElement delay={1} />
|
||||
<CircleElement delay={2} />
|
||||
<CircleElement delay={0} playing={true} />
|
||||
<CircleElement delay={1} playing={true} />
|
||||
<CircleElement delay={2} playing={true} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Header */}
|
||||
<div className="p-3">
|
||||
<h2 className="text-xl font-semibold text-[#08307f] flex justify-between items-center">
|
||||
<div className='flex items-center gap-2'>
|
||||
<h2 className="text-xl font-semibold text-[#1a3c87] flex justify-center items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<SearchIcon />
|
||||
数联网搜索相关内容
|
||||
</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>
|
||||
{/*<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-[#08307f] mt-1 align-middle">
|
||||
<p className="text-sm text-[#1a3c87] mt-1 text-center">
|
||||
下面是在数联网上进行深度搜索的相关内容
|
||||
</p>
|
||||
</div>
|
||||
@@ -156,25 +208,30 @@ export const PlaygroundIodRelevant: React.FC = () => {
|
||||
<div className="space-y-2 flex-1 overflow-y-auto">
|
||||
{data.map((item, index) => (
|
||||
<Card
|
||||
className="[&>*:first-child]:!p-3 shadow-md"
|
||||
key={index}
|
||||
>
|
||||
<div className="flex items-start gap-2">
|
||||
<div className="w-5 h-5 mt-1 flex-shrink-0">
|
||||
{item.status === "success" ? (
|
||||
<SuccessIcon />
|
||||
) : (
|
||||
<LoadingIcon />
|
||||
)}
|
||||
className="[&_.ant-card-body]:!p-3 [&_.ant-card-body]:h-full shadow-md h-[88px]"
|
||||
key={index}>
|
||||
<div
|
||||
className={`flex flex-col gap-2 h-full items-start ${showDescription ? "justify-start" : "justify-center"}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className={`${showDescription ? "w-5 h-5" : "w-6 h-6"}`}>
|
||||
{iodSearch && iodLoading ? (
|
||||
<LoadingIcon />
|
||||
) : (
|
||||
<SuccessIcon />
|
||||
)}
|
||||
</div>
|
||||
<p
|
||||
className={`text-gray-700 ${showDescription ? "text-sm" : "text-lg"}`}>
|
||||
{item.title}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="text-sm text-gray-700">{item.title}</p>
|
||||
{item.description && (
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
{item.description && (
|
||||
<div className="flex-1">
|
||||
<p className="text-xs text-gray-500 mt-1 pl-7">
|
||||
{item.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
import Markdown from "../../Common/Markdown"
|
||||
import React from "react"
|
||||
import { Tag, Image, Tooltip, Collapse, Popover } from "antd"
|
||||
import { Collapse, Image, Popover, Tag, Tooltip } from "antd"
|
||||
import { WebSearch } from "./WebSearch"
|
||||
import {
|
||||
ArrowUpSquare,
|
||||
CheckIcon,
|
||||
ClipboardIcon,
|
||||
InfoIcon,
|
||||
MessageSquareShare,
|
||||
Pen,
|
||||
PlayIcon,
|
||||
RotateCcw,
|
||||
Square,
|
||||
Star,
|
||||
ThumbsUp,
|
||||
ThumbsDown,
|
||||
MessageSquareShare,
|
||||
ArrowUpSquare
|
||||
ThumbsUp
|
||||
} from "lucide-react"
|
||||
import { EditMessageForm } from "./EditMessageForm"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { MessageSource } from "./MessageSource"
|
||||
import { useTTS } from "@/hooks/useTTS"
|
||||
import { tagColors } from "@/utils/color"
|
||||
import { removeModelSuffix } from "@/db/models"
|
||||
import { GenerationInfo } from "./GenerationInfo"
|
||||
import { parseReasoning } from "@/libs/reasoning"
|
||||
import { humanizeMilliseconds } from "@/utils/humanize-milliseconds"
|
||||
import { AllIodRegistryEntry } from "@/types/iod.ts"
|
||||
|
||||
type Props = {
|
||||
message: string
|
||||
message_type?: string
|
||||
@@ -42,7 +43,7 @@ type Props = {
|
||||
webSearch?: {}
|
||||
isSearchingInternet?: boolean
|
||||
webSources?: any[]
|
||||
iodSources?: any[]
|
||||
iodSources?: AllIodRegistryEntry
|
||||
hideEditAndRegenerate?: boolean
|
||||
onSourceClick?: (source: any) => void
|
||||
isTTSEnabled?: boolean
|
||||
@@ -60,7 +61,8 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
return (
|
||||
<div className="group relative flex w-full flex-col items-end justify-center pb-2 md:px-4 text-gray-800 dark:text-gray-100">
|
||||
{/* <div className="text-base md:max-w-2xl lg:max-w-xl xl:max-w-3xl flex lg:px-0 m-auto w-full"> */}
|
||||
<div className={`flex flex-row gap-1 md:gap-1 my-2 m-auto w-full ${props.isBot ? "" : "flex-row-reverse"}`}>
|
||||
<div
|
||||
className={`flex flex-row gap-1 md:gap-1 my-2 m-auto w-full ${props.isBot ? "" : "flex-row-reverse"}`}>
|
||||
<div className="w-8 flex flex-col relative items-center justify-center bottom-[8px]">
|
||||
<div className="relative h-7 w-7 p-1 rounded-sm text-white flex items-center justify-center text-opacity-100r">
|
||||
{props.isBot ? (
|
||||
@@ -77,8 +79,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-[calc(100%-50px)] flex-col gap-2 lg:w-[calc(100%-115px)]">
|
||||
<span className="text-xs font-bold text-gray-800 dark:text-white">
|
||||
</span>
|
||||
<span className="text-xs font-bold text-gray-800 dark:text-white"></span>
|
||||
|
||||
{props.isBot &&
|
||||
props.isSearchingInternet &&
|
||||
@@ -101,6 +102,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
return (
|
||||
<Collapse
|
||||
key={i}
|
||||
defaultActiveKey={['reasoning']}
|
||||
className="border-none !mb-3"
|
||||
items={[
|
||||
{
|
||||
@@ -132,8 +134,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
) : (
|
||||
<p
|
||||
className={`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"
|
||||
props.message_type && "italic dark:text-gray-400"
|
||||
} flex flex-row-reverse`}>
|
||||
{props.message}
|
||||
{/*<span className="bg-[#0000000a] inline-block py-[9px] text-[#000000d9] rounded-xl px-4 font-light text-sm">{props.message}</span>*/}
|
||||
@@ -170,9 +171,10 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
<Collapse
|
||||
className="mt-6"
|
||||
ghost
|
||||
// defaultActiveKey={['webSources']}
|
||||
items={[
|
||||
{
|
||||
key: "1",
|
||||
key: "webSources",
|
||||
label: (
|
||||
<div className="italic text-gray-500 dark:text-gray-400">
|
||||
{t("webCitations")}
|
||||
@@ -194,13 +196,14 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
{props.isBot && props?.iodSources && props?.iodSources.length > 0 && (
|
||||
{props.isBot && props?.iodSources && Object.values(props?.iodSources).map(item => item.data).flat().length > 0 && (
|
||||
<Collapse
|
||||
className="mt-6"
|
||||
ghost
|
||||
// defaultActiveKey={['iod']}
|
||||
items={[
|
||||
{
|
||||
key: "1",
|
||||
key: "iod",
|
||||
label: (
|
||||
<div className="italic text-gray-500 dark:text-gray-400">
|
||||
{t("iodCitations")}
|
||||
@@ -208,7 +211,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
),
|
||||
children: (
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{props?.iodSources?.map((source, index) => (
|
||||
{Object.values(props?.iodSources).map(item => item.data).flat()?.map((source, index) => (
|
||||
<MessageSource
|
||||
onSourceClick={props.onSourceClick}
|
||||
key={index}
|
||||
@@ -315,7 +318,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{ (
|
||||
{
|
||||
<Tooltip title="收藏">
|
||||
<button
|
||||
aria-label="收藏"
|
||||
@@ -323,8 +326,8 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
<Star className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{ (
|
||||
}
|
||||
{
|
||||
<Tooltip title="发布语用">
|
||||
<button
|
||||
aria-label="发布语用"
|
||||
@@ -332,8 +335,8 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
<ArrowUpSquare className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{ (
|
||||
}
|
||||
{
|
||||
<Tooltip title="发布对话">
|
||||
<button
|
||||
aria-label="发布对话"
|
||||
@@ -341,8 +344,8 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
<MessageSquareShare className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{ (
|
||||
}
|
||||
{
|
||||
<Tooltip title="点赞">
|
||||
<button
|
||||
aria-label="点赞"
|
||||
@@ -350,8 +353,8 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
<ThumbsUp className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{ (
|
||||
}
|
||||
{
|
||||
<Tooltip title="点踩">
|
||||
<button
|
||||
aria-label="点踩"
|
||||
@@ -359,7 +362,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
<ThumbsDown className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
// add invisible div to prevent layout shift
|
||||
|
||||
@@ -1,44 +1,98 @@
|
||||
import React, { useState } from "react"
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
|
||||
import { Card, Drawer, List } from "antd"
|
||||
import { Card, Drawer, Skeleton } from "antd"
|
||||
import { IodRegistryEntry } from "@/types/iod.ts"
|
||||
|
||||
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 ShowCardProps = {
|
||||
loading: boolean
|
||||
record: IodRegistryEntry
|
||||
truncate?: boolean
|
||||
}
|
||||
|
||||
const ShowCard: React.FC<ShowCardProps> = ({
|
||||
loading,
|
||||
record,
|
||||
truncate = true
|
||||
}) => (
|
||||
<Card className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
{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={record.name}>
|
||||
{record.name}
|
||||
</h3>
|
||||
<p
|
||||
className={`text-sm text-[#383838] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||||
title={record.doId}>
|
||||
数字对象标识:{record.doId}
|
||||
</p>
|
||||
<p
|
||||
className={`text-[#828282] text-xs break-all ${truncate ? "truncate" : ""}`}
|
||||
title={record.description}>
|
||||
{record.description}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
|
||||
export const PlaygroundScene = () => {
|
||||
// 模拟数据
|
||||
const data = [
|
||||
{
|
||||
title: "绿色化工工艺项目",
|
||||
description:
|
||||
"基于生物基原料,采用repeal2.0可降解材料技术,开发新型环保材料。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
},
|
||||
{
|
||||
title: "智能农业解决方案",
|
||||
description: "利用物联网技术,实现精准农业管理,提高农作物产量。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
},
|
||||
{
|
||||
title: "新能源汽车电池技术",
|
||||
description: "研发高能量密度、长寿命的新型电池材料,推动电动汽车发展。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
},
|
||||
{
|
||||
title: "碳捕集与封存技术",
|
||||
description: "开发高效的碳捕集技术,减少工业排放,助力碳中和目标。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
}
|
||||
]
|
||||
const { messages, iodLoading, currentMessageId, iodSearch } =
|
||||
useMessageOption()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
data.push({
|
||||
title: "开发新型电池材料",
|
||||
description: "研发高能量密度、长寿命的新型电池材料,推动电动汽车发展。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
})
|
||||
}
|
||||
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])
|
||||
|
||||
const title = useMemo(() => {
|
||||
return messages.length > 0 ? "推荐场景" : "热点场景"
|
||||
}, [messages])
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const showDrawer = () => {
|
||||
if (iodLoading) {
|
||||
return
|
||||
}
|
||||
setOpen(true)
|
||||
}
|
||||
|
||||
@@ -54,7 +108,7 @@ export const PlaygroundScene = () => {
|
||||
{/* 数据导航 */}
|
||||
<DataNavigation
|
||||
Header={
|
||||
<div className="flex items-center text-[#52c41a] gap-1">
|
||||
<div className="flex items-center text-[#54c41d] gap-1">
|
||||
<svg
|
||||
className="icon"
|
||||
viewBox="0 0 1025 1024"
|
||||
@@ -65,76 +119,39 @@ export const PlaygroundScene = () => {
|
||||
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="#52c41a"
|
||||
fill="#54c41d"
|
||||
p-id="6236"></path>
|
||||
</svg>
|
||||
相关场景
|
||||
{title}
|
||||
</div>
|
||||
}
|
||||
onClick={showDrawer}
|
||||
/>
|
||||
|
||||
{/* 场景列表 */}
|
||||
{/* 数据列表 */}
|
||||
<div className="space-y-1.5 flex-1 overflow-y-auto">
|
||||
{data.slice(0, 3).map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="text-base font-medium mb-1 text-[#222222] line-clamp-2">
|
||||
{item.title}
|
||||
</h3>
|
||||
<span className="text-sm text-[#383838] line-clamp-2">
|
||||
{item.description}
|
||||
</span>
|
||||
<p className="text-[#828282] text-xs truncate">
|
||||
{item.demander}
|
||||
</p>
|
||||
<p className="flex items-center gap-1.5">
|
||||
<span className="inline-block text-[#003AD4] bg-[#003ad430] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
技术应用
|
||||
</span>
|
||||
<span className="inline-block text-[#00BF68] bg-[#00bf6830] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
制造业
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
{data.slice(0, 3).map((item, index) => {
|
||||
return (
|
||||
<ShowCard key={item.doId} loading={iodLoading} record={item} />
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 抽屉 */}
|
||||
<Drawer
|
||||
title="相关场景"
|
||||
title={title}
|
||||
closable={{ "aria-label": "Close Button" }}
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
width="33.33%">
|
||||
<div className="grid grid-cols-1 gap-3 overflow-y-auto">
|
||||
{data.slice(0, 3).map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
hoverable
|
||||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="text-base font-medium mb-1 text-[#222222]">
|
||||
{item.title}
|
||||
</h3>
|
||||
<span className="text-sm text-[#383838]">
|
||||
{item.description}
|
||||
</span>
|
||||
<p className="text-[#828282] text-xs">{item.demander}</p>
|
||||
<p className="flex items-center gap-1.5">
|
||||
<span className="inline-block text-[#003AD4] bg-[#003ad430] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
技术应用
|
||||
</span>
|
||||
<span className="inline-block text-[#00BF68] bg-[#00bf6830] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
制造业
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
{data.map((item, index) => (
|
||||
<ShowCard
|
||||
key={item.doId}
|
||||
loading={iodLoading}
|
||||
record={item}
|
||||
truncate={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Drawer>
|
||||
|
||||
@@ -1,40 +1,85 @@
|
||||
import React, { useState } from "react"
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
|
||||
import { Card, Drawer, List } from "antd"
|
||||
import { Card, Drawer, Skeleton } from "antd"
|
||||
import { IodRegistryEntry } from "@/types/iod.ts"
|
||||
|
||||
type ShowCardProps = {
|
||||
loading: boolean
|
||||
record: IodRegistryEntry
|
||||
truncate?: boolean
|
||||
}
|
||||
|
||||
const ShowCard: React.FC<ShowCardProps> = ({
|
||||
loading,
|
||||
record,
|
||||
truncate = true
|
||||
}) => (
|
||||
<Card className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
{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={record.name}>
|
||||
{record.name}
|
||||
</h3>
|
||||
<p
|
||||
className={`text-sm text-[#383838] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||||
title={record.doId}>
|
||||
数字对象标识:{record.doId}
|
||||
</p>
|
||||
<p
|
||||
className={`text-[#828282] text-xs break-all ${truncate ? "truncate" : ""}`}
|
||||
title={record.description}>
|
||||
{record.description}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
|
||||
const defaultData:IodRegistryEntry[] = [
|
||||
{
|
||||
name: "上海芯飞睿科技有限公司",
|
||||
description:
|
||||
"上海芯飞睿科技有限公司专业从事集成化激光材料与微型化激光器件的研发",
|
||||
doId: "CSTR:15552.13.05.61.2022.783"
|
||||
},
|
||||
{
|
||||
name: "长三角先进材料研究院",
|
||||
description: "由江苏省人民政府联合中国科学院、中国钢研科技集团和中国",
|
||||
doId: "CSTR:15552.12.01.11.2021.528"
|
||||
},
|
||||
{
|
||||
name: "清华大学智能系统实验室",
|
||||
description: "清华大学",
|
||||
doId: "CSTR:15552.13.04.91.2021.614",
|
||||
},
|
||||
]
|
||||
|
||||
export const PlaygroundTeam = () => {
|
||||
// 模拟数据
|
||||
const data = [
|
||||
{
|
||||
title: "绿色化工工艺项目",
|
||||
description:
|
||||
"基于生物基原料,采用repeal2.0可降解材料技术,开发新型环保材料。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
},
|
||||
{
|
||||
title: "智能农业解决方案",
|
||||
description: "利用物联网技术,实现精准农业管理,提高农作物产量。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
},
|
||||
{
|
||||
title: "新能源汽车电池技术",
|
||||
description: "研发高能量密度、长寿命的新型电池材料,推动电动汽车发展。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
},
|
||||
{
|
||||
title: "碳捕集与封存技术",
|
||||
description: "开发高效的碳捕集技术,减少工业排放,助力碳中和目标。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
}
|
||||
]
|
||||
const { messages, iodLoading, currentMessageId, iodSearch } = useMessageOption()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
data.push({
|
||||
title: "开发新型电池材料",
|
||||
description: "研发高能量密度、长寿命的新型电池材料,推动电动汽车发展。",
|
||||
demander: "奥赛康药业 供方:美国Propella公司"
|
||||
})
|
||||
}
|
||||
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])
|
||||
|
||||
const title = useMemo(() => {
|
||||
return messages.length > 0 ? "推荐团队" : "热点团队"
|
||||
}, [messages])
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
@@ -72,7 +117,7 @@ export const PlaygroundTeam = () => {
|
||||
p-id="7274"
|
||||
fill="#BE0BAC"></path>
|
||||
</svg>
|
||||
相关团队
|
||||
{title}
|
||||
</div>
|
||||
}
|
||||
onClick={showDrawer}
|
||||
@@ -80,59 +125,27 @@ export const PlaygroundTeam = () => {
|
||||
|
||||
{/* 场景列表 */}
|
||||
<div className="grid grid-cols-3 gap-3 flex-1 overflow-y-auto">
|
||||
{data.slice(0, 5).map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="text-base font-medium mb-1 text-[#222222] line-clamp-2">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-[#828282] text-xs truncate">
|
||||
{item.description}
|
||||
</p>
|
||||
<p className="flex items-center gap-1.5">
|
||||
<span className="inline-block text-[#BE0BAC] bg-[#be0bac30] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
晶体材料
|
||||
</span>
|
||||
<span className="inline-block text-[#EB1C1C] bg-[#eb1c1c30] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
中国
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
{data.slice(0, 3).map((item, index) => (
|
||||
<ShowCard key={item.doId} loading={iodLoading} record={item} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 抽屉 */}
|
||||
<Drawer
|
||||
title="相关团队"
|
||||
title={title}
|
||||
closable={{ "aria-label": "Close Button" }}
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
width="33.33%">
|
||||
<div className="grid grid-cols-1 gap-3 overflow-y-auto">
|
||||
{data.slice(0, 5).map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
hoverable
|
||||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 className="text-base font-medium mb-1 text-[#222222]">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-[#828282] text-xs">{item.description}</p>
|
||||
<p className="flex items-center gap-1.5">
|
||||
<span className="inline-block text-[#BE0BAC] bg-[#be0bac30] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
晶体材料
|
||||
</span>
|
||||
<span className="inline-block text-[#EB1C1C] bg-[#eb1c1c30] h-5 leading-5 mt-1 text-xs rounded-full px-2.5">
|
||||
中国
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
{data.map((item, index) => (
|
||||
<ShowCard
|
||||
key={item.doId}
|
||||
loading={iodLoading}
|
||||
record={item}
|
||||
truncate={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Drawer>
|
||||
|
||||
Reference in New Issue
Block a user