diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx index aa6349d8..69648b49 100644 --- a/react-ui/src/pages/Experiment/index.jsx +++ b/react-ui/src/pages/Experiment/index.jsx @@ -198,7 +198,7 @@ function Experiment() { }; const routeToEdit = (e, record) => { e.stopPropagation(); - navgite({ pathname: `/pipeline/template/${record.workflow_id}/${record.workflow_name}` }); + navgite({ pathname: `/pipeline/template/${record.workflow_id}` }); }; // 创建或者编辑实验接口请求 const handleAddExperiment = async (values) => { diff --git a/react-ui/src/pages/Experiment/training/index.jsx b/react-ui/src/pages/Experiment/training/index.jsx index 6cbabfe0..991e9855 100644 --- a/react-ui/src/pages/Experiment/training/index.jsx +++ b/react-ui/src/pages/Experiment/training/index.jsx @@ -23,24 +23,12 @@ function ExperimentText() { const [paramsModalOpen, openParamsModal, closeParamsModal] = useVisible(false); const graphRef = useRef(); - // const onDragEnd = (val) => { - // console.log(val, 'eee'); - // const _x = val.x; - // const _y = val.y; - // const point = graph.getPointByClient(_x, _y); - // let model = {}; - // // 元模型 - // model = { - // ...val, - // x: point.x, - // y: point.y, - // id: val.component_name + '-' + s8(), - // isCluster: false, - // }; - // graph.addItem('node', model, true); - // }; const getGraphData = (data) => { if (graph) { + // 修改历史数据有蓝色边框的问题 + data.nodes.forEach((item) => { + item.style.stroke = '#fff'; + }); graph.data(data); graph.render(); } else { @@ -92,9 +80,11 @@ function ExperimentText() { getAnchorPoints(cfg) { return ( cfg.anchorPoints || [ - // 上下各3,左右各1 + // 四个,上下左右 [0.5, 0], [0.5, 1], + [0, 0.5], + [1, 0.5], ] ); }, @@ -120,6 +110,7 @@ function ExperimentText() { textAlign: 'left', textBaseline: 'middle', fill: '#000', + cursor: 'pointer', }, name: 'text-shape', draggable: true, @@ -166,8 +157,12 @@ function ExperimentText() { width: graphRef.current.clientWidth || 500, height: graphRef.current.clientHeight || 760, animate: false, - groupByTypes: false, - enabledStack: true, + groupByTypes: true, + enabledStack: false, + fitView: true, + minZoom: 0.5, + maxZoom: 5, + fitViewPadding: 300, modes: { default: [ // config the shouldBegin for drag-node to avoid node moving while dragging on the anchor-point circles @@ -181,15 +176,6 @@ function ExperimentText() { // config the shouldBegin and shouldEnd to make sure the create-edge is began and ended at anchor-point circles 'drag-canvas', 'zoom-canvas', - // 'brush-select', - 'drag-combo', - ], - altSelect: [ - { - type: 'brush-select', - trigger: 'drag', - }, - 'drag-node', ], }, @@ -217,7 +203,7 @@ function ExperimentText() { }, defaultEdge: { // type: 'quadratic', - type: 'cubic-vertical', + // type: 'cubic-vertical', style: { endArrow: { @@ -232,15 +218,8 @@ function ExperimentText() { stroke: '#a2a6b5', radius: 1, }, - nodeStateStyle: { - hover: { - opacity: 1, - stroke: '#8fe8ff', - }, - }, labelCfg: { autoRotate: true, - // refY: 10, style: { fontSize: 10, fill: '#FFF', @@ -257,11 +236,6 @@ function ExperimentText() { cursor: 'pointer', }, }, - // linkCenter: true, - fitView: true, - minZoom: 0.5, - maxZoom: 5, - fitViewPadding: 300, }); graph.on('node:click', (e) => { if (e.target.get('name') !== 'anchor-point' && e.item) { diff --git a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx index bd8286cf..6a6e74e8 100644 --- a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx +++ b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx @@ -12,7 +12,14 @@ import GraphLegend from '../GraphLegend'; import NodeTooltips from '../NodeTooltips'; import styles from './index.less'; import type { ModelDepsData, ProjectDependency, TrainDataset } from './utils'; -import { NodeType, getGraphData, nodeHeight, nodeWidth, normalizeTreeData } from './utils'; +import { + NodeType, + getGraphData, + nodeFontSize, + nodeHeight, + nodeWidth, + normalizeTreeData, +} from './utils'; type modeModelEvolutionProps = { resourceId: number; @@ -73,7 +80,7 @@ function ModelEvolution({ width: graphRef.current!.clientWidth, height: graphRef.current!.clientHeight, fitView: true, - fitViewPadding: [50, 100, 50, 100], + fitViewPadding: [100, 100, 100, 100], minZoom: 0.5, maxZoom: 5, defaultNode: { @@ -95,7 +102,7 @@ function ModelEvolution({ position: 'center', style: { fill: '#ffffff', - fontSize: 8, + fontSize: nodeFontSize, textAlign: 'center', cursor: 'pointer', }, @@ -107,7 +114,7 @@ function ModelEvolution({ autoRotate: true, }, style: { - stroke: '#a2c1ff', + stroke: '#DEE0E5', lineWidth: 1, }, }, @@ -163,28 +170,32 @@ function ModelEvolution({ graph.on('node:click', (e: G6GraphEvent) => { const nodeItem = e.item; - const model = nodeItem.getModel(); + const model = nodeItem.getModel() as ModelDepsData | ProjectDependency | TrainDataset; const { model_type } = model; const { origin } = location; let url: string = ''; switch (model_type) { case NodeType.children: case NodeType.parent: { - const { current_model_id, version } = model as ModelDepsData; + const { current_model_id, version } = model; url = `${origin}/dataset/model/${current_model_id}?tab=${ResourceInfoTabKeys.Evolution}&version=${version}`; break; } case NodeType.project: { - const { url: projectUrl } = model as ProjectDependency; + const { url: projectUrl } = model; url = projectUrl; break; } case NodeType.trainDataset: case NodeType.testDataset: { - const { dataset_id, dataset_version } = model as TrainDataset; + const { dataset_id, dataset_version } = model; url = `${origin}/dataset/dataset/${dataset_id}?tab=${ResourceInfoTabKeys.Version}&version=${dataset_version}`; break; } + case NodeType.current: { + // TODO: 隐藏数据集和项目 + break; + } default: break; } diff --git a/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx b/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx index 78fdb87a..3c3f4225 100644 --- a/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx +++ b/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx @@ -6,8 +6,10 @@ import Hierarchy from '@antv/hierarchy'; export const nodeWidth = 110; export const nodeHeight = 50; export const vGap = nodeHeight + 20; -export const hGap = nodeHeight + 20; +export const hGap = nodeWidth; export const ellipseWidth = nodeWidth; +export const labelPadding = 30; +export const nodeFontSize = 8; // 数据集节点 const datasetNodes: NodeConfig[] = []; @@ -38,14 +40,14 @@ export interface TrainDataset extends NodeConfig { dataset_id: number; dataset_name: string; dataset_version: string; - model_type: NodeType; + model_type: NodeType.testDataset | NodeType.trainDataset; } export interface ProjectDependency extends NodeConfig { url: string; name: string; branch: string; - model_type: NodeType; + model_type: NodeType.project; } export type ModalDetail = { @@ -63,7 +65,7 @@ export interface ModelDepsAPIData { current_model_id: number; version: string; exp_ins_id: number; - model_type: NodeType; + model_type: NodeType.children | NodeType.current | NodeType.parent; current_model_name: string; project_dependency: ProjectDependency; test_dataset: TrainDataset[]; @@ -94,9 +96,13 @@ export function normalizeChildren(data: ModelDepsData[]) { // 获取 label export function getLabel(node: ModelDepsData | ModelDepsAPIData) { return ( - fittingString(`${node.model_version_dependcy_vo.name ?? ''}`, nodeWidth - 12, 8) + + fittingString( + `${node.model_version_dependcy_vo.name ?? ''}`, + nodeWidth - labelPadding, + nodeFontSize, + ) + '\n' + - fittingString(`${node.version}`, nodeWidth - 12, 8) + fittingString(`${node.version}`, nodeWidth - labelPadding, nodeFontSize) ); } @@ -231,12 +237,12 @@ const addDatasetDependency = ( node.type = 'ellipse'; node.size = [ellipseWidth, nodeHeight]; node.label = - fittingString(node.dataset_name, ellipseWidth - 12, 8) + + fittingString(node.dataset_name, ellipseWidth - labelPadding, nodeFontSize) + '\n' + - fittingString(node.dataset_version, ellipseWidth - 12, 8); + fittingString(node.dataset_version, ellipseWidth - labelPadding, nodeFontSize); const half = len / 2 - 0.5; - node.x = currentNode.x! - (half - index) * (ellipseWidth + hGap / 2); + node.x = currentNode.x! - (half - index) * (ellipseWidth + 20); node.y = currentNode.y! - nodeHeight - vGap; nodes.push(node); datasetNodes.push(node); @@ -263,7 +269,7 @@ const addProjectDependency = ( node.id = `$P_${node.url}_${node.branch}`; node.model_type = NodeType.project; node.type = 'rect'; - node.label = fittingString(node.name, nodeWidth - 12, 8); + node.label = fittingString(node.name, nodeWidth - labelPadding, nodeFontSize); node.style = getStyle(NodeType.project); node.style.radius = nodeHeight / 2; node.x = currentNode.x; @@ -311,15 +317,13 @@ function adjustDatasetPosition(node: NodeConfig) { }; const overlapRect = isChildrenOverlapDataset(datasetNodes, nodeRect); if (overlapRect) { - console.log(node); - const adjustRect = { x: overlapRect.x - nodeWidth - hGap / 2, y: overlapRect.y, width: overlapRect.width, height: overlapRect.height, }; - const lastNode = datasetNodes[datasetNodes.length - 1] as NodeConfig; + const lastNode = datasetNodes[datasetNodes.length - 1]; const distance = lastNode.x! - adjustRect.x; datasetNodes.forEach((item) => { item.x = item.x! - distance; diff --git a/react-ui/src/pages/Model/components/NodeTooltips/index.tsx b/react-ui/src/pages/Model/components/NodeTooltips/index.tsx index dc926114..a4b3f13b 100644 --- a/react-ui/src/pages/Model/components/NodeTooltips/index.tsx +++ b/react-ui/src/pages/Model/components/NodeTooltips/index.tsx @@ -118,14 +118,18 @@ function ProjectInfo({ data }: { data: ProjectDependency }) { function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsProps) { if (!data) return null; - let Component; + let Component = null; const { model_type } = data; if (model_type === NodeType.testDataset || model_type === NodeType.trainDataset) { - Component = ; + Component = ; } else if (model_type === NodeType.project) { - Component = ; - } else { - Component = ; + Component = ; + } else if ( + model_type === NodeType.children || + model_type === NodeType.parent || + model_type === NodeType.current + ) { + Component = ; } return (
{ const [paramsDrawerOpen, openParamsDrawer, closeParamsDrawer] = useVisible(false); const [globalParam, setGlobalParam, globalParamRef] = useStateRef([]); const { message } = App.useApp(); - let sourceAnchorIdx, targetAnchorIdx; + let sourceAnchorIdx, targetAnchorIdx, dropAnchorIdx; + let sourceNode; useEffect(() => { initMenu(); @@ -35,9 +36,8 @@ const EditPipeline = () => { }, []); const onDragEnd = (val) => { - const _x = val.x; - const _y = val.y; - const point = graph.getPointByClient(_x, _y); + const { x, y } = val; + const point = graph.getPointByClient(x, y); // 元模型 const model = { ...val, @@ -46,8 +46,8 @@ const EditPipeline = () => { id: val.component_name + '-' + s8(), isCluster: false, }; - console.log('model', model); - graph.addItem('node', model, true); + // console.log('model', model); + graph.addItem('node', model, false); }; const formChange = (val) => { if (graph) { @@ -110,6 +110,10 @@ const EditPipeline = () => { }; const getGraphData = (data) => { if (graph) { + // 修改历史数据有蓝色边框的问题 + data.nodes.forEach((item) => { + item.style.stroke = '#fff'; + }); graph.data(data); graph.render(); } else { @@ -118,7 +122,6 @@ const EditPipeline = () => { }, 500); } }; - const processParallelEdgesOnAnchorPoint = ( edges, offsetDiff = 15, @@ -230,6 +233,15 @@ const EditPipeline = () => { } return edges; }; + // 判断两个节点之间是否有边 + const hasEdge = (source, target) => { + const neighbors = source.getNeighbors(); + for (const node of neighbors) { + // 新建边的时候,获取的 neighbors 的数据有问题,不全是 INode 类型,可能没有 getID 方法 + if (node.getID?.() === target.getID?.()) return true; + } + return false; + }; const cloneElement = (item) => { console.log(item); let data = graph.save(); @@ -263,6 +275,8 @@ const EditPipeline = () => { // const selectedNodes = this.selectedNodes; contextMenu = new G6.Menu({ getContent(evt) { + const type = evt.item.getType(); + const cloneDisplay = type === 'node' ? 'block' : 'none'; return `
    - -
  • 复制
  • +
  • 复制
  • 删除
`; }, @@ -314,11 +327,11 @@ const EditPipeline = () => { getAnchorPoints(cfg) { return ( cfg.anchorPoints || [ - // 四个 + // 四个,上下左右 [0.5, 0], [0.5, 1], - // [0, 0.5], - // [1, 0.5], + [0, 0.5], + [1, 0.5], ] ); }, @@ -344,6 +357,7 @@ const EditPipeline = () => { textAlign: 'left', textBaseline: 'middle', fill: '#000', + cursor: 'pointer', }, name: 'text-shape', draggable: true, @@ -380,10 +394,9 @@ const EditPipeline = () => { // if (value || point.get('links') > 0) point.show(); // else point.hide(); // }); - const group = item.getContainer(); const shape = group.get('children')[0]; - const anchorPoints = group.findAll((ele) => ele.get('name') === 'anchor-point'); + const anchorPoints = group.findAll((item) => item.get('name') === 'anchor-point'); if (name === 'hover') { if (value) { shape.attr('stroke', themes['primaryColor']); @@ -396,6 +409,24 @@ const EditPipeline = () => { point.hide(); }); } + } else if (name === 'drag') { + if (sourceAnchorIdx === null || sourceAnchorIdx === undefined) { + return; + } + const anchorPoint = anchorPoints[sourceAnchorIdx]; + anchorPoint.attr('stroke', value ? themes['primaryColor'] : '#a4a4a5'); + } else if (name === 'drop') { + if (dropAnchorIdx === null || dropAnchorIdx === undefined) { + return; + } + const anchorPoint = anchorPoints[dropAnchorIdx]; + if (value) { + anchorPoint.attr('stroke', themes['primaryColor']); + } else { + anchorPoints.forEach((point) => { + anchorPoint.attr('stroke', '#a4a4a5'); + }); + } } }, }, @@ -407,10 +438,14 @@ const EditPipeline = () => { width: graphRef.current.clientWidth || 500, height: graphRef.current.clientHeight || '100%', animate: false, - groupByTypes: false, + groupByTypes: true, fitView: true, plugins: [contextMenu], - enabledStack: true, + enabledStack: false, + fitView: true, + minZoom: 0.5, + maxZoom: 5, + fitViewPadding: 300, modes: { default: [ // config the shouldBegin for drag-node to avoid node moving while dragging on the anchor-point circles @@ -420,10 +455,6 @@ const EditPipeline = () => { if (e.target.get('name') === 'anchor-point') return false; return true; }, - // shouldEnd: e => { - // console.log(e); - // return false; - // }, }, // config the shouldBegin and shouldEnd to make sure the create-edge is began and ended at anchor-point circles { @@ -434,11 +465,17 @@ const EditPipeline = () => { if (e.target && e.target.get('name') !== 'anchor-point') return false; sourceAnchorIdx = e.target.get('anchorPointIdx'); e.target.set('links', e.target.get('links') + 1); // cache the number of edge connected to this anchor-point circle + sourceNode = e.item; return true; }, shouldEnd: (e) => { // avoid ending at other shapes on the node if (e.target && e.target.get('name') !== 'anchor-point') return false; + if (!sourceNode || !e.item) return false; + // 不允许连接自己 + if (sourceNode.getID() === e.item.getID()) return false; + // 两个节点不允许多条边 + if (hasEdge(sourceNode, e.item)) return false; if (e.target) { targetAnchorIdx = e.target.get('anchorPointIdx'); e.target.set('links', e.target.get('links') + 1); // cache the number of edge connected to this anchor-point circle @@ -450,22 +487,11 @@ const EditPipeline = () => { }, 'drag-canvas', 'zoom-canvas', - // 'brush-select', - 'drag-combo', - ], - altSelect: [ - { - type: 'brush-select', - trigger: 'drag', - }, - 'drag-node', ], }, - defaultNode: { type: 'rect-node', size: [110, 36], - labelCfg: { style: { fill: 'transparent', @@ -488,8 +514,7 @@ const EditPipeline = () => { }, }, defaultEdge: { - //type: 'cubic-vertical', - + // type: 'cubic-vertical', style: { endArrow: { // 设置终点箭头 @@ -503,15 +528,8 @@ const EditPipeline = () => { stroke: '#CDD0DC', radius: 1, }, - nodeStateStyle: { - hover: { - opacity: 1, - stroke: '#8fe8ff', - }, - }, labelCfg: { autoRotate: true, - // refY: 10, style: { fontSize: 10, fill: '#FFF', @@ -528,40 +546,40 @@ const EditPipeline = () => { cursor: 'pointer', }, }, - // linkCenter: true, - fitView: true, - minZoom: 0.5, - maxZoom: 5, - fitViewPadding: 300, }); graph.on('node:click', (e) => { e.stopPropagation(); if (e.target.get('name') !== 'anchor-point' && e.item) { - // graph.setItemState(e.item, 'nodeClicked', true); + // 获取所有的上游节点 const parentNodes = findAllParentNodes(graph, e.item); // 如果没有打开过全局参数抽屉,获取不到全局参数 const globalParams = paramsDrawerRef.current.getFieldsValue().global_param || globalParamRef.current; + // 打开节点编辑抽屉 propsRef.current.showDrawer(e, globalParams, parentNodes); } }); graph.on('aftercreateedge', (e) => { + console.log('aftercreateedge', e); + // update the sourceAnchor and targetAnchor for the newly added edge graph.updateItem(e.edge, { sourceAnchor: sourceAnchorIdx, targetAnchor: targetAnchorIdx, + type: + targetAnchorIdx === 0 || targetAnchorIdx === 1 ? 'cubic-vertical' : 'cubic-horizontal', }); - // update the curveOffset for parallel edges - const edges = graph.save().edges; - processParallelEdgesOnAnchorPoint(edges); - graph.getEdges().forEach((edge, i) => { - graph.updateItem(edge, { - curveOffset: edges[i].curveOffset, - curvePosition: edges[i].curvePosition, - }); - }); + // const edges = graph.save().edges; + // processParallelEdgesOnAnchorPoint(edges); + // graph.getEdges().forEach((edge, i) => { + // graph.updateItem(edge, { + // curveOffset: edges[i].curveOffset, + // curvePosition: edges[i].curvePosition, + // }); + // }); }); + // 删除边时,修改 anchor-point 的 links 值 graph.on('afterremoveitem', (e) => { if (e.item && e.item.source && e.item.target) { const sourceNode = graph.findById(e.item.source); @@ -587,7 +605,7 @@ const EditPipeline = () => { } } }); - // after clicking on the first node, the edge is created, update the sourceAnchor + // after drag on the first node, the edge is created, update the sourceAnchor graph.on('afteradditem', (e) => { if (e.item && e.item.getType() === 'edge') { graph.updateItem(e.item, { @@ -601,17 +619,36 @@ const EditPipeline = () => { graph.on('node:mouseleave', (e) => { graph.setItemState(e.item, 'hover', false); }); - graph.on('node:dragenter', (e) => { + + graph.on('node:dragstart', (e) => { graph.setItemState(e.item, 'hover', true); + graph.setItemState(e.item, 'drag', true); }); - graph.on('node:dragleave', (e) => { + graph.on('node:drag', (e) => { + graph.setItemState(e.item, 'hover', true); + }); + graph.on('node:dragend', (e) => { graph.setItemState(e.item, 'hover', false); + graph.setItemState(e.item, 'drag', false); }); - graph.on('node:dragstart', (e) => { + graph.on('node:dragenter', (e) => { graph.setItemState(e.item, 'hover', true); + if (e.target.get('name') === 'anchor-point') { + dropAnchorIdx = e.target.get('anchorPointIdx'); + graph.setItemState(e.item, 'drop', true); + } else { + graph.setItemState(e.item, 'drop', false); + } }); - graph.on('node:drag', (e) => { - graph.setItemState(e.item, 'hover', true); + graph.on('node:dragleave', (e) => { + graph.setItemState(e.item, 'hover', false); + graph.setItemState(e.item, 'drop', false); + dropAnchorIdx = undefined; + }); + graph.on('node:drop', (e) => { + graph.setItemState(e.item, 'hover', false); + graph.setItemState(e.item, 'drop', false); + dropAnchorIdx = undefined; }); window.onresize = () => { if (!graph || graph.get('destroyed')) return; diff --git a/react-ui/src/pages/Pipeline/index.jsx b/react-ui/src/pages/Pipeline/index.jsx index cf5fb571..12dbaae8 100644 --- a/react-ui/src/pages/Pipeline/index.jsx +++ b/react-ui/src/pages/Pipeline/index.jsx @@ -43,32 +43,30 @@ const Pipeline = () => { }; const routeToEdit = (e, record) => { e.stopPropagation(); - navgite({ pathname: `/pipeline/template/${record.id}/${record.name}` }); + navgite({ pathname: `/pipeline/template/${record.id}` }); }; const showModal = () => { form.resetFields(); + setFormId(null); setDialogTitle('新建流水线'); setIsModalOpen(true); }; - const handleOk = () => { - console.log(1111); - setIsModalOpen(false); - }; const handleCancel = () => { setIsModalOpen(false); }; const onFinish = (values) => { if (formId) { editWorkflow({ ...values, id: formId }).then((ret) => { + setIsModalOpen(false); message.success('编辑成功'); getList(); - setIsModalOpen(false); }); } else { addWorkflow(values).then((ret) => { - console.log(ret); + setIsModalOpen(false); + message.success('新建成功'); if (ret.code === 200) { - navgite({ pathname: `/pipeline/template/${ret.data.id}/${ret.data.name}` }); + navgite({ pathname: `/pipeline/template/${ret.data.id}` }); } }); } diff --git a/react-ui/src/requestConfig.ts b/react-ui/src/requestConfig.ts index 8a976abc..93a30443 100644 --- a/react-ui/src/requestConfig.ts +++ b/react-ui/src/requestConfig.ts @@ -9,12 +9,16 @@ import { clearSessionToken, getAccessToken } from './access'; import { setRemoteMenu } from './services/session'; import { gotoLoginPage } from './utils/ui'; +// [antd: Notification] You are calling notice in render which will break in React 18 concurrent mode. Please trigger in effect instead. +const popupError = (error: string) => { + message.error(error); +}; + /** * Umi Max 网络请求配置 * @doc https://umijs.org/docs/max/request#配置 */ export const requestConfig: RequestConfig = { - errorConfig: {}, requestInterceptors: [ (url: string, options: AxiosRequestConfig) => { const headers = options.headers ?? {}; @@ -30,26 +34,32 @@ export const requestConfig: RequestConfig = { }, ], responseInterceptors: [ - (response: AxiosResponse) => { - const { status, data } = response || {}; - if (status >= 200 && status < 300) { - if (data && (data instanceof Blob || data.code === 200)) { - return response; - } else if (data && data.code === 401) { - clearSessionToken(); - setRemoteMenu(null); - gotoLoginPage(false); - message.error('请重新登录'); - return Promise.reject(response); + [ + (response: AxiosResponse) => { + const { status, data } = response || {}; + console.log(message, data); + if (status >= 200 && status < 300) { + if (data && (data instanceof Blob || data.code === 200)) { + return response; + } else if (data && data.code === 401) { + clearSessionToken(); + setRemoteMenu(null); + gotoLoginPage(false); + popupError('请重新登录'); + return Promise.reject(response); + } else { + popupError(data?.msg ?? '请求失败'); + return Promise.reject(response); + } } else { - console.log(message, data); - message.error(data?.msg ?? '请求失败'); + popupError('请求失败'); return Promise.reject(response); } - } else { - message.error('请求失败'); - return Promise.reject(response); - } - }, + }, + (error: Error) => { + popupError(error.message ?? '请求失败'); + return Promise.reject(error); + }, + ], ], }; diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/JupyterService.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/JupyterService.java index f1aeb2cf..09a7fc68 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/JupyterService.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/JupyterService.java @@ -12,7 +12,7 @@ public interface JupyterService { void mlflow(); - String runJupyterService(Integer id); + String runJupyterService(Integer id) throws Exception; String stopJupyterService(Integer id) throws Exception; diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/JupyterServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/JupyterServiceImpl.java index b3eb4bdf..c57b498a 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/JupyterServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/JupyterServiceImpl.java @@ -76,13 +76,11 @@ public class JupyterServiceImpl implements JupyterService { } @Override - public String runJupyterService(Integer id) { + public String runJupyterService(Integer id) throws Exception { DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id); -// if(devEnvironment == null){ -// -// } - String envName = devEnvironment.getName(); - //TODO 设置环境变量 + if(devEnvironment == null){ + throw new Exception("开发环境配置不存在"); + } // 提取数据集,模型信息,得到数据集模型的path Map dataset = JacksonUtil.parseJSONStr2Map(devEnvironment.getDataset()); @@ -132,7 +130,6 @@ public class JupyterServiceImpl implements JupyterService { if(StringUtils.isEmpty(frameLogPathVo.getPath())){ return JupyterStatusVo; } - LoginUser loginUser = SecurityUtils.getLoginUser(); String podName = loginUser.getUsername().toLowerCase() + "-editor-pod";