diff --git a/frontend/packages/common/src/components/aoplatform/UnUsedWordForTranslate.tsx b/frontend/packages/common/src/components/aoplatform/UnUsedWordForTranslate.tsx
index 939fe6d9..7298d6cb 100644
--- a/frontend/packages/common/src/components/aoplatform/UnUsedWordForTranslate.tsx
+++ b/frontend/packages/common/src/components/aoplatform/UnUsedWordForTranslate.tsx
@@ -56,6 +56,7 @@ export const TranslateWord = () => {
{$t('无需审核:允许任何消费者调用该服务')}
{$t('人工审核:仅允许通过人工审核的消费者调用该服务')}
{$t('开启:AI Agent 等产品能够通过 MCP 方式调用服务')}
+ {$t('总览')}
{$t('永久')}
{$t('否')}
{$t('是')}
diff --git a/frontend/packages/common/src/components/postcat/ApiEdit.tsx b/frontend/packages/common/src/components/postcat/ApiEdit.tsx
index 9fb41e90..9bb654a7 100644
--- a/frontend/packages/common/src/components/postcat/ApiEdit.tsx
+++ b/frontend/packages/common/src/components/postcat/ApiEdit.tsx
@@ -234,12 +234,16 @@ export default function ApiEdit({
<>
-
- {type === 'service' && service?.basic.enableMcp && (
-
-
setActiveTab('openApi')}
- >
- Open API
+ {type === 'service' && service?.basic.enableMcp && (
+
+
setActiveTab('openApi')}
+ >
+ Open API
+
+
setActiveTab('mcp')}
+ >
+ MCP
+
+
+ )}
+ {type === 'service' && !apiKeyList.length ? (
+ <>
+
+
+ {$t('请先订阅该服务')}
+
- setActiveTab('mcp')}
- >
- MCP
+
+ >
+ ) : (
+ <>
+
+
+ {activeTab === 'openApi' ? tabContent.openApi?.title : tabContent.mcp.title}
+
+ {/* 标签页内容区域 */}
+
+ {activeTab === 'mcp' ? (
+
{
+ try {
+ return JSON.parse(configContent)
+ } catch (e) {
+ return {}
+ }
+ })()
+ : configContent
+ : {}
+ }
+ theme="monokai"
+ indentWidth={2}
+ displayDataTypes={false}
+ displayObjectSize={false}
+ name={false}
+ collapsed={false}
+ enableClipboard={false}
+ style={{
+ backgroundColor: 'transparent',
+ wordBreak: 'break-word',
+ whiteSpace: 'normal'
+ }}
+ />
+ ) : (
+ <>
+ {configContent || ''}
+ >
+ )}
+ handleCopy(configContent)}
+ sx={{
+ position: 'absolute',
+ top: '5px',
+ right: '5px',
+ color: '#999',
+ transition: 'none',
+ '&.MuiButtonBase-root:hover': {
+ background: 'transparent',
+ color: '#3D46F2',
+ transition: 'none'
+ }
+ }}
+ >
- )}
-
- {activeTab === 'openApi' ? tabContent.openApi?.title : tabContent.mcp.title}
-
- {/* 标签页内容区域 */}
-
- {activeTab === 'mcp' ? (
-
{
- try {
- return JSON.parse(configContent);
- } catch (e) {
- return {};
- }
- })()
- : configContent
- : {}
- }
- theme="monokai"
- indentWidth={2}
- displayDataTypes={false}
- displayObjectSize={false}
- name={false}
- collapsed={false}
- enableClipboard={false}
- style={{
- backgroundColor: 'transparent',
- wordBreak: 'break-word',
- whiteSpace: 'normal'
- }}
- />
- ) : (
+ {activeTab === 'mcp' && (
<>
- {configContent || ''}
+ API Key
+ {apiKeyList.length ? (
+ <>
+ {type === 'global' ? (
+ <>
+
+
+
+ {apiKey}
+ handleCopy(apiKey)}
+ sx={{
+ position: 'absolute',
+ top: '0px',
+ right: '5px',
+ color: '#999',
+ transition: 'none',
+ '&.MuiButtonBase-root:hover': {
+ background: 'transparent',
+ color: '#3D46F2',
+ transition: 'none'
+ }
+ }}
+ >
+
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+ >
+ ) : (
+
+
+
+ )}
>
)}
- handleCopy(configContent)}
- sx={{
- position: 'absolute',
- top: '5px',
- right: '5px',
- color: '#999',
- transition: 'none',
- '&.MuiButtonBase-root:hover': {
- background: 'transparent',
- color: '#3D46F2',
- transition: 'none'
- }
- }}
- >
-
-
- {activeTab === 'mcp' && (
- <>
- API Key
- {apiKeyList.length ? (
- <>
-
-
-
- {apiKey}
- handleCopy(apiKey)}
- sx={{
- position: 'absolute',
- top: '0px',
- right: '5px',
- color: '#999',
- transition: 'none',
- '&.MuiButtonBase-root:hover': {
- background: 'transparent',
- color: '#3D46F2',
- transition: 'none'
- }
- }}
- >
-
-
- >
- ) : (
-
-
-
- )}
>
)}
>
)
-}
-
-export default IntegrationAIContainer
+})
\ No newline at end of file
diff --git a/frontend/packages/core/src/pages/mcpService/McpServiceContainer.tsx b/frontend/packages/core/src/pages/mcpService/McpServiceContainer.tsx
index 6f52db14..7a71d706 100644
--- a/frontend/packages/core/src/pages/mcpService/McpServiceContainer.tsx
+++ b/frontend/packages/core/src/pages/mcpService/McpServiceContainer.tsx
@@ -1,6 +1,6 @@
import InsidePage from "@common/components/aoplatform/InsidePage"
import { $t } from '@common/locales/index.ts'
-import IntegrationAIContainer from "./IntegrationAIContainer"
+import { IntegrationAIContainer } from "./IntegrationAIContainer"
import { Tool } from "@modelcontextprotocol/sdk/types.js"
import { useEffect, useState } from "react"
import McpToolsContainer from "./McpToolsContainer"
diff --git a/frontend/packages/core/src/pages/member/MemberList.tsx b/frontend/packages/core/src/pages/member/MemberList.tsx
index f8c473d7..864814de 100644
--- a/frontend/packages/core/src/pages/member/MemberList.tsx
+++ b/frontend/packages/core/src/pages/member/MemberList.tsx
@@ -480,6 +480,8 @@ const MemberList = () => {
render: (_, entity) => (
x.id)}
diff --git a/frontend/packages/core/src/pages/partitions/DashboardSettingEdit.tsx b/frontend/packages/core/src/pages/partitions/DashboardSettingEdit.tsx
index d133e6ea..1d4897b7 100644
--- a/frontend/packages/core/src/pages/partitions/DashboardSettingEdit.tsx
+++ b/frontend/packages/core/src/pages/partitions/DashboardSettingEdit.tsx
@@ -60,7 +60,13 @@ export type DashboardSettingEditProps = {
name="driver"
rules={[{ required: true }]}
>
-
+
diff --git a/frontend/packages/core/src/pages/policy/FilterForm.tsx b/frontend/packages/core/src/pages/policy/FilterForm.tsx
index 1c3a1bb8..361d1c6f 100644
--- a/frontend/packages/core/src/pages/policy/FilterForm.tsx
+++ b/frontend/packages/core/src/pages/policy/FilterForm.tsx
@@ -301,7 +301,13 @@ const FilterForm = forwardRef(
return (
-
+
((_,ref) => {
name="type"
rules={[{ required: true }]}
>
-
-
+
diff --git a/frontend/packages/core/src/pages/policy/dataMasking/DataMaskingRuleForm.tsx b/frontend/packages/core/src/pages/policy/dataMasking/DataMaskingRuleForm.tsx
index 6393481d..705db146 100644
--- a/frontend/packages/core/src/pages/policy/dataMasking/DataMaskingRuleForm.tsx
+++ b/frontend/packages/core/src/pages/policy/dataMasking/DataMaskingRuleForm.tsx
@@ -146,6 +146,8 @@ const DataMaskRuleForm: React.FC = ({
= ({
{matchType === 'inner' ? (
= ({
= ({
rules={[{ required: true }]}
>
((_, ref) => {
{!onEdit && (
label={$t('所属团队')} name="team" rules={[{ required: true }]}>
((_, ref) => {
label={$t('标签')} name="tags">
{
diff --git a/frontend/packages/core/src/pages/system/SystemList.tsx b/frontend/packages/core/src/pages/system/SystemList.tsx
index 06b53ab5..321976ed 100644
--- a/frontend/packages/core/src/pages/system/SystemList.tsx
+++ b/frontend/packages/core/src/pages/system/SystemList.tsx
@@ -180,10 +180,24 @@ const SystemList: FC = () => {
- {$t(SERVICE_KIND_OPTIONS.find((x) => x.value === record.service_kind)?.label || '-')}
- {record.enable_mcp && (
- MCP
- )}
+
+ {SERVICE_KIND_OPTIONS.find((x) => x.value === record.service_kind)?.label || '-'}
+
+ {record?.enable_mcp && (
+
+ MCP
+
+ )}
)
}
diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx
index c47b2b1e..adc87901 100644
--- a/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx
+++ b/frontend/packages/core/src/pages/system/api/SystemInsideApiProxy.tsx
@@ -30,7 +30,10 @@ const SystemInsideApiProxy = forwardRefPROXY_HEADER_CONFIG.map((x)=>({
...x,
...(x.key === 'optType' ? {
- component: ({...x, label:$t(x.label)}))}/>
+ component: ({...x, label:$t(x.label)}))}/>
} : {})
}))
,[state.language])
diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideRouterCreate.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideRouterCreate.tsx
index 3b3e9cc4..5ce1ecb4 100644
--- a/frontend/packages/core/src/pages/system/api/SystemInsideRouterCreate.tsx
+++ b/frontend/packages/core/src/pages/system/api/SystemInsideRouterCreate.tsx
@@ -179,6 +179,8 @@ const SystemInsideRouterCreate = forwardRef {
return { label: $t(value), value: key }
@@ -192,6 +194,8 @@ const SystemInsideRouterCreate = forwardRef {
return { label: $t(value), value: key }
@@ -252,6 +256,8 @@ const SystemInsideRouterCreate = forwardRef label={$t('请求协议')} name="protocols" rules={[{ required: true }]}>
label={$t('请求方式')} name="methods" rules={[{ required: true }]}>
PROXY_HEADER_CONFIG.map((x)=>({
...x,
...(x.key === 'optType' ? {
- component: ({...x, label:$t(x.label)}))}/>
+ component: ({...x, label:$t(x.label)}))}/>
} : {})
}))
,[state.language])
@@ -175,7 +175,7 @@ const globalConfigNodesRule: FormItemProps['rules'] = [
name="scheme"
rules={[{ required: true }]}
>
-
+
@@ -192,7 +192,7 @@ const globalConfigNodesRule: FormItemProps['rules'] = [
name="passHost"
rules={[{ required: true }]}
>
- setFormShowHost(val === 'rewrite')}>
+ setFormShowHost(val === 'rewrite')}>
diff --git a/frontend/packages/core/src/pages/team/TeamConfig.tsx b/frontend/packages/core/src/pages/team/TeamConfig.tsx
index 7be89f56..b8ab0c42 100644
--- a/frontend/packages/core/src/pages/team/TeamConfig.tsx
+++ b/frontend/packages/core/src/pages/team/TeamConfig.tsx
@@ -205,6 +205,8 @@ const TeamConfig = forwardRef((props, ref) =>
rules={[{ required: true }]}
>
{
render: (_, entity) => (
()
- const [activeKey, setActiveKey] = useState('total')
const navigateTo = useNavigate()
useEffect(() => {
- setActiveKey(dashboardType || 'total')
+ const activeKey = dashboardType || 'total'
+ navigateTo(`/analytics/${activeKey === 'total' ? activeKey : `${activeKey}/list`}`)
}, [dashboardType])
- const monitorTabItems: TabsProps['items'] = [
- {
- label: $t('监控总览'),
- key: 'total',
- children:
- },
- {
- label: $t('服务被调用统计'),
- key: 'subscriber',
- children:
- },
- {
- label: $t('消费者调用统计'),
- key: 'provider',
- children:
- },
- {
- label: $t('API 调用统计'),
- key: 'api',
- children:
- }
- ]
-
return (
<>
- {
- setActiveKey(val)
- navigateTo(`/analytics/${val === 'total' ? val : `${val}/list`}`)
- }}
- items={monitorTabItems}
- className="h-full overflow-hidden mt-[6px] [&>.ant-tabs-content-holder]:overflow-auto [&>.ant-tabs-content-holder]:pr-PAGE_INSIDE_X [&>.ant-tabs-content-holder>.ant-tabs-content]:h-full [&>.ant-tabs-content-holder>.ant-tabs-content>.ant-tabs-tabpane]:h-full"
- size="small"
- tabBarStyle={{ paddingLeft: '10px', marginTop: '0px', marginBottom: '0px' }}
- />
+
>
)
}
diff --git a/frontend/packages/market/src/index.css b/frontend/packages/market/src/index.css
index 69e22726..e5752ce5 100644
--- a/frontend/packages/market/src/index.css
+++ b/frontend/packages/market/src/index.css
@@ -1053,6 +1053,11 @@ p{
.ant-table-wrapper .ant-table{
scrollbar-color: none !important;
}
+.ant-select .ant-select-clear {
+ height:16px !important;
+ width: 16px !important;
+ top: 45%;
+}
.eo_page_drag .ant-table-body{
overflow-y: auto !important;
diff --git a/frontend/packages/market/src/pages/serviceHub/ApplyServiceModal.tsx b/frontend/packages/market/src/pages/serviceHub/ApplyServiceModal.tsx
index 382392dc..4ca9647a 100644
--- a/frontend/packages/market/src/pages/serviceHub/ApplyServiceModal.tsx
+++ b/frontend/packages/market/src/pages/serviceHub/ApplyServiceModal.tsx
@@ -2,7 +2,7 @@ import WithPermission from '@common/components/aoplatform/WithPermission'
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const'
import { useFetch } from '@common/hooks/http'
import { $t } from '@common/locales'
-import { App, Col, Form, Input, Row, Select } from 'antd'
+import { App, Col, Form, Input, Row, Select, Tooltip } from 'antd'
import { forwardRef, useEffect, useImperativeHandle } from 'react'
import { ApplyServiceHandle, ApplyServiceProps } from '../../const/serviceHub/type'
@@ -70,11 +70,23 @@ export const ApplyServiceModal = forwardRef
x.value !== entity.id)}
+ optionRender={(option) => {
+ if (option.data.disabled) {
+ return (
+
+ {option.data.label}
+
+ )
+ }
+ return {option.data.label}
+ }}
/>
{entity.approvalType === 'manual' && (
diff --git a/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx b/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx
index d82587ad..82e41dd5 100644
--- a/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx
+++ b/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx
@@ -15,7 +15,7 @@ import { ApplyServiceHandle, ServiceBasicInfoType, ServiceDetailType } from '../
import { ApplyServiceModal } from './ApplyServiceModal.tsx'
import ServiceHubApiDocument from './ServiceHubApiDocument.tsx'
import { SERVICE_KIND_OPTIONS } from '@core/const/system/const.tsx'
-import IntegrationAIContainer from '@core/pages/mcpService/IntegrationAIContainer.tsx'
+import { IntegrationAIContainer, IntegrationAIContainerRef } from '@core/pages/mcpService/IntegrationAIContainer.tsx'
import { Tool } from '@modelcontextprotocol/sdk/types.js'
import McpToolsContainer from '@core/pages/mcpService/McpToolsContainer.tsx'
import { useGlobalContext } from '@common/contexts/GlobalStateContext.tsx'
@@ -48,6 +48,7 @@ const ServiceHubDetail = () => {
const [tabItem, setTabItem] = useState([])
const [currentTab, setCurrentTab] = useState('')
const { state } = useGlobalContext()
+ const integrationAIContainerRef = useRef(null)
const navigate = useNavigate()
const modifyApiDoc = (apiDoc: string, apiPrefix: string) => {
@@ -191,7 +192,7 @@ servers:
content: serviceBasicInfo?.catalogue?.name || '-'
},
{
- color: '#fbe5e5',
+ color: `#${serviceBasicInfo?.serviceKind === 'ai' ? 'EADEFF' : 'DEFFE7'}`,
textColor: 'text-[#000]',
title: serviceBasicInfo?.serviceKind || '-',
content: SERVICE_KIND_OPTIONS.find((x) => x.value === serviceBasicInfo?.serviceKind)?.label || '-'
@@ -201,7 +202,7 @@ servers:
// 如果启用了MCP,添加MCP标签
if (serviceBasicInfo?.enableMcp) {
tags.push({
- color: '#ffc107',
+ color: '#FFF0C1',
textColor: 'text-[#000]',
title: 'MCP',
content: 'MCP'
@@ -234,16 +235,28 @@ servers:
const getMySelectList = () => {
setMySystemOptionList([])
- fetchData>('apps/can_subscribe', { method: 'GET' }).then((response) => {
+ fetchData>('apps/can_subscribe', {
+ method: 'GET',
+ eoParams: { service: serviceId },
+ eoTransformKeys: ['is_subscribed']
+ }).then((response) => {
const { code, data, msg } = response
if (code === STATUS_CODE.SUCCESS) {
setMySystemOptionList(
- data.app?.map((x: EntityItem) => {
- return {
- label: x.name,
- value: x.id
- }
- })
+ data.app
+ ?.sort((a: EntityItem, b: EntityItem) => {
+ // 已订阅的排在后面
+ if (a.isSubscribed && !b.isSubscribed) return 1
+ if (!a.isSubscribed && b.isSubscribed) return -1
+ return 0
+ })
+ .map((x: EntityItem) => {
+ return {
+ label: x.name,
+ value: x.id,
+ disabled: x.isSubscribed // 已订阅的设为禁用
+ }
+ })
)
} else {
message.error(msg || $t(RESPONSE_TIPS.error))
@@ -263,7 +276,10 @@ servers:
),
onOk: () => {
return applyRef.current?.apply().then((res) => {
- // if(res === true) setApplied(true)
+ if (res === true) {
+ integrationAIContainerRef.current?.getServiceKeysList()
+ getMySelectList()
+ }
})
},
okText: $t('确认'),
@@ -490,11 +506,13 @@ servers:
items={tabItem}
/>
diff --git a/frontend/packages/market/src/pages/serviceHub/ServiceHubGroup.tsx b/frontend/packages/market/src/pages/serviceHub/ServiceHubGroup.tsx
index ad228af3..fa67e9ec 100644
--- a/frontend/packages/market/src/pages/serviceHub/ServiceHubGroup.tsx
+++ b/frontend/packages/market/src/pages/serviceHub/ServiceHubGroup.tsx
@@ -119,7 +119,7 @@ export const ServiceHubGroup = ({ children, filterOption, dispatch }: ServiceHub
return (
-
+
{
}
+ indicator={
+
+ }
spinning={filterOption.listLoading}
>
{filterOption.showServicesList && filterOption.showServicesList.length > 0 ? (
@@ -189,7 +195,12 @@ const ServiceHubList: FC = () => {
}}
/>
) : (
-
+ <>
+ {!filterOption.listLoading &&
+ (!filterOption.showServicesList || filterOption.showServicesList.length === 0) && (
+
+ )}
+ >
)}
@@ -225,7 +236,7 @@ const CardTitle = (service: ServiceHubTableListItem) => {
{
{service.catalogue?.name || '-'}
@@ -242,7 +253,7 @@ const CardTitle = (service: ServiceHubTableListItem) => {
{service?.enableMcp && (
label={$t('鉴权类型')} name="driver" rules={[{ required: true }]}>
{
@@ -205,6 +211,8 @@ export const ManagementAuthorityConfig = forwardRef label={$t('校验字段')} name={['config', 'claimsToVerify']}>
label={$t('所属团队')} name="team" rules={[{ required: true }]}>