diff --git a/react-ui/config/config.ts b/react-ui/config/config.ts
index cebef5c0..b2ff93b9 100644
--- a/react-ui/config/config.ts
+++ b/react-ui/config/config.ts
@@ -76,7 +76,7 @@ export default defineConfig({
* @name layout 插件
* @doc https://umijs.org/docs/max/layout-menu
*/
- title: 'Ant Design Pro',
+ title: '复杂智能软件',
layout: {
locale: true,
...defaultSettings,
diff --git a/react-ui/config/defaultSettings.ts b/react-ui/config/defaultSettings.ts
index e72ccdb3..0d58faa1 100644
--- a/react-ui/config/defaultSettings.ts
+++ b/react-ui/config/defaultSettings.ts
@@ -14,9 +14,9 @@ const Settings: ProLayoutProps & {
contentWidth: 'Fluid',
fixedHeader: false,
fixSiderbar: false,
- splitMenus: true,
+ splitMenus: false,
colorWeak: false,
- title: 'Ant Design Pro',
+ title: '复杂智能软件',
pwa: true,
logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
iconfontUrl: '',
diff --git a/react-ui/config/proxy.ts b/react-ui/config/proxy.ts
index 5f33242d..3f381754 100644
--- a/react-ui/config/proxy.ts
+++ b/react-ui/config/proxy.ts
@@ -15,14 +15,15 @@ export default {
// localhost:8000/api/** -> https://preview.pro.ant.design/api/**
'/api/': {
// 要代理的地址
- target: 'http://localhost:8082',
+ // target: 'http://172.20.32.181:31205',
+ target: 'http://172.20.32.150:8082',
// 配置了这个可以从 http 代理到 https
// 依赖 origin 的功能可能需要这个,比如 cookie
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
'/profile/avatar/': {
- target: 'http://localhost:8082',
+ target: 'http://172.20.32.181:31205',
changeOrigin: true,
}
},
diff --git a/react-ui/config/routes.ts b/react-ui/config/routes.ts
index ffad02ff..224541ce 100644
--- a/react-ui/config/routes.ts
+++ b/react-ui/config/routes.ts
@@ -46,6 +46,49 @@ export default [
},
],
},
+ {
+ name: 'pipeline',
+ path: '/pipeline',
+ routes: [
+ {
+ name: '流水线',
+ path: '/pipeline',
+ component: './Pipeline/index',
+ },
+ {
+ name: '训练',
+ path: '/pipeline/pytorchtext/:id/:name',
+ component: './Pipeline/editPipeline/index',
+ },
+ ],
+ },
+ {
+ name: 'experiment',
+ path: '/experiment',
+ routes: [
+ {
+ name: '实验',
+ path: '/experiment',
+ component: './Experiment/index',
+ },
+ {
+ name: '实验训练',
+ path: '/experiment/pytorchtext/:workflowId/:id',
+ component: './Experiment/experimentText/index',
+ },
+ ],
+ },
+ {
+ name: 'developmentEnvironment',
+ path: '/developmentEnvironment',
+ routes: [
+ {
+ name: '开发环境',
+ path: '/developmentEnvironment',
+ component: './DevelopmentEnvironment/index',
+ },
+ ],
+ },
{
name: 'system',
path: '/system',
diff --git a/react-ui/jest.config.ts b/react-ui/jest.config.ts
index ad09a2b3..1de2a1af 100644
--- a/react-ui/jest.config.ts
+++ b/react-ui/jest.config.ts
@@ -12,7 +12,7 @@ export default async () => {
...config,
testEnvironmentOptions: {
...(config?.testEnvironmentOptions || {}),
- url: 'http://localhost:8081',
+ url: 'http://localhost:8000',
},
setupFiles: [...(config.setupFiles || []), './tests/setupTests.jsx'],
globals: {
diff --git a/react-ui/package.json b/react-ui/package.json
index 3763e5e1..0a55edde 100644
--- a/react-ui/package.json
+++ b/react-ui/package.json
@@ -56,13 +56,14 @@
"@ant-design/icons": "^5.0.0",
"@ant-design/pro-components": "^2.4.4",
"@ant-design/use-emotion-css": "1.0.4",
+ "@antv/g6": "^4.8.24",
"@umijs/route-utils": "^4.0.1",
"antd": "^5.4.4",
"classnames": "^2.3.2",
"fabric": "^5.3.0",
"highlight.js": "^11.7.0",
"lodash": "^4.17.21",
- "moment": "^2.29.4",
+ "moment": "^2.30.1",
"omit.js": "^2.0.2",
"pnpm": "^8.9.0",
"query-string": "^8.1.0",
diff --git a/react-ui/public/assets/images/component-icon-1--Omitted.png b/react-ui/public/assets/images/component-icon-1--Omitted.png
new file mode 100644
index 00000000..f4e53527
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1--Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-1-Failed.png b/react-ui/public/assets/images/component-icon-1-Failed.png
new file mode 100644
index 00000000..ca81ea52
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-1-Omitted.png b/react-ui/public/assets/images/component-icon-1-Omitted.png
new file mode 100644
index 00000000..f4e53527
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-1-Pending.png b/react-ui/public/assets/images/component-icon-1-Pending.png
new file mode 100644
index 00000000..7f4c9eca
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-1-Running.png b/react-ui/public/assets/images/component-icon-1-Running.png
new file mode 100644
index 00000000..06562f00
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-1-Succeeded.png b/react-ui/public/assets/images/component-icon-1-Succeeded.png
new file mode 100644
index 00000000..9b74bfc7
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-1.png b/react-ui/public/assets/images/component-icon-1.png
new file mode 100644
index 00000000..5e5d7149
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-1.png differ
diff --git a/react-ui/public/assets/images/component-icon-2-Failed.png b/react-ui/public/assets/images/component-icon-2-Failed.png
new file mode 100644
index 00000000..e9808639
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-2-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-2-Omitted.png b/react-ui/public/assets/images/component-icon-2-Omitted.png
new file mode 100644
index 00000000..6ee447f3
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-2-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-2-Pending.png b/react-ui/public/assets/images/component-icon-2-Pending.png
new file mode 100644
index 00000000..20c62415
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-2-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-2-Running.png b/react-ui/public/assets/images/component-icon-2-Running.png
new file mode 100644
index 00000000..14d102cd
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-2-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-2-Succeeded.png b/react-ui/public/assets/images/component-icon-2-Succeeded.png
new file mode 100644
index 00000000..4cb50702
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-2-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-2.png b/react-ui/public/assets/images/component-icon-2.png
new file mode 100644
index 00000000..2f4fba75
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-2.png differ
diff --git a/react-ui/public/assets/images/component-icon-3-Failed.png b/react-ui/public/assets/images/component-icon-3-Failed.png
new file mode 100644
index 00000000..e14d6801
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-3-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-3-Omitted.png b/react-ui/public/assets/images/component-icon-3-Omitted.png
new file mode 100644
index 00000000..4bd1c261
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-3-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-3-Pending.png b/react-ui/public/assets/images/component-icon-3-Pending.png
new file mode 100644
index 00000000..b5590219
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-3-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-3-Running.png b/react-ui/public/assets/images/component-icon-3-Running.png
new file mode 100644
index 00000000..2dda9dd8
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-3-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-3-Succeeded.png b/react-ui/public/assets/images/component-icon-3-Succeeded.png
new file mode 100644
index 00000000..a915145d
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-3-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-3.png b/react-ui/public/assets/images/component-icon-3.png
new file mode 100644
index 00000000..941b323a
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-3.png differ
diff --git a/react-ui/public/assets/images/component-icon-4-Failed.png b/react-ui/public/assets/images/component-icon-4-Failed.png
new file mode 100644
index 00000000..4b1d6592
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-4-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-4-Omitted.png b/react-ui/public/assets/images/component-icon-4-Omitted.png
new file mode 100644
index 00000000..03e3d391
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-4-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-4-Pending.png b/react-ui/public/assets/images/component-icon-4-Pending.png
new file mode 100644
index 00000000..3c4b6f6f
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-4-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-4-Running.png b/react-ui/public/assets/images/component-icon-4-Running.png
new file mode 100644
index 00000000..b991a59a
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-4-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-4-Succeeded.png b/react-ui/public/assets/images/component-icon-4-Succeeded.png
new file mode 100644
index 00000000..0338686f
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-4-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-4.png b/react-ui/public/assets/images/component-icon-4.png
new file mode 100644
index 00000000..fd240707
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-4.png differ
diff --git a/react-ui/public/assets/images/component-icon-5-Failed.png b/react-ui/public/assets/images/component-icon-5-Failed.png
new file mode 100644
index 00000000..34e79c11
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-5-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-5-Omitted.png b/react-ui/public/assets/images/component-icon-5-Omitted.png
new file mode 100644
index 00000000..c3476b75
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-5-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-5-Pending.png b/react-ui/public/assets/images/component-icon-5-Pending.png
new file mode 100644
index 00000000..31125144
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-5-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-5-Running.png b/react-ui/public/assets/images/component-icon-5-Running.png
new file mode 100644
index 00000000..ad44c4c0
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-5-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-5-Succeeded.png b/react-ui/public/assets/images/component-icon-5-Succeeded.png
new file mode 100644
index 00000000..6981591e
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-5-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-5.png b/react-ui/public/assets/images/component-icon-5.png
new file mode 100644
index 00000000..b86bd925
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-5.png differ
diff --git a/react-ui/public/assets/images/component-icon-6-Failed.png b/react-ui/public/assets/images/component-icon-6-Failed.png
new file mode 100644
index 00000000..5bf8ed50
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-6-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-6-Omitted.png b/react-ui/public/assets/images/component-icon-6-Omitted.png
new file mode 100644
index 00000000..89e477ca
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-6-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-6-Pending.png b/react-ui/public/assets/images/component-icon-6-Pending.png
new file mode 100644
index 00000000..24e83971
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-6-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-6-Running.png b/react-ui/public/assets/images/component-icon-6-Running.png
new file mode 100644
index 00000000..e45b1fbb
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-6-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-6-Succeeded.png b/react-ui/public/assets/images/component-icon-6-Succeeded.png
new file mode 100644
index 00000000..8d4a4680
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-6-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-6.png b/react-ui/public/assets/images/component-icon-6.png
new file mode 100644
index 00000000..7676a037
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-6.png differ
diff --git a/react-ui/public/assets/images/component-icon-7-Failed.png b/react-ui/public/assets/images/component-icon-7-Failed.png
new file mode 100644
index 00000000..2427996b
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-7-Failed.png differ
diff --git a/react-ui/public/assets/images/component-icon-7-Omitted.png b/react-ui/public/assets/images/component-icon-7-Omitted.png
new file mode 100644
index 00000000..33a4445e
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-7-Omitted.png differ
diff --git a/react-ui/public/assets/images/component-icon-7-Pending.png b/react-ui/public/assets/images/component-icon-7-Pending.png
new file mode 100644
index 00000000..12a5aa4e
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-7-Pending.png differ
diff --git a/react-ui/public/assets/images/component-icon-7-Running.png b/react-ui/public/assets/images/component-icon-7-Running.png
new file mode 100644
index 00000000..0328188f
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-7-Running.png differ
diff --git a/react-ui/public/assets/images/component-icon-7-Succeeded.png b/react-ui/public/assets/images/component-icon-7-Succeeded.png
new file mode 100644
index 00000000..30676934
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-7-Succeeded.png differ
diff --git a/react-ui/public/assets/images/component-icon-7.png b/react-ui/public/assets/images/component-icon-7.png
new file mode 100644
index 00000000..28c1803d
Binary files /dev/null and b/react-ui/public/assets/images/component-icon-7.png differ
diff --git a/react-ui/public/assets/images/duty-message.png b/react-ui/public/assets/images/duty-message.png
new file mode 100644
index 00000000..3b187643
Binary files /dev/null and b/react-ui/public/assets/images/duty-message.png differ
diff --git a/react-ui/public/assets/images/static-message.png b/react-ui/public/assets/images/static-message.png
new file mode 100644
index 00000000..097f48a2
Binary files /dev/null and b/react-ui/public/assets/images/static-message.png differ
diff --git a/react-ui/public/fonts/font.css b/react-ui/public/fonts/font.css
index 136b2788..5d110456 100644
--- a/react-ui/public/fonts/font.css
+++ b/react-ui/public/fonts/font.css
@@ -1,4 +1,4 @@
-@font-face {
- font-family: Alibaba;
+@font-face {
+ font-family: Alibaba;
src: url('./ALIBABA-PUHUITI-MEDIUM.TTF');
- }
+ }
\ No newline at end of file
diff --git a/react-ui/src/pages/DevelopmentEnvironment/index.jsx b/react-ui/src/pages/DevelopmentEnvironment/index.jsx
new file mode 100644
index 00000000..378d12f8
--- /dev/null
+++ b/react-ui/src/pages/DevelopmentEnvironment/index.jsx
@@ -0,0 +1,14 @@
+import React ,{ useState,useEffect,useRef }from 'react';
+import {getJupyterUrl} from '@/services/developmentEnvironment/index.js'
+const developmentEnvironment = React.FC = () => {
+ const [iframeUrl,setIframeUrl]=useState('')
+ useEffect(()=>{
+ getJupyterUrl().then(ret=>{
+ console.log(ret);
+ setIframeUrl(ret.msg)
+ })
+ },[])
+ return (
+
+ )};
+export default developmentEnvironment;
\ No newline at end of file
diff --git a/react-ui/src/pages/Experiment/experimentText/editPipeline.less b/react-ui/src/pages/Experiment/experimentText/editPipeline.less
new file mode 100644
index 00000000..d0562f67
--- /dev/null
+++ b/react-ui/src/pages/Experiment/experimentText/editPipeline.less
@@ -0,0 +1,30 @@
+#graph {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ }
+.editPipelinePropsContent{
+ display: flex;
+ align-items: center;
+ width: 100%;
+ height:43px;
+ background:#f8fbff;
+ color:#1d1d20;
+ font-size:15px;
+ font-family: 'Alibaba';
+ padding: 0 20px;
+}
+.centerContainer{
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+.buttonList{
+ display: flex;
+ align-items: center;
+ padding: 0 30px;
+ width: 100%;
+ height:45px;
+ background:#ffffff;
+ box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
+}
\ No newline at end of file
diff --git a/react-ui/src/pages/Experiment/experimentText/index.jsx b/react-ui/src/pages/Experiment/experimentText/index.jsx
new file mode 100644
index 00000000..30022345
--- /dev/null
+++ b/react-ui/src/pages/Experiment/experimentText/index.jsx
@@ -0,0 +1,335 @@
+import React ,{ useState,useEffect,useRef }from 'react';
+import { useParams } from 'react-router-dom'
+import Props from './props';
+import { useEmotionCss } from '@ant-design/use-emotion-css';
+import G6 from '@antv/g6';
+import Styles from './editPipeline.less'
+import { s8 } from '../../../utils';
+import { Button, message} from 'antd';
+import {SaveOutlined} from '@ant-design/icons';
+import {saveWorkflow,getWorkflowById,} from '@/services/pipeline/index.js'
+import {getExperimentIns} from '@/services/experiment/index.js'
+import { useNavigate} from 'react-router-dom';
+const ExperimentText = React.FC = () => {
+ const propsRef=useRef()
+ const navgite=useNavigate();
+ const locationParams =useParams () //新版本获取路由参数接口
+ let graph=null
+ const [experimentStatusObj,setExperimentStatusObj]=useState({})
+ const pipelineContainer = useEmotionCss(() => {
+ return {
+ display: 'flex',
+ backgroundColor:'#fff',
+ height:'81vh'
+ };
+ });
+ const graphStyle = useEmotionCss(() => {
+ return {
+ width:'100%',
+ backgroundColor:'#f9fafb',
+ flex:1
+ };
+ });
+ 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,
+ };
+ console.log(graph, model);
+
+ graph.addItem('node', model, true);
+ console.log(graph);
+
+ }
+ const formChange=(val)=>{
+ }
+ const handlerClick=(e)=>{
+ 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);
+ propsRef.current.showDrawer(e,locationParams.id)
+ }
+ const getGraphData=(data)=>{
+ if(graph){
+ console.log(graph);
+ graph.data(data)
+ graph.render()
+ }
+ else{
+ setTimeout(()=>{
+ getGraphData(data)
+ },500)
+ }
+ }
+ const getFirstWorkflow=(val)=>{
+ getWorkflowById(val).then(ret=>{
+ console.log(ret,'retttttttttt');
+ if(ret.code==200){
+ if(graph&&ret.data&&ret.data.dag){
+ console.log(JSON.parse(ret.data.dag));
+ getExperimentIns(locationParams.id).then(res=>{
+ if(res.code==200){
+ const experimentStatusObjs=JSON.parse(res.data.nodes_status)
+ const newNodeList= JSON.parse(ret.data.dag).nodes.map(item=>{console.log(experimentStatusObjs); return {...item,component_id:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].id,img:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].phase?item.img.slice(0,item.img.length-4)+'-'+experimentStatusObjs[item.id].phase+'.png':item.img}})
+ const newData={...JSON.parse(ret.data.dag),nodes:newNodeList}
+ console.log(newData);
+ getGraphData(newData)
+ // setExperimentStatusObj(JSON.parse(ret.data.nodes_status))
+ }
+
+ })
+
+
+ }
+ }
+ // graph&&graph.data(JSON.parse(ret.dag))
+ // graph.render()
+ })
+ }
+ // const getExperimentIn=(val)=>{
+ // getExperimentIns(val).then(ret=>{
+ // if(ret.code==200){
+ // console.log(JSON.parse(ret.data.nodes_status));
+ // setExperimentStatusObj(JSON.parse(ret.data.nodes_status))
+ // setTimeout(() => {
+ // console.log(experimentStatusObj);
+
+ // }, 1000);
+ // }
+
+ // })
+ // }
+ useEffect(()=>{
+
+ initGraph()
+ getFirstWorkflow(locationParams.workflowId)
+ },[])
+ const initGraph=()=>{
+ G6.registerNode(
+ 'rect-node',
+ {
+ // draw anchor-point circles according to the anchorPoints in afterDraw
+ getAnchorPoints(cfg) {
+ return (
+ cfg.anchorPoints || [
+ // 上下各3,左右各1
+ [0.1, 0.05],
+ [0.5, 0.05],
+ [0.9, 0.05],
+ [0, 0.5],
+ [1, 0.5],
+ [0.1, 1],
+ [0.5, 1],
+ [0.9, 1],
+
+ // 四边中间
+ // [0.5, 0.05],
+ // [0, 0.5],
+ // [1, 0.5],
+ // [0.5, 1],
+ // 四个角落
+ // [0.05, 0.05],
+ // [0.9, 0.05],
+ // [0.05, 1],
+ // [0.9, 1],
+ ]
+ );
+ },
+ afterDraw(cfg, group) {
+ // console.log(group, cfg, 12312);
+ const image = group.addShape('image', {
+ attrs: {
+ x: -25,
+ y: -13,
+ width: 23,
+ height: 21,
+ img: cfg.img,
+ cursor: 'pointer',
+ },
+ draggable: true,
+ });
+ // if (cfg.label) {
+ // group.addShape('text', {
+ // attrs: {
+ // x: 0,
+ // y: cfg.height / 2 - 5,
+ // textAlign: 'center',
+ // textBaseline: 'middle',
+ // text: cfg.label,
+ // fill: '#fff',
+ // },
+ // draggable: true,
+ // });
+ // }
+ const bbox = group.getBBox();
+ const anchorPoints = this.getAnchorPoints(cfg);
+ // console.log(anchorPoints);
+ anchorPoints.forEach((anchorPos, i) => {
+ group.addShape('circle', {
+ attrs: {
+ r: 5,
+ x: bbox.x + bbox.width * anchorPos[0],
+ y: bbox.y + bbox.height * anchorPos[1],
+ fill: '#000',
+ stroke: '#000',
+ },
+ name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point')
+ 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, // allow to catch the drag events on this shape
+ });
+ });
+ return image;
+ },
+
+ // response the state changes and show/hide the link-point circles
+ setState(name, value, item) {
+ // 默认显示全部锚点,防止过宽导致锚点无法被选中
+ // if (name === 'showAnchors') {
+ const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point');
+ anchorPoints.forEach(point => {
+ // if (value) point.show();
+ // else point.hide();
+ point.show();
+ });
+ // }
+ },
+ },
+ 'rect'
+ );
+ console.log(graphRef,'graphRef');
+ graph = new G6.Graph({
+ container: graphRef.current,
+ grid: true,
+ width: graphRef.current.clientWidth ||500,
+ height: graphRef.current.clientHeight||760,
+ animate: false,
+ groupByTypes: false,
+
+ plugins: [],
+ enabledStack: true,
+ modes: {
+ default: [
+ 'drag-canvas',
+ 'zoom-canvas',
+ ],
+ altSelect: [
+ {
+ type: 'brush-select',
+ trigger: 'drag',
+ },
+ 'drag-node',
+ ],
+ },
+
+ defaultNode: {
+ type: 'rect-node',
+ size: 70,
+
+ labelCfg: {
+ style: {
+ fill: '#000',
+ fontSize: 12,
+ cursor: 'pointer',
+ x: 0,
+ y: 0,
+ textAlign: 'left',
+ textBaseline: 'middle',
+ },
+ },
+ style: {
+ fill: 'transparent',
+ stroke: 'transparent',
+ },
+ },
+ // nodeStateStyles: {
+ // nodeSelected: {
+ // fill: 'red',
+ // shadowColor: 'red',
+ // stroke: 'red',
+ // 'text-shape': {
+ // fill: 'red',
+ // stroke: 'red',
+ // },
+ // },
+ // },
+ defaultEdge: {
+ // type: 'quadratic',
+ type: 'polyline',
+
+ style: {
+ endArrow: {
+ path: G6.Arrow.triangle(),
+ },
+ cursor: 'pointer',
+ endArrow: true,
+ lineWidth: 1,
+ opacity: 1,
+ stroke: '#a2a6b5',
+ radius: 10,
+ },
+ nodeStateStyle: {
+ hover: {
+ opacity: 1,
+ stroke: '#8fe8ff',
+ },
+ },
+ labelCfg: {
+ autoRotate: true,
+ // refY: 10,
+ style: {
+ fontSize: 10,
+ fill: '#FFF',
+ },
+ },
+ },
+ defaultCombo: {
+ type: 'rect',
+ fixCollapseSize: 70,
+ style: {
+ fill: '#00e0ff0d',
+ stroke: '#00e0ff',
+ lineDash: [5, 10],
+ cursor: 'pointer',
+ },
+ },
+ linkCenter: true,
+ fitView: true,
+ fitViewPadding: [60, 60, 60, 80],
+ });
+ graph.on('dblclick', handlerClick);
+ window.onresize = () => {
+ if (!graph || graph.get('destroyed')) return;
+ if (!graphRef.current || !graphRef.current.scrollWidth || !graphRef.current.scrollHeight) return;
+ graph.changeSize(graphRef.current.scrollWidth, graphRef.current.scrollHeight - 20);
+ };
+ }
+ return (
)};
+export default ExperimentText;
\ No newline at end of file
diff --git a/react-ui/src/pages/Experiment/experimentText/props.jsx b/react-ui/src/pages/Experiment/experimentText/props.jsx
new file mode 100644
index 00000000..3bf1029b
--- /dev/null
+++ b/react-ui/src/pages/Experiment/experimentText/props.jsx
@@ -0,0 +1,265 @@
+import React, { useState,useImperativeHandle ,forwardRef } from 'react';
+import { Button, Drawer,Form, Input ,Tabs } from 'antd';
+import Styles from './editPipeline.less'
+import{getQueryByExperimentLog}from '@/services/experiment/index.js'
+import { ProfileOutlined, DatabaseOutlined} from '@ant-design/icons';
+const { TextArea } = Input;
+const Props = forwardRef(({onParentChange}, ref) =>{
+ const [form] = Form.useForm();
+ const [stagingItem,setStagingItem]=useState({})
+ const [messageItem,setMessageItem]=useState('')
+
+ const items = [
+ {
+ key: '1',
+ label: '日志详情',
+ children: ,
+ icon:
+ },
+ {
+ key: '2',
+ label: '配置参数',
+ icon:,
+ children:
+
+
+
+
+
+
+

+ 任务信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {stagingItem.control_strategy&&Object.keys(stagingItem.control_strategy)&&Object.keys(stagingItem.control_strategy).length>0?Object.keys(stagingItem.control_strategy).map(item=>
+
+
+
+
+ ):''}
+
+

+ 输入参数
+
+ {stagingItem.in_parameters&&Object.keys(stagingItem.in_parameters)&&Object.keys(stagingItem.in_parameters).length>0?Object.keys(stagingItem.in_parameters).map(item=>
+
+
+
+ ):''}
+
+

+ 输出参数
+
+ {stagingItem.out_parameters&&Object.keys(stagingItem.out_parameters)&&Object.keys(stagingItem.out_parameters).length>0?Object.keys(stagingItem.out_parameters).map(item=>
+
+
+
+ ):''}
+ ,
+ },
+ ];
+ const [open, setOpen] = useState(false);
+ const afterOpenChange=()=>{
+
+ if(!open){
+ console.log(111,open);
+
+ console.log(stagingItem,form.getFieldsValue());
+ for(let i in form.getFieldsValue()){
+ for(let j in stagingItem.in_parameters){
+
+ if(i==j){
+ console.log(j,i);
+ stagingItem.in_parameters[j].value=form.getFieldsValue()[i]
+ }
+ }
+ for(let p in stagingItem.out_parameters){
+ if(i==p){
+ stagingItem.out_parameters[p].value=form.getFieldsValue()[i]
+ }
+ }
+ for(let k in stagingItem.control_strategy){
+ if(i==k){
+ stagingItem.control_strategy[k].value=form.getFieldsValue()[i]
+ }
+ }
+ }
+ // setStagingItem({...stagingItem,})
+ console.log((stagingItem.control_strategy));
+ onParentChange({...stagingItem,control_strategy:JSON.stringify(stagingItem.control_strategy),in_parameters:JSON.stringify(stagingItem.in_parameters),out_parameters:JSON.stringify(stagingItem.out_parameters),...form.getFieldsValue()})
+ // onParentChange({...stagingItem,...form.getFieldsValue()})
+ }
+ }
+ const onClose=()=> {
+ setOpen(false);
+ };
+ const onFinish = (values) => {
+
+ console.log('Success:', values);
+ };
+ const onFinishFailed = (errorInfo) => {
+ console.log('Failed:', errorInfo);
+ };
+ useImperativeHandle(ref, () => ({
+ showDrawer (e,id) {
+ setMessageItem('')
+ if(e.item&&e.item.getModel().component_id){
+ let params={
+ id:Number(id),
+ component_id:e.item&&e.item.getModel().component_id
+ }
+ getQueryByExperimentLog(params).then(ret=>{
+ console.log(ret);
+ let msg=ret.msg.replace(/\n/g,"")
+ let newMsg=msg.replace(/\r/g,"")
+ setMessageItem(newMsg)
+ form.resetFields();
+ form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)})
+ setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)})
+ // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)})
+ // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)})
+ // setTimeout(() => {
+ // console.log(stagingItem);
+ // }, (500));
+ setOpen(true);
+ })
+ }
+ else{
+ form.resetFields();
+ form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)})
+ setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)})
+ // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)})
+ // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)})
+ // setTimeout(() => {
+ // console.log(stagingItem);
+ // }, (500));
+ setOpen(true);
+ }
+ // console.log(e.item.getModel().in_parameters);
+
+ },
+
+ }));
+ return (
+ <>
+
+
+
+
+ >
+ );
+});
+
+export default Props;
diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx
new file mode 100644
index 00000000..91aa7704
--- /dev/null
+++ b/react-ui/src/pages/Experiment/index.jsx
@@ -0,0 +1,364 @@
+import React ,{ useState,useEffect,useRef }from 'react';
+import { Space, Table, Tag,Button,Modal, Form, Input ,message, Select,} from 'antd';
+import { PlusOutlined, EditOutlined ,PlayCircleOutlined} from '@ant-design/icons';
+import {getWorkflow,addWorkflow,removeWorkflow,cloneWorkflow} from '@/services/pipeline/index.js'
+import {getExperiment,runExperiments,getExperimentById,postExperiment,putExperiment,getQueryByExperimentId} from '@/services/experiment/index.js'
+import Styles from './index.less'
+import { useNavigate} from 'react-router-dom';
+import momnet from 'moment'
+const { TextArea } = Input;
+
+const Experiment = React.FC = () => {
+ const [form] = Form.useForm();
+ const navgite=useNavigate();
+ const statusObj={
+ "Running":'运行中',
+ "Succeeded":'成功',
+ "Failed":'失败',
+ "Error":'错误',
+ "Teminated":'终止'
+ }
+ const [experimentList, setExperimentList] = useState([]);
+
+ const [workflowList, setWorkflowList] = useState([]);
+ const [queryFlow,setQueryFlow]=useState({
+ offset:1,
+ page:0,
+ size:10000,
+ name:null
+ });
+ const timers=(time)=>{
+ let timer=new Date(time)
+ let hours = timer.getHours(); //转换成时
+ let minutes = timer.getMinutes(); //转换成分
+ let secend = timer.getSeconds(); //转换成秒
+
+ let str = `${minutes}分${secend}秒`;
+ return str;
+ }
+ const [formId,setFormId]=useState(null)
+ const [experimentInList,setExperimentInList]=useState([])
+ const [expandedRowKeys,setExpandedRowKeys]=useState(null)
+ const [total, setTotal] = useState(0);
+ const [dialogTitle, setDialogTitle] = useState('新建实验');
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const getWorkflowList=()=>{
+ getWorkflow(queryFlow).then(ret=>{
+ console.log(ret);
+ if(ret.code==200){
+ setWorkflowList(ret.data.content)
+ }
+
+ })
+ }
+ const getQueryByExperiment=(val)=>{
+ getQueryByExperimentId(val).then(ret=>{
+ setExpandedRowKeys(val)
+ if(ret.code==200&&ret.data&&ret.data.length>0){
+ setExperimentInList(ret.data)
+
+ }
+ else{
+ setExperimentInList([])
+ }
+ })
+ }
+ const expandChange=(e,record)=>{
+ if(record.id==expandedRowKeys){
+ setExpandedRowKeys(null)
+ }
+ else{
+ getQueryByExperiment(record.id)
+ }
+ }
+ const showModal = () => {
+ setDialogTitle('新建实验')
+ console.log(workflowList);
+ setIsModalOpen(true);
+ };
+ const editTable=(id)=>{
+ getExperimentById(id).then(ret=>{
+ if(ret.code==200){
+ form.setFieldsValue({...ret.data})
+ setFormId(ret.data.id)
+ setDialogTitle('编辑实验')
+ getWorkflowList()
+ setIsModalOpen(true)
+ }
+
+ })
+
+ // navgite({pathname:`/pipeline/pytorchtext/${record.id}/${record.name}` });
+ }
+ const handleOk = () => {
+ console.log(1111);
+ setIsModalOpen(false);
+ };
+ const handleCancel = () => {
+ setIsModalOpen(false);
+ };
+ const routeToEdit=(e,record)=>{
+ e.stopPropagation()
+ navgite({pathname:`/pipeline/pytorchtext/${record.workflow_id}/${record.workflow_name}` });
+ }
+ const onFinish = (values) => {
+ console.log(values,formId);
+ if(!formId){
+ postExperiment(values).then(ret=>{
+ if(ret.code==200){
+ message.success('新建实验成功')
+ setIsModalOpen(false)
+ getList()
+ }
+ else{
+ message.error('新建实验失败')
+ }
+ })
+ }
+
+ else{
+ putExperiment({...values,id:formId}).then(ret=>{
+ if(ret.code==200){
+ message.success('编辑实验成功')
+ setIsModalOpen(false)
+ getList()
+ }
+ else{
+ message.error('编辑实验失败')
+ }
+ })
+ }
+ setFormId(null)
+ };
+
+ const onFinishFailed = (errorInfo) => {
+ console.log('Failed:', errorInfo);
+ };
+ const pageOption = useRef({page: 1,size: 10})
+ const paginationProps = {
+ showQuickJumper: true,
+ showTotal: () => `共${total}条`,
+ total: total,
+ page: pageOption.current.page,
+ size: pageOption.current.size,
+ onChange: (current, size) => paginationChange(current, size)
+ }
+ // 当前页面切换
+ const paginationChange = async (current, size) => {
+ console.log('page', current, size)
+ pageOption.current={
+ page:current,
+ size:size
+ }
+ getList()
+ }
+ const runExperiment=(id)=>{
+ runExperiments(id).then(ret=>{
+ if(ret.code==200){
+ message.success('运行成功')
+ getQueryByExperiment(id)
+ getList()
+ }
+ else{
+ message.error('运行失败')
+ }
+ })
+ }
+ const routerToText=(e,item,record)=>{
+ e.stopPropagation()
+ navgite({pathname:`/experiment/pytorchtext/${record.workflow_id}/${item.id}` });
+ }
+ const getList=()=>{
+ let params={
+ offset:0,
+ page:pageOption.current.page-1,
+ size:pageOption.current.size
+ }
+ console.log(params,pageOption);
+ getExperiment(params).then(ret=>{
+ if(ret.code==200){
+ setExperimentList(ret.data.content.map(item=>{return{...item,key:item.id}}))
+
+ setTotal(ret.data.totalElements)
+ }
+ console.log(experimentList,total);
+ })
+ }
+ useEffect(()=>{
+ getList()
+ getWorkflowList()
+ // const timeOut= setInterval(() => {
+ // getList()
+ // }, 2000);
+ return () => {
+ // timeOut&&clearInterval(timeOut)
+ // console.log('will unmount');
+ }
+ },[])
+ const columns = [
+ // {
+ // title: '序号',
+ // dataIndex: 'index',
+ // key: 'index',
+ // width: 60,
+ // render(text, record, index) {
+ // return (
+ // {(pageOption.current.page - 1) * 10 + index + 1}
+ // )
+ // }
+ // // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
+ // },
+ {
+ title: '实验名称',
+ dataIndex: 'name',
+ key: 'name',
+ render: (text) => {text}
,
+ },
+ {
+ title: '关联流水线名称',
+ dataIndex: 'workflow_name',
+ key: 'workflow_name',
+ render: (text,record) => routeToEdit(e,record)}>{text},
+ },
+ {
+ title: '实验描述',
+ dataIndex: 'description',
+ key: 'description',
+ },
+ {
+ title: '最近五次运行状态',
+ dataIndex: 'state',
+ key: 'state',
+ },
+
+ {
+ title: '操作',
+ key: 'action',
+ render: (_, record) => (
+
+ }
+ onClick={() => {
+ runExperiment(record.id)
+ }}
+ >
+ 运行
+
+ }
+ onClick={() => {
+ editTable(record.id)
+ }}
+ >
+ 编辑
+
+
+
+ ),
+ },
+ ];
+ return (
+
+ }>
+ 新建实验
+
+
+
(
+
+
+ {experimentInList&&experimentInList.length>0?
+
序号
+
状态
+
运行时长
+
开始时间
+
:''}
+
+ {experimentInList&&experimentInList.length>0?experimentInList.map((item,index)=>(
+
+
routerToText(e,item,record)}>{index+1}
+
{statusObj[item.status]}
+
{item.finish_time?timers(new Date(item.finish_time).getTime()-new Date(item.start_time).getTime()):timers(new Date().getTime()-new Date(item.start_time).getTime())}
+
{momnet(item.start_time).format('YYYY-MM-DD HH:mm:ss')}
+
+ )):''}
+
+
+ ),
+ onExpand:(e,a)=>{expandChange(e,a)},
+ expandedRowKeys:[expandedRowKeys],
+ rowExpandable: (record) =>true,
+ }}/>
+
+
+
+
+
+
+
+
+
+
+
+
+ )};
+export default Experiment;
\ No newline at end of file
diff --git a/react-ui/src/pages/Experiment/index.less b/react-ui/src/pages/Experiment/index.less
new file mode 100644
index 00000000..701c4cbd
--- /dev/null
+++ b/react-ui/src/pages/Experiment/index.less
@@ -0,0 +1,35 @@
+.experimentTopBox{
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ padding-right: 30px;
+ width: 100%;
+ height: 49px;
+ background-size: 100% 100%;
+ background-image: url(/assets/images/pipeline-back.png);
+}
+// .plusButton{
+// background:rgba(22, 100, 255, 0.06);
+// border:1px solid;
+// border-color:rgba(22, 100, 255, 0.11);
+// border-radius:4px;
+// color:#1d1d20;
+// font-size:15px;
+// font-family: 'Alibaba';
+// }
+// .plusButton:hover{
+// background:rgba(22, 100, 255, 0.06);
+// border:1px solid;
+// border-color:rgba(22, 100, 255, 0.11);
+// border-radius:4px;
+// }
+.tableExpandBox{
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ color:#1d1d20;
+ font-size:15px;
+
+ padding: 0 65px 0 40px;
+}
\ No newline at end of file
diff --git a/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less b/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less
new file mode 100644
index 00000000..d0562f67
--- /dev/null
+++ b/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less
@@ -0,0 +1,30 @@
+#graph {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ }
+.editPipelinePropsContent{
+ display: flex;
+ align-items: center;
+ width: 100%;
+ height:43px;
+ background:#f8fbff;
+ color:#1d1d20;
+ font-size:15px;
+ font-family: 'Alibaba';
+ padding: 0 20px;
+}
+.centerContainer{
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+.buttonList{
+ display: flex;
+ align-items: center;
+ padding: 0 30px;
+ width: 100%;
+ height:45px;
+ background:#ffffff;
+ box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
+}
\ No newline at end of file
diff --git a/react-ui/src/pages/Pipeline/editPipeline/index.jsx b/react-ui/src/pages/Pipeline/editPipeline/index.jsx
new file mode 100644
index 00000000..087f26af
--- /dev/null
+++ b/react-ui/src/pages/Pipeline/editPipeline/index.jsx
@@ -0,0 +1,366 @@
+import React ,{ useState,useEffect,useRef }from 'react';
+import { useParams } from 'react-router-dom'
+import ModelMenus from './modelMenus';
+import Props from './props';
+import { useEmotionCss } from '@ant-design/use-emotion-css';
+import G6 from '@antv/g6';
+import Styles from './editPipeline.less'
+import { s8 } from '../../../utils';
+import { Button, message} from 'antd';
+import {SaveOutlined} from '@ant-design/icons';
+import {saveWorkflow,getWorkflowById} from '@/services/pipeline/index.js'
+import { useNavigate} from 'react-router-dom';
+const editPipeline = React.FC = () => {
+ const propsRef=useRef()
+ const navgite=useNavigate();
+ const locationParams =useParams () //新版本获取路由参数接口
+ let graph=null
+ const pipelineContainer = useEmotionCss(() => {
+ return {
+ display: 'flex',
+ backgroundColor:'#fff',
+ height:'81vh'
+ };
+ });
+ const graphStyle = useEmotionCss(() => {
+ return {
+ width:'100%',
+ backgroundColor:'#f9fafb',
+ flex:1
+ };
+ });
+ 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,
+ };
+ console.log(graph, model);
+
+ graph.addItem('node', model, true);
+ console.log(graph);
+
+ }
+ const formChange=(val)=>{
+
+ const data = graph.save();
+ const index = data.nodes.findIndex(item => {
+ return item.id ===val.id;
+ });
+ data.nodes[index] = val;
+ graph.changeData(data)
+ }
+ const savePipeline=()=>{
+ const data = graph.save();
+ console.log(data);
+ let params={
+ ...locationParams,
+ dag:JSON.stringify(data)
+ }
+ saveWorkflow(params).then(ret=>{
+ console.log(ret);
+ message.success('保存成功')
+ setTimeout(()=>{
+ navgite({pathname:`/pipeline`,});
+ },500)
+ })
+ console.log(params);
+ }
+ const handlerClick=(e)=>{
+ 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);
+ propsRef.current.showDrawer(e)
+ }
+ const getGraphData=(data)=>{
+ if(graph){
+ console.log(graph);
+ graph.data(data)
+ graph.render()
+ }
+ else{
+ setTimeout(()=>{
+ getGraphData(data)
+ },500)
+ }
+ }
+ const getFirstWorkflow=(val)=>{
+ getWorkflowById(val).then(ret=>{
+ console.log(ret);
+ if(ret.code==200){
+ if(graph&&ret.data&&ret.data.dag){
+
+ getGraphData(JSON.parse(ret.data.dag))
+
+ }
+ }
+
+ // graph&&graph.data(JSON.parse(ret.dag))
+ // graph.render()
+ })
+ }
+ useEffect(()=>{
+ getFirstWorkflow(locationParams.id)
+ initGraph()
+ },[])
+ const initGraph=()=>{
+ G6.registerNode(
+ 'rect-node',
+ {
+ // draw anchor-point circles according to the anchorPoints in afterDraw
+ getAnchorPoints(cfg) {
+ return (
+ cfg.anchorPoints || [
+ // 上下各3,左右各1
+ [0.1, 0.05],
+ [0.5, 0.05],
+ [0.9, 0.05],
+ [0, 0.5],
+ [1, 0.5],
+ [0.1, 1],
+ [0.5, 1],
+ [0.9, 1],
+
+ // 四边中间
+ // [0.5, 0.05],
+ // [0, 0.5],
+ // [1, 0.5],
+ // [0.5, 1],
+ // 四个角落
+ // [0.05, 0.05],
+ // [0.9, 0.05],
+ // [0.05, 1],
+ // [0.9, 1],
+ ]
+ );
+ },
+ afterDraw(cfg, group) {
+ // console.log(group, cfg, 12312);
+ const image = group.addShape('image', {
+ attrs: {
+ x: -25,
+ y: -13,
+ width: 21,
+ height: 21,
+ img: cfg.img,
+ cursor: 'pointer',
+ },
+ draggable: true,
+ });
+ // if (cfg.label) {
+ // group.addShape('text', {
+ // attrs: {
+ // x: 0,
+ // y: cfg.height / 2 - 5,
+ // textAlign: 'center',
+ // textBaseline: 'middle',
+ // text: cfg.label,
+ // fill: '#fff',
+ // },
+ // draggable: true,
+ // });
+ // }
+ const bbox = group.getBBox();
+ const anchorPoints = this.getAnchorPoints(cfg);
+ // console.log(anchorPoints);
+ anchorPoints.forEach((anchorPos, i) => {
+ group.addShape('circle', {
+ attrs: {
+ r: 5,
+ x: bbox.x + bbox.width * anchorPos[0],
+ y: bbox.y + bbox.height * anchorPos[1],
+ fill: '#000',
+ stroke: '#000',
+ },
+ name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point')
+ 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, // allow to catch the drag events on this shape
+ });
+ });
+ return image;
+ },
+
+ // response the state changes and show/hide the link-point circles
+ setState(name, value, item) {
+ // 默认显示全部锚点,防止过宽导致锚点无法被选中
+ // if (name === 'showAnchors') {
+ const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point');
+ anchorPoints.forEach(point => {
+ // if (value) point.show();
+ // else point.hide();
+ point.show();
+ });
+ // }
+ },
+ },
+ 'rect'
+ );
+ console.log(graphRef,'graphRef');
+ graph = new G6.Graph({
+ container: graphRef.current,
+ grid: true,
+ width: graphRef.current.clientWidth ||500,
+ height: graphRef.current.clientHeight||760,
+ animate: false,
+ groupByTypes: false,
+ fitView:true,
+ plugins: [],
+ enabledStack: true,
+ modes: {
+ default: [
+ // config the shouldBegin for drag-node to avoid node moving while dragging on the anchor-point circles
+ {
+ type: 'drag-node',
+ shouldBegin: e => {
+ 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
+ {
+ type: 'create-edge',
+ key: 'shift', // undefined by default, options: 'shift', 'control', 'ctrl', 'meta', 'alt'
+ },
+ 'drag-canvas',
+ 'zoom-canvas',
+ // 'brush-select',
+ 'drag-combo',
+ ],
+ altSelect: [
+ {
+ type: 'brush-select',
+ trigger: 'drag',
+ },
+ 'drag-node',
+ ],
+ },
+
+ defaultNode: {
+ type: 'rect-node',
+ size: 70,
+
+ labelCfg: {
+ style: {
+ fill: '#000',
+ fontSize: 12,
+ cursor: 'pointer',
+ x: 0,
+ y: 0,
+ textAlign: 'left',
+ textBaseline: 'middle',
+ },
+ },
+ style: {
+ fill: 'transparent',
+ stroke: 'transparent',
+ },
+ },
+ // nodeStateStyles: {
+ // nodeSelected: {
+ // fill: 'red',
+ // shadowColor: 'red',
+ // stroke: 'red',
+ // 'text-shape': {
+ // fill: 'red',
+ // stroke: 'red',
+ // },
+ // },
+ // },
+ defaultEdge: {
+ // type: 'quadratic',
+ type: 'polyline',
+
+ style: {
+ endArrow: {
+ path: G6.Arrow.triangle(),
+ },
+ cursor: 'pointer',
+ endArrow: true,
+ lineWidth: 1,
+ opacity: 1,
+ stroke: '#a2a6b5',
+ radius: 10,
+ },
+ nodeStateStyle: {
+ hover: {
+ opacity: 1,
+ stroke: '#8fe8ff',
+ },
+ },
+ labelCfg: {
+ autoRotate: true,
+ // refY: 10,
+ style: {
+ fontSize: 10,
+ fill: '#FFF',
+ },
+ },
+ },
+ defaultCombo: {
+ type: 'rect',
+ fixCollapseSize: 70,
+ style: {
+ fill: '#00e0ff0d',
+ stroke: '#00e0ff',
+ lineDash: [5, 10],
+ cursor: 'pointer',
+ },
+ },
+ linkCenter: true,
+ fitView: true,
+ fitViewPadding: [60, 60, 60, 80],
+ });
+ graph.on('dblclick', handlerClick);
+ graph.on('aftercreateedge', (e) => {
+ const edges = graph.save().edges;
+ G6.Util.processParallelEdges(edges);
+ graph.getEdges().forEach((edge, i) => {
+ graph.updateItem(edge, {
+ curveOffset: edges[i].curveOffset,
+ curvePosition: edges[i].curvePosition,
+ });
+ });
+ });
+ window.onresize = () => {
+ if (!graph || graph.get('destroyed')) return;
+ if (!graphRef.current || !graphRef.current.scrollWidth || !graphRef.current.scrollHeight) return;
+ graph.changeSize(graphRef.current.scrollWidth, graphRef.current.scrollHeight - 20);
+ };
+ }
+ return (
+
+
+
+ } onClick={savePipeline}>撤回
+ } onClick={savePipeline}>恢复
+ } onClick={savePipeline}>保存
+
+
+
+
+
)};
+export default editPipeline;
\ No newline at end of file
diff --git a/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx b/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx
new file mode 100644
index 00000000..38cba27a
--- /dev/null
+++ b/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx
@@ -0,0 +1,60 @@
+import React ,{ useState,useEffect,useRef }from 'react';
+import { Collapse, Divider } from 'antd';
+import Styles from './modelMenus.less'
+import {getComponentAll} from '@/services/pipeline/index.js'
+const items = [
+ {
+ key: '1',
+ label: 'This is panel header 1',
+ children: [1,2,3,4,5],
+ },
+ {
+ key: '2',
+ label: 'This is panel header 2',
+ children: [1,2,3,4,5],
+ },
+ {
+ key: '3',
+ label: 'This is panel header 3',
+ children: [1,2,3,4,5],
+ },
+ ];
+const modelMenus = ({onParDragEnd}) => {
+ const [modelMenusList,setModelMenusList]=useState([])
+ useEffect(()=>{
+ getComponentAll().then(ret=>{
+ console.log(ret);
+ if(ret.code==200){
+ setModelMenusList(ret.data)
+ }
+ })
+ },[])
+ const dragEnd=(e,data)=>{
+ console.log(e,data);
+ onParDragEnd({...data,x:e.clientX,y:e.clientY,label:data.component_label,img:`/assets/images/${data.icon_path}.png`})
+ }
+ const { Panel } = Collapse;
+ return (
+
+ {modelMenusList && modelMenusList.length > 0
+ ? modelMenusList.map(item => (
+ {item.name} }
+ key={item.key}
+ >
+ {item.value&&item.value.length>0?item.value.map(ele=>({dragEnd(e,ele)}} className={Styles.collapseItem}>
+

+ {ele.component_label}
+
)
+
+ ):''}
+
+ ))
+ : ""}
+
+ )};
+export default modelMenus;
\ No newline at end of file
diff --git a/react-ui/src/pages/Pipeline/editPipeline/modelMenus.less b/react-ui/src/pages/Pipeline/editPipeline/modelMenus.less
new file mode 100644
index 00000000..96cad5dc
--- /dev/null
+++ b/react-ui/src/pages/Pipeline/editPipeline/modelMenus.less
@@ -0,0 +1,12 @@
+.collapseList{
+
+}
+.collapseItem{
+
+ display: flex;
+ align-items: center;
+ color:#575757;
+ font-size:14px;
+ height:40px;
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/react-ui/src/pages/Pipeline/editPipeline/props.jsx b/react-ui/src/pages/Pipeline/editPipeline/props.jsx
new file mode 100644
index 00000000..3f032ad1
--- /dev/null
+++ b/react-ui/src/pages/Pipeline/editPipeline/props.jsx
@@ -0,0 +1,214 @@
+import React, { useState,useImperativeHandle ,forwardRef } from 'react';
+import { Button, Drawer,Form, Input , } from 'antd';
+import Styles from './editPipeline.less'
+const { TextArea } = Input;
+const Props = forwardRef(({onParentChange}, ref) =>{
+ const [form] = Form.useForm();
+ const [stagingItem,setStagingItem]=useState({})
+ const [open, setOpen] = useState(false);
+ const afterOpenChange=()=>{
+
+ if(!open){
+ console.log(111,open);
+
+ console.log(stagingItem,form.getFieldsValue());
+ for(let i in form.getFieldsValue()){
+ for(let j in stagingItem.in_parameters){
+
+ if(i==j){
+ console.log(j,i);
+ stagingItem.in_parameters[j].value=form.getFieldsValue()[i]
+ }
+ }
+ for(let p in stagingItem.out_parameters){
+ if(i==p){
+ stagingItem.out_parameters[p].value=form.getFieldsValue()[i]
+ }
+ }
+ for(let k in stagingItem.control_strategy){
+ if(i==k){
+ stagingItem.control_strategy[k].value=form.getFieldsValue()[i]
+ }
+ }
+ }
+ // setStagingItem({...stagingItem,})
+ console.log((stagingItem.control_strategy));
+ onParentChange({...stagingItem,control_strategy:JSON.stringify(stagingItem.control_strategy),in_parameters:JSON.stringify(stagingItem.in_parameters),out_parameters:JSON.stringify(stagingItem.out_parameters),...form.getFieldsValue()})
+ // onParentChange({...stagingItem,...form.getFieldsValue()})
+ }
+ }
+ const onClose=()=> {
+ setOpen(false);
+ };
+ const onFinish = (values) => {
+
+ console.log('Success:', values);
+ };
+ const onFinishFailed = (errorInfo) => {
+ console.log('Failed:', errorInfo);
+ };
+ useImperativeHandle(ref, () => ({
+ showDrawer (e) {
+ console.log(e.item.getModel());
+ // console.log(e.item.getModel().in_parameters);
+ form.resetFields();
+ form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)})
+ setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)})
+ // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)})
+ // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)})
+ // setTimeout(() => {
+ // console.log(stagingItem);
+ // }, (500));
+ setOpen(true);
+ },
+
+ }));
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+

