微服务架构-ruoyi

前言

一款基于SpringBoot+Bootstrap的极速后台开发框架。

经典技术组合(Spring Boot、Apache Shiro、MyBatis、Thymeleaf、Bootstrap)
经典技术组合(Spring Boot、Apache Shiro、MyBatis、vue + element)

内置模块如:机构管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、通知公告等。

在线定时任务配置;支持集群,支持多数据源。

技术选型

系统环境

  • jdk/javaee8
  • apache maven

主框架

  • Spring Boot 2.0
  • Apache Shiro 1.4

持久层

  • Apache MyBatisPlus

视图层

  • vue2.x
  • element

内置

支持CRUD下载

管理工具:
登录日志:系统登录日志记录查询包含登录异常。
操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
在线用户:当前系统中活跃用户状态监控。

系统管理:
用户管理:用户是系统操作者,该功能主要完成系统用户配置。
部门管理:系统组织机构(公司、部门、小组),树结构展现支持数据权限。
岗位管理:配置系统用户所属担任职务。
角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
菜单管理:配置系统菜单,操作权限,按钮权限标识等。

开发工具:
参数管理:对系统动态配置常用参数。
字典管理:对系统中经常使用的一些较为固定的数据进行维护。
代码生成(开发规范)
定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。

集成:
本地nacos服务监控(集成)
http://127.0.0.1:8848/nacos/#/login
nacos/nacos
本地sentinel服务监控(集成)
http://127.0.0.1:8718/
根据业务代码自动生成相关的api接口文档(集成)

layout.vue

