From a6eb693636f6131c7c88818669a56f3c5988aa29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=A8=E6=96=8C?= <892728595@qq.com>
Date: Wed, 6 Sep 2017 11:13:26 +0800
Subject: [PATCH 1/3] dva@2.0
---
.roadhogrc.js | 18 +--
package.json | 15 +-
src/components/Layout/Bread.js | 6 +-
src/components/Layout/Menu.js | 6 +-
src/components/LinkWrapper/index.js | 10 ++
src/components/index.js | 2 +
src/index.js | 4 +-
src/router.js | 206 ++++++++++------------------
src/routes/app.js | 3 +-
src/routes/user/List.js | 4 +-
10 files changed, 114 insertions(+), 160 deletions(-)
create mode 100644 src/components/LinkWrapper/index.js
diff --git a/.roadhogrc.js b/.roadhogrc.js
index 1f65c6a..9b76d6f 100644
--- a/.roadhogrc.js
+++ b/.roadhogrc.js
@@ -7,17 +7,17 @@ const svgSpriteDirs = [
]
export default {
- entry : 'src/index.js',
- svgSpriteLoaderDirs : svgSpriteDirs,
- theme : "./theme.config.js",
- publicPath : `/${version}/`,
- outputPath : `./dist/${version}`,
+ entry: 'src/index.js',
+ svgSpriteLoaderDirs: svgSpriteDirs,
+ theme: "./theme.config.js",
+ publicPath: `/${version}/`,
+ outputPath: `./dist/${version}`,
// 接口代理示例
proxy: {
"/api/v1/weather": {
"target": "https://api.seniverse.com/",
"changeOrigin": true,
- "pathRewrite": { "^/api/v1/weather" : "/v3/weather" }
+ "pathRewrite": { "^/api/v1/weather": "/v3/weather" }
},
// "/api/v2": {
// "target": "http://192.168.0.110",
@@ -25,7 +25,7 @@ export default {
// "pathRewrite": { "^/api/v2" : "/api/v2" }
// }
},
- env : {
+ env: {
development: {
extraBabelPlugins: [
"dva-hmr",
@@ -50,8 +50,8 @@ export default {
]
}
},
- dllPlugin : {
- exclude: ["babel-runtime"],
+ dllPlugin: {
+ exclude: ["babel-runtime", "roadhog", "cross-env"],
include: ["dva/router", "dva/saga", "dva/fetch"]
}
}
diff --git a/package.json b/package.json
index 49962fd..bf076d8 100644
--- a/package.json
+++ b/package.json
@@ -7,11 +7,13 @@
"axios": "^0.16.2",
"babel-polyfill": "^6.23.0",
"classnames": "^2.2.5",
+ "cross-env": "^5.0.5",
"d3-shape": "^1.2.0",
"draftjs-to-markdown": "^0.4.0",
- "dva": "^1.2.0",
+ "dva": "^2.0.1",
"dva-loading": "^0.2.0",
"ejs-loader": "^0.3.0",
+ "history": "^4.7.2",
"js-beautify": "^1.6.14",
"jsonp": "^0.2.1",
"less-vars-to-js": "^1.1.2",
@@ -21,6 +23,7 @@
"path-to-regexp": "^1.7.0",
"prop-types": "^15.5.10",
"qs": "^6.5.0",
+ "query-string": "^5.0.0",
"rc-tween-one": "^1.3.1",
"react": "^15.6.1",
"react-countup": "^2.1.1",
@@ -50,14 +53,16 @@
"html-webpack-plugin": "^2.29.0",
"html-webpack-template": "^5.6.0",
"redbox-react": "^1.2.10",
- "roadhog": "1.0.0-beta.7"
+ "roadhog": "^1.2.2"
},
- "pre-commit": ["lint"],
+ "pre-commit": [
+ "lint"
+ ],
"scripts": {
- "dev": "set BROWSER=none&&set HOST=0.0.0.0&&roadhog server",
+ "dev": "cross-env BROWSER=none HOST=0.0.0.0 roadhog server",
"lint": "eslint --fix --ext .js src",
"build": "roadhog build",
"build:dll": "roadhog buildDll",
"build:new": "node version && roadhog build"
}
-}
\ No newline at end of file
+}
diff --git a/src/components/Layout/Bread.js b/src/components/Layout/Bread.js
index ad4d5b5..be05ef4 100644
--- a/src/components/Layout/Bread.js
+++ b/src/components/Layout/Bread.js
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Breadcrumb, Icon } from 'antd'
-import { Link } from 'dva/router'
+import { LinkWrapper } from 'components'
import pathToRegexp from 'path-to-regexp'
import { queryArray } from 'utils'
import styles from './Bread.less'
@@ -48,9 +48,9 @@ const Bread = ({ menu, location }) => {
return (
{((pathArray.length - 1) !== key)
- ?
+ ?
{content}
-
+
: content}
)
diff --git a/src/components/Layout/Menu.js b/src/components/Layout/Menu.js
index 3662b87..60e42ff 100644
--- a/src/components/Layout/Menu.js
+++ b/src/components/Layout/Menu.js
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Menu, Icon } from 'antd'
-import { Link } from 'dva/router'
+import { LinkWrapper } from 'components'
import { arrayToTree, queryArray } from 'utils'
import pathToRegexp from 'path-to-regexp'
@@ -31,10 +31,10 @@ const Menus = ({ siderFold, darkTheme, handleClickNavMenu, navOpenKeys, changeOp
}
return (
-
+
{item.icon && }
{(!siderFoldN || !menuTree.includes(item)) && item.name}
-
+
)
})
diff --git a/src/components/LinkWrapper/index.js b/src/components/LinkWrapper/index.js
new file mode 100644
index 0000000..320e315
--- /dev/null
+++ b/src/components/LinkWrapper/index.js
@@ -0,0 +1,10 @@
+import { Link } from 'react-router-dom'
+
+export default (props) => {
+ const Component = props.to ? Link : 'a'
+ return (
+
+ {props.children}
+
+ )
+}
diff --git a/src/components/index.js b/src/components/index.js
index 6694a34..2c8a0d6 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -6,6 +6,7 @@ import Editor from './Editor'
import FilterItem from './FilterItem'
import Loader from './Loader'
import * as Layout from './Layout/index.js'
+import LinkWrapper from './LinkWrapper'
import layer from './layer'
@@ -19,4 +20,5 @@ export {
FilterItem,
Loader,
layer,
+ LinkWrapper,
}
diff --git a/src/index.js b/src/index.js
index 3be2c3c..e880e17 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,7 @@
import { message } from 'antd'
import dva from 'dva'
import createLoading from 'dva-loading'
-import { browserHistory } from 'dva/router'
+import createHistory from 'history/createBrowserHistory'
import 'babel-polyfill'
// 1. Initialize
@@ -9,7 +9,7 @@ const app = dva({
...createLoading({
effects: true,
}),
- history: browserHistory,
+ history: createHistory(),
onError (error) {
message.error(error.message)
},
diff --git a/src/router.js b/src/router.js
index ec8f046..0813662 100644
--- a/src/router.js
+++ b/src/router.js
@@ -1,149 +1,85 @@
import React from 'react'
import PropTypes from 'prop-types'
-import { Router } from 'dva/router'
+import { Router, Switch, Route, Redirect, routerRedux } from 'dva/router'
+import dynamic from 'dva/dynamic'
import App from 'routes/app'
-const registerModel = (app, model) => {
- if (!(app._models.filter(m => m.namespace === model.namespace).length === 1)) {
- app.model(model)
- }
-}
+const { ConnectedRouter } = routerRedux
const Routers = function ({ history, app }) {
+ const error = dynamic({
+ app,
+ component: () => import('./routes/error'),
+ })
const routes = [
{
- path: '/',
- component: App,
- getIndexRoute (nextState, cb) {
- require.ensure([], (require) => {
- registerModel(app, require('models/dashboard'))
- cb(null, { component: require('routes/dashboard/') })
- }, 'dashboard')
- },
- childRoutes: [
- {
- path: 'dashboard',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- registerModel(app, require('models/dashboard'))
- cb(null, require('routes/dashboard/'))
- }, 'dashboard')
- },
- }, {
- path: 'user',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- registerModel(app, require('models/user'))
- cb(null, require('routes/user/'))
- }, 'user')
- },
- }, {
- path: 'user/:id',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- registerModel(app, require('models/user/detail'))
- cb(null, require('routes/user/detail/'))
- }, 'user-detail')
- },
- }, {
- path: 'login',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- registerModel(app, require('models/login'))
- cb(null, require('routes/login/'))
- }, 'login')
- },
- }, {
- path: 'request',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/request/'))
- }, 'request')
- },
- }, {
- path: 'UIElement/iconfont',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/UIElement/iconfont/'))
- }, 'UIElement-iconfont')
- },
- }, {
- path: 'UIElement/search',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/UIElement/search/'))
- }, 'UIElement-search')
- },
- }, {
- path: 'UIElement/dropOption',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/UIElement/dropOption/'))
- }, 'UIElement-dropOption')
- },
- }, {
- path: 'UIElement/layer',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/UIElement/layer/'))
- }, 'UIElement-layer')
- },
- }, {
- path: 'UIElement/dataTable',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/UIElement/dataTable/'))
- }, 'UIElement-dataTable')
- },
- }, {
- path: 'UIElement/editor',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/UIElement/editor/'))
- }, 'UIElement-editor')
- },
- }, {
- path: 'chart/lineChart',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/chart/lineChart/'))
- }, 'chart-lineChart')
- },
- }, {
- path: 'chart/barChart',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/chart/barChart/'))
- }, 'chart-barChart')
- },
- }, {
- path: 'chart/areaChart',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/chart/areaChart/'))
- }, 'chart-areaChart')
- },
- }, {
- path: 'post',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- registerModel(app, require('models/post'))
- cb(null, require('routes/post/'))
- }, 'post')
- },
- }, {
- path: '*',
- getComponent (nextState, cb) {
- require.ensure([], (require) => {
- cb(null, require('routes/error/'))
- }, 'error')
- },
- },
- ],
+ path: '/dashboard',
+ models: () => [import('./models/dashboard')],
+ component: () => import('./routes/dashboard/'),
+ }, {
+ path: '/user',
+ models: () => [import('./models/user')],
+ component: () => import('./routes/user/'),
+ }, {
+ path: '/user/:id',
+ models: () => [import('./models/user/detail')],
+ component: () => import('./routes/user/detail/'),
+ }, {
+ path: '/login',
+ models: () => [import('./models/login')],
+ component: () => import('./routes/login/'),
+ }, {
+ path: '/request',
+ component: () => import('./routes/request/'),
+ }, {
+ path: '/UIElement/iconfont',
+ component: () => import('./routes/UIElement/iconfont/'),
+ }, {
+ path: '/UIElement/search',
+ component: () => import('./routes/UIElement/search/'),
+ }, {
+ path: '/UIElement/dropOption',
+ component: () => import('./routes/UIElement/dropOption/'),
+ }, {
+ path: '/UIElement/layer',
+ component: () => import('./routes/UIElement/layer/'),
+ }, {
+ path: '/UIElement/dataTable',
+ component: () => import('./routes/UIElement/dataTable/'),
+ }, {
+ path: '/UIElement/editor',
+ component: () => import('./routes/UIElement/editor/'),
+ }, {
+ path: '/chart/lineChart',
+ component: () => import('./routes/chart/lineChart/'),
+ }, {
+ path: '/chart/barChart',
+ component: () => import('./routes/chart/barChart/'),
+ }, {
+ path: '/chart/areaChart',
+ component: () => import('./routes/chart/areaChart/'),
+ }, {
+ path: '/post',
+ models: () => [import('./models/post')],
+ component: () => import('./routes/post/'),
},
]
- return
+ return (
+
+
+
+ ()} />
+ {
+ routes.map(({ path, ...dynamics }, key) => (
+
+ ))
+ }
+
+
+
+
+ )
}
Routers.propTypes = {
diff --git a/src/routes/app.js b/src/routes/app.js
index 9e75aad..3ec5dbb 100644
--- a/src/routes/app.js
+++ b/src/routes/app.js
@@ -10,6 +10,7 @@ import { Helmet } from 'react-helmet'
import '../themes/index.less'
import './app.less'
import Error from './error'
+import { withRouter } from 'dva/router'
const { prefix, openPages } = config
@@ -116,4 +117,4 @@ App.propTypes = {
loading: PropTypes.object,
}
-export default connect(({ app, loading }) => ({ app, loading }))(App)
+export default withRouter(connect(({ app, loading }) => ({ app, loading }))(App))
diff --git a/src/routes/user/List.js b/src/routes/user/List.js
index e80c2b5..cd7543a 100644
--- a/src/routes/user/List.js
+++ b/src/routes/user/List.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { Table, Modal } from 'antd'
import classnames from 'classnames'
import { DropOption } from 'components'
-import { Link } from 'dva/router'
+import { LinkWrapper } from 'components'
import AnimTableBody from '../../components/DataTable/AnimTableBody'
import styles from './List.less'
@@ -35,7 +35,7 @@ const List = ({ onDeleteItem, onEditItem, isMotion, location, ...tableProps }) =
title: 'Name',
dataIndex: 'name',
key: 'name',
- render: (text, record) => {text},
+ render: (text, record) => {text},
}, {
title: 'NickName',
dataIndex: 'nickName',
From 7bf031699aa643d67cfa30ec64214326f6052efe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=A8=E6=96=8C?= <892728595@qq.com>
Date: Wed, 6 Sep 2017 20:36:14 +0800
Subject: [PATCH 2/3] add LoadingComponent
---
package.json | 3 +--
src/components/Loader/Loader.js | 8 ++++++--
src/components/Loader/Loader.less | 6 +++++-
src/router.js | 7 ++++++-
src/routes/app.js | 16 ++++++++--------
5 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/package.json b/package.json
index bf076d8..03d1b02 100644
--- a/package.json
+++ b/package.json
@@ -30,8 +30,7 @@
"react-dom": "^15.6.1",
"react-draft-wysiwyg": "^1.10.0",
"react-helmet": "^5.1.3",
- "recharts": "^0.22.4",
- "roadhog": "^1.2.1"
+ "recharts": "^0.22.4"
},
"devDependencies": {
"babel-eslint": "^7.2.3",
diff --git a/src/components/Loader/Loader.js b/src/components/Loader/Loader.js
index fe24a19..2d2943f 100644
--- a/src/components/Loader/Loader.js
+++ b/src/components/Loader/Loader.js
@@ -3,8 +3,11 @@ import PropTypes from 'prop-types'
import classNames from 'classnames'
import styles from './Loader.less'
-const Loader = ({ spinning }) => {
- return (
+const Loader = ({ spinning, fullScreen }) => {
+ return (
LOADING
@@ -15,6 +18,7 @@ const Loader = ({ spinning }) => {
Loader.propTypes = {
spinning: PropTypes.bool,
+ fullScreen: PropTypes.bool,
}
export default Loader
diff --git a/src/components/Loader/Loader.less b/src/components/Loader/Loader.less
index ba3685a..723402d 100644
--- a/src/components/Loader/Loader.less
+++ b/src/components/Loader/Loader.less
@@ -1,8 +1,12 @@
+.loader_fullScreen {
+ position: fixed !important;
+}
+
.loader {
display: block;
background-color: #fff;
width: 100%;
- position: fixed;
+ position: absolute;
top: 0;
bottom: 0;
left: 0;
diff --git a/src/router.js b/src/router.js
index 0813662..4aef55a 100644
--- a/src/router.js
+++ b/src/router.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import { Router, Switch, Route, Redirect, routerRedux } from 'dva/router'
import dynamic from 'dva/dynamic'
import App from 'routes/app'
+import { Loader } from 'components'
const { ConnectedRouter } = routerRedux
@@ -72,7 +73,11 @@ const Routers = function ({ history, app }) {
()} />
{
routes.map(({ path, ...dynamics }, key) => (
-
+ (),
+ ...dynamics
+ })} />
))
}
diff --git a/src/routes/app.js b/src/routes/app.js
index 3ec5dbb..5569caa 100644
--- a/src/routes/app.js
+++ b/src/routes/app.js
@@ -41,16 +41,16 @@ const App = ({ children, dispatch, app, loading, location }) => {
isNavbar,
menuPopoverVisible,
navOpenKeys,
- switchMenuPopover () {
+ switchMenuPopover() {
dispatch({ type: 'app/switchMenuPopver' })
},
- logout () {
+ logout() {
dispatch({ type: 'app/logout' })
},
- switchSider () {
+ switchSider() {
dispatch({ type: 'app/switchSider' })
},
- changeOpenKeys (openKeys) {
+ changeOpenKeys(openKeys) {
dispatch({ type: 'app/handleNavOpenKeys', payload: { navOpenKeys: openKeys } })
},
}
@@ -61,10 +61,10 @@ const App = ({ children, dispatch, app, loading, location }) => {
siderFold,
darkTheme,
navOpenKeys,
- changeTheme () {
+ changeTheme() {
dispatch({ type: 'app/switchTheme' })
},
- changeOpenKeys (openKeys) {
+ changeOpenKeys(openKeys) {
window.localStorage.setItem(`${prefix}navOpenKeys`, JSON.stringify(openKeys))
dispatch({ type: 'app/handleNavOpenKeys', payload: { navOpenKeys: openKeys } })
},
@@ -76,13 +76,13 @@ const App = ({ children, dispatch, app, loading, location }) => {
}
if (openPages && openPages.includes(pathname)) {
return (
-
+
{children}
)
}
return (
-
+
ANTD ADMIN
From d3e7e177899f5db53d793e91ec528b009ba0921e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=A8=E6=96=8C?= <892728595@qq.com>
Date: Fri, 8 Sep 2017 13:20:25 +0800
Subject: [PATCH 3/3] query-string
---
src/models/app.js | 3 ++-
src/models/post.js | 3 ++-
src/models/user.js | 3 ++-
src/routes/user/List.js | 3 +++
src/routes/user/index.js | 2 ++
5 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/models/app.js b/src/models/app.js
index c5d0a34..5e2f7a0 100644
--- a/src/models/app.js
+++ b/src/models/app.js
@@ -7,6 +7,7 @@ import config from 'config'
import { EnumRoleType } from 'enums'
import { query, logout } from 'services/app'
import * as menusService from 'services/menus'
+import queryString from 'query-string'
const { prefix } = config
@@ -41,7 +42,7 @@ export default {
type: 'updateState',
payload: {
locationPathname: location.pathname,
- locationQuery: location.query,
+ locationQuery: queryString.parse(location.search),
},
})
})
diff --git a/src/models/post.js b/src/models/post.js
index 6ed99a8..1e3c7a1 100644
--- a/src/models/post.js
+++ b/src/models/post.js
@@ -1,6 +1,7 @@
import modelExtend from 'dva-model-extend'
import { query } from 'services/posts'
import { pageModel } from 'models/common'
+import queryString from 'query-string'
export default modelExtend(pageModel, {
@@ -13,7 +14,7 @@ export default modelExtend(pageModel, {
dispatch({ type: 'query',
payload: {
status: 2,
- ...location.query,
+ ...queryString.parse(location.search),
} })
}
})
diff --git a/src/models/user.js b/src/models/user.js
index 0a789e7..cfaf1fa 100644
--- a/src/models/user.js
+++ b/src/models/user.js
@@ -4,6 +4,7 @@ import { config } from 'utils'
import { create, remove, update } from 'services/user'
import * as usersService from 'services/users'
import { pageModel } from './common'
+import queryString from 'query-string'
const { query } = usersService
const { prefix } = config
@@ -25,7 +26,7 @@ export default modelExtend(pageModel, {
if (location.pathname === '/user') {
dispatch({
type: 'query',
- payload: location.query,
+ payload: queryString.parse(location.search),
})
}
})
diff --git a/src/routes/user/List.js b/src/routes/user/List.js
index cd7543a..8f43f5d 100644
--- a/src/routes/user/List.js
+++ b/src/routes/user/List.js
@@ -5,11 +5,14 @@ import classnames from 'classnames'
import { DropOption } from 'components'
import { LinkWrapper } from 'components'
import AnimTableBody from '../../components/DataTable/AnimTableBody'
+import queryString from 'query-string'
import styles from './List.less'
const confirm = Modal.confirm
const List = ({ onDeleteItem, onEditItem, isMotion, location, ...tableProps }) => {
+ location.query = queryString.parse(location.search)
+
const handleMenuClick = (record, e) => {
if (e.key === '1') {
onEditItem(record)
diff --git a/src/routes/user/index.js b/src/routes/user/index.js
index df64acd..258899d 100644
--- a/src/routes/user/index.js
+++ b/src/routes/user/index.js
@@ -6,8 +6,10 @@ import { Row, Col, Button, Popconfirm } from 'antd'
import List from './List'
import Filter from './Filter'
import Modal from './Modal'
+import queryString from 'query-string'
const User = ({ location, dispatch, user, loading }) => {
+ location.query = queryString.parse(location.search)
const { list, pagination, currentItem, modalVisible, modalType, isMotion, selectedRowKeys } = user
const { pageSize } = pagination