如何从零开始搭建一套后台管理系统(带权限管理)

1、使用技术与开源项目

后端: java、springboot、mybatis、mybatis-plus
前端: vue

开源项目 名称 源码 演示地址 文档地址
CRUD框架 d2-crud-plus github 演示地址 文档地址
管理系统脚手架 d2-admin github 演示地址 文档地址
基础UI组件 element-ui github 演示地址 文档地址

2、最终成果预览

登录界面
权限资源管理
角色管理
用户管理

3、准备工作

  1. 安装git
  2. 安装nodejs
  3. 安装java
  4. 开发工具:idea、或vscode等

4、前端框架

1、搭建 d2-crud-plus 与 d2-admin 整合的启动项目

根据d2-crud-plus的文档

d2-crud-plus与d2-admin的启动项目

打开cmd,执行如下命令

# 克隆代码
git clone  https://github.com/greper/d2-crud-plus-with-d2admin-starter
# 进入项目目录
cd d2-crud-plus-with-d2admin-starter
# 安装依赖
npm install

启动项目看看效果

npm run dev

启动成功后,一个基本的前端管理框架就搭建好了,接下来我们对接后台和集成权限管理模块


成功后自动打开浏览器

5、加入权限模块

根据d2-crud-plus的文档权限管理章节一步一步照着做

1、复制权限模块代码到我们的starter项目中

d2-crud-plus-example里面带有权限模块,在/src/business/modules目录下,我们去复制过来
先clone d2-crud-plus的代码下来

git clone  https://github.com/greper/d2-crud-plus

进入 .\d2-crud-plus\packages\d2-crud-plus-example\src\business\modules 目录
permissionusersphere两个目录复制到d2-crud-plus-with-d2admin-starter项目中的/src/business/modules目录下

2、 在starter项目中的.env文件里配置VUE_APP_PM_ENABLED = true

3、 安装permission模块

// 在main.js中加入
import '@/business/modules/permission' // 加载permission
  1. /src/store/modules/d2admin/modules/account.js中加入以下代码
    用于注销时清空权限信息
    logout ({ commit, dispatch }, { confirm = false } = {}) {
      /**
       * @description 注销
       */
      async function logout () {
        // 删除cookie
        util.cookies.remove('token')
        util.cookies.remove('uuid')
        // 清空 vuex 用户信息
        await dispatch('d2admin/user/set', {}, { root: true })

        // 注销登录时清空permission信息,↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓增加这一行↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
        commit('permission/clear', true, { root: true })

        // 跳转路由
        router.push({ name: 'login' })
      }
  1. 登录请求由模拟改为请求真实后端
  SYS_USER_LOGIN (data = {}) {
    // 模拟数据
    mock
      .onAny('/login')
      .reply(config => {
        const user = find(users, tools.parse(config.data))
        return user
          ? tools.responseSuccess(assign({}, user, { token: faker.random.uuid() }))
          : tools.responseError({}, '账号或密码不正确')
      })
    // 接口请求
    return requestForMock({
      url: '/login',
      method: 'post',
      data
    })
  }

修改为如下

 SYS_USER_LOGIN (data = {}) {
    // 登录请求真实后端
    return request({
      url: '/login',   // 真实的后端地址 /api/login
      method: 'post',
      data
    })
  }
  1. 配置本地代理
    解决本地开发时请求后台接口的跨域问题
    vue.config.js中添加如下配置
module.exports = {
  publicPath,
  lintOnSave: true,
  devServer: {
    publicPath, // 和 publicPath 保持一致
    disableHostCheck: process.env.NODE_ENV === 'development', // 关闭 host check,方便使用 ngrok 之类的内网转发工具
    //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓配置如下代理↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    proxy: {
      '/api': { // 请求/api/时代理到http://localhost:7070/api这个地址上去
        target: 'http://localhost:7070',
        ws: true
      }
    }
  }
}
  1. 重新启动项目
    由于我们还没有启动后端服务,所以登录等接口都不可用
# ctrl+c 关闭,然后重新启动
npm run dev

6、启动后端

配套后端开源项目地址:d2-crud-plus-server

1.1.1 克隆项目

git clone https://github.com/greper/d2-crud-plus-server.git

在idea中打开该项目【注意: 需要安装lombok插件】

1.1.2 创建数据库

创建数据库`d2p_pm`
server启动后会自动创建表

1.1.3修改数据库连接配置

# ./api-service/src/main/resources/application.xml
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/d2p_pm?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true

1.1.4 启动api-server

右键 com\veryreader\d2p\api\ApiServerApplication.java
点击RUN

