mirror of
https://github.com/zuiidea/antd-admin
synced 2026-10-28 03:04:48 +00:00
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
@import "../vars.less";
|
||||
|
||||
.bread {
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
margin-bottom: -24px;
|
||||
}
|
||||
@@ -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}>
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
@import "../vars.less";
|
||||
@@ -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,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}>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user