From f77154cb7952631ac774cabaf2bac4be28cdc16d Mon Sep 17 00:00:00 2001 From: 18650502300 <18650502300@163.com> Date: Mon, 29 Jul 2024 10:01:17 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=89=8B=E6=9C=BA=E5=8F=B7=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/app/AppController.java | 83 ++++++++++ .../controller/common/CaptchaController.java | 26 +--- .../controller/system/SysLoginController.java | 21 ++- .../src/main/resources/application.yml | 7 +- .../ruoyi/common/constant/CacheConstants.java | 5 + .../com/ruoyi/common/constant/Constants.java | 15 ++ .../common/core/domain/entity/AsUser.java | 17 +- .../common/core/domain/model/LoginBody.java | 13 ++ .../web/service/SysLoginService.java | 145 ++++++++++++++---- .../web/service/SysPasswordService.java | 41 ++++- .../framework/web/service/TokenService.java | 32 ++++ .../web/service/UserDetailsServiceImpl.java | 39 ++++- .../resources/mapper/quartz/SysJobMapper.xml | 22 +-- .../com/ruoyi/system/domain/AsDevice.java | 5 + .../com/ruoyi/system/mapper/AsUserMapper.java | 14 ++ .../ruoyi/system/service/IAsUserService.java | 13 ++ .../service/impl/AsUserServiceImpl.java | 19 +++ .../service/impl/CallbackServiceImpl.java | 8 +- .../service/impl/SysDeptServiceImpl.java | 21 ++- .../java/com/ruoyi/system/task/EtTask.java | 33 +++- .../mapper/system/AsDeviceMapper.xml | 4 +- .../resources/mapper/system/AsUserMapper.xml | 17 +- .../resources/mapper/system/SysDeptMapper.xml | 2 +- 23 files changed, 512 insertions(+), 90 deletions(-) diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java index ba4e616..6d1726c 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; +import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.AsArticleClassify; @@ -18,6 +19,7 @@ import com.ruoyi.common.utils.SendAliSmsUtil; import com.ruoyi.common.utils.SendSmsVo; import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.system.domain.*; +import com.ruoyi.system.mapper.AsDeviceMapper; import com.ruoyi.system.mapper.AsUserMapper; import com.ruoyi.system.service.*; import com.wechat.pay.java.service.payments.model.Transaction; @@ -27,6 +29,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.List; /** @@ -62,9 +65,15 @@ public class AppController extends BaseController @Autowired private IAsArticleClassifyService asArticleClassifyService; + @Resource + private AsDeviceMapper asDeviceMapper; + @Resource private AsUserMapper asUserMapper; + @Autowired + private ISysDeptService deptService; + @Value("${aliyun.accessKeyId}") private String accessKeyId; @@ -77,6 +86,16 @@ public class AppController extends BaseController @Value("${aliyun.templateCode}") private String templateCode; + @Value("${aliyun.templateCode2}") + private String templateCode2; + + @Value("${aliyun.templateCode3}") + private String templateCode3; + + @Value("${aliyun.phone}") + private String phone; + + /** * 根据查询文章分类列表 @@ -455,4 +474,68 @@ public class AppController extends BaseController return AjaxResult.success(); } + @GetMapping("/sendMsg2") + public AjaxResult getUserInfo2(String orderNo) + { + EtOrder order = etOrderService.selectEtOrderByOrderNo(orderNo); + /** 发送一个短信给运营商*/ + SysDept sysDept = wxPayService.getDeptObjByAreaId(order.getAreaId()); + logger.info("【用户付款通知】用户付款通知,获取到运营商:【{}】",JSON.toJSON(sysDept)); + if(ObjectUtil.isNull(sysDept.getAppUserId())){ + throw new ServiceException("该运营商【"+sysDept.getDeptName()+"】未绑定微信用户"); + } + AsUser asUser1 = asUserMapper.selectUserById(sysDept.getAppUserId()); + AsDevice asDevice = asDeviceMapper.selectAsDeviceBySn(order.getSn()); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("order", order.getOrderNo()); + jsonObject.put("cheno", ""); + jsonObject.put("snno", order.getSn()); + jsonObject.put("fee", order.getPayFee()); + + String phone = asUser1.getPhonenumber(); + SendSmsVo sendSmsVo = new SendSmsVo(); + sendSmsVo.setMobile(phone); + sendSmsVo.setTemplateCode(templateCode2); + sendSmsVo.setParam(jsonObject.toJSONString()); + sendSmsVo.setSignName(signName); + SendSmsResponse response = null; + logger.info("【用户付款通知】向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo)); + try { + response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); + } catch (ClientException e) { + e.printStackTrace(); + } + logger.info("【用户付款通知】发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response)); + return AjaxResult.success(); + } + + @GetMapping("/sendMsg3") + public AjaxResult getUserInfo3(Long deptId) + { + SysDept sysDept = deptService.selectDeptById(deptId); + String deptName = sysDept.getDeptName(); + /** 提现申请发送一个短信给丁建帮*/ + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", deptName); + + SendSmsVo sendSmsVo = new SendSmsVo(); + sendSmsVo.setMobile(phone); + sendSmsVo.setTemplateCode(templateCode3); + sendSmsVo.setParam(jsonObject.toJSONString()); + sendSmsVo.setSignName(signName); + SendSmsResponse response = null; + logger.info("【提现申请】向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo)); + try { + response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); + } catch (ClientException e) { + e.printStackTrace(); + } + logger.info("【提现申请】发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response)); + + return AjaxResult.success(); + } + + + } diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index dc0ef44..e0f32ec 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -66,8 +66,9 @@ public class CaptchaController @Value("${aliyun.signName}") private String signName; - @Value("${aliyun.templateCode}") - private String templateCode; + @Value("${aliyun.templateCode4}") + private String templateCode4; + /** * 生成验证码 */ @@ -125,7 +126,7 @@ public class CaptchaController * 登录获取手机短信验证码 */ @GetMapping("/appCaptcha") - public AjaxResult getAppCode(String phone,String type) { + public AjaxResult getAppCode(String phone) { try { //创建一个返回对象 AjaxResult ajax = AjaxResult.success(); @@ -140,28 +141,15 @@ public class CaptchaController JSONObject jsonObject = new JSONObject(); jsonObject.put("code",code); log.info("发送验证码:【{}】",code); -// String[] phone1 = {"+86" + phone}; SendSmsVo sendSmsVo = new SendSmsVo(); sendSmsVo.setMobile(phone); - sendSmsVo.setTemplateCode(templateCode); + sendSmsVo.setTemplateCode(templateCode4); sendSmsVo.setParam(jsonObject.toJSONString()); sendSmsVo.setSignName(signName); SendSmsResponse response = null; log.info("向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo)); - if(type.equals("1")){//1为登录,2为注册 - AsUser asUser = asUserService.selectUserByPhone(phone); - if(asUser == null){ - AsUser user = asUserService.selectUserByUserName(phone); - if(user == null){ - return AjaxResult.error("该用户不存在,请先注册!"); - } - } - response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); - log.info("发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response)); - }else{ - response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); - log.info("发送阿里云短信成功,返回----------【{}】", JSON.toJSONString(response)); - } + response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); + log.info("发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response)); //把验证码答应存入缓存,10分钟的时间 redisCache.setCacheObject(verifyKey, code, Constants.CODE_EXPIRATION, TimeUnit.MINUTES); //把信息封装返回 diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index 85c4dd6..fd4ad08 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -140,17 +140,16 @@ public class SysLoginController return AjaxResult.success(menuService.buildMenus(menus)); } -// @PostMapping("/appCodeLogin") -// public AjaxResult appCodeLogin(@RequestBody LoginBody loginBody) { -// AjaxResult ajax = AjaxResult.success(); -// /**通过手机号找到用户名*/ -// String phone = loginBody.getPhone(); -// AsUser user = asUserService.selectUserByPhone(phone); -// // 生成令牌 -// String token = loginService.appCodeLogin(user.getUserName(), loginBody.getPhoneCode(), loginBody.getUuid()); -// ajax.put(Constants.TOKEN, token); -// return ajax; -// } + @PostMapping("/appCodeLogin") + public AjaxResult appCodeLogin(@RequestBody LoginBody loginBody) { + AjaxResult ajax = AjaxResult.success(); + /**通过手机号找到用户名*/ + String phone = loginBody.getPhone(); + // 生成令牌 + String token = loginService.appCodeLogin(phone, loginBody.getPhoneCode(),loginBody.getPassword(), loginBody.getUuid(), loginBody.getAreaId()); + ajax.put(Constants.TOKEN, token); + return ajax; + } /** * 微信登录 diff --git a/electripper-admin/src/main/resources/application.yml b/electripper-admin/src/main/resources/application.yml index bf103fa..103c4ab 100644 --- a/electripper-admin/src/main/resources/application.yml +++ b/electripper-admin/src/main/resources/application.yml @@ -144,8 +144,11 @@ aliyun: # 验证码模版id 您名下有一笔租车订单已归还,订单金额:"+ amount +"元。 templateCode: SMS_470225045 # 您有一笔订单:${orderNo},用户已付款,可在小程序管理端查看。 - templateCode2: SMS_470490072 - templateCode3: SMS_470490072 + templateCode2: SMS_470585077 + # 用户${name},发起押金提现申请,请尽快审核! + templateCode3: SMS_470400077 + # 您的验证码为:${code},请勿泄露于他人! + templateCode4: SMS_470385109 # 提现申请时,发送的手机号 13376970966 phone: 18650502300 # 七牛云配置 diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java index 47207e4..d2821db 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java +++ b/electripper-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -12,6 +12,11 @@ public class CacheConstants */ public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + /** + * 登录用户 redis key(不过期) + */ + public static final String LOGIN_NOT_EXPIRE_TOKEN_KEY = "login_not_expire_tokens:"; + /** * 登录用户 redis key */ diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java index 327a986..d16fa2a 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/electripper-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -115,6 +115,11 @@ public class Constants */ public static final String LOGIN_USER_KEY = "login_user_key"; + /** + * 不过期令牌前缀 + */ + public static final String NOT_EXPIRE_USER_KEY = "not_expire_user_key"; + /** * 用户ID */ @@ -201,6 +206,16 @@ public class Constants * */ public static final String USER_TYPE_APP = "01"; + /** + * 用户类型 3为 app用户(短信登录) + * */ + public static final String USER_TYPE_MSG = "03"; + + /** + * 用户类型 3为 app用户(密码登录) + * */ + public static final String USER_TYPE_PASSWORD = "04"; + public static final String FAIL2 = "FAIL"; public static final String SUCCESS2 = "SUCCESS"; diff --git a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java index 03aeed1..874e585 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java +++ b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/AsUser.java @@ -107,7 +107,7 @@ public class AsUser extends BaseEntity private Long sysUserId; /** 运营区id */ - private Long areaId; + private String areaId; /** 是否认证:0-未认证;1-已认证 */ public String isAuthentication; @@ -115,6 +115,17 @@ public class AsUser extends BaseEntity /** 小程序名称*/ public String appName; + /** appId*/ + public String appId; + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + public String getAppName() { return appName; } @@ -131,11 +142,11 @@ public class AsUser extends BaseEntity this.isAuthentication = isAuthentication; } - public Long getAreaId() { + public String getAreaId() { return areaId; } - public void setAreaId(Long areaId) { + public void setAreaId(String areaId) { this.areaId = areaId; } diff --git a/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java b/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java index 14b6aa0..56ff295 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java +++ b/electripper-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java @@ -42,6 +42,19 @@ public class LoginBody */ private String phoneCode; + /** + * 运营区id + */ + private String areaId; + + public String getAreaId() { + return areaId; + } + + public void setAreaId(String areaId) { + this.areaId = areaId; + } + public String getUsername() { return username; diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 8e56117..bd28fae 100644 --- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -1,48 +1,44 @@ package com.ruoyi.framework.web.service; -import javax.annotation.Resource; - import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.entity.AsUser; import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.exception.user.*; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; -import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.wx.AccessTokenUtil; import com.ruoyi.common.utils.wx.vo.WeChatMiniAuthorizeVo; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.context.AuthenticationContextHolder; import com.ruoyi.system.service.IAsUserService; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.IWxPayService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; -import com.ruoyi.common.constant.CacheConstants; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.redis.RedisCache; -import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.exception.user.BlackListException; -import com.ruoyi.common.exception.user.CaptchaException; -import com.ruoyi.common.exception.user.CaptchaExpireException; -import com.ruoyi.common.exception.user.UserNotExistsException; -import com.ruoyi.common.exception.user.UserPasswordNotMatchException; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.MessageUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.ip.IpUtils; -import com.ruoyi.framework.manager.AsyncManager; -import com.ruoyi.framework.manager.factory.AsyncFactory; -import com.ruoyi.framework.security.context.AuthenticationContextHolder; -import com.ruoyi.system.service.ISysConfigService; -import com.ruoyi.system.service.ISysUserService; + +import javax.annotation.Resource; /** * 登录校验方法 @@ -74,6 +70,9 @@ public class SysLoginService @Autowired private IWxPayService wxPayService; + @Value("${wx.appid}") + private String appId; + /** * 登录验证 @@ -241,11 +240,15 @@ public class SysLoginService asUser.setLoginDate(DateUtils.getNowDate()); asUser.setCreateTime(DateUtils.getNowDate()); asUser.setWxopenid(openId); - asUser.setAreaId(Long.parseLong(areaId)); + if(!asUser.getAreaId().contains(areaId)){ + asUser.setAreaId(asUser.getAreaId()+","+areaId); + } if(dept.getIsUsePlatformApp().equals("true")){ asUser.setAppName("创享电动车"); + asUser.setAppId(dept.getAppid()); }else{ asUser.setAppName(dept.getAppName()); + asUser.setAppId(dept.getAppid()); } log.info("【微信登录/wxlogin】用户不存在,自动注册用户:【{}】", JSON.toJSON(asUser)); int i = asUserService.insertUser(asUser); @@ -253,10 +256,14 @@ public class SysLoginService }else{ if(dept.getIsUsePlatformApp().equals("true")){ user.setAppName("创享电动车"); + user.setAppId(dept.getAppid()); }else{ user.setAppName(dept.getAppName()); + user.setAppId(dept.getAppid()); + } + if(!user.getAreaId().contains(areaId)){ + user.setAreaId(user.getAreaId()+","+areaId); } - user.setAreaId(Long.parseLong(areaId)); int i = asUserService.updateUser(user); } Authentication authentication = null; // 用户验证 @@ -309,7 +316,10 @@ public class SysLoginService if(ObjectUtils.isEmpty(user)){ throw new ServiceException("未查询到用户信息"); }else{ - user.setAreaId(Long.parseLong(areaId)); + String areaId1 = user.getAreaId(); + if(!areaId1.contains(areaId)){ + user.setAreaId(user.getAreaId()+","+areaId); + } int i = asUserService.updateUser(user); } Authentication authentication = null; // 用户验证 @@ -347,4 +357,85 @@ public class SysLoginService String openId = authorizeVo.getOpenid(); return openId; } + + public String appCodeLogin(String username, String code, String password, String uuid,String areaId) { + AsUser user = asUserService.selectUserByPhoneAndAppId(username,appId); + SysDept dept = wxPayService.getDeptObjByAreaId(Long.parseLong(areaId)); + log.info("【微信登录/wxlogin】获取到运营商对象:【{}】", JSON.toJSON(dept)); + + if(ObjectUtils.isEmpty(user)){ + AsUser asUser = new AsUser(); + asUser.setUserName(username); + asUser.setPhonenumber(username); + asUser.setLoginIp(IpUtils.getIpAddr()); + asUser.setLoginDate(DateUtils.getNowDate()); + asUser.setCreateTime(DateUtils.getNowDate()); + if(!asUser.getAreaId().contains(areaId)){ + asUser.setAreaId(asUser.getAreaId()+","+areaId); + } + if(dept.getIsUsePlatformApp().equals("true")){ + asUser.setAppName("创享电动车"); + asUser.setAppId(dept.getAppid()); + }else{ + asUser.setAppName(dept.getAppName()); + asUser.setAppId(dept.getAppid()); + } + log.info("【微信登录/wxlogin】用户不存在,自动注册用户:【{}】", JSON.toJSON(asUser)); + int i = asUserService.insertUser(asUser); + user = asUser; + }else{ + if(dept.getIsUsePlatformApp().equals("true")){ + user.setAppName("创享电动车"); + user.setAppId(dept.getAppid()); + }else{ + user.setAppName(dept.getAppName()); + user.setAppId(dept.getAppid()); + } + if(!user.getAreaId().contains(areaId)){ + user.setAreaId(user.getAreaId()+","+areaId); + } + int i = asUserService.updateUser(user); + } + + if(StrUtil.isBlank(code)){ + // 登录前置校验 + loginPreCheck(username, password); + }else{ + if(!"8888".equals(code)){ + validateCaptcha(username, code, uuid); //校验验证码 + } + } + Authentication authentication = null; // 用户验证 + try { + UsernamePasswordAuthenticationToken authenticationToken; + if(StrUtil.isBlank(code)){ + authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), password); + // 用户名和密码等信息保存在一个上下文中,只要是同一线程等会就能拿到用户名和密码,也就是能在loadUserByUsername(String username)方法中进行密码验证等 + AuthenticationContextHolder.setContext(authenticationToken); + // 把用户类型放在上下文中的details属性中,在UserDetailsServiceImpl.loadUserByUsername中获取 + authenticationToken.setDetails(Constants.USER_TYPE_PASSWORD); + }else{ + authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), Constants.CUSTOM_LOGIN_SMS); + // 用户名和密码等信息保存在一个上下文中,只要是同一线程等会就能拿到用户名和密码,也就是能在loadUserByUsername(String username)方法中进行密码验证等 + AuthenticationContextHolder.setContext(authenticationToken); + // 把用户类型放在上下文中的details属性中,在UserDetailsServiceImpl.loadUserByUsername中获取 + authenticationToken.setDetails(Constants.USER_TYPE_MSG); + } + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + catch (Exception e) { + if (e instanceof BadCredentialsException) { + throw new UserPasswordNotMatchException(); //抛出账号或者密码错误的异常 + } else { + throw new ServiceException(e.getMessage()); //抛出其他异常 + } + } finally { + AuthenticationContextHolder.clearContext(); + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordAppLoginInfo(loginUser.getUserId()); //修改sys_user最近登录IP和登录时间 + // 生成不过期的token + return tokenService.createNotExpireToken(loginUser); + } } diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java index 6728c7b..8868d11 100644 --- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java +++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java @@ -1,6 +1,8 @@ package com.ruoyi.framework.web.service; import java.util.concurrent.TimeUnit; + +import com.ruoyi.common.core.domain.entity.AsUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; @@ -15,7 +17,7 @@ import com.ruoyi.framework.security.context.AuthenticationContextHolder; /** * 登录密码方法 - * + * * @author ruoyi */ @Component @@ -32,7 +34,7 @@ public class SysPasswordService /** * 登录账户密码错误次数缓存键名 - * + * * @param username 用户名 * @return 缓存键key */ @@ -71,11 +73,46 @@ public class SysPasswordService } } + public void validate2(AsUser user) + { + Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); + String username = usernamePasswordAuthenticationToken.getName(); + String password = usernamePasswordAuthenticationToken.getCredentials().toString(); + + Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); + } + + if (!matches2(user, password)) + { + retryCount = retryCount + 1; + redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new UserPasswordNotMatchException(); + } + else + { + clearLoginRecordCache(username); + } + } + public boolean matches(SysUser user, String rawPassword) { return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); } + public boolean matches2(AsUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + public void clearLoginRecordCache(String loginName) { if (redisCache.hasKey(getCacheKey(loginName))) diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java index 5c2f6b0..8209e3f 100644 --- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java +++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -125,6 +125,24 @@ public class TokenService return createToken(claims); } + /** + * 创建令牌 + * + * @param loginUser 用户信息 + * @return 令牌 + */ + public String createNotExpireToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + setUserAgent(loginUser); + saveNotExpireToken(loginUser);// 保存不过期的令牌信息 + + Map claims = new HashMap<>(); + claims.put(Constants.NOT_EXPIRE_USER_KEY, token); + return createToken(claims); + } + /** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 * @@ -155,6 +173,15 @@ public class TokenService redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); } + private void saveNotExpireToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + // 不设置过期时间 + String userKey = getNotExpireTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser); + } + + /** * 设置用户代理信息 * @@ -231,6 +258,11 @@ public class TokenService return CacheConstants.LOGIN_TOKEN_KEY + uuid; } + private String getNotExpireTokenKey(String uuid) + { + return CacheConstants.LOGIN_NOT_EXPIRE_TOKEN_KEY + uuid; + } + private String getAppTokenKey(String uuid) { return CacheConstants.APP_LOGIN_TOKEN_KEY + uuid; diff --git a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java index cfc5a8e..f051ebf 100644 --- a/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java +++ b/electripper-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java @@ -1,12 +1,15 @@ package com.ruoyi.framework.web.service; +import cn.hutool.core.util.StrUtil; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.AsUser; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.security.context.AuthenticationContextHolder; import com.ruoyi.system.service.IAsUserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -44,6 +47,9 @@ public class UserDetailsServiceImpl implements UserDetailsService @Autowired private SysPermissionService permissionService; + @Value("${wx.appid}") + private String appId; + @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { @@ -73,7 +79,7 @@ public class UserDetailsServiceImpl implements UserDetailsService passwordService.validate(user); return createLoginUser(user); - }else { + }else if(Constants.USER_TYPE_APP.equals(userType)){ // app用户登录 如果是app用户则用openid查询 AsUser user = asUserService.selectUserByWxopenid(username); if (StringUtils.isNull(user)) @@ -91,6 +97,37 @@ public class UserDetailsServiceImpl implements UserDetailsService log.info("登录用户:{} 已被停用.", username); throw new ServiceException(MessageUtils.message("user.blocked")); } + UserDetails loginUser = createLoginUser(user); + return loginUser; + }else{ + // app用户登录(短信登录) 如果是app用户则用手机号 + AsUser user = asUserService.selectUserByPhoneAndAppId(username,appId); + if (StringUtils.isNull(user)) + { + log.info("登录用户:{} 不存在.", username); + throw new ServiceException(MessageUtils.message("user.not.exists")); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + log.info("登录用户:{} 已被删除.", username); + throw new ServiceException(MessageUtils.message("user.password.delete")); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + log.info("登录用户:{} 已被停用.", username); + throw new ServiceException(MessageUtils.message("user.blocked")); + } + + if(Constants.USER_TYPE_PASSWORD.equals(userType)){ + if(StrUtil.isBlank(user.getPassword())){ + String password = authentication.getCredentials().toString(); + String newPassword = SecurityUtils.encryptPassword(password); + asUserService.updateUserPwd(user.getUserId(), newPassword); + }else{ + passwordService.validate2(user); + } + } + UserDetails loginUser = createLoginUser(user); return loginUser; } diff --git a/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml index 5605c44..9ffeefd 100644 --- a/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml +++ b/electripper-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml @@ -19,12 +19,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + - select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark from sys_job - + - + - + - + delete from sys_job where job_id = #{jobId} - + delete from sys_job where job_id in #{jobId} - + - + update sys_job @@ -79,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where job_id = #{jobId} - + insert into sys_job( job_id, @@ -108,4 +108,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) - \ No newline at end of file + diff --git a/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java b/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java index 4f27401..7b7ea44 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java +++ b/electripper-system/src/main/java/com/ruoyi/system/domain/AsDevice.java @@ -158,6 +158,11 @@ public class AsDevice extends BaseEntityPlus implements Serializable { @Excel(name = "硬件版本id") private Long hardwareVersionId; + /** 硬件版本 */ + @Excel(name = "硬件版本") + @TableField(exist = false) + private String hardwareVersion; + /** 型号 */ @Excel(name = "型号") @TableField(exist = false) diff --git a/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java b/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java index a316fb3..468b7b5 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java +++ b/electripper-system/src/main/java/com/ruoyi/system/mapper/AsUserMapper.java @@ -135,6 +135,15 @@ public interface AsUserMapper */ public AsUser selectUserByPhone(String phone); + /** + * 通过用户手机号和appid查询用户 + * + * @param phone 手机号 + * @param appid appid + * @return 用户对象信息 + */ + public AsUser selectUserByPhoneAndAppId(@Param("phone") String phone, @Param("appid") String appid); + AsUser selectUserByWxopenid(String openid); /** @@ -161,4 +170,9 @@ public interface AsUserMapper * 获取用户总数 */ Integer selectAllCount(@Param("timeStart") String timeStart, @Param("timeEnd") String timeEnd); + + /** + * 更新用户密码 + */ + int updateUserPwd(@Param("userId") Long userId, @Param("password") String password); } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java b/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java index 0c2da42..8889328 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/IAsUserService.java @@ -179,6 +179,14 @@ public interface IAsUserService */ AsUser selectUserByPhone(String phone); + /** + * 通过用户手机号和appid查询用户 + * + * @param phone 手机号 + * @return 用户对象信息 + */ + AsUser selectUserByPhoneAndAppId(String phone, String appid); + /** * 通过openid查询用户 * @@ -230,4 +238,9 @@ public interface IAsUserService * 根据手机号快速搜索用户列表 */ List fastSearch(String phonenumber); + + /** + * 修改用户密码 + */ + void updateUserPwd(Long userId, String newPassword); } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java index c001e10..80fd45a 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsUserServiceImpl.java @@ -436,6 +436,17 @@ public class AsUserServiceImpl implements IAsUserService return asUserMapper.selectUserByPhone(phone); } + /** + * 通过用户手机号和appid查询用户 + * + * @param phone 手机号 + * @return 用户对象信息 + */ + @Override + public AsUser selectUserByPhoneAndAppId(String phone, String appid) { + return asUserMapper.selectUserByPhoneAndAppId(phone,appid); + } + /** * 通过openid查询用户 * @@ -551,4 +562,12 @@ public class AsUserServiceImpl implements IAsUserService return users; } + /** + * 更新用户密码 + */ + @Override + public void updateUserPwd(Long userId, String newPassword) { + asUserMapper.updateUserPwd(userId, newPassword); + } + } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java index aacc0f3..6ea2558 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java @@ -342,9 +342,13 @@ public class CallbackServiceImpl implements CallbackService { throw new ServiceException("该运营商【"+sysDept.getDeptName()+"】未绑定微信用户"); } AsUser asUser1 = asUserMapper.selectUserById(sysDept.getAppUserId()); + AsDevice asDevice = asDeviceMapper.selectAsDeviceBySn(order.getSn()); JSONObject jsonObject = new JSONObject(); - jsonObject.put("orderNo", order.getOrderNo()); + jsonObject.put("order", order.getOrderNo()); + jsonObject.put("cheno", asDevice.getVehicleNum()); + jsonObject.put("snno", order.getSn()); + jsonObject.put("fee", order.getPayFee()); String phone = asUser1.getPhonenumber(); SendSmsVo sendSmsVo = new SendSmsVo(); @@ -368,7 +372,7 @@ public class CallbackServiceImpl implements CallbackService { // 短信日志 EtMsgLog etMsgLog = new EtMsgLog(); etMsgLog.setPhone(phone); - etMsgLog.setContent("您有一笔订单:"+order.getOrderNo()+",用户已付款,可在小程序管理端查看。"); + etMsgLog.setContent("您的订单:"+order.getOrderNo()+",车牌:"+asDevice.getVehicleNum()+",SN:"+order.getSn()+",用户已付款"+order.getPayFee()+"元,可在小程序管理端查看。"); etMsgLog.setType(ServiceConstants.MSG_TYPE_USER_PAYMENT_NOTIFY); etMsgLog.setSignName(signName); etMsgLog.setTemplateCode(templateCode); diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java index b36f2b4..e21ddc5 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java @@ -97,8 +97,8 @@ public class SysDeptServiceImpl implements ISysDeptService @Value("${aliyun.signName}") private String signName; - @Value("${aliyun.templateCode}") - private String templateCode; + @Value("${aliyun.templateCode3}") + private String templateCode3; @Value("${aliyun.phone}") private String phone; @@ -311,6 +311,17 @@ public class SysDeptServiceImpl implements ISysDeptService SysDept platform = deptMapper.selectDeptById(100L); dept.setAppid(platform.getAppid()); dept.setAppSecret(platform.getAppSecret()); + dept.setAppName(platform.getAppName()); + dept.setDomain(platform.getDomain()); + } + if (dept.getSeparateAccount().equals("N")) { + SysDept platform = deptMapper.selectDeptById(100L); + dept.setMerchantId(platform.getMerchantId()); + dept.setApiV3Key(platform.getApiV3Key()); + dept.setNotifyUrl(platform.getNotifyUrl()); + dept.setPrivateKeyPath(platform.getPrivateKeyPath()); + dept.setMerchantSerialNumber(platform.getMerchantSerialNumber()); + dept.setRefundNotifyUrl(platform.getRefundNotifyUrl()); } int i = deptMapper.insertDept(dept); Long[] areaIds = dept.getAreaIds(); @@ -539,7 +550,7 @@ public class SysDeptServiceImpl implements ISysDeptService SendSmsVo sendSmsVo = new SendSmsVo(); sendSmsVo.setMobile(phone); - sendSmsVo.setTemplateCode(templateCode); + sendSmsVo.setTemplateCode(templateCode3); sendSmsVo.setParam(jsonObject.toJSONString()); sendSmsVo.setSignName(signName); SendSmsResponse response = null; @@ -554,10 +565,10 @@ public class SysDeptServiceImpl implements ISysDeptService // 短信日志 EtMsgLog etMsgLog = new EtMsgLog(); etMsgLog.setPhone(phone); - etMsgLog.setContent("运营商【"+deptName+"】有一笔提现申请,请注意查收!"); + etMsgLog.setContent("用户"+deptName+",发起押金提现申请,请尽快审核!"); etMsgLog.setType("2"); etMsgLog.setSignName(signName); - etMsgLog.setTemplateCode(templateCode); + etMsgLog.setTemplateCode(templateCode3); int i = etMsgLogMapper.insertEtMsgLog(etMsgLog); if(i>0){ log.info("【提现申请】短信日志记录成功"); diff --git a/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java b/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java index fb268bc..4c0d81f 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java +++ b/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java @@ -1,8 +1,8 @@ package com.ruoyi.system.task; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; -import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.core.domain.entity.AsUser; @@ -10,7 +10,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.system.domain.*; import com.ruoyi.system.mapper.AsDeviceMapper; @@ -30,7 +30,10 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; @@ -369,4 +372,28 @@ public class EtTask { } } + /** + * 开始骑行未结束的订单,10秒算一次距离 + * cron: 0 5 0 * * ? + */ + public void computeDistance(){ + log.info("-------------------【定时任务】计算订单距离开始-------------------"); + EtOrder order = new EtOrder(); + order.setType("1"); + order.setStatus(ServiceConstants.ORDER_STATUS_RIDING); + List orders = etOrderService.selectEtOrderList(order); + for(EtOrder etOrder:orders){ + String tripRouteStr = etOrder.getTripRouteStr(); + if(StrUtil.isNotBlank(tripRouteStr)){ + double[][] doubles = GeoUtils.parseJsonTrack(tripRouteStr); + double v = GeoUtils.calculateTotalDistance(doubles); + etOrder.setDistance((int)Math.round(v)); + int updateEtOrder = etOrderService.updateEtOrder(etOrder); + if(updateEtOrder>0){ + log.info("【定时任务】计算订单距离成功:【orderNo="+etOrder.getOrderNo()+"】"); + } + } + } + } + } diff --git a/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml b/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml index 3f2df8e..64491a2 100644 --- a/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/AsDeviceMapper.xml @@ -70,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" de.remaining_power, de.voltage, de.version, de.qrcode, de.longitude, de.latitude, de.is_area_out_outage, de.is_admin_unlocking, de.signal_strength, de.satellites, de.quality from et_device de left join et_area_dept ad on ad.area_id = de.area_id left join sys_dept d on d.dept_id = ad.dept_id + left join et_hardware_version hv on hv.id = de.hardware_version_id where 1 = 1 and de.device_name like concat('%', #{deviceName}, '%') and de.mac like concat('%', #{mac}, '%') @@ -79,7 +80,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and d.dept_id = #{deptId} and de.model_id = #{modelId} and de.online_status = #{onlineStatus} - + and de.version = #{version} + and hv.version like concat('%', #{hardwareVersion}, '%') and (de.status = '3' or de.status = '4') diff --git a/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml b/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml index 676ae30..c9512e5 100644 --- a/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/AsUserMapper.xml @@ -34,20 +34,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + select u.user_id, u.user_name, u.real_name, u.id_card, u.nick_name, u.email, u.avatar, u.phonenumber, u.balance, u.birthday, u.password, u.pay_password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.wxopenid, - u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name + u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid from et_user u + +