AdminLeft.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import React, { Component } from 'react';
  2. import { Link } from 'react-router-dom';
  3. import { Layout, Menu, Icon, Dropdown, Avatar, Breadcrumb, LocaleProvider } from 'antd';
  4. import zhCN from 'antd/lib/locale-provider/zh_CN';
  5. import '../style/adminLeft.less';
  6. import { User } from '../stores/user';
  7. import { asyncForm, asyncDelConfirm, asyncSMessage } from '../services/AsyncTools';
  8. const { SubMenu } = Menu;
  9. const { Header, Sider } = Layout;
  10. const passwordItemList = [
  11. {
  12. key: 'password',
  13. name: '新密码',
  14. type: 'input',
  15. placeholder: '请输入新密码',
  16. require: true,
  17. },
  18. ];
  19. export default class extends Component {
  20. constructor(props) {
  21. super(props);
  22. const { config, moduleMap } = props;
  23. const state = { routes: [] };
  24. if (config.group) {
  25. state.routes.push({
  26. name: config.group.name,
  27. path: moduleMap[config.module.key].groupMap[config.group.key].path,
  28. });
  29. }
  30. if (config.module && config.group) {
  31. if (moduleMap[config.module.key].groupMap[config.group.key].subList.length > 1 || config.showKey) {
  32. state.routes.push({
  33. name: config.title,
  34. });
  35. }
  36. }
  37. this.state = state;
  38. }
  39. render() {
  40. const { config } = this.props;
  41. return (
  42. <div className="admin-left" style={{ height: window.document.documentElement.clientHeight }}>
  43. {config.module ? this.renderLayoutView() : this.renderContentView(true)}
  44. </div>
  45. );
  46. }
  47. getUserconfigMenu() {
  48. return (
  49. <Menu
  50. style={{ width: '100px', textAlign: 'center' }}
  51. onClick={item => {
  52. switch (item.key) {
  53. case 'password':
  54. asyncForm('修改密码', passwordItemList, {}, data => {
  55. return User.editPassword(data).then(() => {
  56. asyncSMessage('密码修改成功!');
  57. });
  58. });
  59. break;
  60. case 'logout':
  61. asyncDelConfirm('退出', '是否退出当前帐号?', () => {
  62. User.logout().then(() => {
  63. asyncSMessage('帐号已退出!');
  64. });
  65. });
  66. break;
  67. default:
  68. break;
  69. }
  70. }}
  71. >
  72. <Menu.Item key="password">
  73. <Icon type="edit" />
  74. 修改密码
  75. </Menu.Item>
  76. <Menu.Divider />
  77. <Menu.Item key="logout">
  78. <Icon type="logout" />
  79. 退出登录
  80. </Menu.Item>
  81. </Menu>
  82. );
  83. }
  84. getOtherLink() {
  85. const { project } = this.props;
  86. return (
  87. <Menu
  88. style={{ width: '100px', textAlign: 'center' }}
  89. onClick={item => {
  90. toLink(item.key);
  91. }}
  92. >
  93. {project.otherLink.map(link => {
  94. return (
  95. <Menu.Item key={link.path}>
  96. <Icon type="link" />
  97. {link.title}
  98. </Menu.Item>
  99. );
  100. })}
  101. </Menu>
  102. );
  103. }
  104. renderLayoutView() {
  105. const { moduleMap, config, user, project } = this.props;
  106. const { collapsed, logo, name, username, openMenu } = user;
  107. return (
  108. <LocaleProvider locale={zhCN}>
  109. <Layout style={{ height: '100%' }}>
  110. {config.group && (
  111. <Sider className="left-slider" collapsed={collapsed}>
  112. <Link to="/">
  113. <div id="logo">
  114. <img src={logo} />
  115. <h1>{name}</h1>
  116. </div>
  117. </Link>
  118. <Menu
  119. mode="inline"
  120. theme="dark"
  121. key={`${collapsed}`}
  122. defaultSelectedKeys={[config.showKey || config.key, config.group.key]}
  123. defaultOpenKeys={collapsed ? [] : openMenu[config.module.key] || [config.group.key]}
  124. onClick={e => linkTo(e.item.props.path)}
  125. onOpenChange={keys => !collapsed && User.openMenu(config.module.key, keys)}
  126. >
  127. {moduleMap[config.module.key].groupList.map(key => {
  128. const group = moduleMap[config.module.key].groupMap[key];
  129. const hasSub = group.subList.length > 1;
  130. const view = hasSub ? (
  131. <SubMenu
  132. key={group.key}
  133. title={
  134. <span>
  135. <Icon type={group.icon} />
  136. <span>{group.name}</span>
  137. </span>
  138. }
  139. >
  140. {group.subList.map(k => {
  141. const sub = group.subMap[k];
  142. return (
  143. <Menu.Item key={sub.key} path={sub.path}>
  144. <Icon type={sub.icon} />
  145. <span>{sub.name || sub.title}</span>
  146. </Menu.Item>
  147. );
  148. })}
  149. </SubMenu>
  150. ) : (
  151. <Menu.Item key={group.key} path={group.path}>
  152. <Icon type={group.icon} />
  153. <span>{group.name}</span>
  154. </Menu.Item>
  155. );
  156. return view;
  157. })}
  158. </Menu>
  159. </Sider>
  160. )}
  161. <Layout id="right-layout">
  162. <Header id="layout-header">
  163. <Icon
  164. className="trigger"
  165. type={collapsed ? 'menu-unfold' : 'menu-fold'}
  166. onClick={() => User.switchCollapse()}
  167. />
  168. <div className="f-r">
  169. {/* <Tooltip placement="bottom" title="使用文档">
  170. <Icon className="icon" type="question-circle" />
  171. </Tooltip>
  172. <Tooltip placement="bottom" title="消息">
  173. <Icon className="icon" type="bell" />
  174. </Tooltip> */}
  175. {project.otherLink && project.otherLink.length > 0 && (
  176. <Dropdown overlay={this.getOtherLink()} placement="bottomCenter">
  177. <Icon className="icon" type="link" />
  178. </Dropdown>
  179. )}
  180. <Dropdown overlay={this.getUserconfigMenu()} placement="bottomCenter">
  181. <div className="user-info" style={{ display: 'inline-block' }}>
  182. <Avatar className="avatar" size="small" icon="user" />
  183. <span className="m-l-1">{username}</span>
  184. </div>
  185. </Dropdown>
  186. </div>
  187. </Header>
  188. <Layout className="page-layout">{this.renderContentView(false)}</Layout>
  189. </Layout>
  190. </Layout>
  191. </LocaleProvider>
  192. );
  193. }
  194. itemRender(route) {
  195. return !route.path ? <span>{route.name}</span> : <Link to={route.path}>{route.name}</Link>;
  196. }
  197. renderContentView(free) {
  198. const { config, children } = this.props;
  199. return (
  200. <div className="page-content">
  201. {!free && !config.free && (
  202. <Breadcrumb
  203. hidden={config.free || !config.module}
  204. itemRender={this.itemRender}
  205. routes={this.state.routes}
  206. separator="/"
  207. />
  208. )}
  209. {children}
  210. </div>
  211. );
  212. }
  213. }