From bcee37b84bde39072e6e35e642b0911a94f52eef Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: 星期一, 11 十一月 2019 08:59:15 +0800
Subject: [PATCH] 若依 1.1

---
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java        |   15 
 ruoyi-ui/src/api/monitor/logininfor.js                                                   |   25 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java                     |   31 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java                         |   36 
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java                |    8 
 ruoyi/pom.xml                                                                            |   10 
 ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java                        |   51 
 ruoyi-ui/src/views/system/user/index.vue                                                 |   95 +
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java              |   10 
 ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java                       |    1 
 ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java        |   24 
 ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java                  |   11 
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java                |   17 
 ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml                                |    7 
 ruoyi-ui/src/views/system/dict/index.vue                                                 |  112 +
 ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java         |    4 
 ruoyi-ui/package.json                                                                    |    2 
 ruoyi-ui/src/main.js                                                                     |    3 
 ruoyi/sql/ry_20191111.sql                                                                |   40 
 ruoyi-ui/src/api/system/dict/type.js                                                     |    9 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java               |    8 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java                 |    8 
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java            |    8 
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java      |   14 
 ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml                            |    2 
 ruoyi-ui/src/views/system/post/index.vue                                                 |  104 +
 ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java                            |  872 ++++++++++++++
 ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml                                |    7 
 ruoyi-ui/src/utils/ruoyi.js                                                              |    7 
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java                |   16 
 ruoyi-ui/src/views/system/notice/index.vue                                               |   82 +
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java       |   24 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java                   |    8 
 ruoyi-ui/vue.config.js                                                                   |    2 
 ruoyi-ui/src/api/system/post.js                                                          |    9 
 ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml                                |    7 
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java              |    8 
 README.md                                                                                |   12 
 ruoyi-ui/src/views/system/config/index.vue                                               |  103 +
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java                         |   51 
 ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java               |    4 
 ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java    |   10 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java                         |   25 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java                     |   23 
 ruoyi-ui/src/api/system/dict/data.js                                                     |    9 
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java         |    5 
 ruoyi-ui/src/views/monitor/online/index.vue                                              |   12 
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java         |   22 
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java      |   11 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java                         |   37 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java               |    8 
 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java            |    8 
 ruoyi-ui/src/views/system/role/index.vue                                                 |   99 +
 ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java            |    4 
 ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml                            |    7 
 ruoyi-ui/src/api/system/user.js                                                          |   11 
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java    |   11 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java                 |   10 
 ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml                              |    7 
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java       |   24 
 ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml                         |    2 
 ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java    |   33 
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java        |   36 
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java           |    6 
 ruoyi-ui/src/views/monitor/logininfor/index.vue                                          |  100 +
 ruoyi-ui/src/views/system/dict/data.vue                                                  |  106 +
 ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java                     |  406 ++++++
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java           |   23 
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java    |   11 
 ruoyi-ui/src/api/monitor/operlog.js                                                      |   25 
 ruoyi-ui/src/api/system/role.js                                                          |    9 
 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java        |   38 
 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java              |   18 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java                       |   25 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java                   |    7 
 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java               |  113 +
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java           |   22 
 ruoyi-ui/src/assets/styles/ruoyi.scss                                                    |   50 
 ruoyi-ui/src/views/monitor/operlog/index.vue                                             |  102 +
 ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml                            |    7 
 ruoyi-ui/src/api/system/config.js                                                        |    9 
 ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java            |    4 
 ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java                     |   18 
 ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java |    7 
 ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java                       |   43 
 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java                   |    8 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java                       |   22 
 ruoyi/src/main/resources/application.yml                                                 |    2 
 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java                         |   33 
 ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml                              |    7 
 ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java       |   32 
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java           |    7 
 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java           |   25 
 93 files changed, 3,328 insertions(+), 238 deletions(-)

