| @@ -224,8 +224,8 @@ const Dataset = () => { | |||
| <span style={{ color: '#1d1d20', fontSize: '20px' }}>{datasetDetailObj.name}</span> | |||
| <div className={Styles.smallTagBox}> | |||
| <div className={Styles.tagItem}>数据集 id:{datasetDetailObj.id}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.data_tag || '...'}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.data_type}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.dataset_type_name || '...'}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.dataset_tag_name || '...'}</div> | |||
| </div> | |||
| </div> | |||
| <div className={Styles.datasetIntroCneterBox}> | |||
| @@ -229,6 +229,11 @@ | |||
| border-color: #eaeaea; | |||
| border-radius: 4px; | |||
| cursor: pointer; | |||
| .dropdown{ | |||
| position: absolute; | |||
| right: 20px; | |||
| top: 15px; | |||
| } | |||
| .itemText { | |||
| position: absolute; | |||
| top: 20px; | |||
| @@ -1,14 +1,22 @@ | |||
| import { getAccessToken } from '@/access'; | |||
| import clock from '@/assets/img/clock.png'; | |||
| import creatByImg from '@/assets/img/creatBy.png'; | |||
| import deleteIcon from '@/assets/img/delete-icon.png'; | |||
| import KFIcon from '@/components/KFIcon'; | |||
| import { addDatesetAndVesion, getAssetIcon, getDatasetList } from '@/services/dataset/index.js'; | |||
| import { | |||
| addDatesetAndVesion, | |||
| deleteDataset, | |||
| getAssetIcon, | |||
| getDatasetList, | |||
| } from '@/services/dataset/index.js'; | |||
| import { getDictSelectOption } from '@/services/system/dict'; | |||
| import { modalConfirm } from '@/utils/ui'; | |||
| import { UploadOutlined } from '@ant-design/icons'; | |||
| import { Button, Form, Input, Modal, Pagination, Radio, Select, Upload } from 'antd'; | |||
| import moment from 'moment'; | |||
| import React, { useEffect, useState } from 'react'; | |||
| import { useNavigate } from 'react-router-dom'; | |||
| import './index.less'; | |||
| import Styles from './index.less'; | |||
| const { Search } = Input; | |||
| @@ -277,7 +285,30 @@ const PublicData = (React.FC = () => { | |||
| return ( | |||
| <div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}> | |||
| <span className={Styles.itemText}>{item.name}</span> | |||
| <img | |||
| onClick={(e) => { | |||
| e.stopPropagation(); | |||
| modalConfirm({ | |||
| title: '确定删除该条数据集实例吗?', | |||
| onOk: () => { | |||
| deleteDataset(item.id).then((ret) => { | |||
| if (ret.code === 200) { | |||
| message.success('删除成功'); | |||
| getModelLists(queryFlow); | |||
| } else { | |||
| message.error(ret.msg); | |||
| } | |||
| }); | |||
| }, | |||
| }); | |||
| }} | |||
| className={Styles.dropdown} | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| src={deleteIcon} | |||
| alt="" | |||
| /> | |||
| <div className={Styles.itemDescripition}>{item.description}</div> | |||
| <div className={Styles.itemTime}> | |||
| <img | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| @@ -1,6 +1,8 @@ | |||
| import clock from '@/assets/img/clock.png'; | |||
| import creatByImg from '@/assets/img/creatBy.png'; | |||
| import { getAssetIcon, getDatasetList } from '@/services/dataset/index.js'; | |||
| import deleteIcon from '@/assets/img/delete-icon.png'; | |||
| import { deleteDataset, getAssetIcon, getDatasetList } from '@/services/dataset/index.js'; | |||
| import { modalConfirm } from '@/utils/ui'; | |||
| import { Form, Input, Pagination } from 'antd'; | |||
| import moment from 'moment'; | |||
| import { useEffect, useState } from 'react'; | |||
| @@ -225,6 +227,28 @@ const PublicData = () => { | |||
| return ( | |||
| <div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}> | |||
| <span className={Styles.itemText}>{item.name}</span> | |||
| <img | |||
| onClick={(e) => { | |||
| e.stopPropagation(); | |||
| modalConfirm({ | |||
| title: '确定删除该条数据集实例吗?', | |||
| onOk: () => { | |||
| deleteDataset(item.id).then((ret) => { | |||
| if (ret.code === 200) { | |||
| message.success('删除成功'); | |||
| getModelLists(queryFlow); | |||
| } else { | |||
| message.error(ret.msg); | |||
| } | |||
| }); | |||
| }, | |||
| }); | |||
| }} | |||
| className={Styles.dropdown} | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| src={deleteIcon} | |||
| alt="" | |||
| /> | |||
| <div className={Styles.itemDescripition}>{item.description}</div> | |||
| <div className={Styles.itemTime}> | |||
| <img | |||
| @@ -68,19 +68,9 @@ function ExperimentText() { | |||
| }; | |||
| const formChange = (val) => {}; | |||
| const handlerClick = (e) => { | |||
| console.log(propsRef, graph, messageRef.current); | |||
| // let cache = []; | |||
| // let json_str = JSON.stringify(graph, function(key, value) { | |||
| // if (typeof value === 'object' && value !== null) { | |||
| // if (cache.indexOf(value) !== -1) { | |||
| // return; | |||
| // } | |||
| // cache.push(value); | |||
| // } | |||
| // return value; | |||
| // }); | |||
| // console.log(json_str); | |||
| propsRef.current.showDrawer(e, locationParams.id, messageRef.current); | |||
| if (e.target.get('name') !== 'anchor-point' && e.item) { | |||
| propsRef.current.showDrawer(e, locationParams.id, messageRef.current); | |||
| } | |||
| }; | |||
| const getGraphData = (data) => { | |||
| if (graph) { | |||
| @@ -387,8 +377,7 @@ function ExperimentText() { | |||
| fitView: true, | |||
| fitViewPadding: [320, 320, 220, 320], | |||
| }); | |||
| graph.on('dblclick', handlerClick); | |||
| graph.on('node:click', handlerClick); | |||
| window.onresize = () => { | |||
| if (!graph || graph.get('destroyed')) return; | |||
| if (!graphRef.current || !graphRef.current.scrollWidth || !graphRef.current.scrollHeight) | |||
| @@ -29,12 +29,37 @@ | |||
| background: #ffffff; | |||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||
| } | |||
| .drawBox{ | |||
| :global{ | |||
| .ant-drawer .ant-drawer-body{ | |||
| overflow: hidden; | |||
| } | |||
| } | |||
| } | |||
| .experimentDrawer{ | |||
| :global{ | |||
| .ant-tabs >.ant-tabs-nav .ant-tabs-nav-list{ | |||
| margin-left: 24px; | |||
| } | |||
| .ant-drawer .ant-drawer-body{ | |||
| overflow-y: hidden; | |||
| } | |||
| .ant-tabs { | |||
| height: calc(100% - 160px); | |||
| overflow-y: auto; | |||
| } | |||
| } | |||
| } | |||
| .detailBox { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 15px; | |||
| color: #1d1d20; | |||
| font-size: 15px; | |||
| padding-left: 24px; | |||
| } | |||
| .allMessageItem { | |||
| display: flex; | |||
| @@ -12,7 +12,7 @@ import styles from './paramsModal.less'; | |||
| type ParamsModalProps = { | |||
| open: boolean; | |||
| onCancel: () => void; | |||
| globalParam?: PipelineGlobalParam[]; | |||
| globalParam?: PipelineGlobalParam[] | null; | |||
| }; | |||
| function ParamsModal({ open, onCancel, globalParam = [] }: ParamsModalProps) { | |||
| @@ -26,7 +26,7 @@ function ParamsModal({ open, onCancel, globalParam = [] }: ParamsModalProps) { | |||
| cancelButtonProps={{ style: { display: 'none' } }} | |||
| > | |||
| <div className={styles.params_container}> | |||
| {globalParam.map((item) => ( | |||
| {globalParam?.map((item) => ( | |||
| <div key={item.param_name} className={styles.params_container_line}> | |||
| <span className={styles.params_container_line_label}>{getParamType(item)}</span> | |||
| <span className={styles.params_container_line_value}>{item.param_value}</span> | |||
| @@ -386,7 +386,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||
| }, | |||
| })); | |||
| return ( | |||
| <> | |||
| <div className={Styles.drawBox}> | |||
| <Drawer | |||
| title="任务执行详情" | |||
| placement="right" | |||
| @@ -397,9 +397,12 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||
| afterOpenChange={afterOpenChange} | |||
| open={open} | |||
| width={420} | |||
| className={Styles.experimentDrawer} | |||
| destroyOnClose={true} | |||
| > | |||
| <div className={Styles.detailBox}>任务名称:{stagingItem.label}</div> | |||
| <div className={Styles.detailBox} style={{ marginTop: '15px' }}> | |||
| 任务名称:{stagingItem.label} | |||
| </div> | |||
| <div className={Styles.detailBox}> | |||
| 执行状态: | |||
| <div | |||
| @@ -429,7 +432,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||
| </div> | |||
| <Tabs defaultActiveKey="1" items={items} /> | |||
| </Drawer> | |||
| </> | |||
| </div> | |||
| ); | |||
| }); | |||
| @@ -69,6 +69,7 @@ function Experiment() { | |||
| return { ...item, key: item.id }; | |||
| }), | |||
| ); | |||
| setTotal(res.data.totalElements); | |||
| } | |||
| }; | |||
| @@ -82,6 +83,7 @@ function Experiment() { | |||
| // 获取实验实例 | |||
| const getQueryByExperiment = (val) => { | |||
| getQueryByExperimentId(val).then((ret) => { | |||
| console.log(val); | |||
| setExpandedRowKeys(val); | |||
| if (ret && ret.data && ret.data.length > 0) { | |||
| try { | |||
| @@ -159,6 +161,7 @@ function Experiment() { | |||
| }; | |||
| const expandChange = (e, record) => { | |||
| clearExperimentInTimers(); | |||
| console.log(e, record); | |||
| if (record.id === expandedRowKeys) { | |||
| setExpandedRowKeys(null); | |||
| } else { | |||
| @@ -517,6 +520,7 @@ function Experiment() { | |||
| : ''} | |||
| </div> | |||
| ), | |||
| onExpand: (e, a) => { | |||
| expandChange(e, a); | |||
| }, | |||
| @@ -219,6 +219,11 @@ | |||
| border-color: #eaeaea; | |||
| border-radius: 4px; | |||
| cursor: pointer; | |||
| .dropdown{ | |||
| position: absolute; | |||
| right: 20px; | |||
| top: 15px; | |||
| } | |||
| .itemText { | |||
| position: absolute; | |||
| top: 20px; | |||
| @@ -222,8 +222,8 @@ const Dataset = () => { | |||
| <span style={{ color: '#1d1d20', fontSize: '20px' }}>{datasetDetailObj.name}</span> | |||
| <div className={Styles.smallTagBox}> | |||
| <div className={Styles.tagItem}>模型 id:{datasetDetailObj.id}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.data_tag || '...'}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.data_type}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.model_type_name || '...'}</div> | |||
| <div className={Styles.tagItem}>{datasetDetailObj.model_tag_name || '...'}</div> | |||
| </div> | |||
| </div> | |||
| <div className={Styles.datasetIntroCneterBox}> | |||
| @@ -1,10 +1,12 @@ | |||
| import { getAccessToken } from '@/access'; | |||
| import clock from '@/assets/img/clock.png'; | |||
| import creatByImg from '@/assets/img/creatBy.png'; | |||
| import deleteIcon from '@/assets/img/delete-icon.png'; | |||
| import KFIcon from '@/components/KFIcon'; | |||
| import { addModel, getAssetIcon, getModelList } from '@/services/dataset/index.js'; | |||
| import { addModel, deleteModel, getAssetIcon, getModelList } from '@/services/dataset/index.js'; | |||
| import { modalConfirm } from '@/utils/ui'; | |||
| import { UploadOutlined } from '@ant-design/icons'; | |||
| import { Button, Form, Input, Modal, Pagination, Select, Upload } from 'antd'; | |||
| import { Button, Form, Input, Modal, Pagination, Select, Upload, message } from 'antd'; | |||
| import moment from 'moment'; | |||
| import { useEffect, useState } from 'react'; | |||
| import { useNavigate } from 'react-router-dom'; | |||
| @@ -54,8 +56,8 @@ const PublicData = () => { | |||
| }); | |||
| const [activeType, setActiveType] = useState(null); | |||
| const [activeTag, setActiveTag] = useState(null); | |||
| const [datasetTypeList, setDatasetTypeList] = useState([]); | |||
| const [datasetDirectionList, setDatasetDirectionList] = useState([]); | |||
| const [modelTypeList, setmodelTypeList] = useState([]); | |||
| const [modelDirectionList, setmodelDirectionList] = useState([]); | |||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||
| const [datasetList, setDatasetList] = useState([]); | |||
| const [total, setTotal] = useState(0); | |||
| @@ -82,11 +84,11 @@ const PublicData = () => { | |||
| getAssetIcon(params).then((ret) => { | |||
| console.log(ret); | |||
| if (ret.code == 200 && ret.data.content && ret.data.content.length > 0) { | |||
| setDatasetTypeList(ret.data.content.filter((item) => item.category_id == 3)); | |||
| setDatasetDirectionList(ret.data.content.filter((item) => item.category_id == 4)); | |||
| setmodelTypeList(ret.data.content.filter((item) => item.category_id == 3)); | |||
| setmodelDirectionList(ret.data.content.filter((item) => item.category_id == 4)); | |||
| } else { | |||
| setDatasetTypeList([]); | |||
| setDatasetDirectionList([]); | |||
| setmodelTypeList([]); | |||
| setmodelDirectionList([]); | |||
| } | |||
| }); | |||
| }; | |||
| @@ -181,8 +183,8 @@ const PublicData = () => { | |||
| /> | |||
| <div className={Styles.itemTitle}>模型框架</div> | |||
| <div className={Styles.itemBox}> | |||
| {datasetTypeList && datasetTypeList.length > 0 | |||
| ? datasetTypeList.map((item) => { | |||
| {modelTypeList && modelTypeList.length > 0 | |||
| ? modelTypeList.map((item) => { | |||
| return ( | |||
| <div> | |||
| <div | |||
| @@ -222,8 +224,8 @@ const PublicData = () => { | |||
| </div> | |||
| <div className={Styles.itemTitle}>模型能力</div> | |||
| <div className={Styles.itemBox}> | |||
| {datasetDirectionList && datasetDirectionList.length > 0 | |||
| ? datasetDirectionList.map((item) => { | |||
| {modelDirectionList && modelDirectionList.length > 0 | |||
| ? modelDirectionList.map((item) => { | |||
| return ( | |||
| <div> | |||
| <div | |||
| @@ -282,9 +284,80 @@ const PublicData = () => { | |||
| {datasetList && datasetList.length > 0 | |||
| ? datasetList.map((item) => { | |||
| return ( | |||
| <div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}> | |||
| <div | |||
| className={Styles.dataItem} | |||
| onClick={(e) => { | |||
| routeToIntro(e, item); | |||
| }} | |||
| > | |||
| <span className={Styles.itemText}>{item.name}</span> | |||
| <div className={Styles.itemDescripition}>{item.description}</div> | |||
| <img | |||
| onClick={(e) => { | |||
| e.stopPropagation(); | |||
| modalConfirm({ | |||
| title: '确定删除该条模型实例吗?', | |||
| onOk: () => { | |||
| deleteModel(item.id).then((ret) => { | |||
| if (ret.code === 200) { | |||
| message.success('删除成功'); | |||
| getModelLists(queryFlow); | |||
| } else { | |||
| message.error(ret.msg); | |||
| } | |||
| }); | |||
| }, | |||
| }); | |||
| }} | |||
| className={Styles.dropdown} | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| src={deleteIcon} | |||
| alt="" | |||
| /> | |||
| {/* <Dropdown | |||
| className={Styles.dropdown} | |||
| key={item.name} | |||
| menu={{ | |||
| items: [ | |||
| { | |||
| label: '详情', | |||
| key: 'detail', | |||
| }, | |||
| { | |||
| label: '删除', | |||
| key: 'delete', | |||
| }, | |||
| ], | |||
| onClick: (e) => { | |||
| console.log(e); | |||
| if (e.key === 'detail') { | |||
| routeToIntro(e, item); | |||
| } else if (e.key === 'delete') { | |||
| modalConfirm({ | |||
| title: '确定删除该条模型实例吗?', | |||
| onOk: () => { | |||
| deleteModel(item.id).then((ret) => { | |||
| if (ret.code === 200) { | |||
| message.success('删除成功'); | |||
| getModelLists(queryFlow); | |||
| } else { | |||
| message.error(ret.msg); | |||
| } | |||
| }); | |||
| }, | |||
| }); | |||
| } | |||
| }, | |||
| }} | |||
| > | |||
| <div> | |||
| <img | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| src={moreBack} | |||
| alt="" | |||
| /> | |||
| </div> | |||
| </Dropdown> */} | |||
| ,<div className={Styles.itemDescripition}>{item.description}</div> | |||
| <div className={Styles.itemTime}> | |||
| <img | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| @@ -401,7 +474,13 @@ const PublicData = () => { | |||
| ] | |||
| } | |||
| > | |||
| <Select allowClear placeholder="请选择模型类型" options={[]} /> | |||
| <Select | |||
| allowClear | |||
| placeholder="请选择模型类型" | |||
| options={modelTypeList.map((item) => { | |||
| return { value: item.id, label: item.name }; | |||
| })} | |||
| /> | |||
| </Form.Item> | |||
| <Form.Item | |||
| label="模型能力" | |||
| @@ -415,7 +494,13 @@ const PublicData = () => { | |||
| ] | |||
| } | |||
| > | |||
| <Select allowClear placeholder="请选择模型标签" options={[]} /> | |||
| <Select | |||
| allowClear | |||
| placeholder="请选择模型标签" | |||
| options={modelDirectionList.map((item) => { | |||
| return { value: item.id, label: item.name }; | |||
| })} | |||
| /> | |||
| </Form.Item> | |||
| <Form.Item label="模型文件" name="models_version_vos"> | |||
| <Upload {...props} data={{ uuid: uuid }} accept=".zip,.tgz"> | |||
| @@ -1,7 +1,9 @@ | |||
| import clock from '@/assets/img/clock.png'; | |||
| import creatByImg from '@/assets/img/creatBy.png'; | |||
| import { getAssetIcon, getModelList } from '@/services/dataset/index.js'; | |||
| import { Form, Input, Modal, Pagination, Radio } from 'antd'; | |||
| import deleteIcon from '@/assets/img/delete-icon.png'; | |||
| import { deleteModel, getAssetIcon, getModelList } from '@/services/dataset/index.js'; | |||
| import { modalConfirm } from '@/utils/ui'; | |||
| import { Form, Input, Modal, Pagination, Radio, message } from 'antd'; | |||
| import moment from 'moment'; | |||
| import { useEffect, useState } from 'react'; | |||
| import { useNavigate } from 'react-router-dom'; | |||
| @@ -224,8 +226,35 @@ const PublicData = () => { | |||
| {datasetList && datasetList.length > 0 | |||
| ? datasetList.map((item) => { | |||
| return ( | |||
| <div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}> | |||
| <div | |||
| className={Styles.dataItem} | |||
| onClick={(e) => { | |||
| routeToIntro(e, item); | |||
| }} | |||
| > | |||
| <span className={Styles.itemText}>{item.name}</span> | |||
| <img | |||
| onClick={(e) => { | |||
| e.stopPropagation(); | |||
| modalConfirm({ | |||
| title: '确定删除该条模型实例吗?', | |||
| onOk: () => { | |||
| deleteModel(item.id).then((ret) => { | |||
| if (ret.code === 200) { | |||
| message.success('删除成功'); | |||
| getModelLists(queryFlow); | |||
| } else { | |||
| message.error(ret.msg); | |||
| } | |||
| }); | |||
| }, | |||
| }); | |||
| }} | |||
| className={Styles.dropdown} | |||
| style={{ width: '17px', marginRight: '6px' }} | |||
| src={deleteIcon} | |||
| alt="" | |||
| /> | |||
| <div className={Styles.itemDescripition}>{item.description}</div> | |||
| <div className={Styles.itemTime}> | |||
| <img | |||
| @@ -14,7 +14,7 @@ import styles from './globalParamsDrawer.less'; | |||
| type GlobalParamsDrawerProps = { | |||
| open: boolean; | |||
| onClose: () => void; | |||
| globalParam: PipelineGlobalParam[]; | |||
| globalParam: PipelineGlobalParam[] | null; | |||
| }; | |||
| const GlobalParamsDrawer = forwardRef( | |||
| @@ -128,18 +128,7 @@ const EditPipeline = () => { | |||
| }; | |||
| const handlerClick = (e) => { | |||
| e.stopPropagation(); | |||
| console.log(propsRef, graph); | |||
| // let cache = []; | |||
| // let json_str = JSON.stringify(graph, function(key, value) { | |||
| // if (typeof value === 'object' && value !== null) { | |||
| // if (cache.indexOf(value) !== -1) { | |||
| // return; | |||
| // } | |||
| // cache.push(value); | |||
| // } | |||
| // return value; | |||
| // }); | |||
| // console.log(json_str); | |||
| // console.log(propsRef, graph); | |||
| propsRef.current.showDrawer(e); | |||
| }; | |||
| const getGraphData = (data) => { | |||
| @@ -281,7 +270,7 @@ const EditPipeline = () => { | |||
| const getFirstWorkflow = (val) => { | |||
| getWorkflowById(val).then((ret) => { | |||
| if (ret && ret.data) { | |||
| setGlobalParam(ret.data.global_param); | |||
| setGlobalParam(ret.data.global_param || []); | |||
| } | |||
| if (graph && ret.data && ret.data.dag) { | |||
| getGraphData(JSON.parse(ret.data.dag)); | |||
| @@ -353,7 +342,7 @@ const EditPipeline = () => { | |||
| // this.graph.setItemState(e.item, 'showAnchors', false); | |||
| graph.setItemState(e.item, 'nodeSelected', false); | |||
| }); | |||
| graph.off('dblclick', handlerClick); | |||
| // graph.off('dblclick', handlerClick); | |||
| }; | |||
| }, []); | |||
| const initGraph = () => { | |||
| @@ -390,30 +379,15 @@ const EditPipeline = () => { | |||
| getAnchorPoints(cfg) { | |||
| return ( | |||
| cfg.anchorPoints || [ | |||
| // 上下各3,左右各1 | |||
| [0.5, 0], | |||
| [0.5, 1], | |||
| // 四个 | |||
| // [0.5, 0], | |||
| // [0.5, 1], | |||
| [0, 0.5], | |||
| [1, 0.5], | |||
| ] | |||
| ); | |||
| }, | |||
| // draw(cfg, group) { | |||
| // let rect=group.addShape('text', { | |||
| // attrs: { | |||
| // text: fittingString(cfg.label, 110, 15), | |||
| // x: 90 - getTextSize(cfg.label, 110, 15), | |||
| // y: 0, | |||
| // fontSize: 10, | |||
| // textAlign: 'center', | |||
| // textBaseline: 'middle', | |||
| // fill:'#000' | |||
| // }, | |||
| // name: 'text-shape', | |||
| // }); | |||
| // return rect; | |||
| // }, | |||
| afterDraw(cfg, group) { | |||
| // console.log(group, cfg, 12312); | |||
| const image = group.addShape('image', { | |||
| attrs: { | |||
| x: -45, | |||
| @@ -442,7 +416,6 @@ const EditPipeline = () => { | |||
| } | |||
| const bbox = group.getBBox(); | |||
| const anchorPoints = this.getAnchorPoints(cfg); | |||
| // console.log(anchorPoints); | |||
| anchorPoints.forEach((anchorPos, i) => { | |||
| group.addShape('circle', { | |||
| attrs: { | |||
| @@ -456,6 +429,7 @@ const EditPipeline = () => { | |||
| anchorPointIdx: i, // flag the idx of the anchor-point circle | |||
| links: 0, // cache the number of edges connected to this shape | |||
| visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state | |||
| draggable: true, | |||
| }); | |||
| }); | |||
| return image; | |||
| @@ -503,7 +477,7 @@ const EditPipeline = () => { | |||
| // config the shouldBegin and shouldEnd to make sure the create-edge is began and ended at anchor-point circles | |||
| { | |||
| type: 'create-edge', | |||
| // trigger: 'drag', | |||
| trigger: 'drag', | |||
| shouldBegin: (e) => { | |||
| // avoid beginning at other shapes on the node | |||
| if (e.target && e.target.get('name') !== 'anchor-point') return false; | |||
| @@ -575,7 +549,7 @@ const EditPipeline = () => { | |||
| }, | |||
| defaultEdge: { | |||
| // type: 'quadratic', | |||
| type: 'cubic-vertical', | |||
| // type: 'cubic-vertical', | |||
| style: { | |||
| endArrow: { | |||
| @@ -619,16 +593,20 @@ const EditPipeline = () => { | |||
| fitView: true, | |||
| fitViewPadding: [320, 320, 220, 320], | |||
| }); | |||
| graph.on('dblclick', (e) => { | |||
| console.log(e.item); | |||
| if (e.item) { | |||
| // graph.on('dblclick', (e) => { | |||
| // console.log(e.item); | |||
| // if (e.item) { | |||
| // graph.setItemState(e.item, 'nodeClicked', true); | |||
| // handlerClick(e); | |||
| // } | |||
| // }); | |||
| graph.on('node:click', (e) => { | |||
| console.log(e.target.get('name')); | |||
| if (e.target.get('name') !== 'anchor-point' && e.item) { | |||
| graph.setItemState(e.item, 'nodeClicked', true); | |||
| handlerClick(e); | |||
| } | |||
| }); | |||
| graph.on('click', (e) => { | |||
| console.log(e.item); | |||
| }); | |||
| graph.on('aftercreateedge', (e) => { | |||
| // update the sourceAnchor and targetAnchor for the newly added edge | |||
| graph.updateItem(e.edge, { | |||
| @@ -666,6 +644,39 @@ const EditPipeline = () => { | |||
| }, | |||
| }); | |||
| }); | |||
| graph.on('node:dragenter', (e) => { | |||
| console.log(e.target.get('name')); | |||
| console.log('node:dragenter'); | |||
| graph.setItemState(e.item, 'nodeSelected', true); | |||
| graph.updateItem(e.item, { | |||
| // 节点的样式 | |||
| style: { | |||
| stroke: '#1664ff', | |||
| }, | |||
| }); | |||
| }); | |||
| graph.on('node:dragleave', (e) => { | |||
| console.log(e.target.get('name')); | |||
| console.log('node:dragleave'); | |||
| graph.setItemState(e.item, 'nodeSelected', false); | |||
| graph.updateItem(e.item, { | |||
| // 节点的样式 | |||
| style: { | |||
| stroke: 'transparent', | |||
| }, | |||
| }); | |||
| }); | |||
| graph.on('node:dragstart', (e) => { | |||
| console.log('node:dragstart'); | |||
| graph.setItemState(e.item, 'nodeSelected', true); | |||
| graph.updateItem(e.item, { | |||
| // 节点的样式 | |||
| style: { | |||
| stroke: '#1664ff', | |||
| }, | |||
| }); | |||
| }); | |||
| graph.on('afterremoveitem', (e) => { | |||
| if (e.item && e.item.source && e.item.target) { | |||
| const sourceNode = graph.findById(e.item.source); | |||
| @@ -118,3 +118,15 @@ export function exportDataset(id) { | |||
| method: 'GET', | |||
| }); | |||
| } | |||
| // 删除模型集 | |||
| export function deleteModel(id) { | |||
| return request(`/api/mmp/models/${id}`, { | |||
| method: 'DELETE', | |||
| }); | |||
| } | |||
| // 删除数据集 | |||
| export function deleteDataset(id) { | |||
| return request(`/api/mmp/dataset/${id}`, { | |||
| method: 'DELETE', | |||
| }); | |||
| } | |||
| @@ -17,7 +17,9 @@ import org.springframework.scheduling.annotation.EnableScheduling; | |||
| @EnableRyFeignClients | |||
| @SpringBootApplication | |||
| @EnableScheduling | |||
| public class RuoYiManagementPlatformApplication { | |||
| public class | |||
| RuoYiManagementPlatformApplication { | |||
| public static void main(String[] args) { | |||
| SpringApplication.run(RuoYiManagementPlatformApplication.class, args); | |||
| System.out.println("(♥◠‿◠)ノ゙ 复杂智能软件管理平台启动成功 ლ(´ڡ`ლ)゙ \n" + | |||
| @@ -158,7 +158,7 @@ public class DatasetController { | |||
| */ | |||
| @DeleteMapping({"{id}"}) | |||
| @ApiOperation("根据id删除数据集") | |||
| public AjaxResult deleteById(@PathVariable("id") Integer id) { | |||
| public AjaxResult deleteById(@PathVariable("id") Integer id) throws Exception { | |||
| return AjaxResult.success(this.datasetService.removeById(id)); | |||
| } | |||
| @@ -161,7 +161,7 @@ public class ModelsController extends BaseController { | |||
| */ | |||
| @DeleteMapping("{id}") | |||
| @ApiOperation("删除模型") | |||
| public GenericsAjaxResult<String> deleteById(@PathVariable("id") Integer id) { | |||
| public GenericsAjaxResult<String> deleteById(@PathVariable("id") Integer id) throws Exception { | |||
| return genericsSuccess(this.modelsService.removeById(id)); | |||
| } | |||
| @@ -19,8 +19,8 @@ public class AssetIcon implements Serializable { | |||
| /** | |||
| * 主键 | |||
| */ | |||
| @ApiModelProperty(value = "资产ID") | |||
| private Integer id; | |||
| @ApiModelProperty(value = "资产ID") | |||
| private Integer id; | |||
| @ApiModelProperty(value = "资产图标名称") | |||
| private String name; | |||
| @@ -76,6 +76,13 @@ public class Dataset implements Serializable { | |||
| @ApiModelProperty(value = "状态:0失效,1生效") | |||
| private Integer state; | |||
| @ApiModelProperty(value = "数据集类型名字") | |||
| private String datasetTypeName; | |||
| @ApiModelProperty(value = "数据集tag名字") | |||
| private String datasetTagName; | |||
| public Integer getId() { | |||
| return id; | |||
| @@ -165,5 +172,21 @@ public class Dataset implements Serializable { | |||
| this.state = state; | |||
| } | |||
| public String getDatasetTypeName() { | |||
| return datasetTypeName; | |||
| } | |||
| public String getDatasetTagName() { | |||
| return datasetTagName; | |||
| } | |||
| public void setDatasetTagName(String datasetTagName) { | |||
| this.datasetTagName = datasetTagName; | |||
| } | |||
| public void setDatasetTypeName(String datasetTypeName) { | |||
| this.datasetTypeName = datasetTypeName; | |||
| } | |||
| } | |||
| @@ -118,7 +118,7 @@ public class Image implements Serializable { | |||
| this.updateTime = updateTime; | |||
| } | |||
| // Getter 和 Setter | |||
| public Integer getVersionCount() { | |||
| return versionCount; | |||
| } | |||
| @@ -52,6 +52,16 @@ public class Models implements Serializable { | |||
| private Integer state; | |||
| @ApiModelProperty(value = "模型类型名") | |||
| private String modelTypeName; | |||
| @ApiModelProperty(value = "模型tag名") | |||
| private String modelTagName; | |||
| public Integer getId() { | |||
| return id; | |||
| } | |||
| @@ -158,5 +168,21 @@ public class Models implements Serializable { | |||
| this.state = state; | |||
| } | |||
| public String getModelTagName() { | |||
| return modelTagName; | |||
| } | |||
| public void setModelTagName(String modelTagName) { | |||
| this.modelTagName = modelTagName; | |||
| } | |||
| public String getModelTypeName() { | |||
| return modelTypeName; | |||
| } | |||
| public void setModelTypeName(String modelTypeName) { | |||
| this.modelTypeName = modelTypeName; | |||
| } | |||
| } | |||
| @@ -84,5 +84,6 @@ public interface AssetIconDao { | |||
| List<AssetIcon> queryByCategoryId(Integer categoryId); | |||
| AssetIcon queryByPath(String path); | |||
| } | |||
| @@ -22,6 +22,15 @@ public interface AssetIconService { | |||
| */ | |||
| AssetIcon queryById(Integer id); | |||
| /** | |||
| * 通过path查询单条数据 | |||
| * | |||
| * @param path 路径 | |||
| * @return 实例对象 | |||
| */ | |||
| AssetIcon queryByPath(String path); | |||
| /** | |||
| * 分页查询 | |||
| * | |||
| @@ -68,7 +68,7 @@ DatasetService { | |||
| */ | |||
| boolean deleteById(Integer id); | |||
| String removeById(Integer id); | |||
| String removeById(Integer id) throws Exception; | |||
| ResponseEntity<InputStreamResource> downloadDataset(Integer id) throws Exception; | |||
| @@ -64,7 +64,7 @@ public interface ModelsService { | |||
| */ | |||
| boolean deleteById(Integer id); | |||
| String removeById(Integer id); | |||
| String removeById(Integer id) throws Exception; | |||
| ResponseEntity<InputStreamResource> downloadModels(Integer id) throws Exception; | |||
| @@ -2,7 +2,6 @@ package com.ruoyi.platform.service.impl; | |||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||
| import com.ruoyi.platform.domain.AssetIcon; | |||
| import com.ruoyi.platform.domain.Models; | |||
| import com.ruoyi.platform.mapper.AssetIconDao; | |||
| import com.ruoyi.platform.service.AssetIconService; | |||
| import com.ruoyi.system.api.model.LoginUser; | |||
| @@ -38,6 +37,12 @@ public class AssetIconServiceImpl implements AssetIconService { | |||
| return this.assetIconDao.queryById(id); | |||
| } | |||
| @Override | |||
| public AssetIcon queryByPath(String path) { | |||
| return this.assetIconDao.queryByPath(path); | |||
| } | |||
| /** | |||
| * 分页查询 | |||
| * | |||
| @@ -125,4 +130,6 @@ public class AssetIconServiceImpl implements AssetIconService { | |||
| public List<AssetIcon> queryByCategoryId(Integer categoryId) { | |||
| return this.assetIconDao.queryByCategoryId(categoryId); | |||
| } | |||
| } | |||
| @@ -3,10 +3,12 @@ package com.ruoyi.platform.service.impl; | |||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||
| import com.ruoyi.platform.annotations.CheckDuplicate; | |||
| import com.ruoyi.platform.domain.AssetIcon; | |||
| import com.ruoyi.platform.domain.Dataset; | |||
| import com.ruoyi.platform.domain.DatasetVersion; | |||
| import com.ruoyi.platform.mapper.DatasetDao; | |||
| import com.ruoyi.platform.mapper.DatasetVersionDao; | |||
| import com.ruoyi.platform.service.AssetIconService; | |||
| import com.ruoyi.platform.service.DatasetService; | |||
| import com.ruoyi.platform.service.DatasetVersionService; | |||
| import com.ruoyi.platform.service.MinioService; | |||
| @@ -58,6 +60,9 @@ public class DatasetServiceImpl implements DatasetService { | |||
| @Resource | |||
| private DatasetVersionService datasetVersionService; | |||
| @Resource | |||
| private AssetIconService assetIconService; | |||
| @Resource | |||
| private MinioService minioService; | |||
| @@ -77,7 +82,27 @@ public class DatasetServiceImpl implements DatasetService { | |||
| */ | |||
| @Override | |||
| public Dataset queryById(Integer id) { | |||
| return this.datasetDao.queryById(id); | |||
| Dataset dataset = this.datasetDao.queryById(id); | |||
| if (dataset != null) { | |||
| String dataType = dataset.getDataType(); | |||
| String dataTag = dataset.getDataTag(); | |||
| // 判空逻辑,只有当dataType和dataTag不为空时,才进行查询 | |||
| if (dataType != null && !dataType.isEmpty()) { | |||
| AssetIcon dataTypeAssetIcon = assetIconService.queryById(Integer.valueOf(dataType)); | |||
| if (dataTypeAssetIcon != null) { | |||
| dataset.setDatasetTypeName(dataTypeAssetIcon.getName()); | |||
| } | |||
| } | |||
| if (dataTag != null && !dataTag.isEmpty()) { | |||
| AssetIcon dataTagAssetIcon = assetIconService.queryById(Integer.valueOf(dataTag)); | |||
| if (dataTagAssetIcon != null) { | |||
| dataset.setDatasetTagName(dataTagAssetIcon.getName()); | |||
| } | |||
| } | |||
| } | |||
| return dataset; | |||
| } | |||
| /** | |||
| @@ -146,10 +171,10 @@ public class DatasetServiceImpl implements DatasetService { | |||
| } | |||
| @Override | |||
| public String removeById(Integer id) { | |||
| public String removeById(Integer id) throws Exception { | |||
| Dataset dataset = this.datasetDao.queryById(id); | |||
| if (dataset == null){ | |||
| return "数据集不存在"; | |||
| throw new Exception("数据集不存在"); | |||
| } | |||
| //判断权限,只有admin和创建者本身可以删除该数据集 | |||
| @@ -157,10 +182,10 @@ public class DatasetServiceImpl implements DatasetService { | |||
| String username = loginUser.getUsername(); | |||
| String createdBy = dataset.getCreateBy(); | |||
| if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){ | |||
| return "无权限删除该数据集版本"; | |||
| throw new Exception("无权限删除该数据集"); | |||
| } | |||
| if (datasetVersionService.queryByDatasetId(id).size()>0){ | |||
| return "请先删除该数据集的版本文件"; | |||
| throw new Exception("请先删除该数据集下的版本文件"); | |||
| } | |||
| dataset.setState(0); | |||
| @@ -316,6 +316,7 @@ public class ImageServiceImpl implements ImageService { | |||
| String filePath = "/data/argo-workflow/" + bucketName + "/" +path; | |||
| String logs2 = k8sClientUtil.executeCommand(pod,"docker load -i "+filePath); | |||
| // 在容器里执行 docker tag name:tag nexus3.kube-system.svc:8083/imageName:imageTag | |||
| if (StringUtils.isNoneBlank(logs2)){ | |||
| String substring = logs2.substring(logs2.indexOf(":")+1).trim(); | |||
| String tagCmd = "docker tag " + substring + " " + harborUrl + "/" + repository + "/" + username + "/" + imageName + ":" + imageTag; | |||
| @@ -1,10 +1,12 @@ | |||
| package com.ruoyi.platform.service.impl; | |||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||
| import com.ruoyi.platform.domain.AssetIcon; | |||
| import com.ruoyi.platform.domain.Models; | |||
| import com.ruoyi.platform.domain.ModelsVersion; | |||
| import com.ruoyi.platform.mapper.ModelsDao; | |||
| import com.ruoyi.platform.mapper.ModelsVersionDao; | |||
| import com.ruoyi.platform.service.AssetIconService; | |||
| import com.ruoyi.platform.service.MinioService; | |||
| import com.ruoyi.platform.service.ModelsService; | |||
| import com.ruoyi.platform.service.ModelsVersionService; | |||
| @@ -57,6 +59,9 @@ public class ModelsServiceImpl implements ModelsService { | |||
| @Resource | |||
| private MinioService minioService; | |||
| @Resource | |||
| private AssetIconService assetIconService; | |||
| // 固定存储桶名 | |||
| private final String bucketName = "platform-data"; | |||
| @@ -72,7 +77,23 @@ public class ModelsServiceImpl implements ModelsService { | |||
| */ | |||
| @Override | |||
| public Models queryById(Integer id) { | |||
| return this.modelsDao.queryById(id); | |||
| Models models = this.modelsDao.queryById(id); | |||
| String modelType = models.getModelType(); | |||
| String modelTag = models.getModelTag(); | |||
| //去资产管理表中查询对应的图标名,注意判空逻辑,只有当dataType和dataTag不为空时,才进行查询 | |||
| if(modelType != null && !modelType.isEmpty()){ | |||
| AssetIcon modelTypeAssetIcon = assetIconService.queryById(Integer.valueOf(modelType)); | |||
| if (modelTypeAssetIcon != null){ | |||
| models.setModelTypeName(modelTypeAssetIcon.getName()); | |||
| } | |||
| } | |||
| if(modelTag != null && !modelTag.isEmpty()){ | |||
| AssetIcon modelTagAssetIcon = assetIconService.queryById(Integer.valueOf(modelTag)); | |||
| if (modelTagAssetIcon != null){ | |||
| models.setModelTagName(modelTagAssetIcon.getName()); | |||
| } | |||
| } | |||
| return models; | |||
| } | |||
| /** | |||
| @@ -137,23 +158,23 @@ public class ModelsServiceImpl implements ModelsService { | |||
| } | |||
| @Override | |||
| public String removeById(Integer id) { | |||
| public String removeById(Integer id) throws Exception { | |||
| Models models = this.modelsDao.queryById(id); | |||
| if (models == null){ | |||
| return "模型不存在"; | |||
| throw new Exception("模型不存在"); | |||
| } | |||
| //判断权限,只有admin和创建者本身可以删除该数据集 | |||
| //判断权限,只有admin和创建者本身可以删除该模型 | |||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||
| String username = loginUser.getUsername(); | |||
| String createdBy = models.getCreateBy(); | |||
| if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){ | |||
| return "无权限删除该模型"; | |||
| throw new Exception("无权限删除该模型"); | |||
| } | |||
| if (modelsVersionService.queryByModelsId(id).size()>0){ | |||
| return "请先删除该模型的版本文件"; | |||
| throw new Exception("请先删除该镜像下的版本文件"); | |||
| } | |||
| models.setState(0); | |||
| return this.modelsDao.update(models)>0?"删除成功":"删除失败"; | |||
| @@ -207,7 +228,6 @@ public class ModelsServiceImpl implements ModelsService { | |||
| */ | |||
| @Override | |||
| public List<Map<String, String>> uploadModels(MultipartFile[] files, String uuid) throws Exception { | |||
| List<Map<String, String>> results = new ArrayList<>(); | |||
| for (MultipartFile file:files) { | |||
| // 构建objectName | |||
| @@ -232,7 +252,6 @@ public class ModelsServiceImpl implements ModelsService { | |||
| ModelsVersion version = modelsVersionService.queryByModelsVersion(modelsVersion); | |||
| String url = ""; | |||
| if (version == null) { | |||
| //插表,因为这里是一次直接插表所以这里定掉date,然后用DAO插入 | |||
| @@ -43,6 +43,13 @@ | |||
| </where> | |||
| </select> | |||
| <select id="queryByPath" resultMap="AssetIconMap" > | |||
| select | |||
| id, name,category_id, path, description, create_by, create_time, update_by, update_time, state | |||
| from asset_icon | |||
| where path = #{path} and state = 1 | |||
| </select> | |||
| <select id="queryAllByLimit" resultMap="AssetIconMap"> | |||
| select | |||
| id, name, category_id, path, description, create_by, create_time, update_by, update_time, state | |||
| @@ -123,6 +130,7 @@ | |||
| </where> | |||
| </select> | |||
| <insert id="insert" keyProperty="id" useGeneratedKeys="true"> | |||
| insert into asset_icon(name, category_id, path, description, create_by, create_time, update_by, update_time, state) | |||
| values (#{assetIcon.name}, #{assetIcon.categoryId}, #{assetIcon.path}, #{assetIcon.description}, #{assetIcon.createBy}, #{assetIcon.createTime}, #{assetIcon.updateBy}, #{assetIcon.updateTime}, #{assetIcon.state}) | |||
| @@ -152,13 +152,13 @@ | |||
| description = #{dataset.description}, | |||
| </if> | |||
| <if test="dataset.availableRange != null and dataset.availableRange != ''"> | |||
| available_range = #{dataset.availableRange} | |||
| </if>, | |||
| available_range = #{dataset.availableRange}, | |||
| </if> | |||
| <if test="dataset.dataType != null"> | |||
| data_type = #{dataset.dataType}, | |||
| </if> | |||
| <if test="dataset.dataTag != null"> | |||
| data_tag = #{dataset.dataTag} | |||
| data_tag = #{dataset.dataTag}, | |||
| </if> | |||
| <if test="dataset.createBy != null and dataset.createBy != ''"> | |||
| create_by = #{dataset.createBy}, | |||
| @@ -179,6 +179,7 @@ | |||
| where id = #{dataset.id} | |||
| </update> | |||
| <!--通过主键删除--> | |||
| <delete id="deleteById"> | |||
| delete from dataset where id = #{id} | |||
| @@ -154,7 +154,7 @@ | |||
| description = #{models.description}, | |||
| </if> | |||
| <if test="models.availableRange != null and models.availableRange != ''"> | |||
| available_range = #{models.availableRange} | |||
| available_range = #{models.availableRange}, | |||
| </if> | |||
| <if test="models.modelType != null"> | |||
| model_type = #{models.modelType}, | |||