diff --git a/react-ui/src/assets/img/comfirm-icon.png b/react-ui/src/assets/img/comfirm-icon.png new file mode 100644 index 00000000..b0eebfe8 Binary files /dev/null and b/react-ui/src/assets/img/comfirm-icon.png differ diff --git a/react-ui/src/components/KFConfirmModal/index.less b/react-ui/src/components/KFConfirmModal/index.less new file mode 100644 index 00000000..5c82b5ec --- /dev/null +++ b/react-ui/src/components/KFConfirmModal/index.less @@ -0,0 +1,7 @@ +.kf-confirm-modal { + &__content { + width: 100%; + font-size: 18px; + text-align: center; + } +} diff --git a/react-ui/src/components/KFConfirmModal/index.tsx b/react-ui/src/components/KFConfirmModal/index.tsx new file mode 100644 index 00000000..d494ad2a --- /dev/null +++ b/react-ui/src/components/KFConfirmModal/index.tsx @@ -0,0 +1,37 @@ +/* + * @Author: 赵伟 + * @Date: 2024-10-10 10:54:25 + * @Description: 自定义 Confirm Modal + */ + +import classNames from 'classnames'; +import KFModal, { KFModalProps } from '../KFModal'; +import './index.less'; + +export interface KFConfirmModalProps extends KFModalProps { + content: string; +} +function KFConfirmModal({ + title, + image, + className = '', + centered, + maskClosable, + content, + ...rest +}: KFConfirmModalProps) { + return ( + +
{content}
+
+ ); +} + +export default KFConfirmModal; diff --git a/react-ui/src/enums/index.ts b/react-ui/src/enums/index.ts index 4b3ded7b..e489515c 100644 --- a/react-ui/src/enums/index.ts +++ b/react-ui/src/enums/index.ts @@ -80,7 +80,7 @@ export enum ServiceType { export const serviceTypeOptions = [ { label: '视频', value: ServiceType.Video }, - { label: '图像', value: ServiceType.Image }, + { label: '图片', value: ServiceType.Image }, { label: '音频', value: ServiceType.Audio }, { label: '文本', value: ServiceType.Text }, ]; diff --git a/react-ui/src/pages/ModelDeployment/CreateService/index.tsx b/react-ui/src/pages/ModelDeployment/CreateService/index.tsx index a827828f..62e26412 100644 --- a/react-ui/src/pages/ModelDeployment/CreateService/index.tsx +++ b/react-ui/src/pages/ModelDeployment/CreateService/index.tsx @@ -18,7 +18,7 @@ import { useNavigate } from '@umijs/max'; import { App, Button, Col, Form, Input, Row, Select } from 'antd'; import { pick } from 'lodash'; import { useEffect, useState } from 'react'; -import { ServiceData, ServiceOperationType } from '../types'; +import { ServiceData, ServiceOperationType, createServiceVersionMessage } from '../types'; import styles from './index.less'; // 表单数据 @@ -59,9 +59,12 @@ function CreateService() { ...formData, }; const [res] = await to(request(params)); - if (res) { + if (res && res.data) { message.success('操作成功'); navigate(-1); + setTimeout(() => { + window.postMessage({ type: createServiceVersionMessage, payload: res.data.id }); + }, 500); } }; diff --git a/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx b/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx index 39013390..92ea62bd 100644 --- a/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx +++ b/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx @@ -31,7 +31,12 @@ import { useNavigate, useParams } from '@umijs/max'; import { App, Button, Col, Flex, Form, Input, Row, Select } from 'antd'; import { omit, pick } from 'lodash'; import { useEffect, useState } from 'react'; -import { ServiceData, ServiceOperationType, ServiceVersionData } from '../types'; +import { + CreateServiceVersionFrom, + ServiceData, + ServiceOperationType, + ServiceVersionData, +} from '../types'; import styles from './index.less'; // 表单数据 @@ -53,6 +58,7 @@ function CreateServiceVersion() { const [form] = Form.useForm(); const [resourceStandardList, filterResourceStandard] = useComputingResource(); const [operationType, setOperationType] = useState(ServiceOperationType.Create); + const [lastPage, setLastPage] = useState(CreateServiceVersionFrom.ServiceInfo); const { message } = App.useApp(); const [serviceInfo, setServiceInfo] = useState(undefined); const [versionInfo, setVersionInfo] = useState(undefined); @@ -60,10 +66,15 @@ function CreateServiceVersion() { const id = params.id; useEffect(() => { - const res: (ServiceVersionData & { operationType: ServiceOperationType }) | undefined = - getSessionStorageItem(serviceVersionInfoKey, true); + const res: + | (ServiceVersionData & { + operationType: ServiceOperationType; + lastPage: CreateServiceVersionFrom; + }) + | undefined = getSessionStorageItem(serviceVersionInfoKey, true); if (res) { setOperationType(res.operationType); + setLastPage(res.lastPage); setVersionInfo(res); let model, codeConfig, envVariables; if (res.model && typeof res.model === 'object') { @@ -156,7 +167,11 @@ function CreateServiceVersion() { const [res] = await to(request(params)); if (res) { message.success('操作成功'); - navigate(-1); + if (lastPage === CreateServiceVersionFrom.ServiceInfo) { + navigate(-1); + } else { + navigate(`/modelDeployment/serviceInfo/${serviceInfo?.id}`, { replace: true }); + } } }; @@ -401,7 +416,8 @@ function CreateServiceVersion() { }, { pattern: /^\/[a-zA-Z0-9._/-]+$/, - message: '请输入正确的挂载绝对路径', + message: + '请输入正确的挂载路径,以 / 开头,只支持字母、数字、点、下划线、横杠、斜杠', }, ]} > diff --git a/react-ui/src/pages/ModelDeployment/List/index.tsx b/react-ui/src/pages/ModelDeployment/List/index.tsx index f0e4cb70..238e4b40 100644 --- a/react-ui/src/pages/ModelDeployment/List/index.tsx +++ b/react-ui/src/pages/ModelDeployment/List/index.tsx @@ -12,7 +12,11 @@ import { useCacheState } from '@/hooks/pageCacheState'; import { deleteServiceReq, getServiceListReq } from '@/services/modelDeployment'; import themes from '@/styles/theme.less'; import { to } from '@/utils/promise'; -import { serviceInfoKey, setSessionStorageItem } from '@/utils/sessionStorage'; +import { + serviceInfoKey, + serviceVersionInfoKey, + setSessionStorageItem, +} from '@/utils/sessionStorage'; import { modalConfirm } from '@/utils/ui'; import { useNavigate } from '@umijs/max'; import { @@ -28,7 +32,12 @@ import { import { type SearchProps } from 'antd/es/input'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; -import { ServiceData, ServiceOperationType } from '../types'; +import { + CreateServiceVersionFrom, + ServiceData, + ServiceOperationType, + createServiceVersionMessage, +} from '../types'; import styles from './index.less'; const allServiceTypeOptions = [{ label: '全部', value: '' }, ...serviceTypeOptions]; @@ -49,6 +58,13 @@ function ModelDeployment() { }, ); + useEffect(() => { + window.addEventListener('message', handleMessage); + return () => { + window.removeEventListener('message', handleMessage); + }; + }, []); + useEffect(() => { getServiceList(); }, [pagination, searchText, serviceType]); @@ -137,6 +153,35 @@ function ModelDeployment() { navigate(`/modelDeployment/serviceInfo/${record.id}`); }; + const handleMessage = (e: MessageEvent) => { + const { type, payload } = e.data; + if (type === createServiceVersionMessage) { + modalConfirm({ + title: '创建服务成功', + content: '是否创建服务版本?', + isDelete: false, + cancelText: '稍后创建', + onOk: () => { + gotoCreateServiceVersion(payload); + }, + }); + } + }; + + // 去创建服务版本 + const gotoCreateServiceVersion = (serviceId: number) => { + setSessionStorageItem( + serviceVersionInfoKey, + { + operationType: ServiceOperationType.Create, + lastPage: CreateServiceVersionFrom.CreateService, + }, + true, + ); + + navigate(`/modelDeployment/addVersion/${serviceId}`); + }; + // 分页切换 const handleTableChange: TableProps['onChange'] = (pagination, _filters, _sorter, { action }) => { if (action === 'paginate') { diff --git a/react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx b/react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx index 21091b5a..771a1c4f 100644 --- a/react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx +++ b/react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx @@ -38,7 +38,12 @@ import { type SearchProps } from 'antd/es/input'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; import ServiceRunStatusCell from '../components/ModelDeployStatusCell'; -import { ServiceData, ServiceOperationType, ServiceVersionData } from '../types'; +import { + CreateServiceVersionFrom, + ServiceData, + ServiceOperationType, + ServiceVersionData, +} from '../types'; import styles from './index.less'; const allServiceStatusOptions = [{ label: '全部', value: '' }, ...serviceStatusOptions]; @@ -171,13 +176,14 @@ function ServiceInfo() { }); }; - // 创建、更新、重启模型部署 + // 创建、更新、重启服务版本 const createServiceVersion = (type: ServiceOperationType, record?: ServiceVersionData) => { setSessionStorageItem( serviceVersionInfoKey, { ...record, operationType: type, + lastPage: CreateServiceVersionFrom.ServiceInfo, }, true, ); diff --git a/react-ui/src/pages/ModelDeployment/components/ModelDeployStatusCell/index.tsx b/react-ui/src/pages/ModelDeployment/components/ModelDeployStatusCell/index.tsx index 7029c8fd..e11f8e43 100644 --- a/react-ui/src/pages/ModelDeployment/components/ModelDeployStatusCell/index.tsx +++ b/react-ui/src/pages/ModelDeployment/components/ModelDeployStatusCell/index.tsx @@ -1,7 +1,7 @@ /* * @Author: 赵伟 * @Date: 2024-04-18 18:35:41 - * @Description: 模型部署状态 + * @Description: 服务运行状态 */ import { ServiceRunStatus } from '@/enums'; import styles from './index.less'; diff --git a/react-ui/src/pages/ModelDeployment/components/ServerLog/index.tsx b/react-ui/src/pages/ModelDeployment/components/ServerLog/index.tsx index ad74986f..2f6d0368 100644 --- a/react-ui/src/pages/ModelDeployment/components/ServerLog/index.tsx +++ b/react-ui/src/pages/ModelDeployment/components/ServerLog/index.tsx @@ -57,7 +57,7 @@ function ServerLog({ info }: ServerLogProps) { getModelDeploymentLog(); }, [info, logTime]); - // 获取模型部署日志 + // 获取服务日志 const getModelDeploymentLog = async () => { if (info && logTime && logTime.length === 2) { const params = { diff --git a/react-ui/src/pages/ModelDeployment/components/UserGuide/index.tsx b/react-ui/src/pages/ModelDeployment/components/UserGuide/index.tsx index c2b73d47..8abd15be 100644 --- a/react-ui/src/pages/ModelDeployment/components/UserGuide/index.tsx +++ b/react-ui/src/pages/ModelDeployment/components/UserGuide/index.tsx @@ -14,7 +14,7 @@ function UserGuide({ info }: UserGuideProps) { getModelDeploymentDocs(); }, [info]); - // 获取模型部署文档 + // 获取服务文档 const getModelDeploymentDocs = async () => { if (info) { const [res] = await to(getServiceVersionDocsReq(info.id)); diff --git a/react-ui/src/pages/ModelDeployment/types.ts b/react-ui/src/pages/ModelDeployment/types.ts index d53655b2..a932b71c 100644 --- a/react-ui/src/pages/ModelDeployment/types.ts +++ b/react-ui/src/pages/ModelDeployment/types.ts @@ -57,3 +57,12 @@ export enum ServiceOperationType { Update = 'Update', // 更新 Restart = 'Restart', // 重启 } + +// 操作类型 +export enum CreateServiceVersionFrom { + CreateService = 'CreateService', // 来自创建服务 + ServiceInfo = 'ServiceInfo', // 来自服务详情 +} + +// 去创建服务版本消息 +export const createServiceVersionMessage = 'createServiceVersion'; diff --git a/react-ui/src/utils/ui.tsx b/react-ui/src/utils/ui.tsx index 7625a771..9034a67b 100644 --- a/react-ui/src/utils/ui.tsx +++ b/react-ui/src/utils/ui.tsx @@ -10,8 +10,20 @@ import { history } from '@umijs/max'; import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; import { closeAllModals } from './modal'; -// 自定义 Confirm 弹框 -export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps) { +type ModalConfirmProps = ModalFuncProps & { + isDelete?: boolean; +}; + +// 自定义删除 Confirm 弹框 +export function modalConfirm({ + title, + content, + okText = '确认', + cancelText = '取消', + isDelete = true, + onOk, + ...rest +}: ModalConfirmProps) { Modal.confirm({ ...rest, width: 600, @@ -19,7 +31,11 @@ export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps) title: (
), content: content &&
{content}
, - okText: '确认', - cancelText: '取消', + okText: okText, + cancelText: cancelText, onOk: onOk, }); }