├── .gitignore ├── LICENSE ├── README.md ├── config ├── env.js ├── jest │ ├── cssTransform.js │ └── fileTransform.js ├── paths.js ├── webpack.config.dev.js ├── webpack.config.prod.js └── webpackDevServer.config.js ├── doc ├── 10.第十章 员工管理 │ └── 10 员工管理.md ├── 11.第十一章 车辆地图 │ └── 11 车辆地图.md ├── 12.第十二章 Echarts图表 │ └── 12 Echarts图表.md ├── 13.第十三章 权限模块 │ ├── 13.1 权限设置.md │ ├── 13.2 菜单调整.md │ └── 13.3 用户授权.md ├── 14.第十四章 redux集成 │ └── 14 redux项目集成.md ├── 15.第十五章 登录模块 │ ├── 15.1 登录部分.md │ ├── 15.2登录部分封装redux.md │ └── 15.3 页面刷新面包屑.md ├── 4.第四章 UI组件 │ ├── 4.1- 按钮+Modal组件.md │ ├── 4.2-Spin组件.md │ ├── 4.3 Notification 通知提醒框.md │ ├── 4.4 Message全局提示.md │ ├── 4.5 Tabs标签页.md │ ├── 4.6 gallery图片画廊.md │ └── 4.7 Carousel轮播图.md ├── 5.第五章 Form表单 │ ├── 5.1 From组件登录页面.md │ └── 5.2 From组件注册页面.md ├── 6.第六章 Table表格 │ ├── 6.1 Table表格.md │ └── 6.2 高级表格.md ├── 7.第七章 富文本编辑器 │ └── 7 富文本编辑器.md ├── 8.第八章 城市管理和订单管理 │ ├── 8.1 城市管理.md │ └── 8.2 订单管理.md ├── 9.第九章 项目工程化 │ └── 9 项目工程化.md ├── README.md ├── react 单车 │ ├── 2-项目主页工程搭建.pdf │ ├── 2.2-页面主页结构开发.pdf │ ├── 2.6-头部组件实现(上).pdf │ └── 第三章 │ │ └── pdf │ │ ├── 3-1.React Router 4.0 基本概念的介绍.pdf │ │ ├── 3-2 4.0基本路由功能DEMO实现-配置化.pdf │ │ ├── 3.1-1 React Router4.0 Demo介绍.pdf │ │ ├── 3.3 获取路由的id(获取url的id值).pdf │ │ └── 3.4 项目路由实战开发.pdf ├── 接口列表.txt ├── 搭建React开发环境之前的准备工作.md └── 项目地址.txt ├── package.json ├── public ├── assets │ ├── bike.jpg │ ├── end_point.png │ ├── imooc.png │ ├── logo-ant.svg │ ├── start_point.png │ └── user_location.png ├── carousel-img │ ├── carousel-1.jpg │ ├── carousel-2.jpg │ └── carousel-3.jpg ├── favicon.ico ├── gallery │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 17.png │ ├── 18.png │ ├── 19.png │ ├── 2.png │ ├── 20.png │ ├── 21.png │ ├── 22.png │ ├── 23.png │ ├── 24.png │ ├── 25.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png ├── index.html └── manifest.json ├── scripts ├── build.js ├── start.js └── test.js ├── src ├── App.css ├── App.js ├── App.test.js ├── admin.js ├── axios │ └── index.js ├── common.js ├── components │ ├── BaseForm │ │ └── index.js │ ├── ETable │ │ ├── index.js │ │ └── index.less │ ├── Footer │ │ ├── index.js │ │ └── index.less │ ├── Header │ │ ├── index.js │ │ └── index.less │ └── NavLeft │ │ ├── index.js │ │ └── index.less ├── config │ └── menuConfig.js ├── index.css ├── index.js ├── logo.svg ├── pages │ ├── city │ │ └── index.js │ ├── demo │ │ ├── Child.js │ │ ├── Life.js │ │ └── index.less │ ├── echarts │ │ ├── bar │ │ │ └── index.js │ │ ├── echartTheme.js │ │ ├── line │ │ │ └── index.js │ │ ├── pie │ │ │ └── index.js │ │ └── themeLight.js │ ├── form │ │ ├── login.js │ │ └── register.js │ ├── home │ │ ├── index.js │ │ └── index.less │ ├── login │ │ ├── index.js │ │ └── index.less │ ├── map │ │ └── bikeMap.js │ ├── nomatch │ │ └── index.js │ ├── order │ │ ├── detail.js │ │ ├── detail.less │ │ └── index.js │ ├── permission │ │ └── index.js │ ├── rich │ │ └── index.js │ ├── route_demo │ │ ├── router1 │ │ │ ├── About.js │ │ │ ├── Home.js │ │ │ ├── Main.js │ │ │ └── Topic.js │ │ ├── router2 │ │ │ ├── Home.js │ │ │ └── router.js │ │ ├── router3 │ │ │ ├── Home.js │ │ │ ├── Main.js │ │ │ └── router.js │ │ ├── router4 │ │ │ ├── Home.js │ │ │ ├── Main.js │ │ │ ├── info.js │ │ │ └── router.js │ │ └── router5 │ │ │ ├── Home.js │ │ │ ├── Main.js │ │ │ ├── NoMatch.js │ │ │ ├── info.js │ │ │ └── router.js │ ├── table │ │ ├── basicTable.js │ │ └── highTable.js │ ├── ui │ │ ├── buttons.js │ │ ├── carousel.js │ │ ├── gallery.js │ │ ├── loadings.js │ │ ├── messages.js │ │ ├── modals.js │ │ ├── notice.js │ │ ├── tabs.js │ │ └── ui.less │ └── user │ │ └── index.js ├── redux │ ├── action │ │ └── index.js │ ├── reducer │ │ └── index.js │ └── store │ │ └── configureStore.js ├── resources │ ├── assets │ │ ├── bike.jpg │ │ ├── carousel-img │ │ │ ├── carousel-1.jpg │ │ │ ├── carousel-2.jpg │ │ │ └── carousel-3.jpg │ │ ├── end_point.png │ │ ├── imooc.png │ │ ├── logo-ant.svg │ │ ├── start_point.png │ │ └── user_location.png │ ├── menuConfig.js │ └── resource │ │ ├── api │ │ ├── .json │ │ ├── city │ │ │ ├── list.json │ │ │ └── open.json │ │ ├── info_alarm.json │ │ ├── map │ │ │ └── bike_list.json │ │ ├── mock.json │ │ ├── open_city.json │ │ ├── order │ │ │ ├── detail.json │ │ │ ├── ebike_info.json │ │ │ ├── finish_order.json │ │ │ └── list.json │ │ ├── permission │ │ │ └── edit.json │ │ ├── proxy.json │ │ ├── query.json │ │ ├── restful │ │ │ └── _id │ │ │ │ └── list.json │ │ ├── role │ │ │ ├── create.json │ │ │ ├── list.json │ │ │ ├── user_list.json │ │ │ └── user_role_edit.json │ │ ├── table │ │ │ ├── high │ │ │ │ └── list.json │ │ │ ├── list.json │ │ │ └── list1.json │ │ ├── upload.json │ │ └── user │ │ │ ├── add.json │ │ │ ├── delete.json │ │ │ └── edit.json │ │ ├── assets │ │ ├── bike.jpg │ │ ├── carousel-img │ │ │ ├── carousel-1.jpg │ │ │ ├── carousel-2.jpg │ │ │ └── carousel-3.jpg │ │ ├── end_point.png │ │ ├── imooc.png │ │ ├── logo-ant.svg │ │ ├── start_point.png │ │ └── user_location.png │ │ ├── carousel-img │ │ ├── carousel-1.jpg │ │ ├── carousel-2.jpg │ │ └── carousel-3.jpg │ │ ├── common.less │ │ ├── default.less │ │ ├── doc.js │ │ ├── favicon.ico │ │ ├── gallery │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ │ ├── header │ │ └── index.less │ │ ├── image │ │ └── demo.png │ │ ├── loading.html │ │ ├── loading.less │ │ ├── menuConfig.js │ │ ├── order │ │ └── detail.less │ │ └── ui.less ├── router.js ├── serviceWorker.js ├── style │ ├── common.less │ ├── default.less │ └── loading.less └── utils │ └── utils.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 lenvo222 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # React全家桶+AntD框架开发共享单车后台管理系统 4 | 5 | ### 使用介绍 6 | 7 | #### npm install 安装项目 8 | 9 | #### npm start 运行项目 10 | 11 | ------ 12 | 13 | 14 | 15 | 16 | ​ 大家好,我是河畔一角,目前在一家共享单车公司担任前端架构师职位,作为一名前端工程师,我非常渴望能够讲自己多年来汲取的精华知识传授给大家,非常渴望能够去解决大家在开发过程中的痛点。经过一段时间的调研,我总结出了其中一个非常重要的结论,大家在开发后台管理系统的时候,往往举足不定,因为工作经验不足,技术有壁垒。本次借此机会,我耗时几个月给大家做了一次针对后台管理系统的课程:[React全家桶+AntD框架开发共享单车后台管理系统](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji) 17 | 18 | [ 这门课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)从几个维度进行刨析: 19 | 20 | ​ 第一:使用目前最流行的前端MV*框架开发,React全家桶一应俱全,技术不落伍。 21 | 22 | ​ 第二:好马配好鞍,有了技术框架,对于后台系统来说,必然需要有一把利剑,那就是AntD. AntD是蚂蚁金服公司出品的一款React UI框架,极大便利了我们的前端React开发者。可能有的同学会说,React UI框架有很多,并不止这一个,这样说确实没有问题,UI框架有很多,我们要从很多方面去综合评估,比如star数量、社区活跃度、github的issue解决数量、版本更新周期、公司平台规模等各个方面进行考察,千万别一失足成千古恨。 当然elementUI也是一款不错的UI框架,根据自己的喜好进行自由选择。 23 | 24 | ​ 第三:后台管理系统必然需要在架构层面,做到坚如磐石,能扛起一个公司的业务,要让新入职的同事莫名的喜欢,觉得我们的系统做的非常好,工作及其有动力。 25 | 26 | ​ 第四:对于后台管理系统来说,各个公司业务不尽相同,但是也会有业务上的差异,比如传统公司的后台会有各种报表、普通的互联网公司后台通常会有权限、增删改查的功能、单车公司的后台通常会有各种地图业务等等,面对这样的需求点,[本门实战课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)将以上功能全部进行汇聚,根据自身业务,选择性套用,一旦掌握,就可以以不变应万变,理解知识、学以致用。 27 | 28 | ​ 第五:从技术层来讲,[本次实战课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)包括了各种公共机制的封装,比如:Loading封装、错误拦截、Ajax请求封装、Promise的使用、Modal封装、分页封装、日期金额格式化、Notice组件、message组件的使用等,对于后台管理系统来说是极大的福利。 29 | 30 | ​ 第六:项目架构设计。 一个优秀的后台系统必然有一个优秀的后台架构。[本次实战课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)在页面结构设计上可以说涵盖了多个层次,登录页面、主页面、订单详情页面作为一级窗口,但在架构设计上又不完全相同。主页面本身又分为多级视图,因此次页面设计已经能够符合我们主流的后台管理系统设计开发。 31 | 32 | 以上是我对[本次实战课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)的6条总结,接下来我们看一下页面的内容: 33 | 34 | 1. 登录页面 35 | 36 | ![https://img3.mukewang.com/5b2a652700012d5325541396.jpg](https://img2.mukewang.com/5b2a652700012d5305000274.jpg) 37 | 38 | 登录页面并未在[本次实战课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)做详细介绍,目前课程源码已经包含了此页面,主要是一张大背景,外加AntD设计的登录框功能,风格简单,功能实用。 39 | 40 | \2. 项目主页面 41 | 42 | ![https://img3.mukewang.com/5b2a68160001aae525561402.jpg](https://img3.mukewang.com/5b2a68160001aae505000275.jpg) 43 | 44 | 主页面会根据当前登录用户的权限进行动态加载菜单。 45 | 46 | 3.AntD的Button页面 47 | 48 | ![https://img4.mukewang.com/5b2a68060001ce7d25521392.jpg](https://img3.mukewang.com/5b2a68060001ce7d05000273.jpg) 49 | 50 | 4.Echart图表页面 51 | 52 | ![https://img3.mukewang.com/5b2a680a00010e3725581408.jpg](https://img1.mukewang.com/5b2a680a00010e3705000276.jpg) 53 | 54 | 5.城市管理页面 55 | 56 | ![https://img1.mukewang.com/5b2a680e0001107c25561404.jpg](https://img1.mukewang.com/5b2a680e0001107c05000275.jpg) 57 | 58 | 6.Echart饼形图页面 59 | 60 | ![https://img2.mukewang.com/5b2a68130001295225501402.jpg](https://img2.mukewang.com/5b2a68130001295205000275.jpg) 61 | 62 | 7.UI轮播图,包含文字轮播和图片轮播 63 | 64 | ![https://img3.mukewang.com/5b2a681b0001fd6c25541400.jpg](https://img1.mukewang.com/5b2a681b0001fd6c05000275.jpg) 65 | 66 | 8.车辆地图页面 67 | 68 | ![https://img3.mukewang.com/5b2a681d000118bc25541382.jpg](https://img.mukewang.com/5b2a681d000118bc05000271.jpg) 69 | 70 | 9.用户授权页面 71 | 72 | ![https://img.mukewang.com/5b2a681e000125e125541404.jpg](https://img.mukewang.com/5b2a681e000125e105000275.jpg) 73 | 74 | 10.高级表格页面 75 | 76 | ![https://img4.mukewang.com/5b2a68210001cb4e25561408.jpg](https://img.mukewang.com/5b2a68210001cb4e05000276.jpg) 77 | 78 | 11.菜单权限页面 79 | 80 | ![https://img4.mukewang.com/5b2a68250001885625541402.jpg](https://img1.mukewang.com/5b2a68250001885605000275.jpg) 81 | 82 | 12.员工管理页面 83 | 84 | ![https://img2.mukewang.com/5b2a68280001222b25581400.jpg](https://img.mukewang.com/5b2a68280001222b05000274.jpg) 85 | 86 | 13.表单页面 87 | 88 | ![https://img3.mukewang.com/5b2a68290001530825561400.jpg](https://img4.mukewang.com/5b2a68290001530805000274.jpg) 89 | 90 | 14.订单详情页面 91 | 92 | ![https://img2.mukewang.com/5b2a6bf7000146c525581404.jpg](https://img4.mukewang.com/5b2a6bf7000146c505000275.jpg) 93 | 94 | 从页面分布来看,[实战课程](https://coding.imooc.com/class/236.html?mc_marking=6ad933461923d016d2d2682dbe41158f&mc_channel=shouji)内容非常丰富,从UI框架到共享单车的核心模块,一应俱全。从React全家桶知识介绍到项目架构、项目工程化等非常详细的讲解了后台管理系统的开发流程和前端工程师的进阶之路。 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /config/env.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const paths = require('./paths'); 6 | 7 | // Make sure that including paths.js after env.js will read .env variables. 8 | delete require.cache[require.resolve('./paths')]; 9 | 10 | const NODE_ENV = process.env.NODE_ENV; 11 | if (!NODE_ENV) { 12 | throw new Error( 13 | 'The NODE_ENV environment variable is required but was not specified.' 14 | ); 15 | } 16 | 17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use 18 | var dotenvFiles = [ 19 | `${paths.dotenv}.${NODE_ENV}.local`, 20 | `${paths.dotenv}.${NODE_ENV}`, 21 | // Don't include `.env.local` for `test` environment 22 | // since normally you expect tests to produce the same 23 | // results for everyone 24 | NODE_ENV !== 'test' && `${paths.dotenv}.local`, 25 | paths.dotenv, 26 | ].filter(Boolean); 27 | 28 | // Load environment variables from .env* files. Suppress warnings using silent 29 | // if this file is missing. dotenv will never modify any environment variables 30 | // that have already been set. Variable expansion is supported in .env files. 31 | // https://github.com/motdotla/dotenv 32 | // https://github.com/motdotla/dotenv-expand 33 | dotenvFiles.forEach(dotenvFile => { 34 | if (fs.existsSync(dotenvFile)) { 35 | require('dotenv-expand')( 36 | require('dotenv').config({ 37 | path: dotenvFile, 38 | }) 39 | ); 40 | } 41 | }); 42 | 43 | // We support resolving modules according to `NODE_PATH`. 44 | // This lets you use absolute paths in imports inside large monorepos: 45 | // https://github.com/facebook/create-react-app/issues/253. 46 | // It works similar to `NODE_PATH` in Node itself: 47 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders 48 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. 49 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. 50 | // https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421 51 | // We also resolve them to make sure all tools using them work consistently. 52 | const appDirectory = fs.realpathSync(process.cwd()); 53 | process.env.NODE_PATH = (process.env.NODE_PATH || '') 54 | .split(path.delimiter) 55 | .filter(folder => folder && !path.isAbsolute(folder)) 56 | .map(folder => path.resolve(appDirectory, folder)) 57 | .join(path.delimiter); 58 | 59 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 60 | // injected into the application via DefinePlugin in Webpack configuration. 61 | const REACT_APP = /^REACT_APP_/i; 62 | 63 | function getClientEnvironment(publicUrl) { 64 | const raw = Object.keys(process.env) 65 | .filter(key => REACT_APP.test(key)) 66 | .reduce( 67 | (env, key) => { 68 | env[key] = process.env[key]; 69 | return env; 70 | }, 71 | { 72 | // Useful for determining whether we’re running in production mode. 73 | // Most importantly, it switches React into the correct mode. 74 | NODE_ENV: process.env.NODE_ENV || 'development', 75 | // Useful for resolving the correct path to static assets in `public`. 76 | // For example, . 77 | // This should only be used as an escape hatch. Normally you would put 78 | // images into the `src` and `import` them in code to get their paths. 79 | PUBLIC_URL: publicUrl, 80 | } 81 | ); 82 | // Stringify all values so we can feed into Webpack DefinePlugin 83 | const stringified = { 84 | 'process.env': Object.keys(raw).reduce((env, key) => { 85 | env[key] = JSON.stringify(raw[key]); 86 | return env; 87 | }, {}), 88 | }; 89 | 90 | return { raw, stringified }; 91 | } 92 | 93 | module.exports = getClientEnvironment; 94 | -------------------------------------------------------------------------------- /config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | // This is a custom Jest transformer turning file imports into filenames. 6 | // http://facebook.github.io/jest/docs/en/webpack.html 7 | 8 | module.exports = { 9 | process(src, filename) { 10 | const assetFilename = JSON.stringify(path.basename(filename)); 11 | 12 | if (filename.match(/\.svg$/)) { 13 | return `module.exports = { 14 | __esModule: true, 15 | default: ${assetFilename}, 16 | ReactComponent: (props) => ({ 17 | $$typeof: Symbol.for('react.element'), 18 | type: 'svg', 19 | ref: null, 20 | key: null, 21 | props: Object.assign({}, props, { 22 | children: ${assetFilename} 23 | }) 24 | }), 25 | };`; 26 | } 27 | 28 | return `module.exports = ${assetFilename};`; 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const url = require('url'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebook/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | const envPublicUrl = process.env.PUBLIC_URL; 13 | 14 | function ensureSlash(inputPath, needsSlash) { 15 | const hasSlash = inputPath.endsWith('/'); 16 | if (hasSlash && !needsSlash) { 17 | return inputPath.substr(0, inputPath.length - 1); 18 | } else if (!hasSlash && needsSlash) { 19 | return `${inputPath}/`; 20 | } else { 21 | return inputPath; 22 | } 23 | } 24 | 25 | const getPublicUrl = appPackageJson => 26 | envPublicUrl || require(appPackageJson).homepage; 27 | 28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 29 | // "public path" at which the app is served. 30 | // Webpack needs to know it to put the right 26 | 27 | 28 | 29 | 32 |
33 | 40 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /scripts/start.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = 'development'; 5 | process.env.NODE_ENV = 'development'; 6 | 7 | // Makes the script crash on unhandled rejections instead of silently 8 | // ignoring them. In the future, promise rejections that are not handled will 9 | // terminate the Node.js process with a non-zero exit code. 10 | process.on('unhandledRejection', err => { 11 | throw err; 12 | }); 13 | 14 | // Ensure environment variables are read. 15 | require('../config/env'); 16 | 17 | 18 | const fs = require('fs'); 19 | const chalk = require('chalk'); 20 | const webpack = require('webpack'); 21 | const WebpackDevServer = require('webpack-dev-server'); 22 | const clearConsole = require('react-dev-utils/clearConsole'); 23 | const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); 24 | const { 25 | choosePort, 26 | createCompiler, 27 | prepareProxy, 28 | prepareUrls, 29 | } = require('react-dev-utils/WebpackDevServerUtils'); 30 | const openBrowser = require('react-dev-utils/openBrowser'); 31 | const paths = require('../config/paths'); 32 | const config = require('../config/webpack.config.dev'); 33 | const createDevServerConfig = require('../config/webpackDevServer.config'); 34 | 35 | const useYarn = fs.existsSync(paths.yarnLockFile); 36 | const isInteractive = process.stdout.isTTY; 37 | 38 | // Warn and crash if required files are missing 39 | if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { 40 | process.exit(1); 41 | } 42 | 43 | // Tools like Cloud9 rely on this. 44 | const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; 45 | const HOST = process.env.HOST || '0.0.0.0'; 46 | 47 | if (process.env.HOST) { 48 | console.log( 49 | chalk.cyan( 50 | `Attempting to bind to HOST environment variable: ${chalk.yellow( 51 | chalk.bold(process.env.HOST) 52 | )}` 53 | ) 54 | ); 55 | console.log( 56 | `If this was unintentional, check that you haven't mistakenly set it in your shell.` 57 | ); 58 | console.log( 59 | `Learn more here: ${chalk.yellow('http://bit.ly/CRA-advanced-config')}` 60 | ); 61 | console.log(); 62 | } 63 | 64 | // We require that you explictly set browsers and do not fall back to 65 | // browserslist defaults. 66 | const { checkBrowsers } = require('react-dev-utils/browsersHelper'); 67 | checkBrowsers(paths.appPath, isInteractive) 68 | .then(() => { 69 | // We attempt to use the default port but if it is busy, we offer the user to 70 | // run on a different port. `choosePort()` Promise resolves to the next free port. 71 | return choosePort(HOST, DEFAULT_PORT); 72 | }) 73 | .then(port => { 74 | if (port == null) { 75 | // We have not found a port. 76 | return; 77 | } 78 | const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; 79 | const appName = require(paths.appPackageJson).name; 80 | const urls = prepareUrls(protocol, HOST, port); 81 | // Create a webpack compiler that is configured with custom messages. 82 | const compiler = createCompiler(webpack, config, appName, urls, useYarn); 83 | // Load proxy config 84 | const proxySetting = require(paths.appPackageJson).proxy; 85 | const proxyConfig = prepareProxy(proxySetting, paths.appPublic); 86 | // Serve webpack assets generated by the compiler over a web server. 87 | const serverConfig = createDevServerConfig( 88 | proxyConfig, 89 | urls.lanUrlForConfig 90 | ); 91 | const devServer = new WebpackDevServer(compiler, serverConfig); 92 | // Launch WebpackDevServer. 93 | devServer.listen(port, HOST, err => { 94 | if (err) { 95 | return console.log(err); 96 | } 97 | if (isInteractive) { 98 | clearConsole(); 99 | } 100 | console.log(chalk.cyan('Starting the development server...\n')); 101 | openBrowser(urls.localUrlForBrowser); 102 | }); 103 | 104 | ['SIGINT', 'SIGTERM'].forEach(function(sig) { 105 | process.on(sig, function() { 106 | devServer.close(); 107 | process.exit(); 108 | }); 109 | }); 110 | }) 111 | .catch(err => { 112 | if (err && err.message) { 113 | console.log(err.message); 114 | } 115 | process.exit(1); 116 | }); 117 | -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = 'test'; 5 | process.env.NODE_ENV = 'test'; 6 | process.env.PUBLIC_URL = ''; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on('unhandledRejection', err => { 12 | throw err; 13 | }); 14 | 15 | // Ensure environment variables are read. 16 | require('../config/env'); 17 | 18 | 19 | const jest = require('jest'); 20 | const execSync = require('child_process').execSync; 21 | let argv = process.argv.slice(2); 22 | 23 | function isInGitRepository() { 24 | try { 25 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); 26 | return true; 27 | } catch (e) { 28 | return false; 29 | } 30 | } 31 | 32 | function isInMercurialRepository() { 33 | try { 34 | execSync('hg --cwd . root', { stdio: 'ignore' }); 35 | return true; 36 | } catch (e) { 37 | return false; 38 | } 39 | } 40 | 41 | // Watch unless on CI, in coverage mode, or explicitly running all tests 42 | if ( 43 | !process.env.CI && 44 | argv.indexOf('--coverage') === -1 && 45 | argv.indexOf('--watchAll') === -1 46 | ) { 47 | // https://github.com/facebook/create-react-app/issues/5210 48 | const hasSourceControl = isInGitRepository() || isInMercurialRepository(); 49 | argv.push(hasSourceControl ? '--watch' : '--watchAll'); 50 | } 51 | 52 | 53 | jest.run(argv); 54 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | } 9 | 10 | .App-header { 11 | background-color: #282c34; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-direction: column; 15 | align-items: center; 16 | justify-content: center; 17 | font-size: calc(10px + 2vmin); 18 | color: white; 19 | } 20 | 21 | .App-link { 22 | color: #61dafb; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { 27 | transform: rotate(0deg); 28 | } 29 | to { 30 | transform: rotate(360deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import './App.css'; 3 | 4 | class App extends Component { 5 | render() { 6 | return ( 7 |
8 | {this.props.children} 9 |
10 | ); 11 | } 12 | } 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/admin.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Row, Col } from "antd"; 3 | import Header from "./components/Header"; 4 | import Footer from "./components/Footer"; 5 | import NavLeft from "./components/NavLeft"; 6 | import './style/common.less' 7 | import Home from './pages/home'//在这里导入Home组件,以后使用路由进行更改 8 | export default class Admin extends React.Component { 9 | render() { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | {/* Right */} 17 |
18 | 19 | {/*content*/} 20 | {/* */} 21 | {this.props.children} 22 | 23 |
Footer
24 | 25 | 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/axios/index.js: -------------------------------------------------------------------------------- 1 | //src/axios/index.js 2 | //对jsonp的方法进行封装 3 | import JsonP from "jsonp";//*导入jsonp的插件 4 | import axios from 'axios';//*导入axios插件 5 | import {Modal} from "antd"; 6 | import Utils from "../utils/utils"; 7 | //导出一个对象供其他对象进行使用 8 | export default class Axios { 9 | // _this: this ,url:接口的url, params:需要传递到接口的数据, isMock:是否为Mock数据 10 | // 定义方法,为请求的列表使用 11 | static requestList(_this, url, params,isMock){ 12 | var data = { 13 | params: params, 14 | isMock // 使用Mock数据 15 | }; 16 | 17 | // 调用ajax 拦截公共机制 18 | // ES6省略语法 19 | // 相当于 url:url 20 | this.ajax({ 21 | url, 22 | data 23 | }).then((data) => { //得到数据data 24 | if (data && data.result) { 25 | // 如果data 是true 进行操作 26 | let list = data.result.item_list.map((item, index) => { 27 | item.key = index; 28 | return item; 29 | }); 30 | _this.setState({ 31 | list, 32 | pagination: Utils.pagination(data, (current) => { 33 | _this.params.page = current; 34 | _this.requestList(); 35 | }) 36 | }); 37 | } 38 | }); 39 | }; 40 | 41 | static jsonp(options) {//定义静态的方法 jsonp 供其他页面进行使用 42 | return new Promise((resolve, reject) => {//使用Promise解决函数间的嵌套问题 链式调用 43 | JsonP(options.url, { 44 | param: 'callback' 45 | }, function (err, response) { 46 | //to-do 47 | //传入JsoP的对象进行操作 48 | //如果返回的对象是成功,使用resolve方法进行返回 49 | //debugger;//通过这个打断点 50 | if (response.status == 'success') {//成功后 用resolve返回数据 51 | resolve(response); 52 | } else { //失败后用reject返回数据 53 | reject(response.message); 54 | } 55 | }); 56 | }); 57 | } 58 | 59 | static ajax(options) {//封装axios 定义为ajax请求,使用Promise 60 | let loading; 61 | if (options.data && options.data.isShowLoading !== false) { 62 | loading = document.getElementById('ajaxLoading'); 63 | loading.style.display = 'block'; 64 | } 65 | let baseApi = ''; 66 | if (options.isMock) { 67 | baseApi = 'https://easy-mock.com/mock/5c0893b83b84ee1919884836/mock.api'; 68 | }else { 69 | // 不是mock数据修改为真实接口 70 | baseApi = 'https://easy-mock.com/mock/5c0893b83b84ee1919884836/mock.api'; 71 | } 72 | 73 | return new Promise((resolve, reject) => { 74 | axios({ 75 | url: options.url, 76 | method: 'get', 77 | baseURL: baseApi, 78 | timeout: 5000, 79 | params: (options.data && options.data.params) || '' 80 | }).then((response) => { 81 | if (options.data && options.data.isShowLoading !== false) { 82 | loading = document.getElementById('ajaxLoading'); 83 | loading.style.display = 'none'; 84 | } 85 | if (response.status == '200') { 86 | let res = response.data; 87 | if (res.code == '0') { 88 | resolve(res); 89 | } else { 90 | Modal.info({ 91 | title: "提示", 92 | content: res.msg 93 | }); 94 | } 95 | } else { 96 | reject(response.data); 97 | } 98 | }); 99 | }); 100 | } 101 | } -------------------------------------------------------------------------------- /src/common.js: -------------------------------------------------------------------------------- 1 | // src/common.js 2 | import React from "react"; 3 | import {Row, Col} from "antd"; 4 | import Header from "./components/Header"; 5 | import './style/common.less'; 6 | 7 | export default class Common extends React.Component { 8 | render() { 9 | return ( 10 |
11 | 12 |
13 | 14 | 15 | {this.props.children} 16 | 17 |
18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/components/BaseForm/index.js: -------------------------------------------------------------------------------- 1 | // src/components/BaseForm/index.js 2 | import React from 'react'; 3 | import {Input, Select, Form, Button, Checkbox, Radio, DatePicker} from "antd"; 4 | import Utils from '../../utils/utils'; 5 | 6 | const FormItem = Form.Item; 7 | 8 | class FilterForm extends React.Component { 9 | 10 | handleFilterSubmit = () => { 11 | let fieldsValue = this.props.form.getFieldsValue();// 获取表单的值 12 | this.props.filterSubmit(fieldsValue); // 将子组件的值传递到父组件(order.js) 13 | }; 14 | 15 | reset = () => { 16 | this.props.form.resetFields(); // 重置表单的方法 17 | }; 18 | 19 | initFormList = () => { 20 | const {getFieldDecorator} = this.props.form; 21 | const formList = this.props.formList; // 从父组件Order.js 中获取该对象进行使用 22 | const formItemList = []; 23 | if (formList && formList.length > 0) { 24 | formList.forEach((item, i) => { 25 | let label = item.label; 26 | let field = item.field; 27 | let initialValue = item.initialValue || ''; //默认给空字符串 28 | let placeholder = item.placeholder; 29 | let width = item.width; 30 | 31 | if (item.type == '城市') { 32 | const city = 33 | { 34 | getFieldDecorator('city',{ 35 | initialValue:'0' 36 | })( 37 | 43 | ) 44 | } 45 | ; 46 | formItemList.push(city); 47 | 48 | } else if (item.type == '时间查询') { 49 | const begin_time = 50 | { 51 | getFieldDecorator('begin_time')( 52 | 53 | ) 54 | } 55 | ; 56 | formItemList.push(begin_time); 57 | 58 | const end_time = 59 | { 60 | getFieldDecorator('end_time')( 61 | 62 | ) 63 | } 64 | ; 65 | formItemList.push(end_time); 66 | 67 | } else if (item.type == 'INPUT') { 68 | // 中括号 [变量] ,会将其看作变量对待 69 | const INPUT = 70 | { 71 | getFieldDecorator([field], { 72 | initialValue: initialValue 73 | })( 74 | 75 | ) 76 | } 77 | ; 78 | formItemList.push(INPUT); 79 | } else if (item.type == 'SELECT') { 80 | // 中括号 [变量] ,会将其看作变量对待 81 | const SELECT = 82 | { 83 | getFieldDecorator([field], { 84 | initialValue: initialValue 85 | })( 86 | 92 | ) 93 | } 94 | ; 95 | formItemList.push(SELECT); 96 | } else if (item.type == 'CHECKBOX') { 97 | const CHECKBOX = 98 | { 99 | getFieldDecorator([field], { 100 | valuePropName: 'checked', // 设置checkbox的属性 101 | initialValue: initialValue // true | false 102 | })( 103 | 104 | {label} 105 | 106 | ) 107 | } 108 | ; 109 | formItemList.push(CHECKBOX); 110 | } else if (item.type == 'DATE') { 111 | const Date = 112 | { 113 | getFieldDecorator([field])( 114 | 115 | ) 116 | } 117 | ; 118 | formItemList.push(Date); 119 | } 120 | }); 121 | } 122 | return formItemList; 123 | }; 124 | 125 | render() { 126 | return ( 127 |
128 | {this.initFormList()} 129 | 130 | 131 | 132 | 133 |
134 | ); 135 | } 136 | } 137 | 138 | export default Form.create({})(FilterForm); 139 | 140 | -------------------------------------------------------------------------------- /src/components/ETable/index.js: -------------------------------------------------------------------------------- 1 | // src/components/ETable/index.js 2 | import React from 'react' 3 | import {Table} from 'antd' 4 | import "./index.less" 5 | export default class ETable extends React.Component { 6 | 7 | state = {} 8 | //处理行点击事件 9 | onRowClick = (record, index) => { 10 | let rowSelection = this.props.rowSelection; 11 | if(rowSelection == 'checkbox'){ 12 | let selectedRowKeys = this.props.selectedRowKeys; 13 | let selectedIds = this.props.selectedIds; 14 | let selectedItem = this.props.selectedItem || []; 15 | if (selectedIds) { 16 | const i = selectedIds.indexOf(record.id); 17 | if (i == -1) {//避免重复添加 18 | selectedIds.push(record.id) 19 | selectedRowKeys.push(index); 20 | selectedItem.push(record); 21 | }else{ 22 | selectedIds.splice(i,1); 23 | selectedRowKeys.splice(i,1); 24 | selectedItem.splice(i,1); 25 | } 26 | } else { 27 | selectedIds = [record.id]; 28 | selectedRowKeys = [index] 29 | selectedItem = [record]; 30 | } 31 | this.props.updateSelectedItem(selectedRowKeys,selectedItem || {},selectedIds); 32 | }else{ 33 | let selectKey = [index]; 34 | const selectedRowKeys = this.props.selectedRowKeys; 35 | if (selectedRowKeys && selectedRowKeys[0] == index){ 36 | return; 37 | } 38 | this.props.updateSelectedItem(selectKey,record || {}); 39 | } 40 | }; 41 | 42 | // 选择框变更 43 | onSelectChange = (selectedRowKeys, selectedRows) => { 44 | let rowSelection = this.props.rowSelection; 45 | const selectedIds = []; 46 | if(rowSelection == 'checkbox'){ 47 | selectedRows.map((item)=>{ 48 | selectedIds.push(item.id); 49 | }); 50 | this.setState({ 51 | selectedRowKeys, 52 | selectedIds:selectedIds, 53 | selectedItem: selectedRows[0] 54 | }); 55 | } 56 | this.props.updateSelectedItem(selectedRowKeys,selectedRows[0],selectedIds); 57 | }; 58 | 59 | onSelectAll = (selected, selectedRows, changeRows) => { 60 | let selectedIds = []; 61 | let selectKey = []; 62 | selectedRows.forEach((item,i)=> { 63 | selectedIds.push(item.id); 64 | selectKey.push(i); 65 | }); 66 | this.props.updateSelectedItem(selectKey,selectedRows[0] || {},selectedIds); 67 | } 68 | 69 | getOptions = () => { 70 | let p = this.props; 71 | const name_list = { 72 | "订单编号":170, 73 | "车辆编号":80, 74 | "手机号码":96, 75 | "用户姓名":70, 76 | "密码":70, 77 | "运维区域":300, 78 | "车型":42, 79 | "故障编号":76, 80 | "代理商编码":97, 81 | "角色ID":64 82 | }; 83 | if (p.columns && p.columns.length > 0) { 84 | p.columns.forEach((item)=> { 85 | //开始/结束 时间 86 | if(!item.title){ 87 | return 88 | } 89 | if(!item.width){ 90 | if(item.title.indexOf("时间") > -1 && item.title.indexOf("持续时间") < 0){ 91 | item.width = 132 92 | }else if(item.title.indexOf("图片") > -1){ 93 | item.width = 86 94 | }else if(item.title.indexOf("权限") > -1 || item.title.indexOf("负责城市") > -1){ 95 | item.width = '40%'; 96 | item.className = "text-left"; 97 | }else{ 98 | if(name_list[item.title]){ 99 | item.width = name_list[item.title]; 100 | } 101 | } 102 | } 103 | item.bordered = true; 104 | }); 105 | } 106 | const { selectedRowKeys } = this.props; 107 | const rowSelection = { 108 | type: 'radio', 109 | selectedRowKeys, 110 | onChange: this.onSelectChange, 111 | onSelect:(record, selected, selectedRows)=>{ 112 | console.log('...') 113 | }, 114 | onSelectAll:this.onSelectAll 115 | }; 116 | let row_selection = this.props.rowSelection; 117 | // 当属性未false或者null时,说明没有单选或者复选列 118 | if(row_selection===false || row_selection === null){ 119 | row_selection = false; 120 | }else if(row_selection == 'checkbox'){ 121 | //设置类型未复选框 122 | rowSelection.type = 'checkbox'; 123 | }else{ 124 | //默认未单选 125 | row_selection = 'radio'; 126 | } 127 | return ({ 133 | onClick: ()=>{ 134 | if(!row_selection){ 135 | return; 136 | } 137 | this.onRowClick(record,index) 138 | } 139 | })} 140 | /> 141 | }; 142 | render = () => { 143 | return ( 144 |
145 | {this.getOptions()} 146 |
147 | ) 148 | } 149 | } -------------------------------------------------------------------------------- /src/components/ETable/index.less: -------------------------------------------------------------------------------- 1 | // src/components/ETable/index.less 2 | @import '../../style/default'; 3 | .ant-table{ 4 | &-thead > tr > th, 5 | &-tbody > tr > td{ 6 | padding:14px 6px; 7 | text-align:center; 8 | } 9 | .ant-table-selection-column{ 10 | min-width:42px!important; 11 | width:42px!important;; 12 | } 13 | 14 | .text-center { 15 | text-align: center; 16 | } 17 | .text-left { 18 | text-align: left; 19 | } 20 | &.ant-table-middle{ 21 | &-thead > tr > th, 22 | &-tbody > tr > td{ 23 | padding:10px 6px; 24 | } 25 | } 26 | &.ant-table-small{ 27 | &-thead > tr > th, 28 | &-tbody > tr > td{ 29 | padding:8px 6px; 30 | } 31 | } 32 | } 33 | .ant-table-pagination{ 34 | padding:0 20px; 35 | } -------------------------------------------------------------------------------- /src/components/Footer/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './index.less' 3 | export default class Footer extends React.Component{ 4 | render(){ 5 | return( 6 |
7 | 版权所有:©2018:太阳王子(推荐使用谷歌浏览器,可以获得更佳操作页面体验) 技术支持:太阳王子 8 |
9 | ) 10 | } 11 | } -------------------------------------------------------------------------------- /src/components/Footer/index.less: -------------------------------------------------------------------------------- 1 | @import './../../style/default.less';//导入预先定义的默认less文件 2 | .footer{ 3 | height: 100px; 4 | padding: 40px 0; 5 | text-align: center; 6 | //color: #d7d7d7; 7 | color: @colorJ; 8 | } -------------------------------------------------------------------------------- /src/components/Header/index.js: -------------------------------------------------------------------------------- 1 | // src/components/Header/index.js 2 | import React from "react"; 3 | /* 4 | Header组件 分两部分建立两行Row 5 | 第一行是用户的个人信息(这里以后要通过变量传输进来) 6 | * */ 7 | import {Row, Col, Modal} from "antd"; 8 | import "./index.less"; 9 | import Util from "../../utils/utils"; //导入公共机制 10 | import axios from "../../axios"; //引入axios组件 11 | import {connect} from "react-redux"; 12 | import {switchMenu} from "../../redux/action"; //连接器 13 | import {Menu} from "antd/lib/menu"; 14 | import MenuConfig from "./../../config/menuConfig"; //导入menuConfig这个文件 15 | 16 | 17 | class Header extends React.Component { 18 | //声明 state变量 在setState之前要声明变量 19 | state = {}; 20 | 21 | componentWillMount() { 22 | this.setState({ 23 | userName: "太阳王子", 24 | }); 25 | /* 26 | 创建定时器,每隔一秒获取时间 27 | * 获取时间的方法 28 | */ 29 | setInterval(() => { 30 | // new Date(); 31 | let sysTime = Util.formateDate(new Date().getTime()); 32 | this.setState({ 33 | sysTime 34 | }); 35 | }, 1000); 36 | this.getWeatherAPIData(); //在这里调用下天气 37 | } 38 | 39 | // 处理页面刷新的修改面包屑的代码 40 | handleMenUpdate = (data) => { 41 | let currentKey = window.location.hash.replace(/#|\?.*$/g, ""); 42 | const {dispatch} = this.props; 43 | 44 | let obj = []; //创建数组,将需要的数据放入其中,代码无形中使用了工厂模式👍,将需要值进行了处理 45 | data.map(item => { 46 | if (item.children) {// 如果有children属性,将其展开放入数组中 47 | obj.push(...item.children); 48 | } else{ 49 | obj.push(item); 50 | } 51 | }); 52 | const menuName = obj; 53 | menuName.forEach((item)=>{ 54 | if(currentKey==item.key){ 55 | dispatch(switchMenu(item.title)) 56 | } 57 | }) 58 | }; 59 | 60 | /* 判断页面是否刷新,定义生命周期方法 ,如果页面刷新,重新给menuName值*/ 61 | componentDidMount() { 62 | this.handleMenUpdate(MenuConfig); 63 | } 64 | 65 | /*定义得到API天气的方法*/ 66 | getWeatherAPIData() { 67 | //通过jsonp的方式 调用百度Api接口 68 | //1.安装jsonp插件 yarn add jsonp --save 69 | //2.对jsonp插件进行的封装 新建文件夹axios-----index.js 70 | //3.通过axios插件来发送jsonp()方法 71 | //通过字符串的方式发送url 72 | //地区动态储存,定义变量 city // url:'http://api.map.baidu.com/telematics/v3/weather?location='+this.city+'&output=json&ak=3p49MVra6urFRGOT9s8UBWr2' 73 | //对中文进行编码,转为页面字符 74 | // 编码后通过 .then 进行接收 75 | 76 | let city = "咸阳"; 77 | 78 | axios 79 | .jsonp({ 80 | // url:'http://api.map.baidu.com/telematics/v3/weather?location='+this.city+'&output=json&ak=3p49MVra6urFRGOT9s8UBWr2' 81 | url: 82 | "http://api.map.baidu.com/telematics/v3/weather?location=" + 83 | encodeURIComponent(city) + 84 | "&output=json&ak=3p49MVra6urFRGOT9s8UBWr2" 85 | }) 86 | .then(res => { 87 | //通过这里拿到返回值,可以先看下返回值是什么 88 | 89 | if (res.status == "success") { 90 | //状态成功取得数据进行使用 91 | let data = res.results[0].weather_data[0]; 92 | this.setState({ 93 | //将状态设置进去 94 | date: data.date, 95 | dayPictureUrl: data.dayPictureUrl, 96 | weather: data.weather 97 | }); 98 | } 99 | }); 100 | } 101 | 102 | showExitConfirm = () => { 103 | Modal.confirm({ 104 | title: "是否确定退出系统?", 105 | onOk() { 106 | window.location.href = "/#/login"; 107 | }, 108 | onCancel() { 109 | console.log("Cancel"); 110 | } 111 | }); 112 | }; 113 | 114 | render() { 115 | // 取出menuType 用作二级导航(父组件Common.js传来) 116 | const menuType = this.props.menuType; 117 | return ( 118 |
119 | 120 | {menuType ? ( 121 |
122 | 123 | IMooc 通用管理系统 124 | 125 | ) : ( 126 | "" 127 | )} 128 | 129 | 欢迎, {this.props.userName || this.state.userName} 130 | 退出 131 | 132 | 133 | {menuType ? ( 134 | "" 135 | ) : ( 136 | 137 | 138 | {/* 首页 */} 139 | {this.props.menuName} 140 | 141 | 142 | {this.state.sysTime} 143 | 144 | 145 | 146 | 147 | {this.state.weather} 148 | {/*{this.state.date}*/} 149 | 150 | 151 | 152 | )} 153 | 154 | ); 155 | } 156 | } 157 | 158 | //将state.menuName 绑定到 props 的menuName 159 | const mapStateToProps = state => { 160 | console.log(state); 161 | return { 162 | menuName: state.menuName, 163 | userName: state.userName 164 | }; 165 | }; 166 | export default connect(mapStateToProps)(Header); 167 | -------------------------------------------------------------------------------- /src/components/Header/index.less: -------------------------------------------------------------------------------- 1 | // src/components/Header/index.less 2 | @import "./../../style/default.less"; 3 | .header { 4 | background-color:@colorM ; 5 | .header-top { 6 | height: 60px; 7 | line-height: 60px; 8 | padding: 0 20px; 9 | text-align: right; 10 | .logo{ 11 | line-height: 60px; 12 | text-align: left; 13 | font-size: 18px; 14 | img{ 15 | height: 40px; 16 | vertical-align: middle; 17 | } 18 | span{ 19 | margin-left: 5px; 20 | } 21 | }; 22 | a { 23 | margin-left: 40px; 24 | } 25 | } 26 | .breadcrumb { 27 | height: 40px; 28 | line-height: 40px; 29 | text-align: right; 30 | padding: 0 20px; 31 | border-top: 1px solid #f9c700; 32 | .breadcrumb-title { 33 | text-align: center; 34 | font-size: @fontC; 35 | &:after{ 36 | position: absolute; 37 | content: ''; 38 | left: 83px; 39 | top: 39px; 40 | border-top: 9px solid @colorM; 41 | border-left: 12px solid transparent; 42 | border-right: 12px solid transparent; 43 | } 44 | } 45 | .weather { 46 | text-align: right; 47 | font-size: 14px; 48 | .date { 49 | margin-right: 10px; 50 | vertical-align: middle; 51 | } 52 | .weather-img{ 53 | img{ 54 | height: 15px; 55 | } 56 | } 57 | .weather-detail{ 58 | margin-left: 5px; 59 | vertical-align: middle; 60 | } 61 | 62 | } 63 | } 64 | } 65 | 66 | // common 页面简单头 67 | .simple-page{ 68 | .header-top{ 69 | background:#1890ff; 70 | color:@colorM; 71 | } 72 | } -------------------------------------------------------------------------------- /src/components/NavLeft/index.js: -------------------------------------------------------------------------------- 1 | // src/components/NavLeft/index.js 2 | import React from "react"; 3 | import MenuConfig from "./../../config/menuConfig"; //导入menuConfig这个文件 4 | import {Menu, Icon} from "antd"; //导入子组件菜单 5 | import {NavLink} from "react-router-dom"; 6 | import "./index.less"; 7 | import {connect} from "react-redux"; // 连接器 8 | import {switchMenu} from "./../../redux/action"; //事件行为 9 | 10 | const SubMenu = Menu.SubMenu; 11 | 12 | class NavLeft extends React.Component { 13 | state = { 14 | currentKey: "" 15 | }; 16 | handleClick = ({item, key}) => { 17 | if (key === this.state.currentKey) { 18 | return false; 19 | } 20 | // 事件派发,自动调用reducer,通过reducer保存到store对象中 21 | const {dispatch} = this.props; 22 | dispatch(switchMenu(item.props.title)); 23 | this.setState({ 24 | currentKey: key 25 | }); 26 | }; 27 | 28 | /* 29 | * 获取到对象后,可以通过setState将对象存进去 ,这是React的一个特色 30 | * */ 31 | componentWillMount() { 32 | //通过MenuConfig读取文件 33 | //通过递归(遍历)实现菜单(是一个List)的渲染 34 | const menuTreeNode = this.renderMenu(MenuConfig); 35 | let currentKey = window.location.hash.replace(/#|\?.*$/g, ""); 36 | //通过setState存入state 37 | this.setState({ 38 | currentKey, 39 | menuTreeNode 40 | }); 41 | } 42 | 43 | homeHandleClick = () => { 44 | const {dispatch} = this.props; 45 | dispatch(switchMenu('首页')); 46 | this.setState({ 47 | currentKey: "" 48 | }); 49 | }; 50 | 51 | //菜单渲染 52 | renderMenu = data => { 53 | return data.map(item => { 54 | //如果item有子元素,遍历自己,再次调用,直到子节点加载完毕 55 | if (item.children) { 56 | return ( 57 | 58 | {this.renderMenu(item.children)} 59 | 60 | ); 61 | } 62 | return ( 63 | 64 | {item.title} 65 | 66 | ); 67 | }); 68 | }; 69 | 70 | render() { 71 | // var style = { 72 | // backgroundColor:'red' 73 | // } 74 | return ( 75 |
76 | 77 |
78 | 79 |

