Commit f942b34d02928e65aea16e49036e9b230fb4f7e1

Authored by YunaiV
1 parent 02ff516f

1. 完成用户导出的功能

2. 完成前后端的导出的封装
ruoyi-ui/src/main.js
@@ -16,7 +16,7 @@ import './assets/icons' // icon @@ -16,7 +16,7 @@ import './assets/icons' // icon
16 import './permission' // permission control 16 import './permission' // permission control
17 import { getDicts } from "@/api/system/dict/data"; 17 import { getDicts } from "@/api/system/dict/data";
18 import { getConfigKey } from "@/api/system/config"; 18 import { getConfigKey } from "@/api/system/config";
19 -import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi"; 19 +import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree, downloadExcel } from "@/utils/ruoyi";
20 import Pagination from "@/components/Pagination"; 20 import Pagination from "@/components/Pagination";
21 // 自定义表格工具扩展 21 // 自定义表格工具扩展
22 import RightToolbar from "@/components/RightToolbar" 22 import RightToolbar from "@/components/RightToolbar"
@@ -33,6 +33,7 @@ Vue.prototype.addDateRange = addDateRange @@ -33,6 +33,7 @@ Vue.prototype.addDateRange = addDateRange
33 Vue.prototype.selectDictLabel = selectDictLabel 33 Vue.prototype.selectDictLabel = selectDictLabel
34 Vue.prototype.selectDictLabels = selectDictLabels 34 Vue.prototype.selectDictLabels = selectDictLabels
35 Vue.prototype.download = download 35 Vue.prototype.download = download
  36 +Vue.prototype.downloadExcel = downloadExcel
