Compare commits

..

2 Commits

Author SHA1 Message Date
jiangxucong a4d9f072e3 Merge remote-tracking branch 'origin/main' into main 3 months ago
jiangxucong 615976e315 智能会话和知识库 3 months ago

@ -38,7 +38,7 @@
"db:push-test": "NODE_ENV=test drizzle-kit push", "db:push-test": "NODE_ENV=test drizzle-kit push",
"db:studio": "drizzle-kit studio", "db:studio": "drizzle-kit studio",
"db:z-pull": "drizzle-kit introspect", "db:z-pull": "drizzle-kit introspect",
"dev": "next dev -p 3010", "dev": "next dev -p 3011",
"docs:i18n": "lobe-i18n md && npm run lint:mdx", "docs:i18n": "lobe-i18n md && npm run lint:mdx",
"docs:seo": "lobe-seo && npm run lint:mdx", "docs:seo": "lobe-seo && npm run lint:mdx",
"i18n": "npm run workflow:i18n && lobe-i18n", "i18n": "npm run workflow:i18n && lobe-i18n",
@ -109,6 +109,7 @@
"@azure/core-rest-pipeline": "1.16.0", "@azure/core-rest-pipeline": "1.16.0",
"@azure/openai": "1.0.0-beta.12", "@azure/openai": "1.0.0-beta.12",
"@cfworker/json-schema": "^2.0.0", "@cfworker/json-schema": "^2.0.0",
"@chevrotain/regexp-to-ast": "^11.0.3",
"@clerk/localizations": "^3.0.4", "@clerk/localizations": "^3.0.4",
"@clerk/nextjs": "^5.3.3", "@clerk/nextjs": "^5.3.3",
"@clerk/themes": "^2.1.27", "@clerk/themes": "^2.1.27",
@ -144,6 +145,8 @@
"axios": "^1.7.9", "axios": "^1.7.9",
"brotli-wasm": "^3.0.1", "brotli-wasm": "^3.0.1",
"chroma-js": "^2.6.0", "chroma-js": "^2.6.0",
"csv-string": "^4.1.1",
"csv-stringify": "^6.5.2",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"debug": "^4.3.6", "debug": "^4.3.6",
"dexie": "^3.2.7", "dexie": "^3.2.7",

@ -1,6 +1,6 @@
import {Image} from 'antd'; import {Image} from 'antd';
import { memo } from 'react'; import { memo } from 'react';
import { Flexbox } from 'react-layout-kit'; // import { Flexbox } from 'react-layout-kit';
// import UserAvatar from '@/features/User/UserAvatar'; // import UserAvatar from '@/features/User/UserAvatar';
// import UserPanel from '@/features/User/UserPanel'; // import UserPanel from '@/features/User/UserPanel';

