Browse Source

Merge pull request '合并' (#6) from dev into master

tags/v20240126
fanshuai 2 years ago
parent
commit
6af228f21c
23 changed files with 427 additions and 90 deletions
  1. +0
    -0
      react-ui/public/assets/images/component-icon-1-Skipped.png
  2. BIN
      react-ui/public/assets/images/component-icon-2-Skipped.png
  3. BIN
      react-ui/public/assets/images/fail-icon.png
  4. BIN
      react-ui/public/assets/images/omitted-icon.png
  5. BIN
      react-ui/public/assets/images/pending-icon.png
  6. BIN
      react-ui/public/assets/images/running-icon.png
  7. BIN
      react-ui/public/assets/images/success-icon.png
  8. +14
    -0
      react-ui/src/pages/Experiment/experimentText/editPipeline.less
  9. +48
    -5
      react-ui/src/pages/Experiment/experimentText/index.jsx
  10. +44
    -14
      react-ui/src/pages/Experiment/experimentText/props.jsx
  11. +126
    -12
      react-ui/src/pages/Experiment/index.jsx
  12. +12
    -0
      react-ui/src/pages/Experiment/index.less
  13. +44
    -1
      react-ui/src/pages/Pipeline/editPipeline/index.jsx
  14. +4
    -2
      react-ui/src/pages/Pipeline/editPipeline/props.jsx
  15. +18
    -0
      react-ui/src/services/experiment/index.js
  16. +4
    -3
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/experiment/ExperimentController.java
  17. +5
    -4
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/experiment/ExperimentInsController.java
  18. +8
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Experiment.java
  19. +5
    -4
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ExperimentInsService.java
  20. +4
    -3
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ExperimentService.java
  21. +65
    -30
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java
  22. +4
    -3
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java
  23. +22
    -9
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentDaoMapper.xml

react-ui/public/assets/images/component-icon-1--Omitted.png → react-ui/public/assets/images/component-icon-1-Skipped.png View File


BIN
react-ui/public/assets/images/component-icon-2-Skipped.png View File

Before After
Width: 108  |  Height: 108  |  Size: 3.6 kB

BIN
react-ui/public/assets/images/fail-icon.png View File

Before After
Width: 34  |  Height: 34  |  Size: 1.0 kB

BIN
react-ui/public/assets/images/omitted-icon.png View File

Before After
Width: 51  |  Height: 51  |  Size: 1.4 kB

BIN
react-ui/public/assets/images/pending-icon.png View File

Before After
Width: 36  |  Height: 36  |  Size: 1.1 kB

BIN
react-ui/public/assets/images/running-icon.png View File

Before After
Width: 34  |  Height: 34  |  Size: 1.1 kB

BIN
react-ui/public/assets/images/success-icon.png View File

Before After
Width: 34  |  Height: 34  |  Size: 1.1 kB

+ 14
- 0
react-ui/src/pages/Experiment/experimentText/editPipeline.less View File

@@ -27,4 +27,18 @@
height:45px; height:45px;
background:#ffffff; background:#ffffff;
box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
}
.detailBox{
color:#1d1d20;
font-size:15px;
margin-bottom: 15px;
display: flex;
align-items: center;
}
.allMessageItem{
display: flex;
align-items: center;
color:rgba(29, 29, 32, 0.8);
font-size:15px;
margin-right: 30px;
} }

+ 48
- 5
react-ui/src/pages/Experiment/experimentText/index.jsx View File

