diff --git a/react-ui/config/routes.ts b/react-ui/config/routes.ts
index 8ec050ae..ec2d251f 100644
--- a/react-ui/config/routes.ts
+++ b/react-ui/config/routes.ts
@@ -141,12 +141,18 @@ export default [
{
name: '实验对比',
path: 'compare',
- component: './Experiment/Comparison/index',
- },
- {
- name: '实验可视化对比',
- path: 'compare-visual',
- component: './Experiment/Aim/index',
+ routes: [
+ {
+ name: '实验对比',
+ path: '',
+ component: './Experiment/Comparison/index',
+ },
+ {
+ name: '可视化对比',
+ path: 'compare-visual',
+ component: './Experiment/Aim/index',
+ },
+ ],
},
{
name: '可视化',
@@ -223,7 +229,18 @@ export default [
{
name: '实验实例详情',
path: 'instance/:experimentId/:id',
- component: './HyperParameter/Instance/index',
+ routes: [
+ {
+ name: '实验实例详情',
+ path: '',
+ component: './HyperParameter/Instance/index',
+ },
+ {
+ name: '可视化对比',
+ path: 'compare-visual',
+ component: './HyperParameter/Aim/index',
+ },
+ ],
},
],
},
diff --git a/react-ui/src/app.tsx b/react-ui/src/app.tsx
index 686c495d..91b0389b 100644
--- a/react-ui/src/app.tsx
+++ b/react-ui/src/app.tsx
@@ -21,6 +21,7 @@ import {
} from './services/session';
import './styles/menu.less';
import { needAuth } from './utils';
+// import { closeAllModals } from './utils/modal';
import { gotoLoginPage } from './utils/ui';
export { requestConfig as request } from './requestConfig';
@@ -96,6 +97,7 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => {
},
onPageChange: () => {
const { location } = history;
+ // closeAllModals();
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && needAuth(location.pathname)) {
gotoLoginPage();
diff --git a/react-ui/src/pages/Dataset/components/ResourcePage/index.tsx b/react-ui/src/pages/Dataset/components/ResourcePage/index.tsx
index c21984ac..4714a4f0 100644
--- a/react-ui/src/pages/Dataset/components/ResourcePage/index.tsx
+++ b/react-ui/src/pages/Dataset/components/ResourcePage/index.tsx
@@ -98,7 +98,7 @@ function ResourcePage({ resourceType }: ResourcePageProps) {
dataType={activeType}
dataTag={activeTag}
initialSearchText={cacheState?.searchText}
- initialPagination={cacheState?.initialPagination}
+ initialPagination={cacheState?.pagination}
setCacheState={setCacheState}
>
diff --git a/react-ui/src/pages/Experiment/Comparison/index.tsx b/react-ui/src/pages/Experiment/Comparison/index.tsx
index 200b4ba1..d10e8069 100644
--- a/react-ui/src/pages/Experiment/Comparison/index.tsx
+++ b/react-ui/src/pages/Experiment/Comparison/index.tsx
@@ -77,7 +77,7 @@ function ExperimentComparison() {
const url = res.data;
// window.open(url, '_blank');
SessionStorage.setItem(SessionStorage.aimUrlKey, url);
- navigate('../compare-visual');
+ navigate('compare-visual');
}
};
diff --git a/react-ui/src/pages/Experiment/Info/index.jsx b/react-ui/src/pages/Experiment/Info/index.jsx
index 1e96c34c..56f7e979 100644
--- a/react-ui/src/pages/Experiment/Info/index.jsx
+++ b/react-ui/src/pages/Experiment/Info/index.jsx
@@ -3,7 +3,6 @@ import { ExperimentStatus } from '@/enums';
import { useStateRef } from '@/hooks/useStateRef';
import { useVisible } from '@/hooks/useVisible';
import { getExperimentIns } from '@/services/experiment/index.js';
-import { getWorkflowById } from '@/services/pipeline/index.js';
import themes from '@/styles/theme.less';
import { fittingString, parseJsonText } from '@/utils';
import { formatDate } from '@/utils/date';
@@ -40,7 +39,7 @@ function ExperimentText() {
useEffect(() => {
initGraph();
- getWorkflow();
+ getExperimentInstance();
return () => {
if (evtSourceRef.current) {
@@ -66,38 +65,54 @@ function ExperimentText() {
}, []);
// 获取流水线模版
- const getWorkflow = async () => {
- const [res] = await to(getWorkflowById(locationParams.workflowId));
- if (res && res.data && res.data.dag) {
- try {
- const dag = JSON.parse(res.data.dag);
- dag.nodes.forEach((item) => {
- item.in_parameters = JSON.parse(item.in_parameters);
- item.out_parameters = JSON.parse(item.out_parameters);
- item.control_strategy = JSON.parse(item.control_strategy);
- item.imgName = item.img.slice(0, item.img.length - 4);
- });
- workflowRef.current = dag;
- getExperimentInstance();
- } catch (error) {
- // JSON.parse 错误
- console.error('JSON.parse error: ', error);
- }
- }
- };
+ // const getWorkflow = async () => {
+ // const [res] = await to(getWorkflowById(locationParams.workflowId));
+ // if (res && res.data && res.data.dag) {
+ // try {
+ // const dag = JSON.parse(res.data.dag);
+ // dag.nodes.forEach((item) => {
+ // item.in_parameters = JSON.parse(item.in_parameters);
+ // item.out_parameters = JSON.parse(item.out_parameters);
+ // item.control_strategy = JSON.parse(item.control_strategy);
+ // item.imgName = item.img.slice(0, item.img.length - 4);
+ // });
+ // workflowRef.current = dag;
+ // getExperimentInstance();
+ // } catch (error) {
+ // // JSON.parse 错误
+ // console.error('JSON.parse error: ', error);
+ // }
+ // }
+ // };
// 获取实验实例
const getExperimentInstance = async () => {
const [res] = await to(getExperimentIns(locationParams.id));
- if (res && res.data && workflowRef.current) {
+ if (res && res.data) {
setExperimentIns(res.data);
- const { status, nodes_status, argo_ins_ns, argo_ins_name, finish_time } = res.data;
- const workflowData = workflowRef.current;
+ const { status, nodes_status, argo_ins_ns, argo_ins_name, finish_time, dag } = res.data;
+ if (!dag) {
+ return;
+ }
+
+ const workflow = parseJsonText(dag);
const experimentStatusObjs = parseJsonText(nodes_status);
+ if (!workflow || !workflow.nodes) {
+ return;
+ }
+
+ workflow.nodes.forEach((item) => {
+ item.in_parameters = parseJsonText(item.in_parameters);
+ item.out_parameters = parseJsonText(item.out_parameters);
+ item.control_strategy = parseJsonText(item.control_strategy);
+ item.imgName = item.img.slice(0, item.img.length - 4);
+ });
+ workflowRef.current = workflow;
+
if (experimentStatusObjs) {
// 更新各个节点
- workflowData.nodes.forEach((item) => {
- const experimentNode = experimentStatusObjs?.[item.id];
+ workflow.nodes.forEach((item) => {
+ const experimentNode = experimentStatusObjs[item.id];
updateWorkflowNode(item, experimentNode);
});
@@ -113,20 +128,20 @@ function ExperimentText() {
}
// 绘制图
- getGraphData(workflowData, true);
+ getGraphData(workflow, true);
if (status === ExperimentStatus.Pending) {
// 如果状态是 Pending, 打开第一个节点
- const node = workflowData.nodes[0];
+ const node = workflow.nodes[0];
if (node) {
setExperimentNodeData(node);
openPropsDrawer();
}
} else if (status === ExperimentStatus.Running) {
- // 如果状态是 Running,打开第一个运行中的节点,如果没有运行中的节点,则打开第一个节点
+ // 如果状态是 Running,打开第一个 Running 或者 pending 的节点,如果没有,则打开第一个节点
const node =
- workflowData.nodes.find((item) => item.experimentStatus === ExperimentStatus.Running) ??
- workflowData.nodes[0];
+ workflow.nodes.find((item) => item.experimentStatus === ExperimentStatus.Running || item.experimentStatus === ExperimentStatus.Pending) ??
+ workflow.nodes[0];
if (node) {
setExperimentNodeData(node);
openPropsDrawer();
@@ -153,13 +168,13 @@ function ExperimentText() {
return;
}
try {
- const dataJson = JSON.parse(data);
+ const dataJson = parseJsonText(data);
const statusData = dataJson?.result?.object?.status;
if (!statusData) {
return;
}
const { finishedAt, phase, nodes = {} } = statusData;
-
+
// 更新实验实例状态和结束时间
// setExperimentIns((prev) => ({
// ...prev,
diff --git a/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx b/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
index edb66534..2bd39c29 100644
--- a/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
+++ b/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
@@ -11,9 +11,15 @@ type ExperimentParameterProps = {
function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
// 控制策略
- const controlStrategyList = Object.entries(nodeData.control_strategy ?? {}).map(
- ([key, value]) => ({ key, value }),
- );
+ // const controlStrategyList = Object.entries(nodeData.control_strategy ?? {}).map(
+ // ([key, value]) => ({ key, value }),
+ // );
+ const nodeId = nodeData.id;
+ const hasTaskInfo =
+ nodeId &&
+ !nodeId.startsWith('git-clone') &&
+ !nodeId.startsWith('dataset-export') &&
+ !nodeId.startsWith('model-export');
// 输入参数
const inParametersList = Object.entries(nodeData.in_parameters ?? {}).map(([key, value]) => ({
@@ -74,54 +80,58 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
>
-
-
-
-
-
-
-
-
-
+ {hasTaskInfo && (
+ <>
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
- {controlStrategyList.map((item) => (
-
-
-
- ))}
+
+
+
+
+
+
+ {/*
+
+ */}
+
+
+
+ {/* {controlStrategyList.map((item) => (
+
+
+
+ ))} */}
+ >
+ )}
diff --git a/react-ui/src/pages/HyperParameter/Aim/index.tsx b/react-ui/src/pages/HyperParameter/Aim/index.tsx
new file mode 100644
index 00000000..3a8d1d0d
--- /dev/null
+++ b/react-ui/src/pages/HyperParameter/Aim/index.tsx
@@ -0,0 +1,12 @@
+/*
+ * @Author: 赵伟
+ * @Date: 2025-03-31 16:38:59
+ * @Description: 实验对比 Aim
+ */
+
+import IframePage, { IframePageType } from '@/components/IFramePage';
+
+function AimPage() {
+ return ;
+}
+export default AimPage;
diff --git a/react-ui/src/pages/HyperParameter/components/ExperimentHistory/index.tsx b/react-ui/src/pages/HyperParameter/components/ExperimentHistory/index.tsx
index c9c9dce5..39ecebda 100644
--- a/react-ui/src/pages/HyperParameter/components/ExperimentHistory/index.tsx
+++ b/react-ui/src/pages/HyperParameter/components/ExperimentHistory/index.tsx
@@ -3,7 +3,9 @@ import TrialStatusCell from '@/pages/HyperParameter/components/TrialStatusCell';
import { HyperParameterTrial } from '@/pages/HyperParameter/types';
import { getExpMetricsReq } from '@/services/hyperParameter';
import { to } from '@/utils/promise';
+import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
+import { useNavigate } from '@umijs/max';
import { App, Button, Table, type TableProps } from 'antd';
import classNames from 'classnames';
import { useEffect, useState } from 'react';
@@ -36,6 +38,7 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) {
const metricAnalysis: Record = first?.metric_analysis ?? {};
const paramsNames = Object.keys(config);
const metricNames = Object.keys(metricAnalysis);
+ const navigate = useNavigate();
const trialColumns: TableProps['columns'] = [
{
@@ -160,7 +163,8 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) {
const [res] = await to(getExpMetricsReq(selectedRowKeys));
if (res && res.data) {
const url = res.data;
- window.open(url, '_blank');
+ SessionStorage.setItem(SessionStorage.aimUrlKey, url);
+ navigate('compare-visual');
}
};
diff --git a/react-ui/src/pages/ModelDeployment/components/ServerLog/index.less b/react-ui/src/pages/ModelDeployment/components/ServerLog/index.less
index 11f3bf34..4b7f5762 100644
--- a/react-ui/src/pages/ModelDeployment/components/ServerLog/index.less
+++ b/react-ui/src/pages/ModelDeployment/components/ServerLog/index.less
@@ -20,5 +20,9 @@
&__more {
padding: 20px 0;
}
+
+ &::-webkit-scrollbar-thumb {
+ background: rgba(255, 255, 255, 0.5);
+ }
}
}
diff --git a/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx b/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx
index 9279e76d..4855eb00 100644
--- a/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx
+++ b/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx
@@ -35,6 +35,12 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
const [stagingItem, setStagingItem] = useState(
{} as PipelineNodeModelSerialize,
);
+ const nodeId = Form.useWatch('id', form) as string;
+ const hasTaskInfo =
+ nodeId &&
+ !nodeId.startsWith('git-clone') &&
+ !nodeId.startsWith('dataset-export') &&
+ !nodeId.startsWith('model-export');
const [open, setOpen] = useState(false);
const [menuItems, setMenuItems] = useState([]);
@@ -46,10 +52,11 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
const fields = form.getFieldsValue();
// 保存字段顺序
- const control_strategy = {
- ...stagingItem.control_strategy,
- ...fields.control_strategy,
- };
+ // const control_strategy = {
+ // ...stagingItem.control_strategy,
+ // ...fields.control_strategy,
+ // };
+
const in_parameters = {
...stagingItem.in_parameters,
...fields.in_parameters,
@@ -64,7 +71,7 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
const res = {
...stagingItem,
...fields,
- control_strategy: JSON.stringify(control_strategy),
+ // control_strategy: JSON.stringify(control_strategy),
in_parameters: JSON.stringify(in_parameters),
out_parameters: JSON.stringify(out_parameters),
formError: !!error,
@@ -91,7 +98,7 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
...model,
in_parameters: JSON.parse(model.in_parameters),
out_parameters: JSON.parse(model.out_parameters),
- control_strategy: JSON.parse(model.control_strategy),
+ // control_strategy: JSON.parse(model.control_strategy),
};
// console.log('model', nodeData);
setStagingItem({
@@ -348,9 +355,9 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
};
// 控制策略
- const controlStrategyList = Object.entries(stagingItem.control_strategy ?? {}).map(
- ([key, value]) => ({ key, value }),
- );
+ // const controlStrategyList = Object.entries(stagingItem.control_strategy ?? {}).map(
+ // ([key, value]) => ({ key, value }),
+ // );
// 输入参数
const inParametersList = Object.entries(stagingItem.in_parameters ?? {}).map(([key, value]) => ({
@@ -422,71 +429,73 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
>
-
-
-
-
-
-
- {
- handleParameterClick('working_directory', value);
- }}
- />
- }
- >
-
-
- {
- handleParameterClick('command', value);
- }}
- />
- }
- >
-
-
-
-
-
- {
+ handleParameterClick('command', value);
+ }}
+ />
+ }
+ >
+
+
+
+
+
+ {/*
-
- {
- handleParameterClick('env_variables', value);
- }}
- />
- }
- >
-
-
- {/* 控制参数 */}
- {controlStrategyList.map((item) => (
+ */}
+ {
+ handleParameterClick('env_variables', value);
+ }}
+ />
+ }
+ >
+
+
+ {/* 控制参数 */}
+ {/* {controlStrategyList.map((item) => (
- ))}
+ ))} */}
+ >
+ )}
+
{/* 输入参数 */}
{inParametersList.length > 0 && (
<>
diff --git a/react-ui/src/pages/Workspace/components/AssetsManagement/index.less b/react-ui/src/pages/Workspace/components/AssetsManagement/index.less
index 122d3bf4..53f7af70 100644
--- a/react-ui/src/pages/Workspace/components/AssetsManagement/index.less
+++ b/react-ui/src/pages/Workspace/components/AssetsManagement/index.less
@@ -37,7 +37,18 @@
&__summary {
display: flex;
flex-direction: column;
- width: 33.33%;
+ width: 40%;
+ text-align: left;
+
+ &:nth-child(3n+2) {
+ text-align: center;
+ width: 30%;
+ }
+
+ &:nth-child(3n) {
+ text-align: right;
+ width: 30%;
+ }
&__title {
margin-bottom: 12px;
diff --git a/react-ui/src/pages/Workspace/components/AssetsManagement/index.tsx b/react-ui/src/pages/Workspace/components/AssetsManagement/index.tsx
index 46a57ca8..1e5b2989 100644
--- a/react-ui/src/pages/Workspace/components/AssetsManagement/index.tsx
+++ b/react-ui/src/pages/Workspace/components/AssetsManagement/index.tsx
@@ -16,7 +16,7 @@ function AssetsManagement() {
};
const [res] = await to(getWorkspaceAssetCountReq(params));
if (res && res.data) {
- const { dataset, image, model, workflow } = res.data;
+ const { dataset, image, model, workflow, codeConfig, service } = res.data;
const items = [
{
title: '数据集',
@@ -42,6 +42,14 @@ function AssetsManagement() {
title: '流水线模版',
value: workflow,
},
+ {
+ title: '代码配置',
+ value: codeConfig,
+ },
+ {
+ title: '服务',
+ value: service,
+ },
];
setAssetCounts(items);
}
@@ -53,7 +61,7 @@ function AssetsManagement() {
return (
- AI资产
+ 多形态资源库
{/*
今日新增数量:5
*/}
-
+
{assetCounts.map((item, index) => (
{item.title}
-
{item.value}
+
{item.value ?? '-'}
))}
diff --git a/react-ui/src/pages/Workspace/components/ExperimentTable/index.less b/react-ui/src/pages/Workspace/components/ExperimentTable/index.less
index 4b692883..b957cc8b 100644
--- a/react-ui/src/pages/Workspace/components/ExperimentTable/index.less
+++ b/react-ui/src/pages/Workspace/components/ExperimentTable/index.less
@@ -1,6 +1,6 @@
.experiment-table {
flex: 1;
- min-width: 378px;
+ min-width: 460px;
height: 140px;
padding: 12px;
background: @workspace-background;
@@ -32,7 +32,7 @@
}
&__status {
- width: 15%;
+ width: 25%;
}
&__duration {
@@ -40,11 +40,11 @@
}
&__date {
- width: calc(60% - 60px);
+ width: 40%;
}
&__operation {
- width: 60px;
+ width: 10%;
:global {
.ant-btn-link {
diff --git a/react-ui/src/pages/Workspace/components/QuickStart/index.tsx b/react-ui/src/pages/Workspace/components/QuickStart/index.tsx
index e27d2b76..95bea20e 100644
--- a/react-ui/src/pages/Workspace/components/QuickStart/index.tsx
+++ b/react-ui/src/pages/Workspace/components/QuickStart/index.tsx
@@ -55,7 +55,7 @@ function QuickStart() {
navigate('/datasetPreparation/datasetAnnotation')}
@@ -80,7 +80,7 @@ function QuickStart() {
navigate('/pipeline/experiment')}
diff --git a/react-ui/src/pages/Workspace/components/TotalStatistics/index.less b/react-ui/src/pages/Workspace/components/TotalStatistics/index.less
index 8a409b82..039d5e2f 100644
--- a/react-ui/src/pages/Workspace/components/TotalStatistics/index.less
+++ b/react-ui/src/pages/Workspace/components/TotalStatistics/index.less
@@ -3,16 +3,16 @@
align-items: center;
justify-content: center;
height: 140px;
- padding: 0 16px;
+ padding: 0 35px;
- // 媒体查询
- @media screen and (max-width: 1600px) {
- flex: auto;
- }
+ // // 媒体查询
+ // @media screen and (max-width: 1600px) {
+ // flex: auto;
+ // }
&__icon {
- width: 63px;
- margin-right: 16px;
+ width: 80px;
+ margin-right: 20px;
}
&__title {
diff --git a/react-ui/src/pages/Workspace/components/UserPoints/index.less b/react-ui/src/pages/Workspace/components/UserPoints/index.less
index e8f9b750..7316a5d6 100644
--- a/react-ui/src/pages/Workspace/components/UserPoints/index.less
+++ b/react-ui/src/pages/Workspace/components/UserPoints/index.less
@@ -7,6 +7,7 @@
height: 228px;
padding: 0 20px;
.backgroundFullImage(url(@/assets/img/user-points-bg.png));
+ margin-bottom: 16px;
&__label {
margin-top: 60px;
diff --git a/react-ui/src/pages/Workspace/components/WorkspaceIntro/index.tsx b/react-ui/src/pages/Workspace/components/WorkspaceIntro/index.tsx
index bc8d30e8..57ee3e3c 100644
--- a/react-ui/src/pages/Workspace/components/WorkspaceIntro/index.tsx
+++ b/react-ui/src/pages/Workspace/components/WorkspaceIntro/index.tsx
@@ -4,9 +4,9 @@ function WorkspaceIntro() {
return (
-
自主实验平台
+
智能材料科研平台
- 材料领域的自主实验系统是一种用于材料研究和开发的技术平台,它旨在提供实验数据收集、分析和可视化等功能,
+ 智能材料科研平台是用于材料研究和开发的技术平台,它旨在提供实验数据收集、分析和可视化等功能,
以支持材料工程师、科学家和研究人员在材料设计、性能评估和工艺优化方面的工作
{/*
diff --git a/react-ui/src/pages/Workspace/index.less b/react-ui/src/pages/Workspace/index.less
index addf2fcd..7ff7592b 100644
--- a/react-ui/src/pages/Workspace/index.less
+++ b/react-ui/src/pages/Workspace/index.less
@@ -27,7 +27,7 @@
&__statistics {
flex: none;
- min-width: 431px;
+ // min-width: 500px;
background: linear-gradient(
123.08deg,
rgba(138, 138, 138, 0.06) 1.32%,
@@ -35,10 +35,10 @@
);
border-radius: 4px;
- // 媒体查询
- @media screen and (max-width: 1600px) {
- flex: 1;
- }
+ // // 媒体查询
+ // @media screen and (max-width: 1600px) {
+ // flex: 1;
+ // }
}
}
}
diff --git a/react-ui/src/pages/Workspace/index.tsx b/react-ui/src/pages/Workspace/index.tsx
index 9aa7600a..5da8f2fe 100644
--- a/react-ui/src/pages/Workspace/index.tsx
+++ b/react-ui/src/pages/Workspace/index.tsx
@@ -12,7 +12,6 @@ import QuickStart from './components/QuickStart';
// import RobotFrame from './components/RobotFrame';
import TotalStatistics from './components/TotalStatistics';
import UserPoints from './components/UserPoints';
-import UserSpace from './components/UserSpace';
import WorkspaceIntro from './components/WorkspaceIntro';
import styles from './index.less';
@@ -67,7 +66,6 @@ function Workspace() {
count={overviewData?.runningExperimentInsCount}
/>
-
@@ -76,12 +74,12 @@ function Workspace() {
)}
-
diff --git a/react-ui/src/types.ts b/react-ui/src/types.ts
index 8297a0fc..36bf3a98 100644
--- a/react-ui/src/types.ts
+++ b/react-ui/src/types.ts
@@ -112,9 +112,9 @@ export type KeysToCamelCase
= {
// 序列化后的流水线节点
export type PipelineNodeModelSerialize = Omit<
PipelineNodeModel,
- 'control_strategy' | 'in_parameters' | 'out_parameters'
+ 'in_parameters' | 'out_parameters'
> & {
- control_strategy: Record;
+ // control_strategy: Record;
in_parameters: Record;
out_parameters: Record;
};
diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/config/MultiDSConfig.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/config/MultiDSConfig.java
new file mode 100644
index 00000000..376ae232
--- /dev/null
+++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/config/MultiDSConfig.java
@@ -0,0 +1,110 @@
+package com.ruoyi.platform.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import com.alibaba.druid.pool.DruidDataSource;
+
+@Configuration
+public class MultiDSConfig {
+ private Logger logger = LoggerFactory.getLogger(this.getClass());
+ @Value("${mysql.datasource.master.url}")
+ private String masterUrl;
+ @Value("${mysql.datasource.master.username}")
+ private String username;
+ @Value("${mysql.datasource.master.password}")
+ private String password;
+ @Value("${mysql.datasource.master.driverClassName}")
+ private String driverClassName;
+ @Value("${mysql.datasource.master.initialSize}")
+ private int initialSize;
+ @Value("${mysql.datasource.master.minIdle}")
+ private int minIdle;
+ @Value("${mysql.datasource.master.maxActive}")
+ private int maxActive;
+ @Value("${mysql.datasource.master.maxWait}")
+ private int maxWait;
+ // 故意注释
+ @Value("${mysql.datasource.master.timeBetweenEvictionRunsMillis}")
+ private int timeBetweenEvictionRunsMillis;
+ @Value("${mysql.datasource.master.validationQuery}")
+ private String validationQuery;
+ @Value("${mysql.datasource.master.testWhileIdle}")
+ private boolean testWhileIdle;
+ @Value("${mysql.datasource.master.testOnBorrow}")
+ private boolean testOnBorrow;
+ @Value("${mysql.datasource.master.testOnReturn}")
+ private boolean testOnReturn;
+ @Value("${mysql.datasource.master.ConnectionErrorRetryAttempts}")
+ private int connectionErrorRetryAttempts;
+ @Value("${mysql.datasource.master.NotFullTimeoutRetryCount}")
+ private int notFullTimeoutRetryCount;
+ // @Value("${mysql.datasource.master.removeAbandonedTimeoutMillis}")
+ // private long removeAbandonedTimeoutMillis;
+ // @Value("${mysql.datasource.master.removeAbandoned}")
+ // private boolean removeAbandoned;
+ @Value("${mysql.datasource.master.keepalive}")
+ private boolean keepAlive = true;
+ @Value("${mysql.datasource.master.minEvictableIdleTimeMillis}")
+ private int minEvictableIdleTimeMillis;
+ @Value("${mysql.datasource.master.maxEvictableIdleTimeMillis}")
+ private int maxEvictableIdleTimeMillis;
+ @Value("${mysql.datasource.master.keepAliveBetweenTimeMillis}")
+ private int keepAliveBetweenTimeMillis;
+
+ @Bean
+ @ConfigurationProperties(prefix = "mysql.datasource.master")
+ public DataSource masterDataSource() {
+ DruidDataSource datasource = new DruidDataSource();
+ datasource.setUrl(masterUrl);
+ datasource.setUsername(username);
+ datasource.setPassword(password);
+ datasource.setDriverClassName(driverClassName);
+ // configuration
+ datasource.setInitialSize(initialSize);
+ datasource.setMinIdle(minIdle);
+ datasource.setMaxActive(maxActive);
+ datasource.setMaxWait(maxWait);
+ // 故意注释下面这一句
+ datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+ logger.info(">>>>>>timeBetweenEvictionRunsMillis->" + timeBetweenEvictionRunsMillis);
+ // datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+ datasource.setValidationQuery(validationQuery);
+ datasource.setTestWhileIdle(testWhileIdle);
+ datasource.setTestOnBorrow(testOnBorrow);
+ datasource.setTestOnReturn(testOnReturn);
+ // datasource.setPoolPreparedStatements(poolPreparedStatements);
+ // datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
+ datasource.setConnectionErrorRetryAttempts(connectionErrorRetryAttempts);
+ datasource.setNotFullTimeoutRetryCount(notFullTimeoutRetryCount);
+ //datasource.setRemoveAbandonedTimeoutMillis(removeAbandonedTimeoutMillis);
+ //datasource.setRemoveAbandoned(removeAbandoned);
+ datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+ datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
+ datasource.setKeepAliveBetweenTimeMillis(keepAliveBetweenTimeMillis);
+ datasource.setKeepAlive(keepAlive);
+ return datasource;
+ }
+
+ @Bean
+ public JdbcTemplate dataSource(DataSource myRoutingDataSource) {
+ return new JdbcTemplate(myRoutingDataSource);
+ }
+
+ @Bean
+ public DataSourceTransactionManager txManager(DataSource myRoutingDataSource) {
+ return new DataSourceTransactionManager(myRoutingDataSource);
+ }
+}
diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java
index d29b7e10..f7d946d2 100644
--- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java
+++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java
@@ -80,6 +80,8 @@ public class ExperimentIns implements Serializable {
@ApiModelProperty(value = "状态:0失效,1生效")
private Integer state;
+ @ApiModelProperty(value = "DAG图")
+ private String dag;
@ApiModelProperty(value = "实验实例对应的流水线ID")
private Long workflowId;
diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java
index d7b559da..ccde6279 100644
--- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java
+++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java
@@ -280,6 +280,7 @@ public class ExperimentServiceImpl implements ExperimentService {
//获取训练参数
experimentIns.setExperimentId(experiment.getId());
+ experimentIns.setDag(dag);
experimentIns.setArgoInsNs((String) metadata.get("namespace"));
experimentIns.setArgoInsName((String) metadata.get("name"));
experimentIns.setStatus(Constant.Pending);
diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java
index d238b7b4..8e0beab8 100644
--- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java
+++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java
@@ -104,9 +104,12 @@ public class NewDatasetServiceImpl implements NewDatasetService {
String gitLinkUsername = loginUser.getSysUser().getUserName();
String gitLinkPassword = decrypt(loginUser.getSysUser().getOriginPassword());
String userReq = jedis.get(ci4sUsername + "_gitUserInfo");
+
// 得到用户操作的路径
Map userInfo = JsonUtils.jsonToMap(userReq);
Integer userId = (Integer) userInfo.get("user_id");
+ String owner = (String) userInfo.get("login");
+
// 拼接project
ci4sUsername = Boolean.TRUE.equals(datasetVo.getIsPublic()) ? Constant.Item_Public : loginUser.getUsername();
String repositoryName = ci4sUsername + "_dataset_" + DateUtils.dateTimeNow();
@@ -117,17 +120,13 @@ public class NewDatasetServiceImpl implements NewDatasetService {
gitProjectVo.setPrivate(!datasetVo.getIsPublic());
gitProjectVo.setUserId(userId);
gitProjectVo.setProjectCategoryId(projectDatasetId);
+
// 创建项目
Map project = gitService.createProject(token, gitProjectVo);
Integer gitlinIid = (Integer) project.get("id");
if (gitlinIid == null) {
throw new Exception("创建数据集失败:" + project.get("message"));
}
- // 创建分支
- String branchName = datasetVo.getVersion();
- String owner = (String) userInfo.get("login");
-
- gitService.createBranch(token, (String) userInfo.get("login"), repositoryName, branchName, "master");
// 定义标签 标签1:dataset 标签2:DataTag 标签3:DataType
gitService.createTopic(token, gitlinIid, Constant.Topic_Dataset);
if (StringUtils.isNotEmpty(datasetVo.getDataTag())) {
@@ -137,23 +136,65 @@ public class NewDatasetServiceImpl implements NewDatasetService {
gitService.createTopic(token, gitlinIid, "datatype-" + datasetVo.getDataType());
}
+ String relatePath = ci4sUsername + "/datasets/" + gitlinIid + "/" + repositoryName + "/master";
+ String localPath = localPathlocal + relatePath;
+ String datasetPath = localPath + "/dataset";
+ String s3Path = bucketName + "/mini-model-management-platform-files" + "/" + relatePath;
+
// 得到项目地址
String projectUrl = gitCloneEndpoint + "/" + owner + "/" + repositoryName + ".git";
+ // 创建master分支
+ dvcUtils.gitClone(localPath, projectUrl, "master", gitLinkUsername, gitLinkPassword);
+ // 拼接生产的元数据后写入yaml文件
+ datasetVo.setCreateBy(String.valueOf(StringUtils.isNotEmpty((String) userInfo.get("nickname")) ? userInfo.get("nickname") : userInfo.get("login")));
+ datasetVo.setUpdateTime(DateUtils.getTime());
+ datasetVo.setIdentifier(repositoryName);
+ datasetVo.setId(gitlinIid);
+ datasetVo.setOwner(owner);
+ datasetVo.setRelativePaths(relatePath + "/dataset");
+// addDatasetSourceToDataVo(datasetVo);
+ YamlUtils.generateYamlFile(JsonUtils.objectToMap(datasetVo), localPath, "dataset");
+
+ // dvc init 初始化
+ dvcUtils.mkdir(datasetPath);
+ dvcUtils.dvcInit(localPath);
+ // 配置远程S3地址
+ dvcUtils.dvcRemoteAdd(localPath, s3Path);
+ dvcUtils.dvcConfigS3Credentials(localPath, endpoint);
+ dvcUtils.dvcConfigS3Credentials2(localPath, accessKeyId);
+ dvcUtils.dvcConfigS3Credentials3(localPath, secretAccessKey);
+ // dvc 跟踪
+ dvcUtils.dvcAdd(localPath, "dataset");
+ // git commit
+ dvcUtils.gitCommit(localPath, "commit from ci4s with " + loginUser.getUsername());
+ dvcUtils.gitPush(localPath, gitLinkUsername, gitLinkPassword);
+ // dvc push 到远程S3
+ dvcUtils.dvcPush(localPath);
+
+ // 创建分支
+ String branchName = datasetVo.getVersion();
+
// 得到用户操作的路径
String sourcePath = datasetVo.getDatasetVersionVos().get(0).getUrl();
- String relatePath = ci4sUsername + "/datasets/" + gitlinIid + "/" + repositoryName + "/" + branchName;
- String localPath = localPathlocal + relatePath;
- String datasetPath = localPath + "/dataset";
+ String relatePath1 = ci4sUsername + "/datasets/" + gitlinIid + "/" + repositoryName + "/" + branchName;
+ String localPath1 = localPathlocal + relatePath1;
+ String datasetPath1 = localPath1 + "/dataset";
// 命令行操作 git clone 项目地址
- dvcUtils.gitClone(localPath, projectUrl, branchName, gitLinkUsername, gitLinkPassword);
- String s3Path = bucketName + "/mini-model-management-platform-files" + "/" + relatePath + "/" + branchName;
- //干掉目标文件夹
- dvcUtils.deleteDirectory(datasetPath);
- dvcUtils.moveFiles(sourcePath, datasetPath);
+ dvcUtils.gitClone(localPath1, projectUrl, "master", gitLinkUsername, gitLinkPassword);
+ dvcUtils.refreshRemoteBranches(localPath1, gitLinkUsername, gitLinkPassword, "master");
+ // 创建本地分支
+ dvcUtils.createLocalBranchBasedOnMaster(localPath1, branchName);
+ //dvc checkout
+ dvcUtils.dvcPull(localPath1);
+ dvcUtils.dvcCheckout(localPath1);
+
+ String s3Path1 = bucketName + "/mini-model-management-platform-files" + "/" + relatePath1;
+ //删掉已存在文件夹
+ dvcUtils.deleteDirectory(datasetPath1);
+ dvcUtils.moveFiles(sourcePath, datasetPath1);
// 拼接生产的元数据后写入yaml文件
- datasetVo.setCreateBy(String.valueOf(StringUtils.isNotEmpty((String) userInfo.get("nickname")) ? userInfo.get("nickname") : userInfo.get("login")));
datasetVo.setUpdateTime(DateUtils.getTime());
datasetVo.setUsage("" +
"# 克隆数据集配置文件与存储参数到本地\n" +
@@ -161,37 +202,28 @@ public class NewDatasetServiceImpl implements NewDatasetService {
"# 远程拉取配置文件\n" +
"dvc pull\n" +
"
");
- datasetVo.setIdentifier(repositoryName);
- datasetVo.setId(gitlinIid);
- datasetVo.setOwner(owner);
- datasetVo.setRelativePaths(relatePath + "/dataset");
+ datasetVo.setRelativePaths(relatePath1 + "/dataset");
+ YamlUtils.generateYamlFile(JsonUtils.objectToMap(datasetVo), localPath1, "dataset");
- addDatasetSourceToDataVo(datasetVo);
-
- YamlUtils.generateYamlFile(JsonUtils.objectToMap(datasetVo), localPath, "dataset");
-
- CompletableFuture.supplyAsync(() -> {
- try {
- // dvc init 初始化
- dvcUtils.dvcInit(localPath);
+// CompletableFuture.supplyAsync(() -> {
+// try {
// 配置远程S3地址
- dvcUtils.dvcRemoteAdd(localPath, s3Path);
- dvcUtils.dvcConfigS3Credentials(localPath, endpoint);
- dvcUtils.dvcConfigS3Credentials2(localPath, accessKeyId);
- dvcUtils.dvcConfigS3Credentials3(localPath, secretAccessKey);
+ dvcUtils.dvcRemoteAdd(localPath1, s3Path1);
+ dvcUtils.dvcConfigS3Credentials(localPath1, endpoint);
+ dvcUtils.dvcConfigS3Credentials2(localPath1, accessKeyId);
+ dvcUtils.dvcConfigS3Credentials3(localPath1, secretAccessKey);
// dvc 跟踪
- dvcUtils.dvcAdd(localPath, "dataset");
+ dvcUtils.dvcAdd(localPath1, "dataset");
// git commit
- dvcUtils.gitCommit(localPath, "commit from ci4s with " + loginUser.getUsername());
- dvcUtils.gitPush(localPath, gitLinkUsername, gitLinkPassword);
+ dvcUtils.pushNewBranchToRemote(localPath1, gitLinkUsername, gitLinkPassword, branchName);
// dvc push 到远程S3
- dvcUtils.dvcPush(localPath);
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- throw new RuntimeException(e.getMessage());
- }
- return null;
- });
+ dvcUtils.dvcPush(localPath1);
+// } catch (Exception e) {
+// logger.error(e.getMessage(), e);
+// throw new RuntimeException(e.getMessage());
+// }
+// return null;
+// });
return "新增数据集成功";
}
@@ -214,7 +246,7 @@ public class NewDatasetServiceImpl implements NewDatasetService {
ci4sUsername = Boolean.TRUE.equals(datasetVo.getIsPublic()) ? Constant.Item_Public : loginUser.getUsername();
Map userInfo = JsonUtils.jsonToMap(userReq);
// 创建分支
- String branchName = StringUtils.isEmpty(datasetVo.getVersion()) ? "master" : datasetVo.getVersion();
+ String branchName = datasetVo.getVersion();
String owner = (String) userInfo.get("login");
String repositoryName = datasetVo.getIdentifier();
@@ -232,14 +264,14 @@ public class NewDatasetServiceImpl implements NewDatasetService {
Map projectDetail = gitService.getProjectDetail(owner, repositoryName, token);
//克隆
- List