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
9f684bbb
Commit
9f684bbb
authored
Nov 19, 2021
by
wenmo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
系统配置界面
parent
28c5e425
Changes
47
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
47 changed files
with
431 additions
and
3527 deletions
+431
-3527
SysConfigController.java
...c/main/java/com/dlink/controller/SysConfigController.java
+9
-6
SysConfigService.java
...min/src/main/java/com/dlink/service/SysConfigService.java
+4
-0
SysConfigServiceImpl.java
...ain/java/com/dlink/service/impl/SysConfigServiceImpl.java
+9
-6
SystemConfiguration.java
...on/src/main/java/com/dlink/model/SystemConfiguration.java
+14
-0
routes.ts
dlink-web/config/routes.ts
+19
-107
index.tsx
dlink-web/src/components/Studio/index.tsx
+2
-0
menu.ts
dlink-web/src/locales/zh-CN/menu.ts
+1
-1
_mock.ts
dlink-web/src/pages/Demo/FormAdvancedForm/_mock.ts
+0
-8
TableForm.tsx
.../src/pages/Demo/FormAdvancedForm/components/TableForm.tsx
+0
-257
index.tsx
dlink-web/src/pages/Demo/FormAdvancedForm/index.tsx
+0
-305
model.ts
dlink-web/src/pages/Demo/FormAdvancedForm/model.ts
+0
-26
service.ts
dlink-web/src/pages/Demo/FormAdvancedForm/service.ts
+0
-8
style.less
dlink-web/src/pages/Demo/FormAdvancedForm/style.less
+0
-65
_mock.ts
dlink-web/src/pages/Demo/FormStepForm/_mock.ts
+0
-8
index.less
...b/src/pages/Demo/FormStepForm/components/Step1/index.less
+0
-78
index.tsx
...eb/src/pages/Demo/FormStepForm/components/Step1/index.tsx
+0
-133
index.less
...b/src/pages/Demo/FormStepForm/components/Step2/index.less
+0
-78
index.tsx
...eb/src/pages/Demo/FormStepForm/components/Step2/index.tsx
+0
-123
index.less
...b/src/pages/Demo/FormStepForm/components/Step3/index.less
+0
-71
index.tsx
...eb/src/pages/Demo/FormStepForm/components/Step3/index.tsx
+0
-62
index.tsx
dlink-web/src/pages/Demo/FormStepForm/index.tsx
+0
-57
en-US.ts
dlink-web/src/pages/Demo/FormStepForm/locales/en-US.ts
+0
-62
pt-BR.ts
dlink-web/src/pages/Demo/FormStepForm/locales/pt-BR.ts
+0
-58
zh-CN.ts
dlink-web/src/pages/Demo/FormStepForm/locales/zh-CN.ts
+0
-59
zh-TW.ts
dlink-web/src/pages/Demo/FormStepForm/locales/zh-TW.ts
+0
-59
model.ts
dlink-web/src/pages/Demo/FormStepForm/model.ts
+0
-74
service.ts
dlink-web/src/pages/Demo/FormStepForm/service.ts
+0
-8
style.less
dlink-web/src/pages/Demo/FormStepForm/style.less
+0
-90
_mock.ts
dlink-web/src/pages/Demo/ListBasicList/_mock.ts
+0
-152
OperationModal.tsx
...rc/pages/Demo/ListBasicList/components/OperationModal.tsx
+0
-130
data.d.ts
dlink-web/src/pages/Demo/ListBasicList/data.d.ts
+0
-29
index.tsx
dlink-web/src/pages/Demo/ListBasicList/index.tsx
+0
-281
model.ts
dlink-web/src/pages/Demo/ListBasicList/model.ts
+0
-77
service.ts
dlink-web/src/pages/Demo/ListBasicList/service.ts
+0
-54
style.less
dlink-web/src/pages/Demo/ListBasicList/style.less
+0
-195
utils.less
dlink-web/src/pages/Demo/ListBasicList/utils/utils.less
+0
-50
_mock.ts
dlink-web/src/pages/Demo/ListTableList/_mock.ts
+0
-169
CreateForm.tsx
...eb/src/pages/Demo/ListTableList/components/CreateForm.tsx
+0
-25
UpdateForm.tsx
...eb/src/pages/Demo/ListTableList/components/UpdateForm.tsx
+0
-214
data.d.ts
dlink-web/src/pages/Demo/ListTableList/data.d.ts
+0
-36
index.tsx
dlink-web/src/pages/Demo/ListTableList/index.tsx
+0
-268
service.ts
dlink-web/src/pages/Demo/ListTableList/service.ts
+0
-38
flinkConfig.tsx
dlink-web/src/pages/Settings/components/flinkConfig.tsx
+104
-0
function.ts
dlink-web/src/pages/Settings/function.ts
+23
-0
index.tsx
dlink-web/src/pages/Settings/index.tsx
+111
-0
model.ts
dlink-web/src/pages/Settings/model.ts
+42
-0
style.less
dlink-web/src/pages/Settings/style.less
+93
-0
No files found.
dlink-admin/src/main/java/com/dlink/controller/SysConfigController.java
View file @
9f684bbb
...
@@ -7,12 +7,7 @@ import com.dlink.service.SysConfigService;
...
@@ -7,12 +7,7 @@ import com.dlink.service.SysConfigService;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.DeleteMapping
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.PutMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -82,6 +77,14 @@ public class SysConfigController {
...
@@ -82,6 +77,14 @@ public class SysConfigController {
return
Result
.
succeed
(
sysConfig
,
"获取成功"
);
return
Result
.
succeed
(
sysConfig
,
"获取成功"
);
}
}
/**
* 获取所有配置
*/
@GetMapping
(
"/getAll"
)
public
Result
getAll
()
{
return
Result
.
succeed
(
sysConfigService
.
getAll
(),
"获取成功"
);
}
/**
/**
* 批量更新配置
* 批量更新配置
*/
*/
...
...
dlink-admin/src/main/java/com/dlink/service/SysConfigService.java
View file @
9f684bbb
...
@@ -4,6 +4,8 @@ import com.dlink.db.service.ISuperService;
...
@@ -4,6 +4,8 @@ import com.dlink.db.service.ISuperService;
import
com.dlink.model.SysConfig
;
import
com.dlink.model.SysConfig
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
java.util.Map
;
/**
/**
* SysConfig
* SysConfig
*
*
...
@@ -12,6 +14,8 @@ import com.fasterxml.jackson.databind.JsonNode;
...
@@ -12,6 +14,8 @@ import com.fasterxml.jackson.databind.JsonNode;
**/
**/
public
interface
SysConfigService
extends
ISuperService
<
SysConfig
>
{
public
interface
SysConfigService
extends
ISuperService
<
SysConfig
>
{
Map
<
String
,
String
>
getAll
();
void
initSysConfig
();
void
initSysConfig
();
void
updateSysConfigByJson
(
JsonNode
node
);
void
updateSysConfigByJson
(
JsonNode
node
);
...
...
dlink-admin/src/main/java/com/dlink/service/impl/SysConfigServiceImpl.java
View file @
9f684bbb
...
@@ -29,16 +29,19 @@ public class SysConfigServiceImpl extends SuperServiceImpl<SysConfigMapper, SysC
...
@@ -29,16 +29,19 @@ public class SysConfigServiceImpl extends SuperServiceImpl<SysConfigMapper, SysC
private
static
final
ObjectMapper
mapper
=
new
ObjectMapper
();
private
static
final
ObjectMapper
mapper
=
new
ObjectMapper
();
@Override
@Override
public
void
initSysConfig
()
{
public
Map
<
String
,
String
>
getAll
()
{
List
<
SysConfig
>
sysConfigs
=
list
();
if
(
sysConfigs
.
size
()==
0
){
return
;
}
Map
<
String
,
String
>
map
=
new
HashMap
<>();
Map
<
String
,
String
>
map
=
new
HashMap
<>();
List
<
SysConfig
>
sysConfigs
=
list
();
for
(
SysConfig
item
:
sysConfigs
){
for
(
SysConfig
item
:
sysConfigs
){
map
.
put
(
item
.
getName
(),
item
.
getValue
());
map
.
put
(
item
.
getName
(),
item
.
getValue
());
}
}
SystemConfiguration
.
getInstances
().
setConfiguration
(
mapper
.
valueToTree
(
map
));
SystemConfiguration
.
getInstances
().
addConfiguration
(
map
);
return
map
;
}
@Override
public
void
initSysConfig
()
{
SystemConfiguration
.
getInstances
().
setConfiguration
(
mapper
.
valueToTree
(
getAll
()));
}
}
@Override
@Override
...
...
dlink-common/src/main/java/com/dlink/model/SystemConfiguration.java
View file @
9f684bbb
...
@@ -2,6 +2,8 @@ package com.dlink.model;
...
@@ -2,6 +2,8 @@ package com.dlink.model;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
java.util.Map
;
/**
/**
* SystemConfiguration
* SystemConfiguration
*
*
...
@@ -49,6 +51,18 @@ public class SystemConfiguration {
...
@@ -49,6 +51,18 @@ public class SystemConfiguration {
}
}
}
}
public
void
addConfiguration
(
Map
<
String
,
String
>
map
){
if
(!
map
.
containsKey
(
"sqlSubmitJarPath"
)){
map
.
put
(
"sqlSubmitJarPath"
,
sqlSubmitJarPath
.
getValue
().
toString
());
}
if
(!
map
.
containsKey
(
"sqlSubmitJarParas"
)){
map
.
put
(
"sqlSubmitJarParas"
,
sqlSubmitJarParas
.
getValue
().
toString
());
}
if
(!
map
.
containsKey
(
"sqlSubmitJarMainAppClass"
)){
map
.
put
(
"sqlSubmitJarMainAppClass"
,
sqlSubmitJarMainAppClass
.
getValue
().
toString
());
}
}
public
String
getSqlSubmitJarParas
()
{
public
String
getSqlSubmitJarParas
()
{
return
sqlSubmitJarParas
.
getValue
().
toString
();
return
sqlSubmitJarParas
.
getValue
().
toString
();
}
}
...
...
dlink-web/config/routes.ts
View file @
9f684bbb
...
@@ -31,38 +31,39 @@ export default [
...
@@ -31,38 +31,39 @@ export default [
path
:
'/taskcenter'
,
path
:
'/taskcenter'
,
name
:
'taskcenter'
,
name
:
'taskcenter'
,
icon
:
'partition'
,
icon
:
'partition'
,
routes
:[
routes
:
[
/*{
/*{
path: '/taskcenter/task',
path: '/taskcenter/task',
name: 'task',
name: 'task',
icon: 'task',
icon: 'task',
component: './Task',
component: './Task',
},*/
},*/
{
{
path
:
'/taskcenter/jar'
,
path
:
'/taskcenter/jar'
,
name
:
'jar'
,
name
:
'jar'
,
icon
:
'code-sandbox'
,
icon
:
'code-sandbox'
,
component
:
'./Jar'
,
component
:
'./Jar'
,
}
}
,
]
]
,
},
},
{
{
path
:
'/clusters'
,
path
:
'/clusters'
,
name
:
'clusters'
,
name
:
'clusters'
,
icon
:
'cluster'
,
icon
:
'cluster'
,
routes
:[
routes
:
[
{
{
path
:
'/clusters/cluster'
,
path
:
'/clusters/cluster'
,
name
:
'cluster'
,
name
:
'cluster'
,
icon
:
'cluster'
,
icon
:
'cluster'
,
component
:
'./Cluster'
,
component
:
'./Cluster'
,
},{
},
{
path
:
'/clusters/clusterConfiguration'
,
path
:
'/clusters/clusterConfiguration'
,
name
:
'clusterConfiguration'
,
name
:
'clusterConfiguration'
,
icon
:
'setting'
,
icon
:
'setting'
,
component
:
'./ClusterConfiguration'
,
component
:
'./ClusterConfiguration'
,
}
}
,
]
]
,
},
},
{
{
path
:
'/database'
,
path
:
'/database'
,
...
@@ -76,105 +77,16 @@ export default [
...
@@ -76,105 +77,16 @@ export default [
icon
:
'container'
,
icon
:
'container'
,
component
:
'./Document'
,
component
:
'./Document'
,
},
},
/*{
path: '/dev',
name: 'dev',
icon: 'crown',
routes: [
{
path: '/dev/flink',
name: 'flink',
icon: 'github',
routes: [
{
path: 'https://ci.apache.org/projects/flink/flink-docs-release-1.13/',
name: 'docs',
},
],
},
{
path: '/dev/ant',
name: 'ant-design',
icon: 'antDesign',
routes: [
{
path: 'https://ant.design/components/icon-cn/',
name: 'docs',
},
{
path:
'https://preview.pro.ant.design/dashboard/analysis?primaryColor=%231890ff&fixSiderbar=true&colorWeak=false&pwa=false',
name: 'preview',
},
],
},
],
},*/
/*{
path: '/admin',
name: 'admin',
icon: 'crown',
access: 'canAdmin',
component: './Admin',
routes: [
{
path: '/admin/sub-page',
name: 'sub-page',
icon: 'smile',
component: './Welcome',
},
],
},*/
/*{
path: '/demo',
name: 'demo',
icon: 'crown',
//access: 'canAdmin',
routes: [
{
name: 'list',
icon: 'table',
path: '/demo/list',
routes: [
{
name: 'table-list',
icon: 'table',
path: '/demo/list/listtablelist',
component: './Demo/ListTableList',
},
{
name: 'basic-list',
icon: 'smile',
path: '/demo/list/listbasiclist',
component: './Demo/ListBasicList',
},
],
},
{
name: 'form',
icon: 'smile',
path: '/demo/form',
routes: [
{
name: 'advanced-form',
icon: 'smile',
path: '/demo/form/formadvancedform',
component: './Demo/FormAdvancedForm',
},
{
name: '分步表单',
icon: 'smile',
path: '/demo/form/formstepform',
component: './Demo/FormStepForm',
},
],
},
],
},*/
{
{
path
:
'/'
,
path
:
'/'
,
redirect
:
'/welcome'
,
redirect
:
'/welcome'
,
},
},
{
name
:
'settings'
,
icon
:
'setting'
,
path
:
'/settings'
,
component
:
'./Settings'
,
},
{
{
component
:
'./404'
,
component
:
'./404'
,
},
},
...
...
dlink-web/src/components/Studio/index.tsx
View file @
9f684bbb
...
@@ -15,6 +15,7 @@ import {
...
@@ -15,6 +15,7 @@ import {
listSession
,
showCluster
,
showDataBase
,
getFillAllByVersion
,
listSession
,
showCluster
,
showDataBase
,
getFillAllByVersion
,
showClusterConfiguration
showClusterConfiguration
}
from
"@/components/Studio/StudioEvent/DDL"
;
}
from
"@/components/Studio/StudioEvent/DDL"
;
import
{
loadSettings
}
from
"@/pages/Settings/function"
;
type
StudioProps
=
{
type
StudioProps
=
{
rightClickMenu
:
StateType
[
'rightClickMenu'
];
rightClickMenu
:
StateType
[
'rightClickMenu'
];
...
@@ -25,6 +26,7 @@ const Studio: React.FC<StudioProps> = (props) => {
...
@@ -25,6 +26,7 @@ const Studio: React.FC<StudioProps> = (props) => {
const
{
rightClickMenu
,
dispatch
}
=
props
;
const
{
rightClickMenu
,
dispatch
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
const
[
form
]
=
Form
.
useForm
();
loadSettings
(
dispatch
);
getFillAllByVersion
(
''
,
dispatch
);
getFillAllByVersion
(
''
,
dispatch
);
showCluster
(
dispatch
);
showCluster
(
dispatch
);
showClusterConfiguration
(
dispatch
);
showClusterConfiguration
(
dispatch
);
...
...
dlink-web/src/locales/zh-CN/menu.ts
View file @
9f684bbb
...
@@ -60,7 +60,7 @@ export default {
...
@@ -60,7 +60,7 @@ export default {
'menu.taskcenter.task'
:
'作业管理'
,
'menu.taskcenter.task'
:
'作业管理'
,
'menu.taskcenter.jar'
:
'Jar 管理'
,
'menu.taskcenter.jar'
:
'Jar 管理'
,
'menu.document'
:
'文档中心'
,
'menu.document'
:
'文档中心'
,
'menu.
dev'
:
'Dev 开发者工具
'
,
'menu.
settings'
:
'系统设置
'
,
'menu.dev.flink'
:
'Flink 计算框架'
,
'menu.dev.flink'
:
'Flink 计算框架'
,
'menu.dev.flink.docs'
:
'官方文档'
,
'menu.dev.flink.docs'
:
'官方文档'
,
'menu.dev.ant-design'
:
'Ant Design UI框架'
,
'menu.dev.ant-design'
:
'Ant Design UI框架'
,
...
...
dlink-web/src/pages/Demo/FormAdvancedForm/_mock.ts
deleted
100644 → 0
View file @
28c5e425
// eslint-disable-next-line import/no-extraneous-dependencies
import
type
{
Request
,
Response
}
from
'express'
;
export
default
{
'POST /api/forms'
:
(
_
:
Request
,
res
:
Response
)
=>
{
res
.
send
({
message
:
'Ok'
});
},
};
dlink-web/src/pages/Demo/FormAdvancedForm/components/TableForm.tsx
deleted
100644 → 0
View file @
28c5e425
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
Button
,
Divider
,
Input
,
Popconfirm
,
Table
,
message
}
from
'antd'
;
import
type
{
FC
}
from
'react'
;
import
React
,
{
useState
}
from
'react'
;
import
styles
from
'../style.less'
;
type
TableFormDateType
=
{
key
:
string
;
workId
?:
string
;
name
?:
string
;
department
?:
string
;
isNew
?:
boolean
;
editable
?:
boolean
;
};
type
TableFormProps
=
{
value
?:
TableFormDateType
[];
onChange
?:
(
value
:
TableFormDateType
[])
=>
void
;
};
const
TableForm
:
FC
<
TableFormProps
>
=
({
value
,
onChange
})
=>
{
const
[
clickedCancel
,
setClickedCancel
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
index
,
setIndex
]
=
useState
(
0
);
const
[
cacheOriginData
,
setCacheOriginData
]
=
useState
({});
const
[
data
,
setData
]
=
useState
(
value
);
const
getRowByKey
=
(
key
:
string
,
newData
?:
TableFormDateType
[])
=>
(
newData
||
data
)?.
filter
((
item
)
=>
item
.
key
===
key
)[
0
];
const
toggleEditable
=
(
e
:
React
.
MouseEvent
|
React
.
KeyboardEvent
,
key
:
string
)
=>
{
e
.
preventDefault
();
const
newData
=
data
?.
map
((
item
)
=>
({
...
item
}));
const
target
=
getRowByKey
(
key
,
newData
);
if
(
target
)
{
// 进入编辑状态时保存原始数据
if
(
!
target
.
editable
)
{
cacheOriginData
[
key
]
=
{
...
target
};
setCacheOriginData
(
cacheOriginData
);
}
target
.
editable
=
!
target
.
editable
;
setData
(
newData
);
}
};
const
newMember
=
()
=>
{
const
newData
=
data
?.
map
((
item
)
=>
({
...
item
}))
||
[];
newData
.
push
({
key
:
`NEW_TEMP_ID_
${
index
}
`
,
workId
:
''
,
name
:
''
,
department
:
''
,
editable
:
true
,
isNew
:
true
,
});
setIndex
(
index
+
1
);
setData
(
newData
);
};
const
remove
=
(
key
:
string
)
=>
{
const
newData
=
data
?.
filter
((
item
)
=>
item
.
key
!==
key
)
as
TableFormDateType
[];
setData
(
newData
);
if
(
onChange
)
{
onChange
(
newData
);
}
};
const
handleFieldChange
=
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
,
fieldName
:
string
,
key
:
string
,
)
=>
{
const
newData
=
[...(
data
as
TableFormDateType
[])];
const
target
=
getRowByKey
(
key
,
newData
);
if
(
target
)
{
target
[
fieldName
]
=
e
.
target
.
value
;
setData
(
newData
);
}
};
const
saveRow
=
(
e
:
React
.
MouseEvent
|
React
.
KeyboardEvent
,
key
:
string
)
=>
{
e
.
persist
();
setLoading
(
true
);
setTimeout
(()
=>
{
if
(
clickedCancel
)
{
setClickedCancel
(
false
);
return
;
}
const
target
=
getRowByKey
(
key
)
||
({}
as
any
);
if
(
!
target
.
workId
||
!
target
.
name
||
!
target
.
department
)
{
message
.
error
(
'请填写完整成员信息。'
);
(
e
.
target
as
HTMLInputElement
).
focus
();
setLoading
(
false
);
return
;
}
delete
target
.
isNew
;
toggleEditable
(
e
,
key
);
if
(
onChange
)
{
onChange
(
data
as
TableFormDateType
[]);
}
setLoading
(
false
);
},
500
);
};
const
handleKeyPress
=
(
e
:
React
.
KeyboardEvent
,
key
:
string
)
=>
{
if
(
e
.
key
===
'Enter'
)
{
saveRow
(
e
,
key
);
}
};
const
cancel
=
(
e
:
React
.
MouseEvent
,
key
:
string
)
=>
{
setClickedCancel
(
true
);
e
.
preventDefault
();
const
newData
=
[...(
data
as
TableFormDateType
[])];
// 编辑前的原始数据
let
cacheData
=
[];
cacheData
=
newData
.
map
((
item
)
=>
{
if
(
item
.
key
===
key
)
{
if
(
cacheOriginData
[
key
])
{
const
originItem
=
{
...
item
,
...
cacheOriginData
[
key
],
editable
:
false
,
};
delete
cacheOriginData
[
key
];
setCacheOriginData
(
cacheOriginData
);
return
originItem
;
}
}
return
item
;
});
setData
(
cacheData
);
setClickedCancel
(
false
);
};
const
columns
=
[
{
title
:
'成员姓名'
,
dataIndex
:
'name'
,
key
:
'name'
,
width
:
'20%'
,
render
:
(
text
:
string
,
record
:
TableFormDateType
)
=>
{
if
(
record
.
editable
)
{
return
(
<
Input
value=
{
text
}
autoFocus
onChange=
{
(
e
)
=>
handleFieldChange
(
e
,
'name'
,
record
.
key
)
}
onKeyPress=
{
(
e
)
=>
handleKeyPress
(
e
,
record
.
key
)
}
placeholder=
"成员姓名"
/>
);
}
return
text
;
},
},
{
title
:
'工号'
,
dataIndex
:
'workId'
,
key
:
'workId'
,
width
:
'20%'
,
render
:
(
text
:
string
,
record
:
TableFormDateType
)
=>
{
if
(
record
.
editable
)
{
return
(
<
Input
value=
{
text
}
onChange=
{
(
e
)
=>
handleFieldChange
(
e
,
'workId'
,
record
.
key
)
}
onKeyPress=
{
(
e
)
=>
handleKeyPress
(
e
,
record
.
key
)
}
placeholder=
"工号"
/>
);
}
return
text
;
},
},
{
title
:
'所属部门'
,
dataIndex
:
'department'
,
key
:
'department'
,
width
:
'40%'
,
render
:
(
text
:
string
,
record
:
TableFormDateType
)
=>
{
if
(
record
.
editable
)
{
return
(
<
Input
value=
{
text
}
onChange=
{
(
e
)
=>
handleFieldChange
(
e
,
'department'
,
record
.
key
)
}
onKeyPress=
{
(
e
)
=>
handleKeyPress
(
e
,
record
.
key
)
}
placeholder=
"所属部门"
/>
);
}
return
text
;
},
},
{
title
:
'操作'
,
key
:
'action'
,
render
:
(
text
:
string
,
record
:
TableFormDateType
)
=>
{
if
(
!!
record
.
editable
&&
loading
)
{
return
null
;
}
if
(
record
.
editable
)
{
if
(
record
.
isNew
)
{
return
(
<
span
>
<
a
onClick=
{
(
e
)
=>
saveRow
(
e
,
record
.
key
)
}
>
添加
</
a
>
<
Divider
type=
"vertical"
/>
<
Popconfirm
title=
"是否要删除此行?"
onConfirm=
{
()
=>
remove
(
record
.
key
)
}
>
<
a
>
删除
</
a
>
</
Popconfirm
>
</
span
>
);
}
return
(
<
span
>
<
a
onClick=
{
(
e
)
=>
saveRow
(
e
,
record
.
key
)
}
>
保存
</
a
>
<
Divider
type=
"vertical"
/>
<
a
onClick=
{
(
e
)
=>
cancel
(
e
,
record
.
key
)
}
>
取消
</
a
>
</
span
>
);
}
return
(
<
span
>
<
a
onClick=
{
(
e
)
=>
toggleEditable
(
e
,
record
.
key
)
}
>
编辑
</
a
>
<
Divider
type=
"vertical"
/>
<
Popconfirm
title=
"是否要删除此行?"
onConfirm=
{
()
=>
remove
(
record
.
key
)
}
>
<
a
>
删除
</
a
>
</
Popconfirm
>
</
span
>
);
},
},
];
return
(
<>
<
Table
<
TableFormDateType
>
loading=
{
loading
}
columns=
{
columns
}
dataSource=
{
data
}
pagination=
{
false
}
rowClassName=
{
(
record
)
=>
(
record
.
editable
?
styles
.
editable
:
''
)
}
/
>
<
Button
style=
{
{
width
:
'100%'
,
marginTop
:
16
,
marginBottom
:
8
}
}
type=
"dashed"
onClick=
{
newMember
}
>
<
PlusOutlined
/>
新增成员
</
Button
>
</>
);
};
export default TableForm;
dlink-web/src/pages/Demo/FormAdvancedForm/index.tsx
deleted
100644 → 0
View file @
28c5e425
This diff is collapsed.
Click to expand it.
dlink-web/src/pages/Demo/FormAdvancedForm/model.ts
deleted
100644 → 0
View file @
28c5e425
import
type
{
Effect
}
from
'umi'
;
import
{
message
}
from
'antd'
;
import
{
fakeSubmitForm
}
from
'./service'
;
export
type
ModelType
=
{
namespace
:
string
;
state
:
{};
effects
:
{
submitAdvancedForm
:
Effect
;
};
};
const
Model
:
ModelType
=
{
namespace
:
'formAdvancedForm'
,
state
:
{},
effects
:
{
*
submitAdvancedForm
({
payload
},
{
call
})
{
yield
call
(
fakeSubmitForm
,
payload
);
message
.
success
(
'提交成功'
);
},
},
};
export
default
Model
;
dlink-web/src/pages/Demo/FormAdvancedForm/service.ts
deleted
100644 → 0
View file @
28c5e425
import
request
from
'umi-request'
;
export
async
function
fakeSubmitForm
(
params
:
any
)
{
return
request
(
'/api/forms'
,
{
method
:
'POST'
,
data
:
params
,
});
}
dlink-web/src/pages/Demo/FormAdvancedForm/style.less
deleted
100644 → 0
View file @
28c5e425
@import '~antd/es/style/themes/default.less';
.card {
margin-bottom: 24px;
:global {
.ant-legacy-form-item .ant-legacy-form-item-control-wrapper {
width: 100%;
}
}
}
.errorIcon {
margin-right: 24px;
color: @error-color;
cursor: pointer;
span.anticon {
margin-right: 4px;
}
}
.errorPopover {
:global {
.ant-popover-inner-content {
min-width: 256px;
max-height: 290px;
padding: 0;
overflow: auto;
}
}
}
.errorListItem {
padding: 8px 16px;
list-style: none;
border-bottom: 1px solid @border-color-split;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: @item-active-bg;
}
&:last-child {
border: 0;
}
.errorIcon {
float: left;
margin-top: 4px;
margin-right: 12px;
padding-bottom: 22px;
color: @error-color;
}
.errorField {
margin-top: 2px;
color: @text-color-secondary;
font-size: 12px;
}
}
.editable {
td {
padding-top: 13px !important;
padding-bottom: 12.5px !important;
}
}
dlink-web/src/pages/Demo/FormStepForm/_mock.ts
deleted
100644 → 0
View file @
28c5e425
// eslint-disable-next-line import/no-extraneous-dependencies
import
type
{
Request
,
Response
}
from
'express'
;
export
default
{
'POST /api/forms'
:
(
_
:
Request
,
res
:
Response
)
=>
{
res
.
send
({
message
:
'Ok'
});
},
};
dlink-web/src/pages/Demo/FormStepForm/components/Step1/index.less
deleted
100644 → 0
View file @
28c5e425
@import '~antd/es/style/themes/default.less';
.stepForm {
max-width: 500px;
margin: 40px auto 0;
}
.stepFormText {
margin-bottom: 24px;
:global {
.ant-form-item-label,
.ant-form-item-control {
line-height: 22px;
}
}
}
.result {
max-width: 560px;
margin: 0 auto;
padding: 24px 0 8px;
}
.desc {
padding: 0 56px;
color: @text-color-secondary;
h3 {
margin: 0 0 12px 0;
color: @text-color-secondary;
font-size: 16px;
line-height: 32px;
}
h4 {
margin: 0 0 4px 0;
color: @text-color-secondary;
font-size: 14px;
line-height: 22px;
}
p {
margin-top: 0;
margin-bottom: 12px;
line-height: 22px;
}
}
@media screen and (max-width: @screen-md) {
.desc {
padding: 0;
}
}
.information {
line-height: 22px;
:global {
.ant-row:not(:last-child) {
margin-bottom: 24px;
}
}
.label {
padding-right: 8px;
color: @heading-color;
text-align: right;
@media screen and (max-width: @screen-sm) {
text-align: left;
}
}
}
.money {
font-weight: 500;
font-size: 20px;
font-family: 'Helvetica Neue', sans-serif;
line-height: 14px;
}
.uppercase {
font-size: 12px;
}
dlink-web/src/pages/Demo/FormStepForm/components/Step1/index.tsx
deleted
100644 → 0
View file @
28c5e425
import
React
from
'react'
;
import
{
Form
,
Button
,
Divider
,
Input
,
Select
}
from
'antd'
;
import
type
{
Dispatch
}
from
'umi'
;
import
{
connect
}
from
'umi'
;
import
type
{
StateType
}
from
'../../model'
;
import
styles
from
'./index.less'
;
const
{
Option
}
=
Select
;
const
formItemLayout
=
{
labelCol
:
{
span
:
5
,
},
wrapperCol
:
{
span
:
19
,
},
};
type
Step1Props
=
{
data
?:
StateType
[
'step'
];
dispatch
?:
Dispatch
;
};
const
Step1
:
React
.
FC
<
Step1Props
>
=
(
props
)
=>
{
const
{
dispatch
,
data
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
if
(
!
data
)
{
return
null
;
}
const
{
validateFields
}
=
form
;
const
onValidateForm
=
async
()
=>
{
const
values
=
await
validateFields
();
if
(
dispatch
)
{
dispatch
({
type
:
'demoAndFormStepForm/saveStepFormData'
,
payload
:
values
,
});
dispatch
({
type
:
'demoAndFormStepForm/saveCurrentStep'
,
payload
:
'confirm'
,
});
}
};
return
(
<>
<
Form
{
...
formItemLayout
}
form=
{
form
}
layout=
"horizontal"
className=
{
styles
.
stepForm
}
hideRequiredMark
initialValues=
{
data
}
>
<
Form
.
Item
label=
"付款账户"
name=
"payAccount"
rules=
{
[{
required
:
true
,
message
:
'请选择付款账户'
}]
}
>
<
Select
placeholder=
"test@example.com"
>
<
Option
value=
"ant-design@alipay.com"
>
ant-design@alipay.com
</
Option
>
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
label=
"收款账户"
>
<
Input
.
Group
compact
>
<
Select
defaultValue=
"alipay"
style=
{
{
width
:
100
}
}
>
<
Option
value=
"alipay"
>
支付宝
</
Option
>
<
Option
value=
"bank"
>
银行账户
</
Option
>
</
Select
>
<
Form
.
Item
noStyle
name=
"receiverAccount"
rules=
{
[
{
required
:
true
,
message
:
'请输入收款人账户'
},
{
type
:
'email'
,
message
:
'账户名应为邮箱格式'
},
]
}
>
<
Input
style=
{
{
width
:
'calc(100% - 100px)'
}
}
placeholder=
"test@example.com"
/>
</
Form
.
Item
>
</
Input
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
"收款人姓名"
name=
"receiverName"
rules=
{
[{
required
:
true
,
message
:
'请输入收款人姓名'
}]
}
>
<
Input
placeholder=
"请输入收款人姓名"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"转账金额"
name=
"amount"
rules=
{
[
{
required
:
true
,
message
:
'请输入转账金额'
},
{
pattern
:
/^
(\d
+
)((?:\.\d
+
)?)
$/
,
message
:
'请输入合法金额数字'
,
},
]
}
>
<
Input
prefix=
"¥"
placeholder=
"请输入金额"
/>
</
Form
.
Item
>
<
Form
.
Item
wrapperCol=
{
{
xs
:
{
span
:
24
,
offset
:
0
},
sm
:
{
span
:
formItemLayout
.
wrapperCol
.
span
,
offset
:
formItemLayout
.
labelCol
.
span
,
},
}
}
>
<
Button
type=
"primary"
onClick=
{
onValidateForm
}
>
下一步
</
Button
>
</
Form
.
Item
>
</
Form
>
<
Divider
style=
{
{
margin
:
'40px 0 24px'
}
}
/>
<
div
className=
{
styles
.
desc
}
>
<
h3
>
说明
</
h3
>
<
h4
>
转账到支付宝账户
</
h4
>
<
p
>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</
p
>
<
h4
>
转账到银行卡
</
h4
>
<
p
>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</
p
>
</
div
>
</>
);
};
export
default
connect
(({
demoAndFormStepForm
}:
{
demoAndFormStepForm
:
StateType
})
=>
({
data
:
demoAndFormStepForm
.
step
,
}))(
Step1
);
dlink-web/src/pages/Demo/FormStepForm/components/Step2/index.less
deleted
100644 → 0
View file @
28c5e425
@import '~antd/es/style/themes/default.less';
.stepForm {
max-width: 500px;
margin: 40px auto 0;
}
.stepFormText {
margin-bottom: 24px;
:global {
.ant-form-item-label,
.ant-form-item-control {
line-height: 22px;
}
}
}
.result {
max-width: 560px;
margin: 0 auto;
padding: 24px 0 8px;
}
.desc {
padding: 0 56px;
color: @text-color-secondary;
h3 {
margin: 0 0 12px 0;
color: @text-color-secondary;
font-size: 16px;
line-height: 32px;
}
h4 {
margin: 0 0 4px 0;
color: @text-color-secondary;
font-size: 14px;
line-height: 22px;
}
p {
margin-top: 0;
margin-bottom: 12px;
line-height: 22px;
}
}
@media screen and (max-width: @screen-md) {
.desc {
padding: 0;
}
}
.information {
line-height: 22px;
:global {
.ant-row:not(:last-child) {
margin-bottom: 24px;
}
}
.label {
padding-right: 8px;
color: @heading-color;
text-align: right;
@media screen and (max-width: @screen-sm) {
text-align: left;
}
}
}
.money {
font-weight: 500;
font-size: 20px;
font-family: 'Helvetica Neue', sans-serif;
line-height: 14px;
}
.uppercase {
font-size: 12px;
}
dlink-web/src/pages/Demo/FormStepForm/components/Step2/index.tsx
deleted
100644 → 0
View file @
28c5e425
import
React
from
'react'
;
import
{
Form
,
Alert
,
Button
,
Descriptions
,
Divider
,
Statistic
,
Input
}
from
'antd'
;
import
type
{
Dispatch
}
from
'umi'
;
import
{
connect
}
from
'umi'
;
import
type
{
StateType
}
from
'../../model'
;
import
styles
from
'./index.less'
;
const
formItemLayout
=
{
labelCol
:
{
span
:
5
,
},
wrapperCol
:
{
span
:
19
,
},
};
type
Step2Props
=
{
data
?:
StateType
[
'step'
];
dispatch
?:
Dispatch
;
submitting
?:
boolean
;
};
const
Step2
:
React
.
FC
<
Step2Props
>
=
(
props
)
=>
{
const
[
form
]
=
Form
.
useForm
();
const
{
data
,
dispatch
,
submitting
}
=
props
;
if
(
!
data
)
{
return
null
;
}
const
{
validateFields
,
getFieldsValue
}
=
form
;
const
onPrev
=
()
=>
{
if
(
dispatch
)
{
const
values
=
getFieldsValue
();
dispatch
({
type
:
'demoAndFormStepForm/saveStepFormData'
,
payload
:
{
...
data
,
...
values
,
},
});
dispatch
({
type
:
'demoAndFormStepForm/saveCurrentStep'
,
payload
:
'info'
,
});
}
};
const
onValidateForm
=
async
()
=>
{
const
values
=
await
validateFields
();
if
(
dispatch
)
{
dispatch
({
type
:
'demoAndFormStepForm/submitStepForm'
,
payload
:
{
...
data
,
...
values
,
},
});
}
};
const
{
payAccount
,
receiverAccount
,
receiverName
,
amount
}
=
data
;
return
(
<
Form
{
...
formItemLayout
}
form=
{
form
}
layout=
"horizontal"
className=
{
styles
.
stepForm
}
initialValues=
{
{
password
:
'123456'
}
}
>
<
Alert
closable
showIcon
message=
"确认转账后,资金将直接打入对方账户,无法退回。"
style=
{
{
marginBottom
:
24
}
}
/>
<
Descriptions
column=
{
1
}
>
<
Descriptions
.
Item
label=
"付款账户"
>
{
payAccount
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"收款账户"
>
{
receiverAccount
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"收款人姓名"
>
{
receiverName
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"转账金额"
>
<
Statistic
value=
{
amount
}
suffix=
"元"
/>
</
Descriptions
.
Item
>
</
Descriptions
>
<
Divider
style=
{
{
margin
:
'24px 0'
}
}
/>
<
Form
.
Item
label=
"支付密码"
name=
"password"
required=
{
false
}
rules=
{
[{
required
:
true
,
message
:
'需要支付密码才能进行支付'
}]
}
>
<
Input
type=
"password"
autoComplete=
"off"
style=
{
{
width
:
'80%'
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
style=
{
{
marginBottom
:
8
}
}
wrapperCol=
{
{
xs
:
{
span
:
24
,
offset
:
0
},
sm
:
{
span
:
formItemLayout
.
wrapperCol
.
span
,
offset
:
formItemLayout
.
labelCol
.
span
,
},
}
}
>
<
Button
type=
"primary"
onClick=
{
onValidateForm
}
loading=
{
submitting
}
>
提交
</
Button
>
<
Button
onClick=
{
onPrev
}
style=
{
{
marginLeft
:
8
}
}
>
上一步
</
Button
>
</
Form
.
Item
>
</
Form
>
);
};
export
default
connect
(
({
demoAndFormStepForm
,
loading
,
}:
{
demoAndFormStepForm
:
StateType
;
loading
:
{
effects
:
Record
<
string
,
boolean
>
;
};
})
=>
({
submitting
:
loading
.
effects
[
'demoAndFormStepForm/submitStepForm'
],
data
:
demoAndFormStepForm
.
step
,
}),
)(
Step2
);
dlink-web/src/pages/Demo/FormStepForm/components/Step3/index.less
deleted
100644 → 0
View file @
28c5e425
@import '~antd/es/style/themes/default.less';
.stepForm {
max-width: 500px;
margin: 40px auto 0;
}
.stepFormText {
margin-bottom: 24px;
:global {
.ant-form-item-label,
.ant-form-item-control {
line-height: 22px;
}
}
}
.result {
max-width: 560px;
margin: 0 auto;
padding: 24px 0 8px;
}
.desc {
padding: 0 56px;
color: @text-color-secondary;
h3 {
margin: 0 0 12px 0;
color: @text-color-secondary;
font-size: 16px;
line-height: 32px;
}
h4 {
margin: 0 0 4px 0;
color: @text-color-secondary;
font-size: 14px;
line-height: 22px;
}
p {
margin-top: 0;
margin-bottom: 12px;
line-height: 22px;
}
}
@media screen and (max-width: @screen-md) {
.desc {
padding: 0;
}
}
.information {
line-height: 22px;
:global {
.ant-row:not(:last-child) {
margin-bottom: 24px;
}
}
.label {
padding-right: 8px;
color: @heading-color;
text-align: right;
@media screen and (max-width: @screen-sm) {
text-align: left;
}
}
}
.uppercase {
font-size: 12px;
}
dlink-web/src/pages/Demo/FormStepForm/components/Step3/index.tsx
deleted
100644 → 0
View file @
28c5e425
import
{
Button
,
Result
,
Descriptions
,
Statistic
}
from
'antd'
;
import
React
from
'react'
;
import
type
{
Dispatch
}
from
'umi'
;
import
{
connect
}
from
'umi'
;
import
type
{
StateType
}
from
'../../model'
;
import
styles
from
'./index.less'
;
type
Step3Props
=
{
data
?:
StateType
[
'step'
];
dispatch
?:
Dispatch
;
};
const
Step3
:
React
.
FC
<
Step3Props
>
=
(
props
)
=>
{
const
{
data
,
dispatch
}
=
props
;
if
(
!
data
)
{
return
null
;
}
const
{
payAccount
,
receiverAccount
,
receiverName
,
amount
}
=
data
;
const
onFinish
=
()
=>
{
if
(
dispatch
)
{
dispatch
({
type
:
'demoAndFormStepForm/saveCurrentStep'
,
payload
:
'info'
,
});
}
};
const
information
=
(
<
div
className=
{
styles
.
information
}
>
<
Descriptions
column=
{
1
}
>
<
Descriptions
.
Item
label=
"付款账户"
>
{
payAccount
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"收款账户"
>
{
receiverAccount
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"收款人姓名"
>
{
receiverName
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"转账金额"
>
<
Statistic
value=
{
amount
}
suffix=
"元"
/>
</
Descriptions
.
Item
>
</
Descriptions
>
</
div
>
);
const
extra
=
(
<>
<
Button
type=
"primary"
onClick=
{
onFinish
}
>
再转一笔
</
Button
>
<
Button
>
查看账单
</
Button
>
</>
);
return
(
<
Result
status=
"success"
title=
"操作成功"
subTitle=
"预计两小时内到账"
extra=
{
extra
}
className=
{
styles
.
result
}
>
{
information
}
</
Result
>
);
};
export
default
connect
(({
demoAndFormStepForm
}:
{
demoAndFormStepForm
:
StateType
})
=>
({
data
:
demoAndFormStepForm
.
step
,
}))(
Step3
);
dlink-web/src/pages/Demo/FormStepForm/index.tsx
deleted
100644 → 0
View file @
28c5e425
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
Card
,
Steps
}
from
'antd'
;
import
{
PageContainer
}
from
'@ant-design/pro-layout'
;
import
{
connect
}
from
'umi'
;
import
type
{
StateType
}
from
'./model'
;
import
Step1
from
'./components/Step1'
;
import
Step2
from
'./components/Step2'
;
import
Step3
from
'./components/Step3'
;
import
styles
from
'./style.less'
;
const
{
Step
}
=
Steps
;
type
FormStepFormProps
=
{
current
:
StateType
[
'current'
];
};
const
getCurrentStepAndComponent
=
(
current
?:
string
)
=>
{
switch
(
current
)
{
case
'confirm'
:
return
{
step
:
1
,
component
:
<
Step2
/>
};
case
'result'
:
return
{
step
:
2
,
component
:
<
Step3
/>
};
case
'info'
:
default
:
return
{
step
:
0
,
component
:
<
Step1
/>
};
}
};
const
FormStepForm
:
React
.
FC
<
FormStepFormProps
>
=
({
current
})
=>
{
const
[
stepComponent
,
setStepComponent
]
=
useState
<
React
.
ReactNode
>
(<
Step1
/>);
const
[
currentStep
,
setCurrentStep
]
=
useState
<
number
>
(
0
);
useEffect
(()
=>
{
const
{
step
,
component
}
=
getCurrentStepAndComponent
(
current
);
setCurrentStep
(
step
);
setStepComponent
(
component
);
},
[
current
]);
return
(
<
PageContainer
content=
"将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"
>
<
Card
bordered=
{
false
}
>
<>
<
Steps
current=
{
currentStep
}
className=
{
styles
.
steps
}
>
<
Step
title=
"填写转账信息"
/>
<
Step
title=
"确认转账信息"
/>
<
Step
title=
"完成"
/>
</
Steps
>
{
stepComponent
}
</>
</
Card
>
</
PageContainer
>
);
};
export
default
connect
(({
demoAndFormStepForm
}:
{
demoAndFormStepForm
:
StateType
})
=>
({
current
:
demoAndFormStepForm
.
current
,
}))(
FormStepForm
);
dlink-web/src/pages/Demo/FormStepForm/locales/en-US.ts
deleted
100644 → 0
View file @
28c5e425
export
default
{
'demoandformstepform.basic.title'
:
'Basic form'
,
'demoandformstepform.basic.description'
:
'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.'
,
'demoandformstepform.email.required'
:
'Please enter your email!'
,
'demoandformstepform.email.wrong-format'
:
'The email address is in the wrong format!'
,
'demoandformstepform.userName.required'
:
'Please enter your userName!'
,
'demoandformstepform.password.required'
:
'Please enter your password!'
,
'demoandformstepform.password.twice'
:
'The passwords entered twice do not match!'
,
'demoandformstepform.strength.msg'
:
"Please enter at least 6 characters and don't use passwords that are easy to guess."
,
'demoandformstepform.strength.strong'
:
'Strength: strong'
,
'demoandformstepform.strength.medium'
:
'Strength: medium'
,
'demoandformstepform.strength.short'
:
'Strength: too short'
,
'demoandformstepform.confirm-password.required'
:
'Please confirm your password!'
,
'demoandformstepform.phone-number.required'
:
'Please enter your phone number!'
,
'demoandformstepform.phone-number.wrong-format'
:
'Malformed phone number!'
,
'demoandformstepform.verification-code.required'
:
'Please enter the verification code!'
,
'demoandformstepform.title.required'
:
'Please enter a title'
,
'demoandformstepform.date.required'
:
'Please select the start and end date'
,
'demoandformstepform.goal.required'
:
'Please enter a description of the goal'
,
'demoandformstepform.standard.required'
:
'Please enter a metric'
,
'demoandformstepform.form.get-captcha'
:
'Get Captcha'
,
'demoandformstepform.captcha.second'
:
'sec'
,
'demoandformstepform.form.optional'
:
' (optional) '
,
'demoandformstepform.form.submit'
:
'Submit'
,
'demoandformstepform.form.save'
:
'Save'
,
'demoandformstepform.email.placeholder'
:
'Email'
,
'demoandformstepform.password.placeholder'
:
'Password'
,
'demoandformstepform.confirm-password.placeholder'
:
'Confirm password'
,
'demoandformstepform.phone-number.placeholder'
:
'Phone number'
,
'demoandformstepform.verification-code.placeholder'
:
'Verification code'
,
'demoandformstepform.title.label'
:
'Title'
,
'demoandformstepform.title.placeholder'
:
'Give the target a name'
,
'demoandformstepform.date.label'
:
'Start and end date'
,
'demoandformstepform.placeholder.start'
:
'Start date'
,
'demoandformstepform.placeholder.end'
:
'End date'
,
'demoandformstepform.goal.label'
:
'Goal description'
,
'demoandformstepform.goal.placeholder'
:
'Please enter your work goals'
,
'demoandformstepform.standard.label'
:
'Metrics'
,
'demoandformstepform.standard.placeholder'
:
'Please enter a metric'
,
'demoandformstepform.client.label'
:
'Client'
,
'demoandformstepform.label.tooltip'
:
'Target service object'
,
'demoandformstepform.client.placeholder'
:
'Please describe your customer service, internal customers directly @ Name / job number'
,
'demoandformstepform.invites.label'
:
'Inviting critics'
,
'demoandformstepform.invites.placeholder'
:
'Please direct @ Name / job number, you can invite up to 5 people'
,
'demoandformstepform.weight.label'
:
'Weight'
,
'demoandformstepform.weight.placeholder'
:
'Please enter weight'
,
'demoandformstepform.public.label'
:
'Target disclosure'
,
'demoandformstepform.label.help'
:
'Customers and invitees are shared by default'
,
'demoandformstepform.radio.public'
:
'Public'
,
'demoandformstepform.radio.partially-public'
:
'Partially public'
,
'demoandformstepform.radio.private'
:
'Private'
,
'demoandformstepform.publicUsers.placeholder'
:
'Open to'
,
'demoandformstepform.option.A'
:
'Colleague A'
,
'demoandformstepform.option.B'
:
'Colleague B'
,
'demoandformstepform.option.C'
:
'Colleague C'
,
};
dlink-web/src/pages/Demo/FormStepForm/locales/pt-BR.ts
deleted
100644 → 0
View file @
28c5e425
export
default
{
'demoandformstepform.basic.title'
:
'Basic form'
,
'demoandformstepform.basic.description'
:
'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.'
,
'demoandformstepform.email.required'
:
'Por favor insira seu email!'
,
'demoandformstepform.email.wrong-format'
:
'O email está errado!'
,
'demoandformstepform.userName.required'
:
'Por favor insira nome de usuário!'
,
'demoandformstepform.password.required'
:
'Por favor insira sua senha!'
,
'demoandformstepform.password.twice'
:
'As senhas não estão iguais!'
,
'demoandformstepform.strength.msg'
:
'Por favor insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.'
,
'demoandformstepform.strength.strong'
:
'Força: forte'
,
'demoandformstepform.strength.medium'
:
'Força: média'
,
'demoandformstepform.strength.short'
:
'Força: curta'
,
'demoandformstepform.confirm-password.required'
:
'Por favor confirme sua senha!'
,
'demoandformstepform.phone-number.required'
:
'Por favor insira seu telefone!'
,
'demoandformstepform.phone-number.wrong-format'
:
'Formato de telefone errado!'
,
'demoandformstepform.verification-code.required'
:
'Por favor insira seu código de verificação!'
,
'demoandformstepform.form.get-captcha'
:
'Get Captcha'
,
'demoandformstepform.captcha.second'
:
'sec'
,
'demoandformstepform.email.placeholder'
:
'Email'
,
'demoandformstepform.password.placeholder'
:
'Senha'
,
'demoandformstepform.confirm-password.placeholder'
:
'Confirme a senha'
,
'demoandformstepform.phone-number.placeholder'
:
'Telefone'
,
'demoandformstepform.verification-code.placeholder'
:
'Código de verificação'
,
'demoandformstepform.form.optional'
:
' (optional) '
,
'demoandformstepform.form.submit'
:
'Submit'
,
'demoandformstepform.form.save'
:
'Save'
,
'demoandformstepform.title.label'
:
'Title'
,
'demoandformstepform.title.placeholder'
:
'Give the target a name'
,
'demoandformstepform.date.label'
:
'Start and end date'
,
'demoandformstepform.placeholder.start'
:
'Start date'
,
'demoandformstepform.placeholder.end'
:
'End date'
,
'demoandformstepform.goal.label'
:
'Goal description'
,
'demoandformstepform.goal.placeholder'
:
'Please enter your work goals'
,
'demoandformstepform.standard.label'
:
'Metrics'
,
'demoandformstepform.standard.placeholder'
:
'Please enter a metric'
,
'demoandformstepform.client.label'
:
'Client'
,
'demoandformstepform.label.tooltip'
:
'Target service object'
,
'demoandformstepform.client.placeholder'
:
'Please describe your customer service, internal customers directly @ Name / job number'
,
'demoandformstepform.invites.label'
:
'Inviting critics'
,
'demoandformstepform.invites.placeholder'
:
'Please direct @ Name / job number, you can invite up to 5 people'
,
'demoandformstepform.weight.label'
:
'Weight'
,
'demoandformstepform.weight.placeholder'
:
'Please enter weight'
,
'demoandformstepform.public.label'
:
'Target disclosure'
,
'demoandformstepform.label.help'
:
'Customers and invitees are shared by default'
,
'demoandformstepform.radio.public'
:
'Public'
,
'demoandformstepform.radio.partially-public'
:
'Partially public'
,
'demoandformstepform.radio.private'
:
'Private'
,
'demoandformstepform.publicUsers.placeholder'
:
'Open to'
,
'demoandformstepform.option.A'
:
'Colleague A'
,
'demoandformstepform.option.B'
:
'Colleague B'
,
'demoandformstepform.option.C'
:
'Colleague C'
,
};
dlink-web/src/pages/Demo/FormStepForm/locales/zh-CN.ts
deleted
100644 → 0
View file @
28c5e425
export
default
{
'demoandformstepform.basic.title'
:
'基础表单'
,
'demoandformstepform.basic.description'
:
'表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。'
,
'demoandformstepform.email.required'
:
'请输入邮箱地址!'
,
'demoandformstepform.email.wrong-format'
:
'邮箱地址格式错误!'
,
'demoandformstepform.userName.required'
:
'请输入用户名!'
,
'demoandformstepform.password.required'
:
'请输入密码!'
,
'demoandformstepform.password.twice'
:
'两次输入的密码不匹配!'
,
'demoandformstepform.strength.msg'
:
'请至少输入 6 个字符。请不要使用容易被猜到的密码。'
,
'demoandformstepform.strength.strong'
:
'强度:强'
,
'demoandformstepform.strength.medium'
:
'强度:中'
,
'demoandformstepform.strength.short'
:
'强度:太短'
,
'demoandformstepform.confirm-password.required'
:
'请确认密码!'
,
'demoandformstepform.phone-number.required'
:
'请输入手机号!'
,
'demoandformstepform.phone-number.wrong-format'
:
'手机号格式错误!'
,
'demoandformstepform.verification-code.required'
:
'请输入验证码!'
,
'demoandformstepform.title.required'
:
'请输入标题'
,
'demoandformstepform.date.required'
:
'请选择起止日期'
,
'demoandformstepform.goal.required'
:
'请输入目标描述'
,
'demoandformstepform.standard.required'
:
'请输入衡量标准'
,
'demoandformstepform.form.get-captcha'
:
'获取验证码'
,
'demoandformstepform.captcha.second'
:
'秒'
,
'demoandformstepform.form.optional'
:
'(选填)'
,
'demoandformstepform.form.submit'
:
'提交'
,
'demoandformstepform.form.save'
:
'保存'
,
'demoandformstepform.email.placeholder'
:
'邮箱'
,
'demoandformstepform.password.placeholder'
:
'至少6位密码,区分大小写'
,
'demoandformstepform.confirm-password.placeholder'
:
'确认密码'
,
'demoandformstepform.phone-number.placeholder'
:
'手机号'
,
'demoandformstepform.verification-code.placeholder'
:
'验证码'
,
'demoandformstepform.title.label'
:
'标题'
,
'demoandformstepform.title.placeholder'
:
'给目标起个名字'
,
'demoandformstepform.date.label'
:
'起止日期'
,
'demoandformstepform.placeholder.start'
:
'开始日期'
,
'demoandformstepform.placeholder.end'
:
'结束日期'
,
'demoandformstepform.goal.label'
:
'目标描述'
,
'demoandformstepform.goal.placeholder'
:
'请输入你的阶段性工作目标'
,
'demoandformstepform.standard.label'
:
'衡量标准'
,
'demoandformstepform.standard.placeholder'
:
'请输入衡量标准'
,
'demoandformstepform.client.label'
:
'客户'
,
'demoandformstepform.label.tooltip'
:
'目标的服务对象'
,
'demoandformstepform.client.placeholder'
:
'请描述你服务的客户,内部客户直接 @姓名/工号'
,
'demoandformstepform.invites.label'
:
'邀评人'
,
'demoandformstepform.invites.placeholder'
:
'请直接 @姓名/工号,最多可邀请 5 人'
,
'demoandformstepform.weight.label'
:
'权重'
,
'demoandformstepform.weight.placeholder'
:
'请输入'
,
'demoandformstepform.public.label'
:
'目标公开'
,
'demoandformstepform.label.help'
:
'客户、邀评人默认被分享'
,
'demoandformstepform.radio.public'
:
'公开'
,
'demoandformstepform.radio.partially-public'
:
'部分公开'
,
'demoandformstepform.radio.private'
:
'不公开'
,
'demoandformstepform.publicUsers.placeholder'
:
'公开给'
,
'demoandformstepform.option.A'
:
'同事甲'
,
'demoandformstepform.option.B'
:
'同事乙'
,
'demoandformstepform.option.C'
:
'同事丙'
,
};
dlink-web/src/pages/Demo/FormStepForm/locales/zh-TW.ts
deleted
100644 → 0
View file @
28c5e425
export
default
{
'demoandformstepform.basic.title'
:
'基礎表單'
,
'demoandformstepform.basic.description'
:
'表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。'
,
'demoandformstepform.email.required'
:
'請輸入郵箱地址!'
,
'demoandformstepform.email.wrong-format'
:
'郵箱地址格式錯誤!'
,
'demoandformstepform.userName.required'
:
'請輸入賬戶!'
,
'demoandformstepform.password.required'
:
'請輸入密碼!'
,
'demoandformstepform.password.twice'
:
'兩次輸入的密碼不匹配!'
,
'demoandformstepform.strength.msg'
:
'請至少輸入 6 個字符。請不要使用容易被猜到的密碼。'
,
'demoandformstepform.strength.strong'
:
'強度:強'
,
'demoandformstepform.strength.medium'
:
'強度:中'
,
'demoandformstepform.strength.short'
:
'強度:太短'
,
'demoandformstepform.confirm-password.required'
:
'請確認密碼!'
,
'demoandformstepform.phone-number.required'
:
'請輸入手機號!'
,
'demoandformstepform.phone-number.wrong-format'
:
'手機號格式錯誤!'
,
'demoandformstepform.verification-code.required'
:
'請輸入驗證碼!'
,
'demoandformstepform.title.required'
:
'請輸入標題'
,
'demoandformstepform.date.required'
:
'請選擇起止日期'
,
'demoandformstepform.goal.required'
:
'請輸入目標描述'
,
'demoandformstepform.standard.required'
:
'請輸入衡量標淮'
,
'demoandformstepform.form.get-captcha'
:
'獲取驗證碼'
,
'demoandformstepform.captcha.second'
:
'秒'
,
'demoandformstepform.form.optional'
:
'(選填)'
,
'demoandformstepform.form.submit'
:
'提交'
,
'demoandformstepform.form.save'
:
'保存'
,
'demoandformstepform.email.placeholder'
:
'郵箱'
,
'demoandformstepform.password.placeholder'
:
'至少6位密碼,區分大小寫'
,
'demoandformstepform.confirm-password.placeholder'
:
'確認密碼'
,
'demoandformstepform.phone-number.placeholder'
:
'手機號'
,
'demoandformstepform.verification-code.placeholder'
:
'驗證碼'
,
'demoandformstepform.title.label'
:
'標題'
,
'demoandformstepform.title.placeholder'
:
'給目標起個名字'
,
'demoandformstepform.date.label'
:
'起止日期'
,
'demoandformstepform.placeholder.start'
:
'開始日期'
,
'demoandformstepform.placeholder.end'
:
'結束日期'
,
'demoandformstepform.goal.label'
:
'目標描述'
,
'demoandformstepform.goal.placeholder'
:
'請輸入妳的階段性工作目標'
,
'demoandformstepform.standard.label'
:
'衡量標淮'
,
'demoandformstepform.standard.placeholder'
:
'請輸入衡量標淮'
,
'demoandformstepform.client.label'
:
'客戶'
,
'demoandformstepform.label.tooltip'
:
'目標的服務對象'
,
'demoandformstepform.client.placeholder'
:
'請描述妳服務的客戶,內部客戶直接 @姓名/工號'
,
'demoandformstepform.invites.label'
:
'邀評人'
,
'demoandformstepform.invites.placeholder'
:
'請直接 @姓名/工號,最多可邀請 5 人'
,
'demoandformstepform.weight.label'
:
'權重'
,
'demoandformstepform.weight.placeholder'
:
'請輸入'
,
'demoandformstepform.public.label'
:
'目標公開'
,
'demoandformstepform.label.help'
:
'客戶、邀評人默認被分享'
,
'demoandformstepform.radio.public'
:
'公開'
,
'demoandformstepform.radio.partially-public'
:
'部分公開'
,
'demoandformstepform.radio.private'
:
'不公開'
,
'demoandformstepform.publicUsers.placeholder'
:
'公開給'
,
'demoandformstepform.option.A'
:
'同事甲'
,
'demoandformstepform.option.B'
:
'同事乙'
,
'demoandformstepform.option.C'
:
'同事丙'
,
};
dlink-web/src/pages/Demo/FormStepForm/model.ts
deleted
100644 → 0
View file @
28c5e425
import
type
{
Effect
,
Reducer
}
from
'umi'
;
import
{
fakeSubmitForm
}
from
'./service'
;
export
type
StateType
=
{
current
?:
string
;
step
?:
{
payAccount
:
string
;
receiverAccount
:
string
;
receiverName
:
string
;
amount
:
string
;
};
};
export
type
ModelType
=
{
namespace
:
string
;
state
:
StateType
;
effects
:
{
submitStepForm
:
Effect
;
};
reducers
:
{
saveStepFormData
:
Reducer
<
StateType
>
;
saveCurrentStep
:
Reducer
<
StateType
>
;
};
};
const
Model
:
ModelType
=
{
namespace
:
'demoAndFormStepForm'
,
state
:
{
current
:
'info'
,
step
:
{
payAccount
:
'ant-design@alipay.com'
,
receiverAccount
:
'test@example.com'
,
receiverName
:
'Alex'
,
amount
:
'500'
,
},
},
effects
:
{
*
submitStepForm
({
payload
},
{
call
,
put
})
{
yield
call
(
fakeSubmitForm
,
payload
);
yield
put
({
type
:
'saveStepFormData'
,
payload
,
});
yield
put
({
type
:
'saveCurrentStep'
,
payload
:
'result'
,
});
},
},
reducers
:
{
saveCurrentStep
(
state
,
{
payload
})
{
return
{
...
state
,
current
:
payload
,
};
},
saveStepFormData
(
state
,
{
payload
})
{
return
{
...
state
,
step
:
{
...(
state
as
StateType
).
step
,
...
payload
,
},
};
},
},
};
export
default
Model
;
dlink-web/src/pages/Demo/FormStepForm/service.ts
deleted
100644 → 0
View file @
28c5e425
import
request
from
'umi-request'
;
export
async
function
fakeSubmitForm
(
params
:
any
)
{
return
request
(
'/api/forms'
,
{
method
:
'POST'
,
data
:
params
,
});
}
dlink-web/src/pages/Demo/FormStepForm/style.less
deleted
100644 → 0
View file @
28c5e425
@import '~antd/es/style/themes/default.less';
.card {
margin-bottom: 24px;
}
.heading {
margin: 0 0 16px 0;
font-size: 14px;
line-height: 22px;
}
.steps:global(.ant-steps) {
max-width: 750px;
margin: 16px auto;
}
.errorIcon {
margin-right: 24px;
color: @error-color;
cursor: pointer;
span.anticon {
margin-right: 4px;
}
}
.errorPopover {
:global {
.ant-popover-inner-content {
min-width: 256px;
max-height: 290px;
padding: 0;
overflow: auto;
}
}
}
.errorListItem {
padding: 8px 16px;
list-style: none;
border-bottom: 1px solid @border-color-split;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: @item-active-bg;
}
&:last-child {
border: 0;
}
.errorIcon {
float: left;
margin-top: 4px;
margin-right: 12px;
padding-bottom: 22px;
color: @error-color;
}
.errorField {
margin-top: 2px;
color: @text-color-secondary;
font-size: 12px;
}
}
.editable {
td {
padding-top: 13px !important;
padding-bottom: 12.5px !important;
}
}
// custom footer for fixed footer toolbar
.advancedForm + div {
padding-bottom: 64px;
}
.advancedForm {
:global {
.ant-form .ant-row:last-child .ant-form-item {
margin-bottom: 24px;
}
.ant-table td {
transition: none !important;
}
}
}
.optional {
color: @text-color-secondary;
font-style: normal;
}
dlink-web/src/pages/Demo/ListBasicList/_mock.ts
deleted
100644 → 0
View file @
28c5e425
// eslint-disable-next-line import/no-extraneous-dependencies
import
type
{
Request
,
Response
}
from
'express'
;
import
type
{
BasicListItemDataType
}
from
'./data.d'
;
const
titles
=
[
'Alipay'
,
'Angular'
,
'Ant Design'
,
'Ant Design Pro'
,
'Bootstrap'
,
'React'
,
'Vue'
,
'Webpack'
,
];
const
avatars
=
[
'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png'
,
// Alipay
'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png'
,
// Angular
'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png'
,
// Ant Design
'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png'
,
// Ant Design Pro
'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png'
,
// Bootstrap
'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png'
,
// React
'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png'
,
// Vue
'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png'
,
// Webpack
];
const
covers
=
[
'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png'
,
'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png'
,
'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png'
,
'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png'
,
];
const
desc
=
[
'那是一种内在的东西, 他们到达不了,也无法触及的'
,
'希望是一个好东西,也许是最好的,好东西是不会消亡的'
,
'生命就像一盒巧克力,结果往往出人意料'
,
'城镇中有那么多的酒馆,她却偏偏走进了我的酒馆'
,
'那时候我只会想自己想要什么,从不想自己拥有什么'
,
];
const
user
=
[
'付小小'
,
'曲丽丽'
,
'林东东'
,
'周星星'
,
'吴加好'
,
'朱偏右'
,
'鱼酱'
,
'乐哥'
,
'谭小仪'
,
'仲尼'
,
];
function
fakeList
(
count
:
number
):
BasicListItemDataType
[]
{
const
list
=
[];
for
(
let
i
=
0
;
i
<
count
;
i
+=
1
)
{
list
.
push
({
id
:
`fake-list-
${
i
}
`
,
owner
:
user
[
i
%
10
],
title
:
titles
[
i
%
8
],
avatar
:
avatars
[
i
%
8
],
cover
:
parseInt
(
`
${
i
/
4
}
`
,
10
)
%
2
===
0
?
covers
[
i
%
4
]
:
covers
[
3
-
(
i
%
4
)],
status
:
[
'active'
,
'exception'
,
'normal'
][
i
%
3
]
as
|
'normal'
|
'exception'
|
'active'
|
'success'
,
percent
:
Math
.
ceil
(
Math
.
random
()
*
50
)
+
50
,
logo
:
avatars
[
i
%
8
],
href
:
'https://ant.design'
,
updatedAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
).
getTime
(),
createdAt
:
new
Date
(
new
Date
().
getTime
()
-
1000
*
60
*
60
*
2
*
i
).
getTime
(),
subDescription
:
desc
[
i
%
5
],
description
:
'在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
,
activeUser
:
Math
.
ceil
(
Math
.
random
()
*
100000
)
+
100000
,
newUser
:
Math
.
ceil
(
Math
.
random
()
*
1000
)
+
1000
,
star
:
Math
.
ceil
(
Math
.
random
()
*
100
)
+
100
,
like
:
Math
.
ceil
(
Math
.
random
()
*
100
)
+
100
,
message
:
Math
.
ceil
(
Math
.
random
()
*
10
)
+
10
,
content
:
'段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。'
,
members
:
[
{
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png'
,
name
:
'曲丽丽'
,
id
:
'member1'
,
},
{
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png'
,
name
:
'王昭君'
,
id
:
'member2'
,
},
{
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png'
,
name
:
'董娜娜'
,
id
:
'member3'
,
},
],
});
}
return
list
;
}
let
sourceData
:
BasicListItemDataType
[]
=
[];
function
getFakeList
(
req
:
Request
,
res
:
Response
)
{
const
params
=
req
.
query
as
any
const
count
=
params
.
count
*
1
||
20
;
const
result
=
fakeList
(
count
);
sourceData
=
result
;
return
res
.
json
(
result
);
}
function
postFakeList
(
req
:
Request
,
res
:
Response
)
{
const
{
/* url = '', */
body
}
=
req
;
// const params = getUrlParams(url);
const
{
method
,
id
}
=
body
;
// const count = (params.count * 1) || 20;
let
result
=
sourceData
||
[];
switch
(
method
)
{
case
'delete'
:
result
=
result
.
filter
((
item
)
=>
item
.
id
!==
id
);
break
;
case
'update'
:
result
.
forEach
((
item
,
i
)
=>
{
if
(
item
.
id
===
id
)
{
result
[
i
]
=
{
...
item
,
...
body
};
}
});
break
;
case
'post'
:
result
.
unshift
({
...
body
,
id
:
`fake-list-
${
result
.
length
}
`
,
createdAt
:
new
Date
().
getTime
(),
});
break
;
default
:
break
;
}
return
res
.
json
(
result
);
}
export
default
{
'GET /api/fake_list'
:
getFakeList
,
'POST /api/fake_list'
:
postFakeList
,
};
dlink-web/src/pages/Demo/ListBasicList/components/OperationModal.tsx
deleted
100644 → 0
View file @
28c5e425
import
type
{
FC
}
from
'react'
;
import
React
,
{
useEffect
}
from
'react'
;
import
moment
from
'moment'
;
import
{
Modal
,
Result
,
Button
,
Form
,
DatePicker
,
Input
,
Select
}
from
'antd'
;
import
type
{
UserTableListItem
}
from
'../data.d'
;
import
styles
from
'../style.less'
;
type
OperationModalProps
=
{
done
:
boolean
;
visible
:
boolean
;
current
:
Partial
<
UserTableListItem
>
|
undefined
;
onDone
:
()
=>
void
;
onSubmit
:
(
values
:
UserTableListItem
)
=>
void
;
onCancel
:
()
=>
void
;
};
const
{
TextArea
}
=
Input
;
const
formLayout
=
{
labelCol
:
{
span
:
7
},
wrapperCol
:
{
span
:
13
},
};
const
OperationModal
:
FC
<
OperationModalProps
>
=
(
props
)
=>
{
const
[
form
]
=
Form
.
useForm
();
const
{
done
,
visible
,
current
,
onDone
,
onCancel
,
onSubmit
}
=
props
;
useEffect
(()
=>
{
if
(
form
&&
!
visible
)
{
form
.
resetFields
();
}
},
[
props
.
visible
]);
useEffect
(()
=>
{
if
(
current
)
{
form
.
setFieldsValue
({
...
current
,
createdAt
:
current
.
createdAt
?
moment
(
current
.
createdAt
)
:
null
,
});
}
},
[
props
.
current
]);
const
handleSubmit
=
()
=>
{
if
(
!
form
)
return
;
form
.
submit
();
};
const
handleFinish
=
(
values
:
Record
<
string
,
any
>
)
=>
{
if
(
onSubmit
)
{
onSubmit
(
values
as
UserTableListItem
);
}
};
const
modalFooter
=
done
?
{
footer
:
null
,
onCancel
:
onDone
}
:
{
okText
:
'保存'
,
onOk
:
handleSubmit
,
onCancel
};
const
getModalContent
=
()
=>
{
if
(
done
)
{
return
(
<
Result
status=
"success"
title=
"操作成功"
subTitle=
"一系列的信息描述,很短同样也可以带标点。"
extra=
{
<
Button
type=
"primary"
onClick=
{
onDone
}
>
知道了
</
Button
>
}
className=
{
styles
.
formResult
}
/>
);
}
return
(
<
Form
{
...
formLayout
}
form=
{
form
}
onFinish=
{
handleFinish
}
>
<
Form
.
Item
name=
"title"
label=
"任务名称"
rules=
{
[{
required
:
true
,
message
:
'请输入任务名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
<
Form
.
Item
name=
"createdAt"
label=
"开始时间"
rules=
{
[{
required
:
true
,
message
:
'请选择开始时间'
}]
}
>
<
DatePicker
showTime
placeholder=
"请选择"
format=
"YYYY-MM-DD HH:mm:ss"
style=
{
{
width
:
'100%'
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
name=
"owner"
label=
"任务负责人"
rules=
{
[{
required
:
true
,
message
:
'请选择任务负责人'
}]
}
>
<
Select
placeholder=
"请选择"
>
<
Select
.
Option
value=
"付晓晓"
>
付晓晓
</
Select
.
Option
>
<
Select
.
Option
value=
"周毛毛"
>
周毛毛
</
Select
.
Option
>
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
name=
"subDescription"
label=
"产品描述"
rules=
{
[{
message
:
'请输入至少五个字符的产品描述!'
,
min
:
5
}]
}
>
<
TextArea
rows=
{
4
}
placeholder=
"请输入至少五个字符"
/>
</
Form
.
Item
>
</
Form
>
);
};
return
(
<
Modal
title=
{
done
?
null
:
`任务${current ? '编辑' : '添加'}`
}
className=
{
styles
.
standardListForm
}
width=
{
640
}
bodyStyle=
{
done
?
{
padding
:
'72px 0'
}
:
{
padding
:
'28px 0 0'
}
}
destroyOnClose
visible=
{
visible
}
{
...
modalFooter
}
>
{
getModalContent
()
}
</
Modal
>
);
};
export
default
OperationModal
;
dlink-web/src/pages/Demo/ListBasicList/data.d.ts
deleted
100644 → 0
View file @
28c5e425
export
type
Member
=
{
avatar
:
string
;
name
:
string
;
id
:
string
;
};
export
type
BasicListItemDataType
=
{
id
:
string
;
owner
:
string
;
title
:
string
;
avatar
:
string
;
cover
:
string
;
status
:
'normal'
|
'exception'
|
'active'
|
'success'
;
percent
:
number
;
logo
:
string
;
href
:
string
;
body
?:
any
;
updatedAt
:
number
;
createdAt
:
number
;
subDescription
:
string
;
description
:
string
;
activeUser
:
number
;
newUser
:
number
;
star
:
number
;
like
:
number
;
message
:
number
;
content
:
string
;
members
:
Member
[];
};
dlink-web/src/pages/Demo/ListBasicList/index.tsx
deleted
100644 → 0
View file @
28c5e425
import
type
{
FC
}
from
'react'
;
import
React
,
{
useRef
,
useState
,
useEffect
}
from
'react'
;
import
{
DownOutlined
,
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
Avatar
,
Button
,
Card
,
Col
,
Dropdown
,
Input
,
List
,
Menu
,
Modal
,
Progress
,
Radio
,
Row
,
}
from
'antd'
;
import
{
findDOMNode
}
from
'react-dom'
;
import
{
PageContainer
}
from
'@ant-design/pro-layout'
;
import
type
{
Dispatch
}
from
'umi'
;
import
{
connect
}
from
'umi'
;
import
moment
from
'moment'
;
import
OperationModal
from
'./components/OperationModal'
;
import
type
{
StateType
}
from
'./model'
;
import
type
{
BasicListItemDataType
}
from
'./data.d'
;
import
styles
from
'./style.less'
;
const
RadioButton
=
Radio
.
Button
;
const
RadioGroup
=
Radio
.
Group
;
const
{
Search
}
=
Input
;
type
ListBasicListProps
=
{
listBasicList
:
StateType
;
dispatch
:
Dispatch
;
loading
:
boolean
;
};
const
Info
:
FC
<
{
title
:
React
.
ReactNode
;
value
:
React
.
ReactNode
;
bordered
?:
boolean
;
}
>
=
({
title
,
value
,
bordered
})
=>
(
<
div
className=
{
styles
.
headerInfo
}
>
<
span
>
{
title
}
</
span
>
<
p
>
{
value
}
</
p
>
{
bordered
&&
<
em
/>
}
</
div
>
);
const
ListContent
=
({
data
:
{
owner
,
createdAt
,
percent
,
status
},
}:
{
data
:
BasicListItemDataType
;
})
=>
(
<
div
className=
{
styles
.
listContent
}
>
<
div
className=
{
styles
.
listContentItem
}
>
<
span
>
Owner
</
span
>
<
p
>
{
owner
}
</
p
>
</
div
>
<
div
className=
{
styles
.
listContentItem
}
>
<
span
>
开始时间
</
span
>
<
p
>
{
moment
(
createdAt
).
format
(
'YYYY-MM-DD HH:mm'
)
}
</
p
>
</
div
>
<
div
className=
{
styles
.
listContentItem
}
>
<
Progress
percent=
{
percent
}
status=
{
status
}
strokeWidth=
{
6
}
style=
{
{
width
:
180
}
}
/>
</
div
>
</
div
>
);
export
const
ListBasicList
:
FC
<
ListBasicListProps
>
=
(
props
)
=>
{
const
addBtn
=
useRef
(
null
);
const
{
loading
,
dispatch
,
listBasicList
:
{
list
},
}
=
props
;
const
[
done
,
setDone
]
=
useState
<
boolean
>
(
false
);
const
[
visible
,
setVisible
]
=
useState
<
boolean
>
(
false
);
const
[
current
,
setCurrent
]
=
useState
<
Partial
<
BasicListItemDataType
>
|
undefined
>
(
undefined
);
useEffect
(()
=>
{
dispatch
({
type
:
'listBasicList/fetch'
,
payload
:
{
count
:
5
,
},
});
},
[
1
]);
const
paginationProps
=
{
showSizeChanger
:
true
,
showQuickJumper
:
true
,
pageSize
:
5
,
total
:
50
,
};
const
showModal
=
()
=>
{
setVisible
(
true
);
setCurrent
(
undefined
);
};
const
showEditModal
=
(
item
:
BasicListItemDataType
)
=>
{
setVisible
(
true
);
setCurrent
(
item
);
};
const
deleteItem
=
(
id
:
string
)
=>
{
dispatch
({
type
:
'listBasicList/submit'
,
payload
:
{
id
},
});
};
const
editAndDelete
=
(
key
:
string
|
number
,
currentItem
:
BasicListItemDataType
)
=>
{
if
(
key
===
'edit'
)
showEditModal
(
currentItem
);
else
if
(
key
===
'delete'
)
{
Modal
.
confirm
({
title
:
'删除任务'
,
content
:
'确定删除该任务吗?'
,
okText
:
'确认'
,
cancelText
:
'取消'
,
onOk
:
()
=>
deleteItem
(
currentItem
.
id
),
});
}
};
const
extraContent
=
(
<
div
className=
{
styles
.
extraContent
}
>
<
RadioGroup
defaultValue=
"all"
>
<
RadioButton
value=
"all"
>
全部
</
RadioButton
>
<
RadioButton
value=
"progress"
>
进行中
</
RadioButton
>
<
RadioButton
value=
"waiting"
>
等待中
</
RadioButton
>
</
RadioGroup
>
<
Search
className=
{
styles
.
extraContentSearch
}
placeholder=
"请输入"
onSearch=
{
()
=>
({})
}
/>
</
div
>
);
const
MoreBtn
:
React
.
FC
<
{
item
:
BasicListItemDataType
;
}
>
=
({
item
})
=>
(
<
Dropdown
overlay=
{
<
Menu
onClick=
{
({
key
})
=>
editAndDelete
(
key
,
item
)
}
>
<
Menu
.
Item
key=
"edit"
>
编辑
</
Menu
.
Item
>
<
Menu
.
Item
key=
"delete"
>
删除
</
Menu
.
Item
>
</
Menu
>
}
>
<
a
>
更多
<
DownOutlined
/>
</
a
>
</
Dropdown
>
);
const
setAddBtnblur
=
()
=>
{
if
(
addBtn
.
current
)
{
// eslint-disable-next-line react/no-find-dom-node
const
addBtnDom
=
findDOMNode
(
addBtn
.
current
)
as
HTMLButtonElement
;
setTimeout
(()
=>
addBtnDom
.
blur
(),
0
);
}
};
const
handleDone
=
()
=>
{
setAddBtnblur
();
setDone
(
false
);
setVisible
(
false
);
};
const
handleCancel
=
()
=>
{
setAddBtnblur
();
setVisible
(
false
);
};
const
handleSubmit
=
(
values
:
BasicListItemDataType
)
=>
{
setAddBtnblur
();
setDone
(
true
);
dispatch
({
type
:
'listBasicList/submit'
,
payload
:
values
,
});
};
return
(
<
div
>
<
PageContainer
>
<
div
className=
{
styles
.
standardList
}
>
<
Card
bordered=
{
false
}
>
<
Row
>
<
Col
sm=
{
8
}
xs=
{
24
}
>
<
Info
title=
"我的待办"
value=
"8个任务"
bordered
/>
</
Col
>
<
Col
sm=
{
8
}
xs=
{
24
}
>
<
Info
title=
"本周任务平均处理时间"
value=
"32分钟"
bordered
/>
</
Col
>
<
Col
sm=
{
8
}
xs=
{
24
}
>
<
Info
title=
"本周完成任务数"
value=
"24个任务"
/>
</
Col
>
</
Row
>
</
Card
>
<
Card
className=
{
styles
.
listCard
}
bordered=
{
false
}
title=
"基本列表"
style=
{
{
marginTop
:
24
}
}
bodyStyle=
{
{
padding
:
'0 32px 40px 32px'
}
}
extra=
{
extraContent
}
>
<
Button
type=
"dashed"
style=
{
{
width
:
'100%'
,
marginBottom
:
8
}
}
onClick=
{
showModal
}
ref=
{
addBtn
}
>
<
PlusOutlined
/>
添加
</
Button
>
<
List
size=
"large"
rowKey=
"id"
loading=
{
loading
}
pagination=
{
paginationProps
}
dataSource=
{
list
}
renderItem=
{
(
item
)
=>
(
<
List
.
Item
actions=
{
[
<
a
key=
"edit"
onClick=
{
(
e
)
=>
{
e
.
preventDefault
();
showEditModal
(
item
);
}
}
>
编辑
</
a
>,
<
MoreBtn
key=
"more"
item=
{
item
}
/>,
]
}
>
<
List
.
Item
.
Meta
avatar=
{
<
Avatar
src=
{
item
.
logo
}
shape=
"square"
size=
"large"
/>
}
title=
{
<
a
href=
{
item
.
href
}
>
{
item
.
title
}
</
a
>
}
description=
{
item
.
subDescription
}
/>
<
ListContent
data=
{
item
}
/>
</
List
.
Item
>
)
}
/>
</
Card
>
</
div
>
</
PageContainer
>
<
OperationModal
done=
{
done
}
current=
{
current
}
visible=
{
visible
}
onDone=
{
handleDone
}
onCancel=
{
handleCancel
}
onSubmit=
{
handleSubmit
}
/>
</
div
>
);
};
export
default
connect
(
({
listBasicList
,
loading
,
}:
{
listBasicList
:
StateType
;
loading
:
{
models
:
Record
<
string
,
boolean
>
;
};
})
=>
({
listBasicList
,
loading
:
loading
.
models
.
listBasicList
,
}),
)(
ListBasicList
);
dlink-web/src/pages/Demo/ListBasicList/model.ts
deleted
100644 → 0
View file @
28c5e425
import
type
{
Effect
,
Reducer
}
from
'umi'
;
import
{
addFakeList
,
queryFakeList
,
removeFakeList
,
updateFakeList
}
from
'./service'
;
import
type
{
BasicListItemDataType
}
from
'./data.d'
;
export
type
StateType
=
{
list
:
BasicListItemDataType
[];
};
export
type
ModelType
=
{
namespace
:
string
;
state
:
StateType
;
effects
:
{
fetch
:
Effect
;
appendFetch
:
Effect
;
submit
:
Effect
;
};
reducers
:
{
queryList
:
Reducer
<
StateType
>
;
appendList
:
Reducer
<
StateType
>
;
};
};
const
Model
:
ModelType
=
{
namespace
:
'listBasicList'
,
state
:
{
list
:
[],
},
effects
:
{
*
fetch
({
payload
},
{
call
,
put
})
{
const
response
=
yield
call
(
queryFakeList
,
payload
);
yield
put
({
type
:
'queryList'
,
payload
:
Array
.
isArray
(
response
)
?
response
:
[],
});
},
*
appendFetch
({
payload
},
{
call
,
put
})
{
const
response
=
yield
call
(
queryFakeList
,
payload
);
yield
put
({
type
:
'appendList'
,
payload
:
Array
.
isArray
(
response
)
?
response
:
[],
});
},
*
submit
({
payload
},
{
call
,
put
})
{
let
callback
;
if
(
payload
.
id
)
{
callback
=
Object
.
keys
(
payload
).
length
===
1
?
removeFakeList
:
updateFakeList
;
}
else
{
callback
=
addFakeList
;
}
const
response
=
yield
call
(
callback
,
payload
);
// post
yield
put
({
type
:
'queryList'
,
payload
:
response
,
});
},
},
reducers
:
{
queryList
(
state
,
action
)
{
return
{
...
state
,
list
:
action
.
payload
,
};
},
appendList
(
state
=
{
list
:
[]
},
action
)
{
return
{
...
state
,
list
:
state
.
list
.
concat
(
action
.
payload
),
};
},
},
};
export
default
Model
;
dlink-web/src/pages/Demo/ListBasicList/service.ts
deleted
100644 → 0
View file @
28c5e425
import
request
from
'umi-request'
;
import
type
{
BasicListItemDataType
}
from
'./data.d'
;
type
ParamsType
=
{
count
?:
number
;
}
&
Partial
<
BasicListItemDataType
>
;
export
async
function
queryFakeList
(
params
:
ParamsType
)
{
return
request
(
'/api/fake_list'
,
{
params
,
});
}
export
async
function
removeFakeList
(
params
:
ParamsType
)
{
const
{
count
=
5
,
...
restParams
}
=
params
;
return
request
(
'/api/fake_list'
,
{
method
:
'POST'
,
params
:
{
count
,
},
data
:
{
...
restParams
,
method
:
'delete'
,
},
});
}
export
async
function
addFakeList
(
params
:
ParamsType
)
{
const
{
count
=
5
,
...
restParams
}
=
params
;
return
request
(
'/api/fake_list'
,
{
method
:
'POST'
,
params
:
{
count
,
},
data
:
{
...
restParams
,
method
:
'post'
,
},
});
}
export
async
function
updateFakeList
(
params
:
ParamsType
)
{
const
{
count
=
5
,
...
restParams
}
=
params
;
return
request
(
'/api/fake_list'
,
{
method
:
'POST'
,
params
:
{
count
,
},
data
:
{
...
restParams
,
method
:
'update'
,
},
});
}
dlink-web/src/pages/Demo/ListBasicList/style.less
deleted
100644 → 0
View file @
28c5e425
@import '~antd/es/style/themes/default.less';
@import './utils/utils.less';
.standardList {
:global {
.ant-card-head {
border-bottom: none;
}
.ant-card-head-title {
padding: 24px 0;
line-height: 32px;
}
.ant-card-extra {
padding: 24px 0;
}
.ant-list-pagination {
margin-top: 24px;
text-align: right;
}
.ant-avatar-lg {
width: 48px;
height: 48px;
line-height: 48px;
}
}
.headerInfo {
position: relative;
text-align: center;
& > span {
display: inline-block;
margin-bottom: 4px;
color: @text-color-secondary;
font-size: @font-size-base;
line-height: 22px;
}
& > p {
margin: 0;
color: @heading-color;
font-size: 24px;
line-height: 32px;
}
& > em {
position: absolute;
top: 0;
right: 0;
width: 1px;
height: 56px;
background-color: @border-color-split;
}
}
.listContent {
font-size: 0;
.listContentItem {
display: inline-block;
margin-left: 40px;
color: @text-color-secondary;
font-size: @font-size-base;
vertical-align: middle;
> span {
line-height: 20px;
}
> p {
margin-top: 4px;
margin-bottom: 0;
line-height: 22px;
}
}
}
.extraContentSearch {
width: 272px;
margin-left: 16px;
}
}
@media screen and (max-width: @screen-xs) {
.standardList {
:global {
.ant-list-item-content {
display: block;
flex: none;
width: 100%;
}
.ant-list-item-action {
margin-left: 0;
}
}
.listContent {
margin-left: 0;
& > div {
margin-left: 0;
}
}
.listCard {
:global {
.ant-card-head-title {
overflow: visible;
}
}
}
}
}
@media screen and (max-width: @screen-sm) {
.standardList {
.extraContentSearch {
width: 100%;
margin-left: 0;
}
.headerInfo {
margin-bottom: 16px;
& > em {
display: none;
}
}
}
}
@media screen and (max-width: @screen-md) {
.standardList {
.listContent {
& > div {
display: block;
}
& > div:last-child {
top: 0;
width: 100%;
}
}
}
.listCard {
:global {
.ant-radio-group {
display: block;
margin-bottom: 8px;
}
}
}
}
@media screen and (max-width: @screen-lg) and (min-width: @screen-md) {
.standardList {
.listContent {
& > div {
display: block;
}
& > div:last-child {
top: 0;
width: 100%;
}
}
}
}
@media screen and (max-width: @screen-xl) {
.standardList {
.listContent {
& > div {
margin-left: 24px;
}
& > div:last-child {
top: 0;
}
}
}
}
@media screen and (max-width: 1400px) {
.standardList {
.listContent {
text-align: right;
& > div:last-child {
top: 0;
}
}
}
}
.standardListForm {
:global {
.ant-form-item {
margin-bottom: 12px;
&:last-child {
margin-bottom: 32px;
padding-top: 4px;
}
}
}
}
.formResult {
width: 100%;
[class^='title'] {
margin-bottom: 8px;
}
}
dlink-web/src/pages/Demo/ListBasicList/utils/utils.less
deleted
100644 → 0
View file @
28c5e425
.textOverflow() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
}
.textOverflowMulti(@line: 3, @bg: #fff) {
position: relative;
max-height: @line * 1.5em;
margin-right: -1em;
padding-right: 1em;
overflow: hidden;
line-height: 1.5em;
text-align: justify;
&::before {
position: absolute;
right: 14px;
bottom: 0;
padding: 0 1px;
background: @bg;
content: '...';
}
&::after {
position: absolute;
right: 14px;
width: 1em;
height: 1em;
margin-top: 0.2em;
background: white;
content: '';
}
}
// mixins for clearfix
// ------------------------
.clearfix() {
zoom: 1;
&::before,
&::after {
display: table;
content: ' ';
}
&::after {
clear: both;
height: 0;
font-size: 0;
visibility: hidden;
}
}
dlink-web/src/pages/Demo/ListTableList/_mock.ts
deleted
100644 → 0
View file @
28c5e425
// eslint-disable-next-line import/no-extraneous-dependencies
import
type
{
Request
,
Response
}
from
'express'
;
import
{
parse
}
from
'url'
;
import
type
{
TableListItem
,
TableListParams
}
from
'./data.d'
;
// mock tableListDataSource
const
genList
=
(
current
:
number
,
pageSize
:
number
)
=>
{
const
tableListDataSource
:
TableListItem
[]
=
[];
for
(
let
i
=
0
;
i
<
pageSize
;
i
+=
1
)
{
const
index
=
(
current
-
1
)
*
10
+
i
;
tableListDataSource
.
push
({
key
:
index
,
disabled
:
i
%
6
===
0
,
href
:
'https://ant.design'
,
avatar
:
[
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png'
,
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png'
,
][
i
%
2
],
name
:
`TradeCode
${
index
}
`
,
owner
:
'曲丽丽'
,
desc
:
'这是一段描述'
,
callNo
:
Math
.
floor
(
Math
.
random
()
*
1000
),
status
:
(
Math
.
floor
(
Math
.
random
()
*
10
)
%
4
).
toString
(),
updatedAt
:
new
Date
(),
createdAt
:
new
Date
(),
progress
:
Math
.
ceil
(
Math
.
random
()
*
100
),
});
}
tableListDataSource
.
reverse
();
return
tableListDataSource
;
};
let
tableListDataSource
=
genList
(
1
,
100
);
function
getRule
(
req
:
Request
,
res
:
Response
,
u
:
string
)
{
let
realUrl
=
u
;
if
(
!
realUrl
||
Object
.
prototype
.
toString
.
call
(
realUrl
)
!==
'[object String]'
)
{
realUrl
=
req
.
url
;
}
const
{
current
=
1
,
pageSize
=
10
}
=
req
.
query
;
const
params
=
(
parse
(
realUrl
,
true
).
query
as
unknown
)
as
TableListParams
;
let
dataSource
=
[...
tableListDataSource
].
slice
(
((
current
as
number
)
-
1
)
*
(
pageSize
as
number
),
(
current
as
number
)
*
(
pageSize
as
number
),
);
const
sorter
=
JSON
.
parse
(
params
.
sorter
as
any
);
if
(
sorter
)
{
dataSource
=
dataSource
.
sort
((
prev
,
next
)
=>
{
let
sortNumber
=
0
;
Object
.
keys
(
sorter
).
forEach
((
key
)
=>
{
if
(
sorter
[
key
]
===
'descend'
)
{
if
(
prev
[
key
]
-
next
[
key
]
>
0
)
{
sortNumber
+=
-
1
;
}
else
{
sortNumber
+=
1
;
}
return
;
}
if
(
prev
[
key
]
-
next
[
key
]
>
0
)
{
sortNumber
+=
1
;
}
else
{
sortNumber
+=
-
1
;
}
});
return
sortNumber
;
});
}
if
(
params
.
filter
)
{
const
filter
=
JSON
.
parse
(
params
.
filter
as
any
)
as
Record
<
string
,
string
[]
>
;
if
(
Object
.
keys
(
filter
).
length
>
0
)
{
dataSource
=
dataSource
.
filter
((
item
)
=>
{
return
Object
.
keys
(
filter
).
some
((
key
)
=>
{
if
(
!
filter
[
key
])
{
return
true
;
}
if
(
filter
[
key
].
includes
(
`
${
item
[
key
]}
`
))
{
return
true
;
}
return
false
;
});
});
}
}
if
(
params
.
name
)
{
dataSource
=
dataSource
.
filter
((
data
)
=>
data
.
name
.
includes
(
params
.
name
||
''
));
}
const
result
=
{
data
:
dataSource
,
total
:
tableListDataSource
.
length
,
success
:
true
,
pageSize
,
current
:
parseInt
(
`
${
params
.
currentPage
}
`
,
10
)
||
1
,
};
return
res
.
json
(
result
);
}
function
postRule
(
req
:
Request
,
res
:
Response
,
u
:
string
,
b
:
Request
)
{
let
realUrl
=
u
;
if
(
!
realUrl
||
Object
.
prototype
.
toString
.
call
(
realUrl
)
!==
'[object String]'
)
{
realUrl
=
req
.
url
;
}
const
body
=
(
b
&&
b
.
body
)
||
req
.
body
;
const
{
method
,
name
,
desc
,
key
}
=
body
;
switch
(
method
)
{
/* eslint no-case-declarations:0 */
case
'delete'
:
tableListDataSource
=
tableListDataSource
.
filter
((
item
)
=>
key
.
indexOf
(
item
.
key
)
===
-
1
);
break
;
case
'post'
:
(()
=>
{
const
i
=
Math
.
ceil
(
Math
.
random
()
*
10000
);
const
newRule
=
{
key
:
tableListDataSource
.
length
,
href
:
'https://ant.design'
,
avatar
:
[
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png'
,
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png'
,
][
i
%
2
],
name
,
owner
:
'曲丽丽'
,
desc
,
callNo
:
Math
.
floor
(
Math
.
random
()
*
1000
),
status
:
(
Math
.
floor
(
Math
.
random
()
*
10
)
%
2
).
toString
(),
updatedAt
:
new
Date
(),
createdAt
:
new
Date
(),
progress
:
Math
.
ceil
(
Math
.
random
()
*
100
),
};
tableListDataSource
.
unshift
(
newRule
);
return
res
.
json
(
newRule
);
})();
return
;
case
'update'
:
(()
=>
{
let
newRule
=
{};
tableListDataSource
=
tableListDataSource
.
map
((
item
)
=>
{
if
(
item
.
key
===
key
)
{
newRule
=
{
...
item
,
desc
,
name
};
return
{
...
item
,
desc
,
name
};
}
return
item
;
});
return
res
.
json
(
newRule
);
})();
return
;
default
:
break
;
}
const
result
=
{
list
:
tableListDataSource
,
pagination
:
{
total
:
tableListDataSource
.
length
,
},
};
res
.
json
(
result
);
}
export
default
{
'GET /api/rule'
:
getRule
,
'POST /api/rule'
:
postRule
,
};
dlink-web/src/pages/Demo/ListTableList/components/CreateForm.tsx
deleted
100644 → 0
View file @
28c5e425
import
React
from
'react'
;
import
{
Modal
}
from
'antd'
;
type
CreateFormProps
=
{
modalVisible
:
boolean
;
onCancel
:
()
=>
void
;
};
const
CreateForm
:
React
.
FC
<
CreateFormProps
>
=
(
props
)
=>
{
const
{
modalVisible
,
onCancel
}
=
props
;
return
(
<
Modal
destroyOnClose
title=
"新建规则"
visible=
{
modalVisible
}
onCancel=
{
()
=>
onCancel
()
}
footer=
{
null
}
>
{
props
.
children
}
</
Modal
>
);
};
export
default
CreateForm
;
dlink-web/src/pages/Demo/ListTableList/components/UpdateForm.tsx
deleted
100644 → 0
View file @
28c5e425
import
React
,
{
useState
}
from
'react'
;
import
{
Form
,
Button
,
DatePicker
,
Input
,
Modal
,
Radio
,
Select
,
Steps
}
from
'antd'
;
import
type
{
TableListItem
}
from
'../data.d'
;
export
type
FormValueType
=
{
target
?:
string
;
template
?:
string
;
type
?:
string
;
time
?:
string
;
frequency
?:
string
;
}
&
Partial
<
TableListItem
>
;
export
type
UpdateFormProps
=
{
onCancel
:
(
flag
?:
boolean
,
formVals
?:
FormValueType
)
=>
void
;
onSubmit
:
(
values
:
FormValueType
)
=>
void
;
updateModalVisible
:
boolean
;
values
:
Partial
<
TableListItem
>
;
};
const
FormItem
=
Form
.
Item
;
const
{
Step
}
=
Steps
;
const
{
TextArea
}
=
Input
;
const
{
Option
}
=
Select
;
const
RadioGroup
=
Radio
.
Group
;
export
type
UpdateFormState
=
{
formVals
:
FormValueType
;
currentStep
:
number
;
};
const
formLayout
=
{
labelCol
:
{
span
:
7
},
wrapperCol
:
{
span
:
13
},
};
const
UpdateForm
:
React
.
FC
<
UpdateFormProps
>
=
(
props
)
=>
{
const
[
formVals
,
setFormVals
]
=
useState
<
FormValueType
>
({
name
:
props
.
values
.
name
,
desc
:
props
.
values
.
desc
,
key
:
props
.
values
.
key
,
target
:
'0'
,
template
:
'0'
,
type
:
'1'
,
time
:
''
,
frequency
:
'month'
,
});
const
[
currentStep
,
setCurrentStep
]
=
useState
<
number
>
(
0
);
const
[
form
]
=
Form
.
useForm
();
const
{
onSubmit
:
handleUpdate
,
onCancel
:
handleUpdateModalVisible
,
updateModalVisible
,
values
,
}
=
props
;
const
forward
=
()
=>
setCurrentStep
(
currentStep
+
1
);
const
backward
=
()
=>
setCurrentStep
(
currentStep
-
1
);
const
handleNext
=
async
()
=>
{
const
fieldsValue
=
await
form
.
validateFields
();
setFormVals
({
...
formVals
,
...
fieldsValue
});
if
(
currentStep
<
2
)
{
forward
();
}
else
{
handleUpdate
({
...
formVals
,
...
fieldsValue
});
}
};
const
renderContent
=
()
=>
{
if
(
currentStep
===
1
)
{
return
(
<>
<
FormItem
name=
"target"
label=
"监控对象"
>
<
Select
style=
{
{
width
:
'100%'
}
}
>
<
Option
value=
"0"
>
表一
</
Option
>
<
Option
value=
"1"
>
表二
</
Option
>
</
Select
>
</
FormItem
>
<
FormItem
name=
"template"
label=
"规则模板"
>
<
Select
style=
{
{
width
:
'100%'
}
}
>
<
Option
value=
"0"
>
规则模板一
</
Option
>
<
Option
value=
"1"
>
规则模板二
</
Option
>
</
Select
>
</
FormItem
>
<
FormItem
name=
"type"
label=
"规则类型"
>
<
RadioGroup
>
<
Radio
value=
"0"
>
强
</
Radio
>
<
Radio
value=
"1"
>
弱
</
Radio
>
</
RadioGroup
>
</
FormItem
>
</>
);
}
if
(
currentStep
===
2
)
{
return
(
<>
<
FormItem
name=
"time"
label=
"开始时间"
rules=
{
[{
required
:
true
,
message
:
'请选择开始时间!'
}]
}
>
<
DatePicker
style=
{
{
width
:
'100%'
}
}
showTime
format=
"YYYY-MM-DD HH:mm:ss"
placeholder=
"选择开始时间"
/>
</
FormItem
>
<
FormItem
name=
"frequency"
label=
"调度周期"
>
<
Select
style=
{
{
width
:
'100%'
}
}
>
<
Option
value=
"month"
>
月
</
Option
>
<
Option
value=
"week"
>
周
</
Option
>
</
Select
>
</
FormItem
>
</>
);
}
return
(
<>
<
FormItem
name=
"name"
label=
"规则名称"
rules=
{
[{
required
:
true
,
message
:
'请输入规则名称!'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
FormItem
>
<
FormItem
name=
"desc"
label=
"规则描述"
rules=
{
[{
required
:
true
,
message
:
'请输入至少五个字符的规则描述!'
,
min
:
5
}]
}
>
<
TextArea
rows=
{
4
}
placeholder=
"请输入至少五个字符"
/>
</
FormItem
>
</>
);
};
const
renderFooter
=
()
=>
{
if
(
currentStep
===
1
)
{
return
(
<>
<
Button
style=
{
{
float
:
'left'
}
}
onClick=
{
backward
}
>
上一步
</
Button
>
<
Button
onClick=
{
()
=>
handleUpdateModalVisible
(
false
,
values
)
}
>
取消
</
Button
>
<
Button
type=
"primary"
onClick=
{
()
=>
handleNext
()
}
>
下一步
</
Button
>
</>
);
}
if
(
currentStep
===
2
)
{
return
(
<>
<
Button
style=
{
{
float
:
'left'
}
}
onClick=
{
backward
}
>
上一步
</
Button
>
<
Button
onClick=
{
()
=>
handleUpdateModalVisible
(
false
,
values
)
}
>
取消
</
Button
>
<
Button
type=
"primary"
onClick=
{
()
=>
handleNext
()
}
>
完成
</
Button
>
</>
);
}
return
(
<>
<
Button
onClick=
{
()
=>
handleUpdateModalVisible
(
false
,
values
)
}
>
取消
</
Button
>
<
Button
type=
"primary"
onClick=
{
()
=>
handleNext
()
}
>
下一步
</
Button
>
</>
);
};
return
(
<
Modal
width=
{
640
}
bodyStyle=
{
{
padding
:
'32px 40px 48px'
}
}
destroyOnClose
title=
"规则配置"
visible=
{
updateModalVisible
}
footer=
{
renderFooter
()
}
onCancel=
{
()
=>
handleUpdateModalVisible
()
}
>
<
Steps
style=
{
{
marginBottom
:
28
}
}
size=
"small"
current=
{
currentStep
}
>
<
Step
title=
"基本信息"
/>
<
Step
title=
"配置规则属性"
/>
<
Step
title=
"设定调度周期"
/>
</
Steps
>
<
Form
{
...
formLayout
}
form=
{
form
}
initialValues=
{
{
target
:
formVals
.
target
,
template
:
formVals
.
template
,
type
:
formVals
.
type
,
frequency
:
formVals
.
frequency
,
name
:
formVals
.
name
,
desc
:
formVals
.
desc
,
}
}
>
{
renderContent
()
}
</
Form
>
</
Modal
>
);
};
export
default
UpdateForm
;
dlink-web/src/pages/Demo/ListTableList/data.d.ts
deleted
100644 → 0
View file @
28c5e425
export
type
TableListItem
=
{
key
:
number
;
disabled
?:
boolean
;
href
:
string
;
avatar
:
string
;
name
:
string
;
owner
:
string
;
desc
:
string
;
callNo
:
number
;
status
:
string
;
updatedAt
:
Date
;
createdAt
:
Date
;
progress
:
number
;
};
export
type
TableListPagination
=
{
total
:
number
;
pageSize
:
number
;
current
:
number
;
};
export
type
TableListData
=
{
list
:
TableListItem
[];
pagination
:
Partial
<
TableListPagination
>
;
};
export
type
TableListParams
=
{
status
?:
string
;
name
?:
string
;
desc
?:
string
;
key
?:
number
;
pageSize
?:
number
;
currentPage
?:
number
;
filter
?:
Record
<
string
,
any
[]
>
;
sorter
?:
Record
<
string
,
any
>
;
};
dlink-web/src/pages/Demo/ListTableList/index.tsx
deleted
100644 → 0
View file @
28c5e425
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
Button
,
Divider
,
message
,
Input
,
Drawer
}
from
'antd'
;
import
React
,
{
useState
,
useRef
}
from
'react'
;
import
{
PageContainer
,
FooterToolbar
}
from
'@ant-design/pro-layout'
;
import
type
{
ProColumns
,
ActionType
}
from
'@ant-design/pro-table'
;
import
ProTable
from
'@ant-design/pro-table'
;
import
ProDescriptions
from
'@ant-design/pro-descriptions'
;
import
CreateForm
from
'./components/CreateForm'
;
import
type
{
FormValueType
}
from
'./components/UpdateForm'
;
import
UpdateForm
from
'./components/UpdateForm'
;
import
type
{
TableListItem
}
from
'./data.d'
;
import
{
queryRule
,
updateRule
,
addRule
,
removeRule
}
from
'./service'
;
/**
* 添加节点
*
* @param fields
*/
const
handleAdd
=
async
(
fields
:
TableListItem
)
=>
{
const
hide
=
message
.
loading
(
'正在添加'
);
try
{
await
addRule
({
...
fields
});
hide
();
message
.
success
(
'添加成功'
);
return
true
;
}
catch
(
error
)
{
hide
();
message
.
error
(
'添加失败请重试!'
);
return
false
;
}
};
/**
* 更新节点
*
* @param fields
*/
const
handleUpdate
=
async
(
fields
:
FormValueType
)
=>
{
const
hide
=
message
.
loading
(
'正在配置'
);
try
{
await
updateRule
({
name
:
fields
.
name
,
desc
:
fields
.
desc
,
key
:
fields
.
key
,
});
hide
();
message
.
success
(
'配置成功'
);
return
true
;
}
catch
(
error
)
{
hide
();
message
.
error
(
'配置失败请重试!'
);
return
false
;
}
};
/**
* 删除节点
*
* @param selectedRows
*/
const
handleRemove
=
async
(
selectedRows
:
TableListItem
[])
=>
{
const
hide
=
message
.
loading
(
'正在删除'
);
if
(
!
selectedRows
)
return
true
;
try
{
await
removeRule
({
key
:
selectedRows
.
map
((
row
)
=>
row
.
key
),
});
hide
();
message
.
success
(
'删除成功,即将刷新'
);
return
true
;
}
catch
(
error
)
{
hide
();
message
.
error
(
'删除失败,请重试'
);
return
false
;
}
};
const
TableList
:
React
.
FC
<
{}
>
=
()
=>
{
const
[
createModalVisible
,
handleModalVisible
]
=
useState
<
boolean
>
(
false
);
const
[
updateModalVisible
,
handleUpdateModalVisible
]
=
useState
<
boolean
>
(
false
);
const
[
stepFormValues
,
setStepFormValues
]
=
useState
({});
const
actionRef
=
useRef
<
ActionType
>
();
const
[
row
,
setRow
]
=
useState
<
TableListItem
>
();
const
[
selectedRowsState
,
setSelectedRows
]
=
useState
<
TableListItem
[]
>
([]);
const
columns
:
ProColumns
<
TableListItem
>
[]
=
[
{
title
:
'规则名称'
,
dataIndex
:
'name'
,
tip
:
'规则名称是唯一的 key'
,
formItemProps
:
{
rules
:
[
{
required
:
true
,
message
:
'规则名称为必填项'
,
},
],
},
render
:
(
dom
,
entity
)
=>
{
return
<
a
onClick=
{
()
=>
setRow
(
entity
)
}
>
{
dom
}
</
a
>;
},
},
{
title
:
'描述'
,
dataIndex
:
'desc'
,
valueType
:
'textarea'
,
},
{
title
:
'服务调用次数'
,
dataIndex
:
'callNo'
,
sorter
:
true
,
hideInForm
:
true
,
renderText
:
(
val
:
string
)
=>
`
${
val
}
万`
,
},
{
title
:
'状态'
,
dataIndex
:
'status'
,
hideInForm
:
true
,
valueEnum
:
{
0
:
{
text
:
'关闭'
,
status
:
'Default'
},
1
:
{
text
:
'运行中'
,
status
:
'Processing'
},
2
:
{
text
:
'已上线'
,
status
:
'Success'
},
3
:
{
text
:
'异常'
,
status
:
'Error'
},
},
},
{
title
:
'上次调度时间'
,
dataIndex
:
'updatedAt'
,
sorter
:
true
,
valueType
:
'dateTime'
,
hideInForm
:
true
,
renderFormItem
:
(
item
,
{
defaultRender
,
...
rest
},
form
)
=>
{
const
status
=
form
.
getFieldValue
(
'status'
);
if
(
`
${
status
}
`
===
'0'
)
{
return
false
;
}
if
(
`
${
status
}
`
===
'3'
)
{
return
<
Input
{
...
rest
}
placeholder=
"请输入异常原因!"
/>;
}
return
defaultRender
(
item
);
},
},
{
title
:
'操作'
,
dataIndex
:
'option'
,
valueType
:
'option'
,
render
:
(
_
,
record
)
=>
[
<
a
onClick=
{
()
=>
{
handleUpdateModalVisible
(
true
);
setStepFormValues
(
record
);
}
}
>
配置
</
a
>,
<
Divider
type=
"vertical"
/>,
<
a
href=
""
>
订阅警报
</
a
>,
],
},
];
return
(
<
PageContainer
>
<
ProTable
<
TableListItem
>
headerTitle="查询表格"
actionRef=
{
actionRef
}
rowKey="key"
search=
{
{
labelWidth
:
120
,
}
}
toolBarRender=
{
()
=>
[
<
Button
type=
"primary"
onClick=
{
()
=>
handleModalVisible
(
true
)
}
>
<
PlusOutlined
/>
新建
</
Button
>,
]
}
request=
{
(
params
,
sorter
,
filter
)
=>
queryRule
({
...
params
,
sorter
,
filter
})
}
columns=
{
columns
}
rowSelection=
{
{
onChange
:
(
_
,
selectedRows
)
=>
setSelectedRows
(
selectedRows
),
}
}
/
>
{
selectedRowsState
?.
length
>
0
&&
(
<
FooterToolbar
extra=
{
<
div
>
已选择
<
a
style=
{
{
fontWeight
:
600
}
}
>
{
selectedRowsState
.
length
}
</
a
>
项
<
span
>
服务调用次数总计
{
selectedRowsState
.
reduce
((
pre
,
item
)
=>
pre
+
item
.
callNo
,
0
)
}
万
</
span
>
</
div
>
}
>
<
Button
onClick=
{
async
()
=>
{
await
handleRemove
(
selectedRowsState
);
setSelectedRows
([]);
actionRef
.
current
?.
reloadAndRest
?.();
}
}
>
批量删除
</
Button
>
<
Button
type=
"primary"
>
批量审批
</
Button
>
</
FooterToolbar
>
)
}
<
CreateForm
onCancel=
{
()
=>
handleModalVisible
(
false
)
}
modalVisible=
{
createModalVisible
}
>
<
ProTable
<
TableListItem
,
TableListItem
>
onSubmit=
{
async
(
value
)
=>
{
const
success
=
await
handleAdd
(
value
);
if
(
success
)
{
handleModalVisible
(
false
);
if
(
actionRef
.
current
)
{
actionRef
.
current
.
reload
();
}
}
}
}
rowKey="key"
type="form"
columns=
{
columns
}
/
>
</
CreateForm
>
{
stepFormValues
&&
Object
.
keys
(
stepFormValues
).
length
?
(
<
UpdateForm
onSubmit=
{
async
(
value
)
=>
{
const
success
=
await
handleUpdate
(
value
);
if
(
success
)
{
handleUpdateModalVisible
(
false
);
setStepFormValues
({});
if
(
actionRef
.
current
)
{
actionRef
.
current
.
reload
();
}
}
}
}
onCancel=
{
()
=>
{
handleUpdateModalVisible
(
false
);
setStepFormValues
({});
}
}
updateModalVisible=
{
updateModalVisible
}
values=
{
stepFormValues
}
/>
)
:
null
}
<
Drawer
width=
{
600
}
visible=
{
!!
row
}
onClose=
{
()
=>
{
setRow
(
undefined
);
}
}
closable=
{
false
}
>
{
row
?.
name
&&
(
<
ProDescriptions
<
TableListItem
>
column=
{
2
}
title=
{
row
?.
name
}
request=
{
async
()
=>
({
data
:
row
||
{},
})
}
params=
{
{
id
:
row
?.
name
,
}
}
columns=
{
columns
}
/
>
)
}
</
Drawer
>
</
PageContainer
>
);
};
export default TableList;
dlink-web/src/pages/Demo/ListTableList/service.ts
deleted
100644 → 0
View file @
28c5e425
import
request
from
'umi-request'
;
import
type
{
TableListParams
}
from
'./data.d'
;
export
async
function
queryRule
(
params
?:
TableListParams
)
{
return
request
(
'/api/rule'
,
{
params
,
});
}
export
async
function
removeRule
(
params
:
{
key
:
number
[]
})
{
return
request
(
'/api/rule'
,
{
method
:
'POST'
,
data
:
{
...
params
,
method
:
'delete'
,
},
});
}
export
async
function
addRule
(
params
:
TableListParams
)
{
return
request
(
'/api/rule'
,
{
method
:
'POST'
,
data
:
{
...
params
,
method
:
'post'
,
},
});
}
export
async
function
updateRule
(
params
:
TableListParams
)
{
return
request
(
'/api/rule'
,
{
method
:
'POST'
,
data
:
{
...
params
,
method
:
'update'
,
},
});
}
dlink-web/src/pages/Settings/components/flinkConfig.tsx
0 → 100644
View file @
9f684bbb
import
React
,
{
useState
}
from
'react'
;
import
{
List
,
Input
}
from
'antd'
;
import
{
connect
}
from
"umi"
;
import
{
SettingsStateType
}
from
"@/pages/Settings/model"
;
import
{
saveSettings
}
from
"@/pages/Settings/function"
;
type
FlinkConfigProps
=
{
sqlSubmitJarPath
:
SettingsStateType
[
'sqlSubmitJarPath'
];
sqlSubmitJarParas
:
SettingsStateType
[
'sqlSubmitJarParas'
];
sqlSubmitJarMainAppClass
:
SettingsStateType
[
'sqlSubmitJarMainAppClass'
];
dispatch
:
any
;
};
const
FlinkConfigView
:
React
.
FC
<
FlinkConfigProps
>
=
(
props
)
=>
{
const
{
sqlSubmitJarPath
,
sqlSubmitJarParas
,
sqlSubmitJarMainAppClass
,
dispatch
}
=
props
;
const
[
editName
,
setEditName
]
=
useState
<
string
>
(
''
);
const
[
formValues
,
setFormValues
]
=
useState
(
props
);
const
getData
=
()
=>
[
{
title
:
'提交FlinkSQL的Jar文件路径'
,
description
:
(
editName
!=
'sqlSubmitJarPath'
?
(
sqlSubmitJarPath
?
sqlSubmitJarPath
:
'未设置'
):(<
Input
id=
'sqlSubmitJarPath'
defaultValue=
{
sqlSubmitJarPath
}
onChange=
{
onChange
}
placeholder=
"hdfs:///dlink/jar/dlink-app.jar"
/>)),
actions
:
editName
!=
'sqlSubmitJarPath'
?[<
a
onClick=
{
({})
=>
handleEditClick
(
'sqlSubmitJarPath'
)
}
>
修改
</
a
>]:
[<
a
onClick=
{
({})
=>
handleSaveClick
(
'sqlSubmitJarPath'
)
}
>
保存
</
a
>,
<
a
onClick=
{
({})
=>
handleCancelClick
()
}
>
取消
</
a
>],
},
{
title
:
'提交FlinkSQL的Jar的主类入参'
,
description
:
(
editName
!=
'sqlSubmitJarParas'
?
(
sqlSubmitJarParas
?
sqlSubmitJarParas
:
'未设置'
):(<
Input
id=
'sqlSubmitJarParas'
defaultValue=
{
sqlSubmitJarParas
}
onChange=
{
onChange
}
placeholder=
""
/>)),
actions
:
editName
!=
'sqlSubmitJarParas'
?[<
a
onClick=
{
({})
=>
handleEditClick
(
'sqlSubmitJarParas'
)
}
>
修改
</
a
>]:
[<
a
onClick=
{
({})
=>
handleSaveClick
(
'sqlSubmitJarParas'
)
}
>
保存
</
a
>,
<
a
onClick=
{
({})
=>
handleCancelClick
()
}
>
取消
</
a
>],
},
{
title
:
'提交FlinkSQL的Jar的主类'
,
description
:
(
editName
!=
'sqlSubmitJarMainAppClass'
?
(
sqlSubmitJarMainAppClass
?
sqlSubmitJarMainAppClass
:
'未设置'
):(<
Input
id=
'sqlSubmitJarMainAppClass'
defaultValue=
{
sqlSubmitJarMainAppClass
}
onChange=
{
onChange
}
placeholder=
"com.dlink.app.MainApp"
/>)),
actions
:
editName
!=
'sqlSubmitJarMainAppClass'
?[<
a
onClick=
{
({})
=>
handleEditClick
(
'sqlSubmitJarMainAppClass'
)
}
>
修改
</
a
>]:
[<
a
onClick=
{
({})
=>
handleSaveClick
(
'sqlSubmitJarMainAppClass'
)
}
>
保存
</
a
>,
<
a
onClick=
{
({})
=>
handleCancelClick
()
}
>
取消
</
a
>],
},
];
const
onChange
=
e
=>
{
let
values
=
{};
values
[
e
.
target
.
id
]
=
e
.
target
.
value
;
setFormValues
({...
formValues
,...
values
});
};
const
handleEditClick
=
(
name
:
string
)
=>
{
setEditName
(
name
);
};
const
handleSaveClick
=
(
name
:
string
)
=>
{
if
(
formValues
[
name
]
!=
props
[
name
])
{
let
values
=
{};
values
[
name
]
=
formValues
[
name
];
saveSettings
(
values
,
dispatch
);
}
setEditName
(
''
);
};
const
handleCancelClick
=
()
=>
{
setFormValues
(
props
);
setEditName
(
''
);
};
const
data
=
getData
();
return
(
<>
<
List
itemLayout=
"horizontal"
dataSource=
{
data
}
renderItem=
{
(
item
)
=>
(
<
List
.
Item
actions=
{
item
.
actions
}
>
<
List
.
Item
.
Meta
title=
{
item
.
title
}
description=
{
item
.
description
}
/>
</
List
.
Item
>
)
}
/>
</>
);
};
export
default
connect
(({
Settings
}:
{
Settings
:
SettingsStateType
})
=>
({
sqlSubmitJarPath
:
Settings
.
sqlSubmitJarPath
,
sqlSubmitJarParas
:
Settings
.
sqlSubmitJarParas
,
sqlSubmitJarMainAppClass
:
Settings
.
sqlSubmitJarMainAppClass
,
}))(
FlinkConfigView
);
dlink-web/src/pages/Settings/function.ts
0 → 100644
View file @
9f684bbb
import
{
postAll
,
getData
}
from
"@/components/Common/crud"
;
import
{
message
}
from
"antd"
;
export
function
loadSettings
(
dispatch
:
any
)
{
const
res
=
getData
(
'api/sysConfig/getAll'
);
res
.
then
((
result
)
=>
{
result
.
datas
&&
dispatch
&&
dispatch
({
type
:
"Settings/saveSettings"
,
payload
:
result
.
datas
,
});
});
}
export
function
saveSettings
(
values
:{},
dispatch
:
any
)
{
const
res
=
postAll
(
"api/sysConfig/updateSysConfigByJson"
,
values
);
res
.
then
((
result
)
=>
{
message
.
success
(
`修改配置成功!`
);
dispatch
&&
dispatch
({
type
:
"Settings/saveSettings"
,
payload
:
values
,
});
});
}
dlink-web/src/pages/Settings/index.tsx
0 → 100644
View file @
9f684bbb
import
React
,
{
useState
,
useRef
,
useLayoutEffect
}
from
'react'
;
import
{
GridContent
}
from
'@ant-design/pro-layout'
;
import
{
Menu
}
from
'antd'
;
import
FlinkConfigView
from
'./components/flinkConfig'
;
import
styles
from
'./style.less'
;
import
{
loadSettings
}
from
"@/pages/Settings/function"
;
import
{
SettingsStateType
}
from
"@/pages/Settings/model"
;
import
{
connect
}
from
"umi"
;
const
{
Item
}
=
Menu
;
type
SettingsStateKeys
=
'flinkConfig'
|
'sysConfig'
;
type
SettingsState
=
{
mode
:
'inline'
|
'horizontal'
;
selectKey
:
SettingsStateKeys
;
};
type
SettingsProps
=
{
dispatch
:
any
;
};
const
Settings
:
React
.
FC
<
SettingsProps
>
=
(
props
)
=>
{
const
menuMap
:
Record
<
string
,
React
.
ReactNode
>
=
{
flinkConfig
:
'Flink 设置'
,
};
const
{
dispatch
}
=
props
;
const
[
initConfig
,
setInitConfig
]
=
useState
<
SettingsState
>
({
mode
:
'inline'
,
selectKey
:
'flinkConfig'
,
});
const
dom
=
useRef
<
HTMLDivElement
>
();
loadSettings
(
dispatch
);
const
resize
=
()
=>
{
requestAnimationFrame
(()
=>
{
if
(
!
dom
.
current
)
{
return
;
}
let
mode
:
'inline'
|
'horizontal'
=
'inline'
;
const
{
offsetWidth
}
=
dom
.
current
;
if
(
dom
.
current
.
offsetWidth
<
641
&&
offsetWidth
>
400
)
{
mode
=
'horizontal'
;
}
if
(
window
.
innerWidth
<
768
&&
offsetWidth
>
400
)
{
mode
=
'horizontal'
;
}
setInitConfig
({
...
initConfig
,
mode
:
mode
as
SettingsState
[
'mode'
]
});
});
};
useLayoutEffect
(()
=>
{
if
(
dom
.
current
)
{
window
.
addEventListener
(
'resize'
,
resize
);
resize
();
}
return
()
=>
{
window
.
removeEventListener
(
'resize'
,
resize
);
};
},
[
dom
.
current
]);
const
getMenu
=
()
=>
{
return
Object
.
keys
(
menuMap
).
map
((
item
)
=>
<
Item
key=
{
item
}
>
{
menuMap
[
item
]
}
</
Item
>);
};
const
renderChildren
=
()
=>
{
const
{
selectKey
}
=
initConfig
;
switch
(
selectKey
)
{
case
'flinkConfig'
:
return
<
FlinkConfigView
/>;
default
:
return
null
;
}
};
return
(
<
GridContent
>
<
div
className=
{
styles
.
main
}
ref=
{
(
ref
)
=>
{
if
(
ref
)
{
dom
.
current
=
ref
;
}
}
}
>
<
div
className=
{
styles
.
leftMenu
}
>
<
Menu
mode=
{
initConfig
.
mode
}
selectedKeys=
{
[
initConfig
.
selectKey
]
}
onClick=
{
({
key
})
=>
{
setInitConfig
({
...
initConfig
,
selectKey
:
key
as
SettingsStateKeys
,
});
}
}
>
{
getMenu
()
}
</
Menu
>
</
div
>
<
div
className=
{
styles
.
right
}
>
<
div
className=
{
styles
.
title
}
>
{
menuMap
[
initConfig
.
selectKey
]
}
</
div
>
{
renderChildren
()
}
</
div
>
</
div
>
</
GridContent
>
);
};
export
default
connect
(({
Settings
}:
{
Settings
:
SettingsStateType
})
=>
({
sqlSubmitJarPath
:
Settings
.
sqlSubmitJarPath
,
sqlSubmitJarParas
:
Settings
.
sqlSubmitJarParas
,
sqlSubmitJarMainAppClass
:
Settings
.
sqlSubmitJarMainAppClass
,
}))(
Settings
);
dlink-web/src/pages/Settings/model.ts
0 → 100644
View file @
9f684bbb
import
{
Effect
,
Reducer
}
from
"umi"
;
export
type
SettingsStateType
=
{
sqlSubmitJarPath
:
string
,
sqlSubmitJarParas
:
string
,
sqlSubmitJarMainAppClass
:
string
,
};
export
type
ModelType
=
{
namespace
:
string
;
state
:
SettingsStateType
;
effects
:
{
};
reducers
:
{
saveSettings
:
Reducer
<
SettingsStateType
>
;
};
};
const
SettingsModel
:
ModelType
=
{
namespace
:
'Settings'
,
state
:
{
sqlSubmitJarPath
:
''
,
sqlSubmitJarParas
:
''
,
sqlSubmitJarMainAppClass
:
''
,
},
effects
:
{
},
reducers
:
{
saveSettings
(
state
,
{
payload
})
{
return
{
...
state
,
...
payload
,
};
},
},
};
export
default
SettingsModel
;
dlink-web/src/pages/Settings/style.less
0 → 100644
View file @
9f684bbb
@import '~antd/es/style/themes/default.less';
.main {
display: flex;
width: 100%;
height: 100%;
padding-top: 16px;
padding-bottom: 16px;
background-color: @menu-bg;
.leftMenu {
width: 224px;
border-right: @border-width-base @border-style-base @border-color-split;
:global {
.ant-menu-inline {
border: none;
}
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
font-weight: bold;
}
}
}
.right {
flex: 1;
padding: 8px 40px;
.title {
margin-bottom: 12px;
color: @heading-color;
font-weight: 500;
font-size: 20px;
line-height: 28px;
}
}
:global {
.ant-list-split .ant-list-item:last-child {
border-bottom: 1px solid @border-color-split;
}
.ant-list-item {
padding-top: 14px;
padding-bottom: 14px;
}
}
}
:global {
.ant-list-item-meta {
// 账号绑定图标
.taobao {
display: block;
color: #ff4000;
font-size: 48px;
line-height: 48px;
border-radius: @border-radius-base;
}
.dingding {
margin: 2px;
padding: 6px;
color: #fff;
font-size: 32px;
line-height: 32px;
background-color: #2eabff;
border-radius: @border-radius-base;
}
.alipay {
color: #2eabff;
font-size: 48px;
line-height: 48px;
border-radius: @border-radius-base;
}
}
// 密码强度
font.strong {
color: @success-color;
}
font.medium {
color: @warning-color;
}
font.weak {
color: @error-color;
}
}
@media screen and (max-width: @screen-md) {
.main {
flex-direction: column;
.leftMenu {
width: 100%;
border: none;
}
.right {
padding: 40px;
}
}
}
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