Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
bkunyun
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
bkunyun
Commits
541232f3
Commit
541232f3
authored
Oct 26, 2022
by
wuyongsheng
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat-20221012-environment' into 'release'
Feat 20221012 environment See merge request
!152
parents
eeb2ca44
541e7a1e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
1707 additions
and
283 deletions
+1707
-283
api_manager.ts
src/api/api_manager.ts
+6
-1
resourceCenter.ts
src/api/resourceCenter.ts
+58
-2
expandOperationSvg.svg
src/assets/project/expandOperationSvg.svg
+19
-0
batchOperator.svg
src/assets/resourceCenter/batchOperator.svg
+61
-0
flowOperator.svg
src/assets/resourceCenter/flowOperator.svg
+81
-0
templateIcon.svg
src/assets/resourceCenter/templateIcon.svg
+22
-0
index.module.css
...ponents/BusinessComponents/ProductSelect/index.module.css
+0
-0
index.tsx
src/components/BusinessComponents/ProductSelect/index.tsx
+61
-0
index.module.css
src/components/CommonComponents/CardTable/index.module.css
+8
-0
index.tsx
src/components/CommonComponents/CardTable/index.tsx
+74
-4
index.tsx
src/components/CommonComponents/Code/index.tsx
+25
-4
useMyRouter.ts
src/components/MyRouter/useMyRouter.ts
+0
-4
MyBorderlessSelect.tsx
src/components/mui/MyBorderlessSelect.tsx
+27
-27
MyMenu.tsx
src/components/mui/MyMenu.tsx
+7
-2
MySelect.tsx
src/components/mui/MySelect.tsx
+5
-2
index.ts
src/router/index.ts
+3
-2
index.tsx
src/views/CustomOperator/components/OperatorList/index.tsx
+6
-10
index.tsx
src/views/CustomOperator/index.tsx
+16
-115
useCheckOperator.tsx
src/views/CustomOperator/useCheckOperator.tsx
+143
-0
index.tsx
...r/UserResources/UserResourcesEnvironment/SeeEnv/index.tsx
+5
-1
index.tsx
...ceCenter/UserResources/UserResourcesEnvironment/index.tsx
+10
-2
index.module.css
...ces/UserResourcesTemplate/TemplateDetail/index.module.css
+140
-0
index.tsx
...rResources/UserResourcesTemplate/TemplateDetail/index.tsx
+214
-0
index.module.css
...nter/UserResources/UserResourcesTemplate/index.module.css
+77
-0
index.tsx
...ourceCenter/UserResources/UserResourcesTemplate/index.tsx
+213
-0
index.module.css
.../WorkflowOperator/components/AddOperator/index.module.css
+14
-0
index.tsx
...sources/WorkflowOperator/components/AddOperator/index.tsx
+0
-0
utils.ts
...esources/WorkflowOperator/components/AddOperator/utils.ts
+109
-14
index.module.css
...WorkflowOperator/components/OperatorCard/index.module.css
+4
-2
index.tsx
...ources/WorkflowOperator/components/OperatorCard/index.tsx
+23
-5
index.module.css
...kflowOperator/components/OperatorDetails/index.module.css
+30
-1
index.tsx
...ces/WorkflowOperator/components/OperatorDetails/index.tsx
+75
-13
index.tsx
...s/ResourceCenter/UserResources/WorkflowOperator/index.tsx
+18
-4
interface.ts
...esourceCenter/UserResources/WorkflowOperator/interface.ts
+5
-2
index.tsx
src/views/ResourceCenter/UserResources/index.tsx
+5
-2
index.tsx
...views/ResourceCenter/components/SwitchBatchFolw/index.tsx
+48
-31
index.tsx
src/views/WorkFlowEdit/components/OperatorList/index.tsx
+6
-8
interface.ts
src/views/WorkFlowEdit/components/OperatorList/interface.ts
+2
-0
index.tsx
...iews/WorkFlowEdit/components/SaveCustomTemplate/index.tsx
+21
-23
index.tsx
src/views/WorkFlowEdit/index.tsx
+8
-1
index.tsx
src/views/demo/CardTableDemo/index.tsx
+58
-1
No files found.
src/api/api_manager.ts
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 09:56:57
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-2
0 14:56:21
* @LastEditTime: 2022-10-2
5 18:23:37
* @FilePath: /bkunyun/src/api/api_manager.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -56,6 +56,11 @@ const RESTAPI = {
API_ACTORENV_DELETE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/delete`
,
// 删除用户算子环境
API_ACTORENV_DETAIL
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/detail`
,
// 查询应用环境的详情信息
API_ACTOR_ENV_OPTIONS
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/usableenv`
,
// 查询用户应用环境下拉
API_SAVE_OPERATOR
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/custom/actor`
,
// 保存自定义批流算子
API_WORKFLOWSPEC_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/product/workflowspec/list`
,
// 模板列表 所有的
API_WORKFLOWSPEC_DELETE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/workflowspec/delete`
,
// 删除模板
API_WORKFLOWSPEC_DETAIL
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/workflowspec`
,
// 删除模板
API_OPERATOR_DETAILS
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/actorspec/detail`
,
// 获取算子详情
};
export
default
RESTAPI
;
src/api/resourceCenter.ts
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-19 17:09:23
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-2
0 15:01:36
* @LastEditTime: 2022-10-2
5 20:26:42
* @FilePath: /bkunyun/src/api/resourceCenter.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -59,6 +59,7 @@ const getActorenvList = (params: {
page
:
number
,
size
:
number
,
title
?:
string
,
order
?:
string
,
})
=>
{
return
request
({
url
:
Api
.
API_ACTORENV_LIST
,
...
...
@@ -102,6 +103,56 @@ const getActorEnvOptions = (params: {type: string}) => {
});
};
// 获取工作流模板
const
getWorkflowspecList
=
(
params
:
{
productId
?:
string
,
title
?:
string
})
=>
{
return
request
({
// url:`${Api.API_WORKFLOWSPEC_LIST}/${params.productId}`,
url
:
`
${
Api
.
API_WORKFLOWSPEC_LIST
}
`
,
method
:
"get"
,
params
});
};
// API_WORKFLOWSPEC_LIST
// 新增应用环境
const
saveOperator
=
(
params
:
any
,
isEdit
:
boolean
)
=>
{
return
request
({
url
:
`
${
Api
.
API_SAVE_OPERATOR
}
?isEdit=
${
isEdit
}
`
,
method
:
"post"
,
data
:
params
,
});
};
// 删除工作流模板
const
deleteWorkflowspec
=
(
params
:
{
id
:
string
})
=>
{
return
request
({
url
:
`
${
Api
.
API_WORKFLOWSPEC_DELETE
}
`
,
method
:
"delete"
,
params
});
};
// 查询算子的详情信息
const
getOperatorDetail
=
(
id
:
string
)
=>
{
return
request
({
url
:
`
${
Api
.
API_OPERATOR_DETAILS
}
/
${
id
}
`
,
method
:
"get"
,
});
};
// 获取工作流模板详情
const
getWorkflowspecDetail
=
(
id
:
string
)
=>
{
return
request
({
url
:
Api
.
API_WORKFLOWSPEC_DETAIL
+
'/'
+
id
,
method
:
"get"
,
});
};
export
{
getPublicEnv
,
getPublicProject
,
...
...
@@ -110,5 +161,10 @@ export {
deleteActorenv
,
getOperatorList
,
getActorenvDetail
,
getActorEnvOptions
getActorEnvOptions
,
getWorkflowspecList
,
saveOperator
,
deleteWorkflowspec
,
getWorkflowspecDetail
,
getOperatorDetail
};
src/assets/project/expandOperationSvg.svg
0 → 100644
View file @
541232f3
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"16px"
height=
"16px"
viewBox=
"0 0 16 16"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 89备份
</title>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"个人资源-工作流算子"
transform=
"translate(-982.000000, -323.000000)"
>
<g
id=
"编组-6备份"
transform=
"translate(641.000000, 298.000000)"
>
<g
id=
"编组-89备份"
transform=
"translate(349.000000, 33.000000) rotate(-270.000000) translate(-349.000000, -33.000000) translate(341.000000, 25.000000)"
>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
<g
id=
"编组-88"
transform=
"translate(2.250000, 6.750000)"
fill=
"#8A9099"
>
<circle
id=
"椭圆形"
cx=
"1.25"
cy=
"1.25"
r=
"1.25"
></circle>
<circle
id=
"椭圆形备份-15"
cx=
"5.75"
cy=
"1.25"
r=
"1.25"
></circle>
<circle
id=
"椭圆形备份-16"
cx=
"10.25"
cy=
"1.25"
r=
"1.25"
></circle>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/resourceCenter/batchOperator.svg
0 → 100644
View file @
541232f3
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"240px"
height=
"249px"
viewBox=
"0 0 240 249"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
矩形备份 26
</title>
<defs>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"240"
height=
"249"
rx=
"8"
></rect>
<filter
x=
"-14.5%"
y=
"-17.6%"
width=
"129.1%"
height=
"135.2%"
filterUnits=
"objectBoundingBox"
id=
"filter-3"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"3"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.803607664 0 0 0 0 0.598314046 0 0 0 0 0.12907149 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
result=
"shadowMatrixOuter1"
></feColorMatrix>
<feMerge>
<feMergeNode
in=
"shadowMatrixOuter1"
></feMergeNode>
<feMergeNode
in=
"SourceGraphic"
></feMergeNode>
</feMerge>
</filter>
<rect
id=
"path-4"
x=
"0"
y=
"0"
width=
"110"
height=
"91"
rx=
"5.5"
></rect>
</defs>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"矩形备份-26"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<use
id=
"蒙版"
fill=
"#FFFFFF"
xlink:href=
"#path-1"
></use>
<rect
id=
"矩形备份-6"
fill=
"#FFB919"
mask=
"url(#mask-2)"
x=
"0"
y=
"0"
width=
"240"
height=
"165"
></rect>
<g
id=
"编组-8备份-3"
mask=
"url(#mask-2)"
>
<g
transform=
"translate(65.000000, 37.000000)"
id=
"编组-19"
>
<g
id=
"矩形"
filter=
"url(#filter-3)"
>
<mask
id=
"mask-5"
fill=
"white"
>
<use
xlink:href=
"#path-4"
></use>
</mask>
<use
id=
"蒙版"
fill=
"#FFFFFF"
xlink:href=
"#path-4"
></use>
<rect
fill=
"#136EFA"
mask=
"url(#mask-5)"
x=
"0"
y=
"0"
width=
"2.5"
height=
"91.4251263"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-5)"
x=
"15"
y=
"8.76679293"
width=
"25"
height=
"5.00959596"
></rect>
</g>
<g
id=
"编组-7"
transform=
"translate(15.250000, 26.070581)"
>
<path
d=
"M11.25,5.51515152 L7.125,5.51515152 C5.60621694,5.51515152 4.375,6.74636845 4.375,8.26515152 L4.375,46.8863636 C4.375,48.4051467 5.60621694,49.6363636 7.125,49.6363636 L11.25,49.6363636 L11.25,49.6363636"
id=
"路径-4"
stroke=
"#979797"
stroke-width=
"1.375"
></path>
<rect
id=
"矩形备份-10"
fill=
"#F0F2F5"
x=
"0"
y=
"0"
width=
"45"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-11"
fill=
"#F0F2F5"
x=
"0"
y=
"22.0606061"
width=
"24.75"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-15"
fill=
"#F0F2F5"
x=
"39.875"
y=
"33.332197"
width=
"24.75"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-12"
fill=
"#F0F2F5"
x=
"0"
y=
"44.1212121"
width=
"24.75"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-4"
fill=
"#C2C6CC"
x=
"2.25"
y=
"3.20453283"
width=
"32.5"
height=
"3.75719697"
></rect>
<rect
id=
"矩形备份-5"
fill=
"#C2C6CC"
x=
"2.25"
y=
"25.7477146"
width=
"13.75"
height=
"3.75719697"
></rect>
<rect
id=
"矩形备份-8"
fill=
"#C2C6CC"
x=
"2.25"
y=
"48.2908965"
width=
"13.75"
height=
"3.75719697"
></rect>
<rect
id=
"矩形备份-9"
fill=
"#C2C6CC"
x=
"42.25"
y=
"37.0193056"
width=
"13.75"
height=
"3.75719697"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
cx=
"39"
cy=
"5.00959596"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<ellipse
id=
"椭圆形备份-4"
fill=
"#0DD09B"
cx=
"20.25"
cy=
"27.5527778"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<ellipse
id=
"椭圆形备份-5"
fill=
"#0DD09B"
cx=
"20.25"
cy=
"50.0959596"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<ellipse
id=
"椭圆形备份-6"
fill=
"#0DD09B"
cx=
"60.25"
cy=
"38.8243687"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<line
x1=
"4.125"
y1=
"38.7726641"
x2=
"39.875"
y2=
"38.8473485"
id=
"路径-6"
stroke=
"#979797"
stroke-width=
"1.375"
></line>
</g>
</g>
</g>
<text
id=
"构建批式算子"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Medium, PingFang SC"
font-size=
"16"
font-weight=
"400"
line-spacing=
"24"
fill=
"#1E2633"
>
<tspan
x=
"72"
y=
"198.000567"
>
构建批式算子
</tspan>
</text>
<text
id=
"仅支持shell脚本"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Regular, PingFang SC"
font-size=
"12"
font-weight=
"normal"
line-spacing=
"20"
fill=
"#8A9099"
>
<tspan
x=
"77.484"
y=
"222"
>
仅支持shell脚本
</tspan>
</text>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/resourceCenter/flowOperator.svg
0 → 100644
View file @
541232f3
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"240px"
height=
"249px"
viewBox=
"0 0 240 249"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 40备份 8
</title>
<defs>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"240"
height=
"249"
rx=
"8"
></rect>
<rect
id=
"path-3"
x=
"0"
y=
"0"
width=
"96.2033898"
height=
"23.9201798"
rx=
"4.80638562"
></rect>
<filter
x=
"-8.8%"
y=
"-27.2%"
width=
"117.7%"
height=
"171.1%"
filterUnits=
"objectBoundingBox"
id=
"filter-5"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"2.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.114151225 0 0 0 0 0.59037626 0 0 0 0 0.477660275 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
></feColorMatrix>
</filter>
<rect
id=
"path-6"
x=
"0"
y=
"0"
width=
"96.2033898"
height=
"23.9201798"
rx=
"4.80638562"
></rect>
<filter
x=
"-8.8%"
y=
"-27.2%"
width=
"117.7%"
height=
"171.1%"
filterUnits=
"objectBoundingBox"
id=
"filter-8"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"2.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.114151225 0 0 0 0 0.59037626 0 0 0 0 0.477660275 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
></feColorMatrix>
</filter>
<rect
id=
"path-9"
x=
"0"
y=
"0"
width=
"96.2033898"
height=
"23.9201798"
rx=
"4.80638562"
></rect>
<filter
x=
"-8.8%"
y=
"-27.2%"
width=
"117.7%"
height=
"171.1%"
filterUnits=
"objectBoundingBox"
id=
"filter-11"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"2.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.114151225 0 0 0 0 0.59037626 0 0 0 0 0.477660275 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
></feColorMatrix>
</filter>
</defs>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"编组-40备份-8"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<use
id=
"蒙版"
fill=
"#FFFFFF"
xlink:href=
"#path-1"
></use>
<rect
id=
"矩形"
fill=
"#02AB83"
mask=
"url(#mask-2)"
x=
"0"
y=
"0"
width=
"240"
height=
"165"
></rect>
<g
id=
"编组-2"
mask=
"url(#mask-2)"
>
<g
transform=
"translate(56.000000, 40.000000)"
>
<g
id=
"矩形"
>
<mask
id=
"mask-4"
fill=
"white"
>
<use
xlink:href=
"#path-3"
></use>
</mask>
<g
id=
"蒙版"
>
<use
fill=
"black"
fill-opacity=
"1"
filter=
"url(#filter-5)"
xlink:href=
"#path-3"
></use>
<use
fill=
"#FFFFFF"
fill-rule=
"evenodd"
xlink:href=
"#path-3"
></use>
</g>
<rect
fill=
"#136EFA"
mask=
"url(#mask-4)"
x=
"0"
y=
"0"
width=
"2.18644068"
height=
"24.0319281"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-4)"
x=
"13.1186441"
y=
"7.64652257"
width=
"50.2881356"
height=
"8.73888294"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
mask=
"url(#mask-4)"
cx=
"77.6186441"
cy=
"12.015964"
rx=
"3.27966102"
ry=
"3.2770811"
></ellipse>
</g>
<g
id=
"矩形"
transform=
"translate(32.796610, 30.586090)"
>
<mask
id=
"mask-7"
fill=
"white"
>
<use
xlink:href=
"#path-6"
></use>
</mask>
<g
id=
"蒙版"
>
<use
fill=
"black"
fill-opacity=
"1"
filter=
"url(#filter-8)"
xlink:href=
"#path-6"
></use>
<use
fill=
"#FFFFFF"
fill-rule=
"evenodd"
xlink:href=
"#path-6"
></use>
</g>
<rect
fill=
"#136EFA"
mask=
"url(#mask-7)"
x=
"0"
y=
"0"
width=
"2.18644068"
height=
"24.0319281"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-7)"
x=
"13.1186441"
y=
"7.64652257"
width=
"50.2881356"
height=
"8.73888294"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
mask=
"url(#mask-7)"
cx=
"77.6186441"
cy=
"12.015964"
rx=
"3.27966102"
ry=
"3.2770811"
></ellipse>
</g>
<g
id=
"矩形"
transform=
"translate(4.372881, 60.079820)"
>
<mask
id=
"mask-10"
fill=
"white"
>
<use
xlink:href=
"#path-9"
></use>
</mask>
<g
id=
"蒙版"
>
<use
fill=
"black"
fill-opacity=
"1"
filter=
"url(#filter-11)"
xlink:href=
"#path-9"
></use>
<use
fill=
"#FFFFFF"
fill-rule=
"evenodd"
xlink:href=
"#path-9"
></use>
</g>
<rect
fill=
"#136EFA"
mask=
"url(#mask-10)"
x=
"0"
y=
"0"
width=
"2.18644068"
height=
"24.0319281"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-10)"
x=
"13.1186441"
y=
"7.64652257"
width=
"50.2881356"
height=
"8.73888294"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
mask=
"url(#mask-10)"
cx=
"77.6186441"
cy=
"12.015964"
rx=
"3.27966102"
ry=
"3.2770811"
></ellipse>
</g>
</g>
</g>
<text
id=
"构建流式算子"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Medium, PingFang SC"
font-size=
"16"
font-weight=
"400"
line-spacing=
"24"
fill=
"#1E2633"
>
<tspan
x=
"72"
y=
"198"
>
构建流式算子
</tspan>
</text>
<text
id=
"仅支持Python脚本"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Regular, PingFang SC"
font-size=
"12"
font-weight=
"normal"
line-spacing=
"20"
fill=
"#8A9099"
>
<tspan
x=
"70.836"
y=
"222"
>
仅支持Python脚本
</tspan>
</text>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/resourceCenter/templateIcon.svg
0 → 100644
View file @
541232f3
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 84
</title>
<g
id=
"上线UI"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"个人资源-工作流模版"
transform=
"translate(-661.000000, -574.000000)"
>
<g
id=
"编组-4"
transform=
"translate(641.000000, 526.000000)"
>
<g
id=
"编组-84"
transform=
"translate(20.000000, 48.000000)"
>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"24"
height=
"24"
></rect>
<g
id=
"编组-83"
transform=
"translate(3.500000, 2.000000)"
>
<polyline
id=
"路径"
stroke=
"#1370FF"
stroke-width=
"1.5"
stroke-linecap=
"round"
stroke-linejoin=
"round"
points=
"17 8.19811748 17 4.99985 8.5 0 0 4.99985 0 14.9999 2.37372196 16.396235"
></polyline>
<circle
id=
"椭圆形"
fill=
"#1370FF"
cx=
"3"
cy=
"17"
r=
"2"
></circle>
<circle
id=
"椭圆形备份-13"
fill=
"#1370FF"
cx=
"17"
cy=
"12"
r=
"2"
></circle>
<polyline
id=
"路径-72"
stroke=
"#1370FF"
stroke-width=
"1.5"
points=
"0.283430346 5.19688053 8.5 9.92482816 8.5 19.6575672"
></polyline>
<line
x1=
"8.5"
y1=
"9.92482816"
x2=
"17"
y2=
"4.99985"
id=
"路径-73"
stroke=
"#1370FF"
stroke-width=
"1.5"
></line>
<polyline
id=
"路径"
stroke=
"#1370FF"
stroke-width=
"1.5"
stroke-linecap=
"round"
stroke-linejoin=
"round"
points=
"6.25871064 18.7359651 8.5 20 17 14.9999 17 12.5168189"
></polyline>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
src/components/BusinessComponents/ProductSelect/index.module.css
0 → 100644
View file @
541232f3
src/components/BusinessComponents/ProductSelect/index.tsx
0 → 100644
View file @
541232f3
import
MySelect
from
"@/components/mui/MySelect"
;
import
MyDialog
from
"@/components/mui/MyDialog"
;
import
{
toJS
}
from
"mobx"
;
import
{
useStores
}
from
"@/store"
;
import
{
useEffect
}
from
"react"
;
interface
IProductSelectProps
{
open
:
boolean
;
setOpen
:
any
;
productId
:
string
;
setProductId
:
any
;
okText
?:
string
;
onConfirm
?:
any
;
}
const
ProductSelect
=
(
props
:
IProductSelectProps
)
=>
{
const
{
open
,
productId
,
setProductId
,
okText
=
"下一步"
,
setOpen
,
onConfirm
,
}
=
props
;
const
{
productListStore
}
=
useStores
();
useEffect
(()
=>
{
if
(
!
productId
)
{
setProductId
(
toJS
(
productListStore
.
productList
)[
0
].
value
);
}
},
[
productId
,
productListStore
.
productList
,
setProductId
]);
const
handleChange
=
(
e
:
any
)
=>
{
console
.
log
(
e
);
setProductId
(
e
);
};
const
handleConfirm
=
()
=>
{
setOpen
(
false
);
onConfirm
&&
onConfirm
();
};
return
(
<
MyDialog
open=
{
open
}
title=
"选择产品"
okText=
{
okText
}
onClose=
{
()
=>
setOpen
(
false
)
}
onConfirm=
{
()
=>
handleConfirm
()
}
>
<
MySelect
value=
{
productId
}
onChange=
{
(
e
)
=>
handleChange
(
e
)
}
options=
{
[...
productListStore
?.
productList
]
||
[]
}
fullWidth
></
MySelect
>
</
MyDialog
>
);
};
export
default
ProductSelect
;
src/components/CommonComponents/CardTable/index.module.css
View file @
541232f3
.tableBox
{
display
:
flex
;
justify-content
:
flex-start
;
flex-wrap
:
wrap
;
}
.itemBox
{
/* flex: 1; */
}
src/components/CommonComponents/CardTable/index.tsx
View file @
541232f3
import
{
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
style
from
"./index.module.css"
;
interface
ICardTableProps
{
data
:
Array
<
any
>
;
renderItem
:
any
;
data
:
Array
<
any
>
;
// 列表数据
renderItem
:
any
;
// 单个卡片的渲染函数
itemMinWidth
?:
number
;
// 单个卡片的最小宽度,有这个参数时numberOfColumns参数失效,效果为根据屏幕大小和单个卡片的最小宽度来适配每行渲染个数
tableKey
?:
string
;
// 表格数据的key
numberOfColumns
?:
number
;
// 列数 每行渲染几个
horizontalSpacing
?:
number
;
// 水平方向的间隔
verticalSpacing
?:
number
;
// 垂直方向的间隔
}
const
CardTable
=
(
props
:
ICardTableProps
)
=>
{
const
{
data
,
renderItem
}
=
props
;
return
<
div
>
CardTable
</
div
>;
const
{
data
,
renderItem
,
tableKey
=
"id"
,
numberOfColumns
:
propsNumberOfColumns
=
3
,
horizontalSpacing
=
20
,
verticalSpacing
=
20
,
itemMinWidth
,
}
=
props
;
const
[
numberOfColumns
,
setNumberOfColumns
]
=
useState
(
3
);
const
tableBoxRef
:
any
=
useRef
(
null
);
const
getNumberOfColumns
=
useCallback
(()
=>
{
if
(
itemMinWidth
)
{
const
boxWidth
=
tableBoxRef
?.
current
?.
offsetWidth
;
if
(
boxWidth
)
{
setNumberOfColumns
(
Math
.
floor
(
boxWidth
/
itemMinWidth
));
}
else
{
setNumberOfColumns
(
propsNumberOfColumns
);
}
}
else
{
setNumberOfColumns
(
propsNumberOfColumns
);
}
},
[
itemMinWidth
,
propsNumberOfColumns
]);
useEffect
(()
=>
{
getNumberOfColumns
();
},
[
getNumberOfColumns
]);
const
boxWidth
=
useMemo
(()
=>
{
return
`
${
100
/
numberOfColumns
}
%`
;
},
[
numberOfColumns
]);
window
.
onresize
=
()
=>
{
getNumberOfColumns
();
};
return
(
<
div
className=
{
style
.
tableBox
}
style=
{
{
marginLeft
:
`-${horizontalSpacing / 2}px`
,
marginRight
:
`-${horizontalSpacing / 2}px`
,
}
}
ref=
{
tableBoxRef
}
>
{
data
.
map
((
item
,
index
)
=>
{
return
(
<
div
className=
{
style
.
itemBox
}
key=
{
item
[
tableKey
]
?
item
[
tableKey
]
:
index
}
style=
{
{
width
:
boxWidth
,
paddingLeft
:
`${horizontalSpacing / 2}px`
,
paddingRight
:
`${horizontalSpacing / 2}px`
,
paddingBottom
:
`${verticalSpacing}px`
,
boxSizing
:
"border-box"
,
}
}
>
{
renderItem
(
item
,
index
)
}
</
div
>
);
})
}
</
div
>
);
};
export
default
CardTable
;
src/components/CommonComponents/Code/index.tsx
View file @
541232f3
import
CodeMirror
from
"@uiw/react-codemirror"
;
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-20 19:45:32
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-25 21:16:13
* @FilePath: /bkunyun/src/components/CommonComponents/Code/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
CodeMirror
,
{
ReactCodeMirrorProps
}
from
"@uiw/react-codemirror"
;
import
{
memo
}
from
"react"
;
import
{
isEqual
}
from
"lodash"
;
// import { javascript } from "@codemirror/lang-javascript";
type
ICodeType
=
{
value
:
string
;
interface
ICodeType
extends
ReactCodeMirrorProps
{
value
?
:
string
;
onChange
:
any
;
height
?:
string
;
width
?:
string
;
maxWidth
?:
string
;
theme
?:
"light"
|
"dark"
;
}
;
}
const
Code
=
(
props
:
ICodeType
)
=>
{
console
.
log
(
"----"
);
const
{
value
,
onChange
,
height
,
theme
=
"dark"
,
width
,
maxWidth
}
=
props
;
return
(
<
CodeMirror
{
...
props
}
height=
{
height
||
"100%"
}
width=
{
width
||
"100%"
}
maxWidth=
{
maxWidth
||
"100%"
}
...
...
@@ -22,4 +35,12 @@ const Code = (props: ICodeType) => {
/>
);
};
// const handleEqual = (prvProps: ICodeType, nextProps: ICodeType) => {
// if (isEqual(prvProps, nextProps)) {
// return true;
// }
// return true;
// };
export
default
Code
;
src/components/MyRouter/useMyRouter.ts
View file @
541232f3
...
...
@@ -51,9 +51,6 @@ const useMyRouter = () => {
route
.
path
=
`
${
routeHead
}
/
${
item
.
id
}${
route
.
path
}
`
if
(
Array
.
isArray
(
route
.
children
))
{
route
.
children
.
forEach
((
childrenItem
:
any
,
index
:
number
)
=>
{
console
.
log
(
route
)
console
.
log
(
childrenItem
)
console
.
log
(
routeHead
)
if
(
childrenItem
.
path
)
{
childrenRoutes
.
push
({
...
childrenItem
,
...
...
@@ -63,7 +60,6 @@ const useMyRouter = () => {
})
}
})
// http://localhost:8088/v3/product/resourceCenter/userResources/seeEnv
route
.
children
=
route
.
children
.
filter
((
childrenItem
:
any
)
=>
!
childrenItem
.
path
)
}
}
...
...
src/components/mui/MyBorderlessSelect.tsx
View file @
541232f3
...
...
@@ -76,14 +76,14 @@ export default function MyBorderlessSelect(props: IProps) {
background
:
"rgba(247, 248, 250, 1)"
,
cursor
:
"not-allowed"
,
"& .MuiOutlinedInput-notchedOutline"
:
{
borderWidth
:
'0px'
borderWidth
:
"0px"
,
},
},
},
input
:
{
fontSize
:
"14px"
,
"&.Mui-focused"
:{
color
:
"#1370FF"
,
"&.Mui-focused"
:
{
color
:
"#1370FF"
,
},
"&.Mui-disabled"
:
{
background
:
"rgba(247, 248, 250, 1)"
,
...
...
@@ -127,7 +127,7 @@ export default function MyBorderlessSelect(props: IProps) {
root
:
{
"&.Mui-focused .MuiOutlinedInput-notchedOutline"
:
{
borderWidth
:
"0px"
,
color
:
'#1370FF'
color
:
"#1370FF"
,
},
"& .MuiOutlinedInput-notchedOutline"
:
{
borderColor
:
"#DDE1E6"
,
...
...
@@ -213,29 +213,29 @@ export default function MyBorderlessSelect(props: IProps) {
>
{
options
.
length
?
options
?.
map
((
item
:
IOption
,
index
)
=>
{
return
(
<
MenuItem
value=
{
item
.
value
}
disabled=
{
item
?.
disabled
}
key=
{
index
}
>
{
item
.
label
}
{
value
===
item
.
value
&&
(
<
img
style=
{
{
width
:
"16px"
,
height
:
"16px"
,
position
:
"absolute"
,
top
:
"10px"
,
right
:
"12px"
,
}
}
src=
{
selectActive
}
alt=
""
/>
)
}
</
MenuItem
>
);
})
return
(
<
MenuItem
value=
{
item
.
value
}
disabled=
{
item
?.
disabled
}
key=
{
index
}
>
{
item
.
label
}
{
value
===
item
.
value
&&
(
<
img
style=
{
{
width
:
"16px"
,
height
:
"16px"
,
position
:
"absolute"
,
top
:
"10px"
,
right
:
"12px"
,
}
}
src=
{
selectActive
}
alt=
""
/>
)
}
</
MenuItem
>
);
})
:
null
}
</
Select
>
{
helpertext
&&
error
&&
<
FormHelperText
>
{
helpertext
}
</
FormHelperText
>
}
...
...
src/components/mui/MyMenu.tsx
View file @
541232f3
...
...
@@ -77,14 +77,19 @@ const MyMenu = (props: IMyMenuProps) => {
const
open
=
Boolean
(
anchorEl
);
const
handleClick
=
(
event
:
React
.
MouseEvent
<
HTMLDivElement
>
)
=>
{
setAnchorEl
(
event
.
currentTarget
);
event
.
stopPropagation
();
};
const
handleClose
=
(
value
:
string
)
=>
{
setAnchorEl
(
null
);
};
const
handleMenuClick
=
(
value
:
string
)
=>
{
const
handleMenuClick
=
(
value
:
string
,
event
:
React
.
MouseEvent
<
HTMLLIElement
,
MouseEvent
>
)
=>
{
setValue
&&
setValue
(
value
);
setAnchorEl
(
null
);
event
.
stopPropagation
();
};
return
(
...
...
@@ -124,7 +129,7 @@ const MyMenu = (props: IMyMenuProps) => {
{
options
.
map
((
option
,
index
)
=>
{
return
(
<
MenuItem
onClick=
{
(
)
=>
handleMenuClick
(
option
.
valu
e
)
}
onClick=
{
(
e
)
=>
handleMenuClick
(
option
.
value
,
e
)
}
selected=
{
value
===
option
.
value
}
key=
{
index
}
>
...
...
src/components/mui/MySelect.tsx
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2021-12-04 15:46:25
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 18:41:0
4
* @LastEditTime: 2022-10-
24 17:39:2
4
* @FilePath: /lionet-slb-pc/src/components/SearchView/components/Collapse.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -49,6 +49,8 @@ interface IProps
isTitle
?:
boolean
;
/** 是否显示提示文案 */
error
?:
boolean
;
/** 默认值 */
defaultValue
?:
string
;
/** 提示文案 */
helpertext
?:
string
;
}
...
...
@@ -64,6 +66,7 @@ export default function MySelect(props: IProps) {
fullWidth
,
error
=
false
,
helpertext
,
defaultValue
,
...
other
}
=
props
;
...
...
@@ -193,7 +196,7 @@ export default function MySelect(props: IProps) {
},
});
const
[
insideValue
,
setInsideValue
]
=
useState
<
string
>
(
""
);
const
[
insideValue
,
setInsideValue
]
=
useState
<
string
>
(
defaultValue
||
""
);
const
handleChange
=
(
e
:
SelectChangeEvent
<
unknown
>
)
=>
{
setInsideValue
(
e
.
target
.
value
as
string
);
...
...
src/router/index.ts
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
18 10:54:54
* @LastEditTime: 2022-10-
25 21:27:26
* @FilePath: /bkunyun/src/router/index.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
import { AnyMap } from "immer/dist/internal";
...
...
@@ -14,6 +14,7 @@ import * as React from "react";
import
NotFound
from
"@/views/404"
;
import
Demo
from
"@/views/demo"
;
import
SeeEnv
from
"@/views/ResourceCenter/UserResources/UserResourcesEnvironment/SeeEnv"
;
import
OperatorDetails
from
"@/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorDetails"
;
import
ProjectSetting
from
"@/views/Project/ProjectSetting"
;
import
ProjectData
from
"@/views/Project/ProjectData"
;
import
ProjectWorkbench
from
"@/views/Project/ProjectWorkbench"
;
...
...
@@ -53,9 +54,9 @@ export const elements: {
})
=>
JSX
.
Element
|
any
;
}
=
{
Demo
:
Demo
,
SeeTemplate
:
Demo
,
UserResources
:
UserResources
,
SeeEnv
:
SeeEnv
,
SeeFloe
:
OperatorDetails
,
ProjectSetting
:
ProjectSetting
,
ProjectData
:
ProjectData
,
ProjectWorkbench
:
ProjectWorkbench
,
...
...
src/views/CustomOperator/components/OperatorList/index.tsx
View file @
541232f3
...
...
@@ -7,22 +7,18 @@ import { useState, useCallback, useEffect, useMemo } from "react";
import
{
getOperatorList
}
from
"@/api/project_api"
;
import
CircularProgress
from
"@mui/material/CircularProgress"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
useStores
}
from
"@/store"
;
import
{
toJS
}
from
"mobx"
;
import
{
ITask
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
import
{
observer
}
from
"mobx-react-lite"
;
type
IProps
=
{
operatorList
:
ITask
[];
setOperatorList
:
any
;
setInputActive
:
any
;
productId
:
string
;
};
const
OperatorList
=
observer
((
props
:
IProps
)
=>
{
const
{
operatorList
,
setOperatorList
,
setInputActive
}
=
props
;
// 流程图中流算子列表
const
{
currentProjectStore
}
=
useStores
();
const
OperatorList
=
(
props
:
IProps
)
=>
{
const
{
operatorList
,
setOperatorList
,
setInputActive
,
productId
}
=
props
;
// 流程图中流算子列表
const
[
list
,
setList
]
=
useState
<
ITask
[]
>
([]);
// 算子列表
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
// 产品ID
const
[
keyword
,
setKeyword
]
=
useState
(
""
);
// 搜索算子列表时的关键词
const
[
dragItem
,
setDragItem
]
=
useState
<
any
>
({});
// 拖拽的算子
const
[
page
,
setPage
]
=
useState
(
0
);
// 算子列表页码
...
...
@@ -34,11 +30,11 @@ const OperatorList = observer((props: IProps) => {
return
1
;
}
else
{
const
countArr
=
operatorList
.
map
((
operatorLi
)
=>
{
const
_index
=
operatorLi
.
id
.
indexOf
(
"_"
);
const
_index
=
operatorLi
.
id
?
.
indexOf
(
"_"
);
if
(
_index
===
-
1
)
{
return
1
;
}
else
{
return
Number
(
operatorLi
.
id
.
slice
(
_index
+
1
));
return
Number
(
operatorLi
.
id
?
.
slice
(
_index
+
1
));
}
});
const
maxCount
=
Math
.
max
(...
countArr
);
...
...
@@ -250,6 +246,6 @@ const OperatorList = observer((props: IProps) => {
</
div
>
</
div
>
);
}
)
;
};
export
default
OperatorList
;
src/views/CustomOperator/index.tsx
View file @
541232f3
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-24 17:32:00
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-24 19:42:23
* @FilePath: /bkunyun/src/views/CustomOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
React
,
{
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
FullScreenDrawer
from
"@/components/CommonComponents/FullScreenDrawer"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
OperatorList
from
"./components/OperatorList"
;
// import Flow from "../Project/components/Flow";
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
BatchOperatorFlow
from
"../Project/components/Flow/components/BatchOperatorFlow"
;
import
SaveOperator
from
"./components/SaveOperator"
;
import
{
ITask
}
from
"../Project/ProjectSubmitWork/interface"
;
import
_
from
"lodash"
;
import
styles
from
"./index.module.css"
;
import
useCheckOperator
from
"./useCheckOperator"
;
type
IProps
=
{
setShowCustomOperator
:
any
;
initOperatorList
:
ITask
[];
productId
:
string
;
};
const
CustomOperator
=
observer
((
props
:
IProps
)
=>
{
const
{
setShowCustomOperator
,
initOperatorList
}
=
props
;
const
Message
=
useMessage
();
const
{
setShowCustomOperator
,
initOperatorList
,
productId
}
=
props
;
const
[
operatorList
,
setOperatorList
]
=
useState
<
ITask
[]
>
(
initOperatorList
);
const
[
saveFormDialog
,
setSaveFormDialog
]
=
useState
(
false
);
const
[
inputActive
,
setInputActive
]
=
useState
(
false
);
// const [showCustomOperator, setShowCustomOperator] = useState(false);
const
{
handleCheck
}
=
useCheckOperator
(
operatorList
,
()
=>
setSaveFormDialog
(
true
)
);
/** 设置选中唯一标识符 */
const
handleNodeClick
=
useCallback
((
val
:
string
)
=>
{
// setSelectTaskId(val);
},
[]);
// 判断 每个流算子必须至少有一条连接线。
const
checkHasOneLine
=
(
sourceArr
:
string
[],
targetArr
:
string
[])
=>
{
const
all
=
_
.
uniq
([...
sourceArr
,
...
targetArr
]);
if
(
all
.
length
===
operatorList
.
length
)
{
return
true
;
}
else
{
return
false
;
}
// _.uniq([2, 1, 2]);
};
// 判断 每个起始算子(可以有多个起始点)的输入必须为文件的路径输入或数据集的路径输入。
const
checkIn
=
(
targetArr
:
string
[])
=>
{
const
uniqTargetArr
=
_
.
uniq
(
targetArr
);
if
(
uniqTargetArr
.
length
===
operatorList
.
length
)
{
// 流节点连成一个圈了
return
false
;
}
let
check
=
true
;
operatorList
.
forEach
((
flowNode
)
=>
{
if
(
uniqTargetArr
.
indexOf
(
flowNode
.
id
)
===
-
1
)
{
// 该节点的输入没有连线 也就是说这个节点是起点
const
inArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"in"
);
if
(
inArr
.
length
>
0
)
{
if
(
!
inArr
.
some
((
inItem
)
=>
{
return
(
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"dataset"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"file"
);
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
// 判断 起码有一个结尾算子(可以有多个结尾点)的输出必须为文件保存或数据集保存。
const
checkOut
=
(
sourceArr
:
string
[])
=>
{
const
uniqSourceArr
=
_
.
uniq
(
sourceArr
);
if
(
uniqSourceArr
.
length
===
operatorList
.
length
)
{
// 流节点连成一个圈了
return
false
;
}
let
check
=
true
;
operatorList
.
forEach
((
flowNode
)
=>
{
if
(
uniqSourceArr
.
indexOf
(
flowNode
.
id
)
===
-
1
)
{
// 该节点的输入没有连线 也就是说这个节点是起点
const
outArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"out"
);
if
(
outArr
.
length
>
0
)
{
if
(
!
outArr
.
some
((
outItem
)
=>
{
return
(
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"dataset"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"file"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"input"
);
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
useEffect
(()
=>
{
sessionStorage
.
setItem
(
"operatorList"
,
JSON
.
stringify
(
operatorList
));
},
[
operatorList
]);
const
handleCheck
=
()
=>
{
if
(
operatorList
.
length
===
0
)
{
Message
.
error
(
"内容不能为空!"
);
return
;
}
let
sourceArr
:
string
[]
=
[];
let
targetArr
:
string
[]
=
[];
operatorList
.
forEach
((
flowNode
)
=>
{
flowNode
.
edges
.
forEach
((
edge
)
=>
{
edge
.
source
&&
sourceArr
.
push
(
edge
.
source
);
edge
.
target
&&
targetArr
.
push
(
edge
.
target
);
});
});
if
(
!
checkHasOneLine
([...
sourceArr
],
[...
targetArr
]))
{
Message
.
error
(
"部分算子没有流程线,请检查流程!"
);
return
;
}
if
(
!
checkIn
([...
targetArr
]))
{
Message
.
error
(
"每个流程第一步需读取文件/数据集,请检查流程!"
);
return
;
}
if
(
!
checkOut
([...
sourceArr
]))
{
Message
.
error
(
"每个流程最后一步必须将数据写入为文件/数据集,请检查流程!"
);
return
;
}
setSaveFormDialog
(
true
);
};
return
(
<
FullScreenDrawer
handleClose=
{
setShowCustomOperator
}
zIndex=
{
1100
}
>
<
div
className=
{
styles
.
customOperator
}
>
...
...
@@ -168,6 +68,7 @@ const CustomOperator = observer((props: IProps) => {
operatorList=
{
operatorList
}
setOperatorList=
{
setOperatorList
}
setInputActive=
{
setInputActive
}
productId=
{
productId
}
/>
<
BatchOperatorFlow
tasks=
{
operatorList
}
...
...
src/views/CustomOperator/useCheckOperator.tsx
0 → 100644
View file @
541232f3
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
_
from
"lodash"
;
import
{
useState
}
from
"react"
;
import
{
ITask
}
from
"../Project/ProjectSubmitWork/interface"
;
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-24 18:08:47
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-25 18:16:34
* @FilePath: /bkunyun/src/views/CustomOperator/useCheckOperator.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
const
useCheckOperator
=
(
operatorList
:
ITask
[],
successCallBack
?:
any
,
nullText
?:
string
)
=>
{
const
Message
=
useMessage
();
let
checkStatus
=
false
;
// 判断 每个起始算子(可以有多个起始点)的输入必须为文件的路径输入或数据集的路径输入。
const
checkIn
=
(
targetArr
:
string
[])
=>
{
const
uniqTargetArr
=
_
.
uniq
(
targetArr
);
if
(
uniqTargetArr
.
length
===
operatorList
.
length
)
{
// 流节点连成一个圈了
return
false
;
}
let
check
=
true
;
operatorList
.
forEach
((
flowNode
)
=>
{
if
(
uniqTargetArr
.
indexOf
(
flowNode
.
id
)
===
-
1
)
{
// 该节点的输入没有连线 也就是说这个节点是起点
const
inArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"in"
);
if
(
inArr
.
length
>
0
)
{
if
(
!
inArr
.
some
((
inItem
)
=>
{
return
(
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"dataset"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"file"
);
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
// 判断 起码有一个结尾算子(可以有多个结尾点)的输出必须为文件保存或数据集保存。
const
checkOut
=
(
sourceArr
:
string
[])
=>
{
const
uniqSourceArr
=
_
.
uniq
(
sourceArr
);
if
(
uniqSourceArr
.
length
===
operatorList
.
length
)
{
// 流节点连成一个圈了
return
false
;
}
let
check
=
true
;
operatorList
.
forEach
((
flowNode
)
=>
{
if
(
uniqSourceArr
.
indexOf
(
flowNode
.
id
)
===
-
1
)
{
// 该节点的输入没有连线 也就是说这个节点是起点
const
outArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"out"
);
if
(
outArr
.
length
>
0
)
{
if
(
!
outArr
.
some
((
outItem
)
=>
{
return
(
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"dataset"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"file"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"input"
);
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
// 判断 每个流算子必须至少有一条连接线。
const
checkHasOneLine
=
(
sourceArr
:
string
[],
targetArr
:
string
[])
=>
{
const
all
=
_
.
uniq
([...
sourceArr
,
...
targetArr
]);
if
(
all
.
length
===
operatorList
.
length
)
{
return
true
;
}
else
{
return
false
;
}
// _.uniq([2, 1, 2]);
};
const
handleCheck
=
()
=>
{
if
(
operatorList
.
length
===
0
)
{
Message
.
error
(
nullText
||
"内容不能为空!"
);
checkStatus
=
false
;
return
;
}
let
sourceArr
:
string
[]
=
[];
let
targetArr
:
string
[]
=
[];
operatorList
.
forEach
((
flowNode
)
=>
{
flowNode
.
edges
.
forEach
((
edge
)
=>
{
edge
.
source
&&
sourceArr
.
push
(
edge
.
source
);
edge
.
target
&&
targetArr
.
push
(
edge
.
target
);
});
});
if
(
!
checkHasOneLine
([...
sourceArr
],
[...
targetArr
]))
{
checkStatus
=
false
;
Message
.
error
(
"部分算子没有流程线,请检查流程!"
);
return
;
}
if
(
!
checkIn
([...
targetArr
]))
{
checkStatus
=
false
;
Message
.
error
(
"每个流程第一步需读取文件/数据集,请检查流程!"
);
return
;
}
if
(
!
checkOut
([...
sourceArr
]))
{
checkStatus
=
false
;
Message
.
error
(
"每个流程最后一步必须将数据写入为文件/数据集,请检查流程!"
);
return
;
}
checkStatus
=
true
;
successCallBack
();
};
return
{
handleCheck
,
checkStatus
};
};
export
default
useCheckOperator
;
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/SeeEnv/index.tsx
View file @
541232f3
...
...
@@ -144,7 +144,11 @@ const SeeEnv = () => {
className=
{
style
.
goBackIcon
}
src=
{
goback
}
alt=
""
onClick=
{
()
=>
navigate
(
"/utility/resourceCenter/userResources"
)
}
onClick=
{
()
=>
navigate
(
"/utility/resourceCenter/userResources"
,
{
state
:
{
defaultTab
:
"USERRESOURCES_ENVIRONMENT"
},
})
}
/>
<
div
className=
{
style
.
title
}
>
{
info
.
title
}
</
div
>
<
div
className=
{
style
.
type
}
>
...
...
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/index.tsx
View file @
541232f3
...
...
@@ -5,7 +5,7 @@ import style from "./index.module.css";
import
SearchInput
from
"@/components/BusinessComponents/SearchInput"
;
import
MySelect
from
"@/components/mui/MySelect"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
MyTable
from
"@/components/mui/MyTableNew"
;
import
MyTable
,
{
sortState
}
from
"@/components/mui/MyTableNew"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getActorenvList
}
from
"@/api/resourceCenter"
;
import
Add
from
"@mui/icons-material/Add"
;
...
...
@@ -28,6 +28,10 @@ const UserResourcesEnvironment = () => {
const
[
id
,
setId
]
=
useState
(
""
);
const
[
deleteOpen
,
setDeleteOpen
]
=
useState
(
false
);
const
[
totalElements
,
setTotalElements
]
=
useState
(
0
);
const
[
sortState
,
setSortState
]
=
useState
<
sortState
>
({
field
:
"createdTime"
,
order
:
"DESC"
,
});
const
headCells
:
Array
<
any
>
=
[
{
id
:
"title"
,
...
...
@@ -42,6 +46,7 @@ const UserResourcesEnvironment = () => {
id
:
"createdTime"
,
label
:
"创建时间"
,
width
:
180
,
sort
:
true
,
},
{
id
:
"status"
,
...
...
@@ -73,9 +78,10 @@ const UserResourcesEnvironment = () => {
size
,
title
,
type
:
type
===
"ALL"
?
""
:
type
,
order
:
sortState
.
order
||
"DESC"
,
});
}
},
[
getList
,
page
,
size
,
title
,
type
,
addOpen
,
deleteOpen
]);
},
[
getList
,
page
,
size
,
title
,
type
,
addOpen
,
deleteOpen
,
sortState
]);
const
renderType
=
(
item
:
any
)
=>
{
if
(
item
.
type
===
"BATCH"
)
{
...
...
@@ -256,6 +262,8 @@ const UserResourcesEnvironment = () => {
paginationType=
"complex"
totalElements=
{
totalElements
}
loading=
{
loading
}
sortState=
{
sortState
}
setSortState=
{
setSortState
}
></
MyTable
>
</
div
>
{
addOpen
&&
<
AddEnvironment
setAddopen=
{
setAddopen
}
></
AddEnvironment
>
}
...
...
src/views/ResourceCenter/UserResources/UserResourcesTemplate/TemplateDetail/index.module.css
0 → 100644
View file @
541232f3
.swBox
{
position
:
fixed
;
z-index
:
1000
;
top
:
0
;
left
:
0
;
width
:
100vw
;
height
:
100vh
;
background-color
:
RGBA
(
247
,
248
,
250
,
1
);
overflow-y
:
overlay
;
}
.swHeader
{
z-index
:
1001
;
position
:
sticky
;
top
:
0
;
height
:
56px
;
background-color
:
#fff
;
box-shadow
:
0px
3px
10px
0px
rgba
(
0
,
24
,
57
,
0.06
);
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
0
24px
;
}
.swHeaderLeft
{
display
:
flex
;
justify-content
:
flex-start
;
align-items
:
center
;
}
.goBackIcon
{
cursor
:
pointer
;
}
.goBackIconBox
{
width
:
32px
;
height
:
32px
;
border-radius
:
4px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.goBackIconBox
:hover
{
background-color
:
rgb
(
240
,
242
,
245
);
}
.swTemplateTitle
{
margin
:
0
19px
0
3px
;
line-height
:
20px
;
font-size
:
14px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
font-weight
:
700
;
}
.swContent
{
display
:
flex
;
height
:
calc
(
100vh
-
56px
);
}
.swFormBox
{
background-color
:
#fff
;
border-right
:
1px
solid
#ebedf0
;
width
:
360px
;
overflow-y
:
overlay
;
box-sizing
:
border-box
;
padding
:
24px
;
}
.swFlowBox
{
flex
:
1
;
height
:
calc
(
100vh
-
56px
);
}
.title
{
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
16px
;
line-height
:
24px
;
font-weight
:
600
;
margin-bottom
:
16px
;
}
.taskInfoLi
{
margin-bottom
:
20px
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
flex-start
;
}
.taskInfoParams
{
color
:
rgba
(
138
,
144
,
153
,
1
);
font-size
:
14px
;
line-height
:
22px
;
width
:
80px
;
margin-right
:
44px
;
word-wrap
:
break-word
;
}
.taskInfoValue
{
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
14px
;
line-height
:
22px
;
display
:
flex
;
position
:
relative
;
align-items
:
center
;
text-align
:
left
;
word-break
:
break-all
;
flex
:
1
;
justify-content
:
flex-end
;
word-wrap
:
break-word
;
}
.taskInfoValueShowAll
{
white-space
:
normal
;
}
.taskInfoValueIcon
{
margin-right
:
9px
;
}
.tabs
{
display
:
flex
;
justify-content
:
flex-start
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
245
,
1
);
}
.tabLi
{
cursor
:
pointer
;
font-size
:
14px
;
line-height
:
22px
;
padding-bottom
:
8px
;
color
:
rgba
(
138
,
144
,
153
,
1
);
margin-right
:
32px
;
position
:
relative
;
}
.tabLiAcitve
{
color
:
rgba
(
19
,
112
,
255
,
1
);
border-bottom
:
2px
solid
rgba
(
19
,
112
,
255
,
1
);
}
.overview
{
padding-top
:
19px
;
}
.params
{
padding-top
:
19px
;
}
.options
{
position
:
absolute
;
top
:
33px
;
max-height
:
230px
;
overflow-y
:
overlay
;
padding
:
8px
0px
;
background
:
#ffffff
;
box-shadow
:
0px
3px
10px
0px
rgba
(
0
,
24
,
57
,
0.14
);
border-radius
:
4px
;
z-index
:
1002
;
}
src/views/ResourceCenter/UserResources/UserResourcesTemplate/TemplateDetail/index.tsx
0 → 100644
View file @
541232f3
import
{
useEffect
,
useState
,
useMemo
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
classNames
from
"classnames"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getWorkflowspecDetail
}
from
"@/api/resourceCenter"
;
import
{
IResponse
}
from
"@/api/http"
;
import
goback
from
"@/assets/project/goback.svg"
;
import
{
ITaskInfo
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
import
Flow
from
"@/views/Project/components/Flow"
;
import
moment
from
"moment"
;
import
MyTooltip
from
"@/components/mui/MyTooltip"
;
import
{
toJS
}
from
"mobx"
;
import
{
useStores
}
from
"@/store"
;
import
styles
from
"./index.module.css"
;
interface
ITemplateDetailProps
{
id
:
string
;
setShowDetail
:
any
;
}
const
TemplateDetail
=
observer
((
props
:
ITemplateDetailProps
)
=>
{
const
{
id
,
setShowDetail
}
=
props
;
const
[
templateInfo
,
setTemplateInfo
]
=
useState
<
any
>
({});
const
[
overviewActive
,
setOverviewActive
]
=
useState
(
true
);
/** 选中的node Id */
const
[
activeFlowIndex
,
setActiveFlowIndex
]
=
useState
<
string
>
(
""
);
const
{
productListStore
}
=
useStores
();
const
getProductName
=
(
productId
:
string
)
=>
{
let
res
=
"-"
;
toJS
(
productListStore
.
productList
).
forEach
((
item
)
=>
{
if
(
item
.
value
===
productId
)
{
res
=
item
.
label
;
}
});
return
res
;
};
const
taskInfo
=
useMemo
(()
=>
{
if
(
activeFlowIndex
)
{
return
templateInfo
.
tasks
.
filter
(
(
task
:
any
)
=>
task
.
id
===
activeFlowIndex
)[
0
];
}
else
{
return
{};
}
},
[
templateInfo
,
activeFlowIndex
]);
const
randerParameters
=
useMemo
(()
=>
{
return
taskInfo
.
parameters
;
},
[
taskInfo
]);
/** 获取模版数据 */
const
{
run
}
=
useMyRequest
(
getWorkflowspecDetail
,
{
onSuccess
:
(
res
:
IResponse
<
ITaskInfo
>
)
=>
{
console
.
log
(
res
);
setTemplateInfo
(
res
.
data
);
},
});
useEffect
(()
=>
{
run
(
id
);
},
[
id
,
run
]);
/** 返回事件 */
const
onBack
=
()
=>
{
setShowDetail
(
false
);
};
const
setExternalSelectedNodeId
=
(
id
:
string
)
=>
{
setActiveFlowIndex
(
id
);
};
const
handleParams
=
()
=>
{
setOverviewActive
(
false
);
};
return
(
<
div
className=
{
styles
.
swBox
}
>
<
div
className=
{
styles
.
swHeader
}
>
<
div
className=
{
styles
.
swHeaderLeft
}
>
<
div
className=
{
styles
.
goBackIconBox
}
>
<
img
onClick=
{
onBack
}
className=
{
styles
.
goBackIcon
}
src=
{
goback
}
alt=
""
/>
</
div
>
<
div
className=
{
styles
.
swTemplateTitle
}
>
{
templateInfo
.
title
}
</
div
>
</
div
>
</
div
>
<
div
className=
{
styles
.
swContent
}
>
<
div
className=
{
styles
.
swFormBox
}
>
{
!
activeFlowIndex
&&
(
<
div
>
<
div
className=
{
styles
.
title
}
>
基础信息
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
模板名称
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
title
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
描述
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
description
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
创建时间
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
moment
(
new
Date
(
templateInfo
.
createdAt
)).
format
(
"yyyy-MM-DD hh:mm"
)
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
创建人
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
creator
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
版本
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
version
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
所属产品
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
getProductName
(
templateInfo
.
productId
)
}
</
div
>
</
div
>
</
div
>
)
}
{
activeFlowIndex
&&
(
<
div
className=
{
styles
.
suanziInfo
}
>
<
MyTooltip
>
<
div
className=
{
styles
.
title
}
>
{
taskInfo
?.
title
}
</
div
>
</
MyTooltip
>
<
div
className=
{
styles
.
tabs
}
>
<
div
className=
{
classNames
({
[
styles
.
tabLi
]:
true
,
[
styles
.
tabLiAcitve
]:
overviewActive
,
})
}
onClick=
{
()
=>
setOverviewActive
(
true
)
}
>
概览
</
div
>
<
div
className=
{
classNames
({
[
styles
.
tabLi
]:
true
,
[
styles
.
tabLiAcitve
]:
!
overviewActive
,
})
}
onClick=
{
()
=>
handleParams
()
}
>
参数
</
div
>
</
div
>
{
overviewActive
&&
(
<
div
className=
{
styles
.
overview
}
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
描述
</
div
>
<
div
className=
{
classNames
({
[
styles
.
taskInfoValue
]:
true
,
[
styles
.
taskInfoValueShowAll
]:
true
,
})
}
>
{
taskInfo
?.
description
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
算子版本
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
taskInfo
?.
version
||
"-"
}
</
div
>
</
div
>
</
div
>
)
}
{
!
overviewActive
&&
(
<
div
className=
{
styles
.
params
}
>
{
randerParameters
?.
map
((
parameter
:
any
)
=>
{
return
(
<
div
className=
{
styles
.
taskInfoLi
}
key=
{
parameter
.
name
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
{
parameter
.
name
}
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
parameter
.
defaultValue
||
"-"
}
</
div
>
</
div
>
);
})
}
</
div
>
)
}
</
div
>
)
}
</
div
>
<
div
className=
{
styles
.
swFlowBox
}
>
<
Flow
externalSelectedNodeId=
{
activeFlowIndex
}
tasks=
{
templateInfo
?.
tasks
}
setExternalSelectedNodeId=
{
setExternalSelectedNodeId
}
/>
</
div
>
</
div
>
</
div
>
);
});
export
default
TemplateDetail
;
src/views/ResourceCenter/UserResources/UserResourcesTemplate/index.module.css
0 → 100644
View file @
541232f3
.template
{
padding
:
19px
24px
0
;
}
.top
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
20px
;
}
.tableBox
{
height
:
calc
(
100vh
-
177px
);
}
.templateBox
{
border
:
2px
solid
#fff
;
box-shadow
:
0px
3px
12px
0px
rgba
(
3
,
47
,
105
,
0.09
);
border-radius
:
6px
;
background
:
linear-gradient
(
180deg
,
#f5f7fa
0%
,
#ffffff
100%
);
height
:
208px
;
box-sizing
:
border-box
;
padding
:
16px
20px
;
}
.templateTop
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
margin-bottom
:
12px
;
}
.templateTopItem
{
font-size
:
12px
;
line-height
:
20px
;
color
:
rgba
(
138
,
144
,
153
,
1
);
}
.templateTopLine
{
width
:
1px
;
height
:
16px
;
background-color
:
rgba
(
221
,
225
,
230
,
1
);
margin
:
0
11px
;
}
.templateTitleBox
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
margin-bottom
:
12px
;
}
.templateTitleBox
{
height
:
24px
;
}
.templateTitle
{
font-size
:
14px
;
line-height
:
22px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
margin-left
:
8px
;
font-weight
:
550
;
}
.templateDesc
{
height
:
60px
;
font-size
:
12px
;
line-height
:
20px
;
color
:
rgba
(
86
,
92
,
102
,
1
);
margin-bottom
:
16px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
-webkit-box-orient
:
vertical
;
-webkit-line-clamp
:
3
;
display
:
-webkit-box
;
}
.templateButtons
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
}
.button
{
cursor
:
pointer
;
line-height
:
22px
;
font-size
:
14px
;
color
:
rgba
(
19
,
112
,
255
,
1
);
}
src/views/ResourceCenter/UserResources/UserResourcesTemplate/index.tsx
0 → 100644
View file @
541232f3
import
{
useEffect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react"
;
import
SearchInput
from
"@/components/BusinessComponents/SearchInput"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
MySelect
from
"@/components/mui/MySelect"
;
import
Add
from
"@mui/icons-material/Add"
;
import
CardTable
from
"@/components/CommonComponents/CardTable"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getWorkflowspecList
,
deleteWorkflowspec
}
from
"@/api/resourceCenter"
;
import
MyDialog
from
"@/components/mui/MyDialog"
;
import
templateIcon
from
"@/assets/resourceCenter/templateIcon.svg"
;
import
{
useStores
}
from
"@/store"
;
import
{
toJS
}
from
"mobx"
;
import
ProductSelect
from
"@/components/BusinessComponents/ProductSelect"
;
import
WorkFlowEdit
from
"@/views/WorkFlowEdit"
;
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
TemplateDetail
from
"./TemplateDetail"
;
import
style
from
"./index.module.css"
;
const
UserResourcesTemplate
=
observer
(()
=>
{
const
[
title
,
setTitle
]
=
useState
(
""
);
const
Message
=
useMessage
();
const
[
showAddTemplate
,
setShowAddTemplate
]
=
useState
(
false
);
// 新增、编辑模板弹窗
const
[
showProductSelect
,
setShowProductSelect
]
=
useState
(
false
);
const
[
showDeleteDialog
,
setShowDeleteDialog
]
=
useState
(
false
);
const
[
showDetail
,
setShowDetail
]
=
useState
(
false
);
// 详情
const
[
templateId
,
setTemplateId
]
=
useState
(
""
);
const
[
product
,
setProduct
]
=
useState
(
""
);
// 搜索列表用
const
[
productId
,
setProductId
]
=
useState
(
""
);
// 新增模板用
const
[
list
,
setList
]
=
useState
([]);
const
{
productListStore
}
=
useStores
();
const
getProductName
=
(
productId
:
string
)
=>
{
let
res
=
"-"
;
toJS
(
productListStore
.
productList
).
forEach
((
item
)
=>
{
if
(
item
.
value
===
productId
)
{
res
=
item
.
label
;
}
});
return
res
;
};
const
renderItem
=
(
item
:
any
)
=>
{
return
(
<
div
className=
{
style
.
templateBox
}
>
<
div
className=
{
style
.
templateTop
}
>
<
div
className=
{
style
.
templateTopItem
}
>
{
getProductName
(
item
.
productId
)
}
</
div
>
<
div
className=
{
style
.
templateTopLine
}
></
div
>
<
div
className=
{
style
.
templateTopItem
}
>
{
item
.
version
}
</
div
>
<
div
className=
{
style
.
templateTopLine
}
></
div
>
<
div
className=
{
style
.
templateTopItem
}
>
{
item
.
updatedTime
}
</
div
>
</
div
>
<
div
className=
{
style
.
templateTitleBox
}
>
<
img
src=
{
templateIcon
}
alt=
""
/>
<
div
className=
{
style
.
templateTitle
}
>
{
item
.
title
}
</
div
>
</
div
>
<
div
className=
{
style
.
templateDesc
}
>
{
item
.
description
}
</
div
>
<
div
className=
{
style
.
templateButtons
}
>
<
div
className=
{
style
.
templateBL
}
>
<
span
className=
{
style
.
button
}
onClick=
{
()
=>
{
setTemplateId
(
item
.
id
);
setProductId
(
item
.
productId
);
setShowAddTemplate
(
true
);
}
}
>
升级
</
span
>
</
div
>
<
div
className=
{
style
.
templateBR
}
>
<
MyButton
text=
"删除"
variant=
"outlined"
style=
{
{
border
:
"1px solid rgba(221, 225, 230, 1)"
,
color
:
"rgba(138, 144, 153, 1)"
,
marginRight
:
"12px"
,
}
}
onClick=
{
()
=>
{
setShowDeleteDialog
(
true
);
setTemplateId
(
item
.
id
);
}
}
></
MyButton
>
<
MyButton
text=
"查看"
variant=
"outlined"
onClick=
{
()
=>
{
setTemplateId
(
item
.
id
);
setShowDetail
(
true
);
}
}
></
MyButton
>
</
div
>
</
div
>
</
div
>
);
};
// 获取模板列表
const
{
run
}
=
useMyRequest
(
getWorkflowspecList
,
{
onSuccess
:
(
result
:
any
)
=>
{
setList
(
result
.
data
);
},
});
useEffect
(()
=>
{
if
(
!
showAddTemplate
)
{
run
({
productId
:
product
===
"all"
?
""
:
product
,
title
,
});
}
},
[
run
,
title
,
product
,
showAddTemplate
]);
const
{
run
:
deleteWorkflowspecFn
}
=
useMyRequest
(
deleteWorkflowspec
,
{
onSuccess
:
()
=>
{
Message
.
success
(
"删除成功"
);
setShowDeleteDialog
(
false
);
run
({
productId
:
product
===
"all"
?
""
:
product
,
title
,
});
},
});
const
deleteConfirm
=
()
=>
{
deleteWorkflowspecFn
({
id
:
templateId
});
};
return
(
<
div
className=
{
style
.
template
}
>
<
div
className=
{
style
.
top
}
>
<
div
className=
{
style
.
topLeft
}
>
<
SearchInput
sx=
{
{
width
:
340
,
marginRight
:
"16px"
}
}
onKeyUp=
{
(
e
:
any
)
=>
{
if
(
e
.
keyCode
===
13
)
{
setTitle
(
e
.
target
.
value
);
}
}
}
></
SearchInput
>
<
MySelect
title=
"产品类型"
isTitle=
{
true
}
options=
{
[
{
label
:
"全部"
,
value
:
"all"
},
...
productListStore
?.
productList
,
]
||
[]
}
value=
{
product
}
onChange=
{
(
e
:
any
)
=>
setProduct
(
e
)
}
sx=
{
{
width
:
"150px"
,
height
:
"32px"
}
}
></
MySelect
>
</
div
>
<
div
className=
{
style
.
topRight
}
>
<
MyButton
text=
"新建自定义模板"
onClick=
{
()
=>
setShowProductSelect
(
true
)
}
startIcon=
{
<
Add
/>
}
></
MyButton
>
</
div
>
</
div
>
<
div
className=
{
style
.
tableBox
}
>
<
CardTable
data=
{
list
}
renderItem=
{
renderItem
}
itemMinWidth=
{
377
}
></
CardTable
>
</
div
>
{
showAddTemplate
&&
(
<
WorkFlowEdit
id=
{
templateId
}
propsProductId=
{
productId
}
onBack=
{
()
=>
{
setShowAddTemplate
(
false
);
}
}
></
WorkFlowEdit
>
)
}
{
showProductSelect
&&
(
<
ProductSelect
open=
{
showProductSelect
}
setOpen=
{
setShowProductSelect
}
productId=
{
productId
}
setProductId=
{
setProductId
}
onConfirm=
{
()
=>
{
setTemplateId
(
""
);
setShowAddTemplate
(
true
);
}
}
></
ProductSelect
>
)
}
{
showDeleteDialog
&&
(
<
MyDialog
onClose=
{
()
=>
setShowDeleteDialog
(
false
)
}
onConfirm=
{
()
=>
deleteConfirm
()
}
open=
{
showDeleteDialog
}
isText=
{
true
}
title=
"提示"
>
确定要删除这个模板吗?
</
MyDialog
>
)
}
{
showDetail
&&
(
<
TemplateDetail
id=
{
templateId
}
setShowDetail=
{
setShowDetail
}
></
TemplateDetail
>
)
}
</
div
>
);
});
export
default
UserResourcesTemplate
;
src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.module.css
View file @
541232f3
...
...
@@ -39,6 +39,7 @@
}
.form
{
width
:
368px
;
min-width
:
368px
;
box-sizing
:
border-box
;
padding
:
16px
24px
;
border
:
1px
solid
#ebedf0
;
...
...
@@ -48,6 +49,7 @@
}
.newForm
{
width
:
368px
;
min-width
:
368px
;
box-sizing
:
border-box
;
padding
:
16px
32px
0px
0
;
border-right
:
1px
solid
#ebedf0
;
...
...
@@ -62,6 +64,9 @@
}
.codeTitle
{
background-color
:
rgba
(
230
,
233
,
237
,
1
);
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
11px
20px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
14px
;
...
...
@@ -89,3 +94,12 @@
.descBox
{
padding-left
:
32px
;
}
.codeErrorBox
{
padding-left
:
20px
;
height
:
32px
;
line-height
:
32px
;
width
:
calc
(
100%
-
20px
);
color
:
#ff4e4e
;
background-color
:
#ffe8e8
;
}
src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.tsx
View file @
541232f3
This diff is collapsed.
Click to expand it.
src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/utils.ts
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-20 17:36:14
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-2
0 19:44:52
* @LastEditTime: 2022-10-2
4 15:52:56
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/utils.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -10,7 +10,9 @@
import
{
IOperatorAddFormData
}
from
"../../interface"
;
export
const
checkFormData
=
(
formData
:
IOperatorAddFormData
,
taskType
:
'BATCH'
|
'FLOW'
)
=>
{
type
IBuildType
=
"ENVIRONMENT"
|
"OPERATOR"
;
export
const
checkFormData
=
(
formData
:
IOperatorAddFormData
,
taskType
:
IBuildType
)
=>
{
const
reg
=
new
RegExp
(
"^[A-Za-z0-9
\
u4e00-
\
u9fa5]{1,15}$"
);
const
result
:
IOperatorAddFormData
=
{}
...
...
@@ -30,7 +32,7 @@ export const checkFormData = (formData: IOperatorAddFormData, taskType: 'BATCH'
if
(
!
formData
?.
productId
){
result
.
productId
=
'请选择所属产品'
}
if
(
taskType
===
'
BATCH
'
&&
!
formData
?.
envId
){
if
(
taskType
===
'
ENVIRONMENT
'
&&
!
formData
?.
envId
){
result
.
envId
=
'请选择应用环境'
}
...
...
@@ -39,15 +41,108 @@ export const checkFormData = (formData: IOperatorAddFormData, taskType: 'BATCH'
/** 参数配置校验 */
export
const
checkParamsConfig
=
(
val
:
string
)
=>
{
let
result
:
string
=
''
const
arr
=
val
.
split
(
'
\
n'
||
','
)
if
(
!
val
){
result
=
'请输入参数配置'
}
if
(
!
true
){
result
=
'参数配置格式不正确'
let
result
:
any
=
[]
try
{
const
value
=
JSON
.
parse
(
val
)
value
?.
length
&&
value
.
forEach
((
item
:
any
)
=>
{
const
nameReg
=
new
RegExp
(
"^[A-Za-z][A-Za-z0-9_]{1,14}$"
);
const
titleReg
=
new
RegExp
(
"^[A-Za-z0-9
\
u4e00-
\
u9fa5]{1,15}$"
);
if
(
!
nameReg
.
test
(
item
?.
name
)
){
result
.
push
(
`name:
${
item
?.
name
}
`)
}
if( !titleReg.test(item?.title) ){
result.push(`
title
:
$
{
item
?.
title
}
`)
}
if( item?.description > 300 ){
result.push(`
description
:
$
{
item
?.
description
}
`)
}
if( !['STRING','FILE','DATASET','INT','FLOAT','DOUBLE','BOOLEAN','ARRAY_STRING','ARRAY_FILE','ARRAY_DATASET','ARRAY_INT','ARRAY_FLOAT','ARRAY_DOUBLE','ARRAY_BOOLEAN'].includes(item?.classType )){
result.push(`
classType
:
$
{
item
?.
classType
}
`)
}
if(!['true','false'].includes(String(item?.required)) ) {
result.push(`
required
:
$
{
item
?.
required
}
`)
}
if( !['PATH','DATASET','FILE','INPUT','SELECT','MULTIPLESELECT','RADIO','CHECKBOX'].includes(item?.domType )){
result.push(`
domType
:
$
{
item
?.
domType
}
`)
}
})
} catch(error){
console.log(error)
}
return result
}
\ No newline at end of file
}
export const initCode = [{
"name" : "timeout",
"classType" : "INT",
"required" : false,
"defaultValue" : 10000,
"description" : "",
"hidden" : true,
"title" : "",
"order" : 0,
"domType" : "INPUT",
"choices" : [
{
"label" : "是",
"value" : "true"
},
{
"label": "否",
"value": "false"
}
],
"validators" : [
{
"regex" : "^.*\\.(pdb|PDB|pdbqt|PDBQT)$",
"message" : "请输入PDB或PDBQT文件"
}
]
}]
export const text = `
{
// 参数名, 必填,在15字符以内,仅限大小写字母、数字、"_",且只能以大小写字母开头
"name"
:
"timeout"
,
/** 参数类型。可选值有 STRING:字符串、FILE:文件、DATASET:数据集、INT:整型、FLOAT:单精度浮点型、
* DOUBLE:多精度浮点型、BOOLEAN:布尔值、ARRAY_STRING:字符串数组、ARRAY_FILE:文件数组、ARRAY_DATASET:数据集数组、
* ARRAY_INT:整型数组、ARRAY_FLOAT:单精度浮点型数组、ARRAY_DOUBLE:多精度浮点型数组、ARRAY_BOOLEAN:布尔值数组
*/
"classType"
:
"INT"
,
// 是否必填。在使用该算子时是否必须输入改参数的值
"required"
:
false
,
// 默认值
"defaultValue"
:
10000
,
// 参数描述。在300字符以内
"description"
:
""
,
// 是否隐藏,隐藏就在页面不显示该参数 必填
"hidden"
:
true
,
// 页面展示的参数的名称
"title"
:
""
,
// 参数展示的顺序优先级
"order"
:
0
,
/**
* 前端填值的方式 PATH:路径选择器、DATASET:数据集选择器、FILE:文件选择器、INPUT:输入框、
* SELECT:下拉框、MULTIPLESELECT:多选下拉框、RADIO:单选按钮、CHECKBOX:多选按钮
*/
"domType"
:
"INPUT"
,
// 选项。当domType为SELECT、MULTIPLESELECT、RADIO、CHECKBOX时生效。以对象数组的形式保存
"choices"
:
[
{
// 在前端展示的值
"label"
:
"是"
,
//选中时传递服务使用的值
"value"
:
"true"
},
],
//用于校验输入值。以对象数组的形式保存
"validators"
:
[
{
//正则表达式
"regex"
:
"^.*
\\
.(pdb|PDB|pdbqt|PDBQT)$"
,
//不符合正则时的报错信息
"message"
:
"请输入PDB或PDBQT文件"
}
]
}
`
\ No newline at end of file
src/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorCard/index.module.css
View file @
541232f3
...
...
@@ -3,6 +3,7 @@
height
:
108px
;
padding
:
20px
;
margin
:
0
20px
20px
0
;
cursor
:
pointer
;
background
:
linear-gradient
(
180deg
,
#f5f7fa
0%
,
#ffffff
100%
);
box-shadow
:
0px
3px
12px
0px
rgba
(
3
,
47
,
105
,
0.09
);
border-radius
:
6px
;
...
...
@@ -50,8 +51,9 @@
display
:
inline-block
;
width
:
24px
;
height
:
24px
;
text-align
:
center
;
line-height
:
24px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
cursor
:
pointer
;
}
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorCard/index.tsx
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-17 14:35:11
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-2
0 11:39:55
* @LastEditTime: 2022-10-2
5 21:32:49
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -13,16 +13,21 @@ import { observer } from "mobx-react";
import
{
useStores
}
from
"@/store"
;
import
{
useMemo
}
from
"react"
;
import
MyMenu
from
"@/components/mui/MyMenu"
;
import
{
useNavigate
}
from
"react-router-dom"
;
import
expandOperationSvg
from
"@/assets/project/expandOperationSvg.svg"
;
interface
IProps
{
operatorInfo
:
IOperatorInfo
;
setPageType
:
(
val
:
string
)
=>
void
;
setDetailsId
:
(
val
:
string
)
=>
void
;
}
const
OperatorCard
=
observer
((
props
:
IProps
)
=>
{
const
navigate
=
useNavigate
();
const
{
operatorInfo
:
{
title
=
""
,
type
,
version
,
productId
,
create
Time
},
operatorInfo
:
{
title
=
""
,
type
,
version
,
productId
,
create
dTime
,
id
},
setPageType
,
setDetailsId
,
}
=
props
;
/** 产品store */
const
{
productListStore
}
=
useStores
();
...
...
@@ -37,11 +42,18 @@ const OperatorCard = observer((props: IProps) => {
const
onClickOperation
=
(
val
:
string
)
=>
{
if
(
val
===
"upgrade"
)
{
setPageType
(
"edit"
);
setDetailsId
(
id
||
""
);
}
};
const
handleToSeeOperator
=
()
=>
{
navigate
(
"/utility/resourceCenter/userResources/seeFloe"
,
{
state
:
{
id
},
});
};
return
(
<
div
className=
{
styles
.
itemBox
}
>
<
div
className=
{
styles
.
itemBox
}
onClick=
{
handleToSeeOperator
}
>
<
div
className=
{
styles
.
itemHeaderBox
}
>
<
div
className=
{
styles
.
startTitleBox
}
>
{
title
?.
slice
(
0
,
1
)
}
</
div
>
<
div
style=
{
{
flex
:
1
,
marginLeft
:
12
}
}
>
...
...
@@ -59,7 +71,13 @@ const OperatorCard = observer((props: IProps) => {
zIndex
:
1601
,
}
}
>
<
span
className=
{
styles
.
operationBox
}
>
d
</
span
>
<
span
className=
{
styles
.
operationBox
}
>
<
img
style=
{
{
width
:
16
,
height
:
16
}
}
src=
{
expandOperationSvg
}
alt=
""
/>
</
span
>
</
MyMenu
>
</
div
>
<
div
className=
{
styles
.
itemContentBox
}
>
...
...
@@ -70,7 +88,7 @@ const OperatorCard = observer((props: IProps) => {
算子版本:
<
span
>
{
`V${version}`
}
</
span
>
</
p
>
<
p
className=
{
styles
.
infoBox
}
>
创建时间:
<
span
>
{
createTime
}
</
span
>
创建时间:
<
span
>
{
create
d
Time
}
</
span
>
</
p
>
</
div
>
</
div
>
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorDetails/index.module.css
View file @
541232f3
...
...
@@ -2,9 +2,38 @@
padding
:
0
24px
;
}
.
title
Box
{
.
baseInfo
Box
{
font-size
:
16px
;
color
:
#1e2633
;
line-height
:
24px
;
padding
:
20px
0
;
}
.titleBox
{
padding
:
14px
24px
;
display
:
flex
;
justify-content
:
flex-start
;
align-items
:
center
;
border-bottom
:
1px
solid
rgba
(
235
,
237
,
240
,
1
);
}
.goBackIcon
{
width
:
22px
;
height
:
22px
;
cursor
:
pointer
;
}
.title
{
margin-left
:
2px
;
font-size
:
18px
;
line-height
:
26px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
font-weight
:
550
;
margin-right
:
16px
;
}
.type
{
background-color
:
rgba
(
235
,
237
,
240
,
1
);
font-size
:
12px
;
line-height
:
20px
;
padding
:
1px
9px
;
color
:
#565c66
;
border-radius
:
2px
;
}
src/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorDetails/index.tsx
View file @
541232f3
...
...
@@ -2,17 +2,25 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-17 14:35:11
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 10:30:55
* @LastEditTime: 2022-10-
26 09:27:56
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
styles
from
"./index.module.css"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
{
useLocation
,
useNavigate
}
from
"react-router-dom"
;
import
BasicInfo
from
"../../../../components/BasinInfo"
;
import
{
useMemo
,
useState
}
from
"react"
;
import
RadioGroupOfButtonStyle
from
"@/components/CommonComponents/RadioGroupOfButtonStyle"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getOperatorDetail
}
from
"@/api/resourceCenter"
;
import
{
useStores
}
from
"@/store"
;
import
goback
from
"@/assets/project/goback.svg"
;
const
OperatorDetails
=
()
=>
{
import
styles
from
"./index.module.css"
;
const
OperatorDetails
=
observer
(()
=>
{
const
contentTypeList
=
useMemo
(()
=>
{
return
[
{
value
:
"flowChart"
,
label
:
"流程图"
},
...
...
@@ -21,31 +29,85 @@ const OperatorDetails = () => {
];
},
[]);
/** 产品store */
const
{
productListStore
}
=
useStores
();
const
navigate
=
useNavigate
();
/** 详情类型 */
const
[
contentType
,
setContentType
]
=
useState
<
string
>
(
"flowChart"
);
/** 详情数据 */
const
[
detailInfo
,
setDetailInfo
]
=
useState
<
any
>
({});
/** 获取算子详情 */
const
{
run
:
fetchOperatorDetail
}
=
useMyRequest
(
getOperatorDetail
,
{
onSuccess
:
(
res
:
any
)
=>
{
if
(
res
.
message
===
"success"
)
{
/** 设置详情信息 */
setDetailInfo
(
res
.
data
);
}
},
});
const
location
=
useLocation
();
const
locationInfo
:
any
=
location
?.
state
;
const
{
title
=
""
,
version
=
""
,
productId
=
""
,
createdTime
=
""
,
creator
=
""
,
description
=
""
,
type
,
}
=
detailInfo
;
/** 切换类型 */
const
handleRadio
=
(
val
:
string
)
=>
{
setContentType
(
val
);
};
const
productText
=
useMemo
(()
=>
{
const
result
=
productListStore
.
productList
?.
filter
((
item
)
=>
{
return
item
.
value
===
productId
;
});
return
result
?.
length
?
result
[
0
].
label
:
""
;
},
[
productListStore
.
productList
,
productId
]);
useEffect
(()
=>
{
fetchOperatorDetail
(
locationInfo
.
id
);
},
[
fetchOperatorDetail
,
locationInfo
.
id
]);
return
(
<
div
className=
{
styles
.
detailsBox
}
>
<
h2
className=
{
styles
.
titleBox
}
>
基础信息
</
h2
>
<
div
className=
{
styles
.
titleBox
}
>
<
img
className=
{
styles
.
goBackIcon
}
src=
{
goback
}
alt=
""
onClick=
{
()
=>
navigate
(
"/utility/resourceCenter/userResources"
,
{
state
:
{
defaultTab
:
"USERRESOURCES_FLOE"
},
})
}
/>
<
div
className=
{
styles
.
title
}
>
{
title
}
</
div
>
<
div
className=
{
styles
.
type
}
>
{
type
===
"BATCH"
?
"批算子"
:
"流算子"
}
</
div
>
</
div
>
<
h2
className=
{
styles
.
baseInfoBox
}
>
基础信息
</
h2
>
<
div
style=
{
{
border
:
"1px solid #EBEDF0"
}
}
>
<
BasicInfo
infoList=
{
[
{
label
:
"
33333331"
,
value
:
"1"
},
{
label
:
"
所属产品"
,
value
:
productText
},
{
label
:
"
1
"
,
value
:
"42543253245325325432452345235432452323542352354235235321"
,
label
:
"
创建时间
"
,
value
:
createdTime
,
},
{
label
:
"
1"
,
value
:
"1"
},
{
label
:
"
1"
,
value
:
"1"
},
{
label
:
"
1
"
,
value
:
"1"
},
{
label
:
"
创建人"
,
value
:
creator
},
{
label
:
"
算子版本"
,
value
:
version
},
{
label
:
"
应用环境
"
,
value
:
"1"
},
]
}
/>
<
BasicInfo
infoList=
{
[{
label
:
"
2"
,
value
:
"2"
}]
}
/>
<
BasicInfo
infoList=
{
[{
label
:
"
描述"
,
value
:
description
}]
}
/>
</
div
>
<
div
style=
{
{
padding
:
"26px 0 16px 0"
}
}
>
<
RadioGroupOfButtonStyle
...
...
@@ -58,6 +120,6 @@ const OperatorDetails = () => {
<
div
>
11
</
div
>
</
div
>
);
};
}
)
;
export
default
OperatorDetails
;
src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
View file @
541232f3
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-17 14:35:11
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-2
0 17:11:22
* @LastEditTime: 2022-10-2
5 20:53:24
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -35,6 +35,8 @@ const WorkflowOperator = observer(() => {
type
:
"all"
,
});
const
[
detailsId
,
setDetailsId
]
=
useState
<
string
>
(
""
);
const
[
list
,
setList
]
=
useState
<
IOperatorInfo
[]
>
();
const
{
run
:
getList
}
=
useMyRequest
(
getOperatorList
,
{
...
...
@@ -121,19 +123,31 @@ const WorkflowOperator = observer(() => {
<
MyButton
text=
"构建算子"
startIcon=
{
<
Add
/>
}
onClick=
{
()
=>
setPageType
(
"add"
)
}
onClick=
{
()
=>
{
setPageType
(
"add"
);
setDetailsId
(
""
);
}
}
></
MyButton
>
</
div
>
<
div
className=
{
styles
.
contentBox
}
>
{
list
?.
map
((
item
)
=>
{
return
(
<
OperatorCard
operatorInfo=
{
item
}
setPageType=
{
setPageType
}
/>
<
OperatorCard
setDetailsId=
{
setDetailsId
}
operatorInfo=
{
item
}
setPageType=
{
setPageType
}
/>
);
})
}
</
div
>
</
div
>
{
pageType
&&
(
<
AddOperator
setPageType=
{
setPageType
}
pageType=
{
pageType
}
/>
<
AddOperator
getList=
{
newGetList
}
detailsId=
{
detailsId
}
setPageType=
{
setPageType
}
pageType=
{
pageType
}
/>
)
}
</>
);
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/interface.ts
View file @
541232f3
...
...
@@ -2,18 +2,19 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-19 20:50:18
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-2
0 19:05:27
* @LastEditTime: 2022-10-2
4 20:38:09
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/interface.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export
type
IOperatorType
=
'BATCH'
|
'FLOW'
export
interface
IOperatorInfo
{
id
:
string
;
title
:
string
;
type
:
IOperatorType
;
version
:
string
;
productId
:
string
;
createTime
:
string
;
create
d
Time
:
string
;
}
export
enum
operatorType
{
...
...
@@ -28,4 +29,5 @@ export interface IOperatorAddFormData {
productId
?:
string
;
description
?:
string
;
envId
?:
string
;
parameters
?:
any
}
\ No newline at end of file
src/views/ResourceCenter/UserResources/index.tsx
View file @
541232f3
import
style
from
"./index.module.css"
;
import
usePass
from
"@/hooks/usePass"
;
import
UserResourcesTemplate
from
"./UserResourcesTemplate"
;
import
UserResourcesEnvironment
from
"./UserResourcesEnvironment"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useMemo
}
from
"react"
;
import
Tabs
from
"@/components/mui/MyTabs"
;
import
WorkflowOperator
from
"./WorkflowOperator"
;
import
OperatorDetails
from
"./WorkflowOperator/components/OperatorDetails"
;
const
UserResources
=
()
=>
{
const
isPass
=
usePass
();
const
location
:
any
=
useLocation
();
const
tabList
=
useMemo
(()
=>
{
return
[
{
label
:
"工作流模版"
,
value
:
"USERRESOURCES_TEMPLATE"
,
component
:
<
div
/>,
component
:
<
UserResourcesTemplate
/>,
hide
:
!
isPass
(
"USERRESOURCES_TEMPLATE"
),
},
{
...
...
@@ -35,7 +38,7 @@ const UserResources = () => {
<
Tabs
title=
"个人资源"
tabList=
{
tabList
}
defaultValue=
{
"USERRESOURCES_ENVIRONMENT
"
}
defaultValue=
{
location
?.
state
?.
defaultTab
||
"USERRESOURCES_TEMPLATE
"
}
tabPanelSx=
{
{
padding
:
"0"
}
}
/>
{
/* <OperatorDetails /> */
}
...
...
src/views/ResourceCenter/components/SwitchBatchFolw/index.tsx
View file @
541232f3
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-18 09:32:40
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-25 14:48:51
* @FilePath: /bkunyun/src/views/ResourceCenter/components/SwitchBatchFolw/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
batchImg
from
"@/assets/resourceCenter/batchImg.svg"
;
import
flowImg
from
"@/assets/resourceCenter/flowImg.svg"
;
import
classNames
from
"classnames"
;
import
goback
from
"@/assets/project/goback.svg"
;
import
style
from
"./index.module.css"
;
type
ISwitchBatchFolwProps
=
{
topImg
?:
string
;
bottomImg
?:
string
;
active
:
"BATCH"
|
"FLOW"
;
type
?:
"edit"
;
setActive
:
any
;
goBack
:
any
;
};
const
SwitchBatchFolw
=
(
props
:
ISwitchBatchFolwProps
)
=>
{
const
{
active
,
setActive
,
goBack
}
=
props
;
const
{
active
,
setActive
,
goBack
,
topImg
,
bottomImg
,
type
}
=
props
;
return
(
<
div
className=
{
style
.
switchBatchFolw
}
>
<
div
className=
{
style
.
goBackBox
}
>
...
...
@@ -24,40 +36,45 @@ const SwitchBatchFolw = (props: ISwitchBatchFolwProps) => {
<
span
className=
{
style
.
goBackText
}
>
返回
</
span
>
</
div
>
<
div
className=
{
style
.
switchBox
}
>
<
div
className=
{
classNames
({
[
style
.
switchItem
]:
true
,
[
style
.
activeSwitchItem
]:
active
===
"BATCH"
,
})
}
>
<
img
onClick=
{
()
=>
setActive
(
"BATCH"
)
}
{
/* type为edit 只显示一个 */
}
{
type
===
"edit"
&&
active
!==
"BATCH"
?
null
:
(
<
div
className=
{
classNames
({
[
style
.
itemImg
]:
true
,
[
style
.
active
Img
]:
active
===
"BATCH"
,
[
style
.
switchItem
]:
true
,
[
style
.
active
SwitchItem
]:
active
===
"BATCH"
,
})
}
src=
{
batchImg
}
alt=
""
/>
{
active
===
"BATCH"
&&
<
div
className=
{
style
.
arrow
}
></
div
>
}
</
div
>
<
div
className=
{
classNames
({
[
style
.
switchItem
]:
true
,
[
style
.
activeSwitchItem
]:
active
===
"FLOW"
,
})
}
>
<
img
onClick=
{
()
=>
setActive
(
"FLOW"
)
}
>
<
img
onClick=
{
()
=>
setActive
(
"BATCH"
)
}
className=
{
classNames
({
[
style
.
itemImg
]:
true
,
[
style
.
activeImg
]:
active
===
"BATCH"
,
})
}
src=
{
topImg
||
batchImg
}
alt=
""
/>
{
active
===
"BATCH"
&&
<
div
className=
{
style
.
arrow
}
></
div
>
}
</
div
>
)
}
{
type
===
"edit"
&&
active
!==
"FLOW"
?
null
:
(
<
div
className=
{
classNames
({
[
style
.
itemImg
]:
true
,
[
style
.
active
Img
]:
active
===
"FLOW"
,
[
style
.
switchItem
]:
true
,
[
style
.
active
SwitchItem
]:
active
===
"FLOW"
,
})
}
src=
{
flowImg
}
alt=
""
/>
{
active
===
"FLOW"
&&
<
div
className=
{
style
.
arrow
}
></
div
>
}
</
div
>
>
<
img
onClick=
{
()
=>
setActive
(
"FLOW"
)
}
className=
{
classNames
({
[
style
.
itemImg
]:
true
,
[
style
.
activeImg
]:
active
===
"FLOW"
,
})
}
src=
{
bottomImg
||
flowImg
}
alt=
""
/>
{
active
===
"FLOW"
&&
<
div
className=
{
style
.
arrow
}
></
div
>
}
</
div
>
)
}
</
div
>
</
div
>
);
...
...
src/views/WorkFlowEdit/components/OperatorList/index.tsx
View file @
541232f3
import
{
OutlinedInput
}
from
"@mui/material"
;
import
SearchIcon
from
"@mui/icons-material/Search"
;
import
classNames
from
"classnames"
;
import
{
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
toJS
}
from
"mobx"
;
import
cloneDeep
from
"lodash/cloneDeep"
;
import
{
IOperatorItemProps
,
IOperatorListProps
}
from
"./interface"
;
...
...
@@ -11,7 +8,6 @@ import { ITask } from "@/views/Project/ProjectSubmitWork/interface";
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
IResponse
}
from
"@/api/http"
;
import
{
fetchOperatorList
}
from
"@/api/workbench_api"
;
import
{
useStores
}
from
"@/store"
;
import
noTemplate
from
"@/assets/project/noTemplate.svg"
;
import
SearchInput
from
"@/components/BusinessComponents/SearchInput"
;
...
...
@@ -158,10 +154,12 @@ const OperatorItem = (props: IOperatorItemProps) => {
};
const
OperatorList
=
observer
((
props
:
IOperatorListProps
)
=>
{
const
{
currentProjectStore
}
=
useStores
();
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
{
templateConfigInfo
,
setTemplateConfigInfo
,
showCustomOperator
}
=
props
;
const
{
templateConfigInfo
,
productId
,
setTemplateConfigInfo
,
showCustomOperator
,
}
=
props
;
const
[
operatorListData
,
setOperatorListData
]
=
useState
<
ITask
[]
>
([]);
const
[
keyword
,
setKeyword
]
=
useState
<
string
>
(
""
);
...
...
src/views/WorkFlowEdit/components/OperatorList/interface.ts
View file @
541232f3
...
...
@@ -20,4 +20,5 @@ export interface IOperatorListProps {
templateConfigInfo
:
ITask
[]
setTemplateConfigInfo
:
(
val
:
ITask
[])
=>
void
showCustomOperator
:
boolean
productId
:
string
}
\ No newline at end of file
src/views/WorkFlowEdit/components/SaveCustomTemplate/index.tsx
View file @
541232f3
...
...
@@ -12,11 +12,9 @@ import MyInput from "@/components/mui/MyInput";
import
{
checkIsNumberLetterChinese
}
from
"@/utils/util"
;
import
{
useState
}
from
"react"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
useStores
}
from
"@/store"
;
import
styles
from
"./index.module.css"
;
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
{
toJS
}
from
"mobx"
;
import
{
ITask
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
interface
IProps
{
saveFormDialog
:
boolean
;
...
...
@@ -32,6 +30,7 @@ interface IProps {
creator
?:
string
;
templateConfigInfo
:
ITask
[];
id
?:
string
;
productId
:
string
;
}
const
SaveCustomTemplate
=
(
props
:
IProps
)
=>
{
const
{
...
...
@@ -48,10 +47,9 @@ const SaveCustomTemplate = (props: IProps) => {
templateConfigInfo
,
creator
,
id
,
productId
,
}
=
props
;
const
{
currentProjectStore
}
=
useStores
();
const
Message
=
useMessage
();
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
[
titleHelper
,
setTitleHelper
]
=
useState
({
// 自定义模板名称错误提示
error
:
false
,
...
...
@@ -192,25 +190,25 @@ const SaveCustomTemplate = (props: IProps) => {
// 表单弹窗确定,新建/编辑自定义模板保存
const
handleOncofirm
=
()
=>
{
if
(
checkTitle
(
title
)
&&
checkVersion
(
version
))
{
if
(
id
)
{
saveUserSpecRun
({
title
,
version
,
description
,
tasks
:
templateConfigInfo
,
productId
,
id
,
creator
,
});
}
else
{
saveUserSpecRun
({
title
,
version
,
description
,
tasks
:
templateConfigInfo
,
productId
,
});
}
//
if (id) {
//
saveUserSpecRun({
//
title,
//
version,
//
description,
//
tasks: templateConfigInfo,
//
productId,
//
id,
//
creator,
//
});
//
} else {
saveUserSpecRun
({
title
,
version
,
description
,
tasks
:
templateConfigInfo
,
productId
,
});
//
}
}
};
...
...
src/views/WorkFlowEdit/index.tsx
View file @
541232f3
...
...
@@ -45,14 +45,18 @@ const radioOptions = [
interface
IProps
{
onBack
?:
()
=>
void
;
id
?:
string
;
propsProductId
?:
string
;
}
const
WorkFlowEdit
=
observer
((
props
:
IProps
)
=>
{
const
{
onBack
,
id
}
=
props
;
const
{
onBack
,
id
,
propsProductId
}
=
props
;
const
Message
=
useMessage
();
const
[
templateConfigInfo
,
setTemplateConfigInfo
]
=
useState
<
ITask
[]
>
([]);
// 算子大数组
const
[
showCustomOperator
,
setShowCustomOperator
]
=
useState
(
false
);
// 是否显示自定义算子
const
{
currentProjectStore
}
=
useStores
();
const
productId
=
propsProductId
?
propsProductId
:
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
zoneId
=
toJS
(
currentProjectStore
.
currentProjectInfo
.
zoneId
);
const
[
saveFormDialog
,
setSaveFormDialog
]
=
useState
(
false
);
// 保存弹窗显示与否控制
const
[
title
,
setTitle
]
=
useState
(
""
);
// 自定义模板名称
...
...
@@ -274,6 +278,7 @@ const WorkFlowEdit = observer((props: IProps) => {
showCustomOperator=
{
showCustomOperator
}
templateConfigInfo=
{
templateConfigInfo
}
setTemplateConfigInfo=
{
setTemplateConfigInfo
}
productId=
{
productId
as
string
}
/>
)
}
{
leftContentType
!==
"list"
&&
(
...
...
@@ -333,6 +338,7 @@ const WorkFlowEdit = observer((props: IProps) => {
templateConfigInfo=
{
templateConfigInfo
}
id=
{
id
}
oldversion=
{
oldversion
}
productId=
{
productId
as
string
}
/>
)
}
{
showCustomOperator
&&
(
...
...
@@ -341,6 +347,7 @@ const WorkFlowEdit = observer((props: IProps) => {
initOperatorList=
{
JSON
.
parse
(
sessionStorage
.
getItem
(
"operatorList"
)
||
"[]"
)
}
productId=
{
productId
as
string
}
/>
)
}
</
div
>
...
...
src/views/demo/CardTableDemo/index.tsx
View file @
541232f3
import
CardTable
from
"@/components/CommonComponents/CardTable"
;
const
CardTableDemo
=
()
=>
{
return
<
div
>
CardTableDemo
</
div
>;
const
list
=
[
{
id
:
1
,
},
{
id
:
2
,
},
{
id
:
3
,
},
{
id
:
4
,
},
{
id
:
5
,
},
{
id
:
6
,
},
{
id
:
7
,
},
{
id
:
8
,
},
{
id
:
9
,
},
{
id
:
10
,
},
{
id
:
11
,
},
{
id
:
12
,
},
{
id
:
13
,
},
];
const
renderItem
=
(
item
:
any
)
=>
{
return
(
<
div
style=
{
{
border
:
"1px solid red"
,
height
:
"200px"
}
}
>
{
item
.
id
}
</
div
>
);
};
return
(
<
div
>
CardTableDemo
<
CardTable
data=
{
list
}
renderItem=
{
renderItem
}
numberOfColumns=
{
4
}
></
CardTable
>
</
div
>
);
};
export
default
CardTableDemo
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment