Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions himarket-web/himarket-frontend/src/components/ProductHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useImperativeHandle, forwardRef } from "react";
import { Typography, Button, Modal, Select, message, Popconfirm, Input, Pagination, Spin } from "antd";
import { ApiOutlined, CheckCircleFilled, ClockCircleFilled, ExclamationCircleFilled, PlusOutlined, RobotOutlined, BulbOutlined } from "@ant-design/icons";
import { useParams } from "react-router-dom";
Expand All @@ -10,6 +10,10 @@ import APIs, { getProductSubscriptionStatus, type ISubscription } from "../lib/a
const { Title, Paragraph } = Typography;
const { Search } = Input;

export interface ProductHeaderHandle {
showManageModal: () => void;
}

interface ProductHeaderProps {
name: string;
description: string;
Expand All @@ -19,6 +23,7 @@ interface ProductHeaderProps {
agentConfig?: IAgentConfig;
updatedAt?: string;
productType?: 'REST_API' | 'MCP_SERVER' | 'AGENT_API' | 'MODEL_API' | 'AGENT_SKILL';
onSubscriptionStatusChange?: (hasSubscription: boolean) => void;
}

type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
Expand All @@ -42,7 +47,7 @@ const getIconUrl = (icon?: IProductIcon, defaultIcon?: string): string => {
}
};

export const ProductHeader: React.FC<ProductHeaderProps> = ({
export const ProductHeader = forwardRef<ProductHeaderHandle, ProductHeaderProps>(({
name,
description,
icon,
Expand All @@ -51,7 +56,8 @@ export const ProductHeader: React.FC<ProductHeaderProps> = ({
agentConfig,
updatedAt,
productType,
}) => {
onSubscriptionStatusChange,
}, ref) => {
const {
apiProductId,
mcpProductId,
Expand Down Expand Up @@ -122,6 +128,18 @@ export const ProductHeader: React.FC<ProductHeaderProps> = ({
}
}, [productId, shouldShowSubscribeButton]);

// 暴露给父组件的方法
useImperativeHandle(ref, () => ({
showManageModal,
}));

// 订阅状态变化时通知父组件
useEffect(() => {
if (subscriptionStatus !== undefined && onSubscriptionStatusChange) {
onSubscriptionStatusChange(subscriptionStatus.hasSubscription);
}
}, [subscriptionStatus, onSubscriptionStatusChange]);

// 获取订阅详情(用于管理弹窗)
const fetchSubscriptionDetails = async (page: number = 1, search: string = ''): Promise<void> => {
if (!productId) return Promise.resolve();
Expand Down Expand Up @@ -589,4 +607,4 @@ export const ProductHeader: React.FC<ProductHeaderProps> = ({
</Modal>
</>
);
};
});
20 changes: 17 additions & 3 deletions himarket-web/himarket-frontend/src/pages/ModelDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useEffect, useState } from "react";
import { useEffect, useRef, useState, useCallback } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { Layout } from "../components/Layout";
import { ProductHeader } from "../components/ProductHeader";
import type { ProductHeaderHandle } from "../components/ProductHeader";
import {
Alert,
Button,
Expand Down Expand Up @@ -29,6 +30,12 @@ function ModelDetail() {
const [data, setData] = useState<IProductDetail>();
const [modelConfig, setModelConfig] = useState<IModelConfig>();
const [selectedModelDomainIndex, setSelectedModelDomainIndex] = useState<number>(0);
const [hasSubscription, setHasSubscription] = useState(false);
const headerRef = useRef<ProductHeaderHandle>(null);

const handleSubscriptionStatusChange = useCallback((subscribed: boolean) => {
setHasSubscription(subscribed);
}, []);


useEffect(() => {
Expand Down Expand Up @@ -260,11 +267,13 @@ function ModelDetail() {
</button>

<ProductHeader
ref={headerRef}
name={data.name}
description={data.description}
icon={data.icon}
updatedAt={data.updatedAt}
productType="MODEL_API"
onSubscriptionStatusChange={handleSubscriptionStatusChange}
/>
</div>

Expand Down Expand Up @@ -510,10 +519,15 @@ function ModelDetail() {
icon={<MessageOutlined />}
className="rounded-lg mt-4"
onClick={() => {
navigate("/chat", { state: { selectedProduct: data } });
if (hasSubscription) {
navigate("/chat", { state: { selectedProduct: data } });
} else {
message.warning('请先订阅该产品后再进行对话测试');
headerRef.current?.showManageModal();
}
}}
>
开始对话测试
{hasSubscription ? '开始对话测试' : '订阅并开始对话'}
</Button>
</div>
),
Expand Down
Loading