Commit bcee37b84bde39072e6e35e642b0911a94f52eef

Authored by RuoYi
1 parent 85c17f45

若依 1.1

Showing 93 changed files with 3327 additions and 237 deletions
README.md
... ... @@ -49,12 +49,12 @@
49 49 <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
50 50 </tr>
51 51 <tr>
52   - <td><img src="https://oscimg.oschina.net/oscnet/97fcdc766fa04c03722aef4b3d77f71e8d2.jpg"/></td>
53   - <td><img src="https://oscimg.oschina.net/oscnet/642858372da91853c39e2d4746f036ea171.jpg"/></td>
  52 + <td><img src="https://oscimg.oschina.net/oscnet/707825ad3f29de74a8d6d02fbd73ad631ea.jpg"/></td>
  53 + <td><img src="https://oscimg.oschina.net/oscnet/46be40cc6f01aa300eed53a19b5012bf484.jpg"/></td>
54 54 </tr>
55 55 <tr>
56   - <td><img src="https://oscimg.oschina.net/oscnet/8678d5204148e2610c9d02822274a961dcf.jpg"/></td>
57   - <td><img src="https://oscimg.oschina.net/oscnet/feb2b25a08bf9dd121b8f51274ae935ead6.jpg"/></td>
  56 + <td><img src="https://oscimg.oschina.net/oscnet/4284796d4cea240d181b8f2201813dda710.jpg"/></td>
  57 + <td><img src="https://oscimg.oschina.net/oscnet/3ecfac87a049f7fe36abbcaafb2c40d36cf.jpg"/></td>
58 58 </tr>
59 59 <tr>
60 60 <td><img src="https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg"/></td>
... ... @@ -65,8 +65,8 @@
65 65 <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
66 66 </tr>
67 67 <tr>
68   - <td><img src="https://oscimg.oschina.net/oscnet/c162686bf3a39e3cd6b4fd6b5919f515ebf.jpg"/></td>
69   - <td><img src="https://oscimg.oschina.net/oscnet/412fb931faa8b3e3de6f9cbbc5b7979cf36.jpg"/></td>
  68 + <td><img src="https://oscimg.oschina.net/oscnet/fdea1d8bb8625c27bf964176a2c8ebc6945.jpg"/></td>
  69 + <td><img src="https://oscimg.oschina.net/oscnet/509d2708cfd762b6e6339364cac1cc1970c.jpg"/></td>
70 70 </tr>
71 71 <tr>
72 72 <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
... ...
ruoyi-ui/package.json
1 1 {
2 2 "name": "ruoyi",
3   - "version": "1.0.0",
  3 + "version": "1.1.0",
4 4 "description": "若依管理系统",
5 5 "author": "若依",
6 6 "license": "MIT",
... ...
ruoyi-ui/src/api/monitor/logininfor.js
... ... @@ -7,4 +7,29 @@ export function list(query) {
7 7 method: 'get',
8 8 params: query
9 9 })
  10 +}
  11 +
  12 +// 删除登录日志
  13 +export function delLogininfor(infoId) {
  14 + return request({
  15 + url: '/monitor/logininfor/' + infoId,
  16 + method: 'delete'
  17 + })
  18 +}
  19 +
  20 +// 清空登录日志
  21 +export function cleanLogininfor() {
  22 + return request({
  23 + url: '/monitor/logininfor/clean',
  24 + method: 'delete'
  25 + })
  26 +}
  27 +
  28 +// 导出登录日志
  29 +export function exportLogininfor(query) {
  30 + return request({
  31 + url: '/monitor/logininfor/export',
  32 + method: 'get',
  33 + params: query
  34 + })
10 35 }
11 36 \ No newline at end of file
... ...
ruoyi-ui/src/api/monitor/operlog.js
... ... @@ -7,4 +7,29 @@ export function list(query) {
7 7 method: 'get',
8 8 params: query
9 9 })
  10 +}
  11 +
  12 +// 删除操作日志
  13 +export function delOperlog(operId) {
  14 + return request({
  15 + url: '/monitor/operlog/' + operId,
  16 + method: 'delete'
  17 + })
  18 +}
  19 +
  20 +// 清空操作日志
  21 +export function cleanOperlog() {
  22 + return request({
  23 + url: '/monitor/operlog/clean',
  24 + method: 'delete'
  25 + })
  26 +}
  27 +
  28 +// 导出操作日志
  29 +export function exportOperlog(query) {
  30 + return request({
  31 + url: '/monitor/operlog/export',
  32 + method: 'get',
  33 + params: query
  34 + })
10 35 }
11 36 \ No newline at end of file
... ...
ruoyi-ui/src/api/system/config.js
... ... @@ -49,4 +49,13 @@ export function delConfig(configId) {
49 49 url: '/system/config/' + configId,
50 50 method: 'delete'
51 51 })
  52 +}
  53 +
  54 +// 导出参数
  55 +export function exportConfig(query) {
  56 + return request({
  57 + url: '/system/config/export',
  58 + method: 'get',
  59 + params: query
  60 + })
52 61 }
53 62 \ No newline at end of file
... ...
ruoyi-ui/src/api/system/dict/data.js
... ... @@ -49,4 +49,13 @@ export function delData(dictCode) {
49 49 url: '/system/dict/data/' + dictCode,
50 50 method: 'delete'
51 51 })
  52 +}
  53 +
  54 +// 导出字典数据
  55 +export function exportData(query) {
  56 + return request({
  57 + url: '/system/dict/data/export',
  58 + method: 'get',
  59 + params: query
  60 + })
52 61 }
53 62 \ No newline at end of file
... ...
ruoyi-ui/src/api/system/dict/type.js
... ... @@ -42,3 +42,12 @@ export function delType(dictId) {
42 42 method: 'delete'
43 43 })
44 44 }
  45 +
  46 +// 导出字典类型
  47 +export function exportType(query) {
  48 + return request({
  49 + url: '/system/dict/type/export',
  50 + method: 'get',
  51 + params: query
  52 + })
  53 +}
... ...
ruoyi-ui/src/api/system/post.js
... ... @@ -41,4 +41,13 @@ export function delPost(postId) {
41 41 url: '/system/post/' + postId,
42 42 method: 'delete'
43 43 })
  44 +}
  45 +
  46 +// 导出岗位
  47 +export function exportPost(query) {
  48 + return request({
  49 + url: '/system/post/export',
  50 + method: 'get',
  51 + params: query
  52 + })
44 53 }
45 54 \ No newline at end of file
... ...
ruoyi-ui/src/api/system/role.js
... ... @@ -63,4 +63,13 @@ export function delRole(roleId) {
63 63 url: '/system/role/' + roleId,
64 64 method: 'delete'
65 65 })
  66 +}
  67 +
  68 +// 导出角色
  69 +export function exportRole(query) {
  70 + return request({
  71 + url: '/system/role/export',
  72 + method: 'get',
  73 + params: query
  74 + })
66 75 }
67 76 \ No newline at end of file
... ...
ruoyi-ui/src/api/system/user.js
... ... @@ -43,6 +43,15 @@ export function delUser(userId) {
43 43 })
44 44 }
45 45  
  46 +// 导出用户
  47 +export function exportUser(query) {
  48 + return request({
  49 + url: '/system/user/export',
  50 + method: 'get',
  51 + params: query
  52 + })
  53 +}
  54 +
46 55 // 用户密码重置
47 56 export function resetUserPwd(userId, password) {
48 57 const data = {
... ... @@ -106,4 +115,4 @@ export function uploadAvatar(data) {
106 115 method: 'post',
107 116 data: data
108 117 })
109   -}
110 118 \ No newline at end of file
  119 +}
... ...
ruoyi-ui/src/assets/styles/ruoyi.scss
... ... @@ -3,6 +3,56 @@
3 3 * Copyright (c) 2019 ruoyi
4 4 */
5 5  
  6 + /** 基础通用 **/
  7 +.pt5 {
  8 + padding-top: 5px;
  9 +}
  10 +.pr5 {
  11 + padding-right: 5px;
  12 +}
  13 +.pb5 {
  14 + padding-bottom: 5px;
  15 +}
  16 +.mt5 {
  17 + margin-top: 5px;
  18 +}
  19 +.mr5 {
  20 + margin-right: 5px;
  21 +}
  22 +.mb5 {
  23 + margin-bottom: 5px;
  24 +}
  25 +.mb8 {
  26 + margin-bottom: 8px;
  27 +}
  28 +.ml5 {
  29 + margin-left: 5px;
  30 +}
  31 +.mt10 {
  32 + margin-top: 10px;
  33 +}
  34 +.mr10 {
  35 + margin-right: 10px;
  36 +}
  37 +.mb10 {
  38 + margin-bottom: 10px;
  39 +}
  40 +.ml0 {
  41 + margin-left: 10px;
  42 +}
  43 +.mt20 {
  44 + margin-top: 20px;
  45 +}
  46 +.mr20 {
  47 + margin-right: 20px;
  48 +}
  49 +.mb20 {
  50 + margin-bottom: 20px;
  51 +}
  52 +.m20 {
  53 + margin-left: 20px;
  54 +}
  55 +