7、打开浏览器看看效果

http://localhost:8080
登录之后就可以看到权限管理模块了

image.png

8、 开发一个CRUD功能

下面将体验一下急速开发CRUD

  1. 建表
-- ----------------------------
-- 商品分类表
-- ----------------------------
CREATE TABLE `shop_category` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '分类名称',
  `code` varchar(255) DEFAULT NULL COMMENT '分类代码',
  `icon` varchar(50) DEFAULT NULL COMMENT '分类图标',
  `disabled` tinyint(1) DEFAULT NULL COMMENT '是否启用',
  `del_flag` tinyint(1) NOT NULL DEFAULT '0',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='商品分类';

  1. 根据表生成代码
    code-generator工程的CodeGeneratorApplicationTests 中添加
@Test
    void shop() {
        GenerateRequest request = GenerateRequest.builder()
                .moduleName("shop") //模块名
                .tableName("shop_category") //表名,可以传多个
                .parentPackage("com.veryreader.d2p.api.modules") //包名
                .tablePrefix("shop") //表前缀
                .apiUrlPrefix("") 
                .logicDeleteField("del_flag") //逻辑删除字段名
                .superControllerClass("com.veryreader.d2p.api.modules.base.controller.AbstractCrudController")
                .build();
        request.addFill("create_time", FieldFill.INSERT); //要自动填充的字段
        request.addFill("update_time",FieldFill.INSERT_UPDATE);//要自动填充和更新的字段
        generateService.generate(request);  //开始生成
    }
  1. 右键运行此单元测试

将在code-generagor/.generated 中生成如下代码:

image.png

将这些代码复制到相应的工程目录下,菜单的sql去数据库中执行一下

  1. 重启后端服务

  2. 重启starter 前端工程

  3. 给管理员分配权限


    image.png

修改一下菜单结构,将商城管理放到单独的顶部菜单去


image.png
  1. 重新登录
    就可以看到商品分类管理菜单啦


    image.png

现在的字段目前还都是el-input,一些不必要编辑的字段也出来了,我们接下来再修改修改。。。


image.png
  1. 修改字段类型
    修改shop/category/crud.js
 {
        title: 'ID',
        key: 'id',
        width: 100,
        form: {
          disabled: true //ID字段不参与编辑 ,
        },
        sortable: true
      },
    ...
    {
        title: '分类名称',
        key: 'name',
        sortable: true,
        form: {
          rules: [{ required: true, message: '分类名称不能为空' }] // 非空校验
        }
      },
      {
        title: '分类图标',
        key: 'icon',
        type: 'icon-selector', // 这里改成 icon-selector 类型
        sortable: true
      },
      {
        title: '是否启用',
        key: 'disabled',
        dict: {
          data: [
            { value: true, label: '启用' },
            { value: false, label: '禁用' }
          ]
        },
        type: 'dict-switch', // 这里改成 switch 类型
        sortable: true
      }
...
//  delFlag字段删掉
// 创建时间和更新时间,都配置 form:{disabled:true}

看看修改后的最终效果


修改后的效果

image.png
  1. 还可以改成行编辑模式
    修改shop/category/crud.js
rowHandle: {
      edit: {
        show: false //对话框编辑按钮不显示
      },
      lineEdit: { //显示行编辑按钮
        show: true,
        disabled: () => {
          return !vm.hasPermissions('shop:shopCategory:edit')
        }
      }
    },
    options: {
      lineEdit: { validation: true }, //开启行编辑表单校验
    },

修改shop/category/index.vue

<template>
//将click的addRow 方法改成 lineEditAdd() ↓ ↓ ↓ ↓ ↓ ↓ ↓
 <el-button v-permission="'shop:shopCategory:add'" size="small" type="primary" @click="lineEditAdd()"><i class="el-icon-plus"/> 新增</el-button>
</template>
<script>
export default{
    addRequest (row) {
      return api.AddObj(row).then(ret => { //改成返回{row},要带上id
        row.id = ret.data
        return { row: row }
      })
    },
    updateRequest (row) {
      return api.UpdateObj(row).then(ret => { // 改成返回 {row}
        return { row }
      })
    },
}
</script>

保存即可查看行编辑效果

image.png

总结

d2-admin作为管理后台脚手架还是很美观大气的
d2-crud-plus 开发CRUD真是太舒服了,赶紧star起来

d2-crud-plus git : https://github.com/greper/d2-crud-plus
d2-crud-plus 示例: http://preview.d2-crud-plus.docmirror.cn/D2CrudPlusExample/
d2-crud-plus 文档: http://greper.gitee.io/d2-crud-plus/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268