@@ -8,14 +8,45 @@ import { s8 } from '../../../utils';
import { Button, message} from 'antd'; import { Button, message} from 'antd';
import {SaveOutlined} from '@ant-design/icons'; import {SaveOutlined} from '@ant-design/icons';
import {saveWorkflow,getWorkflowById,} from '@/services/pipeline/index.js' import {saveWorkflow,getWorkflowById,} from '@/services/pipeline/index.js'
import {getExperimentIns} from '@/services/experiment/index.js'
import {getExperimentIns,} from '@/services/experiment/index.js'
import { useNavigate} from 'react-router-dom'; import { useNavigate} from 'react-router-dom';
import momnet from 'moment'
const ExperimentText = React.FC = () => { const ExperimentText = React.FC = () => {
const propsRef=useRef() const propsRef=useRef()
const navgite=useNavigate(); const navgite=useNavigate();
const locationParams =useParams () //新版本获取路由参数接口 const locationParams =useParams () //新版本获取路由参数接口
let graph=null let graph=null
const [experimentStatusObj,setExperimentStatusObj]=useState({}) const [experimentStatusObj,setExperimentStatusObj]=useState({})
const [experimentAllMessage,setExperimentAllMessage]=useState({})
const statusObj={
"Running":'运行中',
"Succeeded":'成功',
"Pending":'等待中',
"Failed":'失败',
"Error":'错误',
"Terminated":'终止',
"Skipped":'未执行',
"Omitted":'未执行',
}
const statusColorObj={
"Running":'#165bff',
"Succeeded":'#63a728',
"Pending":'#f981eb',
"Failed":'#c73131',
"Error":'#c73131',
"Terminated":'#8a8a8a',
"Skipped":'#8a8a8a',
"Omitted":'#8a8a8ae',
}
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 pipelineContainer = useEmotionCss(() => { const pipelineContainer = useEmotionCss(() => {
return { return {
display: 'flex', display: 'flex',
@@ -88,11 +119,13 @@ const ExperimentText = React.FC = () => {
console.log(JSON.parse(ret.data.dag)); console.log(JSON.parse(ret.data.dag));
getExperimentIns(locationParams.id).then(res=>{ getExperimentIns(locationParams.id).then(res=>{
if(res.code==200){ if(res.code==200){
console.log(ret.data,'data');
const experimentStatusObjs=JSON.parse(res.data.nodes_status) 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)
const newNodeList= JSON.parse(ret.data.dag).nodes.map(item=>{console.log(experimentStatusObjs); return {...item,experimentEndTime:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].finishedAt,experimentStartTime:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].startedAt,experimentStatus:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].phase,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);
setExperimentAllMessage(res.data)
getGraphData(newData)
// setExperimentStatusObj(JSON.parse(ret.data.nodes_status)) // setExperimentStatusObj(JSON.parse(ret.data.nodes_status))
} }
@@ -327,6 +360,16 @@ const ExperimentText = React.FC = () => {
return (<div className={pipelineContainer}> return (<div className={pipelineContainer}>
<div className={Styles.centerContainer}> <div className={Styles.centerContainer}>
<div className={Styles.buttonList}> <div className={Styles.buttonList}>
<div className={Styles.allMessageItem}>启动时间:{momnet(experimentAllMessage.create_time).format('YYYY-MM-DD HH:mm:ss')}</div>
<div className={Styles.allMessageItem}>执行时长:{experimentAllMessage.finish_time?timers(new Date(experimentAllMessage.finish_time).getTime()-new Date(experimentAllMessage.create_time).getTime()):timers(new Date().getTime()-new Date(experimentAllMessage.create_time).getTime())}</div>
<div className={Styles.allMessageItem}>状态:
<div style={{width:'8px',
height:'8px',
borderRadius:'50%',
marginRight:'6px',
backgroundColor:statusColorObj[experimentAllMessage.status]
}}></div>
<span style={{color:statusColorObj[experimentAllMessage.status]}}>{statusObj[experimentAllMessage.status]}</span></div>
</div> </div>
<div className={graphStyle} ref={graphRef} id={Styles.graphStyle}></div> <div className={graphStyle} ref={graphRef} id={Styles.graphStyle}></div>
</div> </div>


+ 44
- 14
react-ui/src/pages/Experiment/experimentText/props.jsx View File

@@ -3,19 +3,48 @@ import { Button, Drawer,Form, Input ,Tabs } from 'antd';
import Styles from './editPipeline.less' import Styles from './editPipeline.less'
import{getQueryByExperimentLog}from '@/services/experiment/index.js' import{getQueryByExperimentLog}from '@/services/experiment/index.js'
import { ProfileOutlined, DatabaseOutlined} from '@ant-design/icons'; import { ProfileOutlined, DatabaseOutlined} from '@ant-design/icons';
import momnet from 'moment'
const { TextArea } = Input; const { TextArea } = Input;
const Props = forwardRef(({onParentChange}, ref) =>{ const Props = forwardRef(({onParentChange}, ref) =>{
const [form] = Form.useForm(); const [form] = Form.useForm();
const [stagingItem,setStagingItem]=useState({}) const [stagingItem,setStagingItem]=useState({})
const [messageItem,setMessageItem]=useState('') const [messageItem,setMessageItem]=useState('')

const statusObj={
"Running":'运行中',
"Succeeded":'成功',
"Pending":'等待中',
"Failed":'失败',
"Error":'错误',
"Terminated":'终止',
"Skipped":'未执行',
"Omitted":'未执行',
}
const statusColorObj={
"Running":'#165bff',
"Succeeded":'#63a728',
"Pending":'#f981eb',
"Failed":'#c73131',
"Error":'#c73131',
"Terminated":'#8a8a8a',
"Skipped":'#8a8a8a',
"Omitted":'#8a8a8ae',
}
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 items = [ const items = [
{ {
key: '1', key: '1',
label: '日志详情', label: '日志详情',
children: <div style={{height:'740px', children: <div style={{height:'740px',
background:'rgba(234, 234, 234, 0.5)',
color:'rgba(29, 29, 32, 0.8)',
background:'#19253b',
color:'#fff',
fontSize:'14px' fontSize:'14px'
}} dangerouslySetInnerHTML={{ __html: messageItem }}></div>, }} dangerouslySetInnerHTML={{ __html: messageItem }}></div>,
icon:<ProfileOutlined/> icon:<ProfileOutlined/>
@@ -226,11 +255,6 @@ const Props = forwardRef(({onParentChange}, ref) =>{
form.resetFields(); 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)}) 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)}) 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); setOpen(true);
}) })
} }
@@ -238,11 +262,6 @@ const Props = forwardRef(({onParentChange}, ref) =>{
form.resetFields(); 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)}) 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)}) 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); setOpen(true);
} }
// console.log(e.item.getModel().in_parameters); // console.log(e.item.getModel().in_parameters);
@@ -252,7 +271,18 @@ const Props = forwardRef(({onParentChange}, ref) =>{
})); }));
return ( return (
<> <>
<Drawer title="编辑任务" placement="right" closeIcon={false} onClose={onClose} afterOpenChange={afterOpenChange} open={open}>
<Drawer title="任务执行详情" placement="right" closeIcon={false} onClose={onClose} afterOpenChange={afterOpenChange} open={open}>
<div className={Styles.detailBox}>任务名称:{stagingItem.label}</div>
<div className={Styles.detailBox} >执行状态:
<div style={{width:'8px',
height:'8px',
borderRadius:'50%',
marginRight:'6px',
backgroundColor:statusColorObj[stagingItem.experimentStatus]
}}></div>
<span style={{color:statusColorObj[stagingItem.experimentStatus]}}>{statusObj[stagingItem.experimentStatus]}</span></div>
<div className={Styles.detailBox}>启动时间:{momnet(stagingItem.experimentStartTime).format('YYYY-MM-DD HH:mm:ss')}</div>
<div className={Styles.detailBox}>耗时:{stagingItem.experimentEndTime?timers(new Date(stagingItem.experimentEndTime).getTime()-new Date(stagingItem.experimentStartTime).getTime()):timers(new Date().getTime()-new Date(stagingItem.experimentStartTime).getTime())}</div>
<Tabs <Tabs
defaultActiveKey="1" defaultActiveKey="1"
items={items}/> items={items}/>


+ 126
- 12
react-ui/src/pages/Experiment/index.jsx View File

@@ -1,8 +1,8 @@
import React ,{ useState,useEffect,useRef }from 'react'; import React ,{ useState,useEffect,useRef }from 'react';
import { Space, Table, Tag,Button,Modal, Form, Input ,message, Select,} from 'antd'; 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 { PlusOutlined, EditOutlined ,PlayCircleOutlined,DeleteOutlined,FieldTimeOutlined} from '@ant-design/icons';
import {getWorkflow,} from '@/services/pipeline/index.js'
import {getExperiment,runExperiments,getExperimentById,postExperiment,putExperiment,getQueryByExperimentId,deleteExperimentById,deleteQueryByExperimentInsId,putQueryByExperimentInsId} from '@/services/experiment/index.js'
import Styles from './index.less' import Styles from './index.less'
import { useNavigate} from 'react-router-dom'; import { useNavigate} from 'react-router-dom';
import momnet from 'moment' import momnet from 'moment'
@@ -14,9 +14,31 @@ const Experiment = React.FC = () => {
const statusObj={ const statusObj={
"Running":'运行中', "Running":'运行中',
"Succeeded":'成功', "Succeeded":'成功',
"Pending":'等待中',
"Failed":'失败', "Failed":'失败',
"Error":'错误', "Error":'错误',
"Teminated":'终止'
"Terminated":'终止',
"Skipped":'未执行',
"Omitted":'未执行',
}
const statusColorObj={
"Running":'#165bff',
"Succeeded":'#63a728',
"Pending":'#f981eb',
"Failed":'#c73131',
"Error":'#c73131',
"Terminated":'#8a8a8a',
"Skipped":'#8a8a8a',
"Omitted":'#8a8a8ae',
}
const statusImgObj={
'Running':'/assets/images/running-icon.png',
'Succeeded':'/assets/images/success-icon.png',
'Pending':'/assets/images/pending-icon.png',
'Failed':'/assets/images/fail-icon.png',
'Terminated':'/assets/images/omitted-icon.png',
'Skipped':'/assets/images/omitted-icon.png',
'Omitted':'/assets/images/omitted-icon.png',
} }
const [experimentList, setExperimentList] = useState([]); const [experimentList, setExperimentList] = useState([]);
@@ -56,10 +78,11 @@ const Experiment = React.FC = () => {
setExpandedRowKeys(val) setExpandedRowKeys(val)
if(ret.code==200&&ret.data&&ret.data.length>0){ if(ret.code==200&&ret.data&&ret.data.length>0){
setExperimentInList(ret.data) setExperimentInList(ret.data)
getList()
} }
else{ else{
setExperimentInList([]) setExperimentInList([])
getList()
} }
}) })
} }
@@ -157,7 +180,6 @@ const Experiment = React.FC = () => {
if(ret.code==200){ if(ret.code==200){
message.success('运行成功') message.success('运行成功')
getQueryByExperiment(id) getQueryByExperiment(id)
getList()
} }
else{ else{
message.error('运行失败') message.error('运行失败')
@@ -227,8 +249,14 @@ const Experiment = React.FC = () => {
}, },
{ {
title: '最近五次运行状态', title: '最近五次运行状态',
dataIndex: 'state',
key: 'state',
dataIndex: 'status_list',
key: 'status_list',
render: (text) => {

let newText=text&&text.replace(/\s+/g,'').split(',')
console.log(newText);
return <>{ newText&&newText.length>0?newText.map((item,index)=>{console.log(item,statusImgObj[item]); return <img style={{width:'17px',marginRight:'6px'}} key={index} src={statusImgObj[item]} />}):null}</>
}
}, },
{ {
@@ -258,7 +286,41 @@ const Experiment = React.FC = () => {
> >
编辑 编辑
</Button> </Button>

<Button
type="link"
size="small"
danger
key="batchRemove"
icon = {< DeleteOutlined />}
onClick={async () => {
Modal.confirm({
title: '删除',
content: '确定删除该条实验吗?',
okText: '确认',
cancelText: '取消',
onOk: () => {
console.log(record);
deleteExperimentById(record.id).then(ret=>{
if(ret.code==200){
message.success('删除成功')
getList()
}
else{
message.error(ret.msg)
}
});
// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
// }
// }
},
});
}}
>
删除
</Button>
</Space> </Space>
), ),
}, },
@@ -278,14 +340,66 @@ const Experiment = React.FC = () => {
<div style={{width:'200px'}}>状态</div> <div style={{width:'200px'}}>状态</div>
<div style={{width:'300px'}}>运行时长</div> <div style={{width:'300px'}}>运行时长</div>
<div style={{width:'300px'}}>开始时间</div> <div style={{width:'300px'}}>开始时间</div>
<div style={{width:'300px'}}>操作</div>
</div>:''} </div>:''}
{experimentInList&&experimentInList.length>0?experimentInList.map((item,index)=>( {experimentInList&&experimentInList.length>0?experimentInList.map((item,index)=>(
<div className={Styles.tableExpandBox} style={{border:'1px solid #eaeaea',backgroundColor:'#fff',height:'45px'}}> <div className={Styles.tableExpandBox} style={{border:'1px solid #eaeaea',backgroundColor:'#fff',height:'45px'}}>
<a style={{width:'50px'}} onClick={(e)=>routerToText(e,item,record)}>{index+1}</a> <a style={{width:'50px'}} onClick={(e)=>routerToText(e,item,record)}>{index+1}</a>
<div style={{width:'200px'}}>{statusObj[item.status]}</div>
<div style={{width:'300px'}}>{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())}</div>
<div style={{width:'300px'}}>{momnet(item.start_time).format('YYYY-MM-DD HH:mm:ss')}</div>
<div className={Styles.statusBox} style={{width:'200px'}}><img style={{width:'17px',marginRight:'7px'}} src={statusImgObj[item.status]}/> <span style={{color:statusColorObj[item.status]}} className={Styles.statusIcon}>{statusObj[item.status]}</span></div>
<div style={{width:'300px'}}>{item.finish_time?timers(new Date(item.finish_time).getTime()-new Date(item.create_time).getTime()):timers(new Date().getTime()-new Date(item.create_time).getTime())}</div>
<div style={{width:'300px'}}>{momnet(item.create_time).format('YYYY-MM-DD HH:mm:ss')}</div>
<div style={{width:'300px'}}>
<Button
type="link"
size="small"
key="batchRemove"
disabled={item.status=='Succeeded'||item.status=='Failed'||item.status=='Terminated'}
icon = {<FieldTimeOutlined />}
onClick={async () => {
putQueryByExperimentInsId(item.id).then(ret=>{
if(ret.code==200){
message.success('终止成功')
getQueryByExperiment(record.id)
}
else{
message.error(ret.msg)
}
})
}}
>
终止
</Button>
<Button
type="link"
size="small"
danger
key="batchRemove"
disabled={item.status=='Running'||item.status=='Pending'}
icon = {< DeleteOutlined />}
onClick={async () => {
Modal.confirm({
title: '删除',
content: '确定删除该条实例吗?',
okText: '确认',
cancelText: '取消',
onOk: () => {
deleteQueryByExperimentInsId(item.id).then(ret=>{
if(ret.code==200){
message.success('删除成功')
getQueryByExperiment(record.id)
}
else{
message.error(ret.msg)
}
});
},
});
}}
>
删除
</Button>
</div>
</div> </div>
)):''} )):''}
</div> </div>


