Browse Source

feat: 创建服务之后提示去创建服务版本

pull/135/head
cp3hnu 1 year ago
parent
commit
126e0cb7a5
13 changed files with 159 additions and 20 deletions
  1. BIN
      react-ui/src/assets/img/comfirm-icon.png
  2. +7
    -0
      react-ui/src/components/KFConfirmModal/index.less
  3. +37
    -0
      react-ui/src/components/KFConfirmModal/index.tsx
  4. +1
    -1
      react-ui/src/enums/index.ts
  5. +5
    -2
      react-ui/src/pages/ModelDeployment/CreateService/index.tsx
  6. +21
    -5
      react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx
  7. +47
    -2
      react-ui/src/pages/ModelDeployment/List/index.tsx
  8. +8
    -2
      react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx
  9. +1
    -1
      react-ui/src/pages/ModelDeployment/components/ModelDeployStatusCell/index.tsx
  10. +1
    -1
      react-ui/src/pages/ModelDeployment/components/ServerLog/index.tsx
  11. +1
    -1
      react-ui/src/pages/ModelDeployment/components/UserGuide/index.tsx
  12. +9
    -0
      react-ui/src/pages/ModelDeployment/types.ts
  13. +21
    -5
      react-ui/src/utils/ui.tsx

BIN
react-ui/src/assets/img/comfirm-icon.png View File

Before After
Width: 432  |  Height: 287  |  Size: 22 kB

+ 7
- 0
react-ui/src/components/KFConfirmModal/index.less View File

@@ -0,0 +1,7 @@
.kf-confirm-modal {
&__content {
width: 100%;
font-size: 18px;
text-align: center;
}
}

+ 37
- 0
react-ui/src/components/KFConfirmModal/index.tsx View File

@@ -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 (
<KFModal
className={classNames(['kf-confirm-modal', className])}
{...rest}
centered={centered ?? true}
maskClosable={maskClosable ?? false}
title={title}
image={image ?? require('@/assets/img/edit-experiment.png')}
>
<div className="kf-confirm-modal__content">{content}</div>
</KFModal>
);
}

export default KFConfirmModal;

+ 1
- 1
react-ui/src/enums/index.ts View File

@@ -80,7 +80,7 @@ export enum ServiceType {


export const serviceTypeOptions = [ export const serviceTypeOptions = [
{ label: '视频', value: ServiceType.Video }, { label: '视频', value: ServiceType.Video },
{ label: '图', value: ServiceType.Image },
{ label: '图', value: ServiceType.Image },
{ label: '音频', value: ServiceType.Audio }, { label: '音频', value: ServiceType.Audio },
{ label: '文本', value: ServiceType.Text }, { label: '文本', value: ServiceType.Text },
]; ];

+ 5
- 2
react-ui/src/pages/ModelDeployment/CreateService/index.tsx View File

@@ -18,7 +18,7 @@ import { useNavigate } from '@umijs/max';
import { App, Button, Col, Form, Input, Row, Select } from 'antd'; import { App, Button, Col, Form, Input, Row, Select } from 'antd';
import { pick } from 'lodash'; import { pick } from 'lodash';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { ServiceData, ServiceOperationType } from '../types';
import { ServiceData, ServiceOperationType, createServiceVersionMessage } from '../types';
import styles from './index.less'; import styles from './index.less';


// 表单数据 // 表单数据
@@ -59,9 +59,12 @@ function CreateService() {
...formData, ...formData,
}; };
const [res] = await to(request(params)); const [res] = await to(request(params));
if (res) {
if (res && res.data) {
message.success('操作成功'); message.success('操作成功');
navigate(-1); navigate(-1);
setTimeout(() => {
window.postMessage({ type: createServiceVersionMessage, payload: res.data.id });
}, 500);
} }
}; };




+ 21
- 5
react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx View File

@@ -31,7 +31,12 @@ import { useNavigate, useParams } from '@umijs/max';
import { App, Button, Col, Flex, Form, Input, Row, Select } from 'antd'; import { App, Button, Col, Flex, Form, Input, Row, Select } from 'antd';
import { omit, pick } from 'lodash'; import { omit, pick } from 'lodash';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { ServiceData, ServiceOperationType, ServiceVersionData } from '../types';
import {
CreateServiceVersionFrom,
ServiceData,
ServiceOperationType,
ServiceVersionData,
} from '../types';
import styles from './index.less'; import styles from './index.less';


