Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dlink
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
zhaowei
dlink
Commits
cab944cb
Unverified
Commit
cab944cb
authored
Jul 21, 2022
by
JPengCheng
Committed by
GitHub
Jul 21, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature][admin,web] Add import and export tasks json (#749)
parent
c12cdbd3
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
445 additions
and
33 deletions
+445
-33
TaskController.java
...in/src/main/java/com/dlink/controller/TaskController.java
+26
-0
Catalogue.java
dlink-admin/src/main/java/com/dlink/model/Catalogue.java
+11
-0
Task.java
dlink-admin/src/main/java/com/dlink/model/Task.java
+45
-0
CatalogueService.java
...min/src/main/java/com/dlink/service/CatalogueService.java
+2
-0
TaskService.java
dlink-admin/src/main/java/com/dlink/service/TaskService.java
+8
-0
CatalogueServiceImpl.java
...ain/java/com/dlink/service/impl/CatalogueServiceImpl.java
+23
-0
TaskServiceImpl.java
...src/main/java/com/dlink/service/impl/TaskServiceImpl.java
+209
-30
crud.ts
dlink-web/src/components/Common/crud.ts
+15
-0
index.tsx
dlink-web/src/components/Studio/StudioTree/index.tsx
+106
-3
No files found.
dlink-admin/src/main/java/com/dlink/controller/TaskController.java
View file @
cab944cb
...
...
@@ -30,6 +30,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -228,5 +229,30 @@ public class TaskController {
public
Result
getTaskAPIAddress
()
{
return
Result
.
succeed
(
taskService
.
getTaskAPIAddress
(),
"重启成功"
);
}
/**
* 导出json
*/
@GetMapping
(
value
=
"/exportJsonByTaskId"
)
public
Result
exportJsonByTaskId
(
@RequestParam
Integer
id
)
{
return
Result
.
succeed
(
taskService
.
exportJsonByTaskId
(
id
),
"获取成功"
);
}
/**
* 导出json数组
*/
@PostMapping
(
value
=
"/exportJsonByTaskIds"
)
public
Result
exportJsonByTaskIds
(
@RequestBody
JsonNode
para
)
{
return
Result
.
succeed
(
taskService
.
exportJsonByTaskIds
(
para
),
"获取成功"
);
}
/**
* json文件上传 导入task
*/
@PostMapping
(
value
=
"/uploadTaskJson"
)
public
Result
uploadTaskJson
(
@RequestParam
(
"file"
)
MultipartFile
file
)
throws
Exception
{
return
taskService
.
uploadTaskJson
(
file
);
}
}
dlink-admin/src/main/java/com/dlink/model/Catalogue.java
View file @
cab944cb
...
...
@@ -45,4 +45,15 @@ public class Catalogue extends SuperEntity {
private
Integer
parentId
;
private
Boolean
isLeaf
;
public
Catalogue
()
{
}
public
Catalogue
(
String
name
,
Integer
taskId
,
String
type
,
Integer
parentId
,
Boolean
isLeaf
)
{
this
.
setName
(
name
);
this
.
taskId
=
taskId
;
this
.
type
=
type
;
this
.
parentId
=
parentId
;
this
.
isLeaf
=
isLeaf
;
}
}
dlink-admin/src/main/java/com/dlink/model/Task.java
View file @
cab944cb
...
...
@@ -27,7 +27,9 @@ import com.dlink.assertion.Asserts;
import
com.dlink.db.model.SuperEntity
;
import
com.dlink.job.JobConfig
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
...
...
@@ -104,6 +106,23 @@ public class Task extends SuperEntity {
@TableField
(
exist
=
false
)
private
List
<
Map
<
String
,
String
>>
config
=
new
ArrayList
<>();
@TableField
(
exist
=
false
)
private
String
path
;
@TableField
(
exist
=
false
)
private
String
jarName
;
@TableField
(
exist
=
false
)
private
String
clusterConfigurationName
;
@TableField
(
exist
=
false
)
private
String
databaseName
;
@TableField
(
exist
=
false
)
private
String
envName
;
@TableField
(
exist
=
false
)
private
String
alertGroupName
;
public
List
<
Map
<
String
,
String
>>
parseConfig
()
{
ObjectMapper
objectMapper
=
new
ObjectMapper
();
...
...
@@ -135,4 +154,30 @@ public class Task extends SuperEntity {
alias
,
fg
,
sts
,
batchModel
,
checkPoint
,
parallelism
,
savePointStrategy
,
savePointPath
,
map
);
}
public
JsonNode
parseJsonNode
(){
ObjectMapper
mapper
=
new
ObjectMapper
();
return
parseJsonNode
(
mapper
);
}
public
JsonNode
parseJsonNode
(
ObjectMapper
mapper
){
JsonNode
jsonNode
=
mapper
.
createObjectNode
();
((
ObjectNode
)
jsonNode
).
put
(
"name"
,
this
.
getName
());
((
ObjectNode
)
jsonNode
).
put
(
"alias"
,
this
.
alias
);
((
ObjectNode
)
jsonNode
).
put
(
"dialect"
,
this
.
dialect
);
((
ObjectNode
)
jsonNode
).
put
(
"type"
,
this
.
type
);
((
ObjectNode
)
jsonNode
).
put
(
"statement"
,
this
.
statement
);
((
ObjectNode
)
jsonNode
).
put
(
"checkPoint"
,
this
.
checkPoint
);
((
ObjectNode
)
jsonNode
).
put
(
"savePointStrategy"
,
this
.
savePointStrategy
);
((
ObjectNode
)
jsonNode
).
put
(
"savePointPath"
,
this
.
savePointPath
);
((
ObjectNode
)
jsonNode
).
put
(
"parallelism"
,
this
.
parallelism
);
((
ObjectNode
)
jsonNode
).
put
(
"fragment"
,
this
.
fragment
);
((
ObjectNode
)
jsonNode
).
put
(
"statementSet"
,
this
.
statementSet
);
((
ObjectNode
)
jsonNode
).
put
(
"batchModel"
,
this
.
batchModel
);
((
ObjectNode
)
jsonNode
).
put
(
"clusterName"
,
this
.
clusterName
);
((
ObjectNode
)
jsonNode
).
put
(
"configJson"
,
this
.
configJson
);
((
ObjectNode
)
jsonNode
).
put
(
"note"
,
this
.
note
);
((
ObjectNode
)
jsonNode
).
put
(
"step"
,
this
.
step
);
((
ObjectNode
)
jsonNode
).
put
(
"enabled"
,
this
.
getEnabled
());
return
jsonNode
;
}
}
dlink-admin/src/main/java/com/dlink/service/CatalogueService.java
View file @
cab944cb
...
...
@@ -49,4 +49,6 @@ public interface CatalogueService extends ISuperService<Catalogue> {
boolean
moveCatalogue
(
Integer
id
,
Integer
parentId
);
boolean
copyTask
(
Catalogue
catalogue
);
Integer
addDependCatalogue
(
String
[]
catalogueNames
);
}
dlink-admin/src/main/java/com/dlink/service/TaskService.java
View file @
cab944cb
...
...
@@ -29,6 +29,8 @@ import com.dlink.model.JobInfoDetail;
import
com.dlink.model.JobInstance
;
import
com.dlink.model.Task
;
import
com.dlink.result.SqlExplainResult
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.List
;
...
...
@@ -85,4 +87,10 @@ public interface TaskService extends ISuperService<Task> {
Result
rollbackTask
(
TaskRollbackVersionDTO
dto
);
Integer
queryAllSizeByName
(
String
name
);
String
exportJsonByTaskId
(
Integer
taskId
);
String
exportJsonByTaskIds
(
JsonNode
para
);
Result
uploadTaskJson
(
MultipartFile
file
)
throws
Exception
;
}
dlink-admin/src/main/java/com/dlink/service/impl/CatalogueServiceImpl.java
View file @
cab944cb
...
...
@@ -23,7 +23,9 @@ package com.dlink.service.impl;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.dlink.assertion.Asserts
;
import
com.dlink.db.service.impl.SuperServiceImpl
;
import
com.dlink.dto.CatalogueTaskDTO
;
import
com.dlink.mapper.CatalogueMapper
;
...
...
@@ -34,6 +36,7 @@ import com.dlink.model.Task;
import
com.dlink.service.CatalogueService
;
import
com.dlink.service.StatementService
;
import
com.dlink.service.TaskService
;
import
org.apache.kafka.common.internals.Topic
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -192,4 +195,24 @@ public class CatalogueServiceImpl extends SuperServiceImpl<CatalogueMapper, Cata
return
this
.
save
(
catalogue
);
}
@Override
public
Integer
addDependCatalogue
(
String
[]
catalogueNames
){
Integer
parentId
=
0
;
for
(
int
i
=
0
;
i
<
catalogueNames
.
length
-
1
;
i
++)
{
String
catalogueName
=
catalogueNames
[
i
];
Catalogue
catalogue
=
getOne
(
new
QueryWrapper
<
Catalogue
>().
eq
(
"name"
,
catalogueName
).
eq
(
"parent_id"
,
parentId
).
last
(
" limit 1"
));
if
(
Asserts
.
isNotNull
(
catalogue
))
{
parentId
=
catalogue
.
getId
();
continue
;
}
catalogue
=
new
Catalogue
();
catalogue
.
setName
(
catalogueName
);
catalogue
.
setParentId
(
parentId
);
catalogue
.
setIsLeaf
(
false
);
this
.
save
(
catalogue
);
parentId
=
catalogue
.
getId
();
}
return
parentId
;
}
}
dlink-admin/src/main/java/com/dlink/service/impl/TaskServiceImpl.java
View file @
cab944cb
This diff is collapsed.
Click to expand it.
dlink-web/src/components/Common/crud.ts
View file @
cab944cb
...
...
@@ -208,6 +208,21 @@ export const handleOption = async (url:string,title:string,param:any) => {
}
};
export
const
handleData
=
async
(
url
:
string
,
id
:
any
)
=>
{
try
{
const
{
code
,
datas
,
msg
}
=
await
getData
(
url
,
id
);
if
(
code
==
CODE
.
SUCCESS
){
return
datas
;
}
else
{
message
.
warn
(
msg
);
return
false
;
}
}
catch
(
error
)
{
message
.
error
(
'获取失败,请重试'
);
return
false
;
}
};
export
const
handleInfo
=
async
(
url
:
string
,
id
:
number
)
=>
{
try
{
const
{
datas
}
=
await
getInfoById
(
url
,
id
);
...
...
dlink-web/src/components/Studio/StudioTree/index.tsx
View file @
cab944cb
...
...
@@ -20,14 +20,21 @@
import
React
,
{
useEffect
,
useState
,
Key
}
from
"react"
;
import
{
connect
}
from
"umi"
;
import
{
DownOutlined
,
SwitcherOutlined
,
FolderAddOutlined
}
from
"@ant-design/icons"
;
import
{
Tree
,
Menu
,
Empty
,
Button
,
message
,
Modal
,
Tooltip
,
Row
,
Col
,
Input
}
from
'antd'
;
import
{
DownOutlined
,
SwitcherOutlined
,
FolderAddOutlined
,
UploadOutlined
,
DownloadOutlined
}
from
"@ant-design/icons"
;
import
{
Tree
,
Menu
,
Empty
,
Button
,
message
,
Modal
,
Tooltip
,
Row
,
Col
,
Input
,
Upload
}
from
'antd'
;
import
type
{
UploadProps
}
from
'antd'
;
import
{
getCatalogueTreeData
}
from
"@/pages/DataStudio/service"
;
import
{
convertToTreeData
,
getTreeNodeByKey
,
TreeDataNode
}
from
"@/components/Studio/StudioTree/Function"
;
import
style
from
"./index.less"
;
import
{
StateType
}
from
"@/pages/DataStudio/model"
;
import
{
getInfoById
,
handleAddOrUpdate
,
handleAddOrUpdateWithResult
,
handleOption
,
handleRemoveById
,
handleSubmit
handleData
,
getInfoById
,
handleAddOrUpdate
,
handleAddOrUpdateWithResult
,
handleOption
,
handleRemoveById
,
handleSubmit
,
CODE
,
postAll
,
}
from
"@/components/Common/crud"
;
import
UpdateCatalogueForm
from
'./components/UpdateCatalogueForm'
;
import
SimpleTaskForm
from
"@/components/Studio/StudioTree/components/SimpleTaskForm"
;
...
...
@@ -104,6 +111,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const
[
searchValue
,
setSearchValue
]
=
useState
(
''
);
const
[
autoExpandParent
,
setAutoExpandParent
]
=
useState
(
true
);
const
[
cutId
,
setCutId
]
=
useState
<
number
|
undefined
>
(
undefined
);
const
[
exportTaskIds
,
setExportTaskIds
]
=
useState
<
any
[]
>
([]);
const
getTreeData
=
async
()
=>
{
const
result
=
await
getCatalogueTreeData
();
...
...
@@ -123,6 +131,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
//默认展开所有
setExpandedKeys
(
expendList
||
[]);
setDefaultExpandedKeys
(
expendList
||
[]);
setExportTaskIds
([]);
};
const
onChange
=
(
e
:
any
)
=>
{
...
...
@@ -192,6 +201,8 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
toPaste
(
rightClickNode
);
}
else
if
(
key
==
'Copy'
)
{
toCopy
(
rightClickNode
);
}
else
if
(
key
==
'ExportJson'
)
{
toExportJson
(
rightClickNode
);
}
};
...
...
@@ -340,6 +351,54 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}
};
const
toExportJson
=
async
(
node
:
TreeDataNode
|
undefined
)
=>
{
let
taskId
=
node
?.
taskId
;
const
datas
=
await
handleData
(
'/api/task/exportJsonByTaskId'
,{
id
:
taskId
});
if
(
datas
)
{
let
data
=
JSON
.
parse
(
datas
);
saveJSON
(
data
,
data
.
alias
);
message
.
success
(
'导出json成功'
);
}
};
const
toExportSelectedTaskJson
=
async
()
=>
{
if
(
exportTaskIds
.
length
<=
0
)
{
message
.
warn
(
"请先选择要导出的作业"
);
}
else
{
try
{
const
{
code
,
datas
,
msg
}
=
await
postAll
(
'/api/task/exportJsonByTaskIds'
,
{
taskIds
:
exportTaskIds
});
if
(
code
==
CODE
.
SUCCESS
)
{
saveJSON
(
datas
);
message
.
success
(
'导出json成功'
);
}
else
{
message
.
warn
(
msg
);
}
}
catch
(
error
)
{
message
.
error
(
'获取失败,请重试'
);
}
}
}
const
saveJSON
=
(
data
:
any
,
filename
?:
any
)
=>
{
if
(
!
data
)
{
message
.
error
(
"保存的json数据为空"
);
return
;
}
if
(
!
filename
)
filename
=
new
Date
().
toLocaleDateString
().
replaceAll
(
"/"
,
"-"
);
if
(
typeof
data
===
'object'
)
{
data
=
JSON
.
stringify
(
data
,
undefined
,
4
)
}
let
blob
=
new
Blob
([
data
],
{
type
:
'text/json'
}),
e
=
document
.
createEvent
(
'MouseEvents'
),
a
=
document
.
createElement
(
'a'
)
a
.
download
=
filename
+
'.json'
a
.
href
=
window
.
URL
.
createObjectURL
(
blob
)
a
.
dataset
.
downloadurl
=
[
'text/json'
,
a
.
download
,
a
.
href
].
join
(
':'
)
e
.
initMouseEvent
(
'click'
,
true
,
false
,
window
,
0
,
0
,
0
,
0
,
0
,
false
,
false
,
false
,
false
,
0
,
null
)
a
.
dispatchEvent
(
e
)
}
const
createTask
=
(
node
:
TreeDataNode
|
undefined
)
=>
{
if
(
!
node
?.
isLeaf
)
{
handleUpdateTaskModalVisible
(
true
);
...
...
@@ -384,6 +443,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
menuItems = (<>
<Menu.Item key='Open'>{'打开'}</Menu.Item>
<Menu.Item key='Submit'>{'异步提交'}</Menu.Item>
<Menu.Item key='ExportJson'>{'导出Json'}</Menu.Item>
<Menu.Item key='Rename'>{'重命名'}</Menu.Item>
<Menu.Item key='Copy'>{'复制'}</Menu.Item>
<Menu.Item key='Cut'>{'剪切'}</Menu.Item>
...
...
@@ -462,6 +522,13 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
});
toOpen(e.node);
}
let taskIds = [];
for (let i = 0; i < e.selectedNodes.length; i++) {
if(e.selectedNodes[i].isLeaf){
taskIds.push(e.selectedNodes[i].taskId);
}
}
setExportTaskIds(taskIds);
};
const offExpandAll = () => {
...
...
@@ -517,6 +584,27 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
};
});
const uProps: UploadProps = {
name: 'file',
action: '/api/task/uploadTaskJson',
accept: 'application/json',
headers: {
authorization: 'authorization-text',
},
onChange(info) {
if (info.file.status === 'done') {
if(info.file.response.code == CODE.SUCCESS){
message.success(info.file.response.msg);
}else{
message.warn(info.file.response.msg);
}
getTreeData();
} else if (info.file.status === 'error') {
message.error(`
$
{
info
.
file
.
name
}
上传失败
`);
}
},
};
return (
<div className={style.tree_div}>
<Row>
...
...
@@ -535,6 +623,21 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
onClick={offExpandAll}
/>
</Tooltip>
<Tooltip title="导出json">
<Button
type="text"
icon={<DownloadOutlined />}
onClick={toExportSelectedTaskJson}
/>
</Tooltip>
<Upload {...uProps}>
<Tooltip title="导入json">
<Button
type="text"
icon={<UploadOutlined/>}
/>
</Tooltip>
</Upload>
</Col>
</Row>
<Search style={{marginBottom: 8}} placeholder="Search" onChange={onChange} allowClear={true}/>
...
...
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