diff --git a/README.md b/README.md
index 3d24601..f171485 100644
--- a/README.md
+++ b/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>
diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json
index 1122913..ae3a5c3 100644
--- a/ruoyi-ui/package.json
+++ b/ruoyi-ui/package.json
@@ -1,6 +1,6 @@
 {
   "name": "ruoyi",
-  "version": "1.0.0",
+  "version": "1.1.0",
   "description": "鑻ヤ緷绠$悊绯荤粺",
   "author": "鑻ヤ緷",
   "license": "MIT",
diff --git a/ruoyi-ui/src/api/monitor/logininfor.js b/ruoyi-ui/src/api/monitor/logininfor.js
index 9914aaf..0b89cdc 100644
--- a/ruoyi-ui/src/api/monitor/logininfor.js
+++ b/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
+  })
 }
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/monitor/operlog.js b/ruoyi-ui/src/api/monitor/operlog.js
index a6088ad..c519355 100644
--- a/ruoyi-ui/src/api/monitor/operlog.js
+++ b/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
+  })
 }
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/config.js b/ruoyi-ui/src/api/system/config.js
index 6ed1050..124c981 100644
--- a/ruoyi-ui/src/api/system/config.js
+++ b/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
+  })
 }
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/dict/data.js b/ruoyi-ui/src/api/system/dict/data.js
index a0fb115..6a3f418 100644
--- a/ruoyi-ui/src/api/system/dict/data.js
+++ b/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
+  })
 }
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/dict/type.js b/ruoyi-ui/src/api/system/dict/type.js
index 749bfaa..80a6cfa 100644
--- a/ruoyi-ui/src/api/system/dict/type.js
+++ b/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
+  })
+}
diff --git a/ruoyi-ui/src/api/system/post.js b/ruoyi-ui/src/api/system/post.js
index 1bdf069..fb124d9 100644
--- a/ruoyi-ui/src/api/system/post.js
+++ b/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
+  })
 }
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/role.js b/ruoyi-ui/src/api/system/role.js
index 95a606d..736708c 100644
--- a/ruoyi-ui/src/api/system/role.js
+++ b/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
+  })
 }
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/user.js b/ruoyi-ui/src/api/system/user.js
index 55766af..3b1170e 100644
--- a/ruoyi-ui/src/api/system/user.js
+++ b/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
   })
-}
\ No newline at end of file
+}
diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss
index 7c3aca1..9e0cdc3 100644
--- a/ruoyi-ui/src/assets/styles/ruoyi.scss
+++ b/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;
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index 2b5419d..fbd3d6d 100644
--- a/ruoyi-ui/src/main.js
+++ b/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" });
diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js
index 6442ce2..db97dcc 100644
--- a/ruoyi-ui/src/utils/ruoyi.js
+++ b/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;
diff --git a/ruoyi-ui/src/views/monitor/logininfor/index.vue b/ruoyi-ui/src/views/monitor/logininfor/index.vue
index 1e3811e..9dee330 100644
--- a/ruoyi-ui/src/views/monitor/logininfor/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/monitor/online/index.vue b/ruoyi-ui/src/views/monitor/online/index.vue
index 17104de..e5b4b1f 100644
--- a/ruoyi-ui/src/views/monitor/online/index.vue
+++ b/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 + '"鐨勬暟鎹」?', "璀﹀憡", {
diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue
index 9ea7f77..187de28 100644
--- a/ruoyi-ui/src/views/monitor/operlog/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/config/index.vue b/ruoyi-ui/src/views/system/config/index.vue
index 957bb83..b84fac5 100644
--- a/ruoyi-ui/src/views/system/config/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue
index 8c4db3f..649e302 100644
--- a/ruoyi-ui/src/views/system/dict/data.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue
index 86de17b..2dd211f 100644
--- a/ruoyi-ui/src/views/system/dict/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/notice/index.vue b/ruoyi-ui/src/views/system/notice/index.vue
index f65e8ea..caedc50 100644
--- a/ruoyi-ui/src/views/system/notice/index.vue
+++ b/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("鍒犻櫎鎴愬姛");
diff --git a/ruoyi-ui/src/views/system/post/index.vue b/ruoyi-ui/src/views/system/post/index.vue
index f380b23..5c4f28f 100644
--- a/ruoyi-ui/src/views/system/post/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue
index 7f0feb9..05379c2 100644
--- a/ruoyi-ui/src/views/system/role/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue
index 2d57670..760036b 100644
--- a/ruoyi-ui/src/views/system/user/index.vue
+++ b/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() {});
     }
   }
 };
diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js
index 62589f0..5dce8d6 100644
--- a/ruoyi-ui/vue.config.js
+++ b/ruoyi-ui/vue.config.js
@@ -17,7 +17,7 @@
   // 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆�
   // 榛樿鎯呭喌涓嬶紝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" ? "/" : "/",
   // 鍦╪pm run build 鎴� yarn build 鏃� 锛岀敓鎴愭枃浠剁殑鐩綍鍚嶇О锛堣鍜宐aseUrl鐨勭敓浜х幆澧冭矾寰勪竴鑷达級锛堥粯璁ist锛�
   outputDir: 'dist',
   // 鐢ㄤ簬鏀剧疆鐢熸垚鐨勯潤鎬佽祫婧� (js銆乧ss銆乮mg銆乫onts) 鐨勶紱锛堥」鐩墦鍖呬箣鍚庯紝闈欐�佽祫婧愪細鏀惧湪杩欎釜鏂囦欢澶逛笅锛�
diff --git a/ruoyi/pom.xml b/ruoyi/pom.xml
index 0e04df7..f9f6b9a 100644
--- a/ruoyi/pom.xml
+++ b/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>
 
diff --git a/ruoyi/sql/ry_20191008.sql b/ruoyi/sql/ry_20191111.sql
similarity index 96%
rename from ruoyi/sql/ry_20191008.sql
rename to ruoyi/sql/ry_20191111.sql
index 7d75501..0558cba 100644
--- a/ruoyi/sql/ry_20191008.sql
+++ b/ruoyi/sql/ry_20191111.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 '鑿滃崟绫诲瀷锛圡鐩綍 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 '鍦ㄧ嚎鐘舵�乷n_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 (
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
new file mode 100644
index 0000000..27652fe
--- /dev/null
+++ b/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;
+
+    /**
+     * 瀵煎嚭绫诲瀷锛圗XPORT:瀵煎嚭鏁版嵁锛汭MPORT锛氬鍏ユā鏉匡級
+     */
+    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();
+    }
+
+    /**
+     * 瀵筫xcel琛ㄥ崟榛樿绗竴涓储寮曞悕杞崲鎴恖ist
+     * 
+     * @param is 杈撳叆娴�
+     * @return 杞崲鍚庨泦鍚�
+     */
+    public List<T> importExcel(InputStream is) throws Exception
+    {
+        return importExcel(StringUtils.EMPTY, is);
+    }
+
+    /**
+     * 瀵筫xcel琛ㄥ崟鎸囧畾琛ㄦ牸绱㈠紩鍚嶈浆鎹㈡垚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
+        {
+            // 濡傛灉浼犲叆鐨剆heet鍚嶄笉瀛樺湪鍒欓粯璁ゆ寚鍚戠1涓猻heet.
+            sheet = wb.getSheetAt(0);
+        }
+
+        if (sheet == null)
+        {
+            throw new IOException("鏂囦欢sheet涓嶅瓨鍦�");
+        }
+
+        int rows = sheet.getPhysicalNumberOfRows();
+
+        if (rows > 0)
+        {
+            // 瀹氫箟涓�涓猰ap鐢ㄤ簬瀛樻斁excel鍒楃殑搴忓彿鍜宖ield.
+            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);
+                }
+            }
+            // 鏈夋暟鎹椂鎵嶅鐞� 寰楀埌绫荤殑鎵�鏈塮ield.
+            Field[] allFields = clazz.getDeclaredFields();
+            // 瀹氫箟涓�涓猰ap鐢ㄤ簬瀛樻斁鍒楃殑搴忓彿鍜宖ield.
+            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);
+                    // 浠巑ap涓緱鍒板搴斿垪鐨刦ield.
+                    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;
+    }
+
+    /**
+     * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
+     * 
+     * @param list 瀵煎嚭鏁版嵁闆嗗悎
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @return 缁撴灉
+     */
+    public AjaxResult exportExcel(List<T> list, String sheetName)
+    {
+        this.init(list, sheetName, Type.EXPORT);
+        return exportExcel();
+    }
+
+    /**
+     * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
+     * 
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @return 缁撴灉
+     */
+    public AjaxResult importTemplateExcel(String sheetName)
+    {
+        this.init(null, sheetName, Type.IMPORT);
+        return exportExcel();
+    }
+
+    /**
+     * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
+     * 
+     * @return 缁撴灉
+     */
+    public AjaxResult exportExcel()
+    {
+        OutputStream out = null;
+        try
+        {
+            // 鍙栧嚭涓�鍏辨湁澶氬皯涓猻heet.
+            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);
+        }
+        // 濡傛灉璁剧疆浜哻ombo灞炴�у垯鏈垪鍙兘閫夋嫨涓嶈兘杈撳叆
+        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);
+    }
+
+    /**
+     * 瑙f瀽瀵煎嚭鍊� 0=鐢�,1=濂�,2=鏈煡
+     * 
+     * @param propertyValue 鍙傛暟鍊�
+     * @param converterExp 缈昏瘧娉ㄨВ
+     * @return 瑙f瀽鍚庡��
+     * @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;
+    }
+
+    /**
+     * 鍙嶅悜瑙f瀽鍊� 鐢�=0,濂�=1,鏈煡=2
+     * 
+     * @param propertyValue 鍙傛暟鍊�
+     * @param converterExp 缈昏瘧娉ㄨВ
+     * @return 瑙f瀽鍚庡��
+     * @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;
+    }
+}
\ No newline at end of file
diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
new file mode 100644
index 0000000..b78e53e
--- /dev/null
+++ b/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, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟.
+ * 
+ * @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淇グ绗�, 涓嶇粡杩噂etter鍑芥暟.
+     */
+    @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淇グ绗�, 涓嶇粡杩噑etter鍑芥暟.
+     */
+    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);
+        }
+    }
+
+    /**
+     * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredField, 骞跺己鍒惰缃负鍙闂�.
+     * 濡傚悜涓婅浆鍨嬪埌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;
+    }
+
+    /**
+     * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�.
+     * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
+     * 鍖归厤鍑芥暟鍚�+鍙傛暟绫诲瀷銆�
+     * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤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;
+    }
+
+    /**
+     * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�.
+     * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
+     * 鍙尮閰嶅嚱鏁板悕銆�
+     * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤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鐨凷ecurityManager鎶辨�ㄣ��
+     */
+    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鐨凷ecurityManager鎶辨�ㄣ��
+     */
+    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瀹氫箟涓0鏄庣殑娉涘瀷鍙傛暟鐨勭被鍨�, 娉ㄦ剰娉涘瀷蹇呴』瀹氫箟鍦ㄧ埗绫诲
+     * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Class<T> getClassGenricType(final Class clazz)
+    {
+        return getClassGenricType(clazz, 0);
+    }
+
+    /**
+     * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑鐖剁被鐨勬硾鍨嬪弬鏁扮殑绫诲瀷.
+     * 濡傛棤娉曟壘鍒�, 杩斿洖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;
+
+    }
+
+    /**
+     * 灏嗗弽灏勬椂鐨刢hecked exception杞崲涓簎nchecked 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);
+    }
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java
new file mode 100644
index 0000000..8037cb8
--- /dev/null
+++ b/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;
+
+/**
+ * 鑷畾涔夊鍑篍xcel鏁版嵁娉ㄨВ
+ * 
+ * @author ruoyi
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Excel
+{
+    /**
+     * 瀵煎嚭鍒癊xcel涓殑鍚嶅瓧.
+     */
+    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;
+        }
+    }
+}
\ No newline at end of file
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java
new file mode 100644
index 0000000..ff22802
--- /dev/null
+++ b/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();
+}
\ No newline at end of file
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 45000b5..4e0eca4 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/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()
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
index a2da4e8..a51cd34 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
+++ b/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")
                 // 鐢ㄦ潵鍒涘缓璇PI鐨勫熀鏈俊鎭紝灞曠ず鍦ㄦ枃妗g殑椤甸潰涓紙鑷畾涔夊睍绀虹殑淇℃伅锛�
                 .apiInfo(apiInfo())
                 // 璁剧疆鍝簺鎺ュ彛鏆撮湶缁橲wagger灞曠ず