36 Vue.prototype.handleTree = handleTree 37 Vue.prototype.handleTree = handleTree
37 38
38 Vue.prototype.msgSuccess = function (msg) { 39 Vue.prototype.msgSuccess = function (msg) {
ruoyi-ui/src/utils/ruoyi.js
@@ -101,6 +101,21 @@ export function download(fileName) { @@ -101,6 +101,21 @@ export function download(fileName) {
101 window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true; 101 window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
102 } 102 }
103 103
  104 +// 下载 Excel 方法
  105 +export function downloadExcel(data, fileName) {
  106 + // 创建 blob
  107 + let blob = new Blob([data], {type: 'application/vnd.ms-excel'});
  108 + // 创建 href 超链接,点击进行下载
  109 + window.URL = window.URL || window.webkitURL;
  110 + let href = URL.createObjectURL(blob);
  111 + let downA = document.createElement("a");
  112 + downA.href = href;
  113 + downA.download = fileName;
  114 + downA.click();
  115 + // 销毁超连接
  116 + window.URL.revokeObjectURL(href);
  117 +}
  118 +
104 // 字符串格式化(%s ) 119 // 字符串格式化(%s )
105 export function sprintf(str) { 120 export function sprintf(str) {
106 var args = arguments, flag = true, i = 1; 121 var args = arguments, flag = true, i = 1;
ruoyi-ui/src/views/system/user/index.vue
@@ -510,7 +510,7 @@ export default { @@ -510,7 +510,7 @@ export default {
510 this.reset(); 510 this.reset();
511 }, 511 },
512 // 取消按钮(角色权限) 512 // 取消按钮(角色权限)
513 - cancelMenu() { 513 + cancelRole() {
514 this.openRole = false; 514 this.openRole = false;
515 this.reset(); 515 this.reset();
516 }, 516 },
@@ -647,7 +647,10 @@ export default { @@ -647,7 +647,10 @@ export default {
647 }, 647 },
648 /** 导出按钮操作 */ 648 /** 导出按钮操作 */
649 handleExport() { 649 handleExport() {
650 - const queryParams = this.queryParams; 650 + const queryParams = this.addDateRange(this.queryParams, [
  651 + this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,
  652 + this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,
  653 + ]);
651 this.$confirm('是否确认导出所有用户数据项?', "警告", { 654 this.$confirm('是否确认导出所有用户数据项?', "警告", {
652 confirmButtonText: "确定", 655 confirmButtonText: "确定",
653 cancelButtonText: "取消", 656 cancelButtonText: "取消",
@@ -655,15 +658,7 @@ export default { @@ -655,15 +658,7 @@ export default {
655 }).then(function() { 658 }).then(function() {
656 return exportUser(queryParams); 659 return exportUser(queryParams);
657 }).then(response => { 660 }).then(response => {
658 - // this.download(response.msg);  
659 - let blob = new Blob([response], {type: 'application/vnd.ms-excel'});  
660 - window.URL = window.URL || window.webkitURL;  
661 - let href = URL.createObjectURL(blob);  
662 - let downA = document.createElement("a");  
663 - downA.href = href;//  
664 - downA.download = '123321.xls';  
665 - downA.click();  
666 - window.URL.revokeObjectURL(href); 661 + this.downloadExcel(response, '用户数据.xls');
667 }) 662 })
668 }, 663 },
669 /** 导入按钮操作 */ 664 /** 导入按钮操作 */
src/main/java/cn/iocoder/dashboard/framework/excel/core/convert/DictConvert.java
@@ -54,7 +54,7 @@ public class DictConvert implements Converter<Object> { @@ -54,7 +54,7 @@ public class DictConvert implements Converter<Object> {
54 return null; 54 return null;
55 } 55 }
56 // 生成 Excel 小表格 56 // 生成 Excel 小表格
57 - return new CellData<>(dictData.getValue()); 57 + return new CellData<>(dictData.getLabel());
58 } 58 }
59 59
60 private static DictTypeEnum getType(ExcelContentProperty contentProperty) { 60 private static DictTypeEnum getType(ExcelContentProperty contentProperty) {
src/main/java/cn/iocoder/dashboard/framework/excel/core/util/ExcelUtils.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.excel.core.util;
  2 +
  3 +import com.alibaba.excel.EasyExcel;
  4 +import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
  5 +
  6 +import javax.servlet.http.HttpServletResponse;
  7 +import java.io.IOException;
  8 +import java.net.URLEncoder;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * Excel 工具类
  13 + */
  14 +public class ExcelUtils {
  15 +
  16 + public static void write(HttpServletResponse response, String filename, String sheetName,
  17 + Class<?> head, List<?> data) throws IOException {
  18 + // 设置 header 和 contentType
  19 + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
  20 + response.setContentType("application/vnd.ms-excel;charset=UTF-8");
  21 + // 输出 Excel
  22 + EasyExcel.write(response.getOutputStream(), head)
  23 + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
  24 + .sheet(sheetName).doWrite(data);
  25 + }
  26 +
  27 +}
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/SysUserController.java
@@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.user; @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.user;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.dashboard.common.pojo.CommonResult; 4 import cn.iocoder.dashboard.common.pojo.CommonResult;
5 import cn.iocoder.dashboard.common.pojo.PageResult; 5 import cn.iocoder.dashboard.common.pojo.PageResult;
  6 +import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*; 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
7 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert; 8 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
8 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; 9 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
@@ -10,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; @@ -10,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
10 import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; 11 import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
11 import cn.iocoder.dashboard.modules.system.service.user.SysUserService; 12 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
12 import cn.iocoder.dashboard.util.collection.CollectionUtils; 13 import cn.iocoder.dashboard.util.collection.CollectionUtils;
13 -import com.alibaba.excel.EasyExcel; 14 +import cn.iocoder.dashboard.util.collection.MapUtils;
14 import io.swagger.annotations.Api; 15 import io.swagger.annotations.Api;
15 import io.swagger.annotations.ApiImplicitParam; 16 import io.swagger.annotations.ApiImplicitParam;
16 import io.swagger.annotations.ApiOperation; 17 import io.swagger.annotations.ApiOperation;
@@ -20,7 +21,10 @@ import org.springframework.web.bind.annotation.*; @@ -20,7 +21,10 @@ import org.springframework.web.bind.annotation.*;
20 import javax.annotation.Resource; 21 import javax.annotation.Resource;
21 import javax.servlet.http.HttpServletResponse; 22 import javax.servlet.http.HttpServletResponse;
22 import java.io.IOException; 23 import java.io.IOException;
23 -import java.util.*; 24 +import java.util.ArrayList;
  25 +import java.util.Collection;
  26 +import java.util.List;
  27 +import java.util.Map;
24 28
25 import static cn.iocoder.dashboard.common.pojo.CommonResult.success; 29 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
26 30
@@ -37,7 +41,7 @@ public class SysUserController { @@ -37,7 +41,7 @@ public class SysUserController {
37 @ApiOperation("获得用户分页列表") 41 @ApiOperation("获得用户分页列表")
38 @GetMapping("/page") 42 @GetMapping("/page")
39 // @PreAuthorize("@ss.hasPermi('system:user:list')") 43 // @PreAuthorize("@ss.hasPermi('system:user:list')")
40 - public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(SysUserPageReqVO reqVO) { 44 + public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) {
41 // 获得用户分页列表 45 // 获得用户分页列表
42 PageResult<SysUserDO> pageResult = userService.pageUsers(reqVO); 46 PageResult<SysUserDO> pageResult = userService.pageUsers(reqVO);
43 if (CollUtil.isEmpty(pageResult.getList())) { 47 if (CollUtil.isEmpty(pageResult.getList())) {
@@ -45,13 +49,8 @@ public class SysUserController { @@ -45,13 +49,8 @@ public class SysUserController {
45 } 49 }
46 50
47 // 获得拼接需要的数据 51 // 获得拼接需要的数据
48 - Map<Long, SysDeptDO> deptMap;  
49 Collection<Long> deptIds = CollectionUtils.convertList(pageResult.getList(), SysUserDO::getDeptId); 52 Collection<Long> deptIds = CollectionUtils.convertList(pageResult.getList(), SysUserDO::getDeptId);
50 - if (CollUtil.isNotEmpty(deptIds)) {  
51 - deptMap = CollectionUtils.convertMap(deptService.listDepts(deptIds), SysDeptDO::getId);  
52 - } else {  
53 - deptMap = Collections.emptyMap();  
54 - } 53 + Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(deptIds);
55 // 拼接结果返回 54 // 拼接结果返回
56 List<SysUserPageItemRespVO> userList = new ArrayList<>(pageResult.getList().size()); 55 List<SysUserPageItemRespVO> userList = new ArrayList<>(pageResult.getList().size());
57 pageResult.getList().forEach(user -> { 56 pageResult.getList().forEach(user -> {
@@ -121,11 +120,29 @@ public class SysUserController { @@ -121,11 +120,29 @@ public class SysUserController {
121 120
122 @ApiOperation("导出用户") 121 @ApiOperation("导出用户")
123 @GetMapping("/export") 122 @GetMapping("/export")
124 - public void exportUsers(HttpServletResponse response) throws IOException {  
125 - String fileName = "测试文件.xls";  
126 - response.addHeader("Content-Disposition", "attachment;filename=" + fileName);  
127 - response.setContentType("application/vnd.ms-excel;charset=UTF-8");  
128 - EasyExcel.write(response.getOutputStream(), SysUserExcelVO.class).sheet().doWrite(new ArrayList<>()); 123 +// @PreAuthorize("@ss.hasPermi('system:user:export')") , @Validated SysUserExportReqVO reqVO
  124 +// @Log(title = "用户管理", businessType = BusinessType.EXPORT)
  125 + public void exportUsers(HttpServletResponse response, @Validated SysUserExportReqVO reqVO) throws IOException {
  126 + // 获得用户列表
  127 + List<SysUserDO> users = userService.listUsers(reqVO);
  128 +
  129 + // 获得拼接需要的数据
  130 + Collection<Long> deptIds = CollectionUtils.convertList(users, SysUserDO::getDeptId);
  131 + Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(deptIds);
  132 + // 拼接数据
  133 + List<SysUserExcelVO> excelUsers = new ArrayList<>(users.size());
  134 + users.forEach(user -> {
  135 + SysUserExcelVO excelVO = SysUserConvert.INSTANCE.convert02(user);
  136 + MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> {
  137 + excelVO.setDeptName(dept.getName());
  138 + excelVO.setDeptLeader(dept.getLeader());
  139 + });
  140 + excelUsers.add(excelVO);
  141 + });
  142 +
  143 + // 输出
  144 + ExcelUtils.write(response, "用户数据.xls", "用户列表",
  145 + SysUserExcelVO.class, excelUsers);
129 } 146 }
130 147
131 // @Log(title = "用户管理", businessType = BusinessType.EXPORT) 148 // @Log(title = "用户管理", businessType = BusinessType.EXPORT)
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserExcelVO.java
@@ -22,7 +22,7 @@ public class SysUserExcelVO { @@ -22,7 +22,7 @@ public class SysUserExcelVO {
22 @ExcelProperty("用户名称") 22 @ExcelProperty("用户名称")
23 private String username; 23 private String username;
24 24
25 - @ExcelProperty("用户名称") 25 + @ExcelProperty("用户昵称")
26 private String nickname; 26 private String nickname;
27 27
28 @ExcelProperty("用户邮箱") 28 @ExcelProperty("用户邮箱")
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserExportReqVO.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Data;
  7 +import lombok.NoArgsConstructor;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.util.Date;
  11 +
  12 +import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@ApiModel(value = "用户导出 Request VO", description = "参数和 SysUserPageReqVO 是一致的")
  15 +@Data
  16 +@NoArgsConstructor
  17 +@AllArgsConstructor
  18 +public class SysUserExportReqVO {
  19 +
  20 + @ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配")
  21 + private String username;
  22 +
  23 + @ApiModelProperty(value = "手机号码", example = "yudao", notes = "模糊匹配")
  24 + private String mobile;
  25 +
  26 + @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 SysCommonStatusEnum 枚举类")
  27 + private Integer status;
  28 +
  29 + @ApiModelProperty(value = "开始时间", example = "2020-10-24")
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + private Date beginTime;
  32 +
  33 + @ApiModelProperty(value = "结束时间", example = "2020-10-24")
  34 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  35 + private Date endTime;
  36 +
  37 + @ApiModelProperty(value = "部门编号", example = "1024", notes = "同时筛选子部门")
  38 + private Long deptId;
  39 +
  40 +}
src/main/java/cn/iocoder/dashboard/modules/system/convert/user/SysUserConvert.java
@@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.convert.user; @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.convert.user;
2 2
3 import cn.iocoder.dashboard.common.pojo.PageResult; 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO; 4 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExcelVO;
5 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO; 6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
7 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; 8 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
@@ -27,4 +28,6 @@ public interface SysUserConvert { @@ -27,4 +28,6 @@ public interface SysUserConvert {
27 28
28 SysUserDO convert(SysUserUpdateReqVO bean); 29 SysUserDO convert(SysUserUpdateReqVO bean);
29 30
  31 + SysUserExcelVO convert02(SysUserDO bean);
  32 +
30 } 33 }
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/user/SysUserMapper.java
@@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dao.user; @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dao.user;
2 2
3 import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX; 3 import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
4 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils; 4 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
5 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO; 6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
6 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; 7 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
7 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 8 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; @@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
9 import com.baomidou.mybatisplus.core.metadata.IPage; 10 import com.baomidou.mybatisplus.core.metadata.IPage;
10 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
11 12
  13 +import java.util.Collection;
12 import java.util.List; 14 import java.util.List;
13 15
14 @Mapper 16 @Mapper
@@ -26,7 +28,7 @@ public interface SysUserMapper extends BaseMapper&lt;SysUserDO&gt; { @@ -26,7 +28,7 @@ public interface SysUserMapper extends BaseMapper&lt;SysUserDO&gt; {
26 return selectOne(new QueryWrapper<SysUserDO>().eq("email", email)); 28 return selectOne(new QueryWrapper<SysUserDO>().eq("email", email));
27 } 29 }
28 30
29 - default IPage<SysUserDO> selectList(SysUserPageReqVO reqVO, List<Long> deptIds) { 31 + default IPage<SysUserDO> selectList(SysUserPageReqVO reqVO, Collection<Long> deptIds) {
30 return selectPage(MyBatisUtils.buildPage(reqVO), 32 return selectPage(MyBatisUtils.buildPage(reqVO),
31 new QueryWrapperX<SysUserDO>().likeIfPresent("username", reqVO.getUsername()) 33 new QueryWrapperX<SysUserDO>().likeIfPresent("username", reqVO.getUsername())
32 .likeIfPresent("mobile", reqVO.getMobile()) 34 .likeIfPresent("mobile", reqVO.getMobile())
@@ -35,5 +37,13 @@ public interface SysUserMapper extends BaseMapper&lt;SysUserDO&gt; { @@ -35,5 +37,13 @@ public interface SysUserMapper extends BaseMapper&lt;SysUserDO&gt; {
35 .inIfPresent("dept_id", deptIds)); 37 .inIfPresent("dept_id", deptIds));
36 } 38 }
37 39
  40 + default List<SysUserDO> selectList(SysUserExportReqVO reqVO, Collection<Long> deptIds) {
  41 + return selectList(new QueryWrapperX<SysUserDO>().likeIfPresent("username", reqVO.getUsername())
  42 + .likeIfPresent("mobile", reqVO.getMobile())
  43 + .eqIfPresent("status", reqVO.getStatus())
  44 + .betweenIfPresent("create_time", reqVO.getBeginTime(), reqVO.getEndTime())
  45 + .inIfPresent("dept_id", deptIds));
  46 + }
  47 +
38 } 48 }
39 49
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptService.java
1 package cn.iocoder.dashboard.modules.system.service.dept; 1 package cn.iocoder.dashboard.modules.system.service.dept;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptCreateReqVO; 4 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptCreateReqVO;
4 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO; 5 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
5 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptUpdateReqVO; 6 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptUpdateReqVO;
6 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; 7 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
  8 +import cn.iocoder.dashboard.util.collection.CollectionUtils;
7 9
8 import java.util.Collection; 10 import java.util.Collection;
  11 +import java.util.Collections;
9 import java.util.List; 12 import java.util.List;
  13 +import java.util.Map;
10 14
11 /** 15 /**
12 * 部门 Service 接口 16 * 部门 Service 接口
@@ -36,6 +40,20 @@ public interface SysDeptService { @@ -36,6 +40,20 @@ public interface SysDeptService {
36 List<SysDeptDO> listDepts(Collection<Long> ids); 40 List<SysDeptDO> listDepts(Collection<Long> ids);
37 41
38 /** 42 /**
  43 + * 获得指定编号的部门 Map
  44 + *
  45 + * @param ids 部门编号数组
  46 + * @return 部门 Map
  47 + */
  48 + default Map<Long, SysDeptDO> getDeptMap(Collection<Long> ids) {
  49 + if (CollUtil.isEmpty(ids)) {
  50 + return Collections.emptyMap();
  51 + }
  52 + List<SysDeptDO> list = listDepts(ids);
  53 + return CollectionUtils.convertMap(list, SysDeptDO::getId);
  54 + }
  55 +
  56 + /**
39 * 筛选部门列表 57 * 筛选部门列表
40 * 58 *
41 * @param reqVO 筛选条件请求 VO 59 * @param reqVO 筛选条件请求 VO
src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
@@ -15,6 +15,7 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService; @@ -15,6 +15,7 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService;
15 import com.google.common.collect.ImmutableTable; 15 import com.google.common.collect.ImmutableTable;
16 import org.springframework.stereotype.Service; 16 import org.springframework.stereotype.Service;
17 17
  18 +import javax.annotation.PostConstruct;
18 import javax.annotation.Resource; 19 import javax.annotation.Resource;
19 import java.util.ArrayList; 20 import java.util.ArrayList;
20 import java.util.Comparator; 21 import java.util.Comparator;
@@ -56,6 +57,7 @@ public class SysDictDataServiceImpl implements SysDictDataService { @@ -56,6 +57,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
56 private SysDictDataMapper dictDataMapper; 57 private SysDictDataMapper dictDataMapper;
57 58
58 @Override 59 @Override
  60 + @PostConstruct
59 public void init() { 61 public void init() {
60 // 获得字典数据 62 // 获得字典数据
61 List<SysDictDataDO> list = this.listDictDatas(); 63 List<SysDictDataDO> list = this.listDictDatas();
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
@@ -2,23 +2,19 @@ package cn.iocoder.dashboard.modules.system.service.user; @@ -2,23 +2,19 @@ package cn.iocoder.dashboard.modules.system.service.user;
2 2
3 import cn.iocoder.dashboard.common.pojo.PageResult; 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO; 4 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
5 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO; 6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
7 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; 8 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
8 9
  10 +import java.util.List;
  11 +
9 /** 12 /**
10 * 用户 Service 接口 13 * 用户 Service 接口
11 * 14 *
12 * @author 芋道源码 15 * @author 芋道源码
13 */ 16 */
14 public interface SysUserService { 17 public interface SysUserService {
15 -// /**  
16 -// * 根据条件分页查询用户列表  
17 -// *  
18 -// * @param user 用户信息  
19 -// * @return 用户信息集合信息  
20 -// */  
21 -// public List<SysUser> selectUserList(SysUser user);  
22 18
23 /** 19 /**
24 * 通过用户名查询用户 20 * 通过用户名查询用户
@@ -45,6 +41,14 @@ public interface SysUserService { @@ -45,6 +41,14 @@ public interface SysUserService {
45 PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO); 41 PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO);
46 42
47 /** 43 /**
  44 + * 获得用户列表
  45 + *
  46 + * @param reqVO 列表请求
  47 + * @return 用户列表
  48 + */
  49 + List<SysUserDO> listUsers(SysUserExportReqVO reqVO);
  50 +
  51 + /**
48 * 创建用户 52 * 创建用户
49 * 53 *
50 * @param reqVO 用户信息 54 * @param reqVO 用户信息
@@ -84,77 +88,6 @@ public interface SysUserService { @@ -84,77 +88,6 @@ public interface SysUserService {
84 88
85 // 89 //
86 // /** 90 // /**
87 -// * 根据用户ID查询用户所属角色组  
88 -// *  
89 -// * @param userName 用户名  
90 -// * @return 结果  
91 -// */  
92 -// public String selectUserRoleGroup(String userName);  
93 -//  
94 -// /**  
95 -// * 根据用户ID查询用户所属岗位组  
96 -// *  
97 -// * @param userName 用户名  
98 -// * @return 结果  
99 -// */  
100 -// public String selectUserPostGroup(String userName);  
101 -//  
102 -// /**  
103 -// * 校验用户名称是否唯一  
104 -// *  
105 -// * @param userName 用户名称  
106 -// * @return 结果  
107 -// */  
108 -// public String checkUserNameUnique(String userName);  
109 -//  
110 -// /**  
111 -// * 校验手机号码是否唯一  
112 -// *  
113 -// * @param user 用户信息  
114 -// * @return 结果  
115 -// */  
116 -// public String checkPhoneUnique(SysUser user);  
117 -//  
118 -// /**  
119 -// * 校验email是否唯一  
120 -// *  
121 -// * @param user 用户信息  
122 -// * @return 结果  
123 -// */  
124 -// public String checkEmailUnique(SysUser user);  
125 -//  
126 -// /**  
127 -// * 校验用户是否允许操作  
128 -// *  
129 -// * @param user 用户信息  
130 -// */  
131 -// public void checkUserAllowed(SysUser user);  
132 -//  
133 -// /**  
134 -// * 新增用户信息  
135 -// *  
136 -// * @param user 用户信息  
137 -// * @return 结果  
138 -// */  
139 -// public int insertUser(SysUser user);  
140 -//  
141 -// /**  
142 -// * 修改用户信息  
143 -// *  
144 -// * @param user 用户信息  
145 -// * @return 结果  
146 -// */  
147 -// public int updateUser(SysUser user);  
148 -//  
149 -// /**  
150 -// * 修改用户状态  
151 -// *  
152 -// * @param user 用户信息  
153 -// * @return 结果  
154 -// */  
155 -// public int updateUserStatus(SysUser user);  
156 -//  
157 -// /**  
158 // * 修改用户基本信息 91 // * 修改用户基本信息
159 // * 92 // *
160 // * @param user 用户信息 93 // * @param user 用户信息
@@ -187,22 +120,7 @@ public interface SysUserService { @@ -187,22 +120,7 @@ public interface SysUserService {
187 // * @return 结果 120 // * @return 结果
188 // */ 121 // */
189 // public int resetUserPwd(String userName, String password); 122 // public int resetUserPwd(String userName, String password);
190 -//  
191 -// /**  
192 -// * 通过用户ID删除用户  
193 -// *  
194 -// * @param userId 用户ID  
195 -// * @return 结果  
196 -// */  
197 -// public int deleteUserById(Long userId);  
198 -//  
199 -// /**  
200 -// * 批量删除用户信息  
201 -// *  
202 -// * @param userIds 需要删除的用户ID  
203 -// * @return 结果  
204 -// */  
205 -// public int deleteUserByIds(Long[] userIds); 123 +
206 // 124 //
207 // /** 125 // /**
208 // * 导入用户数据 126 // * 导入用户数据
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
@@ -6,6 +6,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum; @@ -6,6 +6,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
6 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; 6 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
7 import cn.iocoder.dashboard.common.pojo.PageResult; 7 import cn.iocoder.dashboard.common.pojo.PageResult;
8 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO; 8 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
  9 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
9 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO; 10 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
10 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; 11 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
11 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert; 12 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
@@ -77,15 +78,29 @@ public class SysUserServiceImpl implements SysUserService { @@ -77,15 +78,29 @@ public class SysUserServiceImpl implements SysUserService {
77 78
78 @Override 79 @Override
79 public PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO) { 80 public PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO) {
80 - // 处理部门查询条件  
81 - List<Long> deptIds = Collections.emptyList();  
82 - if (reqVO.getDeptId() != null) {  
83 - deptIds = CollectionUtils.convertList(deptService.listDeptsByParentIdFromCache(  
84 - reqVO.getDeptId(), true), SysDeptDO::getId);  
85 - deptIds.add(reqVO.getDeptId()); 81 + return SysUserConvert.INSTANCE.convertPage(userMapper.selectList(reqVO,
  82 + this.getDeptCondition(reqVO.getDeptId())));
  83 + }
  84 +
  85 + @Override
  86 + public List<SysUserDO> listUsers(SysUserExportReqVO reqVO) {
  87 + return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
  88 + }
  89 +
  90 + /**
  91 + * 获得部门条件:查询指定部门的子部门编号们,包括自身
  92 + *
  93 + * @param deptId 部门编号
  94 + * @return 部门编号集合
  95 + */
  96 + private Set<Long> getDeptCondition(Long deptId) {
  97 + if (deptId == null) {
  98 + return Collections.emptySet();
86 } 99 }
87 - // 执行查询  
88 - return SysUserConvert.INSTANCE.convertPage(userMapper.selectList(reqVO, deptIds)); 100 + Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache(
  101 + deptId, true), SysDeptDO::getId);
  102 + deptIds.add(deptId); // 包括自身
  103 + return deptIds;
89 } 104 }
90 105
91 @Override 106 @Override
src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java
1 package cn.iocoder.dashboard.util.collection; 1 package cn.iocoder.dashboard.util.collection;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.collection.CollectionUtil; 4 import cn.hutool.core.collection.CollectionUtil;
4 5
5 import java.util.*; 6 import java.util.*;
@@ -19,37 +20,61 @@ public class CollectionUtils { @@ -19,37 +20,61 @@ public class CollectionUtils {
19 } 20 }
20 21
21 public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) { 22 public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) {
  23 + if (CollUtil.isEmpty(from)) {
  24 + return new ArrayList<>();
  25 + }
22 return from.stream().filter(predicate).collect(Collectors.toList()); 26 return from.stream().filter(predicate).collect(Collectors.toList());
23 } 27 }
24 28
25 public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) { 29 public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) {
  30 + if (CollUtil.isEmpty(from)) {
  31 + return new ArrayList<>();
  32 + }
26 return from.stream().map(func).collect(Collectors.toList()); 33 return from.stream().map(func).collect(Collectors.toList());
27 } 34 }
28 35
29 public static <T, U> Set<U> convertSet(List<T> from, Function<T, U> func) { 36 public static <T, U> Set<U> convertSet(List<T> from, Function<T, U> func) {
  37 + if (CollUtil.isEmpty(from)) {
  38 + return new HashSet<>();
  39 + }
30 return from.stream().map(func).collect(Collectors.toSet()); 40 return from.stream().map(func).collect(Collectors.toSet());
31 } 41 }
32 42
33 public static <T, K> Map<K, T> convertMap(List<T> from, Function<T, K> keyFunc) { 43 public static <T, K> Map<K, T> convertMap(List<T> from, Function<T, K> keyFunc) {
  44 + if (CollUtil.isEmpty(from)) {
  45 + return new HashMap<>();
  46 + }
34 return from.stream().collect(Collectors.toMap(keyFunc, item -> item)); 47 return from.stream().collect(Collectors.toMap(keyFunc, item -> item));
35 } 48 }
36 49
37 public static <T, K, V> Map<K, V> convertMap(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) { 50 public static <T, K, V> Map<K, V> convertMap(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
  51 + if (CollUtil.isEmpty(from)) {
  52 + return new HashMap<>();
  53 + }
38 return from.stream().collect(Collectors.toMap(keyFunc, valueFunc)); 54 return from.stream().collect(Collectors.toMap(keyFunc, valueFunc));
39 } 55 }
40 56
41 public static <T, K> Map<K, List<T>> convertMultiMap(List<T> from, Function<T, K> keyFunc) { 57 public static <T, K> Map<K, List<T>> convertMultiMap(List<T> from, Function<T, K> keyFunc) {
  58 + if (CollUtil.isEmpty(from)) {
  59 + return new HashMap<>();
  60 + }
42 return from.stream().collect(Collectors.groupingBy(keyFunc, 61 return from.stream().collect(Collectors.groupingBy(keyFunc,
43 Collectors.mapping(t -> t, Collectors.toList()))); 62 Collectors.mapping(t -> t, Collectors.toList())));
44 } 63 }
45 64
46 public static <T, K, V> Map<K, List<V>> convertMultiMap(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) { 65 public static <T, K, V> Map<K, List<V>> convertMultiMap(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
  66 + if (CollUtil.isEmpty(from)) {
  67 + return new HashMap<>();
  68 + }
47 return from.stream().collect(Collectors.groupingBy(keyFunc, 69 return from.stream().collect(Collectors.groupingBy(keyFunc,
48 Collectors.mapping(valueFunc, Collectors.toList()))); 70 Collectors.mapping(valueFunc, Collectors.toList())));
49 } 71 }
50 72
51 // 暂时没想好名字,先以 2 结尾噶 73 // 暂时没想好名字,先以 2 结尾噶
52 public static <T, K, V> Map<K, Set<V>> convertMultiMap2(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) { 74 public static <T, K, V> Map<K, Set<V>> convertMultiMap2(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
  75 + if (CollUtil.isEmpty(from)) {
  76 + return new HashMap<>();
  77 + }
53 return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toSet()))); 78 return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toSet())));
54 } 79 }
55 80
src/main/java/cn/iocoder/dashboard/util/collection/MapUtils.java
1 package cn.iocoder.dashboard.util.collection; 1 package cn.iocoder.dashboard.util.collection;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.collection.CollectionUtil; 4 import cn.hutool.core.collection.CollectionUtil;
4 import com.google.common.collect.Multimap; 5 import com.google.common.collect.Multimap;
5 6
6 import java.util.ArrayList; 7 import java.util.ArrayList;
7 import java.util.Collection; 8 import java.util.Collection;
8 import java.util.List; 9 import java.util.List;
  10 +import java.util.Map;
  11 +import java.util.function.Consumer;
9 12
10 /** 13 /**
11 * Map 工具类 14 * Map 工具类
@@ -14,6 +17,13 @@ import java.util.List; @@ -14,6 +17,13 @@ import java.util.List;
14 */ 17 */
15 public class MapUtils { 18 public class MapUtils {
16 19
  20 + /**
  21 + * 从哈希表表中,获得 keys 对应的所有 value 数组
  22 + *
  23 + * @param multimap 哈希表
  24 + * @param keys keys
  25 + * @return value 数组
  26 + */
17 public static <K, V> List<V> getList(Multimap<K, V> multimap, Collection<K> keys) { 27 public static <K, V> List<V> getList(Multimap<K, V> multimap, Collection<K> keys) {
18 List<V> result = new ArrayList<>(); 28 List<V> result = new ArrayList<>();
19 keys.forEach(k -> { 29 keys.forEach(k -> {
@@ -26,4 +36,23 @@ public class MapUtils { @@ -26,4 +36,23 @@ public class MapUtils {
26 return result; 36 return result;
27 } 37 }
28 38
  39 + /**
  40 + * 从哈希表查找到 key 对应的 value,然后进一步处理
  41 + * 注意,如果查找到的 value 为 null 时,不进行处理
  42 + *
  43 + * @param map 哈希表
  44 + * @param key key
  45 + * @param consumer 进一步处理的逻辑
  46 + */
  47 + public static <K, V> void findAndThen(Map<K, V> map, K key, Consumer<V> consumer) {
  48 + if (CollUtil.isEmpty(map)) {
  49 + return;
  50 + }
  51 + V value = map.get(key);
  52 + if (value == null) {
  53 + return;
  54 + }
  55 + consumer.accept(value);
  56 + }
  57 +
29 } 58 }