+ 任务信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {stagingItem.control_strategy&&Object.keys(stagingItem.control_strategy)&&Object.keys(stagingItem.control_strategy).length>0?Object.keys(stagingItem.control_strategy).map(item=>
+
+
+
+
+ ):''}
+
+

+ 输入参数
+
+ {stagingItem.in_parameters&&Object.keys(stagingItem.in_parameters)&&Object.keys(stagingItem.in_parameters).length>0?Object.keys(stagingItem.in_parameters).map(item=>
+
+
+
+ ):''}
+
+

+ 输出参数
+
+ {stagingItem.out_parameters&&Object.keys(stagingItem.out_parameters)&&Object.keys(stagingItem.out_parameters).length>0?Object.keys(stagingItem.out_parameters).map(item=>
+
+
+
+ ):''}
+
+
+ >
+ );
+});
+
+export default Props;
diff --git a/react-ui/src/pages/Pipeline/index.jsx b/react-ui/src/pages/Pipeline/index.jsx
index 183324c3..5c18fc2f 100644
--- a/react-ui/src/pages/Pipeline/index.jsx
+++ b/react-ui/src/pages/Pipeline/index.jsx
@@ -1,58 +1,142 @@
-import React ,{ useState }from 'react';
-import { Space, Table, Tag,Button,Modal, Form, Input } from 'antd';
-import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined } from '@ant-design/icons';
-import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
+import React ,{ useState,useEffect,useRef }from 'react';
+import { Space, Table, Tag,Button,Modal, Form, Input ,message} from 'antd';
+import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons';
+import {getWorkflow,addWorkflow,removeWorkflow,cloneWorkflow,getWorkflowById,editWorkflow} from '@/services/pipeline/index.js'
import Styles from './index.less'
+import momnet from 'moment'
+import { useNavigate} from 'react-router-dom';
+const { TextArea } = Input;
const Pipeline = React.FC = () => {
- const editTable=()=>{
- console.log(111)
- }
+ const [form] = Form.useForm();
+ const navgite=useNavigate();
+
+ const [formId,setFormId]=useState(null)
+ const [dialogTitle,setDialogTitle]=useState('新建流水线')
+ const [pipeList, setPipeList] = useState([]);
+ const [total, setTotal] = useState(0);
const [isModalOpen, setIsModalOpen] = useState(false);
+ const editTable=(e,record)=>{
+ e.stopPropagation()
+ getWorkflowById(record.id).then(ret=>{
+ if(ret.code==200){
+ form.resetFields()
+ form.setFieldsValue({...ret.data})
+ setFormId(ret.data.id)
+ setDialogTitle('编辑流水线')
+ setIsModalOpen(true)
+ }
+
+ })
+
+ }
+ const routeToEdit=(e,record)=>{
+ e.stopPropagation()
+ navgite({pathname:`/pipeline/pytorchtext/${record.id}/${record.name}` });
+ }
const showModal = () => {
+ form.resetFields()
+ setDialogTitle('编辑流水线')
setIsModalOpen(true);
};
const handleOk = () => {
+ console.log(1111);
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
const onFinish = (values) => {
- console.log('Success:', values);
- };
- const onFinishFailed = (errorInfo) => {
- console.log('Failed:', errorInfo);
+ if(formId){
+ editWorkflow({...values,id:formId}).then(ret=>{
+ message.success('编辑成功')
+ getList()
+ setIsModalOpen(false)
+ })
+ }
+ else{
+ addWorkflow(values).then(ret=>{
+ navgite({pathname:`/pipeline/pytorchtext/${ret.id}/${ret.name}`,});
+ }
+ )
+ }
+
};
+ const onFinishFailed = (errorInfo) => {
+ console.log('Failed:', errorInfo);
+ };
+ const pageOption = useRef({page: 1,size: 10})
+ const paginationProps = {
+ showQuickJumper: true,
+ showTotal: () => `共${total}条`,
+ total: total,
+ page: pageOption.current.page,
+ size: pageOption.current.size,
+ onChange: (current, size) => paginationChange(current, size)
+ }
+ // 当前页面切换
+ const paginationChange = async (current, size) => {
+ console.log('page', current, size)
+ pageOption.current={
+ page:current,
+ size:size
+ }
+ getList()
+ }
+ const getList=()=>{
+ let params={
+ offset:1,
+ page:pageOption.current.page-1,
+ size:pageOption.current.size
+ }
+ console.log(params,pageOption);
+ getWorkflow(params).then(ret=>{
+ if(ret.code==200){
+ setPipeList(ret.data.content)
+
+ setTotal(ret.data.totalElements)
+ }
+
+ })
+ }
+ useEffect(()=>{
+ getList()
+ },[])
const columns = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 60,
- render:(text,record,index)=> index + 1,
+ render(text, record, index) {
+ return (
+ {(pageOption.current.page - 1) * 10 + index + 1}
+ )
+ }
// render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
},
{
title: '流水线名称',
dataIndex: 'name',
key: 'name',
- render: (text) => {text},
+ render: (text,record) => routeToEdit(e,record)}>{text},
},
{
title: '流水线描述',
- dataIndex: 'age',
- key: 'age',
+ dataIndex: 'description',
+ key: 'description',
},
{
title: '创建时间',
- dataIndex: 'address',
- key: 'address',
+ dataIndex: 'create_time',
+ key: 'create_time',
+ render: (text) => {momnet(text).format('YYYY-MM-DD HH:mm:ss')},
},
{
title: '修改时间',
- dataIndex: 'address',
- key: 'address',
+ dataIndex: 'update_time',
+ key: 'update_time',
+ render: (text) => {momnet(text).format('YYYY-MM-DD HH:mm:ss')},
},
{
title: '操作',
@@ -64,8 +148,8 @@ const Pipeline = React.FC = () => {
size="small"
key="edit"
icon = {< EditOutlined />}
- onClick={() => {
- editTable()
+ onClick={(e) => {
+ editTable(e,record)
}}
>
编辑
@@ -73,10 +157,33 @@ const Pipeline = React.FC = () => {
}
- onClick={() => {
- editTable()
+ key="clone"
+ icon = {< CopyOutlined />}
+ onClick={async () => {
+ Modal.confirm({
+ title: '复制',
+ content: '确定复制该条流水线吗?',
+ okText: '确认',
+ cancelText: '取消',
+ onOk: () => {
+ console.log(record);
+ cloneWorkflow(record.id).then(ret=>{
+ if(ret.code==200){
+ message.success('复制成功')
+ getList()
+ }
+ else{
+ message.error('复制失败')
+ }
+ });
+
+ // if (success) {
+ // if (actionRef.current) {
+ // actionRef.current.reload();
+ // }
+ // }
+ },
+ });
}}
>
复制
@@ -90,11 +197,21 @@ const Pipeline = React.FC = () => {
onClick={async () => {
Modal.confirm({
title: '删除',
- content: '确定删除该项吗?',
+ content: '确定删除该条流水线吗?',
okText: '确认',
cancelText: '取消',
- onOk: async () => {
- // const success = await handleRemoveOne(record);
+ onOk: () => {
+ console.log(record);
+ removeWorkflow(record.id).then(ret=>{
+ if(ret.code==200){
+ message.success('删除成功')
+ getList()
+ }
+ else{
+ message.error(ret.msg)
+ }
+ });
+
// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
@@ -110,102 +227,21 @@ const Pipeline = React.FC = () => {
),
},
];
- const data = [
- {
- key: '1',
- name: 'John Brown',
- age: 32,
- address: 'New York No. 1 Lake Park',
- tags: ['nice', 'developer'],
- },
- {
- key: '2',
- name: 'Jim Green',
- age: 42,
- address: 'London No. 1 Lake Park',
- tags: ['loser'],
- },
- {
- key: '3',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '4',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '5',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '6',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '7',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '8',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '9',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '10',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '11',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- {
- key: '12',
- name: 'Joe Black',
- age: 32,
- address: 'Sydney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- },
- ];
return (
}>
新建流水线
-
-
+
+
+
+
+
+
+
+
)};
-export default Pipeline;
+export default Pipeline;
\ No newline at end of file
diff --git a/react-ui/src/pages/Pipeline/index.less b/react-ui/src/pages/Pipeline/index.less
index 2db66314..51aa1c1c 100644
--- a/react-ui/src/pages/Pipeline/index.less
+++ b/react-ui/src/pages/Pipeline/index.less
@@ -22,4 +22,4 @@
// border:1px solid;
// border-color:rgba(22, 100, 255, 0.11);
// border-radius:4px;
-// }
+// }
\ No newline at end of file
diff --git a/react-ui/src/pages/User/Login/index.tsx b/react-ui/src/pages/User/Login/index.tsx
index de2690a4..0ef6030b 100644
--- a/react-ui/src/pages/User/Login/index.tsx
+++ b/react-ui/src/pages/User/Login/index.tsx
@@ -118,7 +118,7 @@ const Login: React.FC = () => {
color:'#1d1d20',
fontSize:'36px',
fontFamily: 'Alibaba',
-
+
};
});
const centerTitleBoX= useEmotionCss(() => {
@@ -249,12 +249,12 @@ const Login: React.FC = () => {
复杂智能软件
-
+
大语言模型运维 统一管理平台
-
+
@@ -480,7 +480,7 @@ const Login: React.FC = () => {
-
+
{/*
diff --git a/react-ui/src/pages/User/Login/login.less b/react-ui/src/pages/User/Login/login.less
index 73046b68..be384a9e 100644
--- a/react-ui/src/pages/User/Login/login.less
+++ b/react-ui/src/pages/User/Login/login.less
@@ -1,6 +1,6 @@
.loginForm{
width: 520px;
-
+
}
:global .ant-pro-form-login-main{
margin: unset;
@@ -26,4 +26,4 @@
color:#ffffff;
font-size:20px;
font-family: 'Alibaba';
-}
+}
\ No newline at end of file
diff --git a/react-ui/src/services/developmentEnvironment/index.js b/react-ui/src/services/developmentEnvironment/index.js
new file mode 100644
index 00000000..a0d3a4a1
--- /dev/null
+++ b/react-ui/src/services/developmentEnvironment/index.js
@@ -0,0 +1,8 @@
+import { request } from '@umijs/max';
+// 查询流水线列表
+export function getJupyterUrl(params) {
+ return request(`/api/mmp/jupyter/getURL`, {
+ method: 'GET',
+ params
+ });
+ }
\ No newline at end of file
diff --git a/react-ui/src/services/experiment/index.js b/react-ui/src/services/experiment/index.js
new file mode 100644
index 00000000..af4a3264
--- /dev/null
+++ b/react-ui/src/services/experiment/index.js
@@ -0,0 +1,62 @@
+import { request } from '@umijs/max';
+// 查询实验列表
+export function getExperiment(params) {
+ return request(`/api/mmp/experiment`, {
+ method: 'GET',
+ params
+ });
+ }
+// 运行实验
+export function runExperiments(id) {
+ return request('/api/mmp/experiment/experiments/'+id, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ });
+ }
+// 根据id查询实验
+export function getExperimentById(id) {
+ return request(`/api/mmp/experiment/${id}`, {
+ method: 'GET',
+ });
+ }
+// 根据id查询实验实例
+export function getQueryByExperimentId(id) {
+ return request(`/api/mmp/experimentIns/queryByExperimentId/${id}`, {
+ method: 'GET',
+ });
+ }
+// 根据id查询查询日志
+export function getQueryByExperimentLog(params) {
+ return request(`/api/mmp/experimentIns/log/`, {
+ method: 'GET',
+ params
+ });
+ }
+// 根据实例查询详情
+export function getExperimentIns(id) {
+ return request(`/api/mmp/experimentIns/${id}`, {
+ method: 'GET',
+ });
+ }
+// 新增实验
+export function postExperiment(data) {
+ return request(`/api/mmp/experiment`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ data
+ });
+ }
+// 编辑实验
+export function putExperiment(data) {
+ return request(`/api/mmp/experiment`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ data
+ });
+ }
\ No newline at end of file
diff --git a/react-ui/src/services/pipeline/index.js b/react-ui/src/services/pipeline/index.js
new file mode 100644
index 00000000..48bebe73
--- /dev/null
+++ b/react-ui/src/services/pipeline/index.js
@@ -0,0 +1,66 @@
+import { request } from '@umijs/max';
+import { ContentType } from '@/enums/httpEnum';
+// 查询流水线列表
+export function getWorkflow(params) {
+ return request(`/api/mmp/workflow`, {
+ method: 'GET',
+ params
+ });
+ }
+// 新建流水线
+export function addWorkflow(params) {
+ return request('/api/mmp/workflow', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ data: params
+ });
+ }
+// 编辑流水线
+export function editWorkflow(params) {
+ return request('/api/mmp/workflow', {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ data: params
+ });
+}
+// 删除流水线
+export async function removeWorkflow(id) {
+ return request(`/api/mmp/workflow/${id}`, {
+ method: 'DELETE',
+ });
+ }
+// 复制流水线
+export function cloneWorkflow(id) {
+ return request(`/api/mmp/workflow/duplicate/${id}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ });
+ }
+// 查询组件模型列表
+export function getComponentAll() {
+ return request(`/api/mmp/component/components/all`, {
+ method: 'GET',
+ });
+ }
+// 保存流水线
+export function saveWorkflow(params) {
+ return request('/api/mmp/workflow', {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json;charset=UTF-8',
+ },
+ data: params
+ });
+}
+// 根据id查询流水线
+export function getWorkflowById(id) {
+ return request(`/api/mmp/workflow/${id}`, {
+ method: 'GET',
+ });
+}
\ No newline at end of file
diff --git a/react-ui/src/utils/index.js b/react-ui/src/utils/index.js
new file mode 100644
index 00000000..4ff68eb3
--- /dev/null
+++ b/react-ui/src/utils/index.js
@@ -0,0 +1,11 @@
+export function s8() {
+ return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1);
+ }
+
+ export function getNameByCode(list,code){
+ let name = ''
+ list.forEach(item=>{
+ if(item.dictValue === code) name = item.dictLabel
+ })
+ return name
+ }
\ No newline at end of file
diff --git a/react-ui/tsconfig.json b/react-ui/tsconfig.json
index 85733f68..3e6ef3ee 100644
--- a/react-ui/tsconfig.json
+++ b/react-ui/tsconfig.json
@@ -19,5 +19,5 @@
"@@test/*": ["./src/.umi-test/*"]
}
},
- "include": ["./**/*.d.ts", "./**/*.ts", "./**/*.tsx"]
+ "include": ["./**/*.d.ts", "./**/*.ts", "./**/*.tsx", "src/pages/Pipeline/index.jsx"]
}