Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
ant-design-pro
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
duanledexianxianxian
ant-design-pro
Commits
81ee2c12
Commit
81ee2c12
authored
Dec 07, 2018
by
愚道
Committed by
Yu
Jan 17, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
remove pages
parent
5ba67a51
Changes
84
Hide whitespace changes
Inline
Side-by-side
Showing
84 changed files
with
25 additions
and
8911 deletions
+25
-8911
.eslintignore
.eslintignore
+1
-1
config/config.js
config/config.js
+19
-2
config/router.config.js
config/router.config.js
+0
-263
src/layouts/BasicLayout.js
src/layouts/BasicLayout.js
+2
-1
src/pages/404.js
src/pages/404.js
+0
-13
src/pages/Account/Center/Applications.js
src/pages/Account/Center/Applications.js
+0
-88
src/pages/Account/Center/Articles.js
src/pages/Account/Center/Articles.js
+0
-59
src/pages/Account/Center/Articles.less
src/pages/Account/Center/Articles.less
+0
-12
src/pages/Account/Center/Center.js
src/pages/Account/Center/Center.js
+0
-216
src/pages/Account/Center/Center.less
src/pages/Account/Center/Center.less
+0
-97
src/pages/Account/Center/Projects.js
src/pages/Account/Center/Projects.js
+0
-52
src/pages/Account/Settings/BaseView.js
src/pages/Account/Settings/BaseView.js
+0
-192
src/pages/Account/Settings/BaseView.less
src/pages/Account/Settings/BaseView.less
+0
-52
src/pages/Account/Settings/BindingView.js
src/pages/Account/Settings/BindingView.js
+0
-60
src/pages/Account/Settings/GeographicView.js
src/pages/Account/Settings/GeographicView.js
+0
-128
src/pages/Account/Settings/GeographicView.less
src/pages/Account/Settings/GeographicView.less
+0
-19
src/pages/Account/Settings/Info.js
src/pages/Account/Settings/Info.js
+0
-125
src/pages/Account/Settings/Info.less
src/pages/Account/Settings/Info.less
+0
-97
src/pages/Account/Settings/NotificationView.js
src/pages/Account/Settings/NotificationView.js
+0
-50
src/pages/Account/Settings/PhoneView.js
src/pages/Account/Settings/PhoneView.js
+0
-33
src/pages/Account/Settings/PhoneView.less
src/pages/Account/Settings/PhoneView.less
+0
-11
src/pages/Account/Settings/SecurityView.js
src/pages/Account/Settings/SecurityView.js
+0
-102
src/pages/Account/Settings/models/geographic.js
src/pages/Account/Settings/models/geographic.js
+0
-65
src/pages/BasicDemo.js
src/pages/BasicDemo.js
+3
-0
src/pages/Dashboard/Analysis.js
src/pages/Dashboard/Analysis.js
+0
-187
src/pages/Dashboard/Analysis.less
src/pages/Dashboard/Analysis.less
+0
-197
src/pages/Dashboard/IntroduceRow.js
src/pages/Dashboard/IntroduceRow.js
+0
-144
src/pages/Dashboard/Monitor.js
src/pages/Dashboard/Monitor.js
+0
-245
src/pages/Dashboard/Monitor.less
src/pages/Dashboard/Monitor.less
+0
-23
src/pages/Dashboard/OfflineData.js
src/pages/Dashboard/OfflineData.js
+0
-65
src/pages/Dashboard/ProportionSales.js
src/pages/Dashboard/ProportionSales.js
+0
-58
src/pages/Dashboard/SalesCard.js
src/pages/Dashboard/SalesCard.js
+0
-150
src/pages/Dashboard/TopSearch.js
src/pages/Dashboard/TopSearch.js
+0
-111
src/pages/Dashboard/Workplace.js
src/pages/Dashboard/Workplace.js
+0
-256
src/pages/Dashboard/Workplace.less
src/pages/Dashboard/Workplace.less
+0
-227
src/pages/Dashboard/models/activities.js
src/pages/Dashboard/models/activities.js
+0
-28
src/pages/Dashboard/models/chart.js
src/pages/Dashboard/models/chart.js
+0
-61
src/pages/Dashboard/models/monitor.js
src/pages/Dashboard/models/monitor.js
+0
-28
src/pages/Exception/403.js
src/pages/Exception/403.js
+0
-15
src/pages/Exception/404.js
src/pages/Exception/404.js
+0
-15
src/pages/Exception/500.js
src/pages/Exception/500.js
+0
-15
src/pages/Exception/TriggerException.js
src/pages/Exception/TriggerException.js
+0
-50
src/pages/Exception/models/error.js
src/pages/Exception/models/error.js
+0
-28
src/pages/Exception/style.less
src/pages/Exception/style.less
+0
-7
src/pages/Forms/AdvancedForm.js
src/pages/Forms/AdvancedForm.js
+0
-323
src/pages/Forms/BasicForm.js
src/pages/Forms/BasicForm.js
+0
-247
src/pages/Forms/StepForm/Step1.js
src/pages/Forms/StepForm/Step1.js
+0
-115
src/pages/Forms/StepForm/Step2.js
src/pages/Forms/StepForm/Step2.js
+0
-99
src/pages/Forms/StepForm/Step3.js
src/pages/Forms/StepForm/Step3.js
+0
-74
src/pages/Forms/StepForm/index.js
src/pages/Forms/StepForm/index.js
+0
-46
src/pages/Forms/StepForm/style.less
src/pages/Forms/StepForm/style.less
+0
-78
src/pages/Forms/TableForm.js
src/pages/Forms/TableForm.js
+0
-261
src/pages/Forms/models/form.js
src/pages/Forms/models/form.js
+0
-47
src/pages/Forms/style.less
src/pages/Forms/style.less
+0
-90
src/pages/List/Applications.js
src/pages/List/Applications.js
+0
-183
src/pages/List/Applications.less
src/pages/List/Applications.less
+0
-43
src/pages/List/Articles.js
src/pages/List/Articles.js
+0
-242
src/pages/List/Articles.less
src/pages/List/Articles.less
+0
-31
src/pages/List/BasicList.js
src/pages/List/BasicList.js
+0
-340
src/pages/List/BasicList.less
src/pages/List/BasicList.less
+0
-195
src/pages/List/CardList.js
src/pages/List/CardList.js
+0
-101
src/pages/List/CardList.less
src/pages/List/CardList.less
+0
-113
src/pages/List/List.js
src/pages/List/List.js
+0
-80
src/pages/List/Projects.js
src/pages/List/Projects.js
+0
-154
src/pages/List/Projects.less
src/pages/List/Projects.less
+0
-57
src/pages/List/TableList.js
src/pages/List/TableList.js
+0
-686
src/pages/List/TableList.less
src/pages/List/TableList.less
+0
-49
src/pages/List/models/rule.js
src/pages/List/models/rule.js
+0
-55
src/pages/Profile/AdvancedProfile.js
src/pages/Profile/AdvancedProfile.js
+0
-353
src/pages/Profile/AdvancedProfile.less
src/pages/Profile/AdvancedProfile.less
+0
-54
src/pages/Profile/BasicProfile.js
src/pages/Profile/BasicProfile.js
+0
-185
src/pages/Profile/BasicProfile.less
src/pages/Profile/BasicProfile.less
+0
-8
src/pages/Profile/models/profile.js
src/pages/Profile/models/profile.js
+0
-38
src/pages/Result/Error.js
src/pages/Result/Error.js
+0
-66
src/pages/Result/Success.js
src/pages/Result/Success.js
+0
-144
src/pages/Result/Success.test.js
src/pages/Result/Success.test.js
+0
-9
src/pages/User/Login.js
src/pages/User/Login.js
+0
-168
src/pages/User/Login.less
src/pages/User/Login.less
+0
-32
src/pages/User/Register.js
src/pages/User/Register.js
+0
-334
src/pages/User/Register.less
src/pages/User/Register.less
+0
-57
src/pages/User/RegisterResult.js
src/pages/User/RegisterResult.js
+0
-41
src/pages/User/RegisterResult.less
src/pages/User/RegisterResult.less
+0
-18
src/pages/User/models/register.js
src/pages/User/models/register.js
+0
-32
src/pages/document.ejs
src/pages/document.ejs
+0
-15
No files found.
.eslintignore
View file @
81ee2c12
/functions/mock/**
/scripts
/config
\ No newline at end of file
/config
config/config.js
View file @
81ee2c12
// https://umijs.org/config/
import
os
from
'
os
'
;
import
pageRoutes
from
'
./router.config
'
;
import
webpackPlugin
from
'
./plugin.config
'
;
import
defaultSettings
from
'
../src/defaultSettings
'
;
import
slash
from
'
slash2
'
;
...
...
@@ -63,7 +62,25 @@ export default {
ie
:
11
,
},
// 路由配置
routes
:
pageRoutes
,
routes
:
[{
path
:
'
/user
'
,
components
:
[
'
../layouts/UserLayout
'
],
routes
:
[],
},
{
path
:
'
/
'
,
component
:
'
../layouts/BasicLayout
'
,
Routes
:
[
'
src/pages/Authorized
'
],
authority
:
[
'
admin
'
,
'
user
'
],
routes
:
[
// dashboard
{
path
:
'
/
'
,
name
:
'
dashboard
'
,
icon
:
'
dashboard
'
,
component
:
'
./BasicDemo
'
,
},
],
}],
// Theme for antd
// https://ant.design/docs/react/customize-theme-cn
theme
:
{
...
...
config/router.config.js
deleted
100644 → 0
View file @
5ba67a51
export
default
[
// user
{
path
:
'
/user
'
,
component
:
'
../layouts/UserLayout
'
,
routes
:
[
{
path
:
'
/user
'
,
redirect
:
'
/user/login
'
},
{
path
:
'
/user/login
'
,
component
:
'
./User/Login
'
},
{
path
:
'
/user/register
'
,
component
:
'
./User/Register
'
},
{
path
:
'
/user/register-result
'
,
component
:
'
./User/RegisterResult
'
},
],
},
// app
{
path
:
'
/
'
,
component
:
'
../layouts/BasicLayout
'
,
Routes
:
[
'
src/pages/Authorized
'
],
authority
:
[
'
admin
'
,
'
user
'
],
routes
:
[
// dashboard
{
path
:
'
/
'
,
redirect
:
'
/dashboard/analysis
'
},
{
path
:
'
/dashboard
'
,
name
:
'
dashboard
'
,
icon
:
'
dashboard
'
,
routes
:
[
{
path
:
'
/dashboard/analysis
'
,
name
:
'
analysis
'
,
component
:
'
./Dashboard/Analysis
'
,
},
{
path
:
'
/dashboard/monitor
'
,
name
:
'
monitor
'
,
component
:
'
./Dashboard/Monitor
'
,
},
{
path
:
'
/dashboard/workplace
'
,
name
:
'
workplace
'
,
component
:
'
./Dashboard/Workplace
'
,
},
],
},
// forms
{
path
:
'
/form
'
,
icon
:
'
form
'
,
name
:
'
form
'
,
routes
:
[
{
path
:
'
/form/basic-form
'
,
name
:
'
basicform
'
,
component
:
'
./Forms/BasicForm
'
,
},
{
path
:
'
/form/step-form
'
,
name
:
'
stepform
'
,
component
:
'
./Forms/StepForm
'
,
hideChildrenInMenu
:
true
,
routes
:
[
{
path
:
'
/form/step-form
'
,
redirect
:
'
/form/step-form/info
'
,
},
{
path
:
'
/form/step-form/info
'
,
name
:
'
info
'
,
component
:
'
./Forms/StepForm/Step1
'
,
},
{
path
:
'
/form/step-form/confirm
'
,
name
:
'
confirm
'
,
component
:
'
./Forms/StepForm/Step2
'
,
},
{
path
:
'
/form/step-form/result
'
,
name
:
'
result
'
,
component
:
'
./Forms/StepForm/Step3
'
,
},
],
},
{
path
:
'
/form/advanced-form
'
,
name
:
'
advancedform
'
,
authority
:
[
'
admin
'
],
component
:
'
./Forms/AdvancedForm
'
,
},
],
},
// list
{
path
:
'
/list
'
,
icon
:
'
table
'
,
name
:
'
list
'
,
routes
:
[
{
path
:
'
/list/table-list
'
,
name
:
'
searchtable
'
,
component
:
'
./List/TableList
'
,
},
{
path
:
'
/list/basic-list
'
,
name
:
'
basiclist
'
,
component
:
'
./List/BasicList
'
,
},
{
path
:
'
/list/card-list
'
,
name
:
'
cardlist
'
,
component
:
'
./List/CardList
'
,
},
{
path
:
'
/list/search
'
,
name
:
'
searchlist
'
,
component
:
'
./List/List
'
,
routes
:
[
{
path
:
'
/list/search
'
,
redirect
:
'
/list/search/articles
'
,
},
{
path
:
'
/list/search/articles
'
,
name
:
'
articles
'
,
component
:
'
./List/Articles
'
,
},
{
path
:
'
/list/search/projects
'
,
name
:
'
projects
'
,
component
:
'
./List/Projects
'
,
},
{
path
:
'
/list/search/applications
'
,
name
:
'
applications
'
,
component
:
'
./List/Applications
'
,
},
],
},
],
},
{
path
:
'
/profile
'
,
name
:
'
profile
'
,
icon
:
'
profile
'
,
routes
:
[
// profile
{
path
:
'
/profile/basic
'
,
name
:
'
basic
'
,
component
:
'
./Profile/BasicProfile
'
,
},
{
path
:
'
/profile/advanced
'
,
name
:
'
advanced
'
,
authority
:
[
'
admin
'
],
component
:
'
./Profile/AdvancedProfile
'
,
},
],
},
{
name
:
'
result
'
,
icon
:
'
check-circle-o
'
,
path
:
'
/result
'
,
routes
:
[
// result
{
path
:
'
/result/success
'
,
name
:
'
success
'
,
component
:
'
./Result/Success
'
,
},
{
path
:
'
/result/fail
'
,
name
:
'
fail
'
,
component
:
'
./Result/Error
'
},
],
},
{
name
:
'
exception
'
,
icon
:
'
warning
'
,
path
:
'
/exception
'
,
routes
:
[
// exception
{
path
:
'
/exception/403
'
,
name
:
'
not-permission
'
,
component
:
'
./Exception/403
'
,
},
{
path
:
'
/exception/404
'
,
name
:
'
not-find
'
,
component
:
'
./Exception/404
'
,
},
{
path
:
'
/exception/500
'
,
name
:
'
server-error
'
,
component
:
'
./Exception/500
'
,
},
{
path
:
'
/exception/trigger
'
,
name
:
'
trigger
'
,
hideInMenu
:
true
,
component
:
'
./Exception/TriggerException
'
,
},
],
},
{
name
:
'
account
'
,
icon
:
'
user
'
,
path
:
'
/account
'
,
routes
:
[
{
path
:
'
/account/center
'
,
name
:
'
center
'
,
component
:
'
./Account/Center/Center
'
,
routes
:
[
{
path
:
'
/account/center
'
,
redirect
:
'
/account/center/articles
'
,
},
{
path
:
'
/account/center/articles
'
,
component
:
'
./Account/Center/Articles
'
,
},
{
path
:
'
/account/center/applications
'
,
component
:
'
./Account/Center/Applications
'
,
},
{
path
:
'
/account/center/projects
'
,
component
:
'
./Account/Center/Projects
'
,
},
],
},
{
path
:
'
/account/settings
'
,
name
:
'
settings
'
,
component
:
'
./Account/Settings/Info
'
,
routes
:
[
{
path
:
'
/account/settings
'
,
redirect
:
'
/account/settings/base
'
,
},
{
path
:
'
/account/settings/base
'
,
component
:
'
./Account/Settings/BaseView
'
,
},
{
path
:
'
/account/settings/security
'
,
component
:
'
./Account/Settings/SecurityView
'
,
},
{
path
:
'
/account/settings/binding
'
,
component
:
'
./Account/Settings/BindingView
'
,
},
{
path
:
'
/account/settings/notification
'
,
component
:
'
./Account/Settings/NotificationView
'
,
},
],
},
],
},
{
component
:
'
404
'
,
},
],
},
];
src/layouts/BasicLayout.js
View file @
81ee2c12
...
...
@@ -14,7 +14,6 @@ import logo from '../assets/logo.svg';
import
Footer
from
'
./Footer
'
;
import
Header
from
'
./Header
'
;
import
Context
from
'
./MenuContext
'
;
import
Exception403
from
'
../pages/Exception/403
'
;
import
PageLoading
from
'
@/components/PageLoading
'
;
import
SiderMenu
from
'
@/components/SiderMenu
'
;
import
{
title
}
from
'
../defaultSettings
'
;
...
...
@@ -25,6 +24,8 @@ const SettingDrawer = React.lazy(() => import('@/components/SettingDrawer'));
const
{
Content
}
=
Layout
;
const
Exception403
=
<
p
>
Exception403
<
/p>
;
const
query
=
{
'
screen-xs
'
:
{
maxWidth
:
575
,
...
...
src/pages/404.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
Link
from
'
umi/link
'
;
import
{
formatMessage
}
from
'
umi/locale
'
;
import
Exception
from
'
ant-design-pro/lib/Exception
'
;
export
default
()
=>
(
<
Exception
type
=
"
404
"
linkElement
=
{
Link
}
desc
=
{
formatMessage
({
id
:
'
app.exception.description.404
'
})}
backText
=
{
formatMessage
({
id
:
'
app.exception.back
'
})}
/
>
);
src/pages/Account/Center/Applications.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
List
,
Card
,
Icon
,
Dropdown
,
Menu
,
Avatar
,
Tooltip
}
from
'
antd
'
;
import
numeral
from
'
numeral
'
;
import
{
connect
}
from
'
dva
'
;
import
{
formatWan
}
from
'
@/utils/utils
'
;
import
stylesApplications
from
'
../../List/Applications.less
'
;
@
connect
(({
list
})
=>
({
list
,
}))
class
Center
extends
PureComponent
{
render
()
{
const
{
list
:
{
list
},
}
=
this
.
props
;
const
itemMenu
=
(
<
Menu
>
<
Menu
.
Item
>
<
a
target
=
"
_blank
"
rel
=
"
noopener noreferrer
"
href
=
"
https://www.alipay.com/
"
>
1
st
menu
item
<
/a
>
<
/Menu.Item
>
<
Menu
.
Item
>
<
a
target
=
"
_blank
"
rel
=
"
noopener noreferrer
"
href
=
"
https://www.taobao.com/
"
>
2
nd
menu
item
<
/a
>
<
/Menu.Item
>
<
Menu
.
Item
>
<
a
target
=
"
_blank
"
rel
=
"
noopener noreferrer
"
href
=
"
https://www.tmall.com/
"
>
3
d
menu
item
<
/a
>
<
/Menu.Item
>
<
/Menu
>
);
const
CardInfo
=
({
activeUser
,
newUser
})
=>
(
<
div
className
=
{
stylesApplications
.
cardInfo
}
>
<
div
>
<
p
>
活跃用户
<
/p
>
<
p
>
{
activeUser
}
<
/p
>
<
/div
>
<
div
>
<
p
>
新增用户
<
/p
>
<
p
>
{
newUser
}
<
/p
>
<
/div
>
<
/div
>
);
return
(
<
List
rowKey
=
"
id
"
className
=
{
stylesApplications
.
filterCardList
}
grid
=
{{
gutter
:
24
,
xxl
:
3
,
xl
:
2
,
lg
:
2
,
md
:
2
,
sm
:
2
,
xs
:
1
}}
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
key
=
{
item
.
id
}
>
<
Card
hoverable
bodyStyle
=
{{
paddingBottom
:
20
}}
actions
=
{[
<
Tooltip
title
=
"
下载
"
>
<
Icon
type
=
"
download
"
/>
<
/Tooltip>
,
<
Tooltip
title
=
"
编辑
"
>
<
Icon
type
=
"
edit
"
/>
<
/Tooltip>
,
<
Tooltip
title
=
"
分享
"
>
<
Icon
type
=
"
share-alt
"
/>
<
/Tooltip>
,
<
Dropdown
overlay
=
{
itemMenu
}
>
<
Icon
type
=
"
ellipsis
"
/>
<
/Dropdown>
,
]}
>
<
Card
.
Meta
avatar
=
{
<
Avatar
size
=
"
small
"
src
=
{
item
.
avatar
}
/>} title={item.title} /
>
<
div
className
=
{
stylesApplications
.
cardItemContent
}
>
<
CardInfo
activeUser
=
{
formatWan
(
item
.
activeUser
)}
newUser
=
{
numeral
(
item
.
newUser
).
format
(
'
0,0
'
)}
/
>
<
/div
>
<
/Card
>
<
/List.Item
>
)}
/
>
);
}
}
export
default
Center
;
src/pages/Account/Center/Articles.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
List
,
Icon
,
Tag
}
from
'
antd
'
;
import
{
connect
}
from
'
dva
'
;
import
ArticleListContent
from
'
@/components/ArticleListContent
'
;
import
styles
from
'
./Articles.less
'
;
@
connect
(({
list
})
=>
({
list
,
}))
class
Center
extends
PureComponent
{
render
()
{
const
{
list
:
{
list
},
}
=
this
.
props
;
const
IconText
=
({
type
,
text
})
=>
(
<
span
>
<
Icon
type
=
{
type
}
style
=
{{
marginRight
:
8
}}
/
>
{
text
}
<
/span
>
);
return
(
<
List
size
=
"
large
"
className
=
{
styles
.
articleList
}
rowKey
=
"
id
"
itemLayout
=
"
vertical
"
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
key
=
{
item
.
id
}
actions
=
{[
<
IconText
type
=
"
star-o
"
text
=
{
item
.
star
}
/>
,
<
IconText
type
=
"
like-o
"
text
=
{
item
.
like
}
/>
,
<
IconText
type
=
"
message
"
text
=
{
item
.
message
}
/>
,
]}
>
<
List
.
Item
.
Meta
title
=
{
<
a
className
=
{
styles
.
listItemMetaTitle
}
href
=
{
item
.
href
}
>
{
item
.
title
}
<
/a
>
}
description
=
{
<
span
>
<
Tag
>
Ant
Design
<
/Tag
>
<
Tag
>
设计语言
<
/Tag
>
<
Tag
>
蚂蚁金服
<
/Tag
>
<
/span
>
}
/
>
<
ArticleListContent
data
=
{
item
}
/
>
<
/List.Item
>
)}
/
>
);
}
}
export
default
Center
;
src/pages/Account/Center/Articles.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.articleList {
:global {
.ant-list-item:first-child {
padding-top: 0;
}
}
}
a.listItemMetaTitle {
color: @heading-color;
}
src/pages/Account/Center/Center.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
Link
from
'
umi/link
'
;
import
router
from
'
umi/router
'
;
import
{
Card
,
Row
,
Col
,
Icon
,
Avatar
,
Tag
,
Divider
,
Spin
,
Input
}
from
'
antd
'
;
import
GridContent
from
'
@/components/PageHeaderWrapper/GridContent
'
;
import
styles
from
'
./Center.less
'
;
@
connect
(({
loading
,
user
,
project
})
=>
({
listLoading
:
loading
.
effects
[
'
list/fetch
'
],
currentUser
:
user
.
currentUser
,
currentUserLoading
:
loading
.
effects
[
'
user/fetchCurrent
'
],
project
,
projectLoading
:
loading
.
effects
[
'
project/fetchNotice
'
],
}))
class
Center
extends
PureComponent
{
state
=
{
newTags
:
[],
inputVisible
:
false
,
inputValue
:
''
,
};
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
user/fetchCurrent
'
,
});
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
8
,
},
});
dispatch
({
type
:
'
project/fetchNotice
'
,
});
}
onTabChange
=
key
=>
{
const
{
match
}
=
this
.
props
;
switch
(
key
)
{
case
'
articles
'
:
router
.
push
(
`
${
match
.
url
}
/articles`
);
break
;
case
'
applications
'
:
router
.
push
(
`
${
match
.
url
}
/applications`
);
break
;
case
'
projects
'
:
router
.
push
(
`
${
match
.
url
}
/projects`
);
break
;
default
:
break
;
}
};
showInput
=
()
=>
{
this
.
setState
({
inputVisible
:
true
},
()
=>
this
.
input
.
focus
());
};
saveInputRef
=
input
=>
{
this
.
input
=
input
;
};
handleInputChange
=
e
=>
{
this
.
setState
({
inputValue
:
e
.
target
.
value
});
};
handleInputConfirm
=
()
=>
{
const
{
state
}
=
this
;
const
{
inputValue
}
=
state
;
let
{
newTags
}
=
state
;
if
(
inputValue
&&
newTags
.
filter
(
tag
=>
tag
.
label
===
inputValue
).
length
===
0
)
{
newTags
=
[...
newTags
,
{
key
:
`new-
${
newTags
.
length
}
`
,
label
:
inputValue
}];
}
this
.
setState
({
newTags
,
inputVisible
:
false
,
inputValue
:
''
,
});
};
render
()
{
const
{
newTags
,
inputVisible
,
inputValue
}
=
this
.
state
;
const
{
listLoading
,
currentUser
,
currentUserLoading
,
project
:
{
notice
},
projectLoading
,
match
,
location
,
children
,
}
=
this
.
props
;
const
operationTabList
=
[
{
key
:
'
articles
'
,
tab
:
(
<
span
>
文章
<
span
style
=
{{
fontSize
:
14
}}
>
(
8
)
<
/span
>
<
/span
>
),
},
{
key
:
'
applications
'
,
tab
:
(
<
span
>
应用
<
span
style
=
{{
fontSize
:
14
}}
>
(
8
)
<
/span
>
<
/span
>
),
},
{
key
:
'
projects
'
,
tab
:
(
<
span
>
项目
<
span
style
=
{{
fontSize
:
14
}}
>
(
8
)
<
/span
>
<
/span
>
),
},
];
return
(
<
GridContent
className
=
{
styles
.
userCenter
}
>
<
Row
gutter
=
{
24
}
>
<
Col
lg
=
{
7
}
md
=
{
24
}
>
<
Card
bordered
=
{
false
}
style
=
{{
marginBottom
:
24
}}
loading
=
{
currentUserLoading
}
>
{
currentUser
&&
Object
.
keys
(
currentUser
).
length
?
(
<
div
>
<
div
className
=
{
styles
.
avatarHolder
}
>
<
img
alt
=
""
src
=
{
currentUser
.
avatar
}
/
>
<
div
className
=
{
styles
.
name
}
>
{
currentUser
.
name
}
<
/div
>
<
div
>
{
currentUser
.
signature
}
<
/div
>
<
/div
>
<
div
className
=
{
styles
.
detail
}
>
<
p
>
<
i
className
=
{
styles
.
title
}
/
>
{
currentUser
.
title
}
<
/p
>
<
p
>
<
i
className
=
{
styles
.
group
}
/
>
{
currentUser
.
group
}
<
/p
>
<
p
>
<
i
className
=
{
styles
.
address
}
/
>
{
currentUser
.
geographic
.
province
.
label
}
{
currentUser
.
geographic
.
city
.
label
}
<
/p
>
<
/div
>
<
Divider
dashed
/>
<
div
className
=
{
styles
.
tags
}
>
<
div
className
=
{
styles
.
tagsTitle
}
>
标签
<
/div
>
{
currentUser
.
tags
.
concat
(
newTags
).
map
(
item
=>
(
<
Tag
key
=
{
item
.
key
}
>
{
item
.
label
}
<
/Tag
>
))}
{
inputVisible
&&
(
<
Input
ref
=
{
this
.
saveInputRef
}
type
=
"
text
"
size
=
"
small
"
style
=
{{
width
:
78
}}
value
=
{
inputValue
}
onChange
=
{
this
.
handleInputChange
}
onBlur
=
{
this
.
handleInputConfirm
}
onPressEnter
=
{
this
.
handleInputConfirm
}
/
>
)}
{
!
inputVisible
&&
(
<
Tag
onClick
=
{
this
.
showInput
}
style
=
{{
background
:
'
#fff
'
,
borderStyle
:
'
dashed
'
}}
>
<
Icon
type
=
"
plus
"
/>
<
/Tag
>
)}
<
/div
>
<
Divider
style
=
{{
marginTop
:
16
}}
dashed
/>
<
div
className
=
{
styles
.
team
}
>
<
div
className
=
{
styles
.
teamTitle
}
>
团队
<
/div
>
<
Spin
spinning
=
{
projectLoading
}
>
<
Row
gutter
=
{
36
}
>
{
notice
.
map
(
item
=>
(
<
Col
key
=
{
item
.
id
}
lg
=
{
24
}
xl
=
{
12
}
>
<
Link
to
=
{
item
.
href
}
>
<
Avatar
size
=
"
small
"
src
=
{
item
.
logo
}
/
>
{
item
.
member
}
<
/Link
>
<
/Col
>
))}
<
/Row
>
<
/Spin
>
<
/div
>
<
/div
>
)
:
(
'
loading...
'
)}
<
/Card
>
<
/Col
>
<
Col
lg
=
{
17
}
md
=
{
24
}
>
<
Card
className
=
{
styles
.
tabsCard
}
bordered
=
{
false
}
tabList
=
{
operationTabList
}
activeTabKey
=
{
location
.
pathname
.
replace
(
`
${
match
.
path
}
/`
,
''
)}
onTabChange
=
{
this
.
onTabChange
}
loading
=
{
listLoading
}
>
{
children
}
<
/Card
>
<
/Col
>
<
/Row
>
<
/GridContent
>
);
}
}
export
default
Center
;
src/pages/Account/Center/Center.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.avatarHolder {
text-align: center;
margin-bottom: 24px;
& > img {
width: 104px;
height: 104px;
margin-bottom: 20px;
}
.name {
font-size: 20px;
line-height: 28px;
font-weight: 500;
color: @heading-color;
margin-bottom: 4px;
}
}
.detail {
p {
margin-bottom: 8px;
padding-left: 26px;
position: relative;
&:last-child {
margin-bottom: 0;
}
}
i {
position: absolute;
height: 14px;
width: 14px;
left: 0;
top: 4px;
background: url(https://gw.alipayobjects.com/zos/rmsportal/pBjWzVAHnOOtAUvZmZfy.svg);
&.title {
background-position: 0 0;
}
&.group {
background-position: 0 -22px;
}
&.address {
background-position: 0 -44px;
}
}
}
.tagsTitle,
.teamTitle {
font-weight: 500;
color: @heading-color;
margin-bottom: 12px;
}
.tags {
:global {
.ant-tag {
margin-bottom: 8px;
}
}
}
.team {
:global {
.ant-avatar {
margin-right: 12px;
}
}
a {
display: block;
margin-bottom: 24px;
color: @text-color;
transition: color 0.3s;
.textOverflow();
&:hover {
color: @primary-color;
}
}
}
.tabsCard {
:global {
.ant-card-head {
padding: 0 16px;
}
}
}
src/pages/Account/Center/Projects.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
List
,
Card
}
from
'
antd
'
;
import
moment
from
'
moment
'
;
import
{
connect
}
from
'
dva
'
;
import
AvatarList
from
'
ant-design-pro/lib/AvatarList
'
;
import
stylesProjects
from
'
../../List/Projects.less
'
;
@
connect
(({
list
})
=>
({
list
,
}))
class
Center
extends
PureComponent
{
render
()
{
const
{
list
:
{
list
},
}
=
this
.
props
;
return
(
<
List
className
=
{
stylesProjects
.
coverCardList
}
rowKey
=
"
id
"
grid
=
{{
gutter
:
24
,
xxl
:
3
,
xl
:
2
,
lg
:
2
,
md
:
2
,
sm
:
2
,
xs
:
1
}}
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
>
<
Card
className
=
{
stylesProjects
.
card
}
hoverable
cover
=
{
<
img
alt
=
{
item
.
title
}
src
=
{
item
.
cover
}
/>
}
>
<
Card
.
Meta
title
=
{
<
a
>
{
item
.
title
}
<
/a>} description={item.subDescription} /
>
<
div
className
=
{
stylesProjects
.
cardItemContent
}
>
<
span
>
{
moment
(
item
.
updatedAt
).
fromNow
()}
<
/span
>
<
div
className
=
{
stylesProjects
.
avatarList
}
>
<
AvatarList
size
=
"
mini
"
>
{
item
.
members
.
map
(
member
=>
(
<
AvatarList
.
Item
key
=
{
`
${
item
.
id
}
-avatar-
${
member
.
id
}
`
}
src
=
{
member
.
avatar
}
tips
=
{
member
.
name
}
/
>
))}
<
/AvatarList
>
<
/div
>
<
/div
>
<
/Card
>
<
/List.Item
>
)}
/
>
);
}
}
export
default
Center
;
src/pages/Account/Settings/BaseView.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Fragment
}
from
'
react
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Form
,
Input
,
Upload
,
Select
,
Button
}
from
'
antd
'
;
import
{
connect
}
from
'
dva
'
;
import
styles
from
'
./BaseView.less
'
;
import
GeographicView
from
'
./GeographicView
'
;
import
PhoneView
from
'
./PhoneView
'
;
// import { getTimeDistance } from '@/utils/utils';
const
FormItem
=
Form
.
Item
;
const
{
Option
}
=
Select
;
// 头像组件 方便以后独立,增加裁剪之类的功能
const
AvatarView
=
({
avatar
})
=>
(
<
Fragment
>
<
div
className
=
{
styles
.
avatar_title
}
>
<
FormattedMessage
id
=
"
app.settings.basic.avatar
"
defaultMessage
=
"
Avatar
"
/>
<
/div
>
<
div
className
=
{
styles
.
avatar
}
>
<
img
src
=
{
avatar
}
alt
=
"
avatar
"
/>
<
/div
>
<
Upload
fileList
=
{[]}
>
<
div
className
=
{
styles
.
button_view
}
>
<
Button
icon
=
"
upload
"
>
<
FormattedMessage
id
=
"
app.settings.basic.change-avatar
"
defaultMessage
=
"
Change avatar
"
/>
<
/Button
>
<
/div
>
<
/Upload
>
<
/Fragment
>
);
const
validatorGeographic
=
(
rule
,
value
,
callback
)
=>
{
const
{
province
,
city
}
=
value
;
if
(
!
province
.
key
)
{
callback
(
'
Please input your province!
'
);
}
if
(
!
city
.
key
)
{
callback
(
'
Please input your city!
'
);
}
callback
();
};
const
validatorPhone
=
(
rule
,
value
,
callback
)
=>
{
const
values
=
value
.
split
(
'
-
'
);
if
(
!
values
[
0
])
{
callback
(
'
Please input your area code!
'
);
}
if
(
!
values
[
1
])
{
callback
(
'
Please input your phone number!
'
);
}
callback
();
};
@
connect
(({
user
})
=>
({
currentUser
:
user
.
currentUser
,
}))
@
Form
.
create
()
class
BaseView
extends
Component
{
componentDidMount
()
{
this
.
setBaseInfo
();
}
setBaseInfo
=
()
=>
{
const
{
currentUser
,
form
}
=
this
.
props
;
Object
.
keys
(
form
.
getFieldsValue
()).
forEach
(
key
=>
{
const
obj
=
{};
obj
[
key
]
=
currentUser
[
key
]
||
null
;
form
.
setFieldsValue
(
obj
);
});
};
getAvatarURL
()
{
const
{
currentUser
}
=
this
.
props
;
if
(
currentUser
.
avatar
)
{
return
currentUser
.
avatar
;
}
const
url
=
'
https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png
'
;
return
url
;
}
getViewDom
=
ref
=>
{
this
.
view
=
ref
;
};
render
()
{
const
{
form
:
{
getFieldDecorator
},
}
=
this
.
props
;
return
(
<
div
className
=
{
styles
.
baseView
}
ref
=
{
this
.
getViewDom
}
>
<
div
className
=
{
styles
.
left
}
>
<
Form
layout
=
"
vertical
"
onSubmit
=
{
this
.
handleSubmit
}
hideRequiredMark
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.email
'
})}
>
{
getFieldDecorator
(
'
email
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.email-message
'
},
{}),
},
],
})(
<
Input
/>
)}
<
/FormItem
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.nickname
'
})}
>
{
getFieldDecorator
(
'
name
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.nickname-message
'
},
{}),
},
],
})(
<
Input
/>
)}
<
/FormItem
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.profile
'
})}
>
{
getFieldDecorator
(
'
profile
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.profile-message
'
},
{}),
},
],
})(
<
Input
.
TextArea
placeholder
=
{
formatMessage
({
id
:
'
app.settings.basic.profile-placeholder
'
})}
rows
=
{
4
}
/
>
)}
<
/FormItem
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.country
'
})}
>
{
getFieldDecorator
(
'
country
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.country-message
'
},
{}),
},
],
})(
<
Select
style
=
{{
maxWidth
:
220
}}
>
<
Option
value
=
"
China
"
>
中国
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.geographic
'
})}
>
{
getFieldDecorator
(
'
geographic
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.geographic-message
'
},
{}),
},
{
validator
:
validatorGeographic
,
},
],
})(
<
GeographicView
/>
)}
<
/FormItem
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.address
'
})}
>
{
getFieldDecorator
(
'
address
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.address-message
'
},
{}),
},
],
})(
<
Input
/>
)}
<
/FormItem
>
<
FormItem
label
=
{
formatMessage
({
id
:
'
app.settings.basic.phone
'
})}
>
{
getFieldDecorator
(
'
phone
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
app.settings.basic.phone-message
'
},
{}),
},
{
validator
:
validatorPhone
},
],
})(
<
PhoneView
/>
)}
<
/FormItem
>
<
Button
type
=
"
primary
"
>
<
FormattedMessage
id
=
"
app.settings.basic.update
"
defaultMessage
=
"
Update Information
"
/>
<
/Button
>
<
/Form
>
<
/div
>
<
div
className
=
{
styles
.
right
}
>
<
AvatarView
avatar
=
{
this
.
getAvatarURL
()}
/
>
<
/div
>
<
/div
>
);
}
}
export
default
BaseView
;
src/pages/Account/Settings/BaseView.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.baseView {
display: flex;
padding-top: 12px;
.left {
max-width: 448px;
min-width: 224px;
}
.right {
flex: 1;
padding-left: 104px;
.avatar_title {
height: 22px;
font-size: @font-size-base;
color: @heading-color;
line-height: 22px;
margin-bottom: 8px;
}
.avatar {
width: 144px;
height: 144px;
margin-bottom: 12px;
overflow: hidden;
img {
width: 100%;
}
}
.button_view {
width: 144px;
text-align: center;
}
}
}
@media screen and (max-width: @screen-xl) {
.baseView {
flex-direction: column-reverse;
.right {
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
max-width: 448px;
.avatar_title {
display: none;
}
}
}
}
src/pages/Account/Settings/BindingView.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Fragment
}
from
'
react
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Icon
,
List
}
from
'
antd
'
;
class
BindingView
extends
Component
{
getData
=
()
=>
[
{
title
:
formatMessage
({
id
:
'
app.settings.binding.taobao
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.binding.taobao-description
'
},
{}),
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.binding.bind
"
defaultMessage
=
"
Bind
"
/>
<
/a>
,
],
avatar
:
<
Icon
type
=
"
taobao
"
className
=
"
taobao
"
/>
,
},
{
title
:
formatMessage
({
id
:
'
app.settings.binding.alipay
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.binding.alipay-description
'
},
{}),
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.binding.bind
"
defaultMessage
=
"
Bind
"
/>
<
/a>
,
],
avatar
:
<
Icon
type
=
"
alipay
"
className
=
"
alipay
"
/>
,
},
{
title
:
formatMessage
({
id
:
'
app.settings.binding.dingding
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.binding.dingding-description
'
},
{}),
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.binding.bind
"
defaultMessage
=
"
Bind
"
/>
<
/a>
,
],
avatar
:
<
Icon
type
=
"
dingding
"
className
=
"
dingding
"
/>
,
},
];
render
()
{
return
(
<
Fragment
>
<
List
itemLayout
=
"
horizontal
"
dataSource
=
{
this
.
getData
()}
renderItem
=
{
item
=>
(
<
List
.
Item
actions
=
{
item
.
actions
}
>
<
List
.
Item
.
Meta
avatar
=
{
item
.
avatar
}
title
=
{
item
.
title
}
description
=
{
item
.
description
}
/
>
<
/List.Item
>
)}
/
>
<
/Fragment
>
);
}
}
export
default
BindingView
;
src/pages/Account/Settings/GeographicView.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
Select
,
Spin
}
from
'
antd
'
;
import
{
connect
}
from
'
dva
'
;
import
styles
from
'
./GeographicView.less
'
;
const
{
Option
}
=
Select
;
const
nullSlectItem
=
{
label
:
''
,
key
:
''
,
};
@
connect
(({
geographic
})
=>
{
const
{
province
,
isLoading
,
city
}
=
geographic
;
return
{
province
,
city
,
isLoading
,
};
})
class
GeographicView
extends
PureComponent
{
componentDidMount
=
()
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
geographic/fetchProvince
'
,
});
};
componentDidUpdate
(
props
)
{
const
{
dispatch
,
value
}
=
this
.
props
;
if
(
!
props
.
value
&&
!!
value
&&
!!
value
.
province
)
{
dispatch
({
type
:
'
geographic/fetchCity
'
,
payload
:
value
.
province
.
key
,
});
}
}
getProvinceOption
()
{
const
{
province
}
=
this
.
props
;
return
this
.
getOption
(
province
);
}
getCityOption
=
()
=>
{
const
{
city
}
=
this
.
props
;
return
this
.
getOption
(
city
);
};
getOption
=
list
=>
{
if
(
!
list
||
list
.
length
<
1
)
{
return
(
<
Option
key
=
{
0
}
value
=
{
0
}
>
没有找到选项
<
/Option
>
);
}
return
list
.
map
(
item
=>
(
<
Option
key
=
{
item
.
id
}
value
=
{
item
.
id
}
>
{
item
.
name
}
<
/Option
>
));
};
selectProvinceItem
=
item
=>
{
const
{
dispatch
,
onChange
}
=
this
.
props
;
dispatch
({
type
:
'
geographic/fetchCity
'
,
payload
:
item
.
key
,
});
onChange
({
province
:
item
,
city
:
nullSlectItem
,
});
};
selectCityItem
=
item
=>
{
const
{
value
,
onChange
}
=
this
.
props
;
onChange
({
province
:
value
.
province
,
city
:
item
,
});
};
conversionObject
()
{
const
{
value
}
=
this
.
props
;
if
(
!
value
)
{
return
{
province
:
nullSlectItem
,
city
:
nullSlectItem
,
};
}
const
{
province
,
city
}
=
value
;
return
{
province
:
province
||
nullSlectItem
,
city
:
city
||
nullSlectItem
,
};
}
render
()
{
const
{
province
,
city
}
=
this
.
conversionObject
();
const
{
isLoading
}
=
this
.
props
;
return
(
<
Spin
spinning
=
{
isLoading
}
wrapperClassName
=
{
styles
.
row
}
>
<
Select
className
=
{
styles
.
item
}
value
=
{
province
}
labelInValue
showSearch
onSelect
=
{
this
.
selectProvinceItem
}
>
{
this
.
getProvinceOption
()}
<
/Select
>
<
Select
className
=
{
styles
.
item
}
value
=
{
city
}
labelInValue
showSearch
onSelect
=
{
this
.
selectCityItem
}
>
{
this
.
getCityOption
()}
<
/Select
>
<
/Spin
>
);
}
}
export
default
GeographicView
;
src/pages/Account/Settings/GeographicView.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.row {
.item {
max-width: 220px;
width: 50%;
}
.item:first-child {
margin-right: 8px;
width: ~'calc(50% - 8px)';
}
}
@media screen and (max-width: @screen-sm) {
.item:first-child {
margin: 0;
margin-bottom: 8px;
}
}
src/pages/Account/Settings/Info.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
router
from
'
umi/router
'
;
import
{
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Menu
}
from
'
antd
'
;
import
GridContent
from
'
@/components/PageHeaderWrapper/GridContent
'
;
import
styles
from
'
./Info.less
'
;
const
{
Item
}
=
Menu
;
@
connect
(({
user
})
=>
({
currentUser
:
user
.
currentUser
,
}))
class
Info
extends
Component
{
constructor
(
props
)
{
super
(
props
);
const
{
match
,
location
}
=
props
;
const
menuMap
=
{
base
:
<
FormattedMessage
id
=
"
app.settings.menuMap.basic
"
defaultMessage
=
"
Basic Settings
"
/>
,
security
:
(
<
FormattedMessage
id
=
"
app.settings.menuMap.security
"
defaultMessage
=
"
Security Settings
"
/>
),
binding
:
(
<
FormattedMessage
id
=
"
app.settings.menuMap.binding
"
defaultMessage
=
"
Account Binding
"
/>
),
notification
:
(
<
FormattedMessage
id
=
"
app.settings.menuMap.notification
"
defaultMessage
=
"
New Message Notification
"
/>
),
};
const
key
=
location
.
pathname
.
replace
(
`
${
match
.
path
}
/`
,
''
);
this
.
state
=
{
mode
:
'
inline
'
,
menuMap
,
selectKey
:
menuMap
[
key
]
?
key
:
'
base
'
,
};
}
static
getDerivedStateFromProps
(
props
,
state
)
{
const
{
match
,
location
}
=
props
;
let
selectKey
=
location
.
pathname
.
replace
(
`
${
match
.
path
}
/`
,
''
);
selectKey
=
state
.
menuMap
[
selectKey
]
?
selectKey
:
'
base
'
;
if
(
selectKey
!==
state
.
selectKey
)
{
return
{
selectKey
};
}
return
null
;
}
componentDidMount
()
{
window
.
addEventListener
(
'
resize
'
,
this
.
resize
);
this
.
resize
();
}
componentWillUnmount
()
{
window
.
removeEventListener
(
'
resize
'
,
this
.
resize
);
}
getmenu
=
()
=>
{
const
{
menuMap
}
=
this
.
state
;
return
Object
.
keys
(
menuMap
).
map
(
item
=>
<
Item
key
=
{
item
}
>
{
menuMap
[
item
]}
<
/Item>
)
;
};
getRightTitle
=
()
=>
{
const
{
selectKey
,
menuMap
}
=
this
.
state
;
return
menuMap
[
selectKey
];
};
selectKey
=
({
key
})
=>
{
router
.
push
(
`/account/settings/
${
key
}
`
);
this
.
setState
({
selectKey
:
key
,
});
};
resize
=
()
=>
{
if
(
!
this
.
main
)
{
return
;
}
requestAnimationFrame
(()
=>
{
let
mode
=
'
inline
'
;
const
{
offsetWidth
}
=
this
.
main
;
if
(
this
.
main
.
offsetWidth
<
641
&&
offsetWidth
>
400
)
{
mode
=
'
horizontal
'
;
}
if
(
window
.
innerWidth
<
768
&&
offsetWidth
>
400
)
{
mode
=
'
horizontal
'
;
}
this
.
setState
({
mode
,
});
});
};
render
()
{
const
{
children
,
currentUser
}
=
this
.
props
;
if
(
!
currentUser
.
userid
)
{
return
''
;
}
const
{
mode
,
selectKey
}
=
this
.
state
;
return
(
<
GridContent
>
<
div
className
=
{
styles
.
main
}
ref
=
{
ref
=>
{
this
.
main
=
ref
;
}}
>
<
div
className
=
{
styles
.
leftmenu
}
>
<
Menu
mode
=
{
mode
}
selectedKeys
=
{[
selectKey
]}
onClick
=
{
this
.
selectKey
}
>
{
this
.
getmenu
()}
<
/Menu
>
<
/div
>
<
div
className
=
{
styles
.
right
}
>
<
div
className
=
{
styles
.
title
}
>
{
this
.
getRightTitle
()}
<
/div
>
{
children
}
<
/div
>
<
/div
>
<
/GridContent
>
);
}
}
export
default
Info
;
src/pages/Account/Settings/Info.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.main {
width: 100%;
height: 100%;
background-color: @body-background;
display: flex;
padding-top: 16px;
padding-bottom: 16px;
overflow: auto;
.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-left: 40px;
padding-right: 40px;
padding-top: 8px;
padding-bottom: 8px;
.title {
font-size: 20px;
color: @heading-color;
line-height: 28px;
font-weight: 500;
margin-bottom: 12px;
}
}
:global {
.ant-list-split .ant-list-item:last-child {
border-bottom: 1px solid #e8e8e8;
}
.ant-list-item {
padding-top: 14px;
padding-bottom: 14px;
}
}
}
:global {
.ant-list-item-meta {
// 账号绑定图标
.taobao {
color: #ff4000;
display: block;
font-size: 48px;
line-height: 48px;
border-radius: @border-radius-base;
}
.dingding {
background-color: #2eabff;
color: #fff;
font-size: 32px;
line-height: 32px;
padding: 6px;
margin: 2px;
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;
}
}
}
src/pages/Account/Settings/NotificationView.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Fragment
}
from
'
react
'
;
import
{
formatMessage
}
from
'
umi/locale
'
;
import
{
Switch
,
List
}
from
'
antd
'
;
class
NotificationView
extends
Component
{
getData
=
()
=>
{
const
Action
=
(
<
Switch
checkedChildren
=
{
formatMessage
({
id
:
'
app.settings.open
'
})}
unCheckedChildren
=
{
formatMessage
({
id
:
'
app.settings.close
'
})}
defaultChecked
/>
);
return
[
{
title
:
formatMessage
({
id
:
'
app.settings.notification.password
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.notification.password-description
'
},
{}),
actions
:
[
Action
],
},
{
title
:
formatMessage
({
id
:
'
app.settings.notification.messages
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.notification.messages-description
'
},
{}),
actions
:
[
Action
],
},
{
title
:
formatMessage
({
id
:
'
app.settings.notification.todo
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.notification.todo-description
'
},
{}),
actions
:
[
Action
],
},
];
};
render
()
{
return
(
<
Fragment
>
<
List
itemLayout
=
"
horizontal
"
dataSource
=
{
this
.
getData
()}
renderItem
=
{
item
=>
(
<
List
.
Item
actions
=
{
item
.
actions
}
>
<
List
.
Item
.
Meta
title
=
{
item
.
title
}
description
=
{
item
.
description
}
/
>
<
/List.Item
>
)}
/
>
<
/Fragment
>
);
}
}
export
default
NotificationView
;
src/pages/Account/Settings/PhoneView.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Fragment
,
PureComponent
}
from
'
react
'
;
import
{
Input
}
from
'
antd
'
;
import
styles
from
'
./PhoneView.less
'
;
class
PhoneView
extends
PureComponent
{
render
()
{
const
{
value
,
onChange
}
=
this
.
props
;
let
values
=
[
''
,
''
];
if
(
value
)
{
values
=
value
.
split
(
'
-
'
);
}
return
(
<
Fragment
>
<
Input
className
=
{
styles
.
area_code
}
value
=
{
values
[
0
]}
onChange
=
{
e
=>
{
onChange
(
`
${
e
.
target
.
value
}
-
${
values
[
1
]}
`
);
}}
/
>
<
Input
className
=
{
styles
.
phone_number
}
onChange
=
{
e
=>
{
onChange
(
`
${
values
[
0
]}
-
${
e
.
target
.
value
}
`
);
}}
value
=
{
values
[
1
]}
/
>
<
/Fragment
>
);
}
}
export
default
PhoneView
;
src/pages/Account/Settings/PhoneView.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.area_code {
max-width: 128px;
margin-right: 8px;
width: 30%;
}
.phone_number {
max-width: 312px;
width: ~'calc(70% - 8px)';
}
src/pages/Account/Settings/SecurityView.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Fragment
}
from
'
react
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
List
}
from
'
antd
'
;
// import { getTimeDistance } from '@/utils/utils';
const
passwordStrength
=
{
strong
:
(
<
font
className
=
"
strong
"
>
<
FormattedMessage
id
=
"
app.settings.security.strong
"
defaultMessage
=
"
Strong
"
/>
<
/font
>
),
medium
:
(
<
font
className
=
"
medium
"
>
<
FormattedMessage
id
=
"
app.settings.security.medium
"
defaultMessage
=
"
Medium
"
/>
<
/font
>
),
weak
:
(
<
font
className
=
"
weak
"
>
<
FormattedMessage
id
=
"
app.settings.security.weak
"
defaultMessage
=
"
Weak
"
/>
Weak
<
/font
>
),
};
class
SecurityView
extends
Component
{
getData
=
()
=>
[
{
title
:
formatMessage
({
id
:
'
app.settings.security.password
'
},
{}),
description
:
(
<
Fragment
>
{
formatMessage
({
id
:
'
app.settings.security.password-description
'
})}
:
{
passwordStrength
.
strong
}
<
/Fragment
>
),
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.security.modify
"
defaultMessage
=
"
Modify
"
/>
<
/a>
,
],
},
{
title
:
formatMessage
({
id
:
'
app.settings.security.phone
'
},
{}),
description
:
`
${
formatMessage
(
{
id
:
'
app.settings.security.phone-description
'
},
{}
)}
:138****8293`
,
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.security.modify
"
defaultMessage
=
"
Modify
"
/>
<
/a>
,
],
},
{
title
:
formatMessage
({
id
:
'
app.settings.security.question
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.security.question-description
'
},
{}),
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.security.set
"
defaultMessage
=
"
Set
"
/>
<
/a>
,
],
},
{
title
:
formatMessage
({
id
:
'
app.settings.security.email
'
},
{}),
description
:
`
${
formatMessage
(
{
id
:
'
app.settings.security.email-description
'
},
{}
)}
:ant***sign.com`
,
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.security.modify
"
defaultMessage
=
"
Modify
"
/>
<
/a>
,
],
},
{
title
:
formatMessage
({
id
:
'
app.settings.security.mfa
'
},
{}),
description
:
formatMessage
({
id
:
'
app.settings.security.mfa-description
'
},
{}),
actions
:
[
<
a
>
<
FormattedMessage
id
=
"
app.settings.security.bind
"
defaultMessage
=
"
Bind
"
/>
<
/a>
,
],
},
];
render
()
{
return
(
<
Fragment
>
<
List
itemLayout
=
"
horizontal
"
dataSource
=
{
this
.
getData
()}
renderItem
=
{
item
=>
(
<
List
.
Item
actions
=
{
item
.
actions
}
>
<
List
.
Item
.
Meta
title
=
{
item
.
title
}
description
=
{
item
.
description
}
/
>
<
/List.Item
>
)}
/
>
<
/Fragment
>
);
}
}
export
default
SecurityView
;
src/pages/Account/Settings/models/geographic.js
deleted
100644 → 0
View file @
5ba67a51
import
{
queryProvince
,
queryCity
}
from
'
@/services/geographic
'
;
export
default
{
namespace
:
'
geographic
'
,
state
:
{
province
:
[],
city
:
[],
isLoading
:
false
,
},
effects
:
{
*
fetchProvince
(
_
,
{
call
,
put
})
{
yield
put
({
type
:
'
changeLoading
'
,
payload
:
true
,
});
const
response
=
yield
call
(
queryProvince
);
yield
put
({
type
:
'
setProvince
'
,
payload
:
response
,
});
yield
put
({
type
:
'
changeLoading
'
,
payload
:
false
,
});
},
*
fetchCity
({
payload
},
{
call
,
put
})
{
yield
put
({
type
:
'
changeLoading
'
,
payload
:
true
,
});
const
response
=
yield
call
(
queryCity
,
payload
);
yield
put
({
type
:
'
setCity
'
,
payload
:
response
,
});
yield
put
({
type
:
'
changeLoading
'
,
payload
:
false
,
});
},
},
reducers
:
{
setProvince
(
state
,
action
)
{
return
{
...
state
,
province
:
action
.
payload
,
};
},
setCity
(
state
,
action
)
{
return
{
...
state
,
city
:
action
.
payload
,
};
},
changeLoading
(
state
,
action
)
{
return
{
...
state
,
isLoading
:
action
.
payload
,
};
},
},
};
src/pages/BasicDemo.js
0 → 100644
View file @
81ee2c12
import
React
from
'
react
'
;
export
default
()
=>
<
p
>
hello
pro
!<
/p>
;
src/pages/Dashboard/Analysis.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Suspense
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Row
,
Col
,
Icon
,
Menu
,
Dropdown
}
from
'
antd
'
;
import
GridContent
from
'
@/components/PageHeaderWrapper/GridContent
'
;
import
{
getTimeDistance
}
from
'
@/utils/utils
'
;
import
styles
from
'
./Analysis.less
'
;
import
PageLoading
from
'
@/components/PageLoading
'
;
const
IntroduceRow
=
React
.
lazy
(()
=>
import
(
'
./IntroduceRow
'
));
const
SalesCard
=
React
.
lazy
(()
=>
import
(
'
./SalesCard
'
));
const
TopSearch
=
React
.
lazy
(()
=>
import
(
'
./TopSearch
'
));
const
ProportionSales
=
React
.
lazy
(()
=>
import
(
'
./ProportionSales
'
));
const
OfflineData
=
React
.
lazy
(()
=>
import
(
'
./OfflineData
'
));
@
connect
(({
chart
,
loading
})
=>
({
chart
,
loading
:
loading
.
effects
[
'
chart/fetch
'
],
}))
class
Analysis
extends
Component
{
state
=
{
salesType
:
'
all
'
,
currentTabKey
:
''
,
rangePickerValue
:
getTimeDistance
(
'
year
'
),
};
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
this
.
reqRef
=
requestAnimationFrame
(()
=>
{
dispatch
({
type
:
'
chart/fetch
'
,
});
});
}
componentWillUnmount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
chart/clear
'
,
});
cancelAnimationFrame
(
this
.
reqRef
);
clearTimeout
(
this
.
timeoutId
);
}
handleChangeSalesType
=
e
=>
{
this
.
setState
({
salesType
:
e
.
target
.
value
,
});
};
handleTabChange
=
key
=>
{
this
.
setState
({
currentTabKey
:
key
,
});
};
handleRangePickerChange
=
rangePickerValue
=>
{
const
{
dispatch
}
=
this
.
props
;
this
.
setState
({
rangePickerValue
,
});
dispatch
({
type
:
'
chart/fetchSalesData
'
,
});
};
selectDate
=
type
=>
{
const
{
dispatch
}
=
this
.
props
;
this
.
setState
({
rangePickerValue
:
getTimeDistance
(
type
),
});
dispatch
({
type
:
'
chart/fetchSalesData
'
,
});
};
isActive
=
type
=>
{
const
{
rangePickerValue
}
=
this
.
state
;
const
value
=
getTimeDistance
(
type
);
if
(
!
rangePickerValue
[
0
]
||
!
rangePickerValue
[
1
])
{
return
''
;
}
if
(
rangePickerValue
[
0
].
isSame
(
value
[
0
],
'
day
'
)
&&
rangePickerValue
[
1
].
isSame
(
value
[
1
],
'
day
'
)
)
{
return
styles
.
currentDate
;
}
return
''
;
};
render
()
{
const
{
rangePickerValue
,
salesType
,
currentTabKey
}
=
this
.
state
;
const
{
chart
,
loading
}
=
this
.
props
;
const
{
visitData
,
visitData2
,
salesData
,
searchData
,
offlineData
,
offlineChartData
,
salesTypeData
,
salesTypeDataOnline
,
salesTypeDataOffline
,
}
=
chart
;
let
salesPieData
;
if
(
salesType
===
'
all
'
)
{
salesPieData
=
salesTypeData
;
}
else
{
salesPieData
=
salesType
===
'
online
'
?
salesTypeDataOnline
:
salesTypeDataOffline
;
}
const
menu
=
(
<
Menu
>
<
Menu
.
Item
>
操作一
<
/Menu.Item
>
<
Menu
.
Item
>
操作二
<
/Menu.Item
>
<
/Menu
>
);
const
dropdownGroup
=
(
<
span
className
=
{
styles
.
iconGroup
}
>
<
Dropdown
overlay
=
{
menu
}
placement
=
"
bottomRight
"
>
<
Icon
type
=
"
ellipsis
"
/>
<
/Dropdown
>
<
/span
>
);
const
activeKey
=
currentTabKey
||
(
offlineData
[
0
]
&&
offlineData
[
0
].
name
);
return
(
<
GridContent
>
<
Suspense
fallback
=
{
<
PageLoading
/>
}
>
<
IntroduceRow
loading
=
{
loading
}
visitData
=
{
visitData
}
/
>
<
/Suspense
>
<
Suspense
fallback
=
{
null
}
>
<
SalesCard
rangePickerValue
=
{
rangePickerValue
}
salesData
=
{
salesData
}
isActive
=
{
this
.
isActive
}
handleRangePickerChange
=
{
this
.
handleRangePickerChange
}
loading
=
{
loading
}
selectDate
=
{
this
.
selectDate
}
/
>
<
/Suspense
>
<
div
className
=
{
styles
.
twoColLayout
}
>
<
Row
gutter
=
{
24
}
>
<
Col
xl
=
{
12
}
lg
=
{
24
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
Suspense
fallback
=
{
null
}
>
<
TopSearch
loading
=
{
loading
}
visitData2
=
{
visitData2
}
selectDate
=
{
this
.
selectDate
}
searchData
=
{
searchData
}
dropdownGroup
=
{
dropdownGroup
}
/
>
<
/Suspense
>
<
/Col
>
<
Col
xl
=
{
12
}
lg
=
{
24
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
Suspense
fallback
=
{
null
}
>
<
ProportionSales
dropdownGroup
=
{
dropdownGroup
}
salesType
=
{
salesType
}
loading
=
{
loading
}
salesPieData
=
{
salesPieData
}
handleChangeSalesType
=
{
this
.
handleChangeSalesType
}
/
>
<
/Suspense
>
<
/Col
>
<
/Row
>
<
/div
>
<
Suspense
fallback
=
{
null
}
>
<
OfflineData
activeKey
=
{
activeKey
}
loading
=
{
loading
}
offlineData
=
{
offlineData
}
offlineChartData
=
{
offlineChartData
}
handleTabChange
=
{
this
.
handleTabChange
}
/
>
<
/Suspense
>
<
/GridContent
>
);
}
}
export
default
Analysis
;
src/pages/Dashboard/Analysis.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.iconGroup {
i {
transition: color 0.32s;
color: @text-color-secondary;
cursor: pointer;
margin-left: 16px;
&:hover {
color: @text-color;
}
}
}
.rankingList {
margin: 25px 0 0;
padding: 0;
list-style: none;
li {
.clearfix();
margin-top: 16px;
display: flex;
align-items: center;
span {
color: @text-color;
font-size: 14px;
line-height: 22px;
}
.rankingItemNumber {
background-color: @background-color-base;
border-radius: 20px;
display: inline-block;
font-size: 12px;
font-weight: 600;
margin-right: 16px;
height: 20px;
line-height: 20px;
width: 20px;
text-align: center;
margin-top: 1.5px;
&.active {
background-color: #314659;
color: #fff;
}
}
.rankingItemTitle {
flex: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-right: 8px;
}
}
}
.salesExtra {
display: inline-block;
margin-right: 24px;
a {
color: @text-color;
margin-left: 24px;
&:hover {
color: @primary-color;
}
&.currentDate {
color: @primary-color;
}
}
}
.salesCard {
.salesBar {
padding: 0 0 32px 32px;
}
.salesRank {
padding: 0 32px 32px 72px;
}
:global {
.ant-tabs-bar {
padding-left: 16px;
.ant-tabs-nav .ant-tabs-tab {
padding-top: 16px;
padding-bottom: 14px;
line-height: 24px;
}
}
.ant-tabs-extra-content {
padding-right: 24px;
line-height: 55px;
}
.ant-card-head {
position: relative;
}
.ant-card-head-title {
align-items: normal;
}
}
}
.salesCardExtra {
height: inherit;
}
.salesTypeRadio {
position: absolute;
right: 54px;
bottom: 12px;
}
.offlineCard {
:global {
.ant-tabs-ink-bar {
bottom: auto;
}
.ant-tabs-bar {
border-bottom: none;
}
.ant-tabs-nav-container-scrolling {
padding-left: 40px;
padding-right: 40px;
}
.ant-tabs-tab-prev-icon:before {
position: relative;
left: 6px;
}
.ant-tabs-tab-next-icon:before {
position: relative;
right: 6px;
}
.ant-tabs-tab-active h4 {
color: @primary-color;
}
}
}
.twoColLayout {
.salesCard {
height: calc(100% - 24px);
}
div[class^='ant-col']:last-child {
right: 0\9;
height: 100%\9;
position: absolute\9;
}
:global {
.ant-row {
display: flex;
display: block\9;
flex-flow: row wrap;
position: relative\9;
}
}
}
.trendText {
margin-left: 8px;
color: @heading-color;
}
@media screen and (max-width: @screen-lg) {
.salesExtra {
display: none;
}
.rankingList {
li {
span:first-child {
margin-right: 8px;
}
}
}
}
@media screen and (max-width: @screen-md) {
.rankingTitle {
margin-top: 16px;
}
.salesCard .salesBar {
padding: 16px;
}
}
@media screen and (max-width: @screen-sm) {
.salesExtraWrap {
display: none;
}
.salesCard {
:global {
.ant-tabs-content {
padding-top: 30px;
}
}
}
}
src/pages/Dashboard/IntroduceRow.js
deleted
100755 → 0
View file @
5ba67a51
import
React
,
{
memo
}
from
'
react
'
;
import
{
Row
,
Col
,
Icon
,
Tooltip
}
from
'
antd
'
;
import
{
FormattedMessage
}
from
'
umi/locale
'
;
import
styles
from
'
./Analysis.less
'
;
import
{
ChartCard
,
MiniArea
,
MiniBar
,
MiniProgress
,
Field
}
from
'
ant-design-pro/lib/Charts
'
;
import
Trend
from
'
ant-design-pro/lib/Trend
'
;
import
numeral
from
'
numeral
'
;
import
Yuan
from
'
@/utils/Yuan
'
;
const
topColResponsiveProps
=
{
xs
:
24
,
sm
:
12
,
md
:
12
,
lg
:
12
,
xl
:
6
,
style
:
{
marginBottom
:
24
},
};
const
IntroduceRow
=
memo
(({
loading
,
visitData
})
=>
(
<
Row
gutter
=
{
24
}
>
<
Col
{...
topColResponsiveProps
}
>
<
ChartCard
bordered
=
{
false
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.total-sales
"
defaultMessage
=
"
Total Sales
"
/>
}
action
=
{
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.analysis.introduce
"
defaultMessage
=
"
Introduce
"
/>
}
>
<
Icon
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
}
loading
=
{
loading
}
total
=
{()
=>
<
Yuan
>
126560
<
/Yuan>
}
footer
=
{
<
Field
label
=
{
<
FormattedMessage
id
=
"
app.analysis.day-sales
"
defaultMessage
=
"
Daily Sales
"
/>
}
value
=
{
`¥
${
numeral
(
12423
).
format
(
'
0,0
'
)}
`
}
/
>
}
contentHeight
=
{
46
}
>
<
Trend
flag
=
"
up
"
style
=
{{
marginRight
:
16
}}
>
<
FormattedMessage
id
=
"
app.analysis.week
"
defaultMessage
=
"
Weekly Changes
"
/>
<
span
className
=
{
styles
.
trendText
}
>
12
%<
/span
>
<
/Trend
>
<
Trend
flag
=
"
down
"
>
<
FormattedMessage
id
=
"
app.analysis.day
"
defaultMessage
=
"
Daily Changes
"
/>
<
span
className
=
{
styles
.
trendText
}
>
11
%<
/span
>
<
/Trend
>
<
/ChartCard
>
<
/Col
>
<
Col
{...
topColResponsiveProps
}
>
<
ChartCard
bordered
=
{
false
}
loading
=
{
loading
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.visits
"
defaultMessage
=
"
Visits
"
/>
}
action
=
{
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.analysis.introduce
"
defaultMessage
=
"
Introduce
"
/>
}
>
<
Icon
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
}
total
=
{
numeral
(
8846
).
format
(
'
0,0
'
)}
footer
=
{
<
Field
label
=
{
<
FormattedMessage
id
=
"
app.analysis.day-visits
"
defaultMessage
=
"
Daily Visits
"
/>
}
value
=
{
numeral
(
1234
).
format
(
'
0,0
'
)}
/
>
}
contentHeight
=
{
46
}
>
<
MiniArea
color
=
"
#975FE4
"
data
=
{
visitData
}
/
>
<
/ChartCard
>
<
/Col
>
<
Col
{...
topColResponsiveProps
}
>
<
ChartCard
bordered
=
{
false
}
loading
=
{
loading
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.payments
"
defaultMessage
=
"
Payments
"
/>
}
action
=
{
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.analysis.introduce
"
defaultMessage
=
"
Introduce
"
/>
}
>
<
Icon
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
}
total
=
{
numeral
(
6560
).
format
(
'
0,0
'
)}
footer
=
{
<
Field
label
=
{
<
FormattedMessage
id
=
"
app.analysis.conversion-rate
"
defaultMessage
=
"
Conversion Rate
"
/>
}
value
=
"
60%
"
/>
}
contentHeight
=
{
46
}
>
<
MiniBar
data
=
{
visitData
}
/
>
<
/ChartCard
>
<
/Col
>
<
Col
{...
topColResponsiveProps
}
>
<
ChartCard
loading
=
{
loading
}
bordered
=
{
false
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.operational-effect
"
defaultMessage
=
"
Operational Effect
"
/>
}
action
=
{
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.analysis.introduce
"
defaultMessage
=
"
Introduce
"
/>
}
>
<
Icon
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
}
total
=
"
78%
"
footer
=
{
<
div
style
=
{{
whiteSpace
:
'
nowrap
'
,
overflow
:
'
hidden
'
}}
>
<
Trend
flag
=
"
up
"
style
=
{{
marginRight
:
16
}}
>
<
FormattedMessage
id
=
"
app.analysis.week
"
defaultMessage
=
"
Weekly Changes
"
/>
<
span
className
=
{
styles
.
trendText
}
>
12
%<
/span
>
<
/Trend
>
<
Trend
flag
=
"
down
"
>
<
FormattedMessage
id
=
"
app.analysis.day
"
defaultMessage
=
"
Weekly Changes
"
/>
<
span
className
=
{
styles
.
trendText
}
>
11
%<
/span
>
<
/Trend
>
<
/div
>
}
contentHeight
=
{
46
}
>
<
MiniProgress
percent
=
{
78
}
strokeWidth
=
{
8
}
target
=
{
80
}
color
=
"
#13C2C2
"
/>
<
/ChartCard
>
<
/Col
>
<
/Row
>
));
export
default
IntroduceRow
;
src/pages/Dashboard/Monitor.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Row
,
Col
,
Card
,
Tooltip
}
from
'
antd
'
;
import
{
Pie
,
WaterWave
,
Gauge
,
TagCloud
}
from
'
ant-design-pro/lib/Charts
'
;
import
NumberInfo
from
'
ant-design-pro/lib/NumberInfo
'
;
import
CountDown
from
'
ant-design-pro/lib/CountDown
'
;
import
ActiveChart
from
'
@/components/ActiveChart
'
;
import
numeral
from
'
numeral
'
;
import
GridContent
from
'
@/components/PageHeaderWrapper/GridContent
'
;
import
Authorized
from
'
@/utils/Authorized
'
;
import
styles
from
'
./Monitor.less
'
;
const
{
Secured
}
=
Authorized
;
const
targetTime
=
new
Date
().
getTime
()
+
3900000
;
// use permission as a parameter
const
havePermissionAsync
=
new
Promise
(
resolve
=>
{
// Call resolve on behalf of passed
setTimeout
(()
=>
resolve
(),
300
);
});
@
Secured
(
havePermissionAsync
)
@
connect
(({
monitor
,
loading
})
=>
({
monitor
,
loading
:
loading
.
models
.
monitor
,
}))
class
Monitor
extends
PureComponent
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
monitor/fetchTags
'
,
});
}
render
()
{
const
{
monitor
,
loading
}
=
this
.
props
;
const
{
tags
}
=
monitor
;
return
(
<
GridContent
>
<
Row
gutter
=
{
24
}
>
<
Col
xl
=
{
18
}
lg
=
{
24
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
style
=
{{
marginBottom
:
24
}}
>
<
Card
title
=
{
<
FormattedMessage
id
=
"
app.monitor.trading-activity
"
defaultMessage
=
"
Real-Time Trading Activity
"
/>
}
bordered
=
{
false
}
>
<
Row
>
<
Col
md
=
{
6
}
sm
=
{
12
}
xs
=
{
24
}
>
<
NumberInfo
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.total-transactions
"
defaultMessage
=
"
Total transactions today
"
/>
}
suffix
=
"
元
"
total
=
{
numeral
(
124543233
).
format
(
'
0,0
'
)}
/
>
<
/Col
>
<
Col
md
=
{
6
}
sm
=
{
12
}
xs
=
{
24
}
>
<
NumberInfo
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.sales-target
"
defaultMessage
=
"
Sales target completion rate
"
/>
}
total
=
"
92%
"
/>
<
/Col
>
<
Col
md
=
{
6
}
sm
=
{
12
}
xs
=
{
24
}
>
<
NumberInfo
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.remaining-time
"
defaultMessage
=
"
Remaining time of activity
"
/>
}
total
=
{
<
CountDown
target
=
{
targetTime
}
/>
}
/>
<
/Col
>
<
Col
md
=
{
6
}
sm
=
{
12
}
xs
=
{
24
}
>
<
NumberInfo
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.total-transactions-per-second
"
defaultMessage
=
"
Total transactions per second
"
/>
}
suffix
=
"
元
"
total
=
{
numeral
(
234
).
format
(
'
0,0
'
)}
/
>
<
/Col
>
<
/Row
>
<
div
className
=
{
styles
.
mapChart
}
>
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.monitor.waiting-for-implementation
"
defaultMessage
=
"
Waiting for implementation
"
/>
}
>
<
img
src
=
"
https://gw.alipayobjects.com/zos/rmsportal/HBWnDEUXCnGnGrRfrpKa.png
"
alt
=
"
map
"
/>
<
/Tooltip
>
<
/div
>
<
/Card
>
<
/Col
>
<
Col
xl
=
{
6
}
lg
=
{
24
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
Card
title
=
{
<
FormattedMessage
id
=
"
app.monitor.activity-forecast
"
defaultMessage
=
"
Activity forecast
"
/>
}
style
=
{{
marginBottom
:
24
}}
bordered
=
{
false
}
>
<
ActiveChart
/>
<
/Card
>
<
Card
title
=
{
<
FormattedMessage
id
=
"
app.monitor.efficiency
"
defaultMessage
=
"
Efficiency
"
/>
}
style
=
{{
marginBottom
:
24
}}
bodyStyle
=
{{
textAlign
:
'
center
'
}}
bordered
=
{
false
}
>
<
Gauge
title
=
{
formatMessage
({
id
:
'
app.monitor.ratio
'
,
defaultMessage
:
'
Ratio
'
})}
height
=
{
180
}
percent
=
{
87
}
/
>
<
/Card
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
24
}
>
<
Col
xl
=
{
12
}
lg
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
style
=
{{
marginBottom
:
24
}}
>
<
Card
title
=
{
<
FormattedMessage
id
=
"
app.monitor.proportion-per-category
"
defaultMessage
=
"
Proportion Per Category
"
/>
}
bordered
=
{
false
}
className
=
{
styles
.
pieCard
}
>
<
Row
style
=
{{
padding
:
'
16px 0
'
}}
>
<
Col
span
=
{
8
}
>
<
Pie
animate
=
{
false
}
percent
=
{
28
}
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.fast-food
"
defaultMessage
=
"
Fast food
"
/>
}
total
=
"
28%
"
height
=
{
128
}
lineWidth
=
{
2
}
/
>
<
/Col
>
<
Col
span
=
{
8
}
>
<
Pie
animate
=
{
false
}
color
=
"
#5DDECF
"
percent
=
{
22
}
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.western-food
"
defaultMessage
=
"
Western food
"
/>
}
total
=
"
22%
"
height
=
{
128
}
lineWidth
=
{
2
}
/
>
<
/Col
>
<
Col
span
=
{
8
}
>
<
Pie
animate
=
{
false
}
color
=
"
#2FC25B
"
percent
=
{
32
}
subTitle
=
{
<
FormattedMessage
id
=
"
app.monitor.hot-pot
"
defaultMessage
=
"
Hot pot
"
/>
}
total
=
"
32%
"
height
=
{
128
}
lineWidth
=
{
2
}
/
>
<
/Col
>
<
/Row
>
<
/Card
>
<
/Col
>
<
Col
xl
=
{
6
}
lg
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
style
=
{{
marginBottom
:
24
}}
>
<
Card
title
=
{
<
FormattedMessage
id
=
"
app.monitor.popular-searches
"
defaultMessage
=
"
Popular Searches
"
/>
}
loading
=
{
loading
}
bordered
=
{
false
}
bodyStyle
=
{{
overflow
:
'
hidden
'
}}
>
<
TagCloud
data
=
{
tags
}
height
=
{
161
}
/
>
<
/Card
>
<
/Col
>
<
Col
xl
=
{
6
}
lg
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
style
=
{{
marginBottom
:
24
}}
>
<
Card
title
=
{
<
FormattedMessage
id
=
"
app.monitor.resource-surplus
"
defaultMessage
=
"
Resource Surplus
"
/>
}
bodyStyle
=
{{
textAlign
:
'
center
'
,
fontSize
:
0
}}
bordered
=
{
false
}
>
<
WaterWave
height
=
{
161
}
title
=
{
<
FormattedMessage
id
=
"
app.monitor.fund-surplus
"
defaultMessage
=
"
Fund Surplus
"
/>
}
percent
=
{
34
}
/
>
<
/Card
>
<
/Col
>
<
/Row
>
<
/GridContent
>
);
}
}
export
default
Monitor
;
src/pages/Dashboard/Monitor.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.mapChart {
padding-top: 24px;
height: 452px;
text-align: center;
img {
display: inline-block;
max-width: 100%;
max-height: 437px;
}
}
.pieCard :global(.pie-stat) {
font-size: 24px !important;
}
@media screen and (max-width: @screen-lg) {
.mapChart {
height: auto;
}
}
src/pages/Dashboard/OfflineData.js
deleted
100755 → 0
View file @
5ba67a51
import
React
,
{
memo
}
from
'
react
'
;
import
{
Card
,
Tabs
,
Row
,
Col
}
from
'
antd
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
TimelineChart
,
Pie
}
from
'
ant-design-pro/lib/Charts
'
;
import
NumberInfo
from
'
ant-design-pro/lib/NumberInfo
'
;
import
styles
from
'
./Analysis.less
'
;
const
CustomTab
=
({
data
,
currentTabKey
:
currentKey
})
=>
(
<
Row
gutter
=
{
8
}
style
=
{{
width
:
138
,
margin
:
'
8px 0
'
}}
>
<
Col
span
=
{
12
}
>
<
NumberInfo
title
=
{
data
.
name
}
subTitle
=
{
<
FormattedMessage
id
=
"
app.analysis.conversion-rate
"
defaultMessage
=
"
Conversion Rate
"
/>
}
gap
=
{
2
}
total
=
{
`
${
data
.
cvr
*
100
}
%`
}
theme
=
{
currentKey
!==
data
.
name
&&
'
light
'
}
/
>
<
/Col
>
<
Col
span
=
{
12
}
style
=
{{
paddingTop
:
36
}}
>
<
Pie
animate
=
{
false
}
color
=
{
currentKey
!==
data
.
name
&&
'
#BDE4FF
'
}
inner
=
{
0.55
}
tooltip
=
{
false
}
margin
=
{[
0
,
0
,
0
,
0
]}
percent
=
{
data
.
cvr
*
100
}
height
=
{
64
}
/
>
<
/Col
>
<
/Row
>
);
const
{
TabPane
}
=
Tabs
;
const
OfflineData
=
memo
(
({
activeKey
,
loading
,
offlineData
,
offlineChartData
,
handleTabChange
})
=>
(
<
Card
loading
=
{
loading
}
className
=
{
styles
.
offlineCard
}
bordered
=
{
false
}
style
=
{{
marginTop
:
32
}}
>
<
Tabs
activeKey
=
{
activeKey
}
onChange
=
{
handleTabChange
}
>
{
offlineData
.
map
(
shop
=>
(
<
TabPane
tab
=
{
<
CustomTab
data
=
{
shop
}
currentTabKey
=
{
activeKey
}
/>} key={shop.name}
>
<
div
style
=
{{
padding
:
'
0 24px
'
}}
>
<
TimelineChart
height
=
{
400
}
data
=
{
offlineChartData
}
titleMap
=
{{
y1
:
formatMessage
({
id
:
'
app.analysis.traffic
'
}),
y2
:
formatMessage
({
id
:
'
app.analysis.payments
'
}),
}}
/
>
<
/div
>
<
/TabPane
>
))}
<
/Tabs
>
<
/Card
>
)
);
export
default
OfflineData
;
src/pages/Dashboard/ProportionSales.js
deleted
100755 → 0
View file @
5ba67a51
import
React
,
{
memo
}
from
'
react
'
;
import
{
Card
,
Radio
}
from
'
antd
'
;
import
{
FormattedMessage
}
from
'
umi/locale
'
;
import
styles
from
'
./Analysis.less
'
;
import
{
Pie
}
from
'
ant-design-pro/lib/Charts
'
;
import
Yuan
from
'
@/utils/Yuan
'
;
const
ProportionSales
=
memo
(
({
dropdownGroup
,
salesType
,
loading
,
salesPieData
,
handleChangeSalesType
})
=>
(
<
Card
loading
=
{
loading
}
className
=
{
styles
.
salesCard
}
bordered
=
{
false
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.the-proportion-of-sales
"
defaultMessage
=
"
The Proportion of Sales
"
/>
}
bodyStyle
=
{{
padding
:
24
}}
extra
=
{
<
div
className
=
{
styles
.
salesCardExtra
}
>
{
dropdownGroup
}
<
div
className
=
{
styles
.
salesTypeRadio
}
>
<
Radio
.
Group
value
=
{
salesType
}
onChange
=
{
handleChangeSalesType
}
>
<
Radio
.
Button
value
=
"
all
"
>
<
FormattedMessage
id
=
"
app.analysis.channel.all
"
defaultMessage
=
"
ALL
"
/>
<
/Radio.Button
>
<
Radio
.
Button
value
=
"
online
"
>
<
FormattedMessage
id
=
"
app.analysis.channel.online
"
defaultMessage
=
"
Online
"
/>
<
/Radio.Button
>
<
Radio
.
Button
value
=
"
stores
"
>
<
FormattedMessage
id
=
"
app.analysis.channel.stores
"
defaultMessage
=
"
Stores
"
/>
<
/Radio.Button
>
<
/Radio.Group
>
<
/div
>
<
/div
>
}
style
=
{{
marginTop
:
24
}}
>
<
h4
style
=
{{
marginTop
:
10
,
marginBottom
:
32
}}
>
<
FormattedMessage
id
=
"
app.analysis.sales
"
defaultMessage
=
"
Sales
"
/>
<
/h4
>
<
Pie
hasLegend
subTitle
=
{
<
FormattedMessage
id
=
"
app.analysis.sales
"
defaultMessage
=
"
Sales
"
/>
}
total
=
{()
=>
<
Yuan
>
{
salesPieData
.
reduce
((
pre
,
now
)
=>
now
.
y
+
pre
,
0
)}
<
/Yuan>
}
data
=
{
salesPieData
}
valueFormat
=
{
value
=>
<
Yuan
>
{
value
}
<
/Yuan>
}
height
=
{
270
}
lineWidth
=
{
4
}
style
=
{{
padding
:
'
8px 0
'
}}
/
>
<
/Card
>
)
);
export
default
ProportionSales
;
src/pages/Dashboard/SalesCard.js
deleted
100755 → 0
View file @
5ba67a51
import
React
,
{
memo
}
from
'
react
'
;
import
{
Row
,
Col
,
Card
,
Tabs
,
DatePicker
}
from
'
antd
'
;
import
{
FormattedMessage
,
formatMessage
}
from
'
umi/locale
'
;
import
numeral
from
'
numeral
'
;
import
{
Bar
}
from
'
ant-design-pro/lib/Charts
'
;
import
styles
from
'
./Analysis.less
'
;
const
{
RangePicker
}
=
DatePicker
;
const
{
TabPane
}
=
Tabs
;
const
rankingListData
=
[];
for
(
let
i
=
0
;
i
<
7
;
i
+=
1
)
{
rankingListData
.
push
({
title
:
formatMessage
({
id
:
'
app.analysis.test
'
},
{
no
:
i
}),
total
:
323234
,
});
}
const
SalesCard
=
memo
(
({
rangePickerValue
,
salesData
,
isActive
,
handleRangePickerChange
,
loading
,
selectDate
})
=>
(
<
Card
loading
=
{
loading
}
bordered
=
{
false
}
bodyStyle
=
{{
padding
:
0
}}
>
<
div
className
=
{
styles
.
salesCard
}
>
<
Tabs
tabBarExtraContent
=
{
<
div
className
=
{
styles
.
salesExtraWrap
}
>
<
div
className
=
{
styles
.
salesExtra
}
>
<
a
className
=
{
isActive
(
'
today
'
)}
onClick
=
{()
=>
selectDate
(
'
today
'
)}
>
<
FormattedMessage
id
=
"
app.analysis.all-day
"
defaultMessage
=
"
All Day
"
/>
<
/a
>
<
a
className
=
{
isActive
(
'
week
'
)}
onClick
=
{()
=>
selectDate
(
'
week
'
)}
>
<
FormattedMessage
id
=
"
app.analysis.all-week
"
defaultMessage
=
"
All Week
"
/>
<
/a
>
<
a
className
=
{
isActive
(
'
month
'
)}
onClick
=
{()
=>
selectDate
(
'
month
'
)}
>
<
FormattedMessage
id
=
"
app.analysis.all-month
"
defaultMessage
=
"
All Month
"
/>
<
/a
>
<
a
className
=
{
isActive
(
'
year
'
)}
onClick
=
{()
=>
selectDate
(
'
year
'
)}
>
<
FormattedMessage
id
=
"
app.analysis.all-year
"
defaultMessage
=
"
All Year
"
/>
<
/a
>
<
/div
>
<
RangePicker
value
=
{
rangePickerValue
}
onChange
=
{
handleRangePickerChange
}
style
=
{{
width
:
256
}}
/
>
<
/div
>
}
size
=
"
large
"
tabBarStyle
=
{{
marginBottom
:
24
}}
>
<
TabPane
tab
=
{
<
FormattedMessage
id
=
"
app.analysis.sales
"
defaultMessage
=
"
Sales
"
/>
}
key
=
"
sales
"
>
<
Row
>
<
Col
xl
=
{
16
}
lg
=
{
12
}
md
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
>
<
div
className
=
{
styles
.
salesBar
}
>
<
Bar
height
=
{
295
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.sales-trend
"
defaultMessage
=
"
Sales Trend
"
/>
}
data
=
{
salesData
}
/
>
<
/div
>
<
/Col
>
<
Col
xl
=
{
8
}
lg
=
{
12
}
md
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
>
<
div
className
=
{
styles
.
salesRank
}
>
<
h4
className
=
{
styles
.
rankingTitle
}
>
<
FormattedMessage
id
=
"
app.analysis.sales-ranking
"
defaultMessage
=
"
Sales Ranking
"
/>
<
/h4
>
<
ul
className
=
{
styles
.
rankingList
}
>
{
rankingListData
.
map
((
item
,
i
)
=>
(
<
li
key
=
{
item
.
title
}
>
<
span
className
=
{
`
${
styles
.
rankingItemNumber
}
${
i
<
3
?
styles
.
active
:
''
}
`
}
>
{
i
+
1
}
<
/span
>
<
span
className
=
{
styles
.
rankingItemTitle
}
title
=
{
item
.
title
}
>
{
item
.
title
}
<
/span
>
<
span
className
=
{
styles
.
rankingItemValue
}
>
{
numeral
(
item
.
total
).
format
(
'
0,0
'
)}
<
/span
>
<
/li
>
))}
<
/ul
>
<
/div
>
<
/Col
>
<
/Row
>
<
/TabPane
>
<
TabPane
tab
=
{
<
FormattedMessage
id
=
"
app.analysis.visits
"
defaultMessage
=
"
Visits
"
/>
}
key
=
"
views
"
>
<
Row
>
<
Col
xl
=
{
16
}
lg
=
{
12
}
md
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
>
<
div
className
=
{
styles
.
salesBar
}
>
<
Bar
height
=
{
292
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.visits-trend
"
defaultMessage
=
"
Visits Trend
"
/>
}
data
=
{
salesData
}
/
>
<
/div
>
<
/Col
>
<
Col
xl
=
{
8
}
lg
=
{
12
}
md
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
>
<
div
className
=
{
styles
.
salesRank
}
>
<
h4
className
=
{
styles
.
rankingTitle
}
>
<
FormattedMessage
id
=
"
app.analysis.visits-ranking
"
defaultMessage
=
"
Visits Ranking
"
/>
<
/h4
>
<
ul
className
=
{
styles
.
rankingList
}
>
{
rankingListData
.
map
((
item
,
i
)
=>
(
<
li
key
=
{
item
.
title
}
>
<
span
className
=
{
`
${
styles
.
rankingItemNumber
}
${
i
<
3
?
styles
.
active
:
''
}
`
}
>
{
i
+
1
}
<
/span
>
<
span
className
=
{
styles
.
rankingItemTitle
}
title
=
{
item
.
title
}
>
{
item
.
title
}
<
/span
>
<
span
>
{
numeral
(
item
.
total
).
format
(
'
0,0
'
)}
<
/span
>
<
/li
>
))}
<
/ul
>
<
/div
>
<
/Col
>
<
/Row
>
<
/TabPane
>
<
/Tabs
>
<
/div
>
<
/Card
>
)
);
export
default
SalesCard
;
src/pages/Dashboard/TopSearch.js
deleted
100755 → 0
View file @
5ba67a51
import
React
,
{
memo
}
from
'
react
'
;
import
{
Row
,
Col
,
Table
,
Tooltip
,
Card
,
Icon
}
from
'
antd
'
;
import
{
FormattedMessage
}
from
'
umi/locale
'
;
import
Trend
from
'
ant-design-pro/lib/Trend
'
;
import
numeral
from
'
numeral
'
;
import
NumberInfo
from
'
ant-design-pro/lib/NumberInfo
'
;
import
{
MiniArea
}
from
'
ant-design-pro/lib/Charts
'
;
import
styles
from
'
./Analysis.less
'
;
const
columns
=
[
{
title
:
<
FormattedMessage
id
=
"
app.analysis.table.rank
"
defaultMessage
=
"
Rank
"
/>
,
dataIndex
:
'
index
'
,
key
:
'
index
'
,
},
{
title
:
(
<
FormattedMessage
id
=
"
app.analysis.table.search-keyword
"
defaultMessage
=
"
Search keyword
"
/>
),
dataIndex
:
'
keyword
'
,
key
:
'
keyword
'
,
render
:
text
=>
<
a
href
=
"
/
"
>
{
text
}
<
/a>
,
},
{
title
:
<
FormattedMessage
id
=
"
app.analysis.table.users
"
defaultMessage
=
"
Users
"
/>
,
dataIndex
:
'
count
'
,
key
:
'
count
'
,
sorter
:
(
a
,
b
)
=>
a
.
count
-
b
.
count
,
className
:
styles
.
alignRight
,
},
{
title
:
<
FormattedMessage
id
=
"
app.analysis.table.weekly-range
"
defaultMessage
=
"
Weekly Range
"
/>
,
dataIndex
:
'
range
'
,
key
:
'
range
'
,
sorter
:
(
a
,
b
)
=>
a
.
range
-
b
.
range
,
render
:
(
text
,
record
)
=>
(
<
Trend
flag
=
{
record
.
status
===
1
?
'
down
'
:
'
up
'
}
>
<
span
style
=
{{
marginRight
:
4
}}
>
{
text
}
%<
/span
>
<
/Trend
>
),
align
:
'
right
'
,
},
];
const
TopSearch
=
memo
(({
loading
,
visitData2
,
searchData
,
dropdownGroup
})
=>
(
<
Card
loading
=
{
loading
}
bordered
=
{
false
}
title
=
{
<
FormattedMessage
id
=
"
app.analysis.online-top-search
"
defaultMessage
=
"
Online Top Search
"
/>
}
extra
=
{
dropdownGroup
}
style
=
{{
marginTop
:
24
}}
>
<
Row
gutter
=
{
68
}
>
<
Col
sm
=
{
12
}
xs
=
{
24
}
style
=
{{
marginBottom
:
24
}}
>
<
NumberInfo
subTitle
=
{
<
span
>
<
FormattedMessage
id
=
"
app.analysis.search-users
"
defaultMessage
=
"
search users
"
/>
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.analysis.introduce
"
defaultMessage
=
"
introduce
"
/>
}
>
<
Icon
style
=
{{
marginLeft
:
8
}}
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
<
/span
>
}
gap
=
{
8
}
total
=
{
numeral
(
12321
).
format
(
'
0,0
'
)}
status
=
"
up
"
subTotal
=
{
17.1
}
/
>
<
MiniArea
line
height
=
{
45
}
data
=
{
visitData2
}
/
>
<
/Col
>
<
Col
sm
=
{
12
}
xs
=
{
24
}
style
=
{{
marginBottom
:
24
}}
>
<
NumberInfo
subTitle
=
{
<
span
>
<
FormattedMessage
id
=
"
app.analysis.per-capita-search
"
defaultMessage
=
"
Per Capita Search
"
/>
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
app.analysis.introduce
"
defaultMessage
=
"
introduce
"
/>
}
>
<
Icon
style
=
{{
marginLeft
:
8
}}
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
<
/span
>
}
total
=
{
2.7
}
status
=
"
down
"
subTotal
=
{
26.2
}
gap
=
{
8
}
/
>
<
MiniArea
line
height
=
{
45
}
data
=
{
visitData2
}
/
>
<
/Col
>
<
/Row
>
<
Table
rowKey
=
{
record
=>
record
.
index
}
size
=
"
small
"
columns
=
{
columns
}
dataSource
=
{
searchData
}
pagination
=
{{
style
:
{
marginBottom
:
0
},
pageSize
:
5
,
}}
/
>
<
/Card
>
));
export
default
TopSearch
;
src/pages/Dashboard/Workplace.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
moment
from
'
moment
'
;
import
{
connect
}
from
'
dva
'
;
import
Link
from
'
umi/link
'
;
import
{
Row
,
Col
,
Card
,
List
,
Avatar
}
from
'
antd
'
;
import
{
Radar
}
from
'
ant-design-pro/lib/Charts
'
;
import
EditableLinkGroup
from
'
@/components/EditableLinkGroup
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
./Workplace.less
'
;
const
links
=
[
{
title
:
'
操作一
'
,
href
:
''
,
},
{
title
:
'
操作二
'
,
href
:
''
,
},
{
title
:
'
操作三
'
,
href
:
''
,
},
{
title
:
'
操作四
'
,
href
:
''
,
},
{
title
:
'
操作五
'
,
href
:
''
,
},
{
title
:
'
操作六
'
,
href
:
''
,
},
];
@
connect
(({
user
,
project
,
activities
,
chart
,
loading
})
=>
({
currentUser
:
user
.
currentUser
,
project
,
activities
,
chart
,
currentUserLoading
:
loading
.
effects
[
'
user/fetchCurrent
'
],
projectLoading
:
loading
.
effects
[
'
project/fetchNotice
'
],
activitiesLoading
:
loading
.
effects
[
'
activities/fetchList
'
],
}))
class
Workplace
extends
PureComponent
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
user/fetchCurrent
'
,
});
dispatch
({
type
:
'
project/fetchNotice
'
,
});
dispatch
({
type
:
'
activities/fetchList
'
,
});
dispatch
({
type
:
'
chart/fetch
'
,
});
}
componentWillUnmount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
chart/clear
'
,
});
}
renderActivities
()
{
const
{
activities
:
{
list
},
}
=
this
.
props
;
return
list
.
map
(
item
=>
{
const
events
=
item
.
template
.
split
(
/@
\{([^
{}
]
*
)\}
/gi
).
map
(
key
=>
{
if
(
item
[
key
])
{
return
(
<
a
href
=
{
item
[
key
].
link
}
key
=
{
item
[
key
].
name
}
>
{
item
[
key
].
name
}
<
/a
>
);
}
return
key
;
});
return
(
<
List
.
Item
key
=
{
item
.
id
}
>
<
List
.
Item
.
Meta
avatar
=
{
<
Avatar
src
=
{
item
.
user
.
avatar
}
/>
}
title
=
{
<
span
>
<
a
className
=
{
styles
.
username
}
>
{
item
.
user
.
name
}
<
/a
>
&
nbsp
;
<
span
className
=
{
styles
.
event
}
>
{
events
}
<
/span
>
<
/span
>
}
description
=
{
<
span
className
=
{
styles
.
datetime
}
title
=
{
item
.
updatedAt
}
>
{
moment
(
item
.
updatedAt
).
fromNow
()}
<
/span
>
}
/
>
<
/List.Item
>
);
});
}
render
()
{
const
{
currentUser
,
currentUserLoading
,
project
:
{
notice
},
projectLoading
,
activitiesLoading
,
chart
:
{
radarData
},
}
=
this
.
props
;
const
pageHeaderContent
=
currentUser
&&
Object
.
keys
(
currentUser
).
length
?
(
<
div
className
=
{
styles
.
pageHeaderContent
}
>
<
div
className
=
{
styles
.
avatar
}
>
<
Avatar
size
=
"
large
"
src
=
{
currentUser
.
avatar
}
/
>
<
/div
>
<
div
className
=
{
styles
.
content
}
>
<
div
className
=
{
styles
.
contentTitle
}
>
早安
,
{
currentUser
.
name
}
,
祝你开心每一天
!
<
/div
>
<
div
>
{
currentUser
.
title
}
|
{
currentUser
.
group
}
<
/div
>
<
/div
>
<
/div
>
)
:
null
;
const
extraContent
=
(
<
div
className
=
{
styles
.
extraContent
}
>
<
div
className
=
{
styles
.
statItem
}
>
<
p
>
项目数
<
/p
>
<
p
>
56
<
/p
>
<
/div
>
<
div
className
=
{
styles
.
statItem
}
>
<
p
>
团队内排名
<
/p
>
<
p
>
8
<
span
>
/ 24</
span
>
<
/p
>
<
/div
>
<
div
className
=
{
styles
.
statItem
}
>
<
p
>
项目访问
<
/p
>
<
p
>
2
,
223
<
/p
>
<
/div
>
<
/div
>
);
return
(
<
PageHeaderWrapper
loading
=
{
currentUserLoading
}
content
=
{
pageHeaderContent
}
extraContent
=
{
extraContent
}
>
<
Row
gutter
=
{
24
}
>
<
Col
xl
=
{
16
}
lg
=
{
24
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
Card
className
=
{
styles
.
projectList
}
style
=
{{
marginBottom
:
24
}}
title
=
"
进行中的项目
"
bordered
=
{
false
}
extra
=
{
<
Link
to
=
"
/
"
>
全部项目
<
/Link>
}
loading
=
{
projectLoading
}
bodyStyle
=
{{
padding
:
0
}}
>
{
notice
.
map
(
item
=>
(
<
Card
.
Grid
className
=
{
styles
.
projectGrid
}
key
=
{
item
.
id
}
>
<
Card
bodyStyle
=
{{
padding
:
0
}}
bordered
=
{
false
}
>
<
Card
.
Meta
title
=
{
<
div
className
=
{
styles
.
cardTitle
}
>
<
Avatar
size
=
"
small
"
src
=
{
item
.
logo
}
/
>
<
Link
to
=
{
item
.
href
}
>
{
item
.
title
}
<
/Link
>
<
/div
>
}
description
=
{
item
.
description
}
/
>
<
div
className
=
{
styles
.
projectItemContent
}
>
<
Link
to
=
{
item
.
memberLink
}
>
{
item
.
member
||
''
}
<
/Link
>
{
item
.
updatedAt
&&
(
<
span
className
=
{
styles
.
datetime
}
title
=
{
item
.
updatedAt
}
>
{
moment
(
item
.
updatedAt
).
fromNow
()}
<
/span
>
)}
<
/div
>
<
/Card
>
<
/Card.Grid
>
))}
<
/Card
>
<
Card
bodyStyle
=
{{
padding
:
0
}}
bordered
=
{
false
}
className
=
{
styles
.
activeCard
}
title
=
"
动态
"
loading
=
{
activitiesLoading
}
>
<
List
loading
=
{
activitiesLoading
}
size
=
"
large
"
>
<
div
className
=
{
styles
.
activitiesList
}
>
{
this
.
renderActivities
()}
<
/div
>
<
/List
>
<
/Card
>
<
/Col
>
<
Col
xl
=
{
8
}
lg
=
{
24
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
Card
style
=
{{
marginBottom
:
24
}}
title
=
"
快速开始 / 便捷导航
"
bordered
=
{
false
}
bodyStyle
=
{{
padding
:
0
}}
>
<
EditableLinkGroup
onAdd
=
{()
=>
{}}
links
=
{
links
}
linkElement
=
{
Link
}
/
>
<
/Card
>
<
Card
style
=
{{
marginBottom
:
24
}}
bordered
=
{
false
}
title
=
"
XX 指数
"
loading
=
{
radarData
.
length
===
0
}
>
<
div
className
=
{
styles
.
chart
}
>
<
Radar
hasLegend
height
=
{
343
}
data
=
{
radarData
}
/
>
<
/div
>
<
/Card
>
<
Card
bodyStyle
=
{{
paddingTop
:
12
,
paddingBottom
:
12
}}
bordered
=
{
false
}
title
=
"
团队
"
loading
=
{
projectLoading
}
>
<
div
className
=
{
styles
.
members
}
>
<
Row
gutter
=
{
48
}
>
{
notice
.
map
(
item
=>
(
<
Col
span
=
{
12
}
key
=
{
`members-item-
${
item
.
id
}
`
}
>
<
Link
to
=
{
item
.
href
}
>
<
Avatar
src
=
{
item
.
logo
}
size
=
"
small
"
/>
<
span
className
=
{
styles
.
member
}
>
{
item
.
member
}
<
/span
>
<
/Link
>
<
/Col
>
))}
<
/Row
>
<
/div
>
<
/Card
>
<
/Col
>
<
/Row
>
<
/PageHeaderWrapper
>
);
}
}
export
default
Workplace
;
src/pages/Dashboard/Workplace.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.activitiesList {
padding: 0 24px 8px 24px;
.username {
color: @text-color;
}
.event {
font-weight: normal;
}
}
.pageHeaderContent {
display: flex;
.avatar {
flex: 0 1 72px;
margin-bottom: 8px;
& > span {
border-radius: 72px;
display: block;
width: 72px;
height: 72px;
}
}
.content {
position: relative;
top: 4px;
margin-left: 24px;
flex: 1 1 auto;
color: @text-color-secondary;
line-height: 22px;
.contentTitle {
font-size: 20px;
line-height: 28px;
font-weight: 500;
color: @heading-color;
margin-bottom: 12px;
}
}
}
.extraContent {
.clearfix();
float: right;
white-space: nowrap;
.statItem {
padding: 0 32px;
position: relative;
display: inline-block;
> p:first-child {
color: @text-color-secondary;
font-size: @font-size-base;
line-height: 22px;
margin-bottom: 4px;
}
> p {
color: @heading-color;
font-size: 30px;
line-height: 38px;
margin: 0;
> span {
color: @text-color-secondary;
font-size: 20px;
}
}
&:after {
background-color: @border-color-split;
position: absolute;
top: 8px;
right: 0;
width: 1px;
height: 40px;
content: '';
}
&:last-child {
padding-right: 0;
&:after {
display: none;
}
}
}
}
.members {
a {
display: block;
margin: 12px 0;
height: 24px;
color: @text-color;
transition: all 0.3s;
.textOverflow();
.member {
font-size: @font-size-base;
line-height: 24px;
vertical-align: top;
margin-left: 12px;
}
&:hover {
color: @primary-color;
}
}
}
.projectList {
:global {
.ant-card-meta-description {
color: @text-color-secondary;
height: 44px;
line-height: 22px;
overflow: hidden;
}
}
.cardTitle {
font-size: 0;
a {
color: @heading-color;
margin-left: 12px;
line-height: 24px;
height: 24px;
display: inline-block;
vertical-align: top;
font-size: @font-size-base;
&:hover {
color: @primary-color;
}
}
}
.projectGrid {
width: 33.33%;
}
.projectItemContent {
display: flex;
margin-top: 8px;
overflow: hidden;
font-size: 12px;
height: 20px;
line-height: 20px;
.textOverflow();
a {
color: @text-color-secondary;
display: inline-block;
flex: 1 1 0;
.textOverflow();
&:hover {
color: @primary-color;
}
}
.datetime {
color: @disabled-color;
flex: 0 0 auto;
float: right;
}
}
}
.datetime {
color: @disabled-color;
}
@media screen and (max-width: @screen-xl) and (min-width: @screen-lg) {
.activeCard {
margin-bottom: 24px;
}
.members {
margin-bottom: 0;
}
.extraContent {
margin-left: -44px;
.statItem {
padding: 0 16px;
}
}
}
@media screen and (max-width: @screen-lg) {
.activeCard {
margin-bottom: 24px;
}
.members {
margin-bottom: 0;
}
.extraContent {
float: none;
margin-right: 0;
.statItem {
padding: 0 16px;
text-align: left;
&:after {
display: none;
}
}
}
}
@media screen and (max-width: @screen-md) {
.extraContent {
margin-left: -16px;
}
.projectList {
.projectGrid {
width: 50%;
}
}
}
@media screen and (max-width: @screen-sm) {
.pageHeaderContent {
display: block;
.content {
margin-left: 0;
}
}
.extraContent {
.statItem {
float: none;
}
}
}
@media screen and (max-width: @screen-xs) {
.projectList {
.projectGrid {
width: 100%;
}
}
}
src/pages/Dashboard/models/activities.js
deleted
100644 → 0
View file @
5ba67a51
import
{
queryActivities
}
from
'
@/services/api
'
;
export
default
{
namespace
:
'
activities
'
,
state
:
{
list
:
[],
},
effects
:
{
*
fetchList
(
_
,
{
call
,
put
})
{
const
response
=
yield
call
(
queryActivities
);
yield
put
({
type
:
'
saveList
'
,
payload
:
Array
.
isArray
(
response
)
?
response
:
[],
});
},
},
reducers
:
{
saveList
(
state
,
action
)
{
return
{
...
state
,
list
:
action
.
payload
,
};
},
},
};
src/pages/Dashboard/models/chart.js
deleted
100644 → 0
View file @
5ba67a51
import
{
fakeChartData
}
from
'
@/services/api
'
;
export
default
{
namespace
:
'
chart
'
,
state
:
{
visitData
:
[],
visitData2
:
[],
salesData
:
[],
searchData
:
[],
offlineData
:
[],
offlineChartData
:
[],
salesTypeData
:
[],
salesTypeDataOnline
:
[],
salesTypeDataOffline
:
[],
radarData
:
[],
loading
:
false
,
},
effects
:
{
*
fetch
(
_
,
{
call
,
put
})
{
const
response
=
yield
call
(
fakeChartData
);
yield
put
({
type
:
'
save
'
,
payload
:
response
,
});
},
*
fetchSalesData
(
_
,
{
call
,
put
})
{
const
response
=
yield
call
(
fakeChartData
);
yield
put
({
type
:
'
save
'
,
payload
:
{
salesData
:
response
.
salesData
,
},
});
},
},
reducers
:
{
save
(
state
,
{
payload
})
{
return
{
...
state
,
...
payload
,
};
},
clear
()
{
return
{
visitData
:
[],
visitData2
:
[],
salesData
:
[],
searchData
:
[],
offlineData
:
[],
offlineChartData
:
[],
salesTypeData
:
[],
salesTypeDataOnline
:
[],
salesTypeDataOffline
:
[],
radarData
:
[],
};
},
},
};
src/pages/Dashboard/models/monitor.js
deleted
100644 → 0
View file @
5ba67a51
import
{
queryTags
}
from
'
@/services/api
'
;
export
default
{
namespace
:
'
monitor
'
,
state
:
{
tags
:
[],
},
effects
:
{
*
fetchTags
(
_
,
{
call
,
put
})
{
const
response
=
yield
call
(
queryTags
);
yield
put
({
type
:
'
saveTags
'
,
payload
:
response
.
list
,
});
},
},
reducers
:
{
saveTags
(
state
,
action
)
{
return
{
...
state
,
tags
:
action
.
payload
,
};
},
},
};
src/pages/Exception/403.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
{
formatMessage
}
from
'
umi/locale
'
;
import
Link
from
'
umi/link
'
;
import
Exception
from
'
ant-design-pro/lib/Exception
'
;
const
Exception403
=
()
=>
(
<
Exception
type
=
"
403
"
desc
=
{
formatMessage
({
id
:
'
app.exception.description.403
'
})}
linkElement
=
{
Link
}
backText
=
{
formatMessage
({
id
:
'
app.exception.back
'
})}
/
>
);
export
default
Exception403
;
src/pages/Exception/404.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
{
formatMessage
}
from
'
umi/locale
'
;
import
Link
from
'
umi/link
'
;
import
Exception
from
'
ant-design-pro/lib/Exception
'
;
const
Exception404
=
()
=>
(
<
Exception
type
=
"
404
"
desc
=
{
formatMessage
({
id
:
'
app.exception.description.404
'
})}
linkElement
=
{
Link
}
backText
=
{
formatMessage
({
id
:
'
app.exception.back
'
})}
/
>
);
export
default
Exception404
;
src/pages/Exception/500.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
{
formatMessage
}
from
'
umi/locale
'
;
import
Link
from
'
umi/link
'
;
import
Exception
from
'
ant-design-pro/lib/Exception
'
;
const
Exception500
=
()
=>
(
<
Exception
type
=
"
500
"
desc
=
{
formatMessage
({
id
:
'
app.exception.description.500
'
})}
linkElement
=
{
Link
}
backText
=
{
formatMessage
({
id
:
'
app.exception.back
'
})}
/
>
);
export
default
Exception500
;
src/pages/Exception/TriggerException.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
Button
,
Spin
,
Card
}
from
'
antd
'
;
import
{
connect
}
from
'
dva
'
;
import
styles
from
'
./style.less
'
;
@
connect
(
state
=>
({
isloading
:
state
.
error
.
isloading
,
}))
class
TriggerException
extends
PureComponent
{
state
=
{
isloading
:
false
,
};
triggerError
=
code
=>
{
this
.
setState
({
isloading
:
true
,
});
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
error/query
'
,
payload
:
{
code
,
},
});
};
render
()
{
const
{
isloading
}
=
this
.
state
;
return
(
<
Card
>
<
Spin
spinning
=
{
isloading
}
wrapperClassName
=
{
styles
.
trigger
}
>
<
Button
type
=
"
danger
"
onClick
=
{()
=>
this
.
triggerError
(
401
)}
>
触发401
<
/Button
>
<
Button
type
=
"
danger
"
onClick
=
{()
=>
this
.
triggerError
(
403
)}
>
触发403
<
/Button
>
<
Button
type
=
"
danger
"
onClick
=
{()
=>
this
.
triggerError
(
500
)}
>
触发500
<
/Button
>
<
Button
type
=
"
danger
"
onClick
=
{()
=>
this
.
triggerError
(
404
)}
>
触发404
<
/Button
>
<
/Spin
>
<
/Card
>
);
}
}
export
default
TriggerException
;
src/pages/Exception/models/error.js
deleted
100644 → 0
View file @
5ba67a51
import
queryError
from
'
@/services/error
'
;
export
default
{
namespace
:
'
error
'
,
state
:
{
error
:
''
,
isloading
:
false
,
},
effects
:
{
*
query
({
payload
},
{
call
,
put
})
{
yield
call
(
queryError
,
payload
.
code
);
yield
put
({
type
:
'
trigger
'
,
payload
:
payload
.
code
,
});
},
},
reducers
:
{
trigger
(
state
,
action
)
{
return
{
error
:
action
.
payload
,
};
},
},
};
src/pages/Exception/style.less
deleted
100644 → 0
View file @
5ba67a51
.trigger {
background: 'red';
:global(.ant-btn) {
margin-right: 8px;
margin-bottom: 12px;
}
}
src/pages/Forms/AdvancedForm.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
Card
,
Button
,
Form
,
Icon
,
Col
,
Row
,
DatePicker
,
TimePicker
,
Input
,
Select
,
Popover
,
}
from
'
antd
'
;
import
{
connect
}
from
'
dva
'
;
import
FooterToolbar
from
'
ant-design-pro/lib/FooterToolbar
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
TableForm
from
'
./TableForm
'
;
import
styles
from
'
./style.less
'
;
const
{
Option
}
=
Select
;
const
{
RangePicker
}
=
DatePicker
;
const
fieldLabels
=
{
name
:
'
仓库名
'
,
url
:
'
仓库域名
'
,
owner
:
'
仓库管理员
'
,
approver
:
'
审批人
'
,
dateRange
:
'
生效日期
'
,
type
:
'
仓库类型
'
,
name2
:
'
任务名
'
,
url2
:
'
任务描述
'
,
owner2
:
'
执行人
'
,
approver2
:
'
责任人
'
,
dateRange2
:
'
生效日期
'
,
type2
:
'
任务类型
'
,
};
const
tableData
=
[
{
key
:
'
1
'
,
workId
:
'
00001
'
,
name
:
'
John Brown
'
,
department
:
'
New York No. 1 Lake Park
'
,
},
{
key
:
'
2
'
,
workId
:
'
00002
'
,
name
:
'
Jim Green
'
,
department
:
'
London No. 1 Lake Park
'
,
},
{
key
:
'
3
'
,
workId
:
'
00003
'
,
name
:
'
Joe Black
'
,
department
:
'
Sidney No. 1 Lake Park
'
,
},
];
@
connect
(({
loading
})
=>
({
submitting
:
loading
.
effects
[
'
form/submitAdvancedForm
'
],
}))
@
Form
.
create
()
class
AdvancedForm
extends
PureComponent
{
state
=
{
width
:
'
100%
'
,
};
componentDidMount
()
{
window
.
addEventListener
(
'
resize
'
,
this
.
resizeFooterToolbar
,
{
passive
:
true
});
}
componentWillUnmount
()
{
window
.
removeEventListener
(
'
resize
'
,
this
.
resizeFooterToolbar
);
}
getErrorInfo
=
()
=>
{
const
{
form
:
{
getFieldsError
},
}
=
this
.
props
;
const
errors
=
getFieldsError
();
const
errorCount
=
Object
.
keys
(
errors
).
filter
(
key
=>
errors
[
key
]).
length
;
if
(
!
errors
||
errorCount
===
0
)
{
return
null
;
}
const
scrollToField
=
fieldKey
=>
{
const
labelNode
=
document
.
querySelector
(
`label[for="
${
fieldKey
}
"]`
);
if
(
labelNode
)
{
labelNode
.
scrollIntoView
(
true
);
}
};
const
errorList
=
Object
.
keys
(
errors
).
map
(
key
=>
{
if
(
!
errors
[
key
])
{
return
null
;
}
return
(
<
li
key
=
{
key
}
className
=
{
styles
.
errorListItem
}
onClick
=
{()
=>
scrollToField
(
key
)}
>
<
Icon
type
=
"
cross-circle-o
"
className
=
{
styles
.
errorIcon
}
/
>
<
div
className
=
{
styles
.
errorMessage
}
>
{
errors
[
key
][
0
]}
<
/div
>
<
div
className
=
{
styles
.
errorField
}
>
{
fieldLabels
[
key
]}
<
/div
>
<
/li
>
);
});
return
(
<
span
className
=
{
styles
.
errorIcon
}
>
<
Popover
title
=
"
表单校验信息
"
content
=
{
errorList
}
overlayClassName
=
{
styles
.
errorPopover
}
trigger
=
"
click
"
getPopupContainer
=
{
trigger
=>
trigger
.
parentNode
}
>
<
Icon
type
=
"
exclamation-circle
"
/>
<
/Popover
>
{
errorCount
}
<
/span
>
);
};
resizeFooterToolbar
=
()
=>
{
requestAnimationFrame
(()
=>
{
const
sider
=
document
.
querySelectorAll
(
'
.ant-layout-sider
'
)[
0
];
if
(
sider
)
{
const
width
=
`calc(100% -
${
sider
.
style
.
width
}
)`
;
const
{
width
:
stateWidth
}
=
this
.
state
;
if
(
stateWidth
!==
width
)
{
this
.
setState
({
width
});
}
}
});
};
validate
=
()
=>
{
const
{
form
:
{
validateFieldsAndScroll
},
dispatch
,
}
=
this
.
props
;
validateFieldsAndScroll
((
error
,
values
)
=>
{
if
(
!
error
)
{
// submit the values
dispatch
({
type
:
'
form/submitAdvancedForm
'
,
payload
:
values
,
});
}
});
};
render
()
{
const
{
form
:
{
getFieldDecorator
},
submitting
,
}
=
this
.
props
;
const
{
width
}
=
this
.
state
;
return
(
<
PageHeaderWrapper
title
=
"
高级表单
"
content
=
"
高级表单常见于一次性输入和提交大批量数据的场景。
"
wrapperClassName
=
{
styles
.
advancedForm
}
>
<
Card
title
=
"
仓库管理
"
className
=
{
styles
.
card
}
bordered
=
{
false
}
>
<
Form
layout
=
"
vertical
"
hideRequiredMark
>
<
Row
gutter
=
{
16
}
>
<
Col
lg
=
{
6
}
md
=
{
12
}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
name
}
>
{
getFieldDecorator
(
'
name
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入仓库名称
'
}],
})(
<
Input
placeholder
=
"
请输入仓库名称
"
/>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
6
,
offset
:
2
}}
lg
=
{{
span
:
8
}}
md
=
{{
span
:
12
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
url
}
>
{
getFieldDecorator
(
'
url
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择
'
}],
})(
<
Input
style
=
{{
width
:
'
100%
'
}}
addonBefore
=
"
http://
"
addonAfter
=
"
.com
"
placeholder
=
"
请输入
"
/>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
8
,
offset
:
2
}}
lg
=
{{
span
:
10
}}
md
=
{{
span
:
24
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
owner
}
>
{
getFieldDecorator
(
'
owner
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择管理员
'
}],
})(
<
Select
placeholder
=
"
请选择管理员
"
>
<
Option
value
=
"
xiao
"
>
付晓晓
<
/Option
>
<
Option
value
=
"
mao
"
>
周毛毛
<
/Option
>
<
/Select
>
)}
<
/Form.Item
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
lg
=
{
6
}
md
=
{
12
}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
approver
}
>
{
getFieldDecorator
(
'
approver
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择审批员
'
}],
})(
<
Select
placeholder
=
"
请选择审批员
"
>
<
Option
value
=
"
xiao
"
>
付晓晓
<
/Option
>
<
Option
value
=
"
mao
"
>
周毛毛
<
/Option
>
<
/Select
>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
6
,
offset
:
2
}}
lg
=
{{
span
:
8
}}
md
=
{{
span
:
12
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
dateRange
}
>
{
getFieldDecorator
(
'
dateRange
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择生效日期
'
}],
})(
<
RangePicker
placeholder
=
{[
'
开始日期
'
,
'
结束日期
'
]}
style
=
{{
width
:
'
100%
'
}}
/
>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
8
,
offset
:
2
}}
lg
=
{{
span
:
10
}}
md
=
{{
span
:
24
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
type
}
>
{
getFieldDecorator
(
'
type
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择仓库类型
'
}],
})(
<
Select
placeholder
=
"
请选择仓库类型
"
>
<
Option
value
=
"
private
"
>
私密
<
/Option
>
<
Option
value
=
"
public
"
>
公开
<
/Option
>
<
/Select
>
)}
<
/Form.Item
>
<
/Col
>
<
/Row
>
<
/Form
>
<
/Card
>
<
Card
title
=
"
任务管理
"
className
=
{
styles
.
card
}
bordered
=
{
false
}
>
<
Form
layout
=
"
vertical
"
hideRequiredMark
>
<
Row
gutter
=
{
16
}
>
<
Col
lg
=
{
6
}
md
=
{
12
}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
name2
}
>
{
getFieldDecorator
(
'
name2
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入
'
}],
})(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
6
,
offset
:
2
}}
lg
=
{{
span
:
8
}}
md
=
{{
span
:
12
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
url2
}
>
{
getFieldDecorator
(
'
url2
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择
'
}],
})(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
8
,
offset
:
2
}}
lg
=
{{
span
:
10
}}
md
=
{{
span
:
24
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
owner2
}
>
{
getFieldDecorator
(
'
owner2
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择管理员
'
}],
})(
<
Select
placeholder
=
"
请选择管理员
"
>
<
Option
value
=
"
xiao
"
>
付晓晓
<
/Option
>
<
Option
value
=
"
mao
"
>
周毛毛
<
/Option
>
<
/Select
>
)}
<
/Form.Item
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{
16
}
>
<
Col
lg
=
{
6
}
md
=
{
12
}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
approver2
}
>
{
getFieldDecorator
(
'
approver2
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择审批员
'
}],
})(
<
Select
placeholder
=
"
请选择审批员
"
>
<
Option
value
=
"
xiao
"
>
付晓晓
<
/Option
>
<
Option
value
=
"
mao
"
>
周毛毛
<
/Option
>
<
/Select
>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
6
,
offset
:
2
}}
lg
=
{{
span
:
8
}}
md
=
{{
span
:
12
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
dateRange2
}
>
{
getFieldDecorator
(
'
dateRange2
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入
'
}],
})(
<
TimePicker
placeholder
=
"
提醒时间
"
style
=
{{
width
:
'
100%
'
}}
getPopupContainer
=
{
trigger
=>
trigger
.
parentNode
}
/
>
)}
<
/Form.Item
>
<
/Col
>
<
Col
xl
=
{{
span
:
8
,
offset
:
2
}}
lg
=
{{
span
:
10
}}
md
=
{{
span
:
24
}}
sm
=
{
24
}
>
<
Form
.
Item
label
=
{
fieldLabels
.
type2
}
>
{
getFieldDecorator
(
'
type2
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择仓库类型
'
}],
})(
<
Select
placeholder
=
"
请选择仓库类型
"
>
<
Option
value
=
"
private
"
>
私密
<
/Option
>
<
Option
value
=
"
public
"
>
公开
<
/Option
>
<
/Select
>
)}
<
/Form.Item
>
<
/Col
>
<
/Row
>
<
/Form
>
<
/Card
>
<
Card
title
=
"
成员管理
"
bordered
=
{
false
}
>
{
getFieldDecorator
(
'
members
'
,
{
initialValue
:
tableData
,
})(
<
TableForm
/>
)}
<
/Card
>
<
FooterToolbar
style
=
{{
width
}}
>
{
this
.
getErrorInfo
()}
<
Button
type
=
"
primary
"
onClick
=
{
this
.
validate
}
loading
=
{
submitting
}
>
提交
<
/Button
>
<
/FooterToolbar
>
<
/PageHeaderWrapper
>
);
}
}
export
default
AdvancedForm
;
src/pages/Forms/BasicForm.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Form
,
Input
,
DatePicker
,
Select
,
Button
,
Card
,
InputNumber
,
Radio
,
Icon
,
Tooltip
,
}
from
'
antd
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
./style.less
'
;
const
FormItem
=
Form
.
Item
;
const
{
Option
}
=
Select
;
const
{
RangePicker
}
=
DatePicker
;
const
{
TextArea
}
=
Input
;
@
connect
(({
loading
})
=>
({
submitting
:
loading
.
effects
[
'
form/submitRegularForm
'
],
}))
@
Form
.
create
()
class
BasicForms
extends
PureComponent
{
handleSubmit
=
e
=>
{
const
{
dispatch
,
form
}
=
this
.
props
;
e
.
preventDefault
();
form
.
validateFieldsAndScroll
((
err
,
values
)
=>
{
if
(
!
err
)
{
dispatch
({
type
:
'
form/submitRegularForm
'
,
payload
:
values
,
});
}
});
};
render
()
{
const
{
submitting
}
=
this
.
props
;
const
{
form
:
{
getFieldDecorator
,
getFieldValue
},
}
=
this
.
props
;
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
7
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
12
},
md
:
{
span
:
10
},
},
};
const
submitFormLayout
=
{
wrapperCol
:
{
xs
:
{
span
:
24
,
offset
:
0
},
sm
:
{
span
:
10
,
offset
:
7
},
},
};
return
(
<
PageHeaderWrapper
title
=
{
<
FormattedMessage
id
=
"
app.forms.basic.title
"
/>
}
content
=
{
<
FormattedMessage
id
=
"
app.forms.basic.description
"
/>
}
>
<
Card
bordered
=
{
false
}
>
<
Form
onSubmit
=
{
this
.
handleSubmit
}
hideRequiredMark
style
=
{{
marginTop
:
8
}}
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
FormattedMessage
id
=
"
form.title.label
"
/>
}
>
{
getFieldDecorator
(
'
title
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.title.required
'
}),
},
],
})(
<
Input
placeholder
=
{
formatMessage
({
id
:
'
form.title.placeholder
'
})}
/>
)
}
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
FormattedMessage
id
=
"
form.date.label
"
/>
}
>
{
getFieldDecorator
(
'
date
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.date.required
'
}),
},
],
})(
<
RangePicker
style
=
{{
width
:
'
100%
'
}}
placeholder
=
{[
formatMessage
({
id
:
'
form.date.placeholder.start
'
}),
formatMessage
({
id
:
'
form.date.placeholder.end
'
}),
]}
/
>
)}
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
FormattedMessage
id
=
"
form.goal.label
"
/>
}
>
{
getFieldDecorator
(
'
goal
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.goal.required
'
}),
},
],
})(
<
TextArea
style
=
{{
minHeight
:
32
}}
placeholder
=
{
formatMessage
({
id
:
'
form.goal.placeholder
'
})}
rows
=
{
4
}
/
>
)}
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
FormattedMessage
id
=
"
form.standard.label
"
/>
}
>
{
getFieldDecorator
(
'
standard
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.standard.required
'
}),
},
],
})(
<
TextArea
style
=
{{
minHeight
:
32
}}
placeholder
=
{
formatMessage
({
id
:
'
form.standard.placeholder
'
})}
rows
=
{
4
}
/
>
)}
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
span
>
<
FormattedMessage
id
=
"
form.client.label
"
/>
<
em
className
=
{
styles
.
optional
}
>
<
FormattedMessage
id
=
"
form.optional
"
/>
<
Tooltip
title
=
{
<
FormattedMessage
id
=
"
form.client.label.tooltip
"
/>
}
>
<
Icon
type
=
"
info-circle-o
"
style
=
{{
marginRight
:
4
}}
/
>
<
/Tooltip
>
<
/em
>
<
/span
>
}
>
{
getFieldDecorator
(
'
client
'
)(
<
Input
placeholder
=
{
formatMessage
({
id
:
'
form.client.placeholder
'
})}
/
>
)}
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
span
>
<
FormattedMessage
id
=
"
form.invites.label
"
/>
<
em
className
=
{
styles
.
optional
}
>
<
FormattedMessage
id
=
"
form.optional
"
/>
<
/em
>
<
/span
>
}
>
{
getFieldDecorator
(
'
invites
'
)(
<
Input
placeholder
=
{
formatMessage
({
id
:
'
form.invites.placeholder
'
})}
/
>
)}
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
span
>
<
FormattedMessage
id
=
"
form.weight.label
"
/>
<
em
className
=
{
styles
.
optional
}
>
<
FormattedMessage
id
=
"
form.optional
"
/>
<
/em
>
<
/span
>
}
>
{
getFieldDecorator
(
'
weight
'
)(
<
InputNumber
placeholder
=
{
formatMessage
({
id
:
'
form.weight.placeholder
'
})}
min
=
{
0
}
max
=
{
100
}
/
>
)}
<
span
className
=
"
ant-form-text
"
>%<
/span
>
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
{
<
FormattedMessage
id
=
"
form.public.label
"
/>
}
help
=
{
<
FormattedMessage
id
=
"
form.public.label.help
"
/>
}
>
<
div
>
{
getFieldDecorator
(
'
public
'
,
{
initialValue
:
'
1
'
,
})(
<
Radio
.
Group
>
<
Radio
value
=
"
1
"
>
<
FormattedMessage
id
=
"
form.public.radio.public
"
/>
<
/Radio
>
<
Radio
value
=
"
2
"
>
<
FormattedMessage
id
=
"
form.public.radio.partially-public
"
/>
<
/Radio
>
<
Radio
value
=
"
3
"
>
<
FormattedMessage
id
=
"
form.public.radio.private
"
/>
<
/Radio
>
<
/Radio.Group
>
)}
<
FormItem
style
=
{{
marginBottom
:
0
}}
>
{
getFieldDecorator
(
'
publicUsers
'
)(
<
Select
mode
=
"
multiple
"
placeholder
=
{
formatMessage
({
id
:
'
form.publicUsers.placeholder
'
})}
style
=
{{
margin
:
'
8px 0
'
,
display
:
getFieldValue
(
'
public
'
)
===
'
2
'
?
'
block
'
:
'
none
'
,
}}
>
<
Option
value
=
"
1
"
>
<
FormattedMessage
id
=
"
form.publicUsers.option.A
"
/>
<
/Option
>
<
Option
value
=
"
2
"
>
<
FormattedMessage
id
=
"
form.publicUsers.option.B
"
/>
<
/Option
>
<
Option
value
=
"
3
"
>
<
FormattedMessage
id
=
"
form.publicUsers.option.C
"
/>
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/div
>
<
/FormItem
>
<
FormItem
{...
submitFormLayout
}
style
=
{{
marginTop
:
32
}}
>
<
Button
type
=
"
primary
"
htmlType
=
"
submit
"
loading
=
{
submitting
}
>
<
FormattedMessage
id
=
"
form.submit
"
/>
<
/Button
>
<
Button
style
=
{{
marginLeft
:
8
}}
>
<
FormattedMessage
id
=
"
form.save
"
/>
<
/Button
>
<
/FormItem
>
<
/Form
>
<
/Card
>
<
/PageHeaderWrapper
>
);
}
}
export
default
BasicForms
;
src/pages/Forms/StepForm/Step1.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Fragment
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Form
,
Input
,
Button
,
Select
,
Divider
}
from
'
antd
'
;
import
router
from
'
umi/router
'
;
import
styles
from
'
./style.less
'
;
const
{
Option
}
=
Select
;
const
formItemLayout
=
{
labelCol
:
{
span
:
5
,
},
wrapperCol
:
{
span
:
19
,
},
};
@
connect
(({
form
})
=>
({
data
:
form
.
step
,
}))
@
Form
.
create
()
class
Step1
extends
React
.
PureComponent
{
render
()
{
const
{
form
,
dispatch
,
data
}
=
this
.
props
;
const
{
getFieldDecorator
,
validateFields
}
=
form
;
const
onValidateForm
=
()
=>
{
validateFields
((
err
,
values
)
=>
{
if
(
!
err
)
{
dispatch
({
type
:
'
form/saveStepFormData
'
,
payload
:
values
,
});
router
.
push
(
'
/form/step-form/confirm
'
);
}
});
};
return
(
<
Fragment
>
<
Form
layout
=
"
horizontal
"
className
=
{
styles
.
stepForm
}
hideRequiredMark
>
<
Form
.
Item
{...
formItemLayout
}
label
=
"
付款账户
"
>
{
getFieldDecorator
(
'
payAccount
'
,
{
initialValue
:
data
.
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
{...
formItemLayout
}
label
=
"
收款账户
"
>
<
Input
.
Group
compact
>
<
Select
defaultValue
=
"
alipay
"
style
=
{{
width
:
100
}}
>
<
Option
value
=
"
alipay
"
>
支付宝
<
/Option
>
<
Option
value
=
"
bank
"
>
银行账户
<
/Option
>
<
/Select
>
{
getFieldDecorator
(
'
receiverAccount
'
,
{
initialValue
:
data
.
receiverAccount
,
rules
:
[
{
required
:
true
,
message
:
'
请输入收款人账户
'
},
{
type
:
'
email
'
,
message
:
'
账户名应为邮箱格式
'
},
],
})(
<
Input
style
=
{{
width
:
'
calc(100% - 100px)
'
}}
placeholder
=
"
test@example.com
"
/>
)}
<
/Input.Group
>
<
/Form.Item
>
<
Form
.
Item
{...
formItemLayout
}
label
=
"
收款人姓名
"
>
{
getFieldDecorator
(
'
receiverName
'
,
{
initialValue
:
data
.
receiverName
,
rules
:
[{
required
:
true
,
message
:
'
请输入收款人姓名
'
}],
})(
<
Input
placeholder
=
"
请输入收款人姓名
"
/>
)}
<
/Form.Item
>
<
Form
.
Item
{...
formItemLayout
}
label
=
"
转账金额
"
>
{
getFieldDecorator
(
'
amount
'
,
{
initialValue
:
data
.
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
,
},
}}
label
=
""
>
<
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
>
<
/Fragment
>
);
}
}
export
default
Step1
;
src/pages/Forms/StepForm/Step2.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Form
,
Input
,
Button
,
Alert
,
Divider
}
from
'
antd
'
;
import
router
from
'
umi/router
'
;
import
{
digitUppercase
}
from
'
@/utils/utils
'
;
import
styles
from
'
./style.less
'
;
const
formItemLayout
=
{
labelCol
:
{
span
:
5
,
},
wrapperCol
:
{
span
:
19
,
},
};
@
connect
(({
form
,
loading
})
=>
({
submitting
:
loading
.
effects
[
'
form/submitStepForm
'
],
data
:
form
.
step
,
}))
@
Form
.
create
()
class
Step2
extends
React
.
PureComponent
{
render
()
{
const
{
form
,
data
,
dispatch
,
submitting
}
=
this
.
props
;
const
{
getFieldDecorator
,
validateFields
}
=
form
;
const
onPrev
=
()
=>
{
router
.
push
(
'
/form/step-form/info
'
);
};
const
onValidateForm
=
e
=>
{
e
.
preventDefault
();
validateFields
((
err
,
values
)
=>
{
if
(
!
err
)
{
dispatch
({
type
:
'
form/submitStepForm
'
,
payload
:
{
...
data
,
...
values
,
},
});
}
});
};
return
(
<
Form
layout
=
"
horizontal
"
className
=
{
styles
.
stepForm
}
>
<
Alert
closable
showIcon
message
=
"
确认转账后,资金将直接打入对方账户,无法退回。
"
style
=
{{
marginBottom
:
24
}}
/
>
<
Form
.
Item
{...
formItemLayout
}
className
=
{
styles
.
stepFormText
}
label
=
"
付款账户
"
>
{
data
.
payAccount
}
<
/Form.Item
>
<
Form
.
Item
{...
formItemLayout
}
className
=
{
styles
.
stepFormText
}
label
=
"
收款账户
"
>
{
data
.
receiverAccount
}
<
/Form.Item
>
<
Form
.
Item
{...
formItemLayout
}
className
=
{
styles
.
stepFormText
}
label
=
"
收款人姓名
"
>
{
data
.
receiverName
}
<
/Form.Item
>
<
Form
.
Item
{...
formItemLayout
}
className
=
{
styles
.
stepFormText
}
label
=
"
转账金额
"
>
<
span
className
=
{
styles
.
money
}
>
{
data
.
amount
}
<
/span
>
<
span
className
=
{
styles
.
uppercase
}
>
(
{
digitUppercase
(
data
.
amount
)}
)
<
/span
>
<
/Form.Item
>
<
Divider
style
=
{{
margin
:
'
24px 0
'
}}
/
>
<
Form
.
Item
{...
formItemLayout
}
label
=
"
支付密码
"
required
=
{
false
}
>
{
getFieldDecorator
(
'
password
'
,
{
initialValue
:
'
123456
'
,
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
,
},
}}
label
=
""
>
<
Button
type
=
"
primary
"
onClick
=
{
onValidateForm
}
loading
=
{
submitting
}
>
提交
<
/Button
>
<
Button
onClick
=
{
onPrev
}
style
=
{{
marginLeft
:
8
}}
>
上一步
<
/Button
>
<
/Form.Item
>
<
/Form
>
);
}
}
export
default
Step2
;
src/pages/Forms/StepForm/Step3.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Fragment
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Button
,
Row
,
Col
}
from
'
antd
'
;
import
router
from
'
umi/router
'
;
import
Result
from
'
ant-design-pro/lib/Result
'
;
import
styles
from
'
./style.less
'
;
@
connect
(({
form
})
=>
({
data
:
form
.
step
,
}))
class
Step3
extends
React
.
PureComponent
{
render
()
{
const
{
data
}
=
this
.
props
;
const
onFinish
=
()
=>
{
router
.
push
(
'
/form/step-form/info
'
);
};
const
information
=
(
<
div
className
=
{
styles
.
information
}
>
<
Row
>
<
Col
xs
=
{
24
}
sm
=
{
8
}
className
=
{
styles
.
label
}
>
付款账户
:
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
{
data
.
payAccount
}
<
/Col
>
<
/Row
>
<
Row
>
<
Col
xs
=
{
24
}
sm
=
{
8
}
className
=
{
styles
.
label
}
>
收款账户
:
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
{
data
.
receiverAccount
}
<
/Col
>
<
/Row
>
<
Row
>
<
Col
xs
=
{
24
}
sm
=
{
8
}
className
=
{
styles
.
label
}
>
收款人姓名
:
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
{
data
.
receiverName
}
<
/Col
>
<
/Row
>
<
Row
>
<
Col
xs
=
{
24
}
sm
=
{
8
}
className
=
{
styles
.
label
}
>
转账金额
:
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
16
}
>
<
span
className
=
{
styles
.
money
}
>
{
data
.
amount
}
<
/span>
元
<
/Col
>
<
/Row
>
<
/div
>
);
const
actions
=
(
<
Fragment
>
<
Button
type
=
"
primary
"
onClick
=
{
onFinish
}
>
再转一笔
<
/Button
>
<
Button
>
查看账单
<
/Button
>
<
/Fragment
>
);
return
(
<
Result
type
=
"
success
"
title
=
"
操作成功
"
description
=
"
预计两小时内到账
"
extra
=
{
information
}
actions
=
{
actions
}
className
=
{
styles
.
result
}
/
>
);
}
}
export
default
Step3
;
src/pages/Forms/StepForm/index.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
,
Fragment
}
from
'
react
'
;
import
{
Card
,
Steps
}
from
'
antd
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
../style.less
'
;
const
{
Step
}
=
Steps
;
export
default
class
StepForm
extends
PureComponent
{
getCurrentStep
()
{
const
{
location
}
=
this
.
props
;
const
{
pathname
}
=
location
;
const
pathList
=
pathname
.
split
(
'
/
'
);
switch
(
pathList
[
pathList
.
length
-
1
])
{
case
'
info
'
:
return
0
;
case
'
confirm
'
:
return
1
;
case
'
result
'
:
return
2
;
default
:
return
0
;
}
}
render
()
{
const
{
location
,
children
}
=
this
.
props
;
return
(
<
PageHeaderWrapper
title
=
"
分步表单
"
tabActiveKey
=
{
location
.
pathname
}
content
=
"
将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。
"
>
<
Card
bordered
=
{
false
}
>
<
Fragment
>
<
Steps
current
=
{
this
.
getCurrentStep
()}
className
=
{
styles
.
steps
}
>
<
Step
title
=
"
填写转账信息
"
/>
<
Step
title
=
"
确认转账信息
"
/>
<
Step
title
=
"
完成
"
/>
<
/Steps
>
{
children
}
<
/Fragment
>
<
/Card
>
<
/PageHeaderWrapper
>
);
}
}
src/pages/Forms/StepForm/style.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.stepForm {
margin: 40px auto 0;
max-width: 500px;
}
.stepFormText {
margin-bottom: 24px;
:global {
.ant-form-item-label,
.ant-form-item-control {
line-height: 22px;
}
}
}
.result {
margin: 0 auto;
max-width: 560px;
padding: 24px 0 8px;
}
.desc {
padding: 0 56px;
color: @text-color-secondary;
h3 {
font-size: 16px;
margin: 0 0 12px 0;
color: @text-color-secondary;
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 {
color: @heading-color;
text-align: right;
padding-right: 8px;
@media screen and (max-width: @screen-sm) {
text-align: left;
}
}
}
.money {
font-family: 'Helvetica Neue', sans-serif;
font-weight: 500;
font-size: 20px;
line-height: 14px;
}
.uppercase {
font-size: 12px;
}
src/pages/Forms/TableForm.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
,
Fragment
}
from
'
react
'
;
import
{
Table
,
Button
,
Input
,
message
,
Popconfirm
,
Divider
}
from
'
antd
'
;
import
isEqual
from
'
lodash/isEqual
'
;
import
styles
from
'
./style.less
'
;
class
TableForm
extends
PureComponent
{
index
=
0
;
cacheOriginData
=
{};
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
data
:
props
.
value
,
loading
:
false
,
/* eslint-disable-next-line react/no-unused-state */
value
:
props
.
value
,
};
}
static
getDerivedStateFromProps
(
nextProps
,
preState
)
{
if
(
isEqual
(
nextProps
.
value
,
preState
.
value
))
{
return
null
;
}
return
{
data
:
nextProps
.
value
,
value
:
nextProps
.
value
,
};
}
getRowByKey
(
key
,
newData
)
{
const
{
data
}
=
this
.
state
;
return
(
newData
||
data
).
filter
(
item
=>
item
.
key
===
key
)[
0
];
}
toggleEditable
=
(
e
,
key
)
=>
{
e
.
preventDefault
();
const
{
data
}
=
this
.
state
;
const
newData
=
data
.
map
(
item
=>
({
...
item
}));
const
target
=
this
.
getRowByKey
(
key
,
newData
);
if
(
target
)
{
// 进入编辑状态时保存原始数据
if
(
!
target
.
editable
)
{
this
.
cacheOriginData
[
key
]
=
{
...
target
};
}
target
.
editable
=
!
target
.
editable
;
this
.
setState
({
data
:
newData
});
}
};
newMember
=
()
=>
{
const
{
data
}
=
this
.
state
;
const
newData
=
data
.
map
(
item
=>
({
...
item
}));
newData
.
push
({
key
:
`NEW_TEMP_ID_
${
this
.
index
}
`
,
workId
:
''
,
name
:
''
,
department
:
''
,
editable
:
true
,
isNew
:
true
,
});
this
.
index
+=
1
;
this
.
setState
({
data
:
newData
});
};
remove
(
key
)
{
const
{
data
}
=
this
.
state
;
const
{
onChange
}
=
this
.
props
;
const
newData
=
data
.
filter
(
item
=>
item
.
key
!==
key
);
this
.
setState
({
data
:
newData
});
onChange
(
newData
);
}
handleKeyPress
(
e
,
key
)
{
if
(
e
.
key
===
'
Enter
'
)
{
this
.
saveRow
(
e
,
key
);
}
}
handleFieldChange
(
e
,
fieldName
,
key
)
{
const
{
data
}
=
this
.
state
;
const
newData
=
data
.
map
(
item
=>
({
...
item
}));
const
target
=
this
.
getRowByKey
(
key
,
newData
);
if
(
target
)
{
target
[
fieldName
]
=
e
.
target
.
value
;
this
.
setState
({
data
:
newData
});
}
}
saveRow
(
e
,
key
)
{
e
.
persist
();
this
.
setState
({
loading
:
true
,
});
setTimeout
(()
=>
{
if
(
this
.
clickedCancel
)
{
this
.
clickedCancel
=
false
;
return
;
}
const
target
=
this
.
getRowByKey
(
key
)
||
{};
if
(
!
target
.
workId
||
!
target
.
name
||
!
target
.
department
)
{
message
.
error
(
'
请填写完整成员信息。
'
);
e
.
target
.
focus
();
this
.
setState
({
loading
:
false
,
});
return
;
}
delete
target
.
isNew
;
this
.
toggleEditable
(
e
,
key
);
const
{
data
}
=
this
.
state
;
const
{
onChange
}
=
this
.
props
;
onChange
(
data
);
this
.
setState
({
loading
:
false
,
});
},
500
);
}
cancel
(
e
,
key
)
{
this
.
clickedCancel
=
true
;
e
.
preventDefault
();
const
{
data
}
=
this
.
state
;
const
newData
=
data
.
map
(
item
=>
({
...
item
}));
const
target
=
this
.
getRowByKey
(
key
,
newData
);
if
(
this
.
cacheOriginData
[
key
])
{
Object
.
assign
(
target
,
this
.
cacheOriginData
[
key
]);
delete
this
.
cacheOriginData
[
key
];
}
target
.
editable
=
false
;
this
.
setState
({
data
:
newData
});
this
.
clickedCancel
=
false
;
}
render
()
{
const
columns
=
[
{
title
:
'
成员姓名
'
,
dataIndex
:
'
name
'
,
key
:
'
name
'
,
width
:
'
20%
'
,
render
:
(
text
,
record
)
=>
{
if
(
record
.
editable
)
{
return
(
<
Input
value
=
{
text
}
autoFocus
onChange
=
{
e
=>
this
.
handleFieldChange
(
e
,
'
name
'
,
record
.
key
)}
onKeyPress
=
{
e
=>
this
.
handleKeyPress
(
e
,
record
.
key
)}
placeholder
=
"
成员姓名
"
/>
);
}
return
text
;
},
},
{
title
:
'
工号
'
,
dataIndex
:
'
workId
'
,
key
:
'
workId
'
,
width
:
'
20%
'
,
render
:
(
text
,
record
)
=>
{
if
(
record
.
editable
)
{
return
(
<
Input
value
=
{
text
}
onChange
=
{
e
=>
this
.
handleFieldChange
(
e
,
'
workId
'
,
record
.
key
)}
onKeyPress
=
{
e
=>
this
.
handleKeyPress
(
e
,
record
.
key
)}
placeholder
=
"
工号
"
/>
);
}
return
text
;
},
},
{
title
:
'
所属部门
'
,
dataIndex
:
'
department
'
,
key
:
'
department
'
,
width
:
'
40%
'
,
render
:
(
text
,
record
)
=>
{
if
(
record
.
editable
)
{
return
(
<
Input
value
=
{
text
}
onChange
=
{
e
=>
this
.
handleFieldChange
(
e
,
'
department
'
,
record
.
key
)}
onKeyPress
=
{
e
=>
this
.
handleKeyPress
(
e
,
record
.
key
)}
placeholder
=
"
所属部门
"
/>
);
}
return
text
;
},
},
{
title
:
'
操作
'
,
key
:
'
action
'
,
render
:
(
text
,
record
)
=>
{
const
{
loading
}
=
this
.
state
;
if
(
!!
record
.
editable
&&
loading
)
{
return
null
;
}
if
(
record
.
editable
)
{
if
(
record
.
isNew
)
{
return
(
<
span
>
<
a
onClick
=
{
e
=>
this
.
saveRow
(
e
,
record
.
key
)}
>
添加
<
/a
>
<
Divider
type
=
"
vertical
"
/>
<
Popconfirm
title
=
"
是否要删除此行?
"
onConfirm
=
{()
=>
this
.
remove
(
record
.
key
)}
>
<
a
>
删除
<
/a
>
<
/Popconfirm
>
<
/span
>
);
}
return
(
<
span
>
<
a
onClick
=
{
e
=>
this
.
saveRow
(
e
,
record
.
key
)}
>
保存
<
/a
>
<
Divider
type
=
"
vertical
"
/>
<
a
onClick
=
{
e
=>
this
.
cancel
(
e
,
record
.
key
)}
>
取消
<
/a
>
<
/span
>
);
}
return
(
<
span
>
<
a
onClick
=
{
e
=>
this
.
toggleEditable
(
e
,
record
.
key
)}
>
编辑
<
/a
>
<
Divider
type
=
"
vertical
"
/>
<
Popconfirm
title
=
"
是否要删除此行?
"
onConfirm
=
{()
=>
this
.
remove
(
record
.
key
)}
>
<
a
>
删除
<
/a
>
<
/Popconfirm
>
<
/span
>
);
},
},
];
const
{
loading
,
data
}
=
this
.
state
;
return
(
<
Fragment
>
<
Table
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
=
{
this
.
newMember
}
icon
=
"
plus
"
>
新增成员
<
/Button
>
<
/Fragment
>
);
}
}
export
default
TableForm
;
src/pages/Forms/models/form.js
deleted
100644 → 0
View file @
5ba67a51
import
{
routerRedux
}
from
'
dva/router
'
;
import
{
message
}
from
'
antd
'
;
import
{
fakeSubmitForm
}
from
'
@/services/api
'
;
export
default
{
namespace
:
'
form
'
,
state
:
{
step
:
{
payAccount
:
'
ant-design@alipay.com
'
,
receiverAccount
:
'
test@example.com
'
,
receiverName
:
'
Alex
'
,
amount
:
'
500
'
,
},
},
effects
:
{
*
submitRegularForm
({
payload
},
{
call
})
{
yield
call
(
fakeSubmitForm
,
payload
);
message
.
success
(
'
提交成功
'
);
},
*
submitStepForm
({
payload
},
{
call
,
put
})
{
yield
call
(
fakeSubmitForm
,
payload
);
yield
put
({
type
:
'
saveStepFormData
'
,
payload
,
});
yield
put
(
routerRedux
.
push
(
'
/form/step-form/result
'
));
},
*
submitAdvancedForm
({
payload
},
{
call
})
{
yield
call
(
fakeSubmitForm
,
payload
);
message
.
success
(
'
提交成功
'
);
},
},
reducers
:
{
saveStepFormData
(
state
,
{
payload
})
{
return
{
...
state
,
step
:
{
...
state
.
step
,
...
payload
,
},
};
},
},
};
src/pages/Forms/style.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.card {
margin-bottom: 24px;
}
.heading {
font-size: 14px;
line-height: 22px;
margin: 0 0 16px 0;
}
.steps:global(.ant-steps) {
max-width: 750px;
margin: 16px auto;
}
.errorIcon {
cursor: pointer;
color: @error-color;
margin-right: 24px;
i {
margin-right: 4px;
}
}
.errorPopover {
:global {
.ant-popover-inner-content {
padding: 0;
max-height: 290px;
overflow: auto;
min-width: 256px;
}
}
}
.errorListItem {
list-style: none;
border-bottom: 1px solid @border-color-split;
padding: 8px 16px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: @primary-1;
}
&:last-child {
border: 0;
}
.errorIcon {
color: @error-color;
float: left;
margin-top: 4px;
margin-right: 12px;
padding-bottom: 22px;
}
.errorField {
font-size: 12px;
color: @text-color-secondary;
margin-top: 2px;
}
}
.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;
}
src/pages/List/Applications.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
numeral
from
'
numeral
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Row
,
Col
,
Form
,
Card
,
Select
,
Icon
,
Avatar
,
List
,
Tooltip
,
Dropdown
,
Menu
}
from
'
antd
'
;
import
TagSelect
from
'
ant-design-pro/lib/TagSelect
'
;
import
StandardFormRow
from
'
@/components/StandardFormRow
'
;
import
{
formatWan
}
from
'
@/utils/utils
'
;
import
styles
from
'
./Applications.less
'
;
const
{
Option
}
=
Select
;
const
FormItem
=
Form
.
Item
;
@
connect
(({
list
,
loading
})
=>
({
list
,
loading
:
loading
.
models
.
list
,
}))
@
Form
.
create
({
onValuesChange
({
dispatch
},
changedValues
,
allValues
)
{
// 表单项变化时请求数据
// eslint-disable-next-line
console
.
log
(
changedValues
,
allValues
);
// 模拟查询表单生效
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
8
,
},
});
},
})
class
FilterCardList
extends
PureComponent
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
8
,
},
});
}
render
()
{
const
{
list
:
{
list
},
loading
,
form
,
}
=
this
.
props
;
const
{
getFieldDecorator
}
=
form
;
const
CardInfo
=
({
activeUser
,
newUser
})
=>
(
<
div
className
=
{
styles
.
cardInfo
}
>
<
div
>
<
p
>
活跃用户
<
/p
>
<
p
>
{
activeUser
}
<
/p
>
<
/div
>
<
div
>
<
p
>
新增用户
<
/p
>
<
p
>
{
newUser
}
<
/p
>
<
/div
>
<
/div
>
);
const
formItemLayout
=
{
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
16
},
},
};
const
itemMenu
=
(
<
Menu
>
<
Menu
.
Item
>
<
a
target
=
"
_blank
"
rel
=
"
noopener noreferrer
"
href
=
"
https://www.alipay.com/
"
>
1
st
menu
item
<
/a
>
<
/Menu.Item
>
<
Menu
.
Item
>
<
a
target
=
"
_blank
"
rel
=
"
noopener noreferrer
"
href
=
"
https://www.taobao.com/
"
>
2
nd
menu
item
<
/a
>
<
/Menu.Item
>
<
Menu
.
Item
>
<
a
target
=
"
_blank
"
rel
=
"
noopener noreferrer
"
href
=
"
https://www.tmall.com/
"
>
3
d
menu
item
<
/a
>
<
/Menu.Item
>
<
/Menu
>
);
return
(
<
div
className
=
{
styles
.
filterCardList
}
>
<
Card
bordered
=
{
false
}
>
<
Form
layout
=
"
inline
"
>
<
StandardFormRow
title
=
"
所属类目
"
block
style
=
{{
paddingBottom
:
11
}}
>
<
FormItem
>
{
getFieldDecorator
(
'
category
'
)(
<
TagSelect
expandable
>
<
TagSelect
.
Option
value
=
"
cat1
"
>
类目一
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat2
"
>
类目二
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat3
"
>
类目三
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat4
"
>
类目四
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat5
"
>
类目五
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat6
"
>
类目六
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat7
"
>
类目七
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat8
"
>
类目八
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat9
"
>
类目九
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat10
"
>
类目十
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat11
"
>
类目十一
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat12
"
>
类目十二
<
/TagSelect.Option
>
<
/TagSelect
>
)}
<
/FormItem
>
<
/StandardFormRow
>
<
StandardFormRow
title
=
"
其它选项
"
grid
last
>
<
Row
gutter
=
{
16
}
>
<
Col
lg
=
{
8
}
md
=
{
10
}
sm
=
{
10
}
xs
=
{
24
}
>
<
FormItem
{...
formItemLayout
}
label
=
"
作者
"
>
{
getFieldDecorator
(
'
author
'
,
{})(
<
Select
placeholder
=
"
不限
"
style
=
{{
maxWidth
:
200
,
width
:
'
100%
'
}}
>
<
Option
value
=
"
lisa
"
>
王昭君
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
Col
lg
=
{
8
}
md
=
{
10
}
sm
=
{
10
}
xs
=
{
24
}
>
<
FormItem
{...
formItemLayout
}
label
=
"
好评度
"
>
{
getFieldDecorator
(
'
rate
'
,
{})(
<
Select
placeholder
=
"
不限
"
style
=
{{
maxWidth
:
200
,
width
:
'
100%
'
}}
>
<
Option
value
=
"
good
"
>
优秀
<
/Option
>
<
Option
value
=
"
normal
"
>
普通
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
/Row
>
<
/StandardFormRow
>
<
/Form
>
<
/Card
>
<
List
rowKey
=
"
id
"
style
=
{{
marginTop
:
24
}}
grid
=
{{
gutter
:
24
,
xl
:
4
,
lg
:
3
,
md
:
3
,
sm
:
2
,
xs
:
1
}}
loading
=
{
loading
}
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
key
=
{
item
.
id
}
>
<
Card
hoverable
bodyStyle
=
{{
paddingBottom
:
20
}}
actions
=
{[
<
Tooltip
title
=
"
下载
"
>
<
Icon
type
=
"
download
"
/>
<
/Tooltip>
,
<
Tooltip
title
=
"
编辑
"
>
<
Icon
type
=
"
edit
"
/>
<
/Tooltip>
,
<
Tooltip
title
=
"
分享
"
>
<
Icon
type
=
"
share-alt
"
/>
<
/Tooltip>
,
<
Dropdown
overlay
=
{
itemMenu
}
>
<
Icon
type
=
"
ellipsis
"
/>
<
/Dropdown>
,
]}
>
<
Card
.
Meta
avatar
=
{
<
Avatar
size
=
"
small
"
src
=
{
item
.
avatar
}
/>} title={item.title} /
>
<
div
className
=
{
styles
.
cardItemContent
}
>
<
CardInfo
activeUser
=
{
formatWan
(
item
.
activeUser
)}
newUser
=
{
numeral
(
item
.
newUser
).
format
(
'
0,0
'
)}
/
>
<
/div
>
<
/Card
>
<
/List.Item
>
)}
/
>
<
/div
>
);
}
}
export
default
FilterCardList
;
src/pages/List/Applications.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.filterCardList {
margin-bottom: -24px;
:global {
.ant-card-meta-content {
margin-top: 0;
}
// disabled white space
.ant-card-meta-avatar {
font-size: 0;
}
.ant-card-actions {
background: #f7f9fa;
}
.ant-list .ant-list-item-content-single {
max-width: 100%;
}
}
.cardInfo {
.clearfix();
margin-top: 16px;
margin-left: 40px;
& > div {
position: relative;
text-align: left;
float: left;
width: 50%;
p {
line-height: 32px;
font-size: 24px;
margin: 0;
}
p:first-child {
color: @text-color-secondary;
font-size: 12px;
line-height: 20px;
margin-bottom: 4px;
}
}
}
}
src/pages/List/Articles.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Fragment
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Form
,
Card
,
Select
,
List
,
Tag
,
Icon
,
Row
,
Col
,
Button
}
from
'
antd
'
;
import
TagSelect
from
'
ant-design-pro/lib/TagSelect
'
;
import
StandardFormRow
from
'
@/components/StandardFormRow
'
;
import
ArticleListContent
from
'
@/components/ArticleListContent
'
;
import
styles
from
'
./Articles.less
'
;
const
{
Option
}
=
Select
;
const
FormItem
=
Form
.
Item
;
const
pageSize
=
5
;
@
connect
(({
list
,
loading
})
=>
({
list
,
loading
:
loading
.
models
.
list
,
}))
@
Form
.
create
({
onValuesChange
({
dispatch
},
changedValues
,
allValues
)
{
// 表单项变化时请求数据
// eslint-disable-next-line
console
.
log
(
changedValues
,
allValues
);
// 模拟查询表单生效
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
5
,
},
});
},
})
class
SearchList
extends
Component
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
5
,
},
});
}
setOwner
=
()
=>
{
const
{
form
}
=
this
.
props
;
form
.
setFieldsValue
({
owner
:
[
'
wzj
'
],
});
};
fetchMore
=
()
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/appendFetch
'
,
payload
:
{
count
:
pageSize
,
},
});
};
render
()
{
const
{
form
,
list
:
{
list
},
loading
,
}
=
this
.
props
;
const
{
getFieldDecorator
}
=
form
;
const
owners
=
[
{
id
:
'
wzj
'
,
name
:
'
我自己
'
,
},
{
id
:
'
wjh
'
,
name
:
'
吴家豪
'
,
},
{
id
:
'
zxx
'
,
name
:
'
周星星
'
,
},
{
id
:
'
zly
'
,
name
:
'
赵丽颖
'
,
},
{
id
:
'
ym
'
,
name
:
'
姚明
'
,
},
];
const
IconText
=
({
type
,
text
})
=>
(
<
span
>
<
Icon
type
=
{
type
}
style
=
{{
marginRight
:
8
}}
/
>
{
text
}
<
/span
>
);
const
formItemLayout
=
{
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
24
},
md
:
{
span
:
12
},
},
};
const
loadMore
=
list
.
length
>
0
?
(
<
div
style
=
{{
textAlign
:
'
center
'
,
marginTop
:
16
}}
>
<
Button
onClick
=
{
this
.
fetchMore
}
style
=
{{
paddingLeft
:
48
,
paddingRight
:
48
}}
>
{
loading
?
(
<
span
>
<
Icon
type
=
"
loading
"
/>
加载中
...
<
/span
>
)
:
(
'
加载更多
'
)}
<
/Button
>
<
/div
>
)
:
null
;
return
(
<
Fragment
>
<
Card
bordered
=
{
false
}
>
<
Form
layout
=
"
inline
"
>
<
StandardFormRow
title
=
"
所属类目
"
block
style
=
{{
paddingBottom
:
11
}}
>
<
FormItem
>
{
getFieldDecorator
(
'
category
'
)(
<
TagSelect
expandable
>
<
TagSelect
.
Option
value
=
"
cat1
"
>
类目一
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat2
"
>
类目二
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat3
"
>
类目三
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat4
"
>
类目四
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat5
"
>
类目五
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat6
"
>
类目六
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat7
"
>
类目七
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat8
"
>
类目八
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat9
"
>
类目九
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat10
"
>
类目十
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat11
"
>
类目十一
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat12
"
>
类目十二
<
/TagSelect.Option
>
<
/TagSelect
>
)}
<
/FormItem
>
<
/StandardFormRow
>
<
StandardFormRow
title
=
"
owner
"
grid
>
<
Row
>
<
Col
lg
=
{
16
}
md
=
{
24
}
sm
=
{
24
}
xs
=
{
24
}
>
<
FormItem
>
{
getFieldDecorator
(
'
owner
'
,
{
initialValue
:
[
'
wjh
'
,
'
zxx
'
],
})(
<
Select
mode
=
"
multiple
"
style
=
{{
maxWidth
:
286
,
width
:
'
100%
'
}}
placeholder
=
"
选择 owner
"
>
{
owners
.
map
(
owner
=>
(
<
Option
key
=
{
owner
.
id
}
value
=
{
owner
.
id
}
>
{
owner
.
name
}
<
/Option
>
))}
<
/Select
>
)}
<
a
className
=
{
styles
.
selfTrigger
}
onClick
=
{
this
.
setOwner
}
>
只看自己的
<
/a
>
<
/FormItem
>
<
/Col
>
<
/Row
>
<
/StandardFormRow
>
<
StandardFormRow
title
=
"
其它选项
"
grid
last
>
<
Row
gutter
=
{
16
}
>
<
Col
xl
=
{
8
}
lg
=
{
10
}
md
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
>
<
FormItem
{...
formItemLayout
}
label
=
"
活跃用户
"
>
{
getFieldDecorator
(
'
user
'
,
{})(
<
Select
placeholder
=
"
不限
"
style
=
{{
maxWidth
:
200
,
width
:
'
100%
'
}}
>
<
Option
value
=
"
lisa
"
>
李三
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
Col
xl
=
{
8
}
lg
=
{
10
}
md
=
{
12
}
sm
=
{
24
}
xs
=
{
24
}
>
<
FormItem
{...
formItemLayout
}
label
=
"
好评度
"
>
{
getFieldDecorator
(
'
rate
'
,
{})(
<
Select
placeholder
=
"
不限
"
style
=
{{
maxWidth
:
200
,
width
:
'
100%
'
}}
>
<
Option
value
=
"
good
"
>
优秀
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
/Row
>
<
/StandardFormRow
>
<
/Form
>
<
/Card
>
<
Card
style
=
{{
marginTop
:
24
}}
bordered
=
{
false
}
bodyStyle
=
{{
padding
:
'
8px 32px 32px 32px
'
}}
>
<
List
size
=
"
large
"
loading
=
{
list
.
length
===
0
?
loading
:
false
}
rowKey
=
"
id
"
itemLayout
=
"
vertical
"
loadMore
=
{
loadMore
}
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
key
=
{
item
.
id
}
actions
=
{[
<
IconText
type
=
"
star-o
"
text
=
{
item
.
star
}
/>
,
<
IconText
type
=
"
like-o
"
text
=
{
item
.
like
}
/>
,
<
IconText
type
=
"
message
"
text
=
{
item
.
message
}
/>
,
]}
extra
=
{
<
div
className
=
{
styles
.
listItemExtra
}
/>
}
>
<
List
.
Item
.
Meta
title
=
{
<
a
className
=
{
styles
.
listItemMetaTitle
}
href
=
{
item
.
href
}
>
{
item
.
title
}
<
/a
>
}
description
=
{
<
span
>
<
Tag
>
Ant
Design
<
/Tag
>
<
Tag
>
设计语言
<
/Tag
>
<
Tag
>
蚂蚁金服
<
/Tag
>
<
/span
>
}
/
>
<
ArticleListContent
data
=
{
item
}
/
>
<
/List.Item
>
)}
/
>
<
/Card
>
<
/Fragment
>
);
}
}
export
default
SearchList
;
src/pages/List/Articles.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
a.listItemMetaTitle {
color: @heading-color;
}
.listItemExtra {
width: 272px;
height: 1px;
}
.selfTrigger {
margin-left: 12px;
}
@media screen and (max-width: @screen-xs) {
.selfTrigger {
display: block;
margin-left: 0;
}
}
@media screen and (max-width: @screen-md) {
.selfTrigger {
display: block;
margin-left: 0;
}
}
@media screen and (max-width: @screen-lg) {
.listItemExtra {
width: 0;
height: 1px;
}
}
src/pages/List/BasicList.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
findDOMNode
}
from
'
react-dom
'
;
import
moment
from
'
moment
'
;
import
{
connect
}
from
'
dva
'
;
import
{
List
,
Card
,
Row
,
Col
,
Radio
,
Input
,
Progress
,
Button
,
Icon
,
Dropdown
,
Menu
,
Avatar
,
Modal
,
Form
,
DatePicker
,
Select
,
}
from
'
antd
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
Result
from
'
ant-design-pro/lib/Result
'
;
import
styles
from
'
./BasicList.less
'
;
const
FormItem
=
Form
.
Item
;
const
RadioButton
=
Radio
.
Button
;
const
RadioGroup
=
Radio
.
Group
;
const
SelectOption
=
Select
.
Option
;
const
{
Search
,
TextArea
}
=
Input
;
@
connect
(({
list
,
loading
})
=>
({
list
,
loading
:
loading
.
models
.
list
,
}))
@
Form
.
create
()
class
BasicList
extends
PureComponent
{
state
=
{
visible
:
false
,
done
:
false
};
formLayout
=
{
labelCol
:
{
span
:
7
},
wrapperCol
:
{
span
:
13
},
};
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
5
,
},
});
}
showModal
=
()
=>
{
this
.
setState
({
visible
:
true
,
current
:
undefined
,
});
};
showEditModal
=
item
=>
{
this
.
setState
({
visible
:
true
,
current
:
item
,
});
};
handleDone
=
()
=>
{
setTimeout
(()
=>
this
.
addBtn
.
blur
(),
0
);
this
.
setState
({
done
:
false
,
visible
:
false
,
});
};
handleCancel
=
()
=>
{
setTimeout
(()
=>
this
.
addBtn
.
blur
(),
0
);
this
.
setState
({
visible
:
false
,
});
};
handleSubmit
=
e
=>
{
e
.
preventDefault
();
const
{
dispatch
,
form
}
=
this
.
props
;
const
{
current
}
=
this
.
state
;
const
id
=
current
?
current
.
id
:
''
;
setTimeout
(()
=>
this
.
addBtn
.
blur
(),
0
);
form
.
validateFields
((
err
,
fieldsValue
)
=>
{
if
(
err
)
return
;
this
.
setState
({
done
:
true
,
});
dispatch
({
type
:
'
list/submit
'
,
payload
:
{
id
,
...
fieldsValue
},
});
});
};
deleteItem
=
id
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/submit
'
,
payload
:
{
id
},
});
};
render
()
{
const
{
list
:
{
list
},
loading
,
}
=
this
.
props
;
const
{
form
:
{
getFieldDecorator
},
}
=
this
.
props
;
const
{
visible
,
done
,
current
=
{}
}
=
this
.
state
;
const
editAndDelete
=
(
key
,
currentItem
)
=>
{
if
(
key
===
'
edit
'
)
this
.
showEditModal
(
currentItem
);
else
if
(
key
===
'
delete
'
)
{
Modal
.
confirm
({
title
:
'
删除任务
'
,
content
:
'
确定删除该任务吗?
'
,
okText
:
'
确认
'
,
cancelText
:
'
取消
'
,
onOk
:
()
=>
this
.
deleteItem
(
currentItem
.
id
),
});
}
};
const
modalFooter
=
done
?
{
footer
:
null
,
onCancel
:
this
.
handleDone
}
:
{
okText
:
'
保存
'
,
onOk
:
this
.
handleSubmit
,
onCancel
:
this
.
handleCancel
};
const
Info
=
({
title
,
value
,
bordered
})
=>
(
<
div
className
=
{
styles
.
headerInfo
}
>
<
span
>
{
title
}
<
/span
>
<
p
>
{
value
}
<
/p
>
{
bordered
&&
<
em
/>
}
<
/div
>
);
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
paginationProps
=
{
showSizeChanger
:
true
,
showQuickJumper
:
true
,
pageSize
:
5
,
total
:
50
,
};
const
ListContent
=
({
data
:
{
owner
,
createdAt
,
percent
,
status
}
})
=>
(
<
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
>
);
const
MoreBtn
=
props
=>
(
<
Dropdown
overlay
=
{
<
Menu
onClick
=
{({
key
})
=>
editAndDelete
(
key
,
props
.
current
)}
>
<
Menu
.
Item
key
=
"
edit
"
>
编辑
<
/Menu.Item
>
<
Menu
.
Item
key
=
"
delete
"
>
删除
<
/Menu.Item
>
<
/Menu
>
}
>
<
a
>
更多
<
Icon
type
=
"
down
"
/>
<
/a
>
<
/Dropdown
>
);
const
getModalContent
=
()
=>
{
if
(
done
)
{
return
(
<
Result
type
=
"
success
"
title
=
"
操作成功
"
description
=
"
一系列的信息描述,很短同样也可以带标点。
"
actions
=
{
<
Button
type
=
"
primary
"
onClick
=
{
this
.
handleDone
}
>
知道了
<
/Button
>
}
className
=
{
styles
.
formResult
}
/
>
);
}
return
(
<
Form
onSubmit
=
{
this
.
handleSubmit
}
>
<
FormItem
label
=
"
任务名称
"
{...
this
.
formLayout
}
>
{
getFieldDecorator
(
'
title
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入任务名称
'
}],
initialValue
:
current
.
title
,
})(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/FormItem
>
<
FormItem
label
=
"
开始时间
"
{...
this
.
formLayout
}
>
{
getFieldDecorator
(
'
createdAt
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择开始时间
'
}],
initialValue
:
current
.
createdAt
?
moment
(
current
.
createdAt
)
:
null
,
})(
<
DatePicker
showTime
placeholder
=
"
请选择
"
format
=
"
YYYY-MM-DD HH:mm:ss
"
style
=
{{
width
:
'
100%
'
}}
/
>
)}
<
/FormItem
>
<
FormItem
label
=
"
任务负责人
"
{...
this
.
formLayout
}
>
{
getFieldDecorator
(
'
owner
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择任务负责人
'
}],
initialValue
:
current
.
owner
,
})(
<
Select
placeholder
=
"
请选择
"
>
<
SelectOption
value
=
"
付晓晓
"
>
付晓晓
<
/SelectOption
>
<
SelectOption
value
=
"
周毛毛
"
>
周毛毛
<
/SelectOption
>
<
/Select
>
)}
<
/FormItem
>
<
FormItem
{...
this
.
formLayout
}
label
=
"
产品描述
"
>
{
getFieldDecorator
(
'
subDescription
'
,
{
rules
:
[{
message
:
'
请输入至少五个字符的产品描述!
'
,
min
:
5
}],
initialValue
:
current
.
subDescription
,
})(
<
TextArea
rows
=
{
4
}
placeholder
=
"
请输入至少五个字符
"
/>
)}
<
/FormItem
>
<
/Form
>
);
};
return
(
<
PageHeaderWrapper
>
<
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
}}
icon
=
"
plus
"
onClick
=
{
this
.
showModal
}
ref
=
{
component
=>
{
/* eslint-disable */
this
.
addBtn
=
findDOMNode
(
component
);
/* eslint-enable */
}}
>
添加
<
/Button
>
<
List
size
=
"
large
"
rowKey
=
"
id
"
loading
=
{
loading
}
pagination
=
{
paginationProps
}
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
actions
=
{[
<
a
onClick
=
{
e
=>
{
e
.
preventDefault
();
this
.
showEditModal
(
item
);
}}
>
编辑
<
/a>
,
<
MoreBtn
current
=
{
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
>
<
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
>
<
/PageHeaderWrapper
>
);
}
}
export
default
BasicList
;
src/pages/List/BasicList.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.standardList {
:global {
.ant-card-head {
border-bottom: none;
}
.ant-card-head-title {
line-height: 32px;
padding: 24px 0;
}
.ant-card-extra {
padding: 24px 0;
}
.ant-list-pagination {
text-align: right;
margin-top: 24px;
}
.ant-avatar-lg {
width: 48px;
height: 48px;
line-height: 48px;
}
}
.headerInfo {
position: relative;
text-align: center;
& > span {
color: @text-color-secondary;
display: inline-block;
font-size: @font-size-base;
line-height: 22px;
margin-bottom: 4px;
}
& > p {
color: @heading-color;
font-size: 24px;
line-height: 32px;
margin: 0;
}
& > em {
background-color: @border-color-split;
position: absolute;
height: 56px;
width: 1px;
top: 0;
right: 0;
}
}
.listContent {
font-size: 0;
.listContentItem {
color: @text-color-secondary;
display: inline-block;
vertical-align: middle;
font-size: @font-size-base;
margin-left: 40px;
> span {
line-height: 20px;
}
> p {
margin-top: 4px;
margin-bottom: 0;
line-height: 22px;
}
}
}
.extraContentSearch {
margin-left: 16px;
width: 272px;
}
}
@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 {
margin-left: 0;
width: 100%;
}
.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 {
padding-top: 4px;
margin-bottom: 32px;
}
}
}
}
.formResult {
width: 100%;
[class^='title'] {
margin-bottom: 8px;
}
}
src/pages/List/CardList.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Card
,
Button
,
Icon
,
List
}
from
'
antd
'
;
import
Ellipsis
from
'
ant-design-pro/lib/Ellipsis
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
./CardList.less
'
;
@
connect
(({
list
,
loading
})
=>
({
list
,
loading
:
loading
.
models
.
list
,
}))
class
CardList
extends
PureComponent
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
8
,
},
});
}
render
()
{
const
{
list
:
{
list
},
loading
,
}
=
this
.
props
;
const
content
=
(
<
div
className
=
{
styles
.
pageHeaderContent
}
>
<
p
>
段落示意
:
蚂蚁金服务设计平台
ant
.
design
,
用最小的工作量
,
无缝接入蚂蚁金服生态
,
提供跨越设计与开发的体验解决方案
。
<
/p
>
<
div
className
=
{
styles
.
contentLink
}
>
<
a
>
<
img
alt
=
""
src
=
"
https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg
"
/>
{
'
'
}
快速开始
<
/a
>
<
a
>
<
img
alt
=
""
src
=
"
https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg
"
/>
{
'
'
}
产品简介
<
/a
>
<
a
>
<
img
alt
=
""
src
=
"
https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg
"
/>
{
'
'
}
产品文档
<
/a
>
<
/div
>
<
/div
>
);
const
extraContent
=
(
<
div
className
=
{
styles
.
extraImg
}
>
<
img
alt
=
"
这是一个标题
"
src
=
"
https://gw.alipayobjects.com/zos/rmsportal/RzwpdLnhmvDJToTdfDPe.png
"
/>
<
/div
>
);
return
(
<
PageHeaderWrapper
title
=
"
卡片列表
"
content
=
{
content
}
extraContent
=
{
extraContent
}
>
<
div
className
=
{
styles
.
cardList
}
>
<
List
rowKey
=
"
id
"
loading
=
{
loading
}
grid
=
{{
gutter
:
24
,
lg
:
3
,
md
:
2
,
sm
:
1
,
xs
:
1
}}
dataSource
=
{[
''
,
...
list
]}
renderItem
=
{
item
=>
item
?
(
<
List
.
Item
key
=
{
item
.
id
}
>
<
Card
hoverable
className
=
{
styles
.
card
}
actions
=
{[
<
a
>
操作一
<
/a>, <a>操作二</
a
>
]}
>
<
Card
.
Meta
avatar
=
{
<
img
alt
=
""
className
=
{
styles
.
cardAvatar
}
src
=
{
item
.
avatar
}
/>
}
title
=
{
<
a
>
{
item
.
title
}
<
/a>
}
description
=
{
<
Ellipsis
className
=
{
styles
.
item
}
lines
=
{
3
}
>
{
item
.
description
}
<
/Ellipsis
>
}
/
>
<
/Card
>
<
/List.Item
>
)
:
(
<
List
.
Item
>
<
Button
type
=
"
dashed
"
className
=
{
styles
.
newButton
}
>
<
Icon
type
=
"
plus
"
/>
新增产品
<
/Button
>
<
/List.Item
>
)
}
/
>
<
/div
>
<
/PageHeaderWrapper
>
);
}
}
export
default
CardList
;
src/pages/List/CardList.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.cardList {
margin-bottom: -24px;
.card {
:global {
.ant-card-meta-title {
margin-bottom: 12px;
& > a {
color: @heading-color;
display: inline-block;
max-width: 100%;
}
}
.ant-card-actions {
background: #f7f9fa;
}
.ant-card-body:hover {
.ant-card-meta-title > a {
color: @primary-color;
}
}
}
}
.item {
height: 64px;
}
:global {
.ant-list .ant-list-item-content-single {
max-width: 100%;
}
}
}
.extraImg {
margin-top: -60px;
text-align: center;
width: 195px;
img {
width: 100%;
}
}
.newButton {
background-color: #fff;
border-color: @border-color-base;
border-radius: @border-radius-sm;
color: @text-color-secondary;
width: 100%;
height: 188px;
}
.cardAvatar {
width: 48px;
height: 48px;
border-radius: 48px;
}
.cardDescription {
.textOverflowMulti();
}
.pageHeaderContent {
position: relative;
}
.contentLink {
margin-top: 16px;
a {
margin-right: 32px;
img {
width: 24px;
}
}
img {
vertical-align: middle;
margin-right: 8px;
}
}
@media screen and (max-width: @screen-lg) {
.contentLink {
a {
margin-right: 16px;
}
}
}
@media screen and (max-width: @screen-md) {
.extraImg {
display: none;
}
}
@media screen and (max-width: @screen-sm) {
.pageHeaderContent {
padding-bottom: 30px;
}
.contentLink {
position: absolute;
left: 0;
bottom: -4px;
width: 1000px;
a {
margin-right: 16px;
}
img {
margin-right: 4px;
}
}
}
src/pages/List/List.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
}
from
'
react
'
;
import
router
from
'
umi/router
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Input
}
from
'
antd
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
@
connect
()
class
SearchList
extends
Component
{
handleTabChange
=
key
=>
{
const
{
match
}
=
this
.
props
;
switch
(
key
)
{
case
'
articles
'
:
router
.
push
(
`
${
match
.
url
}
/articles`
);
break
;
case
'
applications
'
:
router
.
push
(
`
${
match
.
url
}
/applications`
);
break
;
case
'
projects
'
:
router
.
push
(
`
${
match
.
url
}
/projects`
);
break
;
default
:
break
;
}
};
handleFormSubmit
=
value
=>
{
// eslint-disable-next-line
console
.
log
(
value
);
};
render
()
{
const
tabList
=
[
{
key
:
'
articles
'
,
tab
:
'
文章
'
,
},
{
key
:
'
projects
'
,
tab
:
'
项目
'
,
},
{
key
:
'
applications
'
,
tab
:
'
应用
'
,
},
];
const
mainSearch
=
(
<
div
style
=
{{
textAlign
:
'
center
'
}}
>
<
Input
.
Search
placeholder
=
"
请输入
"
enterButton
=
"
搜索
"
size
=
"
large
"
onSearch
=
{
this
.
handleFormSubmit
}
style
=
{{
width
:
522
}}
/
>
<
/div
>
);
const
{
match
,
children
,
location
}
=
this
.
props
;
return
(
<
PageHeaderWrapper
title
=
"
搜索列表
"
content
=
{
mainSearch
}
tabList
=
{
tabList
}
tabActiveKey
=
{
location
.
pathname
.
replace
(
`
${
match
.
path
}
/`
,
''
)}
onTabChange
=
{
this
.
handleTabChange
}
>
{
children
}
{
/* <Switch>
{routes.map(item => (
<Route key={item.key} path={item.path} component={item.component} exact={item.exact} />
))}
</Switch> */
}
<
/PageHeaderWrapper
>
);
}
}
export
default
SearchList
;
src/pages/List/Projects.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
}
from
'
react
'
;
import
moment
from
'
moment
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Row
,
Col
,
Form
,
Card
,
Select
,
List
}
from
'
antd
'
;
import
TagSelect
from
'
ant-design-pro/lib/TagSelect
'
;
import
AvatarList
from
'
ant-design-pro/lib/AvatarList
'
;
import
Ellipsis
from
'
ant-design-pro/lib/Ellipsis
'
;
import
StandardFormRow
from
'
@/components/StandardFormRow
'
;
import
styles
from
'
./Projects.less
'
;
const
{
Option
}
=
Select
;
const
FormItem
=
Form
.
Item
;
/* eslint react/no-array-index-key: 0 */
@
connect
(({
list
,
loading
})
=>
({
list
,
loading
:
loading
.
models
.
list
,
}))
@
Form
.
create
({
onValuesChange
({
dispatch
},
changedValues
,
allValues
)
{
// 表单项变化时请求数据
// eslint-disable-next-line
console
.
log
(
changedValues
,
allValues
);
// 模拟查询表单生效
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
8
,
},
});
},
})
class
CoverCardList
extends
PureComponent
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
list/fetch
'
,
payload
:
{
count
:
8
,
},
});
}
render
()
{
const
{
list
:
{
list
=
[]
},
loading
,
form
,
}
=
this
.
props
;
const
{
getFieldDecorator
}
=
form
;
const
cardList
=
list
?
(
<
List
rowKey
=
"
id
"
loading
=
{
loading
}
grid
=
{{
gutter
:
24
,
xl
:
4
,
lg
:
3
,
md
:
3
,
sm
:
2
,
xs
:
1
}}
dataSource
=
{
list
}
renderItem
=
{
item
=>
(
<
List
.
Item
>
<
Card
className
=
{
styles
.
card
}
hoverable
cover
=
{
<
img
alt
=
{
item
.
title
}
src
=
{
item
.
cover
}
/>
}
>
<
Card
.
Meta
title
=
{
<
a
>
{
item
.
title
}
<
/a>
}
description
=
{
<
Ellipsis
lines
=
{
2
}
>
{
item
.
subDescription
}
<
/Ellipsis>
}
/>
<
div
className
=
{
styles
.
cardItemContent
}
>
<
span
>
{
moment
(
item
.
updatedAt
).
fromNow
()}
<
/span
>
<
div
className
=
{
styles
.
avatarList
}
>
<
AvatarList
size
=
"
mini
"
>
{
item
.
members
.
map
((
member
,
i
)
=>
(
<
AvatarList
.
Item
key
=
{
`
${
item
.
id
}
-avatar-
${
i
}
`
}
src
=
{
member
.
avatar
}
tips
=
{
member
.
name
}
/
>
))}
<
/AvatarList
>
<
/div
>
<
/div
>
<
/Card
>
<
/List.Item
>
)}
/
>
)
:
null
;
const
formItemLayout
=
{
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
16
},
},
};
return
(
<
div
className
=
{
styles
.
coverCardList
}
>
<
Card
bordered
=
{
false
}
>
<
Form
layout
=
"
inline
"
>
<
StandardFormRow
title
=
"
所属类目
"
block
style
=
{{
paddingBottom
:
11
}}
>
<
FormItem
>
{
getFieldDecorator
(
'
category
'
)(
<
TagSelect
expandable
>
<
TagSelect
.
Option
value
=
"
cat1
"
>
类目一
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat2
"
>
类目二
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat3
"
>
类目三
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat4
"
>
类目四
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat5
"
>
类目五
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat6
"
>
类目六
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat7
"
>
类目七
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat8
"
>
类目八
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat9
"
>
类目九
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat10
"
>
类目十
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat11
"
>
类目十一
<
/TagSelect.Option
>
<
TagSelect
.
Option
value
=
"
cat12
"
>
类目十二
<
/TagSelect.Option
>
<
/TagSelect
>
)}
<
/FormItem
>
<
/StandardFormRow
>
<
StandardFormRow
title
=
"
其它选项
"
grid
last
>
<
Row
gutter
=
{
16
}
>
<
Col
lg
=
{
8
}
md
=
{
10
}
sm
=
{
10
}
xs
=
{
24
}
>
<
FormItem
{...
formItemLayout
}
label
=
"
作者
"
>
{
getFieldDecorator
(
'
author
'
,
{})(
<
Select
placeholder
=
"
不限
"
style
=
{{
maxWidth
:
200
,
width
:
'
100%
'
}}
>
<
Option
value
=
"
lisa
"
>
王昭君
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
Col
lg
=
{
8
}
md
=
{
10
}
sm
=
{
10
}
xs
=
{
24
}
>
<
FormItem
{...
formItemLayout
}
label
=
"
好评度
"
>
{
getFieldDecorator
(
'
rate
'
,
{})(
<
Select
placeholder
=
"
不限
"
style
=
{{
maxWidth
:
200
,
width
:
'
100%
'
}}
>
<
Option
value
=
"
good
"
>
优秀
<
/Option
>
<
Option
value
=
"
normal
"
>
普通
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
/Row
>
<
/StandardFormRow
>
<
/Form
>
<
/Card
>
<
div
className
=
{
styles
.
cardList
}
>
{
cardList
}
<
/div
>
<
/div
>
);
}
}
export
default
CoverCardList
;
src/pages/List/Projects.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.coverCardList {
margin-bottom: -24px;
.card {
:global {
.ant-card-meta-title {
margin-bottom: 4px;
& > a {
color: @heading-color;
display: inline-block;
max-width: 100%;
}
}
.ant-card-meta-description {
height: 44px;
line-height: 22px;
overflow: hidden;
}
}
&:hover {
:global {
.ant-card-meta-title > a {
color: @primary-color;
}
}
}
}
.cardItemContent {
display: flex;
margin-top: 16px;
margin-bottom: -4px;
line-height: 20px;
height: 20px;
& > span {
color: @text-color-secondary;
flex: 1;
font-size: 12px;
}
.avatarList {
flex: 0 1 auto;
}
}
.cardList {
margin-top: 24px;
}
:global {
.ant-list .ant-list-item-content-single {
max-width: 100%;
}
}
}
src/pages/List/TableList.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
PureComponent
,
Fragment
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
moment
from
'
moment
'
;
import
{
Row
,
Col
,
Card
,
Form
,
Input
,
Select
,
Icon
,
Button
,
Dropdown
,
Menu
,
InputNumber
,
DatePicker
,
Modal
,
message
,
Badge
,
Divider
,
Steps
,
Radio
,
}
from
'
antd
'
;
import
StandardTable
from
'
@/components/StandardTable
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
./TableList.less
'
;
const
FormItem
=
Form
.
Item
;
const
{
Step
}
=
Steps
;
const
{
TextArea
}
=
Input
;
const
{
Option
}
=
Select
;
const
RadioGroup
=
Radio
.
Group
;
const
getValue
=
obj
=>
Object
.
keys
(
obj
)
.
map
(
key
=>
obj
[
key
])
.
join
(
'
,
'
);
const
statusMap
=
[
'
default
'
,
'
processing
'
,
'
success
'
,
'
error
'
];
const
status
=
[
'
关闭
'
,
'
运行中
'
,
'
已上线
'
,
'
异常
'
];
const
CreateForm
=
Form
.
create
()(
props
=>
{
const
{
modalVisible
,
form
,
handleAdd
,
handleModalVisible
}
=
props
;
const
okHandle
=
()
=>
{
form
.
validateFields
((
err
,
fieldsValue
)
=>
{
if
(
err
)
return
;
form
.
resetFields
();
handleAdd
(
fieldsValue
);
});
};
return
(
<
Modal
destroyOnClose
title
=
"
新建规则
"
visible
=
{
modalVisible
}
onOk
=
{
okHandle
}
onCancel
=
{()
=>
handleModalVisible
()}
>
<
FormItem
labelCol
=
{{
span
:
5
}}
wrapperCol
=
{{
span
:
15
}}
label
=
"
描述
"
>
{
form
.
getFieldDecorator
(
'
desc
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入至少五个字符的规则描述!
'
,
min
:
5
}],
})(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/FormItem
>
<
/Modal
>
);
});
@
Form
.
create
()
class
UpdateForm
extends
PureComponent
{
static
defaultProps
=
{
handleUpdate
:
()
=>
{},
handleUpdateModalVisible
:
()
=>
{},
values
:
{},
};
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
formVals
:
{
name
:
props
.
values
.
name
,
desc
:
props
.
values
.
desc
,
key
:
props
.
values
.
key
,
target
:
'
0
'
,
template
:
'
0
'
,
type
:
'
1
'
,
time
:
''
,
frequency
:
'
month
'
,
},
currentStep
:
0
,
};
this
.
formLayout
=
{
labelCol
:
{
span
:
7
},
wrapperCol
:
{
span
:
13
},
};
}
handleNext
=
currentStep
=>
{
const
{
form
,
handleUpdate
}
=
this
.
props
;
const
{
formVals
:
oldValue
}
=
this
.
state
;
form
.
validateFields
((
err
,
fieldsValue
)
=>
{
if
(
err
)
return
;
const
formVals
=
{
...
oldValue
,
...
fieldsValue
};
this
.
setState
(
{
formVals
,
},
()
=>
{
if
(
currentStep
<
2
)
{
this
.
forward
();
}
else
{
handleUpdate
(
formVals
);
}
}
);
});
};
backward
=
()
=>
{
const
{
currentStep
}
=
this
.
state
;
this
.
setState
({
currentStep
:
currentStep
-
1
,
});
};
forward
=
()
=>
{
const
{
currentStep
}
=
this
.
state
;
this
.
setState
({
currentStep
:
currentStep
+
1
,
});
};
renderContent
=
(
currentStep
,
formVals
)
=>
{
const
{
form
}
=
this
.
props
;
if
(
currentStep
===
1
)
{
return
[
<
FormItem
key
=
"
target
"
{...
this
.
formLayout
}
label
=
"
监控对象
"
>
{
form
.
getFieldDecorator
(
'
target
'
,
{
initialValue
:
formVals
.
target
,
})(
<
Select
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
0
"
>
表一
<
/Option
>
<
Option
value
=
"
1
"
>
表二
<
/Option
>
<
/Select
>
)}
<
/FormItem>
,
<
FormItem
key
=
"
template
"
{...
this
.
formLayout
}
label
=
"
规则模板
"
>
{
form
.
getFieldDecorator
(
'
template
'
,
{
initialValue
:
formVals
.
template
,
})(
<
Select
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
0
"
>
规则模板一
<
/Option
>
<
Option
value
=
"
1
"
>
规则模板二
<
/Option
>
<
/Select
>
)}
<
/FormItem>
,
<
FormItem
key
=
"
type
"
{...
this
.
formLayout
}
label
=
"
规则类型
"
>
{
form
.
getFieldDecorator
(
'
type
'
,
{
initialValue
:
formVals
.
type
,
})(
<
RadioGroup
>
<
Radio
value
=
"
0
"
>
强
<
/Radio
>
<
Radio
value
=
"
1
"
>
弱
<
/Radio
>
<
/RadioGroup
>
)}
<
/FormItem>
,
];
}
if
(
currentStep
===
2
)
{
return
[
<
FormItem
key
=
"
time
"
{...
this
.
formLayout
}
label
=
"
开始时间
"
>
{
form
.
getFieldDecorator
(
'
time
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择开始时间!
'
}],
})(
<
DatePicker
style
=
{{
width
:
'
100%
'
}}
showTime
format
=
"
YYYY-MM-DD HH:mm:ss
"
placeholder
=
"
选择开始时间
"
/>
)}
<
/FormItem>
,
<
FormItem
key
=
"
frequency
"
{...
this
.
formLayout
}
label
=
"
调度周期
"
>
{
form
.
getFieldDecorator
(
'
frequency
'
,
{
initialValue
:
formVals
.
frequency
,
})(
<
Select
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
month
"
>
月
<
/Option
>
<
Option
value
=
"
week
"
>
周
<
/Option
>
<
/Select
>
)}
<
/FormItem>
,
];
}
return
[
<
FormItem
key
=
"
name
"
{...
this
.
formLayout
}
label
=
"
规则名称
"
>
{
form
.
getFieldDecorator
(
'
name
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入规则名称!
'
}],
initialValue
:
formVals
.
name
,
})(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/FormItem>
,
<
FormItem
key
=
"
desc
"
{...
this
.
formLayout
}
label
=
"
规则描述
"
>
{
form
.
getFieldDecorator
(
'
desc
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入至少五个字符的规则描述!
'
,
min
:
5
}],
initialValue
:
formVals
.
desc
,
})(
<
TextArea
rows
=
{
4
}
placeholder
=
"
请输入至少五个字符
"
/>
)}
<
/FormItem>
,
];
};
renderFooter
=
currentStep
=>
{
const
{
handleUpdateModalVisible
,
values
}
=
this
.
props
;
if
(
currentStep
===
1
)
{
return
[
<
Button
key
=
"
back
"
style
=
{{
float
:
'
left
'
}}
onClick
=
{
this
.
backward
}
>
上一步
<
/Button>
,
<
Button
key
=
"
cancel
"
onClick
=
{()
=>
handleUpdateModalVisible
(
false
,
values
)}
>
取消
<
/Button>
,
<
Button
key
=
"
forward
"
type
=
"
primary
"
onClick
=
{()
=>
this
.
handleNext
(
currentStep
)}
>
下一步
<
/Button>
,
];
}
if
(
currentStep
===
2
)
{
return
[
<
Button
key
=
"
back
"
style
=
{{
float
:
'
left
'
}}
onClick
=
{
this
.
backward
}
>
上一步
<
/Button>
,
<
Button
key
=
"
cancel
"
onClick
=
{()
=>
handleUpdateModalVisible
(
false
,
values
)}
>
取消
<
/Button>
,
<
Button
key
=
"
submit
"
type
=
"
primary
"
onClick
=
{()
=>
this
.
handleNext
(
currentStep
)}
>
完成
<
/Button>
,
];
}
return
[
<
Button
key
=
"
cancel
"
onClick
=
{()
=>
handleUpdateModalVisible
(
false
,
values
)}
>
取消
<
/Button>
,
<
Button
key
=
"
forward
"
type
=
"
primary
"
onClick
=
{()
=>
this
.
handleNext
(
currentStep
)}
>
下一步
<
/Button>
,
];
};
render
()
{
const
{
updateModalVisible
,
handleUpdateModalVisible
,
values
}
=
this
.
props
;
const
{
currentStep
,
formVals
}
=
this
.
state
;
return
(
<
Modal
width
=
{
640
}
bodyStyle
=
{{
padding
:
'
32px 40px 48px
'
}}
destroyOnClose
title
=
"
规则配置
"
visible
=
{
updateModalVisible
}
footer
=
{
this
.
renderFooter
(
currentStep
)}
onCancel
=
{()
=>
handleUpdateModalVisible
(
false
,
values
)}
afterClose
=
{()
=>
handleUpdateModalVisible
()}
>
<
Steps
style
=
{{
marginBottom
:
28
}}
size
=
"
small
"
current
=
{
currentStep
}
>
<
Step
title
=
"
基本信息
"
/>
<
Step
title
=
"
配置规则属性
"
/>
<
Step
title
=
"
设定调度周期
"
/>
<
/Steps
>
{
this
.
renderContent
(
currentStep
,
formVals
)}
<
/Modal
>
);
}
}
/* eslint react/no-multi-comp:0 */
@
connect
(({
rule
,
loading
})
=>
({
rule
,
loading
:
loading
.
models
.
rule
,
}))
@
Form
.
create
()
class
TableList
extends
PureComponent
{
state
=
{
modalVisible
:
false
,
updateModalVisible
:
false
,
expandForm
:
false
,
selectedRows
:
[],
formValues
:
{},
stepFormValues
:
{},
};
columns
=
[
{
title
:
'
规则名称
'
,
dataIndex
:
'
name
'
,
},
{
title
:
'
描述
'
,
dataIndex
:
'
desc
'
,
},
{
title
:
'
服务调用次数
'
,
dataIndex
:
'
callNo
'
,
sorter
:
true
,
align
:
'
right
'
,
render
:
val
=>
`
${
val
}
万`
,
// mark to display a total number
needTotal
:
true
,
},
{
title
:
'
状态
'
,
dataIndex
:
'
status
'
,
filters
:
[
{
text
:
status
[
0
],
value
:
0
,
},
{
text
:
status
[
1
],
value
:
1
,
},
{
text
:
status
[
2
],
value
:
2
,
},
{
text
:
status
[
3
],
value
:
3
,
},
],
render
(
val
)
{
return
<
Badge
status
=
{
statusMap
[
val
]}
text
=
{
status
[
val
]}
/>
;
},
},
{
title
:
'
上次调度时间
'
,
dataIndex
:
'
updatedAt
'
,
sorter
:
true
,
render
:
val
=>
<
span
>
{
moment
(
val
).
format
(
'
YYYY-MM-DD HH:mm:ss
'
)}
<
/span>
,
},
{
title
:
'
操作
'
,
render
:
(
text
,
record
)
=>
(
<
Fragment
>
<
a
onClick
=
{()
=>
this
.
handleUpdateModalVisible
(
true
,
record
)}
>
配置
<
/a
>
<
Divider
type
=
"
vertical
"
/>
<
a
href
=
""
>
订阅警报
<
/a
>
<
/Fragment
>
),
},
];
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
rule/fetch
'
,
});
}
handleStandardTableChange
=
(
pagination
,
filtersArg
,
sorter
)
=>
{
const
{
dispatch
}
=
this
.
props
;
const
{
formValues
}
=
this
.
state
;
const
filters
=
Object
.
keys
(
filtersArg
).
reduce
((
obj
,
key
)
=>
{
const
newObj
=
{
...
obj
};
newObj
[
key
]
=
getValue
(
filtersArg
[
key
]);
return
newObj
;
},
{});
const
params
=
{
currentPage
:
pagination
.
current
,
pageSize
:
pagination
.
pageSize
,
...
formValues
,
...
filters
,
};
if
(
sorter
.
field
)
{
params
.
sorter
=
`
${
sorter
.
field
}
_
${
sorter
.
order
}
`
;
}
dispatch
({
type
:
'
rule/fetch
'
,
payload
:
params
,
});
};
handleFormReset
=
()
=>
{
const
{
form
,
dispatch
}
=
this
.
props
;
form
.
resetFields
();
this
.
setState
({
formValues
:
{},
});
dispatch
({
type
:
'
rule/fetch
'
,
payload
:
{},
});
};
toggleForm
=
()
=>
{
const
{
expandForm
}
=
this
.
state
;
this
.
setState
({
expandForm
:
!
expandForm
,
});
};
handleMenuClick
=
e
=>
{
const
{
dispatch
}
=
this
.
props
;
const
{
selectedRows
}
=
this
.
state
;
if
(
selectedRows
.
length
===
0
)
return
;
switch
(
e
.
key
)
{
case
'
remove
'
:
dispatch
({
type
:
'
rule/remove
'
,
payload
:
{
key
:
selectedRows
.
map
(
row
=>
row
.
key
),
},
callback
:
()
=>
{
this
.
setState
({
selectedRows
:
[],
});
},
});
break
;
default
:
break
;
}
};
handleSelectRows
=
rows
=>
{
this
.
setState
({
selectedRows
:
rows
,
});
};
handleSearch
=
e
=>
{
e
.
preventDefault
();
const
{
dispatch
,
form
}
=
this
.
props
;
form
.
validateFields
((
err
,
fieldsValue
)
=>
{
if
(
err
)
return
;
const
values
=
{
...
fieldsValue
,
updatedAt
:
fieldsValue
.
updatedAt
&&
fieldsValue
.
updatedAt
.
valueOf
(),
};
this
.
setState
({
formValues
:
values
,
});
dispatch
({
type
:
'
rule/fetch
'
,
payload
:
values
,
});
});
};
handleModalVisible
=
flag
=>
{
this
.
setState
({
modalVisible
:
!!
flag
,
});
};
handleUpdateModalVisible
=
(
flag
,
record
)
=>
{
this
.
setState
({
updateModalVisible
:
!!
flag
,
stepFormValues
:
record
||
{},
});
};
handleAdd
=
fields
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
rule/add
'
,
payload
:
{
desc
:
fields
.
desc
,
},
});
message
.
success
(
'
添加成功
'
);
this
.
handleModalVisible
();
};
handleUpdate
=
fields
=>
{
const
{
dispatch
}
=
this
.
props
;
const
{
formValues
}
=
this
.
state
;
dispatch
({
type
:
'
rule/update
'
,
payload
:
{
query
:
formValues
,
body
:
{
name
:
fields
.
name
,
desc
:
fields
.
desc
,
key
:
fields
.
key
,
},
},
});
message
.
success
(
'
配置成功
'
);
this
.
handleUpdateModalVisible
();
};
renderSimpleForm
()
{
const
{
form
:
{
getFieldDecorator
},
}
=
this
.
props
;
return
(
<
Form
onSubmit
=
{
this
.
handleSearch
}
layout
=
"
inline
"
>
<
Row
gutter
=
{{
md
:
8
,
lg
:
24
,
xl
:
48
}}
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
规则名称
"
>
{
getFieldDecorator
(
'
name
'
)(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/FormItem
>
<
/Col
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
使用状态
"
>
{
getFieldDecorator
(
'
status
'
)(
<
Select
placeholder
=
"
请选择
"
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
0
"
>
关闭
<
/Option
>
<
Option
value
=
"
1
"
>
运行中
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
span
className
=
{
styles
.
submitButtons
}
>
<
Button
type
=
"
primary
"
htmlType
=
"
submit
"
>
查询
<
/Button
>
<
Button
style
=
{{
marginLeft
:
8
}}
onClick
=
{
this
.
handleFormReset
}
>
重置
<
/Button
>
<
a
style
=
{{
marginLeft
:
8
}}
onClick
=
{
this
.
toggleForm
}
>
展开
<
Icon
type
=
"
down
"
/>
<
/a
>
<
/span
>
<
/Col
>
<
/Row
>
<
/Form
>
);
}
renderAdvancedForm
()
{
const
{
form
:
{
getFieldDecorator
},
}
=
this
.
props
;
return
(
<
Form
onSubmit
=
{
this
.
handleSearch
}
layout
=
"
inline
"
>
<
Row
gutter
=
{{
md
:
8
,
lg
:
24
,
xl
:
48
}}
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
规则名称
"
>
{
getFieldDecorator
(
'
name
'
)(
<
Input
placeholder
=
"
请输入
"
/>
)}
<
/FormItem
>
<
/Col
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
使用状态
"
>
{
getFieldDecorator
(
'
status
'
)(
<
Select
placeholder
=
"
请选择
"
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
0
"
>
关闭
<
/Option
>
<
Option
value
=
"
1
"
>
运行中
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
调用次数
"
>
{
getFieldDecorator
(
'
number
'
)(
<
InputNumber
style
=
{{
width
:
'
100%
'
}}
/>
)
}
<
/FormItem
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{{
md
:
8
,
lg
:
24
,
xl
:
48
}}
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
更新日期
"
>
{
getFieldDecorator
(
'
date
'
)(
<
DatePicker
style
=
{{
width
:
'
100%
'
}}
placeholder
=
"
请输入更新日期
"
/>
)}
<
/FormItem
>
<
/Col
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
使用状态
"
>
{
getFieldDecorator
(
'
status3
'
)(
<
Select
placeholder
=
"
请选择
"
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
0
"
>
关闭
<
/Option
>
<
Option
value
=
"
1
"
>
运行中
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
Col
md
=
{
8
}
sm
=
{
24
}
>
<
FormItem
label
=
"
使用状态
"
>
{
getFieldDecorator
(
'
status4
'
)(
<
Select
placeholder
=
"
请选择
"
style
=
{{
width
:
'
100%
'
}}
>
<
Option
value
=
"
0
"
>
关闭
<
/Option
>
<
Option
value
=
"
1
"
>
运行中
<
/Option
>
<
/Select
>
)}
<
/FormItem
>
<
/Col
>
<
/Row
>
<
div
style
=
{{
overflow
:
'
hidden
'
}}
>
<
div
style
=
{{
float
:
'
right
'
,
marginBottom
:
24
}}
>
<
Button
type
=
"
primary
"
htmlType
=
"
submit
"
>
查询
<
/Button
>
<
Button
style
=
{{
marginLeft
:
8
}}
onClick
=
{
this
.
handleFormReset
}
>
重置
<
/Button
>
<
a
style
=
{{
marginLeft
:
8
}}
onClick
=
{
this
.
toggleForm
}
>
收起
<
Icon
type
=
"
up
"
/>
<
/a
>
<
/div
>
<
/div
>
<
/Form
>
);
}
renderForm
()
{
const
{
expandForm
}
=
this
.
state
;
return
expandForm
?
this
.
renderAdvancedForm
()
:
this
.
renderSimpleForm
();
}
render
()
{
const
{
rule
:
{
data
},
loading
,
}
=
this
.
props
;
const
{
selectedRows
,
modalVisible
,
updateModalVisible
,
stepFormValues
}
=
this
.
state
;
const
menu
=
(
<
Menu
onClick
=
{
this
.
handleMenuClick
}
selectedKeys
=
{[]}
>
<
Menu
.
Item
key
=
"
remove
"
>
删除
<
/Menu.Item
>
<
Menu
.
Item
key
=
"
approval
"
>
批量审批
<
/Menu.Item
>
<
/Menu
>
);
const
parentMethods
=
{
handleAdd
:
this
.
handleAdd
,
handleModalVisible
:
this
.
handleModalVisible
,
};
const
updateMethods
=
{
handleUpdateModalVisible
:
this
.
handleUpdateModalVisible
,
handleUpdate
:
this
.
handleUpdate
,
};
return
(
<
PageHeaderWrapper
title
=
"
查询表格
"
>
<
Card
bordered
=
{
false
}
>
<
div
className
=
{
styles
.
tableList
}
>
<
div
className
=
{
styles
.
tableListForm
}
>
{
this
.
renderForm
()}
<
/div
>
<
div
className
=
{
styles
.
tableListOperator
}
>
<
Button
icon
=
"
plus
"
type
=
"
primary
"
onClick
=
{()
=>
this
.
handleModalVisible
(
true
)}
>
新建
<
/Button
>
{
selectedRows
.
length
>
0
&&
(
<
span
>
<
Button
>
批量操作
<
/Button
>
<
Dropdown
overlay
=
{
menu
}
>
<
Button
>
更多操作
<
Icon
type
=
"
down
"
/>
<
/Button
>
<
/Dropdown
>
<
/span
>
)}
<
/div
>
<
StandardTable
selectedRows
=
{
selectedRows
}
loading
=
{
loading
}
data
=
{
data
}
columns
=
{
this
.
columns
}
onSelectRow
=
{
this
.
handleSelectRows
}
onChange
=
{
this
.
handleStandardTableChange
}
/
>
<
/div
>
<
/Card
>
<
CreateForm
{...
parentMethods
}
modalVisible
=
{
modalVisible
}
/
>
{
stepFormValues
&&
Object
.
keys
(
stepFormValues
).
length
?
(
<
UpdateForm
{...
updateMethods
}
updateModalVisible
=
{
updateModalVisible
}
values
=
{
stepFormValues
}
/
>
)
:
null
}
<
/PageHeaderWrapper
>
);
}
}
export
default
TableList
;
src/pages/List/TableList.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.tableList {
.tableListOperator {
margin-bottom: 16px;
button {
margin-right: 8px;
}
}
}
.tableListForm {
:global {
.ant-form-item {
margin-bottom: 24px;
margin-right: 0;
display: flex;
> .ant-form-item-label {
width: auto;
line-height: 32px;
padding-right: 8px;
}
.ant-form-item-control {
line-height: 32px;
}
}
.ant-form-item-control-wrapper {
flex: 1;
}
}
.submitButtons {
display: block;
white-space: nowrap;
margin-bottom: 24px;
}
}
@media screen and (max-width: @screen-lg) {
.tableListForm :global(.ant-form-item) {
margin-right: 24px;
}
}
@media screen and (max-width: @screen-md) {
.tableListForm :global(.ant-form-item) {
margin-right: 8px;
}
}
src/pages/List/models/rule.js
deleted
100644 → 0
View file @
5ba67a51
import
{
queryRule
,
removeRule
,
addRule
,
updateRule
}
from
'
@/services/api
'
;
export
default
{
namespace
:
'
rule
'
,
state
:
{
data
:
{
list
:
[],
pagination
:
{},
},
},
effects
:
{
*
fetch
({
payload
},
{
call
,
put
})
{
const
response
=
yield
call
(
queryRule
,
payload
);
yield
put
({
type
:
'
save
'
,
payload
:
response
,
});
},
*
add
({
payload
,
callback
},
{
call
,
put
})
{
const
response
=
yield
call
(
addRule
,
payload
);
yield
put
({
type
:
'
save
'
,
payload
:
response
,
});
if
(
callback
)
callback
();
},
*
remove
({
payload
,
callback
},
{
call
,
put
})
{
const
response
=
yield
call
(
removeRule
,
payload
);
yield
put
({
type
:
'
save
'
,
payload
:
response
,
});
if
(
callback
)
callback
();
},
*
update
({
payload
,
callback
},
{
call
,
put
})
{
const
response
=
yield
call
(
updateRule
,
payload
);
yield
put
({
type
:
'
save
'
,
payload
:
response
,
});
if
(
callback
)
callback
();
},
},
reducers
:
{
save
(
state
,
action
)
{
return
{
...
state
,
data
:
action
.
payload
,
};
},
},
};
src/pages/Profile/AdvancedProfile.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
,
Fragment
}
from
'
react
'
;
import
Debounce
from
'
lodash-decorators/debounce
'
;
import
Bind
from
'
lodash-decorators/bind
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Button
,
Menu
,
Dropdown
,
Icon
,
Row
,
Col
,
Steps
,
Card
,
Popover
,
Badge
,
Table
,
Tooltip
,
Divider
,
}
from
'
antd
'
;
import
classNames
from
'
classnames
'
;
import
DescriptionList
from
'
ant-design-pro/lib/DescriptionList
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
./AdvancedProfile.less
'
;
const
{
Step
}
=
Steps
;
const
{
Description
}
=
DescriptionList
;
const
ButtonGroup
=
Button
.
Group
;
const
getWindowWidth
=
()
=>
window
.
innerWidth
||
document
.
documentElement
.
clientWidth
;
const
menu
=
(
<
Menu
>
<
Menu
.
Item
key
=
"
1
"
>
选项一
<
/Menu.Item
>
<
Menu
.
Item
key
=
"
2
"
>
选项二
<
/Menu.Item
>
<
Menu
.
Item
key
=
"
3
"
>
选项三
<
/Menu.Item
>
<
/Menu
>
);
const
action
=
(
<
Fragment
>
<
ButtonGroup
>
<
Button
>
操作
<
/Button
>
<
Button
>
操作
<
/Button
>
<
Dropdown
overlay
=
{
menu
}
placement
=
"
bottomRight
"
>
<
Button
>
<
Icon
type
=
"
ellipsis
"
/>
<
/Button
>
<
/Dropdown
>
<
/ButtonGroup
>
<
Button
type
=
"
primary
"
>
主操作
<
/Button
>
<
/Fragment
>
);
const
extra
=
(
<
Row
>
<
Col
xs
=
{
24
}
sm
=
{
12
}
>
<
div
className
=
{
styles
.
textSecondary
}
>
状态
<
/div
>
<
div
className
=
{
styles
.
heading
}
>
待审批
<
/div
>
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
12
}
>
<
div
className
=
{
styles
.
textSecondary
}
>
订单金额
<
/div
>
<
div
className
=
{
styles
.
heading
}
>
¥
568.08
<
/div
>
<
/Col
>
<
/Row
>
);
const
description
=
(
<
DescriptionList
className
=
{
styles
.
headerList
}
size
=
"
small
"
col
=
"
2
"
>
<
Description
term
=
"
创建人
"
>
曲丽丽
<
/Description
>
<
Description
term
=
"
订购产品
"
>
XX
服务
<
/Description
>
<
Description
term
=
"
创建时间
"
>
2017
-
07
-
07
<
/Description
>
<
Description
term
=
"
关联单据
"
>
<
a
href
=
""
>
12421
<
/a
>
<
/Description
>
<
Description
term
=
"
生效日期
"
>
2017
-
07
-
07
~
2017
-
08
-
08
<
/Description
>
<
Description
term
=
"
备注
"
>
请于两个工作日内确认
<
/Description
>
<
/DescriptionList
>
);
const
tabList
=
[
{
key
:
'
detail
'
,
tab
:
'
详情
'
,
},
{
key
:
'
rule
'
,
tab
:
'
规则
'
,
},
];
const
desc1
=
(
<
div
className
=
{
classNames
(
styles
.
textSecondary
,
styles
.
stepDescription
)}
>
<
Fragment
>
曲丽丽
<
Icon
type
=
"
dingding-o
"
style
=
{{
marginLeft
:
8
}}
/
>
<
/Fragment
>
<
div
>
2016
-
12
-
12
12
:
32
<
/div
>
<
/div
>
);
const
desc2
=
(
<
div
className
=
{
styles
.
stepDescription
}
>
<
Fragment
>
周毛毛
<
Icon
type
=
"
dingding-o
"
style
=
{{
color
:
'
#00A0E9
'
,
marginLeft
:
8
}}
/
>
<
/Fragment
>
<
div
>
<
a
href
=
""
>
催一下
<
/a
>
<
/div
>
<
/div
>
);
const
popoverContent
=
(
<
div
style
=
{{
width
:
160
}}
>
吴加号
<
span
className
=
{
styles
.
textSecondary
}
style
=
{{
float
:
'
right
'
}}
>
<
Badge
status
=
"
default
"
text
=
{
<
span
style
=
{{
color
:
'
rgba(0, 0, 0, 0.45)
'
}}
>
未响应
<
/span>} /
>
<
/span
>
<
div
className
=
{
styles
.
textSecondary
}
style
=
{{
marginTop
:
4
}}
>
耗时
:
2
小时25分钟
<
/div
>
<
/div
>
);
const
customDot
=
(
dot
,
{
status
})
=>
status
===
'
process
'
?
(
<
Popover
placement
=
"
topLeft
"
arrowPointAtCenter
content
=
{
popoverContent
}
>
{
dot
}
<
/Popover
>
)
:
(
dot
);
const
operationTabList
=
[
{
key
:
'
tab1
'
,
tab
:
'
操作日志一
'
,
},
{
key
:
'
tab2
'
,
tab
:
'
操作日志二
'
,
},
{
key
:
'
tab3
'
,
tab
:
'
操作日志三
'
,
},
];
const
columns
=
[
{
title
:
'
操作类型
'
,
dataIndex
:
'
type
'
,
key
:
'
type
'
,
},
{
title
:
'
操作人
'
,
dataIndex
:
'
name
'
,
key
:
'
name
'
,
},
{
title
:
'
执行结果
'
,
dataIndex
:
'
status
'
,
key
:
'
status
'
,
render
:
text
=>
text
===
'
agree
'
?
(
<
Badge
status
=
"
success
"
text
=
"
成功
"
/>
)
:
(
<
Badge
status
=
"
error
"
text
=
"
驳回
"
/>
),
},
{
title
:
'
操作时间
'
,
dataIndex
:
'
updatedAt
'
,
key
:
'
updatedAt
'
,
},
{
title
:
'
备注
'
,
dataIndex
:
'
memo
'
,
key
:
'
memo
'
,
},
];
@
connect
(({
profile
,
loading
})
=>
({
profile
,
loading
:
loading
.
effects
[
'
profile/fetchAdvanced
'
],
}))
class
AdvancedProfile
extends
Component
{
state
=
{
operationkey
:
'
tab1
'
,
stepDirection
:
'
horizontal
'
,
};
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
profile/fetchAdvanced
'
,
});
this
.
setStepDirection
();
window
.
addEventListener
(
'
resize
'
,
this
.
setStepDirection
,
{
passive
:
true
});
}
componentWillUnmount
()
{
window
.
removeEventListener
(
'
resize
'
,
this
.
setStepDirection
);
this
.
setStepDirection
.
cancel
();
}
onOperationTabChange
=
key
=>
{
this
.
setState
({
operationkey
:
key
});
};
@
Bind
()
@
Debounce
(
200
)
setStepDirection
()
{
const
{
stepDirection
}
=
this
.
state
;
const
w
=
getWindowWidth
();
if
(
stepDirection
!==
'
vertical
'
&&
w
<=
576
)
{
this
.
setState
({
stepDirection
:
'
vertical
'
,
});
}
else
if
(
stepDirection
!==
'
horizontal
'
&&
w
>
576
)
{
this
.
setState
({
stepDirection
:
'
horizontal
'
,
});
}
}
render
()
{
const
{
stepDirection
,
operationkey
}
=
this
.
state
;
const
{
profile
,
loading
}
=
this
.
props
;
const
{
advancedOperation1
,
advancedOperation2
,
advancedOperation3
}
=
profile
;
const
contentList
=
{
tab1
:
(
<
Table
pagination
=
{
false
}
loading
=
{
loading
}
dataSource
=
{
advancedOperation1
}
columns
=
{
columns
}
/
>
),
tab2
:
(
<
Table
pagination
=
{
false
}
loading
=
{
loading
}
dataSource
=
{
advancedOperation2
}
columns
=
{
columns
}
/
>
),
tab3
:
(
<
Table
pagination
=
{
false
}
loading
=
{
loading
}
dataSource
=
{
advancedOperation3
}
columns
=
{
columns
}
/
>
),
};
return
(
<
PageHeaderWrapper
title
=
"
单号:234231029431
"
logo
=
{
<
img
alt
=
""
src
=
"
https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png
"
/>
}
action
=
{
action
}
content
=
{
description
}
extraContent
=
{
extra
}
tabList
=
{
tabList
}
>
<
Card
title
=
"
流程进度
"
style
=
{{
marginBottom
:
24
}}
bordered
=
{
false
}
>
<
Steps
direction
=
{
stepDirection
}
progressDot
=
{
customDot
}
current
=
{
1
}
>
<
Step
title
=
"
创建项目
"
description
=
{
desc1
}
/
>
<
Step
title
=
"
部门初审
"
description
=
{
desc2
}
/
>
<
Step
title
=
"
财务复核
"
/>
<
Step
title
=
"
完成
"
/>
<
/Steps
>
<
/Card
>
<
Card
title
=
"
用户信息
"
style
=
{{
marginBottom
:
24
}}
bordered
=
{
false
}
>
<
DescriptionList
style
=
{{
marginBottom
:
24
}}
>
<
Description
term
=
"
用户姓名
"
>
付小小
<
/Description
>
<
Description
term
=
"
会员卡号
"
>
32943898021309809423
<
/Description
>
<
Description
term
=
"
身份证
"
>
3321944288191034921
<
/Description
>
<
Description
term
=
"
联系方式
"
>
18112345678
<
/Description
>
<
Description
term
=
"
联系地址
"
>
曲丽丽
18100000000
浙江省杭州市西湖区黄姑山路工专路交叉路口
<
/Description
>
<
/DescriptionList
>
<
DescriptionList
style
=
{{
marginBottom
:
24
}}
title
=
"
信息组
"
>
<
Description
term
=
"
某某数据
"
>
725
<
/Description
>
<
Description
term
=
"
该数据更新时间
"
>
2017
-
08
-
08
<
/Description
>
<
Description
>&
nbsp
;
<
/Description
>
<
Description
term
=
{
<
span
>
某某数据
<
Tooltip
title
=
"
数据说明
"
>
<
Icon
style
=
{{
color
:
'
rgba(0, 0, 0, 0.43)
'
,
marginLeft
:
4
}}
type
=
"
info-circle-o
"
/>
<
/Tooltip
>
<
/span
>
}
>
725
<
/Description
>
<
Description
term
=
"
该数据更新时间
"
>
2017
-
08
-
08
<
/Description
>
<
/DescriptionList
>
<
h4
style
=
{{
marginBottom
:
16
}}
>
信息组
<
/h4
>
<
Card
type
=
"
inner
"
title
=
"
多层级信息组
"
>
<
DescriptionList
size
=
"
small
"
style
=
{{
marginBottom
:
16
}}
title
=
"
组名称
"
>
<
Description
term
=
"
负责人
"
>
林东东
<
/Description
>
<
Description
term
=
"
角色码
"
>
1234567
<
/Description
>
<
Description
term
=
"
所属部门
"
>
XX公司
-
YY部
<
/Description
>
<
Description
term
=
"
过期时间
"
>
2017
-
08
-
08
<
/Description
>
<
Description
term
=
"
描述
"
>
这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长
...
<
/Description
>
<
/DescriptionList
>
<
Divider
style
=
{{
margin
:
'
16px 0
'
}}
/
>
<
DescriptionList
size
=
"
small
"
style
=
{{
marginBottom
:
16
}}
title
=
"
组名称
"
col
=
"
1
"
>
<
Description
term
=
"
学名
"
>
Citrullus
lanatus
(
Thunb
.)
Matsum
.
et
Nakai一年生蔓生藤本
;
茎
、
枝粗壮
,
具明显的棱
。
卷须较粗
..
<
/Description
>
<
/DescriptionList
>
<
Divider
style
=
{{
margin
:
'
16px 0
'
}}
/
>
<
DescriptionList
size
=
"
small
"
title
=
"
组名称
"
>
<
Description
term
=
"
负责人
"
>
付小小
<
/Description
>
<
Description
term
=
"
角色码
"
>
1234568
<
/Description
>
<
/DescriptionList
>
<
/Card
>
<
/Card
>
<
Card
title
=
"
用户近半年来电记录
"
style
=
{{
marginBottom
:
24
}}
bordered
=
{
false
}
>
<
div
className
=
{
styles
.
noData
}
>
<
Icon
type
=
"
frown-o
"
/>
暂无数据
<
/div
>
<
/Card
>
<
Card
className
=
{
styles
.
tabsCard
}
bordered
=
{
false
}
tabList
=
{
operationTabList
}
onTabChange
=
{
this
.
onOperationTabChange
}
>
{
contentList
[
operationkey
]}
<
/Card
>
<
/PageHeaderWrapper
>
);
}
}
export
default
AdvancedProfile
;
src/pages/Profile/AdvancedProfile.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.headerList {
margin-bottom: 4px;
}
.tabsCard {
:global {
.ant-card-head {
padding: 0 16px;
}
}
}
.noData {
color: @disabled-color;
text-align: center;
line-height: 64px;
font-size: 16px;
i {
font-size: 24px;
margin-right: 16px;
position: relative;
top: 3px;
}
}
.heading {
color: @heading-color;
font-size: 20px;
}
.stepDescription {
font-size: 14px;
position: relative;
left: 38px;
padding-top: 8px;
text-align: left;
> div {
margin-top: 8px;
margin-bottom: 4px;
}
}
.textSecondary {
color: @text-color-secondary;
}
@media screen and (max-width: @screen-sm) {
.stepDescription {
left: 8px;
}
}
src/pages/Profile/BasicProfile.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Card
,
Badge
,
Table
,
Divider
}
from
'
antd
'
;
import
DescriptionList
from
'
ant-design-pro/lib/DescriptionList
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
import
styles
from
'
./BasicProfile.less
'
;
const
{
Description
}
=
DescriptionList
;
const
progressColumns
=
[
{
title
:
'
时间
'
,
dataIndex
:
'
time
'
,
key
:
'
time
'
,
},
{
title
:
'
当前进度
'
,
dataIndex
:
'
rate
'
,
key
:
'
rate
'
,
},
{
title
:
'
状态
'
,
dataIndex
:
'
status
'
,
key
:
'
status
'
,
render
:
text
=>
text
===
'
success
'
?
(
<
Badge
status
=
"
success
"
text
=
"
成功
"
/>
)
:
(
<
Badge
status
=
"
processing
"
text
=
"
进行中
"
/>
),
},
{
title
:
'
操作员ID
'
,
dataIndex
:
'
operator
'
,
key
:
'
operator
'
,
},
{
title
:
'
耗时
'
,
dataIndex
:
'
cost
'
,
key
:
'
cost
'
,
},
];
@
connect
(({
profile
,
loading
})
=>
({
profile
,
loading
:
loading
.
effects
[
'
profile/fetchBasic
'
],
}))
class
BasicProfile
extends
Component
{
componentDidMount
()
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
profile/fetchBasic
'
,
});
}
render
()
{
const
{
profile
,
loading
}
=
this
.
props
;
const
{
basicGoods
,
basicProgress
}
=
profile
;
let
goodsData
=
[];
if
(
basicGoods
.
length
)
{
let
num
=
0
;
let
amount
=
0
;
basicGoods
.
forEach
(
item
=>
{
num
+=
Number
(
item
.
num
);
amount
+=
Number
(
item
.
amount
);
});
goodsData
=
basicGoods
.
concat
({
id
:
'
总计
'
,
num
,
amount
,
});
}
const
renderContent
=
(
value
,
row
,
index
)
=>
{
const
obj
=
{
children
:
value
,
props
:
{},
};
if
(
index
===
basicGoods
.
length
)
{
obj
.
props
.
colSpan
=
0
;
}
return
obj
;
};
const
goodsColumns
=
[
{
title
:
'
商品编号
'
,
dataIndex
:
'
id
'
,
key
:
'
id
'
,
render
:
(
text
,
row
,
index
)
=>
{
if
(
index
<
basicGoods
.
length
)
{
return
<
a
href
=
""
>
{
text
}
<
/a>
;
}
return
{
children
:
<
span
style
=
{{
fontWeight
:
600
}}
>
总计
<
/span>
,
props
:
{
colSpan
:
4
,
},
};
},
},
{
title
:
'
商品名称
'
,
dataIndex
:
'
name
'
,
key
:
'
name
'
,
render
:
renderContent
,
},
{
title
:
'
商品条码
'
,
dataIndex
:
'
barcode
'
,
key
:
'
barcode
'
,
render
:
renderContent
,
},
{
title
:
'
单价
'
,
dataIndex
:
'
price
'
,
key
:
'
price
'
,
align
:
'
right
'
,
render
:
renderContent
,
},
{
title
:
'
数量(件)
'
,
dataIndex
:
'
num
'
,
key
:
'
num
'
,
align
:
'
right
'
,
render
:
(
text
,
row
,
index
)
=>
{
if
(
index
<
basicGoods
.
length
)
{
return
text
;
}
return
<
span
style
=
{{
fontWeight
:
600
}}
>
{
text
}
<
/span>
;
},
},
{
title
:
'
金额
'
,
dataIndex
:
'
amount
'
,
key
:
'
amount
'
,
align
:
'
right
'
,
render
:
(
text
,
row
,
index
)
=>
{
if
(
index
<
basicGoods
.
length
)
{
return
text
;
}
return
<
span
style
=
{{
fontWeight
:
600
}}
>
{
text
}
<
/span>
;
},
},
];
return
(
<
PageHeaderWrapper
title
=
"
基础详情页
"
>
<
Card
bordered
=
{
false
}
>
<
DescriptionList
size
=
"
large
"
title
=
"
退款申请
"
style
=
{{
marginBottom
:
32
}}
>
<
Description
term
=
"
取货单号
"
>
1000000000
<
/Description
>
<
Description
term
=
"
状态
"
>
已取货
<
/Description
>
<
Description
term
=
"
销售单号
"
>
1234123421
<
/Description
>
<
Description
term
=
"
子订单
"
>
3214321432
<
/Description
>
<
/DescriptionList
>
<
Divider
style
=
{{
marginBottom
:
32
}}
/
>
<
DescriptionList
size
=
"
large
"
title
=
"
用户信息
"
style
=
{{
marginBottom
:
32
}}
>
<
Description
term
=
"
用户姓名
"
>
付小小
<
/Description
>
<
Description
term
=
"
联系电话
"
>
18100000000
<
/Description
>
<
Description
term
=
"
常用快递
"
>
菜鸟仓储
<
/Description
>
<
Description
term
=
"
取货地址
"
>
浙江省杭州市西湖区万塘路18号
<
/Description
>
<
Description
term
=
"
备注
"
>
无
<
/Description
>
<
/DescriptionList
>
<
Divider
style
=
{{
marginBottom
:
32
}}
/
>
<
div
className
=
{
styles
.
title
}
>
退货商品
<
/div
>
<
Table
style
=
{{
marginBottom
:
24
}}
pagination
=
{
false
}
loading
=
{
loading
}
dataSource
=
{
goodsData
}
columns
=
{
goodsColumns
}
rowKey
=
"
id
"
/>
<
div
className
=
{
styles
.
title
}
>
退货进度
<
/div
>
<
Table
style
=
{{
marginBottom
:
16
}}
pagination
=
{
false
}
loading
=
{
loading
}
dataSource
=
{
basicProgress
}
columns
=
{
progressColumns
}
/
>
<
/Card
>
<
/PageHeaderWrapper
>
);
}
}
export
default
BasicProfile
;
src/pages/Profile/BasicProfile.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.title {
color: @heading-color;
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
}
src/pages/Profile/models/profile.js
deleted
100644 → 0
View file @
5ba67a51
import
{
queryBasicProfile
,
queryAdvancedProfile
}
from
'
@/services/api
'
;
export
default
{
namespace
:
'
profile
'
,
state
:
{
basicGoods
:
[],
advancedOperation1
:
[],
advancedOperation2
:
[],
advancedOperation3
:
[],
},
effects
:
{
*
fetchBasic
(
_
,
{
call
,
put
})
{
const
response
=
yield
call
(
queryBasicProfile
);
yield
put
({
type
:
'
show
'
,
payload
:
response
,
});
},
*
fetchAdvanced
(
_
,
{
call
,
put
})
{
const
response
=
yield
call
(
queryAdvancedProfile
);
yield
put
({
type
:
'
show
'
,
payload
:
response
,
});
},
},
reducers
:
{
show
(
state
,
{
payload
})
{
return
{
...
state
,
...
payload
,
};
},
},
};
src/pages/Result/Error.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Fragment
}
from
'
react
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Button
,
Icon
,
Card
}
from
'
antd
'
;
import
Result
from
'
ant-design-pro/lib/Result
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
const
extra
=
(
<
Fragment
>
<
div
style
=
{{
fontSize
:
16
,
color
:
'
rgba(0, 0, 0, 0.85)
'
,
fontWeight
:
'
500
'
,
marginBottom
:
16
,
}}
>
<
FormattedMessage
id
=
"
app.result.error.hint-title
"
defaultMessage
=
"
The content you submitted has the following error:
"
/>
<
/div
>
<
div
style
=
{{
marginBottom
:
16
}}
>
<
Icon
style
=
{{
color
:
'
#f5222d
'
,
marginRight
:
8
}}
type
=
"
close-circle-o
"
/>
<
FormattedMessage
id
=
"
app.result.error.hint-text1
"
defaultMessage
=
"
Your account has been frozen
"
/>
<
a
style
=
{{
marginLeft
:
16
}}
>
<
FormattedMessage
id
=
"
app.result.error.hint-btn1
"
defaultMessage
=
"
Thaw immediately
"
/>
<
Icon
type
=
"
right
"
/>
<
/a
>
<
/div
>
<
div
>
<
Icon
style
=
{{
color
:
'
#f5222d
'
,
marginRight
:
8
}}
type
=
"
close-circle-o
"
/>
<
FormattedMessage
id
=
"
app.result.error.hint-text2
"
defaultMessage
=
"
Your account is not yet eligible to apply
"
/>
<
a
style
=
{{
marginLeft
:
16
}}
>
<
FormattedMessage
id
=
"
app.result.error.hint-btn2
"
defaultMessage
=
"
Upgrade immediately
"
/>
<
Icon
type
=
"
right
"
/>
<
/a
>
<
/div
>
<
/Fragment
>
);
const
actions
=
(
<
Button
type
=
"
primary
"
>
<
FormattedMessage
id
=
"
app.result.error.btn-text
"
defaultMessage
=
"
Return to modify
"
/>
<
/Button
>
);
export
default
()
=>
(
<
PageHeaderWrapper
>
<
Card
bordered
=
{
false
}
>
<
Result
type
=
"
error
"
title
=
{
formatMessage
({
id
:
'
app.result.error.title
'
})}
description
=
{
formatMessage
({
id
:
'
app.result.error.description
'
})}
extra
=
{
extra
}
actions
=
{
actions
}
style
=
{{
marginTop
:
48
,
marginBottom
:
16
}}
/
>
<
/Card
>
<
/PageHeaderWrapper
>
);
src/pages/Result/Success.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Fragment
}
from
'
react
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Button
,
Row
,
Col
,
Icon
,
Steps
,
Card
}
from
'
antd
'
;
import
Result
from
'
ant-design-pro/lib/Result
'
;
import
PageHeaderWrapper
from
'
@/components/PageHeaderWrapper
'
;
const
{
Step
}
=
Steps
;
const
desc1
=
(
<
div
style
=
{{
fontSize
:
12
,
color
:
'
rgba(0, 0, 0, 0.45)
'
,
position
:
'
relative
'
,
left
:
42
,
textAlign
:
'
left
'
,
}}
>
<
div
style
=
{{
margin
:
'
8px 0 4px
'
}}
>
<
FormattedMessage
id
=
"
app.result.success.step1-operator
"
defaultMessage
=
"
Qu Lili
"
/>
<
Icon
style
=
{{
marginLeft
:
8
}}
type
=
"
dingding-o
"
/>
<
/div
>
<
div
>
2016
-
12
-
12
12
:
32
<
/div
>
<
/div
>
);
const
desc2
=
(
<
div
style
=
{{
fontSize
:
12
,
position
:
'
relative
'
,
left
:
42
,
textAlign
:
'
left
'
}}
>
<
div
style
=
{{
margin
:
'
8px 0 4px
'
}}
>
<
FormattedMessage
id
=
"
app.result.success.step2-operator
"
defaultMessage
=
"
Zhou Maomao
"
/>
<
Icon
type
=
"
dingding-o
"
style
=
{{
color
:
'
#00A0E9
'
,
marginLeft
:
8
}}
/
>
<
/div
>
<
div
>
<
a
href
=
""
>
<
FormattedMessage
id
=
"
app.result.success.step2-extra
"
defaultMessage
=
"
Urge
"
/>
<
/a
>
<
/div
>
<
/div
>
);
const
extra
=
(
<
Fragment
>
<
div
style
=
{{
fontSize
:
16
,
color
:
'
rgba(0, 0, 0, 0.85)
'
,
fontWeight
:
'
500
'
,
marginBottom
:
20
,
}}
>
<
FormattedMessage
id
=
"
app.result.success.operate-title
"
defaultMessage
=
"
Project Name
"
/>
<
/div
>
<
Row
style
=
{{
marginBottom
:
16
}}
>
<
Col
xs
=
{
24
}
sm
=
{
12
}
md
=
{
12
}
lg
=
{
12
}
xl
=
{
6
}
>
<
span
style
=
{{
color
:
'
rgba(0, 0, 0, 0.85)
'
}}
>
<
FormattedMessage
id
=
"
app.result.success.operate-id
"
defaultMessage
=
"
Project ID:
"
/>
<
/span
>
23421
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
12
}
md
=
{
12
}
lg
=
{
12
}
xl
=
{
6
}
>
<
span
style
=
{{
color
:
'
rgba(0, 0, 0, 0.85)
'
}}
>
<
FormattedMessage
id
=
"
app.result.success.principal
"
defaultMessage
=
"
Principal:
"
/>
<
/span
>
<
FormattedMessage
id
=
"
app.result.success.step1-operator
"
defaultMessage
=
"
Qu Lili
"
/>
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
24
}
md
=
{
24
}
lg
=
{
24
}
xl
=
{
12
}
>
<
span
style
=
{{
color
:
'
rgba(0, 0, 0, 0.85)
'
}}
>
<
FormattedMessage
id
=
"
app.result.success.operate-time
"
defaultMessage
=
"
Effective time:
"
/>
<
/span
>
2016
-
12
-
12
~
2017
-
12
-
12
<
/Col
>
<
/Row
>
<
Steps
style
=
{{
marginLeft
:
-
42
,
width
:
'
calc(100% + 84px)
'
}}
progressDot
current
=
{
1
}
>
<
Step
title
=
{
<
span
style
=
{{
fontSize
:
14
}}
>
<
FormattedMessage
id
=
"
app.result.success.step1-title
"
defaultMessage
=
"
Create project
"
/>
<
/span
>
}
description
=
{
desc1
}
/
>
<
Step
title
=
{
<
span
style
=
{{
fontSize
:
14
}}
>
<
FormattedMessage
id
=
"
app.result.success.step2-title
"
defaultMessage
=
"
Departmental preliminary review
"
/>
<
/span
>
}
description
=
{
desc2
}
/
>
<
Step
title
=
{
<
span
style
=
{{
fontSize
:
14
}}
>
<
FormattedMessage
id
=
"
app.result.success.step3-title
"
defaultMessage
=
"
Financial review
"
/>
<
/span
>
}
/
>
<
Step
title
=
{
<
span
style
=
{{
fontSize
:
14
}}
>
<
FormattedMessage
id
=
"
app.result.success.step4-title
"
defaultMessage
=
"
Finish
"
/>
<
/span
>
}
/
>
<
/Steps
>
<
/Fragment
>
);
const
actions
=
(
<
Fragment
>
<
Button
type
=
"
primary
"
>
<
FormattedMessage
id
=
"
app.result.success.btn-return
"
defaultMessage
=
"
Back to list
"
/>
<
/Button
>
<
Button
>
<
FormattedMessage
id
=
"
app.result.success.btn-project
"
defaultMessage
=
"
View project
"
/>
<
/Button
>
<
Button
>
<
FormattedMessage
id
=
"
app.result.success.btn-print
"
defaultMessage
=
"
Print
"
/>
<
/Button
>
<
/Fragment
>
);
export
default
()
=>
(
<
PageHeaderWrapper
>
<
Card
bordered
=
{
false
}
>
<
Result
type
=
"
success
"
title
=
{
formatMessage
({
id
:
'
app.result.success.title
'
})}
description
=
{
formatMessage
({
id
:
'
app.result.success.description
'
})}
extra
=
{
extra
}
actions
=
{
actions
}
style
=
{{
marginTop
:
48
,
marginBottom
:
16
}}
/
>
<
/Card
>
<
/PageHeaderWrapper
>
);
src/pages/Result/Success.test.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
{
shallow
}
from
'
enzyme
'
;
import
Success
from
'
./Success
'
;
it
(
'
renders with Result
'
,
()
=>
{
const
wrapper
=
shallow
(
<
Success
/>
);
expect
(
wrapper
.
find
(
'
Result
'
).
length
).
toBe
(
1
);
expect
(
wrapper
.
find
(
'
Result
'
).
prop
(
'
type
'
)).
toBe
(
'
success
'
);
});
src/pages/User/Login.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
Link
from
'
umi/link
'
;
import
{
Checkbox
,
Alert
,
Icon
}
from
'
antd
'
;
import
Login
from
'
ant-design-pro/lib/Login
'
;
import
styles
from
'
./Login.less
'
;
const
{
Tab
,
UserName
,
Password
,
Mobile
,
Captcha
,
Submit
}
=
Login
;
@
connect
(({
login
,
loading
})
=>
({
login
,
submitting
:
loading
.
effects
[
'
login/login
'
],
}))
class
LoginPage
extends
Component
{
state
=
{
type
:
'
account
'
,
autoLogin
:
true
,
};
onTabChange
=
type
=>
{
this
.
setState
({
type
});
};
onGetCaptcha
=
()
=>
new
Promise
((
resolve
,
reject
)
=>
{
this
.
loginForm
.
validateFields
([
'
mobile
'
],
{},
(
err
,
values
)
=>
{
if
(
err
)
{
reject
(
err
);
}
else
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
login/getCaptcha
'
,
payload
:
values
.
mobile
,
})
.
then
(
resolve
)
.
catch
(
reject
);
}
});
});
handleSubmit
=
(
err
,
values
)
=>
{
const
{
type
}
=
this
.
state
;
if
(
!
err
)
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'
login/login
'
,
payload
:
{
...
values
,
type
,
},
});
}
};
changeAutoLogin
=
e
=>
{
this
.
setState
({
autoLogin
:
e
.
target
.
checked
,
});
};
renderMessage
=
content
=>
(
<
Alert
style
=
{{
marginBottom
:
24
}}
message
=
{
content
}
type
=
"
error
"
showIcon
/>
);
render
()
{
const
{
login
,
submitting
}
=
this
.
props
;
const
{
type
,
autoLogin
}
=
this
.
state
;
return
(
<
div
className
=
{
styles
.
main
}
>
<
Login
defaultActiveKey
=
{
type
}
onTabChange
=
{
this
.
onTabChange
}
onSubmit
=
{
this
.
handleSubmit
}
ref
=
{
form
=>
{
this
.
loginForm
=
form
;
}}
>
<
Tab
key
=
"
account
"
tab
=
{
formatMessage
({
id
:
'
app.login.tab-login-credentials
'
})}
>
{
login
.
status
===
'
error
'
&&
login
.
type
===
'
account
'
&&
!
submitting
&&
this
.
renderMessage
(
formatMessage
({
id
:
'
app.login.message-invalid-credentials
'
}))}
<
UserName
name
=
"
userName
"
placeholder
=
{
`
${
formatMessage
({
id
:
'
app.login.userName
'
})}
: admin or user`
}
rules
=
{[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.userName.required
'
}),
},
]}
/
>
<
Password
name
=
"
password
"
placeholder
=
{
`
${
formatMessage
({
id
:
'
app.login.password
'
})}
: ant.design`
}
rules
=
{[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.password.required
'
}),
},
]}
onPressEnter
=
{()
=>
this
.
loginForm
.
validateFields
(
this
.
handleSubmit
)}
/
>
<
/Tab
>
<
Tab
key
=
"
mobile
"
tab
=
{
formatMessage
({
id
:
'
app.login.tab-login-mobile
'
})}
>
{
login
.
status
===
'
error
'
&&
login
.
type
===
'
mobile
'
&&
!
submitting
&&
this
.
renderMessage
(
formatMessage
({
id
:
'
app.login.message-invalid-verification-code
'
})
)}
<
Mobile
name
=
"
mobile
"
placeholder
=
{
formatMessage
({
id
:
'
form.phone-number.placeholder
'
})}
rules
=
{[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.phone-number.required
'
}),
},
{
pattern
:
/^1
\d{10}
$/
,
message
:
formatMessage
({
id
:
'
validation.phone-number.wrong-format
'
}),
},
]}
/
>
<
Captcha
name
=
"
captcha
"
placeholder
=
{
formatMessage
({
id
:
'
form.verification-code.placeholder
'
})}
countDown
=
{
120
}
onGetCaptcha
=
{
this
.
onGetCaptcha
}
getCaptchaButtonText
=
{
formatMessage
({
id
:
'
form.get-captcha
'
})}
getCaptchaSecondText
=
{
formatMessage
({
id
:
'
form.captcha.second
'
})}
rules
=
{[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.verification-code.required
'
}),
},
]}
/
>
<
/Tab
>
<
div
>
<
Checkbox
checked
=
{
autoLogin
}
onChange
=
{
this
.
changeAutoLogin
}
>
<
FormattedMessage
id
=
"
app.login.remember-me
"
/>
<
/Checkbox
>
<
a
style
=
{{
float
:
'
right
'
}}
href
=
""
>
<
FormattedMessage
id
=
"
app.login.forgot-password
"
/>
<
/a
>
<
/div
>
<
Submit
loading
=
{
submitting
}
>
<
FormattedMessage
id
=
"
app.login.login
"
/>
<
/Submit
>
<
div
className
=
{
styles
.
other
}
>
<
FormattedMessage
id
=
"
app.login.sign-in-with
"
/>
<
Icon
type
=
"
alipay-circle
"
className
=
{
styles
.
icon
}
theme
=
"
outlined
"
/>
<
Icon
type
=
"
taobao-circle
"
className
=
{
styles
.
icon
}
theme
=
"
outlined
"
/>
<
Icon
type
=
"
weibo-circle
"
className
=
{
styles
.
icon
}
theme
=
"
outlined
"
/>
<
Link
className
=
{
styles
.
register
}
to
=
"
/user/register
"
>
<
FormattedMessage
id
=
"
app.login.signup
"
/>
<
/Link
>
<
/div
>
<
/Login
>
<
/div
>
);
}
}
export
default
LoginPage
;
src/pages/User/Login.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.main {
width: 368px;
margin: 0 auto;
@media screen and (max-width: @screen-sm) {
width: 95%;
}
.icon {
font-size: 24px;
color: rgba(0, 0, 0, 0.2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color 0.3s;
&:hover {
color: @primary-color;
}
}
.other {
text-align: left;
margin-top: 24px;
line-height: 22px;
.register {
float: right;
}
}
}
src/pages/User/Register.js
deleted
100644 → 0
View file @
5ba67a51
import
React
,
{
Component
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
Link
from
'
umi/link
'
;
import
router
from
'
umi/router
'
;
import
{
Form
,
Input
,
Button
,
Select
,
Row
,
Col
,
Popover
,
Progress
}
from
'
antd
'
;
import
styles
from
'
./Register.less
'
;
const
FormItem
=
Form
.
Item
;
const
{
Option
}
=
Select
;
const
InputGroup
=
Input
.
Group
;
const
passwordStatusMap
=
{
ok
:
(
<
div
className
=
{
styles
.
success
}
>
<
FormattedMessage
id
=
"
validation.password.strength.strong
"
/>
<
/div
>
),
pass
:
(
<
div
className
=
{
styles
.
warning
}
>
<
FormattedMessage
id
=
"
validation.password.strength.medium
"
/>
<
/div
>
),
poor
:
(
<
div
className
=
{
styles
.
error
}
>
<
FormattedMessage
id
=
"
validation.password.strength.short
"
/>
<
/div
>
),
};
const
passwordProgressMap
=
{
ok
:
'
success
'
,
pass
:
'
normal
'
,
poor
:
'
exception
'
,
};
@
connect
(({
register
,
loading
})
=>
({
register
,
submitting
:
loading
.
effects
[
'
register/submit
'
],
}))
@
Form
.
create
()
class
Register
extends
Component
{
state
=
{
count
:
0
,
confirmDirty
:
false
,
visible
:
false
,
help
:
''
,
prefix
:
'
86
'
,
};
componentDidUpdate
()
{
const
{
form
,
register
}
=
this
.
props
;
const
account
=
form
.
getFieldValue
(
'
mail
'
);
if
(
register
.
status
===
'
ok
'
)
{
router
.
push
({
pathname
:
'
/user/register-result
'
,
state
:
{
account
,
},
});
}
}
componentWillUnmount
()
{
clearInterval
(
this
.
interval
);
}
onGetCaptcha
=
()
=>
{
let
count
=
59
;
this
.
setState
({
count
});
this
.
interval
=
setInterval
(()
=>
{
count
-=
1
;
this
.
setState
({
count
});
if
(
count
===
0
)
{
clearInterval
(
this
.
interval
);
}
},
1000
);
};
getPasswordStatus
=
()
=>
{
const
{
form
}
=
this
.
props
;
const
value
=
form
.
getFieldValue
(
'
password
'
);
if
(
value
&&
value
.
length
>
9
)
{
return
'
ok
'
;
}
if
(
value
&&
value
.
length
>
5
)
{
return
'
pass
'
;
}
return
'
poor
'
;
};
handleSubmit
=
e
=>
{
e
.
preventDefault
();
const
{
form
,
dispatch
}
=
this
.
props
;
form
.
validateFields
({
force
:
true
},
(
err
,
values
)
=>
{
if
(
!
err
)
{
const
{
prefix
}
=
this
.
state
;
dispatch
({
type
:
'
register/submit
'
,
payload
:
{
...
values
,
prefix
,
},
});
}
});
};
handleConfirmBlur
=
e
=>
{
const
{
value
}
=
e
.
target
;
const
{
confirmDirty
}
=
this
.
state
;
this
.
setState
({
confirmDirty
:
confirmDirty
||
!!
value
});
};
checkConfirm
=
(
rule
,
value
,
callback
)
=>
{
const
{
form
}
=
this
.
props
;
if
(
value
&&
value
!==
form
.
getFieldValue
(
'
password
'
))
{
callback
(
formatMessage
({
id
:
'
validation.password.twice
'
}));
}
else
{
callback
();
}
};
checkPassword
=
(
rule
,
value
,
callback
)
=>
{
const
{
visible
,
confirmDirty
}
=
this
.
state
;
if
(
!
value
)
{
this
.
setState
({
help
:
formatMessage
({
id
:
'
validation.password.required
'
}),
visible
:
!!
value
,
});
callback
(
'
error
'
);
}
else
{
this
.
setState
({
help
:
''
,
});
if
(
!
visible
)
{
this
.
setState
({
visible
:
!!
value
,
});
}
if
(
value
.
length
<
6
)
{
callback
(
'
error
'
);
}
else
{
const
{
form
}
=
this
.
props
;
if
(
value
&&
confirmDirty
)
{
form
.
validateFields
([
'
confirm
'
],
{
force
:
true
});
}
callback
();
}
}
};
changePrefix
=
value
=>
{
this
.
setState
({
prefix
:
value
,
});
};
renderPasswordProgress
=
()
=>
{
const
{
form
}
=
this
.
props
;
const
value
=
form
.
getFieldValue
(
'
password
'
);
const
passwordStatus
=
this
.
getPasswordStatus
();
return
value
&&
value
.
length
?
(
<
div
className
=
{
styles
[
`progress-
${
passwordStatus
}
`
]}
>
<
Progress
status
=
{
passwordProgressMap
[
passwordStatus
]}
className
=
{
styles
.
progress
}
strokeWidth
=
{
6
}
percent
=
{
value
.
length
*
10
>
100
?
100
:
value
.
length
*
10
}
showInfo
=
{
false
}
/
>
<
/div
>
)
:
null
;
};
render
()
{
const
{
form
,
submitting
}
=
this
.
props
;
const
{
getFieldDecorator
}
=
form
;
const
{
count
,
prefix
,
help
,
visible
}
=
this
.
state
;
return
(
<
div
className
=
{
styles
.
main
}
>
<
h3
>
<
FormattedMessage
id
=
"
app.register.register
"
/>
<
/h3
>
<
Form
onSubmit
=
{
this
.
handleSubmit
}
>
<
FormItem
>
{
getFieldDecorator
(
'
mail
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.email.required
'
}),
},
{
type
:
'
email
'
,
message
:
formatMessage
({
id
:
'
validation.email.wrong-format
'
}),
},
],
})(
<
Input
size
=
"
large
"
placeholder
=
{
formatMessage
({
id
:
'
form.email.placeholder
'
})}
/
>
)}
<
/FormItem
>
<
FormItem
help
=
{
help
}
>
<
Popover
getPopupContainer
=
{
node
=>
node
.
parentNode
}
content
=
{
<
div
style
=
{{
padding
:
'
4px 0
'
}}
>
{
passwordStatusMap
[
this
.
getPasswordStatus
()]}
{
this
.
renderPasswordProgress
()}
<
div
style
=
{{
marginTop
:
10
}}
>
<
FormattedMessage
id
=
"
validation.password.strength.msg
"
/>
<
/div
>
<
/div
>
}
overlayStyle
=
{{
width
:
240
}}
placement
=
"
right
"
visible
=
{
visible
}
>
{
getFieldDecorator
(
'
password
'
,
{
rules
:
[
{
validator
:
this
.
checkPassword
,
},
],
})(
<
Input
size
=
"
large
"
type
=
"
password
"
placeholder
=
{
formatMessage
({
id
:
'
form.password.placeholder
'
})}
/
>
)}
<
/Popover
>
<
/FormItem
>
<
FormItem
>
{
getFieldDecorator
(
'
confirm
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.confirm-password.required
'
}),
},
{
validator
:
this
.
checkConfirm
,
},
],
})(
<
Input
size
=
"
large
"
type
=
"
password
"
placeholder
=
{
formatMessage
({
id
:
'
form.confirm-password.placeholder
'
})}
/
>
)}
<
/FormItem
>
<
FormItem
>
<
InputGroup
compact
>
<
Select
size
=
"
large
"
value
=
{
prefix
}
onChange
=
{
this
.
changePrefix
}
style
=
{{
width
:
'
20%
'
}}
>
<
Option
value
=
"
86
"
>+
86
<
/Option
>
<
Option
value
=
"
87
"
>+
87
<
/Option
>
<
/Select
>
{
getFieldDecorator
(
'
mobile
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.phone-number.required
'
}),
},
{
pattern
:
/^
\d{11}
$/
,
message
:
formatMessage
({
id
:
'
validation.phone-number.wrong-format
'
}),
},
],
})(
<
Input
size
=
"
large
"
style
=
{{
width
:
'
80%
'
}}
placeholder
=
{
formatMessage
({
id
:
'
form.phone-number.placeholder
'
})}
/
>
)}
<
/InputGroup
>
<
/FormItem
>
<
FormItem
>
<
Row
gutter
=
{
8
}
>
<
Col
span
=
{
16
}
>
{
getFieldDecorator
(
'
captcha
'
,
{
rules
:
[
{
required
:
true
,
message
:
formatMessage
({
id
:
'
validation.verification-code.required
'
}),
},
],
})(
<
Input
size
=
"
large
"
placeholder
=
{
formatMessage
({
id
:
'
form.verification-code.placeholder
'
})}
/
>
)}
<
/Col
>
<
Col
span
=
{
8
}
>
<
Button
size
=
"
large
"
disabled
=
{
count
}
className
=
{
styles
.
getCaptcha
}
onClick
=
{
this
.
onGetCaptcha
}
>
{
count
?
`
${
count
}
s`
:
formatMessage
({
id
:
'
app.register.get-verification-code
'
})}
<
/Button
>
<
/Col
>
<
/Row
>
<
/FormItem
>
<
FormItem
>
<
Button
size
=
"
large
"
loading
=
{
submitting
}
className
=
{
styles
.
submit
}
type
=
"
primary
"
htmlType
=
"
submit
"
>
<
FormattedMessage
id
=
"
app.register.register
"
/>
<
/Button
>
<
Link
className
=
{
styles
.
login
}
to
=
"
/User/Login
"
>
<
FormattedMessage
id
=
"
app.register.sign-in
"
/>
<
/Link
>
<
/FormItem
>
<
/Form
>
<
/div
>
);
}
}
export
default
Register
;
src/pages/User/Register.less
deleted
100644 → 0
View file @
5ba67a51
@import '~antd/lib/style/themes/default.less';
.main {
width: 368px;
margin: 0 auto;
:global {
.ant-form-item {
margin-bottom: 24px;
}
}
h3 {
font-size: 16px;
margin-bottom: 20px;
}
.getCaptcha {
display: block;
width: 100%;
}
.submit {
width: 50%;
}
.login {
float: right;
line-height: @btn-height-lg;
}
}
.success,
.warning,
.error {
transition: color 0.3s;
}
.success {
color: @success-color;
}
.warning {
color: @warning-color;
}
.error {
color: @error-color;
}
.progress-pass > .progress {
:global {
.ant-progress-bg {
background-color: @warning-color;
}
}
}
src/pages/User/RegisterResult.js
deleted
100644 → 0
View file @
5ba67a51
import
React
from
'
react
'
;
import
{
formatMessage
,
FormattedMessage
}
from
'
umi/locale
'
;
import
{
Button
}
from
'
antd
'
;
import
Link
from
'
umi/link
'
;
import
Result
from
'
ant-design-pro/lib/Result
'
;
import
styles
from
'
./RegisterResult.less
'
;
const
actions
=
(
<
div
className
=
{
styles
.
actions
}
>
<
a
href
=
""
>
<
Button
size
=
"
large
"
type
=
"
primary
"
>
<
FormattedMessage
id
=
"
app.register-result.view-mailbox
"
/>
<
/Button
>
<
/a
>
<
Link
to
=
"
/
"
>
<
Button
size
=
"
large
"
>
<
FormattedMessage
id
=
"
app.register-result.back-home
"
/>
<
/Button
>
<
/Link
>
<
/div
>
);
const
RegisterResult
=
({
location
})
=>
(
<
Result
className
=
{
styles
.
registerResult
}
type
=
"
success
"
title
=
{
<
div
className
=
{
styles
.
title
}
>
<
FormattedMessage
id
=
"
app.register-result.msg
"
values
=
{{
email
:
location
.
state
?
location
.
state
.
account
:
'
AntDesign@example.com
'
}}
/
>
<
/div
>
}
description
=
{
formatMessage
({
id
:
'
app.register-result.activation-email
'
})}
actions
=
{
actions
}
style
=
{{
marginTop
:
56
}}
/
>
);
export
default
RegisterResult
;
src/pages/User/RegisterResult.less
deleted
100644 → 0
View file @
5ba67a51
.registerResult {
:global {
.anticon {
font-size: 64px;
}
}
.title {
margin-top: 32px;
font-size: 20px;
line-height: 28px;
}
.actions {
margin-top: 40px;
a + a {
margin-left: 8px;
}
}
}
src/pages/User/models/register.js
deleted
100644 → 0
View file @
5ba67a51
import
{
fakeRegister
}
from
'
@/services/api
'
;
import
{
setAuthority
}
from
'
@/utils/authority
'
;
import
{
reloadAuthorized
}
from
'
@/utils/Authorized
'
;
export
default
{
namespace
:
'
register
'
,
state
:
{
status
:
undefined
,
},
effects
:
{
*
submit
({
payload
},
{
call
,
put
})
{
const
response
=
yield
call
(
fakeRegister
,
payload
);
yield
put
({
type
:
'
registerHandle
'
,
payload
:
response
,
});
},
},
reducers
:
{
registerHandle
(
state
,
{
payload
})
{
setAuthority
(
'
user
'
);
reloadAuthorized
();
return
{
...
state
,
status
:
payload
.
status
,
};
},
},
};
src/pages/document.ejs
deleted
100644 → 0
View file @
5ba67a51
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"
>
<title>
Ant Design Pro
</title>
<link
rel=
"icon"
href=
"/favicon.png"
type=
"image/x-icon"
>
<script
src=
"https://gw.alipayobjects.com/os/antv/pkg/_antv.data-set-0.9.6/dist/data-set.min.js"
></script>
</head>
<body>
<noscript>
Sorry, we need js to run correctly!
</noscript>
<div
id=
"root"
></div>
</body>
</html>
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