Compare commits

...
21 Commits
Author SHA1 Message Date
zuiidea 85e12caf12 update 2017-06-06 19:31:12 +08:00
zuiidea b83c5e7819 user Multiple Option 2017-06-01 20:16:18 +08:00
zuiidea 9cff4e8dfe 666 2017-05-25 13:55:36 +08:00
zuiidea 6ac7e5e815 Merge pull request #296 from darcygail/master
fix YQL bugs:the chat '&' doesn't encoded
2017-05-17 16:59:21 +08:00
darcy e63dfc9291 fix YQL bugs:the chat '&' doesn't encoded 2017-05-17 15:55:40 +08:00
zuiidea 81e7d2bdca Merge pull request #292 from i06/master
Search.js has a mistake var name
2017-05-15 18:59:57 +08:00
i06 1c46693246 Search.js has a mistake var name
the variable named 'handeleSelectChange' seems not right.
turn `handeleSelectChange` to `handleSelectChange`
Hope  accept my advice, thanks
2017-05-15 17:22:55 +08:00
zuiidea 4832a720e6 Merge pull request #288 from zuiidea/develop
Develop
2017-05-13 14:37:37 +08:00
zuiidea 54964fabfb Update README.md 2017-05-13 14:37:18 +08:00
zuiidea b60e593f09 Update README.md 2017-05-13 14:35:53 +08:00
zuiidea 5359efce36 Merge pull request #287 from zuiidea/develop
update 4.2.1
2017-05-12 18:07:53 +08:00
zuiidea 3decccc87d update 4.2.1 2017-05-12 18:06:43 +08:00
zuiidea d92eecb620 Merge pull request #285 from zuiidea/develop
local icon
2017-05-12 15:56:18 +08:00
zuiidea b4699e75f1 Merge pull request #284 from zuiidea/develop
fix NProgress
2017-05-12 12:26:35 +08:00
zuiidea 19e07aeb7a Merge pull request #277 from zuiidea/develop
favicon
2017-05-11 11:11:49 +08:00
zuiidea 2c74295843 Merge pull request #266 from zuiidea/develop
default.less
2017-05-09 16:36:12 +08:00
zuiidea 55ef9dfc0e Merge pull request #263 from zuiidea/develop
Develop
2017-05-09 15:25:45 +08:00
zuiidea 255b0a95a7 Merge pull request #258 from zuiidea/develop
add:nprogress,dva-loading
2017-05-08 15:34:15 +08:00
zuiidea bf260db940 Update README.md 2017-05-03 17:30:44 +08:00
zuiidea 3e1e782617 Update package.json 2017-05-03 17:29:44 +08:00
zuiidea a1e8f2ed9b Update package.json 2017-05-03 17:15:35 +08:00
20 changed files with 136 additions and 62 deletions
+32 -30
View File
@@ -1,47 +1,48 @@
# Antd Admin
[![React Native](https://img.shields.io/badge/react-^15.4.1-brightgreen.svg?style=flat-square)](https://github.com/facebook/react)
[![Ant Design](https://img.shields.io/badge/ant--design-^2.7.3-yellowgreen.svg?style=flat-square)](https://github.com/ant-design/ant-design)
[![dva](https://img.shields.io/badge/dva-^1.1.0-orange.svg?style=flat-square)](https://github.com/dvajs/dva)
[![React Native](https://img.shields.io/badge/react-^15.4.4-brightgreen.svg?style=flat-square)](https://github.com/facebook/react)
[![Ant Design](https://img.shields.io/badge/ant--design-^2.10.0-yellowgreen.svg?style=flat-square)](https://github.com/ant-design/ant-design)
[![dva](https://img.shields.io/badge/dva-^1.2.0-orange.svg?style=flat-square)](https://github.com/dvajs/dva)
[![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin.svg?style=flat-square)](https://github.com/zuiidea/antd-admin)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls)
[![MIT](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](http://opensource.org/licenses/MIT)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com)
演示地址 <http://zuiidea.github.io/antd-admin/>
备用地址 <http://47.92.30.98:8000>
演示地址 <http://zuiidea.github.io/antd-admin> \| [备用地址](http://47.92.30.98:8000)
## 特性
- 基于[react](https://github.com/facebook/react),[ant-design](https://github.com/ant-design/ant-design),[dva](https://github.com/dvajs/dva),[Mock](https://github.com/nuysoft/Mock) 企业级后台管理系统最佳实践
- 基于[Mock](https://github.com/nuysoft/Mock)实现脱离后端独立开发
- 基于Antd UI 设计语言,提供后台管理系统常见使用场景
- 基于[dva](https://github.com/dvajs/dva)动态加载 Model 和路由,按需加载
- 浅度响应式设计
- 基于[react](https://github.com/facebook/react),[ant-design](https://github.com/ant-design/ant-design),[dva](https://github.com/dvajs/dva),[Mock](https://github.com/nuysoft/Mock) 企业级后台管理系统最佳实践。
- 基于Antd UI 设计语言,提供后台管理系统常见使用场景。
- 基于[dva](https://github.com/dvajs/dva)动态加载 Model 和路由,按需加载。
- 使用[roadhog](https://github.com/sorrycc/roadhog)本地调试和构建,其中Mock功能实现脱离后端独立开发。
- 浅度响应式设计。
## 更新日志
### 4.2.2
`2017-06-01`
-   新增用户管理批量删除。[#320](https://github.com/zuiidea/antd-admin/issues/320)
### 4.2.1
`2017-05-12`
-   新增IconFont扩展方案,本地使用方案。[#270](https://github.com/zuiidea/antd-admin/issues/270) [Live](http://47.92.30.98:666/UIElement/iconfont)
-   新增常见场景使用loading。 [dva-loading](https://github.com/dvajs/dva-loading)
### 4.2
`2017-04-28`
-   修改user相关API使用`Restful`风格
-   增加user页面多条件查询[#266](https://github.com/zuiidea/antd-admin/issues/226)
-   修复菜单默认高亮[#201](https://github.com/zuiidea/antd-admin/issues/201)
-   修改user相关API使用`Restful`风格。
-   增加user页面多条件查询。[#266](https://github.com/zuiidea/antd-admin/issues/226)
-   修复菜单默认高亮。[#201](https://github.com/zuiidea/antd-admin/issues/201)
`2017-04-21`
-   重写Menu,Bread组件及配置文件,[说明](https://github.com/zuiidea/antd-admin/wiki/%E8%8F%9C%E5%8D%95%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6)
### 4.1
`2017-04-14`
- 升级开发工具为[roadhog](https://github.com/sorrycc/roadhog)
- 使用`roadhog`的mock功能
- 增强`utils/request.js`跨域处理能力
[More Change Log](https://github.com/zuiidea/antd-admin/wiki/Change-Log)
## 开发构建
@@ -75,8 +76,8 @@
文件夹命名说明:
- components:组件(方法)为单位以文件夹保存,文件夹名组件首字母大写(如`DataTable`),方法首字母小写(如`layer`),文件夹内主文件与文件夹同名,多文件以`index.js`导出对象(如`./src/components/Layout`)
- routes:页面为单位以文件夹保存,文件夹名首字母小写(特殊除外,如`UIElement`),文件夹内主文件以`index.js`导出,多文件时可建立`components`文件夹(如`./src/routes/dashboard`),如果有子路由,依次按照路由层次建立文件夹(如`./src/routes/UIElement`)
- components:组件(方法)为单位以文件夹保存,文件夹名组件首字母大写(如`DataTable`),方法首字母小写(如`layer`),文件夹内主文件与文件夹同名,多文件以`index.js`导出对象(如`./src/components/Layout`)。
- routes:页面为单位以文件夹保存,文件夹名首字母小写(特殊除外,如`UIElement`),文件夹内主文件以`index.js`导出,多文件时可建立`components`文件夹(如`./src/routes/dashboard`),如果有子路由,依次按照路由层次建立文件夹(如`./src/routes/UIElement`)。
### 快速开始
@@ -87,7 +88,6 @@
进入目录安装依赖:
npm i 或者 yarn install
npm i roadhog@0.6.0-beta.6 -g
开发:
@@ -110,6 +110,8 @@ npm run build
npm run lint
```
项目部署 [#269](https://github.com/zuiidea/antd-admin/issues/269)
## 参考
用户列表:<https://github.com/dvajs/dva/tree/master/examples/user-dashboard>
@@ -120,8 +122,8 @@ dashboard设计稿:<https://dribbble.com/shots/3108122-Dashboard-Admin> (已
web
![](assets/demo4.gif)
![](assets/4.2.1-demo-1.gif)
移动
![](assets/demo3.gif)
![](assets/4.2.1-demo-2.gif)
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

+5 -5
View File
@@ -1,15 +1,15 @@
{
"private": true,
"dependencies": {
"antd": "^2.9.1",
"antd": "^2.10.0",
"classnames": "^2.2.5",
"draftjs-to-markdown": "^0.4.0",
"dva": "^1.1.0",
"dva": "^1.2.0",
"dva-loading": "^0.2.0",
"lodash": "^4.17.4",
"nprogress": "^0.2.0",
"qs": "^6.2.0",
"react": "^15.4.1",
"react": "^15.4.4",
"react-countup": "1.3.0",
"react-dom": "^15.4.1",
"react-draft-wysiwyg": "^1.8.1",
@@ -37,7 +37,7 @@
"path-to-regexp": "^1.7.0",
"rc-tween-one": "^1.0.0",
"redbox-react": "^1.2.10",
"roadhog": "^0.6.0-beta.6"
"roadhog": "0.6.0-beta.6"
},
"pre-commit": [
"lint"
@@ -45,6 +45,6 @@
"scripts": {
"dev": "set BROWSER=none&&set HOST=0.0.0.0&&roadhog server",
"lint": "eslint --fix --ext .js src",
"build": "roadhog build --analyze"
"build": "roadhog build"
}
}
+2 -2
View File
@@ -24,7 +24,7 @@ class Search extends React.Component {
clearVisible: e.target.value !== '',
})
}
handeleSelectChange = value => {
handleSelectChange = value => {
this.setState({
...this.state,
selectValue: value,
@@ -42,7 +42,7 @@ class Search extends React.Component {
const { clearVisible } = this.state
return (
<Input.Group compact size={size} className={styles.search} style={style}>
{select && <Select ref="searchSelect" onChange={this.handeleSelectChange} size={size} {...selectProps}>
{select && <Select ref="searchSelect" onChange={this.handleSelectChange} size={size} {...selectProps}>
{selectOptions && selectOptions.map((item, key) => <Select.Option value={item.value} key={key}>{item.name || item.value}</Select.Option>)}
</Select>}
<Input ref="searchInput" size={size} onChange={this.handleInputChange} onPressEnter={this.handleSearch} defaultValue={keyword} />
+12
View File
@@ -14,6 +14,18 @@
<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="/index.js"></script>
</body>
+7
View File
@@ -163,6 +163,13 @@ module.exports = {
})
},
[`DELETE ${apiPrefix}/users`] (req, res) {
const { ids } = req.body
database = database.filter((item) => !ids.some(_ => _ === item.id))
res.status(204).end()
},
[`POST ${apiPrefix}/user`] (req, res) {
const newData = req.body
newData.createTime = Mock.mock('@now')
+24 -2
View File
@@ -1,7 +1,9 @@
import { create, remove, update } from '../services/user'
import { query } from '../services/users'
import * as usersService from '../services/users'
import { parse } from 'qs'
const { query } = usersService
export default {
namespace: 'user',
@@ -11,6 +13,7 @@ export default {
currentItem: {},
modalVisible: false,
modalType: 'create',
selectedRowKeys: [],
isMotion: localStorage.getItem('antdAdminUserIsMotion') === 'true',
pagination: {
showSizeChanger: true,
@@ -54,9 +57,21 @@ export default {
}
},
*'delete' ({ payload }, { call, put }) {
*'delete' ({ payload }, { call, put, select }) {
const data = yield call(remove, { id: payload })
const { selectedRowKeys } = yield select(_ => _.user)
if (data.success) {
yield put({ type: 'updateState', payload: { selectedRowKeys: selectedRowKeys.filter(_ => _ !== payload) } })
yield put({ type: 'query' })
} else {
throw data
}
},
*'multiDelete' ({ payload }, { call, put }) {
const data = yield call(usersService.remove, payload)
if (data.success) {
yield put({ type: 'updateState', payload: { selectedRowKeys: [] } })
yield put({ type: 'query' })
} else {
throw data
@@ -99,6 +114,13 @@ export default {
} }
},
updateState (state, { payload }) {
return {
...state,
...payload,
}
},
showModal (state, action) {
return { ...state, ...action.payload, modalVisible: true }
},
+1 -1
View File
@@ -90,7 +90,7 @@ const List = ({ onDeleteItem, onEditItem, isMotion, location, ...tableProps }) =
{...tableProps}
className={classnames({ [styles.table]: true, [styles.motion]: isMotion })}
bordered
scroll={{ x: 1200 }}
scroll={{ x: 1250 }}
columns={columns}
simple
rowKey={record => record.id}
+11 -7
View File
@@ -17,11 +17,11 @@
.ant-table-tbody > tr > td,
.ant-table-thead > tr > th {
&:nth-child(1) {
width: 6%;
width: 5%;
}
&:nth-child(2) {
width: 8%;
width: 6%;
}
&:nth-child(3) {
@@ -29,7 +29,7 @@
}
&:nth-child(4) {
width: 6%;
width: 8%;
}
&:nth-child(5) {
@@ -37,22 +37,26 @@
}
&:nth-child(6) {
width: 8%;
width: 6%;
}
&:nth-child(7) {
width: 16%;
width: 8%;
}
&:nth-child(8) {
width: 20%;
width: 15%;
}
&:nth-child(9) {
width: 14%;
width: 17%;
}
&:nth-child(10) {
width: 13%;
}
&:nth-child(11) {
width: 8%;
}
}
+33 -1
View File
@@ -2,12 +2,13 @@ import React from 'react'
import PropTypes from 'prop-types'
import { routerRedux } from 'dva/router'
import { connect } from 'dva'
import { Row, Col, Button, Popconfirm } from 'antd'
import List from './List'
import Filter from './Filter'
import Modal from './Modal'
const User = ({ location, dispatch, user, loading }) => {
const { list, pagination, currentItem, modalVisible, modalType, isMotion } = user
const { list, pagination, currentItem, modalVisible, modalType, isMotion, selectedRowKeys } = user
const { pageSize } = pagination
const modalProps = {
@@ -62,6 +63,17 @@ const User = ({ location, dispatch, user, loading }) => {
},
})
},
rowSelection: {
selectedRowKeys,
onChange: (keys) => {
dispatch({
type: 'user/updateState',
payload: {
selectedRowKeys: keys,
},
})
},
},
}
const filterProps = {
@@ -103,9 +115,29 @@ const User = ({ location, dispatch, user, loading }) => {
},
}
const handleDeleteItems = () => {
dispatch({
type: 'user/multiDelete',
payload: {
ids: selectedRowKeys,
},
})
}
return (
<div className="content-inner">
<Filter {...filterProps} />
{
selectedRowKeys.length > 0 &&
<Row style={{ marginBottom: 24, textAlign: 'right', fontSize: 13 }}>
<Col>
{`Selected ${selectedRowKeys.length} items `}
<Popconfirm title={'Are you sure delete these items?'} placement="left" onConfirm={handleDeleteItems}>
<Button type="primary" size="large" style={{ marginLeft: 8 }}>Remove</Button>
</Popconfirm>
</Col>
</Row>
}
<List {...listProps} />
{modalVisible && <Modal {...modalProps} />}
</div>
+8
View File
@@ -9,3 +9,11 @@ export async function query (params) {
data: params,
})
}
export async function remove (params) {
return request({
url: users,
method: 'delete',
data: params,
})
}
-13
View File
@@ -1,13 +0,0 @@
module.exports = () => {
return {
'@border-radius-base': '3px',
'@border-radius-sm': '2px',
'@shadow-color': 'rgba(0,0,0,0.05)',
'@shadow-1-down': '4px 4px 40px @shadow-color',
'@border-color-split': '#f4f4f4',
'@border-color-base': '#e5e5e5',
'@menu-dark-bg': '#3e3e3e',
'@text-color': '#666',
'@font-family': '"AvenirNext-Regular", "Helvetica Neue", "lucida grande", "PingFangHK-Light", "STHeiti", "Heiti SC", "Hiragino Sans GB", "Microsoft JhengHei", "Microsoft Yahei", SimHei, "WenQuanYi Micro Hei", "Droid Sans", "Roboto", Helvetica, Tahoma, Arial, "sans-serif"',
}
}
+1 -1
View File
@@ -50,7 +50,7 @@ const fetch = (options) => {
})
})
} else if (fetchType === 'YQL') {
url = `http://query.yahooapis.com/v1/public/yql?q=select * from json where url='${options.url}?${qs.stringify(options.data)}'&format=json`
url = `http://query.yahooapis.com/v1/public/yql?q=select * from json where url='${options.url}?${encodeURIComponent(qs.stringify(options.data))}'&format=json`
data = null
}