diff --git a/electripper-admin/src/main/resources/application.yml b/electripper-admin/src/main/resources/application.yml index 146cc56..bf103fa 100644 --- a/electripper-admin/src/main/resources/application.yml +++ b/electripper-admin/src/main/resources/application.yml @@ -141,8 +141,13 @@ aliyun: accessKeyId: LTAI5tS7bUhRvjcTy4yJkagK accessKeySecret: eQJsruUAvFfJblHZJ50QyiALCSZeRK signName: 创享电动车 - # 验证码模版id + # 验证码模版id 您名下有一笔租车订单已归还,订单金额:"+ amount +"元。 templateCode: SMS_470225045 + # 您有一笔订单:${orderNo},用户已付款,可在小程序管理端查看。 + templateCode2: SMS_470490072 + templateCode3: SMS_470490072 + # 提现申请时,发送的手机号 13376970966 + phone: 18650502300 # 七牛云配置 qiniu: # 七牛云key diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java index 70126c9..b8517cc 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java +++ b/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java @@ -639,4 +639,34 @@ public class ServiceConstants { public static final String FLOW_STATUS_COMPLETE = "8"; /**----------------------------资金流水状态end----------------------------*/ + /**----------------------------资金流水状态start----------------------------*/ + /** 短信类型:1-还车审核通知;2-用户付款通知;3-提现申请通知 */ + /** + * 1-还车审核通知 + */ + public static final String MSG_TYPE_VEHICLE_RETURN_AUDIT_NOTIFY = "1"; + /** + * 2-用户付款通知 + */ + public static final String MSG_TYPE_USER_PAYMENT_NOTIFY = "2"; + + /** + * 3-提现申请通知 + */ + public static final String MSG_TYPE_WITHDRAWAL_NOTIFY = "3"; + /**----------------------------资金流水状态end----------------------------*/ + + /**----------------------------提现手续费类型start----------------------------*/ + /** 提现手续费类型:1-按比例;2-按每笔 */ + /** + * 1-按比例 + */ + public static final String HANDLING_CHARGE_TYPE_PERCENT = "1"; + /** + * 2-按每笔 + */ + public static final String HANDLING_CHARGE_TYPE_PER_STROKE = "2"; + + /**----------------------------提现手续费类型end----------------------------*/ + } diff --git a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java index 51f8268..6660ee7 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java +++ b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java @@ -115,6 +115,16 @@ public class SysDept extends BaseEntity /** 区域名称 */ private String areaName; + public String handlingChargeType; + + public String getHandlingChargeType() { + return handlingChargeType; + } + + public void setHandlingChargeType(String handlingChargeType) { + this.handlingChargeType = handlingChargeType; + } + public String getAreaName() { return areaName; } @@ -320,7 +330,7 @@ public class SysDept extends BaseEntity this.deptName = deptName; } - @NotNull(message = "显示顺序不能为空") +// @NotNull(message = "显示顺序不能为空") public Integer getOrderNum() { return orderNum; diff --git a/electripper-system/src/main/java/com/ruoyi/system/domain/EtMsgLog.java b/electripper-system/src/main/java/com/ruoyi/system/domain/EtMsgLog.java index 00404cb..feb076d 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/domain/EtMsgLog.java +++ b/electripper-system/src/main/java/com/ruoyi/system/domain/EtMsgLog.java @@ -18,7 +18,7 @@ public class EtMsgLog extends BaseEntity /** 主键 */ private Long id; - /** 短信类型 */ + /** 短信类型:1-还车审核通知;2-用户付款通知;3-提现申请通知 */ @Excel(name = "短信类型") private String type; 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 182baa2..aacc0f3 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 @@ -136,6 +136,10 @@ public class CallbackServiceImpl implements CallbackService { @Value("${aliyun.templateCode}") private String templateCode; + @Value("${aliyun.templateCode2}") + private String templateCode2; + + @Resource private EtMsgLogMapper etMsgLogMapper; @@ -213,6 +217,10 @@ public class CallbackServiceImpl implements CallbackService { // 退还押金处理 refundDeposit(area.getDeposit(), order, asUser); logger.info("=================【微信支付回调】33333333=================="); + // 用户付款通知 + if("1".equals(area.getMsgSwitch())){ + asynchronousMsg2(order); + } } asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//还车后车辆正常运营 asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); @@ -313,7 +321,7 @@ public class CallbackServiceImpl implements CallbackService { EtMsgLog etMsgLog = new EtMsgLog(); etMsgLog.setPhone(phone); etMsgLog.setContent("您名下有一笔租车订单已归还,订单金额:"+ amount +"元。"); - etMsgLog.setType("1"); + etMsgLog.setType(ServiceConstants.MSG_TYPE_VEHICLE_RETURN_AUDIT_NOTIFY); etMsgLog.setSignName(signName); etMsgLog.setTemplateCode(templateCode); int i = etMsgLogMapper.insertEtMsgLog(etMsgLog); @@ -325,6 +333,54 @@ public class CallbackServiceImpl implements CallbackService { }, 0 , TimeUnit.HOURS); } + private void asynchronousMsg2(EtOrder order) { + scheduledExecutorService.schedule(() -> { + /** 发送一个短信给运营商*/ + 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()); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("orderNo", order.getOrderNo()); + + 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)); + //记录资金流水 + order.setPayFee(new BigDecimal(0.1)); + callbackService.capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_DISBURSE, + ServiceConstants.ORDER_TYPE_MSG,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_YE); + + // 短信日志 + EtMsgLog etMsgLog = new EtMsgLog(); + etMsgLog.setPhone(phone); + etMsgLog.setContent("您有一笔订单:"+order.getOrderNo()+",用户已付款,可在小程序管理端查看。"); + etMsgLog.setType(ServiceConstants.MSG_TYPE_USER_PAYMENT_NOTIFY); + etMsgLog.setSignName(signName); + etMsgLog.setTemplateCode(templateCode); + int i = etMsgLogMapper.insertEtMsgLog(etMsgLog); + if(i>0){ + logger.info("【用户付款通知】短信日志记录成功"); + }else{ + logger.info("【用户付款通知】短信日志记录失败"); + } + }, 0 , TimeUnit.HOURS); + } + private void asynchronousSaveCallbackLog(EtCallbackLog etCallbackLog) { //开异步线程保存回调参数 scheduledExecutorService.schedule(() -> { @@ -739,12 +795,19 @@ public class CallbackServiceImpl implements CallbackService { capitalFlow.setOwnerId(sysDept.getDeptId()); capitalFlow.setOwner(sysDept.getDeptName()); + String handlingChargeType = sysDept.getHandlingChargeType(); String handlingCharge1 = sysDept.getHandlingCharge(); + BigDecimal handlingCharge; logger.info("【保存资金流水记录】 获取到配置手续费==============handlingCharge=====================:"+handlingCharge1); - BigDecimal bigDecimal = new BigDecimal(handlingCharge1).divide(new BigDecimal(1000), 6, BigDecimal.ROUND_HALF_UP); - logger.info("【保存资金流水记录】 转换后手续费==============bigDecimal=====================:"+bigDecimal); - BigDecimal handlingCharge = bigDecimal.multiply(order.getPayFee()).setScale(2, BigDecimal.ROUND_HALF_UP); - logger.info("【保存资金流水记录】 计算出的手续费==============handlingCharge=====================:"+handlingCharge); + if(handlingChargeType.equals(ServiceConstants.HANDLING_CHARGE_TYPE_PERCENT)){ + BigDecimal bigDecimal = new BigDecimal(handlingCharge1).divide(new BigDecimal(1000), 6, BigDecimal.ROUND_HALF_UP); + logger.info("【保存资金流水记录】 按千分比--转换后手续费==============bigDecimal=====================:"+bigDecimal); + handlingCharge = bigDecimal.multiply(order.getPayFee()).setScale(2, BigDecimal.ROUND_HALF_UP); + logger.info("【保存资金流水记录】 按千分比--计算出的手续费==============handlingCharge=====================:"+handlingCharge); + }else{ + handlingCharge = new BigDecimal(handlingCharge1); + logger.info("【保存资金流水记录】 按每笔--计算出的手续费==============handlingCharge=====================:"+handlingCharge); + } BigDecimal serviceFeeScale = new BigDecimal(sysDept.getPlatformServiceFee()).divide(new BigDecimal(100), 6, BigDecimal.ROUND_HALF_UP); BigDecimal platformServiceFee = serviceFeeScale.multiply(order.getPayFee()); logger.info("【保存资金流水记录】 计算出的平台服务费==============platformServiceFee=====================:"+platformServiceFee); diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java index 7f047a9..16883a2 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java @@ -1490,7 +1490,7 @@ public class EtOrderServiceImpl implements IEtOrderService etRefund.setRefundNo(outRefundNo); etRefund.setType(type); if(type.equals(ServiceConstants.REFUND_TYPE_DEPOSIT)){ - etRefund.setItemDesc("押金自动退款"); + etRefund.setItemDesc("押金退款"); }else{ StringBuilder itemDesc = new StringBuilder(); if(ObjectUtil.isNotNull(appointmentFee) && !appointmentFee.equals(BigDecimal.ZERO)){ 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 4eb81c9..b36f2b4 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 @@ -3,6 +3,9 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; 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.annotation.DataScope; import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.constant.UserConstants; @@ -13,15 +16,10 @@ import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.*; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.uuid.IdUtils; -import com.ruoyi.system.domain.EtAreaDept; -import com.ruoyi.system.domain.EtCapitalFlow; -import com.ruoyi.system.domain.EtOrder; -import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.domain.*; import com.ruoyi.system.mapper.*; import com.ruoyi.system.service.*; import com.wechat.pay.java.service.profitsharing.model.AddReceiverResponse; @@ -29,6 +27,7 @@ import com.wechat.pay.java.service.profitsharing.model.DeleteReceiverResponse; import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,6 +36,8 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -81,6 +82,30 @@ public class SysDeptServiceImpl implements ISysDeptService @Resource private EtCapitalFlowMapper etCapitalFlowMapper; + @Resource + private AsUserMapper asUserMapper; + + @Autowired + private ScheduledExecutorService scheduledExecutorService; + + @Value("${aliyun.accessKeyId}") + private String accessKeyId; + + @Value("${aliyun.accessKeySecret}") + private String accessKeySecret; + + @Value("${aliyun.signName}") + private String signName; + + @Value("${aliyun.templateCode}") + private String templateCode; + + @Value("${aliyun.phone}") + private String phone; + + @Resource + private EtMsgLogMapper etMsgLogMapper; + /** * 查询部门管理数据 * @@ -500,10 +525,48 @@ public class SysDeptServiceImpl implements ISysDeptService throw new ServiceException("【提现】提现失败,该运营商id:"+sysDept.getDeptId()+"下未找到该运营区"); } order.setAreaId(longs.get(0)); + // 发短信 + asynchronousMsg(sysDept.getDeptName()); //记录资金流水 return callbackService.capitalFlowRecords2(order,ServiceConstants.FLOW_TYPE_DISBURSE,ServiceConstants.ORDER_TYPE_WITHDRAW,ServiceConstants.OWNER_TYPE_OPERATOR,sysDept); } + private void asynchronousMsg(String deptName) { + scheduledExecutorService.schedule(() -> { + /** 提现申请发送一个短信给丁建帮*/ + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", deptName); + + SendSmsVo sendSmsVo = new SendSmsVo(); + sendSmsVo.setMobile(phone); + sendSmsVo.setTemplateCode(templateCode); + sendSmsVo.setParam(jsonObject.toJSONString()); + sendSmsVo.setSignName(signName); + SendSmsResponse response = null; + log.info("【提现申请】向阿里云发送短信,请求,----------【{}】", JSON.toJSONString(sendSmsVo)); + try { + response = SendAliSmsUtil.sendVerifyCode(accessKeyId,accessKeySecret,sendSmsVo); + } catch (ClientException e) { + e.printStackTrace(); + } + log.info("【提现申请】发送阿里云短信成功,返回----------【{}】",JSON.toJSONString(response)); + + // 短信日志 + EtMsgLog etMsgLog = new EtMsgLog(); + etMsgLog.setPhone(phone); + etMsgLog.setContent("运营商【"+deptName+"】有一笔提现申请,请注意查收!"); + etMsgLog.setType("2"); + etMsgLog.setSignName(signName); + etMsgLog.setTemplateCode(templateCode); + int i = etMsgLogMapper.insertEtMsgLog(etMsgLog); + if(i>0){ + log.info("【提现申请】短信日志记录成功"); + }else{ + log.info("【提现申请】短信日志记录失败"); + } + }, 0 , TimeUnit.HOURS); + } + /** * 管理员提现失败 * 1. 生成一条相同的金额 diff --git a/electripper-system/src/main/resources/mapper/system/EtOrderMapper.xml b/electripper-system/src/main/resources/mapper/system/EtOrderMapper.xml index 9364be5..4175763 100644 --- a/electripper-system/src/main/resources/mapper/system/EtOrderMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/EtOrderMapper.xml @@ -445,10 +445,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and sn = #{sn} and area_id = #{areaId} - AND date_format(create_time,'%y%m%d') >= date_format(#{startDateStr},'%y%m%d') + AND date_format(pay_time,'%y%m%d') >= date_format(#{startDateStr},'%y%m%d') - AND date_format(create_time,'%y%m%d') <= date_format(#{endDateStr},'%y%m%d') + AND date_format(pay_time,'%y%m%d') <= date_format(#{endDateStr},'%y%m%d') AND status = 4 and type = 1 and paid = 1 diff --git a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml index 5b10a7c..c2f3154 100644 --- a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -33,6 +33,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -43,7 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag,d.platform_service_fee, d.handling_charge, d.is_profit_sharing, d.separate_account, d.domain, d.is_use_platform_app, d.appid, d.app_name, d.balance, d.app_secret, - d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url, d.app_user_id, + d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url, d.app_user_id, d.handling_charge_type, d.create_by, d.create_time from sys_dept d @@ -52,7 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" SELECT d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.platform_service_fee, d.handling_charge, d.is_profit_sharing, d.separate_account, d.domain, d.is_use_platform_app, d.appid, d.app_name, d.balance, d.app_secret, - d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path, d.merchant_serial_number, d.refund_notify_url, d.app_user_id, + d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path, d.merchant_serial_number, d.refund_notify_url, d.app_user_id,d.handling_charge_type, u.user_name AS userName, GROUP_CONCAT(oa.area_name SEPARATOR ' | ') AS areaName, d.create_by, d.create_time @@ -99,7 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select d.dept_id, d.parent_id, d.app_user_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status,d.platform_service_fee, d.handling_charge, d.is_profit_sharing,d.domain,d.is_use_platform_app, d.appid, d.app_name, d.balance, d.app_secret,d.balance,d.separate_account, - d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url,d.app_user_id, + d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url,d.app_user_id,d.handling_charge_type, (select dept_name from sys_dept where dept_id = d.parent_id) parent_name from sys_dept d where d.app_user_id = #{appUserId} @@ -169,6 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" merchant_serial_number, refund_notify_url, app_user_id, + handling_charge_type,, create_time )values( #{deptId}, @@ -184,6 +186,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{platformServiceFee}, #{handlingCharge}, #{isProfitSharing}, + #{separateAccount}, #{isUsePlatformApp}, #{domain}, #{appid}, @@ -196,6 +199,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{merchantSerialNumber}, #{refundNotifyUrl}, #{appUserId}, + #{handlingChargeType}, sysdate() ) @@ -228,6 +232,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" merchant_serial_number = #{merchantSerialNumber}, refund_notify_url = #{refundNotifyUrl}, app_user_id = #{appUserId}, + handling_charge_type = #{handlingChargeType}, update_time = sysdate() where dept_id = #{deptId}