@@ -43,7 +50,47 @@
                 //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
                 // 鎵弿鎵�鏈� .apis(RequestHandlerSelectors.any())
                 .paths(PathSelectors.any())
-                .build();
+                .build()
+                /* 璁剧疆瀹夊叏妯″紡锛宻wagger鍙互璁剧疆璁块棶token */
+                .securitySchemes(securitySchemes())
+                .securityContexts(securityContexts());
+    }
+
+    /**
+     * 瀹夊叏妯″紡锛岃繖閲屾寚瀹歵oken閫氳繃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 @@
         // 鐢ˋpiInfoBuilder杩涜瀹氬埗
         return new ApiInfoBuilder()
                 // 璁剧疆鏍囬
-                .title("鏍囬锛氫綑蹇冪鐞嗙郴缁焈鎺ュ彛鏂囨。")
+                .title("鏍囬锛氳嫢渚濈鐞嗙郴缁焈鎺ュ彛鏂囨。")
                 // 鎻忚堪
                 .description("鎻忚堪锛氱敤浜庣鐞嗛泦鍥㈡棗涓嬪叕鍙哥殑浜哄憳淇℃伅,鍏蜂綋鍖呮嫭XXX,XXX妯″潡...")
                 // 浣滆�呬俊鎭�
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
index d5e4289..12b4358 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
+++ b/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)
diff --git a/ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java b/ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java
index 3362e00..3bb81d0 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java
+++ b/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")
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java
index 2915b84..ecda076 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java
+++ b/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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java
index 5d316ab..d0d5c34 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java
+++ b/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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java
index ea0c40f..7519058 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java
+++ b/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()
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java
index a111aca..813100c 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java
+++ b/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=鐢熸垚浠g爜,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姝e父 1寮傚父锛� */
+    @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,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()
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java
index 43cd82e..707fed1 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java
+++ b/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);
 
     /**
      * 娓呯┖绯荤粺鐧诲綍鏃ュ織
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java
index 2f7c2da..25b1904 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java
+++ b/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);
 
     /**
      * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java
index c00bff7..f46dddf 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java
+++ b/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);
 
     /**
      * 娓呯┖绯荤粺鐧诲綍鏃ュ織
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java
index d99eaf0..3e062ac 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java
+++ b/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);
 
     /**
      * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java
index 6de6159..5195bb3 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java
+++ b/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);
     }
 
     /**
diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java
index fdf9684..65193dd 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java
+++ b/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);
     }
 
     /**
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java
index 13b9d7c..df175e3 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java
+++ b/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));
     }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java
index 00700b1..4934dcb 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java
+++ b/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)))
         {
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java
index 488eeb5..8c5f1ea 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java
+++ b/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));
     }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java
index e98abde..f1dabc9 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java
+++ b/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));
     }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java
index d47ff4d..173c0fa 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java
+++ b/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)))
         {
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java
index 8bd3985..2435053 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java
+++ b/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));
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java
index 77c3b55..f40f769 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java
+++ b/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));
     }
 
     /**
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java
index 9eae5b4..62ab858 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java
+++ b/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));
     }
 
     /**
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
index cd8cd89..d7449a5 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
+++ b/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));
     }
 
     /**
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java
index 9b4352a..ba1c022 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java
+++ b/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;
 
     /** 绯荤粺鍐呯疆锛圷鏄� 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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java
index 8541660..ba12f15 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java
+++ b/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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java
index 4c7efc6..8f7ec61 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java
+++ b/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;
 
     /** 鏄惁榛樿锛圷鏄� N鍚︼級 */