@ -18,13 +18,13 @@ const useStyles = createStyles(({ css }) => ({
width: 48px; width: 48px;
height: 48px; height: 48px;
`, `,
iconSelectText: css`
color: #0044FF;
`,
iconText: css` iconText: css`
text-align: center; text-align: center;
color: #fff; color: #fff;
`, `,
iconSelectText: css`
color: #0044FF;
`,
linkUrl: css` linkUrl: css`
width: 100%; width: 100%;
display: inline-block; display: inline-block;
@ -37,7 +37,8 @@ const useStyles = createStyles(({ css }) => ({
export interface TopActionProps { export interface TopActionProps {
tab?: SidebarTabKey; tab?: SidebarTabKey;
} }
const getUserId = (s) => s.user?.id
const getUserId = (s:object) => s.user?.id
const TopActions = memo<TopActionProps>(() => { const TopActions = memo<TopActionProps>(() => {
const { t } = useTranslation('common'); const { t } = useTranslation('common');
const switchBackToChat = useGlobalStore((s) => s.switchBackToChat); const switchBackToChat = useGlobalStore((s) => s.switchBackToChat);
@ -63,19 +64,19 @@ const TopActions = memo<TopActionProps>(() => {
<div className={value === '/chat' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div> <div className={value === '/chat' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link> </Link>
{enableKnowledgeBase && ( {enableKnowledgeBase && (
<Link aria-label={t('tab.files')} className={value === '/discover/assistants' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/assistants?userid=${userId}`} onClick={() => {setValue("/discover/assistants"); window.localStorage.setItem("nowChat", "")}}> <Link aria-label={t('tab.files')} className={value === '/discover/assistants' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/assistants`} onClick={() => {setValue("/discover/assistants"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"files"} className={cx(styles.iconImg)} preview={false} src="/images/zs.png" /> <Image alt={"files"} className={cx(styles.iconImg)} preview={false} src="/images/zs.png" />
<div className={value === '/discover/assistants' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div> <div className={value === '/discover/assistants' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link> </Link>
)} )}
{showMarket && ( {showMarket && (
<Link aria-label={t('tab.discover')} className={value === '/files' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={'/files'} onClick={() => {setValue("/files"); window.localStorage.setItem("nowChat", "")}}> <Link aria-label={t('tab.discover')} className={value === '/applicationset' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={'/applicationset'} onClick={() => {setValue("/applicationset"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"discover"} className={cx(styles.iconImg)} preview={false} src="/images/gj.png" /> <Image alt={"discover"} className={cx(styles.iconImg)} preview={false} src="/images/gj.png" />
<div className={value === '/files' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div> <div className={value === '/applicationset' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }>AI</div>
</Link> </Link>
)} )}
{showMarket && ( {showMarket && (
<Link aria-label={t('tab.Model')} className={value === '/model' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/models?userid=${userId}`} onClick={() => {setValue("/model"); window.localStorage.setItem("nowChat", "")}}> <Link aria-label={t('tab.Model')} className={value === '/model' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/models`} onClick={() => {setValue("/model"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"model"} className={cx(styles.iconImg)} preview={false} src="/images/mx.png" /> <Image alt={"model"} className={cx(styles.iconImg)} preview={false} src="/images/mx.png" />
<div className={value === '/model' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div> <div className={value === '/model' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link> </Link>
@ -87,7 +88,7 @@ const TopActions = memo<TopActionProps>(() => {
</Link> </Link>
)} )}
{showMarket && ( {showMarket && (
<Link aria-label={t('tab.Plugins')} className={value === '/plugins' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/plugins?userid=${userId}`} onClick={() => {setValue("/plugins"); window.localStorage.setItem("nowChat", "")}}> <Link aria-label={t('tab.Plugins')} className={value === '/plugins' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/plugins`} onClick={() => {setValue("/plugins"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"plugins"} className={cx(styles.iconImg)} preview={false} src="/images/cj.png" /> <Image alt={"plugins"} className={cx(styles.iconImg)} preview={false} src="/images/cj.png" />
<div className={value === '/plugins' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div> <div className={value === '/plugins' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link> </Link>

@ -13,7 +13,7 @@ const Nav = memo(() => {
return ( return (
<SideNav <SideNav
avatar={<Avatar />} avatar={<Avatar />}
bottomActions={<></>} bottomActions={<div></div>}
style={{ backgroundColor: '#2E62FF', height: '100%', width: '100px', zIndex: 100 }} style={{ backgroundColor: '#2E62FF', height: '100%', width: '100px', zIndex: 100 }}
topActions={<TopActions tab={sidebarKey} />} topActions={<TopActions tab={sidebarKey} />}
/> />

@ -7,45 +7,45 @@ import { Flexbox } from 'react-layout-kit';
import CloudBanner, { BANNER_HEIGHT } from '@/features/AlertBanner/CloudBanner'; import CloudBanner, { BANNER_HEIGHT } from '@/features/AlertBanner/CloudBanner';
import { usePlatform } from '@/hooks/usePlatform'; import { usePlatform } from '@/hooks/usePlatform';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig'; import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
import { UserOutlined, SearchOutlined } from '@ant-design/icons'; import { UserOutlined } from '@ant-design/icons';
import { LayoutProps } from './type'; import { LayoutProps } from './type';
import { Divider, Avatar } from "antd"; import { Divider, Avatar } from "antd";
const title = { const title = {
"/chat": '会话', "/chat": '会话',
"/discover/assistants": "助手", "/discover/assistants": "助手",
"/files": "工具", "/files": "工具",
"/knowledge": "知识库",
"/model": "模型", "/model": "模型",
"/robot": "数字人",
"/plugins": "插件", "/plugins": "插件",
"/power": "算力", "/power": "算力",
"/knowledge": "知识库" "/robot": "数字人",
} }
const useStyles = createStyles(({ css, token }) => ({ const useStyles = createStyles(({ css }) => ({
topCenten: css`
width: 100%;
line-height: 60px;
background: #FFFFFF;
box-sizing: border-box;
/* 分割线颜色 */
border-width: 0px 0px 2px 0px;
border-style: solid;
border-color: rgba(187, 204, 253, 0.24);
`,
leftTitle: css`
font-size: 20px;
color: #3d3d3d;
display: inline-block
`,
dividerCen: css` dividerCen: css`
width: 1px; width: 1px;
height: 26px; height: 26px;
background-color: #d8d8d8; background-color: #d8d8d8;
margin: 8px 16px; margin: 8px 16px;
`, `,
inp: css`
width: 283px;
margin-right: 43px;
background: #F3F6FF;
&:hover, &:active, &:focus {
border-color: transparent !important;
background: #F3F6FF !important;
}
`,
ledDiv: css ` ledDiv: css `
width: 50%; width: 50%;
display: inline-block; display: inline-block;
`, `,
leftTitle: css`
font-size: 20px;
color: #3d3d3d;
display: inline-block
`,
nameSpn: css` nameSpn: css`
margin-right: 16px; margin-right: 16px;
margin-left: 18px; margin-left: 18px;
@ -55,14 +55,15 @@ const useStyles = createStyles(({ css, token }) => ({
color: #BCCEFF; color: #BCCEFF;
font-size: 24px; font-size: 24px;
`, `,
inp: css` topCenten: css`
width: 283px; width: 100%;
margin-right: 43px; line-height: 60px;
background: #F3F6FF; background: #FFFFFF;
&:hover, &:active, &:focus { box-sizing: border-box;
border-color: transparent !important; /* 分割线颜色 */
background: #F3F6FF !important; border-width: 0px 0px 2px 0px;
} border-style: solid;
border-color: rgba(187, 204, 253, 0.24);
`, `,
})) }))
@ -94,7 +95,7 @@ const Layout = memo<LayoutProps>(({ children, nav }) => {
<span className={cx(styles.leftTitle)}>{title[pathName]}</span> <span className={cx(styles.leftTitle)}>{title[pathName]}</span>
</div> </div>
<div className={cx(styles.ledDiv)} style={{ height: '42px', lineHeight: "42px", textAlign: 'right' }}> <div className={cx(styles.ledDiv)} style={{ height: '42px', lineHeight: "42px", textAlign: 'right' }}>
<Avatar style={{ backgroundColor: '#90ACFF' }} icon={<UserOutlined />} /> <Avatar icon={<UserOutlined />} style={{ backgroundColor: '#90ACFF' }}/>
<span className={cx(styles.nameSpn)}> </span> <span className={cx(styles.nameSpn)}> </span>
</div> </div>
</div> </div>

@ -1,10 +1,10 @@
'use client'; 'use client';
import {memo, useMemo, useEffect, useState} from 'react'; import {memo, useEffect, useState} from 'react';
import {createStyles} from "antd-style"; import {createStyles} from "antd-style";
import {Anchor, Button, Card, Image, Avatar, ConfigProvider} from "antd"; import {Anchor, Button, Card, Image} from "antd";
import {RightCircleOutlined, LikeFilled, WechatFilled, HomeFilled, DribbbleSquareFilled, CopyFilled, MedicineBoxFilled, IeCircleFilled, IdcardFilled, HourglassFilled, InsuranceFilled} from "@ant-design/icons"; import {RightCircleOutlined, LikeFilled, WechatFilled, HomeFilled, DribbbleSquareFilled, CopyFilled, MedicineBoxFilled, IeCircleFilled, IdcardFilled, HourglassFilled, InsuranceFilled} from "@ant-design/icons";
import Link from "next/link"; // import Link from "next/link";
import request from '@/app/api/request'; import request from '@/app/api/request';
import Title from "@/app/(main)/discover/components/Title"; import Title from "@/app/(main)/discover/components/Title";
@ -526,94 +526,29 @@ import Title from "@/app/(main)/discover/components/Title";
const stList = [ const stList = [
{ {
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03', date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。" des: "擅长产品功能分析与用户价值观广告文案创作。",
},
{
title: 'XXX助手', title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
}, },
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
},
{
title: 'XXX助手',
date: '2024-02-03',
des: "擅长产品功能分析与用户价值观广告文案创作。"
}
] ]
const useStyles = createStyles(({css, token}) => ({ const useStyles = createStyles(({css}) => ({
topBtn: css` actionItem: css`
padding: 10px 0px; height: 56px;
background: rgba(239, 243, 255, 0.22); line-height: 56px;
box-sizing: border-box; margin-right: 30px
border-width: 0px 0px 2px 0px;
border-style: solid;
border-color: rgba(146, 154, 178, 0.2392);
`, `,
selectBtn: css` actionItemIcon: css`
background-color: #3B6FFF !important; margin-right: 15px;
color: #fff !important; margin-left: 28px;
`,
actionSpan: css`
color: #2E62FF;
`,
avImg: css`
width: 55px;
height: 55px;
border-radius: 16px
`, `,
btn: css` btn: css`
width: 136px; width: 136px;
@ -623,125 +558,132 @@ const useStyles = createStyles(({css, token}) => ({
border-color: #C2C2C2 !important; border-color: #C2C2C2 !important;
color: #666 !important; color: #666 !important;
`, `,
actionItem: css` card: css`
height: 56px; width: 23%;
line-height: 56px; margin: 32px 1% 0;
margin-right: 30px display: inline-block;
`, `,
actionItemIcon: css` cardCotain: css`
margin-right: 15px; margin-top: -10px;
margin-left: 28px; font-size: 12px;
color: #999
`, `,
first: css` cardMeta: css`
color: #FFAD01 height: 80px
`, `,
sec: css` container: css`
color: #5BD941 marginTop: -20px
`, `,
thd: css` containerTitle: css`
color: #003BFF font-size: 18px
`, `,
four: css` desImg: css`
color: #FF9B06 width: 28px
`,
desText: css`
font-size: 12px;
color: #909090;
`,
egiht: css`
color: #5BD941
`, `,
fif: css` fif: css`
color: #FF4D4D color: #FF4D4D
`, `,
six: css` first: css`
color: #003BFF color: #FFAD01
`, `,
seven: css` four: css`
color: #0EDFFF color: #FF9B06
`, `,
egiht: css` leftTitle: css`
color: #5BD941 font-size: 20px;
margin: 0 1%;
padding-top: 20px;
`, `,
nine: css` nine: css`
color: #07D7F7 color: #07D7F7
`, `,
ten: css` rightCo: css`
color: #E138FF font-size: 16px;
margin-left: 30px;
vertical-align: middle;
`, `,
seleFir: css` sec: css`
background-color: #FFF3D9; color: #5BD941
color: #FFAD01;
`, `,
seleSec: css` seleEight: css`
background-color: #DCF9D6; background-color: #D1FFE7;
color: #5BD941; color: #5BD941;
`, `,
seleThd: css` seleFif: css`
background-color: #E3E9FF; background-color: #FFEBEB;
color: #003BFF; color: #FF4D4D;
`,
seleFir: css`
background-color: #FFF3D9;
color: #FFAD01;
`, `,
seleFou: css` seleFou: css`
background-color: #FFFACD; background-color: #FFFACD;
color: #FF9B06; color: #FF9B06;
`, `,
seleFif: css` seleNine: css`
background-color: #FFEBEB; background-color: #D1FFE7;
color: #FF4D4D; color: #07D7F7;
`, `,
seleSix: css` seleSec: css`
background-color: #E3E9FF; background-color: #DCF9D6;
color: #003BFF; color: #5BD941;
`, `,
seleSeve: css` seleSeve: css`
background-color: #D8FAFF; background-color: #D8FAFF;
color: #0EDFFF; color: #0EDFFF;
`, `,
seleEight: css` seleSix: css`
background-color: #D1FFE7; background-color: #E3E9FF;
color: #5BD941; color: #003BFF;
`,
seleNine: css`
background-color: D1FFE7;
color: #07D7F7;
`, `,
seleTen: css` seleTen: css`
background-color: #FCEBFF; background-color: #FCEBFF;
color: #E138FF; color: #E138FF;
`, `,
leftTitle: css` seleThd: css`
font-size: 20px; background-color: #E3E9FF;
margin: 0 1%; color: #003BFF;
padding-top: 20px;
`, `,
card: css` selectBtn: css`
width: 23%; background-color: #3B6FFF !important;
margin: 32px 1% 0; color: #fff !important;
display: inline-block;
`, `,
rightCo: css` seven: css`
font-size: 16px; color: #0EDFFF
margin-left: 30px;
vertical-align: middle;
`, `,
avImg: css` six: css`
width: 55px; color: #003BFF
height: 55px;
border-radius: 16px
`, `,
desText: css` ten: css`
font-size: 12px; color: #E138FF
color: #909090; `,
thd: css`
color: #003BFF
`, `,
title: css` title: css`
font-size: 18px font-size: 18px
`, `,
cardMeta: css` topBtn: css`
height: 80px padding: 10px 0px;
`, background: rgba(239, 243, 255, 0.22);
actionSpan: css` box-sizing: border-box;
color: #2E62FF; border-width: 0px 0px 2px 0px;
`, border-style: solid;
desImg: css` border-color: rgba(146, 154, 178, 0.2392);
width: 28px
`, `,
cardCotain: css` verImg: css`
margin-top: -10px; height: 2px;
font-size: 12px; width: 80%;
color: #999 background-color: #DFE4FF;
display: inline-block
`, `,
zsds: css` zsds: css`
display: inline-block; display: inline-block;
@ -758,21 +700,22 @@ const useStyles = createStyles(({css, token}) => ({
border: 2px solid #ddd; border: 2px solid #ddd;
display: inline-block display: inline-block
`, `,
verImg: css`
height: 2px;
width: 80%;
background-color: #DFE4FF;
display: inline-block
`,
container: css`
marginTop: -20px
`,
containerTitle: css`
font-size: 18px
`
})) }))
const Filescon = memo(() => { const getContainer = () => document.querySelector("#fileRight")
const handleClickCard = (e) => {
window.open(e.website, '_blank');
}
const onClickAncho = (e,link) => {
e.preventDefault()
let srcolls = document.querySelector(link.href)
srcolls.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}
const ApplicationSet = memo(() => {
const { styles, cx } = useStyles() const { styles, cx } = useStyles()
const [val, setVal] = useState("AI") const [val, setVal] = useState("AI")
const [achVal, setAchVal] = useState("#rmtj") const [achVal, setAchVal] = useState("#rmtj")
@ -780,11 +723,11 @@ const Filescon = memo(() => {
useEffect(() => { useEffect(() => {
const fetchData = () => { const fetchData = () => {
request({ request({
url: "/flxai/api/robot/apptoolsset/getAllAiTools",
method: "get", method: "get",
url: "/flxai/api/robot/apptoolsset/getAllAiTools",
}).then(response => { }).then(response => {
if (response.code == 0) { if (response.code === 0) {
console.log(response,222222222) console.log(response,"2222")
setStData(response.data); setStData(response.data);
} }
}).catch(error => { }).catch(error => {
@ -793,7 +736,6 @@ const Filescon = memo(() => {
}; };
fetchData(); fetchData();
}, []); // 空数组[]意味着仅在组件挂载时调用一次 }, []); // 空数组[]意味着仅在组件挂载时调用一次
const getContainer = () => document.getElementById("fileRight")
const handleClick = (e) => { const handleClick = (e) => {
setVal(e) setVal(e)
@ -803,98 +745,85 @@ const Filescon = memo(() => {
setAchVal(e) setAchVal(e)
} }
const handleClickCard = (e) => {
window.open(e.website, '_blank');
}
const onClickAncho = (e,link) => {
e.preventDefault()
let srcolls = document.querySelector(link.href)
srcolls.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}
return ( return (
<> <>
<div className={cx(styles.topBtn)}> <div className={cx(styles.topBtn)}>
<Button onClick={() => handleClick("AI")} className={cx(styles.btn, val=='AI'&&styles.selectBtn)}>AI</Button> <Button className={cx(styles.btn, val==='AI'&&styles.selectBtn)} onClick={() => handleClick("AI")}>AI</Button>
<Button onClick={() => handleClick("tj")} className={cx(styles.btn, val=='tj'&&styles.selectBtn)}></Button> <Button className={cx(styles.btn, val==='tj'&&styles.selectBtn)} onClick={() => handleClick("tj")}></Button>
</div> </div>
<div style={{ display: 'flex', overflowY: 'scroll' }}> <div style={{ display: 'flex', overflowY: 'scroll' }}>
{val == 'AI' ? <> {val === 'AI' ? <>
<Anchor <Anchor
style={{width: '200px', background: "#fff"}}
affix={false} affix={false}
onClick={onClickAncho}
getContainer={getContainer} getContainer={getContainer}
onChange={(e) => onChangeAnchor(e)}
items={[ items={[
{ {
key: '1',
href: '#rmtj', href: '#rmtj',
title: <div className={cx(styles.actionItem, achVal == '#rmtj' && styles.seleFir)}><LikeFilled key: '1',
title: <div className={cx(styles.actionItem, achVal === '#rmtj' && styles.seleFir)}><LikeFilled
className={cx(styles.actionItemIcon, styles.first)}/></div>, className={cx(styles.actionItemIcon, styles.first)}/></div>,
}, },
{ {
key: '2',
href: '#ailt', href: '#ailt',
title: <div className={cx(styles.actionItem, achVal == '#ailt' && styles.seleSec)}><WechatFilled key: '2',
title: <div className={cx(styles.actionItem, achVal === '#ailt' && styles.seleSec)}><WechatFilled
className={cx(styles.actionItemIcon, styles.sec)}/>AI</div>, className={cx(styles.actionItemIcon, styles.sec)}/>AI</div>,
}, },
{ {
key: '3',
href: '#aixz', href: '#aixz',
title: <div className={cx(styles.actionItem, achVal == '#aixz' && styles.seleThd)}><CopyFilled key: '3',
title: <div className={cx(styles.actionItem, achVal === '#aixz' && styles.seleThd)}><CopyFilled
className={cx(styles.actionItemIcon, styles.thd)}/>AI</div>, className={cx(styles.actionItemIcon, styles.thd)}/>AI</div>,
}, },
{ {
key: '4',
href: '#aihh', href: '#aihh',
title: <div className={cx(styles.actionItem, achVal == '#aihh' && styles.seleFou)}> key: '4',
title: <div className={cx(styles.actionItem, achVal === '#aihh' && styles.seleFou)}>
<DribbbleSquareFilled className={cx(styles.actionItemIcon, styles.four)}/>AI</div>, <DribbbleSquareFilled className={cx(styles.actionItemIcon, styles.four)}/>AI</div>,
}, },
{ {
key: '5',
href: '#aisp', href: '#aisp',
title: <div className={cx(styles.actionItem, achVal == '#aisp' && styles.seleFif)}><HomeFilled key: '5',
title: <div className={cx(styles.actionItem, achVal === '#aisp' && styles.seleFif)}><HomeFilled
className={cx(styles.actionItemIcon, styles.fif)}/>AI</div>, className={cx(styles.actionItemIcon, styles.fif)}/>AI</div>,
}, },
{ {
key: '6',
href: '#aibg', href: '#aibg',
title: <div className={cx(styles.actionItem, achVal == '#aibg' && styles.seleSix)}><HourglassFilled key: '6',
title: <div className={cx(styles.actionItem, achVal === '#aibg' && styles.seleSix)}><HourglassFilled
className={cx(styles.actionItemIcon, styles.six)}/>AI</div>, className={cx(styles.actionItemIcon, styles.six)}/>AI</div>,
}, },
{ {
key: '7',
href: '#aiszr', href: '#aiszr',
title: <div className={cx(styles.actionItem, achVal == '#aiszr' && styles.seleSeve)}><IdcardFilled key: '7',
title: <div className={cx(styles.actionItem, achVal === '#aiszr' && styles.seleSeve)}><IdcardFilled
className={cx(styles.actionItemIcon, styles.seven)}/>AI</div>, className={cx(styles.actionItemIcon, styles.seven)}/>AI</div>,
}, },
{ {
key: '8',
href: '#aijy', href: '#aijy',
title: <div className={cx(styles.actionItem, achVal == '#aijy' && styles.seleEight)}><IeCircleFilled key: '8',
title: <div className={cx(styles.actionItem, achVal === '#aijy' && styles.seleEight)}><IeCircleFilled
className={cx(styles.actionItemIcon, styles.egiht)}/>AI</div>, className={cx(styles.actionItemIcon, styles.egiht)}/>AI</div>,
}, },
{ {
key: '9',
href: '#aibc', href: '#aibc',
title: <div className={cx(styles.actionItem, achVal == '#aibc' && styles.seleNine)}><InsuranceFilled key: '9',
title: <div className={cx(styles.actionItem, achVal === '#aibc' && styles.seleNine)}><InsuranceFilled
className={cx(styles.actionItemIcon, styles.nine)}/>AI</div>, className={cx(styles.actionItemIcon, styles.nine)}/>AI</div>,
}, },
{ {
key: '10',
href: '#aiyp', href: '#aiyp',
title: <div className={cx(styles.actionItem, achVal == '#aiyp' && styles.seleTen)}><MedicineBoxFilled key: '10',
title: <div className={cx(styles.actionItem, achVal === '#aiyp' && styles.seleTen)}><MedicineBoxFilled
className={cx(styles.actionItemIcon, styles.ten)}/>AI</div>, className={cx(styles.actionItemIcon, styles.ten)}/>AI</div>,
}, },
]} ]}
onChange={(e) => onChangeAnchor(e)}
onClick={onClickAncho}
style={{ background: "#fff", width: '200px' }}
/> />
<div id="fileRight" style={{width: "calc(100vw - 300px)", height: "100vh", overflowY: 'scroll'}}> <div id="fileRight" style={{height: "100vh", overflowY: 'scroll', width: "calc(100vw - 300px)"}}>
<div id="rmtj"> <div id="rmtj">
<div className={cx(styles.leftTitle)}></div> <div className={cx(styles.leftTitle)}></div>
<div> <div>
@ -902,15 +831,16 @@ const Filescon = memo(() => {
stData['rmtj'] && stData['rmtj'].map((e) => { stData['rmtj'] && stData['rmtj'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -925,14 +855,15 @@ const Filescon = memo(() => {
stData['chat'] && stData['chat'].map((e) => { stData['chat'] && stData['chat'].map((e) => {
return ( return (
<Card <Card
actions={[<span className={styles.actions} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined className={styles.rightCo}/></span>]}
className={cx(styles.card)} className={cx(styles.card)}
actions={[<span onClick={() => handleClickCard(e)} className={styles.actions}><RightCircleOutlined className={styles.rightCo}/></span>]} key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -947,15 +878,16 @@ const Filescon = memo(() => {
stData['writing'] && stData['writing'].map((e) => { stData['writing'] && stData['writing'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -970,15 +902,16 @@ const Filescon = memo(() => {
stData['conversation'] && stData['conversation'].map((e) => { stData['conversation'] && stData['conversation'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -993,15 +926,16 @@ const Filescon = memo(() => {
stData['video'] && stData['video'].map((e) => { stData['video'] && stData['video'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -1016,15 +950,16 @@ const Filescon = memo(() => {
stData['office'] && stData['office'].map((e) => { stData['office'] && stData['office'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -1039,15 +974,16 @@ const Filescon = memo(() => {
stData['digitalPeople'] && stData['digitalPeople'].map((e) => { stData['digitalPeople'] && stData['digitalPeople'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
className={styles.cardMeta} className={styles.cardMeta}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -1062,15 +998,16 @@ const Filescon = memo(() => {
stData['education'] && stData['education'].map((e) => { stData['education'] && stData['education'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
style={{height: '80px'}} avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>} className={styles.cardMeta}
title={<span onClick={(e) => handleClickCard(e)} className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -1085,15 +1022,16 @@ const Filescon = memo(() => {
stData['programming'] && stData['programming'].map((e) => { stData['programming'] && stData['programming'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
style={{height: '80px'}} avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>} className={styles.cardMeta}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -1108,15 +1046,16 @@ const Filescon = memo(() => {
stData['audio'] && stData['audio'].map((e) => { stData['audio'] && stData['audio'].map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id} onClick={() => handleClickCard(e)}><RightCircleOutlined
actions={[<span onClick={() => handleClickCard(e)} className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<Card.Meta <Card.Meta
style={{height: '80px'}} avatar={<Image alt="" className={styles.avImg} preview={false} src={e.iconurl}/>}
avatar={<Image className={styles.avImg} alt="" preview={false} src={e.iconurl}/>} className={styles.cardMeta}
title={<span className={styles.title}>{e.name}</span>}
description={<span className={styles.desText}>{e.remark}</span>} description={<span className={styles.desText}>{e.remark}</span>}
title={<span className={styles.title}>{e.name}</span>}
/> />
</Card> </Card>
) )
@ -1127,28 +1066,28 @@ const Filescon = memo(() => {
</div> </div>
</> </>
: :
<> <div style={{margin: '0 auto', width: '90%'}}>
<div style={{ width: '90%', margin: '0 auto'}}>
<Title tag={stList.length}></Title> <Title tag={stList.length}></Title>
<div> <div>
{ {
stList.map((e) => { stList.map((e) => {
return ( return (
<Card <Card
className={cx(styles.card)} actions={[<span className={styles.actionSpan} key={e.id}><RightCircleOutlined
actions={[<span className={styles.actionSpan}><RightCircleOutlined
className={styles.rightCo}/></span>]} className={styles.rightCo}/></span>]}
className={cx(styles.card)}
key={e.id}
> >
<div className={styles.containerTitle}>{e.title}</div> <div className={styles.containerTitle}>{e.title}</div>
<div className={styles.container}> <div className={styles.container}>
<div className={styles.verImg}></div> <div className={styles.verImg}></div>
<div className={styles.zsdsCardImg}> <div className={styles.zsdsCardImg}>
<Image src="/images/gjImg.png" alt="" preview={false} /> <Image alt="" preview={false} src="/images/gjImg.png" />
</div> </div>
</div> </div>
<div className={styles.cardCotain}> <div className={styles.cardCotain}>
<div> <div>
<Image clasName={styles.desImg} preview={false} alt="" src="/images/detaicon.png" /> <Image alt="" clasName={styles.desImg} preview={false} src="/images/detaicon.png" />
<span className={styles.zsds}></span> <span className={styles.zsds}></span>
<span>{e.date}</span> <span>{e.date}</span>
</div> </div>
@ -1160,11 +1099,10 @@ const Filescon = memo(() => {
} }
</div> </div>
</div> </div>
</>
} }
</div> </div>
</> </>
); );
}); });
export default Filescon; export default ApplicationSet;

@ -0,0 +1,50 @@
// import StructuredData from '@/components/StructuredData';
import { Locales } from '@/locales/resources';
// import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata';
// import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation';
// import { isMobileDevice } from '@/utils/responsive';
import ApplicationSet from "./applicationset";
// import {Button} from "antd";
type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
return metadataModule.generate({
alternate: true,
description: t('files.description'),
locale,
title: t('files.title'),
url: '/files',
});
};
const Page = async () => {
// const { t, locale } = await translation('metadata', searchParams?.hl);
// const mobile = isMobileDevice();
// const discoverService = new DiscoverService();
// const items = await discoverService.getAssistantList(locale);
// const ld = ldModule.generate({
// description: t('files.description'),
// title: t('files.title'),
// url: '/files',
// webpage: {
// enable: true,
// search: '/files/search',
// },
// });
return (
<ApplicationSet />
);
};
Page.DisplayName = 'DiscoverAssistants';
export default Page;

@ -70,7 +70,7 @@ const SystemRole = memo(() => {
/> />
<Flexbox <Flexbox
className={styles.promptBox} className={styles.promptBox}
height={200} height={175}
onClick={handleOpen} onClick={handleOpen}
onDoubleClick={(e) => { onDoubleClick={(e) => {
if (e.altKey) handleOpenWithEdit(); if (e.altKey) handleOpenWithEdit();

@ -1,43 +1,40 @@
'use client'; 'use client';
// import { ActionIcon } from '@lobehub/ui'; import { ActionIcon } from '@lobehub/ui';
// import { PanelRightClose, PanelRightOpen } from 'lucide-react'; import { PanelRightClose, PanelRightOpen } from 'lucide-react';
import { memo } from 'react'; import { memo } from 'react';
// import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
// import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens'; import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
// import { useGlobalStore } from '@/store/global'; import { useGlobalStore } from '@/store/global';
// import { systemStatusSelectors } from '@/store/global/selectors'; import { systemStatusSelectors } from '@/store/global/selectors';
// import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig'; import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
// import SettingButton from '../../../features/SettingButton'; import SettingButton from '../../../features/SettingButton';
// import ShareButton from '../../../features/ShareButton'; // import ShareButton from '../../../features/ShareButton';
import {Button} from "antd"; import ShareText from '../../../features/ShareText';
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
const HeaderAction = memo(() => { const HeaderAction = memo(() => {
// const { t } = useTranslation('chat'); const { t } = useTranslation('chat');
// const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [ const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
// systemStatusSelectors.showChatSideBar(s), systemStatusSelectors.showChatSideBar(s),
// s.toggleChatSideBar, s.toggleChatSideBar,
// ]); ]);
// const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors); const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors);
const openChatSettings = useOpenChatSettings();
return ( return (
<> <>
<Button onClick={() => openChatSettings()} shape="round" style={{ borderColor: '#2E62FF', color: "#2E62FF" }}></Button> <ShareText/>
{/*<ShareButton />*/} {/*<ShareButton />*/}
{/*<ActionIcon*/} {isAgentEditable && <SettingButton />}
{/* icon={showAgentSettings ? PanelRightClose : PanelRightOpen}*/} <ActionIcon
{/* onClick={() => toggleConfig()}*/} icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
{/* size={DESKTOP_HEADER_ICON_SIZE}*/} onClick={() => toggleConfig()}
{/* title={t('roleAndArchive')}*/} size={DESKTOP_HEADER_ICON_SIZE}
{/*/>*/} title={t('roleAndArchive')}
{/*{isAgentEditable && <SettingButton />}*/} />
</> </>
); );
}); });

@ -1,28 +1,28 @@
'use client'; 'use client';
import { Avatar } from '@lobehub/ui'; import { ActionIcon, Avatar, ChatHeaderTitle } from '@lobehub/ui';
import { Skeleton } from 'antd'; import { Skeleton } from 'antd';
// import { PanelLeftClose, PanelLeftOpen } from 'lucide-react'; import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
import { Suspense, memo } from 'react'; import { Suspense, memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit'; import { Flexbox } from 'react-layout-kit';
// import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens'; import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes'; import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
// import { useGlobalStore } from '@/store/global'; import { useGlobalStore } from '@/store/global';
// import { systemStatusSelectors } from '@/store/global/selectors'; import { systemStatusSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session'; import { useSessionStore } from '@/store/session';
import { sessionMetaSelectors, sessionSelectors } from '@/store/session/selectors'; import { sessionMetaSelectors, sessionSelectors } from '@/store/session/selectors';
import { useInitAgentConfig } from '../../useInitAgentConfig'; import { useInitAgentConfig } from '../../useInitAgentConfig';
// import Tags from './Tags'; import Tags from './Tags';
const Main = memo(() => { const Main = memo(() => {
const { t } = useTranslation('chat'); const { t } = useTranslation('chat');
useInitAgentConfig(); useInitAgentConfig();
const [init, isInbox, title, avatar, backgroundColor] = useSessionStore((s) => [ const [init, isInbox, title, description, avatar, backgroundColor] = useSessionStore((s) => [
sessionSelectors.isSomeSessionActive(s), sessionSelectors.isSomeSessionActive(s),
sessionSelectors.isInboxSession(s), sessionSelectors.isInboxSession(s),
sessionMetaSelectors.currentAgentTitle(s), sessionMetaSelectors.currentAgentTitle(s),
@ -34,9 +34,9 @@ const Main = memo(() => {
const openChatSettings = useOpenChatSettings(); const openChatSettings = useOpenChatSettings();
const displayTitle = isInbox ? t('inbox.title') : title; const displayTitle = isInbox ? t('inbox.title') : title;
// const displayDesc = isInbox ? t('inbox.desc') : description; const displayDesc = isInbox ? t('inbox.desc') : description;
// const showSessionPanel = useGlobalStore(systemStatusSelectors.showSessionPanel); const showSessionPanel = useGlobalStore(systemStatusSelectors.showSessionPanel);
// const updateSystemStatus = useGlobalStore((s) => s.updateSystemStatus); const updateSystemStatus = useGlobalStore((s) => s.updateSystemStatus);
return !init ? ( return !init ? (
<Flexbox horizontal> <Flexbox horizontal>
@ -49,20 +49,20 @@ const Main = memo(() => {
</Flexbox> </Flexbox>
) : ( ) : (
<Flexbox align={'center'} gap={4} horizontal> <Flexbox align={'center'} gap={4} horizontal>
{/*{*/} {
{/* <ActionIcon*/} <ActionIcon
{/* aria-label={t('agents')}*/} aria-label={t('agents')}
{/* icon={showSessionPanel ? PanelLeftClose : PanelLeftOpen}*/} icon={showSessionPanel ? PanelLeftClose : PanelLeftOpen}
{/* onClick={() => {*/} onClick={() => {
{/* updateSystemStatus({*/} updateSystemStatus({
{/* sessionsWidth: showSessionPanel ? 0 : 320,*/} sessionsWidth: showSessionPanel ? 0 : 320,
{/* showSessionPanel: !showSessionPanel,*/} showSessionPanel: !showSessionPanel,
{/* });*/} });
{/* }}*/} }}
{/* size={DESKTOP_HEADER_ICON_SIZE}*/} size={DESKTOP_HEADER_ICON_SIZE}
{/* title={t('agents')}*/} title={t('agents')}
{/* />*/} />
{/*}*/} }
<Avatar <Avatar
avatar={avatar} avatar={avatar}
background={backgroundColor} background={backgroundColor}
@ -70,11 +70,7 @@ const Main = memo(() => {
size={40} size={40}
title={title} title={title}
/> />
<div> <ChatHeaderTitle desc={displayDesc} tag={<Tags />} title={displayTitle} />
<div style={{ fontSize: "15px" }}>{displayTitle}</div>
{/*<ChatHeaderTitle desc={displayDesc} title={displayTitle} />*/}
<div style={{ color: "#A7A0A0", fontSize: '12px' }}>{displayTitle}</div>
</div>
</Flexbox> </Flexbox>
); );
}); });

@ -3,26 +3,21 @@
import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui'; import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
import { createStyles, useResponsive } from 'antd-style'; import { createStyles, useResponsive } from 'antd-style';
import isEqual from 'fast-deep-equal'; import isEqual from 'fast-deep-equal';
import { memo, useEffect, useState } from 'react'; import { PropsWithChildren, memo, useEffect, useState } from 'react';
// import SafeSpacing from '@/components/SafeSpacing'; import SafeSpacing from '@/components/SafeSpacing';
import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens'; import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
import { useChatStore } from '@/store/chat'; import { useChatStore } from '@/store/chat';
import { chatPortalSelectors } from '@/store/chat/slices/portal/selectors'; import { chatPortalSelectors } from '@/store/chat/slices/portal/selectors';
import { useGlobalStore } from '@/store/global'; import { useGlobalStore } from '@/store/global';
import { systemStatusSelectors } from '@/store/global/selectors'; import { systemStatusSelectors } from '@/store/global/selectors';
import {Form, Image} from "antd"; import { Image } from "antd";
import {EditFilled} from "@ant-design/icons";
import TopicListContent from "@/app/(main)/chat/(workspace)/@topic/features/TopicListContent";
import Header from "@/app/(main)/chat/(workspace)/@topic/features/Header";
const useStyles = createStyles(({ css, token }) => ({ const useStyles = createStyles(({ css, token }) => ({
content: css` content: css`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: calc(100% - 64px) !important; height: 100% !important;
margin-top: 64px;
width: 363px !important;
`, `,
drawer: css` drawer: css`
z-index: 10; z-index: 10;
@ -31,24 +26,10 @@ const useStyles = createStyles(({ css, token }) => ({
header: css` header: css`
border-block-end: 1px solid ${token.colorBorder}; border-block-end: 1px solid ${token.colorBorder};
`, `,
topEdit: css`
display: inline-block;
text-align: center;
width: 24px;
height: 24px;
background-color: #AFC1FF;
color: #fff;
`,
topTitle: css`
font-size: 18px;
display: inline-block;
width: calc(100% - 24px)
`,
})); }));
const TopicPanel = memo(() => { const TopicPanel = memo(({ children }: PropsWithChildren) => {
const { styles } = useStyles(); const { styles } = useStyles();
const [form] = Form.useForm()
const { md = true, lg = true } = useResponsive(); const { md = true, lg = true } = useResponsive();
const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [ const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
systemStatusSelectors.showChatSideBar(s), systemStatusSelectors.showChatSideBar(s),
@ -87,38 +68,13 @@ const TopicPanel = memo(() => {
style={{ style={{
flex: 'none', flex: 'none',
height: '100%', height: '100%',
border: "1px solid #ddd",
maxHeight: '100vh', maxHeight: '100vh',
minWidth: CHAT_SIDEBAR_WIDTH, minWidth: CHAT_SIDEBAR_WIDTH,
}} }}
> >
<div style={{ padding: '15px 20px'}}> <SafeSpacing />
<div className={styles.topTitle}></div>
<div className={styles.topEdit}><EditFilled /></div>
</div>
<div><Image alt="头像" preview={false} src="/images/zsImage.png" /></div> <div><Image alt="头像" preview={false} src="/images/zsImage.png" /></div>
<Form colon={false} form={form} labelCol={{ span: 6 }} layout="horizontal" wrapperCol={{ span: 18 }}> {children}
<Form.Item label="名称" name="name">
<span style={{ width: "18px" }}>Linda</span>
</Form.Item>
<Form.Item label="简介" name="jj">
<span style={{ color: "#999999", fontSize: '13px' }}></span>
</Form.Item>
<Form.Item label="任务" name="rw">
<span style={{ color: "#999999", fontSize: '13px' }}></span>
</Form.Item>
</Form>
{/*<div style={{ display: 'flex' }}>*/}
{/* <div style={{ width: '25%', textAlign: 'right' }}>话题</div>*/}
{/* <div style={{ width: '75%', height: 'calc(100vh - 800px)' }}>*/}
<div>
<Header />
<TopicListContent />
</div>
{/*</div>*/}
{/*</div>*/}
{/*<SafeSpacing />*/}
{/*{children}*/}
</DraggablePanelContainer> </DraggablePanelContainer>
</DraggablePanel> </DraggablePanel>
) )

@ -1,24 +1,19 @@
'use client'; 'use client';
import { ActionIcon } from '@lobehub/ui'; // import { ActionIcon } from '@lobehub/ui';
import { AlignJustify } from 'lucide-react'; // import { AlignJustify } from 'lucide-react';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; // import { useTranslation } from 'react-i18next';
import {Button} from "antd";
import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens'; // import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes'; import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
const SettingButton = memo<{ mobile?: boolean }>(({ mobile }) => { const SettingButton = memo<{ mobile?: boolean }>(() => {
const { t } = useTranslation('common'); // const { t } = useTranslation('common');
const openChatSettings = useOpenChatSettings(); const openChatSettings = useOpenChatSettings();
return ( return (
<ActionIcon <Button onClick={() => openChatSettings()} shape="round" style={{borderColor: '#2E62FF', color: "#2E62FF", fontSize: '13px',height: '30px' }}></Button>
icon={AlignJustify}
onClick={() => openChatSettings()}
size={mobile ? MOBILE_HEADER_ICON_SIZE : DESKTOP_HEADER_ICON_SIZE}
title={t('header.session', { ns: 'setting' })}
/>
); );
}); });

@ -0,0 +1,16 @@
import { Markdown } from '@lobehub/ui';
import { memo } from 'react';
import { useContainerStyles } from '../style';
const Preview = memo<{ content: string }>(({ content }) => {
const { styles } = useContainerStyles();
return (
<div className={styles.preview} style={{ padding: 12 }}>
<Markdown>{content}</Markdown>
</div>
);
});
export default Preview;

@ -0,0 +1,102 @@
// import { Form, type FormItemProps, Icon, copyToClipboard } from '@lobehub/ui';
import { Button } from 'antd';
import isEqual from 'fast-deep-equal';
// import { CopyIcon } from 'lucide-react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
// import { FORM_STYLE } from '@/const/layoutTokens';
import { useIsMobile } from '@/hooks/useIsMobile';
import { useAgentStore } from '@/store/agent';
import { agentSelectors } from '@/store/agent/selectors';
import { useChatStore } from '@/store/chat';
import { chatSelectors, topicSelectors } from '@/store/chat/selectors';
import { FieldType } from './type';
import { LOADING_FLAT } from '@/const/message';
import { stringify as csvStringify } from 'csv-stringify';
const DEFAULT_FIELD_VALUE: FieldType = {
includeTool: true,
includeUser: true,
withRole: true,
withSystemRole: false,
};
const ShareText = memo(() => {
// const [fieldValue, setFieldValue] = useState(DEFAULT_FIELD_VALUE);
const { t } = useTranslation(['chat', 'common']);
// const { message } = App.useApp();
const [systemRole] = useAgentStore((s) => [agentSelectors.currentAgentSystemRole(s)]);
const messages = useChatStore(chatSelectors.currentChats, isEqual);
const topic = useChatStore(topicSelectors.currentActiveTopic, isEqual);
console.log(systemRole,messages,'83737373737')
let messagesNew = messages
.filter((m) => m.content !== LOADING_FLAT)
.filter((m) => (!DEFAULT_FIELD_VALUE.includeUser ? m.role !== 'user' : true))
.filter((m) => (!DEFAULT_FIELD_VALUE.includeTool ? m.role !== 'tool' : true))
console.log(messagesNew,'111111111111111')
const topicTitle = topic?.title || t('shareModal.exportTitle');
console.log(topicTitle,'22222222222222222')
const isMobile = useIsMobile();
const downloadCSV = () => {
const data = [
["question", "answer"],
];
let arrItem = [];
messagesNew.forEach((chat)=> {
if (chat.role === 'assistant') {
arrItem.push(chat.content)
} else if(chat.role === 'user') {
arrItem.unshift(chat.content)
}
if(arrItem.length >= 2) {
data.push(arrItem)
arrItem = [];
}
})
console.log(data,'9999111111')
// 将数据转换为CSV字符串
let csvContent = "";
csvStringify(data, (err, output) => {
if (err) {
console.error('Error generating CSV:', err);
return;
}
// 输出 CSV 字符串
console.log(output,'66666666666666');
csvContent = output
// 创建一个Blob对象
const blob = new Blob([csvContent], { type: 'text/csv' });
// 创建一个URL并指向Blob对象
const url = URL.createObjectURL(blob);
// 创建一个隐藏的<a>标签并点击它以触发下载
const a = document.createElement('a');
a.setAttribute('hidden', '');
a.setAttribute('href', url);
a.setAttribute('download', topicTitle + '.csv');
document.body.append(a);
a.click();
// 移除<a>标签
a.remove();
// 释放URL对象
URL.revokeObjectURL(url);
});
}
return (
<Flexbox gap={16} horizontal={!isMobile}>
<Button onClick={() => downloadCSV()} shape="round" style={{borderColor: '#2E62FF', color: "#2E62FF",fontSize: '13px',height: '30px'}}></Button>
</Flexbox>
);
});
export default ShareText;

@ -0,0 +1,178 @@
import { describe, expect, it } from 'vitest';
import { LOADING_FLAT } from '@/const/message';
import { ChatMessage } from '@/types/message';
import { generateMarkdown } from './template';
describe('generateMarkdown', () => {
// 创建测试用的消息数据
const mockMessages = [
{
id: '1',
content: 'Hello',
role: 'user',
createdAt: Date.now(),
},
{
id: '2',
content: 'Hi there',
role: 'assistant',
createdAt: Date.now(),
},
{
id: '3',
content: LOADING_FLAT,
role: 'assistant',
createdAt: Date.now(),
},
{
id: '4',
content: '{"result": "tool data"}',
role: 'tool',
createdAt: Date.now(),
tool_call_id: 'tool1',
},
{
id: '5',
content: 'Message with tools',
role: 'assistant',
createdAt: Date.now(),
tools: [{ name: 'calculator', result: '42' }],
},
] as ChatMessage[];
const defaultParams = {
messages: mockMessages,
title: 'Chat Title',
includeTool: false,
includeUser: true,
withSystemRole: false,
withRole: false,
systemRole: '',
};
it('should generate basic markdown with title', () => {
const result = generateMarkdown(defaultParams);
expect(result).toContain('# Chat Title');
expect(result).toContain('Hello');
expect(result).toContain('Hi there');
});
it('should include system role when withSystemRole is true', () => {
const systemRole = 'I am a helpful assistant';
const result = generateMarkdown({
...defaultParams,
withSystemRole: true,
systemRole,
});
expect(result).toContain('````md\nI am a helpful assistant\n````');
});
it('should not include system role when withSystemRole is false', () => {
const systemRole = 'I am a helpful assistant';
const result = generateMarkdown({
...defaultParams,
withSystemRole: false,
systemRole,
});
expect(result).not.toContain('```\nI am a helpful assistant\n```');
});
it('should add role labels when withRole is true', () => {
const result = generateMarkdown({
...defaultParams,
withRole: true,
});
expect(result).toContain('##### User:');
expect(result).toContain('##### Assistant:');
});
it('should not add role labels when withRole is false', () => {
const result = generateMarkdown({
...defaultParams,
withRole: false,
});
expect(result).not.toContain('##### User:');
expect(result).not.toContain('##### Assistant:');
});
it('should include tool messages when includeTool is true', () => {
const result = generateMarkdown({
...defaultParams,
includeTool: true,
withRole: true,
});
expect(result).toContain('##### Tools Calling:');
expect(result).toContain('```json\n{"result": "tool data"}\n```');
});
it('should exclude tool messages when includeTool is false', () => {
const result = generateMarkdown({
...defaultParams,
includeTool: false,
});
expect(result).not.toContain('{"result": "tool data"}');
});
it('should exclude user messages when includeUser is false', () => {
const result = generateMarkdown({
...defaultParams,
includeUser: false,
});
expect(result).not.toContain('Hello');
expect(result).toContain('Hi there');
});
it('should filter out loading messages', () => {
const result = generateMarkdown(defaultParams);
expect(result).not.toContain(LOADING_FLAT);
});
it('should include tools data when includeTool is true', () => {
const result = generateMarkdown({
...defaultParams,
includeTool: true,
});
expect(result).toContain('"name": "calculator"');
expect(result).toContain('"result": "42"');
});
it('should handle empty messages array', () => {
const result = generateMarkdown({
...defaultParams,
messages: [],
});
expect(result).toContain('# Chat Title');
// Should not throw error and should contain at least the title
});
it('should handle messages with special characters', () => {
const messagesWithSpecialChars = [
{
id: '1',
content: '**Bold** *Italic* `Code`',
role: 'user',
createdAt: Date.now(),
},
] as ChatMessage[];
const result = generateMarkdown({
...defaultParams,
messages: messagesWithSpecialChars,
});
expect(result).toContain('**Bold** *Italic* `Code`');
});
});

@ -0,0 +1,79 @@
import { template } from 'lodash-es';
import { LOADING_FLAT } from '@/const/message';
import { FieldType } from '@/features/ShareModal/ShareText/type';
import { ChatMessage } from '@/types/message';
const markdownTemplate = template(
`# {{title}}
<% if (systemRole) { %>
\`\`\`\`md
{{systemRole}}
\`\`\`\`
<% } %>
<% messages.forEach(function(chat) { %>
<% if (withRole) { %>
<% if (chat.role === 'user') { %>
##### User:
<% } else if (chat.role === 'assistant') { %>
##### Assistant:
<% } else if (chat.role === 'tool') { %>
##### Tools Calling:
<% } %>
<% } %>
<% if (chat.role === 'tool') { %>
\`\`\`json
{{chat.content}}
\`\`\`
<% } else { %>
{{chat.content}}
<% if (includeTool && chat.tools) { %>
\`\`\`json
{{JSON.stringify(chat.tools, null, 2)}}
\`\`\`
<% } %>
<% } %>
<% }); %>
`,
{
evaluate: /<%([\S\s]+?)%>/g,
interpolate: /{{([\S\s]+?)}}/g,
},
);
interface MarkdownParams extends FieldType {
messages: ChatMessage[];
systemRole: string;
title: string;
}
export const generateMarkdown = ({
messages,
title,
includeTool,
includeUser,
withSystemRole,
withRole,
systemRole,
}: MarkdownParams) =>
markdownTemplate({
includeTool,
messages: messages
.filter((m) => m.content !== LOADING_FLAT)
.filter((m) => (!includeUser ? m.role !== 'user' : true))
.filter((m) => (!includeTool ? m.role !== 'tool' : true)),
systemRole: withSystemRole ? systemRole : undefined,
title,
withRole,
});

@ -0,0 +1,6 @@
export type FieldType = {
includeTool: boolean;
includeUser: boolean;
withRole: boolean;
withSystemRole: boolean;
};

@ -1,18 +1,18 @@
'use client'; 'use client';
import { ActionIcon } from '@lobehub/ui'; // import { ActionIcon } from '@lobehub/ui';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import { MessageSquarePlus } from 'lucide-react'; // import { MessageSquarePlus } from 'lucide-react';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; // import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit'; import { Flexbox } from 'react-layout-kit';
import { ProductLogo } from '@/components/Branding'; // import { ProductLogo } from '@/components/Branding';
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens'; // import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import SyncStatusTag from '@/features/SyncStatusInspector'; // import SyncStatusTag from '@/features/SyncStatusInspector';
import { useActionSWR } from '@/libs/swr'; // import { useActionSWR } from '@/libs/swr';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig'; // import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
import { useSessionStore } from '@/store/session'; // import { useSessionStore } from '@/store/session';
import SessionSearchBar from '../../features/SessionSearchBar'; import SessionSearchBar from '../../features/SessionSearchBar';
@ -30,31 +30,15 @@ export const useStyles = createStyles(({ css, token }) => ({
const Header = memo(() => { const Header = memo(() => {
const { styles } = useStyles(); const { styles } = useStyles();
const { t } = useTranslation('chat'); // const { t } = useTranslation('chat');
const [createSession] = useSessionStore((s) => [s.createSession]); // const [createSession] = useSessionStore((s) => [s.createSession]);
const { enableWebrtc, showCreateSession } = useServerConfigStore(featureFlagsSelectors); // const { enableWebrtc, showCreateSession } = useServerConfigStore(featureFlagsSelectors);
const { mutate, isValidating } = useActionSWR('session.createSession', () => createSession()); // const { mutate, isValidating } = useActionSWR('session.createSession', () => createSession());
return ( return (
<Flexbox className={styles.top} gap={16} padding={16}> <Flexbox className={styles.top} gap={16} padding={16}>
{/*<Flexbox distribution={'space-between'} horizontal>*/} <SessionSearchBar />
{/* <Flexbox align={'center'} gap={4} horizontal>*/}
{/* <ProductLogo className={styles.logo} size={36} type={'text'} />*/}
{/* {enableWebrtc && <SyncStatusTag />}*/}
{/* </Flexbox>*/}
{/* {showCreateSession && (*/}
{/* <ActionIcon*/}
{/* icon={MessageSquarePlus}*/}
{/* loading={isValidating}*/}
{/* onClick={() => mutate()}*/}
{/* size={DESKTOP_HEADER_ICON_SIZE}*/}
{/* style={{ flex: 'none' }}*/}
{/* title={t('newAgent')}*/}
{/* />*/}
{/* )}*/}
{/*</Flexbox>*/}
{/*<SessionSearchBar />*/}
</Flexbox> </Flexbox>
); );
}); });

@ -2,38 +2,33 @@ import Link from 'next/link';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { DEFAULT_INBOX_AVATAR } from '@/const/meta'; // import { DEFAULT_INBOX_AVATAR } from '@/const/meta';
import { INBOX_SESSION_ID } from '@/const/session'; import { INBOX_SESSION_ID } from '@/const/session';
import { SESSION_CHAT_URL } from '@/const/url'; import { SESSION_CHAT_URL } from '@/const/url';
import { useServerConfigStore } from '@/store/serverConfig'; import { useServerConfigStore } from '@/store/serverConfig';
import { useSessionStore } from '@/store/session'; // import { useSessionStore } from '@/store/session';
import ListItem from '../ListItem'; // import ListItem from '../ListItem';
import { useSwitchSession } from '../useSwitchSession'; import { useSwitchSession } from '../useSwitchSession';
import {Image} from "antd"; import {Image} from "antd";
const Inbox = memo(() => { const Inbox = memo(() => {
const { t } = useTranslation('chat'); const { t } = useTranslation('chat');
const mobile = useServerConfigStore((s) => s.isMobile); const mobile = useServerConfigStore((s) => s.isMobile);
const activeId = useSessionStore((s) => s.activeId); // const activeId = useSessionStore((s) => s.activeId);
const switchSession = useSwitchSession(); const switchSession = useSwitchSession();
return ( return (
<Link <Link
style={{ textAlign: 'center' }}
aria-label={t('inbox.title')} aria-label={t('inbox.title')}
href={SESSION_CHAT_URL(INBOX_SESSION_ID, mobile)} href={SESSION_CHAT_URL(INBOX_SESSION_ID, mobile)}
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
switchSession(INBOX_SESSION_ID); switchSession(INBOX_SESSION_ID);
}} }}
style={{ textAlign: 'center' }}
> >
<Image alt={'sbChat'} src="/images/sbChat.png" preview={false} /> <Image alt={'sbChat'} preview={false} src="/images/sbChat.png" />
{/*<ListItem*/}
{/* active={activeId === INBOX_SESSION_ID}*/}
{/* avatar={DEFAULT_INBOX_AVATAR}*/}
{/* title={t('inbox.title')}*/}
{/*/>*/}
</Link> </Link>
); );
}); });

@ -27,7 +27,6 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
const [active] = useSessionStore((s) => [s.activeId === id]); const [active] = useSessionStore((s) => [s.activeId === id]);
const [loading] = useChatStore((s) => [chatSelectors.isAIGenerating(s) && id === s.activeId]); const [loading] = useChatStore((s) => [chatSelectors.isAIGenerating(s) && id === s.activeId]);
const [pin, title, description, avatar, avatarBackground, updateAt, model, group] = const [pin, title, description, avatar, avatarBackground, updateAt, model, group] =
useSessionStore((s) => { useSessionStore((s) => {
const session = sessionSelectors.getSessionById(id)(s); const session = sessionSelectors.getSessionById(id)(s);
@ -72,7 +71,6 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
return ( return (
<> <>
<ListItem <ListItem
style={{ position: "relative"}}
actions={actions} actions={actions}
active={active} active={active}
addon={addon} addon={addon}
@ -83,10 +81,11 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
loading={loading} loading={loading}
pin={pin} pin={pin}
showAction={open} showAction={open}
style={{ position: "relative"}}
title={title} title={title}
> >
{window.localStorage.getItem("nowChat") == id ? <div style={{position: 'absolute', right: "40px", top: '15px', textAlign: 'center', color: '#1139FF'}}> {active ? <div style={{color: '#1139FF', position: 'absolute', right: "40px", textAlign: 'center', top: '15px'}}>
<AlignCenterOutlined rotate={90}/><br/></div> : <></>} <AlignCenterOutlined rotate={90}/><br/></div> : null}
</ListItem> </ListItem>
<CreateGroupModal <CreateGroupModal
id={id} id={id}

@ -49,7 +49,6 @@ const SessionList = memo<SessionListProps>(({ dataSource, groupId, showAddButton
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
switchSession(id); switchSession(id);
localStorage.setItem("nowChat", id)
}} }}
> >
<SessionItem id={id} /> <SessionItem id={id} />

@ -10,7 +10,7 @@ const Layout = ({ children, session }: LayoutProps) => {
<Flexbox <Flexbox
height={'100%'} height={'100%'}
horizontal horizontal
style={{ maxWidth: 'calc(100vw - 100px)', maxHeight: "calc(100vh - 46px)", overflow: 'hidden', position: 'relative' }} style={{ maxHeight: "calc(100vh - 46px)", maxWidth: 'calc(100vw - 100px)', overflow: 'hidden', position: 'relative' }}
width={'100%'} width={'100%'}
> >
<SessionPanel>{session}</SessionPanel> <SessionPanel>{session}</SessionPanel>

@ -14,6 +14,7 @@ const ChatSettingsModalFallback = () => {
const router = useQueryRoute(); const router = useQueryRoute();
useLayoutEffect(() => { useLayoutEffect(() => {
router.replace('/chat/settings', { query: { tab: '' } }); router.replace('/chat/settings', { query: { tab: '' } });
}, []); }, []);

@ -16,11 +16,31 @@ import { DiscoverAssistantItem } from '@/types/discover';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
import GitHubAvatar from '../../../../components/GitHubAvatar'; import GitHubAvatar from '../../../../components/GitHubAvatar';
import Actions from './Actions'; import Actions from './Actions';
export const useStyles = createStyles(({ css, token }) => ({ export const useStyles = createStyles(({ css, token }) => ({
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
// tag: css`
// color: ${token.colorTextSecondary};
// background: ${token.colorFillSecondary};
// border: none;
// `,
tag: css` tag: css`
color: ${token.colorTextSecondary}; padding: 0px 45px;
background: ${token.colorFillSecondary}; margin-bottom: 10px;
border: none;
`, `,
time: css` time: css`
font-size: 12px; font-size: 12px;
@ -40,30 +60,11 @@ export const useStyles = createStyles(({ css, token }) => ({
border-color: rgba(187, 204, 253, 0.24); border-color: rgba(187, 204, 253, 0.24);
padding: 20px 50px; padding: 20px 50px;
`, `,
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
topBtn: css` topBtn: css`
border-radius: 20px; border-radius: 20px;
color: #2E62FF; color: #2E62FF;
border: 1px solid #2E62FF; border: 1px solid #2E62FF;
`, `,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css`
padding: 0px 45px;
margin-bottom: 10px;
`,
})); }));
interface HeaderProps { interface HeaderProps {

@ -21,7 +21,7 @@ interface ConversationExampleProps extends FlexboxProps {
const ConversationExample = memo<ConversationExampleProps>(({ data }) => { const ConversationExample = memo<ConversationExampleProps>(({ data }) => {
// const { t } = useTranslation('discover'); // const { t } = useTranslation('discover');
const theme = useTheme(); const theme = useTheme();
console.log(data.config.systemRole,111111111) console.log(data.config.systemRole)
return ( return (
<Flexbox paddingInline={16} style={{padding: '0 45'}}> <Flexbox paddingInline={16} style={{padding: '0 45'}}>
{data.config.systemRole ? ( {data.config.systemRole ? (

@ -7,7 +7,7 @@ import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata'; import { metadataModule } from '@/server/metadata';
import { DiscoverService } from '@/server/services/discover'; import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { DiscoverPlugintem } from '@/types/discover'; // import { DiscoverPlugintem } from '@/types/discover';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import DetailLayout from '../../features/DetailLayout'; import DetailLayout from '../../features/DetailLayout';
@ -65,7 +65,7 @@ const Page = async ({ params, searchParams }: Props) => {
const data = await discoverService.getAssistantById(locale, identifier); const data = await discoverService.getAssistantById(locale, identifier);
if (!data) return notFound(); if (!data) return notFound();
console.log(data,'37373733737') console.log(data,'37373733737')
const { meta, createdAt, author, config } = data; const { meta, createdAt, author } = data;
// let pluginData: DiscoverPlugintem[] = []; // let pluginData: DiscoverPlugintem[] = [];
// if (config?.plugins && config.plugins?.length > 0) { // if (config?.plugins && config.plugins?.length > 0) {

@ -39,7 +39,7 @@ const DetailLayout = memo<DetailLayoutProps>(
<div style={{ backgroundColor: '#fff'}}> <div style={{ backgroundColor: '#fff'}}>
{header} {header}
<Flexbox gap={32} horizontal width={'100%'}> <Flexbox gap={32} horizontal width={'100%'}>
<Flexbox flex={1} gap={48} style={{ overflow: 'hidden', position: 'relative',padding: '0 30px' }}> <Flexbox flex={1} gap={48} style={{ overflow: 'hidden', padding: '0 30px', position: 'relative'}}>
{children} {children}
<Footer /> <Footer />
</Flexbox> </Flexbox>

@ -3,7 +3,7 @@
import { ModelIcon } from '@lobehub/icons'; import { ModelIcon } from '@lobehub/icons';
import { Button } from 'antd'; import { Button } from 'antd';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import Link from 'next/link'; // import Link from 'next/link';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit'; import { Flexbox } from 'react-layout-kit';
@ -12,13 +12,32 @@ import { DiscoverModelItem } from '@/types/discover';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
import ModelFeatureTags from '../../../../features/ModelFeatureTags'; import ModelFeatureTags from '../../../../features/ModelFeatureTags';
import Back from '../../../features/Back'; // import Back from '../../../features/Back';
export const useStyles = createStyles(({ css, token }) => ({ export const useStyles = createStyles(({ css, token }) => ({
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
// tag: css`
// color: ${token.colorTextSecondary};
// background: ${token.colorFillSecondary};
// border: none;
// `,
tag: css` tag: css`
color: ${token.colorTextSecondary}; padding: 0px 45px;
background: ${token.colorFillSecondary}; margin-bottom: 10px;
border: none;
`, `,
time: css` time: css`
font-size: 12px; font-size: 12px;
@ -43,25 +62,6 @@ export const useStyles = createStyles(({ css, token }) => ({
color: #2E62FF; color: #2E62FF;
border: 1px solid #2E62FF; border: 1px solid #2E62FF;
`, `,
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css`
padding: 0px 45px;
margin-bottom: 10px;
`,
})); }));
interface HeaderProps { interface HeaderProps {
@ -70,18 +70,19 @@ interface HeaderProps {
mobile?: boolean; mobile?: boolean;
} }
const getUserId = (s) => s.user?.id
const Header = memo<HeaderProps>(({ identifier, data, mobile }) => { const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
const { styles, theme } = useStyles(); const { styles, theme } = useStyles();
const router = useRouter() const router = useRouter()
const { t } = useTranslation(['discover', 'models']); const { t } = useTranslation(['discover', 'models']);
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
const handleBack = () => { const handleBack = () => {
router.push('/discover/models?userid=' + userId) router.push('/discover/models?userid=' + userId)
} }
return ( return (
<Flexbox gap={12} width={'100%'}> <Flexbox gap={12} width={'100%'}>
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'} className={styles.top}> <Flexbox align={'center'} className={styles.top} gap={8} horizontal justify={'space-between'} width={'100%'}>
<Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}> <Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}>
<ModelIcon model={identifier} size={48} type={'avatar'} /> <ModelIcon model={identifier} size={48} type={'avatar'} />
<Flexbox gap={2}> <Flexbox gap={2}>

@ -11,9 +11,9 @@ import { DiscoverProviderItem } from '@/types/discover';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import DetailLayout from '../../features/DetailLayout'; import DetailLayout from '../../features/DetailLayout';
import Actions from './features/Actions'; // import Actions from './features/Actions';
import Header from './features/Header'; import Header from './features/Header';
import InfoSidebar from './features/InfoSidebar'; // import InfoSidebar from './features/InfoSidebar';
import ParameterList from './features/ParameterList'; import ParameterList from './features/ParameterList';
import ProviderList from './features/ProviderList'; import ProviderList from './features/ProviderList';

@ -2,12 +2,12 @@
import { memo } from 'react'; import { memo } from 'react';
import { Flexbox, FlexboxProps } from 'react-layout-kit'; import { Flexbox, FlexboxProps } from 'react-layout-kit';
import urlJoin from 'url-join'; // import urlJoin from 'url-join';
import { OFFICIAL_URL } from '@/const/url'; // import { OFFICIAL_URL } from '@/const/url';
import { DiscoverPlugintem } from '@/types/discover'; import { DiscoverPlugintem } from '@/types/discover';
import ShareButton from '../../../features/ShareButton'; // import ShareButton from '../../../features/ShareButton';
import InstallTool from './InstallPlugin'; import InstallTool from './InstallPlugin';
interface PluginActionsProps extends FlexboxProps { interface PluginActionsProps extends FlexboxProps {
@ -15,19 +15,10 @@ interface PluginActionsProps extends FlexboxProps {
identifier: string; identifier: string;
} }
const PluginActions = memo<PluginActionsProps>(({ identifier, data }) => { const PluginActions = memo<PluginActionsProps>(({ identifier }) => {
return ( return (
<Flexbox align={'center'} gap={8} horizontal> <Flexbox align={'center'} gap={8} horizontal style={{marginLeft: 100}}>
<InstallTool identifier={identifier} /> <InstallTool identifier={identifier} />
<ShareButton
meta={{
avatar: data.meta.avatar,
desc: data.meta.description,
hashtags: data.meta.tags,
title: data.meta.title,
url: urlJoin(OFFICIAL_URL, '/discover/plugin', identifier),
}}
/>
</Flexbox> </Flexbox>
); );
}); });

@ -1,26 +1,41 @@
'use client'; 'use client';
import { Avatar, Icon, Tag } from '@lobehub/ui'; import { Avatar, Tag } from '@lobehub/ui';
import { Button } from 'antd'; import { Button } from 'antd';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import { startCase } from 'lodash-es'; import { startCase } from 'lodash-es';
import { ChevronRight } from 'lucide-react'; // import { ChevronRight } from 'lucide-react';
import Link from 'next/link'; import Link from 'next/link';
import qs from 'query-string'; // import qs from 'query-string';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; // import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit'; import { Flexbox } from 'react-layout-kit';
import urlJoin from 'url-join'; // import urlJoin from 'url-join';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { DiscoverPlugintem } from '@/types/discover'; import { DiscoverPlugintem } from '@/types/discover';
import Actions from './Actions';
// import Back from '../../../features/Back';
import Back from '../../../features/Back';
export const useStyles = createStyles(({ css, token }) => ({ export const useStyles = createStyles(({ css, token }) => ({
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css` tag: css`
color: ${token.colorTextSecondary}; padding: 0px 45px;
background: ${token.colorFillSecondary}; margin-bottom: 10px;
border: none;
`, `,
time: css` time: css`
font-size: 12px; font-size: 12px;
@ -45,25 +60,6 @@ export const useStyles = createStyles(({ css, token }) => ({
color: #2E62FF; color: #2E62FF;
border: 1px solid #2E62FF; border: 1px solid #2E62FF;
`, `,
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css`
padding: 0px 45px;
margin-bottom: 10px;
`,
})); }));
interface HeaderProps { interface HeaderProps {
@ -71,19 +67,19 @@ interface HeaderProps {
identifier: string; identifier: string;
mobile?: boolean; mobile?: boolean;
} }
const getUserId = (s) => s.user?.id
const Header = memo<HeaderProps>(({ identifier, data, mobile }) => { const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
const { styles, theme } = useStyles(); const { styles, theme } = useStyles();
const router = useRouter() const router = useRouter()
const { t } = useTranslation('discover'); // const { t } = useTranslation('discover');
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
const handleBack = () => { const handleBack = () => {
router.push('/discover/plugins?userid=' + userId) router.push('/discover/plugins?userid=' + userId)
} }
return ( return (
<Flexbox gap={12} width={'100%'}> <Flexbox gap={12} width={'100%'}>
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'} className={styles.top}> <Flexbox align={'center'} className={styles.top} gap={8} horizontal justify={'space-between'} width={'100%'}>
<Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}> <Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}>
<Avatar <Avatar
alt={identifier} alt={identifier}
@ -104,6 +100,7 @@ const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
</time> </time>
</Flexbox> </Flexbox>
</Flexbox> </Flexbox>
<Actions data={data} identifier={identifier} />
</Flexbox> </Flexbox>
{!mobile && ( {!mobile && (
<Flexbox align={'center'} gap={4} horizontal justify={'flex-end'}> <Flexbox align={'center'} gap={4} horizontal justify={'flex-end'}>

@ -10,9 +10,10 @@ import { pluginSelectors, pluginStoreSelectors } from '@/store/tool/selectors';
const useStyles = createStyles(({ css }) => ({ const useStyles = createStyles(({ css }) => ({
button: css` button: css`
button { background-color: #fff;
width: 100%; border: 1px solid #2E62FF;
} border-radius: 20px;
color: #2E62FF !important;
`, `,
})); }));
@ -77,7 +78,6 @@ const InstallPlugin = memo<{ identifier: string }>(({ identifier }) => {
}} }}
size={'large'} size={'large'}
style={{ flex: 1, width: 'unset' }} style={{ flex: 1, width: 'unset' }}
type={installed ? 'default' : 'primary'}
> >
{t(installed ? 'plugins.installed' : 'plugins.install')} {t(installed ? 'plugins.installed' : 'plugins.install')}
</Button> </Button>

@ -10,9 +10,9 @@ import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import DetailLayout from '../../features/DetailLayout'; import DetailLayout from '../../features/DetailLayout';
import Actions from './features/Actions'; // import Actions from './features/Actions';
import Header from './features/Header'; import Header from './features/Header';
import InfoSidebar from './features/InfoSidebar'; // import InfoSidebar from './features/InfoSidebar';
import ParameterList from './features/ParameterList'; import ParameterList from './features/ParameterList';
import Schema from './features/Schema'; import Schema from './features/Schema';

@ -4,7 +4,7 @@ import { Flexbox } from 'react-layout-kit';
import Footer from '@/features/Setting/Footer'; import Footer from '@/features/Setting/Footer';
import { MAX_WIDTH, SCROLL_PARENT_ID } from '../../../features/const'; import { MAX_WIDTH, SCROLL_PARENT_ID } from '../../../features/const';
import Nav from './Nav'; // import Nav from './Nav';
const Layout = ({ children }: PropsWithChildren) => { const Layout = ({ children }: PropsWithChildren) => {
return ( return (

@ -8,7 +8,6 @@ import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { AssistantCategory } from '@/types/discover'; import { AssistantCategory } from '@/types/discover';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import request from '@/app/api/request';
import List from '../features/List'; import List from '../features/List';
type Props = { params: { slug: AssistantCategory }; searchParams: { hl?: Locales } }; type Props = { params: { slug: AssistantCategory }; searchParams: { hl?: Locales } };
@ -31,9 +30,9 @@ const Page = async ({ params, searchParams }: Props) => {
const { t: td } = await translation('discover', searchParams?.hl); const { t: td } = await translation('discover', searchParams?.hl);
const mobile = isMobileDevice(); const mobile = isMobileDevice();
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
console.log(params.slug,3333333) console.log(params.slug,"3333333")
const items = await discoverService.getAssistantCategory(locale, params.slug); const items = await discoverService.getAssistantCategory(locale, params.slug);
console.log(8272772727,items) console.log("8272772727",items)
const ld = ldModule.generate({ const ld = ldModule.generate({
description: t('discover.assistants.description'), description: t('discover.assistants.description'),
title: [td(`category.assistant.${params.slug}`), t('discover.assistants.title')].join(' · '), title: [td(`category.assistant.${params.slug}`), t('discover.assistants.title')].join(' · '),

@ -1,12 +1,12 @@
import { Avatar, Tag } from '@lobehub/ui'; import { Avatar, Tag } from '@lobehub/ui';
import { Skeleton, Typography, App } from 'antd'; import { Typography, App } from 'antd';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import { startCase } from 'lodash-es'; import { startCase } from 'lodash-es';
import dynamic from 'next/dynamic'; // import dynamic from 'next/dynamic';
import qs from 'query-string'; // import qs from 'query-string';
import { memo, useState } from 'react'; import { memo, useState } from 'react';
import { Center, Flexbox, FlexboxProps } from 'react-layout-kit'; import { Center, Flexbox, FlexboxProps } from 'react-layout-kit';
import urlJoin from 'url-join'; // import urlJoin from 'url-join';
import request from '@/app/api/request'; import request from '@/app/api/request';
import { DiscoverAssistantItem } from '@/types/discover'; import { DiscoverAssistantItem } from '@/types/discover';
import CardBanner from '../../../components/CardBanner'; import CardBanner from '../../../components/CardBanner';
@ -15,10 +15,11 @@ import { useCategoryItem } from '../../assistants/features/useCategory';
import { StarOutlined } from '@ant-design/icons'; import { StarOutlined } from '@ant-design/icons';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const Link = dynamic(() => import('next/link'), {
loading: () => <Skeleton.Button size={'small'} style={{ height: 22 }} />, // const Link = dynamic(() => import('next/link'), {
ssr: false, // loading: () => <Skeleton.Button size={'small'} style={{ height: 22 }} />,
}); // ssr: false,
// });
const { Paragraph, Title } = Typography; const { Paragraph, Title } = Typography;
@ -26,6 +27,15 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
banner: css` banner: css`
opacity: ${isDarkMode ? 0.9 : 0.4}; opacity: ${isDarkMode ? 0.9 : 0.4};
`, `,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
container: css` container: css`
cursor: pointer; cursor: pointer;
@ -60,15 +70,6 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
margin-block-end: 0 !important; margin-block-end: 0 !important;
font-weight: bold; font-weight: bold;
`, `,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
})); }));
export interface AssistantCardProps export interface AssistantCardProps
extends Omit<DiscoverAssistantItem, 'suggestions' | 'socialData' | 'config'>, extends Omit<DiscoverAssistantItem, 'suggestions' | 'socialData' | 'config'>,
@ -77,6 +78,8 @@ export interface AssistantCardProps
variant?: 'default' | 'compact'; variant?: 'default' | 'compact';
} }
const getUserId = (s) => s.user?.id
const AssistantCard = memo<AssistantCardProps>( const AssistantCard = memo<AssistantCardProps>(
({ showCategory, className, meta, createdAt, author, variant, ...rest }) => { ({ showCategory, className, meta, createdAt, author, variant, ...rest }) => {
const { avatar, title, description, tags = [], category } = meta; const { avatar, title, description, tags = [], category } = meta;
@ -86,36 +89,35 @@ const AssistantCard = memo<AssistantCardProps>(
const { message } = App.useApp(); const { message } = App.useApp();
const categoryItem = useCategoryItem(category, 12); const categoryItem = useCategoryItem(category, 12);
const isCompact = variant === 'compact'; const isCompact = variant === 'compact';
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
// console.log(tags,avatar,author,9383737) // console.log(tags,avatar,author,9383737)
console.log(userId,9999999999) console.log(userId,"9999999999")
const [val, setVal] = useState('') const [val, setVal] = useState('')
const handleCollect = (e) => { const handleCollect = (e) => {
console.log(e,8844848) console.log(e,"8844848")
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
const params = { const params = {
"author": author, "author": author,
"avatar": avatar,
"category": category,
"createAt": createAt, "createAt": createAt,
"createdAt": createdAt, "createdAt": createdAt,
"description": description,
"homepage": homepage, "homepage": homepage,
"identifier": identifier, "identifier": identifier,
"avatar": avatar, "schemaVersion": schemaVersion,
"description": description,
"tags": tags.join(','), "tags": tags.join(','),
"title": title, "title": title,
"category": category,
"schemaVersion": schemaVersion,
"userid": userId, "userid": userId,
} }
request({ request({
url: "/flxai/api/robot/appaiassistant", data: params,
method: "post", method: "post",
data: params url: "/flxai/api/robot/appaiassistant",
}).then(response => { }).then(response => {
console.log(response,222222222) console.log(response,"222222222")
if (response.code == 0) { if (response.code === 0) {
message.success(t('collectSuccess')); message.success(t('collectSuccess'));
setVal("1") setVal("1")
} }
@ -135,11 +137,11 @@ const AssistantCard = memo<AssistantCardProps>(
</Flexbox> </Flexbox>
); );
const renderElement = () => { const renderElement = () => {
if (classify != 'collect') { if (classify !== 'collect') {
if(status == "1" || val == "1") { if(status === "1" || val === "1") {
return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div> return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div>
} else { } else {
return <div className={styles.collectBtn} style={{background: '#F1F1F1'}} onClick={(e) => handleCollect(e)}><StarOutlined style={{color: '#D6D6D6'}}/></div> return <div className={styles.collectBtn} onClick={(e) => handleCollect(e)} style={{background: '#F1F1F1'}} ><StarOutlined style={{color: '#D6D6D6'}}/></div>
} }
} else { } else {
return; return;
@ -212,12 +214,12 @@ const AssistantCard = memo<AssistantCardProps>(
.slice(0, 4) .slice(0, 4)
.filter(Boolean) .filter(Boolean)
.map((tag: string, index) => { .map((tag: string, index) => {
const url = qs.stringifyUrl({ // const url = qs.stringifyUrl({
query: { q: tag, type: 'assistants' }, // query: { q: tag, type: 'assistants' },
url: '/discover/search', // url: '/discover/search',
}); // });
return ( return (
<Tag style={{ margin: '0 5' }}>{startCase(tag).trim()}</Tag> <Tag key={index} style={{ margin: '0 5' }}>{startCase(tag).trim()}</Tag>
); );
}) })
)} )}

@ -11,6 +11,8 @@ import { useUserStore } from '@/store/user';
import CategoryMenu from '../../../components/CategoryMenu'; import CategoryMenu from '../../../components/CategoryMenu';
import { useCategory } from './useCategory'; import { useCategory } from './useCategory';
const getUserId = (s) => s.user?.id;
const Category = memo(() => { const Category = memo(() => {
const items = useCategory(); const items = useCategory();
const pathname = usePathname(); const pathname = usePathname();
@ -21,7 +23,6 @@ const Category = memo(() => {
return 'all'; return 'all';
}, [pathname]); }, [pathname]);
const router = useQueryRoute(); const router = useQueryRoute();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
console.log(userId,'category333333') console.log(userId,'category333333')
return ( return (

@ -1,8 +1,8 @@
'use client'; 'use client';
import { Grid } from '@lobehub/ui'; import { Grid } from '@lobehub/ui';
import {Button, Empty, Image, Tag} from 'antd'; import { Empty } from 'antd';
import Link from 'next/link'; // import Link from 'next/link';
import {memo, useMemo, useEffect, useState} from 'react'; import {memo, useMemo, useEffect, useState} from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
@ -15,19 +15,20 @@ import VirtuosoGridList from '../../../components/VirtuosoGridList';
import Card from './Card'; import Card from './Card';
import request from '@/app/api/request'; import request from '@/app/api/request';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
export interface ListProps { export interface ListProps {
category?: string; category?: string;
items?: DiscoverAssistantItem[]; items?: DiscoverAssistantItem[];
mobile?: boolean; mobile?: boolean;
searchKeywords?: string; searchKeywords?: string;
} }
const getUserId = (s) => s.user?.id
const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] }) => { const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] }) => {
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');
const router = useRouter() const router = useRouter()
const [stData, setStData] = useState(items) const [stData, setStData] = useState(items)
const recentLength = mobile ? 4 : 8; const recentLength = mobile ? 4 : 8;
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
console.log(userId,'zhushou---3837373266262266') console.log(userId,'zhushou---3837373266262266')
console.log('zhushou--------------',items) console.log('zhushou--------------',items)
@ -40,32 +41,32 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
}, [stData, mobile]); }, [stData, mobile]);
useEffect(() => { useEffect(() => {
const fetchData = async() => { const fetchData = async() => {
if(category == "collect") { if(category === "collect") {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get", method: "get",
params: { params: {
userid: userId userid: userId
} },
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant"
}) })
setStData(res?.data.map((item,index)=> { setStData(res?.data.map((item)=> {
item.classify = 'collect'; item.classify = 'collect';
return item return item
})) }))
} else { } else {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get", method: "get",
params: { params: {
userid: userId userid: userId
} },
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant"
}) })
const array2Object = {}; const array2Object = {};
res?.data?.forEach((item) => { res?.data?.forEach((item) => {
array2Object[item.identifier] = item; array2Object[item.identifier] = item;
}); });
console.log('chajian22222222222222222222222222222--------------') console.log('chajian22222222222222222222222222222--------------')
setStData(stData.map((item,index)=> { setStData(stData.map((item)=> {
const matchingItem = array2Object[item.identifier]; const matchingItem = array2Object[item.identifier];
if (matchingItem) { if (matchingItem) {
matchingItem.status = '1'; matchingItem.status = '1';
@ -79,7 +80,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
}; };
fetchData(); fetchData();
}, []); // 空数组[]意味着仅在组件挂载时调用一次 }, []); // 空数组[]意味着仅在组件挂载时调用一次
console.log(category,recent,last,92929292) console.log(category,recent,last,"92929292")
const handleClickCard = (item) => { const handleClickCard = (item) => {
console.log(item) console.log(item)
router.push(urlJoin('/discover/assistant/', item.identifier)) router.push(urlJoin('/discover/assistant/', item.identifier))
@ -107,14 +108,14 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
} }
return ( return (
<> <div>
{category == "collect"?( {category === "collect"?(
<> <>
<Title tag={all.length}></Title> <Title tag={all.length}></Title>
<Grid maxItemWidth={280} rows={4}> <Grid maxItemWidth={280} rows={4}>
{all.map((item) => ( {all.map((item) => (
// <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}> // <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link> // </Link>
))} ))}
</Grid> </Grid>
@ -125,7 +126,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
<Grid maxItemWidth={280} rows={4}> <Grid maxItemWidth={280} rows={4}>
{recent.map((item) => ( {recent.map((item) => (
// <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}> // <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link> // </Link>
))} ))}
</Grid> </Grid>
@ -147,7 +148,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
)} )}
</> </>
)} )}
</> </div>
); );
}); });

@ -1,20 +1,15 @@
import { Icon } from '@lobehub/ui'; import { Icon } from '@lobehub/ui';
import { useTheme } from 'antd-style'; // import { useTheme } from 'antd-style';
import { import {
BadgeDollarSignIcon,
BriefcaseIcon, BriefcaseIcon,
Coffee, Coffee,
DramaIcon,
GamepadIcon, GamepadIcon,
GraduationCapIcon, GraduationCapIcon,
ImageIcon, ImageIcon,
LanguagesIcon,
LaughIcon, LaughIcon,
Layers, Layers,
LayoutPanelTop, LayoutPanelTop,
MicroscopeIcon,
PencilIcon, PencilIcon,
PrinterIcon,
TerminalSquareIcon, TerminalSquareIcon,
Star, Star,
} from 'lucide-react'; } from 'lucide-react';
@ -25,7 +20,7 @@ import { AssistantCategory } from '@/types/discover';
import { ICON_SIZE } from '../../../components/CategoryMenu'; import { ICON_SIZE } from '../../../components/CategoryMenu';
export const useCategory = (fontsize?: number) => { export const useCategory = (fontsize?: number) => {
const theme = useTheme(); // const theme = useTheme();
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');

@ -6,7 +6,7 @@ import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import List from './features/List'; import List from './features/List';
import urlJoin from 'url-join';
type Props = { searchParams: { hl?: Locales } }; type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => { export const generateMetadata = async ({ searchParams }: Props) => {
@ -25,12 +25,12 @@ const Page = async ({ searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl); const { t, locale } = await translation('metadata', searchParams?.hl);
const mobile = isMobileDevice(); const mobile = isMobileDevice();
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
console.log(searchParams,22222222222) console.log(searchParams,"22222222222")
const items = await discoverService.getAssistantList(locale); const items = await discoverService.getAssistantList(locale);
const ld = ldModule.generate({ const ld = ldModule.generate({
description: t('discover.assistants.description'), description: t('discover.assistants.description'),
title: t('discover.assistants.title'), title: t('discover.assistants.title'),
url: urlJoin('/discover/assistants?userid=',searchParams.userid), url: '/discover/assistants',
webpage: { webpage: {
enable: true, enable: true,
search: '/discover/search', search: '/discover/search',

@ -36,7 +36,7 @@ const Page = async ({ params, searchParams }: Props) => {
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
const list = await discoverService.getProviderList(locale); const list = await discoverService.getProviderList(locale);
const cate = list.find((cate) => cate.identifier === params.slug); const cate = list.find((cate) => cate.identifier === params.slug);
console.log(params.slug,3333333) console.log(params.slug,"3333333")
const items = await discoverService.getModelCategory(locale, params.slug); const items = await discoverService.getModelCategory(locale, params.slug);
const ld = ldModule.generate({ const ld = ldModule.generate({
description: t('discover.models.description'), description: t('discover.models.description'),

@ -9,12 +9,22 @@ import { DiscoverModelItem } from '@/types/discover';
import { StarOutlined } from '@ant-design/icons'; import { StarOutlined } from '@ant-design/icons';
import ModelFeatureTags from '../../../features/ModelFeatureTags'; import ModelFeatureTags from '../../../features/ModelFeatureTags';
import request from '@/app/api/request'; import request from '@/app/api/request';
const { Paragraph, Title } = Typography; const { Paragraph, Title } = Typography;
const useStyles = createStyles(({ css, token, isDarkMode }) => ({ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
banner: css` banner: css`
opacity: ${isDarkMode ? 0.9 : 0.4}; opacity: ${isDarkMode ? 0.9 : 0.4};
`, `,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
container: css` container: css`
cursor: pointer; cursor: pointer;
@ -65,21 +75,12 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
token: css` token: css`
font-family: ${token.fontFamilyCode}; font-family: ${token.fontFamilyCode};
`, `,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
})); }));
export interface ModelCardProps extends DiscoverModelItem, FlexboxProps { export interface ModelCardProps extends DiscoverModelItem, FlexboxProps {
showCategory?: boolean; showCategory?: boolean;
} }
const getUserId = (s) => s.user?.id
const ModelCard = memo<ModelCardProps>(({ className, meta, socialData, identifier, ...rest }) => { const ModelCard = memo<ModelCardProps>(({ className, meta, socialData, identifier, ...rest }) => {
const { title, description, functionCall, vision, tokens, category, id, displayName, enabled } = meta; const { title, description, functionCall, vision, tokens, category, id, displayName, enabled } = meta;
const { conversations, likes, tokens: socialDataToken } = socialData; const { conversations, likes, tokens: socialDataToken } = socialData;
@ -89,37 +90,36 @@ const ModelCard = memo<ModelCardProps>(({ className, meta, socialData, identifie
const { t:d } = useTranslation('discover'); const { t:d } = useTranslation('discover');
const { cx, styles } = useStyles(); const { cx, styles } = useStyles();
const { message } = App.useApp(); const { message } = App.useApp();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
const [val, setVal] = useState(status) const [val, setVal] = useState(status)
const handleCollect = (e) => { const handleCollect = (e) => {
console.log(e,8844848) console.log(e,"8844848")
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
const params = { const params = {
"identifier": identifier, "category": category,
"metaId": id,
"displayname": displayName,
"description": description,
"title": title,
"conversations": conversations, "conversations": conversations,
"createdAt": createdAt,
"description": description,
"displayname": displayName,
"enabled": enabled, "enabled": enabled,
"identifier": identifier,
"likes": likes,
"metaId": id,
"metaTokens": tokens, "metaTokens": tokens,
"createdAt": createdAt,
"tokens": socialDataToken,
"suggestions": suggestions.join(','),
"category": category,
"providers": providers.join(','), "providers": providers.join(','),
"likes": likes, "suggestions": suggestions.join(','),
"title": title,
"tokens": socialDataToken,
"userid": userId, "userid": userId,
} }
request({ request({
url: "/flxai/api/robot/appaimodel", data: params,
method: "post", method: "post",
data: params url: "/flxai/api/robot/appaimodel",
}).then(response => { }).then(response => {
console.log(response,222222222) console.log(response,"222222222")
if (response.code == 0) { if (response.code === 0) {
message.success(d('collectSuccess')); message.success(d('collectSuccess'));
setVal("1") setVal("1")
} }
@ -128,11 +128,11 @@ const ModelCard = memo<ModelCardProps>(({ className, meta, socialData, identifie
}) })
} }
const renderElement = () => { const renderElement = () => {
if (classify != 'collect') { if (classify !== 'collect') {
if(val == "1") { if(val === "1") {
return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div> return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div>
} else { } else {
return <div className={styles.collectBtn} style={{background: '#F1F1F1'}} onClick={(e) => handleCollect(e)}><StarOutlined style={{color: '#D6D6D6'}}/></div> return <div className={styles.collectBtn} onClick={(e) => handleCollect(e)} style={{background: '#F1F1F1'}}><StarOutlined style={{color: '#D6D6D6'}}/></div>
} }
} else { } else {
return; return;

@ -3,14 +3,13 @@
import { ProviderIcon } from '@lobehub/icons'; import { ProviderIcon } from '@lobehub/icons';
import { Icon } from '@lobehub/ui'; import { Icon } from '@lobehub/ui';
import { MenuProps } from 'antd'; import { MenuProps } from 'antd';
import { useTheme } from 'antd-style'; // import { useTheme } from 'antd-style';
import { LayoutPanelTop,Star } from 'lucide-react'; import { LayoutPanelTop,Star } from 'lucide-react';
import Link from 'next/link'; import Link from 'next/link';
import { usePathname } from 'next/navigation'; import { usePathname } from 'next/navigation';
import { memo, useMemo } from 'react'; import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { useUserStore } from '@/store/user';
import { useQueryRoute } from '@/hooks/useQueryRoute'; import { useQueryRoute } from '@/hooks/useQueryRoute';
import { DiscoverProviderItem } from '@/types/discover'; import { DiscoverProviderItem } from '@/types/discover';
@ -25,9 +24,7 @@ const Category = memo<{ data: DiscoverProviderItem[] }>(({ data }) => {
return 'all'; return 'all';
}, [pathname]); }, [pathname]);
const router = useQueryRoute(); const router = useQueryRoute();
const theme = useTheme(); // const theme = useTheme();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');
const items: MenuProps['items'] = [ const items: MenuProps['items'] = [
{ {

@ -1,8 +1,8 @@
'use client'; 'use client';
import { Empty } from 'antd'; import { Empty } from 'antd';
import Link from 'next/link'; // import Link from 'next/link';
import { memo } from 'react'; import { memo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@ -14,68 +14,72 @@ import VirtuosoGridList from '../../../components/VirtuosoGridList';
import Card from './Card'; import Card from './Card';
import request from '@/app/api/request'; import request from '@/app/api/request';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
export interface ListProps { export interface ListProps {
category?: string; category?: string;
items?: DiscoverModelItem[]; items?: DiscoverModelItem[];
mobile?: boolean; mobile?: boolean;
searchKeywords?: string; searchKeywords?: string;
} }
const getUserId = (s) => s.user?.id
const List = memo<ListProps>(async ({ category, searchKeywords, items = [] }) => { const List = memo<ListProps>(async ({ category, searchKeywords, items = [] }) => {
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');
const router = useRouter() const router = useRouter()
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
const [stData, setStData] = useState(items)
console.log(userId,'models---3837373266262266') console.log(userId,'models---3837373266262266')
console.log('models---99999999',items) console.log('models---99999999',items)
if(category == "collect") { if(category === "collect") {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaimodel/getAllAiModel",
method: "get", method: "get",
params: { params: {
userid: userId userid: userId
} },
url: "/flxai/api/robot/appaimodel/getAllAiModel",
}) })
items = res.data; setStData(res?.data.map((item)=> {
items = items.map((item,index)=> {
item.classify = 'collect'; item.classify = 'collect';
return item return item
}) }))
// items = res.data;
// items = items.map((item)=> {
// item.classify = 'collect';
// return item
// })
} else { } else {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaimodel/getAllAiModel",
method: "get", method: "get",
params: { params: {
userid: userId userid: userId
} },
url: "/flxai/api/robot/appaimodel/getAllAiModel",
}) })
const array2Object = {}; const array2Object = {};
res?.data?.forEach(item => { res?.data?.forEach(item => {
array2Object[item.identifier] = item; array2Object[item.identifier] = item;
}); });
items = items.map((item,index)=> { setStData(stData.map((item)=> {
const matchingItem = array2Object[item.identifier]; const matchingItem = array2Object[item.identifier];
if (matchingItem) { if (matchingItem) {
console.log('3838383838',matchingItem);
matchingItem.status = '1'; matchingItem.status = '1';
return matchingItem return matchingItem
} else { } else {
item.status = '0'; item.status = '0';
return item return item
} }
}) }))
} }
const handleClickCard = (item) => { const handleClickCard = (item) => {
console.log(item) console.log(item)
router.push(urlJoin('/discover/model/', item.identifier)) router.push(urlJoin('/discover/model/', item.identifier))
} }
if (searchKeywords) { if (searchKeywords) {
if (!items || items?.length === 0) return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />; if (!stData || stData?.length === 0) return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;
return ( return (
<> <>
<SearchResultCount count={items.length} keyword={searchKeywords} /> <SearchResultCount count={stData.length} keyword={searchKeywords} />
<VirtuosoGridList <VirtuosoGridList
data={items} data={stData}
initialItemCount={24} initialItemCount={24}
itemContent={(_, item) => ( itemContent={(_, item) => (
// <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}> // <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
@ -91,27 +95,27 @@ const List = memo<ListProps>(async ({ category, searchKeywords, items = [] }) =>
} }
return ( return (
<div>
{category === "collect"?(
<> <>
{category == "collect"?( <Title tag={stData.length}></Title>
<>
<Title tag={items.length}></Title>
<Grid maxItemWidth={280} rows={4}> <Grid maxItemWidth={280} rows={4}>
{items.map((item) => ( {stData.map((item) => (
// <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}> // <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link> // </Link>
))} ))}
</Grid> </Grid>
</> </>
):( ):(
<> <>
<Title tag={items.length}>{t('models.list')}</Title> <Title tag={stData.length}>{t('models.list')}</Title>
<VirtuosoGridList <VirtuosoGridList
data={items} data={stData}
initialItemCount={24} initialItemCount={24}
itemContent={(_, item) => ( itemContent={(_, item) => (
// <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}> // <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link> // </Link>
)} )}
style={{ style={{
@ -120,7 +124,7 @@ const List = memo<ListProps>(async ({ category, searchKeywords, items = [] }) =>
/> />
</> </>
)} )}
</> </div>
); );
}); });

@ -8,7 +8,7 @@ import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import List from './features/List'; import List from './features/List';
import urlJoin from 'url-join';
type Props = { searchParams: { hl?: Locales } }; type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => { export const generateMetadata = async ({ searchParams }: Props) => {
@ -28,12 +28,12 @@ const Page = async ({ searchParams }: Props) => {
const mobile = isMobileDevice(); const mobile = isMobileDevice();
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
const items = await discoverService.getModelList(locale); const items = await discoverService.getModelList(locale);
console.log(8272772727,'jiangxucong') console.log("8272772727",'jiangxucong')
const ld = ldModule.generate({ const ld = ldModule.generate({
description: t('discover.models.description'), description: t('discover.models.description'),
title: t('discover.models.title'), title: t('discover.models.title'),
url: urlJoin('/discover/models?userid=',searchParams.userid), url: '/discover/models',
webpage: { webpage: {
enable: true, enable: true,
search: '/discover/search', search: '/discover/search',

@ -1,12 +1,12 @@
import { Avatar, Tag } from '@lobehub/ui'; import { Avatar, Tag } from '@lobehub/ui';
import { Skeleton, Typography, App } from 'antd'; import { Typography, App } from 'antd';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import { startCase } from 'lodash-es'; import { startCase } from 'lodash-es';
import dynamic from 'next/dynamic'; // import dynamic from 'next/dynamic';
import qs from 'query-string'; // import qs from 'query-string';
import { memo, useState } from 'react'; import { memo, useState } from 'react';
import { Center, Flexbox, FlexboxProps } from 'react-layout-kit'; import { Center, Flexbox, FlexboxProps } from 'react-layout-kit';
import urlJoin from 'url-join'; // import urlJoin from 'url-join';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { DiscoverPlugintem } from '@/types/discover'; import { DiscoverPlugintem } from '@/types/discover';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
@ -14,10 +14,11 @@ import CardBanner from '../../../components/CardBanner';
import { useCategoryItem } from './useCategory'; import { useCategoryItem } from './useCategory';
import { StarOutlined } from '@ant-design/icons'; import { StarOutlined } from '@ant-design/icons';
import request from '@/app/api/request'; import request from '@/app/api/request';
const Link = dynamic(() => import('next/link'), {
loading: () => <Skeleton.Button size={'small'} style={{ height: 22 }} />, // const Link = dynamic(() => import('next/link'), {
ssr: false, // loading: () => <Skeleton.Button size={'small'} style={{ height: 22 }} />,
}); // ssr: false,
// });
const { Paragraph, Title } = Typography; const { Paragraph, Title } = Typography;
@ -25,6 +26,15 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
banner: css` banner: css`
opacity: ${isDarkMode ? 0.9 : 0.4}; opacity: ${isDarkMode ? 0.9 : 0.4};
`, `,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
container: css` container: css`
cursor: pointer; cursor: pointer;
@ -62,15 +72,6 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
font-size: 18px !important; font-size: 18px !important;
font-weight: bold; font-weight: bold;
`, `,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
})); }));
interface PluginCardProps interface PluginCardProps
@ -79,47 +80,46 @@ interface PluginCardProps
showCategory?: boolean; showCategory?: boolean;
variant?: 'default' | 'compact'; variant?: 'default' | 'compact';
} }
const getUserId = (s) => s.user?.id
const PluginCard = memo<PluginCardProps>( const PluginCard = memo<PluginCardProps>(
({ className, showCategory, meta, createdAt, author, variant, ...rest }) => { ({ className, showCategory, meta, createdAt, author, variant, ...rest }) => {
const { avatar, title, description, tags = [], category } = meta; const { avatar, title, description, tags = [], category } = meta;
const { createAt, homepage, identifier, schemaVersion, status, classify, manifest,locale } = {...rest} const { homepage, identifier, schemaVersion, status, classify, manifest,locale } = {...rest}
const categoryItem = useCategoryItem(category, 12); const categoryItem = useCategoryItem(category, 12);
const { cx, styles, theme } = useStyles(); const { cx, styles, theme } = useStyles();
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');
const { message } = App.useApp(); const { message } = App.useApp();
const isCompact = variant === 'compact'; const isCompact = variant === 'compact';
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
console.log(status,"9383737-------------------------------------") console.log(status,"9383737-------------------------------------")
console.log(manifest,locale,"plugins9999999999-------------------") console.log(manifest,locale,"plugins9999999999-------------------")
const [val, setVal] = useState('') const [val, setVal] = useState('')
const handleCollect = (e) => { const handleCollect = (e) => {
console.log(e,8844848) console.log(e,"8844848")
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
const params = { const params = {
"author": author, "author": author,
"avatar": avatar,
"category": category,
"createdAt": createdAt, "createdAt": createdAt,
"description": description,
"homepage": homepage, "homepage": homepage,
"identifier": identifier, "identifier": identifier,
"avatar": avatar, "locale": locale,
"description": description, "manifest": manifest,
"schemaVersion": schemaVersion,
"tags": tags.join(','), "tags": tags.join(','),
"title": title, "title": title,
"category": category,
"schemaVersion": schemaVersion,
"manifest": manifest,
"locale": locale,
"userid": userId, "userid": userId,
} }
request({ request({
url: "/flxai/api/robot/appaiplugin", data: params,
method: "post", method: "post",
data: params url: "/flxai/api/robot/appaiplugin",
}).then(response => { }).then(response => {
console.log(response,222222222) console.log(response,"222222222")
if (response.code == 0) { if (response.code === 0) {
message.success(t('collectSuccess')); message.success(t('collectSuccess'));
setVal("1") setVal("1")
} }
@ -129,12 +129,12 @@ const PluginCard = memo<PluginCardProps>(
} }
const renderElement = () => { const renderElement = () => {
console.log(classify,'66666----------------------') console.log(classify,'66666----------------------')
if (classify != 'collect') { if (classify !== 'collect') {
console.log(status,"222222222--------------------------") console.log(status,"222222222--------------------------")
if(status == "1" || val == "1") { if(status === "1" || val === "1") {
return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div> return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div>
} else { } else {
return <div className={styles.collectBtn} style={{background: '#F1F1F1'}} onClick={(e) => handleCollect(e)}><StarOutlined style={{color: '#D6D6D6'}}/></div> return <div className={styles.collectBtn} onClick={(e) => handleCollect(e)} style={{background: '#F1F1F1'}}><StarOutlined style={{color: '#D6D6D6'}}/></div>
} }
} else { } else {
return; return;
@ -195,12 +195,12 @@ const PluginCard = memo<PluginCardProps>(
.slice(0, 4) .slice(0, 4)
.filter(Boolean) .filter(Boolean)
.map((tag: string, index) => { .map((tag: string, index) => {
const url = qs.stringifyUrl({ // const url = qs.stringifyUrl({
query: { q: tag, type: 'plugins' }, // query: { q: tag, type: 'plugins' },
url: '/discover/search', // url: '/discover/search',
}); // });
return ( return (
<Tag style={{ margin: '0 5' }}>{startCase(tag).trim()}</Tag> <Tag key={index} style={{ margin: '0 5' }}>{startCase(tag).trim()}</Tag>
); );
}) })
)} )}

@ -7,7 +7,6 @@ import urlJoin from 'url-join';
import { useQueryRoute } from '@/hooks/useQueryRoute'; import { useQueryRoute } from '@/hooks/useQueryRoute';
import { PluginCategory } from '@/types/discover'; import { PluginCategory } from '@/types/discover';
import { useUserStore } from '@/store/user';
import CategoryMenu from '../../../components/CategoryMenu'; import CategoryMenu from '../../../components/CategoryMenu';
import { useCategory } from './useCategory'; import { useCategory } from './useCategory';
@ -21,8 +20,6 @@ const Category = memo(() => {
return 'all'; return 'all';
}, [pathname]); }, [pathname]);
const router = useQueryRoute(); const router = useQueryRoute();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
return ( return (
<CategoryMenu <CategoryMenu
items={items.map((item: any) => ({ items={items.map((item: any) => ({

@ -2,7 +2,7 @@
import { Grid } from '@lobehub/ui'; import { Grid } from '@lobehub/ui';
import { Empty } from 'antd'; import { Empty } from 'antd';
import Link from 'next/link'; // import Link from 'next/link';
import { memo, useMemo, useEffect,useState } from 'react'; import { memo, useMemo, useEffect,useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
@ -15,19 +15,19 @@ import VirtuosoGridList from '../../../components/VirtuosoGridList';
import Card from './Card'; import Card from './Card';
import request from '@/app/api/request'; import request from '@/app/api/request';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
export interface ListProps { export interface ListProps {
category?: string; category?: string;
items: DiscoverPlugintem[]; items: DiscoverPlugintem[];
mobile?: boolean; mobile?: boolean;
searchKeywords?: string; searchKeywords?: string;
} }
const getUserId = (s) => s.user?.id
const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] }) => { const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] }) => {
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');
const router = useRouter() const router = useRouter()
const [stData, setStData] = useState(items) const [stData, setStData] = useState(items)
const recentLength = mobile ? 4 : 8; const recentLength = mobile ? 4 : 8;
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
console.log(userId,'chajian---3837373266262266') console.log(userId,'chajian---3837373266262266')
console.log('chajian33333333--------------',items) console.log('chajian33333333--------------',items)
@ -40,32 +40,32 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
}, [stData, mobile]); }, [stData, mobile]);
useEffect(() => { useEffect(() => {
const fetchData = async() => { const fetchData = async() => {
if(category == "collect") { if(category === "collect") {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
method: "get", method: "get",
params: { params: {
userid: userId userid: userId
} },
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
}) })
setStData(res?.data.map((item,index)=> { setStData(res?.data.map((item)=> {
item.classify = 'collect'; item.classify = 'collect';
return item return item
})) }))
} else { } else {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
method: "get", method: "get",
params: { params: {
userid: userId userid: userId
} },
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
}) })
const array2Object = {}; const array2Object = {};
res?.data?.forEach((item) => { res?.data?.forEach((item) => {
array2Object[item.identifier] = item; array2Object[item.identifier] = item;
}); });
console.log('chajian22222222222222222222222222222--------------') console.log('chajian22222222222222222222222222222--------------')
setStData(stData.map((item,index)=> { setStData(stData.map((item)=> {
const matchingItem = array2Object[item.identifier]; const matchingItem = array2Object[item.identifier];
if (matchingItem) { if (matchingItem) {
matchingItem.status = '1'; matchingItem.status = '1';
@ -96,7 +96,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
data={all} data={all}
initialItemCount={24} initialItemCount={24}
itemContent={(_, item) => ( itemContent={(_, item) => (
<Card onClick={() => handleClickCard(item)} showCategory variant={'compact'} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory variant={'compact'} {...item} />
)} )}
style={{ style={{
minHeight: '75vh', minHeight: '75vh',
@ -107,14 +107,14 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
} }
return ( return (
<> <div>
{category == "collect"?( {category === "collect"?(
<> <>
<Title tag={all.length}></Title> <Title tag={all.length}></Title>
<Grid maxItemWidth={280} rows={4}> <Grid maxItemWidth={280} rows={4}>
{all?.map((item) => ( {all?.map((item) => (
// <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}> // <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link> // </Link>
))} ))}
</Grid> </Grid>
@ -124,7 +124,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
<Title>{t('plugins.recentSubmits')}</Title> <Title>{t('plugins.recentSubmits')}</Title>
<Grid maxItemWidth={280} rows={4}> <Grid maxItemWidth={280} rows={4}>
{recent?.map((item) => ( {recent?.map((item) => (
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
))} ))}
</Grid> </Grid>
{last && last?.length > 0 && ( {last && last?.length > 0 && (
@ -134,7 +134,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
data={last} data={last}
initialItemCount={12} initialItemCount={12}
itemContent={(_, item) => ( itemContent={(_, item) => (
<Card onClick={() => handleClickCard(item)} showCategory={!category} variant={'compact'} {...item} /> <Card key={item.identifier} onClick={() => handleClickCard(item)} showCategory={!category} variant={'compact'} {...item} />
)} )}
style={{ style={{
minHeight: '75vh', minHeight: '75vh',
@ -144,7 +144,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
)} )}
</> </>
)} )}
</> </div>
); );
}); });

@ -1,5 +1,5 @@
import { Icon } from '@lobehub/ui'; import { Icon } from '@lobehub/ui';
import { useTheme } from 'antd-style'; // import { useTheme } from 'antd-style';
import { import {
Gamepad2, Gamepad2,
ImagePlay, ImagePlay,
@ -19,7 +19,7 @@ import { PluginCategory } from '@/types/discover';
import { ICON_SIZE } from '../../../components/CategoryMenu'; import { ICON_SIZE } from '../../../components/CategoryMenu';
export const useCategory = (fontsize?: number) => { export const useCategory = (fontsize?: number) => {
const theme = useTheme(); // const theme = useTheme();
const { t } = useTranslation('discover'); const { t } = useTranslation('discover');

@ -6,7 +6,7 @@ import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; import { isMobileDevice } from '@/utils/responsive';
import List from './features/List'; import List from './features/List';
import urlJoin from 'url-join';
type Props = { searchParams: { hl?: Locales } }; type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => { export const generateMetadata = async ({ searchParams }: Props) => {
@ -31,7 +31,7 @@ const Page = async ({ searchParams }: Props) => {
const ld = ldModule.generate({ const ld = ldModule.generate({
description: t('discover.plugins.description'), description: t('discover.plugins.description'),
title: t('discover.plugins.title'), title: t('discover.plugins.title'),
url: urlJoin('/discover/plugins?userid=',searchParams.userid), url: '/discover/plugins',
webpage: { webpage: {
enable: true, enable: true,
search: '/discover/search', search: '/discover/search',

@ -1,39 +1,40 @@
'use client'; 'use client';
import { ChatHeader } from '@lobehub/ui'; import { ChatHeader } from '@lobehub/ui';
import Link from 'next/link'; // import Link from 'next/link';
import { memo } from 'react'; import { memo } from 'react';
import {createStyles, useTheme} from 'antd-style'; import {createStyles} from 'antd-style';
import { ProductLogo } from '@/components/Branding'; // import { ProductLogo } from '@/components/Branding';
import { Divider, Avatar } from "antd"; import { Divider, Avatar } from "antd";
import { UserOutlined, SearchOutlined } from '@ant-design/icons'; import { UserOutlined } from '@ant-design/icons';
import CreateButton from '../../features/CreateButton'; // import CreateButton from '../../features/CreateButton';
import StoreSearchBar from '../../features/StoreSearchBar'; import StoreSearchBar from '../../features/StoreSearchBar';
const useStyles = createStyles(({ css, token }) => ({
topCenten: css` const useStyles = createStyles(({ css }) => ({
width: 100%;
background: #FFFFFF;
box-sizing: border-box;
/* 分割线颜色 */
border-width: 0px 0px 2px 0px;
border-style: solid;
border-color: rgba(187, 204, 253, 0.24);
`,
leftTitle: css`
font-size: 20px;
color: #3d3d3d;
display: inline-block
`,
dividerCen: css` dividerCen: css`
width: 1px; width: 1px;
height: 26px; height: 26px;
background-color: #d8d8d8; background-color: #d8d8d8;
margin: 8px 16px; margin: 8px 16px;
`, `,
inp: css`
width: 283px;
margin-right: 43px;
background: #F3F6FF;
&:hover, &:active, &:focus {
border-color: transparent !important;
background: #F3F6FF !important;
}
`,
ledDiv: css ` ledDiv: css `
line-height: 52px; line-height: 52px;
display: inline-block; display: inline-block;
`, `,
leftTitle: css`
font-size: 20px;
color: #3d3d3d;
display: inline-block
`,
nameSpn: css` nameSpn: css`
margin-left: 8px; margin-left: 8px;
display: inline-block; display: inline-block;
@ -42,25 +43,25 @@ const useStyles = createStyles(({ css, token }) => ({
color: #BCCEFF; color: #BCCEFF;
font-size: 24px; font-size: 24px;
`, `,
inp: css` topCenten: css`
width: 283px; width: 100%;
margin-right: 43px; background: #FFFFFF;
background: #F3F6FF; box-sizing: border-box;
&:hover, &:active, &:focus { /* 分割线颜色 */
border-color: transparent !important; border-width: 0px 0px 2px 0px;
background: #F3F6FF !important; border-style: solid;
} border-color: rgba(187, 204, 253, 0.24);
`, `,
})) }))
const title = { const title = {
"/chat": '会话', "/chat": '会话',
"/discover/assistants": "助手", "/discover/assistants": "助手",
"/files": "工具", "/files": "工具",
"/knowledge": "知识库",
"/model": "模型", "/model": "模型",
"/robot": "数字人",
"/plugins": "插件", "/plugins": "插件",
"/power": "算力", "/power": "算力",
"/knowledge": "知识库" "/robot": "数字人",
} }
const Header = memo(() => { const Header = memo(() => {
const { styles, cx } = useStyles() const { styles, cx } = useStyles()
@ -70,17 +71,17 @@ const Header = memo(() => {
<div className={cx(styles.ledDiv)}> <div className={cx(styles.ledDiv)}>
<span className={cx(styles.leftTitle)}>AI</span> <span className={cx(styles.leftTitle)}>AI</span>
<Divider className={cx(styles.dividerCen)} type="vertical" /> <Divider className={cx(styles.dividerCen)} type="vertical" />
<span className={cx(styles.leftTitle)}>{title[window?.location?.pathname]}</span> <span className={cx(styles.leftTitle)}>{title[window.location.pathname]}</span>
</div> </div>
} }
right={<> right={<>
<Avatar style={{ backgroundColor: '#90ACFF' }} icon={<UserOutlined />} /> <Avatar icon={<UserOutlined />} style={{ backgroundColor: '#90ACFF' }}/>
<span className={cx(styles.nameSpn)}></span> <span className={cx(styles.nameSpn)}></span>
</>} </>}
style={{ style={{
background: '#fff',
position: 'relative', position: 'relative',
zIndex: 10, zIndex: 10,
background: '#fff',
}} }}
styles={{ styles={{
center: { flex: 1, maxWidth: 1440 }, center: { flex: 1, maxWidth: 1440 },

@ -9,7 +9,7 @@ const Layout = ({ children }: PropsWithChildren) => {
return ( return (
<> <>
<NProgress /> <NProgress />
<Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative',marginTop: '-64px' }} width={'100%'}> <Flexbox height={'100%'} style={{ marginTop: '-64px', overflow: 'hidden', position: 'relative' }} width={'100%'}>
<Header /> <Header />
{children} {children}
</Flexbox> </Flexbox>

@ -1,13 +1,13 @@
'use client'; 'use client';
import { ConfigProvider, Menu, MenuProps } from 'antd'; import { ConfigProvider, Menu, MenuProps } from 'antd';
import { useTheme } from 'antd-style'; // import { useTheme } from 'antd-style';
import { memo } from 'react'; import { memo } from 'react';
export const ICON_SIZE = { fontSize: '1.25em' }; export const ICON_SIZE = { fontSize: '1.25em' };
const CategoryMenu = memo<MenuProps>(({ style, ...rest }) => { const CategoryMenu = memo<MenuProps>(({ style, ...rest }) => {
const theme = useTheme(); // const theme = useTheme();
return ( return (
<ConfigProvider <ConfigProvider

@ -14,6 +14,7 @@ import { DiscoverTab } from '@/types/discover';
import { useNav } from './useNav'; import { useNav } from './useNav';
import { useUserStore } from '@/store/user'; import { useUserStore } from '@/store/user';
export const useStyles = createStyles(({ css, prefixCls, token }) => ({ export const useStyles = createStyles(({ css, prefixCls, token }) => ({
active: css` active: css`
box-shadow: ${token.boxShadow}; box-shadow: ${token.boxShadow};
@ -28,7 +29,7 @@ export const useStyles = createStyles(({ css, prefixCls, token }) => ({
interface StoreSearchBarProps extends SearchBarProps { interface StoreSearchBarProps extends SearchBarProps {
mobile?: boolean; mobile?: boolean;
} }
const getUserId = (s) => s.user?.id
const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...rest }) => { const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...rest }) => {
const [active, setActive] = useState(false); const [active, setActive] = useState(false);
const pathname = usePathname(); const pathname = usePathname();
@ -41,7 +42,6 @@ const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...
const router = useQueryRoute(); const router = useQueryRoute();
const activeType = activeKey === DiscoverTab.Home ? DiscoverTab.Assistants : activeKey; const activeType = activeKey === DiscoverTab.Home ? DiscoverTab.Assistants : activeKey;
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState()) const userId = getUserId(useUserStore.getState())
useEffect(() => { useEffect(() => {
if (!pathname.includes('/discover/search')) return; if (!pathname.includes('/discover/search')) return;
@ -50,6 +50,7 @@ const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...
}, [q, pathname, activeType]); }, [q, pathname, activeType]);
const handleSearch = (value: string) => { const handleSearch = (value: string) => {
console.log(userId,'33333333333333333333-----------')
router.push('/discover/search', { query: { q: value, type: activeType, userid: userId } }); router.push('/discover/search', { query: { q: value, type: activeType, userid: userId } });
}; };

@ -3,9 +3,9 @@ import { Flexbox } from 'react-layout-kit';
import Footer from '@/features/Setting/Footer'; import Footer from '@/features/Setting/Footer';
import CategoryContainer from '../../components/CategoryContainer'; // import CategoryContainer from '../../components/CategoryContainer';
import { MAX_WIDTH, SCROLL_PARENT_ID } from '../../features/const'; import { MAX_WIDTH, SCROLL_PARENT_ID } from '../../features/const';
import Category from '../features/Category'; // import Category from '../features/Category';
const Layout = async ({ children }: PropsWithChildren) => { const Layout = async ({ children }: PropsWithChildren) => {
return ( return (

@ -16,11 +16,11 @@ const AssistantsResult = async ({
userid: string; userid: string;
}) => { }) => {
const res = await request({ const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get", method: "get",
params: { params: {
userid: userid userid: userid
} },
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
}) })
const array2Object = {}; const array2Object = {};
res?.data?.forEach(item => { res?.data?.forEach(item => {
@ -28,7 +28,7 @@ const AssistantsResult = async ({
}); });
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
let items = await discoverService.searchAssistant(locale, q); let items = await discoverService.searchAssistant(locale, q);
items = items.map((item,index)=> { items = items.map((item)=> {
const matchingItem = array2Object[item.identifier]; const matchingItem = array2Object[item.identifier];
if (matchingItem) { if (matchingItem) {
matchingItem.status = '1'; matchingItem.status = '1';
@ -39,10 +39,9 @@ const AssistantsResult = async ({
} }
}) })
console.log(locale,q,userid,'383737363636363') console.log(locale,q,userid,'383737363636363')
const backUrl = '/discover/assistants?userid=' + userid
return ( return (
<> <>
{!mobile && <Back href={backUrl} style={{ marginBottom: 0 }} />} {!mobile && <Back href={'/discover/assistants'} style={{ marginBottom: 0 }} />}
<List items={items} mobile={mobile} searchKeywords={q} /> <List items={items} mobile={mobile} searchKeywords={q} />
</> </>
); );

@ -1,21 +1,44 @@
import { Locales } from '@/locales/resources'; import { Locales } from '@/locales/resources';
import { DiscoverService } from '@/server/services/discover'; import { DiscoverService } from '@/server/services/discover';
import request from '@/app/api/request';
import Back from '../../(detail)/features/Back'; import Back from '../../(detail)/features/Back';
import List from '../../(list)/models/features/List'; import List from '../../(list)/models/features/List';
const ModelsResult = async ({ const ModelsResult = async ({
locale, locale,
q, q,
userid,
mobile, mobile,
}: { }: {
locale: Locales; locale: Locales;
mobile?: boolean; mobile?: boolean;
q: string; q: string;
userid: string;
}) => { }) => {
const res = await request({
method: "get",
params: {
userid: userid
},
url: "/flxai/api/robot/appaimodel/getAllAiModel",
})
const array2Object = {};
res?.data?.forEach(item => {
array2Object[item.identifier] = item;
});
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
const items = await discoverService.searchModel(locale, q); let items = await discoverService.searchModel(locale, q);
items = items.map((item)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
})
console.log(locale,q,userid,'383737363636363')
return ( return (
<> <>
{!mobile && <Back href={'/discover/models'} style={{ marginBottom: 0 }} />} {!mobile && <Back href={'/discover/models'} style={{ marginBottom: 0 }} />}

@ -1,20 +1,44 @@
import { Locales } from '@/locales/resources'; import { Locales } from '@/locales/resources';
import { DiscoverService } from '@/server/services/discover'; import { DiscoverService } from '@/server/services/discover';
import request from '@/app/api/request';
import Back from '../../(detail)/features/Back'; import Back from '../../(detail)/features/Back';
import List from '../../(list)/plugins/features/List'; import List from '../../(list)/plugins/features/List';
const PluginsResult = async ({ const PluginsResult = async ({
locale, locale,
q, q,
userid,
mobile, mobile,
}: { }: {
locale: Locales; locale: Locales;
mobile?: boolean; mobile?: boolean;
q: string; q: string;
userid: string;
}) => { }) => {
const res = await request({
method: "get",
params: {
userid: userid
},
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
})
const array2Object = {};
res?.data?.forEach(item => {
array2Object[item.identifier] = item;
});
const discoverService = new DiscoverService(); const discoverService = new DiscoverService();
const items = await discoverService.searchPlugin(locale, q); let items = await discoverService.searchPlugin(locale, q);
items = items.map((item)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
})
console.log(locale,q,userid,'383737363636363')
return ( return (
<> <>

@ -66,8 +66,8 @@ const Page = async ({ searchParams }: Props) => {
<> <>
<StructuredData ld={ld} /> <StructuredData ld={ld} />
{type === 'assistants' && <AssistantsResult locale={locale} mobile={mobile} q={keywords} userid={userid} />} {type === 'assistants' && <AssistantsResult locale={locale} mobile={mobile} q={keywords} userid={userid} />}
{type === 'plugins' && <PluginsResult locale={locale} mobile={mobile} q={keywords} />} {type === 'plugins' && <PluginsResult locale={locale} mobile={mobile} q={keywords} userid={userid} />}
{type === 'models' && <ModelsResult locale={locale} mobile={mobile} q={keywords} />} {type === 'models' && <ModelsResult locale={locale} mobile={mobile} q={keywords} userid={userid} />}
{type === 'providers' && <ProvidersResult locale={locale} mobile={mobile} q={keywords} />} {type === 'providers' && <ProvidersResult locale={locale} mobile={mobile} q={keywords} />}
</> </>
); );

@ -1,52 +0,0 @@
import StructuredData from '@/components/StructuredData';
import { Locales } from '@/locales/resources';
import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata';
import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive';
import Filescon from "./filescon";
import {Button} from "antd";
type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
return metadataModule.generate({
alternate: true,
description: t('files.description'),
locale,
title: t('files.title'),
url: '/files',
});
};
const Page = async ({ searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
const mobile = isMobileDevice();
const discoverService = new DiscoverService();
const items = await discoverService.getAssistantList(locale);
const ld = ldModule.generate({
description: t('files.description'),
title: t('files.title'),
url: '/files',
webpage: {
enable: true,
search: '/files/search',
},
});
return (
<>
<Filescon />
</>
);
};
Page.DisplayName = 'DiscoverAssistants';
export default Page;

@ -0,0 +1,76 @@
import { Col, Form, Input, Modal, Row } from 'antd';
import React from 'react';
import { createStyles } from 'antd-style';
const { TextArea } = Input;
const FormItem = Form.Item;
const useStyles = createStyles(({ css }) => ({
formStyle: css`
.ant-form-item-label {
width: 100px !important;
}
`,
modalStyle: css`
.ant-modal-body {
padding: 20px 0;
}
.ant-modal-footer {
.ant-btn:nth-child(1) {
width: 73px;
height: 36px;
border-radius: 4px;
opacity: 1;
background: #EBF4FF;
box-sizing: border-box;
border: 1px solid #B8D8FF;
color: #177FFF;
}
.ant-btn:nth-child(2) {
width: 73px;
height: 36px;
border-radius: 4px;
opacity: 1;
background: #80B9FF;
}
}
`,
}));
const KnowledgeCreateForm = (props) => {
const { styles } = useStyles();
const [form] = Form.useForm();
const { open, handleAdd, handleModalVisible } = props;
const okHandle = () => {
form.validateFields()
.then((fieldsValue) => {
form.resetFields();
handleAdd(fieldsValue);
})
.catch(() => {});
};
return (
<Modal className={styles.modalStyle} destroyOnClose onCancel={() => handleModalVisible(false)} onOk={okHandle} open={open} title="创建知识库" >
<Form className={styles.formStyle} form={form}>
<Row gutter={{ lg: 24, md: 8, xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label="知识库名称" name="name" rules={[{ message: '请输入!', min: 1, required: true}]}>
<Input placeholder="请输入" />
</FormItem>
</Col>
</Row>
<Row gutter={{ lg: 24, md: 8, xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label="知识库描述" name="description" rules={[{ message: '请输入!', min: 1 , required: false}]}>
<TextArea maxLength={255} placeholder="请输入" rows={4} />
</FormItem>
</Col>
</Row>
</Form>
</Modal>
);
};
export default KnowledgeCreateForm;

@ -0,0 +1,83 @@
import { Col, Form, Input, Modal, Row } from 'antd';
import React from 'react';
import { createStyles } from 'antd-style';
const { TextArea } = Input;
const FormItem = Form.Item;
const useStyles = createStyles(({ css }) => ({
formStyle: css`
.ant-form-item-label {
width: 100px !important;
}
`,
modalStyle: css`
.ant-modal-body {
padding: 20px 0;
}
.ant-modal-footer {
.ant-btn:nth-child(1) {
width: 73px;
height: 36px;
border-radius: 4px;
opacity: 1;
background: #EBF4FF;
box-sizing: border-box;
border: 1px solid #B8D8FF;
color: #177FFF;
}
.ant-btn:nth-child(2) {
width: 73px;
height: 36px;
border-radius: 4px;
opacity: 1;
background: #80B9FF;
}
}
`,
}));
const KnowledgeUpdateForm = (props) => {
const { styles } = useStyles();
const [form] = Form.useForm();
const { handleUpdate, open, handleUpdateModalVisible, values } = props;
React.useEffect(() => {
form.setFieldsValue({
description: props.values.description,
id: props.values.id,
title: props.values.title,
});
}, []);
const handleLocalUpdate = () => {
form.validateFields()
.then((fieldsValue) => {
handleUpdate({ ...values, ...fieldsValue });
})
.catch(() => {});
};
return (
<Modal afterClose={() => handleUpdateModalVisible()} className={styles.modalStyle} destroyOnClose onCancel={() => handleUpdateModalVisible(false, values)} onOk={() => handleLocalUpdate()} open={open} title="编辑知识库">
<Form className={styles.formStyle} form={form}>
<Row gutter={{ lg: 24, md: 8, xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label="知识库名称" name="title" rules={[{ message: '请输入!', min: 1, required: true }]}>
<Input placeholder="请输入" />
</FormItem>
</Col>
</Row>
<Row gutter={{ lg: 24, md: 8,xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label="知识库描述" name="description" rules={[{ message: '请输入!', min: 1, required: false }]}>
<TextArea maxLength={255} placeholder="请输入" rows={4} />
</FormItem>
</Col>
</Row>
</Form>
</Modal>
);
};
export default KnowledgeUpdateForm;

@ -1,12 +1,11 @@
import { WelcomeLogo } from '@/components/Branding'; // import StructuredData from '@/components/StructuredData';
import StructuredData from '@/components/StructuredData';
import { BRANDING_NAME } from '@/const/branding'; import { BRANDING_NAME } from '@/const/branding';
import { ldModule } from '@/server/ld'; // import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata'; import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; // import { isMobileDevice } from '@/utils/responsive';
import {Card, Button, List } from "antd";
import KnowledgeList from './components/KnowledgeList'; import KnowledgeList from './components/KnowledgeList';
export const generateMetadata = async () => { export const generateMetadata = async () => {
const { t } = await translation('metadata'); const { t } = await translation('metadata');
return metadataModule.generate({ return metadataModule.generate({
@ -17,18 +16,17 @@ export const generateMetadata = async () => {
}; };
const Page = async () => { const Page = async () => {
const mobile = isMobileDevice(); // const mobile = isMobileDevice();
const { t } = await translation('metadata'); // const { t } = await translation('metadata');
const ld = ldModule.generate({ // const ld = ldModule.generate({
description: t('knowledge.description', { appName: BRANDING_NAME }), // description: t('knowledge.description', { appName: BRANDING_NAME }),
title: t('knowledge.title', { appName: BRANDING_NAME }), // title: t('knowledge.title', { appName: BRANDING_NAME }),
url: '/knowledge', // url: '/knowledge',
}); // });
return ( return (
<> <>
{/*<StructuredData ld={ld} />*/} {/*<StructuredData ld={ld} />*/}
{/*<WelcomeLogo mobile={mobile} />*/}
<KnowledgeList/> <KnowledgeList/>
</> </>
); );

@ -1,38 +0,0 @@
import { WelcomeLogo } from '@/components/Branding';
import StructuredData from '@/components/StructuredData';
import { BRANDING_NAME } from '@/const/branding';
import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive';
export const generateMetadata = async () => {
const { t } = await translation('metadata');
return metadataModule.generate({
description: t('model.description', { appName: BRANDING_NAME }),
title: t('model.title', { appName: BRANDING_NAME }),
url: '/model',
});
};
const Page = async () => {
const mobile = isMobileDevice();
const { t } = await translation('metadata');
const ld = ldModule.generate({
description: t('model.description', { appName: BRANDING_NAME }),
title: t('model.title', { appName: BRANDING_NAME }),
url: '/model',
});
return (
<>
{/*<StructuredData ld={ld} />*/}
{/*<WelcomeLogo mobile={mobile} />*/}
<div></div>
</>
);
};
Page.displayName = 'Model';
export default Page;

@ -1,38 +0,0 @@
import { WelcomeLogo } from '@/components/Branding';
import StructuredData from '@/components/StructuredData';
import { BRANDING_NAME } from '@/const/branding';
import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive';
export const generateMetadata = async () => {
const { t } = await translation('metadata');
return metadataModule.generate({
description: t('plugins.description', { appName: BRANDING_NAME }),
title: t('plugins.title', { appName: BRANDING_NAME }),
url: '/plugins',
});
};
const Page = async () => {
const mobile = isMobileDevice();
const { t } = await translation('metadata');
const ld = ldModule.generate({
description: t('plugins.description', { appName: BRANDING_NAME }),
title: t('plugins.title', { appName: BRANDING_NAME }),
url: '/plugins',
});
return (
<>
{/*<StructuredData ld={ld} />*/}
{/*<WelcomeLogo mobile={mobile} />*/}
<div></div>
</>
);
};
Page.displayName = 'Robot';
export default Page;

@ -1,10 +1,10 @@
import { WelcomeLogo } from '@/components/Branding'; // import { WelcomeLogo } from '@/components/Branding';
import StructuredData from '@/components/StructuredData'; // import StructuredData from '@/components/StructuredData';
import { BRANDING_NAME } from '@/const/branding'; import { BRANDING_NAME } from '@/const/branding';
import { ldModule } from '@/server/ld'; // import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata'; import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; // import { isMobileDevice } from '@/utils/responsive';
export const generateMetadata = async () => { export const generateMetadata = async () => {
const { t } = await translation('metadata'); const { t } = await translation('metadata');
@ -16,13 +16,13 @@ export const generateMetadata = async () => {
}; };
const Page = async () => { const Page = async () => {
const mobile = isMobileDevice(); // const mobile = isMobileDevice();
const { t } = await translation('metadata'); // const { t } = await translation('metadata');
const ld = ldModule.generate({ // const ld = ldModule.generate({
description: t('power.description', { appName: BRANDING_NAME }), // description: t('power.description', { appName: BRANDING_NAME }),
title: t('power.title', { appName: BRANDING_NAME }), // title: t('power.title', { appName: BRANDING_NAME }),
url: '/power', // url: '/power',
}); // });
return ( return (
<> <>

@ -1,59 +1,35 @@
'use client'; 'use client';
import { Avatar, Icon } from '@lobehub/ui'; // import { Avatar, Icon } from '@lobehub/ui';
import { Card, Button, List, Image, Flex, Tabs, Table, Space, Input, Select, Upload, Slider, InputNumber, Carousel } from "antd"; import { Card, Button, List, Image, Flex, Input, Select, Slider, Carousel } from "antd";
import { StarOutlined, StarFilled, StarTwoTone, CloudUploadOutlined} from '@ant-design/icons';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import { LucideArrowUpRightFromSquare, TelescopeIcon } from 'lucide-react';
import Link from 'next/link';
import { memo, useState, useRef } from 'react'; import { memo, useState, useRef } from 'react';
import { useTranslation } from 'react-i18next'; // import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit'; // import { Flexbox } from 'react-layout-kit';
const useStyles = createStyles(({ css }) => ({
import Notification from '@/components/Notification'; buttonDelete: css`
import { BRANDING_NAME } from '@/const/branding'; background: url(/images/delete.png) center center no-repeat;
import { PRIVACY_URL } from '@/const/url'; background-size: 14px;
import { useServerConfigStore } from '@/store/serverConfig'; &:before {
import { serverConfigSelectors } from '@/store/serverConfig/selectors'; content: "11";
import { useUserStore } from '@/store/user'; visibility: hidden;
import { preferenceSelectors } from '@/store/user/selectors';
import styled from 'styled-components';
const { Search } = Input;
const { Dragger } = Upload;
const useStyles = createStyles(({ css, token }) => ({
listStyle: css`
border: none !important;
`,
cardStyle: css`
box-shadow: 1px 0px 12px 0px rgba(42, 77, 255, 0.19);
border: none;
border-radius: 8px;
padding: 10px 0;
width: 100%;
height: 100%;
overflow: auto;
`,
cardRobotStyle: css`
box-shadow: 1px 0px 12px 0px rgba(42, 77, 255, 0.19);
border: none;
border-radius: 8px;
padding: 10px 0;
width: 100%;
height: 100%;
.ant-card-body {
padding: 0 24px;
} }
`, `,
iconImg: css` buttonEdit: css`
width: 48px; background: url(/images/edit.png) center center no-repeat;
height: 48px; background-size: 14px;
`, &:before {
title: css` content: "11";
font-size: 18px; visibility: hidden;
font-weight: 700; }
`, `,
dec: css` buttonManage: css`
color: #666666; background: url(/images/manage.png) center center no-repeat;
background-size: 14px;
&:before {
content: "11";
visibility: hidden;
}
`, `,
buttonStyle: css` buttonStyle: css`
font-size: 16px; font-size: 16px;
@ -85,99 +61,49 @@ const useStyles = createStyles(({ css, token }) => ({
color: #fff !important; color: #fff !important;
} }
`, `,
importButtonStyle: css` cardRobotStyle: css`
font-size: 16px; box-shadow: 1px 0px 12px 0px rgba(42, 77, 255, 0.19);
color: #0044FF;
border: none; border: none;
padding: 18px 30px !important; border-radius: 8px;
box-sizing: border-box; padding: 10px 0;
background-color: rgba(0, 68, 255, 0.102); width: 100%;
margin-left: 50px; height: 100%;
&:hover { .ant-card-body {
color: #0044FF !important; padding: 0 24px;
background-color: rgba(0, 68, 255, 0.102) !important;
}
`,
buttonManage: css`
background: url(/images/manage.png) center center no-repeat;
background-size: 14px;
&:before {
content: "11";
visibility: hidden;
}
`,
buttonEdit: css`
background: url(/images/edit.png) center center no-repeat;
background-size: 14px;
&:before {
content: "11";
visibility: hidden;
} }
`, `,
buttonDelete: css` cardStyle: css`
background: url(/images/delete.png) center center no-repeat; box-shadow: 1px 0px 12px 0px rgba(42, 77, 255, 0.19);
background-size: 14px; border: none;
&:before { border-radius: 8px;
content: "11"; padding: 10px 0;
visibility: hidden; width: 100%;
} height: 100%;
overflow: auto;
`, `,
tableHead: css` checkButtonStyle: css`
.ant-table-thead { font-size: 16px;
.ant-table-cell { color: #fff;
background-color: #F1F8FF !important padding: 15px 30px !important;
} box-shadow: 0px 2px 9px 0px rgba(95, 135, 255, 0.4);
box-sizing: border-box;
border-color: #0044FF;
background-color: #0044FF;
&:hover {
border-color: #0044FF !important;
background-color: #0044FF !important;
color: #fff !important;
} }
`, `,
tabStyle: css` checkItem: css`
.ant-tabs-tab { margin-top: 15px;
margin-right: 40px !important;
}
.ant-tabs-tab-btn {
color: #648EFF
}
.ant-tabs-tab.ant-tabs-tab-active {
.ant-tabs-tab-btn {
color: #0044FF
}
}
.ant-pagination {
.ant-pagination-item-active {
border-color: #0056FF !important
a {
color: #0056FF !important
}
}
}
`, `,
searchStyle: css` checkTitle: css`
.ant-input-affix-wrapper { color: #0044FF;
border: none; margin-right: 5px;
background-color: #F3F6FF;
}
.ant-input-search-button {
border: none;
background-color: #F3F6FF;
&:hover {
background-color: #F3F6FF !important;
}
.ant-btn-icon {
color: #0044FF !important;
}
}
`, `,
selectStyle: css` dec: css`
.ant-select-selector { color: #666666;
border: none !important;
background-color: #F0F3FD !important;
}
.ant-select-selection-item {
color: #4A73FF
}
.ant-select-arrow {
color: #2959FF
}
margin-bottom: 15px;
`, `,
documentCard: css` documentCard: css`
width: 100%; width: 100%;
@ -197,11 +123,31 @@ const useStyles = createStyles(({ css, token }) => ({
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #0044FF; border: 1px solid #0044FF;
`, `,
iconImg: css`
width: 48px;
height: 48px;
`,
importButtonStyle: css`
font-size: 16px;
color: #0044FF;
border: none;
padding: 18px 30px !important;
box-sizing: border-box;
background-color: rgba(0, 68, 255, 0.102);
margin-left: 50px;
&:hover {
color: #0044FF !important;
background-color: rgba(0, 68, 255, 0.102) !important;
}
`,
importFileCard: css` importFileCard: css`
.ant-card-body { .ant-card-body {
height: 100% height: 100%
} }
`, `,
listStyle: css`
border: none !important;
`,
previewContainer: css` previewContainer: css`
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -209,57 +155,29 @@ const useStyles = createStyles(({ css, token }) => ({
text-align: center; text-align: center;
padding: 30% 0; padding: 30% 0;
`, `,
testContent: css`
width: 100%;
height: 500px;
margin-top: 15px;
padding: 10px;
border-radius: 2px;
border: 1px solid #D9D9D9;
`,
checkButtonStyle: css`
font-size: 16px;
color: #fff;
padding: 15px 30px !important;
box-shadow: 0px 2px 9px 0px rgba(95, 135, 255, 0.4);
box-sizing: border-box;
border-color: #0044FF;
background-color: #0044FF;
&:hover {
border-color: #0044FF !important;
background-color: #0044FF !important;
color: #fff !important;
}
`,
viewButtonStyle: css`
font-size: 16px;
color: #0044FF;
border-color: #BECFFF;
padding: 10px 15px !important;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 0) !important;
&:hover {
border-color: #BECFFF !important;
color: #0044FF !important;
background-color: rgba(255, 255, 255, 0) !important;
}
`,
checkTitle: css`
color: #0044FF;
margin-right: 5px;
`,
checkItem: css`
margin-top: 15px;
`,
robotAvatarLeftContainer: css`
margin-bottom: 10px;
`,
robotAvatarLeft: css` robotAvatarLeft: css`
margin-bottom: 5px; margin-bottom: 5px;
background: #DFE7FF; background: #DFE7FF;
border-radius: 8px; border-radius: 8px;
padding: 5px 0; padding: 5px 0;
`, `,
robotAvatarLeftContainer: css`
margin-bottom: 10px;
`,
robotBg: css`
width: 120px !important;
height: 80px !important;
margin-top: 10px;
margin-botom: 5px;
border-radius: 8px;
`,
robotImg: css`
margin: 30px 0;
width: 100%;
.ant-image {
width: 100%;
}
`,
robotSetHead: css` robotSetHead: css`
height: 60px; height: 60px;
line-height: 60px; line-height: 60px;
@ -280,35 +198,35 @@ const useStyles = createStyles(({ css, token }) => ({
font-size: 16px; font-size: 16px;
width: 100px; width: 100px;
`, `,
tagStyle: css` searchStyle: css`
width: 70px; .ant-input-affix-wrapper {
height: 30px; border: none;
line-height: 30px; background-color: #F3F6FF;
text-align: center; }
border-radius: 4px; .ant-input-search-button {
opacity: 1; border: none;
background: #F6F6F6; background-color: #F3F6FF;
color: #999999;
margin-right: 20px;
cursor: pointer;
`,
tagStyleActive: css`
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 4px;
opacity: 1;
background-color: #0044FF;
color: #fff !important;
margin-right: 20px;
cursor: pointer;
&:hover { &:hover {
border-color: #0044FF !important; background-color: #F3F6FF !important;
background-color: #0044FF !important; }
color: #fff !important; .ant-btn-icon {
color: #0044FF !important;
}
} }
`, `,
selectStyle: css`
.ant-select-selector {
border: none !important;
background-color: #F0F3FD !important;
}
.ant-select-selection-item {
color: #4A73FF
}
.ant-select-arrow {
color: #2959FF
}
margin-bottom: 15px;
`,
sliderStyle: css` sliderStyle: css`
.ant-slider-handle { .ant-slider-handle {
::after { ::after {
@ -389,48 +307,116 @@ const useStyles = createStyles(({ css, token }) => ({
color: #3A61CB; color: #3A61CB;
cursor: pointer; cursor: pointer;
`, `,
switchRightButton: css` switchLeftButton: css`
position: absolute; position: absolute;
right: 0; left: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;
width: 30px; width: 30px;
line-height: 100px; line-height: 100px;
box-shadow: -1px 0px 6px 0px rgba(139, 162, 229, 0.2392); box-shadow: -1px 0px 6px 0px rgba(139, 162, 229, 0.2392);
`, `,
switchLeftButton: css` switchRightButton: css`
position: absolute; position: absolute;
left: 0; right: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;
width: 30px; width: 30px;
line-height: 100px; line-height: 100px;
box-shadow: -1px 0px 6px 0px rgba(139, 162, 229, 0.2392); box-shadow: -1px 0px 6px 0px rgba(139, 162, 229, 0.2392);
`, `,
robotBg: css` tabStyle: css`
width: 120px !important; .ant-tabs-tab {
height: 80px !important; margin-right: 40px !important;
margin-top: 10px; }
margin-botom: 5px; .ant-tabs-tab-btn {
border-radius: 8px; color: #648EFF
}
.ant-tabs-tab.ant-tabs-tab-active {
.ant-tabs-tab-btn {
color: #0044FF
}
}
.ant-pagination {
.ant-pagination-item-active {
border-color: #0056FF !important
a {
color: #0056FF !important
}
}
}
`, `,
robotImg: css` tableHead: css`
margin: 30px 0; .ant-table-thead {
width: 100%; .ant-table-cell {
.ant-image { background-color: #F1F8FF !important
}
}
`,
tagStyle: css`
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 4px;
opacity: 1;
background: #F6F6F6;
color: #999999;
margin-right: 20px;
cursor: pointer;
`,
tagStyleActive: css`
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 4px;
opacity: 1;
background-color: #0044FF;
color: #fff !important;
margin-right: 20px;
cursor: pointer;
&:hover {
border-color: #0044FF !important;
background-color: #0044FF !important;
color: #fff !important;
}
`,
testContent: css`
width: 100%; width: 100%;
height: 500px;
margin-top: 15px;
padding: 10px;
border-radius: 2px;
border: 1px solid #D9D9D9;
`,
title: css`
font-size: 18px;
font-weight: 700;
`,
viewButtonStyle: css`
font-size: 16px;
color: #0044FF;
border-color: #BECFFF;
padding: 10px 15px !important;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 0) !important;
&:hover {
border-color: #BECFFF !important;
color: #0044FF !important;
background-color: rgba(255, 255, 255, 0) !important;
} }
`, `,
})); }));
const RobotList = memo<{ mobile?: boolean }>(() => { const RobotList = memo<{ mobile?: boolean }>(() => {
const { cx, styles, theme } = useStyles(); const { cx, styles } = useStyles();
const [value, setValue] = useState(1); const [value, setValue] = useState(1);
const [inputValue, setInputValue] = useState(1); const [inputValue, setInputValue] = useState(1);
const [selectedTags, setSelectedTags] = useState(new Set()); const [selectedTags, setSelectedTags] = useState(new Set());
const carouselRef = useRef(null); const carouselRef = useRef(null);
const carouselBgRef = useRef(null); const carouselBgRef = useRef(null);
const { t } = useTranslation('common'); // const { t } = useTranslation('common');
const tags = ['默认', '新闻', '小说', '知识']; const tags = ['默认', '新闻', '小说', '知识'];
const data = [ const data = [
{ {
@ -483,9 +469,9 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
setSelectedTags(newSelectedTags); setSelectedTags(newSelectedTags);
}; };
const handleChange = () => { // const handleChange = () => {
} // }
const handleSwitchNext = () => { const handleSwitchNext = () => {
carouselRef.current.next(); carouselRef.current.next();
@ -503,52 +489,49 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
carouselBgRef.current.prev(); carouselBgRef.current.prev();
} }
const afterChange = (index) => { // const afterChange = (index) => {
// 当Carousel的activeIndex改变时如果是第一次则获取索引并存储 // // 当Carousel的activeIndex改变时如果是第一次则获取索引并存储
if (index === 0) { // if (index === 0) {
} // }
}; // };
const renderItem = () => {}
return ( return (
<> <>
<div style={{display: value == 1 ? 'block': 'none'}}> <div style={{display: value === 1 ? 'block': 'none'}}>
<div style={{ marginLeft: '60px', fontSize: '20px', height: '70px', lineHeight: '70px'}}> <div style={{ fontSize: '20px', height: '70px', lineHeight: '70px', marginLeft: '60px' }}>
<Button className={styles.buttonStyle} style={{marginLeft: '24px'}} type="link" shape="round" size="small" variant="solid" onClick={(val)=>handleSwitch(2)}> <Button className={styles.buttonStyle} onClick={()=>handleSwitch(2)} shape="round" size="small" style={{marginLeft: '24px'}} type="link" variant="solid">
</Button> </Button>
</div> </div>
<List <List
dataSource={data}
grid={{ grid={{
gutter: 80, gutter: 80,
xs: 1,
sm: 2,
md: 4,
lg: 5, lg: 5,
md: 4,
sm: 2,
xl: 5, xl: 5,
xs: 1,
xxl: 5, xxl: 5,
}} }}
dataSource={data} renderItem={() => (
style={{padding: '0 50px',marginTop: '10px'}}
renderItem={(item) => (
<List.Item className={styles.listStyle}> <List.Item className={styles.listStyle}>
<Card className={styles.cardStyle} style={{padding: '0 !important'}}> <Card className={styles.cardStyle} style={{padding: '0 !important'}}>
<div style={{background: '#EFEFEF',textAlign: 'center',padding: '40px 0'}}> <div style={{background: '#EFEFEF', padding: '40px 0', textAlign: 'center'}}>
<Image className={cx(styles.iconImg)} preview={false} src="/images/robot.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot.png" />
</div> </div>
<div style={{marginTop: '30px'}}> <div style={{marginTop: '30px'}}>
<Flex justify='space-between' style={{height: '100%'}}> <Flex justify='space-between' style={{height: '100%'}}>
<div style={{lineHeight: '36px',fontWeight: '700'}}> <div style={{fontWeight: '700', lineHeight: '36px'}}>
Oliva Oliva
</div> </div>
<div> <div>
<Button type="link" style={{color: '#005EFF',paddingRight: '0'}} onClick={(val)=>handleSwitch(2)}> <Button onClick={()=>handleSwitch(2)} style={{color: '#005EFF',paddingRight: '0'}} type="link">
<span className={styles.buttonEdit}></span> <span className={styles.buttonEdit}></span>
</Button> </Button>
<Button type="link" style={{color: '#FF0C0C', paddingRight: '0'}}> <Button style={{color: '#FF0C0C', paddingRight: '0'}} type="link">
<span className={styles.buttonDelete}></span> <span className={styles.buttonDelete}></span>
</Button> </Button>
</div> </div>
@ -557,21 +540,22 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</Card> </Card>
</List.Item> </List.Item>
)} )}
style={{marginTop: '10px', padding: '0 50px'}}
/> />
</div> </div>
<div style={{display: value == 2 ? 'block': 'none',height: '100%'}}> <div style={{display: value === 2 ? 'block': 'none',height: '100%'}}>
<Flex justify='space-between' style={{margin: '15px 0'}} > <Flex justify='space-between' style={{margin: '15px 0'}} >
<div style={{ marginLeft: '60px',fontSize: '20px',lineHeight: '42px' }}> <div style={{ fontSize: '20px',lineHeight: '42px',marginLeft: '60px' }}>
</div> </div>
<Button className={styles.buttonStyle} style={{marginRight: '150px'}} type="text" onClick={(val)=>handleSwitch(1)} shape="round" size="small" variant="solid"> <Button className={styles.buttonStyle} onClick={()=>handleSwitch(1)} shape="round" size="small" style={{marginRight: '150px'}} type="text" variant="solid">
</Button> </Button>
</Flex> </Flex>
<div style={{padding: '0 150px 0 50px',height: '100%'}}> <div style={{height: '100%', padding: '0 150px 0 50px'}}>
<Flex justify='space-between' gap={30} style={{height: '100%'}}> <Flex gap={30} justify='space-between' style={{height: '100%'}}>
<div style={{width: '6%',height: '85%'}}> <div style={{height: '85%', width: '6%'}}>
<Card className={styles.cardStyle} style={{textAlign: 'center',padding: '0'}}> <Card className={styles.cardStyle} style={{padding: '0', textAlign: 'center'}}>
<div className={styles.robotAvatarLeftContainer}> <div className={styles.robotAvatarLeftContainer}>
<div className={styles.robotAvatarLeft}> <div className={styles.robotAvatarLeft}>
<Image className={cx(styles.iconImg)} preview={false} src="/images/robot1.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot1.png" />
@ -622,56 +606,58 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</div> </div>
</Card> </Card>
</div> </div>
<div style={{width: '52%',height: '85%'}}> <div style={{height: '85%', width: '52%'}}>
<Card className={styles.cardRobotStyle} style={{padding: '0 !important', height: '120px'}}> <Card className={styles.cardRobotStyle} style={{height: '120px', padding: '0 !important'}}>
<Carousel infinite={false} afterChange={afterChange} ref={carouselRef}> <Carousel infinite={false}
// afterChange={afterChange}
ref={carouselRef}>
<div> <div>
<Flex gap={50}> <Flex gap={50}>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
@ -681,49 +667,49 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
<Flex gap={50}> <Flex gap={50}>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
<div> <div>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
<Image className={cx(styles.iconImg)} style={{marginTop: '12px',marginBotom: '5px'}} preview={false} src="/images/robot2.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/robot2.png" style={{marginBotom: '5px', marginTop: '12px'}} />
</div> </div>
<div style={{textAlign: 'center'}}>Ellen</div> <div style={{textAlign: 'center'}}>Ellen</div>
</div> </div>
@ -731,17 +717,19 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</div> </div>
</Carousel> </Carousel>
<div className={styles.switchLeftButton} onClick={handleSwitchPrev}> <div className={styles.switchLeftButton} onClick={handleSwitchPrev}>
<Image className={cx(styles.iconImg)} style={{transform: 'rotate(-180deg)'}} preview={false} src="/images/next.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/next.png" style={{transform: 'rotate(-180deg)'}} />
</div> </div>
<div className={styles.switchRightButton} onClick={handleSwitchNext}> <div className={styles.switchRightButton} onClick={handleSwitchNext}>
<Image className={cx(styles.iconImg)} preview={false} src="/images/next.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/next.png" />
</div> </div>
</Card> </Card>
<div className={styles.robotImg}> <div className={styles.robotImg}>
<Image preview={false} style={{width: '100%',height: '600px'}} src="/images/robot_img.png" /> <Image preview={false} src="/images/robot_img.png" style={{height: '600px', width: '100%'}}/>
</div> </div>
<Card className={styles.cardRobotStyle} style={{padding: '0 !important', height: '120px'}}> <Card className={styles.cardRobotStyle} style={{height: '120px', padding: '0 !important'}}>
<Carousel infinite={false} afterChange={afterChange} ref={carouselBgRef}> <Carousel infinite={false}
// afterChange={afterChange}
ref={carouselBgRef}>
<div> <div>
<Flex gap={30}> <Flex gap={30}>
<div> <div>
@ -794,14 +782,14 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</div> </div>
</Carousel> </Carousel>
<div className={styles.switchLeftButton} onClick={handleSwitchBgPrev}> <div className={styles.switchLeftButton} onClick={handleSwitchBgPrev}>
<Image className={cx(styles.iconImg)} style={{transform: 'rotate(-180deg)'}} preview={false} src="/images/next.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/next.png" style={{transform: 'rotate(-180deg)'}}/>
</div> </div>
<div className={styles.switchRightButton} onClick={handleSwitchBgNext}> <div className={styles.switchRightButton} onClick={handleSwitchBgNext}>
<Image className={cx(styles.iconImg)} preview={false} src="/images/next.png" /> <Image className={cx(styles.iconImg)} preview={false} src="/images/next.png" />
</div> </div>
</Card> </Card>
</div> </div>
<div style={{width: '42%',height: '85%'}}> <div style={{height: '85%',width: '42%'}}>
<Card className={styles.cardStyle} style={{ padding: '0' }}> <Card className={styles.cardStyle} style={{ padding: '0' }}>
<div className={styles.robotSetHead}> <div className={styles.robotSetHead}>
@ -813,18 +801,18 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</div> </div>
<div> <div>
<Select <Select
defaultValue="普通话"
style={{
width: 200,
}}
onChange={handleChange}
className={styles.selectStyle} className={styles.selectStyle}
defaultValue="普通话"
// onChange={handleChange}
options={[ options={[
{ {
value: '普通话',
label: '普通话', label: '普通话',
value: '普通话',
}, },
]} ]}
style={{
width: 200,
}}
/> />
</div> </div>
</Flex> </Flex>
@ -837,7 +825,7 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
<div style={{marginTop: '25px'}}> <div style={{marginTop: '25px'}}>
<Flex justify='space-between'> <Flex justify='space-between'>
{tags.map((tagText) => ( {tags.map((tagText) => (
<div key={tagText} onClick={() => handleTagClick(tagText)} className={`${selectedTags.has(tagText) ? styles.tagStyleActive : styles.tagStyle}`}> <div className={`${selectedTags.has(tagText) ? styles.tagStyleActive : styles.tagStyle}`} key={tagText} onClick={() => handleTagClick(tagText)}>
{tagText} {tagText}
</div> </div>
))} ))}
@ -853,24 +841,24 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
<div style={{marginTop: '25px'}}> <div style={{marginTop: '25px'}}>
<Flex> <Flex>
<Slider <Slider
min={0} className={styles.sliderStyle}
max={2}
defaultValue={1} defaultValue={1}
max={2}
min={0}
onChange={onChange} onChange={onChange}
style={{width: '300px'}} style={{width: '300px'}}
className={styles.sliderStyle}
value={typeof inputValue === 'number' ? inputValue : 0} value={typeof inputValue === 'number' ? inputValue : 0}
/> />
<Input <Input
min={0}
max={2} max={2}
min={0}
onChange={onChange}
style={{ style={{
width: '40px',
marginLeft: '20px', marginLeft: '20px',
textAlign: 'center' textAlign: 'center',
width: '40px'
}} }}
value={inputValue} value={inputValue}
onChange={onChange}
/> />
</Flex> </Flex>
</div> </div>
@ -884,24 +872,24 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
<div style={{marginTop: '25px'}}> <div style={{marginTop: '25px'}}>
<Flex> <Flex>
<Slider <Slider
min={0} className={styles.sliderStyle}
max={2}
defaultValue={1} defaultValue={1}
max={2}
min={0}
onChange={onChange} onChange={onChange}
style={{width: '300px'}} style={{width: '300px'}}
className={styles.sliderStyle}
value={typeof inputValue === 'number' ? inputValue : 0} value={typeof inputValue === 'number' ? inputValue : 0}
/> />
<Input <Input
min={0}
max={2} max={2}
min={0}
onChange={onChange}
style={{ style={{
width: '40px',
marginLeft: '20px', marginLeft: '20px',
textAlign: 'center' textAlign: 'center',
width: '40px'
}} }}
value={inputValue} value={inputValue}
onChange={onChange}
/> />
</Flex> </Flex>
</div> </div>
@ -915,24 +903,24 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
<div style={{marginTop: '25px'}}> <div style={{marginTop: '25px'}}>
<Flex> <Flex>
<Slider <Slider
min={0} className={styles.sliderStyle}
max={2}
defaultValue={1} defaultValue={1}
max={2}
min={0}
onChange={onChange} onChange={onChange}
style={{width: '300px'}} style={{width: '300px'}}
className={styles.sliderStyle}
value={typeof inputValue === 'number' ? inputValue : 0} value={typeof inputValue === 'number' ? inputValue : 0}
/> />
<Input <Input
min={0}
max={2} max={2}
min={0}
onChange={onChange}
style={{ style={{
width: '40px',
marginLeft: '20px', marginLeft: '20px',
textAlign: 'center' textAlign: 'center',
width: '40px'
}} }}
value={inputValue} value={inputValue}
onChange={onChange}
/> />
</Flex> </Flex>
</div> </div>
@ -945,18 +933,17 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</div> </div>
<div style={{marginTop: '25px'}}> <div style={{marginTop: '25px'}}>
<List <List
dataSource={data}
grid={{ grid={{
gutter: 80, gutter: 80,
xs: 1,
sm: 2,
md: 4,
lg: 5, lg: 5,
md: 4,
sm: 2,
xl: 5, xl: 5,
xs: 1,
xxl: 5, xxl: 5,
}} }}
dataSource={data} renderItem={() => (
style={{padding: '0 50px',marginTop: '10px'}}
renderItem={(item) => (
<List.Item className={styles.listStyle}> <List.Item className={styles.listStyle}>
<div className={styles.soundCard}> <div className={styles.soundCard}>
<div className={styles.soundCardAvatar}> <div className={styles.soundCardAvatar}>
@ -968,6 +955,7 @@ const RobotList = memo<{ mobile?: boolean }>(() => {
</div> </div>
</List.Item> </List.Item>
)} )}
style={{marginTop: '10px', padding: '0 50px'}}
/> />
</div> </div>
</Flex> </Flex>

@ -1,13 +1,12 @@
import { WelcomeLogo } from '@/components/Branding'; // import { WelcomeLogo } from '@/components/Branding';
import StructuredData from '@/components/StructuredData'; // import StructuredData from '@/components/StructuredData';
import { BRANDING_NAME } from '@/const/branding'; import { BRANDING_NAME } from '@/const/branding';
import { ldModule } from '@/server/ld'; // import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata'; import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive'; // import { isMobileDevice } from '@/utils/responsive';
import {Button} from "antd";
import {createStyles} from "antd-style";
import RobotList from './components/RobotList'; import RobotList from './components/RobotList';
export const generateMetadata = async () => { export const generateMetadata = async () => {
const { t } = await translation('metadata'); const { t } = await translation('metadata');
return metadataModule.generate({ return metadataModule.generate({
@ -18,13 +17,13 @@ export const generateMetadata = async () => {
}; };
const Page = async () => { const Page = async () => {
const mobile = isMobileDevice(); // const mobile = isMobileDevice();
const { t } = await translation('metadata'); // const { t } = await translation('metadata');
const ld = ldModule.generate({ // const ld = ldModule.generate({
description: t('robot.description', { appName: BRANDING_NAME }), // description: t('robot.description', { appName: BRANDING_NAME }),
title: t('robot.title', { appName: BRANDING_NAME }), // title: t('robot.title', { appName: BRANDING_NAME }),
url: '/robot', // url: '/robot',
}); // });
return ( return (
<> <>

@ -32,7 +32,7 @@ const SidebarLayout = ({ children, className, title, desc, ...rest }: SidebarLay
width={280} width={280}
{...rest} {...rest}
> >
<PanelTitle desc={desc || t('header.desc')} title={title || t('header.session')} /> <PanelTitle desc={desc || t('header.desc')} title={title || t('header.title')} />
{children} {children}
<BrandWatermark paddingInline={12} /> <BrandWatermark paddingInline={12} />
</Flexbox> </Flexbox>

@ -1,32 +1,144 @@
'use client'; 'use client';
import isEqual from 'fast-deep-equal'; import { SiDiscord, SiGithub, SiMedium, SiRss, SiX } from '@icons-pack/react-simple-icons';
import { Form } from '@lobehub/ui';
import { Divider } from 'antd';
import { createStyles } from 'antd-style';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import { INBOX_SESSION_ID } from '@/const/session'; import { BRANDING_NAME } from '@/const/branding';
import { AgentSettingAbout } from '@/features/AgentSetting'; import {
import { useUserStore } from '@/store/user'; BLOG,
import { settingsSelectors } from '@/store/user/selectors'; DISCORD,
EMAIL_BUSINESS,
EMAIL_SUPPORT,
GITHUB,
MEDIDUM,
OFFICIAL_SITE,
PRIVACY_URL,
TERMS_URL,
X,
mailTo,
} from '@/const/url';
import { useServerConfigStore } from '@/store/serverConfig';
import { serverConfigSelectors } from '@/store/serverConfig/selectors';
const Page = memo(() => { import AboutList from './features/AboutList';
const config = useUserStore(settingsSelectors.defaultAgentConfig, isEqual); import Analytics from './features/Analytics';
const meta = useUserStore(settingsSelectors.defaultAgentMeta, isEqual); import ItemCard from './features/ItemCard';
const [updateAgent] = useUserStore((s) => [s.updateDefaultAgent]); import ItemLink from './features/ItemLink';
import Version from './features/Version';
const useStyles = createStyles(({ css, token }) => ({
title: css`
font-size: 14px;
font-weight: bold;
color: ${token.colorTextSecondary};
`,
}));
const Page = memo<{ mobile?: boolean }>(({ mobile }) => {
const { t } = useTranslation('common');
const { styles } = useStyles();
const enabledTelemetryChat = useServerConfigStore(serverConfigSelectors.enabledTelemetryChat);
return ( return (
<AgentSettingAbout <>
config={config} <Form.Group
id={INBOX_SESSION_ID} style={{ width: '100%' }}
meta={meta} title={`${t('about')} ${BRANDING_NAME}`}
onConfigChange={(config) => { variant={'pure'}
updateAgent({ config }); >
}} <Flexbox gap={20} paddingBlock={20} width={'100%'}>
onMetaChange={(meta) => { <div className={styles.title}>{t('version')}</div>
updateAgent({ meta }); <Version mobile={mobile} />
}} <Divider style={{ marginBlock: 0 }} />
<div className={styles.title}>{t('contact')}</div>
<AboutList
ItemRender={ItemLink}
items={[
{
href: OFFICIAL_SITE,
label: t('officialSite'),
value: 'officialSite',
},
{
href: mailTo(EMAIL_SUPPORT),
label: t('mail.support'),
value: 'support',
},
{
href: mailTo(EMAIL_BUSINESS),
label: t('mail.business'),
value: 'business',
},
]}
/>
<Divider style={{ marginBlock: 0 }} />
<div className={styles.title}>{t('information')}</div>
<AboutList
ItemRender={ItemCard}
grid
items={[
{
href: BLOG,
icon: SiRss,
label: t('blog'),
value: 'blog',
},
{
href: GITHUB,
icon: SiGithub,
label: 'GitHub',
value: 'feedback',
},
{
href: DISCORD,
icon: SiDiscord,
label: 'Discord',
value: 'discord',
},
{
href: X,
icon: SiX as any,
label: 'X / Twitter',
value: 'x',
},
{
href: MEDIDUM,
icon: SiMedium,
label: 'Medium',
value: 'medium',
},
]}
/>
<Divider style={{ marginBlock: 0 }} />
<div className={styles.title}>{t('legal')}</div>
<AboutList
ItemRender={ItemLink}
items={[
{
href: TERMS_URL,
label: t('terms'),
value: 'terms',
},
{
href: PRIVACY_URL,
label: t('privacy'),
value: 'privacy',
},
]}
/> />
</Flexbox>
</Form.Group>
{enabledTelemetryChat && <Analytics />}
</>
); );
}); });
Page.displayName = 'AboutSetting'; Page.displayName = 'AboutSetting';
export default Page; export default Page;

@ -1,13 +1,12 @@
'use client'; 'use client';
// import { Form, type ItemGroup, SelectWithImg, SliderWithInput } from '@lobehub/ui'; import { Form, type ItemGroup, SelectWithImg, SliderWithInput } from '@lobehub/ui';
import { Select } from 'antd';
import isEqual from 'fast-deep-equal'; import isEqual from 'fast-deep-equal';
import { Monitor, Moon, Sun } from 'lucide-react'; import { Monitor, Moon, Sun } from 'lucide-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import {Form, Select} from "antd";
import {EditFilled} from "@ant-design/icons";
import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings'; import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
import { FORM_STYLE } from '@/const/layoutTokens'; import { FORM_STYLE } from '@/const/layoutTokens';
@ -23,247 +22,140 @@ import {
import { switchLang } from '@/utils/client/switchLang'; import { switchLang } from '@/utils/client/switchLang';
import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from './ThemeSwatches'; import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from './ThemeSwatches';
import {createStyles} from "antd-style";
// type SettingItemGroup = ItemGroup; type SettingItemGroup = ItemGroup;
const useStyles = createStyles(({ css, token }) => ({
cricle: css`
width: 8px;
height: 8px;
border-radius: 8px;
display: inline-block;
margin-right: 15px;
background-color: #4F4F4F;
`,
onlyDiv: css`
padding: 15px 40px;
`,
leftText: css`
width: 200px;
font-size: 18px;
color: #333;
display: inline-block
`,
leftDir: css`
color: #999999;
font-size: 16px;
display: inline-block;
margin-left: 5px;
`,
rightText: css`
width: calc(100% - 215px);
text-align: right;
color: #333333;
font-size: 16px;
display: inline-block;
margin-right: 15px;
`,
childrenLeftText: css`
margin-left: 50px;
`,
childrenRightText: css`
width: calc(100% - 265px);
`,
childrenlangText: css`
margin-left: 50px;
width: calc(100% - 65px);
text-align: left;
`,
topTitle: css`
font-size: 18px;
font-weight: bold;
color: #333333;
`,
topEdit: css`
display: inline-block;
text-align: center;
width: 24px;
height: 24px;
background-color: #AFC1FF;
color: #fff;
`,
}))
const Theme = memo(() => { const Theme = memo(() => {
const { t } = useTranslation('setting'); const { t } = useTranslation('setting');
const router = useRouter(); const router = useRouter();
const { styles, cx } = useStyles()
const [form] = Form.useForm(); const [form] = Form.useForm();
// const settings = useUserStore(settingsSelectors.currentSettings, isEqual); const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
// const themeMode = useUserStore(userGeneralSettingsSelectors.currentThemeMode); const themeMode = useUserStore(userGeneralSettingsSelectors.currentThemeMode);
// const [setThemeMode, setSettings, enableAuth] = useUserStore((s) => [ const [setThemeMode, setSettings, enableAuth] = useUserStore((s) => [
// s.switchThemeMode, s.switchThemeMode,
// s.setSettings, s.setSettings,
// authSelectors.enabledAuth(s), authSelectors.enabledAuth(s),
// ]); ]);
useSyncSettings(form);
// useSyncSettings(form); const handleLangChange = (value: Locales) => {
// switchLang(value);
// const handleLangChange = (value: Locales) => { router.refresh();
// switchLang(value); };
// router.refresh();
// };
// const theme: SettingItemGroup = { const theme: SettingItemGroup = {
// children: [ children: [
// { {
// children: <AvatarWithUpload />, children: <AvatarWithUpload />,
// hidden: enableAuth, hidden: enableAuth,
// label: t('settingTheme.avatar.title'), label: t('settingTheme.avatar.title'),
// minWidth: undefined, minWidth: undefined,
// }, },
// { {
// children: ( children: (
// <SelectWithImg <SelectWithImg
// height={60} height={60}
// onChange={setThemeMode} onChange={setThemeMode}
// options={[ options={[
// { {
// icon: Sun, icon: Sun,
// img: imageUrl('theme_light.webp'), img: imageUrl('theme_light.webp'),
// label: t('settingTheme.themeMode.light'), label: t('settingTheme.themeMode.light'),
// value: 'light', value: 'light',
// }, },
// { {
// icon: Moon, icon: Moon,
// img: imageUrl('theme_dark.webp'), img: imageUrl('theme_dark.webp'),
// label: t('settingTheme.themeMode.dark'), label: t('settingTheme.themeMode.dark'),
// value: 'dark', value: 'dark',
// }, },
// { {
// icon: Monitor, icon: Monitor,
// img: imageUrl('theme_auto.webp'), img: imageUrl('theme_auto.webp'),
// label: t('settingTheme.themeMode.auto'), label: t('settingTheme.themeMode.auto'),
// value: 'auto', value: 'auto',
// }, },
// ]} ]}
// unoptimized={false} unoptimized={false}
// value={themeMode} value={themeMode}
// width={100} width={100}
// /> />
// ), ),
// label: t('settingTheme.themeMode.title'), label: t('settingTheme.themeMode.title'),
// minWidth: undefined, minWidth: undefined,
// }, },
// { {
// children: ( children: (
// <Select <Select
// onChange={handleLangChange} onChange={handleLangChange}
// options={[{ label: t('settingTheme.lang.autoMode'), value: 'auto' }, ...localeOptions]} options={[{ label: t('settingTheme.lang.autoMode'), value: 'auto' }, ...localeOptions]}
// /> />
// ), ),
// label: t('settingTheme.lang.title'), label: t('settingTheme.lang.title'),
// name: ['general', 'language'], name: ['general', 'language'],
// }, },
// { {
// children: ( children: (
// <SliderWithInput <SliderWithInput
// marks={{ marks={{
// 12: { 12: {
// label: 'A', label: 'A',
// style: { style: {
// fontSize: 12, fontSize: 12,
// marginTop: 4, marginTop: 4,
// }, },
// }, },
// 14: { 14: {
// label: t('settingTheme.fontSize.marks.normal'), label: t('settingTheme.fontSize.marks.normal'),
// style: { style: {
// fontSize: 14, fontSize: 14,
// marginTop: 4, marginTop: 4,
// }, },
// }, },
// 18: { 18: {
// label: 'A', label: 'A',
// style: { style: {
// fontSize: 18, fontSize: 18,
// marginTop: 4, marginTop: 4,
// }, },
// }, },
// }} }}
// max={18} max={18}
// min={12} min={12}
// step={1} step={1}
// /> />
// ), ),
// desc: t('settingTheme.fontSize.desc'), desc: t('settingTheme.fontSize.desc'),
// label: t('settingTheme.fontSize.title'), label: t('settingTheme.fontSize.title'),
// name: ['general', 'fontSize'], name: ['general', 'fontSize'],
// }, },
// { {
// children: <ThemeSwatchesPrimary />, children: <ThemeSwatchesPrimary />,
// desc: t('settingTheme.primaryColor.desc'), desc: t('settingTheme.primaryColor.desc'),
// label: t('settingTheme.primaryColor.title'), label: t('settingTheme.primaryColor.title'),
// minWidth: undefined, minWidth: undefined,
// }, },
// { {
// children: <ThemeSwatchesNeutral />, children: <ThemeSwatchesNeutral />,
// desc: t('settingTheme.neutralColor.desc'), desc: t('settingTheme.neutralColor.desc'),
// label: t('settingTheme.neutralColor.title'), label: t('settingTheme.neutralColor.title'),
// minWidth: undefined, minWidth: undefined,
// }, },
// ], ],
// title: t('settingTheme.title'), title: t('settingTheme.title'),
// }; };
return ( return (
// <Form <Form
// form={form} form={form}
// initialValues={settings} initialValues={settings}
// items={[theme]} items={[theme]}
// itemsType={'group'} itemsType={'group'}
// onValuesChange={setSettings} onValuesChange={setSettings}
// variant={'pure'} variant={'pure'}
// {...FORM_STYLE} {...FORM_STYLE}
// /> />
<Form form={form}>
<div className={cx(styles.onlyDiv, styles.topTitle)}>
<div className={cx(styles.leftText)}></div>
<div className={styles.rightText}><div className={cx(styles.topEdit)}><EditFilled /></div></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}><span className={cx(styles.cricle)}></span><span className={cx(styles.leftDir)}>/Role</span></div>
<div className={cx(styles.rightText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}><span className={cx(styles.cricle)}></span><span className={cx(styles.leftDir)}>/Profile</span></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText, styles.childrenLeftText)}><span className={cx(styles.leftDir)}>/Author</span></div>
<div className={cx(styles.rightText, styles.childrenRightText)}>adoadadu</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText, styles.childrenLeftText)}><span className={cx(styles.leftDir)}>/Version</span></div>
<div className={cx(styles.rightText, styles.childrenRightText)}>1.02</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText, styles.childrenLeftText)}><span className={cx(styles.leftDir)}>/Language</span></div>
<div className={cx(styles.rightText, styles.childrenRightText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText, styles.childrenLeftText)}><span className={cx(styles.leftDir)}>/Description</span></div>
<div className={cx(styles.rightText, styles.childrenRightText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}><span className={cx(styles.cricle)}></span><span className={cx(styles.leftDir)}>/Background</span></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.rightText, styles.childrenlangText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}><span className={cx(styles.cricle)}></span><span className={cx(styles.leftDir)}>/Goals</span></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.rightText, styles.childrenlangText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}><span className={cx(styles.cricle)}></span><span className={cx(styles.leftDir)}>/Rules</span></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.rightText, styles.childrenlangText)}></div>
</div>
</Form>
); );
}); });

@ -1,13 +1,11 @@
import Common from './features/Common'; import Common from './features/Common';
import Theme from './features/Theme'; import Theme from './features/Theme';
import {Form} from "antd";
const Page = () => { const Page = () => {
return ( return (
<> <>
<Theme /> <Theme />
{/*<Common />*/} <Common />
</> </>
); );
}; };

@ -18,15 +18,6 @@ export const useCategory = () => {
const cateItems: MenuProps['items'] = useMemo( const cateItems: MenuProps['items'] = useMemo(
() => () =>
[ [
{
icon: <Icon icon={Bot} />,
key: SettingsTabs.Agent,
label: (
<Link href={'/settings/agent'} onClick={(e) => e.preventDefault()}>
{t('tab.agent')}
</Link>
),
},
{ {
icon: <Icon icon={Settings2} />, icon: <Icon icon={Settings2} />,
key: SettingsTabs.Common, key: SettingsTabs.Common,
@ -45,21 +36,21 @@ export const useCategory = () => {
</Link> </Link>
), ),
}, },
// { enableWebrtc && {
// icon: <Icon icon={Cloudy} />, icon: <Icon icon={Cloudy} />,
// key: SettingsTabs.Sync, key: SettingsTabs.Sync,
// label: ( label: (
// <Link href={'/settings/sync'} onClick={(e) => e.preventDefault()}> <Link href={'/settings/sync'} onClick={(e) => e.preventDefault()}>
// <Flexbox align={'center'} gap={8} horizontal> <Flexbox align={'center'} gap={8} horizontal>
// {t('tab.sync')} {t('tab.sync')}
// <Tag bordered={false} color={'warning'}> <Tag bordered={false} color={'warning'}>
// {t('tab.experiment')} {t('tab.experiment')}
// </Tag> </Tag>
// </Flexbox> </Flexbox>
// </Link> </Link>
// ), ),
// }, },
{ showLLM && {
icon: <Icon icon={Brain} />, icon: <Icon icon={Brain} />,
key: SettingsTabs.LLM, key: SettingsTabs.LLM,
label: ( label: (
@ -69,7 +60,7 @@ export const useCategory = () => {
), ),
}, },
{ enableSTT && {
icon: <Icon icon={Mic2} />, icon: <Icon icon={Mic2} />,
key: SettingsTabs.TTS, key: SettingsTabs.TTS,
label: ( label: (
@ -79,20 +70,20 @@ export const useCategory = () => {
), ),
}, },
{ {
icon: <Icon icon={Info} />, icon: <Icon icon={Bot} />,
key: SettingsTabs.About, key: SettingsTabs.Agent,
label: ( label: (
<Link href={'/settings/about'} onClick={(e) => e.preventDefault()}> <Link href={'/settings/agent'} onClick={(e) => e.preventDefault()}>
{t('tab.about')} {t('tab.agent')}
</Link> </Link>
), ),
}, },
{ !hideDocs && {
icon: <Icon icon={Cloudy} />, icon: <Icon icon={Info} />,
key: SettingsTabs.Szr, key: SettingsTabs.About,
label: ( label: (
<Link href={'/settings/szr'} onClick={(e) => e.preventDefault()}> <Link href={'/settings/about'} onClick={(e) => e.preventDefault()}>
{t('tab.szr')} {t('tab.about')}
</Link> </Link>
), ),
}, },

@ -1,32 +1,23 @@
'use client'; 'use client';
import isEqual from 'fast-deep-equal'; import { Flexbox } from 'react-layout-kit';
import { memo } from 'react';
import { INBOX_SESSION_ID } from '@/const/session'; import { useProviderList } from './ProviderList/providers';
import { AgentSettingLlm } from '@/features/AgentSetting'; import ProviderConfig from './components/ProviderConfig';
import { useUserStore } from '@/store/user'; import Footer from './features/Footer';
import { settingsSelectors } from '@/store/user/selectors';
const Page = memo(() => { const Page = () => {
const config = useUserStore(settingsSelectors.defaultAgentConfig, isEqual); const list = useProviderList();
const meta = useUserStore(settingsSelectors.defaultAgentMeta, isEqual);
const [updateAgent] = useUserStore((s) => [s.updateDefaultAgent]);
return ( return (
<AgentSettingLlm <Flexbox gap={24} width={'100%'}>
config={config} {list.map(({ id, ...res }) => (
id={INBOX_SESSION_ID} <ProviderConfig id={id as any} key={id} {...res} />
meta={meta} ))}
onConfigChange={(config) => { <Footer />
updateAgent({ config }); </Flexbox>
}}
onMetaChange={(meta) => {
updateAgent({ meta });
}}
/>
); );
}); };
Page.displayName = 'LlmSetting'; Page.displayName = 'LlmSetting';

@ -1,32 +1,14 @@
'use client'; import SystemAgentForm from './features/createForm';
import isEqual from 'fast-deep-equal';
import { memo } from 'react';
import { INBOX_SESSION_ID } from '@/const/session';
import { AgentSettingChat } from '@/features/AgentSetting';
import { useUserStore } from '@/store/user';
import { settingsSelectors } from '@/store/user/selectors';
const Page = memo(() => {
const config = useUserStore(settingsSelectors.defaultAgentConfig, isEqual);
const meta = useUserStore(settingsSelectors.defaultAgentMeta, isEqual);
const [updateAgent] = useUserStore((s) => [s.updateDefaultAgent]);
const Page = () => {
return ( return (
<AgentSettingChat <>
config={config} <SystemAgentForm systemAgentKey="topic" />
id={INBOX_SESSION_ID} <SystemAgentForm systemAgentKey="translation" />
meta={meta} <SystemAgentForm systemAgentKey="agentMeta" />
onConfigChange={(config) => { </>
updateAgent({ config });
}}
onMetaChange={(meta) => {
updateAgent({ meta });
}}
/>
); );
}); };
Page.displayName = 'SystemAgent'; Page.displayName = 'SystemAgent';

@ -1,317 +0,0 @@
'use client';
import {memo, useEffect, useState} from 'react';
import {Form, Select, Radio, Slider, InputNumber, Image} from "antd";
import {createStyles} from "antd-style";
const ysOptions = [
{id: '1', name: '男声', icon: '/images/per.png/'},
{id: '2', name: '男声', icon: '/images/per.png/'},
{id: '3', name: '男声', icon: '/images/per.png/'},
{id: '4', name: '男声', icon: '/images/per.png/'},
{id: '5', name: '男声', icon: '/images/per.png/'},
{id: '6', name: '男声', icon: '/images/per.png/'},
{id: '7', name: '男声', icon: '/images/per.png/'},
]
const useStyles = createStyles(({ css, token }) => ({
cricle: css`
width: 8px;
height: 8px;
border-radius: 8px;
display: inline-block;
margin-right: 15px;
background-color: #4F4F4F;
`,
onlyDiv: css`
padding: 15px 40px;
`,
leftText: css`
width: 200px;
font-size: 18px;
color: #333;
display: inline-block
`,
leftDir: css`
color: #999999;
font-size: 16px;
display: inline-block;
margin-left: 5px;
`,
rightText: css`
width: calc(100% - 215px);
text-align: right;
color: #333333;
font-size: 16px;
display: inline-block;
margin-right: 15px;
`,
childrenLeftText: css`
margin-left: 50px;
`,
childrenRightText: css`
width: calc(100% - 265px);
`,
childrenlangText: css`
margin-left: 50px;
width: calc(100% - 65px);
text-align: left;
`,
circleImg: css`
width: 62px;
height: 62px;
line-height: 62px;
display: inline-block;
margin-right: 15px;
text-align: center;
position: relative;
border-radius: 62px;
background-color: #B8C8FF;
border: 1px solid #B8C8FF;
`,
optName: css`
display: inline-block;
position: absolute;
line-height: normal;
font-size: 13px;
background: #C1CFFF;
border-radius: 18px;
color: #3A61CB;
bottom: -5px;
left: 10px;
padding: 2px 6px;
`,
circleSeleImg: css`
border: 1px solid #0044FF;
`,
optSeleName: css`
background: #0044FF;
color: #fff;
`,
radioRigh: css`
margin-right: 24px
`,
topTitle: css`
font-size: 18px;
font-weight: bold;
color: #333333;
`,
}))
const szrOptions = [
{
value: '1',
label: 'Jack',
},
{
value: '2',
label: 'Lucy',
},
{
value: '3',
label: 'yiminghe',
},
]
const yyOptions = [
{
label: '普通话',
value: 'pth',
},
{
label: '英文',
value: 'yw',
},
{
label: '法语',
value: 'fy',
},
]
const Page = memo(() => {
const [form] = Form.useForm()
const { styles, cx } = useStyles()
const [optValue, setOptValue] = useState("")
useEffect(() => {
form.setFieldsValue({
szr: '1',
yy: 'pth',
ys: '1.0',
ysnum: '1.0',
yd: '1.0',
ydnum: '1.0',
yl: '1.0',
ylnum: '1.0',
})
})
const onChangeYs = (val) => {
form.setFieldsValue({
ysnum: val
})
}
const onChangeYd = (val) => {
form.setFieldsValue({
ydnum: val
})
}
const onChangeYl = (val) => {
form.setFieldsValue({
ylnum: val
})
}
const onClickYin = (e) => {
setOptValue(e.id)
}
return (
<>
<Form form={form} style={{ marginBottom: '30px' }}>
<div className={cx(styles.onlyDiv, styles.topTitle)}>
<div className={cx(styles.leftText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
<Form.Item label="" name="szr">
<Select
style={{ width: 120, textAlign: 'left' }}
options={szrOptions}
/>
</Form.Item>
</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.rightText, styles.childrenlangText)} style={{ textAlgin: 'center' }}>
<Image alt={'数字人形象'} src="/images/szrxx.png" preview={false} />
</div>
</div>
<div className={cx(styles.onlyDiv, styles.topTitle)}>
<div className={cx(styles.leftText)}></div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
<Form.Item label="" name="yy">
<Select
style={{ width: 120, textAlign: 'left' }}
options={yyOptions}
/>
</Form.Item>
</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
<Form.Item label="" name="fg">
<Radio.Group disabled buttonStyle="solid">
<Radio.Button className={styles.radioRigh} value="mr"></Radio.Button>
<Radio.Button className={styles.radioRigh} value="xw"></Radio.Button>
<Radio.Button className={styles.radioRigh} value="xx"></Radio.Button>
<Radio.Button className={styles.radioRigh} value="zs"></Radio.Button>
</Radio.Group>
</Form.Item>
</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
<Form.Item style={{ display: 'inline-block'}} label="" name="ys">
<Slider
style={{ width: "120px" }}
min={0}
max={2}
onChange={(e) => onChangeYs(e)}
step={0.1}
/>
</Form.Item>
<Form.Item style={{ display: 'inline-block'}} label="" name="ysnum">
<InputNumber
min={0}
max={2}
style={{
margin: '0 16px',
}}
step={0.1}
/>
</Form.Item>
</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
<Form.Item style={{ display: 'inline-block'}} label="" name="yd">
<Slider
style={{ width: "120px" }}
min={0}
max={2}
onChange={(e) => onChangeYd(e)}
step={0.1}
/>
</Form.Item>
<Form.Item style={{ display: 'inline-block'}} label="" name="ydnum">
<InputNumber
min={0}
max={2}
style={{
margin: '0 16px',
}}
step={0.1}
/>
</Form.Item>
</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
<Form.Item style={{ display: 'inline-block'}} label="" name="yl">
<Slider
style={{ width: "120px" }}
min={0}
max={2}
onChange={(e) => onChangeYl(e)}
step={0.1}
/>
</Form.Item>
<Form.Item style={{ display: 'inline-block'}} label="" name="ylnum">
<InputNumber
min={0}
max={2}
style={{
margin: '0 16px',
}}
step={0.1}
/>
</Form.Item>
</div>
</div>
<div className={cx(styles.onlyDiv)}>
<div className={cx(styles.leftText)}></div>
<div className={cx(styles.rightText)}>
{
ysOptions.map(e => {
return (
<div className={cx(styles.circleImg, optValue==e.id&&styles.circleSeleImg)} onClick={() => onClickYin(e)}>
<Image alt={e.name} src={e.icon} preview={false} />
<span className={cx(styles.optName, optValue==e.id&&styles.optSeleName)}>{e.name}</span>
</div>
)
})
}
</div>
</div>
</Form>
</>
);
});
Page.displayName = 'SzrSetting';
export default Page;

@ -1,12 +0,0 @@
import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
export const generateMetadata = async () => {
const { t } = await translation('setting');
return metadataModule.generate({
description: t('header.desc'),
title: t('tab.szr'),
url: '/settings/szr',
});
};
export { default } from './index';

@ -1,32 +1,14 @@
'use client'; import OpenAI from './features/OpenAI';
import STT from './features/STT';
import isEqual from 'fast-deep-equal';
import { memo } from 'react';
import { INBOX_SESSION_ID } from '@/const/session';
import { AgentSettingTts } from '@/features/AgentSetting';
import { useUserStore } from '@/store/user';
import { settingsSelectors } from '@/store/user/selectors';
const Page = memo(() => {
const config = useUserStore(settingsSelectors.defaultAgentConfig, isEqual);
const meta = useUserStore(settingsSelectors.defaultAgentMeta, isEqual);
const [updateAgent] = useUserStore((s) => [s.updateDefaultAgent]);
const Page = () => {
return ( return (
<AgentSettingTts <>
config={config} <STT />
id={INBOX_SESSION_ID} <OpenAI />
meta={meta} </>
onConfigChange={(config) => {
updateAgent({ config });
}}
onMetaChange={(meta) => {
updateAgent({ meta });
}}
/>
); );
}); };
Page.displayName = 'TtsSetting'; Page.displayName = 'TtsSetting';

@ -1,16 +1,17 @@
import axios from 'axios'; import axios from 'axios';
// 创建axios实例 // 创建axios实例
const service = axios.create({ const service = axios.create({
baseURL: `http://192.168.7.3:18080`, // 设置基础URL baseURL: 'http://192.168.7.3:18080', // 设置基础URL
timeout: 60000 // 设置请求超时时间 timeout: '60000' ,// 设置请求超时时间
// withCredentials: true,
}); });
// service.defaults.withCredentials = true;
// 请求拦截器 // 请求拦截器
service.interceptors.request.use( service.interceptors.request.use(
(config) => { (config) => {
// 在发送请求之前做些什么例如添加token到headers // 在发送请求之前做些什么例如添加token到headers
// config.headers['Authorization'] = 'Bearer ' + token; // config.headers['cookie'] = 'authjs.csrf-token=024846fb3c7ff4d8baffaf9de069396e72ab6c439fb44ce126830edee05d2e88%7Ccc355f6cf425ed6dc60262ef653a29adb8c2a05aba34ddf4a2c1c4dfa59d5613; authjs.callback-url=http%3A%2F%2F192.168.15.199%3A3210%2Fchat%3Fsession%3Dinbox%26topic%3Dtpc_nBRvJCjmn1as; LOBE_LOCALE=zh-CN; LOBE_THEME_PRIMARY_COLOR=undefined; LOBE_THEME_NEUTRAL_COLOR=undefined; authjs.session-token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoiY3FXQ2gyUDdpSVZEdkFQZEtHQU55d0JJdmFaMDhGVzJfV1pBelQxYjVoV0oyRjRubDF1LWFJdllYeHkxMW4zZU1kdjVrMlAxWFRwQWdfZl9SdDU2Q2cifQ..wduWoP240CT_p3rOpF3vWg.do7yfgOkk8YMgwApJ1C2-rkBVPh9x00dXBNe-SMhhTj5NH5EEfwEYQiqHb3ZJwnSdT_L6d_GnY42NvgS6E1yTmi54gCdxabms-Eemy75IB_UCDcQjak7e4hSRFdAbH8AjA0MeS6fpJcFJlkWwniZf9kWZsuvy-m702_4SsP8E9E5b_X-9EIX85cDhRFjUC6cNdpNcwY98CvlhI7X-PMh20unkhSRiKCLJOaEKIZeJg_REGezxGcz3NrIE30fI3KB0T5tHetKYO_6BYJ5KCWgiaKHebgxSA21KTXeggpv0Q-UBS5yOmys32Ra2NwFroyahJ9VC0Z3cQiZegb7GXIjkg.UfjoEB1hV-NjULY12ZqZp_hLeInM4LCUHhUNyeqygws';
config.headers['x-lobe-chat-auth'] = 'http_nosafe.eyJhY2Nlc3NDb2RlIjoiIiwidXNlcklkIjoiZmQ4YWUzNTktNjRkYy00YTU3LWFiNDEtNTQzOGUyZmRhOTc1In0=';
return config; return config;
}, },
(error) => { (error) => {

@ -2,6 +2,7 @@ import { createEnv } from '@t3-oss/env-nextjs';
import { z } from 'zod'; import { z } from 'zod';
export const getServerDBConfig = () => { export const getServerDBConfig = () => {
console.log(process.env.DATABASE_URL,'111111111111111111database------------')
return createEnv({ return createEnv({
client: { client: {
NEXT_PUBLIC_ENABLED_SERVER_SERVICE: z.boolean(), NEXT_PUBLIC_ENABLED_SERVER_SERVICE: z.boolean(),
@ -9,7 +10,7 @@ export const getServerDBConfig = () => {
runtimeEnv: { runtimeEnv: {
DATABASE_DRIVER: process.env.DATABASE_DRIVER || 'neon', DATABASE_DRIVER: process.env.DATABASE_DRIVER || 'neon',
DATABASE_TEST_URL: process.env.DATABASE_TEST_URL, DATABASE_TEST_URL: process.env.DATABASE_TEST_URL,
DATABASE_URL: process.env.DATABASE_URL, DATABASE_URL: 'jdbc:postgresql://192.168.15.199:5432/lobechat',
DISABLE_REMOVE_GLOBAL_FILE: process.env.DISABLE_REMOVE_GLOBAL_FILE === '1', DISABLE_REMOVE_GLOBAL_FILE: process.env.DISABLE_REMOVE_GLOBAL_FILE === '1',

@ -22,12 +22,13 @@ If you don't have it, please run \`openssl rand -base64 32\` to create one.
} }
let connectionString = serverDBEnv.DATABASE_URL; let connectionString = serverDBEnv.DATABASE_URL;
console.log(connectionString,'999999999999999DATABASE_DRIVER')
if (!connectionString) { if (!connectionString) {
throw new Error(`You are try to use database, but "DATABASE_URL" is not set correctly`); throw new Error(`You are try to use database, but "DATABASE_URL" is not set correctly`);
} }
if (serverDBEnv.DATABASE_DRIVER === 'node') { if (serverDBEnv.DATABASE_DRIVER === 'node') {
console.log(connectionString,'8888888888888888DATABASE_DRIVER')
const client = new NodePool({ connectionString }); const client = new NodePool({ connectionString });
return nodeDrizzle(client, { schema }); return nodeDrizzle(client, { schema });
} }
@ -36,7 +37,7 @@ If you don't have it, please run \`openssl rand -base64 32\` to create one.
// https://github.com/neondatabase/serverless/blob/main/CONFIG.md#websocketconstructor-typeof-websocket--undefined // https://github.com/neondatabase/serverless/blob/main/CONFIG.md#websocketconstructor-typeof-websocket--undefined
neonConfig.webSocketConstructor = ws; neonConfig.webSocketConstructor = ws;
} }
console.log(connectionString,'73366666226666DATABASE_DRIVER')
const client = new NeonPool({ connectionString }); const client = new NeonPool({ connectionString });
return neonDrizzle(client, { schema }); return neonDrizzle(client, { schema });
}; };

@ -12,68 +12,12 @@ type AgentSettingsProps = StoreUpdaterProps;
export const AgentSettings = (props: AgentSettingsProps) => { export const AgentSettings = (props: AgentSettingsProps) => {
return ( return (
<Provider createStore={createStore}> <Provider createStore={createStore}>
{/*<StoreUpdater {...props} />*/} <StoreUpdater {...props} />
{/*<AgentPrompt />*/} <AgentPrompt />
<AgentMeta /> <AgentMeta />
{/*<AgentChat />*/}
{/*<AgentModal />*/}
{/*<AgentTTS />*/}
{/*<AgentPlugin />*/}
</Provider>
);
};
export const AgentSettingChat = (props: AgentSettingsProps) => {
return (
<Provider createStore={createStore}>
{/*<StoreUpdater {...props} />*/}
{/*<AgentPrompt />*/}
{/*<AgentMeta />*/}
<AgentChat /> <AgentChat />
{/*<AgentModal />*/}
{/*<AgentTTS />*/}
{/*<AgentPlugin />*/}
</Provider>
);
};
export const AgentSettingLlm = (props: AgentSettingsProps) => {
return (
<Provider createStore={createStore}>
{/*<StoreUpdater {...props} />*/}
{/*<AgentPrompt />*/}
{/*<AgentMeta />*/}
{/*<AgentChat />*/}
<AgentModal /> <AgentModal />
{/*<AgentTTS />*/}
{/*<AgentPlugin />*/}
</Provider>
);
};
export const AgentSettingTts = (props: AgentSettingsProps) => {
return (
<Provider createStore={createStore}>
{/*<StoreUpdater {...props} />*/}
{/*<AgentPrompt />*/}
{/*<AgentMeta />*/}
{/*<AgentChat />*/}
{/*<AgentModal />*/}
<AgentTTS /> <AgentTTS />
{/*<AgentPlugin />*/}
</Provider>
);
};
export const AgentSettingAbout = (props: AgentSettingsProps) => {
return (
<Provider createStore={createStore}>
{/*<StoreUpdater {...props} />*/}
{/*<AgentPrompt />*/}
{/*<AgentMeta />*/}
{/*<AgentChat />*/}
{/*<AgentModal />*/}
{/*<AgentTTS />*/}
<AgentPlugin /> <AgentPlugin />
</Provider> </Provider>
); );

@ -1,3 +1,3 @@
export { AgentSettings, AgentSettingChat, AgentSettingLlm, AgentSettingTts, AgentSettingAbout } from './AgentSettings'; export { AgentSettings } from './AgentSettings';
export { AgentSettingsStore } from './AgentSettingsStore'; export { AgentSettingsStore } from './AgentSettingsStore';
export type { AgentSettingsInstance } from './hooks/useAgentSettings'; export type { AgentSettingsInstance } from './hooks/useAgentSettings';

@ -46,7 +46,7 @@ const ActionBar = memo<ActionBarProps>(
rightAddons={ rightAddons={
<> <>
{rightAreaStartRender} {rightAreaStartRender}
{/*<RenderActionList dataSource={rightActionList} />*/} <RenderActionList dataSource={rightActionList} />
{rightAreaEndRender} {rightAreaEndRender}
</> </>
} }

@ -30,7 +30,7 @@ const Footer = memo<PropsWithChildren>(() => {
const { hideGitHub } = useServerConfigStore(featureFlagsSelectors); const { hideGitHub } = useServerConfigStore(featureFlagsSelectors);
return true ? null : ( return hideGitHub ? null : (
<> <>
<Flexbox flex={1} justify={'flex-end'}> <Flexbox flex={1} justify={'flex-end'}>
<Center <Center

@ -19,6 +19,7 @@ export const useOpenSettings = (tab: SettingsTabs = SettingsTabs.Common) => {
return () => router.push(urlJoin('/settings', tab)); return () => router.push(urlJoin('/settings', tab));
} else { } else {
// use Intercepting Routes on Desktop // use Intercepting Routes on Desktop
console.log(activeId,tab,'/settings/modal,33333333------')
return () => router.push('/settings/modal', { query: { session: activeId, tab } }); return () => router.push('/settings/modal', { query: { session: activeId, tab } });
} }
}, [mobile, tab, activeId, router]); }, [mobile, tab, activeId, router]);
@ -41,6 +42,7 @@ export const useOpenChatSettings = (tab: ChatSettingsTabs = ChatSettingsTabs.Met
return () => router.push('/chat/settings'); return () => router.push('/chat/settings');
} else { } else {
// use Intercepting Routes on Desktop // use Intercepting Routes on Desktop
console.log(activeId,tab,'/chat/settings/modal,33333333------')
return () => router.push('/chat/settings/modal', { query: { session: activeId, tab } }); return () => router.push('/chat/settings/modal', { query: { session: activeId, tab } });
} }
}, [openSettings, mobile, activeId, router, tab]); }, [openSettings, mobile, activeId, router, tab]);

@ -7,12 +7,14 @@ import { trpc } from '../init';
export const userAuth = trpc.middleware(async (opts) => { export const userAuth = trpc.middleware(async (opts) => {
const { ctx } = opts; const { ctx } = opts;
// `ctx.user` is nullable // `ctx.user` is nullable
console.log(ctx.userId,'1111111111111111userId-------------')
if (!ctx.userId) { if (!ctx.userId) {
if (enableClerk) { if (enableClerk) {
console.log('clerk auth:', ctx.clerkAuth); console.log('clerk auth:', ctx.clerkAuth);
} else { } else {
console.log('next auth:', ctx.nextAuth); console.log('next auth:', ctx.nextAuth);
} }
console.log(ctx.userId,'2222222222222222userId-------------')
throw new TRPCError({ code: 'UNAUTHORIZED' }); throw new TRPCError({ code: 'UNAUTHORIZED' });
} }

@ -39,9 +39,9 @@ export default {
input: { input: {
addAi: '添加一条 AI 消息', addAi: '添加一条 AI 消息',
addUser: '添加一条用户消息', addUser: '添加一条用户消息',
clear: '清空内容',
more: '更多', more: '更多',
send: '发送', send: '发送',
clear: '清空内容',
sendWithCmdEnter: '按 {{meta}} + Enter 键发送', sendWithCmdEnter: '按 {{meta}} + Enter 键发送',
sendWithEnter: '按 Enter 键发送', sendWithEnter: '按 Enter 键发送',
stop: '停止', stop: '停止',

@ -189,9 +189,9 @@ export default {
tab: { tab: {
chat: '会话', chat: '会话',
discover: '发现', discover: '发现',
robot: '数字人',
files: '文件', files: '文件',
me: '我', me: '我',
robot: '数字人',
setting: '设置', setting: '设置',
}, },
telemetry: { telemetry: {

@ -19,20 +19,19 @@ export default {
try: '试一下', try: '试一下',
}, },
back: '返回发现', back: '返回发现',
collectSuccess: '收藏成功',
category: { category: {
assistant: { assistant: {
'academic': "政务",
'all': "全部", 'all': "全部",
'collect': "收藏", 'collect': "收藏",
'academic': "政务", 'design': "设计",
'education': "教育", 'education': "教育",
'entertainment': "娱乐",
'general': "通用",
'life': "生活",
'marketing': "营销", 'marketing': "营销",
'design': "设计",
'office': "办公", 'office': "办公",
'programming': "编程", 'programming': "编程",
'entertainment': "娱乐",
'life': "生活",
'general': "通用"
}, },
plugin: { plugin: {
'all': '全部', 'all': '全部',
@ -48,6 +47,7 @@ export default {
}, },
}, },
cleanFilter: '清除筛选', cleanFilter: '清除筛选',
collectSuccess: '收藏成功',
create: '创作', create: '创作',
createGuide: { createGuide: {
func1: { func1: {

@ -392,15 +392,14 @@ export default {
}, },
}, },
tab: { tab: {
'about': '插件设置', 'about': '关于',
'agent': '助手信息', 'agent': '默认助手',
'common': '角色设定', 'common': '通用设置',
'experiment': '实验', 'experiment': '实验',
'llm': '模型设置', 'llm': '语言模型',
'sync': '云端同步', 'sync': '云端同步',
'system-agent': '聊天偏好', 'system-agent': '系统助手',
'tts': '语音服务', 'tts': '语音服务',
'szr': '数字人'
}, },
tools: { tools: {
builtins: { builtins: {

@ -13,12 +13,12 @@ export class AssistantStore {
getAgentIndexUrl = (lang: Locales = DEFAULT_LANG) => { getAgentIndexUrl = (lang: Locales = DEFAULT_LANG) => {
if (isLocaleNotSupport(lang)) return this.baseUrl; if (isLocaleNotSupport(lang)) return this.baseUrl;
console.log(urlJoin(this.baseUrl, `index.${normalizeLocale(lang)}.json`),928272772727) console.log(urlJoin(this.baseUrl, `index.${normalizeLocale(lang)}.json`),'928272772727')
return urlJoin(this.baseUrl, `index.${normalizeLocale(lang)}.json`); return urlJoin(this.baseUrl, `index.${normalizeLocale(lang)}.json`);
}; };
getAgentUrl = (identifier: string, lang: Locales = DEFAULT_LANG) => { getAgentUrl = (identifier: string, lang: Locales = DEFAULT_LANG) => {
console.log(urlJoin(this.baseUrl, `${identifier}.json`),88888888888888888888) console.log(urlJoin(this.baseUrl, `${identifier}.json`),"88888888888888888888")
if (isLocaleNotSupport(lang)) return urlJoin(this.baseUrl, `${identifier}.json`); if (isLocaleNotSupport(lang)) return urlJoin(this.baseUrl, `${identifier}.json`);
return urlJoin(this.baseUrl, `${identifier}.${normalizeLocale(lang)}.json`); return urlJoin(this.baseUrl, `${identifier}.${normalizeLocale(lang)}.json`);

@ -7,7 +7,7 @@ import { KnowledgeBaseItem } from '@/types/knowledgeBase';
const knowledgeBaseProcedure = authedProcedure.use(async (opts) => { const knowledgeBaseProcedure = authedProcedure.use(async (opts) => {
const { ctx } = opts; const { ctx } = opts;
console.log(ctx.userId,'282727727227knowledgeBaseProcedure-----------')
return opts.next({ return opts.next({
ctx: { ctx: {
knowledgeBaseModel: new KnowledgeBaseModel(ctx.userId), knowledgeBaseModel: new KnowledgeBaseModel(ctx.userId),

@ -53,7 +53,7 @@ export class DiscoverService {
let res = await fetch(this.assistantStore.getAgentIndexUrl(locale), { let res = await fetch(this.assistantStore.getAgentIndexUrl(locale), {
next: { revalidate }, next: { revalidate },
}); });
console.log(res.ok,29298811) console.log(res.ok,"29298811")
if (!res.ok) { if (!res.ok) {
res = await fetch(this.assistantStore.getAgentIndexUrl(DEFAULT_LANG), { res = await fetch(this.assistantStore.getAgentIndexUrl(DEFAULT_LANG), {
next: { revalidate }, next: { revalidate },
@ -63,7 +63,7 @@ export class DiscoverService {
if (!res.ok) return []; if (!res.ok) return [];
const json = await res.json(); const json = await res.json();
console.log(json,1919191919) console.log(json,"1919191919")
return json.agents; return json.agents;
}; };
@ -84,7 +84,7 @@ export class DiscoverService {
if (!res.ok) return; if (!res.ok) return;
let assistant = await res.json(); let assistant = await res.json();
console.log(assistant,6868686866868) console.log(assistant,"6868686866868")
if (!assistant) return; if (!assistant) return;
assistant = merge(cloneDeep(DEFAULT_DISCOVER_ASSISTANT_ITEM), assistant); assistant = merge(cloneDeep(DEFAULT_DISCOVER_ASSISTANT_ITEM), assistant);

@ -20,7 +20,7 @@ export class ClientService implements IUserService {
const user = await UserModel.getUser(); const user = await UserModel.getUser();
const messageCount = await MessageModel.count(); const messageCount = await MessageModel.count();
const sessionCount = await SessionModel.count(); const sessionCount = await SessionModel.count();
console.log(user,2827272727) console.log(user,"2827272727")
localStorage.setItem('userId',user.uuid) localStorage.setItem('userId',user.uuid)
return { return {
avatar: user.avatar, avatar: user.avatar,

@ -8,11 +8,11 @@ export enum SidebarTabKey {
Discover = 'discover', Discover = 'discover',
Files = 'files', Files = 'files',
Me = 'me', Me = 'me',
Setting = 'settings',
Robot = 'robot',
Model = 'model', Model = 'model',
Plugins = 'plugins', Plugins = 'plugins',
Power = 'power' Power = 'power',
Robot = 'robot',
Setting = 'settings',
} }
export enum ChatSettingsTabs { export enum ChatSettingsTabs {
@ -31,8 +31,8 @@ export enum SettingsTabs {
LLM = 'llm', LLM = 'llm',
Sync = 'sync', Sync = 'sync',
SystemAgent = 'system-agent', SystemAgent = 'system-agent',
TTS = 'tts',
Szr = 'szr', Szr = 'szr',
TTS = 'tts',
} }
export interface SystemStatus { export interface SystemStatus {

@ -6,13 +6,13 @@ import { MetaData } from '@/types/meta';
import { LobeAgentSettings } from '@/types/session'; import { LobeAgentSettings } from '@/types/session';
export enum AssistantCategory { export enum AssistantCategory {
All = 'all',
Collect = 'collect',
Academic = 'academic', Academic = 'academic',
All = 'all',
Career = 'governmentaffairs', Career = 'governmentaffairs',
Education = 'education', Collect = 'collect',
CopyWriting = 'copywriting', CopyWriting = 'copywriting',
Design = 'design', Design = 'design',
Education = 'education',
Emotions = 'emotions', Emotions = 'emotions',
Entertainment = 'entertainment', Entertainment = 'entertainment',
Games = 'games', Games = 'games',

File diff suppressed because it is too large Load Diff

@ -0,0 +1,64 @@
[2025-02-12 11:45:49.403] [INFO ] [kground-preinit] [ org.hibernate.validator.internal.util.Version:21] : HV000001: Hibernate Validator 6.2.5.Final
[2025-02-12 11:45:49.424] [INFO ] [ main] [ com.pjilisense.flxai.FlxAiApplication:55] : Starting FlxAiApplication using Java 17.0.12 on DESKTOP-O4CA5AM with PID 20716 (D:\AInew\JZ_QGNB\flx-ai\target\classes started by sunboy in D:\AInew\JZ_QGNB\flx-ai)
[2025-02-12 11:45:49.426] [INFO ] [ main] [ com.pjilisense.flxai.FlxAiApplication:637] : The following 1 profile is active: "dev"
[2025-02-12 11:45:52.746] [INFO ] [ main] [ o.s.d.r.config.RepositoryConfigurationDelegate:262] : Multiple Spring Data modules found, entering strict repository configuration mode
[2025-02-12 11:45:52.756] [INFO ] [ main] [ o.s.d.r.config.RepositoryConfigurationDelegate:132] : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
[2025-02-12 11:45:52.815] [INFO ] [ main] [ o.s.d.r.config.RepositoryConfigurationDelegate:201] : Finished Spring Data repository scanning in 24 ms. Found 0 Redis repository interfaces.
[2025-02-12 11:45:54.602] [INFO ] [ main] [ o.s.boot.web.embedded.tomcat.TomcatWebServer:108] : Tomcat initialized with port(s): 18080 (http)
[2025-02-12 11:45:54.629] [INFO ] [ main] [ org.apache.coyote.http11.Http11NioProtocol:173] : Initializing ProtocolHandler ["http-nio-18080"]
[2025-02-12 11:45:54.633] [INFO ] [ main] [ org.apache.catalina.core.StandardService:173] : Starting service [Tomcat]
[2025-02-12 11:45:54.633] [INFO ] [ main] [ org.apache.catalina.core.StandardEngine:173] : Starting Servlet engine: [Apache Tomcat/9.0.79]
[2025-02-12 11:45:54.915] [INFO ] [ main] [ o.a.c.c.C.[Tomcat].[localhost].[/flxai]:173] : Initializing Spring embedded WebApplicationContext
[2025-02-12 11:45:54.920] [INFO ] [ main] [ o.s.b.w.s.c.ServletWebServerApplicationContext:292] : Root WebApplicationContext: initialization completed in 5350 ms
[2025-02-12 11:45:55.134] [INFO ] [ main] [ c.a.d.s.b.a.DruidDataSourceAutoConfigure:55] : Init DruidDataSource
[2025-02-12 11:45:56.557] [INFO ] [ main] [ com.alibaba.druid.pool.DruidDataSource:975] : {dataSource-1} inited
[2025-02-12 11:45:59.480] [INFO ] [ main] [ o.s.b.actuate.endpoint.web.EndpointLinksResolver:58] : Exposing 14 endpoint(s) beneath base path '/actuator'
[2025-02-12 11:46:01.227] [INFO ] [ main] [ org.apache.coyote.http11.Http11NioProtocol:173] : Starting ProtocolHandler ["http-nio-18080"]
[2025-02-12 11:46:01.311] [INFO ] [ main] [ o.s.boot.web.embedded.tomcat.TomcatWebServer:220] : Tomcat started on port(s): 18080 (http) with context path '/flxai'
[2025-02-12 11:46:03.003] [INFO ] [ main] [ com.pjilisense.flxai.FlxAiApplication:61] : Started FlxAiApplication in 15.061 seconds (JVM running for 17.224)
[2025-02-12 11:46:06.247] [INFO ] [4)-192.168.56.1] [ o.a.c.c.C.[Tomcat].[localhost].[/flxai]:173] : Initializing Spring DispatcherServlet 'dispatcherServlet'
[2025-02-12 11:46:06.252] [INFO ] [4)-192.168.56.1] [ org.springframework.web.servlet.DispatcherServlet:525] : Initializing Servlet 'dispatcherServlet'
[2025-02-12 11:46:06.259] [INFO ] [4)-192.168.56.1] [ org.springframework.web.servlet.DispatcherServlet:547] : Completed initialization in 7 ms
[2025-02-12 11:46:08.498] [WARN ] [oundedElastic-1] [ o.s.b.actuate.redis.RedisReactiveHealthIndicator:92] : Redis health check failed
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/<unresolved>:6379
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1383)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1366)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedReactiveConnection(LettuceConnectionFactory.java:1117)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getReactiveConnection(LettuceConnectionFactory.java:509)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getReactiveConnection(LettuceConnectionFactory.java:103)
at reactor.core.publisher.MonoSupplier.call(MonoSupplier.java:86)
at reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:227)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/<unresolved>:6379
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:330)
at io.lettuce.core.RedisClient.connect(RedisClient.java:216)
at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:115)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:115)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1595)
... 14 common frames omitted
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: getsockopt: /127.0.0.1:6379
Caused by: java.net.ConnectException: Connection refused: getsockopt
at java.base/sun.nio.ch.Net.pollConnect(Native Method)
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)
at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:337)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:776)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:840)
Loading…
Cancel
Save