mirror of
https://github.com/zuiidea/antd-admin.git
synced 2026-10-20 08:16:39 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5f013ff23 | ||
|
|
8cff3af897 | ||
|
|
322d5a6d0e | ||
|
|
2ee26f51a7 | ||
|
|
e670ed2f96 | ||
|
|
601a03b5b4 | ||
|
|
fa4385055b | ||
|
|
01f4de55df | ||
|
|
dedd34e8e8 | ||
|
|
d1b373201e | ||
|
|
dbcc90e7ad | ||
|
|
87fce74d5b | ||
|
|
5c51679ad7 | ||
|
|
6d17b5b876 | ||
|
|
1288853112 | ||
|
|
d3e7e17789 | ||
|
|
7bf031699a | ||
|
|
a6eb693636 | ||
|
|
39c377e0e2 | ||
|
|
67b90c4df0 | ||
|
|
0e2727f9c8 | ||
|
|
0cf02e7324 | ||
|
|
68c9f2b65f |
@@ -32,6 +32,7 @@
|
||||
"react/forbid-prop-types": 0,
|
||||
"react/no-string-refs": 0,
|
||||
"react/no-find-dom-node": 0,
|
||||
"react/prefer-stateless-function": 0,
|
||||
"import/no-extraneous-dependencies": 0,
|
||||
"import/prefer-default-export": 0,
|
||||
"react/no-danger": 0,
|
||||
|
||||
+9
-9
@@ -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"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://github.com/facebook/react)
|
||||
[](https://github.com/ant-design/ant-design)
|
||||
[](https://github.com/dvajs/dva)
|
||||
[](https://github.com/dvajs/dva)
|
||||
|
||||
[](https://github.com/zuiidea/antd-admin)
|
||||
[](https://github.com/zuiidea/antd-admin/pulls)
|
||||
@@ -21,6 +21,21 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
|
||||
### 4.3.5
|
||||
|
||||
`2017-09-04`
|
||||
|
||||
- 更新[dva](https://github.com/dvajs/dva)至`2.0.1`,感谢[@yangbin1994](https://github.com/yangbin1994)的[PR](https://github.com/zuiidea/antd-admin/pull/567)。
|
||||
|
||||
### 4.3.4
|
||||
|
||||
`2017-09-04`
|
||||
|
||||
- 更新[roadhog](https://github.com/sorrycc/roadhog)至`1.2.1`,修复闪屏问题。
|
||||
- 修复build css未压缩[#529](https://github.com/zuiidea/antd-admin/issues/529),classname未Hash[#477](https://github.com/zuiidea/antd-admin/issues/477)。
|
||||
- 更新登录成功使用router跳转[#479](https://github.com/zuiidea/antd-admin/issues/479)。
|
||||
|
||||
### 4.3.0
|
||||
|
||||
`2017-07-30`
|
||||
@@ -30,34 +45,8 @@
|
||||
- 新增打包时按项目版本号生成文件目录。[#449](https://github.com/zuiidea/antd-admin/issues/449)
|
||||
- 更新`eslint`,并适当修改了`.eslintrc`。
|
||||
|
||||
### 4.2.3
|
||||
|
||||
`2017-07-07`
|
||||
|
||||
- 新增用户按权限访问。[#384](https://github.com/zuiidea/antd-admin/issues/384)
|
||||
|
||||
### 4.2.2
|
||||
|
||||
`2017-06-01`
|
||||
|
||||
- 新增用户管理批量删除。[#320](https://github.com/zuiidea/antd-admin/issues/320)
|
||||
|
||||
### 4.2.1
|
||||
|
||||
`2017-05-12`
|
||||
|
||||
- 新增IconFont扩展方案,本地使用方案。[#270](https://github.com/zuiidea/antd-admin/issues/270) [Live](http://47.92.30.98:666/UIElement/iconfont)
|
||||
- 新增常见场景使用loading。 [dva-loading](https://github.com/dvajs/dva-loading)
|
||||
|
||||
### 4.2
|
||||
|
||||
`2017-04-28`
|
||||
|
||||
- 修改user相关API使用`Restful`风格。
|
||||
- 增加user页面多条件查询。[#266](https://github.com/zuiidea/antd-admin/issues/226)
|
||||
- 修复菜单默认高亮。[#201](https://github.com/zuiidea/antd-admin/issues/201)
|
||||
|
||||
[More Change Log](https://github.com/zuiidea/antd-admin/wiki/Change-Log)
|
||||
[More Change Log](https://github.com/zuiidea/antd-admin/wiki/Change-Log)
|
||||
|
||||
## 开发构建
|
||||
|
||||
@@ -140,11 +129,11 @@ npm run lint
|
||||
## FAQ
|
||||
|
||||
- 项目打包后如何部署? [#269](https://github.com/zuiidea/antd-admin/issues/269)
|
||||
- 如何做权限管理? [#384](https://github.com/zuiidea/antd-admin/issues/384)
|
||||
- 如何使用mock.js模拟接口,怎么使用线上接口? [#348](https://github.com/zuiidea/antd-admin/issues/348)
|
||||
- 如何使用Iconfont,如何使用本地的svg图标? [#270](https://github.com/zuiidea/antd-admin/issues/270)
|
||||
- 怎么按版本打包,上线时不影响正在访问的用户? [#449](https://github.com/zuiidea/antd-admin/issues/449)
|
||||
- windows处理CRLF?[参考](http://blog.csdn.net/lysc_forever/article/details/42835203)
|
||||
- 如何做权限管理? [#384](https://github.com/zuiidea/antd-admin/issues/384)
|
||||
- 如何使用mock.js模拟接口,怎么使用线上接口? [#348](https://github.com/zuiidea/antd-admin/issues/348)
|
||||
- 如何使用Iconfont,如何使用本地的svg图标? [#270](https://github.com/zuiidea/antd-admin/issues/270)
|
||||
- 怎么按版本打包,上线时不影响正在访问的用户? [#449](https://github.com/zuiidea/antd-admin/issues/449)
|
||||
- windows处理CRLF?[参考](http://blog.csdn.net/lysc_forever/article/details/42835203)
|
||||
|
||||
```bash
|
||||
git config --global core.autocrlf false
|
||||
|
||||
+8
-7
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "antd-admin",
|
||||
"version": "4.3.3",
|
||||
"version": "4.3.6",
|
||||
"dependencies": {
|
||||
"antd": "^2.11.2",
|
||||
"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,14 +23,14 @@
|
||||
"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",
|
||||
"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",
|
||||
@@ -48,13 +50,12 @@
|
||||
"eslint-plugin-jsx-a11y": "^6.0.2",
|
||||
"eslint-plugin-react": "^7.1.0",
|
||||
"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"],
|
||||
"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",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Breadcrumb, Icon } from 'antd'
|
||||
import { Link } from 'dva/router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
import { queryArray } from 'utils'
|
||||
import styles from './Bread.less'
|
||||
@@ -48,7 +48,7 @@ const Bread = ({ menu, location }) => {
|
||||
return (
|
||||
<Breadcrumb.Item key={key}>
|
||||
{((pathArray.length - 1) !== key)
|
||||
? <Link to={item.route}>
|
||||
? <Link to={item.route || '#'}>
|
||||
{content}
|
||||
</Link>
|
||||
: content}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Menu, Icon } from 'antd'
|
||||
import { Link } from 'dva/router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { arrayToTree, queryArray } from 'utils'
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
|
||||
@@ -31,7 +31,7 @@ const Menus = ({ siderFold, darkTheme, handleClickNavMenu, navOpenKeys, changeOp
|
||||
}
|
||||
return (
|
||||
<Menu.Item key={item.id}>
|
||||
<Link to={item.route}>
|
||||
<Link to={item.route || '#'}>
|
||||
{item.icon && <Icon type={item.icon} />}
|
||||
{(!siderFoldN || !menuTree.includes(item)) && item.name}
|
||||
</Link>
|
||||
@@ -112,7 +112,7 @@ const Menus = ({ siderFold, darkTheme, handleClickNavMenu, navOpenKeys, changeOp
|
||||
mode={siderFold ? 'vertical' : 'inline'}
|
||||
theme={darkTheme ? 'dark' : 'light'}
|
||||
onClick={handleClickNavMenu}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
selectedKeys={defaultSelectedKeys}
|
||||
>
|
||||
{menuItems}
|
||||
</Menu>
|
||||
|
||||
@@ -3,8 +3,12 @@ import PropTypes from 'prop-types'
|
||||
import classNames from 'classnames'
|
||||
import styles from './Loader.less'
|
||||
|
||||
const Loader = ({ spinning }) => {
|
||||
return (<div className={classNames(styles.loader, { [styles.hidden]: !spinning })}>
|
||||
const Loader = ({ spinning, fullScreen }) => {
|
||||
return (<div className={classNames(styles.loader, {
|
||||
[styles.hidden]: !spinning,
|
||||
[styles.fullScreen]: fullScreen,
|
||||
})}
|
||||
>
|
||||
<div className={styles.warpper}>
|
||||
<div className={styles.inner} />
|
||||
<div className={styles.text} >LOADING</div>
|
||||
@@ -15,6 +19,7 @@ const Loader = ({ spinning }) => {
|
||||
|
||||
Loader.propTypes = {
|
||||
spinning: PropTypes.bool,
|
||||
fullScreen: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default Loader
|
||||
|
||||
@@ -1,64 +1,68 @@
|
||||
.loader {
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
|
||||
.warpper {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.inner {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin: 0 auto;
|
||||
text-indent: -12345px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.7);
|
||||
border-radius: 50%;
|
||||
z-index: 100001;
|
||||
|
||||
:local {
|
||||
animation: spinner 600ms infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
letter-spacing: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: opacity 1s ease 0.5s, z-index 0.1s ease 1.5s;
|
||||
}
|
||||
}
|
||||
@keyframes spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loader {
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
|
||||
&.fullScreen {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.warpper {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.inner {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin: 0 auto;
|
||||
text-indent: -12345px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.7);
|
||||
border-radius: 50%;
|
||||
z-index: 100001;
|
||||
|
||||
:local {
|
||||
animation: spinner 600ms infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
letter-spacing: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: opacity 1s ease 0.5s, z-index 0.1s ease 1.5s;
|
||||
}
|
||||
}
|
||||
@keyframes spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import Loader from '../Loader'
|
||||
import styles from './Page.less'
|
||||
|
||||
export default class Page extends Component {
|
||||
render () {
|
||||
const { className, children, loading = false, inner = false } = this.props
|
||||
const loadingStyle = {
|
||||
height: 'calc(100vh - 184px)',
|
||||
overflow: 'hidden',
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={classnames(className, {
|
||||
[styles.contentInner]: inner,
|
||||
})}
|
||||
style={loading ? loadingStyle : null}
|
||||
>
|
||||
{loading ? <Loader spinning /> : ''}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Page.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
loading: PropTypes.bool,
|
||||
inner: PropTypes.bool,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
@import "~themes/vars";
|
||||
|
||||
.contentInner{
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
box-shadow: @shadow-1;
|
||||
min-height: e("calc(100vh - 184px)");
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.contentInner {
|
||||
padding: 12px;
|
||||
min-height: e("calc(100vh - 160px)");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Page",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"main": "./Page.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 Page from './Page'
|
||||
|
||||
import layer from './layer'
|
||||
|
||||
@@ -19,4 +20,5 @@ export {
|
||||
FilterItem,
|
||||
Loader,
|
||||
layer,
|
||||
Page,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<% htmlWebpackPlugin.options.headScripts = htmlWebpackPlugin.options.headScripts || [] %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="description" content="A admin dashboard application demo built upon Ant Design and Dva.js">
|
||||
<title>antd admin</title>
|
||||
<!--[if lte IE 10]>
|
||||
<script
|
||||
src="https://as.alipayobjects.com/g/component/??console-polyfill/0.2.2/index.js,media-match/2.0.2/media.match.min.js"></script>
|
||||
<![endif]-->
|
||||
<% for (item of htmlWebpackPlugin.options.headScripts) { %>
|
||||
<script src="<%= item %>"></script>
|
||||
<% } %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
+2
-2
@@ -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)
|
||||
},
|
||||
|
||||
+5
-4
@@ -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),
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -97,10 +98,10 @@ export default {
|
||||
}
|
||||
} else if (config.openPages && config.openPages.indexOf(locationPathname) < 0) {
|
||||
yield put(routerRedux.push({
|
||||
pathname: 'login',
|
||||
query: {
|
||||
pathname: '/login',
|
||||
search: queryString.stringify({
|
||||
from: locationPathname,
|
||||
},
|
||||
}),
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
||||
+2
-1
@@ -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),
|
||||
} })
|
||||
}
|
||||
})
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ import modelExtend from 'dva-model-extend'
|
||||
import { config } from 'utils'
|
||||
import { create, remove, update } from 'services/user'
|
||||
import * as usersService from 'services/users'
|
||||
import queryString from 'query-string'
|
||||
import { pageModel } from './common'
|
||||
|
||||
const { query } = usersService
|
||||
@@ -25,7 +26,7 @@ export default modelExtend(pageModel, {
|
||||
if (location.pathname === '/user') {
|
||||
dispatch({
|
||||
type: 'query',
|
||||
payload: location.query,
|
||||
payload: queryString.parse(location.search),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
+78
-135
@@ -1,149 +1,92 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Router } from 'dva/router'
|
||||
import { 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 <Router history={history} routes={routes} />
|
||||
return (
|
||||
<ConnectedRouter history={history}>
|
||||
<App>
|
||||
<Switch>
|
||||
<Route exact path="/" render={() => (<Redirect to="/dashboard" />)} />
|
||||
{
|
||||
routes.map(({ path, ...dynamics }, key) => (
|
||||
<Route key={key}
|
||||
exact
|
||||
path={path}
|
||||
component={dynamic({
|
||||
app,
|
||||
...dynamics,
|
||||
})}
|
||||
/>
|
||||
))
|
||||
}
|
||||
<Route component={error} />
|
||||
</Switch>
|
||||
</App>
|
||||
</ConnectedRouter>
|
||||
)
|
||||
}
|
||||
|
||||
Routers.propTypes = {
|
||||
|
||||
+5
-3
@@ -7,6 +7,7 @@ import { connect } from 'dva'
|
||||
import { Layout, Loader } from 'components'
|
||||
import { classnames, config } from 'utils'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { withRouter } from 'dva/router'
|
||||
import '../themes/index.less'
|
||||
import './app.less'
|
||||
import Error from './error'
|
||||
@@ -36,6 +37,7 @@ const App = ({ children, dispatch, app, loading, location }) => {
|
||||
const headerProps = {
|
||||
menu,
|
||||
user,
|
||||
location,
|
||||
siderFold,
|
||||
isNavbar,
|
||||
menuPopoverVisible,
|
||||
@@ -75,13 +77,13 @@ const App = ({ children, dispatch, app, loading, location }) => {
|
||||
}
|
||||
if (openPages && openPages.includes(pathname)) {
|
||||
return (<div>
|
||||
<Loader spinning={loading.effects['app/query']} />
|
||||
<Loader fullScreen spinning={loading.effects['app/query']} />
|
||||
{children}
|
||||
</div>)
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Loader spinning={loading.effects['app/query']} />
|
||||
<Loader fullScreen spinning={loading.effects['app/query']} />
|
||||
<Helmet>
|
||||
<title>ANTD ADMIN</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
@@ -116,4 +118,4 @@ App.propTypes = {
|
||||
loading: PropTypes.object,
|
||||
}
|
||||
|
||||
export default connect(({ app, loading }) => ({ app, loading }))(App)
|
||||
export default withRouter(connect(({ app, loading }) => ({ app, loading }))(App))
|
||||
|
||||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import { connect } from 'dva'
|
||||
import { Row, Col, Card } from 'antd'
|
||||
import { color } from 'utils'
|
||||
import { Loader } from 'components'
|
||||
import { Page } from 'components'
|
||||
import { NumberCard, Quote, Sales, Weather, RecentSales, Comments, Completed, Browser, Cpu, User } from './components'
|
||||
import styles from './index.less'
|
||||
|
||||
@@ -21,8 +21,7 @@ function Dashboard ({ dashboard, loading }) {
|
||||
</Col>))
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Loader spinning={loading.models.dashboard && sales.length === 0} />
|
||||
<Page loading={loading.models.dashboard && sales.length === 0}>
|
||||
<Row gutter={24}>
|
||||
{numberCards}
|
||||
<Col lg={18} md={24}>
|
||||
@@ -97,7 +96,7 @@ function Dashboard ({ dashboard, loading }) {
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import { connect } from 'dva'
|
||||
import { Tabs } from 'antd'
|
||||
import { routerRedux } from 'dva/router'
|
||||
import queryString from 'query-string'
|
||||
import List from './List'
|
||||
|
||||
const TabPane = Tabs.TabPane
|
||||
@@ -24,11 +25,11 @@ const Index = ({ post, dispatch, loading, location }) => {
|
||||
onChange (page) {
|
||||
dispatch(routerRedux.push({
|
||||
pathname,
|
||||
query: {
|
||||
search: queryString.stringify({
|
||||
...query,
|
||||
page: page.current,
|
||||
pageSize: page.pageSize,
|
||||
},
|
||||
}),
|
||||
}))
|
||||
},
|
||||
}
|
||||
@@ -36,9 +37,9 @@ const Index = ({ post, dispatch, loading, location }) => {
|
||||
const handleTabClick = (key) => {
|
||||
dispatch(routerRedux.push({
|
||||
pathname,
|
||||
query: {
|
||||
search: queryString.stringify({
|
||||
status: key,
|
||||
},
|
||||
}),
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,16 @@ import PropTypes from 'prop-types'
|
||||
import { Table, Modal } from 'antd'
|
||||
import classnames from 'classnames'
|
||||
import { DropOption } from 'components'
|
||||
import { Link } from 'dva/router'
|
||||
import AnimTableBody from '../../components/DataTable/AnimTableBody'
|
||||
import { Link } from 'react-router-dom'
|
||||
import queryString from 'query-string'
|
||||
import AnimTableBody from 'components/DataTable/AnimTableBody'
|
||||
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)
|
||||
|
||||
@@ -3,11 +3,15 @@ import PropTypes from 'prop-types'
|
||||
import { routerRedux } from 'dva/router'
|
||||
import { connect } from 'dva'
|
||||
import { Row, Col, Button, Popconfirm } from 'antd'
|
||||
import { Page } from 'components'
|
||||
import queryString from 'query-string'
|
||||
import List from './List'
|
||||
import Filter from './Filter'
|
||||
import Modal from './Modal'
|
||||
|
||||
|
||||
const User = ({ location, dispatch, user, loading }) => {
|
||||
location.query = queryString.parse(location.search)
|
||||
const { list, pagination, currentItem, modalVisible, modalType, isMotion, selectedRowKeys } = user
|
||||
const { pageSize } = pagination
|
||||
|
||||
@@ -41,11 +45,11 @@ const User = ({ location, dispatch, user, loading }) => {
|
||||
const { query, pathname } = location
|
||||
dispatch(routerRedux.push({
|
||||
pathname,
|
||||
query: {
|
||||
search: queryString.stringify({
|
||||
...query,
|
||||
page: page.current,
|
||||
pageSize: page.pageSize,
|
||||
},
|
||||
}),
|
||||
}))
|
||||
},
|
||||
onDeleteItem (id) {
|
||||
@@ -84,20 +88,20 @@ const User = ({ location, dispatch, user, loading }) => {
|
||||
onFilterChange (value) {
|
||||
dispatch(routerRedux.push({
|
||||
pathname: location.pathname,
|
||||
query: {
|
||||
search: queryString.stringify({
|
||||
...value,
|
||||
page: 1,
|
||||
pageSize,
|
||||
},
|
||||
}),
|
||||
}))
|
||||
},
|
||||
onSearch (fieldsValue) {
|
||||
fieldsValue.keyword.length ? dispatch(routerRedux.push({
|
||||
pathname: '/user',
|
||||
query: {
|
||||
search: queryString.stringify({
|
||||
field: fieldsValue.field,
|
||||
keyword: fieldsValue.keyword,
|
||||
},
|
||||
}),
|
||||
})) : dispatch(routerRedux.push({
|
||||
pathname: '/user',
|
||||
}))
|
||||
@@ -125,7 +129,7 @@ const User = ({ location, dispatch, user, loading }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="content-inner">
|
||||
<Page inner>
|
||||
<Filter {...filterProps} />
|
||||
{
|
||||
selectedRowKeys.length > 0 &&
|
||||
@@ -140,7 +144,7 @@ const User = ({ location, dispatch, user, loading }) => {
|
||||
}
|
||||
<List {...listProps} />
|
||||
{modalVisible && <Modal {...modalProps} />}
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+9
-28
@@ -1,24 +1,18 @@
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const HtmlWebpackTemplate = require('html-webpack-template')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const webpack = require('webpack')
|
||||
|
||||
module.exports = (webpackConfig, env) => {
|
||||
const production = env === 'production'
|
||||
// FilenameHash
|
||||
webpackConfig.output.chunkFilename = '[name].[hash].js'
|
||||
webpackConfig.output.chunkFilename = '[name].[chunkhash].js'
|
||||
|
||||
if (production) {
|
||||
if (webpackConfig.module) {
|
||||
// ClassnameHash
|
||||
// ClassnameHash
|
||||
webpackConfig.module.rules.map((item) => {
|
||||
if (item.use && item.use[0] === 'style') {
|
||||
return item.use.map((iitem) => {
|
||||
if (iitem && iitem.loader === 'css') {
|
||||
iitem.options.localIdentName = '[hash:base64:5]'
|
||||
}
|
||||
return iitem
|
||||
})
|
||||
if (String(item.test) === '/\\.less$/' || String(item.test) === '/\\.css/') {
|
||||
item.use.filter(iitem => iitem.loader === 'css')[0].options.localIdentName = '[hash:base64:5]'
|
||||
}
|
||||
return item
|
||||
})
|
||||
@@ -39,26 +33,13 @@ module.exports = (webpackConfig, env) => {
|
||||
},
|
||||
]),
|
||||
new HtmlWebpackPlugin({
|
||||
hash: true,
|
||||
mobile: true,
|
||||
title: 'antd-admin',
|
||||
inject: false,
|
||||
appMountId: 'root',
|
||||
template: `!!ejs-loader!${HtmlWebpackTemplate}`,
|
||||
template: `${__dirname}/src/entry.ejs`,
|
||||
filename: production ? '../index.html' : 'index.html',
|
||||
minify: {
|
||||
minify: production ? {
|
||||
collapseWhitespace: true,
|
||||
},
|
||||
scripts: production ? null : ['/roadhog.dll.js'],
|
||||
meta: [
|
||||
{
|
||||
name: 'description',
|
||||
content: 'A admin dashboard application demo built upon Ant Design and Dva.js',
|
||||
}, {
|
||||
name: 'viewport',
|
||||
content: 'width=device-width, initial-scale=1.0',
|
||||
},
|
||||
],
|
||||
} : null,
|
||||
hash: true,
|
||||
headScripts: production ? null : ['/roadhog.dll.js'],
|
||||
}),
|
||||
])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user