作者 RuoYi

若依 1.1

正在显示 60 个修改的文件 包含 2900 行增加202 行删除

要显示太多修改。

为保证性能只显示 60 of 60+ 个文件。

@@ -49,12 +49,12 @@ @@ -49,12 +49,12 @@
49 <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td> 49 <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
50 </tr> 50 </tr>
51 <tr> 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 </tr> 54 </tr>
55 <tr> 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 </tr> 58 </tr>
59 <tr> 59 <tr>
60 <td><img src="https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg"/></td> 60 <td><img src="https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg"/></td>
@@ -65,8 +65,8 @@ @@ -65,8 +65,8 @@
65 <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td> 65 <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
66 </tr> 66 </tr>
67 <tr> 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 </tr> 70 </tr>
71 <tr> 71 <tr>
72 <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td> 72 <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
1 { 1 {
2 "name": "ruoyi", 2 "name": "ruoyi",
3 - "version": "1.0.0", 3 + "version": "1.1.0",
4 "description": "若依管理系统", 4 "description": "若依管理系统",
5 "author": "若依", 5 "author": "若依",
6 "license": "MIT", 6 "license": "MIT",
@@ -8,3 +8,28 @@ export function list(query) { @@ -8,3 +8,28 @@ export function list(query) {
8 params: query 8 params: query
9 }) 9 })
10 } 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 + })
  35 +}
@@ -8,3 +8,28 @@ export function list(query) { @@ -8,3 +8,28 @@ export function list(query) {
8 params: query 8 params: query
9 }) 9 })
10 } 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 + })
  35 +}
@@ -50,3 +50,12 @@ export function delConfig(configId) { @@ -50,3 +50,12 @@ export function delConfig(configId) {
50 method: 'delete' 50 method: 'delete'
51 }) 51 })
52 } 52 }
  53 +
  54 +// 导出参数
  55 +export function exportConfig(query) {
  56 + return request({
  57 + url: '/system/config/export',
  58 + method: 'get',
  59 + params: query
  60 + })
  61 +}
@@ -50,3 +50,12 @@ export function delData(dictCode) { @@ -50,3 +50,12 @@ export function delData(dictCode) {
50 method: 'delete' 50 method: 'delete'
51 }) 51 })
52 } 52 }
  53 +
  54 +// 导出字典数据
  55 +export function exportData(query) {
  56 + return request({
  57 + url: '/system/dict/data/export',
  58 + method: 'get',
  59 + params: query
  60 + })
  61 +}
@@ -42,3 +42,12 @@ export function delType(dictId) { @@ -42,3 +42,12 @@ export function delType(dictId) {
42 method: 'delete' 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 +}
@@ -42,3 +42,12 @@ export function delPost(postId) { @@ -42,3 +42,12 @@ export function delPost(postId) {
42 method: 'delete' 42 method: 'delete'
43 }) 43 })
44 } 44 }
  45 +
  46 +// 导出岗位
  47 +export function exportPost(query) {
  48 + return request({
  49 + url: '/system/post/export',
  50 + method: 'get',
  51 + params: query
  52 + })
  53 +}
@@ -64,3 +64,12 @@ export function delRole(roleId) { @@ -64,3 +64,12 @@ export function delRole(roleId) {
64 method: 'delete' 64 method: 'delete'
65 }) 65 })
66 } 66 }
  67 +
  68 +// 导出角色
  69 +export function exportRole(query) {
  70 + return request({
  71 + url: '/system/role/export',
  72 + method: 'get',
  73 + params: query
  74 + })
  75 +}
