mirror of
https://github.com/zuiidea/antd-admin.git
synced 2026-10-20 18:31:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
587b1f6b9d | ||
|
|
d94580a253 | ||
|
|
531e3c0fcc | ||
|
|
d68de7a30c | ||
|
|
45cb70f006 | ||
|
|
af85384f11 | ||
|
|
208539134f | ||
|
|
a3f41e3d64 | ||
|
|
3855c402c9 | ||
|
|
6a58d8434b | ||
|
|
d26a92ce79 | ||
|
|
0d20717c3c | ||
|
|
a0d81dcda9 | ||
|
|
4490af8553 | ||
|
|
75cc86152d | ||
|
|
3d9f263330 | ||
|
|
70b5d05f1a | ||
|
|
4da23b9133 | ||
|
|
da1c52e82b | ||
|
|
6ae39bfd55 | ||
|
|
d86f0ebd78 | ||
|
|
ecbd8bf51e | ||
|
|
0c9fabe2b4 | ||
|
|
0f27528d2f | ||
|
|
a36d44d402 | ||
|
|
b2b0aa872f | ||
|
|
a320c77ecb | ||
|
|
7f091d7642 | ||
|
|
d8f222f312 | ||
|
|
f6021cbaa4 |
@@ -1 +1,2 @@
|
||||
src/**/*-test.js
|
||||
src/public
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
dist
|
||||
node_modules
|
||||
yarn.lock
|
||||
npm-debug.log
|
||||
dist
|
||||
node_modules
|
||||
yarn.lock
|
||||
npm-debug.log
|
||||
|
||||
+12
-12
@@ -13,18 +13,18 @@ export default {
|
||||
publicPath : `/${version}/`,
|
||||
outputPath : `./dist/${version}`,
|
||||
// 接口代理示例
|
||||
// "proxy": {
|
||||
// "/api/v1": {
|
||||
// "target": "http://api.zuiidea.com",
|
||||
// "changeOrigin": true,
|
||||
// "pathRewrite": { "^/api/v1" : "/v1" }
|
||||
// },
|
||||
// "/api/v2": {
|
||||
// "target": "http://192.168.0.110",
|
||||
// "changeOrigin": true,
|
||||
// "pathRewrite": { "^/api/v2" : "/api/v2" }
|
||||
// }
|
||||
// },
|
||||
proxy: {
|
||||
"/api/v1/weather": {
|
||||
"target": "https://api.seniverse.com/",
|
||||
"changeOrigin": true,
|
||||
"pathRewrite": { "^/api/v1/weather" : "/v3/weather" }
|
||||
},
|
||||
// "/api/v2": {
|
||||
// "target": "http://192.168.0.110",
|
||||
// "changeOrigin": true,
|
||||
// "pathRewrite": { "^/api/v2" : "/api/v2" }
|
||||
// }
|
||||
},
|
||||
env : {
|
||||
development: {
|
||||
extraBabelPlugins: [
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
[](http://standardjs.com)
|
||||
|
||||
演示地址 <http://zuiidea.github.io/antd-admin> \| [备用地址](http://47.92.30.98:8000)
|
||||
演示地址 <http://antd-admin.zuiidea.com>
|
||||
|
||||
## 特性
|
||||
|
||||
@@ -53,9 +53,9 @@
|
||||
|
||||
`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)
|
||||
- 修改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)
|
||||
|
||||
@@ -99,11 +99,16 @@
|
||||
|
||||
克隆项目文件:
|
||||
|
||||
git clone https://github.com/zuiidea/antd-admin.git
|
||||
```bash
|
||||
git clone https://github.com/zuiidea/antd-admin.git
|
||||
```
|
||||
|
||||
进入目录安装依赖:
|
||||
|
||||
npm i 或者 yarn install
|
||||
```bash
|
||||
#开始前请确保没有安装roadhog、webpack到NPM全局目录
|
||||
npm i 或者 yarn install
|
||||
```
|
||||
|
||||
开发:
|
||||
|
||||
@@ -114,11 +119,16 @@ npm run dev
|
||||
```
|
||||
|
||||
构建:
|
||||
[详情](https://github.com/zuiidea/antd-admin/issues/269)
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
|
||||
将会生成dist目录
|
||||
将会打包至dist/{version}目录 #package.json里version字段
|
||||
|
||||
npm run build:new
|
||||
|
||||
将会打包至dist/{version增加1}目录 #package.json里version字段
|
||||
```
|
||||
|
||||
代码检测:
|
||||
@@ -129,11 +139,16 @@ npm run lint
|
||||
|
||||
## FAQ
|
||||
|
||||
- 项目打包后如何部署? [#269](https://github.com/zuiidea/antd-admin/issues/269)
|
||||
- 项目打包后如何部署? [#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)
|
||||
|
||||
```bash
|
||||
git config --global core.autocrlf false
|
||||
```
|
||||
|
||||
## 参考
|
||||
|
||||
|
||||
+9
-8
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "antd-admin",
|
||||
"version": "4.3.0",
|
||||
"version": "4.3.3",
|
||||
"dependencies": {
|
||||
"antd": "^2.11.2",
|
||||
"axios": "^0.16.2",
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"classnames": "^2.2.5",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"d3-shape": "^1.2.0",
|
||||
"draftjs-to-markdown": "^0.4.0",
|
||||
"dva": "^1.2.0",
|
||||
"dva-loading": "^0.2.0",
|
||||
"ejs-loader": "^0.3.0",
|
||||
"js-beautify": "^1.6.14",
|
||||
"jsonp": "^0.2.1",
|
||||
"less-vars-to-js": "^1.1.2",
|
||||
"lodash": "^4.17.4",
|
||||
@@ -27,7 +27,8 @@
|
||||
"react-dom": "^15.6.1",
|
||||
"react-draft-wysiwyg": "^1.10.0",
|
||||
"react-helmet": "^5.1.3",
|
||||
"recharts": "^0.22.4"
|
||||
"recharts": "^0.22.4",
|
||||
"roadhog": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^7.2.3",
|
||||
@@ -36,6 +37,7 @@
|
||||
"babel-plugin-import": "^1.1.1",
|
||||
"babel-plugin-transform-runtime": "^6.9.0",
|
||||
"babel-runtime": "^6.9.2",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"draftjs-to-html": "^0.7.0",
|
||||
"dva-model-extend": "^0.1.1",
|
||||
"eslint": "^4.1.1",
|
||||
@@ -50,13 +52,12 @@
|
||||
"redbox-react": "^1.2.10",
|
||||
"roadhog": "1.0.0-beta.7"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint"
|
||||
],
|
||||
"pre-commit": ["lint"],
|
||||
"scripts": {
|
||||
"dev": "set BROWSER=none&&set HOST=0.0.0.0&&roadhog server",
|
||||
"lint": "eslint --fix --ext .js src",
|
||||
"build": "roadhog build",
|
||||
"build:dll": "roadhog buildDll"
|
||||
"build:dll": "roadhog buildDll",
|
||||
"build:new": "node version && roadhog build"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global location */
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Breadcrumb, Icon } from 'antd'
|
||||
@@ -7,7 +6,7 @@ import pathToRegexp from 'path-to-regexp'
|
||||
import { queryArray } from 'utils'
|
||||
import styles from './Bread.less'
|
||||
|
||||
const Bread = ({ menu }) => {
|
||||
const Bread = ({ menu, location }) => {
|
||||
// 匹配当前路由
|
||||
let pathArray = []
|
||||
let current
|
||||
@@ -68,6 +67,7 @@ const Bread = ({ menu }) => {
|
||||
|
||||
Bread.propTypes = {
|
||||
menu: PropTypes.array,
|
||||
location: PropTypes.object,
|
||||
}
|
||||
|
||||
export default Bread
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@import "../../themes/vars.less";
|
||||
|
||||
.bread {
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
margin-bottom: -24px;
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.bread {
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
margin-bottom: -24px;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@import "../../themes/vars.less";
|
||||
|
||||
.footer {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
background: #fff;
|
||||
box-shadow: @shadow-2;
|
||||
width: 100%;
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.footer {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
background: #fff;
|
||||
box-shadow: @shadow-2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
@import "../../themes/vars.less";
|
||||
|
||||
.header {
|
||||
:global .ant-menu-horizontal {
|
||||
& > .ant-menu-submenu {
|
||||
float: right;
|
||||
}
|
||||
border: none;
|
||||
display: inline-block;
|
||||
}
|
||||
box-shadow: @shadow-2;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 47px;
|
||||
background-color: #fff;
|
||||
z-index: 999;
|
||||
|
||||
.rightWarpper {
|
||||
display: flex;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 47px;
|
||||
height: 47px;
|
||||
line-height: 47px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
transition: @transition-ease-in;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
background-color: fade(@primary-color, 15%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.popovermenu {
|
||||
width: 280px;
|
||||
margin-left: 6px;
|
||||
|
||||
:global .ant-popover-inner-content {
|
||||
padding: 0;
|
||||
|
||||
.ant-menu-inline .ant-menu-item,
|
||||
.ant-menu-vertical .ant-menu-item {
|
||||
border-right: 0;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
.ant-menu-inline .ant-menu-item-selected,
|
||||
.ant-menu-inline .ant-menu-selected {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.header {
|
||||
:global .ant-menu-horizontal {
|
||||
& > .ant-menu-submenu {
|
||||
float: right;
|
||||
}
|
||||
border: none;
|
||||
display: inline-block;
|
||||
}
|
||||
box-shadow: @shadow-2;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 47px;
|
||||
background-color: #fff;
|
||||
z-index: 999;
|
||||
|
||||
.rightWarpper {
|
||||
display: flex;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 47px;
|
||||
height: 47px;
|
||||
line-height: 47px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
transition: @transition-ease-in;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
background-color: fade(@primary-color, 15%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.popovermenu {
|
||||
width: 280px;
|
||||
margin-left: 6px;
|
||||
|
||||
:global .ant-popover-inner-content {
|
||||
padding: 0;
|
||||
|
||||
.ant-menu-inline .ant-menu-item,
|
||||
.ant-menu-vertical .ant-menu-item {
|
||||
border-right: 0;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
.ant-menu-inline .ant-menu-item-selected,
|
||||
.ant-menu-inline .ant-menu-selected {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+292
-292
@@ -1,292 +1,292 @@
|
||||
@import "../../themes/vars.less";
|
||||
|
||||
.layout {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
|
||||
&.withnavbar {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.fold {
|
||||
.sider {
|
||||
width: 42px;
|
||||
|
||||
.logo {
|
||||
img {
|
||||
width: 28px;
|
||||
margin: 6px 7px;
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-menu-root {
|
||||
width: 100%;
|
||||
overflow: visible;
|
||||
|
||||
& > .ant-menu-item {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
|
||||
.anticon {
|
||||
font-size: 14px;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > .ant-menu-submenu {
|
||||
& > .ant-menu-submenu-title {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
|
||||
.anticon {
|
||||
font-size: 14px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.sider {
|
||||
width: 224px;
|
||||
background: #3e3e3e;
|
||||
position: absolute;
|
||||
overflow: visible;
|
||||
padding-bottom: 24px;
|
||||
height: 100vh;
|
||||
transition: @transition-ease-out;
|
||||
box-shadow: @shadow-1;
|
||||
color: #999;
|
||||
|
||||
&.light {
|
||||
background: #fff;
|
||||
|
||||
.switchtheme {
|
||||
background: #fff;
|
||||
border-top: solid 1px #f8f8f8;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
margin: 28px 0;
|
||||
transition: @transition-ease-out;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
transition: @transition-ease-out;
|
||||
}
|
||||
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.anticon {
|
||||
transition: @transition-ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.switchtheme {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 48px;
|
||||
background-color: @dark-half;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 16px 0 24px;
|
||||
overflow: hidden;
|
||||
z-index: 1000;
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
min-width: 14px;
|
||||
margin-right: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-menu-dark,
|
||||
.ant-menu-dark .ant-menu-sub {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ant-menu-root {
|
||||
height: ~"calc(100vh - 144px)";
|
||||
overflow-x: hidden;
|
||||
border-right: none;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-vertical {
|
||||
.ant-menu-sub {
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.ant-menu-submenu-active {
|
||||
.ant-menu-sub {
|
||||
height: auto;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu {
|
||||
transition: @transition-ease-out;
|
||||
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu-title {
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 224px;
|
||||
overflow: auto;
|
||||
height: 100vh;
|
||||
transition: @transition-ease-out;
|
||||
|
||||
:global {
|
||||
.content-inner {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
box-shadow: @shadow-1;
|
||||
min-height: e("calc(100vh - 184px)");
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 24px;
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: e("calc(100vh - 184px)");
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global .ant-menu-dark {
|
||||
color: #999;
|
||||
background-color: #3e3e3e;
|
||||
|
||||
.ant-menu-submenu-title:hover,
|
||||
.ant-menu-submenu:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.ant-menu-sub {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ant-menu-submenu-selected {
|
||||
color: @primary-color;
|
||||
|
||||
&:not(.ant-menu-submenu-open) {
|
||||
background-color: @dark-half;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu-title {
|
||||
& > a {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&:hover > a {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-inline {
|
||||
.ant-menu-item-selected {
|
||||
background-color: @dark-half;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu-item-selected {
|
||||
color: @primary-color;
|
||||
background-color: @dark-half;
|
||||
|
||||
& > a {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: @dark-half;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spin {
|
||||
:global .ant-spin-container {
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.layout {
|
||||
.main {
|
||||
.container {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.bread {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: e("calc(100vh - 160px)");
|
||||
}
|
||||
|
||||
:global {
|
||||
.content-inner {
|
||||
padding: 12px;
|
||||
min-height: e("calc(100vh - 160px)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.layout {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
|
||||
&.withnavbar {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.fold {
|
||||
.sider {
|
||||
width: 42px;
|
||||
|
||||
.logo {
|
||||
img {
|
||||
width: 28px;
|
||||
margin: 6px 7px;
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-menu-root {
|
||||
width: 100%;
|
||||
overflow: visible;
|
||||
|
||||
& > .ant-menu-item {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
|
||||
.anticon {
|
||||
font-size: 14px;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > .ant-menu-submenu {
|
||||
& > .ant-menu-submenu-title {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
|
||||
.anticon {
|
||||
font-size: 14px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.sider {
|
||||
width: 224px;
|
||||
background: #3e3e3e;
|
||||
position: absolute;
|
||||
overflow: visible;
|
||||
padding-bottom: 24px;
|
||||
height: 100vh;
|
||||
transition: @transition-ease-out;
|
||||
box-shadow: @shadow-1;
|
||||
color: #999;
|
||||
|
||||
&.light {
|
||||
background: #fff;
|
||||
|
||||
.switchtheme {
|
||||
background: #fff;
|
||||
border-top: solid 1px #f8f8f8;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
margin: 28px 0;
|
||||
transition: @transition-ease-out;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 40px;
|
||||
margin-right: 8px;
|
||||
transition: @transition-ease-out;
|
||||
}
|
||||
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.anticon {
|
||||
transition: @transition-ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.switchtheme {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 48px;
|
||||
background-color: @dark-half;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 16px 0 24px;
|
||||
overflow: hidden;
|
||||
z-index: 1000;
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
min-width: 14px;
|
||||
margin-right: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-menu-dark,
|
||||
.ant-menu-dark .ant-menu-sub {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ant-menu-root {
|
||||
height: ~"calc(100vh - 144px)";
|
||||
overflow-x: hidden;
|
||||
border-right: none;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-vertical {
|
||||
.ant-menu-sub {
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.ant-menu-submenu-active {
|
||||
.ant-menu-sub {
|
||||
height: auto;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu {
|
||||
transition: @transition-ease-out;
|
||||
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu-title {
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 224px;
|
||||
overflow: auto;
|
||||
height: 100vh;
|
||||
transition: @transition-ease-out;
|
||||
|
||||
:global {
|
||||
.content-inner {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
box-shadow: @shadow-1;
|
||||
min-height: e("calc(100vh - 184px)");
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 24px;
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: e("calc(100vh - 184px)");
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global .ant-menu-dark {
|
||||
color: #999;
|
||||
background-color: #3e3e3e;
|
||||
|
||||
.ant-menu-submenu-title:hover,
|
||||
.ant-menu-submenu:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.ant-menu-sub {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ant-menu-submenu-selected {
|
||||
color: @primary-color;
|
||||
|
||||
&:not(.ant-menu-submenu-open) {
|
||||
background-color: @dark-half;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu-title {
|
||||
& > a {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&:hover > a {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-inline {
|
||||
.ant-menu-item-selected {
|
||||
background-color: @dark-half;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu-item-selected {
|
||||
color: @primary-color;
|
||||
background-color: @dark-half;
|
||||
|
||||
& > a {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: @dark-half;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spin {
|
||||
:global .ant-spin-container {
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.layout {
|
||||
.main {
|
||||
.container {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.bread {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: e("calc(100vh - 160px)");
|
||||
}
|
||||
|
||||
:global {
|
||||
.content-inner {
|
||||
padding: 12px;
|
||||
min-height: e("calc(100vh - 160px)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global location */
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Menu, Icon } from 'antd'
|
||||
@@ -6,7 +5,7 @@ import { Link } from 'dva/router'
|
||||
import { arrayToTree, queryArray } from 'utils'
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
|
||||
const Menus = ({ siderFold, darkTheme, handleClickNavMenu, navOpenKeys, changeOpenKeys, menu }) => {
|
||||
const Menus = ({ siderFold, darkTheme, handleClickNavMenu, navOpenKeys, changeOpenKeys, menu, location }) => {
|
||||
// 生成树状
|
||||
const menuTree = arrayToTree(menu.filter(_ => _.mpid !== '-1'), 'id', 'mpid')
|
||||
const levelMap = {}
|
||||
@@ -103,6 +102,10 @@ const Menus = ({ siderFold, darkTheme, handleClickNavMenu, navOpenKeys, changeOp
|
||||
defaultSelectedKeys = getPathArray(menu, currentMenu, 'mpid', 'id')
|
||||
}
|
||||
|
||||
if (!defaultSelectedKeys) {
|
||||
defaultSelectedKeys = ['1']
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu
|
||||
{...menuProps}
|
||||
@@ -123,6 +126,7 @@ Menus.propTypes = {
|
||||
handleClickNavMenu: PropTypes.func,
|
||||
navOpenKeys: PropTypes.array,
|
||||
changeOpenKeys: PropTypes.func,
|
||||
location: PropTypes.object,
|
||||
}
|
||||
|
||||
export default Menus
|
||||
|
||||
@@ -1 +1 @@
|
||||
@import "../../themes/vars.less";
|
||||
@import "~themes/vars";
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<!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">
|
||||
<link rel="stylesheet" href="/index.css" />
|
||||
<!--[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]-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var __oldConsoleError = window.console.error.bind(console)
|
||||
window.console.error = function(message, b) {
|
||||
if (message === "Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead." ||
|
||||
"Warning: A Component: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.") {
|
||||
return false
|
||||
}
|
||||
__oldConsoleError(message)
|
||||
}
|
||||
})()
|
||||
</script>
|
||||
<script src="roadhog.dll.js"></script>
|
||||
<script src="/index.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -3,7 +3,6 @@ import dva from 'dva'
|
||||
import createLoading from 'dva-loading'
|
||||
import { browserHistory } from 'dva/router'
|
||||
import 'babel-polyfill'
|
||||
import './index.html'
|
||||
|
||||
// 1. Initialize
|
||||
const app = dva({
|
||||
|
||||
+28
-7
@@ -5,8 +5,8 @@ import { routerRedux } from 'dva/router'
|
||||
import { parse } from 'qs'
|
||||
import config from 'config'
|
||||
import { EnumRoleType } from 'enums'
|
||||
import { query, logout } from '../services/app'
|
||||
import * as menusService from '../services/menus'
|
||||
import { query, logout } from 'services/app'
|
||||
import * as menusService from 'services/menus'
|
||||
|
||||
const { prefix } = config
|
||||
|
||||
@@ -30,9 +30,23 @@ export default {
|
||||
darkTheme: window.localStorage.getItem(`${prefix}darkTheme`) === 'true',
|
||||
isNavbar: document.body.clientWidth < 769,
|
||||
navOpenKeys: JSON.parse(window.localStorage.getItem(`${prefix}navOpenKeys`)) || [],
|
||||
locationPathname: '',
|
||||
locationQuery: {},
|
||||
},
|
||||
subscriptions: {
|
||||
|
||||
setupHistory ({ dispatch, history }) {
|
||||
history.listen((location) => {
|
||||
dispatch({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
locationPathname: location.pathname,
|
||||
locationQuery: location.query,
|
||||
},
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setup ({ dispatch }) {
|
||||
dispatch({ type: 'query' })
|
||||
let tid
|
||||
@@ -49,8 +63,9 @@ export default {
|
||||
|
||||
* query ({
|
||||
payload,
|
||||
}, { call, put }) {
|
||||
}, { call, put, select }) {
|
||||
const { success, user } = yield call(query, payload)
|
||||
const { locationPathname } = yield select(_ => _.app)
|
||||
if (success && user) {
|
||||
const { list } = yield call(menusService.query)
|
||||
const { permissions } = user
|
||||
@@ -76,11 +91,17 @@ export default {
|
||||
},
|
||||
})
|
||||
if (location.pathname === '/login') {
|
||||
yield put(routerRedux.push('/dashboard'))
|
||||
yield put(routerRedux.push({
|
||||
pathname: '/dashboard',
|
||||
}))
|
||||
}
|
||||
} else if (config.openPages && config.openPages.indexOf(location.pathname) < 0) {
|
||||
let from = location.pathname
|
||||
window.location = `${location.origin}/login?from=${from}`
|
||||
} else if (config.openPages && config.openPages.indexOf(locationPathname) < 0) {
|
||||
yield put(routerRedux.push({
|
||||
pathname: 'login',
|
||||
query: {
|
||||
from: locationPathname,
|
||||
},
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+40
-194
@@ -1,176 +1,17 @@
|
||||
import { parse } from 'qs'
|
||||
import { myCity, queryWeather, query } from '../services/dashboard'
|
||||
import modelExtend from 'dva-model-extend'
|
||||
import { query } from 'services/dashboard'
|
||||
import { model } from 'models/common'
|
||||
import * as weatherService from 'services/weather'
|
||||
|
||||
// zuimei 摘自 http://www.zuimeitianqi.com/res/js/index.js
|
||||
let zuimei = {
|
||||
parseActualData (actual) {
|
||||
let weather = {
|
||||
icon: `http://www.zuimeitianqi.com/res/icon/${zuimei.getIconName(actual.wea, 'big')}`,
|
||||
name: zuimei.getWeatherName(actual.wea),
|
||||
temperature: actual.tmp,
|
||||
dateTime: new Date(actual.PTm).format('MM-dd hh:mm'),
|
||||
}
|
||||
return weather
|
||||
},
|
||||
|
||||
getIconName (wea, flg) {
|
||||
let myDate = new Date()
|
||||
let hour = myDate.getHours()
|
||||
let num = 0
|
||||
if (wea.indexOf('/') !== -1) {
|
||||
let weas = wea.split('/')
|
||||
if (hour < 12) {
|
||||
num = zuimei.replaceIcon(weas[0])
|
||||
if (num < 6) {
|
||||
num = `${num}_${flg}_night.png`
|
||||
} else {
|
||||
num = `${num}_${flg}.png`
|
||||
}
|
||||
} else if (hour >= 12) {
|
||||
num = zuimei.replaceIcon(weas[1])
|
||||
if (hour >= 18) {
|
||||
num = `${num}_${flg}_night.png`
|
||||
} else {
|
||||
num = `${num}_${flg}.png`
|
||||
}
|
||||
}
|
||||
} else if ((hour >= 18 && hour <= 23) || (hour >= 0 && hour <= 6)) {
|
||||
num = `${num}_${flg}_night.png`
|
||||
} else {
|
||||
num = `${num}_${flg}.png`
|
||||
}
|
||||
|
||||
return num
|
||||
},
|
||||
|
||||
replaceIcon (num) {
|
||||
if (num === 21) {
|
||||
num = 7
|
||||
} else if (num === 22) {
|
||||
num = 8
|
||||
} else if (num === 10 || num === 11 || num === 12 || num === 23 || num === 24 || num === 25) {
|
||||
num = 9
|
||||
} else if (num === 13 || num === 15 || num === 26 || num === 27 || num === 34) {
|
||||
num = 14
|
||||
} else if (num === 17 || num === 28) {
|
||||
num = 16
|
||||
} else if (num === 35) {
|
||||
num = 18
|
||||
} else if (num === 31 || num === 32 || num === 33) {
|
||||
num = 20
|
||||
} else if (num === 30) {
|
||||
num = 29
|
||||
}
|
||||
|
||||
return num
|
||||
},
|
||||
|
||||
getWeatherName (wea) {
|
||||
let name = ''
|
||||
if (wea.indexOf('/') !== -1) {
|
||||
let weas = wea.split('/')
|
||||
name = `${zuimei.getWeatherByCode(weas[0])}转${zuimei.getWeatherByCode(weas[1])}`
|
||||
} else {
|
||||
name = zuimei.getWeatherByCode(wea)
|
||||
}
|
||||
|
||||
return name
|
||||
},
|
||||
|
||||
getWeatherByCode (number) {
|
||||
let wea = ''
|
||||
let num = Number(number)
|
||||
if (num === 0) {
|
||||
wea = '晴'
|
||||
} else if (num === 1) {
|
||||
wea = '多云'
|
||||
} else if (num === 2) {
|
||||
wea = '阴'
|
||||
} else if (num === 3) {
|
||||
wea = '阵雨'
|
||||
} else if (num === 4) {
|
||||
wea = '雷阵雨'
|
||||
} else if (num === 5) {
|
||||
wea = '雷阵雨并伴有冰雹'
|
||||
} else if (num === 6) {
|
||||
wea = '雨夹雪'
|
||||
} else if (num === 7) {
|
||||
wea = '小雨'
|
||||
} else if (num === 8) {
|
||||
wea = '中雨'
|
||||
} else if (num === 9) {
|
||||
wea = '大雨'
|
||||
} else if (num === 10) {
|
||||
wea = '暴雨'
|
||||
} else if (num === 11) {
|
||||
wea = '大暴雨'
|
||||
} else if (num === 12) {
|
||||
wea = '特大暴雨'
|
||||
} else if (num === 13) {
|
||||
wea = '阵雪'
|
||||
} else if (num === 14) {
|
||||
wea = '小雪'
|
||||
} else if (num === 15) {
|
||||
wea = '中雪'
|
||||
} else if (num === 16) {
|
||||
wea = '大雪'
|
||||
} else if (num === 17) {
|
||||
wea = '暴雪'
|
||||
} else if (num === 18) {
|
||||
wea = '雾'
|
||||
} else if (num === 19) {
|
||||
wea = '冻雨'
|
||||
} else if (num === 20) {
|
||||
wea = '沙尘暴'
|
||||
} else if (num === 21) {
|
||||
wea = '小雨-中雨'
|
||||
} else if (num === 22) {
|
||||
wea = '中雨-大雨'
|
||||
} else if (num === 23) {
|
||||
wea = '大雨-暴雨'
|
||||
} else if (num === 24) {
|
||||
wea = '暴雨-大暴雨'
|
||||
} else if (num === 25) {
|
||||
wea = '大暴雨-特大暴雨'
|
||||
} else if (num === 26) {
|
||||
wea = '小雪-中雪'
|
||||
} else if (num === 27) {
|
||||
wea = '中雪-大雪'
|
||||
} else if (num === 28) {
|
||||
wea = '大雪-暴雪'
|
||||
} else if (num === 29) {
|
||||
wea = '浮沉'
|
||||
} else if (num === 30) {
|
||||
wea = '扬沙'
|
||||
} else if (num === 31) {
|
||||
wea = '强沙尘暴'
|
||||
} else if (num === 32) {
|
||||
wea = '飑'
|
||||
} else if (num === 33) {
|
||||
wea = '龙卷风'
|
||||
} else if (num === 34) {
|
||||
wea = '若高吹雪'
|
||||
} else if (num === 35) {
|
||||
wea = '轻雾'
|
||||
} else if (num === 53) {
|
||||
wea = '霾'
|
||||
} else if (num === 99) {
|
||||
wea = '未知'
|
||||
}
|
||||
|
||||
return wea
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
export default modelExtend(model, {
|
||||
namespace: 'dashboard',
|
||||
state: {
|
||||
weather: {
|
||||
city: '成都',
|
||||
temperature: '5',
|
||||
city: '深圳',
|
||||
temperature: '30',
|
||||
name: '晴',
|
||||
icon: 'http://www.zuimeitianqi.com/res/icon/0_big.png',
|
||||
dateTime: new Date().format('MM-dd hh:mm'),
|
||||
icon: '//s5.sencdn.com/web/icons/3d_50/2.png',
|
||||
},
|
||||
sales: [],
|
||||
quote: {
|
||||
@@ -187,9 +28,13 @@ export default {
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup ({ dispatch }) {
|
||||
dispatch({ type: 'query' })
|
||||
dispatch({ type: 'queryWeather' })
|
||||
setup ({ dispatch, history }) {
|
||||
history.listen(({ pathname }) => {
|
||||
if (pathname === '/dashboard' || pathname === '/') {
|
||||
dispatch({ type: 'query' })
|
||||
dispatch({ type: 'queryWeather' })
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
@@ -197,31 +42,32 @@ export default {
|
||||
payload,
|
||||
}, { call, put }) {
|
||||
const data = yield call(query, parse(payload))
|
||||
yield put({ type: 'queryWeather', payload: { ...data } })
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: data,
|
||||
})
|
||||
},
|
||||
* queryWeather (action, { call, put }) {
|
||||
const myCityResult = yield call(myCity, { flg: 0 })
|
||||
const result = yield call(queryWeather, { cityCode: myCityResult.selectCityCode })
|
||||
const weather = zuimei.parseActualData(result.data.actual)
|
||||
weather.city = myCityResult.selectCityName
|
||||
yield put({ type: 'queryWeatherSuccess',
|
||||
payload: {
|
||||
weather,
|
||||
} })
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
queryWeatherSuccess (state, action) {
|
||||
return {
|
||||
...state,
|
||||
...action.payload,
|
||||
}
|
||||
},
|
||||
queryWeather (state, action) {
|
||||
return {
|
||||
...state,
|
||||
...action.payload,
|
||||
* queryWeather ({
|
||||
payload = {},
|
||||
}, { call, put }) {
|
||||
payload.location = 'shenzhen'
|
||||
const result = yield call(weatherService.query, payload)
|
||||
const { success } = result
|
||||
if (success) {
|
||||
const data = result.results[0]
|
||||
const weather = {
|
||||
city: data.location.name,
|
||||
temperature: data.now.temperature,
|
||||
name: data.now.text,
|
||||
icon: `//s5.sencdn.com/web/icons/3d_50/${data.now.code}.png`,
|
||||
}
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
weather,
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
+8
-24
@@ -1,24 +1,21 @@
|
||||
import { routerRedux } from 'dva/router'
|
||||
import { queryURL } from 'utils'
|
||||
import { login } from '../services/login'
|
||||
import { login } from 'services/login'
|
||||
|
||||
export default {
|
||||
namespace: 'login',
|
||||
state: {
|
||||
loginLoading: false,
|
||||
},
|
||||
|
||||
state: {},
|
||||
|
||||
effects: {
|
||||
* login ({
|
||||
payload,
|
||||
}, { put, call }) {
|
||||
yield put({ type: 'showLoginLoading' })
|
||||
}, { put, call, select }) {
|
||||
const data = yield call(login, payload)
|
||||
yield put({ type: 'hideLoginLoading' })
|
||||
const { locationQuery } = yield select(_ => _.app)
|
||||
if (data.success) {
|
||||
const from = queryURL('from')
|
||||
const { from } = locationQuery
|
||||
yield put({ type: 'app/query' })
|
||||
if (from) {
|
||||
if (from && from !== '/login') {
|
||||
yield put(routerRedux.push(from))
|
||||
} else {
|
||||
yield put(routerRedux.push('/dashboard'))
|
||||
@@ -28,18 +25,5 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
showLoginLoading (state) {
|
||||
return {
|
||||
...state,
|
||||
loginLoading: true,
|
||||
}
|
||||
},
|
||||
hideLoginLoading (state) {
|
||||
return {
|
||||
...state,
|
||||
loginLoading: false,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import modelExtend from 'dva-model-extend'
|
||||
import { query } from '../services/posts'
|
||||
import { pageModel } from './common'
|
||||
import { query } from 'services/posts'
|
||||
import { pageModel } from 'models/common'
|
||||
|
||||
export default modelExtend(pageModel, {
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
/* global window */
|
||||
import modelExtend from 'dva-model-extend'
|
||||
import { config } from 'utils'
|
||||
import { create, remove, update } from '../services/user'
|
||||
import * as usersService from '../services/users'
|
||||
import { create, remove, update } from 'services/user'
|
||||
import * as usersService from 'services/users'
|
||||
import { pageModel } from './common'
|
||||
|
||||
const { query } = usersService
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global location */
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
import { query } from '../../services/user'
|
||||
|
||||
@@ -12,8 +11,8 @@ export default {
|
||||
|
||||
subscriptions: {
|
||||
setup ({ dispatch, history }) {
|
||||
history.listen(() => {
|
||||
const match = pathToRegexp('/user/:id').exec(location.pathname)
|
||||
history.listen(({ pathname }) => {
|
||||
const match = pathToRegexp('/user/:id').exec(pathname)
|
||||
if (match) {
|
||||
dispatch({ type: 'query', payload: { id: match[1] } })
|
||||
}
|
||||
|
||||
+24
-24
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Router } from 'dva/router'
|
||||
import App from './routes/app'
|
||||
import App from 'routes/app'
|
||||
|
||||
const registerModel = (app, model) => {
|
||||
if (!(app._models.filter(m => m.namespace === model.namespace).length === 1)) {
|
||||
@@ -16,8 +16,8 @@ const Routers = function ({ history, app }) {
|
||||
component: App,
|
||||
getIndexRoute (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
registerModel(app, require('./models/dashboard'))
|
||||
cb(null, { component: require('./routes/dashboard/') })
|
||||
registerModel(app, require('models/dashboard'))
|
||||
cb(null, { component: require('routes/dashboard/') })
|
||||
}, 'dashboard')
|
||||
},
|
||||
childRoutes: [
|
||||
@@ -25,117 +25,117 @@ const Routers = function ({ history, app }) {
|
||||
path: 'dashboard',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
registerModel(app, require('./models/dashboard'))
|
||||
cb(null, require('./routes/dashboard/'))
|
||||
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/'))
|
||||
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/'))
|
||||
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/'))
|
||||
registerModel(app, require('models/login'))
|
||||
cb(null, require('routes/login/'))
|
||||
}, 'login')
|
||||
},
|
||||
}, {
|
||||
path: 'request',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/request/'))
|
||||
cb(null, require('routes/request/'))
|
||||
}, 'request')
|
||||
},
|
||||
}, {
|
||||
path: 'UIElement/iconfont',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/UIElement/iconfont/'))
|
||||
cb(null, require('routes/UIElement/iconfont/'))
|
||||
}, 'UIElement-iconfont')
|
||||
},
|
||||
}, {
|
||||
path: 'UIElement/search',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/UIElement/search/'))
|
||||
cb(null, require('routes/UIElement/search/'))
|
||||
}, 'UIElement-search')
|
||||
},
|
||||
}, {
|
||||
path: 'UIElement/dropOption',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/UIElement/dropOption/'))
|
||||
cb(null, require('routes/UIElement/dropOption/'))
|
||||
}, 'UIElement-dropOption')
|
||||
},
|
||||
}, {
|
||||
path: 'UIElement/layer',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/UIElement/layer/'))
|
||||
cb(null, require('routes/UIElement/layer/'))
|
||||
}, 'UIElement-layer')
|
||||
},
|
||||
}, {
|
||||
path: 'UIElement/dataTable',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/UIElement/dataTable/'))
|
||||
cb(null, require('routes/UIElement/dataTable/'))
|
||||
}, 'UIElement-dataTable')
|
||||
},
|
||||
}, {
|
||||
path: 'UIElement/editor',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/UIElement/editor/'))
|
||||
cb(null, require('routes/UIElement/editor/'))
|
||||
}, 'UIElement-editor')
|
||||
},
|
||||
}, {
|
||||
path: 'chart/lineChart',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/chart/lineChart/'))
|
||||
cb(null, require('routes/chart/lineChart/'))
|
||||
}, 'chart-lineChart')
|
||||
},
|
||||
}, {
|
||||
path: 'chart/barChart',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/chart/barChart/'))
|
||||
cb(null, require('routes/chart/barChart/'))
|
||||
}, 'chart-barChart')
|
||||
},
|
||||
}, {
|
||||
path: 'chart/areaChart',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/chart/areaChart/'))
|
||||
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/'))
|
||||
registerModel(app, require('models/post'))
|
||||
cb(null, require('routes/post/'))
|
||||
}, 'post')
|
||||
},
|
||||
}, {
|
||||
path: '*',
|
||||
getComponent (nextState, cb) {
|
||||
require.ensure([], (require) => {
|
||||
cb(null, require('./routes/error/'))
|
||||
cb(null, require('routes/error/'))
|
||||
}, 'error')
|
||||
},
|
||||
},
|
||||
|
||||
+4
-1
@@ -56,6 +56,7 @@ const App = ({ children, dispatch, app, loading, location }) => {
|
||||
|
||||
const siderProps = {
|
||||
menu,
|
||||
location,
|
||||
siderFold,
|
||||
darkTheme,
|
||||
navOpenKeys,
|
||||
@@ -70,6 +71,7 @@ const App = ({ children, dispatch, app, loading, location }) => {
|
||||
|
||||
const breadProps = {
|
||||
menu,
|
||||
location,
|
||||
}
|
||||
if (openPages && openPages.includes(pathname)) {
|
||||
return (<div>
|
||||
@@ -79,6 +81,7 @@ const App = ({ children, dispatch, app, loading, location }) => {
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Loader spinning={loading.effects['app/query']} />
|
||||
<Helmet>
|
||||
<title>ANTD ADMIN</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
@@ -88,7 +91,7 @@ const App = ({ children, dispatch, app, loading, location }) => {
|
||||
</Helmet>
|
||||
<div className={classnames(styles.layout, { [styles.fold]: isNavbar ? false : siderFold }, { [styles.withnavbar]: isNavbar })}>
|
||||
{!isNavbar ? <aside className={classnames(styles.sider, { [styles.light]: !darkTheme })}>
|
||||
<Sider {...siderProps} />
|
||||
{siderProps.menu.length === 0 ? null : <Sider {...siderProps} />}
|
||||
</aside> : ''}
|
||||
<div className={styles.main}>
|
||||
<Header {...headerProps} />
|
||||
|
||||
+72
-72
@@ -1,72 +1,72 @@
|
||||
@import "../themes/vars.less";
|
||||
|
||||
:global {
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
|
||||
.bar {
|
||||
background: @primary-color;
|
||||
position: fixed;
|
||||
z-index: 1024;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 10px @primary-color,0 0 5px @primary-color;
|
||||
opacity: 1.0;
|
||||
transform: rotate(3deg) translate(0px,-4px);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.spinner-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
border: solid 2px transparent;
|
||||
border-top-color: @primary-color;
|
||||
border-left-color: @primary-color;
|
||||
border-radius: 50%;
|
||||
|
||||
:local {
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
#nprogress {
|
||||
.bar,
|
||||
.spinner {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
:global {
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
|
||||
.bar {
|
||||
background: @primary-color;
|
||||
position: fixed;
|
||||
z-index: 1024;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 10px @primary-color,0 0 5px @primary-color;
|
||||
opacity: 1.0;
|
||||
transform: rotate(3deg) translate(0px,-4px);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.spinner-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
border: solid 2px transparent;
|
||||
border-top-color: @primary-color;
|
||||
border-left-color: @primary-color;
|
||||
border-radius: 50%;
|
||||
|
||||
:local {
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
#nprogress {
|
||||
.bar,
|
||||
.spinner {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.comments {
|
||||
:global .ant-table-thead > tr > th {
|
||||
background: #fff;
|
||||
border-bottom: solid 1px @border-color-base;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
background: #f8f8f8;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: left;
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
.date {
|
||||
color: #a3a3a3;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.daterow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 14px;
|
||||
color: #474747;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.avatarcolumn {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.comments {
|
||||
:global .ant-table-thead > tr > th {
|
||||
background: #fff;
|
||||
border-bottom: solid 1px @border-color-base;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
background: #f8f8f8;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: left;
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
.date {
|
||||
color: #a3a3a3;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.daterow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 14px;
|
||||
color: #474747;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.avatarcolumn {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.sales {
|
||||
.title {
|
||||
margin-left: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.radiusdot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.legend {
|
||||
color: @dark-half;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
|
||||
li {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
display: inline-block;
|
||||
|
||||
&+li {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
|
||||
.tiptitle {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.tipitem {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.sales {
|
||||
.title {
|
||||
margin-left: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.radiusdot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.legend {
|
||||
color: @dark-half;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
|
||||
li {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
display: inline-block;
|
||||
|
||||
&+li {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
|
||||
.tiptitle {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.tipitem {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.numberCard {
|
||||
padding: 32px;
|
||||
margin-bottom: 24px;
|
||||
cursor: pointer;
|
||||
|
||||
.iconWarp {
|
||||
font-size: 54px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
padding-left: 78px;
|
||||
|
||||
.title {
|
||||
line-height: 16px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
height: 16px;
|
||||
.text-overflow();
|
||||
}
|
||||
|
||||
.number {
|
||||
line-height: 32px;
|
||||
font-size: 24px;
|
||||
height: 32px;
|
||||
.text-overflow();
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.numberCard {
|
||||
padding: 32px;
|
||||
margin-bottom: 24px;
|
||||
cursor: pointer;
|
||||
|
||||
.iconWarp {
|
||||
font-size: 54px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
padding-left: 78px;
|
||||
|
||||
.title {
|
||||
line-height: 16px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
height: 16px;
|
||||
.text-overflow();
|
||||
}
|
||||
|
||||
.number {
|
||||
line-height: 32px;
|
||||
font-size: 24px;
|
||||
height: 32px;
|
||||
.text-overflow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.quote {
|
||||
color: #fff;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
|
||||
.inner {
|
||||
text-overflow: ellipsis;
|
||||
word-wrap: normal;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
overflow: hidden;
|
||||
text-indent: 24px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: relative;
|
||||
margin-top: 14px;
|
||||
|
||||
.description {
|
||||
width: 100%;
|
||||
|
||||
p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 64px;
|
||||
text-align: right;
|
||||
|
||||
&:last-child {
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.quote {
|
||||
color: #fff;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
|
||||
.inner {
|
||||
text-overflow: ellipsis;
|
||||
word-wrap: normal;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
overflow: hidden;
|
||||
text-indent: 24px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: relative;
|
||||
margin-top: 14px;
|
||||
|
||||
.description {
|
||||
width: 100%;
|
||||
|
||||
p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 64px;
|
||||
text-align: right;
|
||||
|
||||
&:last-child {
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.recentsales {
|
||||
:global .ant-table-thead > tr > th {
|
||||
background: #fff;
|
||||
border-bottom: solid 1px @border-color-base;
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.recentsales {
|
||||
:global .ant-table-thead > tr > th {
|
||||
background: #fff;
|
||||
border-bottom: solid 1px @border-color-base;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.sales {
|
||||
.title {
|
||||
margin-left: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.radiusdot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.legend {
|
||||
color: @dark-half;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
|
||||
li {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
display: inline-block;
|
||||
|
||||
&+li {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
|
||||
.tiptitle {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.tipitem {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.sales {
|
||||
.title {
|
||||
margin-left: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.radiusdot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.legend {
|
||||
color: @dark-half;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
|
||||
li {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
display: inline-block;
|
||||
|
||||
&+li {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
|
||||
.tiptitle {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.tipitem {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +1,97 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.user {
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
height: 200px;
|
||||
background-image: ~ "url(./user-background.png)";
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
align-items: center;
|
||||
|
||||
.headerinner {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
background: @purple;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
opacity: 0.4;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.number {
|
||||
display: flex;
|
||||
height: 116px;
|
||||
justify-content: space-between;
|
||||
border-bottom: solid 1px #f5f5f5;
|
||||
|
||||
.item {
|
||||
text-align: center;
|
||||
height: 116px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding: 30px 0;
|
||||
|
||||
&+.item {
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 116px;
|
||||
position: absolute;
|
||||
background: #f5f5f5;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #757575;
|
||||
|
||||
&:first-child {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
height: 116px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
:global .ant-btn {
|
||||
color: @purple;
|
||||
border-color: @purple;
|
||||
padding: 6px 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.user {
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
height: 200px;
|
||||
background-image: ~ "url(./user-background.png)";
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
align-items: center;
|
||||
|
||||
.headerinner {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
background: @purple;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
opacity: 0.4;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.number {
|
||||
display: flex;
|
||||
height: 116px;
|
||||
justify-content: space-between;
|
||||
border-bottom: solid 1px #f5f5f5;
|
||||
|
||||
.item {
|
||||
text-align: center;
|
||||
height: 116px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding: 30px 0;
|
||||
|
||||
&+.item {
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 116px;
|
||||
position: absolute;
|
||||
background: #f5f5f5;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #757575;
|
||||
|
||||
&:first-child {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
height: 116px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
:global .ant-btn {
|
||||
color: @purple;
|
||||
border-color: @purple;
|
||||
padding: 6px 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Spin } from 'antd'
|
||||
import styles from './weather.less'
|
||||
|
||||
function Weather ({ city, icon, dateTime, temperature, name }) {
|
||||
return (<div className={styles.weather}>
|
||||
<div className={styles.left}>
|
||||
<div className={styles.icon}
|
||||
style={{
|
||||
backgroundImage: `url(${icon})`,
|
||||
}}
|
||||
/>
|
||||
<p>{name}</p>
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
<h1 className={styles.temperature}>{`${temperature}°`}</h1>
|
||||
<p className={styles.description}>{city},{dateTime}</p>
|
||||
</div>
|
||||
</div>)
|
||||
function Weather ({ city, icon, dateTime, temperature, name, loading }) {
|
||||
return (
|
||||
<Spin spinning={loading}>
|
||||
<div className={styles.weather}>
|
||||
<div className={styles.left}>
|
||||
<div className={styles.icon}
|
||||
style={{
|
||||
backgroundImage: `url(${icon})`,
|
||||
}}
|
||||
/>
|
||||
<p>{name}</p>
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
<h1 className={styles.temperature}>{`${temperature}°`}</h1>
|
||||
<p className={styles.description}>{city},{dateTime}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Spin>)
|
||||
}
|
||||
|
||||
Weather.propTypes = {
|
||||
@@ -25,6 +29,7 @@ Weather.propTypes = {
|
||||
dateTime: PropTypes.string,
|
||||
temperature: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
loading: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default Weather
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
@import "../../../themes/vars.less";
|
||||
|
||||
.weather {
|
||||
color: #fff;
|
||||
height: 204px;
|
||||
padding: 24px;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 64px;
|
||||
padding-top: 55px;
|
||||
|
||||
.icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
|
||||
.temperature {
|
||||
font-size: 36px;
|
||||
text-align: right;
|
||||
height: 64px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.description {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
.weather {
|
||||
color: #fff;
|
||||
height: 204px;
|
||||
padding: 24px;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 64px;
|
||||
padding-top: 55px;
|
||||
|
||||
.icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
|
||||
.temperature {
|
||||
font-size: 36px;
|
||||
text-align: right;
|
||||
height: 64px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.description {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +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 { NumberCard, Quote, Sales, Weather, RecentSales, Comments, Completed, Browser, Cpu, User } from './components'
|
||||
import styles from './index.less'
|
||||
|
||||
@@ -13,92 +14,96 @@ const bodyStyle = {
|
||||
},
|
||||
}
|
||||
|
||||
function Dashboard ({ dashboard }) {
|
||||
function Dashboard ({ dashboard, loading }) {
|
||||
const { weather, sales, quote, numbers, recentSales, comments, completed, browser, cpu, user } = dashboard
|
||||
const numberCards = numbers.map((item, key) => (<Col key={key} lg={6} md={12}>
|
||||
<NumberCard {...item} />
|
||||
</Col>))
|
||||
|
||||
return (
|
||||
<Row gutter={24}>
|
||||
{numberCards}
|
||||
<Col lg={18} md={24}>
|
||||
<Card bordered={false}
|
||||
bodyStyle={{
|
||||
padding: '24px 36px 24px 0',
|
||||
}}
|
||||
>
|
||||
<Sales data={sales} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={6} md={24}>
|
||||
<Row gutter={24}>
|
||||
<Col lg={24} md={12}>
|
||||
<Card bordered={false}
|
||||
className={styles.weather}
|
||||
bodyStyle={{
|
||||
padding: 0,
|
||||
height: 204,
|
||||
background: color.blue,
|
||||
}}
|
||||
>
|
||||
<Weather {...weather} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={24} md={12}>
|
||||
<Card bordered={false}
|
||||
className={styles.quote}
|
||||
bodyStyle={{
|
||||
padding: 0,
|
||||
height: 204,
|
||||
background: color.peach,
|
||||
}}
|
||||
>
|
||||
<Quote {...quote} />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col lg={12} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<RecentSales data={recentSales} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={12} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<Comments data={comments} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={24} md={24}>
|
||||
<Card bordered={false}
|
||||
bodyStyle={{
|
||||
padding: '24px 36px 24px 0',
|
||||
}}
|
||||
>
|
||||
<Completed data={completed} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={8} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<Browser data={browser} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={8} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<Cpu {...cpu} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={8} md={24}>
|
||||
<Card bordered={false} bodyStyle={{ ...bodyStyle.bodyStyle, padding: 0 }}>
|
||||
<User {...user} />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<div>
|
||||
<Loader spinning={loading.models.dashboard && sales.length === 0} />
|
||||
<Row gutter={24}>
|
||||
{numberCards}
|
||||
<Col lg={18} md={24}>
|
||||
<Card bordered={false}
|
||||
bodyStyle={{
|
||||
padding: '24px 36px 24px 0',
|
||||
}}
|
||||
>
|
||||
<Sales data={sales} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={6} md={24}>
|
||||
<Row gutter={24}>
|
||||
<Col lg={24} md={12}>
|
||||
<Card bordered={false}
|
||||
className={styles.weather}
|
||||
bodyStyle={{
|
||||
padding: 0,
|
||||
height: 204,
|
||||
background: color.blue,
|
||||
}}
|
||||
>
|
||||
<Weather {...weather} loading={loading.effects['dashboard/queryWeather']} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={24} md={12}>
|
||||
<Card bordered={false}
|
||||
className={styles.quote}
|
||||
bodyStyle={{
|
||||
padding: 0,
|
||||
height: 204,
|
||||
background: color.peach,
|
||||
}}
|
||||
>
|
||||
<Quote {...quote} />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col lg={12} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<RecentSales data={recentSales} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={12} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<Comments data={comments} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={24} md={24}>
|
||||
<Card bordered={false}
|
||||
bodyStyle={{
|
||||
padding: '24px 36px 24px 0',
|
||||
}}
|
||||
>
|
||||
<Completed data={completed} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={8} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<Browser data={browser} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={8} md={24}>
|
||||
<Card bordered={false} {...bodyStyle}>
|
||||
<Cpu {...cpu} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg={8} md={24}>
|
||||
<Card bordered={false} bodyStyle={{ ...bodyStyle.bodyStyle, padding: 0 }}>
|
||||
<User {...user} />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Dashboard.propTypes = {
|
||||
dashboard: PropTypes.object,
|
||||
loading: PropTypes.object,
|
||||
}
|
||||
|
||||
export default connect(({ dashboard }) => ({ dashboard }))(Dashboard)
|
||||
export default connect(({ dashboard, loading }) => ({ dashboard, loading }))(Dashboard)
|
||||
|
||||
@@ -8,15 +8,13 @@ import styles from './index.less'
|
||||
const FormItem = Form.Item
|
||||
|
||||
const Login = ({
|
||||
login,
|
||||
loading,
|
||||
dispatch,
|
||||
form: {
|
||||
getFieldDecorator,
|
||||
validateFieldsAndScroll,
|
||||
},
|
||||
}) => {
|
||||
const { loginLoading } = login
|
||||
|
||||
function handleOk () {
|
||||
validateFieldsAndScroll((errors, values) => {
|
||||
if (errors) {
|
||||
@@ -52,7 +50,7 @@ const Login = ({
|
||||
})(<Input size="large" type="password" onPressEnter={handleOk} placeholder="Password" />)}
|
||||
</FormItem>
|
||||
<Row>
|
||||
<Button type="primary" size="large" onClick={handleOk} loading={loginLoading}>
|
||||
<Button type="primary" size="large" onClick={handleOk} loading={loading.effects.login}>
|
||||
Sign in
|
||||
</Button>
|
||||
<p>
|
||||
@@ -68,8 +66,8 @@ const Login = ({
|
||||
|
||||
Login.propTypes = {
|
||||
form: PropTypes.object,
|
||||
login: PropTypes.object,
|
||||
dispatch: PropTypes.func,
|
||||
loading: PropTypes.object,
|
||||
}
|
||||
|
||||
export default connect(({ login }) => ({ login }))(Form.create()(Login))
|
||||
export default connect(({ loading }) => ({ loading }))(Form.create()(Login))
|
||||
|
||||
@@ -3,20 +3,6 @@ import { request, config } from 'utils'
|
||||
const { api } = config
|
||||
const { dashboard } = api
|
||||
|
||||
export async function myCity (params) {
|
||||
return request({
|
||||
url: 'http://www.zuimeitianqi.com/zuimei/myCity',
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
|
||||
export async function queryWeather (params) {
|
||||
return request({
|
||||
url: 'http://www.zuimeitianqi.com/zuimei/queryWeather',
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
|
||||
export async function query (params) {
|
||||
return request({
|
||||
url: dashboard,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { request, config } from 'utils'
|
||||
|
||||
const { APIV1 } = config
|
||||
|
||||
export async function query (params) {
|
||||
params.key = 'i7sau1babuzwhycn'
|
||||
return request({
|
||||
url: `${APIV1}/weather/now.json`,
|
||||
method: 'get',
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
+135
-135
@@ -1,135 +1,135 @@
|
||||
@import "./vars.less";
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-breadcrumb {
|
||||
& > span {
|
||||
&:last-child {
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-breadcrumb-link {
|
||||
.anticon + span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table {
|
||||
.ant-table-thead > tr > th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.ant-table-small {
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.ant-table-body > table {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
float: none!important;
|
||||
display: table;
|
||||
margin: 16px auto !important;
|
||||
}
|
||||
|
||||
.ant-popover-inner {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 20px rgba(100, 100, 100, 0.2);
|
||||
}
|
||||
|
||||
.vertical-center-modal {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.ant-modal {
|
||||
top: 0;
|
||||
|
||||
.ant-modal-body {
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-control {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ant-modal-mask {
|
||||
background-color: rgba(55, 55, 55, 0.2);
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ant-select-dropdown-menu-item {
|
||||
padding: 12px 16px !important;
|
||||
}
|
||||
|
||||
.margin-right {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1600px) {
|
||||
:global {
|
||||
.ant-col-xl-48 {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.ant-col-xl-96 {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
:global {
|
||||
.ant-pagination-item,
|
||||
.ant-pagination-next,
|
||||
.ant-pagination-options,
|
||||
.ant-pagination-prev {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
.ant-card-head {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.ant-card-body {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "~themes/vars";
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-breadcrumb {
|
||||
& > span {
|
||||
&:last-child {
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-breadcrumb-link {
|
||||
.anticon + span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table {
|
||||
.ant-table-thead > tr > th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.ant-table-small {
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.ant-table-body > table {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
float: none!important;
|
||||
display: table;
|
||||
margin: 16px auto !important;
|
||||
}
|
||||
|
||||
.ant-popover-inner {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 20px rgba(100, 100, 100, 0.2);
|
||||
}
|
||||
|
||||
.vertical-center-modal {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.ant-modal {
|
||||
top: 0;
|
||||
|
||||
.ant-modal-body {
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-control {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ant-modal-mask {
|
||||
background-color: rgba(55, 55, 55, 0.2);
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ant-select-dropdown-menu-item {
|
||||
padding: 12px 16px !important;
|
||||
}
|
||||
|
||||
.margin-right {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1600px) {
|
||||
:global {
|
||||
.ant-col-xl-48 {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.ant-col-xl-96 {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
:global {
|
||||
.ant-pagination-item,
|
||||
.ant-pagination-next,
|
||||
.ant-pagination-options,
|
||||
.ant-pagination-prev {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
.ant-card-head {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.ant-card-body {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,14 +1,14 @@
|
||||
@import "./default.less"; // antd-admin
|
||||
@dark-half: #494949;
|
||||
@purple: #d897eb;
|
||||
@shadow-1: 4px 4px 20px 0 rgba(0,0,0,0.01);
|
||||
@shadow-2: 4px 4px 40px 0 rgba(0,0,0,0.05);
|
||||
@transition-ease-in: all 0.3s ease-out;
|
||||
@transition-ease-out: all 0.3s ease-out;
|
||||
@ease-in: ease-in;
|
||||
|
||||
.text-overflow {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
@import "~themes/default"; // antd-admin
|
||||
@dark-half: #494949;
|
||||
@purple: #d897eb;
|
||||
@shadow-1: 4px 4px 20px 0 rgba(0,0,0,0.01);
|
||||
@shadow-2: 4px 4px 40px 0 rgba(0,0,0,0.05);
|
||||
@transition-ease-in: all 0.3s ease-out;
|
||||
@transition-ease-out: all 0.3s ease-out;
|
||||
@ease-in: ease-in;
|
||||
|
||||
.text-overflow {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
@import "./default.less";
|
||||
@import "./mixin.less";
|
||||
@import "~themes/default";
|
||||
@import "~themes/mixin";
|
||||
|
||||
+3
-1
@@ -8,10 +8,11 @@ module.exports = {
|
||||
logo: '/logo.png',
|
||||
iconFontCSS: '/iconfont.css',
|
||||
iconFontJS: '/iconfont.js',
|
||||
YQL: ['http://www.zuimeitianqi.com'],
|
||||
CORS: [],
|
||||
openPages: ['/login'],
|
||||
apiPrefix: '/api/v1',
|
||||
APIV1,
|
||||
APIV2,
|
||||
api: {
|
||||
userLogin: `${APIV1}/user/login`,
|
||||
userLogout: `${APIV1}/user/logout`,
|
||||
@@ -21,6 +22,7 @@ module.exports = {
|
||||
user: `${APIV1}/user/:id`,
|
||||
dashboard: `${APIV1}/dashboard`,
|
||||
menus: `${APIV1}/menus`,
|
||||
weather: `${APIV1}/weather`,
|
||||
v1test: `${APIV1}/test`,
|
||||
v2test: `${APIV2}/test`,
|
||||
},
|
||||
|
||||
@@ -95,13 +95,12 @@ export default function request (options) {
|
||||
list: data,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
return Promise.resolve({
|
||||
success: true,
|
||||
message: statusText,
|
||||
statusCode: status,
|
||||
...data,
|
||||
}
|
||||
})
|
||||
}).catch((error) => {
|
||||
const { response } = error
|
||||
let msg
|
||||
@@ -114,6 +113,6 @@ export default function request (options) {
|
||||
statusCode = 600
|
||||
msg = error.message || 'Network Error'
|
||||
}
|
||||
return { success: false, statusCode, message: msg }
|
||||
return Promise.reject({ success: false, statusCode, message: msg })
|
||||
})
|
||||
}
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const beautify = require('js-beautify').js_beautify
|
||||
const config = require('./package.json')
|
||||
|
||||
const dist = path.join(`${__dirname}/dist`)
|
||||
const maxVersion = 5
|
||||
|
||||
const writeVersion = () => new Promise((resolve, reject) => {
|
||||
const { version } = config
|
||||
const numbers = version.split('.')
|
||||
numbers[2] = Number(numbers[2]) + 1
|
||||
config.version = numbers.join('.')
|
||||
|
||||
fs.writeFile(path.join(__dirname, 'package.json'), beautify(JSON.stringify(config), { indent_size: 2 }), (err) => {
|
||||
if (err) {
|
||||
reject()
|
||||
}
|
||||
resolve()
|
||||
console.log(`version: ${config.version}`)
|
||||
})
|
||||
})
|
||||
|
||||
const removeFolder = (folderPath) => {
|
||||
let files = []
|
||||
if (fs.existsSync(folderPath)) {
|
||||
files = fs.readdirSync(folderPath)
|
||||
files.forEach((file) => {
|
||||
const curPath = `${folderPath}/${file}`
|
||||
if (fs.statSync(curPath).isDirectory()) {
|
||||
removeFolder(curPath)
|
||||
} else {
|
||||
fs.unlinkSync(curPath)
|
||||
}
|
||||
})
|
||||
fs.rmdirSync(folderPath)
|
||||
}
|
||||
}
|
||||
|
||||
const start = async () => {
|
||||
const files = fs.readdirSync(dist)
|
||||
const promises = files.map(file => new Promise((resolve, reject) => {
|
||||
fs.stat(`${dist}/${file}`, (err, stats) => {
|
||||
if (err) {
|
||||
reject()
|
||||
} else {
|
||||
resolve(!stats.isFile()
|
||||
? file
|
||||
: null)
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
const result = await Promise.all(promises)
|
||||
|
||||
const folders = result.filter((item) => {
|
||||
if (item) {
|
||||
return item.split('.').length === 3
|
||||
}
|
||||
return false
|
||||
}).sort((a, b) => {
|
||||
const an = a.split('.').map(_ => Number(_))
|
||||
const bn = b.split('.').map(_ => Number(_))
|
||||
if (an[0] === bn[0]) {
|
||||
if (an[1] === bn[1]) {
|
||||
return an[2] < bn[2]
|
||||
}
|
||||
return an[1] < bn[1]
|
||||
}
|
||||
return an[0] < bn[0]
|
||||
}).filter((item, index) => {
|
||||
return index > (maxVersion - 1)
|
||||
})
|
||||
|
||||
for (const item of folders) {
|
||||
await removeFolder(`${dist}/${item}`)
|
||||
}
|
||||
|
||||
await writeVersion()
|
||||
}
|
||||
|
||||
start()
|
||||
+30
-23
@@ -1,38 +1,41 @@
|
||||
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'
|
||||
|
||||
if (env === 'production' && webpackConfig.module) {
|
||||
// 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
|
||||
})
|
||||
}
|
||||
return item
|
||||
})
|
||||
if (production) {
|
||||
if (webpackConfig.module) {
|
||||
// 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
|
||||
})
|
||||
}
|
||||
return item
|
||||
})
|
||||
}
|
||||
webpackConfig.plugins.push(
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
minimize: true,
|
||||
debug: false,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// PreLoaders
|
||||
// webpackConfig.module.preLoaders = [{
|
||||
// test: /\.js$/,
|
||||
// enforce: 'pre',
|
||||
// loader: 'eslint',
|
||||
// }]
|
||||
|
||||
webpackConfig.plugins = webpackConfig.plugins.concat([
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: 'src/public',
|
||||
to: env === 'production' ? '../' : webpackConfig.output.outputPath,
|
||||
to: production ? '../' : webpackConfig.output.outputPath,
|
||||
},
|
||||
]),
|
||||
new HtmlWebpackPlugin({
|
||||
@@ -42,11 +45,11 @@ module.exports = (webpackConfig, env) => {
|
||||
inject: false,
|
||||
appMountId: 'root',
|
||||
template: `!!ejs-loader!${HtmlWebpackTemplate}`,
|
||||
filename: env === 'production' ? '../index.html' : 'index.html',
|
||||
filename: production ? '../index.html' : 'index.html',
|
||||
minify: {
|
||||
collapseWhitespace: true,
|
||||
},
|
||||
scripts: env === 'production' ? null : ['roadhog.dll.js'],
|
||||
scripts: production ? null : ['/roadhog.dll.js'],
|
||||
meta: [
|
||||
{
|
||||
name: 'description',
|
||||
@@ -65,6 +68,10 @@ module.exports = (webpackConfig, env) => {
|
||||
utils: `${__dirname}/src/utils`,
|
||||
config: `${__dirname}/src/utils/config`,
|
||||
enums: `${__dirname}/src/utils/enums`,
|
||||
services: `${__dirname}/src/services`,
|
||||
models: `${__dirname}/src/models`,
|
||||
routes: `${__dirname}/src/routes`,
|
||||
themes: `${__dirname}/src/themes`,
|
||||
}
|
||||
|
||||
return webpackConfig
|
||||
|
||||
Reference in New Issue
Block a user