Browse Source

Merge pull request '421' (#26) from dev into master

master-fzznrj423
fanshuai 1 year ago
parent
commit
c741456165
63 changed files with 1386 additions and 238 deletions
  1. +1
    -1
      react-ui/config/defaultSettings.ts
  2. +10
    -0
      react-ui/config/routes.ts
  3. BIN
      react-ui/src/assets/img/clock.png
  4. BIN
      react-ui/src/assets/img/creatBy.png
  5. BIN
      react-ui/src/assets/img/mirror-basic.png
  6. BIN
      react-ui/src/assets/img/mirror-version.png
  7. +0
    -0
      react-ui/src/assets/img/page-title-bg.png
  8. +31
    -0
      react-ui/src/components/KFIcon/index.tsx
  9. +5
    -1
      react-ui/src/components/KFModal/index.less
  10. +29
    -0
      react-ui/src/components/KFRadio/index.less
  11. +45
    -0
      react-ui/src/components/KFRadio/index.tsx
  12. +7
    -0
      react-ui/src/components/PageTitle/index.less
  13. +23
    -0
      react-ui/src/components/PageTitle/index.tsx
  14. +8
    -0
      react-ui/src/components/SubAreaTitle/index.less
  15. +24
    -0
      react-ui/src/components/SubAreaTitle/index.tsx
  16. +41
    -3
      react-ui/src/global.less
  17. +10
    -3
      react-ui/src/hooks/index.ts
  18. +1
    -0
      react-ui/src/iconfont/iconfont.js
  19. +1
    -0
      react-ui/src/icons/add.svg
  20. +1
    -0
      react-ui/src/icons/doc-not-inventory.svg
  21. +1
    -1
      react-ui/src/icons/public-mirror-tab.svg
  22. +0
    -1
      react-ui/src/icons/refresh-btn.svg
  23. +1
    -0
      react-ui/src/icons/refresh.svg
  24. +1
    -0
      react-ui/src/icons/remove.svg
  25. +1
    -1
      react-ui/src/icons/view-detail.svg
  26. +1
    -0
      react-ui/src/icons/下载.svg
  27. +0
    -1
      react-ui/src/icons/刷新.svg
  28. +1
    -0
      react-ui/src/icons/查看详情.svg
  29. +37
    -0
      react-ui/src/overrides.less
  30. +52
    -15
      react-ui/src/pages/Dataset/index.less
  31. +25
    -9
      react-ui/src/pages/Dataset/personalData.jsx
  32. +24
    -8
      react-ui/src/pages/Dataset/publicData.jsx
  33. +7
    -7
      react-ui/src/pages/Experiment/experimentText/addExperimentModal.less
  34. +2
    -2
      react-ui/src/pages/Experiment/experimentText/index.less
  35. +8
    -7
      react-ui/src/pages/Experiment/experimentText/props.jsx
  36. +19
    -0
      react-ui/src/pages/Mirror/create.less
  37. +244
    -0
      react-ui/src/pages/Mirror/create.tsx
  38. +55
    -0
      react-ui/src/pages/Mirror/info.less
  39. +231
    -0
      react-ui/src/pages/Mirror/info.tsx
  40. +3
    -16
      react-ui/src/pages/Mirror/list.less
  41. +110
    -47
      react-ui/src/pages/Mirror/list.tsx
  42. +44
    -14
      react-ui/src/pages/Model/index.less
  43. +24
    -8
      react-ui/src/pages/Model/personalData.jsx
  44. +24
    -8
      react-ui/src/pages/Model/publicData.jsx
  45. +2
    -2
      react-ui/src/pages/Pipeline/editPipeline/editPipeline.less
  46. +26
    -16
      react-ui/src/pages/Pipeline/editPipeline/index.jsx
  47. +37
    -9
      react-ui/src/pages/Pipeline/editPipeline/props.jsx
  48. +2
    -2
      react-ui/src/pages/Pipeline/index.jsx
  49. +30
    -7
      react-ui/src/services/mirror/index.ts
  50. +3
    -0
      react-ui/src/styles/theme.less
  51. +9
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetController.java
  52. +2
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/image/ImageController.java
  53. +9
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/image/ImageVersionController.java
  54. +4
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/resources/ComputingResourceController.java
  55. +1
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ComputingResourceDao.java
  56. +3
    -4
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ImageService.java
  57. +1
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetServiceImpl.java
  58. +63
    -14
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java
  59. +1
    -3
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java
  60. +3
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java
  61. +29
    -10
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ImageVo.java
  62. +6
    -6
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ComputingResourceDaoMapper.xml
  63. +3
    -3
      ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ImageDaoMapper.xml

+ 1
- 1
react-ui/config/defaultSettings.ts View File

@@ -19,7 +19,7 @@ const Settings: ProLayoutProps & {
title: '复杂智能软件',
pwa: true,
logo: '/assets/images/left-top-logo.png',
iconfontUrl: '//at.alicdn.com/t/c/font_4509211_dfghcwme8ki.js',
iconfontUrl: '//at.alicdn.com/t/c/font_4511326_ndnvm4elll.js',
token: {
// 参见ts声明,demo 见文档,通过token 修改样式
//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F


+ 10
- 0
react-ui/config/routes.ts View File

@@ -144,6 +144,16 @@ export default [
path: '',
component: './Mirror/list',
},
{
name: '镜像详情',
path: ':id',
component: './Mirror/info',
},
{
name: '创建镜像',
path: 'create',
component: './Mirror/create',
},
],
},
{


BIN
react-ui/src/assets/img/clock.png View File

Before After
Width: 200  |  Height: 200  |  Size: 8.0 kB

BIN
react-ui/src/assets/img/creatBy.png View File

Before After
Width: 48  |  Height: 48  |  Size: 1.6 kB

BIN
react-ui/src/assets/img/mirror-basic.png View File

Before After
Width: 14  |  Height: 15  |  Size: 468 B

BIN
react-ui/src/assets/img/mirror-version.png View File

Before After
Width: 16  |  Height: 16  |  Size: 445 B

react-ui/src/assets/img/mirror-tabs-bg.png → react-ui/src/assets/img/page-title-bg.png View File


+ 31
- 0
react-ui/src/components/KFIcon/index.tsx View File

@@ -0,0 +1,31 @@
/*
* @Author: 赵伟
* @Date: 2024-04-17 12:53:06
* @Description:
*/
import '@/iconfont/iconfont.js';
import { createFromIconfontCN } from '@ant-design/icons';

const Icon = createFromIconfontCN({
scriptUrl: '',
});

type IconFontProps = Parameters<typeof Icon>[0];

interface KFIconProps extends IconFontProps {
type: string;
font?: number;
color?: string;
style?: React.CSSProperties;
}

function KFIcon({ type, font = 15, color = '', style = {} }: KFIconProps) {
const iconStyle = {
...style,
fontSize: font,
color,
};
return <Icon type={type} style={iconStyle} />;
}

export default KFIcon;

+ 5
- 1
react-ui/src/components/KFModal/index.less View File

@@ -1,7 +1,11 @@
.kf-modal {
.ant-modal-content {
padding: 20px 67px;
background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%);
background-image: url(/assets/images/modal-back.png);
background-repeat:no-repeat;
background-size:100%;
background-position: top center;
// background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%);
border-radius: 21px;
}
.ant-modal-header {


+ 29
- 0
react-ui/src/components/KFRadio/index.less View File

@@ -0,0 +1,29 @@
@import '@/styles/theme.less';

.kf-radio {
display: flex;
align-items: center;

&__item {
display: flex;
align-items: center;
padding: 12px 20px;
color: @text-color-second;
border: 1px solid #e0e0e0;
border-radius: 8px;

&:hover {
color: @primary-color-hover;
border: 1px solid @primary-color-hover;
}

&--active {
color: @kf-primary-color;
border: 1px solid @kf-primary-color;
}

& + & {
margin-left: 20px;
}
}
}

+ 45
- 0
react-ui/src/components/KFRadio/index.tsx View File

@@ -0,0 +1,45 @@
/*
* @Author: 赵伟
* @Date: 2024-04-17 16:59:42
* @Description: 自定义Radio
*/

import classNames from 'classnames';
import './index.less';

export type KFRadioItem = {
key: string;
title: string;
icon?: React.ReactNode;
};

type KFRadioProps = {
items: KFRadioItem[];
value?: string;
onChange?: (value: string) => void;
};

function KFRadio({ items, value, onChange }: KFRadioProps) {
return (
<span className={'kf-radio'}>
{items.map((item) => {
return (
<span
key={item.key}
className={
value === item.key
? classNames('kf-radio__item', 'kf-radio__item--active')
: 'kf-radio__item'
}
onClick={() => onChange?.(item.key)}
>
{item.icon}
<span style={{ marginLeft: '5px' }}>{item.title}</span>
</span>
);
})}
</span>
);
}

export default KFRadio;

+ 7
- 0
react-ui/src/components/PageTitle/index.less View File

@@ -0,0 +1,7 @@
.kf-page-title {
display: flex;
align-items: center;
height: 49px;
padding-left: 30px;
background-image: url('../../assets/img/page-title-bg.png');
}

+ 23
- 0
react-ui/src/components/PageTitle/index.tsx View File

@@ -0,0 +1,23 @@
/*
* @Author: 赵伟
* @Date: 2024-04-17 14:01:46
* @Description: 页面标题
*/
import classNames from 'classnames';
import React from 'react';
import './index.less';

type PageTitleProps = {
title: string;
className?: string;
style?: React.CSSProperties;
};
function PageTitle({ title, style, className = '' }: PageTitleProps) {
return (
<div className={classNames('kf-page-title', className)} style={style}>
{title}
</div>
);
}

export default PageTitle;

+ 8
- 0
react-ui/src/components/SubAreaTitle/index.less View File

@@ -0,0 +1,8 @@
@import '@/styles/theme.less';

.kf-subarea-title {
display: flex;
align-items: center;
color: @text-color;
font-size: 16px;
}

+ 24
- 0
react-ui/src/components/SubAreaTitle/index.tsx View File

@@ -0,0 +1,24 @@
/*
* @Author: 赵伟
* @Date: 2024-04-17 15:25:04
* @Description: 分区标题
*/

import './index.less';

type SubAreaTitleProps = {
title: string;
image: string;
style?: React.CSSProperties;
};

function SubAreaTitle({ title, image, style }: SubAreaTitleProps) {
return (
<div className={'kf-subarea-title'} style={style}>
<img src={image} width={14} />
<span style={{ marginLeft: '8px' }}>{title}</span>
</div>
);
}

export default SubAreaTitle;

+ 41
- 3
react-ui/src/global.less View File

@@ -51,10 +51,37 @@ a {
}
.ant-menu-light .ant-menu-item-selected {
background: rgba(197, 232, 255, 0.8) !important;
}
.ant-menu-light .ant-menu-item-selected .ant-pro-base-menu-inline-item-text{
color:#1664ff;
}
.ant-pro-layout .ant-pro-sider .ant-layout-sider-children {
background: #f2f5f7;
}
.ant-pro-base-menu-inline-item-title .ant-pro-base-menu-inline-item-text{
color:#1d1d20;
font-size:16px;
}
// .ant-menu-light .ant-menu-item-selected{
// color:#1664ff;
// }
.ant-pro-layout .ant-pro-sider-menu{
padding-top: 40px;
}
.ant-pro-global-header-logo-mix{
height: 75px;
border-bottom: 1px solid rgba(233, 237, 240, 1);
margin-left: -16px;
width: 257px;
background:#f2f5f7;
border-top-right-radius: 20px;
padding-left: 28px;
}
.ant-pro-layout .ant-pro-sider .ant-layout-sider-children{
border-right: unset;
border-bottom-right-radius: 20px;
}
.ant-pro-base-menu-inline {
// height: 87vh;
background: #f2f5f7;
@@ -63,19 +90,31 @@ a {
.ant-pro-layout .ant-pro-layout-content {
background-color: transparent;
}
.ant-drawer .ant-drawer-body{
padding: 0;
}
.ant-drawer .ant-drawer-body .ant-row{
padding: 0 24px;
}
.ant-drawer .ant-drawer-body .ant-form-item{
margin-bottom: 20px;
}
.ant-menu .ant-menu-submenu-title .anticon {
font-size: 16px;
}
.ant-table-wrapper .ant-table-pagination.ant-pagination {
margin: 0;
padding: 21px 16px;
background-color: #fff;
}
.ant-table-wrapper .ant-table {
height: 75vh;
height: 81vh;
}
.ant-pro-global-header-logo img {
height: 21px;
}
.ant-pro-layout .ant-layout-sider.ant-pro-sider {
height: 87vh;
height: 94vh;
}
.ant-pro-layout .ant-pro-layout-container {
height: 98vh;
@@ -139,7 +178,6 @@ border-color: transparent;
}
.ant-modal-confirm-body-wrapper{
height:303px;
border-radius:21px;
background-image: url(/assets/images/modal-back.png);
background-repeat:no-repeat;
background-size:100%;


+ 10
- 3
react-ui/src/hooks/index.ts View File

@@ -73,21 +73,28 @@ export function useCallbackState<T>(initialValue: T) {
*
* @param initialWidth - The initial width of the element.
* @param initialHeight - The initial height of the element.
* @param deps - dependency list.
* @return - A tuple containing the ref to the DOM element, the current width, and the current height.
*/
export function useDomSize<T extends HTMLElement>(initialWidth: number, initialHeight: number) {
export function useDomSize<T extends HTMLElement>(
initialWidth: number,
initialHeight: number,
deps: React.DependencyList = [],
) {
const domRef = useRef<T>(null);
const [width, setWidth] = useState(initialWidth);
const [height, setHeight] = useState(initialHeight);

useEffect(() => {
console.log('dddddd');

const setDomHeight = () => {
if (domRef.current) {
setHeight(domRef.current.offsetHeight);
setWidth(domRef.current.offsetWidth);
}
};
const debounceFunc = debounce(setDomHeight, 500);
const debounceFunc = debounce(setDomHeight, 200);

setDomHeight();
window.addEventListener('resize', debounceFunc);
@@ -95,7 +102,7 @@ export function useDomSize<T extends HTMLElement>(initialWidth: number, initialH
return () => {
window.removeEventListener('resize', debounceFunc);
};
}, [domRef]);
}, [domRef, ...deps]);

return [domRef, { width, height }] as const;
}

+ 1
- 0
react-ui/src/iconfont/iconfont.js
File diff suppressed because it is too large
View File


+ 1
- 0
react-ui/src/icons/add.svg View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14.902" height="14.902" viewBox="0 0 14.902 14.902"><defs><style>.a{fill:#1664ff;}</style></defs><g transform="translate(-75.735 -76.787)"><path class="a" d="M87.7,88.735a6.355,6.355,0,1,0-8.985,0A6.355,6.355,0,0,0,87.7,88.735Zm.763.763a7.451,7.451,0,1,1,0-10.519A7.451,7.451,0,0,1,88.464,89.5Z" transform="translate(0 0)"/><path class="a" d="M283.541,282.446H286.5a.552.552,0,0,1,0,1.1h-2.954V286.5a.552.552,0,0,1-1.1,0v-2.954h-2.963a.552.552,0,0,1,0-1.1h2.963v-2.963a.552.552,0,0,1,1.1,0Z" transform="translate(-199.785 -198.751)"/></g></svg>

+ 1
- 0
react-ui/src/icons/doc-not-inventory.svg View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1713324052180" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1059" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M440.167543 988.161377h-269.463331c-24.790626 0-45.970444-8.784505-63.539453-26.299621A86.551622 86.551622 0 0 1 80.865138 898.322302v-808.389993C80.865138 65.141682 89.649642 43.961865 107.164759 26.446748A86.551622 86.551622 0 0 1 170.704212 0.147127h471.56083a44.407557 44.407557 0 0 1 33.35956 14.874376l202.097498 224.516847a44.515342 44.515342 0 0 1 11.533031 30.072108v202.097498h-89.839075v-202.097498h44.946484l-33.413453 30.018215-202.097498-224.57074 33.413453-30.018215v44.892591h-471.56083v808.389993h269.463331v89.839075z m45.000377-44.892591a44.946484 44.946484 0 0 1-82.45578 25.006197 44.946484 44.946484 0 1 1 74.856914-50.012394 44.730913 44.730913 0 0 1 7.544973 25.006197z m404.194996-471.56083a45.000376 45.000376 0 1 1-90.000752 0 45.000376 45.000376 0 0 1 90.000752 0zM838.757703 933.460321l-112.312317-89.892968 56.156159-70.114358 112.258423 89.839074-56.102265 70.114359z m73.024562-35.138019a44.892591 44.892591 0 0 1-62.192136 41.605139 44.892591 44.892591 0 0 1-7.814437-79.006649 44.892591 44.892591 0 0 1 66.611335 20.20975 44.892591 44.892591 0 0 1 3.395238 17.245653z m-112.258423-89.785182a44.892591 44.892591 0 0 1-53.784881 44.138094 44.892591 44.892591 0 0 1-32.766741-61.383747 44.892591 44.892591 0 0 1 66.557443-20.20975 44.892591 44.892591 0 0 1 19.994179 37.455403z" fill="#D47AEF" p-id="1060"></path><path d="M844.36254 314.503049H619.7918a44.784806 44.784806 0 0 1-44.892591-44.892591V45.039718h89.785182v224.57074H619.7918v-44.946484h224.57074v89.839075z m45.000376-44.892591a44.892591 44.892591 0 0 1-45.000376 45.000376 44.892591 44.892591 0 0 1-45.000376-45.000376 44.892591 44.892591 0 0 1 62.192137-41.605138 44.892591 44.892591 0 0 1 27.808615 41.605138zM664.792176 45.039718a44.892591 44.892591 0 0 1-53.784881 44.138094A44.892591 44.892591 0 0 1 578.294447 27.794065a44.892591 44.892591 0 0 1 66.557443-20.155857 44.892591 44.892591 0 0 1 19.994179 37.40151zM619.7918 494.127306a188.624332 188.624332 0 1 0 0 377.248663 188.624332 188.624332 0 0 0 0-377.248663z m0 88.922899a99.701433 99.701433 0 1 1 0 199.402865 99.701433 99.701433 0 0 1 0-199.402865z" fill="#D47AEF" p-id="1061"></path></svg>

+ 1
- 1
react-ui/src/icons/public-mirror-tab.svg View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14.239" height="14.266" viewBox="0 0 14.239 14.266" fill="currentColor"><g transform="translate(59 -12320.6)"><path class="a" d="M325.069,355.086a6.46,6.46,0,0,1-4.983-2.344.445.445,0,1,1,.684-.57,5.573,5.573,0,0,0,7.689.869.447.447,0,0,1,.542.712A6.341,6.341,0,0,1,325.069,355.086Zm5.9-4.826a.388.388,0,0,1-.085-.006.445.445,0,0,1-.35-.526,5.641,5.641,0,0,0,.107-1.1,5.548,5.548,0,0,0-3.09-4.993.442.442,0,0,1-.2-.6.447.447,0,0,1,.6-.2,6.443,6.443,0,0,1,3.582,5.79,6.374,6.374,0,0,1-.129,1.276A.442.442,0,0,1,330.972,350.26Zm-11.926-1.389h-.016a.448.448,0,0,1-.435-.463,6.5,6.5,0,0,1,4.965-6.08.448.448,0,0,1,.214.869,5.586,5.586,0,0,0-4.272,5.242A.461.461,0,0,1,319.046,348.871Zm0,0" transform="translate(-376.902 11979.78)"/><path class="a" d="M469.186,298.366a1.783,1.783,0,1,1,1.786-1.78A1.787,1.787,0,0,1,469.186,298.366Z" transform="translate(-521.02 12025.8)"/><path class="a" d="M303.767,323a.891.891,0,1,0,.891.891A.893.893,0,0,0,303.767,323Zm-5.38,11.287a1.786,1.786,0,1,1,1.786-1.786A1.787,1.787,0,0,1,298.386,334.287Z" transform="translate(-355.6 11998.488)"/><path class="a" d="M325.891,568.795a.892.892,0,1,0,.891.892A.893.893,0,0,0,325.891,568.795Zm10.666,2.678a1.786,1.786,0,1,1,1.786-1.786A1.787,1.787,0,0,1,336.558,571.472Z" transform="translate(-383.105 11761.302)"/><path class="a" d="M664.492,596.3a.891.891,0,1,0,.891.891A.893.893,0,0,0,664.492,596.3Z" transform="translate(-711.039 11733.797)"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14.239" height="14.266" viewBox="0 0 14.239 14.266" fill="currentColor"><defs><style></style></defs><g transform="translate(59 -12320.6)"><path class="a" d="M325.069,355.086a6.46,6.46,0,0,1-4.983-2.344.445.445,0,1,1,.684-.57,5.573,5.573,0,0,0,7.689.869.447.447,0,0,1,.542.712A6.341,6.341,0,0,1,325.069,355.086Zm5.9-4.826a.388.388,0,0,1-.085-.006.445.445,0,0,1-.35-.526,5.641,5.641,0,0,0,.107-1.1,5.548,5.548,0,0,0-3.09-4.993.442.442,0,0,1-.2-.6.447.447,0,0,1,.6-.2,6.443,6.443,0,0,1,3.582,5.79,6.374,6.374,0,0,1-.129,1.276A.442.442,0,0,1,330.972,350.26Zm-11.926-1.389h-.016a.448.448,0,0,1-.435-.463,6.5,6.5,0,0,1,4.965-6.08.448.448,0,0,1,.214.869,5.586,5.586,0,0,0-4.272,5.242A.461.461,0,0,1,319.046,348.871Zm0,0" transform="translate(-376.902 11979.78)"/><path class="a" d="M469.186,298.366a1.783,1.783,0,1,1,1.786-1.78A1.787,1.787,0,0,1,469.186,298.366Z" transform="translate(-521.02 12025.8)"/><path class="a" d="M303.767,323a.891.891,0,1,0,.891.891A.893.893,0,0,0,303.767,323Zm-5.38,11.287a1.786,1.786,0,1,1,1.786-1.786A1.787,1.787,0,0,1,298.386,334.287Z" transform="translate(-355.6 11998.488)"/><path class="a" d="M325.891,568.795a.892.892,0,1,0,.891.892A.893.893,0,0,0,325.891,568.795Zm10.666,2.678a1.786,1.786,0,1,1,1.786-1.786A1.787,1.787,0,0,1,336.558,571.472Z" transform="translate(-383.105 11761.302)"/><path class="a" d="M664.492,596.3a.891.891,0,1,0,.891.891A.893.893,0,0,0,664.492,596.3Z" transform="translate(-711.039 11733.797)"/></g></svg>

+ 0
- 1
react-ui/src/icons/refresh-btn.svg View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14.34" height="14.34" viewBox="0 0 14.34 14.34"><defs><style>.a{fill:#1664ff;}</style></defs><path class="a" d="M7.17,0a7.17,7.17,0,1,0,7.17,7.17.664.664,0,1,0-1.328,0A5.894,5.894,0,0,1,7.17,13.012,5.894,5.894,0,0,1,1.328,7.17,5.894,5.894,0,0,1,7.17,1.328a4.9,4.9,0,0,1,3.054.929V2.39h0l-.664.8c-.266.266,0,.8.4.8l3.054.133c.266,0,.531-.4.531-.664L12.614.531A.515.515,0,0,0,11.685.4l-.531.8A7.026,7.026,0,0,0,7.17,0Z"/></svg>

+ 1
- 0
react-ui/src/icons/refresh.svg View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14.34" height="14.34" viewBox="0 0 14.34 14.34" fill="currentColor"><path class="a" d="M7.17,0a7.17,7.17,0,1,0,7.17,7.17.664.664,0,1,0-1.328,0A5.894,5.894,0,0,1,7.17,13.012,5.894,5.894,0,0,1,1.328,7.17,5.894,5.894,0,0,1,7.17,1.328a4.9,4.9,0,0,1,3.054.929V2.39h0l-.664.8c-.266.266,0,.8.4.8l3.054.133c.266,0,.531-.4.531-.664L12.614.531A.515.515,0,0,0,11.685.4l-.531.8A7.026,7.026,0,0,0,7.17,0Z"/></svg>

+ 1
- 0
react-ui/src/icons/remove.svg View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17"><defs><style>.a{fill:#fff;stroke:#707070;}.b{clip-path:url(#a);}.c,.d{fill:#f98e1b;}.c{stroke:#f98e1b;stroke-width:0.2px;}.d{opacity:0.21;}</style><clipPath id="a"><rect class="a" width="17" height="17" transform="translate(1789 324)"/></clipPath></defs><g class="b" transform="translate(-1789 -324)"><g transform="translate(1790.273 325.273)"><path class="c" d="M9.8,11.963H1.359A1.335,1.335,0,0,1,0,10.653V.522A.532.532,0,0,1,.542,0a.538.538,0,0,1,.542.522V10.653a.271.271,0,0,0,.276.266H9.788a.271.271,0,0,0,.276-.266V.522A.532.532,0,0,1,10.605,0a.538.538,0,0,1,.542.522V10.653A1.326,1.326,0,0,1,9.8,11.963Z" transform="translate(1.644 2.491)"/><path class="c" d="M13.9,1.044H.542A.532.532,0,0,1,0,.522.532.532,0,0,1,.542,0H13.912a.532.532,0,0,1,.542.522A.54.54,0,0,1,13.9,1.044Z" transform="translate(0 2.098)"/><path class="c" d="M.542,7.859A.532.532,0,0,1,0,7.337V.522A.532.532,0,0,1,.542,0a.538.538,0,0,1,.542.522V7.337A.538.538,0,0,1,.542,7.859Z" transform="translate(5.246 4.241)"/><path class="c" d="M.542,7.859A.532.532,0,0,1,0,7.337V.522A.532.532,0,0,1,.542,0a.538.538,0,0,1,.542.522V7.337A.526.526,0,0,1,.542,7.859Z" transform="translate(8.458 4.241)"/><path class="c" d="M2.708,1.044H.542A.532.532,0,0,1,0,.522.538.538,0,0,1,.542,0H2.718A.532.532,0,0,1,3.26.522.54.54,0,0,1,2.708,1.044Z" transform="translate(5.597)"/><rect class="d" width="6" height="7" transform="translate(6 2.454)"/></g></g></svg>

+ 1
- 1
react-ui/src/icons/view-detail.svg View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17" fill="currentColor"><defs><style>.a{fill:#fff;stroke:#1431b3;}.b{clip-path:url(#a);}.c,.d{}.c{opacity:0.21;}</style><clipPath id="a"><rect class="a" width="17" height="17" transform="translate(1607 208)"/></clipPath></defs><g class="b" transform="translate(-1607 -208)"><g transform="translate(-0.136 -0.214)"><rect class="c" width="4.75" height="8.011" rx="2" transform="translate(1617.532 209.427)"/><g transform="translate(1511.991 145.627)"><path class="d" d="M282,256.622a.524.524,0,0,0-.522-.522h-6.657a.522.522,0,0,0,0,1.044h6.657A.524.524,0,0,0,282,256.622Zm-7.179,2.6a.522.522,0,0,0,0,1.044h3.109a.522.522,0,0,0,0-1.044Zm7.487,5.349a.464.464,0,0,0-.112-.085,2.565,2.565,0,0,0,.467-1.479,2.631,2.631,0,1,0-2.631,2.6,2.649,2.649,0,0,0,1.443-.425.521.521,0,0,0,.094.13l1.355,1.355a.522.522,0,0,0,.739-.739Zm-2.276.01a1.573,1.573,0,1,1,1.594-1.573A1.584,1.584,0,0,1,280.033,264.581Z" transform="translate(-174.416 -189.172)"/><path class="d" d="M104.819,77.329h-5.8a1.044,1.044,0,0,1-1.041-1.041V65.9a1.044,1.044,0,0,1,1.041-1.041h8.9a1.044,1.044,0,0,1,1.041,1.041v5.18h0v0a.524.524,0,0,0,1.048,0c0-.02,0-.037,0-.057V65.882c0-1.145-.449-2.082-1.594-2.082H99.082A2.089,2.089,0,0,0,97,65.882V76.291a2.089,2.089,0,0,0,2.082,2.082h5.73a.522.522,0,0,0,.007-1.044Z" transform="translate(0 0)"/><path class="d" d="M832.7,607.722a.524.524,0,1,0,.524-.522A.523.523,0,0,0,832.7,607.722Z" transform="translate(-723.731 -534.559)"/></g></g></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17" fill="currentColor"><defs><clipPath id="a"><rect class="a" width="17" height="17" transform="translate(1607 208)"/></clipPath></defs><g class="b" transform="translate(-1607 -208)"><g transform="translate(-0.136 -0.214)"><rect class="c" opacity="0.21" width="4.75" height="8.011" rx="2" transform="translate(1617.532 209.427)"/><g transform="translate(1511.991 145.627)"><path class="d" d="M282,256.622a.524.524,0,0,0-.522-.522h-6.657a.522.522,0,0,0,0,1.044h6.657A.524.524,0,0,0,282,256.622Zm-7.179,2.6a.522.522,0,0,0,0,1.044h3.109a.522.522,0,0,0,0-1.044Zm7.487,5.349a.464.464,0,0,0-.112-.085,2.565,2.565,0,0,0,.467-1.479,2.631,2.631,0,1,0-2.631,2.6,2.649,2.649,0,0,0,1.443-.425.521.521,0,0,0,.094.13l1.355,1.355a.522.522,0,0,0,.739-.739Zm-2.276.01a1.573,1.573,0,1,1,1.594-1.573A1.584,1.584,0,0,1,280.033,264.581Z" transform="translate(-174.416 -189.172)"/><path class="d" d="M104.819,77.329h-5.8a1.044,1.044,0,0,1-1.041-1.041V65.9a1.044,1.044,0,0,1,1.041-1.041h8.9a1.044,1.044,0,0,1,1.041,1.041v5.18h0v0a.524.524,0,0,0,1.048,0c0-.02,0-.037,0-.057V65.882c0-1.145-.449-2.082-1.594-2.082H99.082A2.089,2.089,0,0,0,97,65.882V76.291a2.089,2.089,0,0,0,2.082,2.082h5.73a.522.522,0,0,0,.007-1.044Z" transform="translate(0 0)"/><path class="d" d="M832.7,607.722a.524.524,0,1,0,.524-.522A.523.523,0,0,0,832.7,607.722Z" transform="translate(-723.731 -534.559)"/></g></g></g></svg>

+ 1
- 0
react-ui/src/icons/下载.svg View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1713324237000" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1430" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M912.384 668.551529v88.545883a99.448471 99.448471 0 0 1-99.568941 99.508706H211.184941a99.448471 99.448471 0 0 1-99.568941-99.508706v-88.545883a49.814588 49.814588 0 0 0-99.568941 0v87.100236a199.800471 199.800471 0 0 0 199.80047 199.80047h600.184471a199.800471 199.800471 0 0 0 199.800471-199.80047v-87.100236a49.814588 49.814588 0 0 0-99.568942 0z" fill="#1664FF" p-id="1431"></path><path d="M728.003765 398.516706a50.778353 50.778353 0 0 0-71.740236 0l-95.171764 95.171765V125.530353a49.814588 49.814588 0 1 0-99.568941 0v368.158118l-95.171765-95.171765a50.718118 50.718118 0 1 0-71.740235 71.740235l177.995294 177.995294a54.753882 54.753882 0 0 0 77.462588 0l177.874823-177.995294a50.537412 50.537412 0 0 0 0.060236-71.740235z" fill="#1664FF" p-id="1432"></path></svg>

+ 0
- 1
react-ui/src/icons/刷新.svg View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14.34" height="14.34" viewBox="0 0 14.34 14.34"><defs><style>.a{fill:#1664ff;}</style></defs><path class="a" d="M7.17,0a7.17,7.17,0,1,0,7.17,7.17.664.664,0,1,0-1.328,0A5.894,5.894,0,0,1,7.17,13.012,5.894,5.894,0,0,1,1.328,7.17,5.894,5.894,0,0,1,7.17,1.328a4.9,4.9,0,0,1,3.054.929V2.39h0l-.664.8c-.266.266,0,.8.4.8l3.054.133c.266,0,.531-.4.531-.664L12.614.531A.515.515,0,0,0,11.685.4l-.531.8A7.026,7.026,0,0,0,7.17,0Z"/></svg>

+ 1
- 0
react-ui/src/icons/查看详情.svg View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17"><defs><style>.a{fill:#fff;stroke:#1431b3;}.b{clip-path:url(#a);}.c,.d{fill:#1664ff;}.c{opacity:0.21;}</style><clipPath id="a"><rect class="a" width="17" height="17" transform="translate(1607 208)"/></clipPath></defs><g class="b" transform="translate(-1607 -208)"><g transform="translate(-0.136 -0.214)"><rect class="c" width="4.75" height="8.011" rx="2" transform="translate(1617.532 209.427)"/><g transform="translate(1511.991 145.627)"><path class="d" d="M282,256.622a.524.524,0,0,0-.522-.522h-6.657a.522.522,0,0,0,0,1.044h6.657A.524.524,0,0,0,282,256.622Zm-7.179,2.6a.522.522,0,0,0,0,1.044h3.109a.522.522,0,0,0,0-1.044Zm7.487,5.349a.464.464,0,0,0-.112-.085,2.565,2.565,0,0,0,.467-1.479,2.631,2.631,0,1,0-2.631,2.6,2.649,2.649,0,0,0,1.443-.425.521.521,0,0,0,.094.13l1.355,1.355a.522.522,0,0,0,.739-.739Zm-2.276.01a1.573,1.573,0,1,1,1.594-1.573A1.584,1.584,0,0,1,280.033,264.581Z" transform="translate(-174.416 -189.172)"/><path class="d" d="M104.819,77.329h-5.8a1.044,1.044,0,0,1-1.041-1.041V65.9a1.044,1.044,0,0,1,1.041-1.041h8.9a1.044,1.044,0,0,1,1.041,1.041v5.18h0v0a.524.524,0,0,0,1.048,0c0-.02,0-.037,0-.057V65.882c0-1.145-.449-2.082-1.594-2.082H99.082A2.089,2.089,0,0,0,97,65.882V76.291a2.089,2.089,0,0,0,2.082,2.082h5.73a.522.522,0,0,0,.007-1.044Z" transform="translate(0 0)"/><path class="d" d="M832.7,607.722a.524.524,0,1,0,.524-.522A.523.523,0,0,0,832.7,607.722Z" transform="translate(-723.731 -534.559)"/></g></g></g></svg>

+ 37
- 0
react-ui/src/overrides.less View File

@@ -1 +1,38 @@
// 设置 Table 可以滑动
.vertical-scroll-table {
.ant-table-wrapper {
height: 100%;
.ant-spin-nested-loading {
height: 100%;

.ant-spin-container {
height: 100%;

.ant-table {
height: calc(100% - 74px);

.ant-table-container {
height: 100%;

.ant-table-body {
overflow-y: auto !important;
}
}
}
}
}
}
}

// Tabs 样式
// 删除底部白色横线
.ant-tabs {
.ant-tabs-nav::before {
border: none;
}

// 删除下边的 margin-bottom
.ant-tabs-nav {
margin-bottom: 0;
}
}

+ 52
- 15
react-ui/src/pages/Dataset/index.less View File

@@ -7,6 +7,7 @@
padding-right: 30px;
background-image: url(/assets/images/pipeline-back.png);
background-size: 100% 100%;
font-family: 'Alibaba';
}
.datasetIntroTopBox {
display: flex;
@@ -38,6 +39,7 @@
background: #ffffff;
border-radius: 10px;
box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
font-family: alibaba;
.dataButtonList {
display: flex;
align-items: center;
@@ -68,6 +70,7 @@
.datasetBox {
font-family: 'Alibaba';
background: #f9fafb;
:global {
.ant-tabs-top > .ant-tabs-nav {
margin: 0;
@@ -104,7 +107,7 @@
display: flex;
justify-content: space-between;
width: 100%;
height: 85vh;
height: 87.5vh;
:global {
.ant-btn {
color: #1d1d20;
@@ -117,6 +120,7 @@
margin-right: 10px;
padding-top: 15px;
background: #ffffff;
font-family: 'Alibaba';
box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09);
.custTab {
display: flex;
@@ -136,6 +140,7 @@
padding: 15px 20px;
overflow-x: hidden;
overflow-y: auto;
font-family: 'Alibaba';
.itemTitle {
margin-bottom: 15px;
color: #1d1d20;
@@ -205,6 +210,7 @@
display: flex;
flex: 1;
flex-direction: column;
font-family: 'Alibaba';
height: 100%;
padding: 22px 30px 26px 30px;
background: #ffffff;
@@ -223,38 +229,69 @@
flex: 1;
flex-wrap: wrap;
align-content: flex-start;
width: 100%;
font-family: 'Alibaba';
width: 103%;
.dataItem {
position: relative;
width: 32%;
height: 66px;
margin: 0 15px 18px 0;
background: rgba(128, 128, 128, 0.05);
border-radius: 8px;
box-shadow: 0px 0px 12px rgba(75, 84, 137, 0.05);
width: 23%;
height:164px;
background:#ffffff;
border:1px solid;
border-color:#eaeaea;
border-radius:4px;
margin: 0 20px 25px 0;
cursor: pointer;
.itemText {
position: absolute;
top: 10px;
top: 20px;
left: 20px;
color: #1d1d20;
font-size: 15px;
background: linear-gradient(to right ,rgba(22, 100, 255,0.6) 0,rgba(22, 100, 255,0) 100%);
height: 6px;
line-height: 0px;
color:#1d1d20;
font-size:16px;

}
.itemDescripition{
position: absolute;
top: 57px;
left: 20px;
padding-right: 28px;
color:#575757;
font-size:14px;
word-break: break-all;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.itemTime {
position: absolute;
bottom: 10px;
display: flex;
align-items: center;
bottom: 22px;
left: 20px;
color: #808080;
font-size: 14px;
font-size: 13px;
}
.itemIcon {
position: absolute;
display: flex;
align-items: center;
right: 20px;
bottom: 10px;
bottom: 22px;
color: #808080;
font-size: 14px;
font-size: 13px;
}
}
.dataItem:hover{
border-color: #1664FF;
box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2)
}
.dataItem:hover .itemText{
color: #1664FF;
}
}
}
}


+ 25
- 9
react-ui/src/pages/Dataset/personalData.jsx View File

@@ -1,4 +1,6 @@
import { getAccessToken } from '@/access';
import clock from '@/assets/img/clock.png';
import creatByImg from '@/assets/img/creatBy.png';
import { addDatesetAndVesion, getAssetIcon, getDatasetList } from '@/services/dataset/index.js';
import { getDictSelectOption } from '@/services/system/dict';
import { PlusCircleOutlined, UploadOutlined } from '@ant-design/icons';
@@ -40,7 +42,7 @@ const PublicData = (React.FC = () => {
};
const [queryFlow, setQueryFlow] = useState({
page: 0,
size: 10,
size: 20,
name: null,
available_range: 0,
});
@@ -149,6 +151,11 @@ const PublicData = (React.FC = () => {
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const onPageChange = (pageNum, pageSize) => {
console.log(pageNum, pageSize);
setQueryFlow({ ...queryFlow, page: pageNum - 1, size: pageSize });
getDatasetlist({ ...queryFlow, page: pageNum - 1, size: pageSize });
};
useEffect(() => {
getDictSelectOption('available_cluster').then((data) => {
setClusterOptions(data);
@@ -268,17 +275,19 @@ const PublicData = (React.FC = () => {
? datasetList.map((item) => {
return (
<div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}>
<div className={Styles.itemText}>{item.name}</div>
<span className={Styles.itemText}>{item.name}</span>
<div className={Styles.itemDescripition}>{item.description}</div>
<div className={Styles.itemTime}>
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
<div className={Styles.itemIcon}>
<img
style={{ width: '17px', marginRight: '3px' }}
src={`/assets/images/upload-icon.png`}
style={{ width: '17px', marginRight: '6px' }}
src={creatByImg}
alt=""
/>
<span>1582</span>
<span>{item.create_by}</span>
</div>
<div className={Styles.itemIcon}>
<img style={{ width: '12px', marginRight: '5px' }} src={clock} alt="" />
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
</div>
);
@@ -286,7 +295,14 @@ const PublicData = (React.FC = () => {
: ''}
{/* <Select.Option value="demo">Demo</Select.Option> */}
</div>
<Pagination size="small" total={total} showSizeChanger showQuickJumper />
<Pagination
total={total}
showSizeChanger
defaultPageSize={20}
pageSizeOptions={[20, 40, 60, 80, 100]}
showQuickJumper
onChange={onPageChange}
/>
</div>
</div>
<Modal


+ 24
- 8
react-ui/src/pages/Dataset/publicData.jsx View File

@@ -1,3 +1,5 @@
import clock from '@/assets/img/clock.png';
import creatByImg from '@/assets/img/creatBy.png';
import { getAssetIcon, getDatasetList } from '@/services/dataset/index.js';
import { Form, Input, Pagination } from 'antd';
import moment from 'moment';
@@ -109,6 +111,11 @@ const PublicData = (React.FC = () => {
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const onPageChange = (pageNum, pageSize) => {
console.log(pageNum, pageSize);
setQueryFlow({ ...queryFlow, page: pageNum - 1, size: pageSize });
getDatasetlist({ ...queryFlow, page: pageNum - 1, size: pageSize });
};
useEffect(() => {
getAssetIconList(iconParams);
getDatasetlist(queryFlow);
@@ -217,17 +224,19 @@ const PublicData = (React.FC = () => {
? datasetList.map((item) => {
return (
<div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}>
<div className={Styles.itemText}>{item.name}</div>
<span className={Styles.itemText}>{item.name}</span>
<div className={Styles.itemDescripition}>{item.description}</div>
<div className={Styles.itemTime}>
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
<div className={Styles.itemIcon}>
<img
style={{ width: '17px', marginRight: '3px' }}
src={`/assets/images/upload-icon.png`}
style={{ width: '17px', marginRight: '6px' }}
src={creatByImg}
alt=""
/>
<span>1582</span>
<span>{item.create_by}</span>
</div>
<div className={Styles.itemIcon}>
<img style={{ width: '12px', marginRight: '5px' }} src={clock} alt="" />
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
</div>
);
@@ -235,7 +244,14 @@ const PublicData = (React.FC = () => {
: ''}
{/* <Select.Option value="demo">Demo</Select.Option> */}
</div>
<Pagination size="small" total={total} showSizeChanger showQuickJumper />
<Pagination
total={total}
showSizeChanger
defaultPageSize={20}
pageSizeOptions={[20, 40, 60, 80, 100]}
showQuickJumper
onChange={onPageChange}
/>
</div>
</div>
</>


+ 7
- 7
react-ui/src/pages/Experiment/experimentText/addExperimentModal.less View File

@@ -1,12 +1,12 @@
.modal {
:global {
.ant-input {
height: 30px;
border-color: #e6e6e6;
}
.ant-select-single {
height: 40px;
}
// .ant-input {
// height: 30px;
// border-color: #e6e6e6;
// }
// .ant-select-single {
// height: 40px;
// }
.ant-form-item .ant-form-item-label > label {
color: rgba(29, 29, 32, 0.8);
}


+ 2
- 2
react-ui/src/pages/Experiment/experimentText/index.less View File

@@ -8,8 +8,8 @@
align-items: center;
width: 100%;
height: 43px;
margin-bottom: 10px;
padding: 0 20px;
margin-bottom: 20px;
padding: 0 24px;
color: #1d1d20;
font-size: 15px;
font-family: 'Alibaba';


+ 8
- 7
react-ui/src/pages/Experiment/experimentText/props.jsx View File

@@ -67,7 +67,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
span: 16,
}}
wrapperCol={{
span: 16,
span: 24,
}}
style={{
maxWidth: 600,
@@ -81,7 +81,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
>
<div className={Styles.editPipelinePropsContent}>
<img
style={{ width: '13px', marginRight: '10px' }}
style={{ width: '15px', marginRight: '10px' }}
src={'/assets/images/static-message.png'}
alt=""
/>
@@ -113,7 +113,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
</Form.Item>
<div className={Styles.editPipelinePropsContent}>
<img
style={{ width: '13px', marginRight: '10px' }}
style={{ width: '15px', marginRight: '10px' }}
src={'/assets/images/duty-message.png'}
alt=""
/>
@@ -136,7 +136,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
</Form.Item>

<Form.Item label="启动命令" name="command">
<Input disabled />
<TextArea disabled />
</Form.Item>
<Form.Item
label="资源规格"
@@ -195,7 +195,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
: ''}
<div className={Styles.editPipelinePropsContent}>
<img
style={{ width: '13px', marginRight: '10px' }}
style={{ width: '15px', marginRight: '10px' }}
src={'/assets/images/duty-message.png'}
alt=""
/>
@@ -390,12 +390,13 @@ const Props = forwardRef(({ onParentChange }, ref) => {
<Drawer
title="任务执行详情"
placement="right"
rootStyle={{ marginTop: '45px' }}
rootStyle={{ marginTop: '68px' }}
getContainer={false}
closeIcon={false}
onClose={onClose}
afterOpenChange={afterOpenChange}
open={open}
width={600}
width={420}
destroyOnClose={true}
>
<div className={Styles.detailBox}>任务名称:{stagingItem.label}</div>


+ 19
- 0
react-ui/src/pages/Mirror/create.less View File

@@ -0,0 +1,19 @@
@import '@/styles/theme.less';

.mirror-create {
height: 100%;

&__content {
height: calc(100% - 59px);
margin-top: 10px;
padding: 30px 30px 10px;
overflow: auto;
background-color: white;
border-radius: 10px;

&__title {
display: flex;
align-items: center;
}
}
}

+ 244
- 0
react-ui/src/pages/Mirror/create.tsx View File

@@ -0,0 +1,244 @@
/*
* @Author: 赵伟
* @Date: 2024-04-16 13:58:08
* @Description: 镜像详情
*/
import KFRadio, { type KFRadioItem } from '@/components/KFRadio';
import PageTitle from '@/components/PageTitle';
import SubAreaTitle from '@/components/SubAreaTitle';
import { CommonTabKeys } from '@/enums';
import { createPrivateMirrorReq, createPublicMirrorReq } from '@/services/mirror';
import { to } from '@/utils/promise';
import { useNavigate, useSearchParams } from '@umijs/max';
import { Button, Col, Form, Input, Row, message } from 'antd';
import styles from './create.less';

type FormData = {
name: string;
tag: string;
description: string;
path?: string;
type: string;
};

const mirrorRadioItems: KFRadioItem[] = [
{
key: CommonTabKeys.Public,
title: '基于公网镜像',
},
{
key: CommonTabKeys.Private,
title: '本地上传',
},
];

function MirrorCreate() {
const navgite = useNavigate();
const [seachParams] = useSearchParams();
const [form] = Form.useForm();
const isPublic = seachParams.get('isPublic') === 'true';

// 创建公网、本地镜像
const createPublicMirror = async (params: FormData) => {
// createPrivateMirrorReq
const req = isPublic ? createPublicMirrorReq : createPrivateMirrorReq;
const [res] = await to(req(params));
if (res) {
message.success('创建成功');
navgite(-1);
}
};

// 提交
const handleSubmit = (values: FormData) => {
console.log(values);
createPublicMirror(values);
};

return (
<div className={styles['mirror-create']}>
<PageTitle title="基本信息"></PageTitle>
<div className={styles['mirror-create__content']}>
<div>
<Form
name="mirror-create"
labelCol={{ flex: '120px' }}
wrapperCol={{ flex: 1 }}
labelAlign="left"
form={form}
initialValues={{ type: CommonTabKeys.Public }}
onFinish={handleSubmit}
>
<SubAreaTitle
title="基本信息"
image={require('@/assets/img/mirror-basic.png')}
style={{ marginBottom: '26px' }}
></SubAreaTitle>
<Row gutter={10}>
<Col span={10}>
<Form.Item
label="镜像名称及Tag"
name="name"
rules={[
{
required: true,
message: '请输入镜像名称',
},
]}
>
<Input placeholder="请输入镜像名称" maxLength={64} showCount allowClear />
</Form.Item>
</Col>
<Col span={10}>
<Form.Item
label=" "
name="tag"
labelCol={{ flex: '20px' }}
wrapperCol={{ flex: 1 }}
required={false}
rules={[
{
required: true,
message: '请输入镜像Tag',
},
]}
>
<Input placeholder="请输入镜像Tag" maxLength={64} showCount allowClear />
</Form.Item>
</Col>
</Row>
<Row gutter={10}>
<Col span={20}>
<Form.Item
label="镜像描述"
name="description"
rules={[
{
required: true,
message: '请输入镜像描述',
},
]}
>
<Input.TextArea
autoSize={{ minRows: 2, maxRows: 6 }}
placeholder="请输入镜像描述,最长128字符"
maxLength={128}
showCount
allowClear
/>
</Form.Item>
</Col>
</Row>
<SubAreaTitle
title="镜像构建"
image={require('@/assets/img/mirror-version.png')}
style={{ marginTop: '20px', marginBottom: '24px' }}
></SubAreaTitle>
<Row gutter={10}>
<Col span={10}>
<Form.Item
label="构建方式"
name="type"
rules={[
{
required: true,
message: '请选择构建方式',
},
]}
>
<KFRadio items={mirrorRadioItems}></KFRadio>
</Form.Item>
</Col>
</Row>
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) => prevValues.type !== curValues.type}
>
{({ getFieldValue }) => {
const type = getFieldValue('type');
if (type === CommonTabKeys.Public) {
return (
<>
<Row gutter={10}>
<Col span={10}>
<Form.Item label="仓库类型" required>
<span>公网</span>
</Form.Item>
</Col>
</Row>
<Row gutter={10}>
<Col span={10}>
<Form.Item
label="镜像地址"
name="path"
rules={[
{
required: true,
message: '请输入镜像地址',
},
]}
>
<Input
placeholder="请输入镜像地址"
maxLength={128}
showCount
allowClear
/>
</Form.Item>
</Col>
</Row>
</>
);
} else {
return (
<>
<Row gutter={10}>
<Col span={10}>
<Form.Item
label="镜像文件"
name="path"
rules={[
{
required: true,
message: '请上传镜像地址',
},
]}
>
{/* <Upload {...props} data={{ uuid: uuid }}>
<Button
style={{
fontSize: '14px',
border: '1px solid',
borderColor: '#1664ff',
background: '#fff',
}}
icon={<UploadOutlined style={{ color: '#1664ff' }} />}
>
上传文件
</Button>
</Upload> */}
</Form.Item>
</Col>
</Row>
</>
);
}
}}
</Form.Item>

<Form.Item wrapperCol={{ offset: 0, span: 16 }}>
<Button type="primary" htmlType="submit">
创建镜像
</Button>
<Button type="default" htmlType="reset" style={{ marginLeft: '20px' }}>
取消
</Button>
</Form.Item>
</Form>
</div>
</div>
</div>
);
}

export default MirrorCreate;

+ 55
- 0
react-ui/src/pages/Mirror/info.less View File

@@ -0,0 +1,55 @@
@import '@/styles/theme.less';

.mirror-info {
height: 100%;

&__basic {
&__item {
display: flex;
align-items: flex-start;
font-size: 16px;
line-height: 1.6;

.label {
width: 80px;
color: @text-color-second;
}

.value {
flex: 1;
color: @text-color;
}
}
}

&__content {
height: calc(100% - 59px);
margin-top: 10px;
padding: 30px 30px 0;
background-color: white;
border-radius: 10px;

&__title {
display: flex;
align-items: center;
}

&__table {
:global {
.ant-table-wrapper {
height: 100%;
.ant-spin-nested-loading {
height: 100%;
}
.ant-spin-container {
height: 100%;
}
.ant-table {
height: calc(100% - 74px);
overflow: auto;
}
}
}
}
}
}

+ 231
- 0
react-ui/src/pages/Mirror/info.tsx View File

@@ -0,0 +1,231 @@
/*
* @Author: 赵伟
* @Date: 2024-04-16 13:58:08
* @Description: 镜像详情
*/
import PageTitle from '@/components/PageTitle';
import SubAreaTitle from '@/components/SubAreaTitle';
import { useDomSize } from '@/hooks';
import { getMirrorInfoReq, getMirrorVersionListReq } from '@/services/mirror';
import { to } from '@/utils/promise';
import { useParams, useSearchParams } from '@umijs/max';
import { Button, Col, Row, Table, TablePaginationConfig, TableProps } from 'antd';
import classNames from 'classnames';
import dayjs from 'dayjs';
import { useEffect, useState } from 'react';
import styles from './info.less';

type MirrorInfoData = {
name?: string;
description?: string;
version_count?: string;
create_time?: string;
};

type MirrorVersionData = {
version: string;
url: string;
status: string;
file_size: string;
create_time: string;
};

function MirrorInfo() {
const urlParams = useParams();
const [seachParams] = useSearchParams();
const [mirrorInfo, setMirrorInfo] = useState<MirrorInfoData>({});
const [tableData, setTableData] = useState<MirrorVersionData[]>([]);
const [topRef, { height: topHeight }] = useDomSize<HTMLDivElement>(0, 0, [mirrorInfo]);
const [pagination, setPagination] = useState<TablePaginationConfig>({
showSizeChanger: true,
showQuickJumper: true,
current: 1,
pageSize: 10,
total: 0,
});
const isPublic = seachParams.get('isPublic') === 'true';
useEffect(() => {
getMirrorInfo();
getMirrorVersionList();
}, []);

// 获取镜像详情
const getMirrorInfo = async () => {
const id = Number(urlParams.id);
const [res] = await to(getMirrorInfoReq(id));
if (res && res.data) {
const { name = '', description = '', version_count = '', create_time: time } = res.data;
const create_time = time ? dayjs(time).format('YYYY-MM-DD HH:mm:ss') : '';
setMirrorInfo({
name,
description,
version_count,
create_time,
});
}
};

// 获取镜像版本列表
const getMirrorVersionList = async () => {
const id = Number(urlParams.id);
const params = {
page: pagination.current! - 1,
size: pagination.pageSize,
image_id: id,
};
const [res] = await to(getMirrorVersionListReq(params));
if (res && res.data) {
const { content = [], totalElements = 0 } = res.data;
setTableData(content);
setPagination((prev) => ({
...prev,
total: totalElements,
}));
}
};

// 分页切换
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter, { action }) => {
if (action === 'paginate') {
setPagination(pagination);
getMirrorVersionList();
}
console.log(pagination, filters, sorter, action);
};

const downloadVersion = (record: MirrorVersionData) => {};
const removeVersion = (record: MirrorVersionData) => {};

const columns: TableProps<MirrorVersionData>['columns'] = [
{
title: '镜像版本',
dataIndex: 'version',
key: 'version',
width: '20%',
},
{
title: '镜像地址',
dataIndex: 'url',
key: 'url',
width: '26%',
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: '7%',
},
{
title: '镜像大小',
dataIndex: 'file_size',
key: 'file_size',
width: '7%',
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
width: '20%',
render: (text: string) => <span>{dayjs(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
},
{
title: '操作',
dataIndex: 'operation',
width: '20%',
key: 'operation',
render: (_: any, record: any) => (
<div>
<Button
type="link"
size="small"
key="info"
// icon={<Icon icon="local:view-detail" style={{ verticalAlign: '-4px' }} />}
//icon={<MyIcon type="icon-shiyanduibi" style={{ fontSize: '16px' }}></MyIcon>}
onClick={() => downloadVersion(record)}
>
下载
</Button>
{!isPublic && (
<Button
type="link"
size="small"
key="remove"
// icon={<MyIcon type="icon-shiyanduibi" style={{ fontSize: '16px' }}></MyIcon>}

// icon={<Icon icon="local:view-detail" style={{ verticalAlign: '-2px' }} />}
onClick={() => removeVersion(record)}
>
删除
</Button>
)}
</div>
),
},
];

return (
<div className={styles['mirror-info']}>
<PageTitle title="镜像详情"></PageTitle>
<div className={styles['mirror-info__content']}>
<div ref={topRef}>
<SubAreaTitle
title="基本信息"
image={require('@/assets/img/mirror-basic.png')}
style={{ marginBottom: '26px' }}
></SubAreaTitle>
<div className={styles['mirror-info__basic']}>
<Row gutter={40} style={{ marginBottom: '20px' }}>
<Col span={10}>
<div className={styles['mirror-info__basic__item']}>
<div className={styles['label']}>镜像名称:</div>
<div className={styles['value']}>{mirrorInfo.name}</div>
</div>
</Col>
<Col span={10}>
<div className={styles['mirror-info__basic__item']}>
<div className={styles['label']}>版本数:</div>
<div className={styles['value']}>{mirrorInfo.version_count}</div>
</div>
</Col>
</Row>
<Row gutter={40}>
<Col span={10}>
<div className={styles['mirror-info__basic__item']}>
<div className={styles['label']}>镜像描述:</div>
<div className={styles['value']}>{mirrorInfo.description}</div>
</div>
</Col>
<Col span={10}>
<div className={styles['mirror-info__basic__item']}>
<div className={styles['label']}>创建时间:</div>
<div className={styles['value']}>{mirrorInfo.create_time}</div>
</div>
</Col>
</Row>
</div>

<SubAreaTitle
title="镜像版本"
image={require('@/assets/img/mirror-version.png')}
style={{ marginTop: '40px' }}
></SubAreaTitle>
</div>
<div
className={classNames('vertical-scroll-table', styles['mirror-info__content__table'])}
style={{ marginTop: '24px', height: `calc(100% - ${topHeight + 24}px)` }}
>
<Table
dataSource={tableData}
columns={columns}
scroll={{ y: 'calc(100% - 55px)' }}
pagination={pagination}
onChange={handleTableChange}
rowKey="id"
/>
</div>
</div>
</div>
);
}

export default MirrorInfo;

+ 3
- 16
react-ui/src/pages/Mirror/list.less View File

@@ -1,10 +1,11 @@
@import '@/styles/theme.less';

.mirror-list {
height: 100%;
background-color: #f9fafb;
&__tabs-container {
height: 49px;
padding-left: 27px;
background-image: url('../../assets/img/mirror-tabs-bg.png');
background-image: url('../../assets/img/page-title-bg.png');
}

&__content {
@@ -24,20 +25,6 @@
&__table {
height: calc(100% - 44px);
margin-top: 12px;
:global {
.ant-table-wrapper {
height: 100%;
.ant-spin-nested-loading {
height: 100%;
}
.ant-spin-container {
height: 100%;
}
.ant-table {
height: calc(100% - 74px);
}
}
}
}
}
}

+ 110
- 47
react-ui/src/pages/Mirror/list.tsx View File

@@ -3,12 +3,13 @@
* @Date: 2024-04-16 13:58:08
* @Description: 镜像列表
*/
import KFIcon from '@/components/KFIcon';
import { CommonTabKeys } from '@/enums';
import { useDomSize } from '@/hooks';
import { getMirrorListReq } from '@/services/mirror';
import { to } from '@/utils/promise';
import { Icon } from '@umijs/max';
import { Button, Input, Table, Tabs } from 'antd';
import { Icon, useNavigate } from '@umijs/max';
import { Button, Input, Table, TablePaginationConfig, TableProps, Tabs } from 'antd';
import classNames from 'classnames';
import dayjs from 'dayjs';
import { useEffect, useState } from 'react';
import styles from './list.less';
@@ -26,11 +27,19 @@ const mirrorTabItems = [
},
];

export type MirrorData = {
id: number;
name: string;
description: string;
create_time: string;
};

function MirrorList() {
const navgite = useNavigate();
const [activeTab, setActiveTab] = useState('Public');
const [tableData, setTableData] = useState([]);
const [contentRef, { height: tableHeight }] = useDomSize<HTMLDivElement>(0, 0);
const [pagination, setPagination] = useState({
const [searchText, setSearchText] = useState('');
const [tableData, setTableData] = useState<MirrorData[]>([]);
const [pagination, setPagination] = useState<TablePaginationConfig>({
showSizeChanger: true,
showQuickJumper: true,
current: 1,
@@ -38,10 +47,56 @@ function MirrorList() {
total: 0,
});
useEffect(() => {
getMirrorList('');
getMirrorList();
}, [activeTab]);

const columns = [
// 获取镜像列表
const getMirrorList = async () => {
const params = {
page: pagination.current! - 1,
size: pagination.pageSize,
name: searchText,
image_type: activeTab === CommonTabKeys.Public ? 1 : 0,
};
const [res] = await to(getMirrorListReq(params));
if (res && res.data) {
const { content = [], totalElements = 0 } = res.data;
setTableData(content);
setPagination((prev) => ({
...prev,
total: totalElements,
}));
}
};

// 搜索
const onSearch = () => {
getMirrorList();
};

// 查看详情
const toDetail = (record: MirrorData) => {
console.log('record', record);
navgite({
pathname: `/dataset/mirror/${record.id}?isPublic=${activeTab === CommonTabKeys.Public}`,
});
};

// 创建镜像
const createMirror = () => {
navgite({ pathname: `/dataset/mirror/create?isPublic=${activeTab === CommonTabKeys.Public}` });
};

// 分页切换
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter, { action }) => {
if (action === 'paginate') {
setPagination(pagination);
getMirrorList();
}
console.log(pagination, filters, sorter, action);
};

const columns: TableProps<MirrorData>['columns'] = [
{
title: '镜像名称',
dataIndex: 'name',
@@ -71,45 +126,38 @@ function MirrorList() {
{
title: '操作',
dataIndex: 'operation',
width: '100px',
width: '15%',
key: 'operation',
render: (_: any, record: any) => [
<Button
type="link"
size="small"
key="download"
icon={<Icon icon="local:view-detail" style={{ verticalAlign: '-4px' }} />}
// onClick={(e) => downloadAlone(e, record)}
>
查看详情
</Button>,
],
render: (_: any, record: any) => (
<div>
<Button
type="link"
size="small"
key="info"
// icon={<Icon icon="local:view-detail" style={{ verticalAlign: '-4px' }} />}
icon={<KFIcon type="icon-chakanxiangqing" />}
onClick={() => toDetail(record)}
>
查看详情
</Button>
{activeTab === CommonTabKeys.Private && (
<Button
type="link"
size="small"
key="remove"
icon={<KFIcon type="icon-shiyanduibi1" />}

// icon={<Icon icon="local:view-detail" style={{ verticalAlign: '-2px' }} />}
// onClick={(e) => downloadAlone(e, record)}
>
删除
</Button>
)}
</div>
),
},
];

const getMirrorList = async (name: string) => {
const params = {
page: pagination.current - 1,
size: pagination.pageSize,
name,
image_type: activeTab === CommonTabKeys.Public ? 1 : 0,
};
const [res] = await to(getMirrorListReq(params));
if (res && res.data) {
const { content = [], totalElements = 0 } = res.data;
console.log(res);
setTableData(content);
setPagination((prev) => ({
...prev,
total: totalElements,
}));
}
};

const onSearch = (value: string) => {
getMirrorList(value);
};

return (
<div className={styles['mirror-list']}>
<div className={styles['mirror-list__tabs-container']}>
@@ -126,21 +174,36 @@ function MirrorList() {
placeholder="按数据集名称筛选"
allowClear
onSearch={onSearch}
onChange={(e) => setSearchText(e.target.value)}
style={{ width: 300 }}
value={searchText}
/>
{activeTab === CommonTabKeys.Private && (
<Button
style={{ marginLeft: '20px' }}
type="default"
onClick={createMirror}
icon={<Icon icon="local:refresh" style={{ verticalAlign: '-2px' }} />}
>
制作镜像
</Button>
)}
<Button
type="primary"
icon={<Icon icon="local:refresh-btn" style={{ verticalAlign: '-2px' }} />}
style={{ marginRight: 0, marginLeft: 'auto' }}
type="default"
onClick={getMirrorList}
icon={<Icon icon="local:refresh" style={{ verticalAlign: '-2px' }} />}
>
刷新
</Button>
</div>
<div className={styles['mirror-list__content__table']} ref={contentRef}>
<div className={classNames('vertical-scroll-table', styles['mirror-list__content__table'])}>
<Table
dataSource={tableData}
columns={columns}
scroll={{ y: tableHeight - 55 - 74 }}
scroll={{ y: 'calc(100% - 55px)' }}
pagination={pagination}
onChange={handleTableChange}
rowKey="id"
/>
</div>


+ 44
- 14
react-ui/src/pages/Model/index.less View File

@@ -105,7 +105,7 @@
display: flex;
justify-content: space-between;
width: 100%;
height: 85vh;
height: 87.5vh;

.datasetCneterLeftBox {
width: 340px;
@@ -222,35 +222,65 @@
width: 100%;
.dataItem {
position: relative;
width: 32%;
height: 66px;
margin: 0 15px 18px 0;
background: rgba(128, 128, 128, 0.05);
border-radius: 8px;
box-shadow: 0px 0px 12px rgba(75, 84, 137, 0.05);
width: 23%;
height:164px;
background:#ffffff;
border:1px solid;
border-color:#eaeaea;
border-radius:4px;
margin: 0 20px 25px 0;
cursor: pointer;
.itemText {
position: absolute;
top: 10px;
top: 20px;
left: 20px;
color: #1d1d20;
font-size: 15px;
background: linear-gradient(to right ,rgba(22, 100, 255,0.6) 0,rgba(22, 100, 255,0) 100%);
height: 6px;
line-height: 0px;
color:#1d1d20;
font-size:16px;

}
.itemDescripition{
position: absolute;
top: 57px;
left: 20px;
padding-right: 28px;
color:#575757;
font-size:14px;
word-break: break-all;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.itemTime {
position: absolute;
bottom: 10px;
display: flex;
align-items: center;
bottom: 22px;
left: 20px;
color: #808080;
font-size: 14px;
font-size: 13px;
}
.itemIcon {
position: absolute;
display: flex;
align-items: center;
right: 20px;
bottom: 10px;
bottom: 22px;
color: #808080;
font-size: 14px;
font-size: 13px;
}
}
.dataItem:hover{
border-color: #1664FF;
box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2)
}
.dataItem:hover .itemText{
color: #1664FF;
}
}
}
}


+ 24
- 8
react-ui/src/pages/Model/personalData.jsx View File

@@ -1,4 +1,6 @@
import { getAccessToken } from '@/access';
import clock from '@/assets/img/clock.png';
import creatByImg from '@/assets/img/creatBy.png';
import { addModel, getAssetIcon, getModelList } from '@/services/dataset/index.js';
import { PlusCircleOutlined, UploadOutlined } from '@ant-design/icons';
import { Button, Form, Input, Modal, Pagination, Radio, Select, Upload } from 'antd';
@@ -148,6 +150,11 @@ const PublicData = () => {
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const onPageChange = (pageNum, pageSize) => {
console.log(pageNum, pageSize);
setQueryFlow({ ...queryFlow, page: pageNum - 1, size: pageSize });
getModelLists({ ...queryFlow, page: pageNum - 1, size: pageSize });
};
useEffect(() => {
getAssetIconList(iconParams);
getModelLists(queryFlow);
@@ -271,17 +278,19 @@ const PublicData = () => {
? datasetList.map((item) => {
return (
<div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}>
<div className={Styles.itemText}>{item.name}</div>
<span className={Styles.itemText}>{item.name}</span>
<div className={Styles.itemDescripition}>{item.description}</div>
<div className={Styles.itemTime}>
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
<div className={Styles.itemIcon}>
<img
style={{ width: '17px', marginRight: '3px' }}
src={`/assets/images/upload-icon.png`}
style={{ width: '17px', marginRight: '6px' }}
src={creatByImg}
alt=""
/>
<span>1582</span>
<span>{item.create_by}</span>
</div>
<div className={Styles.itemIcon}>
<img style={{ width: '12px', marginRight: '5px' }} src={clock} alt="" />
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
</div>
);
@@ -289,7 +298,14 @@ const PublicData = () => {
: ''}
{/* <Select.Option value="demo">Demo</Select.Option> */}
</div>
<Pagination size="small" total={total} showSizeChanger showQuickJumper />
<Pagination
total={total}
showSizeChanger
defaultPageSize={20}
pageSizeOptions={[20, 40, 60, 80, 100]}
showQuickJumper
onChange={onPageChange}
/>
</div>
</div>
<Modal


+ 24
- 8
react-ui/src/pages/Model/publicData.jsx View File

@@ -1,3 +1,5 @@
import clock from '@/assets/img/clock.png';
import creatByImg from '@/assets/img/creatBy.png';
import { getAssetIcon, getModelList } from '@/services/dataset/index.js';
import { Form, Input, Modal, Pagination, Radio } from 'antd';
import moment from 'moment';
@@ -110,6 +112,11 @@ const PublicData = () => {
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const onPageChange = (pageNum, pageSize) => {
console.log(pageNum, pageSize);
setQueryFlow({ ...queryFlow, page: pageNum - 1, size: pageSize });
getModelLists({ ...queryFlow, page: pageNum - 1, size: pageSize });
};
useEffect(() => {
getAssetIconList(iconParams);
getModelLists(queryFlow);
@@ -218,17 +225,19 @@ const PublicData = () => {
? datasetList.map((item) => {
return (
<div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}>
<div className={Styles.itemText}>{item.name}</div>
<span className={Styles.itemText}>{item.name}</span>
<div className={Styles.itemDescripition}>{item.description}</div>
<div className={Styles.itemTime}>
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
<div className={Styles.itemIcon}>
<img
style={{ width: '17px', marginRight: '3px' }}
src={`/assets/images/upload-icon.png`}
style={{ width: '17px', marginRight: '6px' }}
src={creatByImg}
alt=""
/>
<span>1582</span>
<span>{item.create_by}</span>
</div>
<div className={Styles.itemIcon}>
<img style={{ width: '12px', marginRight: '5px' }} src={clock} alt="" />
<span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span>
</div>
</div>
);
@@ -236,7 +245,14 @@ const PublicData = () => {
: ''}
{/* <Select.Option value="demo">Demo</Select.Option> */}
</div>
<Pagination size="small" total={total} showSizeChanger showQuickJumper />
<Pagination
total={total}
showSizeChanger
defaultPageSize={20}
pageSizeOptions={[20, 40, 60, 80, 100]}
showQuickJumper
onChange={onPageChange}
/>
</div>
</div>
<Modal


+ 2
- 2
react-ui/src/pages/Pipeline/editPipeline/editPipeline.less View File

@@ -8,8 +8,8 @@
align-items: center;
width: 100%;
height: 43px;
margin-bottom: 10px;
padding: 0 20px;
margin-bottom: 20px;
padding: 0 24px;
color: #1d1d20;
font-size: 15px;
font-family: 'Alibaba';


+ 26
- 16
react-ui/src/pages/Pipeline/editPipeline/index.jsx View File

@@ -101,22 +101,32 @@ const EditPipeline = () => {
openParamsDrawer();
return;
}
const data = graph.save();
console.log(data);
const params = {
...locationParams,
dag: JSON.stringify(data),
global_param: JSON.stringify(res.global_param),
};
saveWorkflow(params).then((ret) => {
message.success('保存成功');
closeParamsDrawer();
setTimeout(() => {
if (val) {
navgite({ pathname: `/pipeline` });
}
}, 500);
});
const [propsRes, propsError] = await to(propsRef.current.getFieldsValue());
console.log(await to(propsRef.current.getFieldsValue()));
if (propsError) {
message.error('基本信息必填项需配置');
// handlerClick();
return;
}
propsRef.current.propClose();
setTimeout(() => {
const data = graph.save();
console.log(data);
const params = {
...locationParams,
dag: JSON.stringify(data),
global_param: JSON.stringify(res.global_param),
};
saveWorkflow(params).then((ret) => {
message.success('保存成功');
closeParamsDrawer();
setTimeout(() => {
if (val) {
navgite({ pathname: `/pipeline` });
}
}, 500);
});
}, 500);
};
const handlerClick = (e) => {
e.stopPropagation();


+ 37
- 9
react-ui/src/pages/Pipeline/editPipeline/props.jsx View File

@@ -1,5 +1,6 @@
import { pick } from '@/utils/index';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import { Icon } from '@umijs/max';
import { Button, Drawer, Form, Input } from 'antd';
import { forwardRef, useImperativeHandle, useState } from 'react';
@@ -8,6 +9,7 @@ import Styles from './editPipeline.less';
const { TextArea } = Input;
const Props = forwardRef(({ onParentChange }, ref) => {
const [form] = Form.useForm();

const [stagingItem, setStagingItem] = useState({});
const [open, setOpen] = useState(false);
const [selectedModel, setSelectedModel] = useState(undefined);
@@ -59,6 +61,15 @@ const Props = forwardRef(({ onParentChange }, ref) => {
console.log('Failed:', errorInfo);
};
useImperativeHandle(ref, () => ({
getFieldsValue: async () => {
const [propsRes, propsError] = await to(form.validateFields());
if (propsRes && !propsError) {
const values = form.getFieldsValue();
return values;
} else {
return Promise.reject(propsError);
}
},
showDrawer(e) {
if (e.item && e.item.getModel()) {
// console.log(e.item.getModel().in_parameters);
@@ -80,9 +91,20 @@ const Props = forwardRef(({ onParentChange }, ref) => {
// setTimeout(() => {
// console.log(stagingItem);
// }, (500));
setSelectedModel(undefined);
setSelectedDataset(undefined);
setOpen(true);
}
},
propClose: async () => {
setOpen(false);
const [openRes, propsError] = await to(setOpen(false));
console.log(setOpen(false));
},
// propClose() {

// setOpen(false);
// },
}));

// 选择数据集、模型
@@ -152,16 +174,22 @@ const Props = forwardRef(({ onParentChange }, ref) => {
onClose={onClose}
afterOpenChange={afterOpenChange}
open={open}
width={540}
width={420}
>
<Form
name="form"
form={form}
// layout="vertical"
labelCol={{ span: 10 }}
wrapperCol={{ span: 20 }}
// initialValues={{ global_param: globalParam }}
labelAlign="left"
layout="vertical"
labelCol={{
span: 16,
}}
wrapperCol={{
span: 24,
}}
style={{
maxWidth: 600,
}}
initialValues={{
remember: true,
}}
@@ -203,7 +231,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
</Form.Item>
<div className={Styles.editPipelinePropsContent}>
<img
style={{ width: '13px', marginRight: '10px' }}
style={{ width: '15px', marginRight: '10px' }}
src={'/assets/images/duty-message.png'}
alt=""
/>
@@ -226,7 +254,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
</Form.Item>

<Form.Item label="启动命令" name="command">
<Input />
<TextArea />
</Form.Item>
<Form.Item
label="资源规格"
@@ -255,7 +283,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
: ''}
<div className={Styles.editPipelinePropsContent}>
<img
style={{ width: '13px', marginRight: '10px' }}
style={{ width: '15px', marginRight: '10px' }}
src={'/assets/images/duty-message.png'}
alt=""
/>
@@ -294,7 +322,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
: ''}
<div className={Styles.editPipelinePropsContent}>
<img
style={{ width: '13px', marginRight: '10px' }}
style={{ width: '15px', marginRight: '10px' }}
src={'/assets/images/duty-message.png'}
alt=""
/>


+ 2
- 2
react-ui/src/pages/Pipeline/index.jsx View File

@@ -297,7 +297,7 @@ const Pipeline = () => {
},
]}
>
<Input showCount maxLength={64} />
<Input placeholder="请输入流水线名称" showCount maxLength={64} />
</Form.Item>
<Form.Item
label="流水线描述"
@@ -309,7 +309,7 @@ const Pipeline = () => {
},
]}
>
<Input showCount maxLength={128} />
<Input placeholder="请输入流水线描述" showCount maxLength={128} />
</Form.Item>
</Form>
</Modal>


+ 30
- 7
react-ui/src/services/mirror/index.ts View File

@@ -13,10 +13,33 @@ export function getMirrorListReq(params: any) {
});
}

// // 分页查询镜像列表
// export function getMirrorList(params: any) {
// return request(`/image/`, {
// method: 'GET',
// params,
// });
// }
// 查询镜像详情
export function getMirrorInfoReq(id: number) {
return request(`/api/mmp/image/${id}`, {
method: 'GET',
});
}

// 查询镜像版本列表
export function getMirrorVersionListReq(params: any) {
return request(`/api/mmp/imageVersion/`, {
method: 'GET',
params,
});
}

// 创建公网镜像
export function createPublicMirrorReq(data: any) {
return request(`/api/mmp/image/net`, {
method: 'POST',
data,
});
}

// 创建本地镜像
export function createPrivateMirrorReq(data: any) {
return request(`/api/mmp/image/local`, {
method: 'POST',
data,
});
}

+ 3
- 0
react-ui/src/styles/theme.less View File

@@ -1,7 +1,10 @@
// 全局颜色变量
// FIXME: 不能设置 @primary-color 不起作用,感觉是哪里被重置了
@kf-primary-color: #1664ff; // 主色调
@primary-color-hover: #4086ff;
@background-color: #f9fafb; // 页面背景颜色
@text-color: #1d1d20;
@text-color-second: #575757;
@font-size: 15px;
@border-color: rgba(22, 100, 255, 0.3);
@border-color-second: rgba(22, 100, 255, 0.1);


+ 9
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetController.java View File

@@ -1,5 +1,6 @@
package com.ruoyi.platform.controller.dataset;

import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.domain.Dataset;
@@ -54,11 +55,15 @@ public class DatasetController {
public AjaxResult queryByPage(Dataset dataset, @RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam(value = "available_range") int availableRange ,
@RequestParam(value = "data_type", required = false) String dataType) {
@RequestParam(value = "data_type", required = false) String dataType,
@RequestParam(value = "data_tag", required = false) String dataTag) {

if (dataType != null) { // 仅当dataType有值时设置
dataset.setDataType(dataType);
}
if (dataTag != null) {
dataset.setDataTag(dataTag);
}
dataset.setAvailableRange(availableRange);
PageRequest pageRequest = PageRequest.of(page, size);
return AjaxResult.success(this.datasetService.queryByPage(dataset, pageRequest));
@@ -79,6 +84,9 @@ public class DatasetController {
if (dataType != null) { // 仅当dataType有值时设置
dataset.setDataType(dataType);
}
if (dataTag != null) {
dataset.setDataTag(dataTag);
}
PageRequest pageRequest = PageRequest.of(page, size);
return AjaxResult.success(this.datasetService.queryByPage(dataset, pageRequest));
}


+ 2
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/image/ImageController.java View File

@@ -122,7 +122,7 @@ public class ImageController extends BaseController {

@PostMapping("/net")
@ApiOperation("从网络上传构建镜像")
public GenericsAjaxResult<String> createImageFromNet(@RequestParam("name") String imageName,
public GenericsAjaxResult<Map<String, String>> createImageFromNet(@RequestParam("name") String imageName,
@RequestParam("tag") String imageTag,
@RequestParam("path") String path) throws Exception {
return genericsSuccess(this.imageService.createImageFromNet(imageName,imageTag,path));
@@ -130,7 +130,7 @@ public class ImageController extends BaseController {

@PostMapping("/local")
@ApiOperation("从本地上传构建镜像")
public GenericsAjaxResult<String> createImageFromLocal(@RequestParam("name") String imageName,
public GenericsAjaxResult<Map<String, String>> createImageFromLocal(@RequestParam("name") String imageName,
@RequestParam("tag") String imageTag,
@RequestParam("path") String path) throws Exception {
return genericsSuccess(this.imageService.createImageFromLocal(imageName,imageTag,path));


+ 9
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/image/ImageVersionController.java View File

@@ -8,8 +8,10 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

/**
* (ImageVersion)表控制层
@@ -36,11 +38,17 @@ public class ImageVersionController extends BaseController {
*/
@GetMapping
@ApiOperation("分页查询")
public GenericsAjaxResult<Page<ImageVersion>> queryByPage(ImageVersion imageVersion, int page, int size) {
public GenericsAjaxResult<Page<ImageVersion>> queryByPage(ImageVersion imageVersion, @RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam(value = "image_id") int imageId) {
imageVersion.setImageId(imageId);
PageRequest pageRequest = PageRequest.of(page,size);
return genericsSuccess(this.imageVersionService.queryByPage(imageVersion, pageRequest));

}



/**
* 通过主键查询单条数据
*


+ 4
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/resources/ComputingResourceController.java View File

@@ -36,7 +36,10 @@ public class ComputingResourceController extends BaseController {
*/
@GetMapping
@ApiOperation("分页查询")
public GenericsAjaxResult<Page<ComputingResource>> queryByPage(ComputingResource computingResource, int page, int size) {
public GenericsAjaxResult<Page<ComputingResource>> queryByPage(ComputingResource computingResource, @RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam(value = "resource_type") String resourceType ) {
computingResource.setComputingResource(resourceType);
PageRequest pageRequest = PageRequest.of(page,size);
return genericsSuccess(this.computingResourceService.queryByPage(computingResource, pageRequest));
}


+ 1
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ComputingResourceDao.java View File

@@ -71,7 +71,7 @@ public interface ComputingResourceDao {
* @param computingResource 实例对象
* @return 影响行数
*/
int update(ComputingResource computingResource);
int update(@Param("computingResource") ComputingResource computingResource);

/**
* 通过主键删除数据


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

@@ -1,13 +1,11 @@
package com.ruoyi.platform.service;

import com.ruoyi.platform.domain.Image;
import com.ruoyi.platform.domain.Workflow;
import com.ruoyi.platform.vo.ImageVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collection;
import java.util.Map;

/**
@@ -69,13 +67,14 @@ public interface ImageService {

/**
* 本地上传构建镜像
*
* @param imageName
* @param imageTag
* @param path
* @return
*/
String createImageFromLocal(String imageName, String imageTag, String path) throws Exception;
String createImageFromNet(String imageName, String imageTag, String NetPath) throws Exception;
Map<String, String> createImageFromLocal(String imageName, String imageTag, String path) throws Exception;
Map<String, String> createImageFromNet(String imageName, String imageTag, String NetPath) throws Exception;
Map<String, String> uploadImageFiles(MultipartFile file) throws Exception;

}

+ 1
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetServiceImpl.java View File

@@ -268,7 +268,7 @@ public class DatasetServiceImpl implements DatasetService {
// 获取所有相同模型ID的记录
List<DatasetVersion> versions = datasetVersionDao.queryByDatasetId(datasetId);
if (versions.isEmpty()) {
throw new Exception("未找到相关数据集版本记录");
return new ArrayList<>(); // 如果没有找到任何版本记录,返回空列表
}
// 使用Stream API提取version字段,并去重
return versions.stream()


+ 63
- 14
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java View File

@@ -8,6 +8,7 @@ import com.ruoyi.platform.mapper.ImageVersionDao;
import com.ruoyi.platform.service.ImageService;
import com.ruoyi.platform.service.ImageVersionService;
import com.ruoyi.platform.service.MinioService;
import com.ruoyi.platform.utils.FileUtil;
import com.ruoyi.platform.utils.K8sClientUtil;
import com.ruoyi.platform.vo.ImageVo;
import com.ruoyi.system.api.model.LoginUser;
@@ -23,7 +24,9 @@ import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
* (Image)表服务实现类
@@ -171,7 +174,6 @@ public class ImageServiceImpl implements ImageService {
image.setName(imageVo.getName());
image.setDescription(imageVo.getDescription());
image.setImageType(imageVo.getImageType());

Image imageInsert = this.insert(image);
if (imageInsert == null){
throw new Exception("新增镜像失败");
@@ -181,17 +183,50 @@ public class ImageServiceImpl implements ImageService {
imageVersion.setVersion(imageVo.getVersion());
imageVersion.setUrl(imageVo.getUrl());
imageVersion.setTagName(imageVo.getTagName());
//imageVersion.setFileSize(datasetVo.getFileSize());
imageVersion.setFileSize(imageVo.getFileSize());
imageVersion.setStatus("building");
ImageVersion imageVersionInsert = this.imageVersionService.insert(imageVersion);
if (imageVersionInsert == null) {
throw new Exception("新增镜像失败");
}
return "新增镜像成功";
// 使用CompletableFuture异步执行不同的镜像构建逻辑
CompletableFuture.supplyAsync(() -> {
Map<String, String> resultMap = new HashMap<>();
try {
if(imageVo.getUploadType()==0){
resultMap = createImageFromNet(imageVo.getName(), imageVo.getTagName(), imageVo.getPath());
}else{
resultMap = createImageFromLocal(imageVo.getName(), imageVo.getTagName(), imageVo.getPath());
}
} catch (Exception e) {
imageVersion.setStatus("failed");
imageVersionService.update(imageVersion);
throw new RuntimeException("镜像构建失败: " + e.getMessage(), e);
}
return resultMap;
}).thenAccept(resultMap ->{
try {
String imageUrl = resultMap.get("url");
String fileSize = resultMap.get("filesize");
imageVersion.setUrl(imageUrl);
imageVersion.setFileSize(fileSize);
imageVersion.setStatus("available");
imageVersionService.update(imageVersion);
} catch (Exception e) {
System.err.println("更新数据库失败: " + e.getMessage());
}
}).exceptionally(ex -> {
System.err.println("异步操作发生错误: " + ex.getMessage());
return null;
});


return "新增镜像成功,镜像构建中...";
}

@Override
public String createImageFromNet(String imageName, String imageTag, String netPath) throws Exception {
public Map<String, String> createImageFromNet(String imageName, String imageTag, String netPath) throws Exception {
Map<String, String> resultMap = new HashMap<>();
// 得到容器
V1Pod pod = k8sClientUtil.getNSPodList(serviceNS, deploymentName);
if (pod == null) {
@@ -203,7 +238,7 @@ public class ImageServiceImpl implements ImageService {
// 在这个容器的/data/admin 目录下执行命令 docker load -i fileName 得到返回的镜像名字name:tag
String username = SecurityUtils.getLoginUser().getUsername();
//
String logs2 = k8sClientUtil.executeCommand(pod,"docker pull "+netPath);
String logs2 = k8sClientUtil.executeCommand(pod,"docker pull "+ netPath);
// 在容器里执行 docker tag name:tag nexus3.kube-system.svc:8083/imageName:imageTag
if (StringUtils.isNoneBlank(logs2)){
String substring = logs2.substring(logs2.indexOf(harborUrl), logs2.length());
@@ -211,19 +246,28 @@ public class ImageServiceImpl implements ImageService {
String cmd1 = "docker tag " + cleanedString+ " " + harborUrl+"/"+repository+"/"+username+"/" + imageName + imageTag;
String imageUrl = harborUrl+"/"+repository+"/"+username+"/" + imageName + imageTag;
String cmd2 = "docker push " + imageUrl;
String cmd3 = "docker inspect --format='{{.Size}}' " + imageUrl;

String s = k8sClientUtil.executeCommand(pod, cmd1);
if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, cmd2))){
return imageUrl;
resultMap.put("url", imageUrl);
//得到镜像文件大小
long sizeInBytes = Long.parseLong(k8sClientUtil.executeCommand(pod, cmd3));
String formattedImageSize = FileUtil.formatFileSize(sizeInBytes); // 格式化镜像文件大小
resultMap.put("fileSize", formattedImageSize);
return resultMap;

}else {
throw new Exception("拉取公网镜像失败,请检查网络或者镜像地址");
throw new Exception("拉取公网镜像失败,请检查网络或者镜像地址");
}
}else {
throw new Exception("拉取公网镜像失败,请检查网络或者镜像地址");
throw new Exception("拉取公网镜像失败,请检查网络或者镜像地址");
}
}

@Override
public String createImageFromLocal(String imageName, String imageTag, String path) throws Exception {
public Map<String, String> createImageFromLocal(String imageName, String imageTag, String path) throws Exception {
Map<String, String> resultMap = new HashMap<>();
// 得到容器
V1Pod pod = k8sClientUtil.getNSPodList(serviceNS, deploymentName);
if (pod == null) {
@@ -244,11 +288,17 @@ public class ImageServiceImpl implements ImageService {
String cmd1 = "docker tag " + cleanedString+ " " + harborUrl+"/"+repository+"/"+username+"/" + imageName + imageTag;
String imageUrl = harborUrl+"/"+repository+"/"+username+"/" + imageName + imageTag;
String cmd2 = "docker push " + imageUrl;
String cmd3 = "docker inspect --format='{{.Size}}' " + imageUrl;
String s = k8sClientUtil.executeCommand(pod, cmd1);
if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, cmd2))){
return imageUrl;
resultMap.put("url", imageUrl);
//得到镜像文件大小
long sizeInBytes = Long.parseLong(k8sClientUtil.executeCommand(pod, cmd3));
String formattedImageSize = FileUtil.formatFileSize(sizeInBytes); // 格式化镜像文件大小
resultMap.put("fileSize", formattedImageSize);
return resultMap;
}else {
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
}
}else {
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
@@ -259,7 +309,6 @@ public class ImageServiceImpl implements ImageService {
public Map<String, String> uploadImageFiles(MultipartFile file) throws Exception {
LoginUser loginUser = SecurityUtils.getLoginUser();
String path = loginUser.getUsername()+"/"+file.getOriginalFilename();
Map<String, String> stringMap = minioService.uploadFile(bucketName, path, file);
return stringMap;
return minioService.uploadFile(bucketName, path, file);
}
}

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

@@ -317,10 +317,8 @@ public class ModelsServiceImpl implements ModelsService {
List<ModelsVersion> versions = modelsVersionDao.queryByModelsId(modelId);

if (versions.isEmpty()) {
throw new Exception("未找到相关模型版本记录");
return new ArrayList<>(); // 如果没有找到任何版本记录,返回空列表
}
// // 将结果按照版本分类
// return versions.stream().collect(Collectors.groupingBy(ModelsVersion::getVersion));

// 使用Stream API提取version字段,并去重
return versions.stream()


+ 3
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java View File

@@ -378,9 +378,10 @@ public class K8sClientUtil {
// invokes the CoreV1Api client

for (V1Pod item : v1PodList.getItems()) {
if (item.getMetadata().getGenerateName().startsWith(deploymentName)) {
String generateName = item.getMetadata().getGenerateName();
if (StringUtils.isNotEmpty(generateName) && generateName.startsWith(deploymentName)) {
// 找到匹配的Pod,获取其名称
return item;
return item;
}
}
return null;


+ 29
- 10
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ImageVo.java View File

@@ -9,10 +9,7 @@ import java.io.Serializable;
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class ImageVo implements Serializable {

/**
* 主键
*/
private Integer id;

/**
* 镜像名称
*/
@@ -58,13 +55,20 @@ public class ImageVo implements Serializable {
@ApiModelProperty(name = "status")
private String status;

public Integer getId() {
return id;
}
@ApiModelProperty(value = "上传方式, 基于公网上传0,基于本地上传1")
private Integer uploadType;

public void setId(Integer id) {
this.id = id;
}
@ApiModelProperty(value = "镜像上传路径")
private String path;


// public Integer getId() {
// return id;
// }
//
// public void setId(Integer id) {
// this.id = id;
// }

public String getName() {
return name;
@@ -129,4 +133,19 @@ public class ImageVo implements Serializable {
public void setStatus(String status) {
this.status = status;
}

public Integer getUploadType() {
return uploadType;
}

public void setUploadType(Integer uploadType) {
this.uploadType = uploadType;
}

public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}

+ 6
- 6
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ComputingResourceDaoMapper.xml View File

@@ -73,7 +73,7 @@
and computing_resource = #{computingResource.computingResource}
</if>
<if test="computingResource.standard != null and computingResource.standard != ''">
and standard = #{computingResource.standard}
and standard = #{computingResource.computingResource}
</if>
<if test="computingResource.description != null and computingResource.description != ''">
and description = #{computingResource.description}
@@ -96,17 +96,17 @@
</where>
</select>

<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into computing_resource(computing_resourcestandarddescriptioncreate_bycreate_timeupdate_byupdate_timestate)
values (#{computingResource}#{standard}#{description}#{createBy}#{createTime}#{updateBy}#{updateTime}#{state})
insert into computing_resource (computing_resource, standard, description, create_by, create_time, update_by, update_time, state)
values (#{computingResource.computingResource}, #{computingResource.standard}, #{computingResource.description}, #{computingResource.createBy}, #{computingResource.createTime}, #{computingResource.updateBy}, #{computingResource.updateTime}, #{computingResource.state})
</insert>


<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into computing_resource(computing_resourcestandarddescriptioncreate_bycreate_timeupdate_byupdate_timestate)
insert into computing_resource(computing_resource,standard,description,create_by,create_time,update_by,update_time,state)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.computingResource}#{entity.standard}#{entity.description}#{entity.createBy}#{entity.createTime}#{entity.updateBy}#{entity.updateTime}#{entity.state})
(#{entity.computingResource},#{entity.standard},#{entity.description},#{entity.createBy},#{entity.createTime},#{entity.updateBy},#{entity.updateTime},#{entity.state})
</foreach>
</insert>



+ 3
- 3
ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ImageDaoMapper.xml View File

@@ -19,7 +19,7 @@
select
id,name,description,image_type,create_by,create_time,update_by,update_time,state
from image
where id = #{id}
where id = #{id} and state = 1
</select>

<!--查询指定行数据-->
@@ -34,7 +34,7 @@
and img.id = #{image.id}
</if>
<if test="image.name != null and image.name != ''">
and img.name like "%"#{image.name}"%"
and img.name like concat('%', #{image.name}, '%')
</if>
<if test="image.description != null and image.description != ''">
and img.description = #{image.description}
@@ -86,7 +86,7 @@
and id = #{image.id}
</if>
<if test="image.name != null and image.name != ''">
and name like "%"#{image.name}"%"
and name like concat('%', #{image.name}, '%')
</if>
<if test="image.description != null and image.description != ''">
and description = #{image.description}


Loading…
Cancel
Save