| @@ -3,6 +3,7 @@ | |||||
| * @Date: 2024-04-16 13:58:08 | * @Date: 2024-04-16 13:58:08 | ||||
| * @Description: 开发环境列表 | * @Description: 开发环境列表 | ||||
| */ | */ | ||||
| import CommonTableCell from '@/components/CommonTableCell'; | import CommonTableCell from '@/components/CommonTableCell'; | ||||
| import DateTableCell from '@/components/DateTableCell'; | import DateTableCell from '@/components/DateTableCell'; | ||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| @@ -15,6 +16,7 @@ import { | |||||
| stopEditorReq, | stopEditorReq, | ||||
| } from '@/services/developmentEnvironment'; | } from '@/services/developmentEnvironment'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { openAntdModal } from '@/utils/modal'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { editorUrlKey, setSessionStorageItem } from '@/utils/sessionStorage'; | import { editorUrlKey, setSessionStorageItem } from '@/utils/sessionStorage'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| @@ -29,6 +31,7 @@ import { | |||||
| } from 'antd'; | } from 'antd'; | ||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||
| import CreateMirrorModal from '../components/CreateMirrorModal'; | |||||
| import EditorStatusCell from '../components/EditorStatusCell'; | import EditorStatusCell from '../components/EditorStatusCell'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| @@ -110,6 +113,16 @@ function EditorList() { | |||||
| } | } | ||||
| }; | }; | ||||
| // 制作镜像 | |||||
| const createMirror = (id: number) => { | |||||
| const { close } = openAntdModal(CreateMirrorModal, { | |||||
| envId: id, | |||||
| onOk: () => { | |||||
| close(); | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| // 处理删除 | // 处理删除 | ||||
| const handleEditorDelete = (record: EditorData) => { | const handleEditorDelete = (record: EditorData) => { | ||||
| modalConfirm({ | modalConfirm({ | ||||
| @@ -218,6 +231,17 @@ function EditorList() { | |||||
| 启动 | 启动 | ||||
| </Button> | </Button> | ||||
| )} | )} | ||||
| {record.status === DevEditorStatus.Running ? ( | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="jingxiang" | |||||
| icon={<KFIcon type="icon-jingxiang" />} | |||||
| onClick={() => createMirror(record.id)} | |||||
| > | |||||
| 制作镜像 | |||||
| </Button> | |||||
| ) : null} | |||||
| <ConfigProvider | <ConfigProvider | ||||
| theme={{ | theme={{ | ||||
| token: { | token: { | ||||
| @@ -0,0 +1,100 @@ | |||||
| import KFModal from '@/components/KFModal'; | |||||
| import { createEditorMirrorReq } from '@/services/developmentEnvironment'; | |||||
| import { to } from '@/utils/promise'; | |||||
| import { Form, Input, message, type ModalProps } from 'antd'; | |||||
| interface CreateMirrorModalProps extends Omit<ModalProps, 'onOk'> { | |||||
| envId: number; // 开发环境id | |||||
| onOk: () => void; | |||||
| } | |||||
| function CreateMirrorModal({ envId, onOk, ...rest }: CreateMirrorModalProps) { | |||||
| // 上传请求 | |||||
| const createDatasetVersion = async (params: any) => { | |||||
| const [res] = await to( | |||||
| createEditorMirrorReq({ | |||||
| ...params, | |||||
| dev_environment_id: envId, | |||||
| upload_type: 1, | |||||
| version: params['tagName'], | |||||
| }), | |||||
| ); | |||||
| if (res) { | |||||
| message.success('创建成功,请到 “AI资产” - “个人镜像” 中查看'); | |||||
| onOk?.(); | |||||
| } | |||||
| }; | |||||
| // 提交 | |||||
| const onFinish = (formData: any) => { | |||||
| createDatasetVersion(formData); | |||||
| }; | |||||
| return ( | |||||
| <KFModal | |||||
| {...rest} | |||||
| title="制作镜像" | |||||
| image={require('@/assets/img/create-experiment.png')} | |||||
| width={825} | |||||
| okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} | |||||
| > | |||||
| <Form name="form" layout="vertical" onFinish={onFinish} autoComplete="off"> | |||||
| <Form.Item | |||||
| label="镜像名称" | |||||
| name="name" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入镜像名称', | |||||
| }, | |||||
| { | |||||
| pattern: /^[a-zA-Z0-9_-]*$/, | |||||
| message: '只支持字母、数字、下划线、中横线', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input placeholder="请输入镜像名称" maxLength={64} showCount allowClear /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| label="镜像Tag" | |||||
| name="tag_name" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入镜像Tag', | |||||
| }, | |||||
| { | |||||
| pattern: /^[a-zA-Z0-9_-]*$/, | |||||
| message: '只支持字母、数字、下划线、中横线', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input placeholder="请输入镜像Tag" maxLength={64} showCount allowClear /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| label="镜像描述描述" | |||||
| name="description" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入镜像描述', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input.TextArea | |||||
| placeholder="请输入镜像描述" | |||||
| autoSize={{ minRows: 3, maxRows: 6 }} | |||||
| maxLength={256} | |||||
| showCount | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| </Form> | |||||
| </KFModal> | |||||
| ); | |||||
| } | |||||
| export default CreateMirrorModal; | |||||
| @@ -51,7 +51,7 @@ export const getParamRules = (paramType: number, required: boolean = false): For | |||||
| // 防止后台返回不是 number 类型 | // 防止后台返回不是 number 类型 | ||||
| if (Number(paramType) === 2) { | if (Number(paramType) === 2) { | ||||
| rules.push({ | rules.push({ | ||||
| pattern: /^-?\d+(\.\d+)?$/, | |||||
| pattern: /^-?((0(\.0*[1-9]\d*)?)|([1-9]\d*(\.\d+)?))$/, | |||||
| message: '整型必须是数字', | message: '整型必须是数字', | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -153,6 +153,10 @@ function MirrorCreate() { | |||||
| required: true, | required: true, | ||||
| message: '请输入镜像名称', | message: '请输入镜像名称', | ||||
| }, | }, | ||||
| { | |||||
| pattern: /^[a-zA-Z0-9_-]*$/, | |||||
| message: '只支持字母、数字、下划线、中横线', | |||||
| }, | |||||
| ]} | ]} | ||||
| > | > | ||||
| <Input | <Input | ||||
| @@ -176,6 +180,10 @@ function MirrorCreate() { | |||||
| required: true, | required: true, | ||||
| message: '请输入镜像Tag', | message: '请输入镜像Tag', | ||||
| }, | }, | ||||
| { | |||||
| pattern: /^[a-zA-Z0-9_-]*$/, | |||||
| message: '只支持字母、数字、下划线、中横线', | |||||
| }, | |||||
| ]} | ]} | ||||
| > | > | ||||
| <Input placeholder="请输入镜像Tag" maxLength={64} showCount allowClear /> | <Input placeholder="请输入镜像Tag" maxLength={64} showCount allowClear /> | ||||
| @@ -49,9 +49,18 @@ export function startEditorReq(id: number) { | |||||
| method: 'POST', | method: 'POST', | ||||
| }); | }); | ||||
| } | } | ||||
| // 停止编辑器 | // 停止编辑器 | ||||
| export function stopEditorReq(id: number) { | export function stopEditorReq(id: number) { | ||||
| return request(`/api/mmp/jupyter/stop/${id}`, { | return request(`/api/mmp/jupyter/stop/${id}`, { | ||||
| method: 'DELETE', | method: 'DELETE', | ||||
| }); | }); | ||||
| } | } | ||||
| // 制作镜像 | |||||
| export function createEditorMirrorReq(data: any) { | |||||
| return request(`/api/mmp/image/saveImage`, { | |||||
| method: 'POST', | |||||
| data, | |||||
| }); | |||||
| } | |||||