精华内容
下载资源
问答
  • react后台管理系统项目
    千次阅读
    2021-09-12 16:45:07

    1、创建一个项目

    • 作为一个React的项目,首先就得先创建一个项目
    • npx create-react-app react-pro

    2、配置一个ui插件库

    • 作为一个程序员,写项目就需要一个非常好用的插件库,这里推荐使用ant.design组件库

    开始

    • 创建一个全局的index.js文件,在index中导入最基本的模块,React以及ReactDOM
    • 一个基本小细节需要注意就是在设置渲染页面时document.querySelector('#root')如果不是使用getElementById的情况下需要记得加上#,如果是使用getElementById时,记得千万不要加#号
    • 创建一个全局App.jsx文件
    • 修改一下目录的解构,将需要的文件夹创建好 :api ,layout,router,store,utils,views
    • 搭建好项目的主要结构,在组件库中选择一个布局结构
    • 在设置log时会有一个问题,当你点击右边小窗口时,会有一个小问题,收起时,文字不会收回去,而是继续显示在这里插入图片描述
      在这里库使用学到的三元运算符去解决,去判断当他收起时,就为空,展开时就把需要设置的标签设置上去
    this.state.collapsed ? null : <span>康娜管理系统</span>
    

    但是这时你会发现一个新的问题,文字确实空了,但是在你展开时,会出现是先显示文字是掉落的,然后再展开回归原位,这时就需要给他的样式上加一个overflow: hidden,这样这个小问题就解决了

    • 在App中设置路由跳转,在这之前需要安装路由yarn add react-router-dom -S,在App设置一个默认跳转,跳转至存放页面的文件夹 min 中
    • 按照ui库中的组件以及Tree树形控件,设计字段,存放至router文件下的menus.js文件中
    • 将菜单文件抽离出来放置一个组件中,在存放的页面文件中导入分离的菜单组件,分离的目的就是为了能够更好的维护代码,更美观,方便查找代码的问题。
    • 在menus.js中设置好跳转的字段
    • path: '/banner', title: '轮播图管理', key: '0-1',
    • 在设置好需要的字段的时候,就可以去抽离出来的组件中导入设置好字段的文件,设置一个方法,将导入的字段文件传入作为参数,把传入的参数进行map循环,此时需要做一个判断,在组件库的拿到的组件代码中,有一个导航的,也有二级导航的,在我们设置的字段当中也是有二级导航和一级导航的,这时循环就需要判断是否有二级菜单导航if (item.children)如果有二级菜单,那么就返回一个标签将二级菜单循环出来,如果没有二级菜单,则直接渲染一级菜单即可。

    实现跳转

    • 实现跳转的方式有很多只
    • 1、类组件实现编程式导航跳转this.props.history.push(要跳转的路由)
    • 2、函数式组件的跳转props.history.push(要跳转的路由)
    • 3、使用useHistory高阶方法,history = useHistory()不可以在组价的内部事件中调用,通过<button onClik = { () => {history.push()}}< /button>

    快速获取路由地址

    • 将数据库文件导入,定义一个方法使用map方法循环得到他的path路由的地址,在这就有一个问题,需要需要去判断是否有二级路由
    • 使用if判断当前的path是否有children二级路由,如果有二级路由则先渲染出以及路由,在利用递归方法去调用自身,将二级路由传入进去进行循环渲染
    • else如果没有二级则直接渲染,很重要的一点,将key值都设置成循环时的path,key={item.path}
    • 在使用的组件上定义一个点击事件 给点击事件传递一个方法,传递的方法中设置history.push方法,而要跳转的值就是key,这样就能实现点击时获取到该值的路由

    将路由和组件映射

    • 在创建好所有组件时,在数据库中绑定对应的组件component: React.lazy(() => import('./../views/banner/index'))将对应的组件绑定后即可实现跳转路由

    axios请求

    • 在工作中的请求网址和上线后的网址 可能不是同一个网址,可以通过设置一个判断给当前的模式设置为开发者模式,然后使用三元运算符去判断如果是开发模式就使用第一个网址,如果不是就使用第二个网址,有些公司上线后的网址不是同一个

    实现登录模块

    • 封装请求登录的接口,拿到请求返回的值,在antd的插件中,有个比较强大的功能,onFinish是整个登入标签的自带标签上定义的,他的value就是你在表单中的输入值,可以把value值传个登录请求作为参数传入。使用状态码判定是否登录,10005则代表没有账号,10003则表示密码有问题,没有则俩种情况就是正确的。需要做的关键一步,在登录成功时把登录的账号和密码等信息传入本地存储起来,并且设置跳转到首页,需要尤其是token。在用户登入之后请求数据时需要带上token去判断用户是否登录,token有没有失效。在拦截器中设置一个判断,token是否为101119或者为空,如果是的话就需要重新登录。设置跳转到到登入页面。
    • 那么新的问题就出现了,假设你在登入的情况下,去把登录状态或者token清除了,这时候就会出现报错,这个报错的原因是因为你清除后还是登入状态,当你去点击其他菜单时会发送请求,而发送请求的时候你的本地已经被清除了,但你又请求了数据,所以会返回一个空,触发了请求后会进入渲染时的循环,循环时就会发现是空的,就会报错。从而导致不会之间跳转到登录页面,而是直接报错,所以这时候就需要在设置跳转后再下方设置一个data为0给他,防止进入循环报错。在将整个设置return出去,防止整个报错。

    隐藏二级路由

    • 在数据库中存在有些二级路由是你不想让他显示的,是需要通过某些方法来触发跳转实现的
    • 比如添加轮播图,只想点击添加轮播图按钮显示,就可以在数据库字段中设置一个showfalse,然后再渲染的时候做一个判断,判断item.show就是数据库的的show是否为false,如果为false的话,该路由就渲染为空,如果没有show这个选项则正常渲染,然后需要使用这个路由时则在需要的地方设置一个点击跳转,跳转到那个路由即可

    按照价格排序或者按照销量等排序

    • 通过title表格中的sorter`方法(a - b )俩个参数,设置 a.这个字段 - b.这个字段即可实现排序

    管理员模块

    • 定义好管理员的请求方法
    • 使用antd UI组件库的中的title表格去渲染拿到的管理员详情列表
    • 使用组件库中的Drawer(抽屉)方法去添加新管理员
    • 通过组件库中的Input方法,可以获取到输入的值
    • 将获取到的值全部集合用data接收,在调用封装好的添加管理员的请求将data作为参数传入进去
    • 传入完成后做判断,判断返回的code状态码,是否为10004,如果是10004就返回警告信息,管理员已存在
    • 添加成功后要记得把输入框中的值全部清空,并且把Drawer抽屉关闭,并且将请求详情管理员的方法封装起来进行调用,调用方法进行视图更新
    • 有管理员就有删除管理员
    • 使用到了antd组件库中的气泡确认框,在点击确认时的回调中调用删除管理员的方法,删除reaord中当前的anminid,在删除后.then调用封装的视图更新方法更新视图
    • 修改管理员权限
    • 在antd组件库中找到树形结构,在该方法中有一个checkedkeys方法可以获取到选中的复选框,把点击时的adminnamerolecheckedkeys等选中的值获取到,在编辑时修改其中的值,并且将弹框关闭

    动态渲染菜单栏

    • checkedkeys就是复选框选中的值,定义一个方法把checkedkeys作为参数传入
    • 传入后利用分割合并拿到的字段,传入的字段是0-0-1这样的字段,而渲染的情况下只会渲染拿到的字段,而一级字段是0-0这样的,所以需要去分割,把拿到的字段分割取前三位,然后将分割的字段与传过来的字段进行合并去重
    • 在将拿到的字段去渲染

    访问权限

    • 有时候你希望普通成员也能拥有一些页面,但是不能查看,这时候就可以在数据库中加入一个role值,普通成员可以看到的就设置字段值为1,管理员能看到的就设置字段为2 ,然后再渲染的时候去做一层判断,如果当前的role值大于或者等于数据库中的role值,就将完整的component渲染,如果小于则渲染一个无权限。

    登入后的权限访问

    在登入后,通过通知栏可以访问到一些你没有权限看到的页面,普通用户的情况下可能不会去触发这些,但是安全起见,需要设置一下,去判断拿回来的值,将总数据库作为参数导入,在将处理好的字段进行导入,去循环对比,总数据中的item.key===val,如果等于val,就将item的值push进定义好的数组中,在将拿到的数组去查找他的二级菜单,利用递归,将拿到的二级菜单和传入的二级菜单做对比,如果你访问的路由值存在数据库中,而你并没有这个路由,则给你返回一个无权限,如果数据库中没有这个路由,则返回404

    项目bug总结

    • 1、在你手动去浏览器清除token时,你再去请求别的页面时,并不会跳转,而是报错,即使你设置了token===10119或者等于空,但是在清除token后去请求数据时是会返回data的,而其他代码中有用到data 的地方,此时他去读取这个data时,就是个空,拿不到数据则会报错
    • 解决方案:在跳转后给他一个data为0,在给他返回出去,就可以避免这样的报错
    • 2、有时候在重新启动程序的时候会在首页,并没有重定义判定
    • 原因:你的重定义需要放在其他路由前面,才会在进入程序时先去判定是否重定向,重定向之后在判断其他路由
    • 3、在退出登入后,你重新登录回去后他不会定位在上一次登入的位置
    • 解决方案:给跳转登录的方法后面加上(/login ?redirect + this.props.location.pathname),将退出前的路由给保存下来,在下次登录的时候,在登录程序后面加上?redirect,但是这样会出问题,因为上传登录的数据中会议redirect,而我们需要的是/pro/List这段,所以先将其分割,拿到pro这段
    • 在跳转的时候做一层判定,如果登录的时候有上一次的记录就跳转至上一层的记录,如果没有就跳转到首页
    更多相关内容
  • React 后台管理系统项目

    万次阅读 多人点赞 2019-10-10 15:34:21
    项目架构是纯手工搭建的,并非使用脚手架搭建~ 相关技术 ...项目预览地址 https://jesonman.github.io/react-admin-demo/ 项目源码地址 https://github.com/JesonMan/react-admin/ 相关页面 登录 首...

    该项目架构是纯手工搭建的,并非使用脚手架搭建~

    相关技术

    react + redux + react-router + sass + antd + eslint + webpack

    项目预览地址 https://jesonman.github.io/react-admin-demo/ (预览地址无法访问的话,把DNS改成 114.114.114.114 即可访问)

    项目源码地址 https://github.com/JesonMan/react-admin/

    相关页面

    登录在这里插入图片描述

    首页在这里插入图片描述

    相关优化

    1. 使用DllPlugin和DllReferencePlugin插件,dll化常用的第三方模块,提高webpack构建速度,也有利于客户端缓存。
    2. 使用HappyPack插件开启多进程loader转换,提高webpack构建速度。
    3. 使用autoprefixer实现自动补全css浏览器兼容前缀。
    4. 使用MiniCssExtractPlugin插件抽离css到单独的css文件,并使用OptimizeCssAssetsPlugin插件对css进行压缩。
    5. 使用react-loadable实现代码分割,从而实现按需加载。
    展开全文
  • 从0到1搭建react后台管理系统项目

    千次阅读 2021-06-26 18:04:18
    今天我们要讲的是基于react框架,如何从0到1快速搭建一个后台管理系统。主要分为以下几步:1. 安装node.js(基本环境,自带npm);2. 安装git(版本管理);3. 安装VSCode(开发工具);4.使用Ant Design Pro搭建...

    如果我们需要从0到1搭建一个全新的企业级web后台管理系统,我们应该怎么做呢?基于我以往的开发经验,给大家讲下我在实战中用到的一些环境、工具、框架等,让大家快速入门上手前端项目开发,并少走弯路。

    在企业,我们首先可能要面临前端框架技术选型问题,个人建议从目前的3大主流框架(vue、react和angular)做选择。具体怎么选,需要结合公司的前端技术方向、公司现有人员对各框架的熟悉程度以及综合系统需求和不同框架的生态圈考虑,在此这不做详细分析。

    今天我们要讲的是基于react框架,如何从0到1快速搭建一个后台管理系统。

    主要分为以下几步:

    1. 安装node.js(基本环境,自带npm

    2. 安装git(版本管理)

    3. 安装VSCode(开发工具)

    4. 使用Ant Design Pro搭建项目

    一、基础安装

    1、安装node.js

    node.js是一个JavaScript运行环境,已经集成了npm包管理工具。npm主要用于管理node包的安装、更新、卸载等。

    官方下载地址:

    http://nodejs.cn/download/

    建议下载稳定版本,下最新版的话后续在依赖安装中可能存在报错(可能是版本太高导致部分插件不兼容)

    在没安装之前,电脑打开cmd(window+R,输入cmd回车)查询node和npm版本是查不到的

    node -v  //查询node版本
    
    npm -v   //查询npm版本

    此时我的电脑还没安装node

    下面开始安装node.js,双击打开下载好的安装文件

    ······

    此处忽略安装步骤,一路按默认选项点下一步即可(也可视自身需要进行修改,比如更改默认安装路径等)

    ······

    安装完成后,我们重新打开cmd查询node和npm版本。由下图可以看到已经查到版本,node安装成功,npm也随同一起安装好了

    2. 安装 git

    在实际项目开发中,我们需要用到版本控制器来管理我们的代码。在此我推荐用git。

    官方下载地址:

    https://git-scm.com/downloads

    官网下载如果存在下载不了或者下载太慢的问题,如果是windows系统用户,我们可以用淘宝的镜像进行下载(选择最新版本),地址如下:

    https://npm.taobao.org/mirrors/git-for-windows/

    下面开始安装git,双击打开下载好的安装文件

    ······

    此处忽略安装步骤,一路按默认选项点下一步即可(也可视自身需要进行修改,比如更改默认安装路径等)

    ······

    安装完成后,在开始菜单里可以找到Git Bash(Git配套的控制台)、Git GUI(Git可视化操作工具)等工具。

    二、前端开发工具

    推荐使用VSCode,全称Visual Studio Code,是一款免费开源的现代化轻量级代码编辑器,也是目前大部分企业都在用的前端开发工具。

    官方下载地址:

    https://code.visualstudio.com/

    下面开始安装VSCode,双击打开下载好的安装文件

    ······

    此处忽略安装步骤,一路按默认选项点下一步即可(也可视自身需要进行修改,比如更改默认安装路径等)

    ······

    安装完成后,我们就可以用此工具进行项目代码的编辑了。功能非常强大,界面既简洁又好看。

    三、搭建项目

    借助Ant Design Pro(简称Antd Pro)实现后台管理系统的搭建。Antd Pro是一套开箱即用的企业级中后台前端/设计解决方案,是一个基于React开发中后台系统的脚手架,它可以帮助我们快速搭建企业级中后台产品原型,同时也方便我们上手开发和学习。

    Antd Pro集成了antd(React UI组件库)、umi(可插拔的企业级react应用框架)、dva(轻量级JS框架)等一系列组件和插件,后续大家可以慢慢深入学习。Antd Pro官方网址:https://pro.ant.design/

    现在,我们先来进行Antd Pro的安装。

    1. 新建一个空的文件夹(以react-demo为例)作为项目目录,并在目录下执行:

    npm create umi
    

    2. 选择模板类型,选默认的ant-design-pro即可

    3. 选择版本,选默认的Pro V4即可,目前V5还是beta版

    4. 选择语言,目前我开发项目基本都用ts,所以我选默认的TypeScript

    5. 选择脚手架模式,simple为简单项目(只有基础功能,包含的组件和功能较少),complete为完整项目。选择默认的simple即可

    6. 选择antd的版本,选择默认的antd@4即可

    经过上述几步操作后,Antd Pro 脚手架将会自动安装。

    安装完成后,react-demo目录下就拥有了项目所需的各种基础文件。

    至此,我们已经把Antd Pro脚手架安装完成,那我们怎么启动项目,让项目跑起来呢?

    首先,我们需要在项目的根目录下安装依赖,命令如下:

    npm install  // 简写为npm i
    

    如果网络状况不佳,可以使用cnpm代替npm进行加速。

    依赖安装完后,会多出一个node_modules文件夹。node_modules是安装node后用来存放用包管理工具下载安装的包的文件夹。

    其次,安装完依赖后启动项目,命令如下:

    npm start
    

    下图代表项目已启动完,运行在本地的8000端口

    这时,我们在浏览器打开localhost:8000

    至此,从浏览器的展示可以看到,后台管理系统的基本结构已经出来了。接下来,我们就可以用vscode工具进行具体项目需求的开发,大家可以具体看下antd pro、umi、antd的Api,以及当前已经搭建好的基础项目的结构和写法,参考着进行开发,相信你很快就能快速上手。

    感谢您读完本文!如果本文对您有帮助,请点个赞呗,您的点赞是对我最大的支持和认可!

    我的公众号:大前端教程,欢迎关注,会定期更新前端知识,希望能帮到您。

    展开全文
  • react-web-admin React后台管理系统
  • 运行 npm run dev 功能列表 用户管理->角色管理 角色管理->菜单分配 部门管理 菜单管理 动态菜单 动态按钮 部门管理关联角色管理 字典管理 文件 [语雀地址]( 《React管理员》)
  • 在此文的基础上,写了篇新文章使用React全家桶搭建一个后台管理系统,欢迎围观。(附注:因为项目不时更新,文章不一定会即时更新,所以以实际的项目为准) 其实这套界面风格不仅仅可以作为后台管理系统界面,也可以...
  • react后台管理项目

    千次阅读 多人点赞 2021-08-19 22:03:14
    git管理项目4. 创建项目的基本结构5 引入antd6. 引入路由7. Login的静态组件8. 收集表单数据和表单的前台验证9. 高阶函数与高阶组件day021. 后台应用2. 编写ajax代码3. 实现登陆(包含自动登陆)4. 搭建admin的整体...

    文章目录

    介绍

    几天时间按照尚硅谷提供的资源做了一个后台管理的项目,放到gitee上了:

    https://gitee.com/aniu251700/react-admin

    熟练了部分常用的react语法,还有用到了redux状态管理,大致效果如下:

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    day01

    1. 项目开发准备

    1). 描述项目
    2). 技术选型 
    3). API接口/接口文档/测试接口
    

    2. 启动项目开发

    1). 使用react脚手架创建项目
    2). 开发环境运行: npm start
    3). 生产环境打包运行: npm run build   serve build
    

    3. git管理项目

    1). 创建远程仓库
    2). 创建本地仓库
        a. 配置.gitignore
        b. git init
        c. git add .
        d. git commit -m "init"
    3). 将本地仓库推送到远程仓库
        git remote add origin url
        git push origin master
    4). 在本地创建dev分支, 并推送到远程
        git checkout -b dev
        git push origin dev
    5). 如果本地有修改
        git add .
        git commit -m "xxx"
        git push origin dev
    6). 新的同事: 克隆仓库
        git clone url
        git checkout -b dev origin/dev
        git pull origin dev
    7). 如果远程修改
        git pull origin dev
    

    4. 创建项目的基本结构

    api: ajax请求的模块
    components: 非路由组件
    pages: 路由组件
    App.js: 应用的根组件
    index.js: 入口js
    

    5 引入antd

    下载antd的包
    按需打包: 只打包import引入组件的js/css
        下载工具包
        config-overrides.js
        package.json
    自定义主题
        下载工具包
        config-overrides.js
    使用antd的组件
        根据antd的文档编写
    

    6. 引入路由

    下载包: react-router-dom
    拆分应用路由:
      Login: 登陆
      Admin: 后台管理界面
    注册路由:
      <BrowserRouter>
      <Switch>
      <Route path='' component={}/>
    

    7. Login的静态组件

    1). 自定义了一部分样式布局
    2). 使用antd的组件实现登陆表单界面
      Form  / Form.Item
      Input
      Icon
      Button
    

    8. 收集表单数据和表单的前台验证

    1). form对象
        如何让包含<Form>的组件得到form对象?  WrapLoginForm = Form.create()(LoginForm)
        WrapLoginForm是LoginForm的父组件, 它给LoginForm传入form属性
        用到了高阶函数和高阶组件的技术
    2). 操作表单数据
        form.getFieldDecorator('标识名称', {initialValue: 初始值, rules: []})(<Input/>)包装表单项组件标签
        form.getFieldsValue(): 得到包含所有输入数据的对象
        form.getFieldValue(id): 根据标识得到对应字段输入的数据
    
    3). 前台表单验证
        a. 声明式实时表单验证:
            form.getFieldDecorator('标识名称', {rules: [{min: 4, message: '错误提示信息'}]})(<Input/>)
        b. 自定义表单验证
            form.getFieldDecorator('标识名称', {rules: [{validator: this.validatePwd}]})(<Input/>)
            validatePwd = (rule, value, callback) => {
              if(有问题) callback('错误提示信息') else callack()
            } 
        c. 点击提示时统一验证
            form.validateFields((error, values) => {
              if(!error) {通过了验证, 发送ajax请求}
            })
    

    9. 高阶函数与高阶组件

    1. 高阶函数    1). 一类特别的函数        a. 接受函数类型的参数        b. 返回值是函数    2). 常见        a. 定时器: setTimeout()/setInterval()        b. Promise: Promise(() => {}) then(value => {}, reason => {})        c. 数组遍历相关的方法: forEach()/filter()/map()/reduce()/find()/findIndex()        d. 函数对象的bind()        e. Form.create()() / getFieldDecorator()()    3). 高阶函数更新动态, 更加具有扩展性2. 高阶组件    1). 本质就是一个函数    2). 接收一个组件(被包装组件), 返回一个新的组件(包装组件), 包装组件会向被包装组件传入特定属性    3). 作用: 扩展组件的功能    3. 高阶组件与高阶函数的关系    高阶组件是特别的高阶函数    接收一个组件函数, 返回是一个新的组件函数
    

    day02

    1. 后台应用

    启动后台应用: mongodb服务必须启动使用postman测试接口(根据接口文档):    访问测试: post请求的参数在body中设置    保存测试接口    导出/导入所有测试接口
    

    2. 编写ajax代码

    1). ajax请求函数模块: api/ajax.js    封装axios + Promise    函数的返回值是promise对象  ===> 后面用上async/await    自己创建Promise      1. 内部统一处理请求异常: 外部的调用都不用使用try..catch来处理请求异常      2. 异步返回是响应数据(而不是响应对象): 外部的调用异步得到的就直接是数据了(response --> response.data)2). 接口请求函数模块: api/index.js    根据接口文档编写(一定要具备这个能力)    接口请求函数: 使用ajax(), 返回值promise对象3). 解决ajax跨域请求问题(开发时)    办法: 配置代理  ==> 只能解决开发环境    编码: package.json: proxy: "http://localhost:5000"4). 对代理的理解    1). 是什么?        具有特定功能的程序    2). 运行在哪?        前台应用端        只能在开发时使用    3). 作用?        解决开发时的ajax请求跨域问题        a. 监视并拦截请求(3000)        b. 转发请求(4000)    4). 配置代理        告诉代理服务器一些信息: 比如转发的目标地址        开发环境: 前端工程师        生产环境: 后端工程师5). async和await    a. 作用?       简化promise对象的使用: 不用再使用then()来指定成功/失败的回调函数       以同步编码(没有回调函数了)方式实现异步流程    b. 哪里写await?        在返回promise的表达式左侧写await: 不想要promise, 想要promise异步执行的成功的value数据    c. 哪里写async?        await所在函数(最近的)定义的左侧写async
    

    3. 实现登陆(包含自动登陆)

    login.jsx    1). 调用登陆的接口请求    2). 如果失败, 显示错误提示信息    3). 如果成功了:        保存user到local/内存中        跳转到admin    4). 如果内存中的user有值, 自动跳转到adminsrc/index.js    读取local中user到内存中保存admin.jsx    判断如果内存中没有user(_id没有值), 自动跳转到loginstorageUtils.js    包含使用localStorage来保存user相关操作的工具模块    使用第三库store        简化编码        兼容不同的浏览器memoryUtils.js    用来在内存中保存数据(user)的工具类
    

    4. 搭建admin的整体界面结构

    1). 整体布局使用antd的Layout组件2). 拆分组件    LeftNav: 左侧导航    Header: 右侧头部3). 子路由    定义路由组件    注册路由
    

    5. LeftNav组件

    1). 使用antd的组件    Menu / Item / SubMenu2). 使用react-router    withRouter(): 包装非路由组件, 给其传入history/location/match属性    history: push()/replace()/goBack()    location: pathname属性    match: params属性3). componentWillMount与componentDidMount的比较    componentWillMount: 在第一次render()前调用一次, 为第一次render()准备数据(同步)    componentDidMount: 在第一次render()之后调用一次, 启动异步任务, 后面异步更新状态重新render4). 根据动态生成Item和SubMenu的数组    map() + 递归: 多级菜单列表    reduce() + 递归: 多级菜单列表5). 2个问题?    刷新时如何选中对应的菜单项?        selectedKey是当前请求的path    刷新子菜单路径时, 自动打开子菜单列表?        openKey是 一级列表项的某个子菜单项是当前对应的菜单项
    

    day03

    1. Header组件

    1). 界面静态布局    三角形效果2). 获取登陆用户的名称显示    MemoryUtils3). 当前时间    循环定时器, 每隔1s更新当前时间状态    格式化指定时间: dateUtils4). 天气预报    使用jsonp库发jsonp请求百度天气预报接口    对jsonp请求的理解5). 当前导航项的标题    得到当前请求的路由path: withRouter()包装非路由组件    根据path在menuList中遍历查找对应的item的title6). 退出登陆    Modal组件显示提示    清除保存的user    跳转到login7). 抽取通用的类链接按钮组件    通过...透传所有接收的属性: <Button {...props} />    <LinkButton>xxxx</LinkButton>    组件标签的所有子节点都会成为组件的children属性
    

    2. jsonp解决ajax跨域的原理

    1). jsonp只能解决GET类型的ajax请求跨域问题2). jsonp请求不是ajax请求, 而是一般的get请求3). 基本原理    浏览器端:        动态生成<script>来请求后台接口(src就是接口的url)        定义好用于接收响应数据的函数(fn), 并将函数名通过请求参数提交给后台(如: callback=fn)    服务器端:        接收到请求处理产生结果数据后, 返回一个函数调用的js代码, 并将结果数据作为实参传入函数调用    浏览器端:        收到响应自动执行函数调用的js代码, 也就执行了提前定义好的回调函数, 并得到了需要的结果数据
    

    day04: Category组件

    1. 使用antd组件构建分类列表界面

    CardTableButtonIcon
    

    2. 相关接口请求函数

    获取一级/二级分类列表添加分类更新分类
    

    3. 异步显示一级分类列表

    设计一级分类列表的状态: categorys异步获取一级分类列表: componentDidMount(){}更新状态, 显示
    

    4. 显示二级分类列表

    设计状态: subCategorys / parentId / parentName显示二级分类列表: 根据parentId状态值, 异步获取分类列表setState()的问题    setState()更新状态是异步更新的, 直接读取状态值还是旧的状态值    setState({}, [callback]), 回调函数是在状态更新且界面更新之后执行, 可以在此获取最新的状态
    

    5. 更新分类

    1). 界面    antd组件: Modal, Form, Input    显示/隐藏: showStatus状态为2/0    2). 功能    父组(Category)件得到子组件(AddForm)的数据(form)    调用更新分类的接口    重新获取分类列表
    

    day05

    1. 添加分类

    1). 界面    antd组件: Modal, Form, Select, Input    显示/隐藏: showStatus状态为1/0    2). 功能    父组(Category)件得到子组件(AddForm)的数据(form)    调用添加分类的接口    重新获取分类列表
    

    2. Product整体路由

    1). 配置子路由:     ProductHome / ProductDetail / ProductAddUpdate    <Route> / <Switch> / <Redirect>2). 匹配路由的逻辑:    默认: 逐层匹配   <Route path='/product' component={ProductHome}/>    exact属性: 完全匹配
    

    3. 分页实现技术(2种)

    1). 前台分页    请求获取数据: 一次获取所有数据, 翻页时不需要再发请求    请求接口:         不需要指定请求参数: 页码(pageNum)和每页数量(pageSize)        响应数据: 所有数据的数组2). 基于后台的分页    请求获取数据: 每次只获取当前页的数据, 翻页时要发请求    请求接口:         需要指定请求参数: 页码(pageNum)和每页数量(pageSize)        响应数据: 当前页数据的数组 + 总记录数(total)3). 如何选择?    基本根据数据多少来选择
    

    4. ProductHome组件

    1). 分页显示   界面: <Card> / <Table> / Select / Icon / Input / Button   状态: products / total   接口请求函数需要的数据: pageNum, pageSize   异步获取第一页数据显示       调用分页的接口请求函数, 获取到当前页的products和总记录数total       更新状态: products / total   翻页:       绑定翻页的监听, 监听回调需要得到pageNum       异步获取指定页码的数据显示   2). 搜索分页   接口请求函数需要的数据:        pageSize: 每页的条目数       pageNum: 当前请求第几页 (从1开始)       productDesc / productName: searchName 根据商品描述/名称搜索   状态:  searchType / searchName  / 在用户操作时实时收集数据   异步搜索显示分页列表       如果searchName有值, 调用搜索的接口请求函数获取数据并更新状态       3). 更新商品的状态   初始显示: 根据product的status属性来显示  status = 1/2   点击切换:       绑定点击监听       异步请求更新状态4). 进入详情界面   history.push('/product/detail', {product})5). 进入添加界面    history.push('/product/addupdate')
    

    5. ProductDetail组件

    1). 读取商品数据: this.props.location.state.product2). 显示商品信息: <Card> / List 3). 异步显示商品所属分类的名称    pCategoryId==0 : 异步获取categoryId的分类名称    pCategoryId!=0: 异步获取 pCategoryId/categoryId的分类名称4). Promise.all([promise1, promise2])    返回值是promise    异步得到的是所有promsie的结果的数组    特点: 一次发多个请求, 只有当所有请求都成功, 才成功, 并得到成功的数据,一旦有一个失败, 整个都失败
    

    day06

    1. ProductAddUpdate

    1). 基本界面    Card / Form / Input / TextArea / Button    FormItem的label标题和layout    2). 分类的级联列表    Cascader的基本使用    异步获取一级分类列表, 生成一级分类options    如果当前是更新二级分类的商品, 异步获取对应的二级分类列表, 生成二级分类options, 并添加为对应option的children    async函数返回值是一个新promise对象, promise的结果和值由async函数的结果决定    当选择某个一级分类项时, 异步获取对应的二级分类列表, 生成二级分类options, 并添加为当前option的children3). 表单数据收集与表单验证
    

    2. PicturesWall

    1). antd组件    Upload / Modal / Icon    根据示例DEMO改造编写2). 上传图片    在<Upload>上配置接口的path和请求参数名    监视文件状态的改变: 上传中 / 上传完成/ 删除    在上传成功时, 保存好相关信息: name / url    为父组件提供获取已上传图片文件名数组的方法3). 删除图片    当文件状态变为删除时, 调用删除图片的接口删除上传到后台的图片4). 父组件调用子组件对象的方法: 使用ref技术    1. 创建ref容器: thi.pw = React.createRef()    2. 将ref容器交给需要获取的标签元素: <PicturesWall ref={this.pw} />  // 自动将将标签对象添加为pw对象的current属性    3. 通过ref容器读取标签元素: this.pw.current
    

    day07

    1. RichTextEditor

    1). 使用基于react的富文本编程器插件库: react-draft-wysiwyg2). 参考库的DEMO和API文档编写3). 如果还有不确定的, 百度搜索, 指定相对准确的关键字
    

    2. 完成商品添加与修改功能

    1). 收集输入数据    通过form收集: name/desc/price/pCategoryId/categoryId    通过ref收集: imgs/detail    如果是更新收集: _id    将收集数据封装成product对象2). 更新商品    定义添加和更新的接口请求函数    调用接口请求函数, 如果成功并返回商品列表界面
    

    3. 角色管理

    1). 角色前台分页显示2). 添加角色3). 给指定角色授权    界面: Tree    状态: checkedKeys, 根据传入的role的menus进行初始化    勾选某个Node时, 更新checkedKeys    点击OK时: 通过ref读取到子组件中的checkedKeys作为要更新product新的menus            发请求更新product    解决默认勾选不正常的bug: 利用组件的componentWillReceiveProps()
    

    day08

    1. setState()的使用

    1). setState(updater, [callback]),    updater为返回stateChange对象的函数: (state, props) => stateChange    接收的state和props被保证为最新的2). setState(stateChange, [callback])    stateChange为对象,    callback是可选的回调函数, 在状态更新且界面更新后才执行3). 总结:    对象方式是函数方式的简写方式        如果新状态不依赖于原状态 ===> 使用对象方式        如果新状态依赖于原状态 ===> 使用函数方式    如果需要在setState()后获取最新的状态数据, 在第二个callback函数中读取
    

    2. setState()的异步与同步

    1). setState()更新状态是异步还是同步的?    a. 执行setState()的位置?        在react控制的回调函数中: 生命周期勾子 / react事件监听回调        非react控制的异步回调函数中: 定时器回调 / 原生事件监听回调 / promise回调 /...    b. 异步 OR 同步?        react相关回调中: 异步        其它异步回调中: 同步2). 关于异步的setState()    a. 多次调用, 如何处理?        setState({}): 合并更新一次状态, 只调用一次render()更新界面 ---状态更新和界面更新都合并了        setState(fn): 更新多次状态, 但只调用一次render()更新界面  ---状态更新没有合并, 但界面更新合并了    b. 如何得到异步更新后的状态数据?        在setState()的callback回调函数中
    

    3. Component与PureComponent

    1). Component存在的问题?    a. 父组件重新render(), 当前组件也会重新执行render(), 即使没有任何变化    b. 当前组件setState(), 重新执行render(), 即使state没有任何变化  2). 解决Component存在的问题    a. 原因: 组件的shouldcomponentUpdate()默认返回true, 即使数据没有变化render()都会重新执行    b. 办法1: 重写shouldComponentUpdate(), 判断如果数据有变化返回true, 否则返回false    c. 办法2: 使用PureComponent代替Component    d. 说明: 一般都使用PureComponent来优化组件性能  3). PureComponent的基本原理    a. 重写实现shouldComponentUpdate()    b. 对组件的新/旧state和props中的数据进行浅比较, 如果都没有变化, 返回false, 否则返回true    c. 一旦componentShouldUpdate()返回false不再执行用于更新的render()  4). 面试题:    组件的哪个生命周期勾子能实现组件优化?    PureComponent的原理?    区别Component与PureComponent?
    

    4. 用户管理

    1). 显示用户分页列表2). 添加用户3). 修改用户4). 删除用户
    

    5. 导航菜单权限控制

    1). 基本思路(依赖于后台):     角色: 包含所拥有权限的所有菜单项key的数组: menus=[key1, key2, key3]    用户: 包含所属角色的ID: role_id    当前登陆用户: user中已经包含了所属role对象    遍历显示菜单项时: 判断只有当有对应的权限才显示2). 判断是否有权限的条件?    a. 如果当前用户是admin    b. 如果当前item是公开的    c. 当前用户有此item的权限: key有没有menus中    d. 如果当前用户有此item的某个子item的权限
    

    day09

    1. redux理解

    什么?: redux是专门做状态管理的独立第3方库, 不是react插件, 但一般都用在react项目中作用?: 对应用中状态进行集中式的管理(写/读)开发: 与react-redux, redux-thunk等插件配合使用
    

    2. redux相关API

    redux中包含: createStore(), applyMiddleware(), combineReducers()store对象: getState(), dispatch(), subscribe()react-redux: 	<Provider store={store}>: 向所有的容器组件提供store	connect(		state => ({xxx: state.xxx}),		{actionCreator1, actionCreator2}	)(UI组件): 		产生的就是容器组件, 负责向UI组件传递标签属性, 		一般属性值从state中获取, 函数属性内部会执行dispatch分发action
    

    3. redux核心概念(3个)

    action: 	默认是对象(同步action), {type: 'xxx', data: value}, 需要通过对应的actionCreator产生, 	它的值也可以是函数(异步action), 需要引入redux-thunk才可以reducer	根据老的state和指定的action, 返回一个新的state	不能修改老的statestore	redux最核心的管理对象	内部管理着: state和reducer	提供方法: getState(), dispatch(action), subscribe(listener)
    

    4. redux工作流程

    5. 使用redux及相关库编码

    需要引入的库: 	redux	react-redux	redux-thunk	redux-devtools-extension(这个只在开发时需要)redux文件夹: 	action-types.js	actions.js	reducers.js	store.js组件分2类: 	ui组件(components): 不使用redux相关API	容器组件(containers): 通过connect()()生成的组件
    

    day10

    1. 在项目中搭建redux整套环境

    1). store.js2). reducer.js3). actions.js4). action-types.js5). index.js6). 在需要与redux进行状态数据通信(读/写)的UI组件包装生成容器组件
    

    2. 通过redux管理头部标题headTitle数据

    1). action-types.js2). actoins.js3). reducer.js4). 相关组件:     left-nav.js    header.js
    

    3. 通过redux管理登陆用户信息user数据

    1). action-types.js2). actoin.js3). reducer.js4). 相关组件:     login.js    admin.js    left-nav.js    header.js    role.js
    

    4. 自定义redux库

    1). redux库向外暴露下面几个函数    createStore(): 接收的参数为reducer函数, 返回为store对象    combineReducers(): 接收包含n个reducer方法的对象, 返回一个新的reducer函数    applyMiddleware() // 暂不实现2). store对象的内部结构    getState(): 返回值为内部保存的state数据    dispatch(): 参数为action对象    subscribe(): 参数为监听内部state更新的回调函数3). combineReducers函数:    返回的总reducer函数内部会根据总的state和指定的action,     调用每个reducer函数得到对应的新的state, 并封装成一个新的总state对象返回
    

    5. 自定义react-redux库

    1). react-redux向外暴露了2个API    a. Provider组件类    b. connect函数2). Provider组件    接收store属性    通过context将store暴露给所有的容器子组件    Provider原样渲染其所有标签子节点    3). connect函数    接收2个参数: mapStateToProps和mapDispatchToProps    connect()执行的返回值为一个高阶组件: 包装UI组件, 返回一个新的容器组件    mapStateToProps:         为一个函数, 返回包含n个一般属性对象,         容器组件中调用得到对象后, 初始化为容器组件的初始状态, 并指定为UI组件标签的一般属性    mapDispatchToProps:        如果为函数, 调用得到包含n个dispatch方法的对象        如果为对象, 遍历封装成包含n个dispatch方法的对象        将包含n个dispatch方法的对象分别作为函数属性传入UI组件    通过store绑定state变化的监听, 在回调函数中根据store中最新的state数据更新容器组件状态, 从而更新UI组件
    

    day11

    1. 数据可视化

    1). echarts(百度) ==> echarts-for-react2). g2(阿里) ==> bizCharts3). d3(国外)
    

    2. 前台404界面

    <Redirect from='/' to='/home' exact/><Route component={NotFound}/>
    

    3. 打包应用运行

    1). 解决生产环境ajax跨域问题    使用nginx的反向代理解决(一般由后台配置)    CORS: 允许浏览器端跨域2). BrowserRouter模式刷新404的问题    a. 问题: 刷新某个路由路径时, 会出现404的错误    b. 原因: 项目根路径后的path路径会被当作后台路由路径, 去请求对应的后台路由, 但没有    c. 解决: 使用自定义中间件去读取返回index页面展现
    

    接口文档

    目录:

    1). 登陆
    2). 添加用户
    3). 更新用户
    4). 获取所有用户列表
    5). 删除用户
    6). 获取一级或某个二级分类列表
    7). 添加分类
    8). 更新品类名称
    9). 根据分类ID获取分类
    10). 获取商品分页列表
    11). 根据ID/Name搜索产品分页列表
    12). 添加商品
    13). 更新商品
    14). 对商品进行上架/下架处理
    15). 上传图片
    16). 删除图片
    17). 添加角色
    18). 获取角色列表
    19). 更新角色(给角色设置权限)
    20). 获取天气信息(支持jsonp)
    

    1. 登陆

    请求URL:

    http://localhost:5000/login
    

    请求方式:

    POST
    

    参数类型

    |参数		|是否必选 |类型     |说明
    |username    |Y       |string   |用户名
    |password    |Y       |string   |密码
    

    返回示例:

    成功:
      {
        "status": 0,
        "data": {
          "_id": "5c3b297dea95883f340178b0",
          "password": "21232f297a57a5a743894a0e4a801fc3",
          "username": "admin",
          "create_time": 1547381117891,
          "__v": 0,
          "role": {
            "menus": []
          }
        }
      }
    失败
      {
        "status": 1,
        "msg": "用户名或密码不正确!"
      }
    

    2. 添加用户

    请求URL:

    http://localhost:5000/manage/user/add
    

    请求方式:

    POST
    

    参数类型

    |参数		|是否必选 |类型     |说明
    |username    |Y       |string   |用户名
    |password    |Y       |string   |密码
    |phone       |N       |string   |手机号
    |email       |N       |string   |邮箱
    |role_id     |N       |string   |角色ID
    

    返回示例:

    成功:
      {
        "status": 0,
        "data": {
          "_id": "5c3b382c82a14446f4ffb647",
          "username": "admin6",
          "password": "d7b79bb6d6f77e6cbb5df2d0d2478361",
          "phone": "13712341234",
          "email": "test@qq.com",
          "create_time": 1547384876804,
          "__v": 0
        }
      }
    失败
      {
        "status": 1,
        "msg": "此用户已存在"
      }
    

    3. 更新用户

    请求URL:

    http://localhost:5000/manage/user/update
    

    请求方式:

    POST
    

    参数类型

    |参数		|是否必选 |类型     |说明
    |_id         |Y       |string   |ID
    |username    |N       |string   |用户名
    |phone       |N       |string   |手机号
    |email       |N       |string   |邮箱
    |role_id     |N       |string   |角色ID
    

    返回示例:

    成功:
      {
        "status": 0,
        "data": {
          "_id": "5c3b382c82a14446f4ffb647",
          "username": "admin6",
          "password": "d7b79bb6d6f77e6cbb5df2d0d2478361",
          "phone": "13712341234",
          "email": "test@qq.com",
          "create_time": 1547384876804,
          "__v": 0
        }
      }
    失败
      {
        "status": 1,
        "msg": "此用户已存在"
      }
    

    4. 获取所有用户列表

    请求URL:

    http://localhost:5000/manage/user/list
    

    请求方式:

    GET
    

    参数类型:

    返回示例:

    {
      "status": 0,
      "data": {
        "users": [
          {
            "_id": "5cb05b4db6ed8c44f42c9af2",
            "username": "test",
            "password": "202cb962ac59075b964b07152d234b70",
            "phone": "123412342134",
            "email": "sd",
            "role_id": "5ca9eab0b49ef916541160d4",
            "create_time": 1555061581734,
            "__v": 0
          },
          {
            "_id": "5cb05b69b6ed8c44f42c9af3",
            "username": "ss22",
            "password": "123",
            "phone": "23343",
            "email": "df",
            "role_id": "5caf5444c61376319cef80a8",
            "create_time": 1555061609666,
            "__v": 0
          }
        ],
        "roles": [
          {
            "menus": [
              "/home",
              "/role",
              "/category",
              "/products",
              "/product",
              "/charts/bar"
            ],
            "_id": "5ca9eaa1b49ef916541160d3",
            "name": "测试",
            "create_time": 1554639521749,
            "__v": 0,
            "auth_time": 1555145863489,
            "auth_name": "admin"
          }
        ]
      }
    }
    

    5. 删除用户

    请求URL:

    http://localhost:5000/manage/user/delete
    

    请求方式:

    POST
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |userId     |Y       |string   |用户ID
    

    返回示例:

    {
      "status": 0
    }
    

    6. 获取一级或某个二级分类列表

    请求URL:

    http://localhost:5000/manage/category/list
    

    请求方式:

    GET
    

    参数类型: query

    |参数		|是否必选 |类型     |说明
    |parentId    |Y       |string   |父级分类的ID
    

    返回示例:

    一级分类:
      {
        "status": 0,
        "data": [
          {
            "parentId": "0",
            "_id": "5c2ed631f352726338607046",
            "name": "分类001",
            "__v": 0
          },
          {
            "parentId": "0",
            "_id": "5c2ed647f352726338607047",
            "name": "分类2",
            "__v": 0
          },
          {
            "parentId": "0",
            "_id": "5c2ed64cf352726338607048",
            "name": "1分类3",
            "__v": 0
          }
        ]
      }
    二级分类
      {
        "status": 0,
        "data": [
          {
            "parentId": "5c2ed64cf352726338607048",
            "_id": "5c2ed65df352726338607049",
            "name": "分类3333",
            "__v": 0
          },
          {
            "parentId": "5c2ed64cf352726338607048",
            "_id": "5c2ed66ff35272633860704a",
            "name": "分类34",
            "__v": 0
          }
        ]
      }
    

    7. 添加分类

    请求URL:

    http://localhost:5000/manage/category/add
    

    请求方式:

    POST
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |parentId      |Y       |string   |父级分类的ID
    |categoryName  |Y       |string   |名称
    

    返回示例:

    添加一级分类:
        {
          "status": 0,
          "data": {
            "parentId": "0",
            "_id": "5c3ec1534594a00e5877b841",
            "name": "分类9",
            "__v": 0
          }
        }
    添加二级分类
        {
          "status": 0,
          "data": {
            "parentId": "5c2ed64cf352726338607048",
            "_id": "5c3ec1814594a00e5877b842",
            "name": "分类39",
            "__v": 0
          }
        }
    

    8. 更新品类名称

    请求URL:

    http://localhost:5000/manage/category/update
    

    请求方式:

    POST
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |categoryId    |Y       |string   |父级分类的ID
    |categoryName  |Y       |string   |名称
    

    返回示例:

    {
      "status": 0
    }
    

    9. 根据分类ID获取分类

    请求URL:

    http://localhost:5000/manage/category/info
    

    请求方式:

    GET
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |categoryId    |Y       |string   |父级分类的ID
    

    返回示例:

    {
      "status": 0,
      "data": {
        "parentId": "0",
        "_id": "5c2ed631f352726338607046",
        "name": "分类001",
        "__v": 0
      }
    }
    

    10. 获取商品分页列表

    请求URL:

    http://localhost:5000/manage/product/list
    

    请求方式:

    GET
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |pageNum    |Y       |Number   |页码
    |pageSize   |Y       |Number   |每页条目数
    

    返回示例:

    {
        "status": 0,
        "data": {
            "pageNum": 1,
            "total": 12,
            "pages": 3,
            "pageSize": 5,
            "list": [
                {
                    "status": 1,
                    "imgs": [
                        "image-1559402396338.jpg"
                    ],
                    "_id": "5ca9e05db49ef916541160cd",
                    "name": "联想ThinkPad 翼4809",
                    "desc": "年度重量级新品,X390、T490全新登场 更加轻薄机身设计9",
                    "price": 65999,
                    "pCategoryId": "5ca9d6c0b49ef916541160bb",
                    "categoryId": "5ca9db9fb49ef916541160cc",
                    "detail": "<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;\">想你所需,超你所想!精致外观,轻薄便携带光驱,内置正版office杜绝盗版死机,全国联保两年!</span> 222</p>\n<p><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">联想(Lenovo)扬天V110 15.6英寸家用轻薄便携商务办公手提笔记本电脑 定制【E2-9010/4G/128G固态】 2G独显 内置</span></p>\n<p><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">99999</span></p>\n",
                    "__v": 0
                },
                {
                    "status": 1,
                    "imgs": [
                        "image-1559402448049.jpg",
                        "image-1559402450480.jpg"
                    ],
                    "_id": "5ca9e414b49ef916541160ce",
                    "name": "华硕(ASUS) 飞行堡垒",
                    "desc": "15.6英寸窄边框游戏笔记本电脑(i7-8750H 8G 256GSSD+1T GTX1050Ti 4G IPS)",
                    "price": 6799,
                    "pCategoryId": "5ca9d6c0b49ef916541160bb",
                    "categoryId": "5ca9db8ab49ef916541160cb",
                    "detail": "<p><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">华硕(ASUS) 飞行堡垒6 15.6英寸窄边框游戏笔记本电脑(i7-8750H 8G 256GSSD+1T GTX1050Ti 4G IPS)火陨红黑</span>&nbsp;</p>\n<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;\">【4.6-4.7号华硕集体放价,大牌够品质!】1T+256G高速存储组合!超窄边框视野无阻,强劲散热一键启动!</span>&nbsp;</p>\n",
                    "__v": 0
                },
                {
                    "status": 2,
                    "imgs": [
                        "image-1559402436395.jpg"
                    ],
                    "_id": "5ca9e4b7b49ef916541160cf",
                    "name": "你不知道的JS(上卷)",
                    "desc": "图灵程序设计丛书: [You Don't Know JS:Scope & Closures] JavaScript开发经典入门图书 打通JavaScript的任督二脉",
                    "price": 35,
                    "pCategoryId": "0",
                    "categoryId": "5ca9d6c9b49ef916541160bc",
                    "detail": "<p style=\"text-align:start;\"><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">图灵程序设计丛书:你不知道的JavaScript(上卷)</span> <span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\"><strong>[You Don't Know JS:Scope &amp; Closures]</strong></span></p>\n<p style=\"text-align:start;\"><span style=\"color: rgb(227,57,60);background-color: rgb(255,255,255);font-size: 12px;\">JavaScript开发经典入门图书 打通JavaScript的任督二脉 领略语言内部的绝美风光</span>&nbsp;</p>\n",
                    "__v": 0
                },
                {
                    "status": 2,
                    "imgs": [
                        "image-1554638240202.jpg"
                    ],
                    "_id": "5ca9e5bbb49ef916541160d0",
                    "name": "美的(Midea) 213升-BCD-213TM",
                    "desc": "爆款直降!大容量三口之家优选! *节能养鲜,自动低温补偿,36分贝静音呵护",
                    "price": 1388,
                    "pCategoryId": "5ca9d695b49ef916541160ba",
                    "categoryId": "5ca9d9cfb49ef916541160c4",
                    "detail": "<p style=\"text-align:start;\"><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;font-family: Arial, \"microsoft yahei;\">美的(Midea) 213升 节能静音家用三门小冰箱 阳光米 BCD-213TM(E)</span></p>\n<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;font-family: tahoma, arial, \"Microsoft YaHei\", \"Hiragino Sans GB\", u5b8bu4f53, sans-serif;\">【4.8美的大牌秒杀日】爆款直降!大容量三口之家优选! *节能养鲜,自动低温补偿,36分贝静音呵护! *每天不到一度电,省钱又省心!</span>&nbsp;</p>\n",
                    "__v": 0
                },
                {
                    "status": 1,
                    "imgs": [
                        "image-1554638403550.jpg"
                    ],
                    "_id": "5ca9e653b49ef916541160d1",
                    "name": "美的(Midea)KFR-35GW/WDAA3",
                    "desc": "正1.5匹 变频 智弧 冷暖 智能壁挂式卧室空调挂机",
                    "price": 2499,
                    "pCategoryId": "5ca9d695b49ef916541160ba",
                    "categoryId": "5ca9da1ab49ef916541160c6",
                    "detail": "<p style=\"text-align:start;\"><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">美的(Midea)正1.5匹 变频 智弧 冷暖 智能壁挂式卧室空调挂机 KFR-35GW/WDAA3@</span></p>\n<p style=\"text-align:start;\"></p>\n<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;\">【4.8美的大牌秒杀日】提前加入购物车!2299元成交价!前50名下单送赠品加湿型电风扇,赠完即止!8日0点开抢!</span><a href=\"https://sale.jd.com/mall/LKHdqZUIYk.html\" target=\"_blank\"><span style=\"color: rgb(94,105,173);background-color: rgb(255,255,255);font-size: 12px;\">更有无风感柜挂组合套购立减500元!猛戳!!</span></a>&nbsp;</p>\n",
                    "__v": 0
                }
            ]
        }
    }
    

    11. 根据ID/Name搜索产品分页列表

    请求URL:

    http://localhost:5000/manage/product/search?pageNum=1&pageSize=5&productName=T
    

    请求方式:

    GET
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |pageNum       |Y       |Number   |页码
    |pageSize      |Y       |Number   |每页条目数
    |productName   |N       |String   |根据商品名称搜索
    |productDesc   |N       |String   |根据商品描述搜索
    

    返回示例:

    {
        "status": 0,
        "data": {
            "pageNum": 1,
            "total": 3,
            "pages": 1,
            "pageSize": 5,
            "list": [
                {
                    "status": 1,
                    "imgs": [
                        "image-1559402396338.jpg"
                    ],
                    "_id": "5ca9e05db49ef916541160cd",
                    "name": "联想ThinkPad 翼4809",
                    "desc": "年度重量级新品,X390、T490全新登场 更加轻薄机身设计9",
                    "price": 65999,
                    "pCategoryId": "5ca9d6c0b49ef916541160bb",
                    "categoryId": "5ca9db9fb49ef916541160cc",
                    "detail": "<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;\">想你所需,超你所想!精致外观,轻薄便携带光驱,内置正版office杜绝盗版死机,全国联保两年!</span> 222</p>\n<p><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">联想(Lenovo)扬天V110 15.6英寸家用轻薄便携商务办公手提笔记本电脑 定制【E2-9010/4G/128G固态】 2G独显 内置</span></p>\n<p><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;\">99999</span></p>\n",
                    "__v": 0
                },
                {
                    "status": 2,
                    "imgs": [
                        "image-1554638240202.jpg"
                    ],
                    "_id": "5ca9e5bbb49ef916541160d0",
                    "name": "美的(Midea) 213升-BCD-213TM",
                    "desc": "爆款直降!大容量三口之家优选! *节能养鲜,自动低温补偿,36分贝静音呵护",
                    "price": 1388,
                    "pCategoryId": "5ca9d695b49ef916541160ba",
                    "categoryId": "5ca9d9cfb49ef916541160c4",
                    "detail": "<p style=\"text-align:start;\"><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;font-family: Arial, \"microsoft yahei;\">美的(Midea) 213升 节能静音家用三门小冰箱 阳光米 BCD-213TM(E)</span></p>\n<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;font-family: tahoma, arial, \"Microsoft YaHei\", \"Hiragino Sans GB\", u5b8bu4f53, sans-serif;\">【4.8美的大牌秒杀日】爆款直降!大容量三口之家优选! *节能养鲜,自动低温补偿,36分贝静音呵护! *每天不到一度电,省钱又省心!</span>&nbsp;</p>\n",
                    "__v": 0
                },
                {
                    "status": 1,
                    "imgs": [
                        "image-1554638676149.jpg",
                        "image-1554638683746.jpg"
                    ],
                    "_id": "5ca9e773b49ef916541160d2",
                    "name": "联想ThinkPad X1 Carbon",
                    "desc": "英特尔酷睿i5 14英寸轻薄笔记本电脑(i5-8250U 8G 256GSSD FHD)黑色",
                    "price": 9999,
                    "pCategoryId": "5ca9d6c0b49ef916541160bb",
                    "categoryId": "5ca9db78b49ef916541160ca",
                    "detail": "<p style=\"text-align:start;\"><span style=\"color: rgb(102,102,102);background-color: rgb(255,255,255);font-size: 16px;font-family: Arial, \"microsoft yahei;\">联想ThinkPad X1 Carbon 2018(09CD)英特尔酷睿i5 14英寸轻薄笔记本电脑(i5-8250U 8G 256GSSD FHD)黑色</span></p>\n<p><span style=\"color: rgb(228,57,60);background-color: rgb(255,255,255);font-size: 12px;font-family: tahoma, arial, \"Microsoft YaHei\", \"Hiragino Sans GB\", u5b8bu4f53, sans-serif;\">年度重量级新品,X390、T490全新登场 更加轻薄机身设计,全面的配置升级,让工作更便捷,让生活更轻松</span><a href=\"https://pro.jd.com/mall/active/2M4o7NTzHH6jEJXS7VbpbTAANQB9/index.html\" target=\"_blank\"><span style=\"color: rgb(94,105,173);background-color: rgb(255,255,255);font-size: 12px;font-family: tahoma, arial, \"Microsoft YaHei\", \"Hiragino Sans GB\", u5b8bu4f53, sans-serif;\">4月9日京东震撼首发,火爆预约</span></a>&nbsp;</p>\n",
                    "__v": 0
                }
            ]
        }
    }
    

    12. 添加商品

    请求URL:

    http://localhost:5000/manage/product/add
    

    请求方式:

    POST
    

    参数类型:

    |参数		       |是否必选 |类型     |说明
    |categoryId    |Y       |string   |分类ID
    |pCategoryId   |Y       |string   |父分类ID
    |name          |Y       |string   |商品名称
    |desc          |N       |string   |商品描述
    |price         |N       |string   |商品价格
    |detail        |N       |string   |商品详情
    |imgs          |N       |array   |商品图片名数组
    

    返回示例:

    {
        "status": 0,
        "data": {
            "status": 1,
            "imgs": [
                "image-1559467198366.jpg"
            ],
            "_id": "5cf394d29929a304dcc0c6eb",
            "name": "商品A",
            "desc": "一个笔记本",
            "price": 11111,
            "detail": "<p><strong>abc</strong></p>\n",
            "pCategoryId": "5ca9d6c0b49ef916541160bb",
            "categoryId": "5ca9db78b49ef916541160ca",
            "__v": 0
        }
    }
    

    13. 更新商品

    请求URL:

    http://localhost:5000/manage/product/update
    

    请求方式:

    POST
    

    参数类型:

    |参数		       |是否必选 |类型     |说明
    |_id           |Y       |string   |商品ID
    |categoryId    |Y       |string   |分类ID
    |pCategoryId   |Y       |string   |父分类ID
    |name          |Y       |string   |商品名称
    |desc          |N       |string   |商品描述
    |price         |N       |string   |商品价格
    |detail        |N       |string   |商品详情
    |imgs          |N       |array   |商品图片名数组
    

    返回示例:

    {
      "status": 0
    }
    

    14. 对商品进行上架/下架处理

    请求URL:

    http://localhost:5000/manage/product/updateStatus
    

    请求方式:

    POST
    

    参数类型:

    |参数		      |是否必选 |类型     |说明
    |productId    |Y       |string   |商品名称
    |status       |Y       |number   |商品状态值
    

    返回示例:

    {
      "status": 0
    }
    

    15. 上传图片

    请求URL:

    http://localhost:5000/manage/img/upload
    

    请求方式:

    POST
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |image  |Y       |文件   |图片文件
    

    返回示例:

    {
        "status": 0,
        "data": {
            "name": "image-1559466841118.jpg",
            "url": "http://localhost:5000/upload/image-1559466841118.jpg"
        }
    }
    

    16. 删除图片

    请求URL:

    http://localhost:5000/manage/img/delete
    

    请求方式:

    POST
    

    参数类型:

    |参数		|是否必选 |类型     |说明
    |name    |Y       |string   |图片文件名
    

    返回示例:

    {
      "status": 0
    }
    

    17. 添加角色

    请求URL:

    http://localhost:5000/manage/role/add
    

    请求方式:

    POST
    

    参数类型:

    |参数		     |是否必选 |类型     |说明
    |roleName    |Y       |string   |角色名称
    

    返回示例:

    {
        "status": 0,
        "data": {
            "menus": [],
            "_id": "5cf39a319929a304dcc0c6ec",
            "name": "角色x",
            "create_time": 1559468593702,
            "__v": 0
        }
    }
    

    18. 获取角色列表

    请求URL:

    http://localhost:5000/manage/role/list
    

    请求方式:

    GET
    

    参数类型:

    返回示例:

    {
        "status": 0,
        "data": [
            {
                "menus": [
                    "/role",
                    "/charts/bar",
                    "/home",
                    "/category"
                ],
                "_id": "5ca9eaa1b49ef916541160d3",
                "name": "测试",
                "create_time": 1554639521749,
                "__v": 0,
                "auth_time": 1558679920395,
                "auth_name": "test007"
            },
            {
                "menus": [
                    "/role",
                    "/charts/bar",
                    "/home",
                    "/charts/line",
                    "/category",
                    "/product",
                    "/products"
                ],
                "_id": "5ca9eab0b49ef916541160d4",
                "name": "经理",
                "create_time": 1554639536419,
                "__v": 0,
                "auth_time": 1558506990798,
                "auth_name": "test008"
            },
            {
                "menus": [
                    "/home",
                    "/products",
                    "/category",
                    "/product",
                    "/role"
                ],
                "_id": "5ca9eac0b49ef916541160d5",
                "name": "角色1",
                "create_time": 1554639552758,
                "__v": 0,
                "auth_time": 1557630307021,
                "auth_name": "admin"
            }
        ]
    }
    

    19. 更新角色(给角色设置权限)

    请求URL:

    http://localhost:5000/manage/role/update
    

    请求方式:

    POST
    

    参数类型:

    |参数		     |是否必选  |类型     |说明
    |_id          |Y       |string   |角色ID
    |menus        |Y       |array    |权限key数组
    |auth_time    |Y       |number   |权限时间
    |auth_name    |Y       |string   |权限人姓名
    

    返回示例:

    {
        "status": 0,
        "data": {
            "menus": [
                "/role",
                "/charts/bar",
                "/home",
                "/category",
                "/user"
            ],
            "_id": "5ca9eaa1b49ef916541160d3",
            "name": "测试",
            "create_time": 1554639521749,
            "__v": 0,
            "auth_time": 1559469116470,
            "auth_name": "admin"
        }
    }
    

    20. 获取天气信息(支持jsonp)

    请求URL:

    http://api.map.baidu.com/telematics/v3/weather
    

    请求方式:

    GET
    

    参数类型:

    |参数		     |是否必选 |类型     |说明
    |location    |Y       |string   |城市名称
    |output      |Y       |string   |返回数据格式: json
    |ak          |Y       |string   |唯一的应用key(3p49MVra6urFRGOT9s8UBWr2)
    

    返回示例:

    {
      "error": 0,
      "status": "success",
      "date": "2019-06-02",
      "results": [
        {
          "currentCity": "北京",
          "pm25": "119",
          "index": [
            {
              "des": "建议着长袖T恤、衬衫加单裤等服装。年老体弱者宜着针织长袖衬衫、马甲和长裤。",
              "tipt": "穿衣指数",
              "title": "穿衣",
              "zs": "舒适"
            },
            {
              "des": "不宜洗车,未来24小时内有雨,如果在此期间洗车,雨水和路上的泥水可能会再次弄脏您的爱车。",
              "tipt": "洗车指数",
              "title": "洗车",
              "zs": "不宜"
            },
            {
              "des": "各项气象条件适宜,无明显降温过程,发生感冒机率较低。",
              "tipt": "感冒指数",
              "title": "感冒",
              "zs": "少发"
            },
            {
              "des": "天气较好,赶快投身大自然参与户外运动,尽情感受运动的快乐吧。",
              "tipt": "运动指数",
              "title": "运动",
              "zs": "适宜"
            },
            {
              "des": "紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。",
              "tipt": "紫外线强度指数",
              "title": "紫外线强度",
              "zs": "弱"
            }
          ],
          "weather_data": [
            {
              "date": "周日 06月02日 (实时:30℃)",
              "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
              "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/leizhenyu.png",
              "weather": "多云转雷阵雨",
              "wind": "西南风3-4级",
              "temperature": "31 ~ 20℃"
            },
            {
              "date": "周一",
              "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
              "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
              "weather": "多云",
              "wind": "南风微风",
              "temperature": "34 ~ 20℃"
            },
            {
              "date": "周二",
              "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/leizhenyu.png",
              "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/leizhenyu.png",
              "weather": "雷阵雨",
              "wind": "东风微风",
              "temperature": "28 ~ 21℃"
            },
            {
              "date": "周三",
              "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
              "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
              "weather": "多云",
              "wind": "北风3-4级",
              "temperature": "33 ~ 19℃"
            }
          ]
        }
      ]
    }
    
    展开全文
  • 拼西西商城后台管理系统源码(react(hook) + antd + ts) 拼西西商城后台管理系统源码(react(hook) + antd + ts) 拼西西商城后台管理系统源码(react(hook) + antd + ts) 拼西西...
  • React-后台管理系统项目实战

    千次阅读 2020-09-19 17:13:51
    模块化:模块化是一种处理复杂系统分解为更好的可管理模块的方式。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能。(描述项目的开发方式) 组件化:实现...
  • react项目 1.使用create-react-app创建基于react脚手架应用(最好精简一下脚手架) 2.引入antd,完成按需引入,自定义主题 3.login静态页面(不使用atnd的任何组件) 4.login的Form表单(不加校验,只是使用静态的...
  • 云生活超市后台管理系统——React后台项目:react react-router4 redux antd axios sass。 (另外配套两个仓库:Spring Boot服务端、 React Native App端)
  • react-antd实现的后台管理系统,有登录退出功能,登录成功后,能够在不同目录下看到各种折线图,表格,同时有上传文件的功能。登录账号:admin,密码:admin。适合需要学习react-antd的新手,或者需要完成毕设的同学...
  • ( :United_States: ) ( :China: ) English | :sparkles: 特征用于Web应用程序的企业级UI设计系统。 开箱即用的一组高质量的React组件。 用具有可预测的静态类型的TypeScript编写。 整套开发设计资源和工具。 :...
  • react的一个后台管理系统代码,包括左侧导航,各种表格展示。 如果你是初学者,那么注意以下步骤: 1. nodejs官网下载安装nodejs 2.将本资源放到nodejs的安装路径下,例如我的在D:\Program Files\nodejs\下 3.解压本...
  • 后台管理系统模板参照了vue-element-admin进行开发,包含动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。
  • 后台管理系统 启动 yarn or npm i yarn start or npm start 使用技术 react + antd design + react-route-dom 界面一览
  • React 后台管理系统

    千次阅读 2021-11-29 11:54:36
    后台管理系统 2.1、技术栈 测试接口环境:nodejs 前端: react.js redux react-redux redux-thunk react-router-dom@5 styled-components/sass(node-sass) ui组件库 ant-design Ant Design - 一套企业级 UI ...
  • React管理员react后台管理系统
  • 它在生产模式下正确捆绑了React,并优化了构建以获得最佳性能。 最小化内部版本,文件名包含哈希值。 您的应用已准备好进行部署! 有关更多信息,请参见关于的部分。yarn eject 注意:这是单向操作。 eject ,您将...
  • 您可以在本项目基础上定制自己的后台系统。 :rocket: :gem_stone:说明项目跑起来后首页有使用说明,里面有接口文档,还有添加页面,添加接口的教程。数据库文件在预算项目中。如果对您对此项目有兴趣,可以点“ Star...
  • react:后台管理系统React
  • 基于React+antd的后台管理模板
  • 硅谷教育管理系统 React项目全新升级 特性 权限管理到按钮等级 蚂蚁4.0 form组件使用React挂钩 ... 项目在线接口文档 http://47.103.203.152/docs 目前只上传客户端代码,服务器会部署上阿里云,访问地址:...
  • React 项目-后台管理系统

    千次阅读 2019-07-29 20:57:14
    React 项目-后台管理系统 尚硅谷前端研究院 第 1 章: 准备 1.1. 项目描述 1) 此项目为一个前后台分离的后台管理的 SPA, 包括前端 PC 应用和后端应用 2) 包括用户管理 / 商品分类管理 / 商品管理 / 权限...
  • react 后台管理系统解决方案
  • MybatisPlus构造器展示商品一二级目录2级...前端数组利用--分割和拼接(图片url和权限)git clone https://github.com/ctrl00100/ReactAdmin.git登陆,商品管理(一二级目录crud,商品图片oss),权限设置(侧边栏回显不完美)
  • 【开发篇】10分钟快速搭建React后台管理系统模板

    千次阅读 多人点赞 2020-09-16 10:11:59
    React后台管理系统模板 一、准备React 1.建立react应用 npx create-react-app react_management_system_template cd react_management_system_template 并对react应用进行整理,整理成如下图所示 在terminal中...
  • 创建 React 应用程序入门这个项目是用引导的。可用脚本在项目目录中,您可以运行:yarn start 在开发模式下运行应用程序。 打开在浏览器中查看。 如果您进行编辑,页面将重新加载。 您还将在控制台中看到任何 lint ...
  • 基于ThinkPHP6和React的极简后台管理系统
  • 基于React+antd写了一个后台管理模板。主要是熟悉antd组件和React,页面主要还是展示页面,比较简单不涉及后台交互的系统模板Demo

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,221
精华内容 6,088
热门标签
关键字:

react后台管理系统项目