6 56 .el-table .el-table__header-wrapper th {
7 57 word-break: break-word;
8 58 background-color: #f8f8f9;
... ...
ruoyi-ui/src/main.js
... ... @@ -18,7 +18,7 @@ import &#39;./assets/icons&#39; // icon
18 18 import './permission' // permission control
19 19 import { getDicts } from "@/api/system/dict/data";
20 20 import { getConfigKey } from "@/api/system/config";
21   -import { parseTime, resetForm, addDateRange, selectDictLabel } from "@/utils/ruoyi";
  21 +import { parseTime, resetForm, addDateRange, selectDictLabel, download } from "@/utils/ruoyi";
22 22 import Pagination from "@/components/Pagination";
23 23  
24 24 // 全局方法挂载
... ... @@ -28,6 +28,7 @@ Vue.prototype.parseTime = parseTime
28 28 Vue.prototype.resetForm = resetForm
29 29 Vue.prototype.addDateRange = addDateRange
30 30 Vue.prototype.selectDictLabel = selectDictLabel
  31 +Vue.prototype.download = download
31 32  
32 33 Vue.prototype.msgSuccess = function (msg) {
33 34 this.$message({ showClose: true, message: msg, type: "success" });
... ...
ruoyi-ui/src/utils/ruoyi.js
... ... @@ -3,6 +3,8 @@
3 3 * Copyright (c) 2019 ruoyi
4 4 */
5 5  
  6 +const baseURL = process.env.VUE_APP_BASE_API
  7 +
6 8 // 日期格式化
7 9 export function parseTime(time, pattern) {
8 10 if (arguments.length === 0) {
... ... @@ -73,6 +75,11 @@ export function selectDictLabel(datas, value) {
73 75 return actions.join('');
74 76 }
75 77  
  78 +// 通用下载方法
  79 +export function download(fileName) {
  80 + window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
  81 +}
  82 +
76 83 // 字符串格式化(%s )
77 84 export function sprintf(str) {
78 85 var args = arguments, flag = true, i = 1;
... ...
ruoyi-ui/src/views/monitor/logininfor/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true" label-width="68px">
4   - <el-form-item label="登录地址">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  4 + <el-form-item label="登录地址" prop="ipaddr">
5 5 <el-input
6 6 v-model="queryParams.ipaddr"
7 7 placeholder="请输入登录地址"
... ... @@ -11,7 +11,7 @@
11 11 @keyup.enter.native="handleQuery"
12 12 />
13 13 </el-form-item>
14   - <el-form-item label="用户名称">
  14 + <el-form-item label="用户名称" prop="userName">
15 15 <el-input
16 16 v-model="queryParams.userName"
17 17 placeholder="请输入用户名称"
... ... @@ -21,7 +21,7 @@
21 21 @keyup.enter.native="handleQuery"
22 22 />
23 23 </el-form-item>
24   - <el-form-item label="状态">
  24 + <el-form-item label="状态" prop="status">
25 25 <el-select
26 26 v-model="queryParams.status"
27 27 placeholder="登录状态"
... ... @@ -51,10 +51,43 @@
51 51 </el-form-item>
52 52 <el-form-item>
53 53 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  54 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
54 55 </el-form-item>
55 56 </el-form>
56 57  
57   - <el-table v-loading="loading" :data="list" style="width: 100%;">
  58 + <el-row :gutter="10" class="mb8">
  59 + <el-col :span="1.5">
  60 + <el-button
  61 + type="danger"
  62 + icon="el-icon-delete"
  63 + size="mini"
  64 + :disabled="multiple"
  65 + @click="handleDelete"
  66 + v-hasPermi="['monitor:logininfor:remove']"
  67 + >删除</el-button>
  68 + </el-col>
  69 + <el-col :span="1.5">
  70 + <el-button
  71 + type="danger"
  72 + icon="el-icon-delete"
  73 + size="mini"
  74 + @click="handleClean"
  75 + v-hasPermi="['monitor:logininfor:remove']"
  76 + >清空</el-button>
  77 + </el-col>
  78 + <el-col :span="1.5">
  79 + <el-button
  80 + type="warning"
  81 + icon="el-icon-download"
  82 + size="mini"
  83 + @click="handleExport"
  84 + v-hasPermi="['system:logininfor:export']"
  85 + >导出</el-button>
  86 + </el-col>
  87 + </el-row>
  88 +
  89 + <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
  90 + <el-table-column type="selection" width="55" align="center" />
58 91 <el-table-column label="访问编号" align="center" prop="infoId" />
59 92 <el-table-column label="用户名称" align="center" prop="userName" />
60 93 <el-table-column label="登录地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" />
... ... @@ -81,13 +114,17 @@
81 114 </template>
82 115  
83 116 <script>
84   -import { list } from "@/api/monitor/logininfor";
  117 +import { list, delLogininfor, cleanLogininfor, exportLogininfor } from "@/api/monitor/logininfor";
85 118  
86 119 export default {
87 120 data() {
88 121 return {
89 122 // 遮罩层
90 123 loading: true,
  124 + // 选中数组
  125 + ids: [],
  126 + // 非多个禁用
  127 + multiple: true,
91 128 // 总条数
92 129 total: 0,
93 130 // 表格数据
... ... @@ -131,6 +168,57 @@ export default {
131 168 handleQuery() {
132 169 this.queryParams.pageNum = 1;
133 170 this.getList();
  171 + },
  172 + /** 重置按钮操作 */
  173 + resetQuery() {
  174 + this.dateRange = [];
  175 + this.resetForm("queryForm");
  176 + this.handleQuery();
  177 + },
  178 + // 多选框选中数据
  179 + handleSelectionChange(selection) {
  180 + this.ids = selection.map(item => item.infoId)
  181 + this.multiple = !selection.length
  182 + },
  183 + /** 删除按钮操作 */
  184 + handleDelete(row) {
  185 + const infoIds = row.infoId || this.ids;
  186 + this.$confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?', "警告", {
  187 + confirmButtonText: "确定",
  188 + cancelButtonText: "取消",
  189 + type: "warning"
  190 + }).then(function() {
  191 + return delLogininfor(infoIds);
  192 + }).then(() => {
  193 + this.getList();
  194 + this.msgSuccess("删除成功");
  195 + }).catch(function() {});
  196 + },
  197 + /** 清空按钮操作 */
  198 + handleClean() {
  199 + this.$confirm('是否确认清空所有登录日志数据项?', "警告", {
  200 + confirmButtonText: "确定",
  201 + cancelButtonText: "取消",
  202 + type: "warning"
  203 + }).then(function() {
  204 + return cleanLogininfor();
  205 + }).then(() => {
  206 + this.getList();
  207 + this.msgSuccess("清空成功");
  208 + }).catch(function() {});
  209 + },
  210 + /** 导出按钮操作 */
  211 + handleExport() {
  212 + const queryParams = this.queryParams;
  213 + this.$confirm('是否确认导出所有操作日志数据项?', "警告", {
  214 + confirmButtonText: "确定",
  215 + cancelButtonText: "取消",
  216 + type: "warning"
  217 + }).then(function() {
  218 + return exportLogininfor(queryParams);
  219 + }).then(response => {
  220 + this.download(response.msg);
  221 + }).catch(function() {});
134 222 }
135 223 }
136 224 };
... ...
ruoyi-ui/src/views/monitor/online/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true">
4   - <el-form-item label="登录地址">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true">
  4 + <el-form-item label="登录地址" prop="ipaddr">
5 5 <el-input
6 6 v-model="queryParams.ipaddr"
7 7 placeholder="请输入登录地址"
... ... @@ -10,7 +10,7 @@
10 10 @keyup.enter.native="handleQuery"
11 11 />
12 12 </el-form-item>
13   - <el-form-item label="用户名称">
  13 + <el-form-item label="用户名称" prop="userName">
14 14 <el-input
15 15 v-model="queryParams.userName"
16 16 placeholder="请输入用户名称"
... ... @@ -21,6 +21,7 @@
21 21 </el-form-item>
22 22 <el-form-item>
23 23 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  24 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
24 25 </el-form-item>
25 26 </el-form>
26 27  
... ... @@ -102,6 +103,11 @@ export default {
102 103 this.pageNum = 1;
103 104 this.getList();
104 105 },
  106 + /** 重置按钮操作 */
  107 + resetQuery() {
  108 + this.resetForm("queryForm");
  109 + this.handleQuery();
  110 + },
105 111 /** 强退按钮操作 */
106 112 handleForceLogout(row) {
107 113 this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", {
... ...
ruoyi-ui/src/views/monitor/operlog/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true" label-width="68px">
4   - <el-form-item label="系统模块">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  4 + <el-form-item label="系统模块" prop="title">
5 5 <el-input
6 6 v-model="queryParams.title"
7 7 placeholder="请输入系统模块"
... ... @@ -11,7 +11,7 @@
11 11 @keyup.enter.native="handleQuery"
12 12 />
13 13 </el-form-item>
14   - <el-form-item label="操作人员">
  14 + <el-form-item label="操作人员" prop="operName">
15 15 <el-input
16 16 v-model="queryParams.operName"
17 17 placeholder="请输入操作人员"
... ... @@ -21,7 +21,7 @@
21 21 @keyup.enter.native="handleQuery"
22 22 />
23 23 </el-form-item>
24   - <el-form-item label="类型">
  24 + <el-form-item label="类型" prop="businessType">
25 25 <el-select
26 26 v-model="queryParams.businessType"
27 27 placeholder="操作类型"
... ... @@ -37,7 +37,7 @@
37 37 />
38 38 </el-select>
39 39 </el-form-item>
40   - <el-form-item label="状态">
  40 + <el-form-item label="状态" prop="status">
41 41 <el-select
42 42 v-model="queryParams.status"
43 43 placeholder="操作状态"
... ... @@ -67,10 +67,43 @@
67 67 </el-form-item>
68 68 <el-form-item>
69 69 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  70 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
70 71 </el-form-item>
71 72 </el-form>
72 73  
73   - <el-table v-loading="loading" :data="list" style="width: 100%;">
  74 + <el-row :gutter="10" class="mb8">
  75 + <el-col :span="1.5">
  76 + <el-button
  77 + type="danger"
  78 + icon="el-icon-delete"
  79 + size="mini"
  80 + :disabled="multiple"
  81 + @click="handleDelete"
  82 + v-hasPermi="['monitor:operlog:remove']"
  83 + >删除</el-button>
  84 + </el-col>
  85 + <el-col :span="1.5">
  86 + <el-button
  87 + type="danger"
  88 + icon="el-icon-delete"
  89 + size="mini"
  90 + @click="handleClean"
  91 + v-hasPermi="['monitor:operlog:remove']"
  92 + >清空</el-button>
  93 + </el-col>
  94 + <el-col :span="1.5">
  95 + <el-button
  96 + type="warning"
  97 + icon="el-icon-download"
  98 + size="mini"
  99 + @click="handleExport"
  100 + v-hasPermi="['system:config:export']"
  101 + >导出</el-button>
  102 + </el-col>
  103 + </el-row>
  104 +
  105 + <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
  106 + <el-table-column type="selection" width="55" align="center" />
74 107 <el-table-column label="日志编号" align="center" prop="operId" />
75 108 <el-table-column label="系统模块" align="center" prop="title" />
76 109 <el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" />
... ... @@ -150,13 +183,17 @@
150 183 </template>
151 184  
152 185 <script>
153   -import { list } from "@/api/monitor/operlog";
  186 +import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/operlog";
154 187  
155 188 export default {
156 189 data() {
157 190 return {
158 191 // 遮罩层
159 192 loading: true,
  193 + // 选中数组
  194 + ids: [],
  195 + // 非多个禁用
  196 + multiple: true,
160 197 // 总条数
161 198 total: 0,
162 199 // 表格数据
... ... @@ -215,10 +252,61 @@ export default {
215 252 this.queryParams.pageNum = 1;
216 253 this.getList();
217 254 },
  255 + /** 重置按钮操作 */
  256 + resetQuery() {
  257 + this.dateRange = [];
  258 + this.resetForm("queryForm");
  259 + this.handleQuery();
  260 + },
  261 + // 多选框选中数据
  262 + handleSelectionChange(selection) {
  263 + this.ids = selection.map(item => item.operId)
  264 + this.multiple = !selection.length
  265 + },
218 266 /** 详细按钮操作 */
219 267 handleView(row) {
220 268 this.open = true;
221 269 this.form = row;
  270 + },
  271 + /** 删除按钮操作 */
  272 + handleDelete(row) {
  273 + const operIds = row.operId || this.ids;
  274 + this.$confirm('是否确认删除日志编号为"' + operIds + '"的数据项?', "警告", {
  275 + confirmButtonText: "确定",
  276 + cancelButtonText: "取消",
  277 + type: "warning"
  278 + }).then(function() {
  279 + return delOperlog(operIds);
  280 + }).then(() => {
  281 + this.getList();
  282 + this.msgSuccess("删除成功");
  283 + }).catch(function() {});
  284 + },
  285 + /** 清空按钮操作 */
  286 + handleClean() {
  287 + this.$confirm('是否确认清空所有操作日志数据项?', "警告", {
  288 + confirmButtonText: "确定",
  289 + cancelButtonText: "取消",
  290 + type: "warning"
  291 + }).then(function() {
  292 + return cleanOperlog();
  293 + }).then(() => {
  294 + this.getList();
  295 + this.msgSuccess("清空成功");
  296 + }).catch(function() {});
  297 + },
  298 + /** 导出按钮操作 */
  299 + handleExport() {
  300 + const queryParams = this.queryParams;
  301 + this.$confirm('是否确认导出所有操作日志数据项?', "警告", {
  302 + confirmButtonText: "确定",
  303 + cancelButtonText: "取消",
  304 + type: "warning"
  305 + }).then(function() {
  306 + return exportOperlog(queryParams);
  307 + }).then(response => {
  308 + this.download(response.msg);
  309 + }).catch(function() {});
222 310 }
223 311 }
224 312 };
... ...
ruoyi-ui/src/views/system/config/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true" label-width="68px">
4   - <el-form-item label="参数名称">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  4 + <el-form-item label="参数名称" prop="configName">
5 5 <el-input
6 6 v-model="queryParams.configName"
7 7 placeholder="请输入参数名称"
... ... @@ -11,7 +11,7 @@
11 11 @keyup.enter.native="handleQuery"
12 12 />
13 13 </el-form-item>
14   - <el-form-item label="参数键名">
  14 + <el-form-item label="参数键名" prop="configKey">
15 15 <el-input
16 16 v-model="queryParams.configKey"
17 17 placeholder="请输入参数键名"
... ... @@ -21,7 +21,7 @@
21 21 @keyup.enter.native="handleQuery"
22 22 />
23 23 </el-form-item>
24   - <el-form-item label="系统内置">
  24 + <el-form-item label="系统内置" prop="configType">
25 25 <el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small">
26 26 <el-option
27 27 v-for="dict in typeOptions"
... ... @@ -45,11 +45,53 @@
45 45 </el-form-item>
46 46 <el-form-item>
47 47 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
48   - <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:config:add']">新增</el-button>
  48 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
49 49 </el-form-item>
50 50 </el-form>
51 51  
52   - <el-table v-loading="loading" :data="configList">
  52 + <el-row :gutter="10" class="mb8">
  53 + <el-col :span="1.5">
  54 + <el-button
  55 + type="primary"
  56 + icon="el-icon-plus"
  57 + size="mini"
  58 + @click="handleAdd"
  59 + v-hasPermi="['system:config:add']"
  60 + >新增</el-button>
  61 + </el-col>
  62 + <el-col :span="1.5">
  63 + <el-button
  64 + type="success"
  65 + icon="el-icon-edit"
  66 + size="mini"
  67 + :disabled="single"
  68 + @click="handleUpdate"
  69 + v-hasPermi="['system:config:edit']"
  70 + >修改</el-button>
  71 + </el-col>
  72 + <el-col :span="1.5">
  73 + <el-button
  74 + type="danger"
  75 + icon="el-icon-delete"
  76 + size="mini"
  77 + :disabled="multiple"
  78 + @click="handleDelete"
  79 + v-hasPermi="['system:config:remove']"
  80 + >删除</el-button>
  81 + </el-col>
  82 + <el-col :span="1.5">
  83 + <el-button
  84 + type="warning"
  85 + icon="el-icon-download"
  86 + size="mini"
  87 + @click="handleExport"
  88 + v-hasPermi="['system:config:export']"
  89 + >导出</el-button>
  90 + </el-col>
  91 + </el-row>
  92 +
  93 + <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
  94 + <el-table-column type="selection" width="55" align="center" />
53 95 <el-table-column label="参数主键" align="center" prop="configId" />
54 96 <el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
55 97 <el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
... ... @@ -63,10 +105,10 @@
63 105 </el-table-column>
64 106 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
65 107 <template slot-scope="scope">
66   - <el-button
67   - size="mini"
68   - type="text"
69   - icon="el-icon-edit"
  108 + <el-button
  109 + size="mini"
  110 + type="text"
  111 + icon="el-icon-edit"
70 112 @click="handleUpdate(scope.row)"
71 113 v-hasPermi="['system:config:edit']"
72 114 >修改</el-button>
... ... @@ -123,13 +165,19 @@
123 165 </template>
124 166  
125 167 <script>
126   -import { listConfig, getConfig, delConfig, addConfig, updateConfig } from "@/api/system/config";
  168 +import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig } from "@/api/system/config";
127 169  
128 170 export default {
129 171 data() {
130 172 return {
131 173 // 遮罩层
132 174 loading: true,
  175 + // 选中数组
  176 + ids: [],
  177 + // 非单个禁用
  178 + single: true,
  179 + // 非多个禁用
  180 + multiple: true,
133 181 // 总条数
134 182 total: 0,
135 183 // 参数表格数据
... ... @@ -209,16 +257,29 @@ export default {
209 257 this.queryParams.pageNum = 1;
210 258 this.getList();
211 259 },
  260 + /** 重置按钮操作 */
  261 + resetQuery() {
  262 + this.dateRange = [];
  263 + this.resetForm("queryForm");
  264 + this.handleQuery();
  265 + },
212 266 /** 新增按钮操作 */
213 267 handleAdd() {
214 268 this.reset();
215 269 this.open = true;
216 270 this.title = "添加参数";
217 271 },
  272 + // 多选框选中数据
  273 + handleSelectionChange(selection) {
  274 + this.ids = selection.map(item => item.configId)
  275 + this.single = selection.length!=1
  276 + this.multiple = !selection.length
  277 + },
218 278 /** 修改按钮操作 */
219 279 handleUpdate(row) {
220 280 this.reset();
221   - getConfig(row.configId).then(response => {
  281 + const configId = row.configId || this.ids
  282 + getConfig(configId).then(response => {
222 283 this.form = response.data;
223 284 this.open = true;
224 285 this.title = "修改参数";
... ... @@ -254,16 +315,30 @@ export default {
254 315 },
255 316 /** 删除按钮操作 */
256 317 handleDelete(row) {
257   - this.$confirm('是否确认删除名称为"' + row.configName + '"的数据项?', "警告", {
  318 + const configIds = row.configId || this.ids;
  319 + this.$confirm('是否确认删除参数编号为"' + configIds + '"的数据项?', "警告", {
258 320 confirmButtonText: "确定",
259 321 cancelButtonText: "取消",
260 322 type: "warning"
261 323 }).then(function() {
262   - return delConfig(row.configId);
  324 + return delConfig(configIds);
263 325 }).then(() => {
264 326 this.getList();
265 327 this.msgSuccess("删除成功");
266 328 }).catch(function() {});
  329 + },
  330 + /** 导出按钮操作 */
  331 + handleExport() {
  332 + const queryParams = this.queryParams;
  333 + this.$confirm('是否确认导出所有参数数据项?', "警告", {
  334 + confirmButtonText: "确定",
  335 + cancelButtonText: "取消",
  336 + type: "warning"
  337 + }).then(function() {
  338 + return exportConfig(queryParams);
  339 + }).then(response => {
  340 + this.download(response.msg);
  341 + }).catch(function() {});
267 342 }
268 343 }
269 344 };
... ...
ruoyi-ui/src/views/system/dict/data.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true">
4   - <el-form-item label="字典名称">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true">
  4 + <el-form-item label="字典名称" prop="dictType">
5 5 <el-select v-model="queryParams.dictType" size="small">
6 6 <el-option
7 7 v-for="item in typeOptions"
... ... @@ -11,7 +11,7 @@
11 11 />
12 12 </el-select>
13 13 </el-form-item>
14   - <el-form-item label="字典标签">
  14 + <el-form-item label="字典标签" prop="dictLabel">
15 15 <el-input
16 16 v-model="queryParams.dictLabel"
17 17 placeholder="请输入字典标签"
... ... @@ -20,7 +20,7 @@
20 20 @keyup.enter.native="handleQuery"
21 21 />
22 22 </el-form-item>
23   - <el-form-item label="状态">
  23 + <el-form-item label="状态" prop="status">
24 24 <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
25 25 <el-option
26 26 v-for="dict in statusOptions"
... ... @@ -32,11 +32,53 @@
32 32 </el-form-item>
33 33 <el-form-item>
34 34 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
35   - <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:dict:add']">新增</el-button>
  35 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
36 36 </el-form-item>
37 37 </el-form>
38 38  
39   - <el-table v-loading="loading" :data="dataList" style="width: 100%;">
  39 + <el-row :gutter="10" class="mb8">
  40 + <el-col :span="1.5">
  41 + <el-button
  42 + type="primary"
  43 + icon="el-icon-plus"
  44 + size="mini"
  45 + @click="handleAdd"
  46 + v-hasPermi="['system:dict:add']"
  47 + >新增</el-button>
  48 + </el-col>
  49 + <el-col :span="1.5">
  50 + <el-button
  51 + type="success"
  52 + icon="el-icon-edit"
  53 + size="mini"
  54 + :disabled="single"
  55 + @click="handleUpdate"
  56 + v-hasPermi="['system:dict:edit']"
  57 + >修改</el-button>
  58 + </el-col>
  59 + <el-col :span="1.5">
  60 + <el-button
  61 + type="danger"
  62 + icon="el-icon-delete"
  63 + size="mini"
  64 + :disabled="multiple"
  65 + @click="handleDelete"
  66 + v-hasPermi="['system:dict:remove']"
  67 + >删除</el-button>
  68 + </el-col>
  69 + <el-col :span="1.5">
  70 + <el-button
  71 + type="warning"
  72 + icon="el-icon-download"
  73 + size="mini"
  74 + @click="handleExport"
  75 + v-hasPermi="['system:dict:export']"
  76 + >导出</el-button>
  77 + </el-col>
  78 + </el-row>
  79 +
  80 + <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
  81 + <el-table-column type="selection" width="55" align="center" />
40 82 <el-table-column label="字典编码" align="center" prop="dictCode" />
41 83 <el-table-column label="字典标签" align="center" prop="dictLabel" />
42 84 <el-table-column label="字典键值" align="center" prop="dictValue" />
... ... @@ -50,10 +92,10 @@
50 92 </el-table-column>
51 93 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
52 94 <template slot-scope="scope">
53   - <el-button
54   - size="mini"
55   - type="text"
56   - icon="el-icon-edit"
  95 + <el-button
  96 + size="mini"
  97 + type="text"
  98 + icon="el-icon-edit"
57 99 @click="handleUpdate(scope.row)"
58 100 v-hasPermi="['system:dict:edit']"
59 101 >修改</el-button>
... ... @@ -113,7 +155,7 @@
113 155 </template>
114 156  
115 157 <script>
116   -import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
  158 +import { listData, getData, delData, addData, updateData, exportData } from "@/api/system/dict/data";
117 159 import { listType, getType } from "@/api/system/dict/type";
118 160  
119 161 export default {
... ... @@ -121,10 +163,18 @@ export default {
121 163 return {
122 164 // 遮罩层
123 165 loading: true,
  166 + // 选中数组
  167 + ids: [],
  168 + // 非单个禁用
  169 + single: true,
  170 + // 非多个禁用
  171 + multiple: true,
124 172 // 总条数
125 173 total: 0,
126 174 // 字典表格数据
127 175 dataList: [],
  176 + // 默认字典类型
  177 + defaultDictType: "",
128 178 // 弹出层标题
129 179 title: "",
130 180 // 是否显示弹出层
... ... @@ -170,6 +220,7 @@ export default {
170 220 getType(dictId) {
171 221 getType(dictId).then(response => {
172 222 this.queryParams.dictType = response.data.dictType;
  223 + this.defaultDictType = response.data.dictType;
173 224 this.getList();
174 225 });
175 226 },
... ... @@ -214,6 +265,12 @@ export default {
214 265 this.queryParams.pageNum = 1;
215 266 this.getList();
216 267 },
  268 + /** 重置按钮操作 */
  269 + resetQuery() {
  270 + this.resetForm("queryForm");
  271 + this.queryParams.dictType = this.defaultDictType;
  272 + this.handleQuery();
  273 + },
217 274 /** 新增按钮操作 */
218 275 handleAdd() {
219 276 this.reset();
... ... @@ -221,10 +278,17 @@ export default {
221 278 this.title = "添加字典数据";
222 279 this.form.dictType = this.queryParams.dictType;
223 280 },
  281 + // 多选框选中数据
  282 + handleSelectionChange(selection) {
  283 + this.ids = selection.map(item => item.dictCode)
  284 + this.single = selection.length!=1
  285 + this.multiple = !selection.length
  286 + },
224 287 /** 修改按钮操作 */
225 288 handleUpdate(row) {
226 289 this.reset();
227   - getData(row.dictCode).then(response => {
  290 + const dictCode = row.dictCode || this.ids
  291 + getData(dictCode).then(response => {
228 292 this.form = response.data;
229 293 this.open = true;
230 294 this.title = "修改字典数据";
... ... @@ -260,16 +324,30 @@ export default {
260 324 },
261 325 /** 删除按钮操作 */
262 326 handleDelete(row) {
263   - this.$confirm('是否确认删除名称为"' + row.dictLabel + '"的数据项?', "警告", {
  327 + const dictCodes = row.dictCode || this.ids;
  328 + this.$confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?', "警告", {
264 329 confirmButtonText: "确定",
265 330 cancelButtonText: "取消",
266 331 type: "warning"
267 332 }).then(function() {
268   - return delData(row.dictCode);
  333 + return delData(dictCodes);
269 334 }).then(() => {
270 335 this.getList();
271 336 this.msgSuccess("删除成功");
272 337 }).catch(function() {});
  338 + },
  339 + /** 导出按钮操作 */
  340 + handleExport() {
  341 + const queryParams = this.queryParams;
  342 + this.$confirm('是否确认导出所有数据项?', "警告", {
  343 + confirmButtonText: "确定",
  344 + cancelButtonText: "取消",
  345 + type: "warning"
  346 + }).then(function() {
  347 + return exportData(queryParams);
  348 + }).then(response => {
  349 + this.download(response.msg);
  350 + }).catch(function() {});
273 351 }
274 352 }
275 353 };
... ...
ruoyi-ui/src/views/system/dict/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true" label-width="68px">
4   - <el-form-item label="字典名称">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  4 + <el-form-item label="字典名称" prop="dictName">
5 5 <el-input
6 6 v-model="queryParams.dictName"
7 7 placeholder="请输入字典名称"
... ... @@ -11,7 +11,7 @@
11 11 @keyup.enter.native="handleQuery"
12 12 />
13 13 </el-form-item>
14   - <el-form-item label="字典类型">
  14 + <el-form-item label="字典类型" prop="dictType">
15 15 <el-input
16 16 v-model="queryParams.dictType"
17 17 placeholder="请输入字典类型"
... ... @@ -21,7 +21,7 @@
21 21 @keyup.enter.native="handleQuery"
22 22 />
23 23 </el-form-item>
24   - <el-form-item label="状态">
  24 + <el-form-item label="状态" prop="status">
25 25 <el-select
26 26 v-model="queryParams.status"
27 27 placeholder="字典状态"
... ... @@ -39,7 +39,7 @@
39 39 </el-form-item>
40 40 <el-form-item label="创建时间">
41 41 <el-date-picker
42   - v-model="queryParams.createTime"
  42 + v-model="dateRange"
43 43 size="small"
44 44 style="width: 240px"
45 45 value-format="yyyy-MM-dd"
... ... @@ -51,14 +51,56 @@
51 51 </el-form-item>
52 52 <el-form-item>
53 53 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
54   - <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:dict:add']">新增</el-button>
  54 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
55 55 </el-form-item>
56 56 </el-form>
57 57  
58   - <el-table v-loading="loading" :data="typeList" style="width: 100%;">
59   - <el-table-column label="字典主键" align="center" prop="dictId" />
  58 + <el-row :gutter="10" class="mb8">
  59 + <el-col :span="1.5">
  60 + <el-button
  61 + type="primary"
  62 + icon="el-icon-plus"
  63 + size="mini"
  64 + @click="handleAdd"
  65 + v-hasPermi="['system:dict:add']"
  66 + >新增</el-button>
  67 + </el-col>
  68 + <el-col :span="1.5">
  69 + <el-button
  70 + type="success"
  71 + icon="el-icon-edit"
  72 + size="mini"
  73 + :disabled="single"
  74 + @click="handleUpdate"
  75 + v-hasPermi="['system:dict:edit']"
  76 + >修改</el-button>
  77 + </el-col>
  78 + <el-col :span="1.5">
  79 + <el-button
  80 + type="danger"
  81 + icon="el-icon-delete"
  82 + size="mini"
  83 + :disabled="multiple"
  84 + @click="handleDelete"
  85 + v-hasPermi="['system:dict:remove']"
  86 + >删除</el-button>
  87 + </el-col>
  88 + <el-col :span="1.5">
  89 + <el-button
  90 + type="warning"
  91 + icon="el-icon-download"
  92 + size="mini"
  93 + @click="handleExport"
  94 + v-hasPermi="['system:dict:export']"
  95 + >导出</el-button>
  96 + </el-col>
  97 + </el-row>
  98 +
  99 + <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
  100 + <el-table-column type="selection" width="55" align="center" />
  101 + <el-table-column label="字典编号" align="center" prop="dictId" />
60 102 <el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" />
61   - <el-table-column label="字典类型" align="center">
  103 + <el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
62 104 <template slot-scope="scope">
63 105 <router-link :to="'/dict/type/data/' + scope.row.dictId" class="link-type">
64 106 <span>{{ scope.row.dictType }}</span>
... ... @@ -74,10 +116,10 @@
74 116 </el-table-column>
75 117 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
76 118 <template slot-scope="scope">
77   - <el-button
78   - size="mini"
79   - type="text"
80   - icon="el-icon-edit"
  119 + <el-button
  120 + size="mini"
  121 + type="text"
  122 + icon="el-icon-edit"
81 123 @click="handleUpdate(scope.row)"
82 124 v-hasPermi="['system:dict:edit']"
83 125 >修改</el-button>
... ... @@ -131,13 +173,19 @@
131 173 </template>
132 174  
133 175 <script>
134   -import { listType, getType, delType, addType, updateType } from "@/api/system/dict/type";
  176 +import { listType, getType, delType, addType, updateType, exportType } from "@/api/system/dict/type";
135 177  
136 178 export default {
137 179 data() {
138 180 return {
139 181 // 遮罩层
140 182 loading: true,
  183 + // 选中数组
  184 + ids: [],
  185 + // 非单个禁用
  186 + single: true,
  187 + // 非多个禁用
  188 + multiple: true,
141 189 // 总条数
142 190 total: 0,
143 191 // 字典表格数据
... ... @@ -181,8 +229,7 @@ export default {
181 229 /** 查询字典类型列表 */
182 230 getList() {
183 231 this.loading = true;
184   - listType(this.addDateRange(this.queryParams, this.dateRange)).then(
185   - response => {
  232 + listType(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
186 233 this.typeList = response.rows;
187 234 this.total = response.total;
188 235 this.loading = false;
... ... @@ -214,16 +261,29 @@ export default {
214 261 this.queryParams.pageNum = 1;
215 262 this.getList();
216 263 },
  264 + /** 重置按钮操作 */
  265 + resetQuery() {
  266 + this.dateRange = [];
  267 + this.resetForm("queryForm");
  268 + this.handleQuery();
  269 + },
217 270 /** 新增按钮操作 */
218 271 handleAdd() {
219 272 this.reset();
220 273 this.open = true;
221 274 this.title = "添加字典类型";
222 275 },
  276 + // 多选框选中数据
  277 + handleSelectionChange(selection) {
  278 + this.ids = selection.map(item => item.dictId)
  279 + this.single = selection.length!=1
  280 + this.multiple = !selection.length
  281 + },
223 282 /** 修改按钮操作 */
224 283 handleUpdate(row) {
225 284 this.reset();
226   - getType(row.dictId).then(response => {
  285 + const dictId = row.dictId || this.ids
  286 + getType(dictId).then(response => {
227 287 this.form = response.data;
228 288 this.open = true;
229 289 this.title = "修改字典类型";
... ... @@ -259,16 +319,30 @@ export default {
259 319 },
260 320 /** 删除按钮操作 */
261 321 handleDelete(row) {
262   - this.$confirm('是否确认删除名称为"' + row.dictName + '"的数据项?', "警告", {
  322 + const dictIds = row.dictId || this.ids;
  323 + this.$confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?', "警告", {
263 324 confirmButtonText: "确定",
264 325 cancelButtonText: "取消",
265 326 type: "warning"
266 327 }).then(function() {
267   - return delType(row.dictId);
  328 + return delType(dictIds);
268 329 }).then(() => {
269 330 this.getList();
270 331 this.msgSuccess("删除成功");
271 332 }).catch(function() {});
  333 + },
  334 + /** 导出按钮操作 */
  335 + handleExport() {
  336 + const queryParams = this.queryParams;
  337 + this.$confirm('是否确认导出所有类型数据项?', "警告", {
  338 + confirmButtonText: "确定",
  339 + cancelButtonText: "取消",
  340 + type: "warning"
  341 + }).then(function() {
  342 + return exportType(queryParams);
  343 + }).then(response => {
  344 + this.download(response.msg);
  345 + }).catch(function() {});
272 346 }
273 347 }
274 348 };
... ...
ruoyi-ui/src/views/system/notice/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true" label-width="68px">
4   - <el-form-item label="公告标题">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  4 + <el-form-item label="公告标题" prop="noticeTitle">
5 5 <el-input
6 6 v-model="queryParams.noticeTitle"
7 7 placeholder="请输入公告标题"
... ... @@ -10,7 +10,7 @@
10 10 @keyup.enter.native="handleQuery"
11 11 />
12 12 </el-form-item>
13   - <el-form-item label="操作人员">
  13 + <el-form-item label="操作人员" prop="createBy">
14 14 <el-input
15 15 v-model="queryParams.createBy"
16 16 placeholder="请输入操作人员"
... ... @@ -19,7 +19,7 @@
19 19 @keyup.enter.native="handleQuery"
20 20 />
21 21 </el-form-item>
22   - <el-form-item label="类型">
  22 + <el-form-item label="类型" prop="noticeType">
23 23 <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small">
24 24 <el-option
25 25 v-for="dict in typeOptions"
... ... @@ -31,11 +31,44 @@
31 31 </el-form-item>
32 32 <el-form-item>
33 33 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
34   - <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:notice:add']">新增</el-button>
  34 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
35 35 </el-form-item>
36 36 </el-form>
37 37  
38   - <el-table v-loading="loading" :data="noticeList">
  38 + <el-row :gutter="10" class="mb8">
  39 + <el-col :span="1.5">
  40 + <el-button
  41 + type="primary"
  42 + icon="el-icon-plus"
  43 + size="mini"
  44 + @click="handleAdd"
  45 + v-hasPermi="['system:notice:add']"
  46 + >新增</el-button>
  47 + </el-col>
  48 + <el-col :span="1.5">
  49 + <el-button
  50 + type="success"
  51 + icon="el-icon-edit"
  52 + size="mini"
  53 + :disabled="single"
  54 + @click="handleUpdate"
  55 + v-hasPermi="['system:notice:edit']"
  56 + >修改</el-button>
  57 + </el-col>
  58 + <el-col :span="1.5">
  59 + <el-button
  60 + type="danger"
  61 + icon="el-icon-delete"
  62 + size="mini"
  63 + :disabled="multiple"
  64 + @click="handleDelete"
  65 + v-hasPermi="['system:notice:remove']"
  66 + >删除</el-button>
  67 + </el-col>
  68 + </el-row>
  69 +
  70 + <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
  71 + <el-table-column type="selection" width="55" align="center" />
39 72 <el-table-column label="序号" align="center" prop="noticeId" width="100" />
40 73 <el-table-column
41 74 label="公告标题"
... ... @@ -65,10 +98,10 @@
65 98 </el-table-column>
66 99 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
67 100 <template slot-scope="scope">
68   - <el-button
69   - size="mini"
70   - type="text"
71   - icon="el-icon-edit"
  101 + <el-button
  102 + size="mini"
  103 + type="text"
  104 + icon="el-icon-edit"
72 105 @click="handleUpdate(scope.row)"
73 106 v-hasPermi="['system:notice:edit']"
74 107 >修改</el-button>
... ... @@ -125,7 +158,7 @@
125 158 </el-col>
126 159 <el-col :span="24">
127 160 <el-form-item label="内容">
128   - <Editor v-model="form.noticeContent"/>
  161 + <Editor v-model="form.noticeContent" />
129 162 </el-form-item>
130 163 </el-col>
131 164 </el-row>
... ... @@ -139,7 +172,7 @@
139 172 </template>
140 173  
141 174 <script>
142   -import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice";
  175 +import { listNotice, getNotice, delNotice, addNotice, updateNotice, exportNotice } from "@/api/system/notice";
143 176 import Editor from '@/components/Editor';
144 177  
145 178 export default {
... ... @@ -150,6 +183,12 @@ export default {
150 183 return {
151 184 // 遮罩层
152 185 loading: true,
  186 + // 选中数组
  187 + ids: [],
  188 + // 非单个禁用
  189 + single: true,
  190 + // 非多个禁用
  191 + multiple: true,
153 192 // 总条数
154 193 total: 0,
155 194 // 公告表格数据
... ... @@ -231,6 +270,17 @@ export default {
231 270 this.queryParams.pageNum = 1;
232 271 this.getList();
233 272 },
  273 + /** 重置按钮操作 */
  274 + resetQuery() {
  275 + this.resetForm("queryForm");
  276 + this.handleQuery();
  277 + },
  278 + // 多选框选中数据
  279 + handleSelectionChange(selection) {
  280 + this.ids = selection.map(item => item.noticeId)
  281 + this.single = selection.length!=1
  282 + this.multiple = !selection.length
  283 + },
234 284 /** 新增按钮操作 */
235 285 handleAdd() {
236 286 this.reset();
... ... @@ -240,7 +290,8 @@ export default {
240 290 /** 修改按钮操作 */
241 291 handleUpdate(row) {
242 292 this.reset();
243   - getNotice(row.noticeId).then(response => {
  293 + const noticeId = row.noticeId || this.ids
  294 + getNotice(noticeId).then(response => {
244 295 this.form = response.data;
245 296 this.open = true;
246 297 this.title = "修改公告";
... ... @@ -276,12 +327,13 @@ export default {
276 327 },
277 328 /** 删除按钮操作 */
278 329 handleDelete(row) {
279   - this.$confirm('是否确认删除公告标题为"' + row.noticeTitle + '"的数据项?', "警告", {
  330 + const noticeIds = row.noticeId || this.ids
  331 + this.$confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?', "警告", {
280 332 confirmButtonText: "确定",
281 333 cancelButtonText: "取消",
282 334 type: "warning"
283 335 }).then(function() {
284   - return delNotice(row.noticeId);
  336 + return delNotice(noticeIds);
285 337 }).then(() => {
286 338 this.getList();
287 339 this.msgSuccess("删除成功");
... ...
ruoyi-ui/src/views/system/post/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true" label-width="68px">
4   - <el-form-item label="岗位编码">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  4 + <el-form-item label="岗位编码" prop="postCode">
5 5 <el-input
6 6 v-model="queryParams.postCode"
7 7 placeholder="请输入岗位编码"
... ... @@ -10,7 +10,7 @@
10 10 @keyup.enter.native="handleQuery"
11 11 />
12 12 </el-form-item>
13   - <el-form-item label="岗位名称">
  13 + <el-form-item label="岗位名称" prop="postName">
14 14 <el-input
15 15 v-model="queryParams.postName"
16 16 placeholder="请输入岗位名称"
... ... @@ -19,7 +19,7 @@
19 19 @keyup.enter.native="handleQuery"
20 20 />
21 21 </el-form-item>
22   - <el-form-item label="状态">
  22 + <el-form-item label="状态" prop="status">
23 23 <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
24 24 <el-option
25 25 v-for="dict in statusOptions"
... ... @@ -31,11 +31,53 @@
31 31 </el-form-item>
32 32 <el-form-item>
33 33 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
34   - <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:post:add']">新增</el-button>
  34 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
35 35 </el-form-item>
36 36 </el-form>
37 37  
38   - <el-table v-loading="loading" :data="postList">
  38 + <el-row :gutter="10" class="mb8">
  39 + <el-col :span="1.5">
  40 + <el-button
  41 + type="primary"
  42 + icon="el-icon-plus"
  43 + size="mini"
  44 + @click="handleAdd"
  45 + v-hasPermi="['system:post:add']"
  46 + >新增</el-button>
  47 + </el-col>
  48 + <el-col :span="1.5">
  49 + <el-button
  50 + type="success"
  51 + icon="el-icon-edit"
  52 + size="mini"
  53 + :disabled="single"
  54 + @click="handleUpdate"
  55 + v-hasPermi="['system:post:edit']"
  56 + >修改</el-button>
  57 + </el-col>
  58 + <el-col :span="1.5">
  59 + <el-button
  60 + type="danger"
  61 + icon="el-icon-delete"
  62 + size="mini"
  63 + :disabled="multiple"
  64 + @click="handleDelete"
  65 + v-hasPermi="['system:post:remove']"
  66 + >删除</el-button>
  67 + </el-col>
  68 + <el-col :span="1.5">
  69 + <el-button
  70 + type="warning"
  71 + icon="el-icon-download"
  72 + size="mini"
  73 + @click="handleExport"
  74 + v-hasPermi="['system:post:export']"
  75 + >导出</el-button>
  76 + </el-col>
  77 + </el-row>
  78 +
  79 + <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
  80 + <el-table-column type="selection" width="55" align="center" />
39 81 <el-table-column label="岗位编号" align="center" prop="postId" />
40 82 <el-table-column label="岗位编码" align="center" prop="postCode" />
41 83 <el-table-column label="岗位名称" align="center" prop="postName" />
... ... @@ -48,10 +90,10 @@
48 90 </el-table-column>
49 91 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
50 92 <template slot-scope="scope">
51   - <el-button
52   - size="mini"
53   - type="text"
54   - icon="el-icon-edit"
  93 + <el-button
  94 + size="mini"
  95 + type="text"
  96 + icon="el-icon-edit"
55 97 @click="handleUpdate(scope.row)"
56 98 v-hasPermi="['system:post:edit']"
57 99 >修改</el-button>
... ... @@ -65,7 +107,7 @@
65 107 </template>
66 108 </el-table-column>
67 109 </el-table>
68   -
  110 +
69 111 <pagination
70 112 v-show="total>0"
71 113 :total="total"
... ... @@ -108,13 +150,19 @@
108 150 </template>
109 151  
110 152 <script>
111   -import { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/post";
  153 +import { listPost, getPost, delPost, addPost, updatePost, exportPost } from "@/api/system/post";
112 154  
113 155 export default {
114 156 data() {
115 157 return {
116 158 // 遮罩层
117 159 loading: true,
  160 + // 选中数组
  161 + ids: [],
  162 + // 非单个禁用
  163 + single: true,
  164 + // 非多个禁用
  165 + multiple: true,
118 166 // 总条数
119 167 total: 0,
120 168 // 岗位表格数据
... ... @@ -191,6 +239,17 @@ export default {
191 239 this.queryParams.pageNum = 1;
192 240 this.getList();
193 241 },
  242 + /** 重置按钮操作 */
  243 + resetQuery() {
  244 + this.resetForm("queryForm");
  245 + this.handleQuery();
  246 + },
  247 + // 多选框选中数据
  248 + handleSelectionChange(selection) {
  249 + this.ids = selection.map(item => item.postId)
  250 + this.single = selection.length!=1
  251 + this.multiple = !selection.length
  252 + },
194 253 /** 新增按钮操作 */
195 254 handleAdd() {
196 255 this.reset();
... ... @@ -200,7 +259,8 @@ export default {
200 259 /** 修改按钮操作 */
201 260 handleUpdate(row) {
202 261 this.reset();
203   - getPost(row.postId).then(response => {
  262 + const postId = row.postId || this.ids
  263 + getPost(postId).then(response => {
204 264 this.form = response.data;
205 265 this.open = true;
206 266 this.title = "修改岗位";
... ... @@ -236,16 +296,30 @@ export default {
236 296 },
237 297 /** 删除按钮操作 */
238 298 handleDelete(row) {
239   - this.$confirm('是否确认删除岗位名称为"' + row.postName + '"的数据项?', "警告", {
  299 + const postIds = row.postId || this.ids;
  300 + this.$confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?', "警告", {
240 301 confirmButtonText: "确定",
241 302 cancelButtonText: "取消",
242 303 type: "warning"
243 304 }).then(function() {
244   - return delPost(row.postId);
  305 + return delPost(postIds);
245 306 }).then(() => {
246 307 this.getList();
247 308 this.msgSuccess("删除成功");
248 309 }).catch(function() {});
  310 + },
  311 + /** 导出按钮操作 */
  312 + handleExport() {
  313 + const queryParams = this.queryParams;
  314 + this.$confirm('是否确认导出所有岗位数据项?', "警告", {
  315 + confirmButtonText: "确定",
  316 + cancelButtonText: "取消",
  317 + type: "warning"
  318 + }).then(function() {
  319 + return exportPost(queryParams);
  320 + }).then(response => {
  321 + this.download(response.msg);
  322 + }).catch(function() {});
249 323 }
250 324 }
251 325 };
... ...
ruoyi-ui/src/views/system/role/index.vue
1 1 <template>
2 2 <div class="app-container">
3   - <el-form :inline="true">
4   - <el-form-item label="角色名称">
  3 + <el-form :model="queryParams" ref="queryForm" :inline="true">
  4 + <el-form-item label="角色名称" prop="roleName">
5 5 <el-input
6 6 v-model="queryParams.roleName"
7 7 placeholder="请输入角色名称"
... ... @@ -11,7 +11,7 @@
11 11 @keyup.enter.native="handleQuery"
12 12 />
13 13 </el-form-item>
14   - <el-form-item label="权限字符">
  14 + <el-form-item label="权限字符" prop="roleKey">
15 15 <el-input
16 16 v-model="queryParams.roleKey"
17 17 placeholder="请输入权限字符"
... ... @@ -21,7 +21,7 @@
21 21 @keyup.enter.native="handleQuery"
22 22 />
23 23 </el-form-item>
24   - <el-form-item label="状态">
  24 + <el-form-item label="状态" prop="status">
25 25 <el-select
26 26 v-model="queryParams.status"
27 27 placeholder="角色状态"
... ... @@ -51,6 +51,12 @@
51 51 </el-form-item>
52 52 <el-form-item>
53 53 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  54 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  55 + </el-form-item>
  56 + </el-form>
  57 +
  58 + <el-row :gutter="10" class="mb8">
  59 + <el-col :span="1.5">
54 60 <el-button
55 61 type="primary"
56 62 icon="el-icon-plus"
... ... @@ -58,15 +64,45 @@
58 64 @click="handleAdd"
59 65 v-hasPermi="['system:role:add']"
60 66 >新增</el-button>
61   - </el-form-item>
62   - </el-form>
  67 + </el-col>
  68 + <el-col :span="1.5">
  69 + <el-button
  70 + type="success"
  71 + icon="el-icon-edit"
  72 + size="mini"
  73 + :disabled="single"
  74 + @click="handleUpdate"
  75 + v-hasPermi="['system:role:edit']"
  76 + >修改</el-button>
  77 + </el-col>
  78 + <el-col :span="1.5">
  79 + <el-button
  80 + type="danger"
  81 + icon="el-icon-delete"
  82 + size="mini"
  83 + :disabled="multiple"
  84 + @click="handleDelete"
  85 + v-hasPermi="['system:role:remove']"
  86 + >删除</el-button>
  87 + </el-col>
  88 + <el-col :span="1.5">
  89 + <el-button
  90 + type="warning"
  91 + icon="el-icon-download"
  92 + size="mini"
  93 + @click="handleExport"
  94 + v-hasPermi="['system:post:export']"
  95 + >导出</el-button>
  96 + </el-col>
  97 + </el-row>
63 98  
64   - <el-table v-loading="loading" :data="roleList">
  99 + <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
  100 + <el-table-column type="selection" width="55" align="center" />
65 101 <el-table-column label="角色编号" prop="roleId" width="120" />
66 102 <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
67   - <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="180" />
68   - <el-table-column label="显示顺序" prop="roleSort" width="120" />
69   - <el-table-column label="状态" align="center" width="120">
  103 + <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
  104 + <el-table-column label="显示顺序" prop="roleSort" width="100" />
  105 + <el-table-column label="状态" align="center" width="100">
70 106 <template slot-scope="scope">
71 107 <el-switch
72 108 v-model="scope.row.status"
... ... @@ -197,7 +233,7 @@
197 233 </template>
198 234  
199 235 <script>
200   -import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/api/system/role";
  236 +import { listRole, getRole, delRole, addRole, updateRole, exportRole, dataScope, changeRoleStatus } from "@/api/system/role";
201 237 import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
202 238 import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
203 239  
... ... @@ -206,6 +242,12 @@ export default {
206 242 return {
207 243 // 遮罩层
208 244 loading: true,
  245 + // 选中数组
  246 + ids: [],
  247 + // 非单个禁用
  248 + single: true,
  249 + // 非多个禁用
  250 + multiple: true,
209 251 // 总条数
210 252 total: 0,
211 253 // 角色表格数据
... ... @@ -384,6 +426,18 @@ export default {
384 426 this.queryParams.pageNum = 1;
385 427 this.getList();
386 428 },
  429 + /** 重置按钮操作 */
  430 + resetQuery() {
  431 + this.dateRange = [];
  432 + this.resetForm("queryForm");
  433 + this.handleQuery();
  434 + },
  435 + // 多选框选中数据
  436 + handleSelectionChange(selection) {
  437 + this.ids = selection.map(item => item.roleId)
  438 + this.single = selection.length!=1
  439 + this.multiple = !selection.length
  440 + },
387 441 /** 新增按钮操作 */
388 442 handleAdd() {
389 443 this.reset();
... ... @@ -394,10 +448,11 @@ export default {
394 448 /** 修改按钮操作 */
395 449 handleUpdate(row) {
396 450 this.reset();
  451 + const roleId = row.roleId || this.ids
397 452 this.$nextTick(() => {
398   - this.getRoleMenuTreeselect(row.roleId);
  453 + this.getRoleMenuTreeselect(roleId);
399 454 });
400   - getRole(row.roleId).then(response => {
  455 + getRole(roleId).then(response => {
401 456 this.form = response.data;
402 457 this.open = true;
403 458 this.title = "修改角色";
... ... @@ -462,16 +517,30 @@ export default {
462 517 },
463 518 /** 删除按钮操作 */
464 519 handleDelete(row) {
465   - this.$confirm('是否确认删除名称为"' + row.roleName + '"的数据项?', "警告", {
  520 + const roleIds = row.roleId || this.ids;
  521 + this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', "警告", {
466 522 confirmButtonText: "确定",
467 523 cancelButtonText: "取消",
468 524 type: "warning"
469 525 }).then(function() {
470   - return delRole(row.roleId);
  526 + return delRole(roleIds);
471 527 }).then(() => {
472 528 this.getList();
473 529 this.msgSuccess("删除成功");
474 530 }).catch(function() {});
  531 + },
  532 + /** 导出按钮操作 */
  533 + handleExport() {
  534 + const queryParams = this.queryParams;
  535 + this.$confirm('是否确认导出所有角色数据项?', "警告", {
  536 + confirmButtonText: "确定",
  537 + cancelButtonText: "取消",
  538 + type: "warning"
  539 + }).then(function() {
  540 + return exportRole(queryParams);
  541 + }).then(response => {
  542 + this.download(response.msg);
  543 + }).catch(function() {});
475 544 }
476 545 }
477 546 };
... ...
ruoyi-ui/src/views/system/user/index.vue
... ... @@ -27,8 +27,8 @@
27 27 </el-col>
28 28 <!--用户数据-->
29 29 <el-col :span="20" :xs="24">
30   - <el-form :inline="true" label-width="68px">
31   - <el-form-item label="用户名称">
  30 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
  31 + <el-form-item label="用户名称" prop="userName">
32 32 <el-input
33 33 v-model="queryParams.userName"
34 34 placeholder="请输入用户名称"
... ... @@ -38,7 +38,7 @@
38 38 @keyup.enter.native="handleQuery"
39 39 />
40 40 </el-form-item>
41   - <el-form-item label="手机号码">
  41 + <el-form-item label="手机号码" prop="phonenumber">
42 42 <el-input
43 43 v-model="queryParams.phonenumber"
44 44 placeholder="请输入手机号码"
... ... @@ -48,7 +48,7 @@
48 48 @keyup.enter.native="handleQuery"
49 49 />
50 50 </el-form-item>
51   - <el-form-item label="状态">
  51 + <el-form-item label="状态" prop="status">
52 52 <el-select
53 53 v-model="queryParams.status"
54 54 placeholder="用户状态"
... ... @@ -78,11 +78,53 @@
78 78 </el-form-item>
79 79 <el-form-item>
80 80 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
81   - <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button>
  81 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
82 82 </el-form-item>
83 83 </el-form>
84 84  
85   - <el-table v-loading="loading" :data="userList">
  85 + <el-row :gutter="10" class="mb8">
  86 + <el-col :span="1.5">
  87 + <el-button
  88 + type="primary"
  89 + icon="el-icon-plus"
  90 + size="mini"
  91 + @click="handleAdd"
  92 + v-hasPermi="['system:user:add']"
  93 + >新增</el-button>
  94 + </el-col>
  95 + <el-col :span="1.5">
  96 + <el-button
  97 + type="success"
  98 + icon="el-icon-edit"
  99 + size="mini"
  100 + :disabled="single"
  101 + @click="handleUpdate"
  102 + v-hasPermi="['system:user:edit']"
  103 + >修改</el-button>
  104 + </el-col>
  105 + <el-col :span="1.5">
  106 + <el-button
  107 + type="danger"
  108 + icon="el-icon-delete"
  109 + size="mini"
  110 + :disabled="multiple"
  111 + @click="handleDelete"
  112 + v-hasPermi="['system:user:remove']"
  113 + >删除</el-button>
  114 + </el-col>
  115 + <el-col :span="1.5">
  116 + <el-button
  117 + type="warning"
  118 + icon="el-icon-download"
  119 + size="mini"
  120 + @click="handleExport"
  121 + v-hasPermi="['system:user:export']"
  122 + >导出</el-button>
  123 + </el-col>
  124 + </el-row>
  125 +
  126 + <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
  127 + <el-table-column type="selection" width="40" align="center" />
86 128 <el-table-column label="用户编号" align="center" prop="userId" />
87 129 <el-table-column label="用户名称" align="center" prop="userName" />
88 130 <el-table-column label="用户昵称" align="center" prop="nickName" />
... ... @@ -246,7 +288,7 @@
246 288 </template>
247 289  
248 290 <script>
249   -import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
  291 +import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
250 292 import { treeselect } from "@/api/system/dept";
251 293 import { listPost } from "@/api/system/post";
252 294 import { listRole } from "@/api/system/role";
... ... @@ -259,6 +301,12 @@ export default {
259 301 return {
260 302 // 遮罩层
261 303 loading: true,
  304 + // 选中数组
  305 + ids: [],
  306 + // 非单个禁用
  307 + single: true,
  308 + // 非多个禁用
  309 + multiple: true,
262 310 // 总条数
263 311 total: 0,
264 312 // 用户表格数据
... ... @@ -430,6 +478,18 @@ export default {
430 478 this.queryParams.page = 1;
431 479 this.getList();
432 480 },
  481 + /** 重置按钮操作 */
  482 + resetQuery() {
  483 + this.dateRange = [];
  484 + this.resetForm("queryForm");
  485 + this.handleQuery();
  486 + },
  487 + // 多选框选中数据
  488 + handleSelectionChange(selection) {
  489 + this.ids = selection.map(item => item.userId)
  490 + this.single = selection.length!=1
  491 + this.multiple = !selection.length
  492 + },
433 493 /** 新增按钮操作 */
434 494 handleAdd() {
435 495 this.reset();
... ... @@ -446,7 +506,8 @@ export default {
446 506 this.getTreeselect();
447 507 this.getPosts();
448 508 this.getRoles();
449   - getUser(row.userId).then(response => {
  509 + const userId = row.userId || this.ids
  510 + getUser(userId).then(response => {
450 511 this.form = response.data;
451 512 this.form.postIds = response.postIds;
452 513 this.form.roleIds = response.roleIds;
... ... @@ -500,16 +561,30 @@ export default {
500 561 },
501 562 /** 删除按钮操作 */
502 563 handleDelete(row) {
503   - this.$confirm('是否确认删除名称为"' + row.userName + '"的数据项?', "警告", {
  564 + const userIds = row.userId || this.ids;
  565 + this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", {
504 566 confirmButtonText: "确定",
505 567 cancelButtonText: "取消",
506 568 type: "warning"
507 569 }).then(function() {
508   - return delUser(row.userId);
  570 + return delUser(userIds);
509 571 }).then(() => {
510 572 this.getList();
511 573 this.msgSuccess("删除成功");
512 574 }).catch(function() {});
  575 + },
  576 + /** 导出按钮操作 */
  577 + handleExport() {
  578 + const queryParams = this.queryParams;
  579 + this.$confirm('是否确认导出所有用户数据项?', "警告", {
  580 + confirmButtonText: "确定",
  581 + cancelButtonText: "取消",
  582 + type: "warning"
  583 + }).then(function() {
  584 + return exportUser(queryParams);
  585 + }).then(response => {
  586 + this.download(response.msg);
  587 + }).catch(function() {});
513 588 }
514 589 }
515 590 };
... ...
ruoyi-ui/vue.config.js
... ... @@ -17,7 +17,7 @@ module.exports = {
17 17 // 部署生产环境和开发环境下的URL。
18 18 // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
19 19 // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
20   - publicPath: process.env.NODE_ENV === "production" ? "./" : "/",
  20 + publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
21 21 // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
22 22 outputDir: 'dist',
23 23 // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
... ...
ruoyi/pom.xml
... ... @@ -5,7 +5,7 @@
5 5  
6 6 <groupId>com.ruoyi</groupId>
7 7 <artifactId>ruoyi</artifactId>
8   - <version>1.0</version>
  8 + <version>1.1</version>
9 9 <packaging>jar</packaging>
10 10  
11 11 <name>ruoyi</name>
... ... @@ -32,6 +32,7 @@
32 32 <bitwalker.version>1.19</bitwalker.version>
33 33 <jwt.version>0.9.0</jwt.version>
34 34 <swagger.version>2.9.2</swagger.version>
  35 + <poi.version>3.17</poi.version>
35 36 <oshi.version>3.9.1</oshi.version>
36 37 </properties>
37 38  
... ... @@ -223,6 +224,13 @@
223 224 <groupId>net.java.dev.jna</groupId>
224 225 <artifactId>jna-platform</artifactId>
225 226 </dependency>
  227 +
  228 + <!-- excel工具 -->
  229 + <dependency>
  230 + <groupId>org.apache.poi</groupId>
  231 + <artifactId>poi-ooxml</artifactId>
  232 + <version>${poi.version}</version>
  233 + </dependency>
226 234  
227 235 </dependencies>
228 236  
... ...
ruoyi/sql/ry_20191008.sql renamed to ruoyi/sql/ry_20191111.sql
... ... @@ -136,7 +136,7 @@ create table sys_menu (
136 136 path varchar(200) default '' comment '路由地址',
137 137 component varchar(255) default null comment '组件路径',
138 138 is_frame int(1) default 1 comment '是否为外链(0是 1否)',
139   - menu_type char(1) default '' comment '菜单类型(0目录 1菜单 2按钮)',
  139 + menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)',
140 140 visible char(1) default 0 comment '菜单状态(0显示 1隐藏)',
141 141 perms varchar(100) default null comment '权限标识',
142 142 icon varchar(100) default '#' comment '菜单图标',
... ... @@ -152,10 +152,10 @@ create table sys_menu (
152 152 -- 初始化-菜单信息表数据
153 153 -- ----------------------------
154 154 -- 一级菜单
155   -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', '系统管理目录');
156   -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', '系统监控目录');
157   -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', '系统工具目录');
158   -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', '若依官网');
  155 +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', '系统管理目录');
  156 +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', '系统监控目录');
  157 +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', '系统工具目录');
  158 +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', '若依官网地址');
159 159 -- 二级菜单
160 160 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', '用户管理菜单');
161 161 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 @@ create table sys_logininfor (
550 550  
551 551  
552 552 -- ----------------------------
553   --- 15、在线用户记录
554   --- ----------------------------
555   -drop table if exists sys_user_online;
556   -create table sys_user_online (
557   - sessionId varchar(50) default '' comment '用户会话id',
558   - user_name varchar(50) default '' comment '用户账号',
559   - dept_name varchar(50) default '' comment '部门名称',
560   - ipaddr varchar(50) default '' comment '登录IP地址',
561   - login_location varchar(255) default '' comment '登录地点',
562   - browser varchar(50) default '' comment '浏览器类型',
563   - os varchar(50) default '' comment '操作系统',
564   - status varchar(10) default '' comment '在线状态on_line在线off_line离线',
565   - start_timestamp datetime comment 'session创建时间',
566   - last_access_time datetime comment 'session最后访问时间',
567   - expire_time int(5) default 0 comment '超时时间,单位为分钟',
568   - primary key (sessionId)
569   -) engine=innodb comment = '在线用户记录';
570   -
571   -
572   --- ----------------------------
573   --- 16、定时任务调度表
  553 +-- 15、定时任务调度表
574 554 -- ----------------------------
575 555 drop table if exists sys_job;
576 556 create table sys_job (
... ... @@ -596,7 +576,7 @@ insert into sys_job values(3, &#39;系统默认(多参)&#39;, &#39;DEFAULT&#39;, &#39;ryTask.ryM
596 576  
597 577  
598 578 -- ----------------------------
599   --- 17、定时任务调度日志表
  579 +-- 16、定时任务调度日志表
600 580 -- ----------------------------
601 581 drop table if exists sys_job_log;
602 582 create table sys_job_log (
... ... @@ -613,7 +593,7 @@ create table sys_job_log (
613 593  
614 594  
615 595 -- ----------------------------
616   --- 18、通知公告表
  596 +-- 17、通知公告表
617 597 -- ----------------------------
618 598 drop table if exists sys_notice;
619 599 create table sys_notice (
... ... @@ -638,7 +618,7 @@ insert into sys_notice values(&#39;2&#39;, &#39;维护通知:2018-07-01 若依系统凌晨
638 618  
639 619  
640 620 -- ----------------------------
641   --- 19、代码生成业务表
  621 +-- 18、代码生成业务表
642 622 -- ----------------------------
643 623 drop table if exists gen_table;
644 624 create table gen_table (
... ... @@ -663,7 +643,7 @@ create table gen_table (
663 643  
664 644  
665 645 -- ----------------------------
666   --- 20、代码生成业务表字段
  646 +-- 19、代码生成业务表字段
667 647 -- ----------------------------
668 648 drop table if exists gen_table_column;
669 649 create table gen_table_column (
... ...
ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java 0 → 100644
  1 +package com.ruoyi.common.utils.poi;
  2 +
  3 +import java.io.File;
  4 +import java.io.FileOutputStream;
  5 +import java.io.IOException;
  6 +import java.io.InputStream;
  7 +import java.io.OutputStream;
  8 +import java.lang.reflect.Field;
  9 +import java.lang.reflect.Method;
  10 +import java.math.BigDecimal;
  11 +import java.text.DecimalFormat;
  12 +import java.util.ArrayList;
  13 +import java.util.Arrays;
  14 +import java.util.Date;
  15 +import java.util.HashMap;
  16 +import java.util.List;
  17 +import java.util.Map;
  18 +import java.util.UUID;
  19 +import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  20 +import org.apache.poi.ss.usermodel.BorderStyle;
  21 +import org.apache.poi.ss.usermodel.Cell;
  22 +import org.apache.poi.ss.usermodel.CellStyle;
  23 +import org.apache.poi.ss.usermodel.CellType;
  24 +import org.apache.poi.ss.usermodel.DataValidation;
  25 +import org.apache.poi.ss.usermodel.DataValidationConstraint;
  26 +import org.apache.poi.ss.usermodel.DataValidationHelper;
  27 +import org.apache.poi.ss.usermodel.DateUtil;
  28 +import org.apache.poi.ss.usermodel.FillPatternType;
  29 +import org.apache.poi.ss.usermodel.Font;
  30 +import org.apache.poi.ss.usermodel.HorizontalAlignment;
  31 +import org.apache.poi.ss.usermodel.IndexedColors;
  32 +import org.apache.poi.ss.usermodel.Row;
  33 +import org.apache.poi.ss.usermodel.Sheet;
  34 +import org.apache.poi.ss.usermodel.VerticalAlignment;
  35 +import org.apache.poi.ss.usermodel.Workbook;
  36 +import org.apache.poi.ss.usermodel.WorkbookFactory;
  37 +import org.apache.poi.ss.util.CellRangeAddressList;
  38 +import org.apache.poi.xssf.streaming.SXSSFWorkbook;
  39 +import org.apache.poi.xssf.usermodel.XSSFDataValidation;
  40 +import org.slf4j.Logger;
  41 +import org.slf4j.LoggerFactory;
  42 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  43 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
  44 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.Type;
  45 +import com.ruoyi.framework.aspectj.lang.annotation.Excels;
  46 +import com.ruoyi.framework.config.RuoYiConfig;
  47 +import com.ruoyi.framework.web.domain.AjaxResult;
  48 +import com.ruoyi.common.core.text.Convert;
  49 +import com.ruoyi.common.exception.CustomException;
  50 +import com.ruoyi.common.utils.DateUtils;
  51 +import com.ruoyi.common.utils.StringUtils;
  52 +import com.ruoyi.common.utils.reflect.ReflectUtils;
  53 +
  54 +/**
  55 + * Excel相关处理
  56 + *
  57 + * @author ruoyi
  58 + */
  59 +public class ExcelUtil<T>
  60 +{
  61 + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
  62 +
  63 + /**
  64 + * Excel sheet最大行数,默认65536
  65 + */
  66 + public static final int sheetSize = 65536;
  67 +
  68 + /**
  69 + * 工作表名称
  70 + */
  71 + private String sheetName;
  72 +
  73 + /**
  74 + * 导出类型(EXPORT:导出数据;IMPORT:导入模板)
  75 + */
  76 + private Type type;
  77 +
  78 + /**
  79 + * 工作薄对象
  80 + */
  81 + private Workbook wb;
  82 +
  83 + /**
  84 + * 工作表对象
  85 + */
  86 + private Sheet sheet;
  87 +
  88 + /**
  89 + * 样式列表
  90 + */
  91 + private Map<String, CellStyle> styles;
  92 +
  93 + /**
  94 + * 导入导出数据列表
  95 + */
  96 + private List<T> list;
  97 +
  98 + /**
  99 + * 注解列表
  100 + */
  101 + private List<Object[]> fields;
  102 +
  103 + /**
  104 + * 实体对象
  105 + */
  106 + public Class<T> clazz;
  107 +
  108 + public ExcelUtil(Class<T> clazz)
  109 + {
  110 + this.clazz = clazz;
  111 + }
  112 +
  113 + public void init(List<T> list, String sheetName, Type type)
  114 + {
  115 + if (list == null)
  116 + {
  117 + list = new ArrayList<T>();
  118 + }
  119 + this.list = list;
  120 + this.sheetName = sheetName;
  121 + this.type = type;
  122 + createExcelField();
  123 + createWorkbook();
  124 + }
  125 +
  126 + /**
  127 + * 对excel表单默认第一个索引名转换成list
  128 + *
  129 + * @param is 输入流
  130 + * @return 转换后集合
  131 + */
  132 + public List<T> importExcel(InputStream is) throws Exception
  133 + {
  134 + return importExcel(StringUtils.EMPTY, is);
  135 + }
  136 +
  137 + /**
  138 + * 对excel表单指定表格索引名转换成list
  139 + *
  140 + * @param sheetName 表格索引名
  141 + * @param is 输入流
  142 + * @return 转换后集合
  143 + */
  144 + public List<T> importExcel(String sheetName, InputStream is) throws Exception
  145 + {
  146 + this.type = Type.IMPORT;
  147 + this.wb = WorkbookFactory.create(is);
  148 + List<T> list = new ArrayList<T>();
  149 + Sheet sheet = null;
  150 + if (StringUtils.isNotEmpty(sheetName))
  151 + {
  152 + // 如果指定sheet名,则取指定sheet中的内容.
  153 + sheet = wb.getSheet(sheetName);
  154 + }
  155 + else
  156 + {
  157 + // 如果传入的sheet名不存在则默认指向第1个sheet.
  158 + sheet = wb.getSheetAt(0);
  159 + }
  160 +
  161 + if (sheet == null)
  162 + {
  163 + throw new IOException("文件sheet不存在");
  164 + }
  165 +
  166 + int rows = sheet.getPhysicalNumberOfRows();
  167 +
  168 + if (rows > 0)
  169 + {
  170 + // 定义一个map用于存放excel列的序号和field.
  171 + Map<String, Integer> cellMap = new HashMap<String, Integer>();
  172 + // 获取表头
  173 + Row heard = sheet.getRow(0);
  174 + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
  175 + {
  176 + Cell cell = heard.getCell(i);
  177 + if (StringUtils.isNotNull(cell != null))
  178 + {
  179 + String value = this.getCellValue(heard, i).toString();
  180 + cellMap.put(value, i);
  181 + }
  182 + else
  183 + {
  184 + cellMap.put(null, i);
  185 + }
  186 + }
  187 + // 有数据时才处理 得到类的所有field.
  188 + Field[] allFields = clazz.getDeclaredFields();
  189 + // 定义一个map用于存放列的序号和field.
  190 + Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();
  191 + for (int col = 0; col < allFields.length; col++)
  192 + {
  193 + Field field = allFields[col];
  194 + Excel attr = field.getAnnotation(Excel.class);
  195 + if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
  196 + {
  197 + // 设置类的私有字段属性可访问.
  198 + field.setAccessible(true);
  199 + Integer column = cellMap.get(attr.name());
  200 + fieldsMap.put(column, field);
  201 + }
  202 + }
  203 + for (int i = 1; i < rows; i++)
  204 + {
  205 + // 从第2行开始取数据,默认第一行是表头.
  206 + Row row = sheet.getRow(i);
  207 + T entity = null;
  208 + for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet())
  209 + {
  210 + Object val = this.getCellValue(row, entry.getKey());
  211 +
  212 + // 如果不存在实例则新建.
  213 + entity = (entity == null ? clazz.newInstance() : entity);
  214 + // 从map中得到对应列的field.
  215 + Field field = fieldsMap.get(entry.getKey());
  216 + // 取得类型,并根据对象类型设置值.
  217 + Class<?> fieldType = field.getType();
  218 + if (String.class == fieldType)
  219 + {
  220 + String s = Convert.toStr(val);
  221 + if (StringUtils.endsWith(s, ".0"))
  222 + {
  223 + val = StringUtils.substringBefore(s, ".0");
  224 + }
  225 + else
  226 + {
  227 + val = Convert.toStr(val);
  228 + }
  229 + }
  230 + else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
  231 + {
  232 + val = Convert.toInt(val);
  233 + }
  234 + else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
  235 + {
  236 + val = Convert.toLong(val);
  237 + }
  238 + else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
  239 + {
  240 + val = Convert.toDouble(val);
  241 + }
  242 + else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
  243 + {
  244 + val = Convert.toFloat(val);
  245 + }
  246 + else if (BigDecimal.class == fieldType)
  247 + {
  248 + val = Convert.toBigDecimal(val);
  249 + }
  250 + else if (Date.class == fieldType)
  251 + {
  252 + if (val instanceof String)
  253 + {
  254 + val = DateUtils.parseDate(val);
  255 + }
  256 + else if (val instanceof Double)
  257 + {
  258 + val = DateUtil.getJavaDate((Double) val);
  259 + }
  260 + }
  261 + if (StringUtils.isNotNull(fieldType))
  262 + {
  263 + Excel attr = field.getAnnotation(Excel.class);
  264 + String propertyName = field.getName();
  265 + if (StringUtils.isNotEmpty(attr.targetAttr()))
  266 + {
  267 + propertyName = field.getName() + "." + attr.targetAttr();
  268 + }
  269 + else if (StringUtils.isNotEmpty(attr.readConverterExp()))
  270 + {
  271 + val = reverseByExp(String.valueOf(val), attr.readConverterExp());
  272 + }
  273 + ReflectUtils.invokeSetter(entity, propertyName, val);
  274 + }
  275 + }
  276 + list.add(entity);
  277 + }
  278 + }
  279 + return list;
  280 + }
  281 +
  282 + /**
  283 + * 对list数据源将其里面的数据导入到excel表单
  284 + *
  285 + * @param list 导出数据集合
  286 + * @param sheetName 工作表的名称
  287 + * @return 结果
  288 + */
  289 + public AjaxResult exportExcel(List<T> list, String sheetName)
  290 + {
  291 + this.init(list, sheetName, Type.EXPORT);
  292 + return exportExcel();
  293 + }
  294 +
  295 + /**
  296 + * 对list数据源将其里面的数据导入到excel表单
  297 + *
  298 + * @param sheetName 工作表的名称
  299 + * @return 结果
  300 + */
  301 + public AjaxResult importTemplateExcel(String sheetName)
  302 + {
  303 + this.init(null, sheetName, Type.IMPORT);
  304 + return exportExcel();
  305 + }
  306 +
  307 + /**
  308 + * 对list数据源将其里面的数据导入到excel表单
  309 + *
  310 + * @return 结果
  311 + */
  312 + public AjaxResult exportExcel()
  313 + {
  314 + OutputStream out = null;
  315 + try
  316 + {
  317 + // 取出一共有多少个sheet.
  318 + double sheetNo = Math.ceil(list.size() / sheetSize);
  319 + for (int index = 0; index <= sheetNo; index++)
  320 + {
  321 + createSheet(sheetNo, index);
  322 +
  323 + // 产生一行
  324 + Row row = sheet.createRow(0);
  325 + int column = 0;
  326 + // 写入各个字段的列头名称
  327 + for (Object[] os : fields)
  328 + {
  329 + Excel excel = (Excel) os[1];
  330 + this.createCell(excel, row, column++);
  331 + }
  332 + if (Type.EXPORT.equals(type))
  333 + {
  334 + fillExcelData(index, row);
  335 + }
  336 + }
  337 + String filename = encodingFilename(sheetName);
  338 + out = new FileOutputStream(getAbsoluteFile(filename));
  339 + wb.write(out);
  340 + return AjaxResult.success(filename);
  341 + }
  342 + catch (Exception e)
  343 + {
  344 + log.error("导出Excel异常{}", e.getMessage());
  345 + throw new CustomException("导出Excel失败,请联系网站管理员!");
  346 + }
  347 + finally
  348 + {
  349 + if (wb != null)
  350 + {
  351 + try
  352 + {
  353 + wb.close();
  354 + }
  355 + catch (IOException e1)
  356 + {
  357 + e1.printStackTrace();
  358 + }
  359 + }
  360 + if (out != null)
  361 + {
  362 + try
  363 + {
  364 + out.close();
  365 + }
  366 + catch (IOException e1)
  367 + {
  368 + e1.printStackTrace();
  369 + }
  370 + }
  371 + }
  372 + }
  373 +
  374 + /**
  375 + * 填充excel数据
  376 + *
  377 + * @param index 序号
  378 + * @param row 单元格行
  379 + */
  380 + public void fillExcelData(int index, Row row)
  381 + {
  382 + int startNo = index * sheetSize;
  383 + int endNo = Math.min(startNo + sheetSize, list.size());
  384 + for (int i = startNo; i < endNo; i++)
  385 + {
  386 + row = sheet.createRow(i + 1 - startNo);
  387 + // 得到导出对象.
  388 + T vo = (T) list.get(i);
  389 + int column = 0;
  390 + for (Object[] os : fields)
  391 + {
  392 + Field field = (Field) os[0];
  393 + Excel excel = (Excel) os[1];
  394 + // 设置实体类私有属性可访问
  395 + field.setAccessible(true);
  396 + this.addCell(excel, row, vo, field, column++);
  397 + }
  398 + }
  399 + }
  400 +
  401 + /**
  402 + * 创建表格样式
  403 + *
  404 + * @param wb 工作薄对象
  405 + * @return 样式列表
  406 + */
  407 + private Map<String, CellStyle> createStyles(Workbook wb)
  408 + {
  409 + // 写入各条记录,每条记录对应excel表中的一行
  410 + Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
  411 + CellStyle style = wb.createCellStyle();
  412 + style.setAlignment(HorizontalAlignment.CENTER);
  413 + style.setVerticalAlignment(VerticalAlignment.CENTER);
  414 + style.setBorderRight(BorderStyle.THIN);
  415 + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
  416 + style.setBorderLeft(BorderStyle.THIN);
  417 + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
  418 + style.setBorderTop(BorderStyle.THIN);
  419 + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
  420 + style.setBorderBottom(BorderStyle.THIN);
  421 + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
  422 + Font dataFont = wb.createFont();
  423 + dataFont.setFontName("Arial");
  424 + dataFont.setFontHeightInPoints((short) 10);
  425 + style.setFont(dataFont);
  426 + styles.put("data", style);
  427 +
  428 + style = wb.createCellStyle();
  429 + style.cloneStyleFrom(styles.get("data"));
  430 + style.setAlignment(HorizontalAlignment.CENTER);
  431 + style.setVerticalAlignment(VerticalAlignment.CENTER);
  432 + style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
  433 + style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  434 + Font headerFont = wb.createFont();
  435 + headerFont.setFontName("Arial");
  436 + headerFont.setFontHeightInPoints((short) 10);
  437 + headerFont.setBold(true);
  438 + headerFont.setColor(IndexedColors.WHITE.getIndex());
  439 + style.setFont(headerFont);
  440 + styles.put("header", style);
  441 +
  442 + return styles;
  443 + }
  444 +
  445 + /**
  446 + * 创建单元格
  447 + */
  448 + public Cell createCell(Excel attr, Row row, int column)
  449 + {
  450 + // 创建列
  451 + Cell cell = row.createCell(column);
  452 + // 写入列信息
  453 + cell.setCellValue(attr.name());
  454 + setDataValidation(attr, row, column);
  455 + cell.setCellStyle(styles.get("header"));
  456 + return cell;
  457 + }
  458 +
  459 + /**
  460 + * 设置单元格信息
  461 + *
  462 + * @param value 单元格值
  463 + * @param attr 注解相关
  464 + * @param cell 单元格信息
  465 + */
  466 + public void setCellVo(Object value, Excel attr, Cell cell)
  467 + {
  468 + if (ColumnType.STRING == attr.cellType())
  469 + {
  470 + cell.setCellType(CellType.NUMERIC);
  471 + cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
  472 + }
  473 + else if (ColumnType.NUMERIC == attr.cellType())
  474 + {
  475 + cell.setCellType(CellType.NUMERIC);
  476 + cell.setCellValue(Integer.parseInt(value + ""));
  477 + }
  478 + }
  479 +
  480 + /**
  481 + * 创建表格样式
  482 + */
  483 + public void setDataValidation(Excel attr, Row row, int column)
  484 + {
  485 + if (attr.name().indexOf("注:") >= 0)
  486 + {
  487 + sheet.setColumnWidth(column, 6000);
  488 + }
  489 + else
  490 + {
  491 + // 设置列宽
  492 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
  493 + row.setHeight((short) (attr.height() * 20));
  494 + }
  495 + // 如果设置了提示信息则鼠标放上去提示.
  496 + if (StringUtils.isNotEmpty(attr.prompt()))
  497 + {
  498 + // 这里默认设了2-101列提示.
  499 + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column);
  500 + }
  501 + // 如果设置了combo属性则本列只能选择不能输入
  502 + if (attr.combo().length > 0)
  503 + {
  504 + // 这里默认设了2-101列只能选择不能输入.
  505 + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column);
  506 + }
  507 + }
  508 +
  509 + /**
  510 + * 添加单元格
  511 + */
  512 + public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
  513 + {
  514 + Cell cell = null;
  515 + try
  516 + {
  517 + // 设置行高
  518 + row.setHeight((short) (attr.height() * 20));
  519 + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
  520 + if (attr.isExport())
  521 + {
  522 + // 创建cell
  523 + cell = row.createCell(column);
  524 + cell.setCellStyle(styles.get("data"));
  525 +
  526 + // 用于读取对象中的属性
  527 + Object value = getTargetValue(vo, field, attr);
  528 + String dateFormat = attr.dateFormat();
  529 + String readConverterExp = attr.readConverterExp();
  530 + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
  531 + {
  532 + cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
  533 + }
  534 + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
  535 + {
  536 + cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
  537 + }
  538 + else
  539 + {
  540 + // 设置列类型
  541 + setCellVo(value, attr, cell);
  542 + }
  543 + }
  544 + }
  545 + catch (Exception e)
  546 + {
  547 + log.error("导出Excel失败{}", e);
  548 + }
  549 + return cell;
  550 + }
  551 +
  552 + /**
  553 + * 设置 POI XSSFSheet 单元格提示
  554 + *
  555 + * @param sheet 表单
  556 + * @param promptTitle 提示标题
  557 + * @param promptContent 提示内容
  558 + * @param firstRow 开始行
  559 + * @param endRow 结束行
  560 + * @param firstCol 开始列
  561 + * @param endCol 结束列
  562 + */
  563 + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow,
  564 + int firstCol, int endCol)
  565 + {
  566 + DataValidationHelper helper = sheet.getDataValidationHelper();
  567 + DataValidationConstraint constraint = helper.createCustomConstraint("DD1");
  568 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
  569 + DataValidation dataValidation = helper.createValidation(constraint, regions);
  570 + dataValidation.createPromptBox(promptTitle, promptContent);
  571 + dataValidation.setShowPromptBox(true);
  572 + sheet.addValidationData(dataValidation);
  573 + }
  574 +
  575 + /**
  576 + * 设置某些列的值只能输入预制的数据,显示下拉框.
  577 + *
  578 + * @param sheet 要设置的sheet.
  579 + * @param textlist 下拉框显示的内容
  580 + * @param firstRow 开始行
  581 + * @param endRow 结束行
  582 + * @param firstCol 开始列
  583 + * @param endCol 结束列
  584 + * @return 设置好的sheet.
  585 + */
  586 + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol)
  587 + {
  588 + DataValidationHelper helper = sheet.getDataValidationHelper();
  589 + // 加载下拉列表内容
  590 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist);
  591 + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
  592 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
  593 + // 数据有效性对象
  594 + DataValidation dataValidation = helper.createValidation(constraint, regions);
  595 + // 处理Excel兼容性问题
  596 + if (dataValidation instanceof XSSFDataValidation)
  597 + {
  598 + dataValidation.setSuppressDropDownArrow(true);
  599 + dataValidation.setShowErrorBox(true);
  600 + }
  601 + else
  602 + {
  603 + dataValidation.setSuppressDropDownArrow(false);
  604 + }
  605 +
  606 + sheet.addValidationData(dataValidation);
  607 + }
  608 +
  609 + /**
  610 + * 解析导出值 0=男,1=女,2=未知
  611 + *
  612 + * @param propertyValue 参数值
  613 + * @param converterExp 翻译注解
  614 + * @return 解析后值
  615 + * @throws Exception
  616 + */
  617 + public static String convertByExp(String propertyValue, String converterExp) throws Exception
  618 + {
  619 + try
  620 + {
  621 + String[] convertSource = converterExp.split(",");
  622 + for (String item : convertSource)
  623 + {
  624 + String[] itemArray = item.split("=");
  625 + if (itemArray[0].equals(propertyValue))
  626 + {
  627 + return itemArray[1];
  628 + }
  629 + }
  630 + }
  631 + catch (Exception e)
  632 + {
  633 + throw e;
  634 + }
  635 + return propertyValue;
  636 + }
  637 +
  638 + /**
  639 + * 反向解析值 男=0,女=1,未知=2
  640 + *
  641 + * @param propertyValue 参数值
  642 + * @param converterExp 翻译注解
  643 + * @return 解析后值
  644 + * @throws Exception
  645 + */
  646 + public static String reverseByExp(String propertyValue, String converterExp) throws Exception
  647 + {
  648 + try
  649 + {
  650 + String[] convertSource = converterExp.split(",");
  651 + for (String item : convertSource)
  652 + {
  653 + String[] itemArray = item.split("=");
  654 + if (itemArray[1].equals(propertyValue))
  655 + {
  656 + return itemArray[0];
  657 + }
  658 + }
  659 + }
  660 + catch (Exception e)
  661 + {
  662 + throw e;
  663 + }
  664 + return propertyValue;
  665 + }
  666 +
  667 + /**
  668 + * 编码文件名
  669 + */
  670 + public String encodingFilename(String filename)
  671 + {
  672 + filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx";
  673 + return filename;
  674 + }
  675 +
  676 + /**
  677 + * 获取下载路径
  678 + *
  679 + * @param filename 文件名称
  680 + */
  681 + public String getAbsoluteFile(String filename)
  682 + {
  683 + String downloadPath = RuoYiConfig.getDownloadPath() + filename;
  684 + File desc = new File(downloadPath);
  685 + if (!desc.getParentFile().exists())
  686 + {
  687 + desc.getParentFile().mkdirs();
  688 + }
  689 + return downloadPath;
  690 + }
  691 +
  692 + /**
  693 + * 获取bean中的属性值
  694 + *
  695 + * @param vo 实体对象
  696 + * @param field 字段
  697 + * @param excel 注解
  698 + * @return 最终的属性值
  699 + * @throws Exception
  700 + */
  701 + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception
  702 + {
  703 + Object o = field.get(vo);
  704 + if (StringUtils.isNotEmpty(excel.targetAttr()))
  705 + {
  706 + String target = excel.targetAttr();
  707 + if (target.indexOf(".") > -1)
  708 + {
  709 + String[] targets = target.split("[.]");
  710 + for (String name : targets)
  711 + {
  712 + o = getValue(o, name);
  713 + }
  714 + }
  715 + else
  716 + {
  717 + o = getValue(o, target);
  718 + }
  719 + }
  720 + return o;
  721 + }
  722 +
  723 + /**
  724 + * 以类的属性的get方法方法形式获取值
  725 + *
  726 + * @param o
  727 + * @param name
  728 + * @return value
  729 + * @throws Exception
  730 + */
  731 + private Object getValue(Object o, String name) throws Exception
  732 + {
  733 + if (StringUtils.isNotEmpty(name))
  734 + {
  735 + Class<?> clazz = o.getClass();
  736 + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
  737 + Method method = clazz.getMethod(methodName);
  738 + o = method.invoke(o);
  739 + }
  740 + return o;
  741 + }
  742 +
  743 + /**
  744 + * 得到所有定义字段
  745 + */
  746 + private void createExcelField()
  747 + {
  748 + this.fields = new ArrayList<Object[]>();
  749 + List<Field> tempFields = new ArrayList<>();
  750 + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
  751 + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
  752 + for (Field field : tempFields)
  753 + {
  754 + // 单注解
  755 + if (field.isAnnotationPresent(Excel.class))
  756 + {
  757 + putToField(field, field.getAnnotation(Excel.class));
  758 + }
  759 +
  760 + // 多注解
  761 + if (field.isAnnotationPresent(Excels.class))
  762 + {
  763 + Excels attrs = field.getAnnotation(Excels.class);
  764 + Excel[] excels = attrs.value();
  765 + for (Excel excel : excels)
  766 + {
  767 + putToField(field, excel);
  768 + }
  769 + }
  770 + }
  771 + }
  772 +
  773 + /**
  774 + * 放到字段集合中
  775 + */
  776 + private void putToField(Field field, Excel attr)
  777 + {
  778 + if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
  779 + {
  780 + this.fields.add(new Object[] { field, attr });
  781 + }
  782 + }
  783 +
  784 + /**
  785 + * 创建一个工作簿
  786 + */
  787 + public void createWorkbook()
  788 + {
  789 + this.wb = new SXSSFWorkbook(500);
  790 + }
  791 +
  792 + /**
  793 + * 创建工作表
  794 + *
  795 + * @param sheetNo sheet数量
  796 + * @param index 序号
  797 + */
  798 + public void createSheet(double sheetNo, int index)
  799 + {
  800 + this.sheet = wb.createSheet();
  801 + this.styles = createStyles(wb);
  802 + // 设置工作表的名称.
  803 + if (sheetNo == 0)
  804 + {
  805 + wb.setSheetName(index, sheetName);
  806 + }
  807 + else
  808 + {
  809 + wb.setSheetName(index, sheetName + index);
  810 + }
  811 + }
  812 +
  813 + /**
  814 + * 获取单元格值
  815 + *
  816 + * @param row 获取的行
  817 + * @param column 获取单元格列号
  818 + * @return 单元格值
  819 + */
  820 + public Object getCellValue(Row row, int column)
  821 + {
  822 + if (row == null)
  823 + {
  824 + return row;
  825 + }
  826 + Object val = "";
  827 + try
  828 + {
  829 + Cell cell = row.getCell(column);
  830 + if (cell != null)
  831 + {
  832 + if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA)
  833 + {
  834 + val = cell.getNumericCellValue();
  835 + if (HSSFDateUtil.isCellDateFormatted(cell))
  836 + {
  837 + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
  838 + }
  839 + else
  840 + {
  841 + if ((Double) val % 1 > 0)
  842 + {
  843 + val = new DecimalFormat("0.00").format(val);
  844 + }
  845 + else
  846 + {
  847 + val = new DecimalFormat("0").format(val);
  848 + }
  849 + }
  850 + }
  851 + else if (cell.getCellTypeEnum() == CellType.STRING)
  852 + {
  853 + val = cell.getStringCellValue();
  854 + }
  855 + else if (cell.getCellTypeEnum() == CellType.BOOLEAN)
  856 + {
  857 + val = cell.getBooleanCellValue();
  858 + }
  859 + else if (cell.getCellTypeEnum() == CellType.ERROR)
  860 + {
  861 + val = cell.getErrorCellValue();
  862 + }
  863 +
  864 + }
  865 + }
  866 + catch (Exception e)
  867 + {
  868 + return val;
  869 + }
  870 + return val;
  871 + }
  872 +}
0 873 \ No newline at end of file
... ...
ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java 0 → 100644
  1 +package com.ruoyi.common.utils.reflect;
  2 +
  3 +import java.lang.reflect.Field;
  4 +import java.lang.reflect.InvocationTargetException;
  5 +import java.lang.reflect.Method;
  6 +import java.lang.reflect.Modifier;
  7 +import java.lang.reflect.ParameterizedType;
  8 +import java.lang.reflect.Type;
  9 +import java.util.Date;
  10 +import org.apache.commons.lang3.StringUtils;
  11 +import org.apache.commons.lang3.Validate;
  12 +import org.apache.poi.ss.usermodel.DateUtil;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
  15 +import com.ruoyi.common.core.text.Convert;
  16 +import com.ruoyi.common.utils.DateUtils;
  17 +
  18 +/**
  19 + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
  20 + *
  21 + * @author ruoyi
  22 + */
  23 +@SuppressWarnings("rawtypes")
  24 +public class ReflectUtils
  25 +{
  26 + private static final String SETTER_PREFIX = "set";
  27 +
  28 + private static final String GETTER_PREFIX = "get";
  29 +
  30 + private static final String CGLIB_CLASS_SEPARATOR = "$$";
  31 +
  32 + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
  33 +
  34 + /**
  35 + * 调用Getter方法.
  36 + * 支持多级,如:对象名.对象名.方法
  37 + */
  38 + @SuppressWarnings("unchecked")
  39 + public static <E> E invokeGetter(Object obj, String propertyName)
  40 + {
  41 + Object object = obj;
  42 + for (String name : StringUtils.split(propertyName, "."))
  43 + {
  44 + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
  45 + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
  46 + }
  47 + return (E) object;
  48 + }
  49 +
  50 + /**
  51 + * 调用Setter方法, 仅匹配方法名。
  52 + * 支持多级,如:对象名.对象名.方法
  53 + */
  54 + public static <E> void invokeSetter(Object obj, String propertyName, E value)
  55 + {
  56 + Object object = obj;
  57 + String[] names = StringUtils.split(propertyName, ".");
  58 + for (int i = 0; i < names.length; i++)
  59 + {
  60 + if (i < names.length - 1)
  61 + {
  62 + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
  63 + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
  64 + }
  65 + else
  66 + {
  67 + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
  68 + invokeMethodByName(object, setterMethodName, new Object[] { value });
  69 + }
  70 + }
  71 + }
  72 +
  73 + /**
  74 + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
  75 + */
  76 + @SuppressWarnings("unchecked")
  77 + public static <E> E getFieldValue(final Object obj, final String fieldName)
  78 + {
  79 + Field field = getAccessibleField(obj, fieldName);
  80 + if (field == null)
  81 + {
  82 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
  83 + return null;
  84 + }
  85 + E result = null;
  86 + try
  87 + {
  88 + result = (E) field.get(obj);
  89 + }
  90 + catch (IllegalAccessException e)
  91 + {
  92 + logger.error("不可能抛出的异常{}", e.getMessage());
  93 + }
  94 + return result;
  95 + }
  96 +
  97 + /**
  98 + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
  99 + */
  100 + public static <E> void setFieldValue(final Object obj, final String fieldName, final E value)
  101 + {
  102 + Field field = getAccessibleField(obj, fieldName);
  103 + if (field == null)
  104 + {
  105 + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
  106 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
  107 + return;
  108 + }
  109 + try
  110 + {
  111 + field.set(obj, value);
  112 + }
  113 + catch (IllegalAccessException e)
  114 + {
  115 + logger.error("不可能抛出的异常: {}", e.getMessage());
  116 + }
  117 + }
  118 +
  119 + /**
  120 + * 直接调用对象方法, 无视private/protected修饰符.
  121 + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
  122 + * 同时匹配方法名+参数类型,
  123 + */
  124 + @SuppressWarnings("unchecked")
  125 + public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
  126 + final Object[] args)
  127 + {
  128 + if (obj == null || methodName == null)
  129 + {
  130 + return null;
  131 + }
  132 + Method method = getAccessibleMethod(obj, methodName, parameterTypes);
  133 + if (method == null)
  134 + {
  135 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
  136 + return null;
  137 + }
  138 + try
  139 + {
  140 + return (E) method.invoke(obj, args);
  141 + }
  142 + catch (Exception e)
  143 + {
  144 + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
  145 + throw convertReflectionExceptionToUnchecked(msg, e);
  146 + }
  147 + }
  148 +
  149 + /**
  150 + * 直接调用对象方法, 无视private/protected修饰符,
  151 + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
  152 + * 只匹配函数名,如果有多个同名函数调用第一个。
  153 + */
  154 + @SuppressWarnings("unchecked")
  155 + public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args)
  156 + {
  157 + Method method = getAccessibleMethodByName(obj, methodName, args.length);
  158 + if (method == null)
  159 + {
  160 + // 如果为空不报错,直接返回空。
  161 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
  162 + return null;
  163 + }
  164 + try
  165 + {
  166 + // 类型转换(将参数数据类型转换为目标方法参数类型)
  167 + Class<?>[] cs = method.getParameterTypes();
  168 + for (int i = 0; i < cs.length; i++)
  169 + {
  170 + if (args[i] != null && !args[i].getClass().equals(cs[i]))
  171 + {
  172 + if (cs[i] == String.class)
  173 + {
  174 + args[i] = Convert.toStr(args[i]);
  175 + if (StringUtils.endsWith((String) args[i], ".0"))
  176 + {
  177 + args[i] = StringUtils.substringBefore((String) args[i], ".0");
  178 + }
  179 + }
  180 + else if (cs[i] == Integer.class)
  181 + {
  182 + args[i] = Convert.toInt(args[i]);
  183 + }
  184 + else if (cs[i] == Long.class)
  185 + {
  186 + args[i] = Convert.toLong(args[i]);
  187 + }
  188 + else if (cs[i] == Double.class)
  189 + {
  190 + args[i] = Convert.toDouble(args[i]);
  191 + }
  192 + else if (cs[i] == Float.class)
  193 + {
  194 + args[i] = Convert.toFloat(args[i]);
  195 + }
  196 + else if (cs[i] == Date.class)
  197 + {
  198 + if (args[i] instanceof String)
  199 + {
  200 + args[i] = DateUtils.parseDate(args[i]);
  201 + }
  202 + else
  203 + {
  204 + args[i] = DateUtil.getJavaDate((Double) args[i]);
  205 + }
  206 + }
  207 + }
  208 + }
  209 + return (E) method.invoke(obj, args);
  210 + }
  211 + catch (Exception e)
  212 + {
  213 + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
  214 + throw convertReflectionExceptionToUnchecked(msg, e);
  215 + }
  216 + }
  217 +
  218 + /**
  219 + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
  220 + * 如向上转型到Object仍无法找到, 返回null.
  221 + */
  222 + public static Field getAccessibleField(final Object obj, final String fieldName)
  223 + {
  224 + // 为空不报错。直接返回 null
  225 + if (obj == null)
  226 + {
  227 + return null;
  228 + }
  229 + Validate.notBlank(fieldName, "fieldName can't be blank");
  230 + for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
  231 + {
  232 + try
  233 + {
  234 + Field field = superClass.getDeclaredField(fieldName);
  235 + makeAccessible(field);
  236 + return field;
  237 + }
  238 + catch (NoSuchFieldException e)
  239 + {
  240 + continue;
  241 + }
  242 + }
  243 + return null;
  244 + }
  245 +
  246 + /**
  247 + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
  248 + * 如向上转型到Object仍无法找到, 返回null.
  249 + * 匹配函数名+参数类型。
  250 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
  251 + */
  252 + public static Method getAccessibleMethod(final Object obj, final String methodName,
  253 + final Class<?>... parameterTypes)
  254 + {
  255 + // 为空不报错。直接返回 null
  256 + if (obj == null)
  257 + {
  258 + return null;
  259 + }
  260 + Validate.notBlank(methodName, "methodName can't be blank");
  261 + for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
  262 + {
  263 + try
  264 + {
  265 + Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
  266 + makeAccessible(method);
  267 + return method;
  268 + }
  269 + catch (NoSuchMethodException e)
  270 + {
  271 + continue;
  272 + }
  273 + }
  274 + return null;
  275 + }
  276 +
  277 + /**
  278 + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
  279 + * 如向上转型到Object仍无法找到, 返回null.
  280 + * 只匹配函数名。
  281 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
  282 + */
  283 + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum)
  284 + {
  285 + // 为空不报错。直接返回 null
  286 + if (obj == null)
  287 + {
  288 + return null;
  289 + }
  290 + Validate.notBlank(methodName, "methodName can't be blank");
  291 + for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
  292 + {
  293 + Method[] methods = searchType.getDeclaredMethods();
  294 + for (Method method : methods)
  295 + {
  296 + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum)
  297 + {
  298 + makeAccessible(method);
  299 + return method;
  300 + }
  301 + }
  302 + }
  303 + return null;
  304 + }
  305 +
  306 + /**
  307 + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
  308 + */
  309 + public static void makeAccessible(Method method)
  310 + {
  311 + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
  312 + && !method.isAccessible())
  313 + {
  314 + method.setAccessible(true);
  315 + }
  316 + }
  317 +
  318 + /**
  319 + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
  320 + */
  321 + public static void makeAccessible(Field field)
  322 + {
  323 + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
  324 + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible())
  325 + {
  326 + field.setAccessible(true);
  327 + }
  328 + }
  329 +
  330 + /**
  331 + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
  332 + * 如无法找到, 返回Object.class.
  333 + */
  334 + @SuppressWarnings("unchecked")
  335 + public static <T> Class<T> getClassGenricType(final Class clazz)
  336 + {
  337 + return getClassGenricType(clazz, 0);
  338 + }
  339 +
  340 + /**
  341 + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
  342 + * 如无法找到, 返回Object.class.
  343 + */
  344 + public static Class getClassGenricType(final Class clazz, final int index)
  345 + {
  346 + Type genType = clazz.getGenericSuperclass();
  347 +
  348 + if (!(genType instanceof ParameterizedType))
  349 + {
  350 + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
  351 + return Object.class;
  352 + }
  353 +
  354 + Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  355 +
  356 + if (index >= params.length || index < 0)
  357 + {
  358 + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
  359 + + params.length);
  360 + return Object.class;
  361 + }
  362 + if (!(params[index] instanceof Class))
  363 + {
  364 + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
  365 + return Object.class;
  366 + }
  367 +
  368 + return (Class) params[index];
  369 + }
  370 +
  371 + public static Class<?> getUserClass(Object instance)
  372 + {
  373 + if (instance == null)
  374 + {
  375 + throw new RuntimeException("Instance must not be null");
  376 + }
  377 + Class clazz = instance.getClass();
  378 + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR))
  379 + {
  380 + Class<?> superClass = clazz.getSuperclass();
  381 + if (superClass != null && !Object.class.equals(superClass))
  382 + {
  383 + return superClass;
  384 + }
  385 + }
  386 + return clazz;
  387 +
  388 + }
  389 +
  390 + /**
  391 + * 将反射时的checked exception转换为unchecked exception.
  392 + */
  393 + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e)
  394 + {
  395 + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
  396 + || e instanceof NoSuchMethodException)
  397 + {
  398 + return new IllegalArgumentException(msg, e);
  399 + }
  400 + else if (e instanceof InvocationTargetException)
  401 + {
  402 + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());
  403 + }
  404 + return new RuntimeException(msg, e);
  405 + }
  406 +}
... ...
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java 0 → 100644
  1 +package com.ruoyi.framework.aspectj.lang.annotation;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +
  8 +/**
  9 + * 自定义导出Excel数据注解
  10 + *
  11 + * @author ruoyi
  12 + */
  13 +@Retention(RetentionPolicy.RUNTIME)
  14 +@Target(ElementType.FIELD)
  15 +public @interface Excel
  16 +{
  17 + /**
  18 + * 导出到Excel中的名字.
  19 + */
  20 + public String name() default "";
  21 +
  22 + /**
  23 + * 日期格式, 如: yyyy-MM-dd
  24 + */
  25 + public String dateFormat() default "";
  26 +
  27 + /**
  28 + * 读取内容转表达式 (如: 0=男,1=女,2=未知)
  29 + */
  30 + public String readConverterExp() default "";
  31 +
  32 + /**
  33 + * 导出类型(0数字 1字符串)
  34 + */
  35 + public ColumnType cellType() default ColumnType.STRING;
  36 +
  37 + /**
  38 + * 导出时在excel中每个列的高度 单位为字符
  39 + */
  40 + public double height() default 14;
  41 +
  42 + /**
  43 + * 导出时在excel中每个列的宽 单位为字符
  44 + */
  45 + public double width() default 16;
  46 +
  47 + /**
  48 + * 文字后缀,如% 90 变成90%
  49 + */
  50 + public String suffix() default "";
  51 +
  52 + /**
  53 + * 当值为空时,字段的默认值
  54 + */
  55 + public String defaultValue() default "";
  56 +
  57 + /**
  58 + * 提示信息
  59 + */
  60 + public String prompt() default "";
  61 +
  62 + /**
  63 + * 设置只能选择不能输入的列内容.
  64 + */
  65 + public String[] combo() default {};
  66 +
  67 + /**
  68 + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
  69 + */
  70 + public boolean isExport() default true;
  71 +
  72 + /**
  73 + * 另一个类中的属性名称,支持多级获取,以小数点隔开
  74 + */
  75 + public String targetAttr() default "";
  76 +
  77 + /**
  78 + * 字段类型(0:导出导入;1:仅导出;2:仅导入)
  79 + */
  80 + Type type() default Type.ALL;
  81 +
  82 + public enum Type
  83 + {
  84 + ALL(0), EXPORT(1), IMPORT(2);
  85 + private final int value;
  86 +
  87 + Type(int value)
  88 + {
  89 + this.value = value;
  90 + }
  91 +
  92 + public int value()
  93 + {
  94 + return this.value;
  95 + }
  96 + }
  97 +
  98 + public enum ColumnType
  99 + {
  100 + NUMERIC(0), STRING(1);
  101 + private final int value;
  102 +
  103 + ColumnType(int value)
  104 + {
  105 + this.value = value;
  106 + }
  107 +
  108 + public int value()
  109 + {
  110 + return this.value;
  111 + }
  112 + }
  113 +}
0 114 \ No newline at end of file
... ...
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java 0 → 100644
  1 +package com.ruoyi.framework.aspectj.lang.annotation;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +
  8 +/**
  9 + * Excel注解集
  10 + *
  11 + * @author ruoyi
  12 + */
  13 +@Target(ElementType.FIELD)
  14 +@Retention(RetentionPolicy.RUNTIME)
  15 +public @interface Excels
  16 +{
  17 + Excel[] value();
  18 +}
0 19 \ No newline at end of file
... ...
ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
... ... @@ -98,6 +98,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
98 98 "/**/*.js"
99 99 ).permitAll()
100 100 .antMatchers("/profile/**").anonymous()
  101 + .antMatchers("/common/download**").anonymous()
101 102 .antMatchers("/swagger-ui.html").anonymous()
102 103 .antMatchers("/swagger-resources/**").anonymous()
103 104 .antMatchers("/webjars/**").anonymous()
... ...
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
1 1 package com.ruoyi.framework.config;
2 2  
  3 +import java.util.ArrayList;
  4 +import java.util.List;
3 5 import org.springframework.beans.factory.annotation.Autowired;
4 6 import org.springframework.context.annotation.Bean;
5 7 import org.springframework.context.annotation.Configuration;
... ... @@ -8,8 +10,12 @@ import springfox.documentation.builders.ApiInfoBuilder;
8 10 import springfox.documentation.builders.PathSelectors;
9 11 import springfox.documentation.builders.RequestHandlerSelectors;
10 12 import springfox.documentation.service.ApiInfo;
  13 +import springfox.documentation.service.ApiKey;
  14 +import springfox.documentation.service.AuthorizationScope;
11 15 import springfox.documentation.service.Contact;
  16 +import springfox.documentation.service.SecurityReference;
12 17 import springfox.documentation.spi.DocumentationType;
  18 +import springfox.documentation.spi.service.contexts.SecurityContext;
13 19 import springfox.documentation.spring.web.plugins.Docket;
14 20 import springfox.documentation.swagger2.annotations.EnableSwagger2;
15 21  
... ... @@ -33,6 +39,7 @@ public class SwaggerConfig
33 39 public Docket createRestApi()
34 40 {
35 41 return new Docket(DocumentationType.SWAGGER_2)
  42 + .pathMapping("/dev-api")
36 43 // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
37 44 .apiInfo(apiInfo())
38 45 // 设置哪些接口暴露给Swagger展示
... ... @@ -43,7 +50,47 @@ public class SwaggerConfig
43 50 //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
44 51 // 扫描所有 .apis(RequestHandlerSelectors.any())
45 52 .paths(PathSelectors.any())
46   - .build();
  53 + .build()
  54 + /* 设置安全模式,swagger可以设置访问token */
  55 + .securitySchemes(securitySchemes())
  56 + .securityContexts(securityContexts());
  57 + }
  58 +
  59 + /**
  60 + * 安全模式,这里指定token通过Authorization头请求头传递
  61 + */
  62 + private List<ApiKey> securitySchemes()
  63 + {
  64 + List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
  65 + apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
  66 + return apiKeyList;
  67 + }
  68 +
  69 + /**
  70 + * 安全上下文
  71 + */
  72 + private List<SecurityContext> securityContexts()
  73 + {
  74 + List<SecurityContext> securityContexts = new ArrayList<>();
  75 + securityContexts.add(
  76 + SecurityContext.builder()
  77 + .securityReferences(defaultAuth())
  78 + .forPaths(PathSelectors.regex("^(?!auth).*$"))
  79 + .build());
  80 + return securityContexts;
  81 + }
  82 +
  83 + /**
  84 + * 默认的安全上引用
  85 + */
  86 + private List<SecurityReference> defaultAuth()
  87 + {
  88 + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
  89 + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
  90 + authorizationScopes[0] = authorizationScope;
  91 + List<SecurityReference> securityReferences = new ArrayList<>();
  92 + securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
  93 + return securityReferences;
47 94 }
48 95  
49 96 /**
... ... @@ -54,7 +101,7 @@ public class SwaggerConfig
54 101 // 用ApiInfoBuilder进行定制
55 102 return new ApiInfoBuilder()
56 103 // 设置标题
57   - .title("标题:余心管理系统_接口文档")
  104 + .title("标题:若依管理系统_接口文档")
58 105 // 描述
59 106 .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
60 107 // 作者信息
... ...
ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
... ... @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory;
5 5 import org.springframework.security.access.AccessDeniedException;
6 6 import org.springframework.security.authentication.AccountExpiredException;
7 7 import org.springframework.security.core.userdetails.UsernameNotFoundException;
  8 +import org.springframework.validation.BindException;
  9 +import org.springframework.web.bind.MethodArgumentNotValidException;
8 10 import org.springframework.web.bind.annotation.ExceptionHandler;
9 11 import org.springframework.web.bind.annotation.RestControllerAdvice;
10 12 import org.springframework.web.servlet.NoHandlerFoundException;
... ... @@ -83,6 +85,28 @@ public class GlobalExceptionHandler
83 85 }
84 86  
85 87 /**
  88 + * 自定义验证异常
  89 + */
  90 + @ExceptionHandler(BindException.class)
  91 + public AjaxResult validatedBindException(BindException e)
  92 + {
  93 + log.error(e.getMessage(), e);
  94 + String message = e.getAllErrors().get(0).getDefaultMessage();
  95 + return AjaxResult.error(message);
  96 + }
  97 +
  98 + /**
  99 + * 自定义验证异常
  100 + */
  101 + @ExceptionHandler(MethodArgumentNotValidException.class)
  102 + public Object validExceptionHandler(MethodArgumentNotValidException e)
  103 + {
  104 + log.error(e.getMessage(), e);
  105 + String message = e.getBindingResult().getFieldError().getDefaultMessage();
  106 + return AjaxResult.error(message);
  107 + }
  108 +
  109 + /**
86 110 * 演示模式异常
87 111 */
88 112 @ExceptionHandler(DemoModeException.class)
... ...
ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java
1 1 package com.ruoyi.project.common;
2 2  
  3 +import javax.servlet.http.HttpServletRequest;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
3 7 import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.web.bind.annotation.GetMapping;
4 9 import org.springframework.web.bind.annotation.PostMapping;
5 10 import org.springframework.web.bind.annotation.RestController;
6 11 import org.springframework.web.multipart.MultipartFile;
  12 +import com.ruoyi.common.utils.StringUtils;
7 13 import com.ruoyi.common.utils.file.FileUploadUtils;
  14 +import com.ruoyi.common.utils.file.FileUtils;
8 15 import com.ruoyi.framework.config.RuoYiConfig;
9 16 import com.ruoyi.framework.config.ServerConfig;
10 17 import com.ruoyi.framework.web.domain.AjaxResult;
... ... @@ -17,10 +24,46 @@ import com.ruoyi.framework.web.domain.AjaxResult;
17 24 @RestController
18 25 public class CommonController
19 26 {
  27 + private static final Logger log = LoggerFactory.getLogger(CommonController.class);
  28 +
20 29 @Autowired
21 30 private ServerConfig serverConfig;
22 31  
23 32 /**
  33 + * 通用下载请求
  34 + *
  35 + * @param fileName 文件名称
  36 + * @param delete 是否删除
  37 + */
  38 + @GetMapping("common/download")
  39 + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
  40 + {
  41 + try
  42 + {
  43 + if (!FileUtils.isValidFilename(fileName))
  44 + {
  45 + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
  46 + }
  47 + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
  48 + String filePath = RuoYiConfig.getDownloadPath() + fileName;
  49 +
  50 + response.setCharacterEncoding("utf-8");
  51 + response.setContentType("multipart/form-data");
  52 + response.setHeader("Content-Disposition",
  53 + "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
  54 + FileUtils.writeBytes(filePath, response.getOutputStream());
  55 + if (delete)
  56 + {
  57 + FileUtils.deleteFile(filePath);
  58 + }
  59 + }
  60 + catch (Exception e)
  61 + {
  62 + log.error("下载文件失败", e);
  63 + }
  64 + }
  65 +
  66 + /**
24 67 * 通用上传请求
25 68 */
26 69 @PostMapping("/common/upload")
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java
... ... @@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.web.bind.annotation.DeleteMapping;
6 7 import org.springframework.web.bind.annotation.GetMapping;
  8 +import org.springframework.web.bind.annotation.PathVariable;
7 9 import org.springframework.web.bind.annotation.RequestMapping;
8 10 import org.springframework.web.bind.annotation.RestController;
  11 +import com.ruoyi.common.utils.poi.ExcelUtil;
  12 +import com.ruoyi.framework.aspectj.lang.annotation.Log;
  13 +import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
9 14 import com.ruoyi.framework.web.controller.BaseController;
  15 +import com.ruoyi.framework.web.domain.AjaxResult;
10 16 import com.ruoyi.framework.web.page.TableDataInfo;
11 17 import com.ruoyi.project.monitor.domain.SysLogininfor;
12 18 import com.ruoyi.project.monitor.service.ISysLogininforService;
... ... @@ -31,4 +37,31 @@ public class SysLogininforController extends BaseController
31 37 List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
32 38 return getDataTable(list);
33 39 }
  40 +
  41 + @Log(title = "登陆日志", businessType = BusinessType.EXPORT)
  42 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
  43 + @GetMapping("/export")
  44 + public AjaxResult export(SysLogininfor logininfor)
  45 + {
  46 + List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
  47 + ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
  48 + return util.exportExcel(list, "登陆日志");
  49 + }
  50 +
  51 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
  52 + @Log(title = "登陆日志", businessType = BusinessType.DELETE)
  53 + @DeleteMapping("/{infoIds}")
  54 + public AjaxResult remove(@PathVariable Long[] infoIds)
  55 + {
  56 + return toAjax(logininforService.deleteLogininforByIds(infoIds));
  57 + }
  58 +
  59 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
  60 + @Log(title = "登陆日志", businessType = BusinessType.CLEAN)
  61 + @DeleteMapping("/clean")
  62 + public AjaxResult clean()
  63 + {
  64 + logininforService.cleanLogininfor();
  65 + return AjaxResult.success();
  66 + }
34 67 }
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java
... ... @@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.web.bind.annotation.DeleteMapping;
6 7 import org.springframework.web.bind.annotation.GetMapping;
  8 +import org.springframework.web.bind.annotation.PathVariable;
7 9 import org.springframework.web.bind.annotation.RequestMapping;
8 10 import org.springframework.web.bind.annotation.RestController;
  11 +import com.ruoyi.common.utils.poi.ExcelUtil;
  12 +import com.ruoyi.framework.aspectj.lang.annotation.Log;
  13 +import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
9 14 import com.ruoyi.framework.web.controller.BaseController;
  15 +import com.ruoyi.framework.web.domain.AjaxResult;
10 16 import com.ruoyi.framework.web.page.TableDataInfo;
11 17 import com.ruoyi.project.monitor.domain.SysOperLog;
12 18 import com.ruoyi.project.monitor.service.ISysOperLogService;
... ... @@ -31,4 +37,30 @@ public class SysOperlogController extends BaseController
31 37 List<SysOperLog> list = operLogService.selectOperLogList(operLog);
32 38 return getDataTable(list);
33 39 }
  40 +
  41 + @Log(title = "操作日志", businessType = BusinessType.EXPORT)
  42 + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
  43 + @GetMapping("/export")
  44 + public AjaxResult export(SysOperLog operLog)
  45 + {
  46 + List<SysOperLog> list = operLogService.selectOperLogList(operLog);
  47 + ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
  48 + return util.exportExcel(list, "操作日志");
  49 + }
  50 +
  51 + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
  52 + @DeleteMapping("/{operIds}")
  53 + public AjaxResult remove(@PathVariable Long[] operIds)
  54 + {
  55 + return toAjax(operLogService.deleteOperLogByIds(operIds));
  56 + }
  57 +
  58 + @Log(title = "操作日志", businessType = BusinessType.CLEAN)
  59 + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
  60 + @DeleteMapping("/clean")
  61 + public AjaxResult clean()
  62 + {
  63 + operLogService.cleanOperLog();
  64 + return AjaxResult.success();
  65 + }
34 66 }
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java
1 1 package com.ruoyi.project.monitor.domain;
2 2  
3 3 import java.util.Date;
  4 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  5 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
4 6 import com.ruoyi.framework.web.domain.BaseEntity;
5 7  
6 8 /**
... ... @@ -13,30 +15,39 @@ public class SysLogininfor extends BaseEntity
13 15 private static final long serialVersionUID = 1L;
14 16  
15 17 /** ID */
  18 + @Excel(name = "序号", cellType = ColumnType.NUMERIC)
16 19 private Long infoId;
17 20  
18 21 /** 用户账号 */
  22 + @Excel(name = "用户账号")
19 23 private String userName;
20 24  
21 25 /** 登录状态 0成功 1失败 */
  26 + @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
22 27 private String status;
23 28  
24 29 /** 登录IP地址 */
  30 + @Excel(name = "登录地址")
25 31 private String ipaddr;
26 32  
27 33 /** 登录地点 */
  34 + @Excel(name = "登录地点")
28 35 private String loginLocation;
29 36  
30 37 /** 浏览器类型 */
  38 + @Excel(name = "浏览器")
31 39 private String browser;
32 40  
33 41 /** 操作系统 */
  42 + @Excel(name = "操作系统")
34 43 private String os;
35 44  
36 45 /** 提示消息 */
  46 + @Excel(name = "提示消息")
37 47 private String msg;
38 48  
39 49 /** 访问时间 */
  50 + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
40 51 private Date loginTime;
41 52  
42 53 public Long getInfoId()
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java
1 1 package com.ruoyi.project.monitor.domain;
2 2  
3 3 import java.util.Date;
  4 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  5 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
4 6 import com.ruoyi.framework.web.domain.BaseEntity;
5 7  
6 8 /**
... ... @@ -13,54 +15,70 @@ public class SysOperLog extends BaseEntity
13 15 private static final long serialVersionUID = 1L;
14 16  
15 17 /** 日志主键 */
  18 + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
16 19 private Long operId;
17 20  
18 21 /** 操作模块 */
  22 + @Excel(name = "操作模块")
19 23 private String title;
20 24  
21 25 /** 业务类型(0其它 1新增 2修改 3删除) */
  26 + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
22 27 private Integer businessType;
23 28  
24 29 /** 业务类型数组 */
25 30 private Integer[] businessTypes;
26 31  
27 32 /** 请求方法 */
  33 + @Excel(name = "请求方法")
28 34 private String method;
29 35  
30 36 /** 请求方式 */
  37 + @Excel(name = "请求方式")
31 38 private String requestMethod;
32 39  
33 40 /** 操作类别(0其它 1后台用户 2手机端用户) */
  41 + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
34 42 private Integer operatorType;
35 43  
36 44 /** 操作人员 */
  45 + @Excel(name = "操作人员")
37 46 private String operName;
38 47  
39 48 /** 部门名称 */
  49 + @Excel(name = "部门名称")
40 50 private String deptName;
41 51  
42 52 /** 请求url */
  53 + @Excel(name = "请求地址")
43 54 private String operUrl;
44 55  
45 56 /** 操作地址 */
  57 + @Excel(name = "操作地址")
46 58 private String operIp;
47 59  
48 60 /** 操作地点 */
  61 + @Excel(name = "操作地点")
49 62 private String operLocation;
50 63  
51 64 /** 请求参数 */
  65 + @Excel(name = "请求参数")
52 66 private String operParam;
53 67  
54 68 /** 返回参数 */
  69 + @Excel(name = "返回参数")
55 70 private String jsonResult;
56 71  
57 72 /** 操作状态(0正常 1异常) */
  73 + @Excel(name = "状态", readConverterExp = "0=正常,1=异常")
58 74 private Integer status;
59 75  
60 76 /** 错误消息 */
  77 + @Excel(name = "错误消息")
61 78 private String errorMsg;
62 79  
63 80 /** 操作时间 */
  81 + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
64 82 private Date operTime;
65 83  
66 84 public Long getOperId()
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java
... ... @@ -28,10 +28,10 @@ public interface SysLogininforMapper
28 28 /**
29 29 * 批量删除系统登录日志
30 30 *
31   - * @param ids 需要删除的数据
  31 + * @param infoIds 需要删除的登录日志ID
32 32 * @return 结果
33 33 */
34   - public int deleteLogininforByIds(String[] ids);
  34 + public int deleteLogininforByIds(Long[] infoIds);
35 35  
36 36 /**
37 37 * 清空系统登录日志
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java
... ... @@ -28,10 +28,10 @@ public interface SysOperLogMapper
28 28 /**
29 29 * 批量删除系统操作日志
30 30 *
31   - * @param ids 需要删除的数据
  31 + * @param operIds 需要删除的操作日志ID
32 32 * @return 结果
33 33 */
34   - public int deleteOperLogByIds(String[] ids);
  34 + public int deleteOperLogByIds(Long[] operIds);
35 35  
36 36 /**
37 37 * 查询操作日志详细
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java
... ... @@ -28,10 +28,10 @@ public interface ISysLogininforService
28 28 /**
29 29 * 批量删除系统登录日志
30 30 *
31   - * @param ids 需要删除的数据
  31 + * @param infoIds 需要删除的登录日志ID
32 32 * @return
33 33 */
34   - public int deleteLogininforByIds(String ids);
  34 + public int deleteLogininforByIds(Long[] infoIds);
35 35  
36 36 /**
37 37 * 清空系统登录日志
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java
... ... @@ -28,10 +28,10 @@ public interface ISysOperLogService
28 28 /**
29 29 * 批量删除系统操作日志
30 30 *
31   - * @param ids 需要删除的数据
  31 + * @param operIds 需要删除的操作日志ID
32 32 * @return 结果
33 33 */
34   - public int deleteOperLogByIds(String ids);
  34 + public int deleteOperLogByIds(Long[] operIds);
35 35  
36 36 /**
37 37 * 查询操作日志详细
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java
... ... @@ -3,7 +3,6 @@ package com.ruoyi.project.monitor.service.impl;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.stereotype.Service;
6   -import com.ruoyi.common.core.text.Convert;
7 6 import com.ruoyi.project.monitor.domain.SysLogininfor;
8 7 import com.ruoyi.project.monitor.mapper.SysLogininforMapper;
9 8 import com.ruoyi.project.monitor.service.ISysLogininforService;
... ... @@ -46,13 +45,13 @@ public class SysLogininforServiceImpl implements ISysLogininforService
46 45 /**
47 46 * 批量删除系统登录日志
48 47 *
49   - * @param ids 需要删除的数据
  48 + * @param infoIds 需要删除的登录日志ID
50 49 * @return
51 50 */
52 51 @Override
53   - public int deleteLogininforByIds(String ids)
  52 + public int deleteLogininforByIds(Long[] infoIds)
54 53 {
55   - return logininforMapper.deleteLogininforByIds(Convert.toStrArray(ids));
  54 + return logininforMapper.deleteLogininforByIds(infoIds);
56 55 }
57 56  
58 57 /**
... ...
ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java
... ... @@ -3,7 +3,6 @@ package com.ruoyi.project.monitor.service.impl;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.stereotype.Service;
6   -import com.ruoyi.common.core.text.Convert;
7 6 import com.ruoyi.project.monitor.domain.SysOperLog;
8 7 import com.ruoyi.project.monitor.mapper.SysOperLogMapper;
9 8 import com.ruoyi.project.monitor.service.ISysOperLogService;
... ... @@ -45,13 +44,12 @@ public class SysOperLogServiceImpl implements ISysOperLogService
45 44 /**
46 45 * 批量删除系统操作日志
47 46 *
48   - * @param ids 需要删除的数据
49   - * @return
  47 + * @param operIds 需要删除的操作日志ID
  48 + * @return 结果
50 49 */
51   - @Override
52   - public int deleteOperLogByIds(String ids)
  50 + public int deleteOperLogByIds(Long[] operIds)
53 51 {
54   - return operLogMapper.deleteOperLogByIds(Convert.toStrArray(ids));
  52 + return operLogMapper.deleteOperLogByIds(operIds);
55 53 }
56 54  
57 55 /**
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 14 import org.springframework.web.bind.annotation.RestController;
14 15 import com.ruoyi.common.constant.UserConstants;
15 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 20 import com.ruoyi.framework.web.controller.BaseController;
... ... @@ -45,6 +47,16 @@ public class SysConfigController extends BaseController
45 47 return getDataTable(list);
46 48 }
47 49  
  50 + @Log(title = "参数管理", businessType = BusinessType.EXPORT)
  51 + @PreAuthorize("@ss.hasPermi('system:config:export')")
  52 + @GetMapping("/export")
  53 + public AjaxResult export(SysConfig config)
  54 + {
  55 + List<SysConfig> list = configService.selectConfigList(config);
  56 + ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
  57 + return util.exportExcel(list, "参数数据");
  58 + }
  59 +
48 60 /**
49 61 * 根据参数编号获取详细信息
50 62 */
... ... @@ -71,7 +83,7 @@ public class SysConfigController extends BaseController
71 83 @PreAuthorize("@ss.hasPermi('system:config:add')")
72 84 @Log(title = "参数管理", businessType = BusinessType.INSERT)
73 85 @PostMapping
74   - public AjaxResult add(@RequestBody SysConfig config)
  86 + public AjaxResult add(@Validated @RequestBody SysConfig config)
75 87 {
76 88 if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
77 89 {
... ... @@ -87,7 +99,7 @@ public class SysConfigController extends BaseController
87 99 @PreAuthorize("@ss.hasPermi('system:config:edit')")
88 100 @Log(title = "参数管理", businessType = BusinessType.UPDATE)
89 101 @PutMapping
90   - public AjaxResult edit(@RequestBody SysConfig config)
  102 + public AjaxResult edit(@Validated @RequestBody SysConfig config)
91 103 {
92 104 if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
93 105 {
... ... @@ -102,9 +114,9 @@ public class SysConfigController extends BaseController
102 114 */
103 115 @PreAuthorize("@ss.hasPermi('system:config:remove')")
104 116 @Log(title = "参数管理", businessType = BusinessType.DELETE)
105   - @DeleteMapping("/{configId}")
106   - public AjaxResult remove(@PathVariable Long configId)
  117 + @DeleteMapping("/{configIds}")
  118 + public AjaxResult remove(@PathVariable Long[] configIds)
107 119 {
108   - return toAjax(configService.deleteConfigById(configId));
  120 + return toAjax(configService.deleteConfigByIds(configIds));
109 121 }
110 122 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -10,7 +11,6 @@ import org.springframework.web.bind.annotation.PostMapping;
10 11 import org.springframework.web.bind.annotation.PutMapping;
11 12 import org.springframework.web.bind.annotation.RequestBody;
12 13 import org.springframework.web.bind.annotation.RequestMapping;
13   -import org.springframework.web.bind.annotation.ResponseBody;
14 14 import org.springframework.web.bind.annotation.RestController;
15 15 import com.ruoyi.common.constant.UserConstants;
16 16 import com.ruoyi.common.utils.SecurityUtils;
... ... @@ -70,7 +70,6 @@ public class SysDeptController extends BaseController
70 70 */
71 71 @PreAuthorize("@ss.hasPermi('system:dept:query')")
72 72 @GetMapping(value = "/roleDeptTreeselect/{roleId}")
73   - @ResponseBody
74 73 public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId)
75 74 {
76 75 return AjaxResult.success(deptService.selectDeptListByRoleId(roleId));
... ... @@ -82,7 +81,7 @@ public class SysDeptController extends BaseController
82 81 @PreAuthorize("@ss.hasPermi('system:dept:add')")
83 82 @Log(title = "部门管理", businessType = BusinessType.INSERT)
84 83 @PostMapping
85   - public AjaxResult add(@RequestBody SysDept dept)
  84 + public AjaxResult add(@Validated @RequestBody SysDept dept)
86 85 {
87 86 if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
88 87 {
... ... @@ -98,7 +97,7 @@ public class SysDeptController extends BaseController
98 97 @PreAuthorize("@ss.hasPermi('system:dept:edit')")
99 98 @Log(title = "部门管理", businessType = BusinessType.UPDATE)
100 99 @PutMapping
101   - public AjaxResult edit(@RequestBody SysDept dept)
  100 + public AjaxResult edit(@Validated @RequestBody SysDept dept)
102 101 {
103 102 if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
104 103 {
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -10,9 +11,9 @@ import org.springframework.web.bind.annotation.PostMapping;
10 11 import org.springframework.web.bind.annotation.PutMapping;
11 12 import org.springframework.web.bind.annotation.RequestBody;
12 13 import org.springframework.web.bind.annotation.RequestMapping;
13   -import org.springframework.web.bind.annotation.ResponseBody;
14 14 import org.springframework.web.bind.annotation.RestController;
15 15 import com.ruoyi.common.utils.SecurityUtils;
  16 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 17 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 18 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 19 import com.ruoyi.framework.web.controller.BaseController;
... ... @@ -35,7 +36,6 @@ public class SysDictDataController extends BaseController
35 36  
36 37 @PreAuthorize("@ss.hasPermi('system:dict:list')")
37 38 @GetMapping("/list")
38   - @ResponseBody
39 39 public TableDataInfo list(SysDictData dictData)
40 40 {
41 41 startPage();
... ... @@ -43,6 +43,16 @@ public class SysDictDataController extends BaseController
43 43 return getDataTable(list);
44 44 }
45 45  
  46 + @Log(title = "字典数据", businessType = BusinessType.EXPORT)
  47 + @PreAuthorize("@ss.hasPermi('system:dict:export')")
  48 + @GetMapping("/export")
  49 + public AjaxResult export(SysDictData dictData)
  50 + {
  51 + List<SysDictData> list = dictDataService.selectDictDataList(dictData);
  52 + ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
  53 + return util.exportExcel(list, "字典数据");
  54 + }
  55 +
46 56 /**
47 57 * 查询字典数据详细
48 58 */
... ... @@ -69,7 +79,7 @@ public class SysDictDataController extends BaseController
69 79 @PreAuthorize("@ss.hasPermi('system:dict:add')")
70 80 @Log(title = "字典数据", businessType = BusinessType.INSERT)
71 81 @PostMapping
72   - public AjaxResult add(@RequestBody SysDictData dict)
  82 + public AjaxResult add(@Validated @RequestBody SysDictData dict)
73 83 {
74 84 dict.setCreateBy(SecurityUtils.getUsername());
75 85 return toAjax(dictDataService.insertDictData(dict));
... ... @@ -81,7 +91,7 @@ public class SysDictDataController extends BaseController
81 91 @PreAuthorize("@ss.hasPermi('system:dict:edit')")
82 92 @Log(title = "字典数据", businessType = BusinessType.UPDATE)
83 93 @PutMapping
84   - public AjaxResult edit(@RequestBody SysDictData dict)
  94 + public AjaxResult edit(@Validated @RequestBody SysDictData dict)
85 95 {
86 96 dict.setUpdateBy(SecurityUtils.getUsername());
87 97 return toAjax(dictDataService.updateDictData(dict));
... ... @@ -92,9 +102,9 @@ public class SysDictDataController extends BaseController
92 102 */
93 103 @PreAuthorize("@ss.hasPermi('system:dict:remove')")
94 104 @Log(title = "字典类型", businessType = BusinessType.DELETE)
95   - @DeleteMapping("/{dictCode}")
96   - public AjaxResult remove(@PathVariable Long dictCode)
  105 + @DeleteMapping("/{dictCodes}")
  106 + public AjaxResult remove(@PathVariable Long[] dictCodes)
97 107 {
98   - return toAjax(dictDataService.deleteDictDataById(dictCode));
  108 + return toAjax(dictDataService.deleteDictDataByIds(dictCodes));
99 109 }
100 110 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -10,10 +11,10 @@ import org.springframework.web.bind.annotation.PostMapping;
10 11 import org.springframework.web.bind.annotation.PutMapping;
11 12 import org.springframework.web.bind.annotation.RequestBody;
12 13 import org.springframework.web.bind.annotation.RequestMapping;
13   -import org.springframework.web.bind.annotation.ResponseBody;
14 14 import org.springframework.web.bind.annotation.RestController;
15 15 import com.ruoyi.common.constant.UserConstants;
16 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
17 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
18 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
19 20 import com.ruoyi.framework.web.controller.BaseController;
... ... @@ -36,7 +37,6 @@ public class SysDictTypeController extends BaseController
36 37  
37 38 @PreAuthorize("@ss.hasPermi('system:dict:list')")
38 39 @GetMapping("/list")
39   - @ResponseBody
40 40 public TableDataInfo list(SysDictType dictType)
41 41 {
42 42 startPage();
... ... @@ -44,6 +44,16 @@ public class SysDictTypeController extends BaseController
44 44 return getDataTable(list);
45 45 }
46 46  
  47 + @Log(title = "字典类型", businessType = BusinessType.EXPORT)
  48 + @PreAuthorize("@ss.hasPermi('system:dict:export')")
  49 + @GetMapping("/export")
  50 + public AjaxResult export(SysDictType dictType)
  51 + {
  52 + List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
  53 + ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
  54 + return util.exportExcel(list, "字典类型");
  55 + }
  56 +
47 57 /**
48 58 * 查询字典类型详细
49 59 */
... ... @@ -60,7 +70,7 @@ public class SysDictTypeController extends BaseController
60 70 @PreAuthorize("@ss.hasPermi('system:dict:add')")
61 71 @Log(title = "字典类型", businessType = BusinessType.INSERT)
62 72 @PostMapping
63   - public AjaxResult add(@RequestBody SysDictType dict)
  73 + public AjaxResult add(@Validated @RequestBody SysDictType dict)
64 74 {
65 75 if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
66 76 {
... ... @@ -76,7 +86,7 @@ public class SysDictTypeController extends BaseController
76 86 @PreAuthorize("@ss.hasPermi('system:dict:edit')")
77 87 @Log(title = "字典类型", businessType = BusinessType.UPDATE)
78 88 @PutMapping
79   - public AjaxResult edit(@RequestBody SysDictType dict)
  89 + public AjaxResult edit(@Validated @RequestBody SysDictType dict)
80 90 {
81 91 if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
82 92 {
... ... @@ -91,9 +101,9 @@ public class SysDictTypeController extends BaseController
91 101 */
92 102 @PreAuthorize("@ss.hasPermi('system:dict:remove')")
93 103 @Log(title = "字典类型", businessType = BusinessType.DELETE)
94   - @DeleteMapping("/{dictId}")
95   - public AjaxResult remove(@PathVariable Long dictId)
  104 + @DeleteMapping("/{dictIds}")
  105 + public AjaxResult remove(@PathVariable Long[] dictIds)
96 106 {
97   - return toAjax(dictTypeService.deleteDictTypeById(dictId));
  107 + return toAjax(dictTypeService.deleteDictTypeByIds(dictIds));
98 108 }
99 109 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java
... ... @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.PostMapping;
11 11 import org.springframework.web.bind.annotation.PutMapping;
12 12 import org.springframework.web.bind.annotation.RequestBody;
13 13 import org.springframework.web.bind.annotation.RequestMapping;
14   -import org.springframework.web.bind.annotation.ResponseBody;
15 14 import org.springframework.web.bind.annotation.RestController;
16 15 import com.ruoyi.common.constant.UserConstants;
17 16 import com.ruoyi.common.utils.SecurityUtils;
... ... @@ -71,7 +70,6 @@ public class SysMenuController extends BaseController
71 70 */
72 71 @PreAuthorize("@ss.hasPermi('system:menu:query')")
73 72 @GetMapping(value = "/roleMenuTreeselect/{roleId}")
74   - @ResponseBody
75 73 public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
76 74 {
77 75 return AjaxResult.success(menuService.selectMenuListByRoleId(roleId));
... ... @@ -83,7 +81,7 @@ public class SysMenuController extends BaseController
83 81 @PreAuthorize("@ss.hasPermi('system:menu:add')")
84 82 @Log(title = "菜单管理", businessType = BusinessType.INSERT)
85 83 @PostMapping
86   - public AjaxResult add(@RequestBody @Validated SysMenu menu)
  84 + public AjaxResult add(@Validated @RequestBody SysMenu menu)
87 85 {
88 86 if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
89 87 {
... ... @@ -99,7 +97,7 @@ public class SysMenuController extends BaseController
99 97 @PreAuthorize("@ss.hasPermi('system:menu:edit')")
100 98 @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
101 99 @PutMapping
102   - public AjaxResult edit(@RequestBody SysMenu menu)
  100 + public AjaxResult edit(@Validated @RequestBody SysMenu menu)
103 101 {
104 102 if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
105 103 {
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -60,7 +61,7 @@ public class SysNoticeController extends BaseController
60 61 @PreAuthorize("@ss.hasPermi('system:notice:add')")
61 62 @Log(title = "通知公告", businessType = BusinessType.INSERT)
62 63 @PostMapping
63   - public AjaxResult add(@RequestBody SysNotice notice)
  64 + public AjaxResult add(@Validated @RequestBody SysNotice notice)
64 65 {
65 66 notice.setCreateBy(SecurityUtils.getUsername());
66 67 return toAjax(noticeService.insertNotice(notice));
... ... @@ -72,7 +73,7 @@ public class SysNoticeController extends BaseController
72 73 @PreAuthorize("@ss.hasPermi('system:notice:edit')")
73 74 @Log(title = "通知公告", businessType = BusinessType.UPDATE)
74 75 @PutMapping
75   - public AjaxResult edit(@RequestBody SysNotice notice)
  76 + public AjaxResult edit(@Validated @RequestBody SysNotice notice)
76 77 {
77 78 notice.setUpdateBy(SecurityUtils.getUsername());
78 79 return toAjax(noticeService.updateNotice(notice));
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 14 import org.springframework.web.bind.annotation.RestController;
14 15 import com.ruoyi.common.constant.UserConstants;
15 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 20 import com.ruoyi.framework.web.controller.BaseController;
... ... @@ -44,6 +46,16 @@ public class SysPostController extends BaseController
44 46 List<SysPost> list = postService.selectPostList(post);
45 47 return getDataTable(list);
46 48 }
  49 +
  50 + @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
  51 + @PreAuthorize("@ss.hasPermi('system:config:export')")
  52 + @GetMapping("/export")
  53 + public AjaxResult export(SysPost post)
  54 + {
  55 + List<SysPost> list = postService.selectPostList(post);
  56 + ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
  57 + return util.exportExcel(list, "岗位数据");
  58 + }
47 59  
48 60 /**
49 61 * 根据岗位编号获取详细信息
... ... @@ -61,7 +73,7 @@ public class SysPostController extends BaseController
61 73 @PreAuthorize("@ss.hasPermi('system:post:add')")
62 74 @Log(title = "岗位管理", businessType = BusinessType.INSERT)
63 75 @PostMapping
64   - public AjaxResult add(@RequestBody SysPost post)
  76 + public AjaxResult add(@Validated @RequestBody SysPost post)
65 77 {
66 78 if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
67 79 {
... ... @@ -81,7 +93,7 @@ public class SysPostController extends BaseController
81 93 @PreAuthorize("@ss.hasPermi('system:post:edit')")
82 94 @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
83 95 @PutMapping
84   - public AjaxResult edit(@RequestBody SysPost post)
  96 + public AjaxResult edit(@Validated @RequestBody SysPost post)
85 97 {
86 98 if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
87 99 {
... ... @@ -100,10 +112,10 @@ public class SysPostController extends BaseController
100 112 */
101 113 @PreAuthorize("@ss.hasPermi('system:post:remove')")
102 114 @Log(title = "岗位管理", businessType = BusinessType.DELETE)
103   - @DeleteMapping("/{postId}")
104   - public AjaxResult remove(@PathVariable Long postId)
  115 + @DeleteMapping("/{postIds}")
  116 + public AjaxResult remove(@PathVariable Long[] postIds)
105 117 {
106   - return toAjax(postService.deletePostById(postId));
  118 + return toAjax(postService.deletePostByIds(postIds));
107 119 }
108 120  
109 121 /**
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 14 import org.springframework.web.bind.annotation.RestController;
14 15 import com.ruoyi.common.constant.UserConstants;
15 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 20 import com.ruoyi.framework.web.controller.BaseController;
... ... @@ -42,6 +44,16 @@ public class SysRoleController extends BaseController
42 44 return getDataTable(list);
43 45 }
44 46  
  47 + @Log(title = "角色管理", businessType = BusinessType.EXPORT)
  48 + @PreAuthorize("@ss.hasPermi('system:role:export')")
  49 + @GetMapping("/export")
  50 + public AjaxResult export(SysRole role)
  51 + {
  52 + List<SysRole> list = roleService.selectRoleList(role);
  53 + ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
  54 + return util.exportExcel(list, "角色数据");
  55 + }
  56 +
45 57 /**
46 58 * 根据角色编号获取详细信息
47 59 */
... ... @@ -58,7 +70,7 @@ public class SysRoleController extends BaseController
58 70 @PreAuthorize("@ss.hasPermi('system:role:add')")
59 71 @Log(title = "角色管理", businessType = BusinessType.INSERT)
60 72 @PostMapping
61   - public AjaxResult add(@RequestBody SysRole role)
  73 + public AjaxResult add(@Validated @RequestBody SysRole role)
62 74 {
63 75 if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
64 76 {
... ... @@ -79,7 +91,7 @@ public class SysRoleController extends BaseController
79 91 @PreAuthorize("@ss.hasPermi('system:role:edit')")
80 92 @Log(title = "角色管理", businessType = BusinessType.UPDATE)
81 93 @PutMapping
82   - public AjaxResult edit(@RequestBody SysRole role)
  94 + public AjaxResult edit(@Validated @RequestBody SysRole role)
83 95 {
84 96 roleService.checkRoleAllowed(role);
85 97 if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
... ... @@ -120,15 +132,14 @@ public class SysRoleController extends BaseController
120 132 }
121 133  
122 134 /**
123   - * 删除岗位
  135 + * 删除角色
124 136 */
125 137 @PreAuthorize("@ss.hasPermi('system:role:remove')")
126 138 @Log(title = "角色管理", businessType = BusinessType.DELETE)
127   - @DeleteMapping("/{roleId}")
128   - public AjaxResult remove(@PathVariable Long roleId)
  139 + @DeleteMapping("/{roleIds}")
  140 + public AjaxResult remove(@PathVariable Long[] roleIds)
129 141 {
130   - roleService.checkRoleAllowed(new SysRole(roleId));
131   - return toAjax(roleService.deleteRoleById(roleId));
  142 + return toAjax(roleService.deleteRoleByIds(roleIds));
132 143 }
133 144  
134 145 /**
... ...
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 3 import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 8 import org.springframework.web.bind.annotation.GetMapping;
8 9 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 14 import org.springframework.web.bind.annotation.RestController;
14 15 import com.ruoyi.common.constant.UserConstants;
15 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 20 import com.ruoyi.framework.web.controller.BaseController;
... ... @@ -53,6 +55,16 @@ public class SysUserController extends BaseController
53 55 return getDataTable(list);
54 56 }
55 57  
  58 + @Log(title = "用户管理", businessType = BusinessType.EXPORT)
  59 + @PreAuthorize("@ss.hasPermi('system:user:export')")
  60 + @GetMapping("/export")
  61 + public AjaxResult export(SysUser user)
  62 + {
  63 + List<SysUser> list = userService.selectUserList(user);
  64 + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
  65 + return util.exportExcel(list, "用户数据");
  66 + }
  67 +
56 68 /**
57 69 * 根据用户编号获取详细信息
58 70 */
... ... @@ -72,7 +84,7 @@ public class SysUserController extends BaseController
72 84 @PreAuthorize("@ss.hasPermi('system:user:add')")
73 85 @Log(title = "用户管理", businessType = BusinessType.INSERT)
74 86 @PostMapping
75   - public AjaxResult add(@RequestBody SysUser user)
  87 + public AjaxResult add(@Validated @RequestBody SysUser user)
76 88 {
77 89 if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
78 90 {
... ... @@ -97,7 +109,7 @@ public class SysUserController extends BaseController
97 109 @PreAuthorize("@ss.hasPermi('system:user:edit')")
98 110 @Log(title = "用户管理", businessType = BusinessType.UPDATE)
99 111 @PutMapping
100   - public AjaxResult edit(@RequestBody SysUser user)
  112 + public AjaxResult edit(@Validated @RequestBody SysUser user)
101 113 {
102 114 userService.checkUserAllowed(user);
103 115 if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
... ... @@ -117,11 +129,10 @@ public class SysUserController extends BaseController
117 129 */
118 130 @PreAuthorize("@ss.hasPermi('system:user:remove')")
119 131 @Log(title = "用户管理", businessType = BusinessType.DELETE)
120   - @DeleteMapping("/{userId}")
121   - public AjaxResult remove(@PathVariable Long userId)
  132 + @DeleteMapping("/{userIds}")
  133 + public AjaxResult remove(@PathVariable Long[] userIds)
122 134 {
123   - userService.checkUserAllowed(new SysUser(userId));
124   - return toAjax(userService.deleteUserById(userId));
  135 + return toAjax(userService.deleteUserByIds(userIds));
125 136 }
126 137  
127 138 /**
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java
... ... @@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain;
2 2  
3 3 import javax.validation.constraints.NotBlank;
4 4 import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
  7 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  8 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
5 9 import com.ruoyi.framework.web.domain.BaseEntity;
6 10  
7 11 /**
... ... @@ -14,18 +18,23 @@ public class SysConfig extends BaseEntity
14 18 private static final long serialVersionUID = 1L;
15 19  
16 20 /** 参数主键 */
  21 + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC)
17 22 private Long configId;
18 23  
19 24 /** 参数名称 */
  25 + @Excel(name = "参数名称")
20 26 private String configName;
21 27  
22 28 /** 参数键名 */
  29 + @Excel(name = "参数键名")
23 30 private String configKey;
24 31  
25 32 /** 参数键值 */
  33 + @Excel(name = "参数键值")
26 34 private String configValue;
27 35  
28 36 /** 系统内置(Y是 N否) */
  37 + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否")
29 38 private String configType;
30 39  
31 40 public Long getConfigId()
... ... @@ -83,4 +92,20 @@ public class SysConfig extends BaseEntity
83 92 {
84 93 this.configType = configType;
85 94 }
  95 +
  96 + @Override
  97 + public String toString() {
  98 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  99 + .append("configId", getConfigId())
  100 + .append("configName", getConfigName())
  101 + .append("configKey", getConfigKey())
  102 + .append("configValue", getConfigValue())
  103 + .append("configType", getConfigType())
  104 + .append("createBy", getCreateBy())
  105 + .append("createTime", getCreateTime())
  106 + .append("updateBy", getUpdateBy())
  107 + .append("updateTime", getUpdateTime())
  108 + .append("remark", getRemark())
  109 + .toString();
  110 + }
86 111 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java
... ... @@ -2,6 +2,11 @@ package com.ruoyi.project.system.domain;
2 2  
3 3 import java.util.ArrayList;
4 4 import java.util.List;
  5 +import javax.validation.constraints.Email;
  6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.Size;
  8 +import org.apache.commons.lang3.builder.ToStringBuilder;
  9 +import org.apache.commons.lang3.builder.ToStringStyle;
5 10 import com.ruoyi.framework.web.domain.BaseEntity;
6 11  
7 12 /**
... ... @@ -45,7 +50,7 @@ public class SysDept extends BaseEntity
45 50  
46 51 /** 父部门名称 */
47 52 private String parentName;
48   -
  53 +
49 54 /** 子部门 */
50 55 private List<SysDept> children = new ArrayList<SysDept>();
51 56  
... ... @@ -79,6 +84,8 @@ public class SysDept extends BaseEntity
79 84 this.ancestors = ancestors;
80 85 }
81 86  
  87 + @NotBlank(message = "部门名称不能为空")
  88 + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
82 89 public String getDeptName()
83 90 {
84 91 return deptName;
... ... @@ -89,6 +96,7 @@ public class SysDept extends BaseEntity
89 96 this.deptName = deptName;
90 97 }
91 98  
  99 + @NotBlank(message = "显示顺序不能为空")
92 100 public String getOrderNum()
93 101 {
94 102 return orderNum;
... ... @@ -109,6 +117,7 @@ public class SysDept extends BaseEntity
109 117 this.leader = leader;
110 118 }
111 119  
  120 + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
112 121 public String getPhone()
113 122 {
114 123 return phone;
... ... @@ -119,6 +128,8 @@ public class SysDept extends BaseEntity
119 128 this.phone = phone;
120 129 }
121 130  
  131 + @Email(message = "邮箱格式不正确")
  132 + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
122 133 public String getEmail()
123 134 {
124 135 return email;
... ... @@ -168,4 +179,24 @@ public class SysDept extends BaseEntity
168 179 {
169 180 this.children = children;
170 181 }
  182 +
  183 + @Override
  184 + public String toString() {
  185 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  186 + .append("deptId", getDeptId())
  187 + .append("parentId", getParentId())
  188 + .append("ancestors", getAncestors())
  189 + .append("deptName", getDeptName())
  190 + .append("orderNum", getOrderNum())
  191 + .append("leader", getLeader())
  192 + .append("phone", getPhone())
  193 + .append("email", getEmail())
  194 + .append("status", getStatus())
  195 + .append("delFlag", getDelFlag())
  196 + .append("createBy", getCreateBy())
  197 + .append("createTime", getCreateTime())
  198 + .append("updateBy", getUpdateBy())
  199 + .append("updateTime", getUpdateTime())
  200 + .toString();
  201 + }
171 202 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java
... ... @@ -2,7 +2,11 @@ package com.ruoyi.project.system.domain;
2 2  
3 3 import javax.validation.constraints.NotBlank;
4 4 import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
5 7 import com.ruoyi.common.constant.UserConstants;
  8 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  9 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
6 10 import com.ruoyi.framework.web.domain.BaseEntity;
7 11  
8 12 /**
... ... @@ -15,18 +19,23 @@ public class SysDictData extends BaseEntity
15 19 private static final long serialVersionUID = 1L;
16 20  
17 21 /** 字典编码 */
  22 + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
18 23 private Long dictCode;
19 24  
20 25 /** 字典排序 */
  26 + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
21 27 private Long dictSort;
22 28  
23 29 /** 字典标签 */
  30 + @Excel(name = "字典标签")
24 31 private String dictLabel;
25 32  
26 33 /** 字典键值 */
  34 + @Excel(name = "字典键值")
27 35 private String dictValue;
28 36  
29 37 /** 字典类型 */
  38 + @Excel(name = "字典类型")
30 39 private String dictType;
31 40  
32 41 /** 样式属性(其他样式扩展) */
... ... @@ -36,9 +45,11 @@ public class SysDictData extends BaseEntity
36 45 private String listClass;
37 46  
38 47 /** 是否默认(Y是 N否) */
  48 + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
39 49 private String isDefault;
40 50  
41 51 /** 状态(0正常 1停用) */
  52 + @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
42 53 private String status;
43 54  
44 55 public Long getDictCode()
... ... @@ -142,4 +153,24 @@ public class SysDictData extends BaseEntity
142 153 {
143 154 this.status = status;
144 155 }
  156 +
  157 + @Override
  158 + public String toString() {
  159 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  160 + .append("dictCode", getDictCode())
  161 + .append("dictSort", getDictSort())
  162 + .append("dictLabel", getDictLabel())
  163 + .append("dictValue", getDictValue())
  164 + .append("dictType", getDictType())
  165 + .append("cssClass", getCssClass())
  166 + .append("listClass", getListClass())
  167 + .append("isDefault", getIsDefault())
  168 + .append("status", getStatus())
  169 + .append("createBy", getCreateBy())
  170 + .append("createTime", getCreateTime())
  171 + .append("updateBy", getUpdateBy())
  172 + .append("updateTime", getUpdateTime())
  173 + .append("remark", getRemark())
  174 + .toString();
  175 + }
145 176 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java
... ... @@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain;
2 2  
3 3 import javax.validation.constraints.NotBlank;
4 4 import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
  7 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  8 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
5 9 import com.ruoyi.framework.web.domain.BaseEntity;
6 10  
7 11 /**
... ... @@ -14,15 +18,19 @@ public class SysDictType extends BaseEntity
14 18 private static final long serialVersionUID = 1L;
15 19  
16 20 /** 字典主键 */
  21 + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
17 22 private Long dictId;
18 23  
19 24 /** 字典名称 */
  25 + @Excel(name = "字典名称")
20 26 private String dictName;
21 27  
22 28 /** 字典类型 */
  29 + @Excel(name = "字典类型")
23 30 private String dictType;
24 31  
25 32 /** 状态(0正常 1停用) */
  33 + @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
26 34 private String status;
27 35  
28 36 public Long getDictId()
... ... @@ -68,4 +76,19 @@ public class SysDictType extends BaseEntity
68 76 {
69 77 this.status = status;
70 78 }
  79 +
  80 + @Override
  81 + public String toString() {
  82 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  83 + .append("dictId", getDictId())
  84 + .append("dictName", getDictName())
  85 + .append("dictType", getDictType())
  86 + .append("status", getStatus())
  87 + .append("createBy", getCreateBy())
  88 + .append("createTime", getCreateTime())
  89 + .append("updateBy", getUpdateBy())
  90 + .append("updateTime", getUpdateTime())
  91 + .append("remark", getRemark())
  92 + .toString();
  93 + }
71 94 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
1 1 package com.ruoyi.project.system.domain;
2 2  
  3 +import java.util.ArrayList;
3 4 import java.util.List;
  5 +import javax.validation.constraints.NotBlank;
  6 +import javax.validation.constraints.Size;
  7 +import org.apache.commons.lang3.builder.ToStringBuilder;
  8 +import org.apache.commons.lang3.builder.ToStringStyle;
4 9 import com.ruoyi.framework.web.domain.BaseEntity;
5   -import java.util.ArrayList;
6 10  
7 11 /**
8 12 * 菜单权限表 sys_menu
... ... @@ -62,6 +66,8 @@ public class SysMenu extends BaseEntity
62 66 this.menuId = menuId;
63 67 }
64 68  
  69 + @NotBlank(message = "菜单名称不能为空")
  70 + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
65 71 public String getMenuName()
66 72 {
67 73 return menuName;
... ... @@ -92,6 +98,7 @@ public class SysMenu extends BaseEntity
92 98 this.parentId = parentId;
93 99 }
94 100  
  101 + @NotBlank(message = "显示顺序不能为空")
95 102 public String getOrderNum()
96 103 {
97 104 return orderNum;
... ... @@ -102,6 +109,7 @@ public class SysMenu extends BaseEntity
102 109 this.orderNum = orderNum;
103 110 }
104 111  
  112 + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
105 113 public String getPath()
106 114 {
107 115 return path;
... ... @@ -112,6 +120,7 @@ public class SysMenu extends BaseEntity
112 120 this.path = path;
113 121 }
114 122  
  123 + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
115 124 public String getComponent()
116 125 {
117 126 return component;
... ... @@ -132,6 +141,7 @@ public class SysMenu extends BaseEntity
132 141 this.isFrame = isFrame;
133 142 }
134 143  
  144 + @NotBlank(message = "菜单类型不能为空")
135 145 public String getMenuType()
136 146 {
137 147 return menuType;
... ... @@ -152,6 +162,7 @@ public class SysMenu extends BaseEntity
152 162 this.visible = visible;
153 163 }
154 164  
  165 + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
155 166 public String getPerms()
156 167 {
157 168 return perms;
... ... @@ -181,4 +192,26 @@ public class SysMenu extends BaseEntity
181 192 {
182 193 this.children = children;
183 194 }
  195 +
  196 + @Override
  197 + public String toString() {
  198 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  199 + .append("menuId", getMenuId())
  200 + .append("menuName", getMenuName())
  201 + .append("parentId", getParentId())
  202 + .append("orderNum", getOrderNum())
  203 + .append("path", getPath())
  204 + .append("component", getComponent())
  205 + .append("isFrame", getIsFrame())
  206 + .append("menuType", getMenuType())
  207 + .append("visible", getVisible())
  208 + .append("perms", getPerms())
  209 + .append("icon", getIcon())
  210 + .append("createBy", getCreateBy())
  211 + .append("createTime", getCreateTime())
  212 + .append("updateBy", getUpdateBy())
  213 + .append("updateTime", getUpdateTime())
  214 + .append("remark", getRemark())
  215 + .toString();
  216 + }
184 217 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
1 1 package com.ruoyi.project.system.domain;
2 2  
  3 +import javax.validation.constraints.NotBlank;
  4 +import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
3 7 import com.ruoyi.framework.web.domain.BaseEntity;
4 8  
5 9 /**
... ... @@ -41,6 +45,8 @@ public class SysNotice extends BaseEntity
41 45 this.noticeTitle = noticeTitle;
42 46 }
43 47  
  48 + @NotBlank(message = "公告标题不能为空")
  49 + @Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
44 50 public String getNoticeTitle()
45 51 {
46 52 return noticeTitle;
... ... @@ -75,4 +81,20 @@ public class SysNotice extends BaseEntity
75 81 {
76 82 return status;
77 83 }
  84 +
  85 + @Override
  86 + public String toString() {
  87 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  88 + .append("noticeId", getNoticeId())
  89 + .append("noticeTitle", getNoticeTitle())
  90 + .append("noticeType", getNoticeType())
  91 + .append("noticeContent", getNoticeContent())
  92 + .append("status", getStatus())
  93 + .append("createBy", getCreateBy())
  94 + .append("createTime", getCreateTime())
  95 + .append("updateBy", getUpdateBy())
  96 + .append("updateTime", getUpdateTime())
  97 + .append("remark", getRemark())
  98 + .toString();
  99 + }
78 100 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java
... ... @@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain;
2 2  
3 3 import javax.validation.constraints.NotBlank;
4 4 import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
  7 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  8 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
5 9 import com.ruoyi.framework.web.domain.BaseEntity;
6 10  
7 11 /**
... ... @@ -14,18 +18,23 @@ public class SysPost extends BaseEntity
14 18 private static final long serialVersionUID = 1L;
15 19  
16 20 /** 岗位序号 */
  21 + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC)
17 22 private Long postId;
18 23  
19 24 /** 岗位编码 */
  25 + @Excel(name = "岗位编码")
20 26 private String postCode;
21 27  
22 28 /** 岗位名称 */
  29 + @Excel(name = "岗位名称")
23 30 private String postName;
24 31  
25 32 /** 岗位排序 */
  33 + @Excel(name = "岗位排序")
26 34 private String postSort;
27 35  
28 36 /** 状态(0正常 1停用) */
  37 + @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
29 38 private String status;
30 39  
31 40 /** 用户是否存在此岗位标识 默认不存在 */
... ... @@ -95,4 +104,20 @@ public class SysPost extends BaseEntity
95 104 {
96 105 this.flag = flag;
97 106 }
  107 +
  108 + @Override
  109 + public String toString() {
  110 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  111 + .append("postId", getPostId())
  112 + .append("postCode", getPostCode())
  113 + .append("postName", getPostName())
  114 + .append("postSort", getPostSort())
  115 + .append("status", getStatus())
  116 + .append("createBy", getCreateBy())
  117 + .append("createTime", getCreateTime())
  118 + .append("updateBy", getUpdateBy())
  119 + .append("updateTime", getUpdateTime())
  120 + .append("remark", getRemark())
  121 + .toString();
  122 + }
98 123 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java
1 1 package com.ruoyi.project.system.domain;
2 2  
  3 +import javax.validation.constraints.NotBlank;
  4 +import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
  7 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  8 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
3 9 import com.ruoyi.framework.web.domain.BaseEntity;
4 10  
5 11 /**
... ... @@ -12,21 +18,27 @@ public class SysRole extends BaseEntity
12 18 private static final long serialVersionUID = 1L;
13 19  
14 20 /** 角色ID */
  21 + @Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
15 22 private Long roleId;
16 23  
17 24 /** 角色名称 */
  25 + @Excel(name = "角色名称")
18 26 private String roleName;
19 27  
20 28 /** 角色权限 */
  29 + @Excel(name = "角色权限")
21 30 private String roleKey;
22 31  
23 32 /** 角色排序 */
  33 + @Excel(name = "角色排序")
24 34 private String roleSort;
25 35  
26   - /** 数据范围 */
  36 + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限) */
  37 + @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限")
27 38 private String dataScope;
28 39  
29 40 /** 角色状态(0正常 1停用) */
  41 + @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
30 42 private String status;
31 43  
32 44 /** 删除标志(0代表存在 2代表删除) */
... ... @@ -71,6 +83,8 @@ public class SysRole extends BaseEntity
71 83 return roleId != null && 1L == roleId;
72 84 }
73 85  
  86 + @NotBlank(message = "角色名称不能为空")
  87 + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
74 88 public String getRoleName()
75 89 {
76 90 return roleName;
... ... @@ -81,6 +95,8 @@ public class SysRole extends BaseEntity
81 95 this.roleName = roleName;
82 96 }
83 97  
  98 + @NotBlank(message = "权限字符不能为空")
  99 + @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
84 100 public String getRoleKey()
85 101 {
86 102 return roleKey;
... ... @@ -91,6 +107,7 @@ public class SysRole extends BaseEntity
91 107 this.roleKey = roleKey;
92 108 }
93 109  
  110 + @NotBlank(message = "显示顺序不能为空")
94 111 public String getRoleSort()
95 112 {
96 113 return roleSort;
... ... @@ -160,4 +177,21 @@ public class SysRole extends BaseEntity
160 177 {
161 178 this.deptIds = deptIds;
162 179 }
  180 +
  181 + public String toString() {
  182 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  183 + .append("roleId", getRoleId())
  184 + .append("roleName", getRoleName())
  185 + .append("roleKey", getRoleKey())
  186 + .append("roleSort", getRoleSort())
  187 + .append("dataScope", getDataScope())
  188 + .append("status", getStatus())
  189 + .append("delFlag", getDelFlag())
  190 + .append("createBy", getCreateBy())
  191 + .append("createTime", getCreateTime())
  192 + .append("updateBy", getUpdateBy())
  193 + .append("updateTime", getUpdateTime())
  194 + .append("remark", getRemark())
  195 + .toString();
  196 + }
163 197 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java
... ... @@ -2,6 +2,14 @@ package com.ruoyi.project.system.domain;
2 2  
3 3 import java.util.Date;
4 4 import java.util.List;
  5 +import javax.validation.constraints.Email;
  6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.Size;
  8 +import org.apache.commons.lang3.builder.ToStringBuilder;
  9 +import org.apache.commons.lang3.builder.ToStringStyle;
  10 +import com.ruoyi.framework.aspectj.lang.annotation.Excel;
  11 +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
  12 +import com.ruoyi.framework.aspectj.lang.annotation.Excels;
5 13 import com.ruoyi.framework.web.domain.BaseEntity;
6 14  
7 15 /**
... ... @@ -14,24 +22,30 @@ public class SysUser extends BaseEntity
14 22 private static final long serialVersionUID = 1L;
15 23  
16 24 /** 用户ID */
  25 + @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
17 26 private Long userId;
18 27  
19 28 /** 部门ID */
20 29 private Long deptId;
21 30  
22 31 /** 用户账号 */
  32 + @Excel(name = "登录名称")
23 33 private String userName;
24 34  
25 35 /** 用户昵称 */
  36 + @Excel(name = "用户名称")
26 37 private String nickName;
27 38  
28 39 /** 用户邮箱 */
  40 + @Excel(name = "用户邮箱")
29 41 private String email;
30 42  
31 43 /** 手机号码 */
  44 + @Excel(name = "手机号码")
32 45 private String phonenumber;
33 46  
34 47 /** 用户性别 */
  48 + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
35 49 private String sex;
36 50  
37 51 /** 用户头像 */
... ... @@ -44,18 +58,22 @@ public class SysUser extends BaseEntity
44 58 private String salt;
45 59  
46 60 /** 帐号状态(0正常 1停用) */
  61 + @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
47 62 private String status;
48 63  
49 64 /** 删除标志(0代表存在 2代表删除) */
50 65 private String delFlag;
51 66  
52 67 /** 最后登陆IP */
  68 + @Excel(name = "最后登陆IP")
53 69 private String loginIp;
54 70  
55 71 /** 最后登陆时间 */
  72 + @Excel(name = "最后登陆时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
56 73 private Date loginDate;
57 74  
58 75 /** 部门对象 */
  76 + @Excels({ @Excel(name = "部门名称", targetAttr = "deptName"), @Excel(name = "部门负责人", targetAttr = "leader") })
59 77 private SysDept dept;
60 78  
61 79 /** 角色对象 */
... ... @@ -107,6 +125,7 @@ public class SysUser extends BaseEntity
107 125 this.deptId = deptId;
108 126 }
109 127  
  128 + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
110 129 public String getNickName()
111 130 {
112 131 return nickName;
... ... @@ -117,6 +136,8 @@ public class SysUser extends BaseEntity
117 136 this.nickName = nickName;
118 137 }
119 138  
  139 + @NotBlank(message = "用户账号不能为空")
  140 + @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
120 141 public String getUserName()
121 142 {
122 143 return userName;
... ... @@ -127,6 +148,8 @@ public class SysUser extends BaseEntity
127 148 this.userName = userName;
128 149 }
129 150  
  151 + @Email(message = "邮箱格式不正确")
  152 + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
130 153 public String getEmail()
131 154 {
132 155 return email;
... ... @@ -137,6 +160,7 @@ public class SysUser extends BaseEntity
137 160 this.email = email;
138 161 }
139 162  
  163 + @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
140 164 public String getPhonenumber()
141 165 {
142 166 return phonenumber;
... ... @@ -266,5 +290,30 @@ public class SysUser extends BaseEntity
266 290 {
267 291 this.postIds = postIds;
268 292 }
269   -
  293 +
  294 + @Override
  295 + public String toString() {
  296 + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
  297 + .append("userId", getUserId())
  298 + .append("deptId", getDeptId())
  299 + .append("userName", getUserName())
  300 + .append("nickName", getNickName())
  301 + .append("email", getEmail())
  302 + .append("phonenumber", getPhonenumber())
  303 + .append("sex", getSex())
  304 + .append("avatar", getAvatar())
  305 + .append("password", getPassword())
  306 + .append("salt", getSalt())
  307 + .append("status", getStatus())
  308 + .append("delFlag", getDelFlag())
  309 + .append("loginIp", getLoginIp())
  310 + .append("loginDate", getLoginDate())
  311 + .append("createBy", getCreateBy())
  312 + .append("createTime", getCreateTime())
  313 + .append("updateBy", getUpdateBy())
  314 + .append("updateTime", getUpdateTime())
  315 + .append("remark", getRemark())
  316 + .append("dept", getDept())
  317 + .toString();
  318 + }
270 319 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java
... ... @@ -53,8 +53,16 @@ public interface SysConfigMapper
53 53 /**
54 54 * 删除参数配置
55 55 *
56   - * @param configId 需要删除的数据ID
  56 + * @param configId 参数ID
57 57 * @return 结果
58 58 */
59 59 public int deleteConfigById(Long configId);
  60 +
  61 + /**
  62 + * 批量删除参数信息
  63 + *
  64 + * @param configIds 需要删除的参数ID
  65 + * @return 结果
  66 + */
  67 + public int deleteConfigByIds(Long[] configIds);
60 68 }
61 69 \ No newline at end of file
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java
... ... @@ -61,6 +61,14 @@ public interface SysDictDataMapper
61 61 public int deleteDictDataById(Long dictCode);
62 62  
63 63 /**
  64 + * 批量删除字典数据信息
  65 + *
  66 + * @param dictCodes 需要删除的字典数据ID
  67 + * @return 结果
  68 + */
  69 + public int deleteDictDataByIds(Long[] dictCodes);
  70 +
  71 + /**
64 72 * 新增字典数据信息
65 73 *
66 74 * @param dictData 字典数据信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java
... ... @@ -52,6 +52,14 @@ public interface SysDictTypeMapper
52 52 public int deleteDictTypeById(Long dictId);
53 53  
54 54 /**
  55 + * 批量删除字典类型信息
  56 + *
  57 + * @param dictIds 需要删除的字典ID
  58 + * @return 结果
  59 + */
  60 + public int deleteDictTypeByIds(Long[] dictIds);
  61 +
  62 + /**
55 63 * 新增字典类型信息
56 64 *
57 65 * @param dictType 字典类型信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java
... ... @@ -49,4 +49,12 @@ public interface SysNoticeMapper
49 49 * @return 结果
50 50 */
51 51 public int deleteNoticeById(Long noticeId);
  52 +
  53 + /**
  54 + * 批量删除公告信息
  55 + *
  56 + * @param noticeIds 需要删除的公告ID
  57 + * @return 结果
  58 + */
  59 + public int deleteNoticeByIds(Long noticeIds);
52 60 }
53 61 \ No newline at end of file
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java
... ... @@ -58,6 +58,14 @@ public interface SysPostMapper
58 58 public int deletePostById(Long postId);
59 59  
60 60 /**
  61 + * 批量删除岗位信息
  62 + *
  63 + * @param postIds 需要删除的岗位ID
  64 + * @return 结果
  65 + */
  66 + public int deletePostByIds(Long[] postIds);
  67 +
  68 + /**
61 69 * 修改岗位信息
62 70 *
63 71 * @param post 岗位信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java
... ... @@ -97,4 +97,11 @@ public interface SysRoleMapper
97 97 */
98 98 public int deleteRoleById(Long roleId);
99 99  
  100 + /**
  101 + * 批量删除角色信息
  102 + *
  103 + * @param roleIds 需要删除的角色ID
  104 + * @return 结果
  105 + */
  106 + public int deleteRoleByIds(Long[] roleIds);
100 107 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
... ... @@ -80,6 +80,14 @@ public interface SysUserMapper
80 80 public int deleteUserById(Long userId);
81 81  
82 82 /**
  83 + * 批量删除用户信息
  84 + *
  85 + * @param userIds 需要删除的用户ID
  86 + * @return 结果
  87 + */
  88 + public int deleteUserByIds(Long[] userIds);
  89 +
  90 + /**
83 91 * 校验用户名称是否唯一
84 92 *
85 93 * @param userName 用户名称
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java
... ... @@ -53,12 +53,20 @@ public interface ISysConfigService
53 53 /**
54 54 * 删除参数配置信息
55 55 *
56   - * @param configId 需要删除的数据ID
  56 + * @param configId 参数ID
57 57 * @return 结果
58 58 */
59 59 public int deleteConfigById(Long configId);
60 60  
61 61 /**
  62 + * 批量删除参数信息
  63 + *
  64 + * @param configIds 需要删除的参数ID
  65 + * @return 结果
  66 + */
  67 + public int deleteConfigByIds(Long[] configIds);
  68 +
  69 + /**
62 70 * 校验参数键名是否唯一
63 71 *
64 72 * @param config 参数信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java
... ... @@ -52,6 +52,14 @@ public interface ISysDictDataService
52 52 public int deleteDictDataById(Long dictCode);
53 53  
54 54 /**
  55 + * 批量删除字典数据信息
  56 + *
  57 + * @param dictCodes 需要删除的字典数据ID
  58 + * @return 结果
  59 + */
  60 + public int deleteDictDataByIds(Long[] dictCodes);
  61 +
  62 + /**
55 63 * 新增保存字典数据信息
56 64 *
57 65 * @param dictData 字典数据信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java
... ... @@ -50,6 +50,14 @@ public interface ISysDictTypeService
50 50 public int deleteDictTypeById(Long dictId);
51 51  
52 52 /**
  53 + * 批量删除字典信息
  54 + *
  55 + * @param dictIds 需要删除的字典ID
  56 + * @return 结果
  57 + */
  58 + public int deleteDictTypeByIds(Long[] dictIds);
  59 +
  60 + /**
53 61 * 新增保存字典类型信息
54 62 *
55 63 * @param dictType 字典类型信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
... ... @@ -49,4 +49,12 @@ public interface ISysNoticeService
49 49 * @return 结果
50 50 */
51 51 public int deleteNoticeById(Long noticeId);
  52 +
  53 + /**
  54 + * 批量删除公告信息
  55 + *
  56 + * @param noticeIds 需要删除的公告ID
  57 + * @return 结果
  58 + */
  59 + public int deleteNoticeByIds(Long noticeIds);
52 60 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java
... ... @@ -58,6 +58,14 @@ public interface ISysPostService
58 58 public String checkPostCodeUnique(SysPost post);
59 59  
60 60 /**
  61 + * 通过岗位ID查询岗位使用数量
  62 + *
  63 + * @param postId 岗位ID
  64 + * @return 结果
  65 + */
  66 + public int countUserPostById(Long postId);
  67 +
  68 + /**
61 69 * 删除岗位信息
62 70 *
63 71 * @param postId 岗位ID
... ... @@ -66,6 +74,15 @@ public interface ISysPostService
66 74 public int deletePostById(Long postId);
67 75  
68 76 /**
  77 + * 批量删除岗位信息
  78 + *
  79 + * @param postIds 需要删除的岗位ID
  80 + * @return 结果
  81 + * @throws Exception 异常
  82 + */
  83 + public int deletePostByIds(Long[] postIds);
  84 +
  85 + /**
69 86 * 新增保存岗位信息
70 87 *
71 88 * @param post 岗位信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java
... ... @@ -74,6 +74,14 @@ public interface ISysRoleService
74 74 public void checkRoleAllowed(SysRole role);
75 75  
76 76 /**
  77 + * 通过角色ID查询角色使用数量
  78 + *
  79 + * @param roleId 角色ID
  80 + * @return 结果
  81 + */
  82 + public int countUserRoleByRoleId(Long roleId);
  83 +
  84 + /**
77 85 * 新增保存角色信息
78 86 *
79 87 * @param role 角色信息
... ... @@ -112,4 +120,12 @@ public interface ISysRoleService
112 120 * @return 结果
113 121 */
114 122 public int deleteRoleById(Long roleId);
  123 +
  124 + /**
  125 + * 批量删除角色信息
  126 + *
  127 + * @param roleIds 需要删除的角色ID
  128 + * @return 结果
  129 + */
  130 + public int deleteRoleByIds(Long[] roleIds);
115 131 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java
... ... @@ -146,4 +146,12 @@ public interface ISysUserService
146 146 * @return 结果
147 147 */
148 148 public int deleteUserById(Long userId);
  149 +
  150 + /**
  151 + * 批量删除用户信息
  152 + *
  153 + * @param userIds 需要删除的用户ID
  154 + * @return 结果
  155 + */
  156 + public int deleteUserByIds(Long[] userIds);
149 157 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java
... ... @@ -88,7 +88,7 @@ public class SysConfigServiceImpl implements ISysConfigService
88 88 /**
89 89 * 删除参数配置信息
90 90 *
91   - * @param configId 需要删除的数据ID
  91 + * @param configId 参数ID
92 92 * @return 结果
93 93 */
94 94 @Override
... ... @@ -98,6 +98,18 @@ public class SysConfigServiceImpl implements ISysConfigService
98 98 }
99 99  
100 100 /**
  101 + * 批量删除参数信息
  102 + *
  103 + * @param configIds 需要删除的参数ID
  104 + * @return 结果
  105 + */
  106 + @Override
  107 + public int deleteConfigByIds(Long[] configIds)
  108 + {
  109 + return configMapper.deleteConfigByIds(configIds);
  110 + }
  111 +
  112 + /**
101 113 * 校验参数键名是否唯一
102 114 *
103 115 * @param config 参数配置信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java
... ... @@ -80,6 +80,17 @@ public class SysDictDataServiceImpl implements ISysDictDataService
80 80 }
81 81  
82 82 /**
  83 + * 批量删除字典数据信息
  84 + *
  85 + * @param dictCodes 需要删除的字典数据ID
  86 + * @return 结果
  87 + */
  88 + public int deleteDictDataByIds(Long[] dictCodes)
  89 + {
  90 + return dictDataMapper.deleteDictDataByIds(dictCodes);
  91 + }
  92 +
  93 + /**
83 94 * 新增保存字典数据信息
84 95 *
85 96 * @param dictData 字典数据信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java
... ... @@ -84,6 +84,17 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
84 84 }
85 85  
86 86 /**
  87 + * 批量删除字典类型信息
  88 + *
  89 + * @param dictIds 需要删除的字典ID
  90 + * @return 结果
  91 + */
  92 + public int deleteDictTypeByIds(Long[] dictIds)
  93 + {
  94 + return dictTypeMapper.deleteDictTypeByIds(dictIds);
  95 + }
  96 +
  97 + /**
87 98 * 新增保存字典类型信息
88 99 *
89 100 * @param dictType 字典类型信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
... ... @@ -77,4 +77,15 @@ public class SysNoticeServiceImpl implements ISysNoticeService
77 77 {
78 78 return noticeMapper.deleteNoticeById(noticeId);
79 79 }
  80 +
  81 + /**
  82 + * 批量删除公告信息
  83 + *
  84 + * @param noticeIds 需要删除的公告ID
  85 + * @return 结果
  86 + */
  87 + public int deleteNoticeByIds(Long noticeIds)
  88 + {
  89 + return noticeMapper.deleteNoticeByIds(noticeIds);
  90 + }
80 91 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java
... ... @@ -4,9 +4,11 @@ import java.util.List;
4 4 import org.springframework.beans.factory.annotation.Autowired;
5 5 import org.springframework.stereotype.Service;
6 6 import com.ruoyi.common.constant.UserConstants;
  7 +import com.ruoyi.common.exception.CustomException;
7 8 import com.ruoyi.common.utils.StringUtils;
8 9 import com.ruoyi.project.system.domain.SysPost;
9 10 import com.ruoyi.project.system.mapper.SysPostMapper;
  11 +import com.ruoyi.project.system.mapper.SysUserPostMapper;
10 12 import com.ruoyi.project.system.service.ISysPostService;
11 13  
12 14 /**
... ... @@ -20,6 +22,9 @@ public class SysPostServiceImpl implements ISysPostService
20 22 @Autowired
21 23 private SysPostMapper postMapper;
22 24  
  25 + @Autowired
  26 + private SysUserPostMapper userPostMapper;
  27 +
23 28 /**
24 29 * 查询岗位信息集合
25 30 *
... ... @@ -66,7 +71,6 @@ public class SysPostServiceImpl implements ISysPostService
66 71 return postMapper.selectPostListByUserId(userId);
67 72 }
68 73  
69   -
70 74 /**
71 75 * 校验岗位名称是否唯一
72 76 *
... ... @@ -104,6 +108,18 @@ public class SysPostServiceImpl implements ISysPostService
104 108 }
105 109  
106 110 /**
  111 + * 通过岗位ID查询岗位使用数量
  112 + *
  113 + * @param postId 岗位ID
  114 + * @return 结果
  115 + */
  116 + @Override
  117 + public int countUserPostById(Long postId)
  118 + {
  119 + return userPostMapper.countUserPostById(postId);
  120 + }
  121 +
  122 + /**
107 123 * 删除岗位信息
108 124 *
109 125 * @param postId 岗位ID
... ... @@ -116,6 +132,26 @@ public class SysPostServiceImpl implements ISysPostService
116 132 }
117 133  
118 134 /**
  135 + * 批量删除岗位信息
  136 + *
  137 + * @param postIds 需要删除的岗位ID
  138 + * @return 结果
  139 + * @throws Exception 异常
  140 + */
  141 + public int deletePostByIds(Long[] postIds)
  142 + {
  143 + for (Long postId : postIds)
  144 + {
  145 + SysPost post = selectPostById(postId);
  146 + if (countUserPostById(postId) > 0)
  147 + {
  148 + throw new CustomException(String.format("%1$s已分配,不能删除", post.getPostName()));
  149 + }
  150 + }
  151 + return postMapper.deletePostByIds(postIds);
  152 + }
  153 +
  154 + /**
119 155 * 新增保存岗位信息
120 156 *
121 157 * @param post 岗位信息
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java
... ... @@ -18,6 +18,7 @@ import com.ruoyi.project.system.domain.SysRoleMenu;
18 18 import com.ruoyi.project.system.mapper.SysRoleDeptMapper;
19 19 import com.ruoyi.project.system.mapper.SysRoleMapper;
20 20 import com.ruoyi.project.system.mapper.SysRoleMenuMapper;
  21 +import com.ruoyi.project.system.mapper.SysUserRoleMapper;
21 22 import com.ruoyi.project.system.service.ISysRoleService;
22 23  
23 24 /**
... ... @@ -35,6 +36,9 @@ public class SysRoleServiceImpl implements ISysRoleService
35 36 private SysRoleMenuMapper roleMenuMapper;
36 37  
37 38 @Autowired
  39 + private SysUserRoleMapper userRoleMapper;
  40 +
  41 + @Autowired
38 42 private SysRoleDeptMapper roleDeptMapper;
39 43  
40 44 /**
... ... @@ -153,6 +157,18 @@ public class SysRoleServiceImpl implements ISysRoleService
153 157 }
154 158  
155 159 /**
  160 + * 通过角色ID查询角色使用数量
  161 + *
  162 + * @param roleId 角色ID
  163 + * @return 结果
  164 + */
  165 + @Override
  166 + public int countUserRoleByRoleId(Long roleId)
  167 + {
  168 + return userRoleMapper.countUserRoleByRoleId(roleId);
  169 + }
  170 +
  171 + /**
156 172 * 新增保存角色信息
157 173 *
158 174 * @param role 角色信息
... ... @@ -272,4 +288,24 @@ public class SysRoleServiceImpl implements ISysRoleService
272 288 {
273 289 return roleMapper.deleteRoleById(roleId);
274 290 }
  291 +
  292 + /**
  293 + * 批量删除角色信息
  294 + *
  295 + * @param roleIds 需要删除的角色ID
  296 + * @return 结果
  297 + */
  298 + public int deleteRoleByIds(Long[] roleIds)
  299 + {
  300 + for (Long roleId : roleIds)
  301 + {
  302 + checkRoleAllowed(new SysRole(roleId));
  303 + SysRole role = selectRoleById(roleId);
  304 + if (countUserRoleByRoleId(roleId) > 0)
  305 + {
  306 + throw new CustomException(String.format("%1$s已分配,不能删除", role.getRoleName()));
  307 + }
  308 + }
  309 + return roleMapper.deleteRoleByIds(roleIds);
  310 + }
275 311 }
... ...
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java
... ... @@ -360,4 +360,19 @@ public class SysUserServiceImpl implements ISysUserService
360 360 userPostMapper.deleteUserPostByUserId(userId);
361 361 return userMapper.deleteUserById(userId);
362 362 }
  363 +
  364 + /**
  365 + * 批量删除用户信息
  366 + *
  367 + * @param userIds 需要删除的用户ID
  368 + * @return 结果
  369 + */
  370 + public int deleteUserByIds(Long[] userIds)
  371 + {
  372 + for (Long userId : userIds)
  373 + {
  374 + checkUserAllowed(new SysUser(userId));
  375 + }
  376 + return userMapper.deleteUserByIds(userIds);
  377 + }
363 378 }
... ...
ruoyi/src/main/resources/application.yml
... ... @@ -3,7 +3,7 @@ ruoyi:
3 3 # 名称
4 4 name: RuoYi
5 5 # 版本
6   - version: 1.0.0
  6 + version: 1.1.0
7 7 # 版权年份
8 8 copyrightYear: 2019
9 9 # 实例演示开关
... ...
ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml
... ... @@ -42,7 +42,7 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
42 42 </where>
43 43 </select>
44 44  
45   - <delete id="deleteLogininforByIds" parameterType="String">
  45 + <delete id="deleteLogininforByIds" parameterType="Long">
46 46 delete from sys_logininfor where info_id in
47 47 <foreach collection="array" item="infoId" open="(" separator="," close=")">
48 48 #{infoId}
... ...
ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml
... ... @@ -63,7 +63,7 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
63 63 </where>
64 64 </select>
65 65  
66   - <delete id="deleteOperLogByIds" parameterType="String">
  66 + <delete id="deleteOperLogByIds" parameterType="Long">
67 67 delete from sys_oper_log where oper_id in
68 68 <foreach collection="array" item="operId" open="(" separator="," close=")">
69 69 #{operId}
... ...
ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml
... ... @@ -102,4 +102,11 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
102 102 delete from sys_config where config_id = #{configId}
103 103 </delete>
104 104  
  105 + <delete id="deleteConfigByIds" parameterType="Long">
  106 + delete from sys_config where config_id in
  107 + <foreach item="configId" collection="array" open="(" separator="," close=")">
  108 + #{configId}
  109 + </foreach>
  110 + </delete>
  111 +
105 112 </mapper>
106 113 \ No newline at end of file
... ...
ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml
... ... @@ -62,6 +62,13 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
62 62 <delete id="deleteDictDataById" parameterType="Long">
63 63 delete from sys_dict_data where dict_code = #{dictCode}
64 64 </delete>
  65 +
  66 + <delete id="deleteDictDataByIds" parameterType="Long">
  67 + delete from sys_dict_data where dict_code in
  68 + <foreach collection="array" item="dictCode" open="(" separator="," close=")">
  69 + #{dictCode}
  70 + </foreach>
  71 + </delete>
65 72  
66 73 <update id="updateDictData" parameterType="SysDictData">
67 74 update sys_dict_data
... ...
ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml
... ... @@ -63,6 +63,13 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
63 63 <delete id="deleteDictTypeById" parameterType="Long">
64 64 delete from sys_dict_type where dict_id = #{dictId}
65 65 </delete>
  66 +
  67 + <delete id="deleteDictTypeByIds" parameterType="Long">
  68 + delete from sys_dict_type where dict_id in
  69 + <foreach collection="array" item="dictId" open="(" separator="," close=")">
  70 + #{dictId}
  71 + </foreach>
  72 + </delete>
66 73  
67 74 <update id="updateDictType" parameterType="SysDictType">
68 75 update sys_dict_type
... ...
ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml
... ... @@ -79,4 +79,11 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
79 79 delete from sys_notice where notice_id = #{noticeId}
80 80 </delete>
81 81  
  82 + <delete id="deleteNoticeByIds" parameterType="Long">
  83 + delete from sys_notice where notice_id in
  84 + <foreach item="noticeId" collection="array" open="(" separator="," close=")">
  85 + #{noticeId}
  86 + </foreach>
  87 + </delete>
  88 +
82 89 </mapper>
83 90 \ No newline at end of file
... ...
ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml
... ... @@ -111,5 +111,12 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
111 111 <delete id="deletePostById" parameterType="Long">
112 112 delete from sys_post where post_id = #{postId}
113 113 </delete>
  114 +
  115 + <delete id="deletePostByIds" parameterType="Long">
  116 + delete from sys_post where post_id in
  117 + <foreach collection="array" item="postId" open="(" separator="," close=")">
  118 + #{postId}
  119 + </foreach>
  120 + </delete>
114 121  
115 122 </mapper>
116 123 \ No newline at end of file
... ...
ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml
... ... @@ -134,4 +134,11 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
134 134 delete from sys_role where role_id = #{roleId}
135 135 </delete>
136 136  
  137 + <delete id="deleteRoleByIds" parameterType="Long">
  138 + update sys_role set del_flag = '2' where role_id in
  139 + <foreach collection="array" item="roleId" open="(" separator="," close=")">
  140 + #{roleId}
  141 + </foreach>
  142 + </delete>
  143 +
137 144 </mapper>
138 145 \ No newline at end of file
... ...
ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml
... ... @@ -170,5 +170,12 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
170 170 <delete id="deleteUserById" parameterType="Long">
171 171 delete from sys_user where user_id = #{userId}
172 172 </delete>
  173 +
  174 + <delete id="deleteUserByIds" parameterType="Long">
  175 + update sys_user set del_flag = '2' where user_id in
  176 + <foreach collection="array" item="userId" open="(" separator="," close=")">
  177 + #{userId}
  178 + </foreach>
  179 + </delete>
173 180  
174 181 </mapper>
175 182 \ No newline at end of file
... ...