mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-30 18:16:57 +08:00 
			
		
		
		
	Merge branch 'master' into ut_infra_logger
This commit is contained in:
		| @ -1,6 +1,11 @@ | |||||||
| package cn.iocoder.dashboard.modules.infra.controller.doc; | package cn.iocoder.dashboard.modules.infra.controller.doc; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.io.FileUtil; | ||||||
|  | import cn.hutool.core.io.IoUtil; | ||||||
|  | import cn.hutool.core.lang.UUID; | ||||||
|  | import cn.hutool.core.util.IdUtil; | ||||||
| import cn.hutool.extra.servlet.ServletUtil; | import cn.hutool.extra.servlet.ServletUtil; | ||||||
|  | import cn.iocoder.dashboard.util.servlet.ServletUtils; | ||||||
| import cn.smallbun.screw.core.Configuration; | import cn.smallbun.screw.core.Configuration; | ||||||
| import cn.smallbun.screw.core.engine.EngineConfig; | import cn.smallbun.screw.core.engine.EngineConfig; | ||||||
| import cn.smallbun.screw.core.engine.EngineFileType; | import cn.smallbun.screw.core.engine.EngineFileType; | ||||||
| @ -10,18 +15,20 @@ import cn.smallbun.screw.core.process.ProcessConfig; | |||||||
| import com.zaxxer.hikari.HikariConfig; | import com.zaxxer.hikari.HikariConfig; | ||||||
| import com.zaxxer.hikari.HikariDataSource; | import com.zaxxer.hikari.HikariDataSource; | ||||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||||
|  | import io.swagger.annotations.ApiImplicitParam; | ||||||
|  | import io.swagger.annotations.ApiImplicitParams; | ||||||
|  | import io.swagger.annotations.ApiOperation; | ||||||
| import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; | import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; | ||||||
| import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.util.StreamUtils; | ||||||
| import org.springframework.web.bind.annotation.GetMapping; | import org.springframework.web.bind.annotation.GetMapping; | ||||||
| import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam; | ||||||
| import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||||
| import javax.sql.DataSource; | import java.io.*; | ||||||
| import java.io.File; |  | ||||||
| import java.io.FileInputStream; |  | ||||||
| import java.io.FileNotFoundException; |  | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
|  |  | ||||||
| @Api(tags = "数据库文档") | @Api(tags = "数据库文档") | ||||||
| @ -34,36 +41,81 @@ public class InfDbDocController { | |||||||
|  |  | ||||||
|     private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator |     private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator | ||||||
|             + "db-doc"; |             + "db-doc"; | ||||||
|     private static final EngineFileType FILE_OUTPUT_TYPE = EngineFileType.HTML; // 可以设置 Word 或者 Markdown 格式 |  | ||||||
|     private static final String DOC_FILE_NAME = "数据库文档"; |     private static final String DOC_FILE_NAME = "数据库文档"; | ||||||
|     private static final String DOC_VERSION = "1.0.0"; |     private static final String DOC_VERSION = "1.0.0"; | ||||||
|     private static final String DOC_DESCRIPTION = "文档描述"; |     private static final String DOC_DESCRIPTION = "文档描述"; | ||||||
|  |  | ||||||
|     @Resource |  | ||||||
|     private DataSource dataSource; |  | ||||||
|  |  | ||||||
|     @GetMapping("/export-html") |     @GetMapping("/export-html") | ||||||
|     public synchronized void exportHtml(HttpServletResponse response) throws FileNotFoundException { |     @ApiOperation("导出html格式的数据文档") | ||||||
|  |     @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class) | ||||||
|  |     public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile, | ||||||
|  |                            HttpServletResponse response) throws IOException { | ||||||
|  |         doExportFile(EngineFileType.HTML, deleteFile, response); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/export-word") | ||||||
|  |     @ApiOperation("导出word格式的数据文档") | ||||||
|  |     @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class) | ||||||
|  |     public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile, | ||||||
|  |                            HttpServletResponse response) throws IOException { | ||||||
|  |         doExportFile(EngineFileType.WORD, deleteFile, response); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/export-markdown") | ||||||
|  |     @ApiOperation("导出markdown格式的数据文档") | ||||||
|  |     @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class) | ||||||
|  |     public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile, | ||||||
|  |                                HttpServletResponse response) throws IOException { | ||||||
|  |         doExportFile(EngineFileType.MD, deleteFile, response); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile, | ||||||
|  |                               HttpServletResponse response) throws IOException { | ||||||
|  |         String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID(); | ||||||
|  |         String filePath = doExportFile(fileOutputType, docFileName); | ||||||
|  |         String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名 | ||||||
|  |         try { | ||||||
|  |             // 读取,返回 | ||||||
|  |             //这里不用hutool工具类,它的中文文件名编码有问题,导致在浏览器下载时有问题 | ||||||
|  |             ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath)); | ||||||
|  |         }finally { | ||||||
|  |             handleDeleteFile(deleteFile, filePath); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 输出文件,返回文件路径 | ||||||
|  |      * | ||||||
|  |      * @param fileOutputType 文件类型 | ||||||
|  |      * @param fileName       文件名, 无需 ".docx" 等文件后缀 | ||||||
|  |      * @return 生成的文件所在路径 | ||||||
|  |      */ | ||||||
|  |     private String doExportFile(EngineFileType fileOutputType, String fileName) { | ||||||
|         try (HikariDataSource dataSource = buildDataSource()) { |         try (HikariDataSource dataSource = buildDataSource()) { | ||||||
|             // 创建 screw 的配置 |             // 创建 screw 的配置 | ||||||
|             Configuration config = Configuration.builder() |             Configuration config = Configuration.builder() | ||||||
|                     .version(DOC_VERSION)  // 版本 |                     .version(DOC_VERSION)  // 版本 | ||||||
|                     .description(DOC_DESCRIPTION) // 描述 |                     .description(DOC_DESCRIPTION) // 描述 | ||||||
|                     .dataSource(dataSource) // 数据源 |                     .dataSource(dataSource) // 数据源 | ||||||
|                     .engineConfig(buildEngineConfig()) // 引擎配置 |                     .engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置 | ||||||
|                     .produceConfig(buildProcessConfig()) // 处理配置 |                     .produceConfig(buildProcessConfig()) // 处理配置 | ||||||
|                     .build(); |                     .build(); | ||||||
|  |  | ||||||
|             // 执行 screw,生成数据库文档 |             // 执行 screw,生成数据库文档 | ||||||
|             new DocumentationExecute(config).execute(); |             new DocumentationExecute(config).execute(); | ||||||
|  |  | ||||||
|             // 读取,返回 |             return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix(); | ||||||
|             ServletUtil.write(response, |  | ||||||
|                     new FileInputStream(FILE_OUTPUT_DIR + File.separator + DOC_FILE_NAME + FILE_OUTPUT_TYPE.getFileSuffix()), |  | ||||||
|                     MediaType.TEXT_HTML_VALUE); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private void handleDeleteFile(Boolean deleteFile, String filePath) { | ||||||
|  |         if (!deleteFile) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         FileUtil.del(filePath); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 创建数据源 |      * 创建数据源 | ||||||
|      */ |      */ | ||||||
| @ -83,13 +135,13 @@ public class InfDbDocController { | |||||||
|     /** |     /** | ||||||
|      * 创建 screw 的引擎配置 |      * 创建 screw 的引擎配置 | ||||||
|      */ |      */ | ||||||
|     private static EngineConfig buildEngineConfig() { |     private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) { | ||||||
|         return EngineConfig.builder() |         return EngineConfig.builder() | ||||||
|                 .fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径 |                 .fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径 | ||||||
|                 .openOutputDir(false) // 打开目录 |                 .openOutputDir(false) // 打开目录 | ||||||
|                 .fileType(FILE_OUTPUT_TYPE) // 文件类型 |                 .fileType(fileOutputType) // 文件类型 | ||||||
|                 .produceType(EngineTemplateType.freemarker) // 文件类型 |                 .produceType(EngineTemplateType.freemarker) // 文件类型 | ||||||
|                 .fileName(DOC_FILE_NAME) // 自定义文件名称 |                 .fileName(docFileName) // 自定义文件名称 | ||||||
|                 .build(); |                 .build(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ public class InfJobServiceImpl implements InfJobService { | |||||||
|     private SchedulerManager schedulerManager; |     private SchedulerManager schedulerManager; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public Long createJob(InfJobCreateReqVO createReqVO) throws SchedulerException { |     public Long createJob(InfJobCreateReqVO createReqVO) throws SchedulerException { | ||||||
|         validateCronExpression(createReqVO.getCronExpression()); |         validateCronExpression(createReqVO.getCronExpression()); | ||||||
|         // 校验唯一性 |         // 校验唯一性 | ||||||
| @ -66,7 +66,7 @@ public class InfJobServiceImpl implements InfJobService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void updateJob(InfJobUpdateReqVO updateReqVO) throws SchedulerException { |     public void updateJob(InfJobUpdateReqVO updateReqVO) throws SchedulerException { | ||||||
|         validateCronExpression(updateReqVO.getCronExpression()); |         validateCronExpression(updateReqVO.getCronExpression()); | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
| @ -86,7 +86,7 @@ public class InfJobServiceImpl implements InfJobService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void updateJobStatus(Long id, Integer status) throws SchedulerException { |     public void updateJobStatus(Long id, Integer status) throws SchedulerException { | ||||||
|         // 校验 status |         // 校验 status | ||||||
|         if (!containsAny(status, InfJobStatusEnum.NORMAL.getStatus(), InfJobStatusEnum.STOP.getStatus())) { |         if (!containsAny(status, InfJobStatusEnum.NORMAL.getStatus(), InfJobStatusEnum.STOP.getStatus())) { | ||||||
| @ -120,7 +120,7 @@ public class InfJobServiceImpl implements InfJobService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void deleteJob(Long id) throws SchedulerException { |     public void deleteJob(Long id) throws SchedulerException { | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
|         InfJobDO job = this.validateJobExists(id); |         InfJobDO job = this.validateJobExists(id); | ||||||
|  | |||||||
| @ -40,8 +40,8 @@ public class SysUserController { | |||||||
|     @Resource |     @Resource | ||||||
|     private SysDeptService deptService; |     private SysDeptService deptService; | ||||||
|  |  | ||||||
|     @ApiOperation("获得用户分页列表") |  | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
|  |     @ApiOperation("获得用户分页列表") | ||||||
|     @PreAuthorize("@ss.hasPermission('system:user:list')") |     @PreAuthorize("@ss.hasPermission('system:user:list')") | ||||||
|     public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) { |     public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) { | ||||||
|         // 获得用户分页列表 |         // 获得用户分页列表 | ||||||
| @ -66,9 +66,9 @@ public class SysUserController { | |||||||
|     /** |     /** | ||||||
|      * 根据用户编号获取详细信息 |      * 根据用户编号获取详细信息 | ||||||
|      */ |      */ | ||||||
|  |     @GetMapping("/get") | ||||||
|     @ApiOperation("获得用户详情") |     @ApiOperation("获得用户详情") | ||||||
|     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) |     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | ||||||
|     @GetMapping("/get") |  | ||||||
| //    @PreAuthorize("@ss.hasPermi('system:user:query')") | //    @PreAuthorize("@ss.hasPermi('system:user:query')") | ||||||
|     public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) { |     public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) { | ||||||
|         return success(SysUserConvert.INSTANCE.convert(userService.getUser(id))); |         return success(SysUserConvert.INSTANCE.convert(userService.getUser(id))); | ||||||
|  | |||||||
| @ -1,92 +1,80 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.controller.user; | package cn.iocoder.dashboard.modules.system.controller.user; | ||||||
|  |  | ||||||
|  | import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | ||||||
|  | import cn.iocoder.dashboard.common.pojo.CommonResult; | ||||||
|  | import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; | ||||||
|  | import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.user.SysUserService; | ||||||
|  | import cn.iocoder.dashboard.util.collection.CollectionUtils; | ||||||
|  | import io.swagger.annotations.Api; | ||||||
|  | import io.swagger.annotations.ApiOperation; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PostMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import org.springframework.web.multipart.MultipartFile; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  | import javax.servlet.http.HttpServletRequest; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||||||
|  | import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.FILE_IS_EMPTY; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @author niudehua | ||||||
|  |  */ | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/system/user/profile") | ||||||
|  | @Api(tags = "用户个人中心") | ||||||
|  | @Slf4j | ||||||
| public class SysUserProfileController { | public class SysUserProfileController { | ||||||
|  |  | ||||||
| //    /** |     @Resource | ||||||
| //     * 个人信息 |     private SysUserService userService; | ||||||
| //     */ |     @Resource | ||||||
| //    @GetMapping |     private SysPermissionService permissionService; | ||||||
| //    public AjaxResult profile() |     @Resource | ||||||
| //    { |     private SysRoleService roleService; | ||||||
| //        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); |  | ||||||
| //        SysUser user = loginUser.getUser(); |  | ||||||
| //        AjaxResult ajax = AjaxResult.success(user); |  | ||||||
| //        ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); |  | ||||||
| //        ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); |  | ||||||
| //        return ajax; |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| //    /** |  | ||||||
| //     * 修改用户 |  | ||||||
| //     */ |  | ||||||
| //    @Log(title = "个人信息", businessType = BusinessType.UPDATE) |  | ||||||
| //    @PutMapping |  | ||||||
| //    public AjaxResult updateProfile(@RequestBody SysUser user) |  | ||||||
| //    { |  | ||||||
| //        if (userService.updateUserProfile(user) > 0) |  | ||||||
| //        { |  | ||||||
| //            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); |  | ||||||
| //            // 更新缓存用户信息 |  | ||||||
| //            loginUser.getUser().setNickName(user.getNickName()); |  | ||||||
| //            loginUser.getUser().setPhonenumber(user.getPhonenumber()); |  | ||||||
| //            loginUser.getUser().setEmail(user.getEmail()); |  | ||||||
| //            loginUser.getUser().setSex(user.getSex()); |  | ||||||
| //            tokenService.setLoginUser(loginUser); |  | ||||||
| //            return AjaxResult.success(); |  | ||||||
| //        } |  | ||||||
| //        return AjaxResult.error("修改个人信息异常,请联系管理员"); |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| //    /** |  | ||||||
| //     * 重置密码 |  | ||||||
| //     */ |  | ||||||
| //    @Log(title = "个人信息", businessType = BusinessType.UPDATE) |  | ||||||
| //    @PutMapping("/updatePwd") |  | ||||||
| //    public AjaxResult updatePwd(String oldPassword, String newPassword) |  | ||||||
| //    { |  | ||||||
| //        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); |  | ||||||
| //        String userName = loginUser.getUsername(); |  | ||||||
| //        String password = loginUser.getPassword(); |  | ||||||
| //        if (!SecurityUtils.matchesPassword(oldPassword, password)) |  | ||||||
| //        { |  | ||||||
| //            return AjaxResult.error("修改密码失败,旧密码错误"); |  | ||||||
| //        } |  | ||||||
| //        if (SecurityUtils.matchesPassword(newPassword, password)) |  | ||||||
| //        { |  | ||||||
| //            return AjaxResult.error("新密码不能与旧密码相同"); |  | ||||||
| //        } |  | ||||||
| //        if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) |  | ||||||
| //        { |  | ||||||
| //            // 更新缓存用户密码 |  | ||||||
| //            loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); |  | ||||||
| //            tokenService.setLoginUser(loginUser); |  | ||||||
| //            return AjaxResult.success(); |  | ||||||
| //        } |  | ||||||
| //        return AjaxResult.error("修改密码异常,请联系管理员"); |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| //    /** |  | ||||||
| //     * 头像上传 |  | ||||||
| //     */ |  | ||||||
| //    @Log(title = "用户头像", businessType = BusinessType.UPDATE) |  | ||||||
| //    @PostMapping("/avatar") |  | ||||||
| //    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException |  | ||||||
| //    { |  | ||||||
| //        if (!file.isEmpty()) |  | ||||||
| //        { |  | ||||||
| //            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); |  | ||||||
| //            String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file); |  | ||||||
| //            if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) |  | ||||||
| //            { |  | ||||||
| //                AjaxResult ajax = AjaxResult.success(); |  | ||||||
| //                ajax.put("imgUrl", avatar); |  | ||||||
| //                // 更新缓存用户头像 |  | ||||||
| //                loginUser.getUser().setAvatar(avatar); |  | ||||||
| //                tokenService.setLoginUser(loginUser); |  | ||||||
| //                return ajax; |  | ||||||
| //            } |  | ||||||
| //        } |  | ||||||
| //        return AjaxResult.error("上传图片异常,请联系管理员"); |  | ||||||
| //    } |  | ||||||
|  |  | ||||||
|  |     @GetMapping("/get") | ||||||
|  |     @ApiOperation("获得登录用户信息") | ||||||
|  |     public CommonResult<SysUserProfileRespVO> profile() { | ||||||
|  |         // 获取用户信息 | ||||||
|  |         Long userId = SecurityFrameworkUtils.getLoginUserId(); | ||||||
|  |         SysUserDO user = userService.getUser(userId); | ||||||
|  |         SysUserProfileRespVO userProfileRespVO = SysUserConvert.INSTANCE.convert03(user); | ||||||
|  |         List<SysRoleDO> userRoles = roleService.listRolesFromCache(permissionService.listUserRoleIs(userId)); | ||||||
|  |         userProfileRespVO.setRoles(CollectionUtils.convertSet(userRoles, SysUserConvert.INSTANCE::convert)); | ||||||
|  |         return success(userProfileRespVO); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/update") | ||||||
|  |     @ApiOperation("修改用户个人信息") | ||||||
|  |     public CommonResult<Boolean> updateProfile(@RequestBody SysUserProfileUpdateReqVO reqVO, HttpServletRequest request) { | ||||||
|  |         userService.updateUserProfile(reqVO); | ||||||
|  |         SecurityFrameworkUtils.setLoginUser(SysAuthConvert.INSTANCE.convert(reqVO), request); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/upload-avatar") | ||||||
|  |     @ApiOperation("上传用户个人头像") | ||||||
|  |     public CommonResult<Boolean> uploadAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException { | ||||||
|  |         if (file.isEmpty()) { | ||||||
|  |             throw ServiceExceptionUtil.exception(FILE_IS_EMPTY); | ||||||
|  |         } | ||||||
|  |         userService.updateAvatar(SecurityFrameworkUtils.getLoginUserId(), file.getInputStream()); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,37 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.controller.user.vo.user; | ||||||
|  |  | ||||||
|  | import io.swagger.annotations.ApiModel; | ||||||
|  | import io.swagger.annotations.ApiModelProperty; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.EqualsAndHashCode; | ||||||
|  | import lombok.NoArgsConstructor; | ||||||
|  |  | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ApiModel("用户个人中心信息 Response VO") | ||||||
|  | @Data | ||||||
|  | @NoArgsConstructor | ||||||
|  | @AllArgsConstructor | ||||||
|  | @EqualsAndHashCode(callSuper = true) | ||||||
|  | public class SysUserProfileRespVO extends SysUserRespVO { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 所属角色 | ||||||
|  |      */ | ||||||
|  |     @ApiModelProperty(value = "所属角色", required = true, example = "123456") | ||||||
|  |     private Set<Role> roles; | ||||||
|  |  | ||||||
|  |     @ApiModel("角色") | ||||||
|  |     @Data | ||||||
|  |     public static class Role { | ||||||
|  |  | ||||||
|  |         @ApiModelProperty(value = "角色编号", required = true, example = "1") | ||||||
|  |         private Long id; | ||||||
|  |  | ||||||
|  |         @ApiModelProperty(value = "角色名称", required = true, example = "普通角色") | ||||||
|  |         private String name; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.controller.user.vo.user; | ||||||
|  |  | ||||||
|  | import io.swagger.annotations.ApiModel; | ||||||
|  | import io.swagger.annotations.ApiModelProperty; | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | import javax.validation.constraints.Email; | ||||||
|  | import javax.validation.constraints.NotNull; | ||||||
|  | import javax.validation.constraints.Size; | ||||||
|  |  | ||||||
|  | @ApiModel("用户个人信息更新 Request VO") | ||||||
|  | @Data | ||||||
|  | public class SysUserProfileUpdateReqVO { | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户编号", required = true, example = "1024") | ||||||
|  |     @NotNull(message = "用户编号不能为空") | ||||||
|  |     private Long id; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") | ||||||
|  |     @Size(max = 30, message = "用户昵称长度不能超过30个字符") | ||||||
|  |     private String nickname; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn") | ||||||
|  |     @Email(message = "邮箱格式不正确") | ||||||
|  |     @Size(max = 50, message = "邮箱长度不能超过50个字符") | ||||||
|  |     private String email; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "手机号码", example = "15601691300") | ||||||
|  |     @Size(max = 11, message = "手机号码长度不能超过11个字符") | ||||||
|  |     private String mobile; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类") | ||||||
|  |     private Integer sex; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png") | ||||||
|  |     private String avatar; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "旧密码", required = true, example = "123456") | ||||||
|  |     private String oldPassword; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "新密码", required = true, example = "654321") | ||||||
|  |     private String newPassword; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.convert.auth; | |||||||
| import cn.iocoder.dashboard.framework.security.core.LoginUser; | import cn.iocoder.dashboard.framework.security.core.LoginUser; | ||||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; | import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; | ||||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; | import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | ||||||
| @ -13,26 +14,33 @@ import org.mapstruct.Mapping; | |||||||
| import org.mapstruct.factory.Mappers; | import org.mapstruct.factory.Mappers; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.*; | import java.util.ArrayList; | ||||||
|  | import java.util.Comparator; | ||||||
|  | import java.util.LinkedHashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
| @Mapper | @Mapper | ||||||
| public interface SysAuthConvert { | public interface SysAuthConvert { | ||||||
|  |  | ||||||
|     SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class); |     SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class); | ||||||
|  |  | ||||||
|     @Mapping(source = "updateTime", target = "updateTime", ignore = true) // 字段相同,但是含义不同,忽略 |     @Mapping(source = "updateTime", target = "updateTime", ignore = true) | ||||||
|  |         // 字段相同,但是含义不同,忽略 | ||||||
|     LoginUser convert(SysUserDO bean); |     LoginUser convert(SysUserDO bean); | ||||||
|  |  | ||||||
|     default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) { |     default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) { | ||||||
|         return SysAuthPermissionInfoRespVO.builder() |         return SysAuthPermissionInfoRespVO.builder() | ||||||
|                 .user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build()) |             .user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build()) | ||||||
|                 .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode)) |             .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode)) | ||||||
|                 .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission)) |             .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission)) | ||||||
|                 .build(); |             .build(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SysAuthMenuRespVO convertTreeNode(SysMenuDO menu); |     SysAuthMenuRespVO convertTreeNode(SysMenuDO menu); | ||||||
|  |  | ||||||
|  |     LoginUser convert(SysUserProfileUpdateReqVO reqVO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 将菜单列表,构建成菜单树 |      * 将菜单列表,构建成菜单树 | ||||||
|      * |      * | ||||||
| @ -47,12 +55,12 @@ public interface SysAuthConvert { | |||||||
|         Map<Long, SysAuthMenuRespVO> treeNodeMap = new LinkedHashMap<>(); |         Map<Long, SysAuthMenuRespVO> treeNodeMap = new LinkedHashMap<>(); | ||||||
|         menuList.forEach(menu -> treeNodeMap.put(menu.getId(), SysAuthConvert.INSTANCE.convertTreeNode(menu))); |         menuList.forEach(menu -> treeNodeMap.put(menu.getId(), SysAuthConvert.INSTANCE.convertTreeNode(menu))); | ||||||
|         // 处理父子关系 |         // 处理父子关系 | ||||||
|         treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach((childNode) -> { |         treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach(childNode -> { | ||||||
|             // 获得父节点 |             // 获得父节点 | ||||||
|             SysAuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId()); |             SysAuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId()); | ||||||
|             if (parentNode == null) { |             if (parentNode == null) { | ||||||
|                 LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]", |                 LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]", | ||||||
|                         childNode.getId(), childNode.getParentId()); |                     childNode.getId(), childNode.getParentId()); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             // 将自己添加到父节点中 |             // 将自己添加到父节点中 | ||||||
|  | |||||||
| @ -1,7 +1,14 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.convert.user; | package cn.iocoder.dashboard.modules.system.convert.user; | ||||||
|  |  | ||||||
| import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*; | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExcelVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | ||||||
| import org.mapstruct.Mapper; | import org.mapstruct.Mapper; | ||||||
| import org.mapstruct.factory.Mappers; | import org.mapstruct.factory.Mappers; | ||||||
| @ -23,4 +30,12 @@ public interface SysUserConvert { | |||||||
|  |  | ||||||
|     SysUserDO convert(SysUserImportExcelVO bean); |     SysUserDO convert(SysUserImportExcelVO bean); | ||||||
|  |  | ||||||
|  |     SysUserProfileRespVO convert03(SysUserDO bean); | ||||||
|  |  | ||||||
|  |     SysUserProfileRespVO.Role convert(SysRoleDO bean); | ||||||
|  |  | ||||||
|  |     SysUserDO convert(SysUserProfileUpdateReqVO bean); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -40,6 +40,7 @@ public interface SysErrorCodeConstants { | |||||||
|     ErrorCode USER_EMAIL_EXISTS = new ErrorCode(1002004002, "邮箱已经存在"); |     ErrorCode USER_EMAIL_EXISTS = new ErrorCode(1002004002, "邮箱已经存在"); | ||||||
|     ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在"); |     ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在"); | ||||||
|     ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!"); |     ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!"); | ||||||
|  |     ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1002004005, "用户密码校验失败"); | ||||||
|  |  | ||||||
|     // ========== 部门模块 1002005000 ========== |     // ========== 部门模块 1002005000 ========== | ||||||
|     ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门"); |     ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门"); | ||||||
| @ -74,5 +75,7 @@ public interface SysErrorCodeConstants { | |||||||
|  |  | ||||||
|     // ========== 文件 1002009000 ========== |     // ========== 文件 1002009000 ========== | ||||||
|     ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在"); |     ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在"); | ||||||
|  |     ErrorCode FILE_UPLOAD_FAILED = new ErrorCode(1002009002, "文件上传失败"); | ||||||
|  |     ErrorCode FILE_IS_EMPTY= new ErrorCode(1002009003, "文件为空"); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -206,7 +206,7 @@ public class SysMenuServiceImpl implements SysMenuService { | |||||||
|      * |      * | ||||||
|      * @param menuId 菜单编号 |      * @param menuId 菜单编号 | ||||||
|      */ |      */ | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void deleteMenu(Long menuId) { |     public void deleteMenu(Long menuId) { | ||||||
|         // 校验更新的菜单是否存在 |         // 校验更新的菜单是否存在 | ||||||
|         if (menuMapper.selectById(menuId) == null) { |         if (menuMapper.selectById(menuId) == null) { | ||||||
|  | |||||||
| @ -176,7 +176,7 @@ public class SysPermissionServiceImpl implements SysPermissionService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void assignRoleMenu(Long roleId, Set<Long> menuIds) { |     public void assignRoleMenu(Long roleId, Set<Long> menuIds) { | ||||||
|         // 获得角色拥有菜单编号 |         // 获得角色拥有菜单编号 | ||||||
|         Set<Long> dbMenuIds = CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId), |         Set<Long> dbMenuIds = CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId), | ||||||
|  | |||||||
| @ -174,7 +174,7 @@ public class SysRoleServiceImpl implements SysRoleService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void deleteRole(Long id) { |     public void deleteRole(Long id) { | ||||||
|         // 校验是否可以更新 |         // 校验是否可以更新 | ||||||
|         this.checkUpdateRole(id); |         this.checkUpdateRole(id); | ||||||
|  | |||||||
| @ -2,10 +2,17 @@ package cn.iocoder.dashboard.modules.system.service.user; | |||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.iocoder.dashboard.common.pojo.PageResult; | import cn.iocoder.dashboard.common.pojo.PageResult; | ||||||
| import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*; | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | ||||||
| import cn.iocoder.dashboard.util.collection.CollectionUtils; | import cn.iocoder.dashboard.util.collection.CollectionUtils; | ||||||
|  |  | ||||||
|  | import java.io.InputStream; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @ -102,6 +109,14 @@ public interface SysUserService { | |||||||
|      */ |      */ | ||||||
|     void updateUser(SysUserUpdateReqVO reqVO); |     void updateUser(SysUserUpdateReqVO reqVO); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 修改用户个人信息 | ||||||
|  |      * | ||||||
|  |      * @param reqVO 用户个人信息 | ||||||
|  |      * @return 修改结果 | ||||||
|  |      */ | ||||||
|  |     void updateUserProfile(SysUserProfileUpdateReqVO reqVO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 删除用户 |      * 删除用户 | ||||||
|      * |      * | ||||||
| @ -112,7 +127,7 @@ public interface SysUserService { | |||||||
|     /** |     /** | ||||||
|      * 修改密码 |      * 修改密码 | ||||||
|      * |      * | ||||||
|      * @param id 用户编号 |      * @param id       用户编号 | ||||||
|      * @param password 密码 |      * @param password 密码 | ||||||
|      */ |      */ | ||||||
|     void updateUserPassword(Long id, String password); |     void updateUserPassword(Long id, String password); | ||||||
| @ -120,7 +135,7 @@ public interface SysUserService { | |||||||
|     /** |     /** | ||||||
|      * 修改密码 |      * 修改密码 | ||||||
|      * |      * | ||||||
|      * @param id 用户编号 |      * @param id     用户编号 | ||||||
|      * @param status 状态 |      * @param status 状态 | ||||||
|      */ |      */ | ||||||
|     void updateUserStatus(Long id, Integer status); |     void updateUserStatus(Long id, Integer status); | ||||||
| @ -128,12 +143,20 @@ public interface SysUserService { | |||||||
|     /** |     /** | ||||||
|      * 批量导入用户 |      * 批量导入用户 | ||||||
|      * |      * | ||||||
|      * @param importUsers 导入用户列表 |      * @param importUsers     导入用户列表 | ||||||
|      * @param isUpdateSupport 是否支持更新 |      * @param isUpdateSupport 是否支持更新 | ||||||
|      * @return 导入结果 |      * @return 导入结果 | ||||||
|      */ |      */ | ||||||
|     SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport); |     SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 更新用户头像 | ||||||
|  |      * | ||||||
|  |      * @param id         用户 id | ||||||
|  |      * @param avatarFile 头像文件 | ||||||
|  |      */ | ||||||
|  |     void updateAvatar(Long id, InputStream avatarFile); | ||||||
|  |  | ||||||
| // | // | ||||||
| //    /** | //    /** | ||||||
| //     * 修改用户基本信息 | //     * 修改用户基本信息 | ||||||
|  | |||||||
| @ -1,17 +1,26 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.service.user; | package cn.iocoder.dashboard.modules.system.service.user; | ||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
|  | import cn.hutool.core.io.IoUtil; | ||||||
|  | import cn.hutool.core.util.IdUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||||
| import cn.iocoder.dashboard.common.exception.ServiceException; | import cn.iocoder.dashboard.common.exception.ServiceException; | ||||||
| import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | ||||||
| import cn.iocoder.dashboard.common.pojo.PageResult; | import cn.iocoder.dashboard.common.pojo.PageResult; | ||||||
| import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*; | import cn.iocoder.dashboard.modules.infra.service.file.InfFileService; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; | ||||||
| import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert; | import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper; |  | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper; | ||||||
| import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; | import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.dept.SysPostService; | import cn.iocoder.dashboard.modules.system.service.dept.SysPostService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | ||||||
| @ -22,7 +31,14 @@ import org.springframework.stereotype.Service; | |||||||
| import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import java.util.*; | import java.io.InputStream; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.LinkedHashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
| import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; | import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; | ||||||
|  |  | ||||||
| @ -49,18 +65,8 @@ public class SysUserServiceImpl implements SysUserService { | |||||||
|     @Resource |     @Resource | ||||||
|     private PasswordEncoder passwordEncoder; |     private PasswordEncoder passwordEncoder; | ||||||
|  |  | ||||||
| //    /** |     @Resource | ||||||
| //     * 根据条件分页查询用户列表 |     private InfFileService fileService; | ||||||
| //     * |  | ||||||
| //     * @param user 用户信息 |  | ||||||
| //     * @return 用户信息集合信息 |  | ||||||
| //     */ |  | ||||||
| //    @Override |  | ||||||
| //    @DataScope(deptAlias = "d", userAlias = "u") |  | ||||||
| //    public List<SysUser> selectUserList(SysUser user) |  | ||||||
| //    { |  | ||||||
| //        return userMapper.selectUserList(user); |  | ||||||
| //    } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public SysUserDO getUserByUserName(String username) { |     public SysUserDO getUserByUserName(String username) { | ||||||
| @ -108,7 +114,7 @@ public class SysUserServiceImpl implements SysUserService { | |||||||
|             return Collections.emptySet(); |             return Collections.emptySet(); | ||||||
|         } |         } | ||||||
|         Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache( |         Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache( | ||||||
|                 deptId, true), SysDeptDO::getId); |             deptId, true), SysDeptDO::getId); | ||||||
|         deptIds.add(deptId); // 包括自身 |         deptIds.add(deptId); // 包括自身 | ||||||
|         return deptIds; |         return deptIds; | ||||||
|     } |     } | ||||||
| @ -117,7 +123,7 @@ public class SysUserServiceImpl implements SysUserService { | |||||||
|     public Long createUser(SysUserCreateReqVO reqVO) { |     public Long createUser(SysUserCreateReqVO reqVO) { | ||||||
|         // 校验正确性 |         // 校验正确性 | ||||||
|         this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), |         this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), | ||||||
|                 reqVO.getDeptId(), reqVO.getPostIds()); |             reqVO.getDeptId(), reqVO.getPostIds()); | ||||||
|         // 插入用户 |         // 插入用户 | ||||||
|         SysUserDO user = SysUserConvert.INSTANCE.convert(reqVO); |         SysUserDO user = SysUserConvert.INSTANCE.convert(reqVO); | ||||||
|         user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 |         user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 | ||||||
| @ -130,12 +136,31 @@ public class SysUserServiceImpl implements SysUserService { | |||||||
|     public void updateUser(SysUserUpdateReqVO reqVO) { |     public void updateUser(SysUserUpdateReqVO reqVO) { | ||||||
|         // 校验正确性 |         // 校验正确性 | ||||||
|         this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), |         this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), | ||||||
|                 reqVO.getDeptId(), reqVO.getPostIds()); |             reqVO.getDeptId(), reqVO.getPostIds()); | ||||||
|         // 更新用户 |         // 更新用户 | ||||||
|         SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO); |         SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO); | ||||||
|         userMapper.updateById(updateObj); |         userMapper.updateById(updateObj); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void updateUserProfile(SysUserProfileUpdateReqVO reqVO) { | ||||||
|  |         // 校验正确性 | ||||||
|  |         this.checkUserExists(reqVO.getId()); | ||||||
|  |         this.checkEmailUnique(reqVO.getId(), reqVO.getEmail()); | ||||||
|  |         this.checkMobileUnique(reqVO.getId(), reqVO.getMobile()); | ||||||
|  |         // 校验填写密码 | ||||||
|  |         String encode = null; | ||||||
|  |         if (this.checkOldPassword(reqVO.getId(), reqVO.getOldPassword(), reqVO.getNewPassword())) { | ||||||
|  |             // 更新密码 | ||||||
|  |             encode = passwordEncoder.encode(reqVO.getNewPassword()); | ||||||
|  |         } | ||||||
|  |         SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO); | ||||||
|  |         if (StrUtil.isNotBlank(encode)) { | ||||||
|  |             updateObj.setPassword(encode); | ||||||
|  |         } | ||||||
|  |         userMapper.updateById(updateObj); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void deleteUser(Long id) { |     public void deleteUser(Long id) { | ||||||
|         // 校验用户存在 |         // 校验用户存在 | ||||||
| @ -278,19 +303,42 @@ public class SysUserServiceImpl implements SysUserService { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 校验旧密码、新密码 | ||||||
|  |      * | ||||||
|  |      * @param id          用户 id | ||||||
|  |      * @param oldPassword 旧密码 | ||||||
|  |      * @param newPassword 新密码 | ||||||
|  |      * @return 校验结果 | ||||||
|  |      */ | ||||||
|  |     private boolean checkOldPassword(Long id, String oldPassword, String newPassword) { | ||||||
|  |         if (id == null || StrUtil.isBlank(oldPassword) || StrUtil.isBlank(newPassword)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         SysUserDO user = userMapper.selectById(id); | ||||||
|  |         if (user == null) { | ||||||
|  |             throw ServiceExceptionUtil.exception(USER_NOT_EXISTS); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!passwordEncoder.matches(oldPassword, user.getPassword())) { | ||||||
|  |             throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED); | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional // 添加事务,异常则回滚所有导入 |     @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 | ||||||
|     public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) { |     public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) { | ||||||
|         if (CollUtil.isEmpty(importUsers)) { |         if (CollUtil.isEmpty(importUsers)) { | ||||||
|             throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY); |             throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY); | ||||||
|         } |         } | ||||||
|         SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>()) |         SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>()) | ||||||
|                 .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build(); |             .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build(); | ||||||
|         importUsers.forEach(importUser -> { |         importUsers.forEach(importUser -> { | ||||||
|             // 校验,判断是否有不符合的原因 |             // 校验,判断是否有不符合的原因 | ||||||
|             try { |             try { | ||||||
|                 checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), |                 checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), | ||||||
|                         importUser.getDeptId(), null); |                     importUser.getDeptId(), null); | ||||||
|             } catch (ServiceException ex) { |             } catch (ServiceException ex) { | ||||||
|                 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); |                 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); | ||||||
|                 return; |                 return; | ||||||
| @ -316,4 +364,16 @@ public class SysUserServiceImpl implements SysUserService { | |||||||
|         return respVO; |         return respVO; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void updateAvatar(Long id, InputStream avatarFile) { | ||||||
|  |         this.checkUserExists(id); | ||||||
|  |         // 存储文件 | ||||||
|  |         String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile)); | ||||||
|  |         // 更新路径 | ||||||
|  |         SysUserDO sysUserDO = new SysUserDO(); | ||||||
|  |         sysUserDO.setId(id); | ||||||
|  |         sysUserDO.setAvatar(avatar); | ||||||
|  |         userMapper.updateById(sysUserDO); | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -109,7 +109,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public List<Long> createCodegenListFromDB(List<String> tableNames) { |     public List<Long> createCodegenListFromDB(List<String> tableNames) { | ||||||
|         List<Long> ids = new ArrayList<>(tableNames.size()); |         List<Long> ids = new ArrayList<>(tableNames.size()); | ||||||
|         // 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量 |         // 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量 | ||||||
| @ -118,7 +118,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void updateCodegen(ToolCodegenUpdateReqVO updateReqVO) { |     public void updateCodegen(ToolCodegenUpdateReqVO updateReqVO) { | ||||||
|         // 校验是否已经存在 |         // 校验是否已经存在 | ||||||
|         if (codegenTableMapper.selectById(updateReqVO.getTable().getId()) == null) { |         if (codegenTableMapper.selectById(updateReqVO.getTable().getId()) == null) { | ||||||
| @ -134,7 +134,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void syncCodegenFromDB(Long tableId) { |     public void syncCodegenFromDB(Long tableId) { | ||||||
|         // 校验是否已经存在 |         // 校验是否已经存在 | ||||||
|         ToolCodegenTableDO table = codegenTableMapper.selectById(tableId); |         ToolCodegenTableDO table = codegenTableMapper.selectById(tableId); | ||||||
| @ -149,7 +149,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void syncCodegenFromSQL(Long tableId, String sql) { |     public void syncCodegenFromSQL(Long tableId, String sql) { | ||||||
|         // 校验是否已经存在 |         // 校验是否已经存在 | ||||||
|         ToolCodegenTableDO table = codegenTableMapper.selectById(tableId); |         ToolCodegenTableDO table = codegenTableMapper.selectById(tableId); | ||||||
| @ -201,7 +201,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void deleteCodegen(Long tableId) { |     public void deleteCodegen(Long tableId) { | ||||||
|         // 校验是否已经存在 |         // 校验是否已经存在 | ||||||
|         if (codegenTableMapper.selectById(tableId) == null) { |         if (codegenTableMapper.selectById(tableId) == null) { | ||||||
|  | |||||||
| @ -145,14 +145,14 @@ yudao: | |||||||
|   swagger: |   swagger: | ||||||
|     title: 管理后台 |     title: 管理后台 | ||||||
|     description: 提供管理员管理的所有功能 |     description: 提供管理员管理的所有功能 | ||||||
|     version: ${yudao.info.base-package} |     version: ${yudao.info.version} | ||||||
|     base-package: ${yudao.info.base-package}.modules |     base-package: ${yudao.info.base-package}.modules | ||||||
|   captcha: |   captcha: | ||||||
|     timeout: 5m |     timeout: 5m | ||||||
|     width: 160 |     width: 160 | ||||||
|     height: 60 |     height: 60 | ||||||
|   file: |   file: | ||||||
|     base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/infra/file/get/ |     base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/ | ||||||
|   codegen: |   codegen: | ||||||
|     base-package: ${yudao.info.base-package} |     base-package: ${yudao.info.base-package} | ||||||
|     db-schemas: ${spring.datasource.name} |     db-schemas: ${spring.datasource.name} | ||||||
|  | |||||||
| @ -145,14 +145,14 @@ yudao: | |||||||
|   swagger: |   swagger: | ||||||
|     title: 管理后台 |     title: 管理后台 | ||||||
|     description: 提供管理员管理的所有功能 |     description: 提供管理员管理的所有功能 | ||||||
|     version: ${yudao.info.base-package} |     version: ${yudao.info.version} | ||||||
|     base-package: ${yudao.info.base-package}.modules |     base-package: ${yudao.info.base-package}.modules | ||||||
|   captcha: |   captcha: | ||||||
|     timeout: 5m |     timeout: 5m | ||||||
|     width: 160 |     width: 160 | ||||||
|     height: 60 |     height: 60 | ||||||
|   file: |   file: | ||||||
|     base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/infra/file/get/ |     base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/ | ||||||
|   codegen: |   codegen: | ||||||
|     base-package: ${yudao.info.base-package} |     base-package: ${yudao.info.base-package} | ||||||
|     db-schemas: ${spring.datasource.name} |     db-schemas: ${spring.datasource.name} | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 wangkai
					wangkai