| @@ -21,6 +21,7 @@ import './styles/menu.less'; | |||||
| export { requestConfig as request } from './requestConfig'; | export { requestConfig as request } from './requestConfig'; | ||||
| // const isDev = process.env.NODE_ENV === 'development'; | // const isDev = process.env.NODE_ENV === 'development'; | ||||
| import { menuItemRender } from '@/utils/menuRender'; | import { menuItemRender } from '@/utils/menuRender'; | ||||
| import { gotoLoginPage } from './utils/ui'; | |||||
| /** | /** | ||||
| * @see https://umijs.org/zh-CN/plugins/plugin-initial-state | * @see https://umijs.org/zh-CN/plugins/plugin-initial-state | ||||
| * */ | * */ | ||||
| @@ -45,7 +46,7 @@ export async function getInitialState(): Promise<{ | |||||
| } as API.CurrentUser; | } as API.CurrentUser; | ||||
| } catch (error) { | } catch (error) { | ||||
| console.log(error); | console.log(error); | ||||
| history.push(PageEnum.LOGIN); | |||||
| gotoLoginPage(); | |||||
| } | } | ||||
| return undefined; | return undefined; | ||||
| }; | }; | ||||
| @@ -97,7 +98,7 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | |||||
| const { location } = history; | const { location } = history; | ||||
| // 如果没有登录,重定向到 login | // 如果没有登录,重定向到 login | ||||
| if (!initialState?.currentUser && location.pathname !== PageEnum.LOGIN) { | if (!initialState?.currentUser && location.pathname !== PageEnum.LOGIN) { | ||||
| history.push(PageEnum.LOGIN); | |||||
| gotoLoginPage(); | |||||
| } | } | ||||
| }, | }, | ||||
| layoutBgImgList: [ | layoutBgImgList: [ | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * @Author: 赵伟 | * @Author: 赵伟 | ||||
| * @Date: 2024-04-15 10:01:29 | * @Date: 2024-04-15 10:01:29 | ||||
| * @Description: | |||||
| * @Description: 自定义 hooks | |||||
| */ | */ | ||||
| import { FormInstance } from 'antd'; | import { FormInstance } from 'antd'; | ||||
| import { debounce } from 'lodash'; | import { debounce } from 'lodash'; | ||||
| @@ -126,3 +126,28 @@ export const useResetFormOnCloseModal = (form: FormInstance, open: boolean) => { | |||||
| } | } | ||||
| }, [form, prevOpen, open]); | }, [form, prevOpen, open]); | ||||
| }; | }; | ||||
| /** | |||||
| * Executes the effect function when the specified condition is true. | |||||
| * | |||||
| * @param effect - The effect function to execute. | |||||
| * @param deps - The dependencies for the effect. | |||||
| * @param when - The condition to trigger the effect. | |||||
| */ | |||||
| export const useEffectWhen = (effect: () => void, deps: React.DependencyList, when: boolean) => { | |||||
| const requestFns = useRef<(() => void)[]>([]); | |||||
| useEffect(() => { | |||||
| if (when) { | |||||
| effect(); | |||||
| } else { | |||||
| requestFns.current.splice(0, 1, effect); | |||||
| } | |||||
| }, deps); | |||||
| useEffect(() => { | |||||
| if (when) { | |||||
| const fn = requestFns.current.pop(); | |||||
| fn?.(); | |||||
| } | |||||
| }, [when]); | |||||
| }; | |||||
| @@ -11,14 +11,21 @@ type ResourceIntroProps = { | |||||
| resourceType: ResourceType; | resourceType: ResourceType; | ||||
| }; | }; | ||||
| enum TabKeys { | |||||
| Introduction = '1', | |||||
| Version = '2', | |||||
| Evolution = '3', | |||||
| } | |||||
| const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | ||||
| const [info, setInfo] = useState<ResourceData>({} as ResourceData); | const [info, setInfo] = useState<ResourceData>({} as ResourceData); | ||||
| const locationParams = useParams(); | const locationParams = useParams(); | ||||
| const [searchParams] = useSearchParams(); | const [searchParams] = useSearchParams(); | ||||
| const [versionList, setVersionList] = useState([]); | |||||
| const [version, setVersion] = useState<string | undefined>(undefined); | |||||
| const defaultTab = searchParams.get('tab') || '1'; | const defaultTab = searchParams.get('tab') || '1'; | ||||
| let versionParam = searchParams.get('version'); | let versionParam = searchParams.get('version'); | ||||
| const [versionList, setVersionList] = useState([]); | |||||
| const [version, setVersion] = useState<string | undefined>(undefined); | |||||
| const [activeTab, setActiveTab] = useState<string>(defaultTab); | |||||
| const resourceId = Number(locationParams.id); | const resourceId = Number(locationParams.id); | ||||
| const typeName = resourceConfig[resourceType].name; // 数据集/模型 | const typeName = resourceConfig[resourceType].name; // 数据集/模型 | ||||
| @@ -67,7 +74,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| const items = [ | const items = [ | ||||
| { | { | ||||
| key: '1', | |||||
| key: TabKeys.Introduction, | |||||
| label: `${typeName}简介`, | label: `${typeName}简介`, | ||||
| children: ( | children: ( | ||||
| <> | <> | ||||
| @@ -77,7 +84,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| ), | ), | ||||
| }, | }, | ||||
| { | { | ||||
| key: '2', | |||||
| key: TabKeys.Version, | |||||
| label: `${typeName}文件/版本`, | label: `${typeName}文件/版本`, | ||||
| children: ( | children: ( | ||||
| <ResourceVersion | <ResourceVersion | ||||
| @@ -87,6 +94,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| isPublic={info.available_range === 1} | isPublic={info.available_range === 1} | ||||
| versionList={versionList} | versionList={versionList} | ||||
| version={version} | version={version} | ||||
| isActive={activeTab === TabKeys.Version} | |||||
| getVersionList={getVersionList} | getVersionList={getVersionList} | ||||
| onVersionChange={handleVersionChange} | onVersionChange={handleVersionChange} | ||||
| ></ResourceVersion> | ></ResourceVersion> | ||||
| @@ -96,7 +104,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| if (resourceType === ResourceType.Model) { | if (resourceType === ResourceType.Model) { | ||||
| items.push({ | items.push({ | ||||
| key: '3', | |||||
| key: TabKeys.Evolution, | |||||
| label: `模型演化`, | label: `模型演化`, | ||||
| children: ( | children: ( | ||||
| <ModelEvolution | <ModelEvolution | ||||
| @@ -104,6 +112,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| resourceName={info.name} | resourceName={info.name} | ||||
| versionList={versionList} | versionList={versionList} | ||||
| version={version} | version={version} | ||||
| isActive={activeTab === TabKeys.Evolution} | |||||
| onVersionChange={handleVersionChange} | onVersionChange={handleVersionChange} | ||||
| ></ModelEvolution> | ></ModelEvolution> | ||||
| ), | ), | ||||
| @@ -136,7 +145,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| </Flex> | </Flex> | ||||
| </div> | </div> | ||||
| <div className={styles['resource-intro__bottom']}> | <div className={styles['resource-intro__bottom']}> | ||||
| <Tabs defaultActiveKey={defaultTab} items={items}></Tabs> | |||||
| <Tabs activeKey={activeTab} items={items} onChange={(key) => setActiveTab(key)}></Tabs> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -1,14 +1,20 @@ | |||||
| import CommonTableCell from '@/components/CommonTableCell'; | import CommonTableCell from '@/components/CommonTableCell'; | ||||
| import DateTableCell from '@/components/DateTableCell'; | import DateTableCell from '@/components/DateTableCell'; | ||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { useEffectWhen } from '@/hooks'; | |||||
| import AddVersionModal from '@/pages/Dataset/components/AddVersionModal'; | import AddVersionModal from '@/pages/Dataset/components/AddVersionModal'; | ||||
| import { ResourceFileData, ResourceType, resourceConfig } from '@/pages/Dataset/config'; | |||||
| import { | |||||
| ResourceFileData, | |||||
| ResourceType, | |||||
| ResourceVersionData, | |||||
| resourceConfig, | |||||
| } from '@/pages/Dataset/config'; | |||||
| import { downLoadZip } from '@/utils/downloadfile'; | import { downLoadZip } from '@/utils/downloadfile'; | ||||
| import { openAntdModal } from '@/utils/modal'; | import { openAntdModal } from '@/utils/modal'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { App, Button, Flex, Select, Table } from 'antd'; | import { App, Button, Flex, Select, Table } from 'antd'; | ||||
| import { useEffect, useState } from 'react'; | |||||
| import { useState } from 'react'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| type ResourceVersionProps = { | type ResourceVersionProps = { | ||||
| @@ -16,8 +22,9 @@ type ResourceVersionProps = { | |||||
| resourceId: number; | resourceId: number; | ||||
| resourceName: string; | resourceName: string; | ||||
| isPublic: boolean; | isPublic: boolean; | ||||
| versionList: { label: string; value: string }[]; | |||||
| versionList: ResourceVersionData[]; | |||||
| version?: string; | version?: string; | ||||
| isActive: boolean; | |||||
| getVersionList: () => void; | getVersionList: () => void; | ||||
| onVersionChange: (version: string) => void; | onVersionChange: (version: string) => void; | ||||
| }; | }; | ||||
| @@ -28,6 +35,7 @@ function ResourceVersion({ | |||||
| isPublic, | isPublic, | ||||
| versionList, | versionList, | ||||
| version, | version, | ||||
| isActive, | |||||
| getVersionList, | getVersionList, | ||||
| onVersionChange, | onVersionChange, | ||||
| }: ResourceVersionProps) { | }: ResourceVersionProps) { | ||||
| @@ -35,13 +43,17 @@ function ResourceVersion({ | |||||
| const { message } = App.useApp(); | const { message } = App.useApp(); | ||||
| // 获取版本文件列表 | // 获取版本文件列表 | ||||
| useEffect(() => { | |||||
| if (version) { | |||||
| getFileList(version); | |||||
| } else { | |||||
| setFileList([]); | |||||
| } | |||||
| }, [resourceId, version]); | |||||
| useEffectWhen( | |||||
| () => { | |||||
| if (version) { | |||||
| getFileList(version); | |||||
| } else { | |||||
| setFileList([]); | |||||
| } | |||||
| }, | |||||
| [resourceId, version], | |||||
| isActive, | |||||
| ); | |||||
| // 获取版本下的文件列表 | // 获取版本下的文件列表 | ||||
| const getFileList = async (version: string) => { | const getFileList = async (version: string) => { | ||||
| @@ -155,6 +155,12 @@ export type ResourceData = { | |||||
| dataset_tag_name?: string; | dataset_tag_name?: string; | ||||
| }; | }; | ||||
| // 版本数据 | |||||
| export type ResourceVersionData = { | |||||
| label: string; | |||||
| value: string; | |||||
| }; | |||||
| // 版本文件数据 | // 版本文件数据 | ||||
| export type ResourceFileData = { | export type ResourceFileData = { | ||||
| id: number; | id: number; | ||||
| @@ -16,7 +16,7 @@ function DatasetAnnotation() { | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <div className={styles.container}> | <div className={styles.container}> | ||||
| <iframe src={iframeUrl} className={styles.frame}></iframe> | |||||
| {iframeUrl && <iframe src={iframeUrl} className={styles.frame}></iframe>} | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -1,12 +1,13 @@ | |||||
| import { useStateRef, useVisible } from '@/hooks'; | import { useStateRef, useVisible } from '@/hooks'; | ||||
| import { getExperimentIns } from '@/services/experiment/index.js'; | import { getExperimentIns } from '@/services/experiment/index.js'; | ||||
| import { getWorkflowById } from '@/services/pipeline/index.js'; | import { getWorkflowById } from '@/services/pipeline/index.js'; | ||||
| import themes from '@/styles/theme.less'; | |||||
| import { fittingString } from '@/utils'; | |||||
| import { elapsedTime, formatDate } from '@/utils/date'; | import { elapsedTime, formatDate } from '@/utils/date'; | ||||
| import G6 from '@antv/g6'; | import G6 from '@antv/g6'; | ||||
| import { Button } from 'antd'; | import { Button } from 'antd'; | ||||
| import { useEffect, useRef } from 'react'; | import { useEffect, useRef } from 'react'; | ||||
| import { useNavigate, useParams } from 'react-router-dom'; | import { useNavigate, useParams } from 'react-router-dom'; | ||||
| import { s8 } from '../../../utils'; | |||||
| import ParamsModal from '../components/ViewParamsModal'; | import ParamsModal from '../components/ViewParamsModal'; | ||||
| import { experimentStatusInfo } from '../status'; | import { experimentStatusInfo } from '../status'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| @@ -22,27 +23,22 @@ function ExperimentText() { | |||||
| const [paramsModalOpen, openParamsModal, closeParamsModal] = useVisible(false); | const [paramsModalOpen, openParamsModal, closeParamsModal] = useVisible(false); | ||||
| const graphRef = useRef(); | const graphRef = useRef(); | ||||
| const onDragEnd = (val) => { | |||||
| console.log(val, 'eee'); | |||||
| const _x = val.x; | |||||
| const _y = val.y; | |||||
| const point = graph.getPointByClient(_x, _y); | |||||
| let model = {}; | |||||
| // 元模型 | |||||
| model = { | |||||
| ...val, | |||||
| x: point.x, | |||||
| y: point.y, | |||||
| id: val.component_name + '-' + s8(), | |||||
| isCluster: false, | |||||
| }; | |||||
| graph.addItem('node', model, true); | |||||
| }; | |||||
| const handlerClick = (e) => { | |||||
| if (e.target.get('name') !== 'anchor-point' && e.item) { | |||||
| propsRef.current.showDrawer(e, locationParams.id, messageRef.current); | |||||
| } | |||||
| }; | |||||
| // const onDragEnd = (val) => { | |||||
| // console.log(val, 'eee'); | |||||
| // const _x = val.x; | |||||
| // const _y = val.y; | |||||
| // const point = graph.getPointByClient(_x, _y); | |||||
| // let model = {}; | |||||
| // // 元模型 | |||||
| // model = { | |||||
| // ...val, | |||||
| // x: point.x, | |||||
| // y: point.y, | |||||
| // id: val.component_name + '-' + s8(), | |||||
| // isCluster: false, | |||||
| // }; | |||||
| // graph.addItem('node', model, true); | |||||
| // }; | |||||
| const getGraphData = (data) => { | const getGraphData = (data) => { | ||||
| if (graph) { | if (graph) { | ||||
| graph.data(data); | graph.data(data); | ||||
| @@ -89,32 +85,6 @@ function ExperimentText() { | |||||
| }, []); | }, []); | ||||
| const initGraph = () => { | const initGraph = () => { | ||||
| const fittingString = (str, maxWidth, fontSize) => { | |||||
| const ellipsis = '...'; | |||||
| const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0]; | |||||
| let currentWidth = 0; | |||||
| let res = str; | |||||
| const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters | |||||
| str.split('').forEach((letter, i) => { | |||||
| if (currentWidth > maxWidth - ellipsisLength) return; | |||||
| if (pattern.test(letter)) { | |||||
| // Chinese charactors | |||||
| currentWidth += fontSize; | |||||
| } else { | |||||
| // get the width of single letter according to the fontSize | |||||
| currentWidth += G6.Util.getLetterWidth(letter, fontSize); | |||||
| } | |||||
| if (currentWidth > maxWidth - ellipsisLength) { | |||||
| res = `${str.substr(0, i)}${ellipsis}`; | |||||
| } | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| // 获取文本的长度 | |||||
| const getTextSize = (str, maxWidth, fontSize) => { | |||||
| let width = G6.Util.getTextSize(str, fontSize)[0]; | |||||
| return width > maxWidth ? maxWidth : width; | |||||
| }; | |||||
| G6.registerNode( | G6.registerNode( | ||||
| 'rect-node', | 'rect-node', | ||||
| { | { | ||||
| @@ -129,7 +99,6 @@ function ExperimentText() { | |||||
| ); | ); | ||||
| }, | }, | ||||
| afterDraw(cfg, group) { | afterDraw(cfg, group) { | ||||
| // console.log(group, cfg, 12312); | |||||
| const image = group.addShape('image', { | const image = group.addShape('image', { | ||||
| attrs: { | attrs: { | ||||
| x: -45, | x: -45, | ||||
| @@ -158,7 +127,6 @@ function ExperimentText() { | |||||
| } | } | ||||
| const bbox = group.getBBox(); | const bbox = group.getBBox(); | ||||
| const anchorPoints = this.getAnchorPoints(cfg); | const anchorPoints = this.getAnchorPoints(cfg); | ||||
| // console.log(anchorPoints); | |||||
| anchorPoints.forEach((anchorPos, i) => { | anchorPoints.forEach((anchorPos, i) => { | ||||
| group.addShape('circle', { | group.addShape('circle', { | ||||
| attrs: { | attrs: { | ||||
| @@ -179,19 +147,19 @@ function ExperimentText() { | |||||
| // response the state changes and show/hide the link-point circles | // response the state changes and show/hide the link-point circles | ||||
| setState(name, value, item) { | setState(name, value, item) { | ||||
| const anchorPoints = item | |||||
| .getContainer() | |||||
| .findAll((ele) => ele.get('name') === 'anchor-point'); | |||||
| anchorPoints.forEach((point) => { | |||||
| if (value || point.get('links') > 0) point.show(); | |||||
| else point.hide(); | |||||
| }); | |||||
| // } | |||||
| const group = item.getContainer(); | |||||
| const shape = group.get('children')[0]; | |||||
| if (name === 'hover') { | |||||
| if (value) { | |||||
| shape.attr('stroke', themes['primaryColor']); | |||||
| } else { | |||||
| shape.attr('stroke', '#fff'); | |||||
| } | |||||
| } | |||||
| }, | }, | ||||
| }, | }, | ||||
| 'rect', | 'rect', | ||||
| ); | ); | ||||
| console.log(graphRef, 'graphRef'); | |||||
| graph = new G6.Graph({ | graph = new G6.Graph({ | ||||
| container: graphRef.current, | container: graphRef.current, | ||||
| grid: true, | grid: true, | ||||
| @@ -209,10 +177,6 @@ function ExperimentText() { | |||||
| if (e.target.get('name') === 'anchor-point') return false; | if (e.target.get('name') === 'anchor-point') return false; | ||||
| return true; | return true; | ||||
| }, | }, | ||||
| // shouldEnd: e => { | |||||
| // console.log(e); | |||||
| // return false; | |||||
| // }, | |||||
| }, | }, | ||||
| // config the shouldBegin and shouldEnd to make sure the create-edge is began and ended at anchor-point circles | // config the shouldBegin and shouldEnd to make sure the create-edge is began and ended at anchor-point circles | ||||
| 'drag-canvas', | 'drag-canvas', | ||||
| @@ -237,7 +201,6 @@ function ExperimentText() { | |||||
| style: { | style: { | ||||
| fill: '#000', | fill: '#000', | ||||
| fontSize: 10, | fontSize: 10, | ||||
| cursor: 'pointer', | cursor: 'pointer', | ||||
| x: -20, | x: -20, | ||||
| y: 0, | y: 0, | ||||
| @@ -252,17 +215,6 @@ function ExperimentText() { | |||||
| lineWidth: 0.5, | lineWidth: 0.5, | ||||
| }, | }, | ||||
| }, | }, | ||||
| nodeStateStyles: { | |||||
| nodeSelected: { | |||||
| fill: 'red', | |||||
| shadowColor: 'red', | |||||
| stroke: 'red', | |||||
| 'text-shape': { | |||||
| fill: 'red', | |||||
| stroke: 'red', | |||||
| }, | |||||
| }, | |||||
| }, | |||||
| defaultEdge: { | defaultEdge: { | ||||
| // type: 'quadratic', | // type: 'quadratic', | ||||
| type: 'cubic-vertical', | type: 'cubic-vertical', | ||||
| @@ -308,15 +260,25 @@ function ExperimentText() { | |||||
| // linkCenter: true, | // linkCenter: true, | ||||
| fitView: true, | fitView: true, | ||||
| minZoom: 0.5, | minZoom: 0.5, | ||||
| maxZoom: 3, | |||||
| fitViewPadding: [320, 320, 220, 320], | |||||
| maxZoom: 5, | |||||
| fitViewPadding: 300, | |||||
| }); | |||||
| graph.on('node:click', (e) => { | |||||
| if (e.target.get('name') !== 'anchor-point' && e.item) { | |||||
| propsRef.current.showDrawer(e, locationParams.id, messageRef.current); | |||||
| } | |||||
| }); | |||||
| graph.on('node:mouseenter', (e) => { | |||||
| graph.setItemState(e.item, 'hover', true); | |||||
| }); | |||||
| graph.on('node:mouseleave', (e) => { | |||||
| graph.setItemState(e.item, 'hover', false); | |||||
| }); | }); | ||||
| graph.on('node:click', handlerClick); | |||||
| 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; | |||||
| graph.changeSize(graphRef.current.scrollWidth, graphRef.current.scrollHeight - 20); | |||||
| if (!graphRef.current) return; | |||||
| graph.changeSize(graphRef.current.clientWidth, graphRef.current.clientHeight); | |||||
| graph.fitView(); | |||||
| }; | }; | ||||
| }; | }; | ||||
| return ( | return ( | ||||
| @@ -1,3 +1,5 @@ | |||||
| import { useEffectWhen } from '@/hooks'; | |||||
| import { ResourceVersionData } from '@/pages/Dataset/config'; | |||||
| import { getModelAtlasReq } from '@/services/dataset/index.js'; | import { getModelAtlasReq } from '@/services/dataset/index.js'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { changePropertyName, fittingString } from '@/utils'; | import { changePropertyName, fittingString } from '@/utils'; | ||||
| @@ -19,10 +21,11 @@ import { useEffect, useRef, useState } from 'react'; | |||||
| import GraphLegand from '../GraphLegand'; | import GraphLegand from '../GraphLegand'; | ||||
| import NodeTooltips from '../NodeTooltips'; | import NodeTooltips from '../NodeTooltips'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| const nodeWidth = 98; | const nodeWidth = 98; | ||||
| const nodeHeight = 58; | const nodeHeight = 58; | ||||
| const vGap = 30; | |||||
| const hGap = 30; | |||||
| const vGap = 58; | |||||
| const hGap = 58; | |||||
| enum NodeType { | enum NodeType { | ||||
| current = 'current', | current = 'current', | ||||
| @@ -53,7 +56,18 @@ interface ProjectDependency extends NodeConfig { | |||||
| model_type: NodeType; | model_type: NodeType; | ||||
| } | } | ||||
| export interface ModelDepsAPIData { | |||||
| type ModalDetail = { | |||||
| name: string; | |||||
| available_range: number; | |||||
| file_name: string; | |||||
| file_size: string; | |||||
| description: string; | |||||
| model_type_name: string; | |||||
| model_tag_name: string; | |||||
| create_time: string; | |||||
| }; | |||||
| interface ModelDepsAPIData { | |||||
| current_model_id: number; | current_model_id: number; | ||||
| version: string; | version: string; | ||||
| exp_ins_id: number; | exp_ins_id: number; | ||||
| @@ -63,11 +77,12 @@ export interface ModelDepsAPIData { | |||||
| test_dataset: TrainDataset[]; | test_dataset: TrainDataset[]; | ||||
| train_dataset: TrainDataset[]; | train_dataset: TrainDataset[]; | ||||
| train_task: TrainTask; | train_task: TrainTask; | ||||
| model_version_dependcy_vo: ModalDetail; | |||||
| children_models: ModelDepsAPIData[]; | children_models: ModelDepsAPIData[]; | ||||
| parent_models: ModelDepsAPIData[]; | parent_models: ModelDepsAPIData[]; | ||||
| } | } | ||||
| interface ModelDepsData extends Omit<ModelDepsAPIData, 'children_models'>, TreeGraphData { | |||||
| export interface ModelDepsData extends Omit<ModelDepsAPIData, 'children_models'>, TreeGraphData { | |||||
| children: ModelDepsData[]; | children: ModelDepsData[]; | ||||
| } | } | ||||
| @@ -75,10 +90,10 @@ interface ModelDepsData extends Omit<ModelDepsAPIData, 'children_models'>, TreeG | |||||
| function normalizeChildren(data: ModelDepsData[]) { | function normalizeChildren(data: ModelDepsData[]) { | ||||
| if (Array.isArray(data)) { | if (Array.isArray(data)) { | ||||
| data.forEach((item) => { | data.forEach((item) => { | ||||
| item.model_type = NodeType.children; | |||||
| item.id = `$M_${item.current_model_id}_${item.version}`; | item.id = `$M_${item.current_model_id}_${item.version}`; | ||||
| item.label = getLabel(item); | item.label = getLabel(item); | ||||
| item.style = getStyle(NodeType.children); | item.style = getStyle(NodeType.children); | ||||
| item.model_type = NodeType.children; | |||||
| normalizeChildren(item.children); | normalizeChildren(item.children); | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -107,7 +122,7 @@ function getStyle(model_type: NodeType) { | |||||
| fill = '#b7cfff'; | fill = '#b7cfff'; | ||||
| break; | break; | ||||
| case NodeType.project: | case NodeType.project: | ||||
| fill = '#0000ff'; | |||||
| fill = '#FA8C16'; | |||||
| break; | break; | ||||
| case NodeType.trainDataset: | case NodeType.trainDataset: | ||||
| fill = '#ff0000'; | fill = '#ff0000'; | ||||
| @@ -131,11 +146,12 @@ function normalizeTreeData(apiData: ModelDepsAPIData, currentNodeName: string): | |||||
| }) as ModelDepsData; | }) as ModelDepsData; | ||||
| // 设置当前模型的数据 | // 设置当前模型的数据 | ||||
| normalizedData.label = getLabel(normalizedData); | |||||
| normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; | |||||
| normalizedData.style = getStyle(NodeType.current); | |||||
| normalizedData.model_type = NodeType.current; | normalizedData.model_type = NodeType.current; | ||||
| normalizedData.current_model_name = currentNodeName; | normalizedData.current_model_name = currentNodeName; | ||||
| normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; | |||||
| normalizedData.label = getLabel(normalizedData); | |||||
| normalizedData.style = getStyle(NodeType.current); | |||||
| normalizeChildren(normalizedData.children as ModelDepsData[]); | normalizeChildren(normalizedData.children as ModelDepsData[]); | ||||
| // 将 parent_models 转换成树形结构 | // 将 parent_models 转换成树形结构 | ||||
| @@ -144,8 +160,8 @@ function normalizeTreeData(apiData: ModelDepsAPIData, currentNodeName: string): | |||||
| const parent = parent_models[0]; | const parent = parent_models[0]; | ||||
| normalizedData = { | normalizedData = { | ||||
| ...parent, | ...parent, | ||||
| id: `$M_${parent.current_model_id}_${parent.version}`, | |||||
| model_type: NodeType.parent, | model_type: NodeType.parent, | ||||
| id: `$M_${parent.current_model_id}_${parent.version}`, | |||||
| label: getLabel(parent), | label: getLabel(parent), | ||||
| style: getStyle(NodeType.parent), | style: getStyle(NodeType.parent), | ||||
| children: [ | children: [ | ||||
| @@ -166,8 +182,8 @@ function getGraphData(data: ModelDepsData): GraphData { | |||||
| direction: 'LR', | direction: 'LR', | ||||
| getHeight: () => nodeHeight, | getHeight: () => nodeHeight, | ||||
| getWidth: () => nodeWidth, | getWidth: () => nodeWidth, | ||||
| getVGap: () => vGap, | |||||
| getHGap: () => hGap, | |||||
| getVGap: () => vGap / 2, | |||||
| getHGap: () => hGap / 2, | |||||
| }; | }; | ||||
| // 树形布局计算出坐标 | // 树形布局计算出坐标 | ||||
| @@ -210,8 +226,8 @@ function getGraphData(data: ModelDepsData): GraphData { | |||||
| const len = train_dataset.length + test_dataset.length; | const len = train_dataset.length + test_dataset.length; | ||||
| [...train_dataset, ...test_dataset].forEach((item, index) => { | [...train_dataset, ...test_dataset].forEach((item, index) => { | ||||
| const half = len / 2 - 0.5; | const half = len / 2 - 0.5; | ||||
| item.x = node.x! - (half - index) * (nodeWidth + 30); | |||||
| item.y = node.y! - nodeHeight - 30; | |||||
| item.x = node.x! - (half - index) * (nodeWidth + hGap); | |||||
| item.y = node.y! - nodeHeight - vGap; | |||||
| nodes.push(item); | nodes.push(item); | ||||
| edges.push({ | edges.push({ | ||||
| source: node.id, | source: node.id, | ||||
| @@ -222,7 +238,7 @@ function getGraphData(data: ModelDepsData): GraphData { | |||||
| }); | }); | ||||
| }); | }); | ||||
| if (project_dependency.url) { | |||||
| if (project_dependency?.url) { | |||||
| project_dependency.id = `$P_${project_dependency.url}`; | project_dependency.id = `$P_${project_dependency.url}`; | ||||
| project_dependency.model_type = NodeType.project; | project_dependency.model_type = NodeType.project; | ||||
| project_dependency.type = 'rect'; | project_dependency.type = 'rect'; | ||||
| @@ -230,7 +246,7 @@ function getGraphData(data: ModelDepsData): GraphData { | |||||
| project_dependency.label = fittingString(project_dependency.name, 48, 8); | project_dependency.label = fittingString(project_dependency.name, 48, 8); | ||||
| project_dependency.style = getStyle(NodeType.project); | project_dependency.style = getStyle(NodeType.project); | ||||
| project_dependency.x = node.x; | project_dependency.x = node.x; | ||||
| project_dependency.y = node.y! + nodeHeight + 30; | |||||
| project_dependency.y = node.y! + nodeHeight + vGap; | |||||
| nodes.push(project_dependency); | nodes.push(project_dependency); | ||||
| edges.push({ | edges.push({ | ||||
| source: node.id, | source: node.id, | ||||
| @@ -248,8 +264,9 @@ function getGraphData(data: ModelDepsData): GraphData { | |||||
| type modeModelEvolutionProps = { | type modeModelEvolutionProps = { | ||||
| resourceId: number; | resourceId: number; | ||||
| resourceName: string; | resourceName: string; | ||||
| versionList: { label: string; value: string }[]; | |||||
| versionList: ResourceVersionData[]; | |||||
| version?: string; | version?: string; | ||||
| isActive: boolean; | |||||
| onVersionChange: (version: string) => void; | onVersionChange: (version: string) => void; | ||||
| }; | }; | ||||
| @@ -259,6 +276,7 @@ function ModelEvolution({ | |||||
| resourceName, | resourceName, | ||||
| versionList, | versionList, | ||||
| version, | version, | ||||
| isActive, | |||||
| onVersionChange, | onVersionChange, | ||||
| }: modeModelEvolutionProps) { | }: modeModelEvolutionProps) { | ||||
| const graphRef = useRef<HTMLDivElement>(null); | const graphRef = useRef<HTMLDivElement>(null); | ||||
| @@ -283,18 +301,17 @@ function ModelEvolution({ | |||||
| }; | }; | ||||
| }, []); | }, []); | ||||
| useEffect(() => { | |||||
| if (version) { | |||||
| getModelAtlas(); | |||||
| } else { | |||||
| graph.data({ | |||||
| nodes: [], | |||||
| edges: [], | |||||
| }); | |||||
| graph.render(); | |||||
| graph.fitView(); | |||||
| } | |||||
| }, [resourceId, version]); | |||||
| useEffectWhen( | |||||
| () => { | |||||
| if (version) { | |||||
| getModelAtlas(); | |||||
| } else { | |||||
| clearGraphData(); | |||||
| } | |||||
| }, | |||||
| [resourceId, version], | |||||
| isActive, | |||||
| ); | |||||
| // 初始化图 | // 初始化图 | ||||
| const initGraph = () => { | const initGraph = () => { | ||||
| @@ -302,7 +319,6 @@ function ModelEvolution({ | |||||
| container: graphRef.current!, | container: graphRef.current!, | ||||
| width: graphRef.current!.clientWidth, | width: graphRef.current!.clientWidth, | ||||
| height: graphRef.current!.clientHeight, | height: graphRef.current!.clientHeight, | ||||
| // animate: false, | |||||
| fitView: true, | fitView: true, | ||||
| fitViewPadding: [50, 100, 50, 100], | fitViewPadding: [50, 100, 50, 100], | ||||
| minZoom: 0.5, | minZoom: 0.5, | ||||
| @@ -380,10 +396,14 @@ function ModelEvolution({ | |||||
| if (point.x + 300 > canvasWidth) { | if (point.x + 300 > canvasWidth) { | ||||
| point.x = canvasWidth - 300; | point.x = canvasWidth - 300; | ||||
| } | } | ||||
| const zoom = graph.getZoom(); | |||||
| // 更加缩放,调整 tooltip 位置 | |||||
| const offsetY = (nodeHeight * zoom) / 4; | |||||
| setHoverNodeData(model as ModelDepsData); | |||||
| setHoverNodeData(model); | |||||
| setNodeToolTipX(point.x); | setNodeToolTipX(point.x); | ||||
| setNodeToolTipY(point.y - 240); | |||||
| // 92: 版本选择器的高度,296: tooltip的高度 | |||||
| setNodeToolTipY(point.y + 92 - 296 - offsetY); | |||||
| setShowNodeTooltip(true); | setShowNodeTooltip(true); | ||||
| }); | }); | ||||
| @@ -395,16 +415,15 @@ function ModelEvolution({ | |||||
| graph.on('node:click', (e: G6GraphEvent) => { | graph.on('node:click', (e: G6GraphEvent) => { | ||||
| const nodeItem = e.item; | const nodeItem = e.item; | ||||
| const model = nodeItem.getModel() as ModelDepsChildren; | |||||
| const model = nodeItem.getModel(); | |||||
| const { model_type } = model; | const { model_type } = model; | ||||
| const { origin } = location; | const { origin } = location; | ||||
| let url: string = ''; | let url: string = ''; | ||||
| switch (model_type) { | switch (model_type) { | ||||
| case NodeType.children: | case NodeType.children: | ||||
| case NodeType.current: | |||||
| case NodeType.parent: { | case NodeType.parent: { | ||||
| const { current_model_id, version } = model as ModelDepsData; | const { current_model_id, version } = model as ModelDepsData; | ||||
| url = `${origin}/dataset/model/${current_model_id}?isPublic=true&tab=3&version=${version}`; | |||||
| url = `${origin}/dataset/model/${current_model_id}?tab=3&version=${version}`; | |||||
| break; | break; | ||||
| } | } | ||||
| case NodeType.project: { | case NodeType.project: { | ||||
| @@ -415,7 +434,7 @@ function ModelEvolution({ | |||||
| case NodeType.trainDataset: | case NodeType.trainDataset: | ||||
| case NodeType.testDataset: { | case NodeType.testDataset: { | ||||
| const { dataset_id, dataset_version } = model as TrainDataset; | const { dataset_id, dataset_version } = model as TrainDataset; | ||||
| url = `${origin}/dataset/dataset/${dataset_id}?isPublic=true&tab=2&version=${dataset_version}`; | |||||
| url = `${origin}/dataset/dataset/${dataset_id}?tab=2&version=${dataset_version}`; | |||||
| break; | break; | ||||
| } | } | ||||
| default: | default: | ||||
| @@ -426,6 +445,12 @@ function ModelEvolution({ | |||||
| window.open(url, '_blank'); | window.open(url, '_blank'); | ||||
| } | } | ||||
| }); | }); | ||||
| // 鼠标滚轮缩放时,隐藏 tooltip | |||||
| graph.on('wheelzoom', () => { | |||||
| setShowNodeTooltip(false); | |||||
| setEnterTooltip(false); | |||||
| }); | |||||
| }; | }; | ||||
| const handleTooltipsMouseEnter = () => { | const handleTooltipsMouseEnter = () => { | ||||
| @@ -450,9 +475,21 @@ function ModelEvolution({ | |||||
| graph.data(graphData); | graph.data(graphData); | ||||
| graph.render(); | graph.render(); | ||||
| graph.fitView(); | graph.fitView(); | ||||
| } else { | |||||
| clearGraphData(); | |||||
| } | } | ||||
| }; | }; | ||||
| // 请求失败或者版本不存在时,清除图形 | |||||
| function clearGraphData() { | |||||
| graph.data({ | |||||
| nodes: [], | |||||
| edges: [], | |||||
| }); | |||||
| graph.render(); | |||||
| graph.fitView(); | |||||
| } | |||||
| return ( | return ( | ||||
| <div className={styles['model-evolution']}> | <div className={styles['model-evolution']}> | ||||
| <Flex align="center" className={styles['model-evolution__top']}> | <Flex align="center" className={styles['model-evolution__top']}> | ||||
| @@ -1,5 +1,4 @@ | |||||
| import { useNavigate } from '@umijs/max'; | |||||
| import { useEffect } from 'react'; | |||||
| import { formatDate } from '@/utils/date'; | |||||
| import { ModelDepsData } from '../ModelEvolution'; | import { ModelDepsData } from '../ModelEvolution'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| @@ -12,12 +11,10 @@ type NodeTooltipsProps = { | |||||
| }; | }; | ||||
| function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsProps) { | function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsProps) { | ||||
| const navigate = useNavigate(); | |||||
| useEffect(() => {}, []); | |||||
| const gotoExperimentPage = () => { | const gotoExperimentPage = () => { | ||||
| if (data.train_task?.ins_id) { | if (data.train_task?.ins_id) { | ||||
| navigate(`/pipeline/experiment/144/${data.train_task.ins_id}`); | |||||
| const { origin } = location; | |||||
| window.open(`${origin}/pipeline/experiment/144/${data.train_task.ins_id}`, '_blank'); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -35,24 +32,32 @@ function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsPr | |||||
| <span className={styles['node-tooltips__row__value']}>{data.current_model_name}</span> | <span className={styles['node-tooltips__row__value']}>{data.current_model_name}</span> | ||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>版本:</span> | |||||
| <span className={styles['node-tooltips__row__title']}>模型版本:</span> | |||||
| <span className={styles['node-tooltips__row__value']}>{data.version}</span> | <span className={styles['node-tooltips__row__value']}>{data.version}</span> | ||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>模型框架:</span> | <span className={styles['node-tooltips__row__title']}>模型框架:</span> | ||||
| <span className={styles['node-tooltips__row__value']}>{data.version}</span> | |||||
| <span className={styles['node-tooltips__row__value']}> | |||||
| {data.model_version_dependcy_vo?.model_type_name || '--'} | |||||
| </span> | |||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>模型大小:</span> | <span className={styles['node-tooltips__row__title']}>模型大小:</span> | ||||
| <span className={styles['node-tooltips__row__value']}>{data.version}</span> | |||||
| <span className={styles['node-tooltips__row__value']}> | |||||
| {data.model_version_dependcy_vo?.file_size || '--'} | |||||
| </span> | |||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>创建时间:</span> | <span className={styles['node-tooltips__row__title']}>创建时间:</span> | ||||
| <span className={styles['node-tooltips__row__value']}>{data.version}</span> | |||||
| <span className={styles['node-tooltips__row__value']}> | |||||
| {formatDate(data.model_version_dependcy_vo?.create_time)} | |||||
| </span> | |||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>模型权限:</span> | <span className={styles['node-tooltips__row__title']}>模型权限:</span> | ||||
| <span className={styles['node-tooltips__row__value']}>{data.version}</span> | |||||
| <span className={styles['node-tooltips__row__value']}> | |||||
| {data.model_version_dependcy_vo?.available_range === 1 ? '公开' : '私有'} | |||||
| </span> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__title']}>训练相关信息</div> | <div className={styles['node-tooltips__title']}>训练相关信息</div> | ||||
| @@ -1,6 +1,8 @@ | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { useStateRef, useVisible } from '@/hooks'; | import { useStateRef, useVisible } from '@/hooks'; | ||||
| import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; | import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; | ||||
| import themes from '@/styles/theme.less'; | |||||
| import { fittingString } from '@/utils'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import G6 from '@antv/g6'; | import G6 from '@antv/g6'; | ||||
| import { App, Button } from 'antd'; | import { App, Button } from 'antd'; | ||||
| @@ -27,6 +29,11 @@ const EditPipeline = () => { | |||||
| const { message } = App.useApp(); | const { message } = App.useApp(); | ||||
| let sourceAnchorIdx, targetAnchorIdx; | let sourceAnchorIdx, targetAnchorIdx; | ||||
| useEffect(() => { | |||||
| initMenu(); | |||||
| getFirstWorkflow(locationParams.id); | |||||
| }, []); | |||||
| const onDragEnd = (val) => { | const onDragEnd = (val) => { | ||||
| console.log(val); | console.log(val); | ||||
| const _x = val.x; | const _x = val.x; | ||||
| @@ -103,20 +110,8 @@ const EditPipeline = () => { | |||||
| }); | }); | ||||
| }, 500); | }, 500); | ||||
| }; | }; | ||||
| const handlerClick = (e) => { | |||||
| e.stopPropagation(); | |||||
| if (e.target.get('name') !== 'anchor-point' && e.item) { | |||||
| graph.setItemState(e.item, 'nodeClicked', true); | |||||
| const parentNodes = findAllParentNodes(graph, e.item); | |||||
| // 如果没有打开过全局参数抽屉,获取不到全局参数 | |||||
| const globalParams = | |||||
| paramsDrawerRef.current.getFieldsValue().global_param || globalParamRef.current; | |||||
| propsRef.current.showDrawer(e, globalParams, parentNodes); | |||||
| } | |||||
| }; | |||||
| const getGraphData = (data) => { | const getGraphData = (data) => { | ||||
| if (graph) { | if (graph) { | ||||
| console.log(data); | |||||
| graph.data(data); | graph.data(data); | ||||
| graph.render(); | graph.render(); | ||||
| } else { | } else { | ||||
| @@ -312,49 +307,8 @@ const EditPipeline = () => { | |||||
| initGraph(); | initGraph(); | ||||
| }; | }; | ||||
| useEffect(() => { | |||||
| initMenu(); | |||||
| getFirstWorkflow(locationParams.id); | |||||
| return () => { | |||||
| graph.off('node:mouseenter', (e) => { | |||||
| graph.setItemState(e.item, 'showAnchors', true); | |||||
| graph.setItemState(e.item, 'nodeSelected', true); | |||||
| }); | |||||
| graph.off('node:mouseleave', (e) => { | |||||
| // this.graph.setItemState(e.item, 'showAnchors', false); | |||||
| graph.setItemState(e.item, 'nodeSelected', false); | |||||
| }); | |||||
| // graph.off('dblclick', handlerClick); | |||||
| }; | |||||
| }, []); | |||||
| const initGraph = () => { | const initGraph = () => { | ||||
| const fittingString = (str, maxWidth, fontSize) => { | |||||
| const ellipsis = '...'; | |||||
| const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0]; | |||||
| let currentWidth = 0; | |||||
| let res = str; | |||||
| const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters | |||||
| str.split('').forEach((letter, i) => { | |||||
| if (currentWidth > maxWidth - ellipsisLength) return; | |||||
| if (pattern.test(letter)) { | |||||
| // Chinese charactors | |||||
| currentWidth += fontSize; | |||||
| } else { | |||||
| // get the width of single letter according to the fontSize | |||||
| currentWidth += G6.Util.getLetterWidth(letter, fontSize); | |||||
| } | |||||
| if (currentWidth > maxWidth - ellipsisLength) { | |||||
| res = `${str.substr(0, i)}${ellipsis}`; | |||||
| } | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| // 获取文本的长度 | |||||
| const getTextSize = (str, maxWidth, fontSize) => { | |||||
| let width = G6.Util.getTextSize(str, fontSize)[0]; | |||||
| return width > maxWidth ? maxWidth : width; | |||||
| }; | |||||
| G6.registerNode( | G6.registerNode( | ||||
| 'rect-node', | 'rect-node', | ||||
| { | { | ||||
| @@ -407,6 +361,7 @@ const EditPipeline = () => { | |||||
| y: bbox.y + bbox.height * anchorPos[1], | y: bbox.y + bbox.height * anchorPos[1], | ||||
| fill: '#fff', | fill: '#fff', | ||||
| stroke: '#a4a4a5', | stroke: '#a4a4a5', | ||||
| cursor: 'crosshair', | |||||
| }, | }, | ||||
| name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') | name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') | ||||
| anchorPointIdx: i, // flag the idx of the anchor-point circle | anchorPointIdx: i, // flag the idx of the anchor-point circle | ||||
| @@ -420,14 +375,30 @@ const EditPipeline = () => { | |||||
| // response the state changes and show/hide the link-point circles | // response the state changes and show/hide the link-point circles | ||||
| setState(name, value, item) { | setState(name, value, item) { | ||||
| const anchorPoints = item | |||||
| .getContainer() | |||||
| .findAll((ele) => ele.get('name') === 'anchor-point'); | |||||
| anchorPoints.forEach((point) => { | |||||
| if (value || point.get('links') > 0) point.show(); | |||||
| else point.hide(); | |||||
| }); | |||||
| // } | |||||
| // const anchorPoints = item | |||||
| // .getContainer() | |||||
| // .findAll((ele) => ele.get('name') === 'anchor-point'); | |||||
| // anchorPoints.forEach((point) => { | |||||
| // if (value || point.get('links') > 0) point.show(); | |||||
| // else point.hide(); | |||||
| // }); | |||||
| const group = item.getContainer(); | |||||
| const shape = group.get('children')[0]; | |||||
| const anchorPoints = group.findAll((ele) => ele.get('name') === 'anchor-point'); | |||||
| if (name === 'hover') { | |||||
| if (value) { | |||||
| shape.attr('stroke', themes['primaryColor']); | |||||
| anchorPoints.forEach((point) => { | |||||
| point.show(); | |||||
| }); | |||||
| } else { | |||||
| shape.attr('stroke', '#fff'); | |||||
| anchorPoints.forEach((point) => { | |||||
| point.hide(); | |||||
| }); | |||||
| } | |||||
| } | |||||
| }, | }, | ||||
| }, | }, | ||||
| 'rect', | 'rect', | ||||
| @@ -435,7 +406,6 @@ const EditPipeline = () => { | |||||
| graph = new G6.Graph({ | graph = new G6.Graph({ | ||||
| container: graphRef.current, | container: graphRef.current, | ||||
| grid: true, | |||||
| width: graphRef.current.clientWidth || 500, | width: graphRef.current.clientWidth || 500, | ||||
| height: graphRef.current.clientHeight || '100%', | height: graphRef.current.clientHeight || '100%', | ||||
| animate: false, | animate: false, | ||||
| @@ -519,20 +489,8 @@ const EditPipeline = () => { | |||||
| lineWidth: 0.5, | lineWidth: 0.5, | ||||
| }, | }, | ||||
| }, | }, | ||||
| nodeStateStyles: { | |||||
| nodeSelected: { | |||||
| fill: 'red', | |||||
| shadowColor: 'red', | |||||
| stroke: 'red', | |||||
| 'text-shape': { | |||||
| fill: 'red', | |||||
| stroke: 'red', | |||||
| }, | |||||
| }, | |||||
| }, | |||||
| defaultEdge: { | defaultEdge: { | ||||
| // type: 'quadratic', | |||||
| // type: 'cubic-vertical', | |||||
| //type: 'cubic-vertical', | |||||
| style: { | style: { | ||||
| endArrow: { | endArrow: { | ||||
| @@ -575,17 +533,20 @@ const EditPipeline = () => { | |||||
| // linkCenter: true, | // linkCenter: true, | ||||
| fitView: true, | fitView: true, | ||||
| minZoom: 0.5, | minZoom: 0.5, | ||||
| maxZoom: 3, | |||||
| fitViewPadding: [320, 320, 220, 320], | |||||
| maxZoom: 5, | |||||
| fitViewPadding: 300, | |||||
| }); | |||||
| graph.on('node:click', (e) => { | |||||
| e.stopPropagation(); | |||||
| if (e.target.get('name') !== 'anchor-point' && e.item) { | |||||
| // graph.setItemState(e.item, 'nodeClicked', true); | |||||
| const parentNodes = findAllParentNodes(graph, e.item); | |||||
| // 如果没有打开过全局参数抽屉,获取不到全局参数 | |||||
| const globalParams = | |||||
| paramsDrawerRef.current.getFieldsValue().global_param || globalParamRef.current; | |||||
| propsRef.current.showDrawer(e, globalParams, parentNodes); | |||||
| } | |||||
| }); | }); | ||||
| // graph.on('dblclick', (e) => { | |||||
| // console.log(e.item); | |||||
| // if (e.item) { | |||||
| // graph.setItemState(e.item, 'nodeClicked', true); | |||||
| // handlerClick(e); | |||||
| // } | |||||
| // }); | |||||
| graph.on('node:click', handlerClick); | |||||
| graph.on('aftercreateedge', (e) => { | graph.on('aftercreateedge', (e) => { | ||||
| // update the sourceAnchor and targetAnchor for the newly added edge | // update the sourceAnchor and targetAnchor for the newly added edge | ||||
| graph.updateItem(e.edge, { | graph.updateItem(e.edge, { | ||||
| @@ -603,59 +564,6 @@ const EditPipeline = () => { | |||||
| }); | }); | ||||
| }); | }); | ||||
| }); | }); | ||||
| graph.on('node:mouseenter', (e) => { | |||||
| // this.graph.setItemState(e.item, 'showAnchors', true); | |||||
| graph.setItemState(e.item, 'nodeSelected', true); | |||||
| graph.updateItem(e.item, { | |||||
| // 节点的样式 | |||||
| style: { | |||||
| stroke: '#1664ff', | |||||
| }, | |||||
| }); | |||||
| }); | |||||
| graph.on('node:mouseleave', (e) => { | |||||
| // this.graph.setItemState(e.item, 'showAnchors', false); | |||||
| graph.setItemState(e.item, 'nodeSelected', false); | |||||
| graph.updateItem(e.item, { | |||||
| // 节点的样式 | |||||
| style: { | |||||
| stroke: 'transparent', | |||||
| }, | |||||
| }); | |||||
| }); | |||||
| graph.on('node:dragenter', (e) => { | |||||
| console.log(e.target.get('name')); | |||||
| console.log('node:dragenter'); | |||||
| graph.setItemState(e.item, 'nodeSelected', true); | |||||
| graph.updateItem(e.item, { | |||||
| // 节点的样式 | |||||
| style: { | |||||
| stroke: '#1664ff', | |||||
| }, | |||||
| }); | |||||
| }); | |||||
| graph.on('node:dragleave', (e) => { | |||||
| console.log(e.target.get('name')); | |||||
| console.log('node:dragleave'); | |||||
| graph.setItemState(e.item, 'nodeSelected', false); | |||||
| graph.updateItem(e.item, { | |||||
| // 节点的样式 | |||||
| style: { | |||||
| stroke: 'transparent', | |||||
| }, | |||||
| }); | |||||
| }); | |||||
| graph.on('node:dragstart', (e) => { | |||||
| console.log('node:dragstart'); | |||||
| graph.setItemState(e.item, 'nodeSelected', true); | |||||
| graph.updateItem(e.item, { | |||||
| // 节点的样式 | |||||
| style: { | |||||
| stroke: '#1664ff', | |||||
| }, | |||||
| }); | |||||
| }); | |||||
| graph.on('afterremoveitem', (e) => { | graph.on('afterremoveitem', (e) => { | ||||
| if (e.item && e.item.source && e.item.target) { | if (e.item && e.item.source && e.item.target) { | ||||
| const sourceNode = graph.findById(e.item.source); | const sourceNode = graph.findById(e.item.source); | ||||
| @@ -681,7 +589,6 @@ const EditPipeline = () => { | |||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| // after clicking on the first node, the edge is created, update the sourceAnchor | // after clicking on the first node, the edge is created, update the sourceAnchor | ||||
| graph.on('afteradditem', (e) => { | graph.on('afteradditem', (e) => { | ||||
| if (e.item && e.item.getType() === 'edge') { | if (e.item && e.item.getType() === 'edge') { | ||||
| @@ -690,11 +597,29 @@ const EditPipeline = () => { | |||||
| }); | }); | ||||
| } | } | ||||
| }); | }); | ||||
| graph.on('node:mouseenter', (e) => { | |||||
| graph.setItemState(e.item, 'hover', true); | |||||
| }); | |||||
| graph.on('node:mouseleave', (e) => { | |||||
| graph.setItemState(e.item, 'hover', false); | |||||
| }); | |||||
| graph.on('node:dragenter', (e) => { | |||||
| graph.setItemState(e.item, 'hover', true); | |||||
| }); | |||||
| graph.on('node:dragleave', (e) => { | |||||
| graph.setItemState(e.item, 'hover', false); | |||||
| }); | |||||
| graph.on('node:dragstart', (e) => { | |||||
| graph.setItemState(e.item, 'hover', true); | |||||
| }); | |||||
| graph.on('node:drag', (e) => { | |||||
| graph.setItemState(e.item, 'hover', true); | |||||
| }); | |||||
| 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; | |||||
| graph.changeSize(graphRef.current.scrollWidth, graphRef.current.scrollHeight - 20); | |||||
| if (!graphRef.current) return; | |||||
| graph.changeSize(graphRef.current.clientWidth, graphRef.current.clientHeight); | |||||
| graph.fitView(); | |||||
| }; | }; | ||||
| }; | }; | ||||
| return ( | return ( | ||||
| @@ -50,16 +50,18 @@ export const getFileListFromEvent = (e: any) => { | |||||
| }); | }); | ||||
| }; | }; | ||||
| // 去登录页面 | |||||
| /** | |||||
| * 跳转到登录页 | |||||
| * @param toHome 是否跳转到首页 | |||||
| */ | |||||
| export const gotoLoginPage = (toHome: boolean = true) => { | export const gotoLoginPage = (toHome: boolean = true) => { | ||||
| const { pathname, search } = window.location; | |||||
| const { pathname, search } = location; | |||||
| const urlParams = new URLSearchParams(); | const urlParams = new URLSearchParams(); | ||||
| urlParams.append('redirect', pathname + search); | urlParams.append('redirect', pathname + search); | ||||
| const newSearch = | |||||
| toHome && pathname !== PageEnum.LOGIN && pathname !== '/' ? '' : urlParams.toString(); | |||||
| console.log('pathname', pathname); | |||||
| console.log('search', search); | |||||
| if (window.location.pathname !== PageEnum.LOGIN) { | |||||
| const newSearch = toHome && pathname !== '/' ? '' : urlParams.toString(); | |||||
| // console.log('pathname', pathname); | |||||
| // console.log('search', search); | |||||
| if (pathname !== PageEnum.LOGIN) { | |||||
| closeAllModals(); | closeAllModals(); | ||||
| removeAllPageCacheState(); | removeAllPageCacheState(); | ||||
| history.replace({ | history.replace({ | ||||
| @@ -0,0 +1,90 @@ | |||||
| package com.ruoyi.platform.controller.devEnvironment; | |||||
| import com.ruoyi.common.core.web.controller.BaseController; | |||||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | |||||
| import com.ruoyi.platform.domain.DevEnvironment; | |||||
| import com.ruoyi.platform.service.DevEnvironmentService; | |||||
| import io.swagger.annotations.Api; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import org.springframework.http.ResponseEntity; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import javax.annotation.Resource; | |||||
| /** | |||||
| * (DevEnvironment)表控制层 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-06-03 15:17:37 | |||||
| */ | |||||
| @RestController | |||||
| @RequestMapping("devEnvironment") | |||||
| @Api("开发环境管理") | |||||
| public class DevEnvironmentController extends BaseController { | |||||
| /** | |||||
| * 服务对象 | |||||
| */ | |||||
| @Resource | |||||
| private DevEnvironmentService devEnvironmentService; | |||||
| /** | |||||
| * 分页查询 | |||||
| * | |||||
| * @param devEnvironment 筛选条件 | |||||
| * @param page 页数 | |||||
| * @param size 每页大小 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| @GetMapping | |||||
| public GenericsAjaxResult<Page<DevEnvironment>> queryByPage(DevEnvironment devEnvironment, int page, int size) { | |||||
| PageRequest pageRequest = PageRequest.of(page,size); | |||||
| return genericsSuccess(this.devEnvironmentService.queryByPage(devEnvironment, pageRequest)); | |||||
| } | |||||
| /** | |||||
| * 通过主键查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 单条数据 | |||||
| */ | |||||
| @GetMapping("{id}") | |||||
| public ResponseEntity<DevEnvironment> queryById(@PathVariable("id") Integer id) { | |||||
| return ResponseEntity.ok(this.devEnvironmentService.queryById(id)); | |||||
| } | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param devEnvironment 实体 | |||||
| * @return 新增结果 | |||||
| */ | |||||
| @PostMapping | |||||
| public ResponseEntity<DevEnvironment> add(@RequestBody DevEnvironment devEnvironment) { | |||||
| return ResponseEntity.ok(this.devEnvironmentService.insert(devEnvironment)); | |||||
| } | |||||
| /** | |||||
| * 编辑数据 | |||||
| * | |||||
| * @param devEnvironment 实体 | |||||
| * @return 编辑结果 | |||||
| */ | |||||
| @PutMapping | |||||
| public ResponseEntity<DevEnvironment> edit(@RequestBody DevEnvironment devEnvironment) { | |||||
| return ResponseEntity.ok(this.devEnvironmentService.update(devEnvironment)); | |||||
| } | |||||
| /** | |||||
| * 删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 删除是否成功 | |||||
| */ | |||||
| @DeleteMapping("{id}") | |||||
| public ResponseEntity<String> deleteById(@PathVariable("id") Integer id) { | |||||
| return ResponseEntity.ok(this.devEnvironmentService.removeById(id)); | |||||
| } | |||||
| } | |||||
| @@ -91,7 +91,7 @@ public class ExperimentController extends BaseController { | |||||
| */ | */ | ||||
| @PutMapping | @PutMapping | ||||
| @ApiOperation("编辑实验") | @ApiOperation("编辑实验") | ||||
| public GenericsAjaxResult<Experiment> edit(@RequestBody Experiment experiment) throws IOException { | |||||
| public GenericsAjaxResult<Experiment> edit(@RequestBody Experiment experiment) throws Exception { | |||||
| return genericsSuccess(this.experimentService.update(experiment)); | return genericsSuccess(this.experimentService.update(experiment)); | ||||
| } | } | ||||
| @@ -4,11 +4,11 @@ import com.ruoyi.common.core.web.controller.BaseController; | |||||
| import com.ruoyi.common.core.web.domain.AjaxResult; | import com.ruoyi.common.core.web.domain.AjaxResult; | ||||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | ||||
| import com.ruoyi.platform.service.JupyterService; | import com.ruoyi.platform.service.JupyterService; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | |||||
| import org.springframework.web.bind.annotation.RestController; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||
| import java.io.File; | import java.io.File; | ||||
| @@ -28,6 +28,35 @@ public class JupyterController extends BaseController { | |||||
| return genericsSuccess(jupyterService.getJupyterServiceUrl()); | return genericsSuccess(jupyterService.getJupyterServiceUrl()); | ||||
| } | } | ||||
| /** | |||||
| * 启动jupyter容器接口 | |||||
| * | |||||
| * @param id 开发环境配置id | |||||
| * @return url | |||||
| */ | |||||
| @PostMapping("/run/{id}") | |||||
| @ApiOperation("根据开发环境id启动jupyter pod") | |||||
| @ApiResponse | |||||
| public GenericsAjaxResult<String> runJupyter(@PathVariable("id") Integer id) throws Exception { | |||||
| return genericsSuccess(this.jupyterService.runJupyterService(id)); | |||||
| } | |||||
| /** | |||||
| * 停止jupyter容器接口 | |||||
| * | |||||
| * @param id 开发环境配置id | |||||
| * @return 操作结果 | |||||
| */ | |||||
| @DeleteMapping("/stop/{id}") | |||||
| @ApiOperation("根据开发环境id停止jupyter pod") | |||||
| @ApiResponse | |||||
| public GenericsAjaxResult<String> stopJupyter(@PathVariable("id") Integer id) throws Exception { | |||||
| return genericsSuccess(this.jupyterService.stopJupyterService(id)); | |||||
| } | |||||
| @GetMapping(value = "/upload") | @GetMapping(value = "/upload") | ||||
| public AjaxResult upload() throws Exception { | public AjaxResult upload() throws Exception { | ||||
| File file = new File("D://nexus-deploy.yaml"); | File file = new File("D://nexus-deploy.yaml"); | ||||
| @@ -0,0 +1,115 @@ | |||||
| package com.ruoyi.platform.controller.model; | |||||
| import com.ruoyi.common.core.web.controller.BaseController; | |||||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | |||||
| import com.ruoyi.platform.domain.ModelDependency; | |||||
| import com.ruoyi.platform.domain.ModelsVersion; | |||||
| import com.ruoyi.platform.service.ModelDependencyService; | |||||
| import com.ruoyi.platform.vo.ModelDependcyTreeVo; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import org.springframework.http.ResponseEntity; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import javax.annotation.Resource; | |||||
| import java.io.IOException; | |||||
| import java.util.List; | |||||
| /** | |||||
| * (ModelDependency)表控制层 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-05-29 13:51:23 | |||||
| */ | |||||
| @RestController | |||||
| @RequestMapping("modelDependency") | |||||
| public class ModelDependencyController extends BaseController { | |||||
| /** | |||||
| * 服务对象 | |||||
| */ | |||||
| @Resource | |||||
| private ModelDependencyService modelDependencyService; | |||||
| /** | |||||
| * 分页查询 | |||||
| * | |||||
| * @param modelDependency 筛选条件 | |||||
| * @param page 分页对象 | |||||
| * @param size 分页对象 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| @GetMapping | |||||
| @ApiOperation("分页查询") | |||||
| public GenericsAjaxResult<Page<ModelDependency>> queryByPage(ModelDependency modelDependency, int page ,int size) { | |||||
| PageRequest pageRequest = PageRequest.of(page,size); | |||||
| return genericsSuccess(this.modelDependencyService.queryByPage(modelDependency, pageRequest)); | |||||
| } | |||||
| /** | |||||
| * 根据对象查询 | |||||
| * | |||||
| * @param modelDependency 筛选条件 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| @GetMapping("/queryModelDependency") | |||||
| @ApiOperation("根据对象查询") | |||||
| public GenericsAjaxResult<List<ModelDependency>> queryByModelDependency(@RequestBody ModelDependency modelDependency) throws IOException { | |||||
| modelDependency.setState(1); | |||||
| return genericsSuccess(this.modelDependencyService.queryByModelDependency(modelDependency)); | |||||
| } | |||||
| /** | |||||
| * 通过主键查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 单条数据 | |||||
| */ | |||||
| @GetMapping("{id}") | |||||
| @ApiOperation("根据id查询") | |||||
| public GenericsAjaxResult<ModelDependency> queryById(@PathVariable("id") Integer id) { | |||||
| return genericsSuccess(this.modelDependencyService.queryById(id)); | |||||
| } | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param modelDependency 实体 | |||||
| * @return 新增结果 | |||||
| */ | |||||
| @PostMapping | |||||
| public GenericsAjaxResult<ModelDependency> add(@RequestBody ModelDependency modelDependency) { | |||||
| return genericsSuccess(this.modelDependencyService.insert(modelDependency)); | |||||
| } | |||||
| /** | |||||
| * 编辑数据 | |||||
| * | |||||
| * @param modelDependency 实体 | |||||
| * @return 编辑结果 | |||||
| */ | |||||
| @PutMapping | |||||
| public GenericsAjaxResult<ModelDependency> edit(@RequestBody ModelDependency modelDependency) { | |||||
| return genericsSuccess(this.modelDependencyService.update(modelDependency)); | |||||
| } | |||||
| /** | |||||
| * 删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 删除是否成功 | |||||
| */ | |||||
| @DeleteMapping("{id}") | |||||
| @ApiOperation("删除模型依赖") | |||||
| public GenericsAjaxResult<String> deleteById(@PathVariable("id") Integer id) { | |||||
| return genericsSuccess(this.modelDependencyService.removeById(id)); | |||||
| } | |||||
| @PostMapping("/queryModelAtlas") | |||||
| @ApiOperation("根据模型id与版本两个属性得到模型的演化图谱") | |||||
| public GenericsAjaxResult<ModelDependcyTreeVo> queryModelAtlas(@RequestBody ModelDependency modelDependency) throws Exception { | |||||
| return genericsSuccess(this.modelDependencyService.getModelDependencyTree(modelDependency)); | |||||
| } | |||||
| } | |||||
| @@ -11,6 +11,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.List; | import java.util.List; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| @@ -129,7 +130,7 @@ public class ModelsVersionController extends BaseController { | |||||
| @DeleteMapping("/deleteVersion") | @DeleteMapping("/deleteVersion") | ||||
| @ApiOperation(value = "逻辑删除模型版本", notes = "根据模型ID和版本逻辑删除模型版本记录。") | @ApiOperation(value = "逻辑删除模型版本", notes = "根据模型ID和版本逻辑删除模型版本记录。") | ||||
| public GenericsAjaxResult<Map<Integer, String>> deleteModelsVersion(@RequestParam("models_id") Integer modelsId, | public GenericsAjaxResult<Map<Integer, String>> deleteModelsVersion(@RequestParam("models_id") Integer modelsId, | ||||
| @RequestParam("version") String version) { | |||||
| @RequestParam("version") String version) throws IOException { | |||||
| return genericsSuccess(this.modelsVersionService.deleteModelsVersion(modelsId, version)); | return genericsSuccess(this.modelsVersionService.deleteModelsVersion(modelsId, version)); | ||||
| } | } | ||||
| @@ -116,7 +116,7 @@ public class WorkflowController extends BaseController { | |||||
| */ | */ | ||||
| @PutMapping | @PutMapping | ||||
| @ApiOperation("编辑流水线") | @ApiOperation("编辑流水线") | ||||
| public GenericsAjaxResult<Workflow> edit(@RequestBody Workflow workflow) { | |||||
| public GenericsAjaxResult<Workflow> edit(@RequestBody Workflow workflow) throws Exception { | |||||
| return genericsSuccess(this.workflowService.update(workflow)); | return genericsSuccess(this.workflowService.update(workflow)); | ||||
| } | } | ||||
| @@ -1,6 +1,7 @@ | |||||
| package com.ruoyi.platform.domain; | package com.ruoyi.platform.domain; | ||||
| import com.fasterxml.jackson.annotation.JsonProperty; | import com.fasterxml.jackson.annotation.JsonProperty; | ||||
| import com.fasterxml.jackson.annotation.JsonRawValue; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | import com.fasterxml.jackson.databind.PropertyNamingStrategy; | ||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | import com.fasterxml.jackson.databind.annotation.JsonNaming; | ||||
| import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
| @@ -58,6 +59,7 @@ public class Component implements Serializable { | |||||
| */ | */ | ||||
| @JsonProperty("env_variables") | @JsonProperty("env_variables") | ||||
| @ApiModelProperty(name = "env_variables", value = "环境变量") | @ApiModelProperty(name = "env_variables", value = "环境变量") | ||||
| //@JsonRawValue | |||||
| private String envVirables; | private String envVirables; | ||||
| /** | /** | ||||
| * 资源规格 | * 资源规格 | ||||
| @@ -78,12 +80,20 @@ public class Component implements Serializable { | |||||
| * 输入参数 | * 输入参数 | ||||
| */ | */ | ||||
| @ApiModelProperty(name = "in_parameters" ,value = "输入参数") | @ApiModelProperty(name = "in_parameters" ,value = "输入参数") | ||||
| //@JsonRawValue | |||||
| private String inParameters; | private String inParameters; | ||||
| /** | /** | ||||
| * 输出参数 | * 输出参数 | ||||
| */ | */ | ||||
| @ApiModelProperty(name = "out_parameters" ,value = "输出参数") | @ApiModelProperty(name = "out_parameters" ,value = "输出参数") | ||||
| //@JsonRawValue | |||||
| private String outParameters; | private String outParameters; | ||||
| /** | |||||
| * 可见范围 | |||||
| */ | |||||
| @ApiModelProperty(name = "available_range" ,value = "1公开0私有") | |||||
| private int availableRange; | |||||
| /** | /** | ||||
| * 描述 | * 描述 | ||||
| */ | */ | ||||
| @@ -94,6 +104,8 @@ public class Component implements Serializable { | |||||
| * 图标路径 | * 图标路径 | ||||
| */ | */ | ||||
| @ApiModelProperty(name = "icon_path" ,value = "图标路径") | @ApiModelProperty(name = "icon_path" ,value = "图标路径") | ||||
| private String iconPath; | private String iconPath; | ||||
| /** | /** | ||||
| * 创建者 | * 创建者 | ||||
| @@ -124,6 +136,8 @@ public class Component implements Serializable { | |||||
| @ApiModelProperty(name = "state" , value = "状态") | @ApiModelProperty(name = "state" , value = "状态") | ||||
| private Integer state; | private Integer state; | ||||
| public Integer getId() { | public Integer getId() { | ||||
| return id; | return id; | ||||
| } | } | ||||
| @@ -228,6 +242,14 @@ public class Component implements Serializable { | |||||
| this.outParameters = outParameters; | this.outParameters = outParameters; | ||||
| } | } | ||||
| public int getAvailableRange() { | |||||
| return availableRange; | |||||
| } | |||||
| public void setAvailableRange(int availableRange) { | |||||
| this.availableRange = availableRange; | |||||
| } | |||||
| public String getDescription() { | public String getDescription() { | ||||
| return description; | return description; | ||||
| } | } | ||||
| @@ -0,0 +1,213 @@ | |||||
| package com.ruoyi.platform.domain; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import java.util.Date; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * (DevEnvironment)实体类 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-06-03 15:17:37 | |||||
| */ | |||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||||
| public class DevEnvironment implements Serializable { | |||||
| private static final long serialVersionUID = 936999018935545992L; | |||||
| /** | |||||
| * 主键 | |||||
| */ | |||||
| private Integer id; | |||||
| /** | |||||
| * 编辑器名称 | |||||
| */ | |||||
| private String name; | |||||
| /** | |||||
| * 状态 | |||||
| */ | |||||
| private String status; | |||||
| /** | |||||
| * 计算资源 | |||||
| */ | |||||
| private String computingResource; | |||||
| /** | |||||
| * 资源规格 | |||||
| */ | |||||
| private String standard; | |||||
| /** | |||||
| * 环境变量 | |||||
| */ | |||||
| private String envVariable; | |||||
| /** | |||||
| * 所用镜像 | |||||
| */ | |||||
| private String image; | |||||
| /** | |||||
| * 对应数据集 | |||||
| */ | |||||
| private String dataset; | |||||
| /** | |||||
| * 对应模型 | |||||
| */ | |||||
| private String model; | |||||
| /** | |||||
| * 备用字段1 | |||||
| */ | |||||
| private String altField1; | |||||
| /** | |||||
| * 备用字段2 | |||||
| */ | |||||
| private String altField2; | |||||
| /** | |||||
| * 创建者 | |||||
| */ | |||||
| private String createBy; | |||||
| /** | |||||
| * 创建时间 | |||||
| */ | |||||
| private Date createTime; | |||||
| /** | |||||
| * 更新者 | |||||
| */ | |||||
| private String updateBy; | |||||
| /** | |||||
| * 更新时间 | |||||
| */ | |||||
| private Date updateTime; | |||||
| /** | |||||
| * 状态,0失效1生效 | |||||
| */ | |||||
| private Integer state; | |||||
| public Integer getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(Integer id) { | |||||
| this.id = id; | |||||
| } | |||||
| public String getName() { | |||||
| return name; | |||||
| } | |||||
| public void setName(String name) { | |||||
| this.name = name; | |||||
| } | |||||
| public String getStatus() { | |||||
| return status; | |||||
| } | |||||
| public void setStatus(String status) { | |||||
| this.status = status; | |||||
| } | |||||
| public String getComputingResource() { | |||||
| return computingResource; | |||||
| } | |||||
| public void setComputingResource(String computingResource) { | |||||
| this.computingResource = computingResource; | |||||
| } | |||||
| public String getStandard() { | |||||
| return standard; | |||||
| } | |||||
| public void setStandard(String standard) { | |||||
| this.standard = standard; | |||||
| } | |||||
| public String getEnvVariable() { | |||||
| return envVariable; | |||||
| } | |||||
| public void setEnvVariable(String envVariable) { | |||||
| this.envVariable = envVariable; | |||||
| } | |||||
| public String getImage() { | |||||
| return image; | |||||
| } | |||||
| public void setImage(String image) { | |||||
| this.image = image; | |||||
| } | |||||
| public String getDataset() { | |||||
| return dataset; | |||||
| } | |||||
| public void setDataset(String dataset) { | |||||
| this.dataset = dataset; | |||||
| } | |||||
| public String getModel() { | |||||
| return model; | |||||
| } | |||||
| public void setModel(String model) { | |||||
| this.model = model; | |||||
| } | |||||
| public String getAltField1() { | |||||
| return altField1; | |||||
| } | |||||
| public void setAltField1(String altField1) { | |||||
| this.altField1 = altField1; | |||||
| } | |||||
| public String getAltField2() { | |||||
| return altField2; | |||||
| } | |||||
| public void setAltField2(String altField2) { | |||||
| this.altField2 = altField2; | |||||
| } | |||||
| public String getCreateBy() { | |||||
| return createBy; | |||||
| } | |||||
| public void setCreateBy(String createBy) { | |||||
| this.createBy = createBy; | |||||
| } | |||||
| public Date getCreateTime() { | |||||
| return createTime; | |||||
| } | |||||
| public void setCreateTime(Date createTime) { | |||||
| this.createTime = createTime; | |||||
| } | |||||
| public String getUpdateBy() { | |||||
| return updateBy; | |||||
| } | |||||
| public void setUpdateBy(String updateBy) { | |||||
| this.updateBy = updateBy; | |||||
| } | |||||
| public Date getUpdateTime() { | |||||
| return updateTime; | |||||
| } | |||||
| public void setUpdateTime(Date updateTime) { | |||||
| this.updateTime = updateTime; | |||||
| } | |||||
| public Integer getState() { | |||||
| return state; | |||||
| } | |||||
| public void setState(Integer state) { | |||||
| this.state = state; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,247 @@ | |||||
| package com.ruoyi.platform.domain; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import java.util.Date; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * (ModelDependency)实体类 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-05-29 13:51:23 | |||||
| */ | |||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||||
| public class ModelDependency implements Serializable { | |||||
| private static final long serialVersionUID = -86753423714028539L; | |||||
| /** | |||||
| * 主键 | |||||
| */ | |||||
| private Integer id; | |||||
| /** | |||||
| * 当前模型id | |||||
| */ | |||||
| private Integer currentModelId; | |||||
| /** | |||||
| * 实验实例id | |||||
| */ | |||||
| private Integer expInsId; | |||||
| /** | |||||
| * 父模型 | |||||
| */ | |||||
| private String parentModels; | |||||
| /** | |||||
| * 引用项目 | |||||
| */ | |||||
| private String refItem; | |||||
| /** | |||||
| * 训练任务 | |||||
| */ | |||||
| private String trainTask; | |||||
| /** | |||||
| * 训练数据集 | |||||
| */ | |||||
| private String trainDataset; | |||||
| /** | |||||
| * 训练参数 | |||||
| */ | |||||
| private String trainParams; | |||||
| /** | |||||
| * 训练镜像 | |||||
| */ | |||||
| private String trainImage; | |||||
| /** | |||||
| * 测试数据集 | |||||
| */ | |||||
| private String testDataset; | |||||
| /** | |||||
| * 依赖项目 | |||||
| */ | |||||
| private String projectDependency; | |||||
| /** | |||||
| * 版本 | |||||
| */ | |||||
| private String version; | |||||
| /** | |||||
| * 创建者 | |||||
| */ | |||||
| private String createBy; | |||||
| /** | |||||
| * 创建时间 | |||||
| */ | |||||
| private Date createTime; | |||||
| /** | |||||
| * 更新者 | |||||
| */ | |||||
| private String updateBy; | |||||
| /** | |||||
| * 更新时间 | |||||
| */ | |||||
| private Date updateTime; | |||||
| /** | |||||
| * 状态,0失效1生效 | |||||
| */ | |||||
| private Integer state; | |||||
| private Long workflowId; | |||||
| private Models models; | |||||
| public Integer getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(Integer id) { | |||||
| this.id = id; | |||||
| } | |||||
| public Integer getCurrentModelId() { | |||||
| return currentModelId; | |||||
| } | |||||
| public void setCurrentModelId(Integer currentModelId) { | |||||
| this.currentModelId = currentModelId; | |||||
| } | |||||
| public Integer getExpInsId() { | |||||
| return expInsId; | |||||
| } | |||||
| public void setExpInsId(Integer expInsId) { | |||||
| this.expInsId = expInsId; | |||||
| } | |||||
| public String getParentModels() { | |||||
| return parentModels; | |||||
| } | |||||
| public void setParentModels(String parentModels) { | |||||
| this.parentModels = parentModels; | |||||
| } | |||||
| public String getRefItem() { | |||||
| return refItem; | |||||
| } | |||||
| public void setRefItem(String refItem) { | |||||
| this.refItem = refItem; | |||||
| } | |||||
| public String getTrainTask() { | |||||
| return trainTask; | |||||
| } | |||||
| public void setTrainTask(String trainTask) { | |||||
| this.trainTask = trainTask; | |||||
| } | |||||
| public String getTrainDataset() { | |||||
| return trainDataset; | |||||
| } | |||||
| public void setTrainDataset(String trainDataset) { | |||||
| this.trainDataset = trainDataset; | |||||
| } | |||||
| public String getTrainParams() { | |||||
| return trainParams; | |||||
| } | |||||
| public void setTrainParams(String trainParams) { | |||||
| this.trainParams = trainParams; | |||||
| } | |||||
| public String getTrainImage() { | |||||
| return trainImage; | |||||
| } | |||||
| public void setTrainImage(String trainImage) { | |||||
| this.trainImage = trainImage; | |||||
| } | |||||
| public String getTestDataset() { | |||||
| return testDataset; | |||||
| } | |||||
| public void setTestDataset(String testDataset) { | |||||
| this.testDataset = testDataset; | |||||
| } | |||||
| public String getProjectDependency() { | |||||
| return projectDependency; | |||||
| } | |||||
| public void setProjectDependency(String projectDependency) { | |||||
| this.projectDependency = projectDependency; | |||||
| } | |||||
| public String getVersion() { | |||||
| return version; | |||||
| } | |||||
| public void setVersion(String version) { | |||||
| this.version = version; | |||||
| } | |||||
| public String getCreateBy() { | |||||
| return createBy; | |||||
| } | |||||
| public void setCreateBy(String createBy) { | |||||
| this.createBy = createBy; | |||||
| } | |||||
| public Date getCreateTime() { | |||||
| return createTime; | |||||
| } | |||||
| public void setCreateTime(Date createTime) { | |||||
| this.createTime = createTime; | |||||
| } | |||||
| public String getUpdateBy() { | |||||
| return updateBy; | |||||
| } | |||||
| public void setUpdateBy(String updateBy) { | |||||
| this.updateBy = updateBy; | |||||
| } | |||||
| public Date getUpdateTime() { | |||||
| return updateTime; | |||||
| } | |||||
| public void setUpdateTime(Date updateTime) { | |||||
| this.updateTime = updateTime; | |||||
| } | |||||
| public Integer getState() { | |||||
| return state; | |||||
| } | |||||
| public void setState(Integer state) { | |||||
| this.state = state; | |||||
| } | |||||
| public Long getWorkflowId() { | |||||
| return workflowId; | |||||
| } | |||||
| public void setWorkflowId(Long workflowId) { | |||||
| this.workflowId = workflowId; | |||||
| } | |||||
| public Models getModels() { | |||||
| return models; | |||||
| } | |||||
| public void setModels(Models models) { | |||||
| this.models = models; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| package com.ruoyi.platform.domain.dependencydomain; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| @Data | |||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||||
| public class ProjectDepency implements Serializable { | |||||
| private String url; | |||||
| private String name; | |||||
| private String branch; | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package com.ruoyi.platform.domain.dependencydomain; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| @Data | |||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||||
| public class TrainTaskDepency implements Serializable { | |||||
| //训练任务名 | |||||
| private String name; | |||||
| //实例id | |||||
| private Integer insId; | |||||
| //节点Id | |||||
| private String taskId; | |||||
| } | |||||
| @@ -0,0 +1,84 @@ | |||||
| package com.ruoyi.platform.mapper; | |||||
| import com.ruoyi.platform.domain.DevEnvironment; | |||||
| import org.apache.ibatis.annotations.Param; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * (DevEnvironment)表数据库访问层 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-06-03 15:17:37 | |||||
| */ | |||||
| public interface DevEnvironmentDao { | |||||
| /** | |||||
| * 通过ID查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| DevEnvironment queryById(Integer id); | |||||
| /** | |||||
| * 查询指定行数据 | |||||
| * | |||||
| * @param devEnvironment 查询条件 | |||||
| * @param pageable 分页对象 | |||||
| * @return 对象列表 | |||||
| */ | |||||
| List<DevEnvironment> queryAllByLimit(@Param("devEnvironment") DevEnvironment devEnvironment, @Param("pageable") Pageable pageable); | |||||
| /** | |||||
| * 统计总行数 | |||||
| * | |||||
| * @param devEnvironment 查询条件 | |||||
| * @return 总行数 | |||||
| */ | |||||
| long count(@Param("devEnvironment") DevEnvironment devEnvironment); | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param devEnvironment 实例对象 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int insert(@Param("devEnvironment") DevEnvironment devEnvironment); | |||||
| /** | |||||
| * 批量新增数据(MyBatis原生foreach方法) | |||||
| * | |||||
| * @param entities List<DevEnvironment> 实例对象列表 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int insertBatch(@Param("entities") List<DevEnvironment> entities); | |||||
| /** | |||||
| * 批量新增或按主键更新数据(MyBatis原生foreach方法) | |||||
| * | |||||
| * @param entities List<DevEnvironment> 实例对象列表 | |||||
| * | |||||
| * @return 影响行数 | |||||
| * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参 | |||||
| */ | |||||
| int insertOrUpdateBatch(@Param("entities") List<DevEnvironment> entities); | |||||
| /** | |||||
| * 修改数据 | |||||
| * | |||||
| * @param devEnvironment 实例对象 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int update(@Param("devEnvironment") DevEnvironment devEnvironment); | |||||
| /** | |||||
| * 通过主键删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int deleteById(Integer id); | |||||
| } | |||||
| @@ -0,0 +1,88 @@ | |||||
| package com.ruoyi.platform.mapper; | |||||
| import com.ruoyi.platform.domain.ModelDependency; | |||||
| import org.apache.ibatis.annotations.Param; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * (ModelDependency)表数据库访问层 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-05-29 13:51:23 | |||||
| */ | |||||
| public interface ModelDependencyDao { | |||||
| /** | |||||
| * 通过ID查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| ModelDependency queryById(Integer id); | |||||
| /** | |||||
| * 查询指定行数据 | |||||
| * | |||||
| * @param modelDependency 查询条件 | |||||
| * @param pageable 分页对象 | |||||
| * @return 对象列表 | |||||
| */ | |||||
| List<ModelDependency> queryAllByLimit(ModelDependency modelDependency, @Param("pageable") Pageable pageable); | |||||
| /** | |||||
| * 统计总行数 | |||||
| * | |||||
| * @param modelDependency 查询条件 | |||||
| * @return 总行数 | |||||
| */ | |||||
| long count(ModelDependency modelDependency); | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param modelDependency 实例对象 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int insert(ModelDependency modelDependency); | |||||
| /** | |||||
| * 批量新增数据(MyBatis原生foreach方法) | |||||
| * | |||||
| * @param entities List<ModelDependency> 实例对象列表 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int insertBatch(@Param("entities") List<ModelDependency> entities); | |||||
| /** | |||||
| * 批量新增或按主键更新数据(MyBatis原生foreach方法) | |||||
| * | |||||
| * @param entities List<ModelDependency> 实例对象列表 | |||||
| * @return 影响行数 | |||||
| * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参 | |||||
| */ | |||||
| int insertOrUpdateBatch(@Param("entities") List<ModelDependency> entities); | |||||
| /** | |||||
| * 修改数据 | |||||
| * | |||||
| * @param modelDependency 实例对象 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int update(ModelDependency modelDependency); | |||||
| /** | |||||
| * 通过主键删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 影响行数 | |||||
| */ | |||||
| int deleteById(Integer id); | |||||
| List<ModelDependency> queryByModelDependency(@Param("modelDependency") ModelDependency modelDependency); | |||||
| List<ModelDependency> queryChildrenByVersionId(@Param("model_id")String modelId, @Param("version")String version); | |||||
| } | |||||
| @@ -1,24 +1,26 @@ | |||||
| package com.ruoyi.platform.scheduling; | package com.ruoyi.platform.scheduling; | ||||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||||
| import com.ruoyi.platform.domain.Experiment; | import com.ruoyi.platform.domain.Experiment; | ||||
| import com.ruoyi.platform.domain.ExperimentIns; | import com.ruoyi.platform.domain.ExperimentIns; | ||||
| import com.ruoyi.platform.domain.ModelDependency; | |||||
| import com.ruoyi.platform.mapper.ExperimentDao; | import com.ruoyi.platform.mapper.ExperimentDao; | ||||
| import com.ruoyi.platform.mapper.ExperimentInsDao; | import com.ruoyi.platform.mapper.ExperimentInsDao; | ||||
| import com.ruoyi.platform.mapper.ModelDependencyDao; | |||||
| import com.ruoyi.platform.service.ExperimentInsService; | import com.ruoyi.platform.service.ExperimentInsService; | ||||
| import com.ruoyi.platform.service.ExperimentService; | |||||
| import com.ruoyi.platform.utils.JsonUtils; | |||||
| import com.ruoyi.system.api.model.LoginUser; | |||||
| import io.swagger.models.auth.In; | |||||
| import com.ruoyi.platform.service.ModelDependencyService; | |||||
| import com.ruoyi.platform.utils.JacksonUtil; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.scheduling.annotation.Scheduled; | import org.springframework.scheduling.annotation.Scheduled; | ||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.util.*; | |||||
| import java.util.stream.Collectors; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| @Component() | @Component() | ||||
| public class ExperimentInstanceStatusTask { | public class ExperimentInstanceStatusTask { | ||||
| @@ -28,7 +30,8 @@ public class ExperimentInstanceStatusTask { | |||||
| private ExperimentDao experimentDao; | private ExperimentDao experimentDao; | ||||
| @Resource | @Resource | ||||
| private ExperimentInsDao experimentInsDao; | private ExperimentInsDao experimentInsDao; | ||||
| @Resource | |||||
| private ModelDependencyDao modelDependencyDao; | |||||
| private List<Integer> experimentIds = new ArrayList<>(); | private List<Integer> experimentIds = new ArrayList<>(); | ||||
| @Scheduled(cron = "0/30 * * * * ?") // 每30S执行一次 | @Scheduled(cron = "0/30 * * * * ?") // 每30S执行一次 | ||||
| @@ -55,12 +58,50 @@ public class ExperimentInstanceStatusTask { | |||||
| updateList.add(experimentIns); | updateList.add(experimentIns); | ||||
| } | } | ||||
| experimentInsDao.update(experimentIns); | |||||
| // experimentInsDao.update(experimentIns); | |||||
| } | } | ||||
| } | } | ||||
| if (updateList.size() > 0){ | if (updateList.size() > 0){ | ||||
| experimentInsDao.insertOrUpdateBatch(updateList); | experimentInsDao.insertOrUpdateBatch(updateList); | ||||
| //遍历模型关系表,找到 | |||||
| List<ModelDependency> modelDependencyList = new ArrayList<ModelDependency>(); | |||||
| for (ExperimentIns experimentIns : updateList){ | |||||
| ModelDependency modelDependencyquery = new ModelDependency(); | |||||
| modelDependencyquery.setExpInsId(experimentIns.getId()); | |||||
| modelDependencyquery.setState(2); | |||||
| List<ModelDependency> modelDependencyListquery = modelDependencyDao.queryByModelDependency(modelDependencyquery); | |||||
| if (modelDependencyListquery==null||modelDependencyListquery.size()==0){ | |||||
| continue; | |||||
| } | |||||
| ModelDependency modelDependency = modelDependencyListquery.get(0); | |||||
| //查看状态, | |||||
| if (StringUtils.equals("Failed",experimentIns.getStatus())){ | |||||
| //取出节点状态 | |||||
| String trainTask = modelDependency.getTrainTask(); | |||||
| Map<String, Object> trainMap = JacksonUtil.parseJSONStr2Map(trainTask); | |||||
| String task_id = (String) trainMap.get("task_id"); | |||||
| if (StringUtils.isEmpty(task_id)){ | |||||
| continue; | |||||
| } | |||||
| String nodesStatus = experimentIns.getNodesStatus(); | |||||
| Map<String, Object> nodeMaps = JacksonUtil.parseJSONStr2Map(nodesStatus); | |||||
| Map<String, Object> nodeMap = JacksonUtil.parseJSONStr2Map(JacksonUtil.toJSONString(nodeMaps.get(task_id))); | |||||
| if (nodeMap==null){ | |||||
| continue; | |||||
| } | |||||
| if (!StringUtils.equals("Succeeded",(String)nodeMap.get("phase"))){ | |||||
| modelDependency.setState(0); | |||||
| modelDependencyList.add(modelDependency); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (modelDependencyList.size()>0) { | |||||
| modelDependencyDao.insertOrUpdateBatch(modelDependencyList); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,57 @@ | |||||
| package com.ruoyi.platform.service; | |||||
| import com.ruoyi.platform.domain.DevEnvironment; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| /** | |||||
| * (DevEnvironment)表服务接口 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-06-03 15:17:37 | |||||
| */ | |||||
| public interface DevEnvironmentService { | |||||
| /** | |||||
| * 通过ID查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| DevEnvironment queryById(Integer id); | |||||
| /** | |||||
| * 分页查询 | |||||
| * | |||||
| * @param devEnvironment 筛选条件 | |||||
| * @param pageRequest 分页对象 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| Page<DevEnvironment> queryByPage(DevEnvironment devEnvironment, PageRequest pageRequest); | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param devEnvironment 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| DevEnvironment insert(DevEnvironment devEnvironment); | |||||
| /** | |||||
| * 修改数据 | |||||
| * | |||||
| * @param devEnvironment 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| DevEnvironment update(DevEnvironment devEnvironment); | |||||
| /** | |||||
| * 通过主键删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 是否成功 | |||||
| */ | |||||
| boolean deleteById(Integer id); | |||||
| String removeById(Integer id); | |||||
| } | |||||
| @@ -100,7 +100,7 @@ public interface ExperimentInsService { | |||||
| /** | /** | ||||
| * 查询非终止态的实例 | * 查询非终止态的实例 | ||||
| * @return | |||||
| * | |||||
| */ | */ | ||||
| List<ExperimentIns> queryByExperimentIsNotTerminated(); | List<ExperimentIns> queryByExperimentIsNotTerminated(); | ||||
| @@ -48,7 +48,7 @@ public interface ExperimentService { | |||||
| * @param experiment 实例对象 | * @param experiment 实例对象 | ||||
| * @return 实例对象 | * @return 实例对象 | ||||
| */ | */ | ||||
| Experiment update(Experiment experiment) throws IOException; | |||||
| Experiment update(Experiment experiment) throws Exception; | |||||
| /** | /** | ||||
| * 通过主键删除数据 | * 通过主键删除数据 | ||||
| @@ -1,5 +1,7 @@ | |||||
| package com.ruoyi.platform.service; | package com.ruoyi.platform.service; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| public interface JupyterService { | public interface JupyterService { | ||||
| @@ -8,4 +10,8 @@ public interface JupyterService { | |||||
| void upload(InputStream inputStream); | void upload(InputStream inputStream); | ||||
| void mlflow(); | void mlflow(); | ||||
| String runJupyterService(Integer id); | |||||
| String stopJupyterService(Integer id) throws Exception; | |||||
| } | } | ||||
| @@ -0,0 +1,65 @@ | |||||
| package com.ruoyi.platform.service; | |||||
| import com.ruoyi.platform.domain.ModelDependency; | |||||
| import com.ruoyi.platform.vo.ModelDependcyTreeVo; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import java.io.IOException; | |||||
| import java.util.List; | |||||
| /** | |||||
| * (ModelDependency)表服务接口 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-05-29 13:51:23 | |||||
| */ | |||||
| public interface ModelDependencyService { | |||||
| /** | |||||
| * 通过ID查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| ModelDependency queryById(Integer id); | |||||
| /** | |||||
| * 分页查询 | |||||
| * | |||||
| * @param modelDependency 筛选条件 | |||||
| * @param pageRequest 分页对象 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| Page<ModelDependency> queryByPage(ModelDependency modelDependency, PageRequest pageRequest); | |||||
| /** | |||||
| * 修改数据 | |||||
| * | |||||
| * @param modelDependency 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| ModelDependency update(ModelDependency modelDependency); | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param modelDependency 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| ModelDependency insert(ModelDependency modelDependency); | |||||
| /** | |||||
| * 通过主键删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 是否成功 | |||||
| */ | |||||
| boolean deleteById(Integer id); | |||||
| String removeById(Integer id); | |||||
| List<ModelDependency> queryByModelDependency(ModelDependency modelDependency) throws IOException; | |||||
| ModelDependcyTreeVo getModelDependencyTree(ModelDependency modelDependency) throws Exception; | |||||
| } | |||||
| @@ -6,6 +6,7 @@ import com.ruoyi.platform.domain.ModelsVersion; | |||||
| 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; | ||||
| @@ -68,7 +69,7 @@ public interface ModelsVersionService { | |||||
| Map<String,Object> queryByModelsIdAndVersion(Integer modelsId, String version); | Map<String,Object> queryByModelsIdAndVersion(Integer modelsId, String version); | ||||
| Map<Integer, String> deleteModelsVersion(Integer modelsId, String version); | |||||
| Map<Integer, String> deleteModelsVersion(Integer modelsId, String version) throws IOException; | |||||
| String addModelVersions(List<ModelsVersion> modelsVersions) throws Exception; | String addModelVersions(List<ModelsVersion> modelsVersions) throws Exception; | ||||
| @@ -45,7 +45,7 @@ public interface WorkflowService { | |||||
| * @param workflow 实例对象 | * @param workflow 实例对象 | ||||
| * @return 实例对象 | * @return 实例对象 | ||||
| */ | */ | ||||
| Workflow update(Workflow workflow); | |||||
| Workflow update(Workflow workflow) throws Exception; | |||||
| /** | /** | ||||
| * 通过主键删除数据 | * 通过主键删除数据 | ||||
| @@ -51,7 +51,7 @@ public class ComponentServiceImpl implements ComponentService { | |||||
| throw new RuntimeException("组件不存在"); | throw new RuntimeException("组件不存在"); | ||||
| } | } | ||||
| return this.componentDao.queryById(id); | |||||
| return component; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -149,6 +149,7 @@ public class ComponentServiceImpl implements ComponentService { | |||||
| String inParameters= gson.toJson(componentVo.getInParameters(), LinkedHashMap.class); | String inParameters= gson.toJson(componentVo.getInParameters(), LinkedHashMap.class); | ||||
| String outParameters = gson.toJson(componentVo.getOutParameters(), LinkedHashMap.class); | String outParameters = gson.toJson(componentVo.getOutParameters(), LinkedHashMap.class); | ||||
| String envVariable = gson.toJson(componentVo.getEnvVirables(), LinkedHashMap.class); | String envVariable = gson.toJson(componentVo.getEnvVirables(), LinkedHashMap.class); | ||||
| component.setEnvVirables(envVariable); | component.setEnvVirables(envVariable); | ||||
| component.setInParameters(inParameters); | component.setInParameters(inParameters); | ||||
| @@ -353,22 +353,15 @@ public class DatasetServiceImpl implements DatasetService { | |||||
| public void checkDeclaredName(Dataset insert) throws Exception { | public void checkDeclaredName(Dataset insert) throws Exception { | ||||
| Dataset existingDataset = datasetDao.findByName(insert.getName()); | Dataset existingDataset = datasetDao.findByName(insert.getName()); | ||||
| if (existingDataset != null) { | if (existingDataset != null) { | ||||
| // Check if the found dataset is not the same as the one being inserted | |||||
| // This is important if you are using this method for both insert and update operations | |||||
| // You may need an identifier check here, e.g., if 'insert' has an ID and it's the same as 'existingDataset' | |||||
| if (insert.getId() != null && insert.getId().equals(existingDataset.getId())) { | if (insert.getId() != null && insert.getId().equals(existingDataset.getId())) { | ||||
| // This is the same dataset, no duplicate name issue for update operation | |||||
| // 相同数据集,无需判断 | |||||
| return; | return; | ||||
| } | } | ||||
| // Now we know there's another dataset with the same name | |||||
| Field[] fields = Dataset.class.getDeclaredFields(); | Field[] fields = Dataset.class.getDeclaredFields(); | ||||
| for (Field field : fields) { | for (Field field : fields) { | ||||
| field.setAccessible(true); // Make private fields accessible | |||||
| field.setAccessible(true); | |||||
| if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { | if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { | ||||
| // If the field is 'name' and is marked with CheckDuplicate annotation | |||||
| CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); | CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); | ||||
| throw new Exception("重复的数据集名称: " + insert.getName() + ". " + annotation.message()); | throw new Exception("重复的数据集名称: " + insert.getName() + ". " + annotation.message()); | ||||
| } | } | ||||
| @@ -0,0 +1,125 @@ | |||||
| package com.ruoyi.platform.service.impl; | |||||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||||
| import com.ruoyi.platform.domain.DevEnvironment; | |||||
| import com.ruoyi.platform.mapper.DevEnvironmentDao; | |||||
| import com.ruoyi.platform.service.DevEnvironmentService; | |||||
| import com.ruoyi.platform.service.JupyterService; | |||||
| import com.ruoyi.platform.utils.JacksonUtil; | |||||
| import com.ruoyi.system.api.model.LoginUser; | |||||
| import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageImpl; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import javax.annotation.Resource; | |||||
| import java.util.Date; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * (DevEnvironment)表服务实现类 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-06-03 15:17:37 | |||||
| */ | |||||
| @Service("devEnvironmentService") | |||||
| public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||||
| @Resource | |||||
| private DevEnvironmentDao devEnvironmentDao; | |||||
| @Resource | |||||
| private JupyterService jupyterService; | |||||
| /** | |||||
| * 通过ID查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| @Override | |||||
| public DevEnvironment queryById(Integer id) { | |||||
| return this.devEnvironmentDao.queryById(id); | |||||
| } | |||||
| /** | |||||
| * 分页查询 | |||||
| * | |||||
| * @param devEnvironment 筛选条件 | |||||
| * @param pageRequest 分页对象 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| @Override | |||||
| public Page<DevEnvironment> queryByPage(DevEnvironment devEnvironment, PageRequest pageRequest) { | |||||
| long total = this.devEnvironmentDao.count(devEnvironment); | |||||
| return new PageImpl<>(this.devEnvironmentDao.queryAllByLimit(devEnvironment, pageRequest), pageRequest, total); | |||||
| } | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param devEnvironment 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| @Override | |||||
| public DevEnvironment insert(DevEnvironment devEnvironment) { | |||||
| //插入预备,此时不需要判断版本重复 | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| devEnvironment.setCreateBy(loginUser.getUsername()); | |||||
| devEnvironment.setUpdateBy(loginUser.getUsername()); | |||||
| devEnvironment.setUpdateTime(new Date()); | |||||
| devEnvironment.setCreateTime(new Date()); | |||||
| this.devEnvironmentDao.insert(devEnvironment); | |||||
| return devEnvironment; | |||||
| } | |||||
| /** | |||||
| * 修改数据 | |||||
| * | |||||
| * @param devEnvironment 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| @Override | |||||
| public DevEnvironment update(DevEnvironment devEnvironment) { | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| devEnvironment.setUpdateBy(loginUser.getUsername()); | |||||
| devEnvironment.setUpdateTime(new Date()); | |||||
| this.devEnvironmentDao.update(devEnvironment); | |||||
| return this.queryById(devEnvironment.getId()); | |||||
| } | |||||
| /** | |||||
| * 通过主键删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 是否成功 | |||||
| */ | |||||
| @Override | |||||
| public boolean deleteById(Integer id) { | |||||
| return this.devEnvironmentDao.deleteById(id) > 0; | |||||
| } | |||||
| @Override | |||||
| public String removeById(Integer id) { | |||||
| DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id); | |||||
| if (devEnvironment == null){ | |||||
| return "开发环境信息不存在"; | |||||
| } | |||||
| //判断权限,只有admin和创建者本身可以删除该数据集 | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| String username = loginUser.getUsername(); | |||||
| String createdBy = devEnvironment.getCreateBy(); | |||||
| if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){ | |||||
| return "无权限删除该开发环境"; | |||||
| } | |||||
| devEnvironment.setState(0); | |||||
| return this.devEnvironmentDao.update(devEnvironment)>0?"删除成功":"删除失败"; | |||||
| } | |||||
| } | |||||
| @@ -427,7 +427,6 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||||
| throw new RuntimeException("日志为空。"); | throw new RuntimeException("日志为空。"); | ||||
| } | } | ||||
| //返回日志内容 | //返回日志内容 | ||||
| return experimentInsLog; | return experimentInsLog; | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| throw new RuntimeException("查询实验日志失败: " + e.getMessage(), e); | throw new RuntimeException("查询实验日志失败: " + e.getMessage(), e); | ||||
| @@ -554,7 +553,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||||
| // 查询具有相同状态的实例数量 | // 查询具有相同状态的实例数量 | ||||
| Long count = experimentInsDao.count(experimentIns); | Long count = experimentInsDao.count(experimentIns); | ||||
| // 将状态及其对应的实例数量放入映射中 | |||||
| // 将状态及其对应的实例数量放入map中 | |||||
| statusCountMap.put(status.toString(), count); | statusCountMap.put(status.toString(), count); | ||||
| } | } | ||||
| @@ -580,8 +579,9 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { | |||||
| flag = StringUtils.equals("Terminated", (String) workflowMap.get("phase")); | flag = StringUtils.equals("Terminated", (String) workflowMap.get("phase")); | ||||
| } | } | ||||
| } | } | ||||
| return flag; | return flag; | ||||
| } | } | ||||
| } | } | ||||
| @@ -2,14 +2,12 @@ package com.ruoyi.platform.service.impl; | |||||
| import com.ruoyi.common.security.utils.SecurityUtils; | import com.ruoyi.common.security.utils.SecurityUtils; | ||||
| import com.ruoyi.platform.annotations.CheckDuplicate; | import com.ruoyi.platform.annotations.CheckDuplicate; | ||||
| import com.ruoyi.platform.domain.Experiment; | |||||
| import com.ruoyi.platform.domain.ExperimentIns; | |||||
| import com.ruoyi.platform.domain.Workflow; | |||||
| import com.ruoyi.platform.domain.*; | |||||
| import com.ruoyi.platform.domain.dependencydomain.ProjectDepency; | |||||
| import com.ruoyi.platform.domain.dependencydomain.TrainTaskDepency; | |||||
| import com.ruoyi.platform.mapper.ExperimentDao; | import com.ruoyi.platform.mapper.ExperimentDao; | ||||
| import com.ruoyi.platform.mapper.ExperimentInsDao; | import com.ruoyi.platform.mapper.ExperimentInsDao; | ||||
| import com.ruoyi.platform.service.ExperimentInsService; | |||||
| import com.ruoyi.platform.service.ExperimentService; | |||||
| import com.ruoyi.platform.service.WorkflowService; | |||||
| import com.ruoyi.platform.service.*; | |||||
| import com.ruoyi.platform.utils.HttpUtils; | import com.ruoyi.platform.utils.HttpUtils; | ||||
| import com.ruoyi.platform.utils.JacksonUtil; | import com.ruoyi.platform.utils.JacksonUtil; | ||||
| import com.ruoyi.platform.utils.JsonUtils; | import com.ruoyi.platform.utils.JsonUtils; | ||||
| @@ -42,8 +40,12 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| @Resource | @Resource | ||||
| private ExperimentInsDao experimentInsDao; | private ExperimentInsDao experimentInsDao; | ||||
| @Resource | |||||
| private ModelsService modelsService; | |||||
| @Resource | |||||
| private DatasetService datasetService; | |||||
| @Resource | |||||
| private ModelDependencyService modelDependencyService; | |||||
| @Resource | @Resource | ||||
| @Lazy | @Lazy | ||||
| @@ -151,8 +153,9 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| * @return 实例对象 | * @return 实例对象 | ||||
| */ | */ | ||||
| @Override | @Override | ||||
| public Experiment update(Experiment experiment) throws IOException { | |||||
| public Experiment update(Experiment experiment) throws Exception { | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | LoginUser loginUser = SecurityUtils.getLoginUser(); | ||||
| checkDeclaredName(experiment); | |||||
| experiment.setUpdateBy(loginUser.getUsername()); | experiment.setUpdateBy(loginUser.getUsername()); | ||||
| experiment.setUpdateTime(new Date()); | experiment.setUpdateTime(new Date()); | ||||
| this.experimentDao.update(experiment); | this.experimentDao.update(experiment); | ||||
| @@ -207,12 +210,9 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| public Experiment runExperiment(Integer id) throws Exception { | public Experiment runExperiment(Integer id) throws Exception { | ||||
| //先查出实验记录 | //先查出实验记录 | ||||
| Experiment experiment = this.queryById(id); | Experiment experiment = this.queryById(id); | ||||
| if (experiment == null) { | if (experiment == null) { | ||||
| System.out.println("No experiment"); | System.out.println("No experiment"); | ||||
| } | } | ||||
| Workflow workflow = workflowService.queryById(experiment.getWorkflowId()); | Workflow workflow = workflowService.queryById(experiment.getWorkflowId()); | ||||
| if(workflow == null) { | if(workflow == null) { | ||||
| throw new RuntimeException("流水线不存在,请先创建流水线"); | throw new RuntimeException("流水线不存在,请先创建流水线"); | ||||
| @@ -226,13 +226,14 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| throw new RuntimeException("转换流水线失败"); | throw new RuntimeException("转换流水线失败"); | ||||
| } | } | ||||
| Map<String, Object> converMap = JsonUtils.jsonToMap(convertRes); | Map<String, Object> converMap = JsonUtils.jsonToMap(convertRes); | ||||
| // 组装运行接口json | // 组装运行接口json | ||||
| Map<String, Object> runReqMap = new HashMap<>(); | Map<String, Object> runReqMap = new HashMap<>(); | ||||
| runReqMap.put("data", converMap.get("data")); | runReqMap.put("data", converMap.get("data")); | ||||
| //这里全局参数是一个json数组,需要转换成一个list<Map> | //这里全局参数是一个json数组,需要转换成一个list<Map> | ||||
| List<Map<String, Object>> params = JacksonUtil.parseJSONStr2MapList(StringUtils.isEmpty(experiment.getGlobalParam()) ? "[]" : experiment.getGlobalParam()); | List<Map<String, Object>> params = JacksonUtil.parseJSONStr2MapList(StringUtils.isEmpty(experiment.getGlobalParam()) ? "[]" : experiment.getGlobalParam()); | ||||
| runReqMap.put("params", params); | runReqMap.put("params", params); | ||||
| //// 实验字段的Map,不要写成一行!否则会返回null | |||||
| // 实验字段的Map,不要写成一行!否则会返回null | |||||
| Map<String, Object> experimentMap = new HashMap<>(); | Map<String, Object> experimentMap = new HashMap<>(); | ||||
| experimentMap.put("name", "experiment-"+experiment.getId()); | experimentMap.put("name", "experiment-"+experiment.getId()); | ||||
| runReqMap.put("experiment", experimentMap); | runReqMap.put("experiment", experimentMap); | ||||
| @@ -246,14 +247,11 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| } | } | ||||
| Map<String, Object> runResMap = JsonUtils.jsonToMap(runRes); | Map<String, Object> runResMap = JsonUtils.jsonToMap(runRes); | ||||
| Map<String, Object> data = (Map<String, Object>) runResMap.get("data"); | Map<String, Object> data = (Map<String, Object>) runResMap.get("data"); | ||||
| //判断data为空 | //判断data为空 | ||||
| if (data == null || MapUtils.isEmpty(data)) { | if (data == null || MapUtils.isEmpty(data)) { | ||||
| throw new RuntimeException("Failed to run workflow."); | throw new RuntimeException("Failed to run workflow."); | ||||
| } | } | ||||
| Map<String, Object> metadata = (Map<String, Object>) data.get("metadata"); | Map<String, Object> metadata = (Map<String, Object>) data.get("metadata"); | ||||
| // 插入记录到实验实例表 | // 插入记录到实验实例表 | ||||
| ExperimentIns experimentIns = new ExperimentIns(); | ExperimentIns experimentIns = new ExperimentIns(); | ||||
| experimentIns.setExperimentId(experiment.getId()); | experimentIns.setExperimentId(experiment.getId()); | ||||
| @@ -262,24 +260,237 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| experimentIns.setStatus("Pending"); | experimentIns.setStatus("Pending"); | ||||
| //传入实验全局参数 | //传入实验全局参数 | ||||
| experimentIns.setGlobalParam(experiment.getGlobalParam()); | experimentIns.setGlobalParam(experiment.getGlobalParam()); | ||||
| //替换argoInsName | //替换argoInsName | ||||
| String outputString = JsonUtils.mapToJson(output); | String outputString = JsonUtils.mapToJson(output); | ||||
| experimentIns.setNodesResult(outputString.replace("{{workflow.name}}", (String) metadata.get("name"))); | experimentIns.setNodesResult(outputString.replace("{{workflow.name}}", (String) metadata.get("name"))); | ||||
| //插入ExperimentIns表中 | //插入ExperimentIns表中 | ||||
| experimentInsService.insert(experimentIns); | |||||
| ExperimentIns insert = experimentInsService.insert(experimentIns); | |||||
| //插入到模型依赖关系表 | |||||
| //得到dependendcy | |||||
| Map<String, Object> converMap2 = JsonUtils.jsonToMap(JacksonUtil.replaceInAarry(convertRes, params)); | |||||
| Map<String ,Object> dependendcy = (Map<String, Object>)converMap2.get("model_dependency"); | |||||
| Map<String ,Object> trainInfo = (Map<String, Object>)converMap2.get("component_info"); | |||||
| insertModelDependency(dependendcy,trainInfo,insert.getId(),experiment.getName()); | |||||
| }catch (Exception e){ | }catch (Exception e){ | ||||
| throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
| } | } | ||||
| List<ExperimentIns> updatedExperimentInsList = experimentInsService.getByExperimentId(id); | List<ExperimentIns> updatedExperimentInsList = experimentInsService.getByExperimentId(id); | ||||
| experiment.setExperimentInsList(updatedExperimentInsList); | experiment.setExperimentInsList(updatedExperimentInsList); | ||||
| return experiment; | return experiment; | ||||
| } | } | ||||
| private void insertModelDependency(Map<String ,Object> dependendcy,Map<String ,Object> trainInfo, Integer experimentInsId, String experimentName) throws Exception { | |||||
| Iterator<Map.Entry<String, Object>> dependendcyIterator = dependendcy.entrySet().iterator(); | |||||
| Map<String, Object> modelTrain = (Map<String, Object>) trainInfo.get("model_train"); | |||||
| Map<String, Object> modelEvaluate = (Map<String, Object>) trainInfo.get("model_evaluate"); | |||||
| Map<String, Object> modelExport = (Map<String, Object>) trainInfo.get("model_export"); | |||||
| while (dependendcyIterator.hasNext()) { | |||||
| ModelDependency modelDependency = new ModelDependency(); | |||||
| Map.Entry<String, Object> entry = dependendcyIterator.next(); | |||||
| Map<String, Object> modelDel = (Map<String, Object>) entry.getValue(); | |||||
| Map<String, Object> source = (Map<String, Object>) modelDel.get("source"); | |||||
| List<Map<String, Object>> test = (List<Map<String, Object>>) modelDel.get("test"); | |||||
| List<Map<String, Object>> target = (List<Map<String, Object>>) modelDel.get("target"); | |||||
| String sourceTaskId = (String) source.get("task_id"); | |||||
| Map<String, Object> modelTrainMap = (Map<String, Object>)modelTrain.get(sourceTaskId); | |||||
| //处理project数据 | |||||
| Map<String, String> projectMap = (Map<String, String>) modelTrainMap.get("project"); | |||||
| ProjectDepency projectDepency = new ProjectDepency(); | |||||
| projectDepency.setBranch(projectMap.get("branch")); | |||||
| String projectUrl = projectMap.get("url"); | |||||
| projectDepency.setUrl(projectUrl); | |||||
| projectDepency.setName(projectUrl.substring(projectUrl.lastIndexOf('/') + 1, projectUrl.length() - 4)); | |||||
| //依赖项目 | |||||
| modelDependency.setProjectDependency(JsonUtils.objectToJson(projectDepency)); | |||||
| //处理镜像 | |||||
| Map<String, String> imagesMap = (Map<String, String>) modelTrainMap.get("image"); | |||||
| modelDependency.setTrainImage(imagesMap.get("name")); | |||||
| List<Map<String, Object>> trainParamList = (List<Map<String, Object>>) modelTrainMap.get("params"); | |||||
| modelDependency.setTrainParams(JsonUtils.objectToJson(trainParamList)); | |||||
| //处理source数据 | |||||
| List<Map<String, Object>> modelsList = (List<Map<String, Object>>) modelTrainMap.get("models"); | |||||
| if (modelsList != null) { | |||||
| for (int i = 0; i < modelsList.size(); i++) { | |||||
| Map<String, Object> model = modelsList.get(i); | |||||
| Models models = modelsService.queryById((Integer) model.get("model_id")); | |||||
| if (models == null) { | |||||
| throw new Exception("源模型不存在"); | |||||
| } | |||||
| model.put("model_name", models.getName()); | |||||
| } | |||||
| //父模型 | |||||
| modelDependency.setParentModels(JsonUtils.objectToJson(modelsList)); | |||||
| } | |||||
| List<Map<String, Object>> datasetsList = (List<Map<String, Object>>) modelTrainMap.get("datasets"); | |||||
| if (datasetsList != null) { | |||||
| for (int i = 0; i < datasetsList.size(); i++) { | |||||
| Map<String, Object> datasets = datasetsList.get(i); | |||||
| Dataset dataset = datasetService.queryById((Integer) datasets.get("dataset_id")); | |||||
| if (dataset == null) { | |||||
| throw new Exception("源数据集不存在"); | |||||
| } | |||||
| datasets.put("dataset_name", dataset.getName()); | |||||
| } | |||||
| } | |||||
| //训练数据集 | |||||
| modelDependency.setTrainDataset(JsonUtils.objectToJson(datasetsList)); | |||||
| TrainTaskDepency trainTaskDepency = new TrainTaskDepency(); | |||||
| trainTaskDepency.setTaskId(sourceTaskId); | |||||
| trainTaskDepency.setInsId(experimentInsId); | |||||
| trainTaskDepency.setName(experimentName); | |||||
| //训练任务 | |||||
| modelDependency.setTrainTask(JsonUtils.objectToJson(trainTaskDepency)); | |||||
| modelDependency.setExpInsId(experimentInsId); | |||||
| List<Map<String, Object>> resultTestDatasets = new ArrayList<Map<String, Object>>(); | |||||
| //处理test数据 | |||||
| if (test != null) { | |||||
| for(int i=0;i<test.size();i++){ | |||||
| Map<String, Object> testMap = test.get(i); | |||||
| String testTaskId = (String) testMap.get("task_id"); | |||||
| Map<String, Object> evaluateMap = (Map<String, Object>) modelEvaluate.get(testTaskId); | |||||
| List<Map<String, Object>> realDataSetList = (List<Map<String, Object>>) evaluateMap.get("datasets"); | |||||
| for(int j=0;j<realDataSetList.size();j++){ | |||||
| Map<String, Object> realDataSet = realDataSetList.get(j); | |||||
| Dataset dataset = datasetService.queryById((Integer) realDataSet.get("dataset_id")); | |||||
| if (dataset == null){ | |||||
| throw new Exception("源数据集不存在"); | |||||
| } | |||||
| realDataSet.put("dataset_name", dataset.getName()); | |||||
| resultTestDatasets.add(realDataSet); | |||||
| } | |||||
| } | |||||
| //测试数据集 | |||||
| modelDependency.setTestDataset(JsonUtils.objectToJson(resultTestDatasets)); | |||||
| } | |||||
| //处理target数据 | |||||
| if (target != null) { | |||||
| for (int i = 0; i < target.size(); i++) { | |||||
| Map<String, Object> targetMap = target.get(i); | |||||
| String targetaskId = (String) targetMap.get("task_id"); | |||||
| Map<String, Object> exportMap = (Map<String, Object>) modelExport.get(targetaskId); | |||||
| List<Map<String, Object>> modelTargetList = (List<Map<String, Object>>) exportMap.get("models"); | |||||
| modelDependency.setState(2); | |||||
| for (int j = 0; j < modelTargetList.size(); j++) { | |||||
| Map<String, Object> model = modelTargetList.get(i); | |||||
| modelDependency.setVersion((String) model.get("model_version")); | |||||
| modelDependency.setCurrentModelId((Integer) model.get("model_id")); | |||||
| //因为可能有多成果模型,多次插入 | |||||
| modelDependencyService.insert(modelDependency); | |||||
| } | |||||
| } | |||||
| }else { | |||||
| modelDependency.setState(2); | |||||
| modelDependencyService.insert(modelDependency); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 被废弃的旧JSON | |||||
| * @param experiment | |||||
| * @return | |||||
| * @throws Exception | |||||
| */ | |||||
| // private void insertModelDependency(Map<String ,Object> dependendcy,Map<String ,Object> trainInfo, Integer experimentInsId, String experimentName, List<Map<String, Object>> params) throws Exception { | |||||
| // Iterator<Map.Entry<String, Object>> dependendcyIterator = dependendcy.entrySet().iterator(); | |||||
| // while (dependendcyIterator.hasNext()) { | |||||
| // ModelDependency modelDependency = new ModelDependency(); | |||||
| // Map.Entry<String, Object> entry = dependendcyIterator.next(); | |||||
| // String key = entry.getKey(); | |||||
| // Map<String, Object> modelDel = (Map<String, Object>) entry.getValue(); | |||||
| // //处理project数据 | |||||
| // Map<String, String> projectMap = (Map<String, String>) modelDel.get("project"); | |||||
| // ProjectDepency projectDepency = new ProjectDepency(); | |||||
| // projectDepency.setBranch(projectMap.get("branch")); | |||||
| // String projectUrl = projectMap.get("url"); | |||||
| // projectDepency.setUrl(projectUrl); | |||||
| // projectDepency.setName(projectUrl.substring(projectUrl.lastIndexOf('/') + 1, projectUrl.length() - 4)); | |||||
| // //依赖项目 | |||||
| // modelDependency.setProjectDependency(JsonUtils.objectToJson(projectDepency)); | |||||
| // //处理source数据 | |||||
| // Map<String, Object> sourceMap = (Map<String, Object>) modelDel.get("source"); | |||||
| // List<Map<String, Object>> modelsList = (List<Map<String, Object>>) sourceMap.get("models"); | |||||
| // for(int i=0;i<modelsList.size();i++){ | |||||
| // Map<String, Object> model = modelsList.get(i); | |||||
| // Models models = modelsService.queryById((Integer) model.get("model_id")); | |||||
| // if (models == null){ | |||||
| // throw new Exception("源模型不存在"); | |||||
| // } | |||||
| // model.put("model_name", models.getName()); | |||||
| // } | |||||
| // //父模型 | |||||
| // modelDependency.setParentModels(JsonUtils.objectToJson(modelsList)); | |||||
| // | |||||
| // List<Map<String, Object>> datasetsList = (List<Map<String, Object>>) sourceMap.get("datasets"); | |||||
| // for(int i=0;i<datasetsList.size();i++){ | |||||
| // Map<String, Object> datasets = datasetsList.get(i); | |||||
| // Dataset dataset = datasetService.queryById((Integer) datasets.get("dataset_id")); | |||||
| // if (dataset == null){ | |||||
| // throw new Exception("源数据集不存在"); | |||||
| // } | |||||
| // datasets.put("dataset_name", dataset.getName()); | |||||
| // } | |||||
| // //训练数据集 | |||||
| // modelDependency.setTrainDataset(JsonUtils.objectToJson(datasetsList)); | |||||
| // | |||||
| // TrainTaskDepency trainTaskDepency = new TrainTaskDepency(); | |||||
| // trainTaskDepency.setTaskId(key); | |||||
| // trainTaskDepency.setInsId(experimentInsId); | |||||
| // trainTaskDepency.setName(experimentName); | |||||
| // //训练任务 | |||||
| // modelDependency.setTrainTask(JsonUtils.objectToJson(trainTaskDepency)); | |||||
| // modelDependency.setExpInsId(experimentInsId); | |||||
| // //处理test数据 | |||||
| // List<Map<String, Object>> testDatasetsList = (List<Map<String, Object>>) modelDel.get("test"); | |||||
| // List<Map<String, Object>> resultTestDatasets = new ArrayList<Map<String, Object>>(); | |||||
| // for(int i=0;i<testDatasetsList.size();i++){ | |||||
| // Map<String, Object> datasets = testDatasetsList.get(i); | |||||
| // List<Map<String, Object>> realDataSetList = (List<Map<String, Object>>) datasets.get("datasets"); | |||||
| // for(int j=0;j<realDataSetList.size();j++){ | |||||
| // Map<String, Object> realDataSet = realDataSetList.get(j); | |||||
| // Dataset dataset = datasetService.queryById((Integer) realDataSet.get("dataset_id")); | |||||
| // if (dataset == null){ | |||||
| // throw new Exception("源数据集不存在"); | |||||
| // } | |||||
| // realDataSet.put("dataset_name", dataset.getName()); | |||||
| // resultTestDatasets.add(realDataSet); | |||||
| // } | |||||
| // | |||||
| // } | |||||
| // //测试数据集 | |||||
| // modelDependency.setTestDataset(JsonUtils.objectToJson(resultTestDatasets)); | |||||
| // | |||||
| // //检查是否存在target,如果存在说明在流水线用了节点导入,如果没有说明没有导入,等待手动push | |||||
| // List<Map<String, Object>> modelTargetList = (List<Map<String, Object>>) modelDel.get("target"); | |||||
| // if (modelTargetList==null||modelTargetList.size()==0){ | |||||
| // modelDependency.setState(1); | |||||
| // modelDependencyService.insert(modelDependency); | |||||
| // }else { | |||||
| // modelDependency.setState(2); | |||||
| // for(int i=0;i<modelTargetList.size();i++){ | |||||
| // Map<String, Object> model = modelTargetList.get(i); | |||||
| // String version = null; | |||||
| // //可能是参数,必须从实验参数读取 | |||||
| // if (params != null) { | |||||
| // for (Map<String, Object> param : params) { | |||||
| // if (param.containsKey("param_name") && StringUtils.equals("model_version",(String) param.get("param_name"))) { | |||||
| // version = param.get("param_value").toString(); | |||||
| // } | |||||
| // } | |||||
| // } | |||||
| // modelDependency.setVersion(StringUtils.isEmpty(version)?(String)model.get("model_version"):version); | |||||
| // modelDependency.setCurrentModelId((Integer) model.get("model_id")); | |||||
| // //因为可能有多成果模型,多次插入 | |||||
| // modelDependencyService.insert(modelDependency); | |||||
| // } | |||||
| // } | |||||
| // } | |||||
| // } | |||||
| @Override | @Override | ||||
| public Experiment addAndRunExperiment(Experiment experiment) throws Exception { | public Experiment addAndRunExperiment(Experiment experiment) throws Exception { | ||||
| @@ -332,7 +543,7 @@ public class ExperimentServiceImpl implements ExperimentService { | |||||
| // 现在我们知道还有另一个具有相同名称的流水线 | // 现在我们知道还有另一个具有相同名称的流水线 | ||||
| Field[] fields = Experiment.class.getDeclaredFields(); | Field[] fields = Experiment.class.getDeclaredFields(); | ||||
| for (Field field : fields) { | for (Field field : fields) { | ||||
| field.setAccessible(true); // 使私有字段可访问 | |||||
| field.setAccessible(true); | |||||
| if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { | if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { | ||||
| // 如果字段是“name”并且标记了CheckDuplicate注解 | // 如果字段是“name”并且标记了CheckDuplicate注解 | ||||
| CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); | CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); | ||||
| @@ -1,7 +1,12 @@ | |||||
| package com.ruoyi.platform.service.impl; | package com.ruoyi.platform.service.impl; | ||||
| import com.ruoyi.common.redis.service.RedisService; | |||||
| import com.ruoyi.common.security.utils.SecurityUtils; | import com.ruoyi.common.security.utils.SecurityUtils; | ||||
| import com.ruoyi.platform.domain.DevEnvironment; | |||||
| import com.ruoyi.platform.mapper.DevEnvironmentDao; | |||||
| import com.ruoyi.platform.service.DevEnvironmentService; | |||||
| import com.ruoyi.platform.service.JupyterService; | import com.ruoyi.platform.service.JupyterService; | ||||
| import com.ruoyi.platform.utils.JacksonUtil; | |||||
| import com.ruoyi.platform.utils.K8sClientUtil; | import com.ruoyi.platform.utils.K8sClientUtil; | ||||
| import com.ruoyi.platform.utils.MinioUtil; | import com.ruoyi.platform.utils.MinioUtil; | ||||
| import com.ruoyi.platform.utils.MlflowUtil; | import com.ruoyi.platform.utils.MlflowUtil; | ||||
| @@ -13,6 +18,7 @@ import org.springframework.stereotype.Service; | |||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | |||||
| @Service | @Service | ||||
| public class JupyterServiceImpl implements JupyterService { | public class JupyterServiceImpl implements JupyterService { | ||||
| @@ -39,6 +45,15 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| @Resource | @Resource | ||||
| private MlflowUtil mlflowUtil; | private MlflowUtil mlflowUtil; | ||||
| @Resource | |||||
| private DevEnvironmentDao devEnvironmentDao; | |||||
| @Resource | |||||
| private DevEnvironmentService devEnvironmentService; | |||||
| @Resource | |||||
| private RedisService redisService; | |||||
| public JupyterServiceImpl(MinioUtil minioUtil) { | public JupyterServiceImpl(MinioUtil minioUtil) { | ||||
| this.minioUtil = minioUtil; | this.minioUtil = minioUtil; | ||||
| } | } | ||||
| @@ -53,6 +68,54 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| return masterIp + ":" + podPort; | return masterIp + ":" + podPort; | ||||
| } | } | ||||
| @Override | |||||
| public String runJupyterService(Integer id) { | |||||
| DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id); | |||||
| String envName = devEnvironment.getName(); | |||||
| //TODO 设置环境变量 | |||||
| // 提取数据集,模型信息,得到数据集模型的path | |||||
| Map<String, Object> dataset = JacksonUtil.parseJSONStr2Map(devEnvironment.getDataset()); | |||||
| String datasetPath = (String) dataset.get("path"); | |||||
| Map<String, Object> model = JacksonUtil.parseJSONStr2Map(devEnvironment.getModel()); | |||||
| String modelPath = (String) model.get("path"); | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| String podName = loginUser.getUsername().toLowerCase() + "-editor-pod"; | |||||
| String pvcName = loginUser.getUsername().toLowerCase() + "-editor-pvc"; | |||||
| V1PersistentVolumeClaim pvc = k8sClientUtil.createPvc(namespace, pvcName, storage, storageClassName); | |||||
| //TODO 设置镜像可配置,这里先用默认镜像启动pod | |||||
| // 调用修改后的 createPod 方法,传入额外的参数 | |||||
| Integer podPort = k8sClientUtil.createConfiguredPod(podName, namespace, port, mountPath, pvc, image, datasetPath, modelPath); | |||||
| return masterIp + ":" + podPort; | |||||
| } | |||||
| @Override | |||||
| public String stopJupyterService(Integer id) throws Exception { | |||||
| DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id); | |||||
| if (devEnvironment==null){ | |||||
| throw new Exception("开发环境配置不存在"); | |||||
| } | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| String podName = loginUser.getUsername().toLowerCase() + "-editor-pod"; | |||||
| // 使用 Kubernetes API 删除 Pod | |||||
| String deleteResult = k8sClientUtil.deletePod(podName, namespace); | |||||
| // 检查 Pod 是否存在 | |||||
| boolean exists = k8sClientUtil.checkPodExists(podName, namespace); | |||||
| if (exists) { | |||||
| throw new Exception("Pod " + podName + " 删除失败"); | |||||
| } | |||||
| return deleteResult + ",编辑器已停止"; | |||||
| } | |||||
| @Override | @Override | ||||
| public void upload(InputStream inputStream) { | public void upload(InputStream inputStream) { | ||||
| try { | try { | ||||
| @@ -71,4 +134,6 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,252 @@ | |||||
| package com.ruoyi.platform.service.impl; | |||||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||||
| import com.ruoyi.platform.domain.*; | |||||
| import com.ruoyi.platform.mapper.ModelDependencyDao; | |||||
| import com.ruoyi.platform.service.*; | |||||
| import com.ruoyi.platform.utils.JacksonUtil; | |||||
| import com.ruoyi.platform.vo.ModelDependcyTreeVo; | |||||
| import com.ruoyi.platform.vo.ModelVersionDependcyVo; | |||||
| import com.ruoyi.system.api.model.LoginUser; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.context.annotation.Lazy; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageImpl; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import javax.annotation.Resource; | |||||
| import java.io.IOException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.stream.Collectors; | |||||
| /** | |||||
| * (ModelDependency)表服务实现类 | |||||
| * | |||||
| * @author Xidaray | |||||
| * @since 2024-05-29 13:51:23 | |||||
| */ | |||||
| @Service("modelDependencyService") | |||||
| public class ModelDependencyServiceImpl implements ModelDependencyService { | |||||
| @Resource | |||||
| private ModelDependencyDao modelDependencyDao; | |||||
| @Resource | |||||
| private ModelsService modelsService; | |||||
| @Resource | |||||
| private ModelsVersionService modelsVersionService; | |||||
| @Lazy | |||||
| @Resource | |||||
| private ExperimentService experimentService; | |||||
| @Lazy | |||||
| @Resource | |||||
| private ExperimentInsService experimentInsService; | |||||
| /** | |||||
| * 通过ID查询单条数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| @Override | |||||
| public ModelDependency queryById(Integer id) { | |||||
| return this.modelDependencyDao.queryById(id); | |||||
| } | |||||
| /** | |||||
| * 分页查询 | |||||
| * | |||||
| * @param modelDependency 筛选条件 | |||||
| * @param pageRequest 分页对象 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| @Override | |||||
| public Page<ModelDependency> queryByPage(ModelDependency modelDependency, PageRequest pageRequest) { | |||||
| long total = this.modelDependencyDao.count(modelDependency); | |||||
| return new PageImpl<>(this.modelDependencyDao.queryAllByLimit(modelDependency, pageRequest), pageRequest, total); | |||||
| } | |||||
| /** | |||||
| * 根据对象查询 | |||||
| * | |||||
| * @param modelDependency 筛选条件 | |||||
| * @return 查询结果 | |||||
| */ | |||||
| @Override | |||||
| public List<ModelDependency> queryByModelDependency(ModelDependency modelDependency) throws IOException { | |||||
| List<ModelDependency> modelDependencyList = this.modelDependencyDao.queryByModelDependency(modelDependency); | |||||
| return modelDependencyList; | |||||
| } | |||||
| @Override | |||||
| public ModelDependcyTreeVo getModelDependencyTree(ModelDependency modelDependencyQuery) throws Exception { | |||||
| //查询当前模型 | |||||
| modelDependencyQuery.setState(1); | |||||
| List<ModelDependency> modelDependencyList = this.queryByModelDependency(modelDependencyQuery); | |||||
| if (modelDependencyList==null || modelDependencyList.size()==0){ | |||||
| throw new Exception("当前模型依赖关系不存在"); | |||||
| } | |||||
| ModelDependency modelDependency = modelDependencyList.get(0); | |||||
| ModelDependcyTreeVo modelDependcyTreeVo = ModelDependencyConvertToTree(modelDependency); | |||||
| //递归父模型 | |||||
| processParentModel(modelDependcyTreeVo); | |||||
| //递归子模型 | |||||
| processChildrenModel(modelDependcyTreeVo); | |||||
| return modelDependcyTreeVo; | |||||
| } | |||||
| /** | |||||
| * 递归父模型 | |||||
| * @param modelDependcyTreeVo | |||||
| */ | |||||
| private void processParentModel(ModelDependcyTreeVo modelDependcyTreeVo) throws IOException { | |||||
| if (modelDependcyTreeVo.getParentModelsMap() != null) { | |||||
| List<Map<String, Object>> parentMaps = modelDependcyTreeVo.getParentModelsMap(); | |||||
| List<ModelDependcyTreeVo> ps = new ArrayList<ModelDependcyTreeVo>(); | |||||
| for (Map<String, Object> parent:parentMaps) { | |||||
| Integer model_id = (Integer) parent.get("model_id"); | |||||
| String version = (String) parent.get("model_version"); | |||||
| ModelDependency modelDependencyQuery = new ModelDependency(); | |||||
| modelDependencyQuery.setVersion(version); | |||||
| modelDependencyQuery.setCurrentModelId(model_id); | |||||
| List<ModelDependency> modelDependencyList = this.queryByModelDependency(modelDependencyQuery); | |||||
| if (modelDependencyList!=null&&modelDependencyList.size()>=0){ | |||||
| for (ModelDependency modelDependency:modelDependencyList){ | |||||
| ModelDependcyTreeVo modelDependencyTreeVoIn = ModelDependencyConvertToTree(modelDependency); | |||||
| processParentModel(modelDependencyTreeVoIn); | |||||
| ps.add(modelDependencyTreeVoIn); | |||||
| } | |||||
| } | |||||
| } | |||||
| modelDependcyTreeVo.setParentModels(ps); | |||||
| } | |||||
| } | |||||
| private void processChildrenModel(ModelDependcyTreeVo modelDependcyTreeVo) throws IOException { | |||||
| String version = modelDependcyTreeVo.getVersion(); | |||||
| Integer modelId = modelDependcyTreeVo.getCurrentModelId(); | |||||
| List<ModelDependcyTreeVo> cs = new ArrayList<ModelDependcyTreeVo>(); | |||||
| //查儿子们 | |||||
| List<ModelDependency> modelDependencyList = modelDependencyDao.queryChildrenByVersionId("\"model_id\":"+modelId, "\"model_version\":\""+version+"\""); | |||||
| if (modelDependencyList!=null&&modelDependencyList.size()>=0){ | |||||
| for (ModelDependency modelDependency:modelDependencyList){ | |||||
| ModelDependcyTreeVo modelDependencyTreeVoIn = ModelDependencyConvertToTree(modelDependency); | |||||
| processChildrenModel(modelDependencyTreeVoIn); | |||||
| cs.add(modelDependencyTreeVoIn); | |||||
| } | |||||
| } | |||||
| modelDependcyTreeVo.setChildrenModels(cs); | |||||
| } | |||||
| private ModelDependcyTreeVo ModelDependencyConvertToTree(ModelDependency modelDependency) throws IOException { | |||||
| ModelDependcyTreeVo modelDependcyTreeVo = new ModelDependcyTreeVo(); | |||||
| modelDependcyTreeVo.setCurrentModelId(modelDependency.getCurrentModelId()); | |||||
| modelDependcyTreeVo.setExpInsId(modelDependency.getExpInsId()); | |||||
| modelDependcyTreeVo.setVersion(modelDependency.getVersion()); | |||||
| modelDependcyTreeVo.setRefItem(modelDependency.getRefItem()); | |||||
| modelDependcyTreeVo.setTrainTask(JacksonUtil.parseJSONStr2Map(modelDependency.getTrainTask())); | |||||
| modelDependcyTreeVo.setTrainDataset(JacksonUtil.parseJSONStr2MapList(modelDependency.getTrainDataset())); | |||||
| modelDependcyTreeVo.setTrainImage(modelDependency.getTrainImage()); | |||||
| modelDependcyTreeVo.setTrainParams(JacksonUtil.parseJSONStr2TList(modelDependency.getTrainParams(),Object.class,null)); | |||||
| modelDependcyTreeVo.setTestDataset(JacksonUtil.parseJSONStr2MapList(modelDependency.getTestDataset())); | |||||
| modelDependcyTreeVo.setProjectDependency(JacksonUtil.parseJSONStr2Map(modelDependency.getProjectDependency())); | |||||
| modelDependcyTreeVo.setParentModelsMap(JacksonUtil.parseJSONStr2MapList(modelDependency.getParentModels())); | |||||
| /** | |||||
| * 补充workFlow_id + 是否共有 | |||||
| */ | |||||
| Integer currentModelId = modelDependency.getCurrentModelId(); | |||||
| Integer expInsId = modelDependency.getExpInsId(); | |||||
| Models models = modelsService.queryById(currentModelId); | |||||
| ModelsVersion modelsVersionquery = new ModelsVersion(); | |||||
| modelsVersionquery.setModelsId(currentModelId); | |||||
| modelsVersionquery.setVersion(modelDependency.getVersion()); | |||||
| ModelsVersion modelsVersion = modelsVersionService.queryByModelsVersion(modelsVersionquery); | |||||
| ExperimentIns experimentIns = experimentInsService.queryById(expInsId); | |||||
| Experiment experiment = experimentService.queryById(experimentIns.getExperimentId()); | |||||
| ModelVersionDependcyVo modelVersionDependcyVo = new ModelVersionDependcyVo(); | |||||
| modelVersionDependcyVo.setName(models.getName()); | |||||
| modelVersionDependcyVo.setAvailableRange(models.getAvailableRange()); | |||||
| modelVersionDependcyVo.setDescription(models.getDescription()); | |||||
| modelVersionDependcyVo.setModelTag(models.getModelTag()); | |||||
| modelVersionDependcyVo.setModelType(models.getModelType()); | |||||
| modelVersionDependcyVo.setModelTagName(models.getModelTagName()); | |||||
| modelVersionDependcyVo.setModelTypeName(models.getModelTypeName()); | |||||
| modelVersionDependcyVo.setFileName(modelsVersion.getFileName()); | |||||
| modelVersionDependcyVo.setFileSize(modelsVersion.getFileSize()); | |||||
| modelVersionDependcyVo.setUrl(modelsVersion.getUrl()); | |||||
| modelDependcyTreeVo.setWorkflowId(experiment.getWorkflowId()); | |||||
| modelDependcyTreeVo.setModelVersionDependcyVo(modelVersionDependcyVo); | |||||
| return modelDependcyTreeVo; | |||||
| } | |||||
| /** | |||||
| * 新增数据 | |||||
| * | |||||
| * @param modelDependency 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| @Override | |||||
| public ModelDependency insert(ModelDependency modelDependency) { | |||||
| //插入预备,此时不需要判断版本重复 | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| modelDependency.setCreateBy(loginUser.getUsername()); | |||||
| modelDependency.setUpdateBy(loginUser.getUsername()); | |||||
| modelDependency.setUpdateTime(new Date()); | |||||
| modelDependency.setCreateTime(new Date()); | |||||
| this.modelDependencyDao.insert(modelDependency); | |||||
| return modelDependency; | |||||
| } | |||||
| /** | |||||
| * 修改数据 | |||||
| * | |||||
| * @param modelDependency 实例对象 | |||||
| * @return 实例对象 | |||||
| */ | |||||
| @Override | |||||
| public ModelDependency update(ModelDependency modelDependency) { | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| modelDependency.setUpdateBy(loginUser.getUsername()); | |||||
| modelDependency.setUpdateTime(new Date()); | |||||
| this.modelDependencyDao.update(modelDependency); | |||||
| return this.queryById(modelDependency.getId()); | |||||
| } | |||||
| /** | |||||
| * 通过主键删除数据 | |||||
| * | |||||
| * @param id 主键 | |||||
| * @return 是否成功 | |||||
| */ | |||||
| @Override | |||||
| public boolean deleteById(Integer id) { | |||||
| return this.modelDependencyDao.deleteById(id) > 0; | |||||
| } | |||||
| @Override | |||||
| public String removeById(Integer id) { | |||||
| ModelDependency modelDependency = this.modelDependencyDao.queryById(id); | |||||
| if (modelDependency == null){ | |||||
| return "模型依赖信息不存在"; | |||||
| } | |||||
| //判断权限,只有admin和创建者本身可以删除该数据集 | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||||
| String username = loginUser.getUsername(); | |||||
| String createdBy = modelDependency.getCreateBy(); | |||||
| if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){ | |||||
| return "无权限删除"; | |||||
| } | |||||
| modelDependency.setState(0); | |||||
| return this.modelDependencyDao.update(modelDependency)>0?"删除成功":"删除失败"; | |||||
| } | |||||
| } | |||||
| @@ -192,6 +192,7 @@ public class ModelsServiceImpl implements ModelsService { | |||||
| * | * | ||||
| * @param id models_version表的主键 | * @param id models_version表的主键 | ||||
| * @return 文件内容 | * @return 文件内容 | ||||
| * | |||||
| */ | */ | ||||
| @Override | @Override | ||||
| @@ -3,20 +3,24 @@ package com.ruoyi.platform.service.impl; | |||||
| import com.ruoyi.common.security.utils.SecurityUtils; | import com.ruoyi.common.security.utils.SecurityUtils; | ||||
| import com.ruoyi.platform.annotations.CheckDuplicate; | import com.ruoyi.platform.annotations.CheckDuplicate; | ||||
| import com.ruoyi.platform.domain.Dataset; | import com.ruoyi.platform.domain.Dataset; | ||||
| import com.ruoyi.platform.domain.ModelDependency; | |||||
| import com.ruoyi.platform.domain.Models; | import com.ruoyi.platform.domain.Models; | ||||
| import com.ruoyi.platform.domain.ModelsVersion; | import com.ruoyi.platform.domain.ModelsVersion; | ||||
| import com.ruoyi.platform.mapper.ModelsDao; | import com.ruoyi.platform.mapper.ModelsDao; | ||||
| import com.ruoyi.platform.mapper.ModelsVersionDao; | import com.ruoyi.platform.mapper.ModelsVersionDao; | ||||
| import com.ruoyi.platform.service.ModelDependencyService; | |||||
| import com.ruoyi.platform.service.ModelsVersionService; | import com.ruoyi.platform.service.ModelsVersionService; | ||||
| import com.ruoyi.system.api.model.LoginUser; | import com.ruoyi.system.api.model.LoginUser; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.context.annotation.Lazy; | |||||
| import org.springframework.data.domain.Page; | import org.springframework.data.domain.Page; | ||||
| import org.springframework.data.domain.PageImpl; | import org.springframework.data.domain.PageImpl; | ||||
| import org.springframework.data.domain.PageRequest; | 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.lang.reflect.Field; | import java.lang.reflect.Field; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.HashMap; | import java.util.HashMap; | ||||
| @@ -36,7 +40,9 @@ public class ModelsVersionServiceImpl implements ModelsVersionService { | |||||
| @Resource | @Resource | ||||
| private ModelsDao modelsDao; | private ModelsDao modelsDao; | ||||
| @Resource | |||||
| @Lazy | |||||
| private ModelDependencyService modelDependencyService; | |||||
| // 固定存储桶名 | // 固定存储桶名 | ||||
| @Value("${minio.dataReleaseBucketName}") | @Value("${minio.dataReleaseBucketName}") | ||||
| private String bucketName; | private String bucketName; | ||||
| @@ -81,6 +87,7 @@ public class ModelsVersionServiceImpl implements ModelsVersionService { | |||||
| modelsVersion.setCreateTime(new Date()); | modelsVersion.setCreateTime(new Date()); | ||||
| modelsVersion.setState(1); | modelsVersion.setState(1); | ||||
| this.modelsVersionDao.insert(modelsVersion); | this.modelsVersionDao.insert(modelsVersion); | ||||
| insertModelsDependency(modelsVersion); | |||||
| return modelsVersion; | return modelsVersion; | ||||
| } | } | ||||
| @@ -191,7 +198,7 @@ public class ModelsVersionServiceImpl implements ModelsVersionService { | |||||
| } | } | ||||
| @Override | @Override | ||||
| public Map<Integer, String> deleteModelsVersion(Integer modelsId, String version) { | |||||
| public Map<Integer, String> deleteModelsVersion(Integer modelsId, String version) throws IOException { | |||||
| Map<Integer, String> results = new HashMap<Integer,String>(); | Map<Integer, String> results = new HashMap<Integer,String>(); | ||||
| // 根据模型ID和版本查询所有模型版本 | // 根据模型ID和版本查询所有模型版本 | ||||
| List<ModelsVersion> versions = this.modelsVersionDao.queryAllByModelsVersion(modelsId, version); | List<ModelsVersion> versions = this.modelsVersionDao.queryAllByModelsVersion(modelsId, version); | ||||
| @@ -200,6 +207,16 @@ public class ModelsVersionServiceImpl implements ModelsVersionService { | |||||
| String result = this.removeById(modelsVersion.getId()); | String result = this.removeById(modelsVersion.getId()); | ||||
| results.put(modelsVersion.getId(), result); | results.put(modelsVersion.getId(), result); | ||||
| } | } | ||||
| // 删除依赖关系 | |||||
| ModelDependency modelDependency = new ModelDependency(); | |||||
| modelDependency.setCurrentModelId(modelsId); | |||||
| modelDependency.setVersion(version); | |||||
| modelDependency.setState(1); | |||||
| List<ModelDependency> modelDependencyList = modelDependencyService.queryByModelDependency(modelDependency); | |||||
| if (modelDependencyList.size()>0){ | |||||
| ModelDependency modelDependency1 = modelDependencyList.get(0); | |||||
| modelDependencyService.removeById(modelDependency1.getId()); | |||||
| } | |||||
| return results; | return results; | ||||
| } | } | ||||
| @@ -210,6 +227,7 @@ public class ModelsVersionServiceImpl implements ModelsVersionService { | |||||
| for(ModelsVersion modelsVersion : modelsVersions) { | for(ModelsVersion modelsVersion : modelsVersions) { | ||||
| insertPrepare(modelsVersion); | insertPrepare(modelsVersion); | ||||
| } | } | ||||
| insertModelsDependency(modelsVersions.get(0)); | |||||
| this.modelsVersionDao.insertBatch(modelsVersions); | this.modelsVersionDao.insertBatch(modelsVersions); | ||||
| return "新增模型版本成功"; | return "新增模型版本成功"; | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| @@ -248,4 +266,23 @@ public class ModelsVersionServiceImpl implements ModelsVersionService { | |||||
| } | } | ||||
| //新增模型依赖关系 | |||||
| private void insertModelsDependency(ModelsVersion modelsVersion) throws Exception { | |||||
| ModelDependency modelDependency = new ModelDependency(); | |||||
| modelDependency.setCurrentModelId(modelsVersion.getModelsId()); | |||||
| modelDependency.setVersion(modelsVersion.getVersion()); | |||||
| modelDependency.setState(2); | |||||
| List<ModelDependency> modelDependencyList = modelDependencyService.queryByModelDependency(modelDependency); | |||||
| if (modelDependencyList != null && modelDependencyList.size()>0){ | |||||
| //查到2,说明是之前流水线推送的,你就直接该状态生效就完了 | |||||
| ModelDependency modelDependency1 = modelDependencyList.get(0); | |||||
| modelDependency1.setState(1); | |||||
| modelDependencyService.update(modelDependency1); | |||||
| }else { | |||||
| modelDependency.setState(1); | |||||
| modelDependencyService.insert(modelDependency); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -110,8 +110,9 @@ public class WorkflowServiceImpl implements WorkflowService { | |||||
| * @return 实例对象 | * @return 实例对象 | ||||
| */ | */ | ||||
| @Override | @Override | ||||
| public Workflow update(Workflow workflow) { | |||||
| public Workflow update(Workflow workflow) throws Exception { | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | LoginUser loginUser = SecurityUtils.getLoginUser(); | ||||
| checkDeclaredName(workflow); | |||||
| workflow.setUpdateBy(loginUser.getUsername()); | workflow.setUpdateBy(loginUser.getUsername()); | ||||
| workflow.setUpdateTime(new Date()); | workflow.setUpdateTime(new Date()); | ||||
| this.workflowDao.update(workflow); | this.workflowDao.update(workflow); | ||||
| @@ -207,10 +208,9 @@ public class WorkflowServiceImpl implements WorkflowService { | |||||
| // 这是相同的流水线,更新操作中没有重复名称问题 | // 这是相同的流水线,更新操作中没有重复名称问题 | ||||
| return; | return; | ||||
| } | } | ||||
| // 现在我们知道还有另一个具有相同名称的流水线 | |||||
| Field[] fields = Workflow.class.getDeclaredFields(); | Field[] fields = Workflow.class.getDeclaredFields(); | ||||
| for (Field field : fields) { | for (Field field : fields) { | ||||
| field.setAccessible(true); // 使私有字段可访问 | |||||
| field.setAccessible(true); | |||||
| if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { | if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { | ||||
| // 如果字段是“name”并且标记了CheckDuplicate注解 | // 如果字段是“name”并且标记了CheckDuplicate注解 | ||||
| CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); | CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); | ||||
| @@ -103,6 +103,7 @@ public class WorkspaceServiceImpl implements WorkspaceService { | |||||
| assetCountMap.put("image", imageCount); | assetCountMap.put("image", imageCount); | ||||
| //统计组件数量 | //统计组件数量 | ||||
| Component component = new Component(); | Component component = new Component(); | ||||
| component.setAvailableRange(availableRange); | |||||
| Integer componentCount = (int) this.componentDao.count(component); | Integer componentCount = (int) this.componentDao.count(component); | ||||
| assetCountMap.put("component", componentCount); | assetCountMap.put("component", componentCount); | ||||
| //统计流水线数量 | //统计流水线数量 | ||||
| @@ -5,9 +5,12 @@ import com.fasterxml.jackson.databind.DeserializationFeature; | |||||
| import com.fasterxml.jackson.databind.ObjectMapper; | import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import com.fasterxml.jackson.databind.SerializationFeature; | import com.fasterxml.jackson.databind.SerializationFeature; | ||||
| import com.fasterxml.jackson.databind.type.CollectionType; | import com.fasterxml.jackson.databind.type.CollectionType; | ||||
| import com.ruoyi.common.core.utils.StringUtils; | |||||
| import org.apache.xmlbeans.impl.xb.xsdschema.Public; | |||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.HashMap; | |||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| @@ -56,6 +59,21 @@ public class JacksonUtil { | |||||
| } | } | ||||
| } | } | ||||
| public static String replaceInAarry(String res, List<Map<String, Object>> params) { | |||||
| // 解析 JSON 数组 | |||||
| if (params == null) { | |||||
| return res; | |||||
| } | |||||
| for (int i = 0; i < params.size(); i++) { | |||||
| Map<String, Object> stringObjectMap = params.get(i); | |||||
| if (res.contains("${" + stringObjectMap.get("param_name") + "}")) { | |||||
| res = res.replace("${" + stringObjectMap.get("param_name") + "}", String.valueOf( stringObjectMap.get("param_value"))); | |||||
| } | |||||
| } | |||||
| return res; | |||||
| } | |||||
| /** | /** | ||||
| * 获取ObjectMapper。其本身是线程安全的,可以作为成员变量,但传入的参数不可能每次都一样,所以不使用成员变量。 | * 获取ObjectMapper。其本身是线程安全的,可以作为成员变量,但传入的参数不可能每次都一样,所以不使用成员变量。 | ||||
| * | * | ||||
| @@ -140,6 +158,7 @@ public class JacksonUtil { | |||||
| */ | */ | ||||
| public static Map<String, Object> parseJSONStr2Map(String jsonStr) { | public static Map<String, Object> parseJSONStr2Map(String jsonStr) { | ||||
| try { | try { | ||||
| if (StringUtils.isEmpty(jsonStr)) {return new HashMap<String, Object>();} | |||||
| // 对于json字符串新增的字段,由于返回的是map,不管 compatNewProps 设置成什么值都不会抛出异常 | // 对于json字符串新增的字段,由于返回的是map,不管 compatNewProps 设置成什么值都不会抛出异常 | ||||
| ObjectMapper objectMapper = getObjectMapper(null, false, false, true); | ObjectMapper objectMapper = getObjectMapper(null, false, false, true); | ||||
| return objectMapper.readValue(jsonStr, Map.class); | return objectMapper.readValue(jsonStr, Map.class); | ||||
| @@ -158,6 +177,7 @@ public class JacksonUtil { | |||||
| */ | */ | ||||
| public static List<Map<String, Object>> parseJSONStr2MapList(String jsonStr) { | public static List<Map<String, Object>> parseJSONStr2MapList(String jsonStr) { | ||||
| try { | try { | ||||
| if (StringUtils.isEmpty(jsonStr)) {return new ArrayList<>();} | |||||
| // 对于json字符串新增的字段,由于返回的是map,不管 compatNewProps 设置成什么值都不会抛出异常 | // 对于json字符串新增的字段,由于返回的是map,不管 compatNewProps 设置成什么值都不会抛出异常 | ||||
| ObjectMapper objectMapper = getObjectMapper(null, false, false, true); | ObjectMapper objectMapper = getObjectMapper(null, false, false, true); | ||||
| CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Map.class); | CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Map.class); | ||||
| @@ -22,9 +22,7 @@ import org.springframework.stereotype.Component; | |||||
| import javax.annotation.PostConstruct; | import javax.annotation.PostConstruct; | ||||
| import java.io.BufferedReader; | import java.io.BufferedReader; | ||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||
| import java.util.HashMap; | |||||
| import java.util.LinkedHashMap; | |||||
| import java.util.Map; | |||||
| import java.util.*; | |||||
| /** | /** | ||||
| * k8s客户端 | * k8s客户端 | ||||
| @@ -282,13 +280,13 @@ public class K8sClientUtil { | |||||
| .endSpec() | .endSpec() | ||||
| .build(); | .build(); | ||||
| try { | try { | ||||
| pod = api.createNamespacedPod(namespace, pod, null, null, null); | pod = api.createNamespacedPod(namespace, pod, null, null, null); | ||||
| } catch (ApiException e) { | } catch (ApiException e) { | ||||
| log.error("创建pod异常:" + e.getResponseBody(), e); | log.error("创建pod异常:" + e.getResponseBody(), e); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| log.error("创建pod系统异常:", e); | log.error("创建pod系统异常:", e); | ||||
| } | } | ||||
| V1Service service = createService(namespace, podName + "-svc", port, selector); | V1Service service = createService(namespace, podName + "-svc", port, selector); | ||||
| @@ -324,7 +322,6 @@ public class K8sClientUtil { | |||||
| for (V1Pod pod1 : v1PodList.getItems()) { | for (V1Pod pod1 : v1PodList.getItems()) { | ||||
| if (StringUtils.equals(pod1.getMetadata().getName(), podName)) { | if (StringUtils.equals(pod1.getMetadata().getName(), podName)) { | ||||
| // PVC 已存在 | // PVC 已存在 | ||||
| V1Service service = createService(namespace, podName + "-svc", port, selector); | V1Service service = createService(namespace, podName + "-svc", port, selector); | ||||
| if (service != null) { | if (service != null) { | ||||
| return service.getSpec().getPorts().get(0).getNodePort(); | return service.getSpec().getPorts().get(0).getNodePort(); | ||||
| @@ -378,6 +375,73 @@ public class K8sClientUtil { | |||||
| return service.getSpec().getPorts().get(0).getNodePort(); | return service.getSpec().getPorts().get(0).getNodePort(); | ||||
| } | } | ||||
| public Integer createConfiguredPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, String image, String datasetPath, String modelPath) { | |||||
| Map<String, String> selector = new LinkedHashMap<>(); | |||||
| selector.put("k8s-jupyter", podName); | |||||
| CoreV1Api api = new CoreV1Api(apiClient); | |||||
| V1PodList v1PodList = null; | |||||
| try { | |||||
| v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null); | |||||
| } catch (ApiException e) { | |||||
| log.error("获取 POD 异常:", e); | |||||
| } | |||||
| if (v1PodList != null) { | |||||
| for (V1Pod pod1 : v1PodList.getItems()) { | |||||
| // PVC 已存在 | |||||
| if (StringUtils.equals(pod1.getMetadata().getName(), podName)) { | |||||
| V1Service service = createService(namespace, podName + "-svc", port, selector); | |||||
| if (service != null) { | |||||
| return service.getSpec().getPorts().get(0).getNodePort(); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| // 配置卷和卷挂载 | |||||
| List<V1VolumeMount> volumeMounts = new ArrayList<>(); | |||||
| volumeMounts.add(new V1VolumeMount().name("workspace").mountPath(mountPath)); | |||||
| volumeMounts.add(new V1VolumeMount().name("dataset").mountPath("/datasets").subPath(datasetPath).readOnly(true)); | |||||
| volumeMounts.add(new V1VolumeMount().name("model").mountPath("/model").subPath(modelPath).readOnly(true)); | |||||
| List<V1Volume> volumes = new ArrayList<>(); | |||||
| volumes.add(new V1Volume().name("workspace").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName()))); | |||||
| volumes.add(new V1Volume().name("dataset").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName()))); | |||||
| volumes.add(new V1Volume().name("model").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName()))); | |||||
| V1Pod pod = new V1PodBuilder() | |||||
| .withNewMetadata() | |||||
| .withName(podName) | |||||
| .withLabels(selector) | |||||
| .endMetadata() | |||||
| .withNewSpec() | |||||
| .addNewContainer() | |||||
| .withName(podName) | |||||
| .withImage(image) | |||||
| .withPorts(new V1ContainerPort().containerPort(port).protocol("TCP")) | |||||
| .withVolumeMounts(volumeMounts) | |||||
| .endContainer() | |||||
| .withVolumes(volumes) | |||||
| .withTerminationGracePeriodSeconds(14400L) | |||||
| .endSpec() | |||||
| .build(); | |||||
| try { | |||||
| pod = api.createNamespacedPod(namespace, pod, null, null, null); | |||||
| } catch (ApiException e) { | |||||
| log.error("创建pod异常:" + e.getResponseBody(), e); | |||||
| } catch (Exception e) { | |||||
| log.error("创建pod系统异常:", e); | |||||
| } | |||||
| V1Service service = createService(namespace, podName + "-svc", port, selector); | |||||
| return service.getSpec().getPorts().get(0).getNodePort(); | |||||
| } | |||||
| /** | /** | ||||
| * 根据获取namespace,deploymentName的Pod Name | * 根据获取namespace,deploymentName的Pod Name | ||||
| * | * | ||||
| @@ -495,4 +559,51 @@ public class K8sClientUtil { | |||||
| } | } | ||||
| return pod; | return pod; | ||||
| } | } | ||||
| /** | |||||
| * 删除 Pod | |||||
| * | |||||
| * @param podName Pod 名称 | |||||
| * @param namespace 命名空间 | |||||
| * @throws ApiException 异常 | |||||
| */ | |||||
| public String deletePod(String podName, String namespace) throws ApiException { | |||||
| CoreV1Api api = new CoreV1Api(apiClient); | |||||
| try { | |||||
| V1Pod pod = api.deleteNamespacedPod(podName, namespace, null, null, null, null, null, null); | |||||
| return "Pod " + podName + " 删除请求已发送"; | |||||
| } catch (ApiException e) { | |||||
| if (e.getCode() == 404) { | |||||
| return "Pod " + podName + " 不存在"; | |||||
| } else { | |||||
| log.error("删除pod异常:" + e.getResponseBody(), e); | |||||
| throw e; | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 检查 Pod 是否存在 | |||||
| * | |||||
| * @param podName Pod 名称 | |||||
| * @param namespace 命名空间 | |||||
| * @return 是否存在 | |||||
| * @throws ApiException 异常 | |||||
| */ | |||||
| public boolean checkPodExists(String podName, String namespace) throws ApiException { | |||||
| CoreV1Api api = new CoreV1Api(apiClient); | |||||
| try { | |||||
| api.readNamespacedPod(podName, namespace, null,false,false); | |||||
| return true; | |||||
| } catch (ApiException e) { | |||||
| if (e.getCode() == 404) { | |||||
| return false; | |||||
| } else { | |||||
| log.error("检查pod存在性异常:" + e.getResponseBody(), e); | |||||
| throw e; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,72 @@ | |||||
| package com.ruoyi.platform.vo; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import com.ruoyi.platform.domain.Models; | |||||
| import lombok.Data; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| @Data | |||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||||
| public class ModelDependcyTreeVo { | |||||
| /** | |||||
| * 当前模型id | |||||
| */ | |||||
| private Integer currentModelId; | |||||
| /** | |||||
| * 实验实例id | |||||
| */ | |||||
| private Integer expInsId; | |||||
| /** | |||||
| * 版本 | |||||
| */ | |||||
| private String version; | |||||
| /** | |||||
| * 引用项目 | |||||
| */ | |||||
| private String refItem; | |||||
| /** | |||||
| * 训练任务 | |||||
| */ | |||||
| private Map trainTask; | |||||
| /** | |||||
| * 训练数据集 | |||||
| */ | |||||
| private List<Map<String, Object>> trainDataset; | |||||
| /** | |||||
| * 训练参数 | |||||
| */ | |||||
| private List trainParams; | |||||
| /** | |||||
| * 训练镜像 | |||||
| */ | |||||
| private String trainImage; | |||||
| /** | |||||
| * 测试数据集 | |||||
| */ | |||||
| private List<Map<String, Object>> testDataset; | |||||
| /** | |||||
| * 依赖项目 | |||||
| */ | |||||
| private Map projectDependency; | |||||
| private List<Map<String, Object>> parentModelsMap; | |||||
| /** | |||||
| * 父模型 | |||||
| */ | |||||
| private List<ModelDependcyTreeVo> parentModels; | |||||
| /** | |||||
| * 子模型 | |||||
| */ | |||||
| private List<ModelDependcyTreeVo> childrenModels; | |||||
| private Long workflowId; | |||||
| private ModelVersionDependcyVo modelVersionDependcyVo; | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| package com.ruoyi.platform.vo; | |||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import com.ruoyi.platform.annotations.CheckDuplicate; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| @Data | |||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||||
| public class ModelVersionDependcyVo implements Serializable { | |||||
| @ApiModelProperty(name = "name") | |||||
| private String name; | |||||
| // private String version; | |||||
| @ApiModelProperty(name = "description") | |||||
| private String description; | |||||
| @ApiModelProperty(value = "模型可见范围,1表示公开,0表示私有") | |||||
| private int availableRange; | |||||
| @ApiModelProperty(value = "模型类型(模型框架)") | |||||
| private String modelType; | |||||
| @ApiModelProperty(value = "模型标签") | |||||
| private String modelTag; | |||||
| @ApiModelProperty(value = "模型类型名") | |||||
| private String modelTypeName; | |||||
| @ApiModelProperty(value = "模型tag名") | |||||
| private String modelTagName; | |||||
| @ApiModelProperty(value = "模型存储地址") | |||||
| private String url; | |||||
| @ApiModelProperty(value = "文件名") | |||||
| private String fileName; | |||||
| @ApiModelProperty(value = "文件大小") | |||||
| private String fileSize; | |||||
| } | |||||
| @@ -16,6 +16,7 @@ | |||||
| <result property="mountPath" column="mount_path" jdbcType="VARCHAR"/> | <result property="mountPath" column="mount_path" jdbcType="VARCHAR"/> | ||||
| <result property="inParameters" column="in_parameters" jdbcType="VARCHAR"/> | <result property="inParameters" column="in_parameters" jdbcType="VARCHAR"/> | ||||
| <result property="outParameters" column="out_parameters" jdbcType="VARCHAR"/> | <result property="outParameters" column="out_parameters" jdbcType="VARCHAR"/> | ||||
| <result property="availableRange" column="available_range" jdbcType="INTEGER"/> | |||||
| <result property="description" column="description" jdbcType="VARCHAR"/> | <result property="description" column="description" jdbcType="VARCHAR"/> | ||||
| <result property="iconPath" column="icon_path" jdbcType="VARCHAR"/> | <result property="iconPath" column="icon_path" jdbcType="VARCHAR"/> | ||||
| <result property="createBy" column="create_by" jdbcType="VARCHAR"/> | <result property="createBy" column="create_by" jdbcType="VARCHAR"/> | ||||
| @@ -28,7 +29,7 @@ | |||||
| <!--查询单个--> | <!--查询单个--> | ||||
| <select id="queryById" resultMap="ComponentMap"> | <select id="queryById" resultMap="ComponentMap"> | ||||
| select | select | ||||
| id,category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,description,icon_path,create_by,create_time,update_by,update_time,state | |||||
| id,category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,available_range,description,icon_path,create_by,create_time,update_by,update_time,state | |||||
| from component | from component | ||||
| where id = #{id} and state = 1 | where id = #{id} and state = 1 | ||||
| </select> | </select> | ||||
| @@ -42,7 +43,7 @@ | |||||
| <!--查询指定行数据--> | <!--查询指定行数据--> | ||||
| <select id="queryAllByLimit" resultMap="ComponentMap"> | <select id="queryAllByLimit" resultMap="ComponentMap"> | ||||
| select | select | ||||
| id,category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,description,icon_path,create_by,create_time,update_by,update_time,state | |||||
| id,category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,available_range,description,icon_path,create_by,create_time,update_by,update_time,state | |||||
| from component | from component | ||||
| <where> | <where> | ||||
| state = 1 | state = 1 | ||||
| @@ -85,6 +86,9 @@ | |||||
| <if test="component.outParameters != null and component.outParameters != ''"> | <if test="component.outParameters != null and component.outParameters != ''"> | ||||
| and out_parameters = #{component.outParameters} | and out_parameters = #{component.outParameters} | ||||
| </if> | </if> | ||||
| <if test="component.availableRange != null"> | |||||
| and available_range = #{component.availableRange} | |||||
| </if> | |||||
| <if test="component.description != null and component.description != ''"> | <if test="component.description != null and component.description != ''"> | ||||
| and description = #{component.description} | and description = #{component.description} | ||||
| </if> | </if> | ||||
| @@ -155,6 +159,9 @@ | |||||
| <if test="component.outParameters != null and component.outParameters != ''"> | <if test="component.outParameters != null and component.outParameters != ''"> | ||||
| and out_parameters = #{component.outParameters} | and out_parameters = #{component.outParameters} | ||||
| </if> | </if> | ||||
| <if test="component.availableRange != null"> | |||||
| and available_range = #{component.availableRange} | |||||
| </if> | |||||
| <if test="component.description != null and component.description != ''"> | <if test="component.description != null and component.description != ''"> | ||||
| and description = #{component.description} | and description = #{component.description} | ||||
| </if> | </if> | ||||
| @@ -190,23 +197,23 @@ | |||||
| <!--新增所有列--> | <!--新增所有列--> | ||||
| <insert id="insert" keyProperty="id" useGeneratedKeys="true"> | <insert id="insert" keyProperty="id" useGeneratedKeys="true"> | ||||
| insert into component(category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,description,icon_path,create_by,create_time,update_by,update_time,state) | |||||
| values (#{component.categoryId},#{component.componentName},#{component.componentLabel},#{component.images},#{component.workingDirectory},#{component.command},#{component.envVirables},#{component.resourcesStandard},#{component.controlStrategy},#{component.mountPath},#{component.inParameters},#{component.outParameters},#{component.description},#{component.iconPath},#{component.createBy},#{component.createTime},#{component.updateBy},#{component.updateTime},#{component.state}) | |||||
| insert into component(category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,available_range,description,icon_path,create_by,create_time,update_by,update_time,state) | |||||
| values (#{component.categoryId},#{component.componentName},#{component.componentLabel},#{component.images},#{component.workingDirectory},#{component.command},#{component.envVirables},#{component.resourcesStandard},#{component.controlStrategy},#{component.mountPath},#{component.inParameters},#{component.outParameters},#{component.availableRange},#{component.description},#{component.iconPath},#{component.createBy},#{component.createTime},#{component.updateBy},#{component.updateTime},#{component.state}) | |||||
| </insert> | </insert> | ||||
| <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> | <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> | ||||
| insert into component(category_idcomponent_namecomponent_labelimagesworking_directorycommandenv_virablesresources_standardcontrol_strategymount_pathin_parametersout_parameterscreate_bycreate_timeupdate_byupdate_timestate) | |||||
| insert into component(category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,available_range,description,icon_path,create_by,create_time,update_by,update_time,state) | |||||
| values | values | ||||
| <foreach collection="entities" item="entity" separator=","> | <foreach collection="entities" item="entity" separator=","> | ||||
| (#{entity.categoryId}#{entity.componentName}#{entity.componentLabel}#{entity.images}#{entity.workingDirectory}#{entity.command}#{entity.envVirables}#{entity.resourcesStandard}#{entity.controlStrategy}#{entity.mountPath}#{entity.inParameters}#{entity.outParameters}#{entity.createBy}#{entity.createTime}#{entity.updateBy}#{entity.updateTime}#{entity.state}) | |||||
| (#{entity.categoryId},#{entity.componentName},#{entity.componentLabel},#{entity.images},#{entity.workingDirectory},#{entity.command},#{entity.envVirables},#{entity.resourcesStandard},#{entity.controlStrategy},#{entity.mountPath},#{entity.inParameters},#{entity.outParameters},#{entity.availableRange},#{entity.createBy},#{entity.createTime},#{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 component(category_idcomponent_namecomponent_labelimagesworking_directorycommandenv_virablesresources_standardcontrol_strategymount_pathin_parametersout_parameterscreate_bycreate_timeupdate_byupdate_timestate) | |||||
| insert into component(category_id,component_name,component_Label,images,working_directory,command,env_virables,resources_standard,control_strategy,mount_path,in_parameters,out_parameters,available_range,description,icon_path,create_by,create_time,update_by,update_time,state) | |||||
| values | values | ||||
| <foreach collection="entities" item="entity" separator=","> | <foreach collection="entities" item="entity" separator=","> | ||||
| (#{entity.categoryId}#{entity.componentName}#{entity.componentId}#{entity.images}#{entity.workingDirectory}#{entity.command}#{entity.envVirables}#{entity.resourcesStandard}#{entity.controlStrategy}#{entity.mountPath}#{entity.inParameters}#{entity.outParameters}#{entity.createBy}#{entity.createTime}#{entity.updateBy}#{entity.updateTime}#{entity.state}) | |||||
| (#{entity.categoryId},#{entity.componentName},#{entity.componentLabel},#{entity.images},#{entity.workingDirectory},#{entity.command},#{entity.envVirables},#{entity.resourcesStandard},#{entity.controlStrategy},#{entity.mountPath},#{entity.inParameters},#{entity.outParameters},#{entity.availableRange},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state}) | |||||
| </foreach> | </foreach> | ||||
| on duplicate key update | on duplicate key update | ||||
| category_id = values(category_id)component_name = values(component_name)component_id = values(component_id)images = values(images)working_directory = values(working_directory)command = values(command)env_virables = values(env_virables)resources_standard = values(resources_standard)control_strategy = values(control_strategy)mount_path = values(mount_path)in_parameters = values(in_parameters)out_parameters = values(out_parameters)create_by = values(create_by)create_time = values(create_time)update_by = values(update_by)update_time = values(update_time)state = values(state) | category_id = values(category_id)component_name = values(component_name)component_id = values(component_id)images = values(images)working_directory = values(working_directory)command = values(command)env_virables = values(env_virables)resources_standard = values(resources_standard)control_strategy = values(control_strategy)mount_path = values(mount_path)in_parameters = values(in_parameters)out_parameters = values(out_parameters)create_by = values(create_by)create_time = values(create_time)update_by = values(update_by)update_time = values(update_time)state = values(state) | ||||
| @@ -255,6 +262,9 @@ category_id = values(category_id)component_name = values(component_name)componen | |||||
| <if test="component.outParameters != null and component.outParameters != ''"> | <if test="component.outParameters != null and component.outParameters != ''"> | ||||
| out_parameters = #{component.outParameters}, | out_parameters = #{component.outParameters}, | ||||
| </if> | </if> | ||||
| <if test="component.availableRange != null"> | |||||
| available_range = #{component.availableRange}, | |||||
| </if> | |||||
| <if test="component.description != null and component.description != ''"> | <if test="component.description != null and component.description != ''"> | ||||
| description = #{component.description}, | description = #{component.description}, | ||||
| </if> | </if> | ||||
| @@ -0,0 +1,246 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.ruoyi.platform.mapper.DevEnvironmentDao"> | |||||
| <resultMap type="com.ruoyi.platform.domain.DevEnvironment" id="DevEnvironmentMap"> | |||||
| <result property="id" column="id" jdbcType="INTEGER"/> | |||||
| <result property="name" column="name" jdbcType="VARCHAR"/> | |||||
| <result property="status" column="status" jdbcType="VARCHAR"/> | |||||
| <result property="computingResource" column="computing_resource" jdbcType="VARCHAR"/> | |||||
| <result property="standard" column="standard" jdbcType="VARCHAR"/> | |||||
| <result property="envVariable" column="env_variable" jdbcType="VARCHAR"/> | |||||
| <result property="image" column="image" jdbcType="VARCHAR"/> | |||||
| <result property="dataset" column="dataset" jdbcType="VARCHAR"/> | |||||
| <result property="model" column="model" jdbcType="VARCHAR"/> | |||||
| <result property="altField1" column="alt_field1" jdbcType="VARCHAR"/> | |||||
| <result property="altField2" column="alt_field2" jdbcType="VARCHAR"/> | |||||
| <result property="createBy" column="create_by" jdbcType="VARCHAR"/> | |||||
| <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> | |||||
| <result property="updateBy" column="update_by" jdbcType="VARCHAR"/> | |||||
| <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/> | |||||
| <result property="state" column="state" jdbcType="INTEGER"/> | |||||
| </resultMap> | |||||
| <!--查询单个--> | |||||
| <select id="queryById" resultMap="DevEnvironmentMap"> | |||||
| select | |||||
| id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state | |||||
| from dev_environment | |||||
| where id = #{id} | |||||
| </select> | |||||
| <!--查询指定行数据--> | |||||
| <select id="queryAllByLimit" resultMap="DevEnvironmentMap"> | |||||
| select | |||||
| id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state | |||||
| from dev_environment | |||||
| <where> | |||||
| <if test="devEnvironment.id != null"> | |||||
| and id = #{devEnvironment.id} | |||||
| </if> | |||||
| <if test="devEnvironment.name != null and devEnvironment.name != ''"> | |||||
| and name = #{devEnvironment.name} | |||||
| </if> | |||||
| <if test="devEnvironment.status != null and devEnvironment.status != ''"> | |||||
| and status = #{devEnvironment.status} | |||||
| </if> | |||||
| <if test="devEnvironment.computingResource != null and devEnvironment.computingResource != ''"> | |||||
| and computing_resource = #{devEnvironment.computingResource} | |||||
| </if> | |||||
| <if test="devEnvironment.standard != null and devEnvironment.standard != ''"> | |||||
| and standard = #{devEnvironment.standard} | |||||
| </if> | |||||
| <if test="devEnvironment.envVariable != null and devEnvironment.envVariable != ''"> | |||||
| and env_variable = #{devEnvironment.envVariable} | |||||
| </if> | |||||
| <if test="devEnvironment.image != null and devEnvironment.image != ''"> | |||||
| and image = #{devEnvironment.image} | |||||
| </if> | |||||
| <if test="devEnvironment.dataset != null and devEnvironment.dataset != ''"> | |||||
| and dataset = #{devEnvironment.dataset} | |||||
| </if> | |||||
| <if test="devEnvironment.model != null and devEnvironment.model != ''"> | |||||
| and model = #{devEnvironment.model} | |||||
| </if> | |||||
| <if test="devEnvironment.altField1 != null and devEnvironment.altField1 != ''"> | |||||
| and alt_field1 = #{devEnvironment.altField1} | |||||
| </if> | |||||
| <if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''"> | |||||
| and alt_field2 = #{devEnvironment.altField2} | |||||
| </if> | |||||
| <if test="devEnvironment.createBy != null and devEnvironment.createBy != ''"> | |||||
| and create_by = #{devEnvironment.createBy} | |||||
| </if> | |||||
| <if test="devEnvironment.createTime != null"> | |||||
| and create_time = #{devEnvironment.createTime} | |||||
| </if> | |||||
| <if test="devEnvironment.updateBy != null and devEnvironment.updateBy != ''"> | |||||
| and update_by = #{devEnvironment.updateBy} | |||||
| </if> | |||||
| <if test="devEnvironment.updateTime != null"> | |||||
| and update_time = #{devEnvironment.updateTime} | |||||
| </if> | |||||
| <if test="devEnvironment.state != null"> | |||||
| and state = #{devEnvironment.state} | |||||
| </if> | |||||
| </where> | |||||
| limit #{pageable.offset}, #{pageable.pageSize} | |||||
| </select> | |||||
| <!--统计总行数--> | |||||
| <select id="count" resultType="java.lang.Long"> | |||||
| select count(1) | |||||
| from dev_environment | |||||
| <where> | |||||
| <if test="devEnvironment.id != null"> | |||||
| and id = #{devEnvironment.id} | |||||
| </if> | |||||
| <if test="devEnvironment.name != null and devEnvironment.name != ''"> | |||||
| and name = #{devEnvironment.name} | |||||
| </if> | |||||
| <if test="devEnvironment.status != null and devEnvironment.status != ''"> | |||||
| and status = #{devEnvironment.status} | |||||
| </if> | |||||
| <if test="devEnvironment.computingResource != null and devEnvironment.computingResource != ''"> | |||||
| and computing_resource = #{devEnvironment.computingResource} | |||||
| </if> | |||||
| <if test="devEnvironment.standard != null and devEnvironment.standard != ''"> | |||||
| and standard = #{devEnvironment.standard} | |||||
| </if> | |||||
| <if test="devEnvironment.envVariable != null and devEnvironment.envVariable != ''"> | |||||
| and env_variable = #{devEnvironment.envVariable} | |||||
| </if> | |||||
| <if test="devEnvironment.image != null and devEnvironment.image != ''"> | |||||
| and image = #{devEnvironment.image} | |||||
| </if> | |||||
| <if test="devEnvironment.dataset != null and devEnvironment.dataset != ''"> | |||||
| and dataset = #{devEnvironment.dataset} | |||||
| </if> | |||||
| <if test="devEnvironment.model != null and devEnvironment.model != ''"> | |||||
| and model = #{devEnvironment.model} | |||||
| </if> | |||||
| <if test="devEnvironment.altField1 != null and devEnvironment.altField1 != ''"> | |||||
| and alt_field1 = #{devEnvironment.altField1} | |||||
| </if> | |||||
| <if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''"> | |||||
| and alt_field2 = #{devEnvironment.altField2} | |||||
| </if> | |||||
| <if test="devEnvironment.createBy != null and devEnvironment.createBy != ''"> | |||||
| and create_by = #{devEnvironment.createBy} | |||||
| </if> | |||||
| <if test="devEnvironment.createTime != null"> | |||||
| and create_time = #{devEnvironment.createTime} | |||||
| </if> | |||||
| <if test="devEnvironment.updateBy != null and devEnvironment.updateBy != ''"> | |||||
| and update_by = #{devEnvironment.updateBy} | |||||
| </if> | |||||
| <if test="devEnvironment.updateTime != null"> | |||||
| and update_time = #{devEnvironment.updateTime} | |||||
| </if> | |||||
| <if test="devEnvironment.state != null"> | |||||
| and state = #{devEnvironment.state} | |||||
| </if> | |||||
| </where> | |||||
| </select> | |||||
| <!--新增所有列--> | |||||
| <insert id="insert" keyProperty="id" useGeneratedKeys="true"> | |||||
| insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state) | |||||
| values (#{devEnvironment.name}, | |||||
| #{devEnvironment.status}, | |||||
| #{devEnvironment.computingResource}, | |||||
| #{devEnvironment.standard}, | |||||
| #{devEnvironment.envVariable}, | |||||
| #{devEnvironment.image}, | |||||
| #{devEnvironment.dataset}, | |||||
| #{devEnvironment.model}, | |||||
| #{devEnvironment.altField1}, | |||||
| #{devEnvironment.altField2}, | |||||
| #{devEnvironment.createBy}, | |||||
| #{devEnvironment.createTime}, | |||||
| #{devEnvironment.updateBy}, | |||||
| #{devEnvironment.updateTime}, | |||||
| #{devEnvironment.state} | |||||
| ) | |||||
| </insert> | |||||
| <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> | |||||
| insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state ) | |||||
| values | |||||
| <foreach collection="entities" item="entity" separator=","> | |||||
| (#{entity.name},#{entity.status},#{entity.computingResource},#{entity.standard},#{entity.envVariable},#{entity.image},#{entity.dataset},#{entity.model},#{entity.altField1},#{entity.altField2},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state}) | |||||
| </foreach> | |||||
| </insert> | |||||
| <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true"> | |||||
| insert into dev_environment(name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state) | |||||
| values | |||||
| <foreach collection="entities" item="entity" separator=","> | |||||
| (#{entity.name}#{entity.status}#{entity.computingResource}#{entity.standard}#{entity.envVariable}#{entity.image}#{entity.dataset}#{entity.model}#{entity.altField1}#{entity.altField2}#{entity.createBy}#{entity.createTime}#{entity.updateBy}#{entity.updateTime}#{entity.state}) | |||||
| </foreach> | |||||
| on duplicate key update | |||||
| name = values(name)status = values(status)computing_resource = values(computing_resource)standard = values(standard)env_variable = values(env_variable)image = values(image)dataset = values(dataset)model = values(model)alt_field1 = values(alt_field1)alt_field2 = values(alt_field2)create_by = values(create_by)create_time = values(create_time)update_by = values(update_by)update_time = values(update_time)state = values(state) | |||||
| </insert> | |||||
| <!--通过主键修改数据--> | |||||
| <update id="update"> | |||||
| update dev_environment | |||||
| <set> | |||||
| <if test="devEnvironment.name != null and devEnvironment.name != ''"> | |||||
| name = #{devEnvironment.name}, | |||||
| </if> | |||||
| <if test="devEnvironment.status != null and devEnvironment.status != ''"> | |||||
| status = #{devEnvironment.status}, | |||||
| </if> | |||||
| <if test="devEnvironment.computingResource != null and devEnvironment.computingResource != ''"> | |||||
| computing_resource = #{devEnvironment.computingResource}, | |||||
| </if> | |||||
| <if test="devEnvironment.standard != null and devEnvironment.standard != ''"> | |||||
| standard = #{devEnvironment.standard}, | |||||
| </if> | |||||
| <if test="devEnvironment.envVariable != null and devEnvironment.envVariable != ''"> | |||||
| env_variable = #{devEnvironment.envVariable}, | |||||
| </if> | |||||
| <if test="devEnvironment.image != null and devEnvironment.image != ''"> | |||||
| image = #{devEnvironment.image}, | |||||
| </if> | |||||
| <if test="devEnvironment.dataset != null and devEnvironment.dataset != ''"> | |||||
| dataset = #{devEnvironment.dataset}, | |||||
| </if> | |||||
| <if test="devEnvironment.model != null and devEnvironment.model != ''"> | |||||
| model = #{devEnvironment.model}, | |||||
| </if> | |||||
| <if test="devEnvironment.altField1 != null and devEnvironment.altField1 != ''"> | |||||
| alt_field1 = #{devEnvironment.altField1}, | |||||
| </if> | |||||
| <if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''"> | |||||
| alt_field2 = #{devEnvironment.altField2}, | |||||
| </if> | |||||
| <if test="devEnvironment.createBy != null and devEnvironment.createBy != ''"> | |||||
| create_by = #{devEnvironment.createBy}, | |||||
| </if> | |||||
| <if test="devEnvironment.createTime != null"> | |||||
| create_time = #{devEnvironment.createTime}, | |||||
| </if> | |||||
| <if test="devEnvironment.updateBy != null and devEnvironment.updateBy != ''"> | |||||
| update_by = #{devEnvironment.updateBy}, | |||||
| </if> | |||||
| <if test="devEnvironment.updateTime != null"> | |||||
| update_time = #{devEnvironment.updateTime}, | |||||
| </if> | |||||
| <if test="devEnvironment.state != null"> | |||||
| state = #{devEnvironment.state}, | |||||
| </if> | |||||
| </set> | |||||
| where id = #{devEnvironment.id} | |||||
| </update> | |||||
| <!--通过主键删除--> | |||||
| <delete id="deleteById"> | |||||
| delete from dev_environment where id = #{id} | |||||
| </delete> | |||||
| </mapper> | |||||
| @@ -0,0 +1,333 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.ruoyi.platform.mapper.ModelDependencyDao"> | |||||
| <resultMap type="com.ruoyi.platform.domain.ModelDependency" id="ModelDependencyMap"> | |||||
| <result property="id" column="id" jdbcType="INTEGER"/> | |||||
| <result property="currentModelId" column="current_model_id" jdbcType="INTEGER"/> | |||||
| <result property="expInsId" column="exp_ins_id" jdbcType="INTEGER"/> | |||||
| <result property="parentModels" column="parent_models" jdbcType="VARCHAR"/> | |||||
| <result property="refItem" column="ref_item" jdbcType="VARCHAR"/> | |||||
| <result property="trainTask" column="train_task" jdbcType="VARCHAR"/> | |||||
| <result property="trainDataset" column="train_dataset" jdbcType="VARCHAR"/> | |||||
| <result property="trainParams" column="train_params" jdbcType="VARCHAR"/> | |||||
| <result property="trainImage" column="train_image" jdbcType="VARCHAR"/> | |||||
| <result property="testDataset" column="test_dataset" jdbcType="VARCHAR"/> | |||||
| <result property="projectDependency" column="project_dependency" jdbcType="VARCHAR"/> | |||||
| <result property="version" column="version" jdbcType="VARCHAR"/> | |||||
| <result property="createBy" column="create_by" jdbcType="VARCHAR"/> | |||||
| <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> | |||||
| <result property="updateBy" column="update_by" jdbcType="VARCHAR"/> | |||||
| <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/> | |||||
| <result property="state" column="state" jdbcType="INTEGER"/> | |||||
| </resultMap> | |||||
| <select id="queryChildrenByVersionId" resultMap="ModelDependencyMap"> | |||||
| select | |||||
| id,current_model_id,exp_ins_id,parent_models,ref_item,train_task,train_dataset,train_params,train_image,test_dataset,project_dependency,version,create_by,create_time,update_by,update_time,state | |||||
| from model_dependency | |||||
| <where> | |||||
| parent_models like concat('%', #{model_id}, '%') AND parent_models like concat('%', #{version}, '%') | |||||
| </where> | |||||
| </select> | |||||
| <select id="queryByModelDependency" resultMap="ModelDependencyMap"> | |||||
| select | |||||
| id,current_model_id,exp_ins_id,parent_models,ref_item,train_task,train_dataset,train_params,train_image,test_dataset,project_dependency,version,create_by,create_time,update_by,update_time,state | |||||
| from model_dependency | |||||
| <where> | |||||
| <if test="modelDependency.id != null"> | |||||
| and id = #{modelDependency.id} | |||||
| </if> | |||||
| <if test="modelDependency.currentModelId != null"> | |||||
| and current_model_id = #{modelDependency.currentModelId} | |||||
| </if> | |||||
| <if test="modelDependency.expInsId != null"> | |||||
| and exp_ins_id = #{modelDependency.expInsId} | |||||
| </if> | |||||
| <if test="modelDependency.parentModels != null"> | |||||
| and parent_models = #{modelDependency.parentModels} | |||||
| </if> | |||||
| <if test="modelDependency.refItem != null and modelDependency.refItem != ''"> | |||||
| and ref_item = #{modelDependency.refItem} | |||||
| </if> | |||||
| <if test="modelDependency.trainTask != null and modelDependency.trainTask != ''"> | |||||
| and train_task = #{modelDependency.trainTask} | |||||
| </if> | |||||
| <if test="modelDependency.trainDataset != null and modelDependency.trainDataset != ''"> | |||||
| and train_dataset = #{modelDependency.trainDataset} | |||||
| </if> | |||||
| <if test="modelDependency.trainParams != null and modelDependency.trainParams != ''"> | |||||
| and train_params = #{modelDependency.trainParams} | |||||
| </if> | |||||
| <if test="modelDependency.trainImage != null and modelDependency.trainImage != ''"> | |||||
| and train_image = #{modelDependency.trainImage} | |||||
| </if> | |||||
| <if test="modelDependency.testDataset != null and modelDependency.testDataset != ''"> | |||||
| and test_dataset = #{modelDependency.testDataset} | |||||
| </if> | |||||
| <if test="modelDependency.projectDependency != null and modelDependency.projectDependency != ''"> | |||||
| and project_dependency = #{modelDependency.projectDependency} | |||||
| </if> | |||||
| <if test="modelDependency.version != null and modelDependency.version != ''"> | |||||
| and version = #{modelDependency.version} | |||||
| </if> | |||||
| <if test="modelDependency.createBy != null and modelDependency.createBy != ''"> | |||||
| and create_by = #{modelDependency.createBy} | |||||
| </if> | |||||
| <if test="modelDependency.createTime != null"> | |||||
| and create_time = #{modelDependency.createTime} | |||||
| </if> | |||||
| <if test="modelDependency.updateBy != null and modelDependency.updateBy != ''"> | |||||
| and update_by = #{modelDependency.updateBy} | |||||
| </if> | |||||
| <if test="modelDependency.updateTime != null"> | |||||
| and update_time = #{modelDependency.updateTime} | |||||
| </if> | |||||
| <if test="modelDependency.state != null"> | |||||
| and state = #{modelDependency.state} | |||||
| </if> | |||||
| </where> | |||||
| </select> | |||||
| <!--查询单个--> | |||||
| <select id="queryById" resultMap="ModelDependencyMap"> | |||||
| select | |||||
| id, current_model_id, exp_ins_id, parent_models, ref_item, train_task, train_dataset, train_params, train_image, test_dataset, project_dependency, version, create_by, create_time, update_by, update_time, state | |||||
| from model_dependency | |||||
| where id = #{id} | |||||
| </select> | |||||
| <!--查询指定行数据--> | |||||
| <select id="queryAllByLimit" resultMap="ModelDependencyMap"> | |||||
| select | |||||
| id, current_model_id, exp_ins_id, parent_models, ref_item, train_task, train_dataset, train_params, train_image, | |||||
| test_dataset, project_dependency, version, create_by, create_time, update_by, update_time, state | |||||
| from model_dependency | |||||
| <where> | |||||
| <if test="id != null"> | |||||
| and id = #{id} | |||||
| </if> | |||||
| <if test="currentModelId != null"> | |||||
| and current_model_id = #{currentModelId} | |||||
| </if> | |||||
| <if test="expInsId != null"> | |||||
| and exp_ins_id = #{expInsId} | |||||
| </if> | |||||
| <if test="parentModels != null and parentModels != ''"> | |||||
| and parent_models = #{parentModels} | |||||
| </if> | |||||
| <if test="refItem != null and refItem != ''"> | |||||
| and ref_item = #{refItem} | |||||
| </if> | |||||
| <if test="trainTask != null and trainTask != ''"> | |||||
| and train_task = #{trainTask} | |||||
| </if> | |||||
| <if test="trainDataset != null and trainDataset != ''"> | |||||
| and train_dataset = #{trainDataset} | |||||
| </if> | |||||
| <if test="trainParams != null and trainParams != ''"> | |||||
| and train_params = #{trainParams} | |||||
| </if> | |||||
| <if test="trainImage != null and trainImage != ''"> | |||||
| and train_image = #{trainImage} | |||||
| </if> | |||||
| <if test="testDataset != null and testDataset != ''"> | |||||
| and test_dataset = #{testDataset} | |||||
| </if> | |||||
| <if test="projectDependency != null and projectDependency != ''"> | |||||
| and project_dependency = #{projectDependency} | |||||
| </if> | |||||
| <if test="version != null and version != ''"> | |||||
| and version = #{version} | |||||
| </if> | |||||
| <if test="createBy != null and createBy != ''"> | |||||
| and create_by = #{createBy} | |||||
| </if> | |||||
| <if test="createTime != null"> | |||||
| and create_time = #{createTime} | |||||
| </if> | |||||
| <if test="updateBy != null and updateBy != ''"> | |||||
| and update_by = #{updateBy} | |||||
| </if> | |||||
| <if test="updateTime != null"> | |||||
| and update_time = #{updateTime} | |||||
| </if> | |||||
| <if test="state != null"> | |||||
| and state = #{state} | |||||
| </if> | |||||
| </where> | |||||
| limit #{pageable.offset}, #{pageable.pageSize} | |||||
| </select> | |||||
| <!--统计总行数--> | |||||
| <select id="count" resultType="java.lang.Long"> | |||||
| select count(1) | |||||
| from model_dependency | |||||
| <where> | |||||
| <if test="id != null"> | |||||
| and id = #{id} | |||||
| </if> | |||||
| <if test="currentModelId != null"> | |||||
| and current_model_id = #{currentModelId} | |||||
| </if> | |||||
| <if test="expInsId != null"> | |||||
| and exp_ins_id = #{expInsId} | |||||
| </if> | |||||
| <if test="parentModels != null and parentModels != ''"> | |||||
| and parent_models = #{parentModels} | |||||
| </if> | |||||
| <if test="refItem != null and refItem != ''"> | |||||
| and ref_item = #{refItem} | |||||
| </if> | |||||
| <if test="trainTask != null and trainTask != ''"> | |||||
| and train_task = #{trainTask} | |||||
| </if> | |||||
| <if test="trainDataset != null and trainDataset != ''"> | |||||
| and train_dataset = #{trainDataset} | |||||
| </if> | |||||
| <if test="trainParams != null and trainParams != ''"> | |||||
| and train_params = #{trainParams} | |||||
| </if> | |||||
| <if test="trainImage != null and trainImage != ''"> | |||||
| and train_image = #{trainImage} | |||||
| </if> | |||||
| <if test="testDataset != null and testDataset != ''"> | |||||
| and test_dataset = #{testDataset} | |||||
| </if> | |||||
| <if test="projectDependency != null and projectDependency != ''"> | |||||
| and project_dependency = #{projectDependency} | |||||
| </if> | |||||
| <if test="version != null and version != ''"> | |||||
| and version = #{version} | |||||
| </if> | |||||
| <if test="createBy != null and createBy != ''"> | |||||
| and create_by = #{createBy} | |||||
| </if> | |||||
| <if test="createTime != null"> | |||||
| and create_time = #{createTime} | |||||
| </if> | |||||
| <if test="updateBy != null and updateBy != ''"> | |||||
| and update_by = #{updateBy} | |||||
| </if> | |||||
| <if test="updateTime != null"> | |||||
| and update_time = #{updateTime} | |||||
| </if> | |||||
| <if test="state != null"> | |||||
| and state = #{state} | |||||
| </if> | |||||
| </where> | |||||
| </select> | |||||
| <!--新增所有列--> | |||||
| <insert id="insert" keyProperty="id" useGeneratedKeys="true"> | |||||
| insert into model_dependency(current_model_id, exp_ins_id, parent_models, ref_item, train_task, train_dataset, train_params, train_image, test_dataset, project_dependency, version, create_by, create_time, update_by, update_time, state) | |||||
| values (#{currentModelId}, #{expInsId}, #{parentModels}, #{refItem}, #{trainTask}, #{trainDataset}, #{trainParams}, #{trainImage}, #{testDataset}, #{projectDependency}, #{version}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state}) | |||||
| </insert> | |||||
| <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> | |||||
| insert into model_dependency(current_model_id, exp_ins_id, parent_models, ref_item, train_task, train_dataset, | |||||
| train_params, train_image, test_dataset, project_dependency, version, create_by, create_time, update_by, | |||||
| update_time, state) | |||||
| values | |||||
| <foreach collection="entities" item="entity" separator=","> | |||||
| (#{entity.currentModelId}, #{entity.expInsId}, #{entity.parentModels}, #{entity.refItem}, | |||||
| #{entity.trainTask}, #{entity.trainDataset}, #{entity.trainParams}, #{entity.trainImage}, | |||||
| #{entity.testDataset}, #{entity.projectDependency}, #{entity.version}, #{entity.createBy}, | |||||
| #{entity.createTime}, #{entity.updateBy}, #{entity.updateTime}, #{entity.state}) | |||||
| </foreach> | |||||
| </insert> | |||||
| <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true"> | |||||
| insert into model_dependency(current_model_id, exp_ins_id, parent_models, ref_item, train_task, train_dataset, | |||||
| train_params, train_image, test_dataset, project_dependency, version, create_by, create_time, update_by, | |||||
| update_time, state) | |||||
| values | |||||
| <foreach collection="entities" item="entity" separator=","> | |||||
| (#{entity.currentModelId}, #{entity.expInsId}, #{entity.parentModels}, #{entity.refItem}, | |||||
| #{entity.trainTask}, #{entity.trainDataset}, #{entity.trainParams}, #{entity.trainImage}, | |||||
| #{entity.testDataset}, #{entity.projectDependency}, #{entity.version}, #{entity.createBy}, | |||||
| #{entity.createTime}, #{entity.updateBy}, #{entity.updateTime}, #{entity.state}) | |||||
| </foreach> | |||||
| on duplicate key update | |||||
| current_model_id = values(current_model_id), | |||||
| exp_ins_id = values(exp_ins_id), | |||||
| parent_models = values(parent_models), | |||||
| ref_item = values(ref_item), | |||||
| train_task = values(train_task), | |||||
| train_dataset = values(train_dataset), | |||||
| train_params = values(train_params), | |||||
| train_image = values(train_image), | |||||
| test_dataset = values(test_dataset), | |||||
| project_dependency = values(project_dependency), | |||||
| version = values(version), | |||||
| create_by = values(create_by), | |||||
| create_time = values(create_time), | |||||
| update_by = values(update_by), | |||||
| update_time = values(update_time), | |||||
| state = values(state) | |||||
| </insert> | |||||
| <!--通过主键修改数据--> | |||||
| <update id="update"> | |||||
| update model_dependency | |||||
| <set> | |||||
| <if test="currentModelId != null"> | |||||
| current_model_id = #{currentModelId}, | |||||
| </if> | |||||
| <if test="expInsId != null"> | |||||
| exp_ins_id = #{expInsId}, | |||||
| </if> | |||||
| <if test="parentModels != null and parentModels != ''"> | |||||
| parent_models = #{parentModels}, | |||||
| </if> | |||||
| <if test="refItem != null and refItem != ''"> | |||||
| ref_item = #{refItem}, | |||||
| </if> | |||||
| <if test="trainTask != null and trainTask != ''"> | |||||
| train_task = #{trainTask}, | |||||
| </if> | |||||
| <if test="trainDataset != null and trainDataset != ''"> | |||||
| train_dataset = #{trainDataset}, | |||||
| </if> | |||||
| <if test="trainParams != null and trainParams != ''"> | |||||
| train_params = #{trainParams}, | |||||
| </if> | |||||
| <if test="trainImage != null and trainImage != ''"> | |||||
| train_image = #{trainImage}, | |||||
| </if> | |||||
| <if test="testDataset != null and testDataset != ''"> | |||||
| test_dataset = #{testDataset}, | |||||
| </if> | |||||
| <if test="projectDependency != null and projectDependency != ''"> | |||||
| project_dependency = #{projectDependency}, | |||||
| </if> | |||||
| <if test="version != null and version != ''"> | |||||
| version = #{version}, | |||||
| </if> | |||||
| <if test="createBy != null and createBy != ''"> | |||||
| create_by = #{createBy}, | |||||
| </if> | |||||
| <if test="createTime != null"> | |||||
| create_time = #{createTime}, | |||||
| </if> | |||||
| <if test="updateBy != null and updateBy != ''"> | |||||
| update_by = #{updateBy}, | |||||
| </if> | |||||
| <if test="updateTime != null"> | |||||
| update_time = #{updateTime}, | |||||
| </if> | |||||
| <if test="state != null"> | |||||
| state = #{state}, | |||||
| </if> | |||||
| </set> | |||||
| where id = #{id} and state = 1 | |||||
| </update> | |||||
| <!--通过主键删除--> | |||||
| <delete id="deleteById"> | |||||
| delete from model_dependency where id = #{id} | |||||
| </delete> | |||||
| </mapper> | |||||