| @@ -108,7 +108,9 @@ export default defineConfig({ | |||
| * @description 内置了 babel import 插件 | |||
| * @doc https://umijs.org/docs/max/antd#antd | |||
| */ | |||
| antd: {}, | |||
| antd: { | |||
| configProvider: {}, | |||
| }, | |||
| /** | |||
| * @name 网络请求配置 | |||
| * @description 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。 | |||
| @@ -1,6 +1,5 @@ | |||
| // 自定义 Modal | |||
| import { ReactComponent as CloseIcon } from '@/assets/svg/modal-close.svg'; | |||
| import ModalTitle from '@/components/ModalTitle'; | |||
| import { Modal, type ModalProps } from 'antd'; | |||
| import classNames from 'classnames'; | |||
| @@ -15,7 +14,6 @@ function KFModal({ title, image, children, className, ...rest }: KFModalProps) { | |||
| className={classNames(['kf-modal', className])} | |||
| {...rest} | |||
| title={<ModalTitle title={title} image={image}></ModalTitle>} | |||
| closeIcon={<CloseIcon></CloseIcon>} | |||
| > | |||
| {children} | |||
| </Modal> | |||
| @@ -81,6 +81,37 @@ a{ | |||
| .ant-pro-layout .ant-pro-layout-container { | |||
| height: 98vh; | |||
| } | |||
| .ant-modal-confirm .ant-modal-confirm-paragraph{ | |||
| margin: 40px 0 auto; | |||
| text-align: center; | |||
| } | |||
| .ant-modal-confirm-confirm .ant-modal-confirm-body>.anticon{ | |||
| display: none; | |||
| } | |||
| .ant-modal-confirm .ant-modal-confirm-btns { | |||
| margin-top: 30px; | |||
| text-align: center; | |||
| } | |||
| .ant-modal-confirm-btns .ant-btn-default{ | |||
| width:91px; | |||
| height:42px; | |||
| background:rgba(22, 100, 255, 0.06); | |||
| border-radius:10px; | |||
| color:#1d1d20; | |||
| font-size:16px; | |||
| margin-right: 10px; | |||
| } | |||
| .ant-modal-confirm-btns .ant-btn-default:hover{ | |||
| background:rgba(22, 100, 255, 0.06); | |||
| border-color: transparent; | |||
| } | |||
| .ant-modal-confirm-btns .ant-btn-primary{ | |||
| width:91px; | |||
| height:42px; | |||
| background:#1664ff; | |||
| border-radius:10px; | |||
| font-size: 16px; | |||
| } | |||
| .ant-modal .ant-modal-close-x{ | |||
| border: 2px solid #272536; | |||
| border-radius: 50%; | |||
| @@ -91,6 +122,18 @@ a{ | |||
| .ant-modal-content{ | |||
| margin-left: -130px; | |||
| margin-top: 50px; | |||
| } | |||
| .ant-modal .ant-modal-content{ | |||
| padding: 0; | |||
| } | |||
| .ant-modal-confirm-body-wrapper{ | |||
| height:303px; | |||
| border-radius:21px; | |||
| background-image: url(/assets/images/modal-back.png); | |||
| background-repeat:no-repeat; | |||
| background-size:100%; | |||
| background-position: top center; | |||
| } | |||
| .ant-modal .ant-modal-close:hover { | |||
| background-color: transparent; | |||
| @@ -59,12 +59,14 @@ const Dataset = () => { | |||
| const locationParams = useParams(); //新版本获取路由参数接口 | |||
| const [wordList, setWordList] = useState([]); | |||
| const [activeTabKey, setActiveTabKey] = useState('1'); | |||
| const [uuid, setUuid] = useState(Date.now()); | |||
| const getDatasetByDetail = () => { | |||
| getDatasetById(locationParams.id).then((ret) => { | |||
| console.log(ret); | |||
| setDatasetDetailObj(ret.data); | |||
| }); | |||
| }; | |||
| // 获取数据集版本 | |||
| const getDatasetVersionList = () => { | |||
| getDatasetVersionsById(locationParams.id).then((ret) => { | |||
| console.log(ret); | |||
| @@ -77,6 +79,8 @@ const Dataset = () => { | |||
| }; | |||
| }), | |||
| ); | |||
| setVersion(ret.data[0]); | |||
| getDatasetVersions({ version: ret.data[0], dataset_id: locationParams.id }); | |||
| } | |||
| }); | |||
| }; | |||
| @@ -90,6 +94,7 @@ const Dataset = () => { | |||
| form.setFieldsValue({ name: datasetDetailObj.name }); | |||
| setDialogTitle('创建新版本'); | |||
| setUuid(Date.now()); | |||
| setIsModalOpen(true); | |||
| }; | |||
| const handleCancel = () => { | |||
| @@ -102,16 +107,23 @@ const Dataset = () => { | |||
| }; | |||
| const deleteDataset = () => { | |||
| Modal.confirm({ | |||
| title: '删除', | |||
| content: '确定删除数据集版本?', | |||
| title: ( | |||
| <div> | |||
| <img | |||
| src="/assets/images/delete-icon.png" | |||
| style={{ width: '120px', marginBottom: '24px' }} | |||
| alt="" | |||
| /> | |||
| <div style={{ color: '#1d1d20', fontSize: '16px' }}>删除后,该数据集版本将不可恢复</div> | |||
| </div> | |||
| ), | |||
| content: <div style={{ color: '#1d1d20', fontSize: '15px' }}>是否确认删除?</div>, | |||
| okText: '确认', | |||
| cancelText: '取消', | |||
| onOk: () => { | |||
| deleteDatasetVersion({ dataset_id: locationParams.id, version }).then((ret) => { | |||
| setVersion(null); | |||
| getDatasetVersionList(); | |||
| getDatasetVersions({ version, dataset_id: locationParams.id }); | |||
| message.success('删除成功'); | |||
| }); | |||
| }, | |||
| @@ -124,6 +136,7 @@ const Dataset = () => { | |||
| message.success('创建成功'); | |||
| }); | |||
| }; | |||
| // 获取版本下的文件列表 | |||
| const getDatasetVersions = (params) => { | |||
| getDatasetVersionIdList(params).then((res) => { | |||
| setWordList(res?.data?.content ?? []); | |||
| @@ -368,7 +381,7 @@ const Dataset = () => { | |||
| }, | |||
| ]} | |||
| > | |||
| <Upload {...props}> | |||
| <Upload {...props} data={{ uuid: uuid }}> | |||
| <Button | |||
| style={{ | |||
| fontSize: '14px', | |||
| @@ -24,7 +24,16 @@ const PublicData = (React.FC = () => { | |||
| onChange({ file, fileList }) { | |||
| if (file.status !== 'uploading') { | |||
| console.log(file, fileList); | |||
| form.setFieldsValue({ dataset_version_vos: fileList.map((item) => item.response.data[0]) }); | |||
| form.setFieldsValue({ | |||
| dataset_version_vos: fileList.map((item) => { | |||
| const data = item.response.data[0]; | |||
| return { | |||
| file_name: data.fileName, | |||
| file_size: data.fileSize, | |||
| url: data.url, | |||
| }; | |||
| }), | |||
| }); | |||
| } | |||
| }, | |||
| defaultFileList: [], | |||
| @@ -98,7 +98,7 @@ function Experiment() { | |||
| setExperimentInList(list); | |||
| // 获取 TensorBoard 状态 | |||
| list.forEach((item) => { | |||
| if (item.nodes_result.tensorboard_log) { | |||
| if (item.nodes_result?.tensorboard_log) { | |||
| const timerId = setTimeout(() => { | |||
| getTensorBoardStatus(item); | |||
| }, 0); | |||
| @@ -161,8 +161,8 @@ function Experiment() { | |||
| } | |||
| }; | |||
| const expandChange = (e, record) => { | |||
| clearExperimentInTimers(); | |||
| if (record.id === expandedRowKeys) { | |||
| clearExperimentInTimers(); | |||
| setExpandedRowKeys(null); | |||
| } else { | |||
| getQueryByExperiment(record.id); | |||
| @@ -350,8 +350,20 @@ function Experiment() { | |||
| icon={<DeleteOutlined />} | |||
| onClick={async () => { | |||
| Modal.confirm({ | |||
| title: '删除', | |||
| content: '确定删除该条实验吗?', | |||
| title: ( | |||
| <div> | |||
| <img | |||
| src="/assets/images/delete-icon.png" | |||
| style={{ width: '120px', marginBottom: '24px' }} | |||
| alt="" | |||
| /> | |||
| <div style={{ color: '#1d1d20', fontSize: '16px' }}> | |||
| 删除后,该实验将不可恢复 | |||
| </div> | |||
| </div> | |||
| ), | |||
| content: <div style={{ color: '#1d1d20', fontSize: '15px' }}>是否确认删除?</div>, | |||
| closable: true, | |||
| okText: '确认', | |||
| cancelText: '取消', | |||
| @@ -434,7 +446,7 @@ function Experiment() { | |||
| {index + 1} | |||
| </a> | |||
| <div style={{ width: '300px' }}> | |||
| {item.nodes_result.tensorboard_log ? ( | |||
| {item.nodes_result?.tensorboard_log ? ( | |||
| <TensorBoardStatus | |||
| status={item.tensorBoardStatus} | |||
| onClick={() => handleTensorboard(item)} | |||
| @@ -101,8 +101,17 @@ const Dataset = () => { | |||
| }; | |||
| const deleteDataset = () => { | |||
| Modal.confirm({ | |||
| title: '删除', | |||
| content: '确定删除模型版本?', | |||
| title: ( | |||
| <div> | |||
| <img | |||
| src="/assets/images/delete-icon.png" | |||
| style={{ width: '120px', marginBottom: '24px' }} | |||
| alt="" | |||
| /> | |||
| <div style={{ color: '#1d1d20', fontSize: '16px' }}>删除后,该模型版本将不可恢复</div> | |||
| </div> | |||
| ), | |||
| content: <div style={{ color: '#1d1d20', fontSize: '15px' }}>是否确认删除?</div>, | |||
| okText: '确认', | |||
| cancelText: '取消', | |||
| @@ -23,14 +23,23 @@ const PublicData = () => { | |||
| onChange({ file, fileList }) { | |||
| if (file.status !== 'uploading') { | |||
| console.log(file, fileList); | |||
| form.setFieldsValue({ dataset_version_vos: fileList.map((item) => item.response.data[0]) }); | |||
| form.setFieldsValue({ | |||
| models_version_vos: fileList.map((item) => { | |||
| const data = item.response.data[0]; | |||
| return { | |||
| file_name: data.fileName, | |||
| file_size: data.fileSize, | |||
| url: data.url, | |||
| }; | |||
| }), | |||
| }); | |||
| } | |||
| }, | |||
| defaultFileList: [], | |||
| }; | |||
| const [queryFlow, setQueryFlow] = useState({ | |||
| page: 0, | |||
| size: 10, | |||
| size: 20, | |||
| name: null, | |||
| available_range: 0, | |||
| }); | |||
| @@ -326,6 +335,21 @@ const PublicData = () => { | |||
| <Input placeholder="请输入模型名称" showCount maxLength={64} /> | |||
| </Form.Item> | |||
| <Form.Item | |||
| label="模型版本" | |||
| name="version" | |||
| rules={ | |||
| [ | |||
| // { | |||
| // required: true, | |||
| // message: 'Please input your username!', | |||
| // }, | |||
| ] | |||
| } | |||
| > | |||
| <Input placeholder="请输入模型版本" /> | |||
| </Form.Item> | |||
| <Form.Item | |||
| label="模型描述" | |||
| name="description" | |||
| @@ -372,9 +396,19 @@ const PublicData = () => { | |||
| > | |||
| <Select allowClear placeholder="请选择模型标签" options={[]} /> | |||
| </Form.Item> | |||
| <Form.Item label="模型文件" name="dataset_version_vos"> | |||
| <Form.Item label="模型文件" name="models_version_vos"> | |||
| <Upload {...props} data={{ uuid: uuid }}> | |||
| <Button icon={<UploadOutlined style={{ color: '#1664ff' }} />}>上传文件</Button> | |||
| <Button | |||
| style={{ | |||
| fontSize: '14px', | |||
| border: '1px solid', | |||
| borderColor: '#1664ff', | |||
| background: '#fff', | |||
| }} | |||
| icon={<UploadOutlined style={{ color: '#1664ff', fontSize: '14px' }} />} | |||
| > | |||
| 上传文件 | |||
| </Button> | |||
| </Upload> | |||
| </Form.Item> | |||
| </Form> | |||
| @@ -10,7 +10,7 @@ const leftdataList = [1, 2, 3]; | |||
| const PublicData = () => { | |||
| const [queryFlow, setQueryFlow] = useState({ | |||
| page: 0, | |||
| size: 10, | |||
| size: 20, | |||
| name: null, | |||
| available_range: 1, | |||
| }); | |||
| @@ -201,14 +201,27 @@ const Pipeline = () => { | |||
| icon={<DeleteOutlined />} | |||
| onClick={async () => { | |||
| Modal.confirm({ | |||
| title: '删除', | |||
| content: '确定删除该条流水线吗?', | |||
| title: ( | |||
| <div> | |||
| <img | |||
| src="/assets/images/delete-icon.png" | |||
| style={{ width: '120px', marginBottom: '24px' }} | |||
| alt="" | |||
| /> | |||
| <div style={{ color: '#1d1d20', fontSize: '16px' }}> | |||
| 删除后,该流水线将不可恢复 | |||
| </div> | |||
| </div> | |||
| ), | |||
| content: <div style={{ color: '#1d1d20', fontSize: '15px' }}>是否确认删除?</div>, | |||
| closable: true, | |||
| okText: '确认', | |||
| cancelText: '取消', | |||
| onOk: () => { | |||
| console.log(record); | |||
| removeWorkflow(record.id).then((ret) => { | |||
| if (ret.code == 200) { | |||
| if (ret.code === 200) { | |||
| message.success('删除成功'); | |||
| getList(); | |||
| } else { | |||
| @@ -62,5 +62,6 @@ | |||
| .ant-btn-primary { | |||
| background: #1664ff; | |||
| } | |||
| } | |||
| } | |||
| @@ -25,7 +25,7 @@ export function addDatesetAndVesion(data) { | |||
| } | |||
| // 新增模型 | |||
| export function addModel(data) { | |||
| return request(`/api/mmp//models`, { | |||
| return request(`/api/mmp/models/addModelAndVersion`, { | |||
| method: 'POST', | |||
| headers: { | |||
| 'Content-Type': 'application/json;charset=UTF-8', | |||