@@ -43,6 +43,15 @@ export function delUser(userId) { @@ -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 export function resetUserPwd(userId, password) { 56 export function resetUserPwd(userId, password) {
48 const data = { 57 const data = {
@@ -3,6 +3,56 @@ @@ -3,6 +3,56 @@
3 * Copyright (c) 2019 ruoyi 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 .el-table .el-table__header-wrapper th { 56 .el-table .el-table__header-wrapper th {
7 word-break: break-word; 57 word-break: break-word;
8 background-color: #f8f8f9; 58 background-color: #f8f8f9;
@@ -18,7 +18,7 @@ import './assets/icons' // icon @@ -18,7 +18,7 @@ import './assets/icons' // icon
18 import './permission' // permission control 18 import './permission' // permission control
19 import { getDicts } from "@/api/system/dict/data"; 19 import { getDicts } from "@/api/system/dict/data";
20 import { getConfigKey } from "@/api/system/config"; 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 import Pagination from "@/components/Pagination"; 22 import Pagination from "@/components/Pagination";
23 23
24 // 全局方法挂载 24 // 全局方法挂载
@@ -28,6 +28,7 @@ Vue.prototype.parseTime = parseTime @@ -28,6 +28,7 @@ Vue.prototype.parseTime = parseTime
28 Vue.prototype.resetForm = resetForm 28 Vue.prototype.resetForm = resetForm
29 Vue.prototype.addDateRange = addDateRange 29 Vue.prototype.addDateRange = addDateRange
30 Vue.prototype.selectDictLabel = selectDictLabel 30 Vue.prototype.selectDictLabel = selectDictLabel
  31 +Vue.prototype.download = download
31 32
32 Vue.prototype.msgSuccess = function (msg) { 33 Vue.prototype.msgSuccess = function (msg) {
33 this.$message({ showClose: true, message: msg, type: "success" }); 34 this.$message({ showClose: true, message: msg, type: "success" });
@@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
3 * Copyright (c) 2019 ruoyi 3 * Copyright (c) 2019 ruoyi
4 */ 4 */
5 5
  6 +const baseURL = process.env.VUE_APP_BASE_API
  7 +
6 // 日期格式化 8 // 日期格式化
7 export function parseTime(time, pattern) { 9 export function parseTime(time, pattern) {
8 if (arguments.length === 0) { 10 if (arguments.length === 0) {
@@ -73,6 +75,11 @@ export function selectDictLabel(datas, value) { @@ -73,6 +75,11 @@ export function selectDictLabel(datas, value) {
73 return actions.join(''); 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 // 字符串格式化(%s ) 83 // 字符串格式化(%s )
77 export function sprintf(str) { 84 export function sprintf(str) {
78 var args = arguments, flag = true, i = 1; 85 var args = arguments, flag = true, i = 1;
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.ipaddr" 6 v-model="queryParams.ipaddr"
7 placeholder="请输入登录地址" 7 placeholder="请输入登录地址"
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 @keyup.enter.native="handleQuery" 11 @keyup.enter.native="handleQuery"
12 /> 12 />
13 </el-form-item> 13 </el-form-item>
14 - <el-form-item label="用户名称"> 14 + <el-form-item label="用户名称" prop="userName">
15 <el-input 15 <el-input
16 v-model="queryParams.userName" 16 v-model="queryParams.userName"
17 placeholder="请输入用户名称" 17 placeholder="请输入用户名称"
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 @keyup.enter.native="handleQuery" 21 @keyup.enter.native="handleQuery"
22 /> 22 />
23 </el-form-item> 23 </el-form-item>
24 - <el-form-item label="状态"> 24 + <el-form-item label="状态" prop="status">
25 <el-select 25 <el-select
26 v-model="queryParams.status" 26 v-model="queryParams.status"
27 placeholder="登录状态" 27 placeholder="登录状态"
@@ -51,10 +51,43 @@ @@ -51,10 +51,43 @@
51 </el-form-item> 51 </el-form-item>
52 <el-form-item> 52 <el-form-item>
53 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 55 </el-form-item>
55 </el-form> 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 <el-table-column label="访问编号" align="center" prop="infoId" /> 91 <el-table-column label="访问编号" align="center" prop="infoId" />
59 <el-table-column label="用户名称" align="center" prop="userName" /> 92 <el-table-column label="用户名称" align="center" prop="userName" />
60 <el-table-column label="登录地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" /> 93 <el-table-column label="登录地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" />
@@ -81,13 +114,17 @@ @@ -81,13 +114,17 @@
81 </template> 114 </template>
82 115
83 <script> 116 <script>
84 -import { list } from "@/api/monitor/logininfor"; 117 +import { list, delLogininfor, cleanLogininfor, exportLogininfor } from "@/api/monitor/logininfor";
85 118
86 export default { 119 export default {
87 data() { 120 data() {
88 return { 121 return {
89 // 遮罩层 122 // 遮罩层
90 loading: true, 123 loading: true,
  124 + // 选中数组
  125 + ids: [],
  126 + // 非多个禁用
  127 + multiple: true,
91 // 总条数 128 // 总条数
92 total: 0, 129 total: 0,
93 // 表格数据 130 // 表格数据
@@ -131,6 +168,57 @@ export default { @@ -131,6 +168,57 @@ export default {
131 handleQuery() { 168 handleQuery() {
132 this.queryParams.pageNum = 1; 169 this.queryParams.pageNum = 1;
133 this.getList(); 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 };
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.ipaddr" 6 v-model="queryParams.ipaddr"
7 placeholder="请输入登录地址" 7 placeholder="请输入登录地址"
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 @keyup.enter.native="handleQuery" 10 @keyup.enter.native="handleQuery"
11 /> 11 />
12 </el-form-item> 12 </el-form-item>
13 - <el-form-item label="用户名称"> 13 + <el-form-item label="用户名称" prop="userName">
14 <el-input 14 <el-input
15 v-model="queryParams.userName" 15 v-model="queryParams.userName"
16 placeholder="请输入用户名称" 16 placeholder="请输入用户名称"
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 </el-form-item> 21 </el-form-item>
22 <el-form-item> 22 <el-form-item>
23 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 25 </el-form-item>
25 </el-form> 26 </el-form>
26 27
@@ -102,6 +103,11 @@ export default { @@ -102,6 +103,11 @@ export default {
102 this.pageNum = 1; 103 this.pageNum = 1;
103 this.getList(); 104 this.getList();
104 }, 105 },
  106 + /** 重置按钮操作 */
  107 + resetQuery() {
  108 + this.resetForm("queryForm");
  109 + this.handleQuery();
  110 + },
105 /** 强退按钮操作 */ 111 /** 强退按钮操作 */
106 handleForceLogout(row) { 112 handleForceLogout(row) {
107 this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", { 113 this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", {
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.title" 6 v-model="queryParams.title"
7 placeholder="请输入系统模块" 7 placeholder="请输入系统模块"
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 @keyup.enter.native="handleQuery" 11 @keyup.enter.native="handleQuery"
12 /> 12 />
13 </el-form-item> 13 </el-form-item>
14 - <el-form-item label="操作人员"> 14 + <el-form-item label="操作人员" prop="operName">
15 <el-input 15 <el-input
16 v-model="queryParams.operName" 16 v-model="queryParams.operName"
17 placeholder="请输入操作人员" 17 placeholder="请输入操作人员"
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 @keyup.enter.native="handleQuery" 21 @keyup.enter.native="handleQuery"
22 /> 22 />
23 </el-form-item> 23 </el-form-item>
24 - <el-form-item label="类型"> 24 + <el-form-item label="类型" prop="businessType">
25 <el-select 25 <el-select
26 v-model="queryParams.businessType" 26 v-model="queryParams.businessType"
27 placeholder="操作类型" 27 placeholder="操作类型"
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 /> 37 />
38 </el-select> 38 </el-select>
39 </el-form-item> 39 </el-form-item>
40 - <el-form-item label="状态"> 40 + <el-form-item label="状态" prop="status">
41 <el-select 41 <el-select
42 v-model="queryParams.status" 42 v-model="queryParams.status"
43 placeholder="操作状态" 43 placeholder="操作状态"
@@ -67,10 +67,43 @@ @@ -67,10 +67,43 @@
67 </el-form-item> 67 </el-form-item>
68 <el-form-item> 68 <el-form-item>
69 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 71 </el-form-item>
71 </el-form> 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 <el-table-column label="日志编号" align="center" prop="operId" /> 107 <el-table-column label="日志编号" align="center" prop="operId" />
75 <el-table-column label="系统模块" align="center" prop="title" /> 108 <el-table-column label="系统模块" align="center" prop="title" />
76 <el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" /> 109 <el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" />
@@ -150,13 +183,17 @@ @@ -150,13 +183,17 @@
150 </template> 183 </template>
151 184
152 <script> 185 <script>
153 -import { list } from "@/api/monitor/operlog"; 186 +import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/operlog";
154 187
155 export default { 188 export default {
156 data() { 189 data() {
157 return { 190 return {
158 // 遮罩层 191 // 遮罩层
159 loading: true, 192 loading: true,
  193 + // 选中数组
  194 + ids: [],
  195 + // 非多个禁用
  196 + multiple: true,
160 // 总条数 197 // 总条数
161 total: 0, 198 total: 0,
162 // 表格数据 199 // 表格数据
@@ -215,10 +252,61 @@ export default { @@ -215,10 +252,61 @@ export default {
215 this.queryParams.pageNum = 1; 252 this.queryParams.pageNum = 1;
216 this.getList(); 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 handleView(row) { 267 handleView(row) {
220 this.open = true; 268 this.open = true;
221 this.form = row; 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 };
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.configName" 6 v-model="queryParams.configName"
7 placeholder="请输入参数名称" 7 placeholder="请输入参数名称"
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 @keyup.enter.native="handleQuery" 11 @keyup.enter.native="handleQuery"
12 /> 12 />
13 </el-form-item> 13 </el-form-item>
14 - <el-form-item label="参数键名"> 14 + <el-form-item label="参数键名" prop="configKey">
15 <el-input 15 <el-input
16 v-model="queryParams.configKey" 16 v-model="queryParams.configKey"
17 placeholder="请输入参数键名" 17 placeholder="请输入参数键名"
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 @keyup.enter.native="handleQuery" 21 @keyup.enter.native="handleQuery"
22 /> 22 />
23 </el-form-item> 23 </el-form-item>
24 - <el-form-item label="系统内置"> 24 + <el-form-item label="系统内置" prop="configType">
25 <el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small"> 25 <el-select v-model="queryParams.configType" placeholder="系统内置" clearable size="small">
26 <el-option 26 <el-option
27 v-for="dict in typeOptions" 27 v-for="dict in typeOptions"
@@ -45,11 +45,53 @@ @@ -45,11 +45,53 @@
45 </el-form-item> 45 </el-form-item>
46 <el-form-item> 46 <el-form-item>
47 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 49 </el-form-item>
50 </el-form> 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 <el-table-column label="参数主键" align="center" prop="configId" /> 95 <el-table-column label="参数主键" align="center" prop="configId" />
54 <el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" /> 96 <el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
55 <el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" /> 97 <el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
@@ -123,13 +165,19 @@ @@ -123,13 +165,19 @@
123 </template> 165 </template>
124 166
125 <script> 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 export default { 170 export default {
129 data() { 171 data() {
130 return { 172 return {
131 // 遮罩层 173 // 遮罩层
132 loading: true, 174 loading: true,
  175 + // 选中数组
  176 + ids: [],
  177 + // 非单个禁用
  178 + single: true,
  179 + // 非多个禁用
  180 + multiple: true,
133 // 总条数 181 // 总条数
134 total: 0, 182 total: 0,
135 // 参数表格数据 183 // 参数表格数据
@@ -209,16 +257,29 @@ export default { @@ -209,16 +257,29 @@ export default {
209 this.queryParams.pageNum = 1; 257 this.queryParams.pageNum = 1;
210 this.getList(); 258 this.getList();
211 }, 259 },
  260 + /** 重置按钮操作 */
  261 + resetQuery() {
  262 + this.dateRange = [];
  263 + this.resetForm("queryForm");
  264 + this.handleQuery();
  265 + },
212 /** 新增按钮操作 */ 266 /** 新增按钮操作 */
213 handleAdd() { 267 handleAdd() {
214 this.reset(); 268 this.reset();
215 this.open = true; 269 this.open = true;
216 this.title = "添加参数"; 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 handleUpdate(row) { 279 handleUpdate(row) {
220 this.reset(); 280 this.reset();
221 - getConfig(row.configId).then(response => { 281 + const configId = row.configId || this.ids
  282 + getConfig(configId).then(response => {
222 this.form = response.data; 283 this.form = response.data;
223 this.open = true; 284 this.open = true;
224 this.title = "修改参数"; 285 this.title = "修改参数";
@@ -254,16 +315,30 @@ export default { @@ -254,16 +315,30 @@ export default {
254 }, 315 },
255 /** 删除按钮操作 */ 316 /** 删除按钮操作 */
256 handleDelete(row) { 317 handleDelete(row) {
257 - this.$confirm('是否确认删除名称为"' + row.configName + '"的数据项?', "警告", { 318 + const configIds = row.configId || this.ids;
  319 + this.$confirm('是否确认删除参数编号为"' + configIds + '"的数据项?', "警告", {
258 confirmButtonText: "确定", 320 confirmButtonText: "确定",
259 cancelButtonText: "取消", 321 cancelButtonText: "取消",
260 type: "warning" 322 type: "warning"
261 }).then(function() { 323 }).then(function() {
262 - return delConfig(row.configId); 324 + return delConfig(configIds);
263 }).then(() => { 325 }).then(() => {
264 this.getList(); 326 this.getList();
265 this.msgSuccess("删除成功"); 327 this.msgSuccess("删除成功");
266 }).catch(function() {}); 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 };
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-select v-model="queryParams.dictType" size="small"> 5 <el-select v-model="queryParams.dictType" size="small">
6 <el-option 6 <el-option
7 v-for="item in typeOptions" 7 v-for="item in typeOptions"
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 /> 11 />
12 </el-select> 12 </el-select>
13 </el-form-item> 13 </el-form-item>
14 - <el-form-item label="字典标签"> 14 + <el-form-item label="字典标签" prop="dictLabel">
15 <el-input 15 <el-input
16 v-model="queryParams.dictLabel" 16 v-model="queryParams.dictLabel"
17 placeholder="请输入字典标签" 17 placeholder="请输入字典标签"
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 @keyup.enter.native="handleQuery" 20 @keyup.enter.native="handleQuery"
21 /> 21 />
22 </el-form-item> 22 </el-form-item>
23 - <el-form-item label="状态"> 23 + <el-form-item label="状态" prop="status">
24 <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small"> 24 <el-select v-model="queryParams.status" placeholder="数据状态" clearable size="small">
25 <el-option 25 <el-option
26 v-for="dict in statusOptions" 26 v-for="dict in statusOptions"
@@ -32,11 +32,53 @@ @@ -32,11 +32,53 @@
32 </el-form-item> 32 </el-form-item>
33 <el-form-item> 33 <el-form-item>
34 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 36 </el-form-item>
37 </el-form> 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 <el-table-column label="字典编码" align="center" prop="dictCode" /> 82 <el-table-column label="字典编码" align="center" prop="dictCode" />
41 <el-table-column label="字典标签" align="center" prop="dictLabel" /> 83 <el-table-column label="字典标签" align="center" prop="dictLabel" />
42 <el-table-column label="字典键值" align="center" prop="dictValue" /> 84 <el-table-column label="字典键值" align="center" prop="dictValue" />
@@ -113,7 +155,7 @@ @@ -113,7 +155,7 @@
113 </template> 155 </template>
114 156
115 <script> 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 import { listType, getType } from "@/api/system/dict/type"; 159 import { listType, getType } from "@/api/system/dict/type";
118 160
119 export default { 161 export default {
@@ -121,10 +163,18 @@ export default { @@ -121,10 +163,18 @@ export default {
121 return { 163 return {
122 // 遮罩层 164 // 遮罩层
123 loading: true, 165 loading: true,
  166 + // 选中数组
  167 + ids: [],
  168 + // 非单个禁用
  169 + single: true,
  170 + // 非多个禁用
  171 + multiple: true,
124 // 总条数 172 // 总条数
125 total: 0, 173 total: 0,
126 // 字典表格数据 174 // 字典表格数据
127 dataList: [], 175 dataList: [],
  176 + // 默认字典类型
  177 + defaultDictType: "",
128 // 弹出层标题 178 // 弹出层标题
129 title: "", 179 title: "",
130 // 是否显示弹出层 180 // 是否显示弹出层
@@ -170,6 +220,7 @@ export default { @@ -170,6 +220,7 @@ export default {
170 getType(dictId) { 220 getType(dictId) {
171 getType(dictId).then(response => { 221 getType(dictId).then(response => {
172 this.queryParams.dictType = response.data.dictType; 222 this.queryParams.dictType = response.data.dictType;
  223 + this.defaultDictType = response.data.dictType;
173 this.getList(); 224 this.getList();
174 }); 225 });
175 }, 226 },
@@ -214,6 +265,12 @@ export default { @@ -214,6 +265,12 @@ export default {
214 this.queryParams.pageNum = 1; 265 this.queryParams.pageNum = 1;
215 this.getList(); 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 handleAdd() { 275 handleAdd() {
219 this.reset(); 276 this.reset();
@@ -221,10 +278,17 @@ export default { @@ -221,10 +278,17 @@ export default {
221 this.title = "添加字典数据"; 278 this.title = "添加字典数据";
222 this.form.dictType = this.queryParams.dictType; 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 handleUpdate(row) { 288 handleUpdate(row) {
226 this.reset(); 289 this.reset();
227 - getData(row.dictCode).then(response => { 290 + const dictCode = row.dictCode || this.ids
  291 + getData(dictCode).then(response => {
228 this.form = response.data; 292 this.form = response.data;
229 this.open = true; 293 this.open = true;
230 this.title = "修改字典数据"; 294 this.title = "修改字典数据";
@@ -260,16 +324,30 @@ export default { @@ -260,16 +324,30 @@ export default {
260 }, 324 },
261 /** 删除按钮操作 */ 325 /** 删除按钮操作 */
262 handleDelete(row) { 326 handleDelete(row) {
263 - this.$confirm('是否确认删除名称为"' + row.dictLabel + '"的数据项?', "警告", { 327 + const dictCodes = row.dictCode || this.ids;
  328 + this.$confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?', "警告", {
264 confirmButtonText: "确定", 329 confirmButtonText: "确定",
265 cancelButtonText: "取消", 330 cancelButtonText: "取消",
266 type: "warning" 331 type: "warning"
267 }).then(function() { 332 }).then(function() {
268 - return delData(row.dictCode); 333 + return delData(dictCodes);
269 }).then(() => { 334 }).then(() => {
270 this.getList(); 335 this.getList();
271 this.msgSuccess("删除成功"); 336 this.msgSuccess("删除成功");
272 }).catch(function() {}); 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 };
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.dictName" 6 v-model="queryParams.dictName"
7 placeholder="请输入字典名称" 7 placeholder="请输入字典名称"
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 @keyup.enter.native="handleQuery" 11 @keyup.enter.native="handleQuery"
12 /> 12 />
13 </el-form-item> 13 </el-form-item>
14 - <el-form-item label="字典类型"> 14 + <el-form-item label="字典类型" prop="dictType">
15 <el-input 15 <el-input
16 v-model="queryParams.dictType" 16 v-model="queryParams.dictType"
17 placeholder="请输入字典类型" 17 placeholder="请输入字典类型"
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 @keyup.enter.native="handleQuery" 21 @keyup.enter.native="handleQuery"
22 /> 22 />
23 </el-form-item> 23 </el-form-item>
24 - <el-form-item label="状态"> 24 + <el-form-item label="状态" prop="status">
25 <el-select 25 <el-select
26 v-model="queryParams.status" 26 v-model="queryParams.status"
27 placeholder="字典状态" 27 placeholder="字典状态"
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 </el-form-item> 39 </el-form-item>
40 <el-form-item label="创建时间"> 40 <el-form-item label="创建时间">
41 <el-date-picker 41 <el-date-picker
42 - v-model="queryParams.createTime" 42 + v-model="dateRange"
43 size="small" 43 size="small"
44 style="width: 240px" 44 style="width: 240px"
45 value-format="yyyy-MM-dd" 45 value-format="yyyy-MM-dd"
@@ -51,14 +51,56 @@ @@ -51,14 +51,56 @@
51 </el-form-item> 51 </el-form-item>
52 <el-form-item> 52 <el-form-item>
53 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 55 </el-form-item>
56 </el-form> 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 <el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" /> 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 <template slot-scope="scope"> 104 <template slot-scope="scope">
63 <router-link :to="'/dict/type/data/' + scope.row.dictId" class="link-type"> 105 <router-link :to="'/dict/type/data/' + scope.row.dictId" class="link-type">
64 <span>{{ scope.row.dictType }}</span> 106 <span>{{ scope.row.dictType }}</span>
@@ -131,13 +173,19 @@ @@ -131,13 +173,19 @@
131 </template> 173 </template>
132 174
133 <script> 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 export default { 178 export default {
137 data() { 179 data() {
138 return { 180 return {
139 // 遮罩层 181 // 遮罩层
140 loading: true, 182 loading: true,
  183 + // 选中数组
  184 + ids: [],
  185 + // 非单个禁用
  186 + single: true,
  187 + // 非多个禁用
  188 + multiple: true,
141 // 总条数 189 // 总条数
142 total: 0, 190 total: 0,
143 // 字典表格数据 191 // 字典表格数据
@@ -181,8 +229,7 @@ export default { @@ -181,8 +229,7 @@ export default {
181 /** 查询字典类型列表 */ 229 /** 查询字典类型列表 */
182 getList() { 230 getList() {
183 this.loading = true; 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 this.typeList = response.rows; 233 this.typeList = response.rows;
187 this.total = response.total; 234 this.total = response.total;
188 this.loading = false; 235 this.loading = false;
@@ -214,16 +261,29 @@ export default { @@ -214,16 +261,29 @@ export default {
214 this.queryParams.pageNum = 1; 261 this.queryParams.pageNum = 1;
215 this.getList(); 262 this.getList();
216 }, 263 },
  264 + /** 重置按钮操作 */
  265 + resetQuery() {
  266 + this.dateRange = [];
  267 + this.resetForm("queryForm");
  268 + this.handleQuery();
  269 + },
217 /** 新增按钮操作 */ 270 /** 新增按钮操作 */
218 handleAdd() { 271 handleAdd() {
219 this.reset(); 272 this.reset();
220 this.open = true; 273 this.open = true;
221 this.title = "添加字典类型"; 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 handleUpdate(row) { 283 handleUpdate(row) {
225 this.reset(); 284 this.reset();
226 - getType(row.dictId).then(response => { 285 + const dictId = row.dictId || this.ids
  286 + getType(dictId).then(response => {
227 this.form = response.data; 287 this.form = response.data;
228 this.open = true; 288 this.open = true;
229 this.title = "修改字典类型"; 289 this.title = "修改字典类型";
@@ -259,16 +319,30 @@ export default { @@ -259,16 +319,30 @@ export default {
259 }, 319 },
260 /** 删除按钮操作 */ 320 /** 删除按钮操作 */
261 handleDelete(row) { 321 handleDelete(row) {
262 - this.$confirm('是否确认删除名称为"' + row.dictName + '"的数据项?', "警告", { 322 + const dictIds = row.dictId || this.ids;
  323 + this.$confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?', "警告", {
263 confirmButtonText: "确定", 324 confirmButtonText: "确定",
264 cancelButtonText: "取消", 325 cancelButtonText: "取消",
265 type: "warning" 326 type: "warning"
266 }).then(function() { 327 }).then(function() {
267 - return delType(row.dictId); 328 + return delType(dictIds);
268 }).then(() => { 329 }).then(() => {
269 this.getList(); 330 this.getList();
270 this.msgSuccess("删除成功"); 331 this.msgSuccess("删除成功");
271 }).catch(function() {}); 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 };
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.noticeTitle" 6 v-model="queryParams.noticeTitle"
7 placeholder="请输入公告标题" 7 placeholder="请输入公告标题"
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 @keyup.enter.native="handleQuery" 10 @keyup.enter.native="handleQuery"
11 /> 11 />
12 </el-form-item> 12 </el-form-item>
13 - <el-form-item label="操作人员"> 13 + <el-form-item label="操作人员" prop="createBy">
14 <el-input 14 <el-input
15 v-model="queryParams.createBy" 15 v-model="queryParams.createBy"
16 placeholder="请输入操作人员" 16 placeholder="请输入操作人员"
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 @keyup.enter.native="handleQuery" 19 @keyup.enter.native="handleQuery"
20 /> 20 />
21 </el-form-item> 21 </el-form-item>
22 - <el-form-item label="类型"> 22 + <el-form-item label="类型" prop="noticeType">
23 <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small"> 23 <el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable size="small">
24 <el-option 24 <el-option
25 v-for="dict in typeOptions" 25 v-for="dict in typeOptions"
@@ -31,11 +31,44 @@ @@ -31,11 +31,44 @@
31 </el-form-item> 31 </el-form-item>
32 <el-form-item> 32 <el-form-item>
33 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 35 </el-form-item>
36 </el-form> 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 <el-table-column label="序号" align="center" prop="noticeId" width="100" /> 72 <el-table-column label="序号" align="center" prop="noticeId" width="100" />
40 <el-table-column 73 <el-table-column
41 label="公告标题" 74 label="公告标题"
@@ -125,7 +158,7 @@ @@ -125,7 +158,7 @@
125 </el-col> 158 </el-col>
126 <el-col :span="24"> 159 <el-col :span="24">
127 <el-form-item label="内容"> 160 <el-form-item label="内容">
128 - <Editor v-model="form.noticeContent"/> 161 + <Editor v-model="form.noticeContent" />
129 </el-form-item> 162 </el-form-item>
130 </el-col> 163 </el-col>
131 </el-row> 164 </el-row>
@@ -139,7 +172,7 @@ @@ -139,7 +172,7 @@
139 </template> 172 </template>
140 173
141 <script> 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 import Editor from '@/components/Editor'; 176 import Editor from '@/components/Editor';
144 177
145 export default { 178 export default {
@@ -150,6 +183,12 @@ export default { @@ -150,6 +183,12 @@ export default {
150 return { 183 return {
151 // 遮罩层 184 // 遮罩层
152 loading: true, 185 loading: true,
  186 + // 选中数组
  187 + ids: [],
  188 + // 非单个禁用
  189 + single: true,
  190 + // 非多个禁用
  191 + multiple: true,
153 // 总条数 192 // 总条数
154 total: 0, 193 total: 0,
155 // 公告表格数据 194 // 公告表格数据
@@ -231,6 +270,17 @@ export default { @@ -231,6 +270,17 @@ export default {
231 this.queryParams.pageNum = 1; 270 this.queryParams.pageNum = 1;
232 this.getList(); 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 handleAdd() { 285 handleAdd() {
236 this.reset(); 286 this.reset();
@@ -240,7 +290,8 @@ export default { @@ -240,7 +290,8 @@ export default {
240 /** 修改按钮操作 */ 290 /** 修改按钮操作 */
241 handleUpdate(row) { 291 handleUpdate(row) {
242 this.reset(); 292 this.reset();
243 - getNotice(row.noticeId).then(response => { 293 + const noticeId = row.noticeId || this.ids
  294 + getNotice(noticeId).then(response => {
244 this.form = response.data; 295 this.form = response.data;
245 this.open = true; 296 this.open = true;
246 this.title = "修改公告"; 297 this.title = "修改公告";
@@ -276,12 +327,13 @@ export default { @@ -276,12 +327,13 @@ export default {
276 }, 327 },
277 /** 删除按钮操作 */ 328 /** 删除按钮操作 */
278 handleDelete(row) { 329 handleDelete(row) {
279 - this.$confirm('是否确认删除公告标题为"' + row.noticeTitle + '"的数据项?', "警告", { 330 + const noticeIds = row.noticeId || this.ids
  331 + this.$confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?', "警告", {
280 confirmButtonText: "确定", 332 confirmButtonText: "确定",
281 cancelButtonText: "取消", 333 cancelButtonText: "取消",
282 type: "warning" 334 type: "warning"
283 }).then(function() { 335 }).then(function() {
284 - return delNotice(row.noticeId); 336 + return delNotice(noticeIds);
285 }).then(() => { 337 }).then(() => {
286 this.getList(); 338 this.getList();
287 this.msgSuccess("删除成功"); 339 this.msgSuccess("删除成功");
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.postCode" 6 v-model="queryParams.postCode"
7 placeholder="请输入岗位编码" 7 placeholder="请输入岗位编码"
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 @keyup.enter.native="handleQuery" 10 @keyup.enter.native="handleQuery"
11 /> 11 />
12 </el-form-item> 12 </el-form-item>
13 - <el-form-item label="岗位名称"> 13 + <el-form-item label="岗位名称" prop="postName">
14 <el-input 14 <el-input
15 v-model="queryParams.postName" 15 v-model="queryParams.postName"
16 placeholder="请输入岗位名称" 16 placeholder="请输入岗位名称"
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 @keyup.enter.native="handleQuery" 19 @keyup.enter.native="handleQuery"
20 /> 20 />
21 </el-form-item> 21 </el-form-item>
22 - <el-form-item label="状态"> 22 + <el-form-item label="状态" prop="status">
23 <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small"> 23 <el-select v-model="queryParams.status" placeholder="岗位状态" clearable size="small">
24 <el-option 24 <el-option
25 v-for="dict in statusOptions" 25 v-for="dict in statusOptions"
@@ -31,11 +31,53 @@ @@ -31,11 +31,53 @@
31 </el-form-item> 31 </el-form-item>
32 <el-form-item> 32 <el-form-item>
33 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 35 </el-form-item>
36 </el-form> 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 <el-table-column label="岗位编号" align="center" prop="postId" /> 81 <el-table-column label="岗位编号" align="center" prop="postId" />
40 <el-table-column label="岗位编码" align="center" prop="postCode" /> 82 <el-table-column label="岗位编码" align="center" prop="postCode" />
41 <el-table-column label="岗位名称" align="center" prop="postName" /> 83 <el-table-column label="岗位名称" align="center" prop="postName" />
@@ -108,13 +150,19 @@ @@ -108,13 +150,19 @@
108 </template> 150 </template>
109 151
110 <script> 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 export default { 155 export default {
114 data() { 156 data() {
115 return { 157 return {
116 // 遮罩层 158 // 遮罩层
117 loading: true, 159 loading: true,
  160 + // 选中数组
  161 + ids: [],
  162 + // 非单个禁用
  163 + single: true,
  164 + // 非多个禁用
  165 + multiple: true,
118 // 总条数 166 // 总条数
119 total: 0, 167 total: 0,
120 // 岗位表格数据 168 // 岗位表格数据
@@ -191,6 +239,17 @@ export default { @@ -191,6 +239,17 @@ export default {
191 this.queryParams.pageNum = 1; 239 this.queryParams.pageNum = 1;
192 this.getList(); 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 handleAdd() { 254 handleAdd() {
196 this.reset(); 255 this.reset();
@@ -200,7 +259,8 @@ export default { @@ -200,7 +259,8 @@ export default {
200 /** 修改按钮操作 */ 259 /** 修改按钮操作 */
201 handleUpdate(row) { 260 handleUpdate(row) {
202 this.reset(); 261 this.reset();
203 - getPost(row.postId).then(response => { 262 + const postId = row.postId || this.ids
  263 + getPost(postId).then(response => {
204 this.form = response.data; 264 this.form = response.data;
205 this.open = true; 265 this.open = true;
206 this.title = "修改岗位"; 266 this.title = "修改岗位";
@@ -236,16 +296,30 @@ export default { @@ -236,16 +296,30 @@ export default {
236 }, 296 },
237 /** 删除按钮操作 */ 297 /** 删除按钮操作 */
238 handleDelete(row) { 298 handleDelete(row) {
239 - this.$confirm('是否确认删除岗位名称为"' + row.postName + '"的数据项?', "警告", { 299 + const postIds = row.postId || this.ids;
  300 + this.$confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?', "警告", {
240 confirmButtonText: "确定", 301 confirmButtonText: "确定",
241 cancelButtonText: "取消", 302 cancelButtonText: "取消",
242 type: "warning" 303 type: "warning"
243 }).then(function() { 304 }).then(function() {
244 - return delPost(row.postId); 305 + return delPost(postIds);
245 }).then(() => { 306 }).then(() => {
246 this.getList(); 307 this.getList();
247 this.msgSuccess("删除成功"); 308 this.msgSuccess("删除成功");
248 }).catch(function() {}); 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 };
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-input 5 <el-input
6 v-model="queryParams.roleName" 6 v-model="queryParams.roleName"
7 placeholder="请输入角色名称" 7 placeholder="请输入角色名称"
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 @keyup.enter.native="handleQuery" 11 @keyup.enter.native="handleQuery"
12 /> 12 />
13 </el-form-item> 13 </el-form-item>
14 - <el-form-item label="权限字符"> 14 + <el-form-item label="权限字符" prop="roleKey">
15 <el-input 15 <el-input
16 v-model="queryParams.roleKey" 16 v-model="queryParams.roleKey"
17 placeholder="请输入权限字符" 17 placeholder="请输入权限字符"
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 @keyup.enter.native="handleQuery" 21 @keyup.enter.native="handleQuery"
22 /> 22 />
23 </el-form-item> 23 </el-form-item>
24 - <el-form-item label="状态"> 24 + <el-form-item label="状态" prop="status">
25 <el-select 25 <el-select
26 v-model="queryParams.status" 26 v-model="queryParams.status"
27 placeholder="角色状态" 27 placeholder="角色状态"
@@ -51,6 +51,12 @@ @@ -51,6 +51,12 @@
51 </el-form-item> 51 </el-form-item>
52 <el-form-item> 52 <el-form-item>
53 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 <el-button 60 <el-button
55 type="primary" 61 type="primary"
56 icon="el-icon-plus" 62 icon="el-icon-plus"
@@ -58,15 +64,45 @@ @@ -58,15 +64,45 @@
58 @click="handleAdd" 64 @click="handleAdd"
59 v-hasPermi="['system:role:add']" 65 v-hasPermi="['system:role:add']"
60 >新增</el-button> 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 <el-table-column label="角色编号" prop="roleId" width="120" /> 101 <el-table-column label="角色编号" prop="roleId" width="120" />
66 <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" /> 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 <template slot-scope="scope"> 106 <template slot-scope="scope">
71 <el-switch 107 <el-switch
72 v-model="scope.row.status" 108 v-model="scope.row.status"
@@ -197,7 +233,7 @@ @@ -197,7 +233,7 @@
197 </template> 233 </template>
198 234
199 <script> 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 import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu"; 237 import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
202 import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept"; 238 import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
203 239
@@ -206,6 +242,12 @@ export default { @@ -206,6 +242,12 @@ export default {
206 return { 242 return {
207 // 遮罩层 243 // 遮罩层
208 loading: true, 244 loading: true,
  245 + // 选中数组
  246 + ids: [],
  247 + // 非单个禁用
  248 + single: true,
  249 + // 非多个禁用
  250 + multiple: true,
209 // 总条数 251 // 总条数
210 total: 0, 252 total: 0,
211 // 角色表格数据 253 // 角色表格数据
@@ -384,6 +426,18 @@ export default { @@ -384,6 +426,18 @@ export default {
384 this.queryParams.pageNum = 1; 426 this.queryParams.pageNum = 1;
385 this.getList(); 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 handleAdd() { 442 handleAdd() {
389 this.reset(); 443 this.reset();
@@ -394,10 +448,11 @@ export default { @@ -394,10 +448,11 @@ export default {
394 /** 修改按钮操作 */ 448 /** 修改按钮操作 */
395 handleUpdate(row) { 449 handleUpdate(row) {
396 this.reset(); 450 this.reset();
  451 + const roleId = row.roleId || this.ids
397 this.$nextTick(() => { 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 this.form = response.data; 456 this.form = response.data;
402 this.open = true; 457 this.open = true;
403 this.title = "修改角色"; 458 this.title = "修改角色";
@@ -462,16 +517,30 @@ export default { @@ -462,16 +517,30 @@ export default {
462 }, 517 },
463 /** 删除按钮操作 */ 518 /** 删除按钮操作 */
464 handleDelete(row) { 519 handleDelete(row) {
465 - this.$confirm('是否确认删除名称为"' + row.roleName + '"的数据项?', "警告", { 520 + const roleIds = row.roleId || this.ids;
  521 + this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', "警告", {
466 confirmButtonText: "确定", 522 confirmButtonText: "确定",
467 cancelButtonText: "取消", 523 cancelButtonText: "取消",
468 type: "warning" 524 type: "warning"
469 }).then(function() { 525 }).then(function() {
470 - return delRole(row.roleId); 526 + return delRole(roleIds);
471 }).then(() => { 527 }).then(() => {
472 this.getList(); 528 this.getList();
473 this.msgSuccess("删除成功"); 529 this.msgSuccess("删除成功");
474 }).catch(function() {}); 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 };
@@ -27,8 +27,8 @@ @@ -27,8 +27,8 @@
27 </el-col> 27 </el-col>
28 <!--用户数据--> 28 <!--用户数据-->
29 <el-col :span="20" :xs="24"> 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 <el-input 32 <el-input
33 v-model="queryParams.userName" 33 v-model="queryParams.userName"
34 placeholder="请输入用户名称" 34 placeholder="请输入用户名称"
@@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
38 @keyup.enter.native="handleQuery" 38 @keyup.enter.native="handleQuery"
39 /> 39 />
40 </el-form-item> 40 </el-form-item>
41 - <el-form-item label="手机号码"> 41 + <el-form-item label="手机号码" prop="phonenumber">
42 <el-input 42 <el-input
43 v-model="queryParams.phonenumber" 43 v-model="queryParams.phonenumber"
44 placeholder="请输入手机号码" 44 placeholder="请输入手机号码"
@@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
48 @keyup.enter.native="handleQuery" 48 @keyup.enter.native="handleQuery"
49 /> 49 />
50 </el-form-item> 50 </el-form-item>
51 - <el-form-item label="状态"> 51 + <el-form-item label="状态" prop="status">
52 <el-select 52 <el-select
53 v-model="queryParams.status" 53 v-model="queryParams.status"
54 placeholder="用户状态" 54 placeholder="用户状态"
@@ -78,11 +78,53 @@ @@ -78,11 +78,53 @@
78 </el-form-item> 78 </el-form-item>
79 <el-form-item> 79 <el-form-item>
80 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> 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 </el-form-item> 82 </el-form-item>
83 </el-form> 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 <el-table-column label="用户编号" align="center" prop="userId" /> 128 <el-table-column label="用户编号" align="center" prop="userId" />
87 <el-table-column label="用户名称" align="center" prop="userName" /> 129 <el-table-column label="用户名称" align="center" prop="userName" />
88 <el-table-column label="用户昵称" align="center" prop="nickName" /> 130 <el-table-column label="用户昵称" align="center" prop="nickName" />
@@ -246,7 +288,7 @@ @@ -246,7 +288,7 @@
246 </template> 288 </template>
247 289
248 <script> 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 import { treeselect } from "@/api/system/dept"; 292 import { treeselect } from "@/api/system/dept";
251 import { listPost } from "@/api/system/post"; 293 import { listPost } from "@/api/system/post";
252 import { listRole } from "@/api/system/role"; 294 import { listRole } from "@/api/system/role";
@@ -259,6 +301,12 @@ export default { @@ -259,6 +301,12 @@ export default {
259 return { 301 return {
260 // 遮罩层 302 // 遮罩层
261 loading: true, 303 loading: true,
  304 + // 选中数组
  305 + ids: [],
  306 + // 非单个禁用
  307 + single: true,
  308 + // 非多个禁用
  309 + multiple: true,
262 // 总条数 310 // 总条数
263 total: 0, 311 total: 0,
264 // 用户表格数据 312 // 用户表格数据
@@ -430,6 +478,18 @@ export default { @@ -430,6 +478,18 @@ export default {
430 this.queryParams.page = 1; 478 this.queryParams.page = 1;
431 this.getList(); 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 handleAdd() { 494 handleAdd() {
435 this.reset(); 495 this.reset();
@@ -446,7 +506,8 @@ export default { @@ -446,7 +506,8 @@ export default {
446 this.getTreeselect(); 506 this.getTreeselect();
447 this.getPosts(); 507 this.getPosts();
448 this.getRoles(); 508 this.getRoles();
449 - getUser(row.userId).then(response => { 509 + const userId = row.userId || this.ids
  510 + getUser(userId).then(response => {
450 this.form = response.data; 511 this.form = response.data;
451 this.form.postIds = response.postIds; 512 this.form.postIds = response.postIds;
452 this.form.roleIds = response.roleIds; 513 this.form.roleIds = response.roleIds;
@@ -500,16 +561,30 @@ export default { @@ -500,16 +561,30 @@ export default {
500 }, 561 },
501 /** 删除按钮操作 */ 562 /** 删除按钮操作 */
502 handleDelete(row) { 563 handleDelete(row) {
503 - this.$confirm('是否确认删除名称为"' + row.userName + '"的数据项?', "警告", { 564 + const userIds = row.userId || this.ids;
  565 + this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", {
504 confirmButtonText: "确定", 566 confirmButtonText: "确定",
505 cancelButtonText: "取消", 567 cancelButtonText: "取消",
506 type: "warning" 568 type: "warning"
507 }).then(function() { 569 }).then(function() {
508 - return delUser(row.userId); 570 + return delUser(userIds);
509 }).then(() => { 571 }).then(() => {
510 this.getList(); 572 this.getList();
511 this.msgSuccess("删除成功"); 573 this.msgSuccess("删除成功");
512 }).catch(function() {}); 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 };
@@ -17,7 +17,7 @@ module.exports = { @@ -17,7 +17,7 @@ module.exports = {
17 // 部署生产环境和开发环境下的URL。 17 // 部署生产环境和开发环境下的URL。
18 // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 18 // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
19 // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 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 // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist) 21 // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
22 outputDir: 'dist', 22 outputDir: 'dist',
23 // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下) 23 // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 5
6 <groupId>com.ruoyi</groupId> 6 <groupId>com.ruoyi</groupId>
7 <artifactId>ruoyi</artifactId> 7 <artifactId>ruoyi</artifactId>
8 - <version>1.0</version> 8 + <version>1.1</version>
9 <packaging>jar</packaging> 9 <packaging>jar</packaging>
10 10
11 <name>ruoyi</name> 11 <name>ruoyi</name>
@@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
32 <bitwalker.version>1.19</bitwalker.version> 32 <bitwalker.version>1.19</bitwalker.version>
33 <jwt.version>0.9.0</jwt.version> 33 <jwt.version>0.9.0</jwt.version>
34 <swagger.version>2.9.2</swagger.version> 34 <swagger.version>2.9.2</swagger.version>
  35 + <poi.version>3.17</poi.version>
35 <oshi.version>3.9.1</oshi.version> 36 <oshi.version>3.9.1</oshi.version>
36 </properties> 37 </properties>
37 38
@@ -224,6 +225,13 @@ @@ -224,6 +225,13 @@
224 <artifactId>jna-platform</artifactId> 225 <artifactId>jna-platform</artifactId>
225 </dependency> 226 </dependency>
226 227
  228 + <!-- excel工具 -->
  229 + <dependency>
  230 + <groupId>org.apache.poi</groupId>
  231 + <artifactId>poi-ooxml</artifactId>
  232 + <version>${poi.version}</version>
  233 + </dependency>
  234 +
227 </dependencies> 235 </dependencies>
228 236
229 <build> 237 <build>
@@ -136,7 +136,7 @@ create table sys_menu ( @@ -136,7 +136,7 @@ create table sys_menu (
136 path varchar(200) default '' comment '路由地址', 136 path varchar(200) default '' comment '路由地址',
137 component varchar(255) default null comment '组件路径', 137 component varchar(255) default null comment '组件路径',
138 is_frame int(1) default 1 comment '是否为外链(0是 1否)', 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 visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', 140 visible char(1) default 0 comment '菜单状态(0显示 1隐藏)',
141 perms varchar(100) default null comment '权限标识', 141 perms varchar(100) default null comment '权限标识',
142 icon varchar(100) default '#' comment '菜单图标', 142 icon varchar(100) default '#' comment '菜单图标',
@@ -155,7 +155,7 @@ create table sys_menu ( @@ -155,7 +155,7 @@ create table sys_menu (
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', '系统管理目录'); 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', '系统监控目录'); 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', '系统工具目录'); 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', '若依官网'); 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 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', '用户管理菜单'); 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 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', '角色管理菜单'); 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,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 drop table if exists sys_job; 555 drop table if exists sys_job;
576 create table sys_job ( 556 create table sys_job (
@@ -596,7 +576,7 @@ insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryM @@ -596,7 +576,7 @@ insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryM
596 576
597 577
598 -- ---------------------------- 578 -- ----------------------------
599 --- 17、定时任务调度日志表 579 +-- 16、定时任务调度日志表
600 -- ---------------------------- 580 -- ----------------------------
601 drop table if exists sys_job_log; 581 drop table if exists sys_job_log;
602 create table sys_job_log ( 582 create table sys_job_log (
@@ -613,7 +593,7 @@ 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 drop table if exists sys_notice; 598 drop table if exists sys_notice;
619 create table sys_notice ( 599 create table sys_notice (
@@ -638,7 +618,7 @@ insert into sys_notice values('2', '维护通知:2018-07-01 若依系统凌晨 @@ -638,7 +618,7 @@ insert into sys_notice values('2', '维护通知:2018-07-01 若依系统凌晨
638 618
639 619
640 -- ---------------------------- 620 -- ----------------------------
641 --- 19、代码生成业务表 621 +-- 18、代码生成业务表
642 -- ---------------------------- 622 -- ----------------------------
643 drop table if exists gen_table; 623 drop table if exists gen_table;
644 create table gen_table ( 624 create table gen_table (
@@ -663,7 +643,7 @@ 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 drop table if exists gen_table_column; 648 drop table if exists gen_table_column;
669 create table gen_table_column ( 649 create table gen_table_column (
  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 +}
  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 +}
  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 +}
  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 +}
@@ -98,6 +98,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter @@ -98,6 +98,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
98 "/**/*.js" 98 "/**/*.js"
99 ).permitAll() 99 ).permitAll()
100 .antMatchers("/profile/**").anonymous() 100 .antMatchers("/profile/**").anonymous()
  101 + .antMatchers("/common/download**").anonymous()
101 .antMatchers("/swagger-ui.html").anonymous() 102 .antMatchers("/swagger-ui.html").anonymous()
102 .antMatchers("/swagger-resources/**").anonymous() 103 .antMatchers("/swagger-resources/**").anonymous()
103 .antMatchers("/webjars/**").anonymous() 104 .antMatchers("/webjars/**").anonymous()
1 package com.ruoyi.framework.config; 1 package com.ruoyi.framework.config;
2 2
  3 +import java.util.ArrayList;
  4 +import java.util.List;
3 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration; 7 import org.springframework.context.annotation.Configuration;
@@ -8,8 +10,12 @@ import springfox.documentation.builders.ApiInfoBuilder; @@ -8,8 +10,12 @@ import springfox.documentation.builders.ApiInfoBuilder;
8 import springfox.documentation.builders.PathSelectors; 10 import springfox.documentation.builders.PathSelectors;
9 import springfox.documentation.builders.RequestHandlerSelectors; 11 import springfox.documentation.builders.RequestHandlerSelectors;
10 import springfox.documentation.service.ApiInfo; 12 import springfox.documentation.service.ApiInfo;
  13 +import springfox.documentation.service.ApiKey;
  14 +import springfox.documentation.service.AuthorizationScope;
11 import springfox.documentation.service.Contact; 15 import springfox.documentation.service.Contact;
  16 +import springfox.documentation.service.SecurityReference;
12 import springfox.documentation.spi.DocumentationType; 17 import springfox.documentation.spi.DocumentationType;
  18 +import springfox.documentation.spi.service.contexts.SecurityContext;
13 import springfox.documentation.spring.web.plugins.Docket; 19 import springfox.documentation.spring.web.plugins.Docket;
14 import springfox.documentation.swagger2.annotations.EnableSwagger2; 20 import springfox.documentation.swagger2.annotations.EnableSwagger2;
15 21
@@ -33,6 +39,7 @@ public class SwaggerConfig @@ -33,6 +39,7 @@ public class SwaggerConfig
33 public Docket createRestApi() 39 public Docket createRestApi()
34 { 40 {
35 return new Docket(DocumentationType.SWAGGER_2) 41 return new Docket(DocumentationType.SWAGGER_2)
  42 + .pathMapping("/dev-api")
36 // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) 43 // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
37 .apiInfo(apiInfo()) 44 .apiInfo(apiInfo())
38 // 设置哪些接口暴露给Swagger展示 45 // 设置哪些接口暴露给Swagger展示
@@ -43,7 +50,47 @@ public class SwaggerConfig @@ -43,7 +50,47 @@ public class SwaggerConfig
43 //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) 50 //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
44 // 扫描所有 .apis(RequestHandlerSelectors.any()) 51 // 扫描所有 .apis(RequestHandlerSelectors.any())
45 .paths(PathSelectors.any()) 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,7 +101,7 @@ public class SwaggerConfig
54 // 用ApiInfoBuilder进行定制 101 // 用ApiInfoBuilder进行定制
55 return new ApiInfoBuilder() 102 return new ApiInfoBuilder()
56 // 设置标题 103 // 设置标题
57 - .title("标题:余心管理系统_接口文档") 104 + .title("标题:若依管理系统_接口文档")
58 // 描述 105 // 描述
59 .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") 106 .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
60 // 作者信息 107 // 作者信息
@@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory;
5 import org.springframework.security.access.AccessDeniedException; 5 import org.springframework.security.access.AccessDeniedException;
6 import org.springframework.security.authentication.AccountExpiredException; 6 import org.springframework.security.authentication.AccountExpiredException;
7 import org.springframework.security.core.userdetails.UsernameNotFoundException; 7 import org.springframework.security.core.userdetails.UsernameNotFoundException;
  8 +import org.springframework.validation.BindException;
  9 +import org.springframework.web.bind.MethodArgumentNotValidException;
8 import org.springframework.web.bind.annotation.ExceptionHandler; 10 import org.springframework.web.bind.annotation.ExceptionHandler;
9 import org.springframework.web.bind.annotation.RestControllerAdvice; 11 import org.springframework.web.bind.annotation.RestControllerAdvice;
10 import org.springframework.web.servlet.NoHandlerFoundException; 12 import org.springframework.web.servlet.NoHandlerFoundException;
@@ -83,6 +85,28 @@ public class GlobalExceptionHandler @@ -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 @ExceptionHandler(DemoModeException.class) 112 @ExceptionHandler(DemoModeException.class)
1 package com.ruoyi.project.common; 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 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.web.bind.annotation.GetMapping;
4 import org.springframework.web.bind.annotation.PostMapping; 9 import org.springframework.web.bind.annotation.PostMapping;
5 import org.springframework.web.bind.annotation.RestController; 10 import org.springframework.web.bind.annotation.RestController;
6 import org.springframework.web.multipart.MultipartFile; 11 import org.springframework.web.multipart.MultipartFile;
  12 +import com.ruoyi.common.utils.StringUtils;
7 import com.ruoyi.common.utils.file.FileUploadUtils; 13 import com.ruoyi.common.utils.file.FileUploadUtils;
  14 +import com.ruoyi.common.utils.file.FileUtils;
8 import com.ruoyi.framework.config.RuoYiConfig; 15 import com.ruoyi.framework.config.RuoYiConfig;
9 import com.ruoyi.framework.config.ServerConfig; 16 import com.ruoyi.framework.config.ServerConfig;
10 import com.ruoyi.framework.web.domain.AjaxResult; 17 import com.ruoyi.framework.web.domain.AjaxResult;
@@ -17,10 +24,46 @@ import com.ruoyi.framework.web.domain.AjaxResult; @@ -17,10 +24,46 @@ import com.ruoyi.framework.web.domain.AjaxResult;
17 @RestController 24 @RestController
18 public class CommonController 25 public class CommonController
19 { 26 {
  27 + private static final Logger log = LoggerFactory.getLogger(CommonController.class);
  28 +
20 @Autowired 29 @Autowired
21 private ServerConfig serverConfig; 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 @PostMapping("/common/upload") 69 @PostMapping("/common/upload")
@@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller; @@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.web.bind.annotation.DeleteMapping;
6 import org.springframework.web.bind.annotation.GetMapping; 7 import org.springframework.web.bind.annotation.GetMapping;
  8 +import org.springframework.web.bind.annotation.PathVariable;
7 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestMapping;
8 import org.springframework.web.bind.annotation.RestController; 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 import com.ruoyi.framework.web.controller.BaseController; 14 import com.ruoyi.framework.web.controller.BaseController;
  15 +import com.ruoyi.framework.web.domain.AjaxResult;
10 import com.ruoyi.framework.web.page.TableDataInfo; 16 import com.ruoyi.framework.web.page.TableDataInfo;
11 import com.ruoyi.project.monitor.domain.SysLogininfor; 17 import com.ruoyi.project.monitor.domain.SysLogininfor;
12 import com.ruoyi.project.monitor.service.ISysLogininforService; 18 import com.ruoyi.project.monitor.service.ISysLogininforService;
@@ -31,4 +37,31 @@ public class SysLogininforController extends BaseController @@ -31,4 +37,31 @@ public class SysLogininforController extends BaseController
31 List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); 37 List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
32 return getDataTable(list); 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 }
@@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller; @@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.web.bind.annotation.DeleteMapping;
6 import org.springframework.web.bind.annotation.GetMapping; 7 import org.springframework.web.bind.annotation.GetMapping;
  8 +import org.springframework.web.bind.annotation.PathVariable;
7 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestMapping;
8 import org.springframework.web.bind.annotation.RestController; 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 import com.ruoyi.framework.web.controller.BaseController; 14 import com.ruoyi.framework.web.controller.BaseController;
  15 +import com.ruoyi.framework.web.domain.AjaxResult;
10 import com.ruoyi.framework.web.page.TableDataInfo; 16 import com.ruoyi.framework.web.page.TableDataInfo;
11 import com.ruoyi.project.monitor.domain.SysOperLog; 17 import com.ruoyi.project.monitor.domain.SysOperLog;
12 import com.ruoyi.project.monitor.service.ISysOperLogService; 18 import com.ruoyi.project.monitor.service.ISysOperLogService;
@@ -31,4 +37,30 @@ public class SysOperlogController extends BaseController @@ -31,4 +37,30 @@ public class SysOperlogController extends BaseController
31 List<SysOperLog> list = operLogService.selectOperLogList(operLog); 37 List<SysOperLog> list = operLogService.selectOperLogList(operLog);
32 return getDataTable(list); 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 }
1 package com.ruoyi.project.monitor.domain; 1 package com.ruoyi.project.monitor.domain;
2 2
3 import java.util.Date; 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 import com.ruoyi.framework.web.domain.BaseEntity; 6 import com.ruoyi.framework.web.domain.BaseEntity;
5 7
6 /** 8 /**
@@ -13,30 +15,39 @@ public class SysLogininfor extends BaseEntity @@ -13,30 +15,39 @@ public class SysLogininfor extends BaseEntity
13 private static final long serialVersionUID = 1L; 15 private static final long serialVersionUID = 1L;
14 16
15 /** ID */ 17 /** ID */
  18 + @Excel(name = "序号", cellType = ColumnType.NUMERIC)
16 private Long infoId; 19 private Long infoId;
17 20
18 /** 用户账号 */ 21 /** 用户账号 */
  22 + @Excel(name = "用户账号")
19 private String userName; 23 private String userName;
20 24
21 /** 登录状态 0成功 1失败 */ 25 /** 登录状态 0成功 1失败 */
  26 + @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
22 private String status; 27 private String status;
23 28
24 /** 登录IP地址 */ 29 /** 登录IP地址 */
  30 + @Excel(name = "登录地址")
25 private String ipaddr; 31 private String ipaddr;
26 32
27 /** 登录地点 */ 33 /** 登录地点 */
  34 + @Excel(name = "登录地点")
28 private String loginLocation; 35 private String loginLocation;
29 36
30 /** 浏览器类型 */ 37 /** 浏览器类型 */
  38 + @Excel(name = "浏览器")
31 private String browser; 39 private String browser;
32 40
33 /** 操作系统 */ 41 /** 操作系统 */
  42 + @Excel(name = "操作系统")
34 private String os; 43 private String os;
35 44
36 /** 提示消息 */ 45 /** 提示消息 */
  46 + @Excel(name = "提示消息")
37 private String msg; 47 private String msg;
38 48
39 /** 访问时间 */ 49 /** 访问时间 */
  50 + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
40 private Date loginTime; 51 private Date loginTime;
41 52
42 public Long getInfoId() 53 public Long getInfoId()
1 package com.ruoyi.project.monitor.domain; 1 package com.ruoyi.project.monitor.domain;
2 2
3 import java.util.Date; 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 import com.ruoyi.framework.web.domain.BaseEntity; 6 import com.ruoyi.framework.web.domain.BaseEntity;
5 7
6 /** 8 /**
@@ -13,54 +15,70 @@ public class SysOperLog extends BaseEntity @@ -13,54 +15,70 @@ public class SysOperLog extends BaseEntity
13 private static final long serialVersionUID = 1L; 15 private static final long serialVersionUID = 1L;
14 16
15 /** 日志主键 */ 17 /** 日志主键 */
  18 + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
16 private Long operId; 19 private Long operId;
17 20
18 /** 操作模块 */ 21 /** 操作模块 */
  22 + @Excel(name = "操作模块")
19 private String title; 23 private String title;
20 24
21 /** 业务类型(0其它 1新增 2修改 3删除) */ 25 /** 业务类型(0其它 1新增 2修改 3删除) */
  26 + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
22 private Integer businessType; 27 private Integer businessType;
23 28
24 /** 业务类型数组 */ 29 /** 业务类型数组 */
25 private Integer[] businessTypes; 30 private Integer[] businessTypes;
26 31
27 /** 请求方法 */ 32 /** 请求方法 */
  33 + @Excel(name = "请求方法")
28 private String method; 34 private String method;
29 35
30 /** 请求方式 */ 36 /** 请求方式 */
  37 + @Excel(name = "请求方式")
31 private String requestMethod; 38 private String requestMethod;
32 39
33 /** 操作类别(0其它 1后台用户 2手机端用户) */ 40 /** 操作类别(0其它 1后台用户 2手机端用户) */
  41 + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
34 private Integer operatorType; 42 private Integer operatorType;
35 43
36 /** 操作人员 */ 44 /** 操作人员 */
  45 + @Excel(name = "操作人员")
37 private String operName; 46 private String operName;
38 47
39 /** 部门名称 */ 48 /** 部门名称 */
  49 + @Excel(name = "部门名称")
40 private String deptName; 50 private String deptName;
41 51
42 /** 请求url */ 52 /** 请求url */
  53 + @Excel(name = "请求地址")
43 private String operUrl; 54 private String operUrl;
44 55
45 /** 操作地址 */ 56 /** 操作地址 */
  57 + @Excel(name = "操作地址")
46 private String operIp; 58 private String operIp;
47 59
48 /** 操作地点 */ 60 /** 操作地点 */
  61 + @Excel(name = "操作地点")
49 private String operLocation; 62 private String operLocation;
50 63
51 /** 请求参数 */ 64 /** 请求参数 */
  65 + @Excel(name = "请求参数")
52 private String operParam; 66 private String operParam;
53 67
54 /** 返回参数 */ 68 /** 返回参数 */
  69 + @Excel(name = "返回参数")
55 private String jsonResult; 70 private String jsonResult;
56 71
57 /** 操作状态(0正常 1异常) */ 72 /** 操作状态(0正常 1异常) */
  73 + @Excel(name = "状态", readConverterExp = "0=正常,1=异常")
58 private Integer status; 74 private Integer status;
59 75
60 /** 错误消息 */ 76 /** 错误消息 */
  77 + @Excel(name = "错误消息")
61 private String errorMsg; 78 private String errorMsg;
62 79
63 /** 操作时间 */ 80 /** 操作时间 */
  81 + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
64 private Date operTime; 82 private Date operTime;
65 83
66 public Long getOperId() 84 public Long getOperId()
@@ -28,10 +28,10 @@ public interface SysLogininforMapper @@ -28,10 +28,10 @@ public interface SysLogininforMapper
28 /** 28 /**
29 * 批量删除系统登录日志 29 * 批量删除系统登录日志
30 * 30 *
31 - * @param ids 需要删除的数据 31 + * @param infoIds 需要删除的登录日志ID
32 * @return 结果 32 * @return 结果
33 */ 33 */
34 - public int deleteLogininforByIds(String[] ids); 34 + public int deleteLogininforByIds(Long[] infoIds);
35 35
36 /** 36 /**
37 * 清空系统登录日志 37 * 清空系统登录日志
@@ -28,10 +28,10 @@ public interface SysOperLogMapper @@ -28,10 +28,10 @@ public interface SysOperLogMapper
28 /** 28 /**
29 * 批量删除系统操作日志 29 * 批量删除系统操作日志
30 * 30 *
31 - * @param ids 需要删除的数据 31 + * @param operIds 需要删除的操作日志ID
32 * @return 结果 32 * @return 结果
33 */ 33 */
34 - public int deleteOperLogByIds(String[] ids); 34 + public int deleteOperLogByIds(Long[] operIds);
35 35
36 /** 36 /**
37 * 查询操作日志详细 37 * 查询操作日志详细
@@ -28,10 +28,10 @@ public interface ISysLogininforService @@ -28,10 +28,10 @@ public interface ISysLogininforService
28 /** 28 /**
29 * 批量删除系统登录日志 29 * 批量删除系统登录日志
30 * 30 *
31 - * @param ids 需要删除的数据 31 + * @param infoIds 需要删除的登录日志ID
32 * @return 32 * @return
33 */ 33 */
34 - public int deleteLogininforByIds(String ids); 34 + public int deleteLogininforByIds(Long[] infoIds);
35 35
36 /** 36 /**
37 * 清空系统登录日志 37 * 清空系统登录日志
@@ -28,10 +28,10 @@ public interface ISysOperLogService @@ -28,10 +28,10 @@ public interface ISysOperLogService
28 /** 28 /**
29 * 批量删除系统操作日志 29 * 批量删除系统操作日志
30 * 30 *
31 - * @param ids 需要删除的数据 31 + * @param operIds 需要删除的操作日志ID
32 * @return 结果 32 * @return 结果
33 */ 33 */
34 - public int deleteOperLogByIds(String ids); 34 + public int deleteOperLogByIds(Long[] operIds);
35 35
36 /** 36 /**
37 * 查询操作日志详细 37 * 查询操作日志详细
@@ -3,7 +3,6 @@ package com.ruoyi.project.monitor.service.impl; @@ -3,7 +3,6 @@ package com.ruoyi.project.monitor.service.impl;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.stereotype.Service; 5 import org.springframework.stereotype.Service;
6 -import com.ruoyi.common.core.text.Convert;  
7 import com.ruoyi.project.monitor.domain.SysLogininfor; 6 import com.ruoyi.project.monitor.domain.SysLogininfor;
8 import com.ruoyi.project.monitor.mapper.SysLogininforMapper; 7 import com.ruoyi.project.monitor.mapper.SysLogininforMapper;
9 import com.ruoyi.project.monitor.service.ISysLogininforService; 8 import com.ruoyi.project.monitor.service.ISysLogininforService;
@@ -46,13 +45,13 @@ public class SysLogininforServiceImpl implements ISysLogininforService @@ -46,13 +45,13 @@ public class SysLogininforServiceImpl implements ISysLogininforService
46 /** 45 /**
47 * 批量删除系统登录日志 46 * 批量删除系统登录日志
48 * 47 *
49 - * @param ids 需要删除的数据 48 + * @param infoIds 需要删除的登录日志ID
50 * @return 49 * @return
51 */ 50 */
52 @Override 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 /**
@@ -3,7 +3,6 @@ package com.ruoyi.project.monitor.service.impl; @@ -3,7 +3,6 @@ package com.ruoyi.project.monitor.service.impl;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.stereotype.Service; 5 import org.springframework.stereotype.Service;
6 -import com.ruoyi.common.core.text.Convert;  
7 import com.ruoyi.project.monitor.domain.SysOperLog; 6 import com.ruoyi.project.monitor.domain.SysOperLog;
8 import com.ruoyi.project.monitor.mapper.SysOperLogMapper; 7 import com.ruoyi.project.monitor.mapper.SysOperLogMapper;
9 import com.ruoyi.project.monitor.service.ISysOperLogService; 8 import com.ruoyi.project.monitor.service.ISysOperLogService;
@@ -45,13 +44,12 @@ public class SysOperLogServiceImpl implements 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 /**
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
14 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
15 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 import com.ruoyi.framework.aspectj.lang.annotation.Log; 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 import com.ruoyi.framework.aspectj.lang.enums.BusinessType; 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 import com.ruoyi.framework.web.controller.BaseController; 20 import com.ruoyi.framework.web.controller.BaseController;
@@ -45,6 +47,16 @@ public class SysConfigController extends BaseController @@ -45,6 +47,16 @@ public class SysConfigController extends BaseController
45 return getDataTable(list); 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,7 +83,7 @@ public class SysConfigController extends BaseController
71 @PreAuthorize("@ss.hasPermi('system:config:add')") 83 @PreAuthorize("@ss.hasPermi('system:config:add')")
72 @Log(title = "参数管理", businessType = BusinessType.INSERT) 84 @Log(title = "参数管理", businessType = BusinessType.INSERT)
73 @PostMapping 85 @PostMapping
74 - public AjaxResult add(@RequestBody SysConfig config) 86 + public AjaxResult add(@Validated @RequestBody SysConfig config)
75 { 87 {
76 if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) 88 if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
77 { 89 {
@@ -87,7 +99,7 @@ public class SysConfigController extends BaseController @@ -87,7 +99,7 @@ public class SysConfigController extends BaseController
87 @PreAuthorize("@ss.hasPermi('system:config:edit')") 99 @PreAuthorize("@ss.hasPermi('system:config:edit')")
88 @Log(title = "参数管理", businessType = BusinessType.UPDATE) 100 @Log(title = "参数管理", businessType = BusinessType.UPDATE)
89 @PutMapping 101 @PutMapping
90 - public AjaxResult edit(@RequestBody SysConfig config) 102 + public AjaxResult edit(@Validated @RequestBody SysConfig config)
91 { 103 {
92 if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) 104 if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
93 { 105 {
@@ -102,9 +114,9 @@ public class SysConfigController extends BaseController @@ -102,9 +114,9 @@ public class SysConfigController extends BaseController
102 */ 114 */
103 @PreAuthorize("@ss.hasPermi('system:config:remove')") 115 @PreAuthorize("@ss.hasPermi('system:config:remove')")
104 @Log(title = "参数管理", businessType = BusinessType.DELETE) 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 }
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -10,7 +11,6 @@ import org.springframework.web.bind.annotation.PostMapping; @@ -10,7 +11,6 @@ import org.springframework.web.bind.annotation.PostMapping;
10 import org.springframework.web.bind.annotation.PutMapping; 11 import org.springframework.web.bind.annotation.PutMapping;
11 import org.springframework.web.bind.annotation.RequestBody; 12 import org.springframework.web.bind.annotation.RequestBody;
12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMapping;
13 -import org.springframework.web.bind.annotation.ResponseBody;  
14 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
15 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
16 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
@@ -70,7 +70,6 @@ public class SysDeptController extends BaseController @@ -70,7 +70,6 @@ public class SysDeptController extends BaseController
70 */ 70 */
71 @PreAuthorize("@ss.hasPermi('system:dept:query')") 71 @PreAuthorize("@ss.hasPermi('system:dept:query')")
72 @GetMapping(value = "/roleDeptTreeselect/{roleId}") 72 @GetMapping(value = "/roleDeptTreeselect/{roleId}")
73 - @ResponseBody  
74 public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId) 73 public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId)
75 { 74 {
76 return AjaxResult.success(deptService.selectDeptListByRoleId(roleId)); 75 return AjaxResult.success(deptService.selectDeptListByRoleId(roleId));
@@ -82,7 +81,7 @@ public class SysDeptController extends BaseController @@ -82,7 +81,7 @@ public class SysDeptController extends BaseController
82 @PreAuthorize("@ss.hasPermi('system:dept:add')") 81 @PreAuthorize("@ss.hasPermi('system:dept:add')")
83 @Log(title = "部门管理", businessType = BusinessType.INSERT) 82 @Log(title = "部门管理", businessType = BusinessType.INSERT)
84 @PostMapping 83 @PostMapping
85 - public AjaxResult add(@RequestBody SysDept dept) 84 + public AjaxResult add(@Validated @RequestBody SysDept dept)
86 { 85 {
87 if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) 86 if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
88 { 87 {
@@ -98,7 +97,7 @@ public class SysDeptController extends BaseController @@ -98,7 +97,7 @@ public class SysDeptController extends BaseController
98 @PreAuthorize("@ss.hasPermi('system:dept:edit')") 97 @PreAuthorize("@ss.hasPermi('system:dept:edit')")
99 @Log(title = "部门管理", businessType = BusinessType.UPDATE) 98 @Log(title = "部门管理", businessType = BusinessType.UPDATE)
100 @PutMapping 99 @PutMapping
101 - public AjaxResult edit(@RequestBody SysDept dept) 100 + public AjaxResult edit(@Validated @RequestBody SysDept dept)
102 { 101 {
103 if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) 102 if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
104 { 103 {
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -10,9 +11,9 @@ import org.springframework.web.bind.annotation.PostMapping; @@ -10,9 +11,9 @@ import org.springframework.web.bind.annotation.PostMapping;
10 import org.springframework.web.bind.annotation.PutMapping; 11 import org.springframework.web.bind.annotation.PutMapping;
11 import org.springframework.web.bind.annotation.RequestBody; 12 import org.springframework.web.bind.annotation.RequestBody;
12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMapping;
13 -import org.springframework.web.bind.annotation.ResponseBody;  
14 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
15 import com.ruoyi.common.utils.SecurityUtils; 15 import com.ruoyi.common.utils.SecurityUtils;
  16 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 import com.ruoyi.framework.aspectj.lang.annotation.Log; 17 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 import com.ruoyi.framework.aspectj.lang.enums.BusinessType; 18 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 import com.ruoyi.framework.web.controller.BaseController; 19 import com.ruoyi.framework.web.controller.BaseController;
@@ -35,7 +36,6 @@ public class SysDictDataController extends BaseController @@ -35,7 +36,6 @@ public class SysDictDataController extends BaseController
35 36
36 @PreAuthorize("@ss.hasPermi('system:dict:list')") 37 @PreAuthorize("@ss.hasPermi('system:dict:list')")
37 @GetMapping("/list") 38 @GetMapping("/list")
38 - @ResponseBody  
39 public TableDataInfo list(SysDictData dictData) 39 public TableDataInfo list(SysDictData dictData)
40 { 40 {
41 startPage(); 41 startPage();
@@ -43,6 +43,16 @@ public class SysDictDataController extends BaseController @@ -43,6 +43,16 @@ public class SysDictDataController extends BaseController
43 return getDataTable(list); 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,7 +79,7 @@ public class SysDictDataController extends BaseController
69 @PreAuthorize("@ss.hasPermi('system:dict:add')") 79 @PreAuthorize("@ss.hasPermi('system:dict:add')")
70 @Log(title = "字典数据", businessType = BusinessType.INSERT) 80 @Log(title = "字典数据", businessType = BusinessType.INSERT)
71 @PostMapping 81 @PostMapping
72 - public AjaxResult add(@RequestBody SysDictData dict) 82 + public AjaxResult add(@Validated @RequestBody SysDictData dict)
73 { 83 {
74 dict.setCreateBy(SecurityUtils.getUsername()); 84 dict.setCreateBy(SecurityUtils.getUsername());
75 return toAjax(dictDataService.insertDictData(dict)); 85 return toAjax(dictDataService.insertDictData(dict));
@@ -81,7 +91,7 @@ public class SysDictDataController extends BaseController @@ -81,7 +91,7 @@ public class SysDictDataController extends BaseController
81 @PreAuthorize("@ss.hasPermi('system:dict:edit')") 91 @PreAuthorize("@ss.hasPermi('system:dict:edit')")
82 @Log(title = "字典数据", businessType = BusinessType.UPDATE) 92 @Log(title = "字典数据", businessType = BusinessType.UPDATE)
83 @PutMapping 93 @PutMapping
84 - public AjaxResult edit(@RequestBody SysDictData dict) 94 + public AjaxResult edit(@Validated @RequestBody SysDictData dict)
85 { 95 {
86 dict.setUpdateBy(SecurityUtils.getUsername()); 96 dict.setUpdateBy(SecurityUtils.getUsername());
87 return toAjax(dictDataService.updateDictData(dict)); 97 return toAjax(dictDataService.updateDictData(dict));
@@ -92,9 +102,9 @@ public class SysDictDataController extends BaseController @@ -92,9 +102,9 @@ public class SysDictDataController extends BaseController
92 */ 102 */
93 @PreAuthorize("@ss.hasPermi('system:dict:remove')") 103 @PreAuthorize("@ss.hasPermi('system:dict:remove')")
94 @Log(title = "字典类型", businessType = BusinessType.DELETE) 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 }
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -10,10 +11,10 @@ import org.springframework.web.bind.annotation.PostMapping; @@ -10,10 +11,10 @@ import org.springframework.web.bind.annotation.PostMapping;
10 import org.springframework.web.bind.annotation.PutMapping; 11 import org.springframework.web.bind.annotation.PutMapping;
11 import org.springframework.web.bind.annotation.RequestBody; 12 import org.springframework.web.bind.annotation.RequestBody;
12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMapping;
13 -import org.springframework.web.bind.annotation.ResponseBody;  
14 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
15 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
16 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
17 import com.ruoyi.framework.aspectj.lang.annotation.Log; 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
18 import com.ruoyi.framework.aspectj.lang.enums.BusinessType; 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
19 import com.ruoyi.framework.web.controller.BaseController; 20 import com.ruoyi.framework.web.controller.BaseController;
@@ -36,7 +37,6 @@ public class SysDictTypeController extends BaseController @@ -36,7 +37,6 @@ public class SysDictTypeController extends BaseController
36 37
37 @PreAuthorize("@ss.hasPermi('system:dict:list')") 38 @PreAuthorize("@ss.hasPermi('system:dict:list')")
38 @GetMapping("/list") 39 @GetMapping("/list")
39 - @ResponseBody  
40 public TableDataInfo list(SysDictType dictType) 40 public TableDataInfo list(SysDictType dictType)
41 { 41 {
42 startPage(); 42 startPage();
@@ -44,6 +44,16 @@ public class SysDictTypeController extends BaseController @@ -44,6 +44,16 @@ public class SysDictTypeController extends BaseController
44 return getDataTable(list); 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,7 +70,7 @@ public class SysDictTypeController extends BaseController
60 @PreAuthorize("@ss.hasPermi('system:dict:add')") 70 @PreAuthorize("@ss.hasPermi('system:dict:add')")
61 @Log(title = "字典类型", businessType = BusinessType.INSERT) 71 @Log(title = "字典类型", businessType = BusinessType.INSERT)
62 @PostMapping 72 @PostMapping
63 - public AjaxResult add(@RequestBody SysDictType dict) 73 + public AjaxResult add(@Validated @RequestBody SysDictType dict)
64 { 74 {
65 if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) 75 if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
66 { 76 {
@@ -76,7 +86,7 @@ public class SysDictTypeController extends BaseController @@ -76,7 +86,7 @@ public class SysDictTypeController extends BaseController
76 @PreAuthorize("@ss.hasPermi('system:dict:edit')") 86 @PreAuthorize("@ss.hasPermi('system:dict:edit')")
77 @Log(title = "字典类型", businessType = BusinessType.UPDATE) 87 @Log(title = "字典类型", businessType = BusinessType.UPDATE)
78 @PutMapping 88 @PutMapping
79 - public AjaxResult edit(@RequestBody SysDictType dict) 89 + public AjaxResult edit(@Validated @RequestBody SysDictType dict)
80 { 90 {
81 if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) 91 if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
82 { 92 {
@@ -91,9 +101,9 @@ public class SysDictTypeController extends BaseController @@ -91,9 +101,9 @@ public class SysDictTypeController extends BaseController
91 */ 101 */
92 @PreAuthorize("@ss.hasPermi('system:dict:remove')") 102 @PreAuthorize("@ss.hasPermi('system:dict:remove')")
93 @Log(title = "字典类型", businessType = BusinessType.DELETE) 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 }
@@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.PostMapping; @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.PostMapping;
11 import org.springframework.web.bind.annotation.PutMapping; 11 import org.springframework.web.bind.annotation.PutMapping;
12 import org.springframework.web.bind.annotation.RequestBody; 12 import org.springframework.web.bind.annotation.RequestBody;
13 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMapping;
14 -import org.springframework.web.bind.annotation.ResponseBody;  
15 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
16 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
17 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
@@ -71,7 +70,6 @@ public class SysMenuController extends BaseController @@ -71,7 +70,6 @@ public class SysMenuController extends BaseController
71 */ 70 */
72 @PreAuthorize("@ss.hasPermi('system:menu:query')") 71 @PreAuthorize("@ss.hasPermi('system:menu:query')")
73 @GetMapping(value = "/roleMenuTreeselect/{roleId}") 72 @GetMapping(value = "/roleMenuTreeselect/{roleId}")
74 - @ResponseBody  
75 public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) 73 public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
76 { 74 {
77 return AjaxResult.success(menuService.selectMenuListByRoleId(roleId)); 75 return AjaxResult.success(menuService.selectMenuListByRoleId(roleId));
@@ -83,7 +81,7 @@ public class SysMenuController extends BaseController @@ -83,7 +81,7 @@ public class SysMenuController extends BaseController
83 @PreAuthorize("@ss.hasPermi('system:menu:add')") 81 @PreAuthorize("@ss.hasPermi('system:menu:add')")
84 @Log(title = "菜单管理", businessType = BusinessType.INSERT) 82 @Log(title = "菜单管理", businessType = BusinessType.INSERT)
85 @PostMapping 83 @PostMapping
86 - public AjaxResult add(@RequestBody @Validated SysMenu menu) 84 + public AjaxResult add(@Validated @RequestBody SysMenu menu)
87 { 85 {
88 if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) 86 if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
89 { 87 {
@@ -99,7 +97,7 @@ public class SysMenuController extends BaseController @@ -99,7 +97,7 @@ public class SysMenuController extends BaseController
99 @PreAuthorize("@ss.hasPermi('system:menu:edit')") 97 @PreAuthorize("@ss.hasPermi('system:menu:edit')")
100 @Log(title = "菜单管理", businessType = BusinessType.UPDATE) 98 @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
101 @PutMapping 99 @PutMapping
102 - public AjaxResult edit(@RequestBody SysMenu menu) 100 + public AjaxResult edit(@Validated @RequestBody SysMenu menu)
103 { 101 {
104 if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) 102 if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
105 { 103 {
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -60,7 +61,7 @@ public class SysNoticeController extends BaseController @@ -60,7 +61,7 @@ public class SysNoticeController extends BaseController
60 @PreAuthorize("@ss.hasPermi('system:notice:add')") 61 @PreAuthorize("@ss.hasPermi('system:notice:add')")
61 @Log(title = "通知公告", businessType = BusinessType.INSERT) 62 @Log(title = "通知公告", businessType = BusinessType.INSERT)
62 @PostMapping 63 @PostMapping
63 - public AjaxResult add(@RequestBody SysNotice notice) 64 + public AjaxResult add(@Validated @RequestBody SysNotice notice)
64 { 65 {
65 notice.setCreateBy(SecurityUtils.getUsername()); 66 notice.setCreateBy(SecurityUtils.getUsername());
66 return toAjax(noticeService.insertNotice(notice)); 67 return toAjax(noticeService.insertNotice(notice));
@@ -72,7 +73,7 @@ public class SysNoticeController extends BaseController @@ -72,7 +73,7 @@ public class SysNoticeController extends BaseController
72 @PreAuthorize("@ss.hasPermi('system:notice:edit')") 73 @PreAuthorize("@ss.hasPermi('system:notice:edit')")
73 @Log(title = "通知公告", businessType = BusinessType.UPDATE) 74 @Log(title = "通知公告", businessType = BusinessType.UPDATE)
74 @PutMapping 75 @PutMapping
75 - public AjaxResult edit(@RequestBody SysNotice notice) 76 + public AjaxResult edit(@Validated @RequestBody SysNotice notice)
76 { 77 {
77 notice.setUpdateBy(SecurityUtils.getUsername()); 78 notice.setUpdateBy(SecurityUtils.getUsername());
78 return toAjax(noticeService.updateNotice(notice)); 79 return toAjax(noticeService.updateNotice(notice));
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
14 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
15 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 import com.ruoyi.framework.aspectj.lang.annotation.Log; 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 import com.ruoyi.framework.aspectj.lang.enums.BusinessType; 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 import com.ruoyi.framework.web.controller.BaseController; 20 import com.ruoyi.framework.web.controller.BaseController;
@@ -45,6 +47,16 @@ public class SysPostController extends BaseController @@ -45,6 +47,16 @@ public class SysPostController extends BaseController
45 return getDataTable(list); 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(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 + }
  59 +
48 /** 60 /**
49 * 根据岗位编号获取详细信息 61 * 根据岗位编号获取详细信息
50 */ 62 */
@@ -61,7 +73,7 @@ public class SysPostController extends BaseController @@ -61,7 +73,7 @@ public class SysPostController extends BaseController
61 @PreAuthorize("@ss.hasPermi('system:post:add')") 73 @PreAuthorize("@ss.hasPermi('system:post:add')")
62 @Log(title = "岗位管理", businessType = BusinessType.INSERT) 74 @Log(title = "岗位管理", businessType = BusinessType.INSERT)
63 @PostMapping 75 @PostMapping
64 - public AjaxResult add(@RequestBody SysPost post) 76 + public AjaxResult add(@Validated @RequestBody SysPost post)
65 { 77 {
66 if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) 78 if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
67 { 79 {
@@ -81,7 +93,7 @@ public class SysPostController extends BaseController @@ -81,7 +93,7 @@ public class SysPostController extends BaseController
81 @PreAuthorize("@ss.hasPermi('system:post:edit')") 93 @PreAuthorize("@ss.hasPermi('system:post:edit')")
82 @Log(title = "岗位管理", businessType = BusinessType.UPDATE) 94 @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
83 @PutMapping 95 @PutMapping
84 - public AjaxResult edit(@RequestBody SysPost post) 96 + public AjaxResult edit(@Validated @RequestBody SysPost post)
85 { 97 {
86 if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) 98 if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
87 { 99 {
@@ -100,10 +112,10 @@ public class SysPostController extends BaseController @@ -100,10 +112,10 @@ public class SysPostController extends BaseController
100 */ 112 */
101 @PreAuthorize("@ss.hasPermi('system:post:remove')") 113 @PreAuthorize("@ss.hasPermi('system:post:remove')")
102 @Log(title = "岗位管理", businessType = BusinessType.DELETE) 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 /**
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
14 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
15 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 import com.ruoyi.framework.aspectj.lang.annotation.Log; 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 import com.ruoyi.framework.aspectj.lang.enums.BusinessType; 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 import com.ruoyi.framework.web.controller.BaseController; 20 import com.ruoyi.framework.web.controller.BaseController;
@@ -42,6 +44,16 @@ public class SysRoleController extends BaseController @@ -42,6 +44,16 @@ public class SysRoleController extends BaseController
42 return getDataTable(list); 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,7 +70,7 @@ public class SysRoleController extends BaseController
58 @PreAuthorize("@ss.hasPermi('system:role:add')") 70 @PreAuthorize("@ss.hasPermi('system:role:add')")
59 @Log(title = "角色管理", businessType = BusinessType.INSERT) 71 @Log(title = "角色管理", businessType = BusinessType.INSERT)
60 @PostMapping 72 @PostMapping
61 - public AjaxResult add(@RequestBody SysRole role) 73 + public AjaxResult add(@Validated @RequestBody SysRole role)
62 { 74 {
63 if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) 75 if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
64 { 76 {
@@ -79,7 +91,7 @@ public class SysRoleController extends BaseController @@ -79,7 +91,7 @@ public class SysRoleController extends BaseController
79 @PreAuthorize("@ss.hasPermi('system:role:edit')") 91 @PreAuthorize("@ss.hasPermi('system:role:edit')")
80 @Log(title = "角色管理", businessType = BusinessType.UPDATE) 92 @Log(title = "角色管理", businessType = BusinessType.UPDATE)
81 @PutMapping 93 @PutMapping
82 - public AjaxResult edit(@RequestBody SysRole role) 94 + public AjaxResult edit(@Validated @RequestBody SysRole role)
83 { 95 {
84 roleService.checkRoleAllowed(role); 96 roleService.checkRoleAllowed(role);
85 if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) 97 if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
@@ -120,15 +132,14 @@ public class SysRoleController extends BaseController @@ -120,15 +132,14 @@ public class SysRoleController extends BaseController
120 } 132 }
121 133
122 /** 134 /**
123 - * 删除岗位 135 + * 删除角色
124 */ 136 */
125 @PreAuthorize("@ss.hasPermi('system:role:remove')") 137 @PreAuthorize("@ss.hasPermi('system:role:remove')")
126 @Log(title = "角色管理", businessType = BusinessType.DELETE) 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 /**
@@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller; @@ -3,6 +3,7 @@ package com.ruoyi.project.system.controller;
3 import java.util.List; 3 import java.util.List;
4 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.security.access.prepost.PreAuthorize; 5 import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
6 import org.springframework.web.bind.annotation.DeleteMapping; 7 import org.springframework.web.bind.annotation.DeleteMapping;
7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
@@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RestController; 14 import org.springframework.web.bind.annotation.RestController;
14 import com.ruoyi.common.constant.UserConstants; 15 import com.ruoyi.common.constant.UserConstants;
15 import com.ruoyi.common.utils.SecurityUtils; 16 import com.ruoyi.common.utils.SecurityUtils;
  17 +import com.ruoyi.common.utils.poi.ExcelUtil;
16 import com.ruoyi.framework.aspectj.lang.annotation.Log; 18 import com.ruoyi.framework.aspectj.lang.annotation.Log;
17 import com.ruoyi.framework.aspectj.lang.enums.BusinessType; 19 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
18 import com.ruoyi.framework.web.controller.BaseController; 20 import com.ruoyi.framework.web.controller.BaseController;
@@ -53,6 +55,16 @@ public class SysUserController extends BaseController @@ -53,6 +55,16 @@ public class SysUserController extends BaseController
53 return getDataTable(list); 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,7 +84,7 @@ public class SysUserController extends BaseController
72 @PreAuthorize("@ss.hasPermi('system:user:add')") 84 @PreAuthorize("@ss.hasPermi('system:user:add')")
73 @Log(title = "用户管理", businessType = BusinessType.INSERT) 85 @Log(title = "用户管理", businessType = BusinessType.INSERT)
74 @PostMapping 86 @PostMapping
75 - public AjaxResult add(@RequestBody SysUser user) 87 + public AjaxResult add(@Validated @RequestBody SysUser user)
76 { 88 {
77 if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) 89 if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
78 { 90 {
@@ -97,7 +109,7 @@ public class SysUserController extends BaseController @@ -97,7 +109,7 @@ public class SysUserController extends BaseController
97 @PreAuthorize("@ss.hasPermi('system:user:edit')") 109 @PreAuthorize("@ss.hasPermi('system:user:edit')")
98 @Log(title = "用户管理", businessType = BusinessType.UPDATE) 110 @Log(title = "用户管理", businessType = BusinessType.UPDATE)
99 @PutMapping 111 @PutMapping
100 - public AjaxResult edit(@RequestBody SysUser user) 112 + public AjaxResult edit(@Validated @RequestBody SysUser user)
101 { 113 {
102 userService.checkUserAllowed(user); 114 userService.checkUserAllowed(user);
103 if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) 115 if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
@@ -117,11 +129,10 @@ public class SysUserController extends BaseController @@ -117,11 +129,10 @@ public class SysUserController extends BaseController
117 */ 129 */
118 @PreAuthorize("@ss.hasPermi('system:user:remove')") 130 @PreAuthorize("@ss.hasPermi('system:user:remove')")
119 @Log(title = "用户管理", businessType = BusinessType.DELETE) 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 /**
@@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain; @@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain;
2 2
3 import javax.validation.constraints.NotBlank; 3 import javax.validation.constraints.NotBlank;
4 import javax.validation.constraints.Size; 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 import com.ruoyi.framework.web.domain.BaseEntity; 9 import com.ruoyi.framework.web.domain.BaseEntity;
6 10
7 /** 11 /**
@@ -14,18 +18,23 @@ public class SysConfig extends BaseEntity @@ -14,18 +18,23 @@ public class SysConfig extends BaseEntity
14 private static final long serialVersionUID = 1L; 18 private static final long serialVersionUID = 1L;
15 19
16 /** 参数主键 */ 20 /** 参数主键 */
  21 + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC)
17 private Long configId; 22 private Long configId;
18 23
19 /** 参数名称 */ 24 /** 参数名称 */
  25 + @Excel(name = "参数名称")
20 private String configName; 26 private String configName;
21 27
22 /** 参数键名 */ 28 /** 参数键名 */
  29 + @Excel(name = "参数键名")
23 private String configKey; 30 private String configKey;
24 31
25 /** 参数键值 */ 32 /** 参数键值 */
  33 + @Excel(name = "参数键值")
26 private String configValue; 34 private String configValue;
27 35
28 /** 系统内置(Y是 N否) */ 36 /** 系统内置(Y是 N否) */
  37 + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否")
29 private String configType; 38 private String configType;
30 39
31 public Long getConfigId() 40 public Long getConfigId()
@@ -83,4 +92,20 @@ public class SysConfig extends BaseEntity @@ -83,4 +92,20 @@ public class SysConfig extends BaseEntity
83 { 92 {
84 this.configType = configType; 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 }
@@ -2,6 +2,11 @@ package com.ruoyi.project.system.domain; @@ -2,6 +2,11 @@ package com.ruoyi.project.system.domain;
2 2
3 import java.util.ArrayList; 3 import java.util.ArrayList;
4 import java.util.List; 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 import com.ruoyi.framework.web.domain.BaseEntity; 10 import com.ruoyi.framework.web.domain.BaseEntity;
6 11
7 /** 12 /**
@@ -79,6 +84,8 @@ public class SysDept extends BaseEntity @@ -79,6 +84,8 @@ public class SysDept extends BaseEntity
79 this.ancestors = ancestors; 84 this.ancestors = ancestors;
80 } 85 }
81 86
  87 + @NotBlank(message = "部门名称不能为空")
  88 + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
82 public String getDeptName() 89 public String getDeptName()
83 { 90 {
84 return deptName; 91 return deptName;
@@ -89,6 +96,7 @@ public class SysDept extends BaseEntity @@ -89,6 +96,7 @@ public class SysDept extends BaseEntity
89 this.deptName = deptName; 96 this.deptName = deptName;
90 } 97 }
91 98
  99 + @NotBlank(message = "显示顺序不能为空")
92 public String getOrderNum() 100 public String getOrderNum()
93 { 101 {
94 return orderNum; 102 return orderNum;
@@ -109,6 +117,7 @@ public class SysDept extends BaseEntity @@ -109,6 +117,7 @@ public class SysDept extends BaseEntity
109 this.leader = leader; 117 this.leader = leader;
110 } 118 }
111 119
  120 + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
112 public String getPhone() 121 public String getPhone()
113 { 122 {
114 return phone; 123 return phone;
@@ -119,6 +128,8 @@ public class SysDept extends BaseEntity @@ -119,6 +128,8 @@ public class SysDept extends BaseEntity
119 this.phone = phone; 128 this.phone = phone;
120 } 129 }
121 130
  131 + @Email(message = "邮箱格式不正确")
  132 + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
122 public String getEmail() 133 public String getEmail()
123 { 134 {
124 return email; 135 return email;
@@ -168,4 +179,24 @@ public class SysDept extends BaseEntity @@ -168,4 +179,24 @@ public class SysDept extends BaseEntity
168 { 179 {
169 this.children = children; 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 }
@@ -2,7 +2,11 @@ package com.ruoyi.project.system.domain; @@ -2,7 +2,11 @@ package com.ruoyi.project.system.domain;
2 2
3 import javax.validation.constraints.NotBlank; 3 import javax.validation.constraints.NotBlank;
4 import javax.validation.constraints.Size; 4 import javax.validation.constraints.Size;
  5 +import org.apache.commons.lang3.builder.ToStringBuilder;
  6 +import org.apache.commons.lang3.builder.ToStringStyle;
5 import com.ruoyi.common.constant.UserConstants; 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 import com.ruoyi.framework.web.domain.BaseEntity; 10 import com.ruoyi.framework.web.domain.BaseEntity;
7 11
8 /** 12 /**
@@ -15,18 +19,23 @@ public class SysDictData extends BaseEntity @@ -15,18 +19,23 @@ public class SysDictData extends BaseEntity
15 private static final long serialVersionUID = 1L; 19 private static final long serialVersionUID = 1L;
16 20
17 /** 字典编码 */ 21 /** 字典编码 */
  22 + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
18 private Long dictCode; 23 private Long dictCode;
19 24
20 /** 字典排序 */ 25 /** 字典排序 */
  26 + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
21 private Long dictSort; 27 private Long dictSort;
22 28
23 /** 字典标签 */ 29 /** 字典标签 */
  30 + @Excel(name = "字典标签")
24 private String dictLabel; 31 private String dictLabel;
25 32
26 /** 字典键值 */ 33 /** 字典键值 */
  34 + @Excel(name = "字典键值")
27 private String dictValue; 35 private String dictValue;
28 36
29 /** 字典类型 */ 37 /** 字典类型 */
  38 + @Excel(name = "字典类型")
30 private String dictType; 39 private String dictType;
31 40
32 /** 样式属性(其他样式扩展) */ 41 /** 样式属性(其他样式扩展) */
@@ -36,9 +45,11 @@ public class SysDictData extends BaseEntity @@ -36,9 +45,11 @@ public class SysDictData extends BaseEntity
36 private String listClass; 45 private String listClass;
37 46
38 /** 是否默认(Y是 N否) */ 47 /** 是否默认(Y是 N否) */
  48 + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
39 private String isDefault; 49 private String isDefault;
40 50
41 /** 状态(0正常 1停用) */ 51 /** 状态(0正常 1停用) */
  52 + @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
42 private String status; 53 private String status;
43 54
44 public Long getDictCode() 55 public Long getDictCode()
@@ -142,4 +153,24 @@ public class SysDictData extends BaseEntity @@ -142,4 +153,24 @@ public class SysDictData extends BaseEntity
142 { 153 {
143 this.status = status; 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 }
@@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain; @@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain;
2 2
3 import javax.validation.constraints.NotBlank; 3 import javax.validation.constraints.NotBlank;
4 import javax.validation.constraints.Size; 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 import com.ruoyi.framework.web.domain.BaseEntity; 9 import com.ruoyi.framework.web.domain.BaseEntity;
6 10
7 /** 11 /**
@@ -14,15 +18,19 @@ public class SysDictType extends BaseEntity @@ -14,15 +18,19 @@ public class SysDictType extends BaseEntity
14 private static final long serialVersionUID = 1L; 18 private static final long serialVersionUID = 1L;
15 19
16 /** 字典主键 */ 20 /** 字典主键 */
  21 + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
17 private Long dictId; 22 private Long dictId;
18 23
19 /** 字典名称 */ 24 /** 字典名称 */
  25 + @Excel(name = "字典名称")
20 private String dictName; 26 private String dictName;
21 27
22 /** 字典类型 */ 28 /** 字典类型 */
  29 + @Excel(name = "字典类型")
23 private String dictType; 30 private String dictType;
24 31
25 /** 状态(0正常 1停用) */ 32 /** 状态(0正常 1停用) */
  33 + @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
26 private String status; 34 private String status;
27 35
28 public Long getDictId() 36 public Long getDictId()
@@ -68,4 +76,19 @@ public class SysDictType extends BaseEntity @@ -68,4 +76,19 @@ public class SysDictType extends BaseEntity
68 { 76 {
69 this.status = status; 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 }
1 package com.ruoyi.project.system.domain; 1 package com.ruoyi.project.system.domain;
2 2
  3 +import java.util.ArrayList;
3 import java.util.List; 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 import com.ruoyi.framework.web.domain.BaseEntity; 9 import com.ruoyi.framework.web.domain.BaseEntity;
5 -import java.util.ArrayList;  
6 10
7 /** 11 /**
8 * 菜单权限表 sys_menu 12 * 菜单权限表 sys_menu
@@ -62,6 +66,8 @@ public class SysMenu extends BaseEntity @@ -62,6 +66,8 @@ public class SysMenu extends BaseEntity
62 this.menuId = menuId; 66 this.menuId = menuId;
63 } 67 }
64 68
  69 + @NotBlank(message = "菜单名称不能为空")
  70 + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
65 public String getMenuName() 71 public String getMenuName()
66 { 72 {
67 return menuName; 73 return menuName;
@@ -92,6 +98,7 @@ public class SysMenu extends BaseEntity @@ -92,6 +98,7 @@ public class SysMenu extends BaseEntity
92 this.parentId = parentId; 98 this.parentId = parentId;
93 } 99 }
94 100
  101 + @NotBlank(message = "显示顺序不能为空")
95 public String getOrderNum() 102 public String getOrderNum()
96 { 103 {
97 return orderNum; 104 return orderNum;
@@ -102,6 +109,7 @@ public class SysMenu extends BaseEntity @@ -102,6 +109,7 @@ public class SysMenu extends BaseEntity
102 this.orderNum = orderNum; 109 this.orderNum = orderNum;
103 } 110 }
104 111
  112 + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
105 public String getPath() 113 public String getPath()
106 { 114 {
107 return path; 115 return path;
@@ -112,6 +120,7 @@ public class SysMenu extends BaseEntity @@ -112,6 +120,7 @@ public class SysMenu extends BaseEntity
112 this.path = path; 120 this.path = path;
113 } 121 }
114 122
  123 + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
115 public String getComponent() 124 public String getComponent()
116 { 125 {
117 return component; 126 return component;
@@ -132,6 +141,7 @@ public class SysMenu extends BaseEntity @@ -132,6 +141,7 @@ public class SysMenu extends BaseEntity
132 this.isFrame = isFrame; 141 this.isFrame = isFrame;
133 } 142 }
134 143
  144 + @NotBlank(message = "菜单类型不能为空")
135 public String getMenuType() 145 public String getMenuType()
136 { 146 {
137 return menuType; 147 return menuType;
@@ -152,6 +162,7 @@ public class SysMenu extends BaseEntity @@ -152,6 +162,7 @@ public class SysMenu extends BaseEntity
152 this.visible = visible; 162 this.visible = visible;
153 } 163 }
154 164
  165 + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
155 public String getPerms() 166 public String getPerms()
156 { 167 {
157 return perms; 168 return perms;
@@ -181,4 +192,26 @@ public class SysMenu extends BaseEntity @@ -181,4 +192,26 @@ public class SysMenu extends BaseEntity
181 { 192 {
182 this.children = children; 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 }
1 package com.ruoyi.project.system.domain; 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 import com.ruoyi.framework.web.domain.BaseEntity; 7 import com.ruoyi.framework.web.domain.BaseEntity;
4 8
5 /** 9 /**
@@ -41,6 +45,8 @@ public class SysNotice extends BaseEntity @@ -41,6 +45,8 @@ public class SysNotice extends BaseEntity
41 this.noticeTitle = noticeTitle; 45 this.noticeTitle = noticeTitle;
42 } 46 }
43 47
  48 + @NotBlank(message = "公告标题不能为空")
  49 + @Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
44 public String getNoticeTitle() 50 public String getNoticeTitle()
45 { 51 {
46 return noticeTitle; 52 return noticeTitle;
@@ -75,4 +81,20 @@ public class SysNotice extends BaseEntity @@ -75,4 +81,20 @@ public class SysNotice extends BaseEntity
75 { 81 {
76 return status; 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 }
@@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain; @@ -2,6 +2,10 @@ package com.ruoyi.project.system.domain;
2 2
3 import javax.validation.constraints.NotBlank; 3 import javax.validation.constraints.NotBlank;
4 import javax.validation.constraints.Size; 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 import com.ruoyi.framework.web.domain.BaseEntity; 9 import com.ruoyi.framework.web.domain.BaseEntity;
6 10
7 /** 11 /**
@@ -14,18 +18,23 @@ public class SysPost extends BaseEntity @@ -14,18 +18,23 @@ public class SysPost extends BaseEntity
14 private static final long serialVersionUID = 1L; 18 private static final long serialVersionUID = 1L;
15 19
16 /** 岗位序号 */ 20 /** 岗位序号 */
  21 + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC)
17 private Long postId; 22 private Long postId;
18 23
19 /** 岗位编码 */ 24 /** 岗位编码 */
  25 + @Excel(name = "岗位编码")
20 private String postCode; 26 private String postCode;
21 27
22 /** 岗位名称 */ 28 /** 岗位名称 */
  29 + @Excel(name = "岗位名称")
23 private String postName; 30 private String postName;
24 31
25 /** 岗位排序 */ 32 /** 岗位排序 */
  33 + @Excel(name = "岗位排序")
26 private String postSort; 34 private String postSort;
27 35
28 /** 状态(0正常 1停用) */ 36 /** 状态(0正常 1停用) */
  37 + @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
29 private String status; 38 private String status;
30 39
31 /** 用户是否存在此岗位标识 默认不存在 */ 40 /** 用户是否存在此岗位标识 默认不存在 */
@@ -95,4 +104,20 @@ public class SysPost extends BaseEntity @@ -95,4 +104,20 @@ public class SysPost extends BaseEntity
95 { 104 {
96 this.flag = flag; 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 }