From 0b24f831bd92553f4416087bfa8b41aef8537938 Mon Sep 17 00:00:00 2001 From: 18650502300 <18650502300@163.com> Date: Mon, 7 Oct 2024 21:47:05 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=89=A9=E5=B1=95=20?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E7=99=BB=E5=BD=95=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E6=94=B9=E9=80=A0=20=E8=81=94=E8=B0=83=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/app/AppController.java | 3 + .../controller/app/AppVerifyController.java | 63 +++-- .../controller/common/CaptchaController.java | 67 +++++- .../web/controller/rl/RlUserController.java | 6 +- .../controller/rl/RlUserExtController.java | 98 ++++++++ .../controller/system/SysLoginController.java | 8 +- .../com/ruoyi/common/constant/Constants.java | 5 + .../common/constant/ServiceConstants.java | 15 +- .../common/core/domain/entity/RlUserVO.java | 19 ++ .../ruoyi/common/utils/SendAliSmsUtil.java | 216 ++++++++++++++++++ .../com/ruoyi/common/utils/SendSmsVo.java | 31 +++ .../framework/config/SecurityConfig.java | 21 +- .../CustomLoginAuthenticationProvider.java | 5 +- .../web/service/SysLoginService.java | 137 +++++------ .../web/service/UserDetailsServiceImpl.java | 2 +- .../ruoyi/system/domain/EtCallbackLog.java | 4 +- .../com/ruoyi/system/domain/RlOnlineLog.java | 2 +- .../system/domain/device/RlDeviceVO.java | 4 + .../ruoyi/system/domain/order/RlOrder.java | 8 + .../system/domain/order/RlOrderQuery.java | 6 + .../system/domain/userExt/RlUserExt.java | 44 ++++ .../ruoyi/system/domain/vo/RlUserQuery.java | 8 +- .../ruoyi/system/mapper/RlOrderMapper.java | 6 + .../ruoyi/system/mapper/RlUserExtMapper.java | 62 +++++ .../com/ruoyi/system/mapper/RlUserMapper.java | 3 +- .../ruoyi/system/service/IRlOrderService.java | 10 +- .../system/service/IRlUserExtService.java | 62 +++++ .../ruoyi/system/service/IRlUserService.java | 4 +- .../service/impl/CallbackServiceImpl.java | 22 +- .../service/impl/RlDeviceServiceImpl.java | 13 +- .../service/impl/RlOrderServiceImpl.java | 109 +++++++-- .../service/impl/RlUserExtServiceImpl.java | 94 ++++++++ .../service/impl/RlUserServiceImpl.java | 20 +- .../java/com/ruoyi/system/task/RlTask.java | 21 ++ .../mapper/system/EtCallbackLogMapper.xml | 20 +- .../mapper/system/RlCommandLogMapper.xml | 10 +- .../mapper/system/RlOnlineLogMapper.xml | 10 +- .../resources/mapper/system/RlOrderMapper.xml | 30 ++- .../mapper/system/RlUserExtMapper.xml | 69 ++++++ .../resources/mapper/system/RlUserMapper.xml | 32 ++- 40 files changed, 1168 insertions(+), 201 deletions(-) create mode 100644 ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserExtController.java create mode 100644 ridelease-common/src/main/java/com/ruoyi/common/utils/SendAliSmsUtil.java create mode 100644 ridelease-common/src/main/java/com/ruoyi/common/utils/SendSmsVo.java create mode 100644 ridelease-system/src/main/java/com/ruoyi/system/domain/userExt/RlUserExt.java create mode 100644 ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserExtMapper.java create mode 100644 ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserExtService.java create mode 100644 ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserExtServiceImpl.java create mode 100644 ridelease-system/src/main/resources/mapper/system/RlUserExtMapper.xml diff --git a/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java b/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java index bdd94ba..31ecca2 100644 --- a/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java +++ b/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java @@ -305,6 +305,9 @@ public class AppController extends BaseController if(order.getDeliveryMethod() == null){ return error("配送方式不能为空"); } + if(StrUtil.isBlank(order.getType())){ + return error("类型不能为空"); + } PriceVO priceVO = orderService.calculatePrice(order); return AjaxResult.success(priceVO); } diff --git a/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java b/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java index 4d57d2d..4d6dc08 100644 --- a/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java +++ b/ridelease-admin/src/main/java/com/ruoyi/web/controller/app/AppVerifyController.java @@ -16,6 +16,7 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.verify.vo.IDResponse; import com.ruoyi.common.utils.wx.vo.PrepayResponseVO; import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.channel.ChannelVO; import com.ruoyi.system.domain.device.RlDevice; import com.ruoyi.system.domain.device.RlDeviceQuery; import com.ruoyi.system.domain.device.RlDeviceVO; @@ -66,6 +67,12 @@ public class AppVerifyController extends BaseController @Autowired private TokenService tokenService; + @Autowired + private RlChannelService channelService; + + @Autowired + private IWxPayService wxPayService; + /** * 实名认证 */ @@ -117,19 +124,16 @@ public class AppVerifyController extends BaseController } private void orderCheck(RlOrderQuery order) { - if(StringUtils.isEmpty(order.getOrderNo())){ - throw new ServiceException("订单号不能为空"); - } // 车型id不能为空 - if(order.getModelId() != null){ + if(order.getModelId() == null){ throw new ServiceException("车型id不能为空"); } // 配送方式不能为空 - if(order.getDeliveryMethod() != null){ + if(order.getDeliveryMethod() == null){ throw new ServiceException("配送方式不能为空"); } // 取车时间不能为空 - if(ObjectUtil.isNotNull(order.getPickupTime())){ + if(ObjectUtil.isNull(order.getPickupTime())){ throw new ServiceException("取车时间不能为空"); } // 取车经纬度不能为空 @@ -137,23 +141,23 @@ public class AppVerifyController extends BaseController throw new ServiceException("取车经度不能为空"); } // ruleId不能为空 - if(order.getRuleId() != null){ + if(order.getRuleId() == null){ throw new ServiceException("计费规则id不能为空"); } // agentId不能为空 - if(order.getAgentId() != null){ + if(order.getAgentId() == null){ throw new ServiceException("代理商id不能为空"); } // storeId不能为空 - if(order.getStoreId() != null){ + if(order.getStoreId() == null){ throw new ServiceException("门店id不能为空"); } // 数量num不能为空 - if(order.getNum() != null){ + if(order.getNum() == null){ throw new ServiceException("数量不能为空"); } // 订单类型type不能为空 - if(order.getType() != null){ + if(order.getType() == null){ throw new ServiceException("订单类型不能为空"); } } @@ -185,12 +189,15 @@ public class AppVerifyController extends BaseController * 我的订单列表 */ @GetMapping("/myOrderList") - public AjaxResult myOrderList(String status) + public AjaxResult myOrderList(String[] statusList) { - logger.info("订单列表请求:status=【"+status+"】"); + logger.info("订单列表请求:statusList=【"+JSON.toJSONString(statusList)+"】"); RlOrderQuery order = new RlOrderQuery(); order.setUserId(getUserId()); - order.setStatus(status); + if(statusList.length == 0){ + statusList = null; + } + order.setStatusList(statusList); List rlOrderVOS = orderService.selectRlOrderList(order); return success(rlOrderVOS); } @@ -262,10 +269,11 @@ public class AppVerifyController extends BaseController */ @Log(title = "续租", businessType = BusinessType.RELET) @PostMapping("/relet") - public AjaxResult relet(String orderNo,Long ruleId ) + public AjaxResult relet(@RequestBody RlOrderQuery orderQuery) { - logger.info("【续租】请求参数:orderNo={},ruleId={}", orderNo,ruleId); - PrepayResponseVO responseVO =orderService.relet(orderNo,ruleId,getUserId()); + logger.info("【续租】请求参数:order={}", JSON.toJSONString(orderQuery)); + orderService.validate(orderQuery); + PrepayResponseVO responseVO =orderService.relet(orderQuery); return success(responseVO); } @@ -507,6 +515,13 @@ public class AppVerifyController extends BaseController if(!ServiceConstants.ORDER_STATUS_TO_BE_PAID.equals(etOrder1.getStatus())){ throw new ServiceException("非待支付订单无法改价"); } + String outTradeNo = etOrder1.getOutTradeNo(); + ChannelVO channelVO = channelService.selectSmChannelByChannelId(etOrder1.getPayChannel()); + if(StrUtil.isNotBlank(outTradeNo)){ + // 如果有outtradeno,则关闭订单 + wxPayService.closeOrder(outTradeNo,channelVO); + logger.info("【订单改价】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", etOrder1.getOrderNo(),outTradeNo); + } BigDecimal payFee = BigDecimal.ZERO; if(ObjectUtil.isNotNull(order.getPayFee())){ payFee = payFee.add(order.getPayFee()); @@ -515,4 +530,18 @@ public class AppVerifyController extends BaseController return toAjax(orderService.updateRlOrderByOrderNo(order)); } + /** + * 根据sn查询正在进行中的订单 + */ + @GetMapping("/getInProgressOrder") + public AjaxResult getInProgressOrder(String sn) + { + logger.info("【根据sn查询正在进行中的订单】:sn=【{}】", sn); + if(StrUtil.isBlank(sn)){ + throw new ServiceException("【根据sn查询正在进行中的订单】sn不能为空"); + } + List orders = orderService.getInProgressOrder(sn); + return success(orders); + } + } diff --git a/ridelease-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ridelease-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java index d2d6e8c..e7f4815 100644 --- a/ridelease-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ridelease-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java @@ -6,7 +6,17 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; + +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.utils.SendAliSmsUtil; +import com.ruoyi.common.utils.SendSmsVo; +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.util.FastByteArrayOutputStream; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -22,12 +32,13 @@ import com.ruoyi.system.service.ISysConfigService; /** * 验证码操作处理 - * + * * @author ruoyi */ @RestController public class CaptchaController { + private static final Logger log = LoggerFactory.getLogger(CaptchaController.class); @Resource(name = "captchaProducer") private Producer captchaProducer; @@ -36,9 +47,22 @@ public class CaptchaController @Autowired private RedisCache redisCache; - + @Autowired private ISysConfigService configService; + + @Value("${aliyun.accessKeyId}") + private String accessKeyId; + + @Value("${aliyun.accessKeySecret}") + private String accessKeySecret; + + @Value("${aliyun.signName}") + private String signName; + + @Value("${aliyun.templateCode4}") + private String templateCode4; + /** * 生成验证码 */ @@ -91,4 +115,43 @@ public class CaptchaController ajax.put("img", Base64.encode(os.toByteArray())); return ajax; } + + /** + * 登录获取手机短信验证码 + */ + @GetMapping("/appCaptcha") + public AjaxResult getAppCode(String phone) { + try { + //创建一个返回对象 + AjaxResult ajax = AjaxResult.success(); + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); //生成一个uuid + String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; + // 生成四位数验证码 + String random = ""+Math.random(); + String code = random.substring(random.length()-4); + // 查询短信参数信息 + // 通过腾讯云短信发送短信 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code",code); + log.info("发送验证码:【{}】",code); + SendSmsVo sendSmsVo = new SendSmsVo(); + sendSmsVo.setMobile(phone); + sendSmsVo.setTemplateCode(templateCode4); + sendSmsVo.setParam(jsonObject.toJSONString()); + sendSmsVo.setSignName(signName); + SendSmsResponse response = null; + log.info("向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo)); + response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); + log.info("发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response)); + //把验证码答应存入缓存,10分钟的时间 + redisCache.setCacheObject(verifyKey, code, Constants.CODE_EXPIRATION, TimeUnit.MINUTES); + //把信息封装返回 + ajax.put("uuid", uuid); + return ajax; + } catch (ClientException e) { + e.printStackTrace(); + } + return null; + } } diff --git a/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserController.java b/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserController.java index 8031183..4876059 100644 --- a/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserController.java +++ b/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserController.java @@ -4,10 +4,12 @@ import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.RlUser; +import com.ruoyi.common.core.domain.entity.RlUserVO; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.vo.RlUserQuery; import com.ruoyi.system.service.IRlUserService; import org.springframework.web.bind.annotation.*; @@ -31,10 +33,10 @@ public class RlUserController extends BaseController * 获取用户列表 */ @GetMapping("/list") - public TableDataInfo list(RlUser rlUser) + public TableDataInfo list(RlUserQuery rlUser) { startPage(); - List list = eUserService.selectUserList(rlUser); + List list = eUserService.selectUserList(rlUser); return getDataTable(list); } diff --git a/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserExtController.java b/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserExtController.java new file mode 100644 index 0000000..0bd5e58 --- /dev/null +++ b/ridelease-admin/src/main/java/com/ruoyi/web/controller/rl/RlUserExtController.java @@ -0,0 +1,98 @@ +package com.ruoyi.web.controller.rl; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.userExt.RlUserExt; +import com.ruoyi.system.service.IRlUserExtService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 用户扩展Controller + * + * @author qzz + * @date 2024-10-07 + */ +@RestController +@RequestMapping("/system/ext") +public class RlUserExtController extends BaseController +{ + @Autowired + private IRlUserExtService rlUserExtService; + + /** + * 查询用户扩展列表 + */ + @PreAuthorize("@ss.hasPermi('system:ext:list')") + @GetMapping("/list") + public TableDataInfo list(RlUserExt rlUserExt) + { + startPage(); + List list = rlUserExtService.selectRlUserExtList(rlUserExt); + return getDataTable(list); + } + + /** + * 导出用户扩展列表 + */ + @PreAuthorize("@ss.hasPermi('system:ext:export')") + @Log(title = "用户扩展", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RlUserExt rlUserExt) + { + List list = rlUserExtService.selectRlUserExtList(rlUserExt); + ExcelUtil util = new ExcelUtil(RlUserExt.class); + util.exportExcel(response, list, "用户扩展数据"); + } + + /** + * 获取用户扩展详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:ext:query')") + @GetMapping(value = "/{extId}") + public AjaxResult getInfo(@PathVariable("extId") Long extId) + { + return success(rlUserExtService.selectRlUserExtByExtId(extId)); + } + + /** + * 新增用户扩展 + */ + @PreAuthorize("@ss.hasPermi('system:ext:add')") + @Log(title = "用户扩展", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody RlUserExt rlUserExt) + { + return toAjax(rlUserExtService.insertRlUserExt(rlUserExt)); + } + + /** + * 修改用户扩展 + */ + @PreAuthorize("@ss.hasPermi('system:ext:edit')") + @Log(title = "用户扩展", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RlUserExt rlUserExt) + { + return toAjax(rlUserExtService.updateRlUserExt(rlUserExt)); + } + + /** + * 删除用户扩展 + */ + @PreAuthorize("@ss.hasPermi('system:ext:remove')") + @Log(title = "用户扩展", businessType = BusinessType.DELETE) + @DeleteMapping("/{extIds}") + public AjaxResult remove(@PathVariable Long[] extIds) + { + return toAjax(rlUserExtService.deleteRlUserExtByExtIds(extIds)); + } +} diff --git a/ridelease-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ridelease-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index 245b64d..b1ba511 100644 --- a/ridelease-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ridelease-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -8,6 +8,7 @@ import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.web.service.SysLoginService; import com.ruoyi.framework.web.service.SysPermissionService; +import com.ruoyi.system.service.IRlUserService; import com.ruoyi.system.service.ISysMenuService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; import java.util.List; import java.util.Set; @@ -37,6 +39,9 @@ public class SysLoginController @Autowired private SysPermissionService permissionService; + @Resource + private IRlUserService eUserService; + /** * 登录方法 * @@ -85,7 +90,8 @@ public class SysLoginController // 权限集合 Set permissions = permissionService.getMenuPermission(user); AjaxResult ajax = AjaxResult.success(); - ajax.put("user", user); + RlUser rlUser = eUserService.selectUserById(user.getUserId()); + ajax.put("user", rlUser); ajax.put("roles", roles); ajax.put("permissions", permissions); return ajax; diff --git a/ridelease-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ridelease-common/src/main/java/com/ruoyi/common/constant/Constants.java index 801605b..2f6d44e 100644 --- a/ridelease-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ridelease-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -65,6 +65,11 @@ public class Constants */ public static final String REGISTER = "Register"; + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + /** * 登录失败 */ diff --git a/ridelease-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java b/ridelease-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java index c1c4d02..d18a99d 100644 --- a/ridelease-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java +++ b/ridelease-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java @@ -70,11 +70,6 @@ public class ServiceConstants { */ public static final String ORDER_STATUS_IN_USE = "4"; - /** - * 订单状态:8-已结束 - */ - public static final String ORDER_STATUS_ORDER_END = "8"; - /** * 订单状态:5-超时自动取消 */ @@ -85,6 +80,16 @@ public class ServiceConstants { */ public static final String ORDER_STATUS_CANCE = "6"; + /** + * 订单状态:7-待审核 + */ + public static final String ORDER_STATUS_TO_BE_AUDITED = "7"; + + /** + * 订单状态:8-已结束 + */ + public static final String ORDER_STATUS_ORDER_END = "8"; + /**----------------------------订单状态end----------------------------*/ /**----------------------------支付状态start----------------------------*/ diff --git a/ridelease-common/src/main/java/com/ruoyi/common/core/domain/entity/RlUserVO.java b/ridelease-common/src/main/java/com/ruoyi/common/core/domain/entity/RlUserVO.java index a088358..a64eff2 100644 --- a/ridelease-common/src/main/java/com/ruoyi/common/core/domain/entity/RlUserVO.java +++ b/ridelease-common/src/main/java/com/ruoyi/common/core/domain/entity/RlUserVO.java @@ -3,6 +3,7 @@ package com.ruoyi.common.core.domain.entity; import lombok.Data; import java.math.BigDecimal; +import java.util.Date; import java.util.List; @Data @@ -13,4 +14,22 @@ public class RlUserVO extends RlUser{ /** 账变记录 */ List changeBalanceList; + + /** 余额 */ + private String balance; + + /** 店铺名称 */ + private String storeName; + + /** 扩展id */ + private Long extId; + + /** 分红比例:百分比 */ + private BigDecimal dividendProportion; + + /** 合作时间 */ + private Date cooperationTime; + + /** 分账状态:0-禁用;1-启动 */ + private Boolean dividendStatus; } diff --git a/ridelease-common/src/main/java/com/ruoyi/common/utils/SendAliSmsUtil.java b/ridelease-common/src/main/java/com/ruoyi/common/utils/SendAliSmsUtil.java new file mode 100644 index 0000000..74d4656 --- /dev/null +++ b/ridelease-common/src/main/java/com/ruoyi/common/utils/SendAliSmsUtil.java @@ -0,0 +1,216 @@ +package com.ruoyi.common.utils; + +import com.alibaba.fastjson2.JSONObject; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest; +import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse; +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.profile.DefaultProfile; +import com.aliyuncs.profile.IClientProfile; +import org.apache.commons.lang3.StringUtils; + +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class SendAliSmsUtil { + // 产品名称:云通信短信API产品,开发者无需替换 + static final String product = "Dysmsapi"; + + // 产品域名,开发者无需替换 + static final String domain = "dysmsapi.aliyuncs.com"; + + private static final String accessKeyId = "LTAI5tR5PUDLcBxZskXhYaar";//需要替换 + private static final String accessKeySecret = "qCziuzsKPwCY6SD0cTr1Gau5dOjHnb";//需要替换 + + // 签名 + private static final String signName = "宁德市宏冠食品";//需要替换 + + //短信模板 + public static final String templateCode = "SMS_295385181";//需要替换 + + //发送短信失败错误码对应的原因 + public static Map errorMags; + + + + static { + Map jsonObject = new HashMap<>(); + jsonObject.put("isp.RAM_PERMISSION_DENY","RAM权限不足"); + jsonObject.put("isv.OUT_OF_SERVICE","业务停机"); + jsonObject.put("isv.PRODUCT_UN_SUBSCRIPT","未开通云通信产品的阿里云客户"); + jsonObject.put("isv.PRODUCT_UNSUBSCRIBE","产品未开通"); + jsonObject.put("isv.ACCOUNT_NOT_EXISTS","账户不存在"); + jsonObject.put("isv.ACCOUNT_ABNORMAL","账户异常"); + jsonObject.put("isv.SMS_TEMPLATE_ILLEGAL","该账号下找不到对应模板"); + jsonObject.put("isv.SMS_TEST_SIGN_TEMPLATE_LIMIT","测试模板和签名限制"); + jsonObject.put("isv.SMS_SIGNATURE_SCENE_ILLEGAL","签名和模板类型不一致"); + jsonObject.put("isv.SMS_SIGN_ILLEGAL","签名禁止使用"); + jsonObject.put("isv.SMS_SIGNATURE_ILLEGAL","该账号下找不到对应签名"); + jsonObject.put("isp.SYSTEM_ERROR","系统出现错误,请重新调用"); + jsonObject.put("isv.MOBILE_NUMBER_ILLEGAL","手机号码格式错误"); + jsonObject.put("isv.MOBILE_COUNT_OVER_LIMIT","手机号码数量超过限制,最多支持1000条"); + jsonObject.put("isv.TEMPLATE_MISSING_PARAMETERS","模板变量中存在未赋值变量"); + jsonObject.put("isv.TEMPLATE_PARAMS_ILLEGAL","传入的变量内容和实际申请模板时变量所选择的属性类型不配"); + jsonObject.put("isv.TEMPLATE_COUNT_OVER_LIMIT","超过单自然日模板申请数量上限"); + jsonObject.put("isv.TEMPLATE_OVER_LIMIT","模板字符数量超过限制"); + jsonObject.put("isv.BUSINESS_LIMIT_CONTROL","触发云通信流控限制"); + jsonObject.put("isv.INVALID_JSON_PARAM","参数格式错误,请修改为字符串值"); + jsonObject.put("isv.INVALID_PARAMETERS","参数格式不正确"); + jsonObject.put("isv.BLACK_KEY_CONTROL_LIMIT","变量中传入疑似违规信息"); + jsonObject.put("isv.PARAM_LENGTH_LIMIT","参数超过长度限制"); + jsonObject.put("isv.PARAM_NOT_SUPPORT_URL","变量不支持传入URL"); + jsonObject.put("isv.AMOUNT_NOT_ENOUGH","账户余额不足"); + jsonObject.put("FILTER","关键字拦截"); + jsonObject.put("VALVE:M_MC","重复过滤"); + jsonObject.put("VALVE:H_MC","重复过滤"); + jsonObject.put("VALVE:D_MC","重复过滤"); + jsonObject.put("MOBILE_SEND_LIMIT","单个号码日或月发送上限,流控超限,频繁发送超限"); + jsonObject.put("isv.TEMPLATE_PARAMS_ILLEGAL","传入的变量内容和实际申请模板时变量所选择的属性类型不配"); + jsonObject.put("MOBILE_IN_BLACK","手机号在黑名单(平台或运营商)"); + jsonObject.put("MOBILE_IN_BLACK","手机号在黑名单(平台或运营商)"); + jsonObject.put("MOBILE_TERMINAL_ERROR","手机终端问题、内存满、SIM卡满、非法设备等"); + jsonObject.put("SP_NOT_BY_INTER_SMS","未开通国际短信"); + jsonObject.put("USER_REJECT","用户手机退订此业务、产品未开通"); + jsonObject.put("SP_UNKNOWN_ERROR","运营商未知错误"); + jsonObject.put("MOBILE_ACCOUNT_ABNORMAL","用户账户异常、携号转网、欠费等"); + jsonObject.put("DELIVERED","消息发送成功"); + jsonObject.put("MOBILE_ACCOUNT_ABNORMAL","用户账户异常、携号转网、欠费等"); + jsonObject.put("CONTENT_KEYWORD","内容关键字拦截"); + jsonObject.put("SIGNATURE_BLACKLIST","签名黑名单"); + jsonObject.put("INVALID_NUMBER","号码不合法"); + jsonObject.put("NO_ROUTE","无路由器"); + jsonObject.put("CONTENT_ERROR","模板内容无退订"); + + errorMags = Collections.unmodifiableMap(jsonObject); + } + + /** + * 发送短信验证码 + * @param sendSmsVo 短信发送api第三方参数实体类 + * @return + * @throws ClientException + */ + public static SendSmsResponse sendVerifyCode(String accessKeyId,String accessKeySecret,SendSmsVo sendSmsVo) + throws ClientException { + // 可自助调整超时时间 + System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); + System.setProperty("sun.net.client.defaultReadTimeout", "10000"); + // 初始化acsClient,暂不支持region化 + IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); + DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); + IAcsClient acsClient = new DefaultAcsClient(profile); + // 组装请求对象-具体描述见控制台-文档部分内容 + SendSmsRequest request = new SendSmsRequest(); + // 必填:待发送手机号 + request.setPhoneNumbers(sendSmsVo.getMobile()); + // 必填:短信签名-可在短信控制台中找到 + request.setSignName(sendSmsVo.getSignName()); + // 必填:短信模板-可在短信控制台中找到 + request.setTemplateCode(sendSmsVo.getTemplateCode()); + // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为 + request.setTemplateParam(sendSmsVo.getParam()); + // hint 此处可能会抛出异常,注意catch + SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); + return sendSmsResponse; + } + + /** + * 查询消息的发送状态 + * @param phoneNum + * @param bizId 发送回执id,调用发送短信api时,会返回 + * @return + * @throws ClientException + */ + public static QuerySendDetailsResponse querySendDetails(String phoneNum, String bizId) throws ClientException { + + // 可自助调整超时时间 + System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); + System.setProperty("sun.net.client.defaultReadTimeout", "10000"); + + // 初始化acsClient,暂不支持region化 + IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); + DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); + IAcsClient acsClient = new DefaultAcsClient(profile); + + // 组装请求对象 + QuerySendDetailsRequest request = new QuerySendDetailsRequest(); + // 必填-号码 + request.setPhoneNumber(phoneNum); + // 可选-流水号 + request.setBizId(bizId); + // 必填-发送日期 支持30天内记录查询,格式yyyyMMdd + SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd"); + request.setSendDate(ft.format(new Date())); + // 必填-页大小 + request.setPageSize(10L); + // 必填-当前页码从1开始计数 + request.setCurrentPage(1L); + + // hint 此处可能会抛出异常,注意catch + QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request); + + return querySendDetailsResponse; + } + + //获取错误码对应的原因 + public static String getSmsSendError(String errCode){ + String mags = null; + if(StringUtils.isNotBlank(errorMags.get(errCode))){ + mags = errorMags.get(errCode); + } + return mags; + } + + public static void main(String[] args) throws ClientException, InterruptedException { + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code","123456"); +// jsonObject.put("Address","河南省盛世大厦8号楼菜鸟驿站;配送员:王金莺"); +// jsonObject.put("Pickingcode","kko90"); + + SendSmsVo sendSmsVo = new SendSmsVo(); + sendSmsVo.setMobile("18650502300"); + sendSmsVo.setSignName(signName); + sendSmsVo.setTemplateCode(templateCode); + sendSmsVo.setParam(jsonObject.toJSONString()); + // 发验证码短信 "18650502300", jsonObject.toJSONString(),templateCode + SendSmsResponse response = sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); + System.out.println("短信接口返回的数据----------------"); + System.out.println("Code=" + response.getCode()); + System.out.println("Message=" + response.getMessage()); + System.out.println("RequestId=" + response.getRequestId()); + System.out.println("BizId=" + response.getBizId());//消息回执id + + //Thread.sleep(3000L); + + // 查明细 + if (response.getCode() != null && response.getCode().equals("OK")) { + QuerySendDetailsResponse querySendDetailsResponse = querySendDetails("18650502300", response.getBizId()); + System.out.println("短信明细查询接口返回数据----------------"); + System.out.println("Code=" + querySendDetailsResponse.getCode()); + System.out.println("Message=" + querySendDetailsResponse.getMessage()); + int i = 0; + for (QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse + .getSmsSendDetailDTOs()) { + System.out.println("SmsSendDetailDTO[" + i + "]:"); + System.out.println("Content=" + smsSendDetailDTO.getContent()); + System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode()); + System.out.println("OutId=" + smsSendDetailDTO.getOutId()); + System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum()); + System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate()); + System.out.println("SendDate=" + smsSendDetailDTO.getSendDate()); + System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus()); + System.out.println("Template=" + smsSendDetailDTO.getTemplateCode()); + } + System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount()); + System.out.println("RequestId=" + querySendDetailsResponse.getRequestId()); + } + } + +} diff --git a/ridelease-common/src/main/java/com/ruoyi/common/utils/SendSmsVo.java b/ridelease-common/src/main/java/com/ruoyi/common/utils/SendSmsVo.java new file mode 100644 index 0000000..73ef661 --- /dev/null +++ b/ridelease-common/src/main/java/com/ruoyi/common/utils/SendSmsVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.common.utils; + +import lombok.Data; + +/** + * 短信发送api第三方参数实体类 + + */ +@Data +public class SendSmsVo { + private String uid; + private String token; + + // 待发送短信手机号 + private String mobile; + + // 模版id + private Integer template; + + // 发送参数 + private String param; + + private String content; + + // 模版编码 + private String templateCode; + + // 签名 + private String signName; + +} diff --git a/ridelease-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ridelease-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index f74e863..d842f21 100644 --- a/ridelease-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ridelease-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -1,5 +1,6 @@ package com.ruoyi.framework.config; +import com.ruoyi.framework.security.filter.CustomLoginAuthenticationProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -7,8 +8,10 @@ import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -21,12 +24,15 @@ import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; +import java.util.Arrays; + /** * spring security配置 * * @author ruoyi */ @EnableMethodSecurity(prePostEnabled = true, securedEnabled = true) +@EnableWebSecurity @Configuration public class SecurityConfig { @@ -66,16 +72,25 @@ public class SecurityConfig @Autowired private PermitAllUrlProperties permitAllUrl; + private final CustomLoginAuthenticationProvider customLoginAuthenticationProvider; + + public SecurityConfig(UserDetailsService userDetailsService, + CustomLoginAuthenticationProvider customLoginAuthenticationProvider) { + this.userDetailsService = userDetailsService; + this.customLoginAuthenticationProvider = customLoginAuthenticationProvider; + } + /** * 身份验证实现 */ @Bean - public AuthenticationManager authenticationManager() - { + public AuthenticationManager authenticationManager() { DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); daoAuthenticationProvider.setUserDetailsService(userDetailsService); daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); - return new ProviderManager(daoAuthenticationProvider); + + // 创建一个 ProviderManager,包含 DaoAuthenticationProvider 和 CustomLoginAuthenticationProvider + return new ProviderManager(Arrays.asList(daoAuthenticationProvider, customLoginAuthenticationProvider)); } /** diff --git a/ridelease-framework/src/main/java/com/ruoyi/framework/security/filter/CustomLoginAuthenticationProvider.java b/ridelease-framework/src/main/java/com/ruoyi/framework/security/filter/CustomLoginAuthenticationProvider.java index 7b7e047..f389b74 100644 --- a/ridelease-framework/src/main/java/com/ruoyi/framework/security/filter/CustomLoginAuthenticationProvider.java +++ b/ridelease-framework/src/main/java/com/ruoyi/framework/security/filter/CustomLoginAuthenticationProvider.java @@ -1,6 +1,7 @@ package com.ruoyi.framework.security.filter; import com.ruoyi.common.constant.Constants; +import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; @@ -8,11 +9,13 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Component; /** * 自定义登录扩展 */ -public class CustomLoginAuthenticationProvider extends DaoAuthenticationProvider { +@Component +public class CustomLoginAuthenticationProvider extends DaoAuthenticationProvider implements AuthenticationProvider { public CustomLoginAuthenticationProvider(UserDetailsService userDetailsService) { super(); diff --git a/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 3323e99..c788b6b 100644 --- a/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -7,12 +7,14 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.utils.wx.AccessTokenUtil; import com.ruoyi.common.utils.wx.vo.WeChatMiniAuthorizeVo; import com.ruoyi.common.core.domain.entity.RlUser; import com.ruoyi.system.service.IRlUserService; 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; @@ -98,6 +100,7 @@ public class SysLoginService { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); AuthenticationContextHolder.setContext(authenticationToken); + authenticationToken.setDetails(Constants.USER_TYPE_PC); // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername authentication = authenticationManager.authenticate(authenticationToken); } @@ -279,6 +282,7 @@ public class SysLoginService asUser.setPhonenumber(phoneNumber); asUser.setLoginIp(IpUtils.getIpAddr()); asUser.setLoginDate(DateUtils.getNowDate()); + asUser.setPassword(SecurityUtils.encryptPassword(Constants.CUSTOM_LOGIN_WX)); asUser.setCreateTime(DateUtils.getNowDate()); asUser.setWxopenid(openId); log.info("【微信登录/wxlogin】用户不存在,自动注册用户:【{}】", JSON.toJSON(asUser)); @@ -378,81 +382,64 @@ public class SysLoginService } public String appCodeLogin(String username, String code, String password, String uuid) { -// 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()); -// asUser.setAreaId(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()); -// } -// user.setAreaId(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()); //修改rl_user最近登录IP和登录时间 -// // 生成token -// return tokenService.createToken(loginUser); - return null; + RlUser user = userService.selectUserByUserName(username); + if(ObjectUtils.isEmpty(user)){ + RlUser asUser = new RlUser(); + asUser.setUserName(username); + asUser.setPhonenumber(username); + asUser.setLoginIp(IpUtils.getIpAddr()); + asUser.setLoginDate(DateUtils.getNowDate()); + asUser.setCreateTime(DateUtils.getNowDate()); + log.info("【微信登录/wxlogin】用户不存在,自动注册用户:【{}】", JSON.toJSON(asUser)); + int i = userService.insertUser(asUser); + user = asUser; + }else{ + user.setLoginIp(IpUtils.getIpAddr()); + user.setLoginDate(DateUtils.getNowDate()); + log.info("【微信登录/wxlogin】用户已存在,登录:【{}】", JSON.toJSON(user)); + int i = userService.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()); //修改rl_user最近登录IP和登录时间 + // 生成token + return tokenService.createToken(loginUser); } /** diff --git a/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java index 54d6714..e308023 100644 --- a/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java +++ b/ridelease-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java @@ -65,7 +65,7 @@ public class UserDetailsServiceImpl implements UserDetailsService user = asUserService.selectUserByWxopenid(username); }else{ // app用户登录(短信登录) 如果是app用户则用手机号 - user = asUserService.selectUserByPhoneAndAppId(username,appId); + user = userService.selectUserByUserName(username); verifyUser(username, user); if(Constants.USER_TYPE_PASSWORD.equals(userType)){ if(StrUtil.isBlank(user.getPassword())){ diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/EtCallbackLog.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/EtCallbackLog.java index 882ca8b..ff768bc 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/domain/EtCallbackLog.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/EtCallbackLog.java @@ -3,11 +3,9 @@ package com.ruoyi.system.domain; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** - * 回调日志对象 et_callback_log + * 回调日志对象 rl_callback_log * * @author 邱贞招 * @date 2024-06-18 diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/RlOnlineLog.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/RlOnlineLog.java index 316213b..aa73eb6 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/domain/RlOnlineLog.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/RlOnlineLog.java @@ -5,7 +5,7 @@ import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; /** - * 在线/离线日志对象 et_online_log + * 在线/离线日志对象 rl_online_log * * @author 邱贞招 * @date 2024-07-13 diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/device/RlDeviceVO.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/device/RlDeviceVO.java index 62f1a5b..0dfa45c 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/domain/device/RlDeviceVO.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/device/RlDeviceVO.java @@ -1,6 +1,7 @@ package com.ruoyi.system.domain.device; import com.ruoyi.common.annotation.Excel; +import com.ruoyi.system.domain.RlFunction; import com.ruoyi.system.domain.accessory.RlAccessoryVO; import lombok.Data; @@ -31,6 +32,9 @@ public class RlDeviceVO extends RlDevice{ @Excel(name = "配件列表") private List accessorys; + @Excel(name = "功能列表") + private List functionList; + @Excel(name = "店铺地址") private String storeLocation; diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrder.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrder.java index bb27c4e..3ec79b1 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrder.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrder.java @@ -39,6 +39,10 @@ public class RlOrder extends BaseEntity @Excel(name = "用户名") private String userName; + /** 真实姓名 */ + @Excel(name = "真实姓名") + private String realName; + /** 手机号 */ @Excel(name = "手机号") private String phone; @@ -115,6 +119,10 @@ public class RlOrder extends BaseEntity @Excel(name = "状态") private String status; + /** 是否逾期 */ + @Excel(name = "是否逾期") + private Boolean isOverdue; + /** 还车时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "还车时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrderQuery.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrderQuery.java index d26fc3d..53d6af8 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrderQuery.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/order/RlOrderQuery.java @@ -26,4 +26,10 @@ public class RlOrderQuery extends RlOrder{ /** jscode*/ private String jscode; + /** 状态列表 */ + private String[] statusList; + + /** 类型 1-租赁订单,2-续租订单*/ + private String type; + } diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/userExt/RlUserExt.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/userExt/RlUserExt.java new file mode 100644 index 0000000..0581a76 --- /dev/null +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/userExt/RlUserExt.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.domain.userExt; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 用户扩展对象 rl_user_ext + * + * @author qzz + * @date 2024-10-07 + */ +@Data +public class RlUserExt extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 扩展id */ + private Long extId; + + /** 用户id */ + @Excel(name = "用户id") + private Long userId; + + /** 余额 */ + @Excel(name = "余额") + private BigDecimal balance; + + /** 分红比例 */ + @Excel(name = "分红比例") + private BigDecimal dividendProportion; + + /** 合作时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "合作时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date cooperationTime; + + /** 分账状态 */ + @Excel(name = "分账状态") + private Boolean dividendStatus; +} diff --git a/ridelease-system/src/main/java/com/ruoyi/system/domain/vo/RlUserQuery.java b/ridelease-system/src/main/java/com/ruoyi/system/domain/vo/RlUserQuery.java index 3faf8ff..5818970 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/domain/vo/RlUserQuery.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/domain/vo/RlUserQuery.java @@ -1,4 +1,10 @@ package com.ruoyi.system.domain.vo; -public class RlUserQuery { +import com.ruoyi.common.core.domain.entity.RlUser; +import lombok.Data; + +@Data +public class RlUserQuery extends RlUser { + + private String[] typeList; } diff --git a/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlOrderMapper.java b/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlOrderMapper.java index d486c00..4e44e50 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlOrderMapper.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlOrderMapper.java @@ -3,6 +3,7 @@ package com.ruoyi.system.mapper; import com.ruoyi.system.domain.order.RlOrder; import com.ruoyi.system.domain.order.RlOrderQuery; import com.ruoyi.system.domain.order.RlOrderVO; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -95,6 +96,11 @@ public interface RlOrderMapper */ RlOrderVO selectRlOrderByOutTradeNo(String outTradeNo); + /** + * 根据sn查询正在进行中的订单 + */ + List getInProgressOrder(@Param("sn") String sn, @Param("userId") Long userId); + // /** // * 扫码绑定车辆 // */ diff --git a/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserExtMapper.java b/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserExtMapper.java new file mode 100644 index 0000000..c7e3e28 --- /dev/null +++ b/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserExtMapper.java @@ -0,0 +1,62 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.userExt.RlUserExt; + +import java.util.List; + +/** + * 用户扩展Mapper接口 + * + * @author qzz + * @date 2024-10-07 + */ +public interface RlUserExtMapper +{ + /** + * 查询用户扩展 + * + * @param extId 用户扩展主键 + * @return 用户扩展 + */ + public RlUserExt selectRlUserExtByExtId(Long extId); + + /** + * 查询用户扩展列表 + * + * @param rlUserExt 用户扩展 + * @return 用户扩展集合 + */ + public List selectRlUserExtList(RlUserExt rlUserExt); + + /** + * 新增用户扩展 + * + * @param rlUserExt 用户扩展 + * @return 结果 + */ + public int insertRlUserExt(RlUserExt rlUserExt); + + /** + * 修改用户扩展 + * + * @param rlUserExt 用户扩展 + * @return 结果 + */ + public int updateRlUserExt(RlUserExt rlUserExt); + + /** + * 删除用户扩展 + * + * @param extId 用户扩展主键 + * @return 结果 + */ + public int deleteRlUserExtByExtId(Long extId); + + /** + * 批量删除用户扩展 + * + * @param extIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteRlUserExtByExtIds(Long[] extIds); +} diff --git a/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserMapper.java b/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserMapper.java index 985ecd6..7ed8260 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserMapper.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/mapper/RlUserMapper.java @@ -3,6 +3,7 @@ package com.ruoyi.system.mapper; import com.ruoyi.common.core.domain.entity.RlUser; import com.ruoyi.common.core.domain.entity.RlUserVO; import com.ruoyi.common.core.domain.vo.LabelVo; +import com.ruoyi.system.domain.vo.RlUserQuery; import org.apache.ibatis.annotations.Param; import java.math.BigDecimal; @@ -21,7 +22,7 @@ public interface RlUserMapper * @param RlUser 用户信息 * @return 用户信息集合信息 */ - public List selectUserList(RlUser RlUser); + public List selectUserList(RlUserQuery RlUser); /** * 根据条件分页查询已配用户角色列表 diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/IRlOrderService.java b/ridelease-system/src/main/java/com/ruoyi/system/service/IRlOrderService.java index f5ebb0d..03dd382 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/service/IRlOrderService.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/IRlOrderService.java @@ -124,7 +124,7 @@ public interface IRlOrderService /** * 续租 */ - PrepayResponseVO relet(String orderNo, Long ruleId,Long userId); + PrepayResponseVO relet(RlOrderQuery order); /** * 订单取消 @@ -150,4 +150,12 @@ public interface IRlOrderService * 根据订单号查询可还车的店铺 */ List getReturnStoreList(String orderNo,String lon,String lat); + + /** + * 根据sn查询正在进行中的订单 + */ + List getInProgressOrder(String sn); + + + void validate(RlOrderQuery orderQuery); } diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserExtService.java b/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserExtService.java new file mode 100644 index 0000000..b8fd86b --- /dev/null +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserExtService.java @@ -0,0 +1,62 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.domain.userExt.RlUserExt; + +import java.util.List; + +/** + * 用户扩展Service接口 + * + * @author qzz + * @date 2024-10-07 + */ +public interface IRlUserExtService +{ + /** + * 查询用户扩展 + * + * @param extId 用户扩展主键 + * @return 用户扩展 + */ + public RlUserExt selectRlUserExtByExtId(Long extId); + + /** + * 查询用户扩展列表 + * + * @param rlUserExt 用户扩展 + * @return 用户扩展集合 + */ + public List selectRlUserExtList(RlUserExt rlUserExt); + + /** + * 新增用户扩展 + * + * @param rlUserExt 用户扩展 + * @return 结果 + */ + public int insertRlUserExt(RlUserExt rlUserExt); + + /** + * 修改用户扩展 + * + * @param rlUserExt 用户扩展 + * @return 结果 + */ + public int updateRlUserExt(RlUserExt rlUserExt); + + /** + * 批量删除用户扩展 + * + * @param extIds 需要删除的用户扩展主键集合 + * @return 结果 + */ + public int deleteRlUserExtByExtIds(Long[] extIds); + + /** + * 删除用户扩展信息 + * + * @param extId 用户扩展主键 + * @return 结果 + */ + public int deleteRlUserExtByExtId(Long extId); +} diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserService.java b/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserService.java index 31ed9f2..c5cc5d6 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserService.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/IRlUserService.java @@ -1,7 +1,9 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.entity.RlUser; +import com.ruoyi.common.core.domain.entity.RlUserVO; import com.ruoyi.system.domain.query.AuthenticationQuery; +import com.ruoyi.system.domain.vo.RlUserQuery; import java.math.BigDecimal; import java.util.List; @@ -19,7 +21,7 @@ public interface IRlUserService * @param user 用户信息 * @return 用户信息集合信息 */ - public List selectUserList(RlUser user); + public List selectUserList(RlUserQuery user); /** * 根据条件分页查询已分配用户角色列表 diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java index 3e5a6bb..310299b 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java @@ -122,15 +122,17 @@ public class CallbackServiceImpl implements CallbackService { logger.info("【微信支付回调】租赁订单支付"); - /** 计算到期时间*/ - calculateExpiryTime(order); - Boolean execute = transactionTemplate.execute(e -> { /** 生成账变记录*/ generateChanggeBalance(order); order1.setPaid("1"); order1.setPayTime(DateUtils.getNowDate()); order1.setPayType(payType); + if(order.getDeliveryMethod().equals(ServiceConstants.DELIVERY_METHOD_SELF_PICKUP)){ + order1.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_TAKEN); + }else{ + order1.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_SENT); + } order1.setCost(getCost(channelVO,order.getPayFee())); logger.info("=================【微信支付回调】开始更新订单信息=================={}",JSON.toJSON(order1)); int updateEtOrder = orderService.updateRlOrder(order1); @@ -166,20 +168,6 @@ public class CallbackServiceImpl implements CallbackService { } } - private void calculateExpiryTime(RlOrder order) { - /** 如果是租赁订单,根据取车时间计算到期时间 - * 如果是续费订单,根据到期时间计算续费订单的到期时间 */ - RlFeeRule feeRule = feeRuleService.selectRlFeeRuleByRuleId(order.getRuleId()); - Date startTime = null; - if(order.getType().equals(ServiceConstants.ORDER_TYPE_LEASE)){ - startTime = order.getPickupTime(); - }else{ - startTime = order.getExpiryTime(); - } - Date expiryTime = DateUtils.getTimeAfterXUnit(startTime, order.getNum(), feeRule.getRentalUnit()); - order.setExpiryTime(expiryTime); - } - private BigDecimal getCost(ChannelVO channel,BigDecimal payFee) { // 获取到渠道成本 BigDecimal costRate = channel.getCostRate(); diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlDeviceServiceImpl.java b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlDeviceServiceImpl.java index 79275e8..8d1ab88 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlDeviceServiceImpl.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlDeviceServiceImpl.java @@ -18,6 +18,7 @@ import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.common.utils.onenet.*; import com.ruoyi.system.domain.RlCommandLog; +import com.ruoyi.system.domain.RlFunction; import com.ruoyi.system.domain.accessory.RlAccessoryVO; import com.ruoyi.system.domain.device.RlDevice; import com.ruoyi.system.domain.RlOnlineLog; @@ -214,6 +215,12 @@ public class RlDeviceServiceImpl extends ServiceImpl i if(ObjectUtil.isNotNull(storeVo)){ rlDevice.setStoreLocation(storeVo.getAddress()); } + RlModelVO rlModelVO = modelService.selectEModelByModelId(rlDevice.getModelId()); + if(ObjectUtil.isNotNull(rlModelVO)){ + rlDevice.setModel(rlModelVO.getModel()); + List functionList = modelService.getFunctionListByModelId(rlDevice.getModelId()); + rlDevice.setFunctionList(functionList); + } return rlDevice; } @@ -1359,7 +1366,7 @@ public class RlDeviceServiceImpl extends ServiceImpl i updateOrder.setOrderId(order.getOrderId()); updateOrder.setReturnType(orderQuery.getReturnType()); updateOrder.setReturnTime(DateUtils.getNowDate()); - updateOrder.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); + updateOrder.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_AUDITED);// 还车后订单状态变成待审核,只有商户确认才算完成 updateOrder.setReturnTime(DateUtils.getNowDate()); String token = Token.getToken(); @@ -1377,7 +1384,7 @@ public class RlDeviceServiceImpl extends ServiceImpl i /** 8.判断是否在店铺附近 先根据手机定位判断,再跟进车辆定位判断,如果两个都不在,则提示不在附近*/ boolean nearStore = isNearStore(orderQuery, device); if(!nearStore){ - throw new ServiceException("不在附近"); + throw new ServiceException("不在店铺附近,请前往店铺还车"); } }else{ ResponseVo responseVo = sendCommandWithResp(device.getMac(), token, IotConstants.COMMAND_CLOSE + IotConstants.COMMAND_FREQUENCY_3600, "辅助还车关锁",orderNo); @@ -1399,8 +1406,8 @@ public class RlDeviceServiceImpl extends ServiceImpl i log.info("【还车关锁】记录行程失败"); throw new ServiceException("【还车关锁】记录行程失败"); } - BigDecimal overdueFee= BigDecimal.ZERO; /** 6.计算逾期费用 */ + BigDecimal overdueFee= BigDecimal.ZERO; if(ObjectUtil.isNull(order.getExpiryTime())){ throw new ServiceException("订单没有到期时间"); } diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlOrderServiceImpl.java b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlOrderServiceImpl.java index 743673d..f398565 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlOrderServiceImpl.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlOrderServiceImpl.java @@ -4,8 +4,10 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.ServiceConstants; +import com.ruoyi.common.core.domain.entity.RlUser; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.common.utils.uuid.IdUtils; @@ -25,8 +27,11 @@ import com.ruoyi.system.service.*; import com.ruoyi.system.service.store.RlStoreService; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import java.math.BigDecimal; @@ -42,6 +47,9 @@ import java.util.*; @Service public class RlOrderServiceImpl implements IRlOrderService { + + private static final Logger logger = LoggerFactory.getLogger(CallbackServiceImpl.class); + @Resource private RlOrderMapper orderMapper; @@ -72,6 +80,12 @@ public class RlOrderServiceImpl implements IRlOrderService @Autowired private RlStoreService storeService; + @Resource + private IRlUserService eUserService; + + @Autowired + private TransactionTemplate transactionTemplate; + /** * 查询订单 * @@ -266,6 +280,12 @@ public class RlOrderServiceImpl implements IRlOrderService order.setPaid(ServiceConstants.ORDER_PAY_STATUS_NON_PAYMENT); order.setType(type); order.setUserId(userId); + RlUser rlUser = eUserService.selectUserById(userId); + if(ObjectUtil.isNotNull(rlUser)){ + order.setUserName(rlUser.getUserName()); + order.setPhone(rlUser.getPhonenumber()); + order.setRealName(rlUser.getRealName()); + } String configByKey = configService.selectConfigByKey("rl.order.auto.cancel"); order.setAutoCancelTime(DateUtils.getTimeAfterXMinutes(order.getCreateTime(),Integer.parseInt(configByKey))); @@ -312,6 +332,16 @@ public class RlOrderServiceImpl implements IRlOrderService order.setOutUnit(feeRule.getOutUnit()); order.setOutPrice(feeRule.getOutPrice()); order.setRentalUnit(feeRule.getRentalUnit()); + /** 如果是租赁订单,根据取车时间计算到期时间 + * 如果是续费订单,根据到期时间计算续费订单的到期时间 */ + Date startTime = null; + if(order.getType().equals(ServiceConstants.ORDER_TYPE_LEASE)){ + startTime = order.getPickupTime(); + }else{ + startTime = order.getExpiryTime(); + } + Date expiryTime = DateUtils.getTimeAfterXUnit(startTime, order.getNum(), feeRule.getRentalUnit()); + order.setExpiryTime(expiryTime); } /** @@ -326,10 +356,24 @@ public class RlOrderServiceImpl implements IRlOrderService if(StrUtil.isNotBlank(order.getSn())){ throw new RuntimeException("该订单已绑定车辆:"+order.getSn()); } - RlOrder rlOrder = new RlOrder(); - rlOrder.setOrderNo(orderNo); - rlOrder.setSn(sn); - return orderMapper.updateRlOrderByOrderNo(rlOrder); + Boolean execute = transactionTemplate.execute(e -> { + logger.info("=================【扫码绑定车辆】=================="); + RlOrder rlOrder = new RlOrder(); + rlOrder.setOrderNo(orderNo); + rlOrder.setSn(sn); + rlOrder.setStatus(ServiceConstants.ORDER_STATUS_IN_USE); + int i = orderMapper.updateRlOrderByOrderNo(rlOrder); + if(i > 0){ + /** 更新设备状态 */ + RlDevice rlDevice = new RlDevice(); + rlDevice.setSn(sn); + rlDevice.setStatus(ServiceConstants.VEHICLE_STATUS_TEMPORARILY_LOCK); + deviceService.updateDeviceBySn(rlDevice); + } + return Boolean.TRUE; + }); + if(!execute)throw new ServiceException("扫码绑定车辆失败"); + return 1; } /** @@ -340,23 +384,24 @@ public class RlOrderServiceImpl implements IRlOrderService * 3. */ @Override - public PrepayResponseVO relet(String orderNo, Long ruleId,Long userId) { - if(StrUtil.isBlank(orderNo)){ - throw new RuntimeException("订单号不能为空"); + public PrepayResponseVO relet(RlOrderQuery query) { + RlOrderVO order = orderMapper.selectRlOrderByOrderNo(query.getOrderNo()); + if(ObjectUtil.isNull(order)){ + throw new RuntimeException("订单["+query.getOrderNo()+"]不存在"); } - RlOrderVO order = orderMapper.selectRlOrderByOrderNo(orderNo); RlOrderQuery orderQuery = new RlOrderQuery(); BeanUtils.copyBeanProp(orderQuery,order); /** 原订单已经到期 */ Date nowDate = DateUtils.getNowDate(); if (order.getExpiryTime().before(nowDate)) { - throw new RuntimeException("订单已过期,请重新下单"); + /** */ +// throw new RuntimeException("订单已过期,请重新下单"); } - orderQuery.setOriginalOrderNo(orderNo); - orderQuery.setRuleId(ruleId); + orderQuery.setOriginalOrderNo(query.getOrderNo()); + orderQuery.setRuleId(query.getRuleId()); orderQuery.setPickupTime(order.getExpiryTime()); String newOrderNo = IdUtils.getOrderNo("xz"); - PrepayResponseVO responseVO = getPrepayResponseVO(orderQuery,newOrderNo,ServiceConstants.ORDER_TYPE_RELET,userId); + PrepayResponseVO responseVO = getPrepayResponseVO(orderQuery,newOrderNo,ServiceConstants.ORDER_TYPE_RELET,SecurityUtils.getUserId()); return responseVO; } @@ -434,15 +479,17 @@ public class RlOrderServiceImpl implements IRlOrderService public PriceVO calculatePrice(RlOrderQuery order) { PriceVO priceVO = new PriceVO(); BigDecimal totalFee = BigDecimal.ZERO; - // 押金 - BigDecimal deposit = deposit(order.getModelId(), priceVO); - totalFee = totalFee.add(deposit); + if(order.getType().equals(ServiceConstants.ORDER_TYPE_LEASE)){ + // 押金 + BigDecimal deposit = deposit(order.getModelId(), priceVO); + totalFee = totalFee.add(deposit); + // 配送费 + BigDecimal deliveryFee = deliveryFee(order.getAgentId(), priceVO); + totalFee = totalFee.add(deliveryFee); + } // 租金 BigDecimal rentFee = rentFee(order, priceVO); totalFee = totalFee.add(rentFee); - // 配送费 - BigDecimal deliveryFee = deliveryFee(order.getAgentId(), priceVO); - totalFee = totalFee.add(deliveryFee); priceVO.setTotalFee(totalFee); return priceVO; } @@ -477,6 +524,32 @@ public class RlOrderServiceImpl implements IRlOrderService return storeList; } + /** + * 根据sn查询正在进行中的订单 + */ + @Override + public List getInProgressOrder(String sn) { + Long userId = SecurityUtils.getUserId(); + List orders = orderMapper.getInProgressOrder(sn,userId); + return orders; + } + + @Override + public void validate(RlOrderQuery orderQuery) { + if(StrUtil.isBlank(orderQuery.getOrderNo())){ + throw new ServiceException("订单号不能为空"); + } + if(StrUtil.isBlank(orderQuery.getType())){ + throw new ServiceException("类型不能为空"); + } + if(orderQuery.getRuleId() == null || orderQuery.getRuleId() <= 0){ + throw new ServiceException("计费规则id不能为空"); + } + if(orderQuery.getNum() == null || orderQuery.getNum() <= 0){ + throw new ServiceException("数量不能为空或小于0"); + } + } + private BigDecimal deposit(Long modelId, PriceVO priceVO) { RlModelVO rlModelVO = modelService.selectEModelByModelId(modelId); if(rlModelVO == null){ diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserExtServiceImpl.java b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserExtServiceImpl.java new file mode 100644 index 0000000..f3f5751 --- /dev/null +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserExtServiceImpl.java @@ -0,0 +1,94 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; + +import com.ruoyi.system.domain.userExt.RlUserExt; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.mapper.RlUserExtMapper; +import com.ruoyi.system.service.IRlUserExtService; + +/** + * 用户扩展Service业务层处理 + * + * @author qzz + * @date 2024-10-07 + */ +@Service +public class RlUserExtServiceImpl implements IRlUserExtService +{ + @Autowired + private RlUserExtMapper rlUserExtMapper; + + /** + * 查询用户扩展 + * + * @param extId 用户扩展主键 + * @return 用户扩展 + */ + @Override + public RlUserExt selectRlUserExtByExtId(Long extId) + { + return rlUserExtMapper.selectRlUserExtByExtId(extId); + } + + /** + * 查询用户扩展列表 + * + * @param rlUserExt 用户扩展 + * @return 用户扩展 + */ + @Override + public List selectRlUserExtList(RlUserExt rlUserExt) + { + return rlUserExtMapper.selectRlUserExtList(rlUserExt); + } + + /** + * 新增用户扩展 + * + * @param rlUserExt 用户扩展 + * @return 结果 + */ + @Override + public int insertRlUserExt(RlUserExt rlUserExt) + { + return rlUserExtMapper.insertRlUserExt(rlUserExt); + } + + /** + * 修改用户扩展 + * + * @param rlUserExt 用户扩展 + * @return 结果 + */ + @Override + public int updateRlUserExt(RlUserExt rlUserExt) + { + return rlUserExtMapper.updateRlUserExt(rlUserExt); + } + + /** + * 批量删除用户扩展 + * + * @param extIds 需要删除的用户扩展主键 + * @return 结果 + */ + @Override + public int deleteRlUserExtByExtIds(Long[] extIds) + { + return rlUserExtMapper.deleteRlUserExtByExtIds(extIds); + } + + /** + * 删除用户扩展信息 + * + * @param extId 用户扩展主键 + * @return 结果 + */ + @Override + public int deleteRlUserExtByExtId(Long extId) + { + return rlUserExtMapper.deleteRlUserExtByExtId(extId); + } +} diff --git a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserServiceImpl.java b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserServiceImpl.java index 10f291e..4ba6e7d 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserServiceImpl.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/service/impl/RlUserServiceImpl.java @@ -12,6 +12,7 @@ import com.ruoyi.system.domain.SysUserPost; import com.ruoyi.system.domain.SysUserRole; import com.ruoyi.system.domain.changeBalance.RlChangeBalance; import com.ruoyi.system.domain.query.AuthenticationQuery; +import com.ruoyi.system.domain.vo.RlUserQuery; import com.ruoyi.system.mapper.RlUserMapper; import com.ruoyi.system.mapper.SysUserPostMapper; import com.ruoyi.system.mapper.SysUserRoleMapper; @@ -85,25 +86,10 @@ public class RlUserServiceImpl implements IRlUserService{ * @return 用户信息集合信息 */ @Override - public List selectUserList(RlUser user) + public List selectUserList(RlUserQuery user) { /** 获取设备绑定数量*/ - List users = rlUserMapper.selectUserList(user); -// for(EUser u:users){ -// EtOrder etOrder = new EtOrder(); -// etOrder.setUserId(u.getUserId()); -// EtOrder order = etOrderService.latestOrder(etOrder); -// if(ObjectUtil.isNotNull(order)){ -// EtOrderDto etOrderVo = new EtOrderDto(); -// BeanUtils.copyBeanProp(etOrderVo,order); -// u.setLatestOrder(etOrderVo); -// } -// if(ObjectUtil.isNotNull(u.getRlUserId())){ -// Long RlUserId = u.getRlUserId(); -// RlUser RlUser = userMapper.selectUserById(RlUserId); -// u.setRlUser(RlUser); -// } -// } + List users = rlUserMapper.selectUserList(user); return users; } diff --git a/ridelease-system/src/main/java/com/ruoyi/system/task/RlTask.java b/ridelease-system/src/main/java/com/ruoyi/system/task/RlTask.java index 9ce6099..1d9453f 100644 --- a/ridelease-system/src/main/java/com/ruoyi/system/task/RlTask.java +++ b/ridelease-system/src/main/java/com/ruoyi/system/task/RlTask.java @@ -66,4 +66,25 @@ public class RlTask { log.info("-------------------【定时任务】处理过期订单---结束----------------"); } + /** + * 超时过期时间的订单增加一个超时标记 + * 处理过期订单 + */ + public void expiredMarkers(){ + log.info("-------------------【定时任务】超时标记---开始----------------"); + RlOrderQuery rlOrderQuery = new RlOrderQuery(); + rlOrderQuery.setStatus(ServiceConstants.ORDER_STATUS_IN_USE); + List rlOrderVOS = orderService.selectAllRlOrderList(rlOrderQuery); + for (RlOrderVO orderVO:rlOrderVOS) { + // 判断订单是否已过期,如果过期了,则标记为已过期 + if (orderVO.getExpiryTime().before(new Date())) { + RlOrder rlOrder = new RlOrder(); + rlOrder.setOrderId(orderVO.getOrderId()); + rlOrder.setIsOverdue(true); + orderService.updateRlOrder(rlOrder); + } + } + log.info("-------------------【定时任务】超时标记---结束----------------"); + } + } diff --git a/ridelease-system/src/main/resources/mapper/system/EtCallbackLogMapper.xml b/ridelease-system/src/main/resources/mapper/system/EtCallbackLogMapper.xml index df033fd..ef5d271 100644 --- a/ridelease-system/src/main/resources/mapper/system/EtCallbackLogMapper.xml +++ b/ridelease-system/src/main/resources/mapper/system/EtCallbackLogMapper.xml @@ -3,7 +3,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -13,25 +13,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, body2, body, create_time, type from et_callback_log + select id, body2, body, create_time, type from rl_callback_log - + - + - insert into et_callback_log + insert into rl_callback_log id, body2, @@ -49,7 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - update et_callback_log + update rl_callback_log body2 = #{body2}, body = #{body}, @@ -60,13 +60,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - delete from et_callback_log where id = #{id} + delete from rl_callback_log where id = #{id} - delete from et_callback_log where id in + delete from rl_callback_log where id in #{id} - \ No newline at end of file + diff --git a/ridelease-system/src/main/resources/mapper/system/RlCommandLogMapper.xml b/ridelease-system/src/main/resources/mapper/system/RlCommandLogMapper.xml index 83fbbe5..df8858e 100644 --- a/ridelease-system/src/main/resources/mapper/system/RlCommandLogMapper.xml +++ b/ridelease-system/src/main/resources/mapper/system/RlCommandLogMapper.xml @@ -21,7 +21,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, url, command, type, mac, sn, result, longitude, latitude, call_status, create_by, create_time, order_no from e_command_log + select id, url, command, type, mac, sn, result, longitude, latitude, call_status, create_by, create_time, order_no from rl_command_log - insert into e_command_log + insert into rl_command_log url, command, @@ -77,7 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - update e_command_log + update rl_command_log url = #{url}, command = #{command}, @@ -94,11 +94,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - delete from e_command_log where id = #{id} + delete from rl_command_log where id = #{id} - delete from e_command_log where id in + delete from rl_command_log where id in #{id} diff --git a/ridelease-system/src/main/resources/mapper/system/RlOnlineLogMapper.xml b/ridelease-system/src/main/resources/mapper/system/RlOnlineLogMapper.xml index 09b3ac3..1eea389 100644 --- a/ridelease-system/src/main/resources/mapper/system/RlOnlineLogMapper.xml +++ b/ridelease-system/src/main/resources/mapper/system/RlOnlineLogMapper.xml @@ -15,7 +15,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, mac, sn, online_status, longitude, latitude, create_time from et_online_log + select id, mac, sn, online_status, longitude, latitude, create_time from rl_online_log - insert into et_online_log + insert into rl_online_log mac, sn, @@ -53,7 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - update et_online_log + update rl_online_log mac = #{mac}, sn = #{sn}, @@ -66,11 +66,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - delete from et_online_log where id = #{id} + delete from rl_online_log where id = #{id} - delete from et_online_log where id in + delete from rl_online_log where id in #{id} diff --git a/ridelease-system/src/main/resources/mapper/system/RlOrderMapper.xml b/ridelease-system/src/main/resources/mapper/system/RlOrderMapper.xml index e607d5e..881767d 100644 --- a/ridelease-system/src/main/resources/mapper/system/RlOrderMapper.xml +++ b/ridelease-system/src/main/resources/mapper/system/RlOrderMapper.xml @@ -7,11 +7,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select order_id, order_no, out_trade_no, user_id, user_name, phone, rule_id, device_mac, sn, pay_time, pay_type, paid, type, total_fee, pay_fee, deposit, overdue_fee, dispatch_fee,delivery_fee, + select order_id, order_no, out_trade_no, user_id, user_name, real_name, phone, rule_id, device_mac, sn, pay_time, pay_type, paid, type, total_fee, pay_fee, deposit, overdue_fee, dispatch_fee,delivery_fee, lease_fee, mark, duration, status, create_time, return_time, deposit_deduction, deposit_order_no, deduction_amount, used_sn, change_reason, auto_refund_deposit, rental_unit, handling_charge, platform_service_fee, operator_dividend, pay_channel, delivery_method, pickup_time, agent_id, store_id, merchant_id, pickup_city, pickup_loc, pickup_lon, pickup_lat, model_id, expiry_time, original_order_no, num, price, `explain`, - instructions, out_unit, out_price,return_type,return_method,address,auto_cancel_time,cost from rl_order + instructions, out_unit, out_price,return_type,return_method,address,auto_cancel_time,cost, is_overdue from rl_order @@ -21,6 +21,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" o.out_trade_no, o.user_id, o.user_name, + o.real_name, o.phone, o.rule_id, o.device_mac, @@ -70,7 +71,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" o.out_unit, o.out_price, u.user_name as userName, - u.real_name as realName, s.name as storeName, s.address as storeAddress, m.model, @@ -82,6 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" o.auto_cancel_time, o.merchant_id, o.cost, + o.is_overdue, CONCAT( CASE WHEN r.rental_unit = 'hours' THEN '时租' @@ -119,6 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and o.out_trade_no = #{outTradeNo} and o.user_id = #{userId} and u.user_name like concat('%', #{userName}, '%') + and o.real_name like concat('%', #{realName}, '%') and u.phone like concat('%', #{phone}, '%') and o.rule_id = #{ruleId} and o.device_mac = #{deviceMac} @@ -163,6 +165,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and date_format(create_time,'%Y%m%d') <= date_format(#{endTime},'%Y%m%d') and u.phonenumber like concat('%', #{phone}, '%') + + AND o.status IN + + #{item} + + @@ -173,6 +181,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and out_trade_no = #{outTradeNo} and user_id = #{userId} and u.user_name like concat('%', #{userName}, '%') + and o.real_name like concat('%', #{realName}, '%') and u.phone like concat('%', #{phone}, '%') and status = #{status} and paid = #{paid} @@ -193,6 +202,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where o.out_trade_no = #{outTradeNo} + + insert into rl_order @@ -200,6 +214,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" out_trade_no, user_id, user_name, + real_name, phone, rule_id, device_mac, @@ -236,6 +251,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pickup_time, agent_id, store_id, + merchant_id, pickup_city, pickup_loc, pickup_lon, @@ -259,6 +275,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{outTradeNo}, #{userId}, #{userName}, + #{realName}, #{phone}, #{ruleId}, #{deviceMac}, @@ -295,6 +312,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{pickupTime}, #{agentId}, #{storeId}, + #{merchantId}, #{pickupCity}, #{pickupLoc}, #{pickupLon}, @@ -322,6 +340,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" out_trade_no = #{outTradeNo}, user_id = #{userId}, user_name = #{userName}, + real_name = #{realName}, phone = #{phone}, rule_id = #{ruleId}, device_mac = #{deviceMac}, @@ -358,6 +377,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pickup_time = #{pickupTime}, agent_id = #{agentId}, store_id = #{storeId}, + merchant_id = #{merchantId}, pickup_city = #{pickupCity}, pickup_loc = #{pickupLoc}, pickup_lon = #{pickupLon}, @@ -374,7 +394,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" return_method = #{returnMethod}, address = #{address}, auto_cancel_time = #{autoCancelTime}, - + is_overdue = #{isOverdue}, where order_id = #{orderId} @@ -386,6 +406,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" out_trade_no = #{outTradeNo}, user_id = #{userId}, user_name = #{userName}, + real_name = #{realName}, phone = #{phone}, rule_id = #{ruleId}, device_mac = #{deviceMac}, @@ -422,6 +443,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pickup_time = #{pickupTime}, agent_id = #{agentId}, store_id = #{storeId}, + merchant_id = #{merchantId}, pickup_city = #{pickupCity}, pickup_loc = #{pickupLoc}, pickup_lon = #{pickupLon}, diff --git a/ridelease-system/src/main/resources/mapper/system/RlUserExtMapper.xml b/ridelease-system/src/main/resources/mapper/system/RlUserExtMapper.xml new file mode 100644 index 0000000..e43ecfa --- /dev/null +++ b/ridelease-system/src/main/resources/mapper/system/RlUserExtMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + select ext_id, user_id, balance, dividend_proportion, cooperation_time, dividend_status from rl_user_ext + + + + + + + + insert into rl_user_ext + + user_id, + balance, + dividend_proportion, + cooperation_time, + dividend_status, + + + #{userId}, + #{balance}, + #{dividendProportion}, + #{cooperationTime}, + #{dividendStatus}, + + + + + update rl_user_ext + + user_id = #{userId}, + balance = #{balance}, + dividend_proportion = #{dividendProportion}, + cooperation_time = #{cooperationTime}, + dividend_status = #{dividendStatus}, + + where user_id = #{userId} + + + + delete from rl_user_ext where ext_id = #{extId} + + + + delete from rl_user_ext where ext_id in + + #{extId} + + + diff --git a/ridelease-system/src/main/resources/mapper/system/RlUserMapper.xml b/ridelease-system/src/main/resources/mapper/system/RlUserMapper.xml index 22ec2a3..61cbe89 100644 --- a/ridelease-system/src/main/resources/mapper/system/RlUserMapper.xml +++ b/ridelease-system/src/main/resources/mapper/system/RlUserMapper.xml @@ -7,16 +7,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, + select u.user_id, u.user_name, u.real_name, u.id_card, u.nick_name, u.email, u.avatar,u.user_type, u.phonenumber, u.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.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.wxopenid,u.is_authentication, + ex.balance,ex.dividend_proportion dividendProportion,ex.cooperation_time cooperationTime,ex.dividend_status dividendStatus from rl_user u + left join rl_user_ext ex on u.user_id = ex.user_id @@ -71,7 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -79,7 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -103,7 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"