+    @Excel(name = "鏄惁榛樿", readConverterExp = "Y=鏄�,N=鍚�")
     private String isDefault;
 
     /** 鐘舵�侊紙0姝e父 1鍋滅敤锛� */
+    @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java
index 8d3021e..a800f69 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java
+++ b/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姝e父 1鍋滅敤锛� */
+    @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
index 73303d2..baeeeed 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
+++ b/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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
index dbf5248..916fd32 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
+++ b/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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java
index 0b1a937..ebafe7d 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java
+++ b/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姝e父 1鍋滅敤锛� */
+    @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java
index 27bed48..ca33e32 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java
+++ b/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姝e父 1鍋滅敤锛� */
+    @Excel(name = "瑙掕壊鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤")
     private String status;
 
     /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
@@ -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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java
index f6549bb..6c2981e 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java
+++ b/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姝e父 1鍋滅敤锛� */
+    @Excel(name = "甯愬彿鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤")
     private String status;
 
     /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */
     private String delFlag;
 
     /** 鏈�鍚庣櫥闄咺P */
+    @Excel(name = "鏈�鍚庣櫥闄咺P")
     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();
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java
index 02d9270..eea48d6 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java
+++ b/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);
 }
\ No newline at end of file
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java
index eaa25da..c938d88 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java
+++ b/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 瀛楀吀鏁版嵁淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java
index 16ceb69..8a71574 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java
+++ b/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 瀛楀吀绫诲瀷淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java
index ed6bcc0..2046c7a 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java
+++ b/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);
 }
