From 0ccaf15f409290c5794bb72fec038dc2e5e613f0 Mon Sep 17 00:00:00 2001 From: xuyuxiang Date: Mon, 6 Mar 2023 17:01:29 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=9B=B4=E6=96=B0=E3=80=91=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E7=94=A8=E6=88=B7=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/SysUserController.java | 43 ++++++++++-- .../sys/modular/user/entity/SysUser.java | 3 + .../modular/user/service/SysUserService.java | 16 +++++ .../user/service/impl/SysUserServiceImpl.java | 62 ++++++++++++++++++ .../main/resources/userExportTemplate.docx | Bin 0 -> 18188 bytes 5 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 snowy-plugin/snowy-plugin-sys/src/main/resources/userExportTemplate.docx diff --git a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/controller/SysUserController.java b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/controller/SysUserController.java index f3e5ec3f..9ee2df36 100644 --- a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/controller/SysUserController.java +++ b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/controller/SysUserController.java @@ -259,12 +259,27 @@ public class SysUserController { } /** - * 用户导入 + * 下载用户导入模板 * * @author xuyuxiang * @date 2022/4/24 20:00 */ @ApiOperationSupport(order = 15) + @ApiOperation("下载用户导入模板") + @CommonLog("下载用户导入模板") + @PostMapping(value = "/sys/user/downloadImportUserTemplate", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) + public CommonResult downloadImportUserTemplate(HttpServletResponse response) throws IOException { + sysUserService.downloadImportUserTemplate(response); + return CommonResult.ok(); + } + + /** + * 用户导入 + * + * @author xuyuxiang + * @date 2022/4/24 20:00 + */ + @ApiOperationSupport(order = 16) @ApiOperation("用户导入") @CommonLog("用户导入") @PostMapping("/sys/user/import") @@ -279,7 +294,7 @@ public class SysUserController { * @author xuyuxiang * @date 2022/4/24 20:00 */ - @ApiOperationSupport(order = 16) + @ApiOperationSupport(order = 17) @ApiOperation("用户导出") @CommonLog("用户导出") @GetMapping(value = "/sys/user/export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @@ -287,6 +302,20 @@ public class SysUserController { sysUserService.exportUser(sysUserExportParam, response); } + /** + * 按模板导出用户个人信息 + * + * @author xuyuxiang + * @date 2022/4/24 20:00 + */ + @ApiOperationSupport(order = 18) + @ApiOperation("导出用户个人信息") + @CommonLog("导出用户个人信息") + @GetMapping(value = "/sys/user/exportUserInfo", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) + public void exportUserInfo(SysUserIdParam sysUserIdParam, HttpServletResponse response) throws IOException { + sysUserService.exportUserInfo(sysUserIdParam, response); + } + /* ====用户部分所需要用到的选择器==== */ /** @@ -295,7 +324,7 @@ public class SysUserController { * @author xuyuxiang * @date 2022/4/24 20:00 */ - @ApiOperationSupport(order = 17) + @ApiOperationSupport(order = 19) @ApiOperation("获取组织树选择器") @GetMapping("/sys/user/orgTreeSelector") public CommonResult>> orgTreeSelector() { @@ -308,7 +337,7 @@ public class SysUserController { * @author xuyuxiang * @date 2022/4/24 20:00 */ - @ApiOperationSupport(order = 18) + @ApiOperationSupport(order = 20) @ApiOperation("获取组织列表选择器") @GetMapping("/sys/user/orgListSelector") public CommonResult> orgListSelector(SysUserSelectorOrgListParam sysUserSelectorOrgListParam) { @@ -321,7 +350,7 @@ public class SysUserController { * @author xuyuxiang * @date 2022/4/24 20:00 */ - @ApiOperationSupport(order = 19) + @ApiOperationSupport(order = 21) @ApiOperation("获取职位选择器") @GetMapping("/sys/user/positionSelector") public CommonResult> positionSelector(SysUserSelectorPositionParam sysUserSelectorPositionParam) { @@ -334,7 +363,7 @@ public class SysUserController { * @author xuyuxiang * @date 2022/4/24 20:00 */ - @ApiOperationSupport(order = 20) + @ApiOperationSupport(order = 22) @ApiOperation("获取角色选择器") @GetMapping("/sys/user/roleSelector") public CommonResult> roleSelector(SysUserSelectorRoleParam sysUserSelectorRoleParam) { @@ -347,7 +376,7 @@ public class SysUserController { * @author xuyuxiang * @date 2022/4/24 20:00 */ - @ApiOperationSupport(order = 21) + @ApiOperationSupport(order = 23) @ApiOperation("获取用户选择器") @GetMapping("/sys/user/userSelector") public CommonResult> userSelector(SysUserSelectorUserParam sysUserSelectorUserParam) { diff --git a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/entity/SysUser.java b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/entity/SysUser.java index dc700afc..fbb61edd 100644 --- a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/entity/SysUser.java +++ b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/entity/SysUser.java @@ -266,14 +266,17 @@ public class SysUser extends CommonEntity implements TransPojo { @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) private String extJson; + /** 组织名称 */ @ApiModelProperty(value = "组织名称", position = 48) @TableField(exist = false) private String orgName; + /** 职位名称 */ @ApiModelProperty(value = "职位名称", position = 49) @TableField(exist = false) private String positionName; + /** 主管名称 */ @ApiModelProperty(value = "主管名称", position = 50) @TableField(exist = false) private String directorName; diff --git a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/SysUserService.java b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/SysUserService.java index 4f417aca..9473760c 100644 --- a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/SysUserService.java +++ b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/SysUserService.java @@ -340,6 +340,14 @@ public interface SysUserService extends IService { **/ List getPermissionList(List userAndRoleIdList, String orgId); + /** + * 下载用户导入模板 + * + * @author xuyuxiang + * @date 2022/8/8 13:16 + **/ + void downloadImportUserTemplate(HttpServletResponse response) throws IOException; + /** * 用户导入 * @@ -356,6 +364,14 @@ public interface SysUserService extends IService { **/ void exportUser(SysUserExportParam sysUserExportParam, HttpServletResponse response) throws IOException; + /** + * 导出用户个人信息 + * + * @author xuyuxiang + * @date 2022/8/8 13:16 + **/ + void exportUserInfo(SysUserIdParam sysUserIdParam, HttpServletResponse response) throws IOException; + /** * 获取登录用户的职位信息 * diff --git a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java index 449588f7..33bc825b 100644 --- a/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java +++ b/snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java @@ -12,6 +12,9 @@ */ package vip.xiaonuo.sys.modular.user.service.impl; +import cn.afterturn.easypoi.cache.manager.POICacheManager; +import cn.afterturn.easypoi.entity.ImageEntity; +import cn.afterturn.easypoi.word.WordExportUtil; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.CircleCaptcha; @@ -19,9 +22,12 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollStreamUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.img.ImgUtil; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNode; import cn.hutool.core.lang.tree.TreeNodeConfig; @@ -51,6 +57,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fhs.trans.service.impl.TransService; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -94,8 +101,10 @@ import vip.xiaonuo.sys.modular.user.service.SysUserService; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.*; import java.util.stream.Collectors; @@ -958,6 +967,18 @@ public class SysUserServiceImpl extends ServiceImpl impl return resultList; } + @Override + public void downloadImportUserTemplate(HttpServletResponse response) throws IOException { + try { + InputStream inputStream = POICacheManager.getFile("userImportTemplate.xlsx"); + byte[] bytes = IoUtil.readBytes(inputStream); + CommonDownloadUtil.download("SNOWY2.0系统B端用户导入模板.xlsx", bytes, response); + } catch (Exception e) { + e.printStackTrace(); + CommonResponseUtil.renderError(response, "导出失败"); + } + } + @Override public void importUser(MultipartFile file) { // TODO @@ -1089,6 +1110,47 @@ public class SysUserServiceImpl extends ServiceImpl impl } } + @Override + public void exportUserInfo(SysUserIdParam sysUserIdParam, HttpServletResponse response) throws IOException { + File destTemplateFile = null; + File resultFile = null; + try { + SysUser sysUser = this.queryEntity(sysUserIdParam.getId()); + transService.transOne(sysUser); + // 读取模板流 + InputStream inputStream = POICacheManager.getFile("userExportTemplate.docx"); + // 创建一个临时模板 + destTemplateFile = FileUtil.writeFromStream(inputStream, FileUtil.file(FileUtil.getTmpDir() + + File.separator + "userExportTemplate.docx")); + // 构造填充的参数 + Map map = BeanUtil.beanToMap(sysUser); + map.put("avatar", new ImageEntity(ImgUtil.toBytes(ImgUtil.toImage(StrUtil.split(sysUser.getAvatar(), + StrUtil.COMMA).get(1)), ImgUtil.IMAGE_TYPE_PNG), 120, 160)); + map.put("exportDateTime", DateUtil.format(DateTime.now(), DatePattern.CHINESE_DATE_PATTERN)); + // 生成doc + XWPFDocument doc = WordExportUtil.exportWord07(destTemplateFile.getAbsolutePath(), map); + // 生成临时导出文件 + resultFile = FileUtil.file(FileUtil.getTmpDir() + File.separator + sysUser.getName() + "个人信息.docx"); + // 写入 + BufferedOutputStream outputStream = FileUtil.getOutputStream(resultFile); + doc.write(outputStream); + outputStream.close(); + // 下载 + CommonDownloadUtil.download(resultFile, response); + } catch (Exception e) { + e.printStackTrace(); + CommonResponseUtil.renderError(response, "导出失败"); + } finally { + // 删除临时文件 + if(ObjectUtil.isNotEmpty(destTemplateFile)) { + FileUtil.del(destTemplateFile); + } + if(ObjectUtil.isNotEmpty(resultFile)) { + FileUtil.del(resultFile); + } + } + } + @Override public List loginPositionInfo(SysUserIdParam sysUserIdParam) { SysUser sysUser = this.queryEntity(sysUserIdParam.getId()); diff --git a/snowy-plugin/snowy-plugin-sys/src/main/resources/userExportTemplate.docx b/snowy-plugin/snowy-plugin-sys/src/main/resources/userExportTemplate.docx new file mode 100644 index 0000000000000000000000000000000000000000..acd4457534407dfff21870aec395e5144aa6ad6e GIT binary patch literal 18188 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 literal 0 HcmV?d00001