| @@ -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; | |||||
| } | } | ||||
| @@ -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> | ||||
| @@ -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}/> | ||||
| @@ -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> | ||||
| @@ -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; | |||||
| } | } | ||||
| @@ -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; | ||||
| @@ -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); | ||||
| } | |||||
| }, | }, | ||||
| })); | })); | ||||
| @@ -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/`, { | ||||
| @@ -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)); | ||||
| } | } | ||||
| @@ -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)); | ||||
| } | } | ||||
| @@ -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; | ||||
| @@ -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; | |||||
| @@ -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; | |||||
| @@ -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; | |||||
| } | } | ||||
| } | } | ||||
| @@ -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()); | ||||
| @@ -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> | ||||