From d43b77b3c88fe4c002cff2fe3bd2af3f7f4f4249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=85?= <1669139609@qq.com> Date: Mon, 24 Jan 2022 16:15:08 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20=E6=96=B0=E5=A2=9EDate=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/LoginController.java | 421 +-------------- .../modules/system/service/ILoginService.java | 112 ++++ .../system/service/impl/LoginServiceImpl.java | 489 ++++++++++++++++++ .../jero/modules/system/util/DateUtils.java | 57 ++ 4 files changed, 676 insertions(+), 403 deletions(-) create mode 100644 jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/ILoginService.java create mode 100644 jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/impl/LoginServiceImpl.java create mode 100644 jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/LoginController.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/LoginController.java index fb9f22be..75661187 100644 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/LoginController.java +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/LoginController.java @@ -5,6 +5,7 @@ import cn.hutool.crypto.asymmetric.RSA; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.jero.modules.system.service.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -21,10 +22,6 @@ import com.jero.common.util.encryption.EncryptedString; import com.jero.modules.system.entity.SysDepart; import com.jero.modules.system.entity.SysUser; import com.jero.modules.system.model.SysLoginModel; -import com.jero.modules.system.service.ISysDepartService; -import com.jero.modules.system.service.ISysDictService; -import com.jero.modules.system.service.ISysLogService; -import com.jero.modules.system.service.ISysUserService; import com.jero.modules.system.util.RandImageUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -48,104 +45,12 @@ import java.util.*; @Slf4j public class LoginController { @Autowired - private ISysUserService sysUserService; - @Autowired - private ISysBaseAPI sysBaseAPI; - @Autowired - private ISysLogService logService; - @Autowired - private RedisUtil redisUtil; - @Autowired - private ISysDepartService sysDepartService; - @Autowired - private ISysDictService sysDictService; - @Resource - private BaseCommonService baseCommonService; + private ILoginService loginService; - private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890"; - //密码登录错误的次数前缀 - public static final String RETRY_LOGIN_PREFIX = "login:retryLoginCount_"; - //密码登录错误的最大限制次数 - public static final int RETRY_LOGIN_MAX_COUNT = 5; @ApiOperation("登录接口") @RequestMapping(value = "/login", method = RequestMethod.POST) public Result login(@RequestBody SysLoginModel sysLoginModel){ - Result result = new Result(); - String username = sysLoginModel.getUsername(); - String password = sysLoginModel.getPassword(); - String rsaPublicKey = sysLoginModel.getRsaPublicKey(); - String rsaPrivateKey = String.valueOf(redisUtil.get(rsaPublicKey)); - //update-begin--Author:scott Date:20190805 for:暂时注释掉密码加密逻辑,有点问题 - //前端密码加密,后端进行密码解密 - //password = AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B", "\\+")).trim();//密码解密 - //update-begin--Author:scott Date:20190805 for:暂时注释掉密码加密逻辑,有点问题 - //update-begin-author:taoyan date:20190828 for:校验验证码 - String captcha = sysLoginModel.getCaptcha(); - if(captcha==null){ - result.error500("验证码无效"); - return result; - } - String lowerCaseCaptcha = captcha.toLowerCase(); - String realKey = MD5Util.MD5Encode(lowerCaseCaptcha+sysLoginModel.getCheckKey(), "utf-8"); - Object checkCode = redisUtil.get(realKey); - //当进入登录页时,有一定几率出现验证码错误 #1714 - if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { - result.error500("验证码错误"); - return result; - } - try { - //解密获取密码和用户名 - password = CommonUtils.decryptBtRsaPriKey(password, rsaPrivateKey); - username = CommonUtils.decryptBtRsaPriKey(username, rsaPrivateKey); - } catch (Exception e) { - e.printStackTrace(); - } - //1. 校验用户是否有效 - //update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysUser::getUsername,username); - SysUser sysUser = sysUserService.getOne(queryWrapper); - //update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false - result = sysUserService.checkUserIsEffective(sysUser); - if(!result.isSuccess()) { - return result; - } - - // 若用户名有效,则查询该账号的登陆失败次数是否符合等保要求 - int retryCount = 0 ; - if ( redisUtil.get(RETRY_LOGIN_PREFIX + username) != null){ - retryCount = (int) redisUtil.get(RETRY_LOGIN_PREFIX + username); - } - if (retryCount >= RETRY_LOGIN_MAX_COUNT){ - result.error500("密码错误次数过多,请稍后重试"); - return result; - } - //2. 校验用户名或密码是否正确 - String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); - String syspassword = sysUser.getPassword(); - if (!syspassword.equals(userpassword)) { - // 重试登录次数加一 - retryCount++; - if( retryCount == 1){ - redisUtil.set(RETRY_LOGIN_PREFIX + username,retryCount,60 * 30); - }else { - redisUtil.set(RETRY_LOGIN_PREFIX + username,retryCount,redisUtil.getExpire(RETRY_LOGIN_PREFIX + username)); - } - String msg = retryCount == RETRY_LOGIN_MAX_COUNT ? "密码错误次数过多,请稍后重试":"用户名或密码错误,剩余可登录次数:"+(RETRY_LOGIN_MAX_COUNT - retryCount); - result.error500(msg); - return result; - } - //登录成功,清除错误登录次数 - redisUtil.del(RETRY_LOGIN_PREFIX + username); - - //用户登录信息 - userInfo(sysUser, result); - //update-begin--Author:wangshuai Date:20200714 for:登录日志没有记录人员 - LoginUser loginUser = new LoginUser(); - BeanUtils.copyProperties(sysUser, loginUser); - baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); - //update-end--Author:wangshuai Date:20200714 for:登录日志没有记录人员 - return result; + return loginService.login(sysLoginModel); } /** @@ -156,30 +61,7 @@ public class LoginController { */ @RequestMapping(value = "/logout") public Result logout(HttpServletRequest request,HttpServletResponse response) { - //用户退出逻辑 - String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); - if(oConvertUtils.isEmpty(token)) { - return Result.error("退出登录失败!"); - } - String username = JwtUtil.getUsername(token); - LoginUser sysUser = sysBaseAPI.getUserByName(username); - if(sysUser!=null) { - //update-begin--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser); - //update-end--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - log.info(" 用户名: "+sysUser.getRealname()+",退出成功! "); - //清空用户登录Token缓存 - redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); - //清空用户登录Shiro权限缓存 - redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); - //清空用户的缓存信息(包括部门信息),例如sys:cache:user:: - redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); - //调用shiro的logout - SecurityUtils.getSubject().logout(); - return Result.OK("退出登录成功!"); - }else { - return Result.error("Token无效!"); - } + return loginService.logout(request,response); } /** @@ -188,29 +70,7 @@ public class LoginController { */ @GetMapping("loginfo") public Result loginfo() { - Result result = new Result(); - JSONObject obj = new JSONObject(); - //update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 - // 获取一天的开始和结束时间 - Calendar calendar = new GregorianCalendar(); - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - Date dayStart = calendar.getTime(); - calendar.add(Calendar.DATE, 1); - Date dayEnd = calendar.getTime(); - // 获取系统访问记录 - Long totalVisitCount = logService.findTotalVisitCount(); - obj.put("totalVisitCount", totalVisitCount); - Long todayVisitCount = logService.findTodayVisitCount(dayStart,dayEnd); - obj.put("todayVisitCount", todayVisitCount); - Long todayIp = logService.findTodayIp(dayStart,dayEnd); - //update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 - obj.put("todayIp", todayIp); - result.setResult(obj); - result.success("登录成功"); - return result; + return loginService.loginfo(); } /** @@ -219,22 +79,9 @@ public class LoginController { */ @GetMapping("visitInfo") public Result>> visitInfo() { - Result>> result = new Result>>(); - Calendar calendar = new GregorianCalendar(); - calendar.set(Calendar.HOUR_OF_DAY,0); - calendar.set(Calendar.MINUTE,0); - calendar.set(Calendar.SECOND,0); - calendar.set(Calendar.MILLISECOND,0); - calendar.add(Calendar.DAY_OF_MONTH, 1); - Date dayEnd = calendar.getTime(); - calendar.add(Calendar.DAY_OF_MONTH, -7); - Date dayStart = calendar.getTime(); - List> list = logService.findVisitCount(dayStart, dayEnd); - result.setResult(oConvertUtils.toLowerCasePageList(list)); - return result; + return loginService.visitInfo(); } - - + /** * 登陆成功选择用户当前部门 * @param user @@ -242,19 +89,7 @@ public class LoginController { */ @RequestMapping(value = "/selectDepart", method = RequestMethod.PUT) public Result selectDepart(@RequestBody SysUser user) { - Result result = new Result(); - String username = user.getUsername(); - if(oConvertUtils.isEmpty(username)) { - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); - username = sysUser.getUsername(); - } - String orgCode= user.getOrgCode(); - this.sysUserService.updateUserDepart(username, orgCode); - SysUser sysUser = sysUserService.getUserByName(username); - JSONObject obj = new JSONObject(); - obj.put("userInfo", sysUser); - result.setResult(obj); - return result; + return loginService.selectDepart(user); } /** @@ -265,83 +100,9 @@ public class LoginController { */ @PostMapping(value = "/sms") public Result sms(@RequestBody JSONObject jsonObject) { - Result result = new Result(); - String mobile = jsonObject.get("mobile").toString(); - //手机号模式 登录模式: "2" 注册模式: "1" - String smsmode=jsonObject.get("smsmode").toString(); - log.info(mobile); - if(oConvertUtils.isEmpty(mobile)){ - result.setMessage("手机号不允许为空!"); - result.setSuccess(false); - return result; - } - Object object = redisUtil.get(mobile); - if (object != null) { - result.setMessage("验证码10分钟内,仍然有效!"); - result.setSuccess(false); - return result; - } - - //随机数 - String captcha = RandomUtil.randomNumbers(6); - JSONObject obj = new JSONObject(); - obj.put("code", captcha); - try { - boolean b = false; - //注册模板 - if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) { - SysUser sysUser = sysUserService.getUserByPhone(mobile); - if(sysUser!=null) { - result.error500(" 手机号已经注册,请直接登录!"); - baseCommonService.addLog("手机号已经注册,请直接登录!", CommonConstant.LOG_TYPE_1, null); - return result; - } - b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE); - }else { - //登录模式,校验用户有效性 - SysUser sysUser = sysUserService.getUserByPhone(mobile); - result = sysUserService.checkUserIsEffective(sysUser); - if(!result.isSuccess()) { - String message = result.getMessage(); - if("该用户不存在,请注册".equals(message)){ - result.error500("该用户不存在或未绑定手机号"); - } - return result; - } - - /** - * smsmode 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板 - */ - if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) { - //登录模板 - b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE); - } else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) { - //忘记密码模板 - b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE); - } - } - - if (b == false) { - result.setMessage("短信验证码发送失败,请稍后重试"); - result.setSuccess(false); - return result; - } - //验证码10分钟内有效 - redisUtil.set(mobile, captcha, 600); - //update-begin--Author:scott Date:20190812 for:issues#391 - //result.setResult(captcha); - //update-end--Author:scott Date:20190812 for:issues#391 - result.setSuccess(true); - - } catch (ClientException e) { - e.printStackTrace(); - result.error500(" 短信接口未配置,请联系管理员!"); - return result; - } - return result; + return loginService.sms(jsonObject); } - /** * 手机号登录接口 * @@ -351,72 +112,7 @@ public class LoginController { @ApiOperation("手机号登录接口") @PostMapping("/phoneLogin") public Result phoneLogin(@RequestBody JSONObject jsonObject) { - Result result = new Result(); - String phone = jsonObject.getString("mobile"); - - //校验用户有效性 - SysUser sysUser = sysUserService.getUserByPhone(phone); - result = sysUserService.checkUserIsEffective(sysUser); - if(!result.isSuccess()) { - return result; - } - - String smscode = jsonObject.getString("captcha"); - Object code = redisUtil.get(phone); - if (!smscode.equals(code)) { - result.setMessage("手机验证码错误"); - return result; - } - //用户信息 - userInfo(sysUser, result); - //添加日志 - baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null); - - return result; - } - - - /** - * 用户信息 - * - * @param sysUser - * @param result - * @return - */ - private Result userInfo(SysUser sysUser, Result result) { - String syspassword = sysUser.getPassword(); - String username = sysUser.getUsername(); - // 生成token - String token = JwtUtil.sign(username, syspassword); - // 设置token缓存有效时间 - redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); - redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000); - - // 获取用户部门信息 - JSONObject obj = new JSONObject(); - List departs = sysDepartService.queryUserDeparts(sysUser.getId()); - obj.put("departs", departs); - if (departs == null || departs.size() == 0) { - obj.put("multi_depart", 0); - } else if (departs.size() == 1) { - sysUserService.updateUserDepart(username, departs.get(0).getOrgCode()); - obj.put("multi_depart", 1); - } else { - //查询当前是否有登录部门 - // update-begin--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去 - SysUser sysUserById = sysUserService.getById(sysUser.getId()); - if(oConvertUtils.isEmpty(sysUserById.getOrgCode())){ - sysUserService.updateUserDepart(username, departs.get(0).getOrgCode()); - } - // update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去 - obj.put("multi_depart", 2); - } - obj.put("token", token); - obj.put("userInfo", sysUser); - obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); - result.setResult(obj); - result.success("登录成功"); - return result; + return loginService.phoneLogin(jsonObject); } /** @@ -425,12 +121,8 @@ public class LoginController { */ @GetMapping(value = "/getEncryptedString") public Result> getEncryptedString(){ - Result> result = new Result>(); - Map map = new HashMap(); - map.put("key", EncryptedString.key); - map.put("iv",EncryptedString.iv); - result.setResult(map); - return result; + return loginService.getEncryptedString(); + } /** @@ -441,20 +133,7 @@ public class LoginController { @ApiOperation("获取验证码") @GetMapping(value = "/randomImage/{key}") public Result randomImage(HttpServletResponse response,@PathVariable String key){ - Result res = new Result(); - try { - String code = RandomUtil.randomString(BASE_CHECK_CODES,4); - String lowerCaseCode = code.toLowerCase(); - String realKey = MD5Util.MD5Encode(lowerCaseCode+key, "utf-8"); - redisUtil.set(realKey, lowerCaseCode, 60); - String base64 = RandImageUtil.generate(code); - res.setSuccess(true); - res.setResult(base64); - } catch (Exception e) { - res.error500("获取验证码出错"+e.getMessage()); - e.printStackTrace(); - } - return res; + return randomImage(response,key); } /** @@ -464,55 +143,8 @@ public class LoginController { * @throws Exception */ @RequestMapping(value = "/mLogin", method = RequestMethod.POST) - public Result mLogin(@RequestBody SysLoginModel sysLoginModel) throws Exception { - Result result = new Result(); - String username = sysLoginModel.getUsername(); - String password = sysLoginModel.getPassword(); - - //1. 校验用户是否有效 - SysUser sysUser = sysUserService.getUserByName(username); - result = sysUserService.checkUserIsEffective(sysUser); - if(!result.isSuccess()) { - return result; - } - - //2. 校验用户名或密码是否正确 - String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); - String syspassword = sysUser.getPassword(); - if (!syspassword.equals(userpassword)) { - result.error500("用户名或密码错误"); - return result; - } - - String orgCode = sysUser.getOrgCode(); - if(oConvertUtils.isEmpty(orgCode)) { - //如果当前用户无选择部门 查看部门关联信息 - List departs = sysDepartService.queryUserDeparts(sysUser.getId()); - if (departs == null || departs.size() == 0) { - result.error500("用户暂未归属部门,不可登录!"); - return result; - } - orgCode = departs.get(0).getOrgCode(); - sysUser.setOrgCode(orgCode); - this.sysUserService.updateUserDepart(username, orgCode); - } - JSONObject obj = new JSONObject(); - //用户登录信息 - obj.put("userInfo", sysUser); - - // 生成token - String token = JwtUtil.sign(username, syspassword); - // 设置超时时间 - redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); - redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000); - - //token 信息 - obj.put("token", token); - result.setResult(obj); - result.setSuccess(true); - result.setCode(200); - baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]!", CommonConstant.LOG_TYPE_1, null); - return result; + public Result mLogin(@RequestBody SysLoginModel sysLoginModel) { + return loginService.mLogin(sysLoginModel); } /** @@ -522,19 +154,9 @@ public class LoginController { */ @RequestMapping(value = "/checkCaptcha", method = RequestMethod.POST) public Result checkCaptcha(@RequestBody SysLoginModel sysLoginModel){ - String captcha = sysLoginModel.getCaptcha(); - String checkKey = sysLoginModel.getCheckKey(); - if(captcha==null){ - return Result.error("验证码无效"); - } - String lowerCaseCaptcha = captcha.toLowerCase(); - String realKey = MD5Util.MD5Encode(lowerCaseCaptcha+checkKey, "utf-8"); - Object checkCode = redisUtil.get(realKey); - if(checkCode==null || !checkCode.equals(lowerCaseCaptcha)) { - return Result.error("验证码错误"); - } - return Result.OK(); + return loginService.checkCaptcha(sysLoginModel); } + /** * 返回一个RSA公钥 * @author 马志朝 @@ -545,13 +167,6 @@ public class LoginController { @ApiOperation("获取RSA公钥") @GetMapping("/getRSAPublicKey") public Result getRSAPublicKey(){ - RSA rsa = new RSA(); - String privateKeyBase64 = rsa.getPrivateKeyBase64(); - String publicKeyBase64 = rsa.getPublicKeyBase64(); - //存到redis key为公钥 value为私钥 - redisUtil.set(publicKeyBase64, privateKeyBase64, 60L); - Result result = new Result<>(); - result.setResult(publicKeyBase64); - return result; + return loginService.getRSAPublicKey(); } } \ No newline at end of file diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/ILoginService.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/ILoginService.java new file mode 100644 index 00000000..0eaf5eb2 --- /dev/null +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/ILoginService.java @@ -0,0 +1,112 @@ +package com.jero.modules.system.service; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import com.jero.common.api.vo.Result; +import com.jero.common.exception.JeroBootException; +import com.jero.modules.system.entity.SysCategory; +import com.jero.modules.system.entity.SysUser; +import com.jero.modules.system.model.SysLoginModel; +import com.jero.modules.system.model.TreeSelectModel; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * @Description: 登录 + * @Author: jero-boot + * @Date: 2022-01-24 + * @Version: V1.0 + */ +public interface ILoginService{ + + /** + * 登录 + * @param sysLoginModel + * @return Result + */ + public Result login(SysLoginModel sysLoginModel); + + /** + * 退出登录 + * @param request response + * @return Result + */ + public Result logout(HttpServletRequest request, HttpServletResponse response); + + /** + * 获取访问量 + * @return Result + */ + public Result loginfo(); + + /** + * 获取访问量 + * @return Result + */ + public Result>> visitInfo(); + + /** + * 登陆成功选择用户当前部门 + * @param user + * @return + */ + public Result selectDepart(SysUser user); + + /** + * 短信登录接口 + * + * @param jsonObject + * @return + */ + public Result sms(JSONObject jsonObject); + + /** + * 手机号登录接口 + * + * @param jsonObject + * @return + */ + public Result phoneLogin(JSONObject jsonObject); + + /** + * 获取加密字符串 + * @return + */ + public Result> getEncryptedString(); + + /** + * 后台生成图形验证码 :有效 + * @param response + * @param key + */ + public Result randomImage(HttpServletResponse response,String key); + + /** + * app登录 + * @param sysLoginModel + * @return + * @throws Exception + */ + public Result mLogin(SysLoginModel sysLoginModel); + + /** + * 图形验证码 + * @param sysLoginModel + * @return + */ + public Result checkCaptcha(@RequestBody SysLoginModel sysLoginModel); + + /** + * 返回一个RSA公钥 + * @author 马志朝 + * @date 2021/4/15 15:01 + * @param + * @return com.jero.common.api.vo.Result + */ + public Result getRSAPublicKey(); +} diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/impl/LoginServiceImpl.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/impl/LoginServiceImpl.java new file mode 100644 index 00000000..b521534a --- /dev/null +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/service/impl/LoginServiceImpl.java @@ -0,0 +1,489 @@ +package com.jero.modules.system.service.impl; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.asymmetric.RSA; +import com.alibaba.fastjson.JSONObject; +import com.aliyuncs.exceptions.ClientException; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.jero.common.api.vo.Result; +import com.jero.common.constant.CacheConstant; +import com.jero.common.constant.CommonConstant; +import com.jero.common.exception.JeroBootException; +import com.jero.common.system.api.ISysBaseAPI; +import com.jero.common.system.util.JwtUtil; +import com.jero.common.system.vo.LoginUser; +import com.jero.common.util.*; +import com.jero.common.util.encryption.EncryptedString; +import com.jero.modules.base.service.BaseCommonService; +import com.jero.modules.system.entity.SysDepart; +import com.jero.modules.system.entity.SysUser; +import com.jero.modules.system.model.SysLoginModel; +import com.jero.modules.system.model.TreeSelectModel; +import com.jero.modules.system.service.*; +import com.jero.modules.system.util.RandImageUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.jeecgframework.poi.excel.imports.base.ImportFileServiceI; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +/** + * 登录 实现类 + */ +@Slf4j +@Service +public class LoginServiceImpl implements ILoginService { + + @Autowired + private ISysUserService sysUserService; + @Autowired + private ISysBaseAPI sysBaseAPI; + @Autowired + private ISysLogService logService; + @Autowired + private RedisUtil redisUtil; + @Autowired + private ISysDepartService sysDepartService; + @Autowired + private ISysDictService sysDictService; + @Resource + private BaseCommonService baseCommonService; + + private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890"; + //密码登录错误的次数前缀 + public static final String RETRY_LOGIN_PREFIX = "login:retryLoginCount_"; + //密码登录错误的最大限制次数 + public static final int RETRY_LOGIN_MAX_COUNT = 5; + + @Override + public Result login(SysLoginModel sysLoginModel) { + Result result = new Result(); + String username = sysLoginModel.getUsername(); + String password = sysLoginModel.getPassword(); + String rsaPublicKey = sysLoginModel.getRsaPublicKey(); + String rsaPrivateKey = String.valueOf(redisUtil.get(rsaPublicKey)); + //update-begin--Author:scott Date:20190805 for:暂时注释掉密码加密逻辑,有点问题 + //前端密码加密,后端进行密码解密 + //password = AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B", "\\+")).trim();//密码解密 + //update-begin--Author:scott Date:20190805 for:暂时注释掉密码加密逻辑,有点问题 + //update-begin-author:taoyan date:20190828 for:校验验证码 + String captcha = sysLoginModel.getCaptcha(); + if(captcha==null){ + result.error500("验证码无效"); + return result; + } + String lowerCaseCaptcha = captcha.toLowerCase(); + String realKey = MD5Util.MD5Encode(lowerCaseCaptcha+sysLoginModel.getCheckKey(), "utf-8"); + Object checkCode = redisUtil.get(realKey); + //当进入登录页时,有一定几率出现验证码错误 #1714 + if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { + result.error500("验证码错误"); + return result; + } + try { + //解密获取密码和用户名 + password = CommonUtils.decryptBtRsaPriKey(password, rsaPrivateKey); + username = CommonUtils.decryptBtRsaPriKey(username, rsaPrivateKey); + } catch (Exception e) { + e.printStackTrace(); + } + //1. 校验用户是否有效 + //update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getUsername,username); + SysUser sysUser = sysUserService.getOne(queryWrapper); + //update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false + result = sysUserService.checkUserIsEffective(sysUser); + if(!result.isSuccess()) { + return result; + } + + // 若用户名有效,则查询该账号的登陆失败次数是否符合等保要求 + int retryCount = 0 ; + if ( redisUtil.get(RETRY_LOGIN_PREFIX + username) != null){ + retryCount = (int) redisUtil.get(RETRY_LOGIN_PREFIX + username); + } + if (retryCount >= RETRY_LOGIN_MAX_COUNT){ + result.error500("密码错误次数过多,请稍后重试"); + return result; + } + //2. 校验用户名或密码是否正确 + String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); + String syspassword = sysUser.getPassword(); + if (!syspassword.equals(userpassword)) { + // 重试登录次数加一 + retryCount++; + if( retryCount == 1){ + redisUtil.set(RETRY_LOGIN_PREFIX + username,retryCount,60 * 30); + }else { + redisUtil.set(RETRY_LOGIN_PREFIX + username,retryCount,redisUtil.getExpire(RETRY_LOGIN_PREFIX + username)); + } + String msg = retryCount == RETRY_LOGIN_MAX_COUNT ? "密码错误次数过多,请稍后重试":"用户名或密码错误,剩余可登录次数:"+(RETRY_LOGIN_MAX_COUNT - retryCount); + result.error500(msg); + return result; + } + //登录成功,清除错误登录次数 + redisUtil.del(RETRY_LOGIN_PREFIX + username); + + //用户登录信息 + userInfo(sysUser, result); + //update-begin--Author:wangshuai Date:20200714 for:登录日志没有记录人员 + LoginUser loginUser = new LoginUser(); + BeanUtils.copyProperties(sysUser, loginUser); + baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); + //update-end--Author:wangshuai Date:20200714 for:登录日志没有记录人员 + return result; + + } + + @Override + public Result logout(HttpServletRequest request, HttpServletResponse response) { + //用户退出逻辑 + String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); + if(oConvertUtils.isEmpty(token)) { + return Result.error("退出登录失败!"); + } + String username = JwtUtil.getUsername(token); + LoginUser sysUser = sysBaseAPI.getUserByName(username); + if(sysUser!=null) { + //update-begin--Author:wangshuai Date:20200714 for:登出日志没有记录人员 + baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser); + //update-end--Author:wangshuai Date:20200714 for:登出日志没有记录人员 + log.info(" 用户名: "+sysUser.getRealname()+",退出成功! "); + //清空用户登录Token缓存 + redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); + //清空用户登录Shiro权限缓存 + redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); + //清空用户的缓存信息(包括部门信息),例如sys:cache:user:: + redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); + //调用shiro的logout + SecurityUtils.getSubject().logout(); + return Result.OK("退出登录成功!"); + }else { + return Result.error("Token无效!"); + } + } + + @Override + public Result loginfo() { + Result result = new Result(); + JSONObject obj = new JSONObject(); + //update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + // 获取一天的开始和结束时间 + Calendar calendar = new GregorianCalendar(); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + Date dayStart = calendar.getTime(); + calendar.add(Calendar.DATE, 1); + Date dayEnd = calendar.getTime(); + // 获取系统访问记录 + Long totalVisitCount = logService.findTotalVisitCount(); + obj.put("totalVisitCount", totalVisitCount); + Long todayVisitCount = logService.findTodayVisitCount(dayStart,dayEnd); + obj.put("todayVisitCount", todayVisitCount); + Long todayIp = logService.findTodayIp(dayStart,dayEnd); + //update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + obj.put("todayIp", todayIp); + result.setResult(obj); + result.success("登录成功"); + return result; + } + + @Override + public Result>> visitInfo() { + Result>> result = new Result>>(); + Calendar calendar = new GregorianCalendar(); + calendar.set(Calendar.HOUR_OF_DAY,0); + calendar.set(Calendar.MINUTE,0); + calendar.set(Calendar.SECOND,0); + calendar.set(Calendar.MILLISECOND,0); + calendar.add(Calendar.DAY_OF_MONTH, 1); + Date dayEnd = calendar.getTime(); + calendar.add(Calendar.DAY_OF_MONTH, -7); + Date dayStart = calendar.getTime(); + List> list = logService.findVisitCount(dayStart, dayEnd); + result.setResult(oConvertUtils.toLowerCasePageList(list)); + return result; + } + + @Override + public Result selectDepart(SysUser user) { + Result result = new Result(); + String username = user.getUsername(); + if(oConvertUtils.isEmpty(username)) { + LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + username = sysUser.getUsername(); + } + String orgCode= user.getOrgCode(); + this.sysUserService.updateUserDepart(username, orgCode); + SysUser sysUser = sysUserService.getUserByName(username); + JSONObject obj = new JSONObject(); + obj.put("userInfo", sysUser); + result.setResult(obj); + return result; + } + + @Override + public Result sms(JSONObject jsonObject) { + Result result = new Result(); + String mobile = jsonObject.get("mobile").toString(); + //手机号模式 登录模式: "2" 注册模式: "1" + String smsmode=jsonObject.get("smsmode").toString(); + log.info(mobile); + if(oConvertUtils.isEmpty(mobile)){ + result.setMessage("手机号不允许为空!"); + result.setSuccess(false); + return result; + } + Object object = redisUtil.get(mobile); + if (object != null) { + result.setMessage("验证码10分钟内,仍然有效!"); + result.setSuccess(false); + return result; + } + + //随机数 + String captcha = RandomUtil.randomNumbers(6); + JSONObject obj = new JSONObject(); + obj.put("code", captcha); + try { + boolean b = false; + //注册模板 + if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) { + SysUser sysUser = sysUserService.getUserByPhone(mobile); + if(sysUser!=null) { + result.error500(" 手机号已经注册,请直接登录!"); + baseCommonService.addLog("手机号已经注册,请直接登录!", CommonConstant.LOG_TYPE_1, null); + return result; + } + b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE); + }else { + //登录模式,校验用户有效性 + SysUser sysUser = sysUserService.getUserByPhone(mobile); + result = sysUserService.checkUserIsEffective(sysUser); + if(!result.isSuccess()) { + String message = result.getMessage(); + if("该用户不存在,请注册".equals(message)){ + result.error500("该用户不存在或未绑定手机号"); + } + return result; + } + + /** + * smsmode 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板 + */ + if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) { + //登录模板 + b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE); + } else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) { + //忘记密码模板 + b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE); + } + } + + if (b == false) { + result.setMessage("短信验证码发送失败,请稍后重试"); + result.setSuccess(false); + return result; + } + //验证码10分钟内有效 + redisUtil.set(mobile, captcha, 600); + //update-begin--Author:scott Date:20190812 for:issues#391 + //result.setResult(captcha); + //update-end--Author:scott Date:20190812 for:issues#391 + result.setSuccess(true); + + } catch (ClientException e) { + e.printStackTrace(); + result.error500(" 短信接口未配置,请联系管理员!"); + return result; + } + return result; + } + + @Override + public Result phoneLogin(JSONObject jsonObject) { + Result result = new Result(); + String phone = jsonObject.getString("mobile"); + + //校验用户有效性 + SysUser sysUser = sysUserService.getUserByPhone(phone); + result = sysUserService.checkUserIsEffective(sysUser); + if(!result.isSuccess()) { + return result; + } + + String smscode = jsonObject.getString("captcha"); + Object code = redisUtil.get(phone); + if (!smscode.equals(code)) { + result.setMessage("手机验证码错误"); + return result; + } + //用户信息 + userInfo(sysUser, result); + //添加日志 + baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null); + + return result; + } + + @Override + public Result> getEncryptedString() { + Result> result = new Result>(); + Map map = new HashMap(); + map.put("key", EncryptedString.key); + map.put("iv",EncryptedString.iv); + result.setResult(map); + return result; + } + + @Override + public Result randomImage(HttpServletResponse response, String key) { + Result res = new Result(); + try { + String code = RandomUtil.randomString(BASE_CHECK_CODES,4); + String lowerCaseCode = code.toLowerCase(); + String realKey = MD5Util.MD5Encode(lowerCaseCode+key, "utf-8"); + redisUtil.set(realKey, lowerCaseCode, 60); + String base64 = RandImageUtil.generate(code); + res.setSuccess(true); + res.setResult(base64); + } catch (Exception e) { + res.error500("获取验证码出错"+e.getMessage()); + e.printStackTrace(); + } + return res; + } + + @Override + public Result mLogin(SysLoginModel sysLoginModel) { + Result result = new Result(); + String username = sysLoginModel.getUsername(); + String password = sysLoginModel.getPassword(); + + //1. 校验用户是否有效 + SysUser sysUser = sysUserService.getUserByName(username); + result = sysUserService.checkUserIsEffective(sysUser); + if(!result.isSuccess()) { + return result; + } + + //2. 校验用户名或密码是否正确 + String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); + String syspassword = sysUser.getPassword(); + if (!syspassword.equals(userpassword)) { + result.error500("用户名或密码错误"); + return result; + } + + String orgCode = sysUser.getOrgCode(); + if(oConvertUtils.isEmpty(orgCode)) { + //如果当前用户无选择部门 查看部门关联信息 + List departs = sysDepartService.queryUserDeparts(sysUser.getId()); + if (departs == null || departs.size() == 0) { + result.error500("用户暂未归属部门,不可登录!"); + return result; + } + orgCode = departs.get(0).getOrgCode(); + sysUser.setOrgCode(orgCode); + this.sysUserService.updateUserDepart(username, orgCode); + } + JSONObject obj = new JSONObject(); + //用户登录信息 + obj.put("userInfo", sysUser); + + // 生成token + String token = JwtUtil.sign(username, syspassword); + // 设置超时时间 + redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000); + + //token 信息 + obj.put("token", token); + result.setResult(obj); + result.setSuccess(true); + result.setCode(200); + baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]!", CommonConstant.LOG_TYPE_1, null); + return result; + } + + @Override + public Result checkCaptcha(SysLoginModel sysLoginModel) { + String captcha = sysLoginModel.getCaptcha(); + String checkKey = sysLoginModel.getCheckKey(); + if(captcha==null){ + return Result.error("验证码无效"); + } + String lowerCaseCaptcha = captcha.toLowerCase(); + String realKey = MD5Util.MD5Encode(lowerCaseCaptcha+checkKey, "utf-8"); + Object checkCode = redisUtil.get(realKey); + if(checkCode==null || !checkCode.equals(lowerCaseCaptcha)) { + return Result.error("验证码错误"); + } + return Result.OK(); + } + + @Override + public Result getRSAPublicKey() { + RSA rsa = new RSA(); + String privateKeyBase64 = rsa.getPrivateKeyBase64(); + String publicKeyBase64 = rsa.getPublicKeyBase64(); + //存到redis key为公钥 value为私钥 + redisUtil.set(publicKeyBase64, privateKeyBase64, 60L); + Result result = new Result<>(); + result.setResult(publicKeyBase64); + return result; + } + + /** + * 用户信息 + * + * @param sysUser + * @param result + * @return + */ + private Result userInfo(SysUser sysUser, Result result) { + String syspassword = sysUser.getPassword(); + String username = sysUser.getUsername(); + // 生成token + String token = JwtUtil.sign(username, syspassword); + // 设置token缓存有效时间 + redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000); + + // 获取用户部门信息 + JSONObject obj = new JSONObject(); + List departs = sysDepartService.queryUserDeparts(sysUser.getId()); + obj.put("departs", departs); + if (departs == null || departs.size() == 0) { + obj.put("multi_depart", 0); + } else if (departs.size() == 1) { + sysUserService.updateUserDepart(username, departs.get(0).getOrgCode()); + obj.put("multi_depart", 1); + } else { + //查询当前是否有登录部门 + // update-begin--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去 + SysUser sysUserById = sysUserService.getById(sysUser.getId()); + if(oConvertUtils.isEmpty(sysUserById.getOrgCode())){ + sysUserService.updateUserDepart(username, departs.get(0).getOrgCode()); + } + // update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去 + obj.put("multi_depart", 2); + } + obj.put("token", token); + obj.put("userInfo", sysUser); + obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); + result.setResult(obj); + result.success("登录成功"); + return result; + } +} diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java new file mode 100644 index 00000000..87f267c6 --- /dev/null +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java @@ -0,0 +1,57 @@ +package com.jero.modules.system.util; + +import cn.hutool.core.date.DateUtil; + +import java.time.*; +import java.util.Date; + +public class DateUtils extends DateUtil { + + /** + * LocalDate转Date + * @param localDate + * @return Date + */ + public static Date localDate2Date(LocalDate localDate) { + if (null == localDate) { + return null; + } + ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); + return Date.from(zonedDateTime.toInstant()); + } + + /** + * Date转LocalDate + * @param date + */ + public static LocalDate date2LocalDate(Date date) { + if(null == date) { + return null; + } + return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + } + + /** + * LocalDateTime转Date + * @param localDateTime + * @return Date + */ + public static Date localDateTime2Date(LocalDateTime localDateTime){ + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); + Instant instant = zonedDateTime.toInstant(); + return Date.from(instant); + } + + /** + * Date转LocalDateTime + * @param date + * @return LocalDateTime + */ + public static LocalDateTime date2LocalDateTime(Date date){ + Instant instant = date.toInstant(); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = instant.atZone(zoneId); + return zonedDateTime.toLocalDateTime(); + } +} \ No newline at end of file From b40371a84f409897a7a42e88029e983468b72aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=85?= <1669139609@qq.com> Date: Mon, 24 Jan 2022 16:35:11 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E7=94=A8=E6=88=B7=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20=E5=8A=A0=E5=AF=86=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jero/common/util/PasswordUtil.java | 14 ++++ .../system/controller/SysUserController.java | 78 +++++++++++++++---- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java index eb1886b1..6ca4b702 100644 --- a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java +++ b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java @@ -96,6 +96,20 @@ public class PasswordUtil { return bytesToHexString(encipheredData); } + /** + * 自定义加密明文字符串 + * + * @param plaintext + * 待加密的明文字符串 + * @return 加密后的密文字符串 + * @throws Exception + */ + public static String encrypt(String plaintext) { + + return encrypt(plaintext, ALGORITHM, Salt); + } + + /** * 解密密文字符串 * diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java index 8a6c035c..600a6a8c 100644 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java @@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jero.common.exception.JeroBootException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.apache.shiro.SecurityUtils; @@ -137,20 +138,42 @@ public class SysUserController { @RequestMapping(value = "/add", method = RequestMethod.POST) public Result add(@RequestBody JSONObject jsonObject) { Result result = new Result(); - String selectedRoles = jsonObject.getString("selectedroles"); - String selectedDeparts = jsonObject.getString("selecteddeparts"); - try { - SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class); - user.setCreateTime(new Date());//设置创建时间 - String salt = oConvertUtils.randomGen(8); - user.setSalt(salt); - String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), salt); - user.setPassword(passwordEncode); - user.setStatus(1); - user.setDelFlag(CommonConstant.DEL_FLAG_0); - sysUserService.addUserWithRole(user, selectedRoles); + try { + String selectedRoles = jsonObject.getString("selectedroles"); + String selectedDeparts = jsonObject.getString("selecteddeparts"); + String rsaPublicKey = jsonObject.getString("rsaPublicKey"); + String rsaPrivateKey = String.valueOf(redisUtil.get(rsaPublicKey)); + SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class); + String email; + String phone; + try { + //1:先用私钥解密数据 + email = CommonUtils.decryptBtRsaPriKey(user.getEmail(), rsaPrivateKey); + phone = CommonUtils.decryptBtRsaPriKey(user.getPhone(), rsaPrivateKey); + } catch (Exception e) { + throw new JeroBootException("解密失败!", e); + } + //3:把数据加密在放回来 + email = PasswordUtil.encrypt(email); + phone = PasswordUtil.encrypt(phone); + user.setEmail(email); + user.setPhone(phone); + String password; + try { + password = CommonUtils.decryptBtRsaPriKey(user.getPassword(), rsaPrivateKey); + } catch (Exception e) { + throw new JeroBootException("解密失败!", e); + } + user.setCreateTime(new Date());//设置创建时间 + String salt = oConvertUtils.randomGen(8); + user.setSalt(salt); + String passwordEncode = PasswordUtil.encrypt(user.getUsername(), password, salt); + user.setPassword(passwordEncode); + user.setStatus(1); + user.setDelFlag(CommonConstant.DEL_FLAG_0); + sysUserService.addUserWithRole(user, selectedRoles); sysUserService.addUserWithDepart(user, selectedDeparts); - result.success("添加成功!"); + result.success("添加成功!"); } catch (Exception e) { log.error(e.getMessage(), e); result.error500("操作失败"); @@ -162,6 +185,10 @@ public class SysUserController { @RequiresPermissions("user:edit") @RequestMapping(value = "/edit", method = RequestMethod.PUT) public Result edit(@RequestBody JSONObject jsonObject) { + String rsaPublicKey = jsonObject.getString("rsaPublicKey"); + String roles = jsonObject.getString("selectedroles"); + String departs = jsonObject.getString("selecteddeparts"); + String rsaPrivateKey = String.valueOf(redisUtil.get(rsaPublicKey)); Result result = new Result(); try { SysUser sysUser = sysUserService.getById(jsonObject.getString("id")); @@ -170,11 +197,23 @@ public class SysUserController { result.error500("未找到对应实体"); }else { SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class); + String email; + String phone; + try { + //1:先用私钥解密数据 + email = CommonUtils.decryptBtRsaPriKey(user.getEmail(), rsaPrivateKey); + phone = CommonUtils.decryptBtRsaPriKey(user.getPhone(), rsaPrivateKey); + } catch (Exception e) { + throw new JeroBootException("解密失败!", e); + } + //3:把数据加密在放回来 + email = PasswordUtil.encrypt(email); + phone = PasswordUtil.encrypt(phone); + user.setEmail(email); + user.setPhone(phone); user.setUpdateTime(new Date()); //String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), sysUser.getSalt()); user.setPassword(sysUser.getPassword()); - String roles = jsonObject.getString("selectedroles"); - String departs = jsonObject.getString("selecteddeparts"); sysUserService.editUserWithRole(user, roles); sysUserService.editUserWithDepart(user, departs); sysUserService.updateNullPhoneEmail(); @@ -542,6 +581,15 @@ public class SysUserController { String oldpassword = json.getString("oldpassword"); String password = json.getString("password"); String confirmpassword = json.getString("confirmpassword"); + String RSAPublicKey = json.getString("rsaPublicKey"); + String RSAPrivateKey = String.valueOf(redisUtil.get(RSAPublicKey)); + try { + oldpassword = CommonUtils.decryptBtRsaPriKey(oldpassword, RSAPrivateKey); + password = CommonUtils.decryptBtRsaPriKey(password, RSAPrivateKey); + confirmpassword = CommonUtils.decryptBtRsaPriKey(confirmpassword, RSAPrivateKey); + }catch (Exception e){ + log.error(e.getMessage(),e); + } SysUser user = this.sysUserService.getOne(new LambdaQueryWrapper().eq(SysUser::getUsername, username)); if(user==null) { return Result.error("用户不存在!"); From 3f0ad6f923b070a84bad245ac063a0e7ef07c6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=85?= <1669139609@qq.com> Date: Mon, 24 Jan 2022 17:09:55 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/jero/common/util/ValidUtil.java | 142 ++++++++++++++++++ .../controller/${entityName}Controller.javai | 14 +- 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java diff --git a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java new file mode 100644 index 00000000..b8fae457 --- /dev/null +++ b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java @@ -0,0 +1,142 @@ +package com.jero.common.util; + +import com.jero.common.exception.JeroBootException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * 手动校验@Vaild方法 + * @author liJiaRao + * @date 2021-08-05 15:09 + */ +@Slf4j +public class ValidUtil { + + private static Validator validator; + + static { + validator = Validation.buildDefaultValidatorFactory() + .getValidator(); + } + + private static Validator validatorAll; + + static { + validatorAll = Validation.buildDefaultValidatorFactory() + .getValidator(); + } + + /** + * 手动校验@Vaild并抛出异常信息 + * + * @param object 待校验对象 + * @param groups 待校验的组 + */ + public static void validate(Object object, Class... groups){ + StringBuilder msg = new StringBuilder(); + Set> set = validator.validate(object, groups); + for (ConstraintViolation constraintViolation : set) { + msg.append(constraintViolation.getMessage()).append(","); + } + if (StringUtils.isNotBlank(msg)) { + throw new JeroBootException(msg.substring(0,msg.length()-1)); + } + } + + /** + * 手动校验@Vaild并抛出异常信息list + * + * @param object 待校验对象 + * @param groups 待校验的组 + * @return errorList + */ + public static List validateReturnList(Object object, Class... groups){ + List list = new ArrayList<>(); + Set> set = validator.validate(object, groups); + for (ConstraintViolation constraintViolation : set) { + list.add(constraintViolation.getMessage()); + } + return list; + } + + /** + * 手动校验@Vaild并抛出异常信息list + * + * @param object 待校验对象 + * @param groups 待校验的组 + * @return errorList + */ + public static List validateReturnListWithNum(Object object, int errorRowNum, Class... groups){ + List list = new ArrayList<>(); + Set> set = validator.validate(object, groups); + for (ConstraintViolation constraintViolation : set) { + list.add("第" + errorRowNum + "行:"+constraintViolation.getMessage()); + } + return list; + } + + /** + * @Description 校验全部数据格式 + * @Author lqt + * @Date 2021/8/26 + * @Param + * @Return + * @Exception + */ + public static StringBuilder validateAll(Object object){ + StringBuilder msg = new StringBuilder(); + Set> set = validatorAll.validate(object); + if(set != null && set.size() >0 ){ + for(ConstraintViolation constraintViolation : set){ + // 这里循环获取错误信息,可以自定义格式 + msg.append(constraintViolation.getMessage()).append("
"); + } + } + return msg; + } + /** + * @Description 校验excel 每行数据格式 + * @Author lqt + * @Date 2021/8/26 + * @Param count excel 行数 + * @Return + * @Exception + */ + public static StringBuilder validateExcel(Object object, int count){ + StringBuilder msg = new StringBuilder(); + Set> set = validatorAll.validate(object); + if(set != null && set.size() > 0 ){ + for(ConstraintViolation constraintViolation : set){ + // 这里循环获取错误信息,可以自定义格式 + msg.append("第").append(count).append("行:").append(constraintViolation.getMessage()).append(",请修改。
"); + } + } + return msg; + } + /** + * @Description 校验excel 每行数据格式(只用于支出合同导入校验) + * @Author lqt + * @Date 2021/8/26 + * @Param count excel 行数 + * @Return + * @Exception + */ + public static StringBuilder validateSpendingContractExcel(Object object, int count,int num){ + StringBuilder msg = new StringBuilder(); + Set> set = validatorAll.validate(object); + if(set != null && set.size() > 0 ){ + for(ConstraintViolation constraintViolation : set){ + // 这里循环获取错误信息,可以自定义格式 + msg.append("第").append(count).append("行:").append(num).append(constraintViolation.getMessage()).append(",请修改。
"); + } + } + return msg; + } +} diff --git a/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index 782e23f7..a6631f30 100644 --- a/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -253,9 +253,21 @@ public class ${entityName}Controller { try { List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params); for (${entityName}Page page : list) { + int lineNumber = i + 1; ${entityName} po = new ${entityName}(); BeanUtils.copyProperties(page, po); - ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); + try { + List errorList = ValidUtil.validateReturnList(po); + if (!errorList.isEmpty()){ + errorLines++; + errorMessage.add("第 " + lineNumber + " 行:"+ StringUtils.join(errorList,",")); + } + ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); + } catch (Exception e) { + // 通过索引名判断出错信息 + errorMessage.add("第 " + lineNumber + " 行:未知错误"); + log.error(e.getMessage(), e); + } } return Result.OK("文件导入成功!数据行数:" + list.size()); } catch (Exception e) { From 19466f3723f096ed292bc1ec76f9d3e2f3b197ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=85?= <1669139609@qq.com> Date: Tue, 25 Jan 2022 10:34:58 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SysDepartPermissionController.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysDepartPermissionController.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysDepartPermissionController.java index 093b4776..ad83c3e7 100644 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysDepartPermissionController.java +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysDepartPermissionController.java @@ -192,33 +192,6 @@ public class SysDepartPermissionController extends JeroController saveDatarule(@RequestBody JSONObject jsonObject) { - try { - String permissionId = jsonObject.getString("permissionId"); - String departId = jsonObject.getString("departId"); - String dataRuleIds = jsonObject.getString("dataRuleIds"); - log.info("保存数据规则>>"+"菜单ID:"+permissionId+"部门ID:"+ departId+"数据权限ID:"+dataRuleIds); - LambdaQueryWrapper query = new LambdaQueryWrapper() - .eq(SysDepartPermission::getPermissionId, permissionId) - .eq(SysDepartPermission::getDepartId,departId); - SysDepartPermission sysDepartPermission = sysDepartPermissionService.getOne(query); - if(sysDepartPermission==null) { - return Result.error("请先保存部门菜单权限!"); - }else { - sysDepartPermission.setDataRuleIds(dataRuleIds); - this.sysDepartPermissionService.updateById(sysDepartPermission); - } - } catch (Exception e) { - log.error("SysDepartPermissionController.saveDatarule()发生异常:" + e.getMessage(),e); - return Result.error("保存失败"); - } - return Result.OK("保存成功!"); - } - /** * 查询角色授权 * From cf5fa2a6c4893a1c66fe4abe98582a5207c01ea1 Mon Sep 17 00:00:00 2001 From: "zyx.net" Date: Tue, 25 Jan 2022 15:05:00 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jerobiz/modal/JSelectUserByDepModal.vue | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jero-web/src/components/jerobiz/modal/JSelectUserByDepModal.vue b/jero-web/src/components/jerobiz/modal/JSelectUserByDepModal.vue index e577c1bc..8be13b93 100644 --- a/jero-web/src/components/jerobiz/modal/JSelectUserByDepModal.vue +++ b/jero-web/src/components/jerobiz/modal/JSelectUserByDepModal.vue @@ -29,12 +29,18 @@ 用户账号: - + > + 用户姓名: + + 查询 重置 Date: Tue, 25 Jan 2022 15:06:49 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=A1=86=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=A6=96=E5=B0=BE=E5=8E=BB=E7=A9=BA=E6=A0=BCjs=20,?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95=E9=A1=B5=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E7=82=B9=E5=87=BB=E6=9F=A5=E7=9C=8B(?= =?UTF-8?q?=E9=9A=90=E8=97=8F)=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jero-web/src/main.js | 2 ++ jero-web/src/utils/trim.js | 8 ++++++++ jero-web/src/views/user/Login.vue | 7 +++++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 jero-web/src/utils/trim.js diff --git a/jero-web/src/main.js b/jero-web/src/main.js index dedf0134..fed3580b 100644 --- a/jero-web/src/main.js +++ b/jero-web/src/main.js @@ -49,6 +49,8 @@ import '@/assets/less/JAreaLinkage.less' import VueAreaLinkage from 'vue-area-linkage' import '@/components/jero/JVxeTable/install' import '@/components/JVxeCells/install' +// 输入框去除首尾空格 +import '@/utils/trim' Vue.config.productionTip = false Vue.use(Storage, config.storageOptions) diff --git a/jero-web/src/utils/trim.js b/jero-web/src/utils/trim.js new file mode 100644 index 00000000..d04f7979 --- /dev/null +++ b/jero-web/src/utils/trim.js @@ -0,0 +1,8 @@ +/* + * 2022-1-25 + * 输入框去除首尾空格 + */ + +document.addEventListener('input', (event) => { + event.srcElement.value=event.srcElement.value.replace(/(^\s*)|(\s*$)/g, '') +}) diff --git a/jero-web/src/views/user/Login.vue b/jero-web/src/views/user/Login.vue index 6dfc4f93..d71528bc 100644 --- a/jero-web/src/views/user/Login.vue +++ b/jero-web/src/views/user/Login.vue @@ -25,10 +25,12 @@ + + @@ -214,7 +216,8 @@ currdatetime:'', randCodeImage:'', requestCodeSuccess:false, - rsaPublicKey:'' + rsaPublicKey:'', + passwordType:'password', //passwordType : password , text } }, created () { From 2cb4c1f48139473cafc136e3477629b9a58959e1 Mon Sep 17 00:00:00 2001 From: baozhipeng <961815525@qq.com> Date: Tue, 25 Jan 2022 20:52:08 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=9A=84=E9=BB=98=E8=AE=A4=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/SysPermissionController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java index 52881156..200a704c 100644 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java @@ -210,10 +210,10 @@ public class SysPermissionController { List metaList = sysPermissionService.queryByUser(loginUser.getUsername()); //添加首页路由 //update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 - if(!PermissionDataUtil.hasIndexPage(metaList)){ - SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper().eq(SysPermission::getName,"首页")).get(0); - metaList.add(0,indexMenu); - } +// if(!PermissionDataUtil.hasIndexPage(metaList)){ +// SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper().eq(SysPermission::getName,"首页")).get(0); +// metaList.add(0,indexMenu); +// } //update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 JSONObject json = new JSONObject(); JSONArray menujsonArray = new JSONArray(); From fe83dd07ae80141d8984ec5d930c58f5d695271d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9A=E4=BA=9A=E7=94=B7?= Date: Wed, 26 Jan 2022 09:58:36 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E9=A6=96=E9=A1=B5=E6=97=A0=E6=9D=83?= =?UTF-8?q?=E9=99=90=E8=B7=B3=E8=BD=AC=E5=88=B0=E7=AC=AC=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=9C=89=E6=9D=83=E9=99=90=E7=9A=84=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jero-web/src/permission.js | 25 +++++++++++++++++++++++-- jero-web/src/utils/util.js | 14 +++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/jero-web/src/permission.js b/jero-web/src/permission.js index 10607c75..e1d423f1 100644 --- a/jero-web/src/permission.js +++ b/jero-web/src/permission.js @@ -17,8 +17,29 @@ router.beforeEach((to, from, next) => { if (Vue.ls.get(ACCESS_TOKEN)) { /* has token */ if (to.path === '/user/login') { - next({ path: INDEX_MAIN_PAGE_PATH }) - NProgress.done() + + store.dispatch('GetPermissionList').then(res => { + const menuData = res.result.menu; + if (menuData === null || menuData === "" || menuData === undefined) { + return; + } + let constRoutes = []; + constRoutes = generateIndexRouter(menuData); + // 添加主界面路由 + store.dispatch('UpdateAppRouter', { constRoutes }).then(() => { + // 根据roles权限生成可访问的路由表 + // 动态添加可访问路由表 + router.addRoutes(store.getters.addRouters) + const redirect = decodeURIComponent(from.query.redirect || to.path) + next(findFirstRoute(menuData)) + NProgress.done() + }) + }) + .catch(() => { + store.dispatch('Logout').then(() => { + next() + }) + }) } else { if (store.getters.permissionList.length === 0) { store.dispatch('GetPermissionList').then(res => { diff --git a/jero-web/src/utils/util.js b/jero-web/src/utils/util.js index 9c1321b3..809eff4a 100644 --- a/jero-web/src/utils/util.js +++ b/jero-web/src/utils/util.js @@ -81,13 +81,14 @@ export function formatDate(value, fmt) { // 生成首页路由 export function generateIndexRouter(data) { + const redirectPath = findFirstRoute(data) let indexRouter = [{ path: '/', name: 'dashboard', //component: () => import('@/components/layouts/BasicLayout'), component: resolve => require(['@/components/layouts/TabLayout'], resolve), meta: { title: '首页' }, - redirect: '/dashboard/analysis', + redirect: redirectPath, children: [ ...generateChildRouters(data) ] @@ -560,4 +561,15 @@ export function removeArrayElement(array, prod, value) { if(index>=0){ array.splice(index, 1); } +} +export function findFirstRoute(data){ + if (data[0]) { + if (data[0] && data[0].children && data[0].children.length > 0) { + return findFirstRoute(data[0].children) + } else { + return data[0].path + } + } else { + return '/' + } } \ No newline at end of file From a2e49f49a74a5fade7a8e6a00f247a5f5b5bcf96 Mon Sep 17 00:00:00 2001 From: zer0Black Date: Thu, 27 Jan 2022 16:37:35 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E9=83=A8=E5=88=86=E7=96=91=E9=97=AE?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/jero/common/util/DateUtils.java | 53 +++++++++++++++++ .../com/jero/common/util/PasswordUtil.java | 1 - .../controller/SysPermissionController.java | 8 +-- .../system/controller/SysUserController.java | 44 +++++++------- .../jero/modules/system/util/DateUtils.java | 57 ------------------- 5 files changed, 75 insertions(+), 88 deletions(-) delete mode 100644 jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java diff --git a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/DateUtils.java b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/DateUtils.java index c6712e45..5f8e01cf 100644 --- a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/DateUtils.java +++ b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/DateUtils.java @@ -5,6 +5,11 @@ import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -647,4 +652,52 @@ public class DateUtils extends PropertyEditorSupport { return calendar.get(Calendar.YEAR); } + /** + * LocalDate转Date + * @param localDate + * @return Date + */ + public static Date localDate2Date(LocalDate localDate) { + if (null == localDate) { + return null; + } + ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); + return Date.from(zonedDateTime.toInstant()); + } + + /** + * Date转LocalDate + * @param date + */ + public static LocalDate date2LocalDate(Date date) { + if(null == date) { + return null; + } + return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + } + + /** + * LocalDateTime转Date + * @param localDateTime + * @return Date + */ + public static Date localDateTime2Date(LocalDateTime localDateTime){ + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); + Instant instant = zonedDateTime.toInstant(); + return Date.from(instant); + } + + /** + * Date转LocalDateTime + * @param date + * @return LocalDateTime + */ + public static LocalDateTime date2LocalDateTime(Date date){ + Instant instant = date.toInstant(); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = instant.atZone(zoneId); + return zonedDateTime.toLocalDateTime(); + } + } \ No newline at end of file diff --git a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java index 6ca4b702..bf534771 100644 --- a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java +++ b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/PasswordUtil.java @@ -105,7 +105,6 @@ public class PasswordUtil { * @throws Exception */ public static String encrypt(String plaintext) { - return encrypt(plaintext, ALGORITHM, Salt); } diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java index 200a704c..74553284 100644 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysPermissionController.java @@ -208,13 +208,7 @@ public class SysPermissionController { return Result.error("请登录系统!"); } List metaList = sysPermissionService.queryByUser(loginUser.getUsername()); - //添加首页路由 - //update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 -// if(!PermissionDataUtil.hasIndexPage(metaList)){ -// SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper().eq(SysPermission::getName,"首页")).get(0); -// metaList.add(0,indexMenu); -// } - //update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 + JSONObject json = new JSONObject(); JSONArray menujsonArray = new JSONArray(); this.getPermissionJsonArray(menujsonArray, metaList, null); diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java index 600a6a8c..289bbe69 100644 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java +++ b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/controller/SysUserController.java @@ -144,33 +144,31 @@ public class SysUserController { String rsaPublicKey = jsonObject.getString("rsaPublicKey"); String rsaPrivateKey = String.valueOf(redisUtil.get(rsaPublicKey)); SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class); - String email; - String phone; + try { //1:先用私钥解密数据 - email = CommonUtils.decryptBtRsaPriKey(user.getEmail(), rsaPrivateKey); - phone = CommonUtils.decryptBtRsaPriKey(user.getPhone(), rsaPrivateKey); + String email = CommonUtils.decryptBtRsaPriKey(user.getEmail(), rsaPrivateKey); + String phone = CommonUtils.decryptBtRsaPriKey(user.getPhone(), rsaPrivateKey); + + //3:把数据加密在放回来 + email = PasswordUtil.encrypt(email); + phone = PasswordUtil.encrypt(phone); + user.setEmail(email); + user.setPhone(phone); + + // 密码加盐 + String password = CommonUtils.decryptBtRsaPriKey(user.getPassword(), rsaPrivateKey); + user.setCreateTime(new Date());//设置创建时间 + String salt = oConvertUtils.randomGen(8); + user.setSalt(salt); + String passwordEncode = PasswordUtil.encrypt(user.getUsername(), password, salt); + user.setPassword(passwordEncode); + user.setStatus(1); + user.setDelFlag(CommonConstant.DEL_FLAG_0); } catch (Exception e) { - throw new JeroBootException("解密失败!", e); + throw new JeroBootException("邮箱和手机号解密失败!", e); } - //3:把数据加密在放回来 - email = PasswordUtil.encrypt(email); - phone = PasswordUtil.encrypt(phone); - user.setEmail(email); - user.setPhone(phone); - String password; - try { - password = CommonUtils.decryptBtRsaPriKey(user.getPassword(), rsaPrivateKey); - } catch (Exception e) { - throw new JeroBootException("解密失败!", e); - } - user.setCreateTime(new Date());//设置创建时间 - String salt = oConvertUtils.randomGen(8); - user.setSalt(salt); - String passwordEncode = PasswordUtil.encrypt(user.getUsername(), password, salt); - user.setPassword(passwordEncode); - user.setStatus(1); - user.setDelFlag(CommonConstant.DEL_FLAG_0); + sysUserService.addUserWithRole(user, selectedRoles); sysUserService.addUserWithDepart(user, selectedDeparts); result.success("添加成功!"); diff --git a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java b/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java deleted file mode 100644 index 87f267c6..00000000 --- a/jero-boot/jero-boot-module-system/src/main/java/com/jero/modules/system/util/DateUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.jero.modules.system.util; - -import cn.hutool.core.date.DateUtil; - -import java.time.*; -import java.util.Date; - -public class DateUtils extends DateUtil { - - /** - * LocalDate转Date - * @param localDate - * @return Date - */ - public static Date localDate2Date(LocalDate localDate) { - if (null == localDate) { - return null; - } - ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); - return Date.from(zonedDateTime.toInstant()); - } - - /** - * Date转LocalDate - * @param date - */ - public static LocalDate date2LocalDate(Date date) { - if(null == date) { - return null; - } - return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); - } - - /** - * LocalDateTime转Date - * @param localDateTime - * @return Date - */ - public static Date localDateTime2Date(LocalDateTime localDateTime){ - ZoneId zoneId = ZoneId.systemDefault(); - ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); - Instant instant = zonedDateTime.toInstant(); - return Date.from(instant); - } - - /** - * Date转LocalDateTime - * @param date - * @return LocalDateTime - */ - public static LocalDateTime date2LocalDateTime(Date date){ - Instant instant = date.toInstant(); - ZoneId zoneId = ZoneId.systemDefault(); - ZonedDateTime zonedDateTime = instant.atZone(zoneId); - return zonedDateTime.toLocalDateTime(); - } -} \ No newline at end of file From 995465984c9382ab1d0213b7a50cce120660eb03 Mon Sep 17 00:00:00 2001 From: zer0Black Date: Thu, 27 Jan 2022 16:39:34 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/jero/common/util/ValidUtil.java | 142 ------------------ .../controller/${entityName}Controller.javai | 14 +- 2 files changed, 1 insertion(+), 155 deletions(-) delete mode 100644 jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java diff --git a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java b/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java deleted file mode 100644 index b8fae457..00000000 --- a/jero-boot/jero-boot-base/jero-boot-base-core/src/main/java/com/jero/common/util/ValidUtil.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.jero.common.util; - -import com.jero.common.exception.JeroBootException; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * 手动校验@Vaild方法 - * @author liJiaRao - * @date 2021-08-05 15:09 - */ -@Slf4j -public class ValidUtil { - - private static Validator validator; - - static { - validator = Validation.buildDefaultValidatorFactory() - .getValidator(); - } - - private static Validator validatorAll; - - static { - validatorAll = Validation.buildDefaultValidatorFactory() - .getValidator(); - } - - /** - * 手动校验@Vaild并抛出异常信息 - * - * @param object 待校验对象 - * @param groups 待校验的组 - */ - public static void validate(Object object, Class... groups){ - StringBuilder msg = new StringBuilder(); - Set> set = validator.validate(object, groups); - for (ConstraintViolation constraintViolation : set) { - msg.append(constraintViolation.getMessage()).append(","); - } - if (StringUtils.isNotBlank(msg)) { - throw new JeroBootException(msg.substring(0,msg.length()-1)); - } - } - - /** - * 手动校验@Vaild并抛出异常信息list - * - * @param object 待校验对象 - * @param groups 待校验的组 - * @return errorList - */ - public static List validateReturnList(Object object, Class... groups){ - List list = new ArrayList<>(); - Set> set = validator.validate(object, groups); - for (ConstraintViolation constraintViolation : set) { - list.add(constraintViolation.getMessage()); - } - return list; - } - - /** - * 手动校验@Vaild并抛出异常信息list - * - * @param object 待校验对象 - * @param groups 待校验的组 - * @return errorList - */ - public static List validateReturnListWithNum(Object object, int errorRowNum, Class... groups){ - List list = new ArrayList<>(); - Set> set = validator.validate(object, groups); - for (ConstraintViolation constraintViolation : set) { - list.add("第" + errorRowNum + "行:"+constraintViolation.getMessage()); - } - return list; - } - - /** - * @Description 校验全部数据格式 - * @Author lqt - * @Date 2021/8/26 - * @Param - * @Return - * @Exception - */ - public static StringBuilder validateAll(Object object){ - StringBuilder msg = new StringBuilder(); - Set> set = validatorAll.validate(object); - if(set != null && set.size() >0 ){ - for(ConstraintViolation constraintViolation : set){ - // 这里循环获取错误信息,可以自定义格式 - msg.append(constraintViolation.getMessage()).append("
"); - } - } - return msg; - } - /** - * @Description 校验excel 每行数据格式 - * @Author lqt - * @Date 2021/8/26 - * @Param count excel 行数 - * @Return - * @Exception - */ - public static StringBuilder validateExcel(Object object, int count){ - StringBuilder msg = new StringBuilder(); - Set> set = validatorAll.validate(object); - if(set != null && set.size() > 0 ){ - for(ConstraintViolation constraintViolation : set){ - // 这里循环获取错误信息,可以自定义格式 - msg.append("第").append(count).append("行:").append(constraintViolation.getMessage()).append(",请修改。
"); - } - } - return msg; - } - /** - * @Description 校验excel 每行数据格式(只用于支出合同导入校验) - * @Author lqt - * @Date 2021/8/26 - * @Param count excel 行数 - * @Return - * @Exception - */ - public static StringBuilder validateSpendingContractExcel(Object object, int count,int num){ - StringBuilder msg = new StringBuilder(); - Set> set = validatorAll.validate(object); - if(set != null && set.size() > 0 ){ - for(ConstraintViolation constraintViolation : set){ - // 这里循环获取错误信息,可以自定义格式 - msg.append("第").append(count).append("行:").append(num).append(constraintViolation.getMessage()).append(",请修改。
"); - } - } - return msg; - } -} diff --git a/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index a6631f30..782e23f7 100644 --- a/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jero-boot/jero-boot-single-startup/src/main/resources/jero/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -253,21 +253,9 @@ public class ${entityName}Controller { try { List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params); for (${entityName}Page page : list) { - int lineNumber = i + 1; ${entityName} po = new ${entityName}(); BeanUtils.copyProperties(page, po); - try { - List errorList = ValidUtil.validateReturnList(po); - if (!errorList.isEmpty()){ - errorLines++; - errorMessage.add("第 " + lineNumber + " 行:"+ StringUtils.join(errorList,",")); - } - ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); - } catch (Exception e) { - // 通过索引名判断出错信息 - errorMessage.add("第 " + lineNumber + " 行:未知错误"); - log.error(e.getMessage(), e); - } + ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); } return Result.OK("文件导入成功!数据行数:" + list.size()); } catch (Exception e) {