<template>
  <div>
    <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
      <el-row gutter="15">
      </el-row>
      <el-form-item size="large">
        <el-button type="primary" @click="submitForm">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  components: {},
  props: [],
  data() {
    return {
      formData: {},
      rules: {},
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  methods: {
    submitForm() {
      this.$refs['elForm'].validate(valid => {
        if (!valid) return
        // TODO 提交表单
      })
    },
    resetForm() {
      this.$refs['elForm'].resetFields()
    },
  }
}

</script>
<style>
</style>

select.vue

<template>
  <div>
    <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
      <el-form-item label="下拉选择" prop="field116">
        <el-select v-model="formData.field116" placeholder="请选择下拉选择" clearable :style="{width: '100%'}">
          <el-option v-for="(item, index) in field116Options" :key="index" :label="item.label"
            :value="item.value" :disabled="item.disabled"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="级联选择" prop="field117">
        <el-cascader v-model="formData.field117" :options="field117Options" :props="field117Props"
          :style="{width: '100%'}" placeholder="请选择级联选择" clearable></el-cascader>
      </el-form-item>
      <el-form-item label="单选框组" prop="field118">
        <el-radio-group v-model="formData.field118" size="medium">
          <el-radio v-for="(item, index) in field118Options" :key="index" :label="item.value"
            :disabled="item.disabled">{{item.label}}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="多选框组" prop="field119">
        <el-checkbox-group v-model="formData.field119" size="medium">
          <el-checkbox v-for="(item, index) in field119Options" :key="index" :label="item.value"
            :disabled="item.disabled">{{item.label}}</el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="上传" prop="field124" required>
        <el-upload ref="field124" :file-list="field124fileList" :action="field124Action"
          :before-upload="field124BeforeUpload">
          <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
        </el-upload>
      </el-form-item>
      <el-form-item size="large">
        <el-button type="primary" @click="submitForm">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  components: {},
  props: [],
  data() {
    return {
      formData: {
        field116: undefined,
        field117: [1, 2],
        field118: undefined,
        field119: [],
        field124: null,
      },
      rules: {
        field116: [{
          required: true,
          message: '请选择下拉选择',
          trigger: 'change'
        }],
        field117: [{
          required: true,
          type: 'array',
          message: '请至少选择一个field117',
          trigger: 'change'
        }],
        field118: [{
          required: true,
          message: '单选框组不能为空',
          trigger: 'change'
        }],
        field119: [{
          required: true,
          type: 'array',
          message: '请至少选择一个field119',
          trigger: 'change'
        }],
      },
      field124Action: 'https://jsonplaceholder.typicode.com/posts/',
      field124fileList: [],
      field116Options: [{
        "label": "选项一",
        "value": 1
      }, {
        "label": "选项二",
        "value": 2
      }],
      field117Options: [],
      field118Options: [{
        "label": "选项一",
        "value": 1
      }, {
        "label": "选项二",
        "value": 2
      }],
      field119Options: [{
        "label": "选项一",
        "value": 1
      }, {
        "label": "选项二",
        "value": 2
      }],
      field117Props: {
        "multiple": false
      },
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  methods: {
    submitForm() {
      this.$refs['elForm'].validate(valid => {
        if (!valid) return
        // TODO 提交表单
      })
    },
    resetForm() {
      this.$refs['elForm'].resetFields()
    },
    getField117Options() {
      // TODO 发起请求获取数据
      this.field117Options
    },
    field124BeforeUpload(file) {
      let isRightSize = file.size / 1024 / 1024 < 2
      if (!isRightSize) {
        this.$message.error('文件大小超过 2MB')
      }
      return isRightSize
    },
  }
}

</script>
<style>
.el-upload__tip {
  line-height: 1.2;
}

</style>

form.vue

<template>
  <div>
    <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
      <el-form-item label="单行文本" prop="field110">
        <el-input v-model="formData.field110" placeholder="请输入单行文本" clearable :style="{width: '100%'}">
        </el-input>
      </el-form-item>
      <el-form-item label="下拉选择" prop="field111">
        <el-select v-model="formData.field111" placeholder="请选择下拉选择" clearable :style="{width: '100%'}">
          <el-option v-for="(item, index) in field111Options" :key="index" :label="item.label"
            :value="item.value" :disabled="item.disabled"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="时间选择" prop="field112">
        <el-time-picker v-model="formData.field112" format="HH:mm:ss" value-format="HH:mm:ss"
          :picker-options='{"selectableRange":"00:00:00-23:59:59"}' :style="{width: '100%'}"
          placeholder="请选择时间选择" clearable></el-time-picker>
      </el-form-item>
      <el-form-item label="时间范围" prop="field113">
        <el-time-picker v-model="formData.field113" is-range format="HH:mm:ss" value-format="HH:mm:ss"
          :style="{width: '100%'}" start-placeholder="开始时间" end-placeholder="结束时间" range-separator=""
          clearable></el-time-picker>
      </el-form-item>
      <el-form-item label="日期选择" prop="field114">
        <el-date-picker v-model="formData.field114" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
          :style="{width: '100%'}" placeholder="请选择日期选择" clearable></el-date-picker>
      </el-form-item>
      <el-form-item label="日期范围" prop="field115">
        <el-date-picker type="daterange" v-model="formData.field115" format="yyyy-MM-dd"
          value-format="yyyy-MM-dd" :style="{width: '100%'}" start-placeholder="开始日期" end-placeholder="结束日期"
          range-separator="" clearable></el-date-picker>
      </el-form-item>
      <el-form-item size="large">
        <el-button type="primary" @click="submitForm">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  components: {},
  props: [],
  data() {
    return {
      formData: {
        field110: undefined,
        field111: undefined,
        field112: null,
        field113: null,
        field114: null,
        field115: null,
      },
      rules: {
        field110: [{
          required: true,
          message: '请输入单行文本',
          trigger: 'blur'
        }],
        field111: [{
          required: true,
          message: '请选择下拉选择',
          trigger: 'change'
        }],
        field112: [{
          required: true,
          message: '请选择时间选择',
          trigger: 'change'
        }],
        field113: [{
          required: true,
          message: '时间范围不能为空',
          trigger: 'change'
        }],
        field114: [{
          required: true,
          message: '请选择日期选择',
          trigger: 'change'
        }],
        field115: [{
          required: true,
          message: '日期范围不能为空',
          trigger: 'change'
        }],
      },
      field111Options: [{
        "label": "选项一",
        "value": 1
      }, {
        "label": "选项二",
        "value": 2
      }],
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  methods: {
    submitForm() {
      this.$refs['elForm'].validate(valid => {
        if (!valid) return
        // TODO 提交表单
      })
    },
    resetForm() {
      this.$refs['elForm'].resetFields()
    },
  }
}

</script>
<style>
</style>



web开发规范

  • css 基础语法
  • scss 语法
  • yml 语法
  • svg 图标 icons
  • png 图片
  • image 图片
  • gif 动图

vue 2.x src 开发目录

  • src\assets static 资源
  • src\mixins mixins.js 混入
  • src\directive 指令.js
  • src\components 组件.vue
  • src\router 路由.js
  • src\api
  • src\views

编码规范

3.1使用swagger 必须 补充完整好注解, 每一example个参数必须要有方便以后测试

3.2 单表操作 请使用 mybatisplus 的方法
3.3 不允许在代码中直接出现数字赋值的情况请使用(枚举/常量)

3.4 在进行对比的时候请使用(枚举/常量)
3.5 字段校验请使用spring validate,需要校验的字段请务必加好注解并补充好规则,以及提示信息
3.5 入参超过三个必须建立一个实体类接收
3.6 出参统一格式是用AjaxResult包装实体类 泛型必须写清楚(返回数据为空的除外)
3.7 每一个方法都必须要有注释
3.8 如果是feign 接口请使用 .inside 结尾

Mybatis Plus

MyBatis:一种操作数据库的框架,提供一种Mapper类,支持让你用java代码进行增删改查的数据库操作,省去了每次都要手写sql语句的麻烦。但是!有一个前提,你得先在xml中写好sql语句,是不是很麻烦?于是有下面的↓
Mybatis Generator:自动为Mybatis生成简单的增删改查sql语句的工具,省去一大票时间,两者配合使用,开发速度快到飞起。至于标题说的↓
Mybatis Plus:国人团队苞米豆在Mybatis的基础上开发的框架,在Mybatis基础上扩展了许多功能,荣获了2018最受欢迎国产开源软件第5名,当然也有配套的↓
Mybatis Plus Generator:同样为苞米豆开发,比Mybatis Generator更加强大,支持功能更多,自动生成Entity、Mapper、Service、Controller等
总结:
数据库框架:Mybatis Plus > Mybatis
代码生成器:Mybatis Plus Generator > Mybatis Generator

如何在你的项目中集成MP

  • 它也提供了一些很有意思的插件,比如SQL性能监控、乐观锁、执行分析等
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-core</artifactId>
	<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-annotation</artifactId>
	<version>${mybatis-plus-boot-starter.version}</version>
</dependency>

MP代码生成器

《需求详细设计》

  • 需求调研文档(可以解决什么问题,提供什么基础服务)
  • 需求分析(细化流程) 【产品/架构各有侧重】
  • 原型交互(进一步沟通)【产品s】
  • UI设计(细化页面风格)【ui进场】

《系统技术方案》

  • 数据库设计【架构】

《开发文档》

  • 接口分析(细化接口参数)
  • 详细设计【开发】
  • 接口交互文档【开发】

《开发文档》

  • src\main\java\com\copote\system\domain\vo db-mapper 【entity】
  • \src\main\java\com\copote\system\mapper xml-mapper 【dao】
  • src\main\resources\mapper 【mapper】
  • src\main\java\com\copote\system\service\ 【定义接口】
  • src\main\java\com\copote\system\service\impl 【接口实现】
  • src\main\java\com\copote\system\controller 【api 提供】

《常见且重要spring 注解》

  • @PreAuthorize 服务鉴权 菜单表配置

查询

 /**
     * 查询终端配置列表
     */
    @PreAuthorize("@ss.hasPermi('system:client:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysClientDetails sysClientDetails){
        startPage();
        List<SysClientDetails> list = sysClientDetailsService.selectSysClientDetailsList(sysClientDetails);
        return getDataTable(list);
    }

新增

/**
     * 新增终端配置
     */
    @PreAuthorize("@ss.hasPermi('system:client:add')")
    @Log(title = "终端配置", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysClientDetails sysClientDetails){
        String clientId = sysClientDetails.getClientId();
        if (StringUtils.isNotNull(sysClientDetailsService.selectSysClientDetailsById(clientId))){
            return AjaxResult.error("新增终端'" + clientId + "'失败,编号已存在");
        }
        sysClientDetails.setClientSecret(SecurityUtils.encryptPassword(sysClientDetails.getClientSecret()));
        return toAjax(sysClientDetailsService.insertSysClientDetails(sysClientDetails));
    }

修改

 /**
     * 修改终端配置
     */
    @PreAuthorize("@ss.hasPermi('system:client:edit')")
    @Log(title = "终端配置", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysClientDetails sysClientDetails){
        sysClientDetails.setClientSecret(SecurityUtils.encryptPassword(sysClientDetails.getClientSecret()));
        return toAjax(sysClientDetailsService.updateSysClientDetails(sysClientDetails));
    }

删除

/**
     * 删除终端配置
     */
    @PreAuthorize("@ss.hasPermi('system:client:remove')")
    @Log(title = "终端配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{clientIds}")
    public AjaxResult remove(@PathVariable String[] clientIds){
        return toAjax(sysClientDetailsService.deleteSysClientDetailsByIds(clientIds));
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值