diff --git a/doc/springbootv2.sql b/doc/springbootv2.sql index c9d4ba3e0f88bc448e1f5bbe39547154cc7663ab..dbadf868cf4b7e10715899681b25ab24fc4097dd 100644 --- a/doc/springbootv2.sql +++ b/doc/springbootv2.sql @@ -1114,7 +1114,12 @@ CREATE TABLE `t_sys_user` ( `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户账号', `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户密码', `nickname` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '昵称', - `dep_id` int(11) NULL DEFAULT NULL COMMENT '部门id', + `user_type` varchar(2) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '00' COMMENT '用户类型(00系统用户 01注册用户)', + `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '用户邮箱', + `phonenumber` varchar(11) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '手机号码', + `sex` char(1) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', + `avatar` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '头像路径', + `dep_id` bigint(30) NULL DEFAULT NULL COMMENT '部门id', `pos_id` bigint(30) NULL DEFAULT NULL COMMENT '岗位id', `create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', @@ -1122,13 +1127,13 @@ CREATE TABLE `t_sys_user` ( `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', `remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '用户表' ROW_FORMAT = DYNAMIC; +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '用户信息表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of t_sys_user -- ---------------------------- -INSERT INTO `t_sys_user` VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '管理员', 2, 410792368778907648, NULL, NULL, NULL, NULL, NULL); -INSERT INTO `t_sys_user` VALUES (433236479427350528, 'fuce', '21232f297a57a5a743894a0e4a801fc3', '付册', 2, 410792443127140352, NULL, NULL, NULL, NULL, NULL); +INSERT INTO `t_sys_user` VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '管理员', '00', 'test@foxmail.com', '18688888888', '0', '',2, 410792368778907648, 'admin', SYSDATE(), NULL, NULL, NULL); +INSERT INTO `t_sys_user` VALUES (433236479427350528, 'fuce', '21232f297a57a5a743894a0e4a801fc3', '付册', '00', 'test@foxmail.com', '18688888888', '0', '',2, 410792443127140352, 'admin', SYSDATE(), NULL, NULL, NULL); -- ---------------------------- -- Table structure for t_test diff --git a/src/main/java/com/fc/v2/common/base/BaseController.java b/src/main/java/com/fc/v2/common/base/BaseController.java index b94375963ef511878d3f58cd67df29aac1ee57cf..ea253ccff2d4858352911ca6d3fcc6bd93e490bb 100644 --- a/src/main/java/com/fc/v2/common/base/BaseController.java +++ b/src/main/java/com/fc/v2/common/base/BaseController.java @@ -119,6 +119,17 @@ public class BaseController { return AjaxResult.success(message); } + /** + * 返回object数据 + * + * @param code + * @param data + * @return + */ + public AjaxResult success(int code, String message, Object data) { + return AjaxResult.success(code, message, data); + } + /** * 返回失败消息 * diff --git a/src/main/java/com/fc/v2/common/conf/V2Config.java b/src/main/java/com/fc/v2/common/conf/V2Config.java index 0dfa0c451c5d763a17537a985282ba274faa7f5a..752572cea6543e2ca93e9f434b17cd00ddd29924 100644 --- a/src/main/java/com/fc/v2/common/conf/V2Config.java +++ b/src/main/java/com/fc/v2/common/conf/V2Config.java @@ -30,6 +30,9 @@ public class V2Config private String demoEnabled; /** 滚动验证码 **/ private Boolean rollVerification; + /** 文件路径 **/ + private String profile; + public String getName() { return name; } @@ -84,6 +87,36 @@ public class V2Config public void setRollVerification(Boolean rollVerification) { this.rollVerification = rollVerification; } - - + + public String getProfile() { + return profile; + } + + public void setProfile(String profile) { + this.profile = profile; + } + + /** + * 获取头像上传路径 + */ + public String getAvatarPath() + { + return this.profile + "/avatar"; + } + + /** + * 获取下载路径 + */ + public String getDownloadPath() + { + return this.profile + "/download/"; + } + + /** + * 获取上传路径 + */ + public String getUploadPath() + { + return this.profile+ "/upload"; + } } diff --git a/src/main/java/com/fc/v2/common/domain/AjaxResult.java b/src/main/java/com/fc/v2/common/domain/AjaxResult.java index a6c0f3745a933ef051cb6c0616744e2d140002d1..959b5cfe5a4137f49468d27a1bea27f2fb05d554 100644 --- a/src/main/java/com/fc/v2/common/domain/AjaxResult.java +++ b/src/main/java/com/fc/v2/common/domain/AjaxResult.java @@ -79,6 +79,20 @@ public class AjaxResult extends HashMap { return AjaxResult.success("操作成功"); } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success(int code, String msg, Object value) + { + AjaxResult json = new AjaxResult(); + json.put("msg", msg); + json.put("code", code); + json.put("data", value); + return json; + } public static AjaxResult successData(int code, Object value){ AjaxResult json = new AjaxResult(); diff --git a/src/main/java/com/fc/v2/common/interceptor/MyWebAppConfigurer.java b/src/main/java/com/fc/v2/common/interceptor/MyWebAppConfigurer.java index 2ae708354e782d6512ce51b5d039a0ffddc8ec52..c3b5ea005fdf393f147f67366fe64d6063d4d7d5 100644 --- a/src/main/java/com/fc/v2/common/interceptor/MyWebAppConfigurer.java +++ b/src/main/java/com/fc/v2/common/interceptor/MyWebAppConfigurer.java @@ -1,5 +1,8 @@ package com.fc.v2.common.interceptor; +import com.fc.v2.common.conf.V2Config; +import com.fc.v2.util.file.FileUploadUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.CorsRegistry; @@ -12,88 +15,83 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupp /** * 拦截器 -* @ClassName: MyWebAppConfigurer -* @author fuce -* @date 2018年6月3日 -* + * + * @ClassName: MyWebAppConfigurer + * @author fuce + * @date 2018年6月3日 */ @Configuration -public class MyWebAppConfigurer extends WebMvcConfigurationSupport { - - //private static Logger logger=LoggerFactory.getLogger(WebMvcConfigurationSupport.class); +public class MyWebAppConfigurer extends WebMvcConfigurationSupport { - /** 解决跨域问题 **/ - @Override - public void addCorsMappings(CorsRegistry registry){ - /* - registry.addMapping("/**") - // 设置允许跨域请求的域名 - .allowedOrigins("*") - // 是否允许证书 - .allowCredentials(true) - // 设置允许的方法 - .allowedMethods("GET", "POST", "DELETE", "PUT") - // 设置允许的header属性 - .allowedHeaders("*") - // 跨域允许时间 - .maxAge(3600); - super.addCorsMappings(registry); - */ - } - - /** 添加拦截器 **/ - @Override - protected void addInterceptors(InterceptorRegistry registry){ - registry.addInterceptor(new MyInterceptor()); - super.addInterceptors(registry); - } - - /** 这里配置视图解析器 **/ - @Override - protected void configureViewResolvers(ViewResolverRegistry registry){ - super.configureViewResolvers(registry); - } - - /** 配置内容裁决的一些选项 **/ - @Override - protected void configureContentNegotiation(ContentNegotiationConfigurer configurer){ - super.configureContentNegotiation(configurer); - } - - /** 视图跳转控制器 **/ - @Override - protected void addViewControllers(ViewControllerRegistry registry) { - - super.addViewControllers(registry); - } - - - /** 静态资源处理 **/ - @Override - protected void addResourceHandlers(ResourceHandlerRegistry registry) { - //配置虚拟路径为项目得static下面 - registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); - //添加swagger -// registry.addResourceHandler("swagger-ui.html").addResourceLocations( -// "classpath:/META-INF/resources/"); -// registry.addResourceHandler("/webjars/**").addResourceLocations( -// "classpath:/META-INF/resources/webjars/"); -// - registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); - registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + // private static Logger logger=LoggerFactory.getLogger(WebMvcConfigurationSupport.class); - super.addResourceHandlers(registry); + @Autowired + private V2Config v2Config; + + /** 解决跨域问题 **/ + @Override + public void addCorsMappings(CorsRegistry registry) { + /* + * registry.addMapping("/**") // 设置允许跨域请求的域名 .allowedOrigins("*") // 是否允许证书 + * .allowCredentials(true) // 设置允许的方法 .allowedMethods("GET", "POST", "DELETE", "PUT") // + * 设置允许的header属性 .allowedHeaders("*") // 跨域允许时间 .maxAge(3600); + * super.addCorsMappings(registry); + */ + } + /** 添加拦截器 **/ + @Override + protected void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new MyInterceptor()); + super.addInterceptors(registry); } - /** 默认静态资源处理器 **/ - protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { - //super.configureDefaultServletHandling(configurer); - //configurer.enable("stati"); - super.configureDefaultServletHandling(configurer); - } + /** 这里配置视图解析器 **/ + @Override + protected void configureViewResolvers(ViewResolverRegistry registry) { + super.configureViewResolvers(registry); + } + /** 配置内容裁决的一些选项 **/ + @Override + protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) { + super.configureContentNegotiation(configurer); + } + /** 视图跳转控制器 **/ + @Override + protected void addViewControllers(ViewControllerRegistry registry) { + super.addViewControllers(registry); + } + /** 静态资源处理 **/ + @Override + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + // 配置虚拟路径为项目得static下面 + registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); + // 添加swagger + // registry.addResourceHandler("swagger-ui.html").addResourceLocations( + // "classpath:/META-INF/resources/"); + // registry.addResourceHandler("/webjars/**").addResourceLocations( + // "classpath:/META-INF/resources/webjars/"); + // + registry.addResourceHandler("doc.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + /** 本地文件上传路径 */ + registry.addResourceHandler(FileUploadUtils.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + v2Config.getProfile() + "/"); + + super.addResourceHandlers(registry); + } + + /** 默认静态资源处理器 **/ + @Override + protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + // super.configureDefaultServletHandling(configurer); + // configurer.enable("stati"); + super.configureDefaultServletHandling(configurer); + } } diff --git a/src/main/java/com/fc/v2/controller/AdminController.java b/src/main/java/com/fc/v2/controller/AdminController.java index 758fa0ccc026706b68aed93fabdae9a216416a67..ddf17c3ec08fb9bd9c7b23e230c7f647de0f0305 100644 --- a/src/main/java/com/fc/v2/controller/AdminController.java +++ b/src/main/java/com/fc/v2/controller/AdminController.java @@ -37,22 +37,23 @@ import java.util.List; @Controller @RequestMapping("/admin") public class AdminController extends BaseController { + private static Logger logger = LoggerFactory.getLogger(AdminController.class); private String prefix = "admin"; - @ApiOperation(value = "首页" , notes = "首页") - @GetMapping({"" , "/index"}) + @ApiOperation(value = "首页", notes = "首页") + @GetMapping({"", "/index"}) public String index(HttpServletRequest request) { - request.getSession().setAttribute("sessionUserName" , ShiroUtils.getUser().getNickname()); + request.getSession().setAttribute("user", sysUserService.selectTSysUserById(ShiroUtils.getUserId())); // 获取公告信息 List notices = sysNoticeService.getuserNoticeNotRead(ShiroUtils.getUser(), 0); - request.getSession().setAttribute("notices" , notices); + request.getSession().setAttribute("notices", notices); return prefix + "/index"; } - @ApiOperation(value = "获取登录用户菜单栏" , notes = "获取登录用户菜单栏") + @ApiOperation(value = "获取登录用户菜单栏", notes = "获取登录用户菜单栏") @GetMapping("/getUserMenu") @ResponseBody public List getUserMenu() { @@ -64,10 +65,10 @@ public class AdminController extends BaseController { /** * 请求到登陆界面 * - * @param request + * @param modelMap * @return */ - @ApiOperation(value = "请求到登陆界面" , notes = "请求到登陆界面") + @ApiOperation(value = "请求到登陆界面", notes = "请求到登陆界面") @GetMapping("/login") public String login(ModelMap modelMap) { try { @@ -75,7 +76,7 @@ public class AdminController extends BaseController { return "redirect:/" + prefix + "/index"; } else { System.out.println("--进行登录验证..验证开始"); - modelMap.put("RollVerification" , v2Config.getRollVerification()); + modelMap.put("RollVerification", v2Config.getRollVerification()); System.out.println("V2Config.getRollVerification()>>>" + v2Config.getRollVerification()); return "login"; } @@ -87,16 +88,14 @@ public class AdminController extends BaseController { /** * 用户登陆验证 - * * @param user - * @param rcode + * @param captcha * @param redirectAttributes * @param rememberMe - * @param model * @param request * @return */ - @ApiOperation(value = "用户登陆验证" , notes = "用户登陆验证") + @ApiOperation(value = "用户登陆验证", notes = "用户登陆验证") @PostMapping("/login") @ResponseBody public AjaxResult login(TSysUser user, String captcha, RedirectAttributes redirectAttributes, boolean rememberMe, @@ -107,8 +106,8 @@ public class AdminController extends BaseController { String verCode = (String) request.getSession().getAttribute("captcha"); // 判断验证码 if (captcha != null && captcha.toLowerCase().equals(verCode.trim().toLowerCase())) { - //清除验证码 - CaptchaUtil.clear(request); // 清除session中的验证码 + //清除session中的验证码 + CaptchaUtil.clear(request); yz = true; } @@ -166,19 +165,14 @@ public class AdminController extends BaseController { } - /** * 手机登录 - * * @param user - * @param redirectAttributes * @param rememberMe * @param request * @return - * @author fuce - * @Date 2020年12月7日 上午12:54:28 */ - @ApiOperation(value = "手机登录" , notes = "手机登录") + @ApiOperation(value = "手机登录", notes = "手机登录") @PostMapping("/API/login") @ResponseBody public AjaxResult APIlogin(TSysUser user, boolean rememberMe, HttpServletRequest request) { @@ -248,10 +242,11 @@ public class AdminController extends BaseController { /** * 退出登陆 - * + * @param request + * @param response * @return */ - @ApiOperation(value = "退出登陆" , notes = "退出登陆") + @ApiOperation(value = "退出登陆", notes = "退出登陆") @GetMapping("/Loginout") @ResponseBody public AjaxResult LoginOut(HttpServletRequest request, HttpServletResponse response) { @@ -262,40 +257,54 @@ public class AdminController extends BaseController { return success(); } - /**** 页面测试 ****/ - @ApiOperation(value = "404页面" , notes = "404页面") + /**** 页面测试BEGIN ****/ + + /** + * 404页面 + * @param request + * @param response + * @return + */ + @ApiOperation(value = "404页面", notes = "404页面") @GetMapping("Out404") public String Out404(HttpServletRequest request, HttpServletResponse response) { - return "redirect:/error/404"; } + /** + * 403页面 + * @param request + * @param response + * @return + */ + @ApiOperation(value = "403页面", notes = "403页面") @GetMapping("Out403") - @ApiOperation(value = "403页面" , notes = "403页面") public String Out403(HttpServletRequest request, HttpServletResponse response) { - return "redirect:/error/403"; } - @ApiOperation(value = "500页面" , notes = "500页面") + /** + * 500页面 + * @param request + * @param response + * @return + */ + @ApiOperation(value = "500页面", notes = "500页面") @GetMapping("Out500") public String Out500(HttpServletRequest request, HttpServletResponse response) { - return "redirect:/error/500"; } /** * 权限测试跳转页面 - * * @param request * @param response * @return */ - @ApiOperation(value = "权限测试跳转页面" , notes = "权限测试跳转页面") + @ApiOperation(value = "权限测试跳转页面", notes = "权限测试跳转页面") @GetMapping("Outqx") @RequiresPermissions("system:user:asd") public String Outqx(HttpServletRequest request, HttpServletResponse response) { - return "redirect:/error/500"; } /**** 页面测试EDN ****/ diff --git a/src/main/java/com/fc/v2/controller/admin/SysDepartmentController.java b/src/main/java/com/fc/v2/controller/admin/SysDepartmentController.java index 2581e278cec7e814f519bcd365884234a3d905e3..d534a45410f571ef9ecf004dc97ec5a6d9490cb6 100644 --- a/src/main/java/com/fc/v2/controller/admin/SysDepartmentController.java +++ b/src/main/java/com/fc/v2/controller/admin/SysDepartmentController.java @@ -183,6 +183,17 @@ public class SysDepartmentController extends BaseController { return sysDepartmentService.selectTSysDepartmentById(id); } + /** + * 跳转树形列表 + * + * @return + */ + @ApiOperation(value = "跳转树形列表", notes = "跳转树形列表") + @GetMapping("/deptTree") + public String deptTree() { + return prefix + "/dept-tree.html"; + } + /** * 获取部门树状数据结构 * diff --git a/src/main/java/com/fc/v2/controller/admin/SysUserController.java b/src/main/java/com/fc/v2/controller/admin/SysUserController.java index 221a0772b9cd8f492fe7bc6a4cbaa062ea4bcbb8..5cc5b0d5a505e22bc28e3f9281dcfb8db5598263 100644 --- a/src/main/java/com/fc/v2/controller/admin/SysUserController.java +++ b/src/main/java/com/fc/v2/controller/admin/SysUserController.java @@ -2,7 +2,9 @@ package com.fc.v2.controller.admin; import java.util.List; +import cn.hutool.http.HttpStatus; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.fc.v2.common.conf.V2Config; import com.fc.v2.common.domain.ResultTable; import com.fc.v2.model.auto.TSysDepartment; import com.fc.v2.model.auto.TSysPosition; @@ -10,6 +12,9 @@ import com.fc.v2.model.auto.TSysRole; import com.fc.v2.model.auto.TSysUser; import com.fc.v2.service.ITSysDepartmentService; import com.fc.v2.service.ITSysPositionService; +import com.fc.v2.shiro.util.ShiroUtils; +import com.fc.v2.util.MD5Util; +import com.fc.v2.util.file.FileUploadUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -22,6 +27,7 @@ import com.fc.v2.model.custom.RoleVo; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.springframework.web.multipart.MultipartFile; /** * 用户Controller @@ -49,6 +55,12 @@ public class SysUserController extends BaseController { @Autowired private ITSysPositionService positionService; + /** + * v2配置 + */ + @Autowired + private V2Config config; + /** * 展示跳转页面 * @@ -70,7 +82,7 @@ public class SysUserController extends BaseController { * @param tSysUser * @return */ - @Log(title = "分页查询", action = "1") + @Log(title = "分页查询", action = "list") @ApiOperation(value = "分页查询", notes = "分页查询") @GetMapping("/list") @RequiresPermissions("system:user:list") @@ -81,6 +93,23 @@ public class SysUserController extends BaseController { return pageTable(page.getList(), page.getTotal()); } + /** + * 按部门查询用户列表 + * + * @param deptIds + * @return + */ + @Log(title = "分页查询", action = "list") + @ApiOperation(value = "分页查询", notes = "分页查询") + @GetMapping("/dept/list") + @RequiresPermissions("system:user:list") + @ResponseBody + public ResultTable list(String deptIds) { + startPage(); + PageInfo page = new PageInfo(sysUserService.selectTSysUserByDepIdList(deptIds)); + return pageTable(page.getList(), page.getTotal()); + } + /** * 新增跳转 * @@ -123,7 +152,7 @@ public class SysUserController extends BaseController { @ResponseBody public AjaxResult add(TSysUser user, @RequestParam(value = "roleIds", required = false) String roleIds) { if (sysUserService.checkLoginNameUnique(user) > 0){ - return error("登陆用户名重复"); + return error("用户账号重复"); } return toAjax(sysUserService.insertUserRoles(user, roleIds)); } @@ -210,4 +239,111 @@ public class SysUserController extends BaseController { public AjaxResult editPwdSave(TSysUser tsysUser) { return toAjax(sysUserService.updateUserPassword(tsysUser)); } + + /** + * 个人详细信息 + * + * @param map + * @return + */ + @ApiOperation(value = "个人详细信息", notes = "个人详细信息") + @GetMapping("/user/person") + public String userInfo(ModelMap map){ + TSysUser tSysUser = ShiroUtils.getUser(); + map.put("user", tSysUser); + map.put("fuce", config); + return prefix + "/person.html"; + } + + /** + * 跳转上传页面 + * + * @return + */ + @ApiOperation(value = "跳转上传页面", notes = "跳转上传页面") + @GetMapping("/user/uploadProfile") + public String uploadProfile(){ + return prefix + "/uploadProfile.html"; + } + + /** + * 上传头像 + * + * @param file + * @return + */ + @ApiOperation(value = "上传头像", notes = "上传头像") + @PostMapping("/user/updateAvatar") + @ResponseBody + public AjaxResult updateAvatar(MultipartFile file){ + + TSysUser tSysUser = ShiroUtils.getUser(); + + try { + if (!file.isEmpty()){ + String avatar = FileUploadUtils.upload(config.getProfile(), config.getAvatarPath(), file); + tSysUser.setAvatar(avatar); + if (sysUserService.updateTSysUser(tSysUser) > 0){ + ShiroUtils.setUser(sysUserService.selectTSysUserById(tSysUser.getId())); + return success(HttpStatus.HTTP_OK,"操作成功", avatar); + } + } + return error(); + }catch (Exception e){ + return error(e.getMessage()); + } + } + + /** + * 修改保存用户 + * + * @param tsysUser + * @return + */ + @Log(title = "修改保存用户", action = "update") + @ApiOperation(value = "修改保存用户", notes = "修改保存用户") + @PostMapping("/user/update") + @ResponseBody + public AjaxResult update(TSysUser tsysUser) { + if (sysUserService.updateTSysUser(tsysUser) > 0){ + ShiroUtils.setUser(sysUserService.selectTSysUserById(tsysUser.getId())); + return success(); + } + return error(); + } + + /** + * 重置密码 + * + * @param tsysUser + * @return + */ + @Log(title = "重置密码", action = "update") + @ApiOperation(value = "重置密码", notes = "重置密码") + @PostMapping("/user/resetPwd") + @ResponseBody + public AjaxResult resetPwd(TSysUser tsysUser, String oldPassword, String newPassword, String confirmPassword) { + + if (!MD5Util.encode(newPassword).equals(MD5Util.encode(confirmPassword))){ + return error("两次密码输入不一致"); + } + + tsysUser = sysUserService.selectTSysUserById(tsysUser.getId()); + + if (!MD5Util.encode(oldPassword).equals(tsysUser.getPassword())){ + return error("修改密码失败,旧密码错误"); + } + + if (MD5Util.encode(newPassword).equals(tsysUser.getPassword())){ + return error("新密码不能与旧密码相同"); + } + + tsysUser.setPassword(MD5Util.encode(newPassword)); + if (sysUserService.updateTSysUser(tsysUser) > 0){ + ShiroUtils.setUser(sysUserService.selectTSysUserById(tsysUser.getId())); + return success(); + } + + return error("修改密码异常,请联系管理员"); + } } diff --git a/src/main/java/com/fc/v2/mapper/auto/TSysUserMapper.java b/src/main/java/com/fc/v2/mapper/auto/TSysUserMapper.java index e6847ffad0af3d458172ccd334d815158a57863f..5d949c2f7f8f9d47ea00f7eb382bd861efca56f9 100644 --- a/src/main/java/com/fc/v2/mapper/auto/TSysUserMapper.java +++ b/src/main/java/com/fc/v2/mapper/auto/TSysUserMapper.java @@ -4,7 +4,6 @@ package com.fc.v2.mapper.auto; import java.util.List; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.fc.v2.model.auto.TSysUser; -import org.apache.ibatis.annotations.Select; /** * 用户Mapper接口 @@ -13,14 +12,14 @@ import org.apache.ibatis.annotations.Select; * @date 2021-08-05 */ public interface TSysUserMapper extends BaseMapper { + /** - * 根据用户名字查询用户 + * 查询用户 * - * @param username + * @param id * @return */ - @Select("select id, username, password, nickname, dep_id, pos_id, create_by, create_time, update_by, update_time, remark from t_sys_user where username = #{username}") - public TSysUser queryUserName(String username); + public TSysUser selectTSysUserById(Long id); /** * 查询用户列表 @@ -29,4 +28,12 @@ public interface TSysUserMapper extends BaseMapper { * @return */ public List selectTSysUserList(TSysUser tSysUser); + + /** + * 查询用户列表 + * + * @param depId + * @return + */ + public List selectTSysUserByDepIdList(String[] depId); } \ No newline at end of file diff --git a/src/main/java/com/fc/v2/model/auto/TSysUser.java b/src/main/java/com/fc/v2/model/auto/TSysUser.java index 183faf195765ee7723a3f0446ec8925295586b57..47bd132c4463f8e7920cbf19a6405ca4124af081 100644 --- a/src/main/java/com/fc/v2/model/auto/TSysUser.java +++ b/src/main/java/com/fc/v2/model/auto/TSysUser.java @@ -40,6 +40,26 @@ public class TSysUser extends BaseEntity @ApiModelProperty(value = "昵称") private String nickname; + /** 用户类型 */ + @ApiModelProperty(value = "用户类型") + private String userType; + + /** 用户邮箱 */ + @ApiModelProperty(value = "用户邮箱") + private String email; + + /** 手机号码 */ + @ApiModelProperty(value = "手机号码") + private String phonenumber; + + /** 用户性别 0=男,1=女,2=未知*/ + @ApiModelProperty(value = "用户性别") + private String sex; + + /** 用户头像 */ + @ApiModelProperty(value = "用户头像") + private String avatar; + /** 部门id */ @ApiModelProperty(value = "部门id") private Long depId; @@ -127,6 +147,46 @@ public class TSysUser extends BaseEntity return posId; } + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhonenumber() { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) { + this.phonenumber = phonenumber; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -134,6 +194,11 @@ public class TSysUser extends BaseEntity .append("username", getUsername()) .append("password", getPassword()) .append("nickname", getNickname()) + .append("userType", getUserType()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) .append("depId", getDepId()) .append("posId", getPosId()) .append("createBy", getCreateBy()) @@ -143,4 +208,6 @@ public class TSysUser extends BaseEntity .append("remark", getRemark()) .toString(); } + + } diff --git a/src/main/java/com/fc/v2/model/custom/email/MailSenderInfo.java b/src/main/java/com/fc/v2/model/custom/email/MailSenderInfo.java index b27544417e0866584d6b96118400fa9d05bf8a55..cc4ec5649cd0d3dd94936287db7167d60eaf4de1 100644 --- a/src/main/java/com/fc/v2/model/custom/email/MailSenderInfo.java +++ b/src/main/java/com/fc/v2/model/custom/email/MailSenderInfo.java @@ -1,164 +1,196 @@ package com.fc.v2.model.custom.email; import java.security.GeneralSecurityException; -/** - * 发送邮件需要使用的基本信息 -* @author FH QQ 313596790[青苔] -* 修改时间:2015年7月27日 -* @version 2.0 - */ import java.util.Properties; - import com.sun.mail.util.MailSSLSocketFactory; + /** * 邮件model - * @ClassName: MailSenderInfo + * + * @className: MailSenderInfo * @author fuce * @date 2019-06-10 01:06 * @version V1.0 */ public class MailSenderInfo { - // 发送邮件的服务器的IP和端口 - private String mailServerHost; - private String mailServerPort = "25"; - // 邮件发送者的地址 - private String fromAddress; - // 邮件接收者的地址 - private String toAddress; - // 登陆邮件发送服务器的用户名和密码 - private String userName; - private String password; - // 是否需要身份验证 - private boolean validate = false; - //开启ssl - private boolean ssl=false; - // 邮件主题 - private String subject; - // 邮件的文本内容 - private String content; - // 邮件附件的文件名 - private String[] attachFileNames; - - /** - * 获得邮件会话属性 - */ - public Properties getProperties() { - Properties p = new Properties(); - p.put("mail.smtp.host", this.mailServerHost); - p.put("mail.smtp.port", this.mailServerPort); - p.put("mail.smtp.auth", validate ? "true" : "false"); - //-------当需使用SSL验证时添加,邮箱不需SSL验证时删除即可(测试SSL验证使用QQ企业邮箱) - if(ssl) { - String SSL_FACTORY="javax.net.ssl.SSLSocketFactory"; - p.put("mail.smtp.socketFactory.class", SSL_FACTORY); - p.put("mail.smtp.socketFactory.fallback", "false"); - p.put("mail.smtp.socketFactory.port", this.mailServerPort); - MailSSLSocketFactory sf=null; - try { - sf = new MailSSLSocketFactory(); - } catch (GeneralSecurityException e) { - e.printStackTrace(); - } - sf.setTrustAllHosts(true); - p.put("mail.smtp.ssl.socketFactory", sf); - } - - return p; - } - - public String getMailServerHost() { - return mailServerHost; - } - - public void setMailServerHost(String mailServerHost) { - this.mailServerHost = mailServerHost; - } - - public String getMailServerPort() { - return mailServerPort; - } - - public void setMailServerPort(String mailServerPort) { - this.mailServerPort = mailServerPort; - } - - public boolean isValidate() { - return validate; - } - - public void setValidate(boolean validate) { - this.validate = validate; - } - - public String[] getAttachFileNames() { - return attachFileNames; - } - - public void setAttachFileNames(String[] fileNames) { - this.attachFileNames = fileNames; - } - - public String getFromAddress() { - return fromAddress; - } - - public void setFromAddress(String fromAddress) { - this.fromAddress = fromAddress; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getToAddress() { - return toAddress; - } - - public void setToAddress(String toAddress) { - this.toAddress = toAddress; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getSubject() { - return subject; - } - - public void setSubject(String subject) { - this.subject = subject; - } - - public String getContent() { - return content; - } - - public void setContent(String textContent) { - this.content = textContent; - } - - /** - * @return the ssl - */ - public boolean isSsl() { - return ssl; - } - - /** - * @param ssl the ssl to set - */ - public void setSsl(boolean ssl) { - this.ssl = ssl; - } - - + + /** + * 发送邮件的服务器的IP和端口 + */ + private String mailServerHost; + + /** + * 默认端口 + */ + private String mailServerPort = "25"; + + /** + * 邮件发送者的地址 + */ + private String fromAddress; + + /** + * 邮件接收者的地址 + */ + private String toAddress; + + /** + * 登陆邮件发送服务器的用户名 + */ + private String userName; + + /** + * 登陆邮件发送服务器的密码 + */ + private String password; + + /** + * 是否需要身份验证 + */ + private boolean validate = false; + + /** + * 开启ssl + */ + private boolean ssl = false; + + /** + * 邮件主题 + */ + private String subject; + + /** + * 邮件的文本内容 + */ + private String content; + + /** + * 邮件附件的文件名 + */ + private String[] attachFileNames; + + /** + * 获得邮件会话属性 + */ + public Properties getProperties() { + Properties p = new Properties(); + p.put("mail.smtp.host", this.mailServerHost); + p.put("mail.smtp.port", this.mailServerPort); + p.put("mail.smtp.auth", validate ? "true" : "false"); + // -------当需使用SSL验证时添加,邮箱不需SSL验证时删除即可(测试SSL验证使用QQ企业邮箱) + if (ssl) { + String sslFactory = "javax.net.ssl.SSLSocketFactory"; + p.put("mail.smtp.socketFactory.class", sslFactory); + p.put("mail.smtp.socketFactory.fallback", "false"); + p.put("mail.smtp.socketFactory.port", this.mailServerPort); + MailSSLSocketFactory sf = null; + try { + sf = new MailSSLSocketFactory(); + } catch (GeneralSecurityException e) { + e.printStackTrace(); + } + sf.setTrustAllHosts(true); + p.put("mail.smtp.ssl.socketFactory", sf); + } + + return p; + } + + public String getMailServerHost() { + return mailServerHost; + } + + public void setMailServerHost(String mailServerHost) { + this.mailServerHost = mailServerHost; + } + + public String getMailServerPort() { + return mailServerPort; + } + + public void setMailServerPort(String mailServerPort) { + this.mailServerPort = mailServerPort; + } + + public boolean isValidate() { + return validate; + } + + public void setValidate(boolean validate) { + this.validate = validate; + } + + public String[] getAttachFileNames() { + return attachFileNames; + } + + public void setAttachFileNames(String[] fileNames) { + this.attachFileNames = fileNames; + } + + public String getFromAddress() { + return fromAddress; + } + + public void setFromAddress(String fromAddress) { + this.fromAddress = fromAddress; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getToAddress() { + return toAddress; + } + + public void setToAddress(String toAddress) { + this.toAddress = toAddress; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getContent() { + return content; + } + + /** + * + * @param textContent + */ + public void setContent(String textContent) { + this.content = textContent; + } + + /** + * @return the ssl + */ + public boolean isSsl() { + return ssl; + } + + /** + * @param ssl the ssl to set + */ + public void setSsl(boolean ssl) { + this.ssl = ssl; + } } diff --git a/src/main/java/com/fc/v2/model/custom/email/MyAuthenticator.java b/src/main/java/com/fc/v2/model/custom/email/MyAuthenticator.java index 0fdfd7a4e692fea24bbbefecffb77baf579dbd5e..14c4653b05daeb5851ee3ab49cde77017dfeefb4 100644 --- a/src/main/java/com/fc/v2/model/custom/email/MyAuthenticator.java +++ b/src/main/java/com/fc/v2/model/custom/email/MyAuthenticator.java @@ -4,23 +4,28 @@ import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** - * 发送邮件需要使用的基本信息 + * 发送邮件需要使用的基本信息 + * * @ClassName: MyAuthenticator * @author fuce * @date 2019-06-10 01:06 * @version V1.0 */ -public class MyAuthenticator extends Authenticator{ - String userName=null; - String password=null; - - public MyAuthenticator(){ - } - public MyAuthenticator(String username, String password) { - this.userName = username; - this.password = password; - } - protected PasswordAuthentication getPasswordAuthentication(){ - return new PasswordAuthentication(userName, password); - } -} +public class MyAuthenticator extends Authenticator { + + String userName = null; + + String password = null; + + public MyAuthenticator() {} + + public MyAuthenticator(String username, String password) { + this.userName = username; + this.password = password; + } + + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(userName, password); + } +} diff --git a/src/main/java/com/fc/v2/service/ITSysUserService.java b/src/main/java/com/fc/v2/service/ITSysUserService.java index b7ecc32e6630b00af50a124be21014b9351230e7..60f0d54a04330f7b91ec75d39e10d6fbee71838c 100644 --- a/src/main/java/com/fc/v2/service/ITSysUserService.java +++ b/src/main/java/com/fc/v2/service/ITSysUserService.java @@ -116,10 +116,10 @@ public interface ITSysUserService extends IService { int updateUserPassword(TSysUser tsysUser); /** - * 根据用户名称查询 + * 查询用户列表 * - * @param username + * @param depIds * @return */ - TSysUser queryUserName(String username); + public List selectTSysUserByDepIdList(String depIds); } diff --git a/src/main/java/com/fc/v2/service/impl/TSysUserServiceImpl.java b/src/main/java/com/fc/v2/service/impl/TSysUserServiceImpl.java index 48d79d0a5d3f55ff7dc63c452bdf4c4e133283d3..051a1ca5dbb98c7f703ffcb800c0b1d10d5b2c09 100644 --- a/src/main/java/com/fc/v2/service/impl/TSysUserServiceImpl.java +++ b/src/main/java/com/fc/v2/service/impl/TSysUserServiceImpl.java @@ -53,7 +53,7 @@ public class TSysUserServiceImpl extends ServiceImpl i */ @Override public TSysUser selectTSysUserById(Long id) { - return this.baseMapper.selectById(id); + return tSysUserMapper.selectTSysUserById(id); } /** @@ -231,13 +231,13 @@ public class TSysUserServiceImpl extends ServiceImpl i } /** - * 根据用户名称查询 + * 查询用户列表 * - * @param username + * @param depIds * @return */ @Override - public TSysUser queryUserName(String username) { - return this.tSysUserMapper.queryUserName(username); + public List selectTSysUserByDepIdList(String depIds) { + return tSysUserMapper.selectTSysUserByDepIdList(ConvertUtil.toStrArray(depIds)); } } diff --git a/src/main/java/com/fc/v2/shiro/service/MyShiroRealm.java b/src/main/java/com/fc/v2/shiro/service/MyShiroRealm.java index e92093297d395e7aaa7b128a99e7ed65cd67065e..8262a79f6eb45095d6e366468216a7eff9c6b715 100644 --- a/src/main/java/com/fc/v2/shiro/service/MyShiroRealm.java +++ b/src/main/java/com/fc/v2/shiro/service/MyShiroRealm.java @@ -7,6 +7,7 @@ import com.fc.v2.service.ITSysPermissionService; import com.fc.v2.service.ITSysRoleService; import com.fc.v2.service.ITSysUserService; import com.fc.v2.util.StringUtils; +import cn.hutool.core.collection.CollUtil; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; @@ -26,82 +27,89 @@ import java.util.List; * 身份校验核心类 * * @author fuce - * @ClassName: MyShiroRealm + * @className: MyShiroRealm * @date 2018年8月25日 */ @Service public class MyShiroRealm extends AuthorizingRealm { + /** + * 用户 + */ @Autowired private ITSysUserService userService; - //权限dao + /** + * 权限 + */ @Autowired private ITSysPermissionService permissionService; - //角色dao + /** + * 角色 + */ @Autowired private ITSysRoleService roleService; /** * 认证登陆 + * @param token + * @return authenticationInfo + * @throws */ @SuppressWarnings("unused") @Override - protected AuthenticationInfo doGetAuthenticationInfo( - AuthenticationToken token) throws AuthenticationException { + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { - //加这一步的目的是在Post请求的时候会先进认证,然后在到请求 - if (token.getPrincipal() == null) { + //加这一步的目的是在Post请求的时候会先进认证,然后在到请求 + if (StringUtils.isNull(token.getPrincipal())) { return null; } + String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); // 通过username从数据库中查找 User对象,如果找到,没找到. // 实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法 - TSysUser userInfo = userService.queryUserName(username); -// System.out.println(userInfo); -// System.out.println("----->>userInfo=" + userInfo.getUsername() + "---"+ userInfo.getPassword()); - if (userInfo == null) + TSysUser userInfo = new TSysUser(); + userInfo.setUsername(username); + List list = userService.selectTSysUserList(userInfo); + + if (CollUtil.isEmpty(list)) { return null; - else { - SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( - userInfo, // 用户对象 - userInfo.getPassword(), // 密码 - getName() // realm name - ); - return authenticationInfo; } + userInfo = list.get(0); + return new SimpleAuthenticationInfo(userInfo, userInfo.getPassword(), getName()); } /** * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用. + * @param principals + * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { - //System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()"); - if (principals == null) { + + if (StringUtils.isNull(principals)) { throw new AuthorizationException("principals should not be null"); } + SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); TSysUser userinfo = (TSysUser) principals.getPrimaryPrincipal(); Long uid = userinfo.getId(); List tsysRoles = roleService.queryUserRole(uid); - for (TSysRole userrole : tsysRoles) { - //System.out.println("角色名字:"+gson.toJson(userrole)); - Long rolid = userrole.getId();//角色id - authorizationInfo.addRole(userrole.getName());//添加角色名字 - List permissions = permissionService.queryRoleId(rolid); - for (TSysPermission p : permissions) { - //System.out.println("角色下面的权限:"+gson.toJson(p)); - if (StringUtils.isNotEmpty(p.getPerms())) { - authorizationInfo.addStringPermission(p.getPerms()); + tsysRoles.forEach(userrole -> { + //添加角色名字 + authorizationInfo.addRole(userrole.getName()); + List permissions = permissionService.queryRoleId(userrole.getId()); + permissions.forEach(permission ->{ + //角色下面的权限 + if (StringUtils.isNotEmpty(permission.getPerms())){ + authorizationInfo.addStringPermission(permission.getPerms()); } - - } - } + }); + }); return authorizationInfo; } @@ -112,5 +120,4 @@ public class MyShiroRealm extends AuthorizingRealm { public void clearCachedAuthorizationInfo() { this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals()); } - } diff --git a/src/main/java/com/fc/v2/util/AutoCode/AutoCodeUtil.java b/src/main/java/com/fc/v2/util/AutoCode/AutoCodeUtil.java index bcff202b4b55240ebfdb17ca8e30a4f3bfbf12b4..c6b4e36769f2905b3ab6cb43da4a1bbccab1c50e 100644 --- a/src/main/java/com/fc/v2/util/AutoCode/AutoCodeUtil.java +++ b/src/main/java/com/fc/v2/util/AutoCode/AutoCodeUtil.java @@ -113,10 +113,13 @@ public class AutoCodeUtil { String filepath = getCoverFileName(template, tableInfo, autoCodeConfig.getConfigkey("parentPack"), targetPath); Template tpl = Velocity.getTemplate(template, "UTF-8"); File file = new File(filepath); - if (!file.getParentFile().exists()) + if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); - if (!file.exists()) + } + + if (!file.exists()) { file.createNewFile(); + } try (FileOutputStream outStream = new FileOutputStream(file); OutputStreamWriter writer = new OutputStreamWriter(outStream, "UTF-8"); BufferedWriter sw = new BufferedWriter(writer)) { diff --git a/src/main/java/com/fc/v2/util/file/FileTypeUtils.java b/src/main/java/com/fc/v2/util/file/FileTypeUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..5a18ee19c526d63be902e4314844cbfc077c8915 --- /dev/null +++ b/src/main/java/com/fc/v2/util/file/FileTypeUtils.java @@ -0,0 +1,77 @@ +package com.fc.v2.util.file; + +import org.apache.commons.lang3.StringUtils; + +import java.io.File; + +/** + * 文件类型工具类 + * + * @author zhaonz + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param file 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(File file) + { + if (null == file) + { + return StringUtils.EMPTY; + } + return getFileType(file.getName()); + } + + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param fileName 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(String fileName) + { + int separatorIndex = fileName.lastIndexOf("."); + if (separatorIndex < 0) + { + return ""; + } + return fileName.substring(separatorIndex + 1).toLowerCase(); + } + + /** + * 获取文件类型 + * + * @param photoByte 文件字节码 + * @return 后缀(不含".") + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "GIF"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "JPG"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "BMP"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } +} \ No newline at end of file diff --git a/src/main/java/com/fc/v2/util/file/FileUploadUtils.java b/src/main/java/com/fc/v2/util/file/FileUploadUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..64beaaf010fe440d1e86aee9ac349a58d8d062f5 --- /dev/null +++ b/src/main/java/com/fc/v2/util/file/FileUploadUtils.java @@ -0,0 +1,198 @@ +package com.fc.v2.util.file; + +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.fc.v2.common.exception.file.InvalidExtensionException; +import com.fc.v2.util.DateUtils; +import com.fc.v2.util.StringUtils; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; + +/** + * 文件上传工具类 + * + * @author zhaonz + */ +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String upload(String defaultDir, String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(defaultDir, baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws Exception 异常 + */ + public static final String upload(String defaultDir, String baseDir, MultipartFile file, String[] allowedExtension) + throws Exception + { + int fileNamelength = file.getOriginalFilename().length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new RuntimeException("文件名称长度超长"); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + File desc = getAbsoluteFile(baseDir, fileName); + file.transferTo(desc); + String pathFileName = getPathFileName(defaultDir, baseDir, fileName); + return pathFileName; + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + fileName = DateUtils.datePath() + "/" + IdWorker.getId() + "." + extension; + return fileName; + } + + private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc; + } + + private static final String getPathFileName(String defaultDir, String uploadDir, String fileName) throws IOException + { + int dirLastIndex = defaultDir.length() + 1; + String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + String pathFileName = RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; + return pathFileName; + } + + /** + * 文件大小校验 + * + * @param file 上传的文件 + * @return + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws InvalidExtensionException + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws Exception + { + long size = file.getSize(); + if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) + { + throw new RuntimeException("文件长度超长"); + } + + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new RuntimeException("filename:"+fileName + " extension:" + extension); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + + } + + /** + * 判断MIME类型是否是允许的MIME类型 + * + * @param extension + * @param allowedExtension + * @return + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } + + /** + * 获取文件名的后缀 + * + * @param file 表单文件 + * @return 后缀名 + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(file.getContentType()); + } + return extension; + } +} \ No newline at end of file diff --git a/src/main/java/com/fc/v2/util/file/FileUtils.java b/src/main/java/com/fc/v2/util/file/FileUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..bef5e19c2fb43bfb82aa8ecc815f8be9f44d67f8 --- /dev/null +++ b/src/main/java/com/fc/v2/util/file/FileUtils.java @@ -0,0 +1,199 @@ +package com.fc.v2.util.file; + +import com.fc.v2.util.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * 文件处理工具类 + * + * @author zhaonz + */ +public class FileUtils +{ + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 输出指定文件的byte数组 + * + * @param filePath 文件路径 + * @param os 输出流 + * @return + */ + public static void writeBytes(String filePath, OutputStream os) throws IOException + { + FileInputStream fis = null; + try + { + File file = new File(filePath); + if (!file.exists()) + { + throw new FileNotFoundException(filePath); + } + fis = new FileInputStream(file); + byte[] b = new byte[1024]; + int length; + while ((length = fis.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + if (os != null) + { + try + { + os.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (fis != null) + { + try + { + fis.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 删除文件 + * + * @param filePath 文件 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 路径为文件且不为空则进行删除 + if (file.isFile() && file.exists()) + { + file.delete(); + flag = true; + } + return flag; + } + + /** + * 文件名称验证 + * + * @param filename 文件名称 + * @return true 正常 false 非法 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 检查文件是否可下载 + * + * @param resource 需要下载的文件 + * @return true 正常 false 非法 + */ + public static boolean checkAllowDownload(String resource) + { + // 禁止目录上跳级别 + if (StringUtils.contains(resource, "..")) + { + return false; + } + + // 检查允许下载的文件规则 + if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) + { + return true; + } + + // 不在允许下载的文件规则 + return false; + } + + /** + * 下载文件名重新编码 + * + * @param request 请求对象 + * @param fileName 文件名 + * @return 编码后的文件名 + */ + public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException + { + final String agent = request.getHeader("USER-AGENT"); + String filename = fileName; + if (agent.contains("MSIE")) + { + // IE浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + filename = filename.replace("+", " "); + } + else if (agent.contains("Firefox")) + { + // 火狐浏览器 + filename = new String(fileName.getBytes(), "ISO8859-1"); + } + else if (agent.contains("Chrome")) + { + // google浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + else + { + // 其它浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + return filename; + } + + /** + * 下载文件名重新编码 + * + * @param response 响应对象 + * @param realFileName 真实文件名 + * @return + */ + public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException + { + String percentEncodedFileName = percentEncode(realFileName); + + StringBuilder contentDispositionValue = new StringBuilder(); + contentDispositionValue.append("attachment; filename=") + .append(percentEncodedFileName) + .append(";") + .append("filename*=") + .append("utf-8''") + .append(percentEncodedFileName); + + response.setHeader("Content-disposition", contentDispositionValue.toString()); + } + + /** + * 百分号编码工具方法 + * + * @param s 需要百分号编码的字符串 + * @return 百分号编码后的字符串 + */ + public static String percentEncode(String s) throws UnsupportedEncodingException + { + String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + return encode.replaceAll("\\+", "%20"); + } +} diff --git a/src/main/java/com/fc/v2/util/file/MimeTypeUtils.java b/src/main/java/com/fc/v2/util/file/MimeTypeUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..8b7b08bf0e2e7bdf4d7daaf1c0539bb12cfd3194 --- /dev/null +++ b/src/main/java/com/fc/v2/util/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.fc.v2.util.file; + +/** + * 媒体类型工具类 + * + * @author zhaonz + */ +public class MimeTypeUtils +{ + public static final String IMAGE_PNG = "image/png"; + + public static final String IMAGE_JPG = "image/jpg"; + + public static final String IMAGE_JPEG = "image/jpeg"; + + public static final String IMAGE_BMP = "image/bmp"; + + public static final String IMAGE_GIF = "image/gif"; + + public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; + + public static final String[] FLASH_EXTENSION = { "swf", "flv" }; + + public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", + "asf", "rm", "rmvb" }; + + public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" }; + + public static final String[] DEFAULT_ALLOWED_EXTENSION = { + // 图片 + "bmp", "gif", "jpg", "jpeg", "png", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 压缩文件 + "rar", "zip", "gz", "bz2", + // 视频格式 + "mp4", "avi", "rmvb", + // pdf + "pdf" }; + + public static String getExtension(String prefix) + { + switch (prefix) + { + case IMAGE_PNG: + return "png"; + case IMAGE_JPG: + return "jpg"; + case IMAGE_JPEG: + return "jpeg"; + case IMAGE_BMP: + return "bmp"; + case IMAGE_GIF: + return "gif"; + default: + return ""; + } + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7139de50f1a5bf1606a39ffe90246aaa01822a69..9ef4e2c8f5a6d6aefab177f30ac3e5bd26569416 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,6 +19,8 @@ fuce: demo-enabled: false #漂亮得拖动验证码 默认false普通验证码、true滚动验证码 roll-verification: false + # 文件路径 示例( Windows配置D:/v2/uploadPath,Linux配置 /home/v2/uploadPath) + profile: D:/v2/uploadPath #tomcat config server : port : 8080 diff --git a/src/main/resources/mybatis/auto/TsysUserMapper.xml b/src/main/resources/mybatis/auto/TsysUserMapper.xml index 8e2566fef9fcdcef2430971b831556da4631290e..8c1b071311b640e197e82699d8614329556696fc 100644 --- a/src/main/resources/mybatis/auto/TsysUserMapper.xml +++ b/src/main/resources/mybatis/auto/TsysUserMapper.xml @@ -9,20 +9,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - - - - - - - - - - - - - - + + + + + @@ -35,23 +26,43 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, username, password, nickname, dep_id, pos_id, create_by, create_time, update_by, update_time, remark from t_sys_user + select user.id, user.username, user.password, user.nickname, user.user_type, user.email, user.avatar, user.phonenumber, + user.sex, user.dep_id, user.pos_id, user.create_by, user.create_time, user.update_by, user.update_time, user.remark, + dept.dept_name "dep_name", post.post_name "pos_name" from t_sys_user user, t_sys_department dept, t_sys_position post - + + + user.dep_id = dept.id and user.pos_id = post.id and user.id = #{id} + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/admin/index.html b/src/main/resources/templates/admin/index.html index bf906dd1ea45132bc343c1a0237d61c1692dde6d..f55fda61dc9561082556a6031126c4d7de6a03ce 100644 --- a/src/main/resources/templates/admin/index.html +++ b/src/main/resources/templates/admin/index.html @@ -35,12 +35,12 @@

  • - - + +
    -
    基本资料
    +
    基本资料
    注销登录
  • @@ -73,44 +73,52 @@ diff --git a/src/main/resources/templates/admin/sysDepartment/dept-tree.html b/src/main/resources/templates/admin/sysDepartment/dept-tree.html new file mode 100644 index 0000000000000000000000000000000000000000..b72c4d51296c42cad7e259666a1cb9d131094bc0 --- /dev/null +++ b/src/main/resources/templates/admin/sysDepartment/dept-tree.html @@ -0,0 +1,62 @@ + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/src/main/resources/templates/admin/sysPermission/tree.html b/src/main/resources/templates/admin/sysPermission/tree.html index 84aba8d860f22f721c5480e0038c3ebceb1ef096..74af9f8cb13349cf627bbcd823809a256c5582d5 100644 --- a/src/main/resources/templates/admin/sysPermission/tree.html +++ b/src/main/resources/templates/admin/sysPermission/tree.html @@ -40,7 +40,7 @@ checkbar: true, skin: "layui", initLevel: "1", - checkbarType: "self", + checkbarType: "all", // 默认就是all,其他的值为: no-all p-casc self only response: {treeId: "powerId", parentId: "parentId", title: "powerName"}, }); diff --git a/src/main/resources/templates/admin/sysUser/add.html b/src/main/resources/templates/admin/sysUser/add.html index a03786ab264580eba7750f2a153c9189422dfbd7..f1ef92cdc9aed9994d769ad2ff06ebb71e106957 100644 --- a/src/main/resources/templates/admin/sysUser/add.html +++ b/src/main/resources/templates/admin/sysUser/add.html @@ -8,45 +8,78 @@
      + + +
      + +
      + +
      +
      +
      - +
      - +
      +
      +
      + +
      + +
      +
      - +
      - +
      +
      - +
      - + +
      - +
      -
        +
        +
        - + +
        + +
        +
        + +
        + +
        + +
        +
        + +
        +
        +
        - +
        @@ -74,30 +107,38 @@ let dtree = layui.dtree; let MODULE_PATH = rootPath+"/UserController"; let DEPAR_PATH=rootPath+"/SysDepartmentController"; - //部门树 - dtree.renderSelect({ - elem: "#selectParent", - url: DEPAR_PATH+"/tree", - method: 'get', - selectInputName: {nodeId: "depId"}, - skin: "layui", - dataFormat: "list", - response: {treeId: "id", parentId: "parentId", title: "deptName"}, - selectInitVal: "1" - }); + + form.render(); //名称验证 form.verify({ username: function(value){ - if(value.length < 2){ - return '标题至少得2个字符啊'; + if(value.length < 4){ + return '用户账号必须大于4个字符'; + } + }, + password: function(value){ + let pwd = $("input[name='newpassword']").val(); + let confirm = $("input[name='password']").val(); + if(pwd !== confirm){ + return '两次密码输入不一致'; } } }); + //点击部门 + $("#depName").focus(function () { + layer.open({ + type: 2, + title: '部门列表', + shade: 0.1, + area: ['320px', '600px'], + content: DEPAR_PATH + '/deptTree' + }); + }); + //保存 form.on('submit(user-save)', function (data) { - let roleIds = ""; $('input[type=checkbox]:checked').each(function () { roleIds += $(this).val() + ","; diff --git a/src/main/resources/templates/admin/sysUser/edit.html b/src/main/resources/templates/admin/sysUser/edit.html index e2fad2beb1d1600e25849d1a3a513d47310e4c54..c9f0fff9b440898ba59f352af26282d369eaec60 100644 --- a/src/main/resources/templates/admin/sysUser/edit.html +++ b/src/main/resources/templates/admin/sysUser/edit.html @@ -8,31 +8,50 @@
        -
        - + + + +
        +
        - +
        +
        - +
        - +
        +
        +
        + +
        + + +
        +
        - +
        - +
        - +
        -
          + +
          +
          + +
          + +
          + +
          @@ -46,10 +65,7 @@
          - - - +
          @@ -58,8 +74,7 @@
          - @@ -77,20 +92,10 @@ let $ = layui.jquery; let dtree = layui.dtree; let MODULE_PATH = rootPath+"/UserController"; - let DEPAR_PATH=rootPath+"/SysDepartmentController"; + let DEPAR_PATH = rootPath+"/SysDepartmentController"; let username='[[${TsysUser.username}]]'; - //部门树 - dtree.renderSelect({ - elem: "#selectParent", - url: DEPAR_PATH+"/tree", - method: 'get', - selectInputName: {nodeId: "depId"}, - skin: "layui", - dataFormat: "list", - response: {treeId: "id", parentId: "parentId", title: "deptName"}, - selectInitVal: "[[${TsysUser.depId}]]" - }); + form.render(); //名称验证 form.verify({ @@ -119,6 +124,17 @@ } }); + //部门 + $("#depName").focus(function () { + layer.open({ + type: 2, + title: '部门列表', + shade: 0.1, + area: ['320px', '550px'], + content: DEPAR_PATH + '/deptTree' + }); + }); + form.on('submit(user-update)', function (data) { let roleIds = ""; $('input[type=checkbox]:checked').each(function () { diff --git a/src/main/resources/templates/admin/sysUser/editPwd.html b/src/main/resources/templates/admin/sysUser/editPwd.html index 48e1e2e82531a7c789a2724fe0af360d189534af..1f990208de503a2e157502964f1ee2c675a643fe 100644 --- a/src/main/resources/templates/admin/sysUser/editPwd.html +++ b/src/main/resources/templates/admin/sysUser/editPwd.html @@ -8,35 +8,28 @@
          -
          - -
          - -
          -
          + +
          - +
          - +
          - +
          - +
          -
          - @@ -53,36 +46,45 @@ let form = layui.form; let $ = layui.jquery; let MODULE_PATH = rootPath+"/UserController"; + + form.render(); + //名称验证 form.verify({ confirm: function(value){ - let pwd=$("input[name='password']").val(); - let confirm=$("input[name='confirm']").val(); - if(pwd!=confirm){ + let pwd = $("input[name='newPassword']").val(); + let confirm = $("input[name='password']").val(); + if(pwd !== confirm){ return '两次密码输入不一致'; } - } }); form.on('submit(user-update)', function (data) { - $.ajax({ - url: MODULE_PATH+'/editPwd', - data: data.field, - dataType: 'json', - contentType: 'application/x-www-form-urlencoded', - type: 'post', - success: function (result) { - if (result.code==200) { - layer.msg(result.msg, {icon: 1, time: 1000}, function () { - parent.layer.close(parent.layer.getFrameIndex(window.name));//关闭当前页 - parent.layui.table.reload("user-table"); - }); - } else { - layer.msg(result.msg, {icon: 2, time: 1000}); + layer.confirm('确定重置密码?', { + btn: ['确定','取消'] + }, function(){ + $.ajax({ + url: MODULE_PATH+'/editPwd', + data: data.field, + dataType: 'json', + contentType: 'application/x-www-form-urlencoded', + type: 'post', + success: function (result) { + if (result.code==200) { + layer.msg(result.msg, {icon: 1, time: 1000}, function () { + parent.layer.close(parent.layer.getFrameIndex(window.name));//关闭当前页 + parent.layui.table.reload("user-table"); + }); + } else { + layer.msg(result.msg, {icon: 2, time: 1000}); + } } - } - }) + }); + }, function(){ + parent.layer.close(parent.layer.getFrameIndex(window.name));//关闭当前页 + parent.layui.table.reload("user-table"); + }); return false; }); }) diff --git a/src/main/resources/templates/admin/sysUser/list.html b/src/main/resources/templates/admin/sysUser/list.html index f1e0c2a5940bae941c32a94e4947bd59999251fe..3c9713c52da94bb541dc7fbdcc94c5137fe88e57 100644 --- a/src/main/resources/templates/admin/sysUser/list.html +++ b/src/main/resources/templates/admin/sysUser/list.html @@ -8,10 +8,16 @@
          - +
          + + +
          + +
          +
          -
          -
          -
          +
          +
          +
          +
          +
          +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            @@ -43,43 +62,68 @@ + + + diff --git a/src/main/resources/templates/admin/sysUser/uploadProfile.html b/src/main/resources/templates/admin/sysUser/uploadProfile.html new file mode 100644 index 0000000000000000000000000000000000000000..60aeea06e2fcdf348cd65d38eb745c9977258ad4 --- /dev/null +++ b/src/main/resources/templates/admin/sysUser/uploadProfile.html @@ -0,0 +1,127 @@ + + + + + + +
            +
            +
            + +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            + + + + + +
            +
            建议:图片的尺寸宽高比为1:1,大小在5m以内。
            +
            +
            + + + + + \ No newline at end of file