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 eb1886b1..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 @@ -96,6 +96,19 @@ 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/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/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("保存成功!"); - } - /** * 查询角色授权 * 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..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 8a6c035c..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 @@ -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,40 @@ 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); + + try { + //1:先用私钥解密数据 + 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); + } + + sysUserService.addUserWithRole(user, selectedRoles); sysUserService.addUserWithDepart(user, selectedDeparts); - result.success("添加成功!"); + result.success("添加成功!"); } catch (Exception e) { log.error(e.getMessage(), e); result.error500("操作失败"); @@ -162,6 +183,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 +195,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 +579,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("用户不存在!"); 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-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 @@ 用户账号: - + > + 用户姓名: + + 查询 重置 { 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/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/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 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 () {