+ 12
- 0
react-ui/src/pages/Experiment/index.less View File

@@ -32,4 +32,16 @@
font-size:15px; font-size:15px;
padding: 0 65px 0 40px; padding: 0 65px 0 40px;
}
.statusBox{
display: flex;
align-items: center;

.statusIcon{
visibility: hidden;
transition: all 0.2s;
}
}
.statusBox:hover .statusIcon{
visibility: visible;
} }

+ 44
- 1
react-ui/src/pages/Pipeline/editPipeline/index.jsx View File

@@ -13,6 +13,7 @@ import { useNavigate} from 'react-router-dom';
const editPipeline = React.FC = () => { const editPipeline = React.FC = () => {
const propsRef=useRef() const propsRef=useRef()
const navgite=useNavigate(); const navgite=useNavigate();
const [contextMenu,setContextMenu]=useState({})
const locationParams =useParams () //新版本获取路由参数接口 const locationParams =useParams () //新版本获取路由参数接口
let graph=null let graph=null
const pipelineContainer = useEmotionCss(() => { const pipelineContainer = useEmotionCss(() => {
@@ -30,6 +31,7 @@ const editPipeline = React.FC = () => {
}; };
}); });
const graphRef=useRef() const graphRef=useRef()
const onDragEnd=(val)=>{ const onDragEnd=(val)=>{
console.log(val,'eee'); console.log(val,'eee');
const _x = val.x const _x = val.x
@@ -117,9 +119,49 @@ const editPipeline = React.FC = () => {
// graph.render() // graph.render()
}) })
} }
const handlerContextMenu=(e)=> {
e.stopPropagation();
// this.menuType = e.item._cfg.type;
}
const initMenu=()=> {
// const selectedNodes = this.selectedNodes;
setContextMenu(new G6.Menu({
getContent(evt) {
console.log(11111, evt);
let ul = `<ul>
<li class="rightmenu-item" code="undo" disabled>撤销</li>
<li class="rightmenu-item" code="redo" >恢复</li>
<li class="rightmenu-item" code="delete" >删除</li>
`;
},
handleMenuClick:(target, item) => {
switch (target.getAttribute('code')) {
// case 'undo':
// this.$emit('handleMenuCall', { code: 'undo' });
// break;
// case 'redo':
// this.$emit('handleMenuCall', { code: 'redo' });
// break;
case 'delete':
graph.removeItem(item);
break;
default:
break;
}
},
offsetX: 16 + 20,
offsetY: 0,
itemTypes: ['node', 'canvas', 'edge'],
}));
};
useEffect(()=>{ useEffect(()=>{
getFirstWorkflow(locationParams.id) getFirstWorkflow(locationParams.id)
initGraph() initGraph()
initMenu()
},[]) },[])
const initGraph=()=>{ const initGraph=()=>{
G6.registerNode( G6.registerNode(
@@ -224,7 +266,7 @@ const editPipeline = React.FC = () => {
animate: false, animate: false,
groupByTypes: false, groupByTypes: false,
fitView:true, fitView:true,
plugins: [],
plugins: [contextMenu],
enabledStack: true, enabledStack: true,
modes: { modes: {
default: [ default: [
@@ -345,6 +387,7 @@ const editPipeline = React.FC = () => {
}); });
}); });
}); });
graph.on('contextmenu', handlerContextMenu);
window.onresize = () => { window.onresize = () => {
if (!graph || graph.get('destroyed')) return; if (!graph || graph.get('destroyed')) return;
if (!graphRef.current || !graphRef.current.scrollWidth || !graphRef.current.scrollHeight) return; if (!graphRef.current || !graphRef.current.scrollWidth || !graphRef.current.scrollHeight) return;


+ 4
- 2
react-ui/src/pages/Pipeline/editPipeline/props.jsx View File

@@ -49,8 +49,8 @@ const Props = forwardRef(({onParentChange}, ref) =>{
}; };
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
showDrawer (e) { showDrawer (e) {
console.log(e.item.getModel());
// console.log(e.item.getModel().in_parameters);
if(e.item&&e.item.getModel()){
// console.log(e.item.getModel().in_parameters);
form.resetFields(); 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)}) 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)}) 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)})
@@ -60,6 +60,8 @@ const Props = forwardRef(({onParentChange}, ref) =>{
// console.log(stagingItem); // console.log(stagingItem);
// }, (500)); // }, (500));
setOpen(true); setOpen(true);
}
}, },
})); }));


