mirror of
https://github.com/zuiidea/antd-admin
synced 2026-10-28 11:24:50 +00:00
repair breadcrumb and routers
This commit is contained in:
@@ -1,81 +1,61 @@
|
||||
import React from 'react';
|
||||
import {Breadcrumb, Icon} from 'antd';
|
||||
import items from 'menu.js';
|
||||
import Logger from '../../utils/logger';
|
||||
import React from 'react'
|
||||
import items from 'menu.js'
|
||||
import {Breadcrumb, Icon} from 'antd'
|
||||
import {Logger} from '../../utils/lib.js'
|
||||
|
||||
const Item = Breadcrumb.Item;
|
||||
const logger = Logger.getLogger('Breadcrumb');
|
||||
const logger = Logger.getLogger('Breadcrumb')
|
||||
|
||||
/**
|
||||
* 定义面包屑导航, 由于和已有的组件重名, 所以改个类名
|
||||
*/
|
||||
class Bread extends React.Component {
|
||||
|
||||
static inited = false; // 表示下面两个map是否初始化
|
||||
static iconMap = new Map(); // 暂存menu.js中key->icon的对应关系
|
||||
static nameMap = new Map(); // 暂存menu.js中key->name的对应关系
|
||||
|
||||
// 初始化iconMap和nameMap
|
||||
static init() {
|
||||
// 箭头函数还是很好用的
|
||||
const Bread = React.createClass({
|
||||
getInitialState() {
|
||||
let iconMap = new Map()
|
||||
let nameMap = new Map()
|
||||
items.forEach((level1) => {
|
||||
Bread.nameMap.set(level1.key, level1.name);
|
||||
logger.debug('nameMap add entry: key=%s, value=%s', level1.key, level1.name);
|
||||
Bread.iconMap.set(level1.key, level1.icon);
|
||||
logger.debug('iconMap add entry: key=%s, value=%s', level1.key, level1.icon);
|
||||
|
||||
nameMap.set(level1.key, level1.name)
|
||||
iconMap.set(level1.key, level1.icon)
|
||||
if (level1.child) {
|
||||
level1.child.forEach((level2) => {
|
||||
Bread.nameMap.set(level2.key, level2.name);
|
||||
logger.debug('nameMap add entry: key=%s, value=%s', level2.key, level2.name);
|
||||
|
||||
nameMap.set(level2.key, level2.name)
|
||||
if (level2.child) {
|
||||
level2.child.forEach((level3)=> {
|
||||
Bread.nameMap.set(level3.key, level3.name);
|
||||
logger.debug('nameMap add entry: key=%s, value=%s', level3.key, level3.name);
|
||||
});
|
||||
level2.child.forEach((level3) => {
|
||||
nameMap.set(level3.key, level3.name)
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
iconMap.set("error", "frown")
|
||||
nameMap.set("error", "页面未找到")
|
||||
return {iconMap, nameMap}
|
||||
},
|
||||
render() {
|
||||
// render之前判断是否要初始化
|
||||
if (!Bread.inited) {
|
||||
logger.debug('not inited, calling init method');
|
||||
Bread.init();
|
||||
Bread.inited = true;
|
||||
}
|
||||
|
||||
const itemArray = [];
|
||||
|
||||
// 面包屑导航的最开始都是一个home图标, 并且这个图标时可以点击的
|
||||
itemArray.push(<Item key="systemHome" href="#"><Icon type="home"/></Item>);
|
||||
|
||||
let itemArray = []
|
||||
const _this = this
|
||||
itemArray.push(
|
||||
<Breadcrumb.Item key="systemHome" href="javascript:;"><Icon type="home"/></Breadcrumb.Item>
|
||||
)
|
||||
for (const route of this.props.routes) {
|
||||
logger.debug('path=%s, route=%o', route.path, route);
|
||||
const name = Bread.nameMap.get(route.path);
|
||||
|
||||
const name = _this.state.nameMap.get(route.path)
|
||||
if (name) {
|
||||
const icon = Bread.iconMap.get(route.path);
|
||||
const icon = _this.state.iconMap.get(route.path)
|
||||
if (icon) {
|
||||
itemArray.push(<Item key={name}><Icon type={icon}/> {name}</Item>); // 有图标的话带上图标
|
||||
itemArray.push(
|
||||
<Breadcrumb.Item key={name}><Icon type={icon}/> {name}</Breadcrumb.Item>
|
||||
)
|
||||
} else {
|
||||
// 这个key属性不是antd需要的, 只是react要求同一个array中各个元素要是不同的, 否则有warning
|
||||
itemArray.push(<Item key={name}>{name}</Item>);
|
||||
itemArray.push(
|
||||
<Breadcrumb.Item key={name}>{name}</Breadcrumb.Item>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 这个面包屑是不可点击的(除了第一级的home图标), 只是给用户一个提示
|
||||
return (
|
||||
<div className="ant-layout-breadcrumb">
|
||||
<Breadcrumb>{itemArray}</Breadcrumb>
|
||||
<Breadcrumb>
|
||||
{itemArray}
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
export default Bread;
|
||||
export default Bread
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
.not-found {
|
||||
color: black;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.not-found h1 {
|
||||
font-family: "PingFang SC",
|
||||
}
|
||||
@@ -1,37 +1,17 @@
|
||||
import React from 'react';
|
||||
import {BackTop} from 'antd';
|
||||
import globalConfig from 'config.js';
|
||||
|
||||
/**
|
||||
* 定义Footer组件
|
||||
*/
|
||||
class Footer extends React.Component {
|
||||
import {config} from '../../utils/lib.js'
|
||||
|
||||
const Footer = React.createClass({
|
||||
render() {
|
||||
// FIXME: gross hack
|
||||
// footer组件第一次render的时候, 不能返回BackTop, 因为main-content-div还没render
|
||||
if (this.inited) {
|
||||
return (
|
||||
<div>
|
||||
<BackTop target={() => document.getElementById('main-content-div')}/>
|
||||
<div className="ant-layout-footer">
|
||||
{globalConfig.footer || 'footer被弄丢啦!'}
|
||||
</div>
|
||||
return (
|
||||
<div>
|
||||
<div className="ant-layout-footer">
|
||||
{config.footer}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
this.inited = true;
|
||||
return (
|
||||
<div>
|
||||
<div className="ant-layout-footer">
|
||||
{globalConfig.footer || 'footer被弄丢啦!'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
export default Footer;
|
||||
|
||||
@@ -5,7 +5,7 @@ import './index.less';
|
||||
|
||||
const SubMenu = Menu.SubMenu;
|
||||
|
||||
let Header = React.createClass({
|
||||
const Header = React.createClass({
|
||||
signOut(){
|
||||
ajax({
|
||||
url:config.user.signOut
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import React from 'react';
|
||||
import './index.less';
|
||||
|
||||
/**
|
||||
* 测试用
|
||||
*/
|
||||
class Hello extends React.Component {
|
||||
|
||||
render() {
|
||||
return <div><h1 className="testStyle">Hello, React!</h1></div>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Hello;
|
||||
@@ -1,3 +0,0 @@
|
||||
.testStyle {
|
||||
color: red;
|
||||
}
|
||||
@@ -12,49 +12,12 @@ const Sider = React.createClass({
|
||||
getInitialState() {
|
||||
let fixed=false;
|
||||
let fixedText="固定";
|
||||
const paths = []
|
||||
const defaultOpenKeys = []
|
||||
if(window.localStorage.getItem("mgFixedSider")&&window.localStorage.getItem("mgFixedSider")=="true"){
|
||||
fixed=true;
|
||||
fixedText="取消";
|
||||
}
|
||||
return {
|
||||
fixed:fixed,
|
||||
collapse: true,
|
||||
fixedText:fixedText
|
||||
}
|
||||
},
|
||||
onCollapseChange() {
|
||||
this.setState({
|
||||
collapse: !this.state.collapse,
|
||||
})
|
||||
},
|
||||
switchFixed(){
|
||||
window.localStorage.setItem("mgFixedSider",!this.state.fixed);
|
||||
this.setState({
|
||||
fixed: !this.state.fixed
|
||||
});
|
||||
if(this.state.fixedText=="固定"){
|
||||
this.setState({
|
||||
fixed: !this.state.fixed,
|
||||
fixedText:"取消"
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
fixed: !this.state.fixed,
|
||||
fixedText:"固定"
|
||||
});
|
||||
}
|
||||
},
|
||||
transFormMenuItem(obj, paths) {
|
||||
const parentPath = paths.join('/')
|
||||
return (
|
||||
<MenuItem key={obj.key}>
|
||||
{obj.child ? obj.name : <Link to={`/${parentPath}`}>{obj.name}</Link> }
|
||||
</MenuItem>
|
||||
)
|
||||
},
|
||||
componentWillMount() {
|
||||
const paths = []
|
||||
const defaultOpenKeys = []
|
||||
const menu = items.map((level1) => {
|
||||
paths.push(level1.key)
|
||||
if (defaultOpenKeys.length === 0) {
|
||||
@@ -84,7 +47,7 @@ const Sider = React.createClass({
|
||||
})
|
||||
paths.pop()
|
||||
return (
|
||||
<SubMenu key={level1.key} title={<span><Icon type={level1.icon} />{level1.name}</span>}>
|
||||
<SubMenu key={level1.key} title={<span> <Icon type={level1.icon} />{level1.name}</span>}>
|
||||
{level2menu}
|
||||
</SubMenu>
|
||||
)
|
||||
@@ -95,8 +58,42 @@ const Sider = React.createClass({
|
||||
return tmp
|
||||
}
|
||||
})
|
||||
this.menu = menu
|
||||
this.defaultOpenKeys = defaultOpenKeys
|
||||
return {
|
||||
fixed:fixed,
|
||||
collapse: true,
|
||||
fixedText:fixedText,
|
||||
menu,
|
||||
}
|
||||
},
|
||||
onCollapseChange() {
|
||||
this.setState({
|
||||
collapse: !this.state.collapse,
|
||||
})
|
||||
},
|
||||
switchFixed(){
|
||||
window.localStorage.setItem("mgFixedSider",!this.state.fixed);
|
||||
this.setState({
|
||||
fixed: !this.state.fixed
|
||||
});
|
||||
if(this.state.fixedText=="固定"){
|
||||
this.setState({
|
||||
fixed: !this.state.fixed,
|
||||
fixedText:"取消"
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
fixed: !this.state.fixed,
|
||||
fixedText:"固定"
|
||||
});
|
||||
}
|
||||
},
|
||||
transFormMenuItem(obj, paths) {
|
||||
const parentPath = paths.join('/')
|
||||
return (
|
||||
<MenuItem key={obj.key}>
|
||||
{obj.child ? obj.name : <Link to={`/${parentPath}`}> {obj.icon ? <Icon type={obj.icon} /> : ''} {obj.name}</Link> }
|
||||
</MenuItem>
|
||||
)
|
||||
},
|
||||
render() {
|
||||
const collapse = this.state.collapse
|
||||
@@ -106,8 +103,8 @@ const Sider = React.createClass({
|
||||
<img src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg" />
|
||||
<span>Ant Design</span>
|
||||
</div>
|
||||
<Menu mode="inline" theme="dark" defaultSelectedKeys={['user']}>
|
||||
{this.menu}
|
||||
<Menu mode="inline" theme="dark" defaultSelectedKeys={['dashboard']}>
|
||||
{this.state.menu}
|
||||
</Menu>
|
||||
<div className="ant-aside-action" onClick={this.onCollapseChange}>
|
||||
{collapse ? <Icon type="right" /> : <Icon type="left" />}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
name: 'Ant Design 管理后台',
|
||||
footer: 'Ant Design Admin 版权所有 © 2016 由zuiidea支持',
|
||||
footer: 'Ant Design Admin 版权所有 © 2016 由 zuiidea 支持',
|
||||
logoImg:'https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg',
|
||||
logoText:'Ant Design',
|
||||
debug: true,
|
||||
|
||||
+7
-5
@@ -1,23 +1,25 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import {Router, Route, IndexRoute, hashHistory} from 'react-router'
|
||||
import {Router, Route, IndexRoute,IndexRedirect,Redirect,hashHistory} from 'react-router'
|
||||
import './utils/index.js'
|
||||
|
||||
import App from './view/index'
|
||||
import SignIn from './view/user/signIn'
|
||||
import List from './view/data/list'
|
||||
import Error from './components/Error'
|
||||
import Hello from './components/Hello'
|
||||
import Dashboard from './view/user/dashboard'
|
||||
import Error from './view/common/error'
|
||||
import './utils/lib.less'
|
||||
|
||||
const routes = (
|
||||
<Router history={hashHistory}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRoute component={List}/>
|
||||
<IndexRedirect to="/dashboard" />
|
||||
<Route path="dashboard" tableName="dashboard" component={Dashboard}/>
|
||||
<Route path="index">
|
||||
<Route path="list" tableName="list" component={List}/>
|
||||
</Route>
|
||||
<Route path="*" component={Error}/>
|
||||
<Route path="error" tableName="error" component={Error}/>
|
||||
<Redirect from="*" to="error" />
|
||||
</Route>
|
||||
</Router>
|
||||
)
|
||||
|
||||
+6
-1
@@ -1,8 +1,13 @@
|
||||
module.exports = [
|
||||
{
|
||||
key: 'dashboard',
|
||||
name: '仪表盘',
|
||||
icon: 'laptop'
|
||||
},
|
||||
{
|
||||
key: 'index',
|
||||
name: '数据相关',
|
||||
icon: 'user',
|
||||
icon: 'file-text',
|
||||
child: [
|
||||
{
|
||||
key: 'list',
|
||||
|
||||
@@ -19,3 +19,34 @@
|
||||
display: table;
|
||||
margin: 16px auto;
|
||||
}
|
||||
|
||||
|
||||
// scrollbar
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
width: 0;
|
||||
height: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
width: 7px;
|
||||
background-color: #b4babf;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import React from 'react';
|
||||
import {Icon} from 'antd';
|
||||
import './index.less';
|
||||
|
||||
/**
|
||||
* 显示错误信息
|
||||
* 可以当404页来用
|
||||
*/
|
||||
class Error extends React.Component {
|
||||
import React from 'react'
|
||||
import { Icon } from 'antd'
|
||||
import './error.less'
|
||||
|
||||
const Error = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<div className="not-found">
|
||||
@@ -16,7 +11,6 @@ class Error extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
export default Error;
|
||||
module.exports = Error
|
||||
@@ -0,0 +1,15 @@
|
||||
.not-found {
|
||||
color: black;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
margin-top: -50px;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
|
||||
h1 {
|
||||
font-family: "PingFang SC",;
|
||||
}
|
||||
}
|
||||
@@ -28,15 +28,14 @@ let List = React.createClass({
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
let pager = this.state.pager
|
||||
pager.current = pagination.current
|
||||
this.setState({
|
||||
pagination: pager,
|
||||
params:{
|
||||
results: pagination.pageSize,
|
||||
page: pagination.current,
|
||||
sortField: sorter.field,
|
||||
sortOrder: sorter.order,
|
||||
...filters
|
||||
}})
|
||||
this.state.pager = pager
|
||||
this.state.params = {
|
||||
results: pagination.pageSize,
|
||||
page: pagination.current,
|
||||
sortField: sorter.field,
|
||||
sortOrder: sorter.order,
|
||||
...filters
|
||||
}
|
||||
this.fetch()
|
||||
},
|
||||
fetch() {
|
||||
|
||||
+8
-11
@@ -28,6 +28,11 @@ const App = React.createClass({
|
||||
},
|
||||
componentDidMount() {
|
||||
const _this = this
|
||||
if(localStorage.getItem("username")&&localStorage.getItem("username")=="guest"&&
|
||||
localStorage.getItem("password")&&localStorage.getItem("password")=='guest'){
|
||||
_this.loginSuccess("guest")
|
||||
return
|
||||
}
|
||||
if (!this.state.login) {
|
||||
const loading = message.loading('正在获取用户信息...', 0)
|
||||
ajax({
|
||||
@@ -70,22 +75,14 @@ const App = React.createClass({
|
||||
</div>
|
||||
</aside>
|
||||
<div className="ant-layout-main">
|
||||
<div className="ant-layout-header">
|
||||
<Header userName={this.state.userName} />
|
||||
</div>
|
||||
<div className="ant-layout-breadcrumb">
|
||||
<Breadcrumb {...this.props} />
|
||||
</div>
|
||||
<Header userName={this.state.userName} />
|
||||
<Breadcrumb {...this.props} />
|
||||
<div className="ant-layout-container">
|
||||
<div className="ant-layout-content">
|
||||
<div style={{ height: 220 }}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ant-layout-footer">
|
||||
Ant Design 版权所有 © 2015 由蚂蚁金服体验技术部支持
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
+6
-1
@@ -96,7 +96,8 @@ body {
|
||||
.ant-layout-content {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
height: e("calc(100vh - 168px)");
|
||||
min-height: e("calc(100vh - 168px)");
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,3 +159,7 @@ body {
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-layout-main{
|
||||
height: 100vh;
|
||||
overflow-y:auto;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react'
|
||||
import { ajax, config, Logger } from '../../utils/lib'
|
||||
import { Icon, message, Button, Row, Col, Form, Input, Select } from 'antd'
|
||||
import './dashboard.less'
|
||||
const logger = Logger.getLogger('Dashboard')
|
||||
|
||||
const Dashboard = React.createClass({
|
||||
render(){
|
||||
return(
|
||||
<div>hello</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = Dashboard
|
||||
|
||||
Reference in New Issue
Block a user