RuoYi
2019-11-11 bcee37b84bde39072e6e35e642b0911a94f52eef
若依 1.1
已重命名1个文件
已修改88个文件
已添加4个文件
3566 ■■■■■ 文件已修改
README.md 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/monitor/logininfor.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/monitor/operlog.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/config.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/dict/data.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/dict/type.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/post.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/role.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/user.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/styles/ruoyi.scss 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/main.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/utils/ruoyi.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/logininfor/index.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/online/index.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/operlog/index.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/config/index.vue 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dict/data.vue 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dict/index.vue 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/notice/index.vue 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/post/index.vue 104 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/role/index.vue 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/user/index.vue 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/vue.config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/pom.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/sql/ry_20191111.sql 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java 872 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java 406 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -49,12 +49,12 @@
        <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
    </tr>
    <tr>
        <td><img src="https://oscimg.oschina.net/oscnet/97fcdc766fa04c03722aef4b3d77f71e8d2.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/642858372da91853c39e2d4746f036ea171.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/707825ad3f29de74a8d6d02fbd73ad631ea.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/46be40cc6f01aa300eed53a19b5012bf484.jpg"/></td>
    </tr>
    <tr>
        <td><img src="https://oscimg.oschina.net/oscnet/8678d5204148e2610c9d02822274a961dcf.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/feb2b25a08bf9dd121b8f51274ae935ead6.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/4284796d4cea240d181b8f2201813dda710.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/3ecfac87a049f7fe36abbcaafb2c40d36cf.jpg"/></td>
    </tr>
    <tr>
        <td><img src="https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg"/></td>
@@ -65,8 +65,8 @@
        <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
    </tr>
    <tr>
        <td><img src="https://oscimg.oschina.net/oscnet/c162686bf3a39e3cd6b4fd6b5919f515ebf.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/412fb931faa8b3e3de6f9cbbc5b7979cf36.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/fdea1d8bb8625c27bf964176a2c8ebc6945.jpg"/></td>
        <td><img src="https://oscimg.oschina.net/oscnet/509d2708cfd762b6e6339364cac1cc1970c.jpg"/></td>
    </tr>
    <tr>
        <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
ruoyi-ui/package.json
@@ -1,6 +1,6 @@
{
  "name": "ruoyi",
  "version": "1.0.0",
  "version": "1.1.0",
  "description": "若依管理系统",
  "author": "若依",
  "license": "MIT",
ruoyi-ui/src/api/monitor/logininfor.js
@@ -7,4 +7,29 @@
    method: 'get',
    params: query
  })
}
// 删除登录日志
export function delLogininfor(infoId) {
  return request({
    url: '/monitor/logininfor/' + infoId,
    method: 'delete'
  })
}
// 清空登录日志
export function cleanLogininfor() {
  return request({
    url: '/monitor/logininfor/clean',
    method: 'delete'
  })
}
// 导出登录日志
export function exportLogininfor(query) {
  return request({
    url: '/monitor/logininfor/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/monitor/operlog.js
@@ -7,4 +7,29 @@
    method: 'get',
    params: query
  })
}
// 删除操作日志
export function delOperlog(operId) {
  return request({
    url: '/monitor/operlog/' + operId,
    method: 'delete'
  })
}
// 清空操作日志
export function cleanOperlog() {
  return request({
    url: '/monitor/operlog/clean',
    method: 'delete'
  })
}
// 导出操作日志
export function exportOperlog(query) {
  return request({
    url: '/monitor/operlog/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/system/config.js
@@ -49,4 +49,13 @@
    url: '/system/config/' + configId,
    method: 'delete'
  })
}
// 导出参数
export function exportConfig(query) {
  return request({
    url: '/system/config/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/system/dict/data.js
@@ -49,4 +49,13 @@
    url: '/system/dict/data/' + dictCode,
    method: 'delete'
  })
}
// 导出字典数据
export function exportData(query) {
  return request({
    url: '/system/dict/data/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/system/dict/type.js
@@ -42,3 +42,12 @@
    method: 'delete'
  })
}
// 导出字典类型
export function exportType(query) {
  return request({
    url: '/system/dict/type/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/system/post.js
@@ -41,4 +41,13 @@
    url: '/system/post/' + postId,
    method: 'delete'
  })
}
// 导出岗位
export function exportPost(query) {
  return request({
    url: '/system/post/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/system/role.js
@@ -63,4 +63,13 @@
    url: '/system/role/' + roleId,
    method: 'delete'
  })
}
// 导出角色
export function exportRole(query) {
  return request({
    url: '/system/role/export',
    method: 'get',
    params: query
  })
}
ruoyi-ui/src/api/system/user.js
@@ -43,6 +43,15 @@
  })
}
// 导出用户
export function exportUser(query) {
  return request({
    url: '/system/user/export',
    method: 'get',
    params: query
  })
}
// 用户密码重置
export function resetUserPwd(userId, password) {
  const data = {
@@ -106,4 +115,4 @@
    method: 'post',
    data: data
  })
}
}
ruoyi-ui/src/assets/styles/ruoyi.scss
@@ -3,6 +3,56 @@
 * Copyright (c) 2019 ruoyi
 */
 /** 基础通用 **/