Imooc MS

80 |
81 |
82 | 87 | {this.state.menuTreeNode} 88 | 89 |
90 | ); 91 | } 92 | } 93 | 94 | export default connect()(NavLeft); 95 | -------------------------------------------------------------------------------- /src/components/NavLeft/index.less: -------------------------------------------------------------------------------- 1 | .nav-left{ 2 | .logo{ 3 | line-height: 90px; 4 | padding-left: 20px; 5 | //background-color:#001529; 6 | background-color:#002140; 7 | img{ 8 | height:35px; 9 | vertical-align: middle; 10 | } 11 | h1{ 12 | color: #ffffff; 13 | font-size: 20px; 14 | display: inline-block; 15 | vertical-align: middle; 16 | margin: 0 0 0 10px; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/config/menuConfig.js: -------------------------------------------------------------------------------- 1 | // src/config/menuConfig.js 2 | const menuList = [ 3 | { 4 | title: '首页', 5 | key: '/home' 6 | }, 7 | { 8 | title: 'UI', 9 | key: '/ui', 10 | children: [ 11 | { 12 | title: '按钮', 13 | key: '/ui/buttons', 14 | }, 15 | { 16 | title: '弹框', 17 | key: '/ui/modals', 18 | }, 19 | { 20 | title: 'Loading', 21 | key: '/ui/loadings', 22 | }, 23 | { 24 | title: '通知提醒', 25 | key: '/ui/notification', 26 | }, 27 | { 28 | title: '全局Message', 29 | key: '/ui/messages', 30 | }, 31 | { 32 | title: 'Tab页签', 33 | key: '/ui/tabs', 34 | }, 35 | { 36 | title: '图片画廊', 37 | key: '/ui/gallery', 38 | }, 39 | { 40 | title: '轮播图', 41 | key: '/ui/carousel', 42 | } 43 | ] 44 | }, 45 | { 46 | title: '表单', 47 | key: '/form', 48 | children: [ 49 | { 50 | title: '登录', 51 | key: '/form/login', 52 | }, 53 | { 54 | title: '注册', 55 | key: '/form/reg', 56 | } 57 | ] 58 | }, 59 | { 60 | title: '表格', 61 | key: '/table', 62 | children: [ 63 | { 64 | title: '基础表格', 65 | key: '/table/basic', 66 | }, 67 | { 68 | title: '高级表格', 69 | key: '/table/high', 70 | } 71 | ] 72 | }, 73 | { 74 | title: '富文本', 75 | key: '/rich' 76 | }, 77 | { 78 | title: '城市管理', 79 | key: '/city' 80 | }, 81 | { 82 | title: '订单管理', 83 | key: '/order', 84 | }, 85 | { 86 | title: '员工管理', 87 | key: '/user' 88 | }, 89 | { 90 | title: '车辆地图', 91 | key: '/bikeMap' 92 | }, 93 | { 94 | title: '图标', 95 | key: '/charts', 96 | children: [ 97 | { 98 | title: '柱形图', 99 | key: '/charts/bar' 100 | }, 101 | { 102 | title: '饼图', 103 | key: '/charts/pie' 104 | }, 105 | { 106 | title: '折线图', 107 | key: '/charts/line' 108 | }, 109 | ] 110 | }, 111 | { 112 | title: '权限设置', 113 | key: '/permission' 114 | }, 115 | ]; 116 | export default menuList; -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import * as serviceWorker from "./serviceWorker"; 6 | import Life from "./pages/demo/Life"; 7 | import Admin from "./admin"; 8 | import Router from "./router"; //全局引入Router文件 9 | import { Provider } from "react-redux"; // 添加项目根组件 10 | import configureStore from "./redux/store/configureStore"; 11 | 12 | const store = configureStore(); 13 | ReactDOM.render( 14 | 15 | 16 | , 17 | document.getElementById("root") 18 | ); 19 | 20 | // import Home from './pages/route_demo/router1/Home'; 21 | // ReactDOM.render(, document.getElementById('root')); 22 | 23 | // import Router from './pages/route_demo/router2/router'; 24 | // ReactDOM.render(, document.getElementById('root')); 25 | 26 | // import Router from './pages/route_demo/router3/router'; 27 | // ReactDOM.render(, document.getElementById('root')); 28 | 29 | // import Router from './pages/route_demo/router4/router'; 30 | // ReactDOM.render(, document.getElementById('root')); 31 | 32 | // import Router from './pages/route_demo/router5/router'; 33 | // ReactDOM.render(, document.getElementById('root')); 34 | 35 | // If you want your app to work offline and load faster, you can change 36 | // unregister() to register() below. Note this comes with some pitfalls. 37 | // Learn more about service workers: http://bit.ly/CRA-PWA 38 | serviceWorker.unregister(); 39 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/pages/demo/Child.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | export default class Child extends React.Component { 3 | constructor(props) { 4 | super(props); 5 | this.state = { 6 | }; 7 | } 8 | 9 | componentWillMount() { 10 | console.log("will mount"); 11 | } 12 | 13 | componentDidMount() { 14 | console.log("did mount"); 15 | } 16 | 17 | componentWillReceiveProps(newProps) { 18 | //接收端的属性 19 | //接收从其他组件传递的属性(拦截传递过来的值) 20 | console.log("will props" + newProps.name); 21 | } 22 | 23 | shouldComponentUpdate() { 24 | //组件更新的方法调用setState就会更新该方法 25 | console.log("should update"); 26 | return true; //默认return true ,return false 后面不会走了 27 | } 28 | 29 | //组件更新之前的方法 30 | componentWillUpdate() { 31 | console.log("will update"); 32 | } 33 | 34 | //组件更新之后的方法 35 | componentDidUpdate() { 36 | console.log("did update"); 37 | } 38 | render() { 39 | return ( 40 |
41 |

这里是子组件,测试子组件的生命周期

42 |

{this.props.name}

43 |
44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/pages/demo/Life.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Child from "./Child"; //导入子组件 3 | 4 | import {Button,Input} from 'antd';//导入antd Ui组件 5 | // import 'antd/dist/antd.css'//导入antd样式 6 | 7 | import './index.less' 8 | export default class Life extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | count: 0 13 | }; 14 | } 15 | // state = { 16 | // count:0 17 | // } 18 | handleAdd = () => { 19 | this.setState({ 20 | count: this.state.count + 1 21 | }); 22 | }; 23 | handleClick() { 24 | this.setState({ 25 | count: this.state.count + 1 26 | }); 27 | } 28 | render() { 29 | 30 | return ( 31 |
32 |

React生命周期介绍

33 | 34 | 35 | 36 | 37 |

{this.state.count}

38 | {/* */} 39 | 40 | 41 | 42 | 43 |
44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/pages/demo/index.less: -------------------------------------------------------------------------------- 1 | .content{ 2 | padding: 55px; 3 | } -------------------------------------------------------------------------------- /src/pages/echarts/bar/index.js: -------------------------------------------------------------------------------- 1 | // src/pages/echarts/bar/index.js 2 | import React from 'react'; 3 | import {Card} from 'antd'; 4 | import ReactEcharts from 'echarts-for-react'; 5 | import echartTheme from './../echartTheme'; 6 | import themeLight from './../themeLight'; 7 | //按需加载 8 | import echarts from 'echarts/lib/echarts'; 9 | //必需基础组件 10 | import 'echarts/lib/component/tooltip'; 11 | import 'echarts/lib/component/title'; 12 | import 'echarts/lib/component/legend'; 13 | import 'echarts/lib/component/markPoint'; 14 | //导入矩形图 15 | import 'echarts/lib/chart/bar'; 16 | 17 | 18 | export default class Bar extends React.Component { 19 | 20 | componentWillMount() { 21 | echarts.registerTheme('Default', echartTheme); 22 | echarts.registerTheme('Light', themeLight); 23 | } 24 | 25 | getOption = () => { 26 | let option = { 27 | title: { 28 | text: '用户骑行订单' 29 | }, 30 | tooltip: { // 提示条 31 | trigger: 'axis', 32 | }, 33 | xAxis: { // X轴 34 | data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 35 | }, 36 | yAxis: {// Y轴 37 | type: 'value' 38 | }, 39 | series: [ // 整体数据源 40 | { 41 | name: '订单量', 42 | type: 'bar', 43 | barWidth: '60%', 44 | data: [10, 52, 200, 334, 390, 330, 220] 45 | } 46 | ] 47 | }; 48 | return option; 49 | }; 50 | 51 | getOption2 = () => { 52 | let option = { 53 | title: { 54 | text: '用户骑行订单' 55 | }, 56 | legend: { // 图例 57 | data: ['OFO', '摩拜', '小蓝'] 58 | }, 59 | tooltip: { // 提示条 60 | trigger: 'axis', 61 | }, 62 | xAxis: { // X轴 63 | data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 64 | }, 65 | yAxis: {// Y轴 66 | type: 'value' 67 | }, 68 | series: [ // 整体数据源 69 | { 70 | name: 'OFO', 71 | type: 'bar', 72 | data: [2000, 3000, 5500, 7000, 8000, 12000, 20000] 73 | }, { 74 | name: '摩拜', 75 | type: 'bar', 76 | data: [1500, 3000, 4500, 6000, 8000, 10000, 15000] 77 | }, { 78 | name: '小蓝', 79 | type: 'bar', 80 | data: [1000, 2500, 4000, 4500, 6000, 7000, 8000] 81 | } 82 | ] 83 | }; 84 | return option; 85 | }; 86 | 87 | render() { 88 | return ( 89 |
90 | 91 | 92 | 93 | 94 | 95 | 96 |
97 | ); 98 | } 99 | } -------------------------------------------------------------------------------- /src/pages/echarts/echartTheme.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "color": [ 3 | "#f9c700", 4 | "#ff5400", 5 | "#6699cc", 6 | "#9cb3c5", 7 | "#e0e6ec", 8 | "#666666", 9 | "#787464", 10 | "#cc7e63", 11 | "#724e58", 12 | "#4b565b" 13 | ], 14 | "backgroundColor": "#ffffff", 15 | "textStyle": {}, 16 | "title": { 17 | "textStyle": { 18 | "color": "#cccccc" 19 | }, 20 | "subtextStyle": { 21 | "color": "#cccccc" 22 | } 23 | }, 24 | "line": { 25 | "itemStyle": { 26 | "normal": { 27 | "borderWidth": 1 28 | } 29 | }, 30 | "lineStyle": { 31 | "normal": { 32 | "width": 2 33 | } 34 | }, 35 | "symbolSize": "10", 36 | "symbol": "emptyCircle", 37 | "smooth": false 38 | }, 39 | "pie": { 40 | "itemStyle": { 41 | "normal": { 42 | "borderWidth": 0, 43 | "borderColor": "#ccc" 44 | }, 45 | "emphasis": { 46 | "borderWidth": 0, 47 | "borderColor": "#ccc" 48 | } 49 | } 50 | }, 51 | "categoryAxis": { 52 | "axisLine": { 53 | "show": true, 54 | "lineStyle": { 55 | "color": "#f1f3f5" 56 | } 57 | }, 58 | "axisTick": { 59 | "show": true, 60 | "lineStyle": { 61 | "color": "#f1f3f5" 62 | } 63 | }, 64 | "axisLabel": { 65 | "show": true, 66 | "textStyle": { 67 | "color": "#999999", 68 | "fontSize": "14" 69 | } 70 | }, 71 | "splitLine": { 72 | "show": true, 73 | "lineStyle": { 74 | "color": [ 75 | "#f1f3f5" 76 | ] 77 | } 78 | }, 79 | "splitArea": { 80 | "show": false, 81 | "areaStyle": { 82 | "color": [ 83 | "rgba(250,250,250,0.3)", 84 | "rgba(200,200,200,0.3)" 85 | ] 86 | } 87 | } 88 | }, 89 | "valueAxis": { 90 | "axisLine": { 91 | "show": true, 92 | "lineStyle": { 93 | "color": "#f1f3f5" 94 | } 95 | }, 96 | "axisTick": { 97 | "show": true, 98 | "lineStyle": { 99 | "color": "#f1f3f5" 100 | } 101 | }, 102 | "axisLabel": { 103 | "show": true, 104 | "textStyle": { 105 | "color": "#999999", 106 | "fontSize": "14" 107 | } 108 | }, 109 | "splitLine": { 110 | "show": true, 111 | "lineStyle": { 112 | "color": [ 113 | "#f1f3f5" 114 | ] 115 | } 116 | }, 117 | "splitArea": { 118 | "show": false, 119 | "areaStyle": { 120 | "color": [ 121 | "rgba(250,250,250,0.3)", 122 | "rgba(200,200,200,0.3)" 123 | ] 124 | } 125 | } 126 | }, 127 | "toolbox": { 128 | "iconStyle": { 129 | "normal": { 130 | "borderColor": "#999999" 131 | }, 132 | "emphasis": { 133 | "borderColor": "#666666" 134 | } 135 | } 136 | }, 137 | "legend": { 138 | "textStyle": { 139 | "color": "#333333" 140 | } 141 | }, 142 | "tooltip": { 143 | "axisPointer": { 144 | "lineStyle": { 145 | "color": "#cccccc", 146 | "width": 1 147 | }, 148 | "crossStyle": { 149 | "color": "#cccccc", 150 | "width": 1 151 | } 152 | } 153 | }, 154 | "timeline": { 155 | "lineStyle": { 156 | "color": "#293c55", 157 | "width": 1 158 | }, 159 | "itemStyle": { 160 | "normal": { 161 | "color": "#293c55", 162 | "borderWidth": 1 163 | }, 164 | "emphasis": { 165 | "color": "#a9334c" 166 | } 167 | }, 168 | "controlStyle": { 169 | "normal": { 170 | "color": "#293c55", 171 | "borderColor": "#293c55", 172 | "borderWidth": 0.5 173 | }, 174 | "emphasis": { 175 | "color": "#293c55", 176 | "borderColor": "#293c55", 177 | "borderWidth": 0.5 178 | } 179 | }, 180 | "checkpointStyle": { 181 | "color": "#e43c59", 182 | "borderColor": "rgba(194,53,49,0.5)" 183 | }, 184 | "label": { 185 | "normal": { 186 | "textStyle": { 187 | "color": "#293c55" 188 | } 189 | }, 190 | "emphasis": { 191 | "textStyle": { 192 | "color": "#293c55" 193 | } 194 | } 195 | } 196 | }, 197 | "markPoint": { 198 | "label": { 199 | "normal": { 200 | "textStyle": { 201 | "color": "#ffffff" 202 | } 203 | }, 204 | "emphasis": { 205 | "textStyle": { 206 | "color": "#ffffff" 207 | } 208 | } 209 | } 210 | } 211 | } -------------------------------------------------------------------------------- /src/pages/echarts/line/index.js: -------------------------------------------------------------------------------- 1 | // src/pages/echarts/line/index.js 2 | import React from 'react'; 3 | import {Card} from 'antd'; 4 | import ReactEcharts from 'echarts-for-react'; 5 | import echartTheme from './../echartTheme'; 6 | import themeLight from './../themeLight'; 7 | //按需加载 8 | import echarts from 'echarts/lib/echarts'; 9 | //必需基础组件 10 | import 'echarts/lib/component/tooltip'; 11 | import 'echarts/lib/component/title'; 12 | import 'echarts/lib/component/legend'; 13 | import 'echarts/lib/component/markPoint'; 14 | //导入折线图 15 | import 'echarts/lib/chart/line'; 16 | 17 | 18 | export default class Bar extends React.Component { 19 | 20 | componentWillMount() { 21 | echarts.registerTheme('Default', echartTheme); 22 | echarts.registerTheme('Light', themeLight); 23 | } 24 | 25 | getOption = () => {// 指定xAxis和yAxis的数据,series中通过data存储趋势点 type:'line' 26 | let option = { 27 | title: { 28 | text: '用户骑行订单' 29 | }, 30 | tooltip: { 31 | trigger: 'axis', 32 | }, 33 | xAxis: { 34 | data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 35 | }, 36 | yAxis: { 37 | type: 'value' 38 | }, 39 | series: [ // 整体数据源 40 | { 41 | name: '订单量', 42 | type: 'line', 43 | data: [1000, 2000, 1500, 3000, 2000, 1200, 800] //趋势点 44 | } 45 | ] 46 | }; 47 | return option; 48 | }; 49 | 50 | getOption2 = () => {// type:'line' 51 | let option = { 52 | title: { 53 | text: '用户骑行订单' 54 | }, 55 | legend: { 56 | data: ['OFO订单量', '摩拜订单量'] 57 | }, 58 | tooltip: { // 提示条 59 | trigger: 'axis', 60 | }, 61 | xAxis: { // X轴 62 | data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 63 | }, 64 | yAxis: {// Y轴 65 | type: 'value' 66 | }, 67 | series: [ // 整体数据源 68 | { 69 | name: 'OFO订单量', 70 | type: 'line', 71 | data: [1200, 3000, 4500, 6000, 8000, 12000, 20000] //趋势点 72 | }, { 73 | name: '摩拜订单量', 74 | type: 'line', 75 | data: [1000, 2000, 5500, 6000, 8000, 10000, 12000] //趋势点 76 | } 77 | ] 78 | }; 79 | return option; 80 | }; 81 | getOption3 = () => { // 1. boundaryGap 2. areaStyle 82 | let option = { 83 | title: { 84 | text: '用户骑行订单' 85 | }, 86 | tooltip: { 87 | trigger: 'axis' 88 | }, 89 | xAxis: { 90 | boundaryGap: false, //坐标轴从起点开始,true时在中间 91 | data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 92 | }, 93 | yAxis: { 94 | type: 'value' 95 | }, 96 | series: [ 97 | { 98 | name: '订单量', 99 | type: 'line', 100 | data: [1000, 2000, 1500, 3000, 2000, 1200, 800], //趋势点 101 | areaStyle: {} //区域填充颜色 102 | } 103 | ] 104 | }; 105 | return option; 106 | }; 107 | 108 | render() { 109 | return ( 110 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
121 | ); 122 | } 123 | } -------------------------------------------------------------------------------- /src/pages/echarts/themeLight.js: -------------------------------------------------------------------------------- 1 | var colorPalette = [ 2 | '#C1232B', 3 | '#27727B', 4 | '#FCCE10', 5 | '#E87C25', 6 | '#B5C334', 7 | '#FE8463', 8 | '#9BCA63', 9 | '#FAD860', 10 | '#F3A43B', 11 | '#60C0DD', 12 | '#D7504B', 13 | '#C6E579', 14 | '#F4E001', 15 | '#F0805A', 16 | '#26C0C0' 17 | ]; 18 | export default { 19 | 20 | color: colorPalette, 21 | 22 | title: { 23 | textStyle: { 24 | fontWeight: 'normal', 25 | color: '#27727B' 26 | } 27 | }, 28 | 29 | visualMap: { 30 | color: ['#C1232B', '#FCCE10'] 31 | }, 32 | 33 | toolbox: { 34 | iconStyle: { 35 | normal: { 36 | borderColor: colorPalette[0] 37 | } 38 | } 39 | }, 40 | 41 | tooltip: { 42 | backgroundColor: 'rgba(50,50,50,0.5)', 43 | axisPointer: { 44 | type: 'line', 45 | lineStyle: { 46 | color: '#27727B', 47 | type: 'dashed' 48 | }, 49 | crossStyle: { 50 | color: '#27727B' 51 | }, 52 | shadowStyle: { 53 | color: 'rgba(200,200,200,0.3)' 54 | } 55 | } 56 | }, 57 | 58 | dataZoom: { 59 | dataBackgroundColor: 'rgba(181,195,52,0.3)', 60 | fillerColor: 'rgba(181,195,52,0.2)', 61 | handleColor: '#27727B' 62 | }, 63 | 64 | categoryAxis: { 65 | axisLine: { 66 | lineStyle: { 67 | color: '#27727B' 68 | } 69 | }, 70 | splitLine: { 71 | show: false 72 | } 73 | }, 74 | 75 | valueAxis: { 76 | axisLine: { 77 | show: false 78 | }, 79 | splitArea: { 80 | show: false 81 | }, 82 | splitLine: { 83 | lineStyle: { 84 | color: ['#ccc'], 85 | type: 'dashed' 86 | } 87 | } 88 | }, 89 | 90 | timeline: { 91 | lineStyle: { 92 | color: '#27727B' 93 | }, 94 | controlStyle: { 95 | normal: { 96 | color: '#27727B', 97 | borderColor: '#27727B' 98 | } 99 | }, 100 | symbol: 'emptyCircle', 101 | symbolSize: 3 102 | }, 103 | 104 | line: { 105 | itemStyle: { 106 | normal: { 107 | borderWidth: 2, 108 | borderColor: '#fff', 109 | lineStyle: { 110 | width: 3 111 | } 112 | }, 113 | emphasis: { 114 | borderWidth: 0 115 | } 116 | }, 117 | symbol: 'circle', 118 | symbolSize: 3.5 119 | }, 120 | 121 | candlestick: { 122 | itemStyle: { 123 | normal: { 124 | color: '#C1232B', 125 | color0: '#B5C334', 126 | lineStyle: { 127 | width: 1, 128 | color: '#C1232B', 129 | color0: '#B5C334' 130 | } 131 | } 132 | } 133 | }, 134 | 135 | graph: { 136 | color: colorPalette 137 | }, 138 | 139 | map: { 140 | label: { 141 | normal: { 142 | textStyle: { 143 | color: '#C1232B' 144 | } 145 | }, 146 | emphasis: { 147 | textStyle: { 148 | color: 'rgb(100,0,0)' 149 | } 150 | } 151 | }, 152 | itemStyle: { 153 | normal: { 154 | areaColor: '#ddd', 155 | borderColor: '#eee' 156 | }, 157 | emphasis: { 158 | areaColor: '#fe994e' 159 | } 160 | } 161 | }, 162 | 163 | gauge: { 164 | axisLine: { 165 | lineStyle: { 166 | color: [ 167 | [ 168 | 0.2, '#B5C334' 169 | ], 170 | [ 171 | 0.8, '#27727B' 172 | ], 173 | [1, '#C1232B'] 174 | ] 175 | } 176 | }, 177 | axisTick: { 178 | splitNumber: 2, 179 | length: 5, 180 | lineStyle: { 181 | color: '#fff' 182 | } 183 | }, 184 | axisLabel: { 185 | textStyle: { 186 | color: '#fff' 187 | } 188 | }, 189 | splitLine: { 190 | length: '5%', 191 | lineStyle: { 192 | color: '#fff' 193 | } 194 | }, 195 | title: { 196 | offsetCenter: [0, -20] 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /src/pages/form/login.js: -------------------------------------------------------------------------------- 1 | //src/pages/form/login.js 2 | import React from "react"; 3 | 4 | import {Button, Card, Checkbox, Form, Icon, Input, message} from "antd"; 5 | 6 | const FormItem = Form.Item; 7 | 8 | class FormLogin extends React.Component { 9 | handleSubmit = () => {//绑定提交事件进行校验 10 | let userInfo = this.props.form.getFieldsValue();//object对象 11 | this.props.form.validateFields((err, values) => { 12 | if (!err) {//全部通过 ${} 是变量 13 | message.success(`${userInfo.userName} 恭喜你,您通过本次表单组件学习,当前密码为:${userInfo.userPwd}`) 14 | } 15 | }); 16 | }; 17 | 18 | render() { 19 | const {getFieldDecorator} = this.props.form; 20 | return ( 21 |
22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 |
37 | 38 | { 39 | getFieldDecorator('userName', { 40 | initialValue: '', 41 | rules: [ 42 | { 43 | required: true, 44 | message: '用户名不能为空' 45 | }, 46 | { 47 | min: 5, max: 10, 48 | message: '长度不在范围内' 49 | }, 50 | { 51 | // pattern: /^\w+$/g, 52 | pattern: new RegExp('^\\w+$', 'g'), 53 | message: '用户名必须为字母或数字' 54 | } 55 | ] 56 | })( 57 | } placeholder="请输入用户名"/> 58 | ) 59 | } 60 | 61 | 62 | 63 | { 64 | getFieldDecorator('userPwd', { 65 | initialValue: '', 66 | rules: [{ 67 | required: true, 68 | message: '密码不能为空' 69 | }] 70 | })( 71 | } type="password" placeholder="请输入密码"/> 72 | ) 73 | } 74 | 75 | 76 | 77 | { 78 | getFieldDecorator('remember', { 79 | valuePropName:'checked', 80 | initialValue: true, 81 | rules: [{ 82 | required: true, 83 | message: '密码不能为空' 84 | }] 85 | })( 86 | 记住密码 87 | ) 88 | } 89 | 忘记密码 90 | 91 | 92 | 93 | 94 | 95 |
96 |
97 | ) 98 | } 99 | } 100 | 101 | export default Form.create()(FormLogin); -------------------------------------------------------------------------------- /src/pages/home/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './index.less' 3 | export default class Home extends React.Component { 4 | render(){ 5 | return ( 6 |
7 | 欢迎学习IMooc后台管理系统课程 8 |
9 | ); 10 | } 11 | } -------------------------------------------------------------------------------- /src/pages/home/index.less: -------------------------------------------------------------------------------- 1 | @import "./../../style/default.less"; 2 | .home-wrap{ 3 | background-color: @colorM; 4 | height: calc(62vh); 5 | display: flex; 6 | align-items: center; 7 | justify-content: center; 8 | font-size: 20px; 9 | } -------------------------------------------------------------------------------- /src/pages/login/index.js: -------------------------------------------------------------------------------- 1 | // src\pages\login\index.js 2 | import React from "react"; 3 | import { Form, Input, Button, Modal } from "antd"; 4 | import Footer from "../../components/Footer"; 5 | import "./index.less"; 6 | import { connect } from "react-redux"; // 连接器 7 | import { switchUsers } from "./../../redux/action"; //事件行为 8 | const FormItem = Form.Item; 9 | 10 | class Login extends React.Component { 11 | state = {}; 12 | 13 | componentDidMount() { 14 | //每次进入登录页清除之前的登录信息 15 | } 16 | 17 | loginReq = params => { 18 | // 事件派发,自动调用reducer,通过reducer讲用户名保存到store对象中 19 | const { dispatch } = this.props; 20 | dispatch(switchUsers(params.username)); 21 | window.location.href = "/#/home"; 22 | }; 23 | 24 | render() { 25 | return ( 26 |
27 |
28 |
29 | 慕课后台管理系统 30 | React全家桶+AntD 共享经济热门项目后台管理系统 31 |
32 |
33 |
34 |
35 |
36 | 共享出行
37 | 引领城市新经济 38 |
39 |
40 |
41 |
42 | {this.state.errorMsg} 43 |
44 |
45 |
慕课欢迎你
46 | 47 |
48 |
49 |
50 |
51 |
52 | ); 53 | } 54 | } 55 | export default connect()(Login); 56 | 57 | class LoginForm extends React.Component { 58 | state = {}; 59 | 60 | loginSubmit = e => { 61 | e && e.preventDefault(); 62 | const _this = this; 63 | this.props.form.validateFieldsAndScroll((err, values) => { 64 | if (!err) { 65 | var formValue = _this.props.form.getFieldsValue(); 66 | _this.props.loginSubmit({ 67 | username: formValue.username, 68 | password: formValue.password 69 | }); 70 | } 71 | }); 72 | }; 73 | 74 | checkUsername = (rule, value, callback) => { 75 | var reg = /^\w+$/; 76 | if (!value) { 77 | callback("请输入用户名!"); 78 | } else if (!reg.test(value)) { 79 | callback("用户名只允许输入英文字母"); 80 | } else { 81 | callback(); 82 | } 83 | }; 84 | 85 | checkPassword = (rule, value, callback) => { 86 | if (!value) { 87 | callback("请输入密码!"); 88 | } else { 89 | callback(); 90 | } 91 | }; 92 | 93 | render() { 94 | const { getFieldDecorator } = this.props.form; 95 | return ( 96 |
97 | 98 | {getFieldDecorator("username", { 99 | initialValue: "admin", 100 | rules: [{ validator: this.checkUsername }] 101 | })()} 102 | 103 | 104 | {getFieldDecorator("password", { 105 | initialValue: "admin", 106 | rules: [{ validator: this.checkPassword }] 107 | })( 108 | (this.pwd = inst)} 112 | /> 113 | )} 114 | 115 | 116 | 123 | 124 | 125 | ); 126 | } 127 | } 128 | LoginForm = Form.create({})(LoginForm); 129 | 130 | 131 | -------------------------------------------------------------------------------- /src/pages/login/index.less: -------------------------------------------------------------------------------- 1 | @import '../../style/default.less'; 2 | .login-page{ 3 | .footer{ 4 | //padding-top:40px; 5 | position:fixed; 6 | bottom:0; 7 | left:0; 8 | width:100%; 9 | height:60px; 10 | padding-top:20px; 11 | background:rgba(21,23,20, .5); 12 | font-size:12px; 13 | letter-spacing: 0.15em; 14 | } 15 | .ant-form-item{ 16 | //margin-bottom:20px; 17 | } 18 | .ant-input-lg, 19 | .ant-btn-lg{ 20 | height:40px; 21 | font-size:@fontD; 22 | } 23 | .login-form-button{ 24 | width:100%; 25 | margin-top:15px; 26 | } 27 | } 28 | .login-header{ 29 | position: fixed; 30 | top:0; 31 | left:0; 32 | width:100%; 33 | height:80px; 34 | line-height: 80px; 35 | background:rgba(21,20,13, .9); 36 | .logo{ 37 | padding-left: 100px; 38 | font-size: 20px; 39 | color: white; 40 | } 41 | img{ 42 | height:40px; 43 | margin-right: 15px; 44 | } 45 | } 46 | .login-content-wrap{ 47 | min-height:550px; 48 | //height:calc(~'100vh - 100px'); 49 | height:calc(~'100vh'); 50 | background:url(https://media.xiaohuali.com/ebike-fc/login/banner.jpg) no-repeat center; 51 | background-size:cover; 52 | } 53 | .login-content{ 54 | position:relative; 55 | top:50%; 56 | display:flex; 57 | max-width:960px; 58 | margin:0 auto; 59 | padding:0 20px; 60 | transform:translateY(-50%); 61 | align-items:center; 62 | justify-content: center; 63 | 64 | .word{ 65 | flex:7; 66 | line-height:1.4; 67 | color:#fff; 68 | font-size:64px; 69 | font-weight:bold; 70 | } 71 | } 72 | .login-box{ 73 | position:relative; 74 | flex:4; 75 | height:370px; 76 | padding:40px 30px 0 30px; 77 | background:#fff; 78 | overflow:hidden; 79 | .title{ 80 | line-height:1; 81 | margin-bottom:50px; 82 | font-size:40px; 83 | color:@colorC; 84 | font-weight:bold; 85 | text-align:center; 86 | } 87 | .error-msg-wrap{ 88 | position:absolute; 89 | top:0; 90 | left:0; 91 | width:100%; 92 | 93 | div{ 94 | visibility: hidden; 95 | height:30px; 96 | line-height:30px; 97 | background:#f60c1a; 98 | color:@colorM; 99 | font-size:@fontD; 100 | text-align:center; 101 | transform:translateY(-30px); 102 | transition: all .3s ease-out; 103 | 104 | &.show{ 105 | visibility:visible; 106 | transform:translateY(0); 107 | transition: all .3s ease-out; 108 | } 109 | } 110 | } 111 | } 112 | @media screen and (max-width: 1200px){ 113 | .login-header{ 114 | padding-left:30px; 115 | padding-right:30px; 116 | } 117 | .login-content{ 118 | .word{ 119 | font-size:48px; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /src/pages/nomatch/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default class NoMatch extends React.Component { 4 | render() { 5 | return ( 6 |
404 No Found!!!
7 | ); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/order/detail.less: -------------------------------------------------------------------------------- 1 | @import '../../style/default'; 2 | @import '../../style/common'; 3 | .detail-items{ 4 | margin-left:90px; 5 | padding:25px 50px 25px 0; 6 | border-bottom:1px solid @colorN; 7 | &:last-child{ 8 | border-bottom:none; 9 | } 10 | .item-title{ 11 | margin:20px 0; 12 | font-size:@fontG; 13 | color:@colorU; 14 | } 15 | .detail-form{ 16 | li{ 17 | .clearfix; 18 | margin:20px 0; 19 | line-height:20px; 20 | font-size:15px; 21 | color:@colorC; 22 | } 23 | } 24 | .detail-form-left{ 25 | float:left; 26 | width:164px; 27 | text-align:right; 28 | color:@colorH; 29 | } 30 | .detail-form-content{ 31 | padding-left:194px; 32 | } 33 | } 34 | .order-map{ 35 | height: 450px; 36 | margin: 25px -31px 0; 37 | } -------------------------------------------------------------------------------- /src/pages/rich/index.js: -------------------------------------------------------------------------------- 1 | // src/pages/rich/index.js 2 | import React from "react"; 3 | import { Card, Button, Modal } from "antd"; 4 | import { Editor } from "react-draft-wysiwyg"; 5 | import draftjs from "draftjs-to-html"; 6 | import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css"; 7 | 8 | export default class RichText extends React.Component { 9 | state = { 10 | showRichText: false, 11 | editorContent: "", 12 | editorState: "" 13 | }; 14 | handleClearContent = () => { 15 | //清空文本 16 | this.setState({ 17 | editorState: "", 18 | editorContent: "" 19 | }); 20 | }; 21 | handleGetText = () => { 22 | //获取文本内容 23 | this.setState({ 24 | showRichText: true 25 | }); 26 | }; 27 | onEditorStateChange = editorState => { 28 | //编辑器的状态 29 | this.setState({ 30 | editorState 31 | }); 32 | }; 33 | onEditorChange = editorContent => { 34 | //编辑器内容的状态 35 | this.setState({ 36 | editorContent 37 | }); 38 | }; 39 | 40 | render() { 41 | const { editorState, editorContent } = this.state; 42 | return ( 43 |
44 | 45 | 48 | 55 | 56 | 57 | 65 | 66 | { 70 | this.setState({ 71 | showRichText: false 72 | }); 73 | }} 74 | footer={null} 75 | > 76 | {draftjs(this.state.editorContent)} 77 | 78 |
79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/pages/route_demo/router1/About.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class About extends React.Component { 4 | render() { 5 | return ( 6 |
7 | this is About page. 8 |
9 | ); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/route_demo/router1/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {HashRouter, Route, Link, Switch} from "react-router-dom";//引入路由 3 | import About from "./About"; 4 | import Topic from "./Topic"; 5 | import Main from "./Main"; 6 | 7 | export default class Home extends React.Component {//默认输出 对象{} 8 | render() { 9 | return ( 10 | 11 |
12 |
    13 |
  • 14 | Home 15 |
  • 16 |
  • 17 | About 18 |
  • 19 |
  • 20 | Topics 21 |
  • 22 |
23 |
24 | {/**/} 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/pages/route_demo/router1/Main.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class Main extends React.Component { 4 | render() { 5 | return ( 6 |
7 | this is Main page. 8 |
9 | ); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/route_demo/router1/Topic.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class Topic extends React.Component { 4 | render() { 5 | return ( 6 |
7 | this is Topic page. 8 |
9 | ); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/route_demo/router2/Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; //引入路由 3 | 4 | 5 | export default class Home extends React.Component { 6 | //默认输出 对象{} 7 | render() { 8 | return ( 9 |
10 |
    11 |
  • 12 | Home1 13 |
  • 14 |
  • 15 | About1 16 |
  • 17 |
  • 18 | Topics1 19 |
  • 20 |
21 |
22 | {this.props.children} 23 |
24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/route_demo/router2/router.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HashRouter as Router, Route } from "react-router-dom"; //导入路由,为HashRouter起别名: Router 3 | import About from "./../router1/About"; 4 | import Topic from "./../router1/Topic"; 5 | import Main from "./../router1/Main"; 6 | import Home from "./Home"; //4.0允许在路由中嵌套标签组件 这里是嵌套组件 7 | 8 | export default class IRouter extends React.Component { 9 | render() { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/route_demo/router3/Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; //引入路由 3 | 4 | 5 | export default class Home extends React.Component { 6 | //默认输出 对象{} 7 | render() { 8 | return ( 9 |
10 |
    11 |
  • 12 | Home1 13 |
  • 14 |
  • 15 | About1 16 |
  • 17 |
  • 18 | Topics1 19 |
  • 20 |
21 |
22 | {this.props.children} 23 |
24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/route_demo/router3/Main.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Link} from 'react-router-dom' 3 | export default class Main extends React.Component { 4 | render() { 5 | return ( 6 |
7 | this is Main page. 8 | 嵌套路由 9 |
10 | {this.props.children} 11 |
12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/pages/route_demo/router3/router.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HashRouter as Router, Route } from "react-router-dom"; //导入路由,为HashRouter起别名: Router 3 | import About from "./../router1/About"; 4 | import Topic from "./../router1/Topic"; 5 | import Main from "./Main"; 6 | import Home from "./Home"; //4.0允许在路由中嵌套标签组件 这里是嵌套组件 7 | /* 嵌套路由中添加 render方法加载 8 | 在子组件中进行嵌套路由 9 | */ 10 | export default class IRouter extends React.Component { 11 | render() { 12 | return ( 13 | 14 | 15 | 18 |
19 | {/*
this is a subchild element
*/} 20 | 21 |
22 | } 23 | /> 24 | 25 | 26 |
27 |
28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/pages/route_demo/router4/Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; //引入路由 3 | 4 | 5 | export default class Home extends React.Component { 6 | //默认输出 对象{} 7 | render() { 8 | return ( 9 |
10 |
    11 |
  • 12 | Home1 13 |
  • 14 |
  • 15 | About1 16 |
  • 17 |
  • 18 | Topics1 19 |
  • 20 |
21 |
22 | {this.props.children} 23 |
24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/route_demo/router4/Main.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Link} from 'react-router-dom' 3 | export default class Main extends React.Component { 4 | render() { 5 | return ( 6 |
7 | this is Main page. 8 |
9 | 嵌套路由1 10 |
11 | 嵌套路由2 12 |
13 |
14 | {this.props.children} 15 |
16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/pages/route_demo/router4/info.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | /* 3 | {this.props.match.params.xxx} 4 | xxx:是:后面的value 5 | 此处写作: {this.props.match.params.value} 6 | */ 7 | export default class Info extends React.Component { 8 | render() { 9 | return ( 10 |
11 | 这里是测试动态路由功能 12 | 动态路由的值是: {this.props.match.params.value} 13 |
14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/route_demo/router4/router.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HashRouter as Router, Route } from "react-router-dom"; 3 | import Info from "./info"; 4 | import Topic from "./../router1/Topic"; 5 | import About from "./../router1/About"; 6 | import Main from "./Main"; 7 | import Home from "./Home"; 8 | 9 | export default class IRouter extends React.Component { 10 | render() { 11 | return ( 12 | 13 | 14 | 17 |
18 | {/*
this is a subchild element
*/} 19 | 20 |
21 | } 22 | /> 23 | 24 | 25 | 26 |
27 |
28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/pages/route_demo/router5/Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; //引入路由 3 | 4 | /* 1.添加不存在的路由 imooc 5 | 2.配置404页 6 | 7 | 3. 定义NoMatch(组件) 即404页 8 | 4.在路由中导入 NoMatch组件 9 | --------------- 10 | 定义NoMatch(组件) 即404页 11 | */ 12 | export default class Home extends React.Component { 13 | render() { 14 | return ( 15 |
16 |
    17 |
  • 18 | Home1 19 |
  • 20 |
  • 21 | About1 22 |
  • 23 |
  • 24 | Topics1 25 |
  • 26 |
  • 27 | Imooc 28 |
  • 29 |
  • 30 | Imooc 31 |
  • 32 |
33 |
34 | {this.props.children} 35 |
36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/pages/route_demo/router5/Main.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Link} from 'react-router-dom' 3 | export default class Main extends React.Component { 4 | render() { 5 | return ( 6 |
7 | this is Main page. 8 |
9 | 嵌套路由1 10 |
11 | 嵌套路由2 12 |
13 |
14 | {this.props.children} 15 |
16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/pages/route_demo/router5/NoMatch.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | /* 1.添加不存在的路由 imooc 4 | 2.配置404页 5 | 6 | 3. 定义NoMatch(组件) 即404页 7 | 4.在路由中导入 NoMatch组件 8 | --------------- 9 | 定义NoMatch(组件) 即404页 10 | */ 11 | export default class Home extends React.Component { 12 | render() { 13 | return ( 14 |
15 | 404 No Pages. 16 |
17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/route_demo/router5/info.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | /* 3 | {this.props.match.params.xxx} 4 | xxx:是:后面的value 5 | 此处写作: {this.props.match.params.value} 6 | */ 7 | export default class Info extends React.Component { 8 | render() { 9 | return ( 10 |
11 | 这里是测试动态路由功能 12 | 动态路由的值是: {this.props.match.params.value} 13 |
14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/route_demo/router5/router.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HashRouter as Router, Route ,Switch} from "react-router-dom"; 3 | import Info from "./info"; 4 | import Topic from "./../router1/Topic"; 5 | import About from "./../router1/About"; 6 | import Main from "./Main"; 7 | import Home from "./Home"; 8 | import NoMatch from "./NoMatch"; 9 | /* 1.添加不存在的路由 imooc 10 | 2.配置404页 11 | 12 | 3. 定义NoMatch(组件) 即404页 13 | 4.在路由中导入 NoMatch组件 14 | + import NoMatch from "./NoMatch"; 15 | 16 | 5.添加Switch防止出现多个页面 17 | + import { HashRouter as Router, Route ,Switch} from "react-router-dom"; 18 | --------------- 19 | 定义NoMatch(组件) 即404页 20 | */ 21 | export default class IRouter extends React.Component { 22 | render() { 23 | return ( 24 | 25 | 26 | 27 | ( 30 |
31 | {/*
this is a subchild element
*/} 32 | 33 |
34 | )} 35 | /> 36 | 37 | 38 | 39 | 40 |
41 |
42 |
43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/pages/ui/buttons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Card, Button, Radio } from "antd"; 3 | import "./ui.less"; 4 | export default class Buttons extends React.Component { 5 | state = { 6 | //设置默认值 7 | loading: true 8 | }; 9 | handleCloseLoading = () => { 10 | this.setState({ 11 | loading: false, 12 | size:'default' 13 | }); 14 | }; 15 | 16 | handleChange=(e)=>{ 17 | this.setState({ 18 | size:e.target.value 19 | }) 20 | }; 21 | render() { 22 | return ( 23 |
24 | {/* this is button page. */} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 43 | 44 | 45 | 48 | 50 | 54 | 57 | 58 | 59 | 60 | 63 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/pages/ui/carousel.js: -------------------------------------------------------------------------------- 1 | //src/pages/ui/carousel.js 2 | import React from 'react'; 3 | import {Card, Carousel} from "antd"; 4 | import "./ui.less"; 5 | 6 | export default class Carousels extends React.Component { 7 | render() { 8 | return ( 9 |
10 | 11 | 12 |

Ant Motion Banner - React

13 |

Ant Motion Banner - Vue

14 |

Ant Motion Banner - Angular

15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 | ); 26 | } 27 | } -------------------------------------------------------------------------------- /src/pages/ui/gallery.js: -------------------------------------------------------------------------------- 1 | // src\pages\ui\gallery.js 2 | import React from "react"; 3 | import { Card, Row, Col, Modal } from "antd"; 4 | export default class Gallery extends React.Component { 5 | state = { 6 | visible: false 7 | }; 8 | openGallery = imgSrc => { 9 | //通过这个方法获得图片,弹出model,将图片保存到,currentImg 10 | this.setState({ 11 | visible: true, 12 | currentImg: "/gallery/"+ imgSrc 13 | }); 14 | }; 15 | render() { 16 | //定义二维数组去存图片 17 | //可以使用两层循环(map),去定义 二维数组 18 | 19 | /* 20 | var a = [1,2,3]; 21 | var b = a.map(function (i) {return i*2}) 22 | console.log(a);//[1,2,3] 23 | console.log(b);//[2,4,6] 24 | */ 25 | 26 | const imgs = [ 27 | ["1.png", "2.png", "3.png", "4.png", "5.png"], 28 | ["6.png", "7.png", "8.png", "9.png", "10.png"], 29 | ["11.png", "12.png", "13.png", "14.png", "15.png"], 30 | ["16.png", "17.png", "18.png", "19.png", "20.png"], 31 | ["21.png", "22.png", "23.png", "24.png", "25.png"] 32 | ]; 33 | const imgList = imgs.map((list, key) => 34 | list.map((item) => ( 35 | this.openGallery(item)} 42 | /> 43 | } 44 | > 45 | 46 | 47 | )) 48 | ); 49 | return ( 50 | //一行5列 51 |
52 | 53 |
{imgList[0]} 54 | {imgList[1]} 55 | {imgList[2]} 56 | {imgList[3]} 57 | {imgList[4]} 58 | 59 | { 65 | this.setState({ 66 | visible: false 67 | }); 68 | }} 69 | footer={null} 70 | > 71 | {} 72 | 73 | 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/pages/ui/loadings.js: -------------------------------------------------------------------------------- 1 | //src\pages\ui\loadings.js 2 | import React from "react"; 3 | import "./ui.less"; 4 | import { Card, Button, Spin, Icon, Alert } from "antd"; 5 | 6 | export default class Loadings extends React.Component { 7 | render() { 8 | const icon = ; 9 | const iconLoading = ; 10 | return ( 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 32 | 33 | 34 | 40 | 41 | 42 | 48 | 49 | 50 |
51 | ); 52 | } 53 | } -------------------------------------------------------------------------------- /src/pages/ui/messages.js: -------------------------------------------------------------------------------- 1 | //src\pages\ui\messages.js 2 | import React from "react"; 3 | import "./ui.less"; 4 | import {Card, Button, message} from "antd"; 5 | 6 | export default class Messages extends React.Component { 7 | showMeassage = type => { 8 | message[type]("恭喜你,React课程晋级成功."); 9 | }; 10 | 11 | render() { 12 | return ( 13 |
14 | 15 | 18 | 21 | 24 | 27 | 30 | 31 |
32 | ); 33 | } 34 | } -------------------------------------------------------------------------------- /src/pages/ui/modals.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Card, Button, Modal } from "antd"; 3 | import "./ui.less"; 4 | export default class Modals extends React.Component { 5 | state = { 6 | //设置默认值 7 | showModal1: false, 8 | showModal2: false, 9 | showModal3: false, 10 | showModal4: false 11 | }; 12 | handleOpen = type => { 13 | //带 [] 会将type 当作变量,动态设置属性 14 | this.setState({ 15 | [type]: true 16 | }); 17 | }; 18 | handleConfirm=(type)=>{ 19 | // Modal.confirm() 20 | // Modal['confirm'] 21 | // var a ={ 22 | // confirm:function(){} 23 | // } 24 | // a.confirm() 25 | // a['confirm'] 26 | 27 | //通过type动态调用函数 28 | // - Modal.confirm({ 29 | // + Modal[type]({ 30 | Modal[type]({ 31 | title:'确认', 32 | content:'你确定学会React了吗', 33 | onOk(){ 34 | console.log('Ok'); 35 | }, 36 | onCancel(){ 37 | console.log('Cancel'); 38 | } 39 | }) 40 | }; 41 | handleOk = () => { 42 | this.setState({ 43 | showModal1: false 44 | }); 45 | }; 46 | render() { 47 | return ( 48 |
49 | {/* this is modals page. */} 50 | 51 | 54 | 57 | 60 | 63 | 64 | 65 | 68 | 71 | 74 | 77 | 80 | 81 | { 85 | this.setState({ 86 | showModal1: false 87 | }); 88 | }} 89 | onCancel={() => { 90 | this.setState({ 91 | showModal1: false 92 | }); 93 | }} 94 | > 95 |

欢迎学习慕课新推出的React高级课程

96 |
97 | { 103 | this.setState({ 104 | showModal2: false 105 | }); 106 | }} 107 | onCancel={() => { 108 | this.setState({ 109 | showModal2: false 110 | }); 111 | }} 112 | > 113 |

欢迎学习慕课新推出的React高级课程

114 |
115 |   116 | { 121 | this.setState({ 122 | showModal3: false 123 | }); 124 | }} 125 | onCancel={() => { 126 | this.setState({ 127 | showModal3: false 128 | }); 129 | }} 130 | > 131 |

欢迎学习慕课新推出的React高级课程

132 |
133 | { 138 | this.setState({ 139 | showModal4: false 140 | }); 141 | }} 142 | onCancel={() => { 143 | this.setState({ 144 | showModal4: false 145 | }); 146 | }} 147 | > 148 |

欢迎学习慕课新推出的React高级课程

149 |
150 |
151 | ); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/pages/ui/notice.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Card, Button, notification } from "antd"; 3 | import "./ui.less"; 4 | export default class Notice extends React.Component { 5 | openNotifications = (type, direction) => { 6 | if (direction) { 7 | //如果配置了direction,说明执行了有方向的通知框,将placement设置为当前方向 8 | notification.config({ 9 | placement:direction 10 | }); 11 | } 12 | notification[type]({ 13 | message: "发工资了", 14 | description: "上个月考勤22天,迟到12天,实发工资250,请笑纳" 15 | }); 16 | }; 17 | handleOk = () => {}; 18 | render() { 19 | return ( 20 |
21 | 22 | 28 | 31 | 37 | 43 | 44 | 45 | 51 | 57 | 63 | 69 | 70 |
71 | ); 72 | } 73 | } -------------------------------------------------------------------------------- /src/pages/ui/tabs.js: -------------------------------------------------------------------------------- 1 | //src\pages\ui\tabs.js 2 | import React from "react"; 3 | import "./ui.less"; 4 | import { Card, Tabs, message, Icon } from "antd"; 5 | const TabPane = Tabs.TabPane; 6 | export default class Tabs1 extends React.Component { 7 | newTabIndex = 0; 8 | componentWillMount() { 9 | const panes = [ 10 | { 11 | title: "Tab 1", 12 | content: "Tab 1", 13 | key: "1" 14 | }, 15 | { 16 | title: "Tab 2", 17 | content: "Tab 2", 18 | key: "2" 19 | }, 20 | { 21 | title: "Tab 3", 22 | content: "Tab 3", 23 | key: "3" 24 | } 25 | ]; 26 | this.setState({ 27 | activeKey: panes[0].key, 28 | // panes: panes 29 | panes 30 | }); 31 | } 32 | add = () => { 33 | const panes = this.state.panes; 34 | const activeKey = `newTab${this.newTabIndex++}`; 35 | panes.push({ title: activeKey, content: "New Tab Pane", key: activeKey }); 36 | this.setState({ panes, activeKey }); 37 | }; 38 | 39 | remove = targetKey => { 40 | let activeKey = this.state.activeKey; 41 | let lastIndex; 42 | this.state.panes.forEach((pane, i) => { 43 | if (pane.key === targetKey) { 44 | lastIndex = i - 1; 45 | } 46 | }); 47 | const panes = this.state.panes.filter(pane => pane.key !== targetKey); 48 | if (lastIndex >= 0 && activeKey === targetKey) { 49 | activeKey = panes[lastIndex].key; 50 | } 51 | this.setState({ panes, activeKey }); 52 | }; 53 | onChange = activeKey => { 54 | this.setState({ 55 | activeKey 56 | }); 57 | }; 58 | onEdit = (targetKey, action) => { 59 | this[action](targetKey); 60 | }; 61 | handleCallback = key => { 62 | // console.log(key) 63 | message.info("Hi,您选择了页签: " + key); 64 | }; 65 | render() { 66 | return ( 67 |
68 | 69 | 70 | 71 | 欢迎学习React课程 72 | 73 | 74 | 欢迎学习React课程 75 | 76 | 77 | React是一门非常受欢迎的MV*框架 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | Tab 1 88 | 89 | } 90 | key="1" 91 | > 92 | 创建属于你的React项目 93 | 94 | 97 | 98 | Tab 2 99 | 100 | } 101 | key="2" 102 | > 103 | 尝试如何使用React进行修改 104 | 105 | 108 | 109 | Tab 3 110 | 111 | } 112 | key="3" 113 | > 114 | 删除它,就这么简单 115 | 116 | 117 | 118 | 119 | 125 | {this.state.panes.map(panel => ( 126 | 127 | {panel.content} 128 | 129 | ))} 130 | 131 | 132 |
133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/pages/ui/ui.less: -------------------------------------------------------------------------------- 1 | //src/pages/ui/ui.less 2 | .card-wrap { 3 | margin-bottom: 10px; 4 | button { 5 | margin-right: 10px; 6 | } 7 | } 8 | 9 | /* modals */ 10 | /* use css to set position of modal */ 11 | .vertical-center-modal { 12 | text-align: center; 13 | white-space: nowrap; 14 | } 15 | 16 | .vertical-center-modal:before { 17 | content: ""; 18 | display: inline-block; 19 | height: 100%; 20 | vertical-align: middle; 21 | width: 0; 22 | } 23 | 24 | .vertical-center-modal .ant-modal { 25 | display: inline-block; 26 | vertical-align: middle; 27 | top: 0; 28 | text-align: left; 29 | } 30 | 31 | 32 | /* For demo */ 33 | .ant-carousel .slick-slide { 34 | text-align: center; 35 | height: 160px; 36 | line-height: 160px; 37 | background: #364d79; 38 | overflow: hidden; 39 | } 40 | 41 | .ant-carousel .slick-slide h3 { 42 | color: #fff; 43 | } 44 | 45 | .slider-wrap .ant-carousel .slick-slide { 46 | height: 240px!important; 47 | } 48 | -------------------------------------------------------------------------------- /src/redux/action/index.js: -------------------------------------------------------------------------------- 1 | // src\redux\action\index.js 2 | /* 3 | * Action类型:用户事件操作 4 | */ 5 | 6 | export const type = { 7 | SWITCH_MENU:'SWITCH_MENU', 8 | SWITCH_USERS:'SWITCH_USERS' 9 | }; 10 | 11 | //菜单点击切换,修改面包屑名称 12 | export function switchMenu(menuName) { 13 | return { 14 | type:type.SWITCH_MENU, 15 | menuName 16 | } 17 | } 18 | 19 | // 用户点击登录,切换用户名称 20 | export function switchUsers(userName) { 21 | return { 22 | type:type.SWITCH_USERS, 23 | userName 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/redux/reducer/index.js: -------------------------------------------------------------------------------- 1 | // src\redux\reducer\index.js 2 | /* 3 | * Reducer: 数据处理 4 | */ 5 | 6 | import { type } from "./../action"; 7 | const initialState = { 8 | menuName: "首页" 9 | }; 10 | 11 | const ebikeData = (state = initialState, action) => { 12 | switch (action.type) { 13 | case type.SWITCH_MENU: 14 | return { 15 | ...state, // 旧值 16 | menuName: action.menuName // 新值 17 | }; 18 | case type.SWITCH_USERS: 19 | return { 20 | ...state, // 旧值 21 | userName: action.userName //新值 22 | }; 23 | default: 24 | return { 25 | ...state 26 | }; 27 | } 28 | }; 29 | 30 | export default ebikeData; 31 | -------------------------------------------------------------------------------- /src/redux/store/configureStore.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 引入createStore 保存数据源 3 | */ 4 | 5 | import { createStore } from "redux"; 6 | // 引入所有的reducer 7 | import reducer from "./../reducer"; 8 | //调试工具插件方法 -- redux降级到3.7可使用 9 | // import { composeWithDevTools } from 'redux-devtools-extension' 10 | // export default ()=>createStore(reducer,composeWithDevTools) 11 | 12 | export default ()=>createStore(reducer) -------------------------------------------------------------------------------- /src/resources/assets/bike.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/bike.jpg -------------------------------------------------------------------------------- /src/resources/assets/carousel-img/carousel-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/carousel-img/carousel-1.jpg -------------------------------------------------------------------------------- /src/resources/assets/carousel-img/carousel-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/carousel-img/carousel-2.jpg -------------------------------------------------------------------------------- /src/resources/assets/carousel-img/carousel-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/carousel-img/carousel-3.jpg -------------------------------------------------------------------------------- /src/resources/assets/end_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/end_point.png -------------------------------------------------------------------------------- /src/resources/assets/imooc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/imooc.png -------------------------------------------------------------------------------- /src/resources/assets/logo-ant.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 28 Copy 5 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 42 | 43 | -------------------------------------------------------------------------------- /src/resources/assets/start_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/start_point.png -------------------------------------------------------------------------------- /src/resources/assets/user_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/assets/user_location.png -------------------------------------------------------------------------------- /src/resources/menuConfig.js: -------------------------------------------------------------------------------- 1 | const menuList = [ 2 | { 3 | title:'首页', 4 | key:'/home' 5 | }, 6 | { 7 | title:'UI', 8 | key:'/ui', 9 | children:[ 10 | { 11 | title:'按钮', 12 | key:'/ui/buttons', 13 | }, 14 | { 15 | title:'弹框', 16 | key:'/ui/modals', 17 | }, 18 | { 19 | title:'Loading', 20 | key:'/ui/loadings', 21 | }, 22 | { 23 | title:'通知提醒', 24 | key:'/ui/notification', 25 | }, 26 | { 27 | title:'全局Message', 28 | key:'/ui/messages', 29 | }, 30 | { 31 | title:'Tab页签', 32 | key:'/ui/tabs', 33 | }, 34 | { 35 | title:'图片画廊', 36 | key:'/ui/gallery', 37 | }, 38 | { 39 | title:'轮播图', 40 | key:'/ui/carousel', 41 | } 42 | ] 43 | }, 44 | { 45 | title:'表单', 46 | key:'/form', 47 | children:[ 48 | { 49 | title:'登录', 50 | key:'/form/login', 51 | }, 52 | { 53 | title:'注册', 54 | key:'/form/reg', 55 | } 56 | ] 57 | }, 58 | { 59 | title:'表格', 60 | key:'/table', 61 | children:[ 62 | { 63 | title:'基础表格', 64 | key:'/table/basic', 65 | }, 66 | { 67 | title:'高级表格', 68 | key:'/table/high', 69 | } 70 | ] 71 | }, 72 | { 73 | title:'富文本', 74 | key:'/rich' 75 | }, 76 | { 77 | title:'城市管理', 78 | key:'/city' 79 | }, 80 | { 81 | title:'订单管理', 82 | key:'/order', 83 | btnList:[ 84 | { 85 | title:'订单详情', 86 | key:'detail' 87 | }, 88 | { 89 | title:'结束订单', 90 | key:'finish' 91 | } 92 | ] 93 | }, 94 | { 95 | title:'员工管理', 96 | key:'/user' 97 | }, 98 | { 99 | title:'车辆地图', 100 | key:'/bikeMap' 101 | }, 102 | { 103 | title:'图标', 104 | key:'/charts', 105 | children:[ 106 | { 107 | title:'柱形图', 108 | key:'/charts/bar' 109 | }, 110 | { 111 | title:'饼图', 112 | key:'/charts/pie' 113 | }, 114 | { 115 | title:'折线图', 116 | key:'/charts/line' 117 | }, 118 | ] 119 | }, 120 | { 121 | title:'权限设置', 122 | key:'/permission' 123 | }, 124 | ]; 125 | export default menuList; -------------------------------------------------------------------------------- /src/resources/resource/api/.json: -------------------------------------------------------------------------------- 1 | {success: true, data: {name: "hh"}, _res: {status: 400, data: {success: false}, cookies: {test: "true"}, headers: {Power: "easy-mock"}}} -------------------------------------------------------------------------------- /src/resources/resource/api/city/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": [{ 3 | "id": 1, 4 | "name": "北京" 5 | }, { 6 | "id": 2, 7 | "name": "上海" 8 | }, { 9 | "id": 3, 10 | "name": "天津" 11 | }, { 12 | "id": 5, 13 | "name": "广州" 14 | }, { 15 | "id": 6, 16 | "name": "深圳" 17 | }, { 18 | "id": 7, 19 | "name": "杭州" 20 | }, { 21 | "id": 8, 22 | "name": "成都" 23 | }, { 24 | "id": 9, 25 | "name": "南京" 26 | }, { 27 | "id": 10, 28 | "name": "苏州" 29 | }] 30 | } -------------------------------------------------------------------------------- /src/resources/resource/api/city/open.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":0, 3 | "result": "开通成功" 4 | } -------------------------------------------------------------------------------- /src/resources/resource/api/info_alarm.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "vol_low": 2, 4 | "offline": 12, 5 | "unlock_ex": 0, 6 | "lock_fail": 0, 7 | "op_lock_timeout": 0, 8 | "bat_lock_timeout": 2 9 | }, 10 | "code": 0, 11 | "message": "success" 12 | } -------------------------------------------------------------------------------- /src/resources/resource/api/map/bike_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":0, 3 | "result": { 4 | "total_count": 100, 5 | "bike_list": ['116.356619,40.017782', '116.437107,39.975331', '116.34972,40.070808', '116.323849,39.964714', '116.404912,40.015129', '116.365243,39.958078'], 6 | "route_list": ['116.353101,40.067835', '116.357701,40.053699', '116.374086,40.027626', '116.397801,40.01641'], 7 | "service_list": [{ 8 | "lon": "116.274737", 9 | "lat": "40.139759", 10 | "ts": null 11 | }, 12 | { 13 | "lon": "116.316562", 14 | "lat": "40.144943", 15 | "ts": null 16 | }, 17 | { 18 | "lon": "116.351631", 19 | "lat": "40.129498", 20 | "ts": null 21 | }, 22 | { 23 | "lon": "116.390582", 24 | "lat": "40.082481", 25 | "ts": null 26 | }, 27 | { 28 | "lon": "116.38742", 29 | "lat": "40.01065", 30 | "ts": null 31 | }, 32 | { 33 | "lon": "116.414297", 34 | "lat": "40.01181", 35 | "ts": null 36 | }, 37 | { 38 | "lon": "116.696242", 39 | "lat": "39.964035", 40 | "ts": null 41 | }, 42 | { 43 | "lon": "116.494498", 44 | "lat": "39.851306", 45 | "ts": null 46 | }, 47 | { 48 | "lon": "116.238086", 49 | "lat": "39.848647", 50 | "ts": null 51 | }, 52 | { 53 | "lon": "116.189454", 54 | "lat": "39.999418", 55 | "ts": null 56 | }, 57 | { 58 | "lon": "116.244646", 59 | "lat": "39.990574", 60 | "ts": null 61 | }, 62 | { 63 | "lon": "116.281441", 64 | "lat": "40.008703", 65 | "ts": null 66 | }, 67 | { 68 | "lon": "116.271092", 69 | "lat": "40.142201", 70 | "ts": null 71 | }, 72 | { 73 | "lon": "116.271092", 74 | "lat": "40.142201", 75 | "ts": null 76 | } 77 | ] 78 | } 79 | } -------------------------------------------------------------------------------- /src/resources/resource/api/mock.json: -------------------------------------------------------------------------------- 1 | {"success":true,"data":{"projects|3-10":[{"name":"演示用","url":"@url","email":"@email","address":"@county(true)","string|1-10":"★","number|1-100":100,"boolean|1-2":true,"object|2":{"310000":"上海市","320000":"江苏省","330000":"浙江省"}}]}} -------------------------------------------------------------------------------- /src/resources/resource/api/open_city.json: -------------------------------------------------------------------------------- 1 | { 2 | 'code':'0', 3 | "result": { 4 | "page": 1, 5 | "page_size": 10, 6 | "total_count": 60, 7 | "page_count": 6, 8 | "item_list|10": [{ 9 | "id|+1": 1, 10 | "name": "@city", 11 | "mode|1-2": 1, 12 | "op_mode|1-2": 1, 13 | "franchisee_id": 77, 14 | "franchisee_name": "松果自营", 15 | "city_admins|1-2": [{ 16 | "user_name": "@cname", 17 | "user_id|+1": 10001 18 | }], 19 | "open_time": "@datetime", 20 | "sys_user_name": "@cname", 21 | "update_time": 1520476737000 22 | }] 23 | } 24 | } -------------------------------------------------------------------------------- /src/resources/resource/api/order/detail.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":'0', 3 | "msg":'', 4 | "result": { 5 | "status": 2, 6 | "order_sn": "T1803244422704080JGJI", 7 | "bike_sn": "802410001", 8 | "mode|1-2": 1, 9 | "start_location": "北京市昌平区回龙观东大街", 10 | "end_location": "北京市海淀区奥林匹克公园", 11 | "city_id": 1, 12 | "mobile": "13597482075", 13 | "user_name": "@cname", 14 | "distance": 10000, 15 | "bike_gps": "116.398806,40.008637", 16 | "start_time": 1521865027000, 17 | "end_time": 1521865251000, 18 | "total_time": 224, 19 | "position_list": [{ 20 | "lon": 116.361221, 21 | "lat": 40.043776 22 | }, { 23 | "lon": 116.363736, 24 | "lat": 40.038086 25 | }, { 26 | "lon": 116.364599, 27 | "lat": 40.036484 28 | }, { 29 | "lon": 116.373438, 30 | "lat": 40.03538 31 | }, { 32 | "lon": 116.377966, 33 | "lat": 40.036263 34 | }, { 35 | "lon": 116.379762, 36 | "lat": 40.03654 37 | }, { 38 | "lon": 116.38084, 39 | "lat": 40.033225 40 | }, { 41 | "lon": 116.38084, 42 | "lat": 40.029413 43 | }, { 44 | "lon": 116.381343, 45 | "lat": 40.021291 46 | }, { 47 | "lon": 116.381846, 48 | "lat": 40.015821 49 | }, { 50 | "lon": 116.382637, 51 | "lat": 40.008084 52 | }, { 53 | "lon": 116.398806, 54 | "lat": 40.008637 55 | }], 56 | "area": [{ 57 | "lon": "116.274737", 58 | "lat": "40.139759", 59 | "ts": null 60 | }, 61 | { 62 | "lon": "116.316562", 63 | "lat": "40.144943", 64 | "ts": null 65 | }, 66 | { 67 | "lon": "116.351631", 68 | "lat": "40.129498", 69 | "ts": null 70 | }, 71 | { 72 | "lon": "116.390582", 73 | "lat": "40.082481", 74 | "ts": null 75 | }, 76 | { 77 | "lon": "116.38742", 78 | "lat": "40.01065", 79 | "ts": null 80 | }, 81 | { 82 | "lon": "116.414297", 83 | "lat": "40.01181", 84 | "ts": null 85 | }, 86 | { 87 | "lon": "116.696242", 88 | "lat": "39.964035", 89 | "ts": null 90 | }, 91 | { 92 | "lon": "116.494498", 93 | "lat": "39.851306", 94 | "ts": null 95 | }, 96 | { 97 | "lon": "116.238086", 98 | "lat": "39.848647", 99 | "ts": null 100 | }, 101 | { 102 | "lon": "116.189454", 103 | "lat": "39.999418", 104 | "ts": null 105 | }, 106 | { 107 | "lon": "116.244646", 108 | "lat": "39.990574", 109 | "ts": null 110 | }, 111 | { 112 | "lon": "116.281441", 113 | "lat": "40.008703", 114 | "ts": null 115 | }, 116 | { 117 | "lon": "116.271092", 118 | "lat": "40.142201", 119 | "ts": null 120 | }, 121 | { 122 | "lon": "116.271092", 123 | "lat": "40.142201", 124 | "ts": null 125 | } 126 | ], 127 | "area_list": null, 128 | "npl_list": [{ 129 | "id": 8265, 130 | "name": "北辰世纪中心-a座", 131 | "city_id": 1, 132 | "type": 3, 133 | "status": 0, 134 | "map_point": "116.39338796444|40.008120315215;116.39494038009002|40.008177258745;116.39496911688|40.006268094213;116.39512457763|40.004256795877;116.39360214742|40.004222412241;116.39357190147|40.005075745782;116.39351397873|40.005836165232;116.39338796444|40.008120315215", 135 | "map_point_array": ["116.39338796444|40.008120315215", "116.396053|40.008273", "116.396448|40.006338", "116.396915|40.004266", "116.39192|40.004072", "116.391525|40.004984", "116.391381|40.005924", "116.391166|40.007913"], 136 | "map_status": 1, 137 | "creator_name": "赵程程", 138 | "create_time": 1507863539000 139 | }] 140 | } 141 | } -------------------------------------------------------------------------------- /src/resources/resource/api/order/ebike_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":'0', 3 | "result": { 4 | "id": 27296, 5 | "bike_sn": "800116116", 6 | "battery": 100, 7 | "start_time": "@datetime", 8 | "location": "北京市海淀区奥林匹克公园" 9 | } 10 | } -------------------------------------------------------------------------------- /src/resources/resource/api/order/finish_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":'0', 3 | "result": 'Ok' 4 | } -------------------------------------------------------------------------------- /src/resources/resource/api/order/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": '0', 3 | "result": { 4 | "page|1-9": 1, 5 | "page_size": 10, 6 | "total_count": 85, 7 | "page_count": 9, 8 | "item_list|10": [{ 9 | "id": 2959165, 10 | "order_sn": /T180[0-9]{6}/, 11 | "bike_sn": "800116090", 12 | "user_id": 908352, 13 | "user_name": "@cname", 14 | "mobile": /1[0-9]{10}/, 15 | "distance": 2000, 16 | "total_time": 4000, 17 | "status|1-2": 1, 18 | "start_time": "@datetime", 19 | "end_time": "@datetime", 20 | "total_fee": 1000, 21 | "user_pay": 300 22 | }] 23 | } 24 | } -------------------------------------------------------------------------------- /src/resources/resource/api/permission/edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0 3 | } -------------------------------------------------------------------------------- /src/resources/resource/api/proxy.json: -------------------------------------------------------------------------------- 1 | https://api.m.sohu.com/autonews/pool/?n=%E6%96%B0%E9%97%BB&s=1 -------------------------------------------------------------------------------- /src/resources/resource/api/query.json: -------------------------------------------------------------------------------- 1 | { success :true, data: { default: "hah", _req: function({ _req }) { return _req }, name: function({ _req }) { return _req.query.name || this.default }}} -------------------------------------------------------------------------------- /src/resources/resource/api/restful/_id/list.json: -------------------------------------------------------------------------------- 1 | {"success":true,"data":[{"user":{"name":"演示用"}}]} -------------------------------------------------------------------------------- /src/resources/resource/api/role/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0 3 | } -------------------------------------------------------------------------------- /src/resources/resource/api/role/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "result": { 4 | "page": 1, 5 | "page_size": 10, 6 | "total_count": 25, 7 | "page_count": 3, 8 | "item_list|7": [{ 9 | "id|+1": 1, 10 | "role_name": /(管理人员)|(客服专员)|(财务专员)|(市场专员)|(人力专员)|(研发)|(测试)|(系统管理员)/, 11 | "status|0-1": 1, 12 | "authorize_user_name": "@cname", 13 | "authorize_time": 1521270166000, 14 | "create_time": 1499305790000, 15 | "menus": ["/home", "/ui/buttons", "/ui/modals", "/ui/loadings", "/ui/notification", "/ui/messages", "/ui/tabs", "/ui/gallery", "/ui/carousel", "/ui"] 16 | }] 17 | } 18 | } -------------------------------------------------------------------------------- /src/resources/resource/api/role/user_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "result|20": [{ 4 | "status|0-1": 0, 5 | "user_id|+1": 1, 6 | "user_name": "@cname" 7 | }] 8 | } -------------------------------------------------------------------------------- /src/resources/resource/api/role/user_role_edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0 3 | } -------------------------------------------------------------------------------- /src/resources/resource/api/table/high/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "message": "", 4 | "result": { 5 | "list|25": [{ 6 | "id|+1": 1, 7 | "username": "Jack", 8 | "sex|1-2": 1, 9 | "age|10-50": 0, 10 | "state|1-5": 1, 11 | "interest|1-8": 1, 12 | "isMarried1|0-1": 1, 13 | "isMarried2|0-1": 1, 14 | "isMarried3|0-1": 1, 15 | "isMarried4|0-1": 1, 16 | "isMarried5|0-1": 1, 17 | "isMarried6|0-1": 1, 18 | "isMarried7|0-1": 1, 19 | "isMarried8|0-1": 1, 20 | "birthday": "2000-01-01", 21 | "address": "北京市海淀区", 22 | "time": "09:00:00" 23 | }], 24 | page: 2, 25 | page_size: 5, 26 | total_count: 30 27 | } 28 | } -------------------------------------------------------------------------------- /src/resources/resource/api/table/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "message": "", 4 | "result": { 5 | "list|10": [{ 6 | "id|+1": 1, 7 | "username": "@cname", 8 | "sex|1-2": 1, 9 | "state|1-5": 1, 10 | "interest|1-8": 1, 11 | "isMarried|0-1": 1, 12 | "birthday": "2000-01-01", 13 | "address": "北京市海淀区", 14 | "time": "09:00:00" 15 | }], 16 | page: 1, 17 | page_size: 10, 18 | total_count: 30 19 | } 20 | } -------------------------------------------------------------------------------- /src/resources/resource/api/table/list1.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "message": "", 4 | "result": { 5 | "list|10": [{ 6 | "id|+1": 1, 7 | "username": "@cname", 8 | "sex|1-2": 1, 9 | "state|1-5": 1, 10 | "interest|1-8": 1, 11 | "isMarried|0-1": 1, 12 | "birthday": "2000-01-01", 13 | "address": "北京市海淀区", 14 | "time": "09:00:00" 15 | }], 16 | page: 1, 17 | page_size: 10, 18 | total_count: 30 19 | } 20 | } -------------------------------------------------------------------------------- /src/resources/resource/api/upload.json: -------------------------------------------------------------------------------- 1 | { data: { img: function({ _req, Mock }) { return _req.body.fileName + "_" + Mock.mock("@image") }}} -------------------------------------------------------------------------------- /src/resources/resource/api/user/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":0, 3 | "result": "Ok" 4 | } -------------------------------------------------------------------------------- /src/resources/resource/api/user/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":0 3 | } -------------------------------------------------------------------------------- /src/resources/resource/api/user/edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "result":'Ok' 4 | } -------------------------------------------------------------------------------- /src/resources/resource/assets/bike.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/bike.jpg -------------------------------------------------------------------------------- /src/resources/resource/assets/carousel-img/carousel-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/carousel-img/carousel-1.jpg -------------------------------------------------------------------------------- /src/resources/resource/assets/carousel-img/carousel-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/carousel-img/carousel-2.jpg -------------------------------------------------------------------------------- /src/resources/resource/assets/carousel-img/carousel-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/carousel-img/carousel-3.jpg -------------------------------------------------------------------------------- /src/resources/resource/assets/end_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/end_point.png -------------------------------------------------------------------------------- /src/resources/resource/assets/imooc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/imooc.png -------------------------------------------------------------------------------- /src/resources/resource/assets/logo-ant.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 28 Copy 5 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 42 | 43 | -------------------------------------------------------------------------------- /src/resources/resource/assets/start_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/start_point.png -------------------------------------------------------------------------------- /src/resources/resource/assets/user_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/assets/user_location.png -------------------------------------------------------------------------------- /src/resources/resource/carousel-img/carousel-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/carousel-img/carousel-1.jpg -------------------------------------------------------------------------------- /src/resources/resource/carousel-img/carousel-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/carousel-img/carousel-2.jpg -------------------------------------------------------------------------------- /src/resources/resource/carousel-img/carousel-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/carousel-img/carousel-3.jpg -------------------------------------------------------------------------------- /src/resources/resource/common.less: -------------------------------------------------------------------------------- 1 | @import './default.less'; 2 | @import './loading.less'; 3 | 4 | body { 5 | background: @colorL; 6 | font-family: "Helvetica Neue For Number", "PingFang SC Light", "Heiti SC", "San Francisco", "Helvetica", Arial, sans-serif; 7 | } 8 | 9 | .container{ 10 | .nav-left{ 11 | background-color:#001529; 12 | color: #ffffff; 13 | height: calc(100vh); 14 | } 15 | .main{ 16 | height: calc(100vh); 17 | background-color: @colorL; 18 | overflow: auto; 19 | } 20 | .content{ 21 | position: relative; 22 | padding: 20px; 23 | } 24 | } 25 | 26 | .content-wrap{ 27 | background: #ffffff; 28 | border: 1px solid #e8e8e8; 29 | margin-top: -3px; 30 | .ant-table-wrapper{ 31 | margin-left: -1px; 32 | margin-right: -2px; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/resources/resource/default.less: -------------------------------------------------------------------------------- 1 | /** 常用色值 **/ 2 | @colorA: #f9c700; 3 | @colorB: #ff5400; 4 | @colorC: #333; 5 | @colorD: #6699cc; 6 | @colorE: #9cb3c5; 7 | @colorF: #e0e6ec; 8 | @colorG: #666; 9 | @colorH: #999; 10 | @colorI: #ccc; 11 | @colorJ: #d7d7d7; 12 | @colorK: #e3e3e3; 13 | @colorL: #f1f3f5; 14 | @colorM: #fff; 15 | @colorN: #e5e5e5; 16 | @colorO: #afafaf; 17 | @colorP: #ff8605; 18 | @colorQ: #f9fbfc; 19 | @colorR: #001529; 20 | @colorS: #002140; 21 | @colorT: #232526; 22 | @colorU: #bebebe; 23 | 24 | /** 常用字体大小 **/ 25 | @fontA: 34px; 26 | @fontB: 22px; 27 | @fontC: 18px; 28 | @fontD: 16px; 29 | @fontE: 14px; 30 | @fontF: 12px; 31 | @fontG: 20px; -------------------------------------------------------------------------------- /src/resources/resource/doc.js: -------------------------------------------------------------------------------- 1 | // 百度天气API接口 2 | //http://api.map.baidu.com/telematics/v3/weather?location=beijing&output=json&ak=3p49MVra6urFRGOT9s8UBWr2 3 | -------------------------------------------------------------------------------- /src/resources/resource/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/favicon.ico -------------------------------------------------------------------------------- /src/resources/resource/gallery/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/1.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/10.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/11.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/12.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/13.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/14.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/15.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/16.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/17.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/18.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/19.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/2.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/20.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/21.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/22.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/23.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/24.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/25.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/3.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/4.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/5.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/6.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/7.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/8.png -------------------------------------------------------------------------------- /src/resources/resource/gallery/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/gallery/9.png -------------------------------------------------------------------------------- /src/resources/resource/header/index.less: -------------------------------------------------------------------------------- 1 | @import './../../style/default.less'; 2 | .header{ 3 | background-color: @colorM; 4 | .header-top{ 5 | height: 60px; 6 | line-height: 60px; 7 | padding: 0 20px; 8 | text-align: right; 9 | .logo{ 10 | line-height: 60px; 11 | img{ 12 | height:40px; 13 | vertical-align: middle; 14 | } 15 | } 16 | a{ 17 | margin-left: 40px; 18 | } 19 | } 20 | .breadcrumb{ 21 | height: 40px; 22 | line-height: 40px; 23 | padding: 0 20px; 24 | border-top: 1px solid #f9c700; 25 | .breadcrumb-title{ 26 | text-align: center; 27 | font-size: @fontC; 28 | &:after{ 29 | position: absolute; 30 | content: ''; 31 | left:73px; 32 | top:39px; 33 | border-top: 9px solid @colorM; 34 | border-left: 12px solid transparent; 35 | border-right: 12px solid transparent; 36 | } 37 | } 38 | .weather{ 39 | text-align: right; 40 | font-size: 14px; 41 | .date{ 42 | margin-right: 10px; 43 | vertical-align: middle; 44 | } 45 | .weather-img{ 46 | img{ 47 | height: 15px; 48 | } 49 | } 50 | .weather-detail{ 51 | margin-left: 5px; 52 | vertical-align: middle; 53 | } 54 | } 55 | } 56 | } 57 | // common 页面简单头 58 | .simple-page{ 59 | .header-top{ 60 | background:#1890ff; 61 | color:@colorM; 62 | } 63 | .ant-form, 64 | .ant-col-12, 65 | .weather{ 66 | display:none; 67 | } 68 | } -------------------------------------------------------------------------------- /src/resources/resource/image/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dL-hx/imoocmanager/b25cf91cd44f52b2d4039a8c41c7a03d8cbdd6ab/src/resources/resource/image/demo.png -------------------------------------------------------------------------------- /src/resources/resource/loading.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Loading 7 | 8 | 9 | 10 | 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /src/resources/resource/loading.less: -------------------------------------------------------------------------------- 1 | /** load **/ 2 | .ajax-loading{ 3 | display: none; 4 | .loading{ 5 | position: fixed; 6 | top: 50%; 7 | left: 50%; 8 | transform: translate(-50%,-50%); 9 | padding:0 40px; 10 | height: 80px; 11 | line-height: 80px; 12 | background: rgba(0, 0, 0, 0.75); 13 | border-radius: 6px; 14 | text-align: center; 15 | z-index: 9999; 16 | font-size:@fontD; 17 | color:#fff; 18 | img{ 19 | width: 32px; 20 | vertical-align: middle; 21 | } 22 | span{ 23 | margin-left:12px; 24 | } 25 | } 26 | .overlay{ 27 | position: fixed; 28 | left: 0; 29 | right: 0; 30 | top: 0; 31 | bottom: 0; 32 | z-index: 9998; 33 | background: rgb(255, 255, 255); 34 | opacity: 0.1; 35 | } 36 | } 37 | 38 | /****/ -------------------------------------------------------------------------------- /src/resources/resource/menuConfig.js: -------------------------------------------------------------------------------- 1 | const menuList = [ 2 | { 3 | title:'首页', 4 | key:'/home' 5 | }, 6 | { 7 | title:'UI', 8 | key:'/ui', 9 | children:[ 10 | { 11 | title:'按钮', 12 | key:'/ui/buttons', 13 | }, 14 | { 15 | title:'弹框', 16 | key:'/ui/modals', 17 | }, 18 | { 19 | title:'Loading', 20 | key:'/ui/loadings', 21 | }, 22 | { 23 | title:'通知提醒', 24 | key:'/ui/notification', 25 | }, 26 | { 27 | title:'全局Message', 28 | key:'/ui/messages', 29 | }, 30 | { 31 | title:'Tab页签', 32 | key:'/ui/tabs', 33 | }, 34 | { 35 | title:'图片画廊', 36 | key:'/ui/gallery', 37 | }, 38 | { 39 | title:'轮播图', 40 | key:'/ui/carousel', 41 | } 42 | ] 43 | }, 44 | { 45 | title:'表单', 46 | key:'/form', 47 | children:[ 48 | { 49 | title:'登录', 50 | key:'/form/login', 51 | }, 52 | { 53 | title:'注册', 54 | key:'/form/reg', 55 | } 56 | ] 57 | }, 58 | { 59 | title:'表格', 60 | key:'/table', 61 | children:[ 62 | { 63 | title:'基础表格', 64 | key:'/table/basic', 65 | }, 66 | { 67 | title:'高级表格', 68 | key:'/table/high', 69 | } 70 | ] 71 | }, 72 | { 73 | title:'富文本', 74 | key:'/rich' 75 | }, 76 | { 77 | title:'城市管理', 78 | key:'/city' 79 | }, 80 | { 81 | title:'订单管理', 82 | key:'/order', 83 | btnList:[ 84 | { 85 | title:'订单详情', 86 | key:'detail' 87 | }, 88 | { 89 | title:'结束订单', 90 | key:'finish' 91 | } 92 | ] 93 | }, 94 | { 95 | title:'员工管理', 96 | key:'/user' 97 | }, 98 | { 99 | title:'车辆地图', 100 | key:'/bikeMap' 101 | }, 102 | { 103 | title:'图标', 104 | key:'/charts', 105 | children:[ 106 | { 107 | title:'柱形图', 108 | key:'/charts/bar' 109 | }, 110 | { 111 | title:'饼图', 112 | key:'/charts/pie' 113 | }, 114 | { 115 | title:'折线图', 116 | key:'/charts/line' 117 | }, 118 | ] 119 | }, 120 | { 121 | title:'权限设置', 122 | key:'/permission' 123 | }, 124 | ]; 125 | export default menuList; -------------------------------------------------------------------------------- /src/resources/resource/order/detail.less: -------------------------------------------------------------------------------- 1 | @import '../../style/default'; 2 | @import '../../style/common'; 3 | .detail-items{ 4 | margin-left:90px; 5 | padding:25px 50px 25px 0; 6 | border-bottom:1px solid @colorN; 7 | &:last-child{ 8 | border-bottom:none; 9 | } 10 | .item-title{ 11 | margin:20px 0; 12 | font-size:@fontG; 13 | color:@colorU; 14 | } 15 | .detail-form{ 16 | li{ 17 | .clearfix; 18 | margin:20px 0; 19 | line-height:20px; 20 | font-size:15px; 21 | color:@colorC; 22 | } 23 | } 24 | .detail-form-left{ 25 | float:left; 26 | width:164px; 27 | text-align:right; 28 | color:@colorH; 29 | } 30 | .detail-form-content{ 31 | padding-left:194px; 32 | } 33 | } 34 | .order-map{ 35 | height: 450px; 36 | margin: 25px -31px 0; 37 | } -------------------------------------------------------------------------------- /src/resources/resource/ui.less: -------------------------------------------------------------------------------- 1 | /* ui */ 2 | .ui-wrap{ 3 | 4 | } 5 | .card-wrap{ 6 | margin-bottom: 10px; 7 | } 8 | button{ 9 | margin-right: 20px; 10 | } 11 | .btn-group button{ 12 | margin-right: 0; 13 | } 14 | /* modals */ 15 | /* use css to set position of modal */ 16 | .vertical-center-modal { 17 | text-align: center; 18 | white-space: nowrap; 19 | } 20 | 21 | .vertical-center-modal:before { 22 | content: ''; 23 | display: inline-block; 24 | height: 100%; 25 | vertical-align: middle; 26 | width: 0; 27 | } 28 | 29 | .vertical-center-modal .ant-modal { 30 | display: inline-block; 31 | vertical-align: middle; 32 | top: 0; 33 | text-align: left; 34 | } 35 | 36 | /* 37 | // Use flex which not working in IE 38 | .vertical-center-modal { 39 | display: flex; 40 | align-items: center; 41 | justify-content: center; 42 | } 43 | 44 | .vertical-center-modal .ant-modal { 45 | top: 0; 46 | } 47 | */ 48 | 49 | // Carousel 50 | 51 | /* For demo */ 52 | .ant-carousel .slick-slide { 53 | text-align: center; 54 | height: 160px; 55 | line-height: 160px; 56 | background: #364d79; 57 | overflow: hidden; 58 | } 59 | 60 | .ant-carousel .slick-slide h3 { 61 | color: rgba(246, 250, 33, 0.966); 62 | } 63 | 64 | // 图片轮播 65 | .slider-wrap .ant-carousel .slick-slide { 66 | height: 240px!important; 67 | } -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | // src/router.js 2 | import React from 'react'; 3 | import {HashRouter, Route, Switch, Redirect} from "react-router-dom"; 4 | import App from "./App"; 5 | import Login from "./pages/login"; 6 | import Admin from "./admin"; 7 | import Home from "./pages/home"; 8 | import Buttons from "./pages/ui/buttons"; 9 | import Modals from "./pages/ui/modals"; 10 | import Loadings from "./pages/ui/loadings"; 11 | import Notice from "./pages/ui/notice"; 12 | import Messages from "./pages/ui/messages"; 13 | import Tabs1 from "./pages/ui/tabs"; 14 | import Gallery from "./pages/ui/gallery"; 15 | import Carousels from "./pages/ui/carousel"; 16 | import FormLogin from "./pages/form/login"; 17 | import FormRegister from "./pages/form/register"; 18 | import BasicTable from "./pages/table/basicTable"; 19 | import HighTable from "./pages/table/highTable"; 20 | import RichText from "./pages/rich"; 21 | import City from "./pages/city"; 22 | import Order from "./pages/order"; 23 | import User from "./pages/user"; 24 | import BikeMap from './pages/map/bikeMap'; 25 | import Bar from './pages/echarts/bar'; 26 | import Pie from './pages/echarts/pie'; 27 | import Line from './pages/echarts/line'; 28 | import Permission from './pages/permission'; 29 | import NoMatch from "./pages/nomatch"; 30 | import Common from "./common"; 31 | import OrderDetail from "./pages/order/detail"; 32 | 33 | export default class IRouter extends React.Component { 34 | render() { 35 | return ( 36 | 37 | 38 | 39 | 40 | { 41 | return 42 | 43 | ; 44 | }} 45 | /> 46 | ( 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | {/**/} 75 | 76 | 77 | )} 78 | /> 79 | 80 | 81 | 82 | 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/style/common.less: -------------------------------------------------------------------------------- 1 | // @colorA:'red'; 2 | // div{ 3 | // color:@colorA 4 | // } 5 | @import "./default.less"; 6 | @import "./loading.less"; //导入loading.less文件 7 | 8 | // 清除li 标签前面的点点 9 | ul, li { 10 | list-style: none; 11 | } 12 | 13 | // 清除左右浮动 14 | .clearfix { 15 | &:after { 16 | content: " "; 17 | clear: both; 18 | display: block; 19 | visibility: hidden; 20 | } 21 | } 22 | 23 | .container { 24 | .nav-left { 25 | width: 15%; 26 | min-width: 180px; 27 | color: #ffffff; 28 | height: calc(100vh); 29 | background-color: #001529; 30 | // background-color:red; 31 | } 32 | 33 | .main { 34 | height: calc(100vh); 35 | background-color: @colorL; 36 | overflow: auto; 37 | } 38 | 39 | .content { 40 | position: relative; 41 | padding: 20px; 42 | } 43 | } 44 | 45 | .content-wrap { 46 | background: #ffffff; 47 | border: 1px solid #e8e8e8; 48 | margin-top: -3px; 49 | 50 | .ant-table-wrapper { 51 | margin-left: -1px; 52 | margin-right: -2px; 53 | } 54 | } 55 | .operate-wrap{ 56 | button{ 57 | margin-right: 10px; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/style/default.less: -------------------------------------------------------------------------------- 1 | /** 常用色值 **/ 2 | @colorA: #f9c700; 3 | @colorB: #ff5400; 4 | @colorC: #333; 5 | @colorD: #6699cc; 6 | @colorE: #9cb3c5; 7 | @colorF: #e0e6ec; 8 | @colorG: #666; 9 | @colorH: #999; 10 | @colorI: #ccc; 11 | @colorJ: #d7d7d7; 12 | @colorK: #e3e3e3; 13 | @colorL: #f1f3f5; 14 | @colorM: #fff; 15 | @colorN: #e5e5e5; 16 | @colorO: #afafaf; 17 | @colorP: #ff8605; 18 | @colorQ: #f9fbfc; 19 | @colorR: #001529; 20 | @colorS: #002140; 21 | @colorT: #232526; 22 | @colorU: #bebebe; 23 | 24 | /** 常用字体大小 **/ 25 | @fontA: 34px; 26 | @fontB: 22px; 27 | @fontC: 18px; 28 | @fontD: 16px; 29 | @fontE: 14px; 30 | @fontF: 12px; 31 | @fontG: 20px; -------------------------------------------------------------------------------- /src/style/loading.less: -------------------------------------------------------------------------------- 1 | /** load **/ 2 | .ajax-loading{ 3 | display: none; 4 | .loading{ 5 | position: fixed; 6 | top: 50%; 7 | left: 50%; 8 | transform: translate(-50%,-50%); 9 | padding:0 40px; 10 | height: 80px; 11 | line-height: 80px; 12 | background: rgba(0, 0, 0, 0.75); 13 | border-radius: 6px; 14 | text-align: center; 15 | z-index: 9999; 16 | font-size:@fontD; 17 | color:#fff; 18 | img{ 19 | width: 32px; 20 | vertical-align: middle; 21 | } 22 | span{ 23 | margin-left:12px; 24 | } 25 | } 26 | .overlay{ 27 | position: fixed; 28 | left: 0; 29 | right: 0; 30 | top: 0; 31 | bottom: 0; 32 | z-index: 9998; 33 | background: rgb(255, 255, 255); 34 | opacity: 0.1; 35 | } 36 | } 37 | 38 | /****/ -------------------------------------------------------------------------------- /src/utils/utils.js: -------------------------------------------------------------------------------- 1 | //src/utils/utils.js 2 | import React from 'react'; 3 | import {Select} from 'antd'; 4 | const Option = Select.Option; 5 | 6 | export default { 7 | formateDate(time) { 8 | function checkTime(time){ 9 | return time<10?"0"+time:time 10 | } 11 | if (!time) return ''; 12 | let date = new Date(time); 13 | return date.getFullYear() + '-' + checkTime(date.getMonth() + 1) + 14 | '-' + checkTime(date.getDate()) + ' ' + 15 | checkTime(date.getHours()) + ":" + checkTime(date.getMinutes()) + ":" + checkTime(date.getSeconds()); 16 | }, 17 | //封装pagination公共机制 18 | pagination(data,callback){ 19 | let page = { 20 | onChange:(current)=>{ 21 | callback(current) 22 | }, 23 | current:data.result.page, 24 | pageSize:data.result.page_size, 25 | total:data.result.total, 26 | showTotal:()=>{ 27 | return `共${data.result.total}条` 28 | }, 29 | showQuickJumper:true 30 | }; 31 | return page; 32 | }, 33 | 34 | // 封装Option 外层接收data 35 | getOptionList(data){ 36 | if (!data) { 37 | return [] 38 | } 39 | let options = [];//[] 40 | 41 | data.map((item) => { 42 | //在options 中添加option 对象 43 | options.push() 44 | }); 45 | 46 | return options; 47 | }, 48 | 49 | /** 50 | * ETable 行点击通用函数 51 | * @param {*选中行的索引} selectedRowKeys 52 | * @param {*选中行对象} selectedItem 53 | */ 54 | updateSelectedItem(selectedRowKeys, selectedRows,selectedIds){ 55 | if(selectedIds){ 56 | this.setState({ 57 | selectedRowKeys, 58 | selectedIds:selectedIds, 59 | selectedItem:selectedRows 60 | }) 61 | }else { 62 | this.setState({ 63 | selectedRowKeys, 64 | selectedItem:selectedRows 65 | }) 66 | } 67 | } 68 | } --------------------------------------------------------------------------------