// 表单数据 // 表单数据
@@ -53,6 +58,7 @@ function CreateServiceVersion() {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [resourceStandardList, filterResourceStandard] = useComputingResource(); const [resourceStandardList, filterResourceStandard] = useComputingResource();
const [operationType, setOperationType] = useState(ServiceOperationType.Create); const [operationType, setOperationType] = useState(ServiceOperationType.Create);
const [lastPage, setLastPage] = useState(CreateServiceVersionFrom.ServiceInfo);
const { message } = App.useApp(); const { message } = App.useApp();
const [serviceInfo, setServiceInfo] = useState<ServiceData | undefined>(undefined); const [serviceInfo, setServiceInfo] = useState<ServiceData | undefined>(undefined);
const [versionInfo, setVersionInfo] = useState<ServiceVersionData | undefined>(undefined); const [versionInfo, setVersionInfo] = useState<ServiceVersionData | undefined>(undefined);
@@ -60,10 +66,15 @@ function CreateServiceVersion() {
const id = params.id; const id = params.id;


useEffect(() => { useEffect(() => {
const res: (ServiceVersionData & { operationType: ServiceOperationType }) | undefined =
getSessionStorageItem(serviceVersionInfoKey, true);
const res:
| (ServiceVersionData & {
operationType: ServiceOperationType;
lastPage: CreateServiceVersionFrom;
})
| undefined = getSessionStorageItem(serviceVersionInfoKey, true);
if (res) { if (res) {
setOperationType(res.operationType); setOperationType(res.operationType);
setLastPage(res.lastPage);
setVersionInfo(res); setVersionInfo(res);
let model, codeConfig, envVariables; let model, codeConfig, envVariables;
if (res.model && typeof res.model === 'object') { if (res.model && typeof res.model === 'object') {
@@ -156,7 +167,11 @@ function CreateServiceVersion() {
const [res] = await to(request(params)); const [res] = await to(request(params));
if (res) { if (res) {
message.success('操作成功'); 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._/-]+$/, pattern: /^\/[a-zA-Z0-9._/-]+$/,
message: '请输入正确的挂载绝对路径',
message:
'请输入正确的挂载路径,以 / 开头,只支持字母、数字、点、下划线、横杠、斜杠',
}, },
]} ]}
> >


+ 47
- 2
react-ui/src/pages/ModelDeployment/List/index.tsx View File

@@ -12,7 +12,11 @@ import { useCacheState } from '@/hooks/pageCacheState';
import { deleteServiceReq, getServiceListReq } from '@/services/modelDeployment'; import { deleteServiceReq, getServiceListReq } from '@/services/modelDeployment';
import themes from '@/styles/theme.less'; import themes from '@/styles/theme.less';
import { to } from '@/utils/promise'; import { to } from '@/utils/promise';
import { serviceInfoKey, setSessionStorageItem } from '@/utils/sessionStorage';
import {
serviceInfoKey,
serviceVersionInfoKey,
setSessionStorageItem,
} from '@/utils/sessionStorage';
import { modalConfirm } from '@/utils/ui'; import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max'; import { useNavigate } from '@umijs/max';
import { import {
@@ -28,7 +32,12 @@ import {
import { type SearchProps } from 'antd/es/input'; import { type SearchProps } from 'antd/es/input';
import classNames from 'classnames'; import classNames from 'classnames';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { ServiceData, ServiceOperationType } from '../types';
import {
CreateServiceVersionFrom,
ServiceData,
ServiceOperationType,
createServiceVersionMessage,
} from '../types';
import styles from './index.less'; import styles from './index.less';


const allServiceTypeOptions = [{ label: '全部', value: '' }, ...serviceTypeOptions]; const allServiceTypeOptions = [{ label: '全部', value: '' }, ...serviceTypeOptions];
@@ -49,6 +58,13 @@ function ModelDeployment() {
}, },
); );


useEffect(() => {
window.addEventListener('message', handleMessage);
return () => {
window.removeEventListener('message', handleMessage);
};
}, []);

useEffect(() => { useEffect(() => {
getServiceList(); getServiceList();
}, [pagination, searchText, serviceType]); }, [pagination, searchText, serviceType]);
@@ -137,6 +153,35 @@ function ModelDeployment() {
navigate(`/modelDeployment/serviceInfo/${record.id}`); 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 }) => { const handleTableChange: TableProps['onChange'] = (pagination, _filters, _sorter, { action }) => {
if (action === 'paginate') { if (action === 'paginate') {


+ 8
- 2
react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx View File

@@ -38,7 +38,12 @@ import { type SearchProps } from 'antd/es/input';
import classNames from 'classnames'; import classNames from 'classnames';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import ServiceRunStatusCell from '../components/ModelDeployStatusCell'; import ServiceRunStatusCell from '../components/ModelDeployStatusCell';
import { ServiceData, ServiceOperationType, ServiceVersionData } from '../types';
import {
CreateServiceVersionFrom,
ServiceData,
ServiceOperationType,
ServiceVersionData,
} from '../types';
import styles from './index.less'; import styles from './index.less';


const allServiceStatusOptions = [{ label: '全部', value: '' }, ...serviceStatusOptions]; const allServiceStatusOptions = [{ label: '全部', value: '' }, ...serviceStatusOptions];
@@ -171,13 +176,14 @@ function ServiceInfo() {
}); });
}; };


// 创建、更新、重启模型部署
// 创建、更新、重启服务版本
const createServiceVersion = (type: ServiceOperationType, record?: ServiceVersionData) => { const createServiceVersion = (type: ServiceOperationType, record?: ServiceVersionData) => {
setSessionStorageItem( setSessionStorageItem(
serviceVersionInfoKey, serviceVersionInfoKey,
{ {
...record, ...record,
operationType: type, operationType: type,
lastPage: CreateServiceVersionFrom.ServiceInfo,
}, },
true, true,
); );


+ 1
- 1
react-ui/src/pages/ModelDeployment/components/ModelDeployStatusCell/index.tsx View File

@@ -1,7 +1,7 @@
/* /*
* @Author: 赵伟 * @Author: 赵伟
* @Date: 2024-04-18 18:35:41 * @Date: 2024-04-18 18:35:41
* @Description: 模型部署状态
* @Description: 服务运行状态
*/ */
import { ServiceRunStatus } from '@/enums'; import { ServiceRunStatus } from '@/enums';
import styles from './index.less'; import styles from './index.less';


+ 1
- 1
react-ui/src/pages/ModelDeployment/components/ServerLog/index.tsx View File

@@ -57,7 +57,7 @@ function ServerLog({ info }: ServerLogProps) {
getModelDeploymentLog(); getModelDeploymentLog();
}, [info, logTime]); }, [info, logTime]);


// 获取模型部署日志
// 获取服务日志
const getModelDeploymentLog = async () => { const getModelDeploymentLog = async () => {
if (info && logTime && logTime.length === 2) { if (info && logTime && logTime.length === 2) {
const params = { const params = {


+ 1
- 1
react-ui/src/pages/ModelDeployment/components/UserGuide/index.tsx View File

@@ -14,7 +14,7 @@ function UserGuide({ info }: UserGuideProps) {
getModelDeploymentDocs(); getModelDeploymentDocs();
}, [info]); }, [info]);


// 获取模型部署文档
// 获取服务文档
const getModelDeploymentDocs = async () => { const getModelDeploymentDocs = async () => {
if (info) { if (info) {
const [res] = await to(getServiceVersionDocsReq(info.id)); const [res] = await to(getServiceVersionDocsReq(info.id));


+ 9
- 0
react-ui/src/pages/ModelDeployment/types.ts View File

@@ -57,3 +57,12 @@ export enum ServiceOperationType {
Update = 'Update', // 更新 Update = 'Update', // 更新
Restart = 'Restart', // 重启 Restart = 'Restart', // 重启
} }

// 操作类型
export enum CreateServiceVersionFrom {
CreateService = 'CreateService', // 来自创建服务
ServiceInfo = 'ServiceInfo', // 来自服务详情
}

// 去创建服务版本消息
export const createServiceVersionMessage = 'createServiceVersion';

+ 21
- 5
react-ui/src/utils/ui.tsx View File

@@ -10,8 +10,20 @@ import { history } from '@umijs/max';
import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd';
import { closeAllModals } from './modal'; 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({ Modal.confirm({
...rest, ...rest,
width: 600, width: 600,
@@ -19,7 +31,11 @@ export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps)
title: ( title: (
<div> <div>
<img <img
src={require('@/assets/img/delete-icon.png')}
src={
isDelete
? require('@/assets/img/delete-icon.png')
: require('@/assets/img/comfirm-icon.png')
}
style={{ width: '120px', marginBottom: '24px' }} style={{ width: '120px', marginBottom: '24px' }}
draggable={false} draggable={false}
alt="" alt=""
@@ -28,8 +44,8 @@ export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps)
</div> </div>
), ),
content: content && <div style={{ color: themes.textColor, fontSize: '15px' }}>{content}</div>, content: content && <div style={{ color: themes.textColor, fontSize: '15px' }}>{content}</div>,
okText: '确认',
cancelText: '取消',
okText: okText,
cancelText: cancelText,
onOk: onOk, onOk: onOk,
}); });
} }


Loading…
Cancel
Save