.pt5 {
    padding-top: 5px;
}
.pr5 {
    padding-right: 5px;
}
.pb5 {
    padding-bottom: 5px;
}
.mt5 {
    margin-top: 5px;
}
.mr5 {
    margin-right: 5px;
}
.mb5 {
    margin-bottom: 5px;
}
.mb8 {
    margin-bottom: 8px;
}
.ml5 {
    margin-left: 5px;
}
.mt10 {
    margin-top: 10px;
}
.mr10 {
    margin-right: 10px;
}
.mb10 {
    margin-bottom: 10px;
}
.ml0 {
    margin-left: 10px;
}
.mt20 {
    margin-top: 20px;
}
.mr20 {
    margin-right: 20px;
}
.mb20 {
    margin-bottom: 20px;
}
.m20 {
    margin-left: 20px;
}
.el-table .el-table__header-wrapper th {
    word-break: break-word;
    background-color: #f8f8f9;
ruoyi-ui/src/main.js
@@ -18,7 +18,7 @@
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel } from "@/utils/ruoyi";
import { parseTime, resetForm, addDateRange, selectDictLabel, download } from "@/utils/ruoyi";
import Pagination from "@/components/Pagination";
// 全局方法挂载
@@ -28,6 +28,7 @@
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.download = download
Vue.prototype.msgSuccess = function (msg) {
  this.$message({ showClose: true, message: msg, type: "success" });
ruoyi-ui/src/utils/ruoyi.js
@@ -3,6 +3,8 @@
 * Copyright (c) 2019 ruoyi
 */
const baseURL = process.env.VUE_APP_BASE_API
// 日期格式化
export function parseTime(time, pattern) {
    if (arguments.length === 0) {
@@ -73,6 +75,11 @@
    return actions.join('');
}
// 通用下载方法
export function download(fileName) {
    window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
}
// 字符串格式化(%s )
export function sprintf(str) {
    var args = arguments, flag = true, i = 1;
ruoyi-ui/src/views/monitor/logininfor/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true" label-width="68px">
      <el-form-item label="登录地址">
    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
      <el-form-item label="登录地址" prop="ipaddr">
        <el-input
          v-model="queryParams.ipaddr"
          placeholder="请输入登录地址"
@@ -11,7 +11,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="用户名称">
      <el-form-item label="用户名称" prop="userName">
        <el-input
          v-model="queryParams.userName"
          placeholder="请输入用户名称"
@@ -21,7 +21,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态">
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryParams.status"
          placeholder="登录状态"
@@ -51,10 +51,43 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="list" style="width: 100%;">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['monitor:logininfor:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          @click="handleClean"
          v-hasPermi="['monitor:logininfor:remove']"
        >清空</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:logininfor:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="访问编号" align="center" prop="infoId" />
      <el-table-column label="用户名称" align="center" prop="userName" />
      <el-table-column label="登录地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" />
@@ -81,13 +114,17 @@
</template>
<script>
import { list } from "@/api/monitor/logininfor";
import { list, delLogininfor, cleanLogininfor, exportLogininfor } from "@/api/monitor/logininfor";
export default {
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 表格数据
@@ -131,6 +168,57 @@
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.infoId)
      this.multiple = !selection.length
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const infoIds = row.infoId || this.ids;
      this.$confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delLogininfor(infoIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 清空按钮操作 */
    handleClean() {
        this.$confirm('是否确认清空所有登录日志数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return cleanLogininfor();
        }).then(() => {
          this.getList();
          this.msgSuccess("清空成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有操作日志数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportLogininfor(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/monitor/online/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true">
      <el-form-item label="登录地址">
    <el-form :model="queryParams" ref="queryForm" :inline="true">
      <el-form-item label="登录地址" prop="ipaddr">
        <el-input
          v-model="queryParams.ipaddr"
          placeholder="请输入登录地址"
@@ -10,7 +10,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="用户名称">
      <el-form-item label="用户名称" prop="userName">
        <el-input
          v-model="queryParams.userName"
          placeholder="请输入用户名称"
@@ -21,6 +21,7 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
@@ -102,6 +103,11 @@
      this.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    /** 强退按钮操作 */
    handleForceLogout(row) {
      this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", {
ruoyi-ui/src/views/monitor/operlog/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true" label-width="68px">
      <el-form-item label="系统模块">
    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
      <el-form-item label="系统模块" prop="title">
        <el-input
          v-model="queryParams.title"
          placeholder="请输入系统模块"
@@ -11,7 +11,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="操作人员">
      <el-form-item label="操作人员" prop="operName">
        <el-input
          v-model="queryParams.operName"
          placeholder="请输入操作人员"
@@ -21,7 +21,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="类型">
      <el-form-item label="类型" prop="businessType">
        <el-select
          v-model="queryParams.businessType"
          placeholder="操作类型"
@@ -37,7 +37,7 @@
          />
        </el-select>
      </el-form-item>
      <el-form-item label="状态">
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryParams.status"
          placeholder="操作状态"
@@ -67,10 +67,43 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="list" style="width: 100%;">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['monitor:operlog:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          @click="handleClean"
          v-hasPermi="['monitor:operlog:remove']"
        >清空</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:config:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="日志编号" align="center" prop="operId" />
      <el-table-column label="系统模块" align="center" prop="title" />
      <el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" />
@@ -150,13 +183,17 @@
</template>
<script>
import { list } from "@/api/monitor/operlog";
import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/operlog";
export default {
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 表格数据
@@ -215,10 +252,61 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.operId)
      this.multiple = !selection.length
    },
    /** 详细按钮操作 */
    handleView(row) {
      this.open = true;
      this.form = row;
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const operIds = row.operId || this.ids;
      this.$confirm('是否确认删除日志编号为"' + operIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delOperlog(operIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 清空按钮操作 */
    handleClean() {
        this.$confirm('是否确认清空所有操作日志数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return cleanOperlog();
        }).then(() => {
          this.getList();
          this.msgSuccess("清空成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有操作日志数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportOperlog(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/system/config/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true" label-width="68px">
      <el-form-item label="参数名称">
    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
      <el-form-item label="参数名称" prop="configName">
        <el-input
          v-model="queryParams.configName"
          placeholder="请输入参数名称"
@@ -11,7 +11,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="参数键名">
      <el-form-item label="参数键名" prop="configKey">
        <el-input
          v-model="queryParams.configKey"
          placeholder="请输入参数键名"
@@ -21,7 +21,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="系统内置">
      <el-form-item label="系统内置" prop="configType">
        <el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small">
          <el-option
            v-for="dict in typeOptions"
@@ -45,11 +45,53 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:config:add']">新增</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="configList">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:config:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:config:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:config:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:config:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="参数主键" align="center" prop="configId" />
      <el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
      <el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
@@ -63,10 +105,10 @@
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:config:edit']"
          >修改</el-button>
@@ -123,13 +165,19 @@
</template>
<script>
import { listConfig, getConfig, delConfig, addConfig, updateConfig } from "@/api/system/config";
import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig } from "@/api/system/config";
export default {
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 参数表格数据
@@ -209,16 +257,29 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加参数";
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.configId)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getConfig(row.configId).then(response => {
      const configId = row.configId || this.ids
      getConfig(configId).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改参数";
@@ -254,16 +315,30 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除名称为"' + row.configName + '"的数据项?', "警告", {
      const configIds = row.configId || this.ids;
      this.$confirm('是否确认删除参数编号为"' + configIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delConfig(row.configId);
          return delConfig(configIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有参数数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportConfig(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/system/dict/data.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true">
      <el-form-item label="字典名称">
    <el-form :model="queryParams" ref="queryForm" :inline="true">
      <el-form-item label="字典名称" prop="dictType">
        <el-select v-model="queryParams.dictType" size="small">
          <el-option
            v-for="item in typeOptions"
@@ -11,7 +11,7 @@
          />
        </el-select>
      </el-form-item>
      <el-form-item label="字典标签">
      <el-form-item label="字典标签" prop="dictLabel">
        <el-input
          v-model="queryParams.dictLabel"
          placeholder="请输入字典标签"
@@ -20,7 +20,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态">
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
          <el-option
            v-for="dict in statusOptions"
@@ -32,11 +32,53 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:dict:add']">新增</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="dataList" style="width: 100%;">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:dict:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:dict:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:dict:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:dict:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="字典编码" align="center" prop="dictCode" />
      <el-table-column label="字典标签" align="center" prop="dictLabel" />
      <el-table-column label="字典键值" align="center" prop="dictValue" />
@@ -50,10 +92,10 @@
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:dict:edit']"
          >修改</el-button>
@@ -113,7 +155,7 @@
</template>
<script>
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
import { listData, getData, delData, addData, updateData, exportData } from "@/api/system/dict/data";
import { listType, getType } from "@/api/system/dict/type";
export default {
@@ -121,10 +163,18 @@
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 字典表格数据
      dataList: [],
      // 默认字典类型
      defaultDictType: "",
      // 弹出层标题
      title: "",
      // 是否显示弹出层
@@ -170,6 +220,7 @@
    getType(dictId) {
      getType(dictId).then(response => {
        this.queryParams.dictType = response.data.dictType;
        this.defaultDictType = response.data.dictType;
        this.getList();
      });
    },
@@ -214,6 +265,12 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.queryParams.dictType = this.defaultDictType;
      this.handleQuery();
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
@@ -221,10 +278,17 @@
      this.title = "添加字典数据";
      this.form.dictType = this.queryParams.dictType;
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.dictCode)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getData(row.dictCode).then(response => {
      const dictCode = row.dictCode || this.ids
      getData(dictCode).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改字典数据";
@@ -260,16 +324,30 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除名称为"' + row.dictLabel + '"的数据项?', "警告", {
      const dictCodes = row.dictCode || this.ids;
      this.$confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delData(row.dictCode);
          return delData(dictCodes);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportData(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/system/dict/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true" label-width="68px">
      <el-form-item label="字典名称">
    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
      <el-form-item label="字典名称" prop="dictName">
        <el-input
          v-model="queryParams.dictName"
          placeholder="请输入字典名称"
@@ -11,7 +11,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="字典类型">
      <el-form-item label="字典类型" prop="dictType">
        <el-input
          v-model="queryParams.dictType"
          placeholder="请输入字典类型"
@@ -21,7 +21,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态">
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryParams.status"
          placeholder="字典状态"
@@ -39,7 +39,7 @@
      </el-form-item>
      <el-form-item label="创建时间">
        <el-date-picker
          v-model="queryParams.createTime"
          v-model="dateRange"
          size="small"
          style="width: 240px"
          value-format="yyyy-MM-dd"
@@ -51,14 +51,56 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:dict:add']">新增</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="typeList" style="width: 100%;">
      <el-table-column label="字典主键" align="center" prop="dictId" />
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:dict:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:dict:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:dict:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:dict:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="字典编号" align="center" prop="dictId" />
      <el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" />
      <el-table-column label="字典类型" align="center">
      <el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <router-link :to="'/dict/type/data/' + scope.row.dictId" class="link-type">
            <span>{{ scope.row.dictType }}</span>
@@ -74,10 +116,10 @@
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:dict:edit']"
          >修改</el-button>
@@ -131,13 +173,19 @@
</template>
<script>
import { listType, getType, delType, addType, updateType } from "@/api/system/dict/type";
import { listType, getType, delType, addType, updateType, exportType } from "@/api/system/dict/type";
export default {
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 字典表格数据
@@ -181,8 +229,7 @@
    /** 查询字典类型列表 */
    getList() {
      this.loading = true;
      listType(this.addDateRange(this.queryParams, this.dateRange)).then(
        response => {
      listType(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
          this.typeList = response.rows;
          this.total = response.total;
          this.loading = false;
@@ -214,16 +261,29 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加字典类型";
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.dictId)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getType(row.dictId).then(response => {
      const dictId = row.dictId || this.ids
      getType(dictId).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改字典类型";
@@ -259,16 +319,30 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除名称为"' + row.dictName + '"的数据项?', "警告", {
      const dictIds = row.dictId || this.ids;
      this.$confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delType(row.dictId);
          return delType(dictIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有类型数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportType(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/system/notice/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true" label-width="68px">
      <el-form-item label="公告标题">
    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
      <el-form-item label="公告标题" prop="noticeTitle">
        <el-input
          v-model="queryParams.noticeTitle"
          placeholder="请输入公告标题"
@@ -10,7 +10,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="操作人员">
      <el-form-item label="操作人员" prop="createBy">
        <el-input
          v-model="queryParams.createBy"
          placeholder="请输入操作人员"
@@ -19,7 +19,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="类型">
      <el-form-item label="类型" prop="noticeType">
        <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small">
          <el-option
            v-for="dict in typeOptions"
@@ -31,11 +31,44 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:notice:add']">新增</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="noticeList">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:notice:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:notice:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:notice:remove']"
        >删除</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="序号" align="center" prop="noticeId" width="100" />
      <el-table-column
        label="公告标题"
@@ -65,10 +98,10 @@
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:notice:edit']"
          >修改</el-button>
@@ -125,7 +158,7 @@
          </el-col>
          <el-col :span="24">
            <el-form-item label="内容">
               <Editor v-model="form.noticeContent"/>
              <Editor v-model="form.noticeContent" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -139,7 +172,7 @@
</template>
<script>
import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice";
import { listNotice, getNotice, delNotice, addNotice, updateNotice, exportNotice } from "@/api/system/notice";
import Editor from '@/components/Editor';
export default {
@@ -150,6 +183,12 @@
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 公告表格数据
@@ -231,6 +270,17 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.noticeId)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
@@ -240,7 +290,8 @@
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getNotice(row.noticeId).then(response => {
      const noticeId = row.noticeId || this.ids
      getNotice(noticeId).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改公告";
@@ -276,12 +327,13 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除公告标题为"' + row.noticeTitle + '"的数据项?', "警告", {
      const noticeIds = row.noticeId || this.ids
      this.$confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delNotice(row.noticeId);
          return delNotice(noticeIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
ruoyi-ui/src/views/system/post/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true" label-width="68px">
      <el-form-item label="岗位编码">
    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
      <el-form-item label="岗位编码" prop="postCode">
        <el-input
          v-model="queryParams.postCode"
          placeholder="请输入岗位编码"
@@ -10,7 +10,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="岗位名称">
      <el-form-item label="岗位名称" prop="postName">
        <el-input
          v-model="queryParams.postName"
          placeholder="请输入岗位名称"
@@ -19,7 +19,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态">
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
          <el-option
            v-for="dict in statusOptions"
@@ -31,11 +31,53 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:post:add']">新增</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="loading" :data="postList">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:post:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:post:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:post:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:post:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="岗位编号" align="center" prop="postId" />
      <el-table-column label="岗位编码" align="center" prop="postCode" />
      <el-table-column label="岗位名称" align="center" prop="postName" />
@@ -48,10 +90,10 @@
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:post:edit']"
          >修改</el-button>
@@ -65,7 +107,7 @@
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="total>0"
      :total="total"
@@ -108,13 +150,19 @@
</template>
<script>
import { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/post";
import { listPost, getPost, delPost, addPost, updatePost, exportPost } from "@/api/system/post";
export default {
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 岗位表格数据
@@ -191,6 +239,17 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.postId)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
@@ -200,7 +259,8 @@
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getPost(row.postId).then(response => {
      const postId = row.postId || this.ids
      getPost(postId).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改岗位";
@@ -236,16 +296,30 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除岗位名称为"' + row.postName + '"的数据项?', "警告", {
      const postIds = row.postId || this.ids;
      this.$confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delPost(row.postId);
          return delPost(postIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有岗位数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportPost(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/system/role/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="app-container">
    <el-form :inline="true">
      <el-form-item label="角色名称">
    <el-form :model="queryParams" ref="queryForm" :inline="true">
      <el-form-item label="角色名称" prop="roleName">
        <el-input
          v-model="queryParams.roleName"
          placeholder="请输入角色名称"
@@ -11,7 +11,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="权限字符">
      <el-form-item label="权限字符" prop="roleKey">
        <el-input
          v-model="queryParams.roleKey"
          placeholder="请输入权限字符"
@@ -21,7 +21,7 @@
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态">
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryParams.status"
          placeholder="角色状态"
@@ -51,6 +51,12 @@
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
@@ -58,15 +64,45 @@
          @click="handleAdd"
          v-hasPermi="['system:role:add']"
        >新增</el-button>
      </el-form-item>
    </el-form>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:role:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:role:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:post:export']"
        >导出</el-button>
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="roleList">
    <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="角色编号" prop="roleId" width="120" />
      <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
      <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="180" />
      <el-table-column label="显示顺序" prop="roleSort" width="120" />
      <el-table-column label="状态" align="center" width="120">
      <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
      <el-table-column label="显示顺序" prop="roleSort" width="100" />
      <el-table-column label="状态" align="center" width="100">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.status"
@@ -197,7 +233,7 @@
</template>
<script>
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/api/system/role";
import { listRole, getRole, delRole, addRole, updateRole, exportRole, dataScope, changeRoleStatus } from "@/api/system/role";
import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
@@ -206,6 +242,12 @@
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 角色表格数据
@@ -384,6 +426,18 @@
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.roleId)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
@@ -394,10 +448,11 @@
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const roleId = row.roleId || this.ids
      this.$nextTick(() => {
        this.getRoleMenuTreeselect(row.roleId);
        this.getRoleMenuTreeselect(roleId);
      });
      getRole(row.roleId).then(response => {
      getRole(roleId).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改角色";
@@ -462,16 +517,30 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除名称为"' + row.roleName + '"的数据项?', "警告", {
      const roleIds = row.roleId || this.ids;
      this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delRole(row.roleId);
          return delRole(roleIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有角色数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportRole(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/src/views/system/user/index.vue
@@ -27,8 +27,8 @@
      </el-col>
      <!--用户数据-->
      <el-col :span="20" :xs="24">
        <el-form :inline="true" label-width="68px">
          <el-form-item label="用户名称">
        <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
          <el-form-item label="用户名称" prop="userName">
            <el-input
              v-model="queryParams.userName"
              placeholder="请输入用户名称"
@@ -38,7 +38,7 @@
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="手机号码">
          <el-form-item label="手机号码" prop="phonenumber">
            <el-input
              v-model="queryParams.phonenumber"
              placeholder="请输入手机号码"
@@ -48,7 +48,7 @@
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="状态">
          <el-form-item label="状态" prop="status">
            <el-select
              v-model="queryParams.status"
              placeholder="用户状态"
@@ -78,11 +78,53 @@
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
            <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
        <el-table v-loading="loading" :data="userList">
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
              v-hasPermi="['system:user:add']"
            >新增</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="success"
              icon="el-icon-edit"
              size="mini"
              :disabled="single"
              @click="handleUpdate"
              v-hasPermi="['system:user:edit']"
            >修改</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              icon="el-icon-delete"
              size="mini"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['system:user:remove']"
            >删除</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="warning"
              icon="el-icon-download"
              size="mini"
              @click="handleExport"
              v-hasPermi="['system:user:export']"
            >导出</el-button>
          </el-col>
        </el-row>
        <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="40" align="center" />
          <el-table-column label="用户编号" align="center" prop="userId" />
          <el-table-column label="用户名称" align="center" prop="userName" />
          <el-table-column label="用户昵称" align="center" prop="nickName" />
@@ -246,7 +288,7 @@
</template>
<script>
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
import { treeselect } from "@/api/system/dept";
import { listPost } from "@/api/system/post";
import { listRole } from "@/api/system/role";
@@ -259,6 +301,12 @@
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 总条数
      total: 0,
      // 用户表格数据
@@ -430,6 +478,18 @@
      this.queryParams.page = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.userId)
      this.single = selection.length!=1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
@@ -446,7 +506,8 @@
      this.getTreeselect();
      this.getPosts();
      this.getRoles();
      getUser(row.userId).then(response => {
      const userId = row.userId || this.ids
      getUser(userId).then(response => {
        this.form = response.data;
        this.form.postIds = response.postIds;
        this.form.roleIds = response.roleIds;
@@ -500,16 +561,30 @@
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除名称为"' + row.userName + '"的数据项?', "警告", {
      const userIds = row.userId || this.ids;
      this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return delUser(row.userId);
          return delUser(userIds);
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        }).catch(function() {});
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm('是否确认导出所有用户数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return exportUser(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(function() {});
    }
  }
};
ruoyi-ui/vue.config.js
@@ -17,7 +17,7 @@
  // 部署生产环境和开发环境下的URL。
  // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
  // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
  publicPath: process.env.NODE_ENV === "production" ? "./" : "/",
  publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
  // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
  outputDir: 'dist',
  // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
ruoyi/pom.xml
@@ -5,7 +5,7 @@
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>1.0</version>
    <version>1.1</version>
    <packaging>jar</packaging>
    <name>ruoyi</name>
@@ -32,6 +32,7 @@
        <bitwalker.version>1.19</bitwalker.version>
        <jwt.version>0.9.0</jwt.version>
        <swagger.version>2.9.2</swagger.version>
        <poi.version>3.17</poi.version>
        <oshi.version>3.9.1</oshi.version>
    </properties>
@@ -223,6 +224,13 @@
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna-platform</artifactId>
        </dependency>
        <!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
    </dependencies>
ruoyi/sql/ry_20191111.sql
文件名从 ruoyi/sql/ry_20191008.sql 修改
@@ -136,7 +136,7 @@
  path              varchar(200)    default ''                 comment '路由地址',
  component         varchar(255)    default null               comment '组件路径',
  is_frame          int(1)          default 1                  comment '是否为外链(0是 1否)',
  menu_type         char(1)         default ''                 comment '菜单类型(0目录 1菜单 2按钮)',
  menu_type         char(1)         default ''                 comment '菜单类型(M目录 C菜单 F按钮)',
  visible           char(1)         default 0                  comment '菜单状态(0显示 1隐藏)',
  perms             varchar(100)    default null               comment '权限标识',
  icon              varchar(100)    default '#'                comment '菜单图标',
@@ -152,10 +152,10 @@
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
insert into sys_menu values('1', '系统管理', '0', '1', 'system',   null,  1, 'M', '0', '', 'system',   'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor',  null,  1, 'M', '0', '', 'monitor',  'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool',     null,  1, 'M', '0', '', 'tool',     'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统工具目录');
INSERT INTO sys_menu VALUES('4', '若依官网', '0', '4', 'http://ruoyi.vip',  NULL ,  0, 'M', '0', '', 'guide',     'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '若依官网');
insert into sys_menu values('1', '系统管理', '0', '1', 'system',           null,   1, 'M', '0', '', 'system',   'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor',          null,   1, 'M', '0', '', 'monitor',  'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool',             null,   1, 'M', '0', '', 'tool',     'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统工具目录');
insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null ,  0, 'M', '0', '', 'guide',    'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '若依官网地址');
-- 二级菜单
insert into sys_menu values('100',  '用户管理', '1',   '1', 'user',       'system/user/index',        1, 'C', '0', 'system:user:list',        'user',          'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '用户管理菜单');
insert into sys_menu values('101',  '角色管理', '1',   '2', 'role',       'system/role/index',        1, 'C', '0', 'system:role:list',        'peoples',       'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '角色管理菜单');
@@ -550,27 +550,7 @@
-- ----------------------------
-- 15、在线用户记录
-- ----------------------------
drop table if exists sys_user_online;
create table sys_user_online (
  sessionId         varchar(50)   default ''                comment '用户会话id',
  user_name         varchar(50)   default ''                comment '用户账号',
  dept_name         varchar(50)   default ''                comment '部门名称',
  ipaddr            varchar(50)   default ''                comment '登录IP地址',
  login_location    varchar(255)  default ''                comment '登录地点',
  browser           varchar(50)   default ''                comment '浏览器类型',
  os                varchar(50)   default ''                comment '操作系统',
  status            varchar(10)   default ''                comment '在线状态on_line在线off_line离线',
  start_timestamp   datetime                                comment 'session创建时间',
  last_access_time  datetime                                comment 'session最后访问时间',
  expire_time       int(5)        default 0                 comment '超时时间,单位为分钟',
  primary key (sessionId)
) engine=innodb comment = '在线用户记录';
-- ----------------------------
-- 16、定时任务调度表
-- 15、定时任务调度表
-- ----------------------------
drop table if exists sys_job;
create table sys_job (
@@ -596,7 +576,7 @@
-- ----------------------------
-- 17、定时任务调度日志表
-- 16、定时任务调度日志表
-- ----------------------------
drop table if exists sys_job_log;
create table sys_job_log (
@@ -613,7 +593,7 @@
-- ----------------------------
-- 18、通知公告表
-- 17、通知公告表
-- ----------------------------
drop table if exists sys_notice;
create table sys_notice (
@@ -638,7 +618,7 @@
-- ----------------------------
-- 19、代码生成业务表
-- 18、代码生成业务表
-- ----------------------------
drop table if exists gen_table;
create table gen_table (
@@ -663,7 +643,7 @@
-- ----------------------------
-- 20、代码生成业务表字段
-- 19、代码生成业务表字段
-- ----------------------------
drop table if exists gen_table_column;
create table gen_table_column (
ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
对比新文件
@@ -0,0 +1,872 @@
package com.ruoyi.common.utils.poi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.Type;
import com.ruoyi.framework.aspectj.lang.annotation.Excels;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
/**
 * Excel相关处理
 *
 * @author ruoyi
 */
public class ExcelUtil<T>
{
    private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
    /**
     * Excel sheet最大行数,默认65536
     */
    public static final int sheetSize = 65536;
    /**
     * 工作表名称
     */
    private String sheetName;
    /**
     * 导出类型(EXPORT:导出数据;IMPORT:导入模板)
     */
    private Type type;
    /**
     * 工作薄对象
     */
    private Workbook wb;
    /**
     * 工作表对象
     */
    private Sheet sheet;
    /**
     * 样式列表
     */
    private Map<String, CellStyle> styles;
    /**
     * 导入导出数据列表
     */
    private List<T> list;
    /**
     * 注解列表
     */
    private List<Object[]> fields;
    /**
     * 实体对象
     */
    public Class<T> clazz;
    public ExcelUtil(Class<T> clazz)
    {
        this.clazz = clazz;
    }
    public void init(List<T> list, String sheetName, Type type)
    {
        if (list == null)
        {
            list = new ArrayList<T>();
        }
        this.list = list;
        this.sheetName = sheetName;
        this.type = type;
        createExcelField();
        createWorkbook();
    }
    /**
     * 对excel表单默认第一个索引名转换成list
     *
     * @param is 输入流
     * @return 转换后集合
     */
    public List<T> importExcel(InputStream is) throws Exception
    {
        return importExcel(StringUtils.EMPTY, is);
    }
    /**
     * 对excel表单指定表格索引名转换成list
     *
     * @param sheetName 表格索引名
     * @param is 输入流
     * @return 转换后集合
     */
    public List<T> importExcel(String sheetName, InputStream is) throws Exception
    {
        this.type = Type.IMPORT;
        this.wb = WorkbookFactory.create(is);
        List<T> list = new ArrayList<T>();
        Sheet sheet = null;
        if (StringUtils.isNotEmpty(sheetName))
        {
            // 如果指定sheet名,则取指定sheet中的内容.
            sheet = wb.getSheet(sheetName);
        }
        else
        {
            // 如果传入的sheet名不存在则默认指向第1个sheet.
            sheet = wb.getSheetAt(0);
        }
        if (sheet == null)
        {
            throw new IOException("文件sheet不存在");
        }
        int rows = sheet.getPhysicalNumberOfRows();
        if (rows > 0)
        {
            // 定义一个map用于存放excel列的序号和field.
            Map<String, Integer> cellMap = new HashMap<String, Integer>();
            // 获取表头
            Row heard = sheet.getRow(0);
            for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
            {
                Cell cell = heard.getCell(i);
                if (StringUtils.isNotNull(cell != null))
                {
                    String value = this.getCellValue(heard, i).toString();
                    cellMap.put(value, i);
                }
                else
                {
                    cellMap.put(null, i);
                }
            }
            // 有数据时才处理 得到类的所有field.
            Field[] allFields = clazz.getDeclaredFields();
            // 定义一个map用于存放列的序号和field.
            Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();
            for (int col = 0; col < allFields.length; col++)
            {
                Field field = allFields[col];
                Excel attr = field.getAnnotation(Excel.class);
                if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
                {
                    // 设置类的私有字段属性可访问.
                    field.setAccessible(true);
                    Integer column = cellMap.get(attr.name());
                    fieldsMap.put(column, field);
                }
            }
            for (int i = 1; i < rows; i++)
            {
                // 从第2行开始取数据,默认第一行是表头.
                Row row = sheet.getRow(i);
                T entity = null;
                for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet())
                {
                    Object val = this.getCellValue(row, entry.getKey());
                    // 如果不存在实例则新建.
                    entity = (entity == null ? clazz.newInstance() : entity);
                    // 从map中得到对应列的field.
                    Field field = fieldsMap.get(entry.getKey());
                    // 取得类型,并根据对象类型设置值.
                    Class<?> fieldType = field.getType();
                    if (String.class == fieldType)
                    {
                        String s = Convert.toStr(val);
                        if (StringUtils.endsWith(s, ".0"))
                        {
                            val = StringUtils.substringBefore(s, ".0");
                        }
                        else
                        {
                            val = Convert.toStr(val);
                        }
                    }
                    else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
                    {
                        val = Convert.toInt(val);
                    }
                    else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
                    {
                        val = Convert.toLong(val);
                    }
                    else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
                    {
                        val = Convert.toDouble(val);
                    }
                    else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
                    {
                        val = Convert.toFloat(val);
                    }
                    else if (BigDecimal.class == fieldType)
                    {
                        val = Convert.toBigDecimal(val);
                    }
                    else if (Date.class == fieldType)
                    {
                        if (val instanceof String)
                        {
                            val = DateUtils.parseDate(val);
                        }
                        else if (val instanceof Double)
                        {
                            val = DateUtil.getJavaDate((Double) val);
                        }
                    }
                    if (StringUtils.isNotNull(fieldType))
                    {
                        Excel attr = field.getAnnotation(Excel.class);
                        String propertyName = field.getName();
                        if (StringUtils.isNotEmpty(attr.targetAttr()))
                        {
                            propertyName = field.getName() + "." + attr.targetAttr();
                        }
                        else if (StringUtils.isNotEmpty(attr.readConverterExp()))
                        {
                            val = reverseByExp(String.valueOf(val), attr.readConverterExp());
                        }
                        ReflectUtils.invokeSetter(entity, propertyName, val);
                    }
                }
                list.add(entity);
            }
        }
        return list;
    }
    /**
     * 对list数据源将其里面的数据导入到excel表单
     *
     * @param list 导出数据集合
     * @param sheetName 工作表的名称
     * @return 结果
     */
    public AjaxResult exportExcel(List<T> list, String sheetName)
    {
        this.init(list, sheetName, Type.EXPORT);
        return exportExcel();
    }
    /**
     * 对list数据源将其里面的数据导入到excel表单
     *
     * @param sheetName 工作表的名称
     * @return 结果
     */
    public AjaxResult importTemplateExcel(String sheetName)
    {
        this.init(null, sheetName, Type.IMPORT);
        return exportExcel();
    }
    /**
     * 对list数据源将其里面的数据导入到excel表单
     *
     * @return 结果
     */
    public AjaxResult exportExcel()
    {
        OutputStream out = null;
        try
        {
            // 取出一共有多少个sheet.
            double sheetNo = Math.ceil(list.size() / sheetSize);
            for (int index = 0; index <= sheetNo; index++)
            {
                createSheet(sheetNo, index);
                // 产生一行
                Row row = sheet.createRow(0);
                int column = 0;
                // 写入各个字段的列头名称
                for (Object[] os : fields)
                {
                    Excel excel = (Excel) os[1];
                    this.createCell(excel, row, column++);
                }
                if (Type.EXPORT.equals(type))
                {
                    fillExcelData(index, row);
                }
            }
            String filename = encodingFilename(sheetName);
            out = new FileOutputStream(getAbsoluteFile(filename));
            wb.write(out);
            return AjaxResult.success(filename);
        }
        catch (Exception e)
        {
            log.error("导出Excel异常{}", e.getMessage());
            throw new CustomException("导出Excel失败,请联系网站管理员!");
        }
        finally
        {
            if (wb != null)
            {
                try
                {
                    wb.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (out != null)
            {
                try
                {
                    out.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }
    /**
     * 填充excel数据
     *
     * @param index 序号
     * @param row 单元格行
     */
    public void fillExcelData(int index, Row row)
    {
        int startNo = index * sheetSize;
        int endNo = Math.min(startNo + sheetSize, list.size());
        for (int i = startNo; i < endNo; i++)
        {
            row = sheet.createRow(i + 1 - startNo);
            // 得到导出对象.
            T vo = (T) list.get(i);
            int column = 0;
            for (Object[] os : fields)
            {
                Field field = (Field) os[0];
                Excel excel = (Excel) os[1];
                // 设置实体类私有属性可访问
                field.setAccessible(true);
                this.addCell(excel, row, vo, field, column++);
            }
        }
    }
    /**
     * 创建表格样式
     *
     * @param wb 工作薄对象
     * @return 样式列表
     */
    private Map<String, CellStyle> createStyles(Workbook wb)
    {
        // 写入各条记录,每条记录对应excel表中的一行
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setBorderRight(BorderStyle.THIN);
        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderLeft(BorderStyle.THIN);
        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderTop(BorderStyle.THIN);
        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderBottom(BorderStyle.THIN);
        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        Font dataFont = wb.createFont();
        dataFont.setFontName("Arial");
        dataFont.setFontHeightInPoints((short) 10);
        style.setFont(dataFont);
        styles.put("data", style);
        style = wb.createCellStyle();
        style.cloneStyleFrom(styles.get("data"));
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font headerFont = wb.createFont();
        headerFont.setFontName("Arial");
        headerFont.setFontHeightInPoints((short) 10);
        headerFont.setBold(true);
        headerFont.setColor(IndexedColors.WHITE.getIndex());
        style.setFont(headerFont);
        styles.put("header", style);
        return styles;
    }
    /**
     * 创建单元格
     */
    public Cell createCell(Excel attr, Row row, int column)
    {
        // 创建列
        Cell cell = row.createCell(column);
        // 写入列信息
        cell.setCellValue(attr.name());
        setDataValidation(attr, row, column);
        cell.setCellStyle(styles.get("header"));
        return cell;
    }
    /**
     * 设置单元格信息
     *
     * @param value 单元格值
     * @param attr 注解相关
     * @param cell 单元格信息
     */
    public void setCellVo(Object value, Excel attr, Cell cell)
    {
        if (ColumnType.STRING == attr.cellType())
        {
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
        }
        else if (ColumnType.NUMERIC == attr.cellType())
        {
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(value + ""));
        }
    }
    /**
     * 创建表格样式
     */
    public void setDataValidation(Excel attr, Row row, int column)
    {
        if (attr.name().indexOf("注:") >= 0)
        {
            sheet.setColumnWidth(column, 6000);
        }
        else
        {
            // 设置列宽
            sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
            row.setHeight((short) (attr.height() * 20));
        }
        // 如果设置了提示信息则鼠标放上去提示.
        if (StringUtils.isNotEmpty(attr.prompt()))
        {
            // 这里默认设了2-101列提示.
            setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column);
        }
        // 如果设置了combo属性则本列只能选择不能输入
        if (attr.combo().length > 0)
        {
            // 这里默认设了2-101列只能选择不能输入.
            setXSSFValidation(sheet, attr.combo(), 1, 100, column, column);
        }
    }
    /**
     * 添加单元格
     */
    public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
    {
        Cell cell = null;
        try
        {
            // 设置行高
            row.setHeight((short) (attr.height() * 20));
            // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
            if (attr.isExport())
            {
                // 创建cell
                cell = row.createCell(column);
                cell.setCellStyle(styles.get("data"));
                // 用于读取对象中的属性
                Object value = getTargetValue(vo, field, attr);
                String dateFormat = attr.dateFormat();
                String readConverterExp = attr.readConverterExp();
                if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
                }
                else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
                }
                else
                {
                    // 设置列类型
                    setCellVo(value, attr, cell);
                }
            }
        }
        catch (Exception e)
        {
            log.error("导出Excel失败{}", e);
        }
        return cell;
    }
    /**
     * 设置 POI XSSFSheet 单元格提示
     *
     * @param sheet 表单
     * @param promptTitle 提示标题
     * @param promptContent 提示内容
     * @param firstRow 开始行
     * @param endRow 结束行
     * @param firstCol 开始列
     * @param endCol 结束列
     */
    public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow,
            int firstCol, int endCol)
    {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = helper.createCustomConstraint("DD1");
        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        dataValidation.createPromptBox(promptTitle, promptContent);
        dataValidation.setShowPromptBox(true);
        sheet.addValidationData(dataValidation);
    }
    /**
     * 设置某些列的值只能输入预制的数据,显示下拉框.
     *
     * @param sheet 要设置的sheet.
     * @param textlist 下拉框显示的内容
     * @param firstRow 开始行
     * @param endRow 结束行
     * @param firstCol 开始列
     * @param endCol 结束列
     * @return 设置好的sheet.
     */
    public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol)
    {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        // 加载下拉列表内容
        DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist);
        // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
        // 数据有效性对象
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        // 处理Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation)
        {
            dataValidation.setSuppressDropDownArrow(true);
            dataValidation.setShowErrorBox(true);
        }
        else
        {
            dataValidation.setSuppressDropDownArrow(false);
        }
        sheet.addValidationData(dataValidation);
    }
    /**
     * 解析导出值 0=男,1=女,2=未知
     *
     * @param propertyValue 参数值
     * @param converterExp 翻译注解
     * @return 解析后值
     * @throws Exception
     */
    public static String convertByExp(String propertyValue, String converterExp) throws Exception
    {
        try
        {
            String[] convertSource = converterExp.split(",");
            for (String item : convertSource)
            {
                String[] itemArray = item.split("=");
                if (itemArray[0].equals(propertyValue))
                {
                    return itemArray[1];
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        return propertyValue;
    }
    /**
     * 反向解析值 男=0,女=1,未知=2
     *
     * @param propertyValue 参数值
     * @param converterExp 翻译注解
     * @return 解析后值
     * @throws Exception
     */
    public static String reverseByExp(String propertyValue, String converterExp) throws Exception
    {
        try
        {
            String[] convertSource = converterExp.split(",");
            for (String item : convertSource)
            {
                String[] itemArray = item.split("=");
                if (itemArray[1].equals(propertyValue))
                {
                    return itemArray[0];
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        return propertyValue;
    }
    /**
     * 编码文件名
     */
    public String encodingFilename(String filename)
    {
        filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx";
        return filename;
    }
    /**
     * 获取下载路径
     *
     * @param filename 文件名称
     */
    public String getAbsoluteFile(String filename)
    {
        String downloadPath = RuoYiConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists())
        {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }
    /**
     * 获取bean中的属性值
     *
     * @param vo 实体对象
     * @param field 字段
     * @param excel 注解
     * @return 最终的属性值
     * @throws Exception
     */
    private Object getTargetValue(T vo, Field field, Excel excel) throws Exception
    {
        Object o = field.get(vo);
        if (StringUtils.isNotEmpty(excel.targetAttr()))
        {
            String target = excel.targetAttr();
            if (target.indexOf(".") > -1)
            {
                String[] targets = target.split("[.]");
                for (String name : targets)
                {
                    o = getValue(o, name);
                }
            }
            else
            {
                o = getValue(o, target);
            }
        }
        return o;
    }
    /**
     * 以类的属性的get方法方法形式获取值
     *
     * @param o
     * @param name
     * @return value
     * @throws Exception
     */
    private Object getValue(Object o, String name) throws Exception
    {
        if (StringUtils.isNotEmpty(name))
        {
            Class<?> clazz = o.getClass();
            String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            Method method = clazz.getMethod(methodName);
            o = method.invoke(o);
        }
        return o;
    }
    /**
     * 得到所有定义字段
     */
    private void createExcelField()
    {
        this.fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields)
        {
            // 单注解
            if (field.isAnnotationPresent(Excel.class))
            {
                putToField(field, field.getAnnotation(Excel.class));
            }
            // 多注解
            if (field.isAnnotationPresent(Excels.class))
            {
                Excels attrs = field.getAnnotation(Excels.class);
                Excel[] excels = attrs.value();
                for (Excel excel : excels)
                {
                    putToField(field, excel);
                }
            }
        }
    }
    /**
     * 放到字段集合中
     */
    private void putToField(Field field, Excel attr)
    {
        if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
        {
            this.fields.add(new Object[] { field, attr });
        }
    }
    /**
     * 创建一个工作簿
     */
    public void createWorkbook()
    {
        this.wb = new SXSSFWorkbook(500);
    }
    /**
     * 创建工作表
     *
     * @param sheetNo sheet数量
     * @param index 序号
     */
    public void createSheet(double sheetNo, int index)
    {
        this.sheet = wb.createSheet();
        this.styles = createStyles(wb);
        // 设置工作表的名称.
        if (sheetNo == 0)
        {
            wb.setSheetName(index, sheetName);
        }
        else
        {
            wb.setSheetName(index, sheetName + index);
        }
    }
    /**
     * 获取单元格值
     *
     * @param row 获取的行
     * @param column 获取单元格列号
     * @return 单元格值
     */
    public Object getCellValue(Row row, int column)
    {
        if (row == null)
        {
            return row;
        }
        Object val = "";
        try
        {
            Cell cell = row.getCell(column);
            if (cell != null)
            {
                if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA)
                {
                    val = cell.getNumericCellValue();
                    if (HSSFDateUtil.isCellDateFormatted(cell))
                    {
                        val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
                    }
                    else
                    {
                        if ((Double) val % 1 > 0)
                        {
                            val = new DecimalFormat("0.00").format(val);
                        }
                        else
                        {
                            val = new DecimalFormat("0").format(val);
                        }
                    }
                }
                else if (cell.getCellTypeEnum() == CellType.STRING)
                {
                    val = cell.getStringCellValue();
                }
                else if (cell.getCellTypeEnum() == CellType.BOOLEAN)
                {
                    val = cell.getBooleanCellValue();
                }
                else if (cell.getCellTypeEnum() == CellType.ERROR)
                {
                    val = cell.getErrorCellValue();
                }
            }
        }
        catch (Exception e)
        {
            return val;
        }
        return val;
    }
}
ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
对比新文件
@@ -0,0 +1,406 @@
package com.ruoyi.common.utils.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.poi.ss.usermodel.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
/**
 * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
 *
 * @author ruoyi
 */
@SuppressWarnings("rawtypes")
public class ReflectUtils
{
    private static final String SETTER_PREFIX = "set";
    private static final String GETTER_PREFIX = "get";
    private static final String CGLIB_CLASS_SEPARATOR = "$$";
    private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
    /**
     * 调用Getter方法.
     * 支持多级,如:对象名.对象名.方法
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeGetter(Object obj, String propertyName)
    {
        Object object = obj;
        for (String name : StringUtils.split(propertyName, "."))
        {
            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
            object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
        }
        return (E) object;
    }
    /**
     * 调用Setter方法, 仅匹配方法名。
     * 支持多级,如:对象名.对象名.方法
     */
    public static <E> void invokeSetter(Object obj, String propertyName, E value)
    {
        Object object = obj;
        String[] names = StringUtils.split(propertyName, ".");
        for (int i = 0; i < names.length; i++)
        {
            if (i < names.length - 1)
            {
                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
                object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
            }
            else
            {
                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                invokeMethodByName(object, setterMethodName, new Object[] { value });
            }
        }
    }
    /**
     * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
     */
    @SuppressWarnings("unchecked")
    public static <E> E getFieldValue(final Object obj, final String fieldName)
    {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null)
        {
            logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            return null;
        }
        E result = null;
        try
        {
            result = (E) field.get(obj);
        }
        catch (IllegalAccessException e)
        {
            logger.error("不可能抛出的异常{}", e.getMessage());
        }
        return result;
    }
    /**
     * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
     */
    public static <E> void setFieldValue(final Object obj, final String fieldName, final E value)
    {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null)
        {
            // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            return;
        }
        try
        {
            field.set(obj, value);
        }
        catch (IllegalAccessException e)
        {
            logger.error("不可能抛出的异常: {}", e.getMessage());
        }
    }
    /**
     * 直接调用对象方法, 无视private/protected修饰符.
     * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
     * 同时匹配方法名+参数类型,
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
            final Object[] args)
    {
        if (obj == null || methodName == null)
        {
            return null;
        }
        Method method = getAccessibleMethod(obj, methodName, parameterTypes);
        if (method == null)
        {
            logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
            return null;
        }
        try
        {
            return (E) method.invoke(obj, args);
        }
        catch (Exception e)
        {
            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }
    /**
     * 直接调用对象方法, 无视private/protected修饰符,
     * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
     * 只匹配函数名,如果有多个同名函数调用第一个。
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args)
    {
        Method method = getAccessibleMethodByName(obj, methodName, args.length);
        if (method == null)
        {
            // 如果为空不报错,直接返回空。
            logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
            return null;
        }
        try
        {
            // 类型转换(将参数数据类型转换为目标方法参数类型)
            Class<?>[] cs = method.getParameterTypes();
            for (int i = 0; i < cs.length; i++)
            {
                if (args[i] != null && !args[i].getClass().equals(cs[i]))
                {
                    if (cs[i] == String.class)
                    {
                        args[i] = Convert.toStr(args[i]);
                        if (StringUtils.endsWith((String) args[i], ".0"))
                        {
                            args[i] = StringUtils.substringBefore((String) args[i], ".0");
                        }
                    }
                    else if (cs[i] == Integer.class)
                    {
                        args[i] = Convert.toInt(args[i]);
                    }
                    else if (cs[i] == Long.class)
                    {
                        args[i] = Convert.toLong(args[i]);
                    }
                    else if (cs[i] == Double.class)
                    {
                        args[i] = Convert.toDouble(args[i]);
                    }
                    else if (cs[i] == Float.class)
                    {
                        args[i] = Convert.toFloat(args[i]);
                    }
                    else if (cs[i] == Date.class)
                    {
                        if (args[i] instanceof String)
                        {
                            args[i] = DateUtils.parseDate(args[i]);
                        }
                        else
                        {
                            args[i] = DateUtil.getJavaDate((Double) args[i]);
                        }
                    }
                }
            }
            return (E) method.invoke(obj, args);
        }
        catch (Exception e)
        {
            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }
    /**
     * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
     * 如向上转型到Object仍无法找到, 返回null.
     */
    public static Field getAccessibleField(final Object obj, final String fieldName)
    {
        // 为空不报错。直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(fieldName, "fieldName can't be blank");
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
        {
            try
            {
                Field field = superClass.getDeclaredField(fieldName);
                makeAccessible(field);
                return field;
            }
            catch (NoSuchFieldException e)
            {
                continue;
            }
        }
        return null;
    }
    /**
     * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
     * 如向上转型到Object仍无法找到, 返回null.
     * 匹配函数名+参数类型。
     * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethod(final Object obj, final String methodName,
            final Class<?>... parameterTypes)
    {
        // 为空不报错。直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
        {
            try
            {
                Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
                makeAccessible(method);
                return method;
            }
            catch (NoSuchMethodException e)
            {
                continue;
            }
        }
        return null;
    }
    /**
     * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
     * 如向上转型到Object仍无法找到, 返回null.
     * 只匹配函数名。
     * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum)
    {
        // 为空不报错。直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
        {
            Method[] methods = searchType.getDeclaredMethods();
            for (Method method : methods)
            {
                if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum)
                {
                    makeAccessible(method);
                    return method;
                }
            }
        }
        return null;
    }
    /**
     * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Method method)
    {
        if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
                && !method.isAccessible())
        {
            method.setAccessible(true);
        }
    }
    /**
     * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Field field)
    {
        if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
                || Modifier.isFinal(field.getModifiers())) && !field.isAccessible())
        {
            field.setAccessible(true);
        }
    }
    /**
     * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
     * 如无法找到, 返回Object.class.
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getClassGenricType(final Class clazz)
    {
        return getClassGenricType(clazz, 0);
    }
    /**
     * 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
     * 如无法找到, 返回Object.class.
     */
    public static Class getClassGenricType(final Class clazz, final int index)
    {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType))
        {
            logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0)
        {
            logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
                    + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class))
        {
            logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            return Object.class;
        }
        return (Class) params[index];
    }
    public static Class<?> getUserClass(Object instance)
    {
        if (instance == null)
        {
            throw new RuntimeException("Instance must not be null");
        }
        Class clazz = instance.getClass();
        if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR))
        {
            Class<?> superClass = clazz.getSuperclass();
            if (superClass != null && !Object.class.equals(superClass))
            {
                return superClass;
            }
        }
        return clazz;
    }
    /**
     * 将反射时的checked exception转换为unchecked exception.
     */
    public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e)
    {
        if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
                || e instanceof NoSuchMethodException)
        {
            return new IllegalArgumentException(msg, e);
        }
        else if (e instanceof InvocationTargetException)
        {
            return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());
        }
        return new RuntimeException(msg, e);
    }
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java
对比新文件
@@ -0,0 +1,113 @@
package com.ruoyi.framework.aspectj.lang.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 自定义导出Excel数据注解
 *
 * @author ruoyi
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{
    /**
     * 导出到Excel中的名字.
     */
    public String name() default "";
    /**
     * 日期格式, 如: yyyy-MM-dd
     */
    public String dateFormat() default "";
    /**
     * 读取内容转表达式 (如: 0=男,1=女,2=未知)
     */
    public String readConverterExp() default "";
    /**
     * 导出类型(0数字 1字符串)
     */
    public ColumnType cellType() default ColumnType.STRING;
    /**
     * 导出时在excel中每个列的高度 单位为字符
     */
    public double height() default 14;
    /**
     * 导出时在excel中每个列的宽 单位为字符
     */
    public double width() default 16;
    /**
     * 文字后缀,如% 90 变成90%
     */
    public String suffix() default "";
    /**
     * 当值为空时,字段的默认值
     */
    public String defaultValue() default "";
    /**
     * 提示信息
     */
    public String prompt() default "";
    /**
     * 设置只能选择不能输入的列内容.
     */
    public String[] combo() default {};
    /**
     * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
     */
    public boolean isExport() default true;
    /**
     * 另一个类中的属性名称,支持多级获取,以小数点隔开
     */
    public String targetAttr() default "";
    /**
     * 字段类型(0:导出导入;1:仅导出;2:仅导入)
     */
    Type type() default Type.ALL;
    public enum Type
    {
        ALL(0), EXPORT(1), IMPORT(2);
        private final int value;
        Type(int value)
        {
            this.value = value;
        }
        public int value()
        {
            return this.value;
        }
    }
    public enum ColumnType
    {
        NUMERIC(0), STRING(1);
        private final int value;
        ColumnType(int value)
        {
            this.value = value;
        }
        public int value()
        {
            return this.value;
        }
    }
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java
对比新文件
@@ -0,0 +1,18 @@
package com.ruoyi.framework.aspectj.lang.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Excel注解集
 *
 * @author ruoyi
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
    Excel[] value();
}
ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -98,6 +98,7 @@
                        "/**/*.js"
                ).permitAll()
                .antMatchers("/profile/**").anonymous()
                .antMatchers("/common/download**").anonymous()
                .antMatchers("/swagger-ui.html").anonymous()
                .antMatchers("/swagger-resources/**").anonymous()
                .antMatchers("/webjars/**").anonymous()
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
@@ -1,5 +1,7 @@
package com.ruoyi.framework.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -8,8 +10,12 @@
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@@ -33,6 +39,7 @@
    public Docket createRestApi()
    {
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/dev-api")
                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
                .apiInfo(apiInfo())
                // 设置哪些接口暴露给Swagger展示
@@ -43,7 +50,47 @@
                //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
                // 扫描所有 .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
                .build()
                /* 设置安全模式,swagger可以设置访问token */
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }
    /**
     * 安全模式,这里指定token通过Authorization头请求头传递
     */
    private List<ApiKey> securitySchemes()
    {
        List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
        return apiKeyList;
    }
    /**
     * 安全上下文
     */
    private List<SecurityContext> securityContexts()
    {
        List<SecurityContext> securityContexts = new ArrayList<>();
        securityContexts.add(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.regex("^(?!auth).*$"))
                        .build());
        return securityContexts;
    }
    /**
     * 默认的安全上引用
     */
    private List<SecurityReference> defaultAuth()
    {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences = new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }
    /**
@@ -54,7 +101,7 @@
        // 用ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                // 设置标题
                .title("标题:余心管理系统_接口文档")
                .title("标题:若依管理系统_接口文档")
                // 描述
                .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
                // 作者信息
ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
@@ -5,6 +5,8 @@
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
@@ -83,6 +85,28 @@
    }
    /**
     * 自定义验证异常
     */
    @ExceptionHandler(BindException.class)
    public AjaxResult validatedBindException(BindException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return AjaxResult.error(message);
    }
    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object validExceptionHandler(MethodArgumentNotValidException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return AjaxResult.error(message);
    }
    /**
     * 演示模式异常
     */
    @ExceptionHandler(DemoModeException.class)
ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java
@@ -1,10 +1,17 @@
package com.ruoyi.project.common;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.framework.web.domain.AjaxResult;
@@ -17,10 +24,46 @@
@RestController
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);
    @Autowired
    private ServerConfig serverConfig;
    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("common/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.isValidFilename(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }
    /**
     * 通用上传请求
     */
    @PostMapping("/common/upload")
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java
@@ -3,10 +3,16 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.monitor.domain.SysLogininfor;
import com.ruoyi.project.monitor.service.ISysLogininforService;
@@ -31,4 +37,31 @@
        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
        return getDataTable(list);
    }
    @Log(title = "登陆日志", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
    @GetMapping("/export")
    public AjaxResult export(SysLogininfor logininfor)
    {
        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
        ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
        return util.exportExcel(list, "登陆日志");
    }
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
    @Log(title = "登陆日志", businessType = BusinessType.DELETE)
    @DeleteMapping("/{infoIds}")
    public AjaxResult remove(@PathVariable Long[] infoIds)
    {
        return toAjax(logininforService.deleteLogininforByIds(infoIds));
    }
    @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
    @Log(title = "登陆日志", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clean")
    public AjaxResult clean()
    {
        logininforService.cleanLogininfor();
        return AjaxResult.success();
    }
}
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java
@@ -3,10 +3,16 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.monitor.domain.SysOperLog;
import com.ruoyi.project.monitor.service.ISysOperLogService;
@@ -31,4 +37,30 @@
        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
        return getDataTable(list);
    }
    @Log(title = "操作日志", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
    @GetMapping("/export")
    public AjaxResult export(SysOperLog operLog)
    {
        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
        ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
        return util.exportExcel(list, "操作日志");
    }
    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
    @DeleteMapping("/{operIds}")
    public AjaxResult remove(@PathVariable Long[] operIds)
    {
        return toAjax(operLogService.deleteOperLogByIds(operIds));
    }
    @Log(title = "操作日志", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
    @DeleteMapping("/clean")
    public AjaxResult clean()
    {
        operLogService.cleanOperLog();
        return AjaxResult.success();
    }
}
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java
@@ -1,6 +1,8 @@
package com.ruoyi.project.monitor.domain;
import java.util.Date;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -13,30 +15,39 @@
    private static final long serialVersionUID = 1L;
    /** ID */
    @Excel(name = "序号", cellType = ColumnType.NUMERIC)
    private Long infoId;
    /** 用户账号 */
    @Excel(name = "用户账号")
    private String userName;
    /** 登录状态 0成功 1失败 */
    @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
    private String status;
    /** 登录IP地址 */
    @Excel(name = "登录地址")
    private String ipaddr;
    /** 登录地点 */
    @Excel(name = "登录地点")
    private String loginLocation;
    /** 浏览器类型 */
    @Excel(name = "浏览器")
    private String browser;
    /** 操作系统 */
    @Excel(name = "操作系统")
    private String os;
    /** 提示消息 */
    @Excel(name = "提示消息")
    private String msg;
    /** 访问时间 */
    @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date loginTime;
    public Long getInfoId()
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java
@@ -1,6 +1,8 @@
package com.ruoyi.project.monitor.domain;
import java.util.Date;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -13,54 +15,70 @@
    private static final long serialVersionUID = 1L;
    /** 日志主键 */
    @Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
    private Long operId;
    /** 操作模块 */
    @Excel(name = "操作模块")
    private String title;
    /** 业务类型(0其它 1新增 2修改 3删除) */
    @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
    private Integer businessType;
    /** 业务类型数组 */
    private Integer[] businessTypes;
    /** 请求方法 */
    @Excel(name = "请求方法")
    private String method;
    /** 请求方式 */
    @Excel(name = "请求方式")
    private String requestMethod;
    /** 操作类别(0其它 1后台用户 2手机端用户) */
    @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
    private Integer operatorType;
    /** 操作人员 */
    @Excel(name = "操作人员")
    private String operName;
    /** 部门名称 */
    @Excel(name = "部门名称")
    private String deptName;
    /** 请求url */
    @Excel(name = "请求地址")
    private String operUrl;
    /** 操作地址 */
    @Excel(name = "操作地址")
    private String operIp;
    /** 操作地点 */
    @Excel(name = "操作地点")
    private String operLocation;
    /** 请求参数 */
    @Excel(name = "请求参数")
    private String operParam;
    /** 返回参数 */
    @Excel(name = "返回参数")
    private String jsonResult;
    /** 操作状态(0正常 1异常) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=异常")
    private Integer status;
    /** 错误消息 */
    @Excel(name = "错误消息")
    private String errorMsg;
    /** 操作时间 */
    @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date operTime;
    public Long getOperId()
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java
@@ -28,10 +28,10 @@
    /**
     * 批量删除系统登录日志
     * 
     * @param ids 需要删除的数据
     * @param infoIds 需要删除的登录日志ID
     * @return 结果
     */
    public int deleteLogininforByIds(String[] ids);
    public int deleteLogininforByIds(Long[] infoIds);
    /**
     * 清空系统登录日志
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java
@@ -28,10 +28,10 @@
    /**
     * 批量删除系统操作日志
     * 
     * @param ids 需要删除的数据
     * @param operIds 需要删除的操作日志ID
     * @return 结果
     */
    public int deleteOperLogByIds(String[] ids);
    public int deleteOperLogByIds(Long[] operIds);
    /**
     * 查询操作日志详细
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java
@@ -28,10 +28,10 @@
    /**
     * 批量删除系统登录日志
     * 
     * @param ids 需要删除的数据
     * @param infoIds 需要删除的登录日志ID
     * @return
     */
    public int deleteLogininforByIds(String ids);
    public int deleteLogininforByIds(Long[] infoIds);
    /**
     * 清空系统登录日志
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java
@@ -28,10 +28,10 @@
    /**
     * 批量删除系统操作日志
     * 
     * @param ids 需要删除的数据
     * @param operIds 需要删除的操作日志ID
     * @return 结果
     */
    public int deleteOperLogByIds(String ids);
    public int deleteOperLogByIds(Long[] operIds);
    /**
     * 查询操作日志详细
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java
@@ -3,7 +3,6 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.project.monitor.domain.SysLogininfor;
import com.ruoyi.project.monitor.mapper.SysLogininforMapper;
import com.ruoyi.project.monitor.service.ISysLogininforService;
@@ -46,13 +45,13 @@
    /**
     * 批量删除系统登录日志
     * 
     * @param ids 需要删除的数据
     * @param infoIds 需要删除的登录日志ID
     * @return
     */
    @Override
    public int deleteLogininforByIds(String ids)
    public int deleteLogininforByIds(Long[] infoIds)
    {
        return logininforMapper.deleteLogininforByIds(Convert.toStrArray(ids));
        return logininforMapper.deleteLogininforByIds(infoIds);
    }
    /**
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java
@@ -3,7 +3,6 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.project.monitor.domain.SysOperLog;
import com.ruoyi.project.monitor.mapper.SysOperLogMapper;
import com.ruoyi.project.monitor.service.ISysOperLogService;
@@ -45,13 +44,12 @@
    /**
     * 批量删除系统操作日志
     * 
     * @param ids 需要删除的数据
     * @return
     * @param operIds 需要删除的操作日志ID
     * @return 结果
     */
    @Override
    public int deleteOperLogByIds(String ids)
    public int deleteOperLogByIds(Long[] operIds)
    {
        return operLogMapper.deleteOperLogByIds(Convert.toStrArray(ids));
        return operLogMapper.deleteOperLogByIds(operIds);
    }
    /**
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
@@ -45,6 +47,16 @@
        return getDataTable(list);
    }
    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:config:export')")
    @GetMapping("/export")
    public AjaxResult export(SysConfig config)
    {
        List<SysConfig> list = configService.selectConfigList(config);
        ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
        return util.exportExcel(list, "参数数据");
    }
    /**
     * 根据参数编号获取详细信息
     */
@@ -71,7 +83,7 @@
    @PreAuthorize("@ss.hasPermi('system:config:add')")
    @Log(title = "参数管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysConfig config)
    public AjaxResult add(@Validated @RequestBody SysConfig config)
    {
        if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
        {
@@ -87,7 +99,7 @@
    @PreAuthorize("@ss.hasPermi('system:config:edit')")
    @Log(title = "参数管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysConfig config)
    public AjaxResult edit(@Validated @RequestBody SysConfig config)
    {
        if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
        {
@@ -102,9 +114,9 @@
     */
    @PreAuthorize("@ss.hasPermi('system:config:remove')")
    @Log(title = "参数管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{configId}")
    public AjaxResult remove(@PathVariable Long configId)
    @DeleteMapping("/{configIds}")
    public AjaxResult remove(@PathVariable Long[] configIds)
    {
        return toAjax(configService.deleteConfigById(configId));
        return toAjax(configService.deleteConfigByIds(configIds));
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -10,7 +11,6 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
@@ -70,7 +70,6 @@
     */
    @PreAuthorize("@ss.hasPermi('system:dept:query')")
    @GetMapping(value = "/roleDeptTreeselect/{roleId}")
    @ResponseBody
    public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId)
    {
        return AjaxResult.success(deptService.selectDeptListByRoleId(roleId));
@@ -82,7 +81,7 @@
    @PreAuthorize("@ss.hasPermi('system:dept:add')")
    @Log(title = "部门管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysDept dept)
    public AjaxResult add(@Validated @RequestBody SysDept dept)
    {
        if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
        {
@@ -98,7 +97,7 @@
    @PreAuthorize("@ss.hasPermi('system:dept:edit')")
    @Log(title = "部门管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysDept dept)
    public AjaxResult edit(@Validated @RequestBody SysDept dept)
    {
        if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
        {
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -10,9 +11,9 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
@@ -35,12 +36,21 @@
    @PreAuthorize("@ss.hasPermi('system:dict:list')")
    @GetMapping("/list")
    @ResponseBody
    public TableDataInfo list(SysDictData dictData)
    {
        startPage();
        List<SysDictData> list = dictDataService.selectDictDataList(dictData);
        return getDataTable(list);
    }
    @Log(title = "字典数据", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:dict:export')")
    @GetMapping("/export")
    public AjaxResult export(SysDictData dictData)
    {
        List<SysDictData> list = dictDataService.selectDictDataList(dictData);
        ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
        return util.exportExcel(list, "字典数据");
    }
    /**
@@ -69,7 +79,7 @@
    @PreAuthorize("@ss.hasPermi('system:dict:add')")
    @Log(title = "字典数据", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysDictData dict)
    public AjaxResult add(@Validated @RequestBody SysDictData dict)
    {
        dict.setCreateBy(SecurityUtils.getUsername());
        return toAjax(dictDataService.insertDictData(dict));
@@ -81,7 +91,7 @@
    @PreAuthorize("@ss.hasPermi('system:dict:edit')")
    @Log(title = "字典数据", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysDictData dict)
    public AjaxResult edit(@Validated @RequestBody SysDictData dict)
    {
        dict.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(dictDataService.updateDictData(dict));
@@ -92,9 +102,9 @@
     */
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @Log(title = "字典类型", businessType = BusinessType.DELETE)
    @DeleteMapping("/{dictCode}")
    public AjaxResult remove(@PathVariable Long dictCode)
    @DeleteMapping("/{dictCodes}")
    public AjaxResult remove(@PathVariable Long[] dictCodes)
    {
        return toAjax(dictDataService.deleteDictDataById(dictCode));
        return toAjax(dictDataService.deleteDictDataByIds(dictCodes));
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -10,10 +11,10 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
@@ -36,12 +37,21 @@
    @PreAuthorize("@ss.hasPermi('system:dict:list')")
    @GetMapping("/list")
    @ResponseBody
    public TableDataInfo list(SysDictType dictType)
    {
        startPage();
        List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
        return getDataTable(list);
    }
    @Log(title = "字典类型", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:dict:export')")
    @GetMapping("/export")
    public AjaxResult export(SysDictType dictType)
    {
        List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
        ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
        return util.exportExcel(list, "字典类型");
    }
    /**
@@ -60,7 +70,7 @@
    @PreAuthorize("@ss.hasPermi('system:dict:add')")
    @Log(title = "字典类型", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysDictType dict)
    public AjaxResult add(@Validated @RequestBody SysDictType dict)
    {
        if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
        {
@@ -76,7 +86,7 @@
    @PreAuthorize("@ss.hasPermi('system:dict:edit')")
    @Log(title = "字典类型", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysDictType dict)
    public AjaxResult edit(@Validated @RequestBody SysDictType dict)
    {
        if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
        {
@@ -91,9 +101,9 @@
     */
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @Log(title = "字典类型", businessType = BusinessType.DELETE)
    @DeleteMapping("/{dictId}")
    public AjaxResult remove(@PathVariable Long dictId)
    @DeleteMapping("/{dictIds}")
    public AjaxResult remove(@PathVariable Long[] dictIds)
    {
        return toAjax(dictTypeService.deleteDictTypeById(dictId));
        return toAjax(dictTypeService.deleteDictTypeByIds(dictIds));
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java
@@ -11,7 +11,6 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
@@ -71,7 +70,6 @@
     */
    @PreAuthorize("@ss.hasPermi('system:menu:query')")
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    @ResponseBody
    public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
    {
        return AjaxResult.success(menuService.selectMenuListByRoleId(roleId));
@@ -83,7 +81,7 @@
    @PreAuthorize("@ss.hasPermi('system:menu:add')")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody @Validated SysMenu menu)
    public AjaxResult add(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
        {
@@ -99,7 +97,7 @@
    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysMenu menu)
    public AjaxResult edit(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
        {
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -60,7 +61,7 @@
    @PreAuthorize("@ss.hasPermi('system:notice:add')")
    @Log(title = "通知公告", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysNotice notice)
    public AjaxResult add(@Validated @RequestBody SysNotice notice)
    {
        notice.setCreateBy(SecurityUtils.getUsername());
        return toAjax(noticeService.insertNotice(notice));
@@ -72,7 +73,7 @@
    @PreAuthorize("@ss.hasPermi('system:notice:edit')")
    @Log(title = "通知公告", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysNotice notice)
    public AjaxResult edit(@Validated @RequestBody SysNotice notice)
    {
        notice.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(noticeService.updateNotice(notice));
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
@@ -44,6 +46,16 @@
        List<SysPost> list = postService.selectPostList(post);
        return getDataTable(list);
    }
    @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:config:export')")
    @GetMapping("/export")
    public AjaxResult export(SysPost post)
    {
        List<SysPost> list = postService.selectPostList(post);
        ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
        return util.exportExcel(list, "岗位数据");
    }
    /**
     * 根据岗位编号获取详细信息
@@ -61,7 +73,7 @@
    @PreAuthorize("@ss.hasPermi('system:post:add')")
    @Log(title = "岗位管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysPost post)
    public AjaxResult add(@Validated @RequestBody SysPost post)
    {
        if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
        {
@@ -81,7 +93,7 @@
    @PreAuthorize("@ss.hasPermi('system:post:edit')")
    @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysPost post)
    public AjaxResult edit(@Validated @RequestBody SysPost post)
    {
        if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
        {
@@ -100,10 +112,10 @@
     */
    @PreAuthorize("@ss.hasPermi('system:post:remove')")
    @Log(title = "岗位管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{postId}")
    public AjaxResult remove(@PathVariable Long postId)
    @DeleteMapping("/{postIds}")
    public AjaxResult remove(@PathVariable Long[] postIds)
    {
        return toAjax(postService.deletePostById(postId));
        return toAjax(postService.deletePostByIds(postIds));
    }
    /**
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
@@ -42,6 +44,16 @@
        return getDataTable(list);
    }
    @Log(title = "角色管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:role:export')")
    @GetMapping("/export")
    public AjaxResult export(SysRole role)
    {
        List<SysRole> list = roleService.selectRoleList(role);
        ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
        return util.exportExcel(list, "角色数据");
    }
    /**
     * 根据角色编号获取详细信息
     */
@@ -58,7 +70,7 @@
    @PreAuthorize("@ss.hasPermi('system:role:add')")
    @Log(title = "角色管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysRole role)
    public AjaxResult add(@Validated @RequestBody SysRole role)
    {
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
        {
@@ -79,7 +91,7 @@
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysRole role)
    public AjaxResult edit(@Validated @RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
@@ -120,15 +132,14 @@
    }
    /**
     * 删除岗位
     * 删除角色
     */
    @PreAuthorize("@ss.hasPermi('system:role:remove')")
    @Log(title = "角色管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{roleId}")
    public AjaxResult remove(@PathVariable Long roleId)
    @DeleteMapping("/{roleIds}")
    public AjaxResult remove(@PathVariable Long[] roleIds)
    {
        roleService.checkRoleAllowed(new SysRole(roleId));
        return toAjax(roleService.deleteRoleById(roleId));
        return toAjax(roleService.deleteRoleByIds(roleIds));
    }
    /**
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
@@ -53,6 +55,16 @@
        return getDataTable(list);
    }
    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:user:export')")
    @GetMapping("/export")
    public AjaxResult export(SysUser user)
    {
        List<SysUser> list = userService.selectUserList(user);
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.exportExcel(list, "用户数据");
    }
    /**
     * 根据用户编号获取详细信息
     */
@@ -72,7 +84,7 @@
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysUser user)
    public AjaxResult add(@Validated @RequestBody SysUser user)
    {
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
        {
@@ -97,7 +109,7 @@
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysUser user)
    public AjaxResult edit(@Validated @RequestBody SysUser user)
    {
        userService.checkUserAllowed(user);
        if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
@@ -117,11 +129,10 @@
     */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userId}")
    public AjaxResult remove(@PathVariable Long userId)
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds)
    {
        userService.checkUserAllowed(new SysUser(userId));
        return toAjax(userService.deleteUserById(userId));
        return toAjax(userService.deleteUserByIds(userIds));
    }
    /**
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java
@@ -2,6 +2,10 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -14,18 +18,23 @@
    private static final long serialVersionUID = 1L;
    /** 参数主键 */
    @Excel(name = "参数主键", cellType = ColumnType.NUMERIC)
    private Long configId;
    /** 参数名称 */
    @Excel(name = "参数名称")
    private String configName;
    /** 参数键名 */
    @Excel(name = "参数键名")
    private String configKey;
    /** 参数键值 */
    @Excel(name = "参数键值")
    private String configValue;
    /** 系统内置(Y是 N否) */
    @Excel(name = "系统内置", readConverterExp = "Y=是,N=否")
    private String configType;
    public Long getConfigId()
@@ -83,4 +92,20 @@
    {
        this.configType = configType;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("configId", getConfigId())
            .append("configName", getConfigName())
            .append("configKey", getConfigKey())
            .append("configValue", getConfigValue())
            .append("configType", getConfigType())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java
@@ -2,6 +2,11 @@
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -45,7 +50,7 @@
    /** 父部门名称 */
    private String parentName;
    /** 子部门 */
    private List<SysDept> children = new ArrayList<SysDept>();
@@ -79,6 +84,8 @@
        this.ancestors = ancestors;
    }
    @NotBlank(message = "部门名称不能为空")
    @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
    public String getDeptName()
    {
        return deptName;
@@ -89,6 +96,7 @@
        this.deptName = deptName;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getOrderNum()
    {
        return orderNum;
@@ -109,6 +117,7 @@
        this.leader = leader;
    }
    @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
    public String getPhone()
    {
        return phone;
@@ -119,6 +128,8 @@
        this.phone = phone;
    }
    @Email(message = "邮箱格式不正确")
    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
    public String getEmail()
    {
        return email;
@@ -168,4 +179,24 @@
    {
        this.children = children;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("deptId", getDeptId())
            .append("parentId", getParentId())
            .append("ancestors", getAncestors())
            .append("deptName", getDeptName())
            .append("orderNum", getOrderNum())
            .append("leader", getLeader())
            .append("phone", getPhone())
            .append("email", getEmail())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java
@@ -2,7 +2,11 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -15,18 +19,23 @@
    private static final long serialVersionUID = 1L;
    /** 字典编码 */
    @Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
    private Long dictCode;
    /** 字典排序 */
    @Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
    private Long dictSort;
    /** 字典标签 */
    @Excel(name = "字典标签")
    private String dictLabel;
    /** 字典键值 */
    @Excel(name = "字典键值")
    private String dictValue;
    /** 字典类型 */
    @Excel(name = "字典类型")
    private String dictType;
    /** 样式属性(其他样式扩展) */
@@ -36,9 +45,11 @@
    private String listClass;
    /** 是否默认(Y是 N否) */
    @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
    private String isDefault;
    /** 状态(0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    public Long getDictCode()
@@ -142,4 +153,24 @@
    {
        this.status = status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("dictCode", getDictCode())
            .append("dictSort", getDictSort())
            .append("dictLabel", getDictLabel())
            .append("dictValue", getDictValue())
            .append("dictType", getDictType())
            .append("cssClass", getCssClass())
            .append("listClass", getListClass())
            .append("isDefault", getIsDefault())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java
@@ -2,6 +2,10 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -14,15 +18,19 @@
    private static final long serialVersionUID = 1L;
    /** 字典主键 */
    @Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
    private Long dictId;
    /** 字典名称 */
    @Excel(name = "字典名称")
    private String dictName;
    /** 字典类型 */
    @Excel(name = "字典类型")
    private String dictType;
    /** 状态(0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    public Long getDictId()
@@ -68,4 +76,19 @@
    {
        this.status = status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("dictId", getDictId())
            .append("dictName", getDictName())
            .append("dictType", getDictType())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
@@ -1,8 +1,12 @@
package com.ruoyi.project.system.domain;
import java.util.List;
import com.ruoyi.framework.web.domain.BaseEntity;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
 * 菜单权限表 sys_menu
@@ -62,6 +66,8 @@
        this.menuId = menuId;
    }
    @NotBlank(message = "菜单名称不能为空")
    @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
    public String getMenuName()
    {
        return menuName;
@@ -92,6 +98,7 @@
        this.parentId = parentId;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getOrderNum()
    {
        return orderNum;
@@ -102,6 +109,7 @@
        this.orderNum = orderNum;
    }
    @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
    public String getPath()
    {
        return path;
@@ -112,6 +120,7 @@
        this.path = path;
    }
    @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
    public String getComponent()
    {
        return component;
@@ -132,6 +141,7 @@
        this.isFrame = isFrame;
    }
    @NotBlank(message = "菜单类型不能为空")
    public String getMenuType()
    {
        return menuType;
@@ -152,6 +162,7 @@
        this.visible = visible;
    }
    @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
    public String getPerms()
    {
        return perms;
@@ -181,4 +192,26 @@
    {
        this.children = children;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("menuId", getMenuId())
            .append("menuName", getMenuName())
            .append("parentId", getParentId())
            .append("orderNum", getOrderNum())
            .append("path", getPath())
            .append("component", getComponent())
            .append("isFrame", getIsFrame())
            .append("menuType", getMenuType())
            .append("visible", getVisible())
            .append("perms", getPerms())
            .append("icon", getIcon())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
@@ -1,5 +1,9 @@
package com.ruoyi.project.system.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -41,6 +45,8 @@
        this.noticeTitle = noticeTitle;
    }
    @NotBlank(message = "公告标题不能为空")
    @Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
    public String getNoticeTitle()
    {
        return noticeTitle;
@@ -75,4 +81,20 @@
    {
        return status;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("noticeId", getNoticeId())
            .append("noticeTitle", getNoticeTitle())
            .append("noticeType", getNoticeType())
            .append("noticeContent", getNoticeContent())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java
@@ -2,6 +2,10 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -14,18 +18,23 @@
    private static final long serialVersionUID = 1L;
    /** 岗位序号 */
    @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC)
    private Long postId;
    /** 岗位编码 */
    @Excel(name = "岗位编码")
    private String postCode;
    /** 岗位名称 */
    @Excel(name = "岗位名称")
    private String postName;
    /** 岗位排序 */
    @Excel(name = "岗位排序")
    private String postSort;
    /** 状态(0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** 用户是否存在此岗位标识 默认不存在 */
@@ -95,4 +104,20 @@
    {
        this.flag = flag;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("postId", getPostId())
            .append("postCode", getPostCode())
            .append("postName", getPostName())
            .append("postSort", getPostSort())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java
@@ -1,5 +1,11 @@
package com.ruoyi.project.system.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -12,21 +18,27 @@
    private static final long serialVersionUID = 1L;
    /** 角色ID */
    @Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
    private Long roleId;
    /** 角色名称 */
    @Excel(name = "角色名称")
    private String roleName;
    /** 角色权限 */
    @Excel(name = "角色权限")
    private String roleKey;
    /** 角色排序 */
    @Excel(name = "角色排序")
    private String roleSort;
    /** 数据范围 */
    /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限) */
    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限")
    private String dataScope;
    /** 角色状态(0正常 1停用) */
    @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** 删除标志(0代表存在 2代表删除) */
@@ -71,6 +83,8 @@
        return roleId != null && 1L == roleId;
    }
    @NotBlank(message = "角色名称不能为空")
    @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
    public String getRoleName()
    {
        return roleName;
@@ -81,6 +95,8 @@
        this.roleName = roleName;
    }
    @NotBlank(message = "权限字符不能为空")
    @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
    public String getRoleKey()
    {
        return roleKey;
@@ -91,6 +107,7 @@
        this.roleKey = roleKey;
    }
    @NotBlank(message = "显示顺序不能为空")
    public String getRoleSort()
    {
        return roleSort;
@@ -160,4 +177,21 @@
    {
        this.deptIds = deptIds;
    }
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("roleId", getRoleId())
            .append("roleName", getRoleName())
            .append("roleKey", getRoleKey())
            .append("roleSort", getRoleSort())
            .append("dataScope", getDataScope())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java
@@ -2,6 +2,14 @@
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.aspectj.lang.annotation.Excels;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
@@ -14,24 +22,30 @@
    private static final long serialVersionUID = 1L;
    /** 用户ID */
    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
    private Long userId;
    /** 部门ID */
    private Long deptId;
    /** 用户账号 */
    @Excel(name = "登录名称")
    private String userName;
    /** 用户昵称 */
    @Excel(name = "用户名称")
    private String nickName;
    /** 用户邮箱 */
    @Excel(name = "用户邮箱")
    private String email;
    /** 手机号码 */
    @Excel(name = "手机号码")
    private String phonenumber;
    /** 用户性别 */
    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
    private String sex;
    /** 用户头像 */
@@ -44,18 +58,22 @@
    private String salt;
    /** 帐号状态(0正常 1停用) */
    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** 删除标志(0代表存在 2代表删除) */
    private String delFlag;
    /** 最后登陆IP */
    @Excel(name = "最后登陆IP")
    private String loginIp;
    /** 最后登陆时间 */
    @Excel(name = "最后登陆时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date loginDate;
    /** 部门对象 */
    @Excels({ @Excel(name = "部门名称", targetAttr = "deptName"), @Excel(name = "部门负责人", targetAttr = "leader") })
    private SysDept dept;
    /** 角色对象 */
@@ -107,6 +125,7 @@
        this.deptId = deptId;
    }
    @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
    public String getNickName()
    {
        return nickName;
@@ -117,6 +136,8 @@
        this.nickName = nickName;
    }
    @NotBlank(message = "用户账号不能为空")
    @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
    public String getUserName()
    {
        return userName;
@@ -127,6 +148,8 @@
        this.userName = userName;
    }
    @Email(message = "邮箱格式不正确")
    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
    public String getEmail()
    {
        return email;
@@ -137,6 +160,7 @@
        this.email = email;
    }
    @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
    public String getPhonenumber()
    {
        return phonenumber;
@@ -266,5 +290,30 @@
    {
        this.postIds = postIds;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("userId", getUserId())
            .append("deptId", getDeptId())
            .append("userName", getUserName())
            .append("nickName", getNickName())
            .append("email", getEmail())
            .append("phonenumber", getPhonenumber())
            .append("sex", getSex())
            .append("avatar", getAvatar())
            .append("password", getPassword())
            .append("salt", getSalt())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("loginIp", getLoginIp())
            .append("loginDate", getLoginDate())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .append("dept", getDept())
            .toString();
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java
@@ -53,8 +53,16 @@
    /**
     * 删除参数配置
     * 
     * @param configId 需要删除的数据ID
     * @param configId 参数ID
     * @return 结果
     */
    public int deleteConfigById(Long configId);
    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     * @return 结果
     */
    public int deleteConfigByIds(Long[] configIds);
}
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java
@@ -61,6 +61,14 @@
    public int deleteDictDataById(Long dictCode);
    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 需要删除的字典数据ID
     * @return 结果
     */
    public int deleteDictDataByIds(Long[] dictCodes);
    /**
     * 新增字典数据信息
     * 
     * @param dictData 字典数据信息
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java
@@ -52,6 +52,14 @@
    public int deleteDictTypeById(Long dictId);
    /**
     * 批量删除字典类型信息
     *
     * @param dictIds 需要删除的字典ID
     * @return 结果
     */
    public int deleteDictTypeByIds(Long[] dictIds);
    /**
     * 新增字典类型信息
     * 
     * @param dictType 字典类型信息
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java
@@ -49,4 +49,12 @@
     * @return 结果
     */
    public int deleteNoticeById(Long noticeId);
    /**
     * 批量删除公告信息
     *
     * @param noticeIds 需要删除的公告ID
     * @return 结果
     */
    public int deleteNoticeByIds(Long noticeIds);
}
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java
@@ -58,6 +58,14 @@
    public int deletePostById(Long postId);
    /**
     * 批量删除岗位信息
     *
     * @param postIds 需要删除的岗位ID
     * @return 结果
     */
    public int deletePostByIds(Long[] postIds);
    /**
     * 修改岗位信息
     * 
     * @param post 岗位信息
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java
@@ -97,4 +97,11 @@
     */
    public int deleteRoleById(Long roleId);
    /**
     * 批量删除角色信息
     *
     * @param roleIds 需要删除的角色ID
     * @return 结果
     */
    public int deleteRoleByIds(Long[] roleIds);
}
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
@@ -80,6 +80,14 @@
    public int deleteUserById(Long userId);
    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    public int deleteUserByIds(Long[] userIds);
    /**
     * 校验用户名称是否唯一
     * 
     * @param userName 用户名称
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java
@@ -53,12 +53,20 @@
    /**
     * 删除参数配置信息
     * 
     * @param configId 需要删除的数据ID
     * @param configId 参数ID
     * @return 结果
     */
    public int deleteConfigById(Long configId);
    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     * @return 结果
     */
    public int deleteConfigByIds(Long[] configIds);
    /**
     * 校验参数键名是否唯一
     * 
     * @param config 参数信息
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java
@@ -52,6 +52,14 @@
    public int deleteDictDataById(Long dictCode);
    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 需要删除的字典数据ID
     * @return 结果
     */
    public int deleteDictDataByIds(Long[] dictCodes);
    /**
     * 新增保存字典数据信息
     * 
     * @param dictData 字典数据信息
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java
@@ -50,6 +50,14 @@
    public int deleteDictTypeById(Long dictId);
    /**
     * 批量删除字典信息
     *
     * @param dictIds 需要删除的字典ID
     * @return 结果
     */
    public int deleteDictTypeByIds(Long[] dictIds);
    /**
     * 新增保存字典类型信息
     * 
     * @param dictType 字典类型信息
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
@@ -49,4 +49,12 @@
     * @return 结果
     */
    public int deleteNoticeById(Long noticeId);
    /**
     * 批量删除公告信息
     *
     * @param noticeIds 需要删除的公告ID
     * @return 结果
     */
    public int deleteNoticeByIds(Long noticeIds);
}
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java
@@ -58,6 +58,14 @@
    public String checkPostCodeUnique(SysPost post);
    /**
     * 通过岗位ID查询岗位使用数量
     *
     * @param postId 岗位ID
     * @return 结果
     */
    public int countUserPostById(Long postId);
    /**
     * 删除岗位信息
     * 
     * @param postId 岗位ID
@@ -66,6 +74,15 @@
    public int deletePostById(Long postId);
    /**
     * 批量删除岗位信息
     *
     * @param postIds 需要删除的岗位ID
     * @return 结果
     * @throws Exception 异常
     */
    public int deletePostByIds(Long[] postIds);
    /**
     * 新增保存岗位信息
     * 
     * @param post 岗位信息
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java
@@ -74,6 +74,14 @@
    public void checkRoleAllowed(SysRole role);
    /**
     * 通过角色ID查询角色使用数量
     *
     * @param roleId 角色ID
     * @return 结果
     */
    public int countUserRoleByRoleId(Long roleId);
    /**
     * 新增保存角色信息
     * 
     * @param role 角色信息
@@ -112,4 +120,12 @@
     * @return 结果
     */
    public int deleteRoleById(Long roleId);
    /**
     * 批量删除角色信息
     *
     * @param roleIds 需要删除的角色ID
     * @return 结果
     */
    public int deleteRoleByIds(Long[] roleIds);
}
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java
@@ -146,4 +146,12 @@
     * @return 结果
     */
    public int deleteUserById(Long userId);
    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    public int deleteUserByIds(Long[] userIds);
}
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java
@@ -88,7 +88,7 @@
    /**
     * 删除参数配置信息
     * 
     * @param configId 需要删除的数据ID
     * @param configId 参数ID
     * @return 结果
     */
    @Override
@@ -98,6 +98,18 @@
    }
    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     * @return 结果
     */
    @Override
    public int deleteConfigByIds(Long[] configIds)
    {
        return configMapper.deleteConfigByIds(configIds);
    }
    /**
     * 校验参数键名是否唯一
     * 
     * @param config 参数配置信息
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java
@@ -80,6 +80,17 @@
    }
    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 需要删除的字典数据ID
     * @return 结果
     */
    public int deleteDictDataByIds(Long[] dictCodes)
    {
        return dictDataMapper.deleteDictDataByIds(dictCodes);
    }
    /**
     * 新增保存字典数据信息
     * 
     * @param dictData 字典数据信息
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java
@@ -84,6 +84,17 @@
    }
    /**
     * 批量删除字典类型信息
     *
     * @param dictIds 需要删除的字典ID
     * @return 结果
     */
    public int deleteDictTypeByIds(Long[] dictIds)
    {
        return dictTypeMapper.deleteDictTypeByIds(dictIds);
    }
    /**
     * 新增保存字典类型信息
     * 
     * @param dictType 字典类型信息
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -77,4 +77,15 @@
    {
        return noticeMapper.deleteNoticeById(noticeId);
    }
    /**
     * 批量删除公告信息
     *
     * @param noticeIds 需要删除的公告ID
     * @return 结果
     */
    public int deleteNoticeByIds(Long noticeIds)
    {
        return noticeMapper.deleteNoticeByIds(noticeIds);
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java
@@ -4,9 +4,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.system.domain.SysPost;
import com.ruoyi.project.system.mapper.SysPostMapper;
import com.ruoyi.project.system.mapper.SysUserPostMapper;
import com.ruoyi.project.system.service.ISysPostService;
/**
@@ -19,6 +21,9 @@
{
    @Autowired
    private SysPostMapper postMapper;
    @Autowired
    private SysUserPostMapper userPostMapper;
    /**
     * 查询岗位信息集合
@@ -66,7 +71,6 @@
        return postMapper.selectPostListByUserId(userId);
    }
    /**
     * 校验岗位名称是否唯一
     * 
@@ -104,6 +108,18 @@
    }
    /**
     * 通过岗位ID查询岗位使用数量
     *
     * @param postId 岗位ID
     * @return 结果
     */
    @Override
    public int countUserPostById(Long postId)
    {
        return userPostMapper.countUserPostById(postId);
    }
    /**
     * 删除岗位信息
     * 
     * @param postId 岗位ID
@@ -116,6 +132,26 @@
    }
    /**
     * 批量删除岗位信息
     *
     * @param postIds 需要删除的岗位ID
     * @return 结果
     * @throws Exception 异常
     */
    public int deletePostByIds(Long[] postIds)
    {
        for (Long postId : postIds)
        {
            SysPost post = selectPostById(postId);
            if (countUserPostById(postId) > 0)
            {
                throw new CustomException(String.format("%1$s已分配,不能删除", post.getPostName()));
            }
        }
        return postMapper.deletePostByIds(postIds);
    }
    /**
     * 新增保存岗位信息
     * 
     * @param post 岗位信息
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java
@@ -18,6 +18,7 @@
import com.ruoyi.project.system.mapper.SysRoleDeptMapper;
import com.ruoyi.project.system.mapper.SysRoleMapper;
import com.ruoyi.project.system.mapper.SysRoleMenuMapper;
import com.ruoyi.project.system.mapper.SysUserRoleMapper;
import com.ruoyi.project.system.service.ISysRoleService;
/**
@@ -33,6 +34,9 @@
    @Autowired
    private SysRoleMenuMapper roleMenuMapper;
    @Autowired
    private SysUserRoleMapper userRoleMapper;
    @Autowired
    private SysRoleDeptMapper roleDeptMapper;
@@ -150,6 +154,18 @@
        {
            throw new CustomException("不允许操作超级管理员角色");
        }
    }
    /**
     * 通过角色ID查询角色使用数量
     *
     * @param roleId 角色ID
     * @return 结果
     */
    @Override
    public int countUserRoleByRoleId(Long roleId)
    {
        return userRoleMapper.countUserRoleByRoleId(roleId);
    }
    /**
@@ -272,4 +288,24 @@
    {
        return roleMapper.deleteRoleById(roleId);
    }
    /**
     * 批量删除角色信息
     *
     * @param roleIds 需要删除的角色ID
     * @return 结果
     */
    public int deleteRoleByIds(Long[] roleIds)
    {
        for (Long roleId : roleIds)
        {
            checkRoleAllowed(new SysRole(roleId));
            SysRole role = selectRoleById(roleId);
            if (countUserRoleByRoleId(roleId) > 0)
            {
                throw new CustomException(String.format("%1$s已分配,不能删除", role.getRoleName()));
            }
        }
        return roleMapper.deleteRoleByIds(roleIds);
    }
}
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java
@@ -360,4 +360,19 @@
        userPostMapper.deleteUserPostByUserId(userId);
        return userMapper.deleteUserById(userId);
    }
    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    public int deleteUserByIds(Long[] userIds)
    {
        for (Long userId : userIds)
        {
            checkUserAllowed(new SysUser(userId));
        }
        return userMapper.deleteUserByIds(userIds);
    }
}
ruoyi/src/main/resources/application.yml
@@ -3,7 +3,7 @@
  # 名称
  name: RuoYi
  # 版本
  version: 1.0.0
  version: 1.1.0
  # 版权年份
  copyrightYear: 2019
  # 实例演示开关
ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml
@@ -42,7 +42,7 @@
        </where>
    </select>
    
    <delete id="deleteLogininforByIds" parameterType="String">
    <delete id="deleteLogininforByIds" parameterType="Long">
         delete from sys_logininfor where info_id in
         <foreach collection="array" item="infoId" open="(" separator="," close=")">
             #{infoId}
ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml
@@ -63,7 +63,7 @@
        </where>
    </select>
    
    <delete id="deleteOperLogByIds" parameterType="String">
    <delete id="deleteOperLogByIds" parameterType="Long">
         delete from sys_oper_log where oper_id in
         <foreach collection="array" item="operId" open="(" separator="," close=")">
             #{operId}
ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml
@@ -102,4 +102,11 @@
        delete from sys_config where config_id = #{configId}
    </delete>
    
    <delete id="deleteConfigByIds" parameterType="Long">
        delete from sys_config where config_id in
        <foreach item="configId" collection="array" open="(" separator="," close=")">
            #{configId}
        </foreach>
    </delete>
</mapper>
ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml
@@ -62,6 +62,13 @@
    <delete id="deleteDictDataById" parameterType="Long">
         delete from sys_dict_data where dict_code = #{dictCode}
     </delete>
     <delete id="deleteDictDataByIds" parameterType="Long">
         delete from sys_dict_data where dict_code in
         <foreach collection="array" item="dictCode" open="(" separator="," close=")">
             #{dictCode}
        </foreach>
     </delete>
    
    <update id="updateDictData" parameterType="SysDictData">
         update sys_dict_data
ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml
@@ -63,6 +63,13 @@
    <delete id="deleteDictTypeById" parameterType="Long">
         delete from sys_dict_type where dict_id = #{dictId}
     </delete>
     <delete id="deleteDictTypeByIds" parameterType="Long">
         delete from sys_dict_type where dict_id in
         <foreach collection="array" item="dictId" open="(" separator="," close=")">
             #{dictId}
        </foreach>
     </delete>
     <update id="updateDictType" parameterType="SysDictType">
         update sys_dict_type
ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml
@@ -79,4 +79,11 @@
        delete from sys_notice where notice_id = #{noticeId}
    </delete>
    
    <delete id="deleteNoticeByIds" parameterType="Long">
        delete from sys_notice where notice_id in
        <foreach item="noticeId" collection="array" open="(" separator="," close=")">
            #{noticeId}
        </foreach>
    </delete>
</mapper>
ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml
@@ -111,5 +111,12 @@
    <delete id="deletePostById" parameterType="Long">
        delete from sys_post where post_id = #{postId}
    </delete>
    <delete id="deletePostByIds" parameterType="Long">
         delete from sys_post where post_id in
         <foreach collection="array" item="postId" open="(" separator="," close=")">
             #{postId}
        </foreach>
     </delete>
</mapper> 
ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml
@@ -134,4 +134,11 @@
         delete from sys_role where role_id = #{roleId}
     </delete>
     
     <delete id="deleteRoleByIds" parameterType="Long">
         update sys_role set del_flag = '2' where role_id in
         <foreach collection="array" item="roleId" open="(" separator="," close=")">
             #{roleId}
        </foreach>
     </delete>
</mapper> 
ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml
@@ -170,5 +170,12 @@
    <delete id="deleteUserById" parameterType="Long">
         delete from sys_user where user_id = #{userId}
     </delete>
     <delete id="deleteUserByIds" parameterType="Long">
         update sys_user set del_flag = '2' where user_id in
         <foreach collection="array" item="userId" open="(" separator="," close=")">
             #{userId}
        </foreach>
     </delete>
    
</mapper>