Commit f942b34d02928e65aea16e49036e9b230fb4f7e1

Authored by YunaiV
1 parent 02ff516f

1. 完成用户导出的功能

2. 完成前后端的导出的封装
ruoyi-ui/src/main.js
... ... @@ -16,7 +16,7 @@ import './assets/icons' // icon
16 16 import './permission' // permission control
17 17 import { getDicts } from "@/api/system/dict/data";
18 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 20 import Pagination from "@/components/Pagination";
21 21 // 自定义表格工具扩展
22 22 import RightToolbar from "@/components/RightToolbar"
... ... @@ -33,6 +33,7 @@ Vue.prototype.addDateRange = addDateRange
33 33 Vue.prototype.selectDictLabel = selectDictLabel
34 34 Vue.prototype.selectDictLabels = selectDictLabels
35 35 Vue.prototype.download = download
  36 +Vue.prototype.downloadExcel = downloadExcel
36 37 Vue.prototype.handleTree = handleTree
37 38  
38 39 Vue.prototype.msgSuccess = function (msg) {
... ...
ruoyi-ui/src/utils/ruoyi.js
... ... @@ -101,6 +101,21 @@ export function download(fileName) {
101 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 119 // 字符串格式化(%s )
105 120 export function sprintf(str) {
106 121 var args = arguments, flag = true, i = 1;
... ...
ruoyi-ui/src/views/system/user/index.vue
... ... @@ -510,7 +510,7 @@ export default {
510 510 this.reset();
511 511 },
512 512 // 取消按钮(角色权限)
513   - cancelMenu() {
  513 + cancelRole() {
514 514 this.openRole = false;
515 515 this.reset();
516 516 },
... ... @@ -647,7 +647,10 @@ export default {
647 647 },
648 648 /** 导出按钮操作 */
649 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 654 this.$confirm('是否确认导出所有用户数据项?', "警告", {
652 655 confirmButtonText: "确定",
653 656 cancelButtonText: "取消",
... ... @@ -655,15 +658,7 @@ export default {
655 658 }).then(function() {
656 659 return exportUser(queryParams);
657 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 54 return null;
55 55 }
56 56 // 生成 Excel 小表格
57   - return new CellData<>(dictData.getValue());
  57 + return new CellData<>(dictData.getLabel());
58 58 }
59 59  
60 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 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.dashboard.common.pojo.CommonResult;
5 5 import cn.iocoder.dashboard.common.pojo.PageResult;
  6 +import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils;
6 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
7 8 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
8 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 11 import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
11 12 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
12 13 import cn.iocoder.dashboard.util.collection.CollectionUtils;
13   -import com.alibaba.excel.EasyExcel;
  14 +import cn.iocoder.dashboard.util.collection.MapUtils;
14 15 import io.swagger.annotations.Api;
15 16 import io.swagger.annotations.ApiImplicitParam;
16 17 import io.swagger.annotations.ApiOperation;
... ... @@ -20,7 +21,10 @@ import org.springframework.web.bind.annotation.*;
20 21 import javax.annotation.Resource;
21 22 import javax.servlet.http.HttpServletResponse;
22 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 29 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
26 30  
... ... @@ -37,7 +41,7 @@ public class SysUserController {
37 41 @ApiOperation("获得用户分页列表")
38 42 @GetMapping("/page")
39 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 46 PageResult<SysUserDO> pageResult = userService.pageUsers(reqVO);
43 47 if (CollUtil.isEmpty(pageResult.getList())) {
... ... @@ -45,13 +49,8 @@ public class SysUserController {
45 49 }
46 50  
47 51 // 获得拼接需要的数据
48   - Map<Long, SysDeptDO> deptMap;
49 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 55 List<SysUserPageItemRespVO> userList = new ArrayList<>(pageResult.getList().size());
57 56 pageResult.getList().forEach(user -> {
... ... @@ -121,11 +120,29 @@ public class SysUserController {
121 120  
122 121 @ApiOperation("导出用户")
123 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 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 22 @ExcelProperty("用户名称")
23 23 private String username;
24 24  
25   - @ExcelProperty("用户名称")
  25 + @ExcelProperty("用户昵称")
26 26 private String nickname;
27 27  
28 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 2  
3 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 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 6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
6 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
7 8 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
... ... @@ -27,4 +28,6 @@ public interface SysUserConvert {
27 28  
28 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 2  
3 3 import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
4 4 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
5 6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
6 7 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
7 8 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
... ... @@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
9 10 import com.baomidou.mybatisplus.core.metadata.IPage;
10 11 import org.apache.ibatis.annotations.Mapper;
11 12  
  13 +import java.util.Collection;
12 14 import java.util.List;
13 15  
14 16 @Mapper
... ... @@ -26,7 +28,7 @@ public interface SysUserMapper extends BaseMapper&lt;SysUserDO&gt; {
26 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 32 return selectPage(MyBatisUtils.buildPage(reqVO),
31 33 new QueryWrapperX<SysUserDO>().likeIfPresent("username", reqVO.getUsername())
32 34 .likeIfPresent("mobile", reqVO.getMobile())
... ... @@ -35,5 +37,13 @@ public interface SysUserMapper extends BaseMapper&lt;SysUserDO&gt; {
35 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 1 package cn.iocoder.dashboard.modules.system.service.dept;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptCreateReqVO;
4 5 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
5 6 import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptUpdateReqVO;
6 7 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
  8 +import cn.iocoder.dashboard.util.collection.CollectionUtils;
7 9  
8 10 import java.util.Collection;
  11 +import java.util.Collections;
9 12 import java.util.List;
  13 +import java.util.Map;
10 14  
11 15 /**
12 16 * 部门 Service 接口
... ... @@ -36,6 +40,20 @@ public interface SysDeptService {
36 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 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 15 import com.google.common.collect.ImmutableTable;
16 16 import org.springframework.stereotype.Service;
17 17  
  18 +import javax.annotation.PostConstruct;
18 19 import javax.annotation.Resource;
19 20 import java.util.ArrayList;
20 21 import java.util.Comparator;
... ... @@ -56,6 +57,7 @@ public class SysDictDataServiceImpl implements SysDictDataService {
56 57 private SysDictDataMapper dictDataMapper;
57 58  
58 59 @Override
  60 + @PostConstruct
59 61 public void init() {
60 62 // 获得字典数据
61 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 2  
3 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 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 6 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
6 7 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
7 8 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
8 9  
  10 +import java.util.List;
  11 +
9 12 /**
10 13 * 用户 Service 接口
11 14 *
12 15 * @author 芋道源码
13 16 */
14 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 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 54 * @param reqVO 用户信息
... ... @@ -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 93 // * @param user 用户信息
... ... @@ -187,22 +120,7 @@ public interface SysUserService {
187 120 // * @return 结果
188 121 // */
189 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 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
7 7 import cn.iocoder.dashboard.common.pojo.PageResult;
8 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 10 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
10 11 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
11 12 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
... ... @@ -77,15 +78,29 @@ public class SysUserServiceImpl implements SysUserService {
77 78  
78 79 @Override
79 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 106 @Override
... ...
src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java
1 1 package cn.iocoder.dashboard.util.collection;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.collection.CollectionUtil;
4 5  
5 6 import java.util.*;
... ... @@ -19,37 +20,61 @@ public class CollectionUtils {
19 20 }
20 21  
21 22 public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) {
  23 + if (CollUtil.isEmpty(from)) {
  24 + return new ArrayList<>();
  25 + }
22 26 return from.stream().filter(predicate).collect(Collectors.toList());
23 27 }
24 28  
25 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 33 return from.stream().map(func).collect(Collectors.toList());
27 34 }
28 35  
29 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 40 return from.stream().map(func).collect(Collectors.toSet());
31 41 }
32 42  
33 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 47 return from.stream().collect(Collectors.toMap(keyFunc, item -> item));
35 48 }
36 49  
37 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 54 return from.stream().collect(Collectors.toMap(keyFunc, valueFunc));
39 55 }
40 56  
41 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 61 return from.stream().collect(Collectors.groupingBy(keyFunc,
43 62 Collectors.mapping(t -> t, Collectors.toList())));
44 63 }
45 64  
46 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 69 return from.stream().collect(Collectors.groupingBy(keyFunc,
48 70 Collectors.mapping(valueFunc, Collectors.toList())));
49 71 }
50 72  
51 73 // 暂时没想好名字,先以 2 结尾噶
52 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 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 1 package cn.iocoder.dashboard.util.collection;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.collection.CollectionUtil;
4 5 import com.google.common.collect.Multimap;
5 6  
6 7 import java.util.ArrayList;
7 8 import java.util.Collection;
8 9 import java.util.List;
  10 +import java.util.Map;
  11 +import java.util.function.Consumer;
9 12  
10 13 /**
11 14 * Map 工具类
... ... @@ -14,6 +17,13 @@ import java.util.List;
14 17 */
15 18 public class MapUtils {
16 19  
  20 + /**
  21 + * 从哈希表表中,获得 keys 对应的所有 value 数组
  22 + *
  23 + * @param multimap 哈希表
  24 + * @param keys keys
  25 + * @return value 数组
  26 + */
17 27 public static <K, V> List<V> getList(Multimap<K, V> multimap, Collection<K> keys) {
18 28 List<V> result = new ArrayList<>();
19 29 keys.forEach(k -> {
... ... @@ -26,4 +36,23 @@ public class MapUtils {
26 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 }
... ...