\ No newline at end of file
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java
index 4c0d41e..2cb34f7 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java
+++ b/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 宀椾綅淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java
index 2f8cbd0..200bb1e 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java
+++ b/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);
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
index a93cb6f..bb07335 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
+++ b/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 鐢ㄦ埛鍚嶇О
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java
index 45353e9..4d8666c 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java
+++ b/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 鍙傛暟淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java
index 936bc44..870f357 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java
+++ b/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 瀛楀吀鏁版嵁淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java
index 1e3e7cf..326beb7 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java
+++ b/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 瀛楀吀绫诲瀷淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
index 77c6722..f45e391 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
+++ b/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);
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java
index f5770f6..5696e08 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java
+++ b/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 宀椾綅淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java
index 1774f13..fbd5617 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java
+++ b/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);
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java
index 2136cc9..9aa9eac 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java
+++ b/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);
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java
index de62e8d..bf4d7c2 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java
+++ b/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 鍙傛暟閰嶇疆淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java
index d940743..e8475dc 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java
+++ b/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 瀛楀吀鏁版嵁淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java
index de784de..2cf5f19 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java
+++ b/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 瀛楀吀绫诲瀷淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
index 800f4d1..ee29660 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
+++ b/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);
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java
index 682d147..e60dc06 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java
+++ b/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 宀椾綅淇℃伅
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java
index 82c458d..4ca63e4 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java
+++ b/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);
+    }
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java
index 0a62aca..5aba7a1 100644
--- a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java
+++ b/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);
+    }
 }
diff --git a/ruoyi/src/main/resources/application.yml b/ruoyi/src/main/resources/application.yml
index 4146e35..a1f653d 100644
--- a/ruoyi/src/main/resources/application.yml
+++ b/ruoyi/src/main/resources/application.yml
@@ -3,7 +3,7 @@
   # 鍚嶇О
   name: RuoYi
   # 鐗堟湰
-  version: 1.0.0
+  version: 1.1.0
   # 鐗堟潈骞翠唤
   copyrightYear: 2019
   # 瀹炰緥婕旂ず寮�鍏�
diff --git a/ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml b/ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml
index 0301a3d..c5521a4 100644
--- a/ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml
+++ b/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}
diff --git a/ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml b/ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml
index 6517828..c6e12c4 100644
--- a/ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml
+++ b/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}
diff --git a/ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml
index 2189371..5cfb1f3 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml
+++ b/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>
\ No newline at end of file
diff --git a/ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml
index 57e53c7..b610053 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml
+++ b/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
diff --git a/ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml
index 0a8b26c..2c3f74e 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml
+++ b/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
diff --git a/ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml
index 952e92f..c12816a 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml
+++ b/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>
\ No newline at end of file
diff --git a/ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml
index 232136c..1fb6f45 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml
+++ b/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> 
\ No newline at end of file
diff --git a/ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml
index 4d62760..182c6c7 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml
+++ b/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> 
\ No newline at end of file
diff --git a/ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml
index eaf27a0..85d1786 100644
--- a/ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml
+++ b/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> 
\ No newline at end of file

--
Gitblit v1.9.3