Merge pull request #139 from zuiidea/4.0-dev

4.0 dev
This commit is contained in:
zuiidea
2017-03-24 11:25:42 +08:00
committed by GitHub
22 changed files with 159 additions and 138 deletions
+1 -1
View File
@@ -114,7 +114,7 @@ npm run lint
- 如需重写antd样式配置,请修改`src/theme.js`
- 项目配置文件在`src/utils/config.js`
- 如需重写异步请求函数,请修改`src/utils/request.js`
(关于为什么使用robe-ajax而不是fetch:在一个无服务器的环境中模拟数据请求,[Mock](https://github.com/nuysoft/Mock)不能拦截Fetch,只能拦截XHR,所以我选了一个类似jquery Ajax的库robe-ajax)
(关于为什么使用axios而不是fetch:在一个无服务器的环境中模拟数据请求,[Mock](https://github.com/nuysoft/Mock)不能拦截Fetch)
## 参考
+1 -1
View File
@@ -14,7 +14,7 @@ let dataKey = mockStorge('AdminUsers', [
module.exports = {
'POST /api/login' (req, res) {
const userItem = req.body
const userItem = JSON.parse(req.body)
const response = {
success: false,
message: '',
+3 -3
View File
@@ -59,7 +59,7 @@ module.exports = {
},
'POST /api/users' (req, res) {
const newData = req.body
const newData = JSON.parse(req.body)
newData.createTime = Mock.mock('@now')
newData.avatar = Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', newData.nickName.substr(0, 1))
@@ -75,7 +75,7 @@ module.exports = {
},
'DELETE /api/users' (req, res) {
const deleteItem = req.body
const deleteItem = JSON.parse(req.body)
usersListData.data = usersListData.data.filter((item) => {
if (item.id === deleteItem.id) {
@@ -92,7 +92,7 @@ module.exports = {
},
'PUT /api/users' (req, res) {
const editItem = req.body
const editItem = JSON.parse(req.body)
editItem.createTime = Mock.mock('@now')
editItem.avatar = Mock.Random.image('100x100', Mock.Random.color(), '#757575', 'png', editItem.nickName.substr(0, 1))
+1 -1
View File
@@ -21,6 +21,7 @@
},
"devDependencies": {
"atool-build": "^0.7.6",
"axios": "^0.15.3",
"babel-eslint": "^6.0.4",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-dva-hmr": "^0.1.0",
@@ -43,7 +44,6 @@
"mockjs": "^1.0.1-beta3",
"rc-tween-one": "^1.0.0",
"redbox-react": "^1.2.10",
"robe-ajax": "^1.0.0",
"watchjs": "^0.0.0"
},
"pre-commit": [
+1 -1
View File
@@ -1,7 +1,7 @@
const mock = {}
require('fs').readdirSync(require('path').join(`${__dirname}/mock`)).forEach((file) => {
Object.assign(mock, require('./mock/' + file))
Object.assign(mock, require(`./mock/${file}`))
})
module.exports = mock
+2 -1
View File
@@ -1,6 +1,7 @@
import React, { PropTypes } from 'react'
import { Breadcrumb, Icon } from 'antd'
import styles from './Layout.less'
import styles from './Bread.less'
import { menu } from '../../utils'
let pathSet = []
+8
View File
@@ -0,0 +1,8 @@
@import "../vars.less";
.bread {
height: 64px;
line-height: 64px;
padding: 0 24px;
margin-bottom: -24px;
}
+1 -1
View File
@@ -1,5 +1,5 @@
import React from 'react'
import styles from './Layout.less'
import styles from './Footer.less'
import { config } from '../../utils'
const Footer = () => <div className={styles.footer}>
+12
View File
@@ -0,0 +1,12 @@
@import "../vars.less";
.footer {
height: 48px;
line-height: 48px;
text-align: center;
font-size: 12px;
color: #999;
background: #fff;
box-shadow: @shadow-2;
width: 100%;
}
+19 -15
View File
@@ -1,6 +1,6 @@
import React, { PropTypes } from 'react'
import { Menu, Icon, Popover } from 'antd'
import styles from './Layout.less'
import styles from './Header.less'
import Menus from './Menu'
const SubMenu = Menu.SubMenu
@@ -20,25 +20,29 @@ function Header ({ user, logout, switchSider, siderFold, isNavbar, menuPopoverVi
<div className={styles.header}>
{isNavbar
? <Popover placement="bottomLeft" onVisibleChange={switchMenuPopover} visible={menuPopoverVisible} overlayClassName={styles.popovermenu} trigger="click" content={<Menus {...menusProps} />}>
<div className={styles.siderbutton}>
<div className={styles.button}>
<Icon type="bars" />
</div>
</Popover>
: <div className={styles.siderbutton} onClick={switchSider}>
: <div className={styles.button} onClick={switchSider}>
<Icon type={siderFold ? 'menu-unfold' : 'menu-fold'} />
</div>}
<Menu className="header-menu" mode="horizontal" onClick={handleClickMenu}>
<SubMenu style={{
float: 'right',
}} title={< span > <Icon type="user" />
{user.name} < /span>}
>
<Menu.Item key="logout">
<a>注销</a>
</Menu.Item>
</SubMenu>
</Menu>
<div className={styles.rightWarpper}>
<div className={styles.button}>
<Icon type="mail" />
</div>
<Menu mode="horizontal" onClick={handleClickMenu}>
<SubMenu style={{
float: 'right',
}} title={< span > <Icon type="user" />
{user.name} < /span>}
>
<Menu.Item key="logout">
<a>注销</a>
</Menu.Item>
</SubMenu>
</Menu>
</div>
</div>
)
}
+57
View File
@@ -0,0 +1,57 @@
@import "../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;
.rightWarpper {
display: flex;
}
.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;
}
}
}
+1 -66
View File
@@ -144,6 +144,7 @@
.ant-menu-root {
height: ~"calc(100vh - 144px)";
overflow-x: hidden;
border-right: none;
&::-webkit-scrollbar-thumb {
background-color: transparent;
@@ -183,40 +184,6 @@
}
}
.header {
:global .ant-menu-horizontal {
& > .ant-menu-submenu {
float: right;
}
border: none;
}
box-shadow: @shadow-2;
position: relative;
.siderbutton {
height: 47px;
width: 47px;
line-height: 47px;
text-align: center;
font-size: 18px;
cursor: pointer;
position: absolute;
transition: @transition-ease-in;
&:hover {
color: @primary-color;
background-color: fade(@primary-color, 15%);
}
}
}
.bread {
height: 64px;
line-height: 64px;
padding: 0 24px;
margin-bottom: -24px;
}
.main {
margin-left: 224px;
overflow: auto;
@@ -241,17 +208,6 @@
position: relative;
}
}
.footer {
height: 48px;
line-height: 48px;
text-align: center;
font-size: 12px;
color: #999;
background: #fff;
box-shadow: @shadow-2;
width: 100%;
}
}
:global .ant-menu-dark {
@@ -306,27 +262,6 @@
}
}
.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;
}
}
}
.spin {
:global .ant-spin-container {
height: 100vh;
+1
View File
@@ -0,0 +1 @@
@import "../vars.less";
+1 -1
View File
@@ -1,6 +1,6 @@
import React, { PropTypes } from 'react'
import { Breadcrumb, Icon } from 'antd'
import styles from './Layout.less'
import styles from './Bread.less'
import { menu } from '../../utils'
let pathSet = []
+1 -1
View File
@@ -1,5 +1,5 @@
import React from 'react'
import styles from './Layout.less'
import styles from './Footer.less'
import { config } from '../../utils'
const Footer = () => <div className={styles.footer}>
+19 -15
View File
@@ -1,6 +1,6 @@
import React, { PropTypes } from 'react'
import { Menu, Icon, Popover } from 'antd'
import styles from './Layout.less'
import styles from './Header.less'
import Menus from './Menu'
const SubMenu = Menu.SubMenu
@@ -20,25 +20,29 @@ function Header ({ user, logout, switchSider, siderFold, isNavbar, menuPopoverVi
<div className={styles.header}>
{isNavbar
? <Popover placement="bottomLeft" onVisibleChange={switchMenuPopover} visible={menuPopoverVisible} overlayClassName={styles.popovermenu} trigger="click" content={<Menus {...menusProps} />}>
<div className={styles.siderbutton}>
<div className={styles.button}>
<Icon type="bars" />
</div>
</Popover>
: <div className={styles.siderbutton} onClick={switchSider}>
: <div className={styles.button} onClick={switchSider}>
<Icon type={siderFold ? 'menu-unfold' : 'menu-fold'} />
</div>}
<Menu className="header-menu" mode="horizontal" onClick={handleClickMenu}>
<SubMenu style={{
float: 'right',
}} title={< span > <Icon type="user" />
{user.name} < /span>}
>
<Menu.Item key="logout">
<a>注销</a>
</Menu.Item>
</SubMenu>
</Menu>
<div className={styles.rightWarpper}>
<div className={styles.button}>
<Icon type="mail" />
</div>
<Menu mode="horizontal" onClick={handleClickMenu}>
<SubMenu style={{
float: 'right',
}} title={< span > <Icon type="user" />
{user.name} < /span>}
>
<Menu.Item key="logout">
<a>注销</a>
</Menu.Item>
</SubMenu>
</Menu>
</div>
</div>
)
}
+1
View File
@@ -16,6 +16,7 @@ const getMenus = function (menuArray, siderFold, parentPath = '/') {
}
return (
<Menu.Item key={linkTo}>
<Link to={linkTo}>
{item.icon ? <Icon type={item.icon} /> : ''}
{siderFold && topMenus.indexOf(item.key) >= 0 ? '' : item.name}
+6 -3
View File
@@ -1,21 +1,24 @@
import { request } from '../utils'
export async function login (params) {
return request('/api/login', {
return request({
url: '/api/login',
method: 'post',
data: params,
})
}
export async function logout (params) {
return request('/api/logout', {
return request({
url: '/api/logout',
method: 'post',
data: params,
})
}
export async function userInfo (params) {
return request('/api/userInfo', {
return request({
url: '/api/userInfo',
method: 'get',
data: params,
})
+6 -7
View File
@@ -1,23 +1,22 @@
import { request } from '../utils'
export async function myCity (params) {
return request('http://www.zuimeitianqi.com/zuimei/myCity', {
method: 'get',
cross: true,
return request({
url: 'http://www.zuimeitianqi.com/zuimei/myCity',
data: params,
})
}
export async function queryWeather (params) {
return request('http://www.zuimeitianqi.com/zuimei/queryWeather', {
method: 'get',
cross: true,
return request({
url: 'http://www.zuimeitianqi.com/zuimei/queryWeather',
data: params,
})
}
export async function query (params) {
return request('/api/dashboard', {
return request({
url: '/api/dashboard',
method: 'get',
data: params,
})
+8 -4
View File
@@ -1,28 +1,32 @@
import { request } from '../utils'
export async function query (params) {
return request('/api/users', {
return request({
url: '/api/users',
method: 'get',
data: params,
})
}
export async function create (params) {
return request('/api/users', {
return request({
url: '/api/users',
method: 'post',
data: params,
})
}
export async function remove (params) {
return request('/api/users', {
return request({
url: '/api/users',
method: 'delete',
data: params,
})
}
export async function update (params) {
return request('/api/users', {
return request({
url: '/api/users',
method: 'put',
data: params,
})
+1 -1
View File
@@ -24,7 +24,7 @@ for (let i in mockData) {
if (options.url.split('?')[1]) {
options.query = serialize(options.url.split('?')[1])
} else {
options.query = options.body ? serialize(options.body) : {}
options.query = options.body ? JSON.parse(options.body) : {}
}
}
let res = {}
+8 -16
View File
@@ -1,20 +1,12 @@
import Ajax from 'robe-ajax'
import axios from 'axios'
import qs from 'qs'
export default function request (url, options) {
if (options.cross) {
return Ajax.getJSON('http://query.yahooapis.com/v1/public/yql', {
q: `select * from json where url='${url}?${Ajax.param(options.data)}'`,
format: 'json',
})
export default function request (options) {
if (options.url.indexOf('//') > -1 && window.location.origin !== `${options.url.split('//')[0]}//${options.url.split('//')[1].split('/')[0]}`) {
options.url = `http://query.yahooapis.com/v1/public/yql?q=select * from json where url='${options.url}?${qs.stringify(options.data)}'&format=json`
delete options.data
}
const { method = 'get' } = options
return Ajax.ajax({
url,
method,
data: options.data || {},
processData: method === 'get',
dataType: 'JSON',
}).done((data) => {
return data
return axios(options).then((result) => {
return result.data
})
}