+ 18
- 0
react-ui/src/services/experiment/index.js View File

@@ -21,12 +21,30 @@ export function getExperimentById(id) {
method: 'GET', method: 'GET',
}); });
} }
// 根据id删除实验
export function deleteExperimentById(id) {
return request(`/api/mmp/experiment/${id}`, {
method: 'DELETE',
});
}
// 根据id查询实验实例 // 根据id查询实验实例
export function getQueryByExperimentId(id) { export function getQueryByExperimentId(id) {
return request(`/api/mmp/experimentIns/queryByExperimentId/${id}`, { return request(`/api/mmp/experimentIns/queryByExperimentId/${id}`, {
method: 'GET', method: 'GET',
}); });
} }
// 根据id删除实验实例
export function deleteQueryByExperimentInsId(id) {
return request(`/api/mmp/experimentIns/${id}`, {
method: 'DELETE',
});
}
// 根据id终止实验实例
export function putQueryByExperimentInsId(id) {
return request(`/api/mmp/experimentIns/${id}`, {
method: 'PUT',
});
}
// 根据id查询查询日志 // 根据id查询查询日志
export function getQueryByExperimentLog(params) { export function getQueryByExperimentLog(params) {
return request(`/api/mmp/experimentIns/log/`, { return request(`/api/mmp/experimentIns/log/`, {


+ 4
- 3
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/experiment/ExperimentController.java View File

@@ -10,6 +10,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;


/** /**
* (Experiment)表控制层 * (Experiment)表控制层
@@ -42,7 +43,7 @@ public class ExperimentController {


@GetMapping(("/status")) @GetMapping(("/status"))
@ApiOperation("查询实验状态") @ApiOperation("查询实验状态")
public AjaxResult selectStatus(@RequestBody Experiment experiment, PageRequest pageRequest){
public AjaxResult selectStatus(@RequestBody Experiment experiment, PageRequest pageRequest) throws IOException {
return AjaxResult.success(this.experimentService.selectStatus(experiment, pageRequest)); return AjaxResult.success(this.experimentService.selectStatus(experiment, pageRequest));
} }


@@ -61,7 +62,7 @@ public class ExperimentController {
*/ */
@GetMapping("{id}") @GetMapping("{id}")
@ApiOperation("通过id查询实验") @ApiOperation("通过id查询实验")
public AjaxResult queryById(@PathVariable("id") Integer id) {
public AjaxResult queryById(@PathVariable("id") Integer id) throws IOException {
return AjaxResult.success(this.experimentService.queryById(id)); return AjaxResult.success(this.experimentService.queryById(id));
} }


@@ -85,7 +86,7 @@ public class ExperimentController {
*/ */
@PutMapping @PutMapping
@ApiOperation("编辑实验") @ApiOperation("编辑实验")
public AjaxResult edit(@RequestBody Experiment experiment) {
public AjaxResult edit(@RequestBody Experiment experiment) throws IOException {
return AjaxResult.success(this.experimentService.update(experiment)); return AjaxResult.success(this.experimentService.update(experiment));
} }




+ 5
- 4
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/experiment/ExperimentInsController.java View File

@@ -9,6 +9,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map; import java.util.Map;


/** /**
@@ -35,7 +36,7 @@ public class ExperimentInsController {
*/ */
@GetMapping @GetMapping
@ApiOperation("分页查询") @ApiOperation("分页查询")
public AjaxResult queryByPage(ExperimentIns experimentIns, int page, int size) {
public AjaxResult queryByPage(ExperimentIns experimentIns, int page, int size) throws IOException {
PageRequest pageRequest = PageRequest.of(page,size); PageRequest pageRequest = PageRequest.of(page,size);
return AjaxResult.success(this.experimentInsService.queryByPage(experimentIns, pageRequest)); return AjaxResult.success(this.experimentInsService.queryByPage(experimentIns, pageRequest));
} }
@@ -48,7 +49,7 @@ public class ExperimentInsController {
*/ */
@GetMapping("{id}") @GetMapping("{id}")
@ApiOperation("通过id查询实验实例") @ApiOperation("通过id查询实验实例")
public AjaxResult queryById(@PathVariable("id") Integer id) {
public AjaxResult queryById(@PathVariable("id") Integer id) throws IOException {
return AjaxResult.success(this.experimentInsService.queryById(id)); return AjaxResult.success(this.experimentInsService.queryById(id));
} }


@@ -60,7 +61,7 @@ public class ExperimentInsController {
*/ */
@GetMapping("/queryByExperimentId/{Experiment_id}") @GetMapping("/queryByExperimentId/{Experiment_id}")
@ApiOperation("通过实验id查询查询实验实例列表") @ApiOperation("通过实验id查询查询实验实例列表")
public AjaxResult queryByExperimentId(@PathVariable("Experiment_id") Integer experimentId) {
public AjaxResult queryByExperimentId(@PathVariable("Experiment_id") Integer experimentId) throws IOException {
return AjaxResult.success(this.experimentInsService.getByExperimentId(experimentId)); return AjaxResult.success(this.experimentInsService.getByExperimentId(experimentId));
} }


@@ -84,7 +85,7 @@ public class ExperimentInsController {
*/ */
@PutMapping @PutMapping
@ApiOperation("编辑实验实例") @ApiOperation("编辑实验实例")
public AjaxResult edit(@RequestBody ExperimentIns experimentIns) {
public AjaxResult edit(@RequestBody ExperimentIns experimentIns) throws IOException {
return AjaxResult.success(this.experimentInsService.update(experimentIns)); return AjaxResult.success(this.experimentInsService.update(experimentIns));
} }




+ 8
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Experiment.java View File

@@ -33,6 +33,8 @@ public class Experiment implements Serializable {
*/ */
@ApiModelProperty(name = "global_param") @ApiModelProperty(name = "global_param")
private String globalParam; private String globalParam;

private String statusList;
/** /**
* 简介 * 简介
*/ */
@@ -100,7 +102,13 @@ public class Experiment implements Serializable {
this.globalParam = globalParam; this.globalParam = globalParam;
} }


public String getStatusList() {
return statusList;
}


public void setStatusList(String statusList) {
this.statusList = statusList;
}


public String getCreateBy() { public String getCreateBy() {
return createBy; return createBy;


+ 5
- 4
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ExperimentInsService.java View File

@@ -4,6 +4,7 @@ import com.ruoyi.platform.domain.ExperimentIns;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;


import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;


@@ -21,7 +22,7 @@ public interface ExperimentInsService {
* @param id 主键 * @param id 主键
* @return 实例对象 * @return 实例对象
*/ */
ExperimentIns queryById(Integer id);
ExperimentIns queryById(Integer id) throws IOException;






@@ -31,7 +32,7 @@ public interface ExperimentInsService {
* @param experimentId 实验id,不是实例id * @param experimentId 实验id,不是实例id
* @return 实例列表 * @return 实例列表
*/ */
List<ExperimentIns> getByExperimentId(Integer experimentId);
List<ExperimentIns> getByExperimentId(Integer experimentId) throws IOException;


/** /**
* 分页查询 * 分页查询
@@ -40,7 +41,7 @@ public interface ExperimentInsService {
* @param pageRequest 分页对象 * @param pageRequest 分页对象
* @return 查询结果 * @return 查询结果
*/ */
Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest);
Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) throws IOException;


/** /**
* 新增数据 * 新增数据
@@ -56,7 +57,7 @@ public interface ExperimentInsService {
* @param experimentIns 实例对象 * @param experimentIns 实例对象
* @return 实例对象 * @return 实例对象
*/ */
ExperimentIns update(ExperimentIns experimentIns);
ExperimentIns update(ExperimentIns experimentIns) throws IOException;








+ 4
- 3
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ExperimentService.java View File

@@ -5,6 +5,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;


import java.io.IOException;
import java.util.List; import java.util.List;


/** /**
@@ -21,7 +22,7 @@ public interface ExperimentService {
* @param id 主键 * @param id 主键
* @return 实例对象 * @return 实例对象
*/ */
Experiment queryById(Integer id);
Experiment queryById(Integer id) throws IOException;


/** /**
* 分页查询 * 分页查询
@@ -46,7 +47,7 @@ public interface ExperimentService {
* @param experiment 实例对象 * @param experiment 实例对象
* @return 实例对象 * @return 实例对象
*/ */
Experiment update(Experiment experiment);
Experiment update(Experiment experiment) throws IOException;


/** /**
* 通过主键删除数据 * 通过主键删除数据
@@ -67,7 +68,7 @@ public interface ExperimentService {
* @param pageRequest 分页对象 * @param pageRequest 分页对象
* @return 查询结果 * @return 查询结果
*/ */
Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest);
Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest) throws IOException;








+ 65
- 30
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java View File

@@ -1,6 +1,7 @@
package com.ruoyi.platform.service.impl; package com.ruoyi.platform.service.impl;


import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.domain.Experiment;
import com.ruoyi.platform.domain.ExperimentIns; import com.ruoyi.platform.domain.ExperimentIns;
import com.ruoyi.platform.mapper.ExperimentDao; import com.ruoyi.platform.mapper.ExperimentDao;
import com.ruoyi.platform.mapper.ExperimentInsDao; import com.ruoyi.platform.mapper.ExperimentInsDao;
@@ -18,6 +19,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;


import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;


@@ -55,12 +57,12 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
* @return 实例对象 * @return 实例对象
*/ */
@Override @Override
public ExperimentIns queryById(Integer id) {
public ExperimentIns queryById(Integer id) throws IOException {
ExperimentIns experimentIns = this.experimentInsDao.queryById(id); ExperimentIns experimentIns = this.experimentInsDao.queryById(id);
if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns.getStatus())) {
if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) {
experimentIns = this.queryStatusFromArgo(experimentIns); experimentIns = this.queryStatusFromArgo(experimentIns);
//只有当新状态是终止态时才更新数据库 //只有当新状态是终止态时才更新数据库
if (isTerminatedState(experimentIns.getStatus())) {
if (isTerminatedState(experimentIns)) {
//同时更新各个节点 //同时更新各个节点
this.update(experimentIns); this.update(experimentIns);
} }
@@ -77,17 +79,21 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
* @return 实验列表 * @return 实验列表
*/ */
@Override @Override
public List<ExperimentIns> getByExperimentId(Integer experimentId) {
public List<ExperimentIns> getByExperimentId(Integer experimentId) throws IOException {
List<ExperimentIns> experimentInsList = experimentInsDao.getByExperimentId(experimentId); List<ExperimentIns> experimentInsList = experimentInsDao.getByExperimentId(experimentId);

//搞个标记,当状态改变才去改表
boolean flag = false;
List<ExperimentIns> result = new ArrayList<ExperimentIns>(); List<ExperimentIns> result = new ArrayList<ExperimentIns>();
if (experimentInsList!=null&&experimentInsList.size()>0) { if (experimentInsList!=null&&experimentInsList.size()>0) {
for (ExperimentIns experimentIns : experimentInsList) { for (ExperimentIns experimentIns : experimentInsList) {
//当原本状态为null或非终止态时才调用argo接口 //当原本状态为null或非终止态时才调用argo接口
if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns.getStatus())) {
if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) {
experimentIns = this.queryStatusFromArgo(experimentIns); experimentIns = this.queryStatusFromArgo(experimentIns);
if (!flag){
flag = true;
}
//只有当新状态是终止态时才更新数据库 //只有当新状态是终止态时才更新数据库
if (isTerminatedState(experimentIns.getStatus())) {
if (isTerminatedState(experimentIns)) {
//同时更新各个节点 //同时更新各个节点
this.update(experimentIns); this.update(experimentIns);
} }
@@ -96,6 +102,17 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
} }
} }


if (flag) {
List<String> statusList = new ArrayList<String>();
// 更新实验状态列表
for (int i=0;i<result.size();i++){
statusList.add(result.get(i).getStatus());
}
Experiment experiment = experimentDao.queryById(experimentId);
experiment.setStatusList(statusList.toString().substring(1, statusList.toString().length()-1));
experimentDao.update(experiment);
}

return result; return result;


} }
@@ -108,7 +125,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
* @return 查询结果 * @return 查询结果
*/ */
@Override @Override
public Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) {
public Page<ExperimentIns> queryByPage(ExperimentIns experimentIns, PageRequest pageRequest) throws IOException {
long total = this.experimentInsDao.count(experimentIns); long total = this.experimentInsDao.count(experimentIns);
List<ExperimentIns> experimentInsList = this.experimentInsDao.queryAllByLimit(experimentIns, pageRequest); List<ExperimentIns> experimentInsList = this.experimentInsDao.queryAllByLimit(experimentIns, pageRequest);
if (experimentInsList!=null && experimentInsList.size()>0) { if (experimentInsList!=null && experimentInsList.size()>0) {
@@ -151,7 +168,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
* @return 实例对象 * @return 实例对象
*/ */
@Override @Override
public ExperimentIns update(ExperimentIns experimentIns) {
public ExperimentIns update(ExperimentIns experimentIns) throws IOException {
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
experimentIns.setUpdateBy(loginUser.getUsername()); experimentIns.setUpdateBy(loginUser.getUsername());
experimentIns.setUpdateTime(new Date()); experimentIns.setUpdateTime(new Date());
@@ -211,8 +228,8 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
String namespace = ins.getArgoInsNs(); String namespace = ins.getArgoInsNs();
String name = ins.getArgoInsName(); String name = ins.getArgoInsName();
Integer id = ins.getId(); Integer id = ins.getId();
ExperimentIns experimentIns = this.experimentInsDao.queryById(id);
// 创建请求数据map // 创建请求数据map
ExperimentIns experimentIns = this.experimentInsDao.queryById(id);
Map<String,Object> requestData = new HashMap<>(); Map<String,Object> requestData = new HashMap<>();
requestData.put("namespace", namespace); requestData.put("namespace", namespace);
requestData.put("name", name); requestData.put("name", name);
@@ -240,11 +257,6 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
if (status == null || status.isEmpty()) { if (status == null || status.isEmpty()) {
throw new RuntimeException("工作流状态为空。"); throw new RuntimeException("工作流状态为空。");
} }
//解析流水线开始时间,开始时间一定存在,所以不需要判断
Date startTime = DateUtils.convertUTCtoShanghaiDate((String) status.get("startedAt"));
experimentIns.setStartTime(startTime);




//解析流水线结束时间 //解析流水线结束时间
String finishedAtString = (String) status.get("finishedAt"); String finishedAtString = (String) status.get("finishedAt");
@@ -255,21 +267,25 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {


// 解析nodes字段,提取节点状态并转换为JSON字符串 // 解析nodes字段,提取节点状态并转换为JSON字符串
Map<String, Object> nodes = (Map<String, Object>) status.get("nodes"); Map<String, Object> nodes = (Map<String, Object>) status.get("nodes");
if (nodes == null || nodes.isEmpty()) {
throw new RuntimeException("工作流的节点数据为空。");
}

Map<String, Object> modifiedNodes = new LinkedHashMap<>(); Map<String, Object> modifiedNodes = new LinkedHashMap<>();

for (Map.Entry<String, Object> nodeEntry : nodes.entrySet()) {
Map<String,Object> nodeDetails = (Map<String, Object>) nodeEntry.getValue();
String templateName = (String) nodeDetails.get("displayName");
modifiedNodes.put(templateName, nodeDetails);
if (nodes != null ) {
for (Map.Entry<String, Object> nodeEntry : nodes.entrySet()) {
Map<String,Object> nodeDetails = (Map<String, Object>) nodeEntry.getValue();
String templateName = (String) nodeDetails.get("displayName");
modifiedNodes.put(templateName, nodeDetails);
}
} }


String nodeStatusJson = JsonUtils.mapToJson(modifiedNodes); String nodeStatusJson = JsonUtils.mapToJson(modifiedNodes);
experimentIns.setNodesStatus(nodeStatusJson); experimentIns.setNodesStatus(nodeStatusJson);
experimentIns.setStatus((String) status.get("phase"));

//终止态为终止不改
if (!StringUtils.equals(experimentIns.getStatus(),"Terminated")) {
experimentIns.setStatus(StringUtils.isNotEmpty((String) status.get("phase"))?(String) status.get("phase"):"Pending");
}
if (StringUtils.equals(experimentIns.getStatus(),"Error")) {
experimentIns.setStatus("Failed");
}


return experimentIns; return experimentIns;


@@ -328,9 +344,11 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
// 从响应Map中直接获取"errCode"的值 // 从响应Map中直接获取"errCode"的值
Integer errCode = (Integer) runResMap.get("errCode"); Integer errCode = (Integer) runResMap.get("errCode");
if (errCode != null && errCode == 0) { if (errCode != null && errCode == 0) {
experimentIns.setStatus("Terminated");
//更新experimentIns,确保状态更新被保存到数据库 //更新experimentIns,确保状态更新被保存到数据库
this.experimentInsDao.update(experimentIns);
ExperimentIns ins = queryStatusFromArgo(experimentIns);
ins.setStatus("Terminated");
ins.setFinishTime(new Date());
this.experimentInsDao.update(ins);
return true; return true;
} else { } else {
return false; return false;
@@ -394,10 +412,27 @@ public class ExperimentInsServiceImpl implements ExperimentInsService {
} }
} }


private boolean isTerminatedState(String state) {
private boolean isTerminatedState(ExperimentIns ins) throws IOException {
// 定义终止态的列表,例如 "Succeeded", "Failed" 等 // 定义终止态的列表,例如 "Succeeded", "Failed" 等
List<String> terminatedStates = Arrays.asList("Succeeded", "Failed", "Terminated");
return terminatedStates.contains(state);
String status = ins.getStatus();
boolean flag = true;
List<String> terminatedStates = Arrays.asList("Succeeded", "Failed");
flag = terminatedStates.contains(status);
if (StringUtils.equals(status, "Terminated")){
//如果跟node_status里面不一样,就要去更新node_status的信息
String nodesStatus = ins.getNodesStatus();
Map<String, Object> nodeMap = JsonUtils.jsonToMap(nodesStatus);
String keyStartsWithWorkflow = nodeMap.keySet().stream()
.filter(key -> key.startsWith("workflow-"))
.findFirst()
.orElse(null);
Map workflowMap = (Map) nodeMap.get(keyStartsWithWorkflow);
if (workflowMap != null){
flag = StringUtils.equals("Terminated", (String) workflowMap.get("phase"));
}
}

return flag;
} }


} }

+ 4
- 3
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java View File

@@ -23,6 +23,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;


import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.*; import java.util.*;


/** /**
@@ -66,7 +67,7 @@ public class ExperimentServiceImpl implements ExperimentService {
* @return 实例对象 * @return 实例对象
*/ */
@Override @Override
public Experiment queryById(Integer id) {
public Experiment queryById(Integer id) throws IOException {
List<ExperimentIns> experimentInsList = this.experimentInsService.getByExperimentId(id); List<ExperimentIns> experimentInsList = this.experimentInsService.getByExperimentId(id);
Experiment experiment = this.experimentDao.queryById(id); Experiment experiment = this.experimentDao.queryById(id);
if (experiment == null) { if (experiment == null) {
@@ -106,7 +107,7 @@ public class ExperimentServiceImpl implements ExperimentService {
* @param pageRequest 分页对象 * @param pageRequest 分页对象
* @return 查询结果 * @return 查询结果
*/ */
public Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest) {
public Page<Experiment> selectStatus(Experiment experiment, PageRequest pageRequest) throws IOException {
List<Experiment> experimentList = this.experimentDao.queryAllByLimit(experiment, pageRequest); List<Experiment> experimentList = this.experimentDao.queryAllByLimit(experiment, pageRequest);
// 存储所有实验的ID列表 // 存储所有实验的ID列表
List<Integer> experimentIds = new ArrayList<>(); List<Integer> experimentIds = new ArrayList<>();
@@ -144,7 +145,7 @@ public class ExperimentServiceImpl implements ExperimentService {
* @return 实例对象 * @return 实例对象
*/ */
@Override @Override
public Experiment update(Experiment experiment) {
public Experiment update(Experiment experiment) throws IOException {
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
experiment.setUpdateBy(loginUser.getUsername()); experiment.setUpdateBy(loginUser.getUsername());
experiment.setUpdateTime(new Date()); experiment.setUpdateTime(new Date());


+ 22
- 9
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentDaoMapper.xml View File

@@ -7,6 +7,7 @@
<result property="name" column="name" jdbcType="VARCHAR"/> <result property="name" column="name" jdbcType="VARCHAR"/>
<result property="workflowId" column="workflow_id" jdbcType="INTEGER"/> <result property="workflowId" column="workflow_id" jdbcType="INTEGER"/>
<result property="globalParam" column="global_param" jdbcType="VARCHAR"/> <result property="globalParam" column="global_param" jdbcType="VARCHAR"/>
<result property="statusList" column="status_list" jdbcType="VARCHAR"/>
<result property="description" column="description" jdbcType="VARCHAR"/> <result property="description" column="description" jdbcType="VARCHAR"/>
<result property="createBy" column="create_by" jdbcType="VARCHAR"/> <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
@@ -18,7 +19,7 @@
<!--查询单个--> <!--查询单个-->
<select id="queryById" resultMap="ExperimentMap"> <select id="queryById" resultMap="ExperimentMap">
select select
id, name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state
id, name,workflow_id, global_param, status_list,status_list, description, create_by, create_time, update_by, update_time, state
from experiment from experiment
where id = #{id} and state = 1 where id = #{id} and state = 1
</select> </select>
@@ -26,7 +27,7 @@
<!--根据experiment查询--> <!--根据experiment查询-->
<select id="queryByExperiment" resultMap="ExperimentMap"> <select id="queryByExperiment" resultMap="ExperimentMap">
select select
id,name, workflow_id, global_param, description, create_by, create_time, update_by, update_time, state
id,name, workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state
from experiment from experiment
<where> <where>
state = 1 state = 1
@@ -42,6 +43,9 @@
<if test="experiment.globalParam != null and experiment.globalParam != ''"> <if test="experiment.globalParam != null and experiment.globalParam != ''">
and global_param = #{experiment.globalParam} and global_param = #{experiment.globalParam}
</if> </if>
<if test="experiment.statusList != null and experiment.statusList != ''">
status_list = #{experiment.statusList},
</if>
<if test="experiment.description != null and experiment.description != ''"> <if test="experiment.description != null and experiment.description != ''">
and description = #{experiment.description} and description = #{experiment.description}
</if> </if>
@@ -63,7 +67,7 @@
<!--查询指定行数据--> <!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="ExperimentMap"> <select id="queryAllByLimit" resultMap="ExperimentMap">
select select
id,name, workflow_id, global_param, description, create_by, create_time, update_by, update_time, state
id,name, workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state
from experiment from experiment
<where> <where>
state = 1 state = 1
@@ -79,6 +83,9 @@
<if test="experiment.globalParam != null and experiment.globalParam != ''"> <if test="experiment.globalParam != null and experiment.globalParam != ''">
and global_param = #{experiment.globalParam} and global_param = #{experiment.globalParam}
</if> </if>
<if test="experiment.statusList != null and experiment.statusList != ''">
status_list = #{experiment.statusList},
</if>
<if test="experiment.description != null and experiment.description != ''"> <if test="experiment.description != null and experiment.description != ''">
and description = #{experiment.description} and description = #{experiment.description}
</if> </if>
@@ -117,6 +124,9 @@
<if test="experiment.globalParam != null and experiment.globalParam != ''"> <if test="experiment.globalParam != null and experiment.globalParam != ''">
and global_param = #{experiment.globalParam} and global_param = #{experiment.globalParam}
</if> </if>
<if test="experiment.statusList != null and experiment.statusList != ''">
status_list = #{experiment.statusList},
</if>
<if test="experiment.description != null and experiment.description != ''"> <if test="experiment.description != null and experiment.description != ''">
and description = #{experiment.description} and description = #{experiment.description}
</if> </if>
@@ -137,24 +147,24 @@


<!--新增所有列--> <!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true"> <insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into experiment(name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state)
values (#{name},#{workflowId}, #{globalParam}, #{description}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state})
insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state)
values (#{name},#{workflowId}, #{globalParam},#{statusList}, #{description}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state})
</insert> </insert>


<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into experiment(name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state)
insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state)
values values
<foreach collection="entities" item="entity" separator=","> <foreach collection="entities" item="entity" separator=",">
(#{entity.name},#{entity.workflowId}, #{entity.globalParam}, #{entity.description}, #{entity.createBy}, #{entity.createTime},
(#{entity.name},#{entity.workflowId}, #{entity.globalParam},#{entity.statusList}, #{entity.description}, #{entity.createBy}, #{entity.createTime},
#{entity.updateBy}, #{entity.updateTime}, #{entity.state}) #{entity.updateBy}, #{entity.updateTime}, #{entity.state})
</foreach> </foreach>
</insert> </insert>


<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true"> <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into experiment(name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state)
insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state)
values values
<foreach collection="entities" item="entity" separator=","> <foreach collection="entities" item="entity" separator=",">
(#{entity.name},#{entity.workflowId}, #{entity.globalParam}, #{entity.description}, #{entity.createBy}, #{entity.createTime},
(#{entity.name},#{entity.workflowId}, #{entity.globalParam}, #{entity.statusList}, #{entity.description}, #{entity.createBy}, #{entity.createTime},
#{entity.updateBy}, #{entity.updateTime}, #{entity.state}) #{entity.updateBy}, #{entity.updateTime}, #{entity.state})
</foreach> </foreach>
on duplicate key update on duplicate key update
@@ -182,6 +192,9 @@
<if test="globalParam != null and globalParam != ''"> <if test="globalParam != null and globalParam != ''">
global_param = #{globalParam}, global_param = #{globalParam},
</if> </if>
<if test="statusList != null and statusList != ''">
status_list = #{statusList},
</if>
<if test="description != null and description != ''"> <if test="description != null and description != ''">
description = #{description}, description = #{description},
</if> </if>


Loading…
Cancel
Save