This commit is contained in:
邱贞招 2024-07-23 21:43:37 +08:00
parent 5d87204bbe
commit 3ee987ce14
26 changed files with 399 additions and 95 deletions

View File

@ -1037,8 +1037,11 @@ public class AppVerifyController extends BaseController
logger.info("管理员提现请求:【{}】", JSON.toJSON(etWithdraw));
AsUser asUser = getLoginUser().getAsUser();
logger.info("【管理员提现】获取当前用户:【{}】", JSON.toJSON(asUser));
Long userId = asUser.getUserId();
int i = deptService.adminWithdraw(etWithdraw.getAmount(),userId);
SysUser sysUser = sysUserService.selectUserById(asUserMapper.selectUserById(asUser.getUserId()).getSysUserId());
logger.info("【管理员提现】获取当前系统用户:【{}】", JSON.toJSON(sysUser));
Long deptId = sysUser.getDeptId();
SysDept sysDept = deptService.selectDeptById(deptId);
int i = deptService.adminWithdraw(etWithdraw.getAmount(),sysDept,"1");
return toAjax(i);
}

View File

@ -138,6 +138,7 @@ public class ReceiveController {
String ver = null;
if(IotConstants.ONENET_VER.equals(jsonObject.get("ds_id")) && ObjectUtil.isNotNull(jsonObject.get("value"))){
ver = (String)jsonObject.get("value");
log.info("获取到版本号------------------------------------"+ver);
}
asynchronousUpdateOnlineStatus(asDevice,ver);
if(IotConstants.ONENET_LOCATION.equals(jsonObject.get("ds_id")) && ObjectUtil.isNotNull(jsonObject.get("value"))){
@ -231,7 +232,7 @@ public class ReceiveController {
}else{
//是否在禁行区20米范围内
boolean inPolygon = asDeviceService.isNoRidingAreaWithTolerance(device.getSn(), device.getAreaId(),20);
if (inPolygon) {
if (inPolygon && !isAdminUnlocking.equals("1")) {
log.info("距离禁行区20米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY2, "距离禁行区20米内",null,null);
}
@ -241,7 +242,7 @@ public class ReceiveController {
if(!isAreaZone){
//是否在30米范围内
boolean inPolygon = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), GeoUtils.fromWkt(area.getBoundary()), 60);
if(inPolygon){
if(inPolygon && !isAdminUnlocking.equals("1")){
//在20米范围内发报警
log.info("超出运营区30米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY3, "超出运营区30米内",null,null);

View File

@ -156,6 +156,17 @@ public class AsDeviceController extends BaseController
return toAjax(asDeviceService.oneClickWarehousing(deviceIds));
}
/**
* 更新设备
*/
@PreAuthorize("@ss.hasPermi('system:device:refresh')")
@Log(title = "更新设备", businessType = BusinessType.REFRESH)
@PostMapping("/refreshDevice/{deviceIds}")
public AjaxResult refreshDevice(@PathVariable Long[] deviceIds)
{
return toAjax(asDeviceService.refreshDevice(deviceIds));
}
/**
* 响铃寻车
*/

View File

@ -1,34 +1,25 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.entity.AsUser;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.EtWithdraw;
import com.ruoyi.system.service.IEtWithdrawService;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.EtCapitalFlow;
import com.ruoyi.system.service.IEtCapitalFlowService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.domain.entity.SysDept;
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.EtCapitalFlow;
import com.ruoyi.system.domain.EtWithdraw;
import com.ruoyi.system.service.IEtCapitalFlowService;
import com.ruoyi.system.service.ISysDeptService;
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
@ -122,13 +113,19 @@ public class EtCapitalFlowController extends BaseController
public AjaxResult add(@RequestBody EtWithdraw etWithdraw)
{
logger.info("管理员提现请求:【{}】", JSON.toJSON(etWithdraw));
Long deptId = getDeptId();
Long deptId = etWithdraw.getDeptId();
if(ObjectUtil.isNull(deptId)){
deptId = getDeptId();
}
SysDept sysDept = deptService.selectDeptById(deptId);
String method = etWithdraw.getMethod();
if(method.equals(ServiceConstants.WITHDRAW_METHOD_WX)){
if(ObjectUtil.isNull(sysDept.getAppUserId())){
throw new RuntimeException("运营商未绑定app用户,请联系管理员添加【绑定微信用户】");
}
}
logger.info("【管理员提现】获取当前部门:【{}】", JSON.toJSON(sysDept));
int i = deptService.adminWithdraw(etWithdraw.getAmount(),sysDept.getAppUserId());
int i = deptService.adminWithdraw(etWithdraw.getAmount(),sysDept,method);
return toAjax(i);
}

View File

@ -122,6 +122,18 @@ public class EtOperatingAreaController extends BaseController
return toAjax(etOperatingAreaService.updateEtOperatingArea(etOperatingArea));
}
/**
* 保存导览图
*/
@PreAuthorize("@ss.hasPermi('system:area:edit')")
@Log(title = "运营区", businessType = BusinessType.UPDATE)
@PutMapping("/guide")
public AjaxResult edit2(@RequestBody EtOperatingArea etOperatingArea)
{
return toAjax(etOperatingAreaService.updateEtOperatingArea2(etOperatingArea));
}
/**
* 删除运营区
*/

View File

@ -189,10 +189,12 @@ public class SysDeptController extends BaseController
* 查询运营商
*/
@GetMapping("/getDept")
public AjaxResult getDept()
public AjaxResult getDept(Long deptId)
{
if(ObjectUtil.isNull(deptId)) {
deptId = getDeptId();
}
AjaxResult ajax = AjaxResult.success();
Long deptId = getDeptId();
SysDept sysDept = deptService.selectDeptById(deptId);
ajax.put(AjaxResult.DATA_TAG, sysDept);
return ajax;

View File

@ -140,7 +140,7 @@ xss:
aliyun:
accessKeyId: LTAI5tS7bUhRvjcTy4yJkagK
accessKeySecret: eQJsruUAvFfJblHZJ50QyiALCSZeRK
signName: 绿小能
signName: 创享电动车
# 验证码模版id
templateCode: SMS_465344261
# 七牛云配置

View File

@ -40,6 +40,11 @@ public class ServiceConstants {
*/
public static final String ORDER_TYPE_WITHDRAW_FAIL = "6";
/**
* 订单类型: 7-车辆损坏
*/
public static final String ORDER_TYPE_VEHICLE_DAMAGE = "7";
/**----------------------------订单类型end----------------------------*/
/**----------------------------支付场景start----------------------------*/
/** 支付场景: 1-骑行支付,2-取消预约支付,3-套餐支付,4-押金支付 */
@ -82,7 +87,7 @@ public class ServiceConstants {
public static final String ORDER_STATUS_RIDING = "2";
/**
* 订单状态:3-骑行结束
* 订单状态:3-骑行结束(待支付)
*/
public static final String ORDER_STATUS_RIDING_END = "3";
@ -556,6 +561,19 @@ public class ServiceConstants {
*/
public static final String WITHDRAW_STATUS_REJECT = "2";
/**----------------------------提现状态end----------------------------*/
/**----------------------------提现方式start----------------------------*/
/** 提现方式1-线下转账2-微信支付 */
/**
* 提现状态:1-线下转账
*/
public static final String WITHDRAW_METHOD_OFFLINE_TRANSFER = "1";
/**
* 提现状态:2-微信支付
*/
public static final String WITHDRAW_METHOD_WX = "2";
/**----------------------------提现方式end----------------------------*/
/**----------------------------是否押金抵扣start----------------------------*/
/** 是否押金抵扣0-否1-是 */

View File

@ -106,7 +106,7 @@ public class SysDept extends BaseEntity
/** 退款回调地址 */
private String refundNotifyUrl;
/** app用户id,用于提现 */
/** app用户id,用于提现,发送短信 */
private Long appUserId;
/** 用户名 */

View File

@ -130,6 +130,11 @@ public enum BusinessType
*/
ONLINE,
/**
* 更新设备
*/
REFRESH,
/**
* 车辆下线
*/

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
@ -84,4 +85,8 @@ public class EtCapitalFlow extends BaseEntity
@Excel(name = "状态: 0-待结算2-驳回,8-已完成")
private String status;
/** 业务类型列表 */
@TableField(exist = false)
private String[] typeList;
}

View File

@ -214,4 +214,13 @@ public class EtOperatingArea extends BaseEntityPlus implements Serializable
/** 还车是否拍照审核0-否1-是 */
private String returnVerify;
/** 右上角坐标*/
private String upperRight;
/** 左下角坐标*/
private String lowerLeft;
/** 图片路径*/
private String guideMap;
}

View File

@ -56,4 +56,8 @@ public class EtWithdraw extends BaseEntity
@Excel(name = "驳回原因")
private String rejectReason;
/** 提现方式 */
@Excel(name = "提现方式")
private String method;
}

View File

@ -33,9 +33,10 @@ public interface CallbackService {
* @param busType 业务类型
* @param ownerType 所属人类型
* @param user 合伙人对象
* @param payType 支付方式
* @return void
*/
public void capitalFlowRecords(EtOrder order, String type, String busType, String ownerType, SysUser user);
public void capitalFlowRecords(EtOrder order, String type, String busType, String ownerType, SysUser user, String payType);
/**
* 新增资金流水记录

View File

@ -132,6 +132,14 @@ public interface IAsDeviceService extends IService<AsDevice>
*/
int oneClickWarehousing(Long[] deviceIds);
/**
* 更新设备
*
* @param deviceIds 需要更新设备的设备主键集合
* @return 结果
*/
int refreshDevice(Long[] deviceIds);
/**
* 删除设备信息
*

View File

@ -55,6 +55,14 @@ public interface IEtOperatingAreaService extends IService<EtOperatingArea>
*/
public int updateEtOperatingArea(EtOperatingArea etOperatingArea);
/**
* 修改运营区
*
* @param etOperatingArea 运营区
* @return 结果
*/
public int updateEtOperatingArea2(EtOperatingArea etOperatingArea);
/**
* 批量删除运营区
*

View File

@ -150,7 +150,7 @@ public interface ISysDeptService
/**
* 管理员提现
*/
int adminWithdraw(BigDecimal amount,Long appUserId);
int adminWithdraw(BigDecimal amount,SysDept dept,String method);
/**
* 绑定app用户

View File

@ -8,10 +8,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.constant.*;
import com.ruoyi.common.core.domain.entity.AsUser;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.CommonUtil;
@ -28,6 +26,7 @@ import com.ruoyi.system.mapper.AsDeviceMapper;
import com.ruoyi.system.mapper.EtCommandLogMapper;
import com.ruoyi.system.mapper.EtOrderMapper;
import com.ruoyi.system.service.*;
import com.wechat.pay.java.service.refund.model.Refund;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@ -42,9 +41,7 @@ import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -103,6 +100,15 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
@Autowired
private IEtOnlineLogService etOnlineLogService;
@Autowired
private IEtRefundService etRefundService;
@Resource
private IAsUserService asUserService;
@Autowired
private CallbackService callbackService;
@Value(value = "${iot.iotUrl}")
private String iotUrl;
@ -468,6 +474,34 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
return asDeviceMapper.oneClickOffline(deviceIds);
}
/**
* 更新设备
* 1. 发送更新版本
* 2. 判断是否在线
*
* @param deviceIds 需要更新设备的设备主键集合
* @return 结果
*/
@Override
public int refreshDevice(Long[] deviceIds)
{
for (Long deviceId:deviceIds) {
AsDevice device = asDeviceMapper.selectAsDeviceByDeviceId(deviceId);
//设备是否在线
if(isOnline(device.getSn())){
log.info("设备【"+device.getSn()+"】在线");
}else{
log.info("设备【"+device.getSn()+"】不在线");
}
if(updateVersion(device.getSn())){
log.info("设备【"+device.getSn()+"】更新版本成功");
}else{
log.info("设备【"+device.getSn()+"】更新版本失败");
}
}
return 1;
}
/**
* 删除设备信息
*
@ -739,7 +773,9 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/** 2.发送命令*/
sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_20,"管理员开锁",null,userName);
asDevice.setIsAdminUnlocking("1");
if(!asDevice.getStatus().equals(ServiceConstants.VEHICLE_STATUS_NOT_LISTING)){
asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_SCHEDULING);
}
asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN);
int i = asDeviceMapper.updateAsDevice(asDevice);
if(i>0){
@ -764,7 +800,9 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/** 2.发送命令*/
sendCommand(mac, token,IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_20,"管理员开锁",null,userName);
asDevice.setIsAdminUnlocking("1");
if(!asDevice.getStatus().equals(ServiceConstants.VEHICLE_STATUS_NOT_LISTING)){
asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_SCHEDULING);
}
asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN);
int i = asDeviceMapper.updateAsDevice(asDevice);
if(i>0){
@ -1194,8 +1232,10 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
if(ObjectUtil.isNotNull(etOrder)){
asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_TEMPORARILY_LOCK);
}else{
if(!asDevice.getStatus().equals(ServiceConstants.VEHICLE_STATUS_NOT_LISTING)){
asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);
}
}
asDevice.setIsAdminUnlocking("0");
int device = asDeviceMapper.updateAsDevice(asDevice);
if(device==0){
@ -1219,7 +1259,9 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
/** 2.发送命令*/
sendCommand(asDevice.getMac(), Token.getToken(),IotConstants.COMMAND_CLOSE+IotConstants.COMMAND_FREQUENCY_3600,"管理员锁车",null,userName);
asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
if(!asDevice.getStatus().equals(ServiceConstants.VEHICLE_STATUS_NOT_LISTING)){
asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);
}
asDevice.setIsAdminUnlocking("0");
int device = asDeviceMapper.updateAsDevice(asDevice);
if(device==0){
@ -1453,7 +1495,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
order.setReturnType(returnType);
order.setStatus(ServiceConstants.ORDER_STATUS_RIDING_END);
order.setReturnTime(DateUtils.getNowDate());
// order.setReturnTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, "2024-06-28 18:15:56"));//2024-06-28 18:15:56
// order.setReturnTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, "2024-07-23 17:09:32"));//2024-06-28 18:15:56
String token = Token.getToken();
AsDevice device = asDeviceMapper.selectAsDeviceBySn(order.getSn());
if(ServiceConstants.RETURN_TYPE_NORMAL.equals(returnType)){
@ -1505,6 +1547,26 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
double v = GeoUtils.calculateTotalDistance(doubles);
order.setDistance((int)Math.round(v));
}
// 开启押金抵扣 直接将骑行费抵扣押金并退款
/**
* 1. 判断是否开启押金抵扣
* 2. 获取最后一次押金
* 3. 将抵扣后的金额 = 押金-骑行订单金额
* * 如果金额大于0
* * 如果金额小于0押金订单金额 = 0更新骑行订单状态为未支付
* 4. 更新押金订单金额做一个押金抵扣的标记
* 5. 更新骑行订单状态为已支付支付方式为 押金抵扣
* 6. 更新用户余额
* */
String isDepositDeduction = area.getIsDepositDeduction();
/** 1. 判断是否开启押金抵扣*/
if(ObjectUtil.isNotNull(isDepositDeduction) && "1".equals(isDepositDeduction)){
if(ServiceConstants.RETURN_VERIFY_NO.equals(area.getReturnVerify())){//关闭还车审核订单直接用押金支付
depositDeduction(order);
}else{
throw new ServiceException("拍照审核和押金点开不能同时开启");
}
}
int i = etOrderService.updateEtOrder(order);
if(i==0){
throw new ServiceException("更新订单状态失败");
@ -1522,6 +1584,75 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
}
}
/** 押金抵扣 */
private void depositDeduction(EtOrder order) {
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
Integer autoRefundDeposit = rule.getAutoRefundDeposit();
log.info("【还车关锁】进入押金抵扣环节--------"+autoRefundDeposit+"个小时后退还押金");
if(autoRefundDeposit!=null){
//创建一个定时器计算出退还时间后执行退款操作
// 往后推autoRefundDeposit小时执行
EtOrder finalOrder = order;
scheduledExecutorService.schedule(() -> {
/** 2. 获取最后一次押金*/
EtOrder depositOrder = etOrderService.getDepositOrder(finalOrder.getUserId());
BigDecimal deposit = depositOrder.getTotalFee();
BigDecimal ridingFee = finalOrder.getTotalFee();
BigDecimal afterDeductionFee;
String mark;
if(deposit.compareTo(ridingFee) <= 0){// 骑行费大于押金订单为未支付, 抵扣后的金额 = 骑行费 - 押金
afterDeductionFee = BigDecimal.ZERO;
mark = "押金抵扣成功,骑行费【"+ridingFee+"】大于押金【"+deposit+"";
finalOrder.setStatus(ServiceConstants.ORDER_STATUS_RIDING_END);
finalOrder.setPayFee(deposit);
}else{
// 押金大于订单金额 扣除后
afterDeductionFee = deposit.subtract(ridingFee);
mark = "押金抵扣成功,骑行费【"+ridingFee+"】小于押金【"+deposit+"】,扣除后金额【"+afterDeductionFee+"";
finalOrder.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END);
}
/** 更新骑行订单*/
finalOrder.setPaid(ServiceConstants.ORDER_PAY_STATUS_PAID);
finalOrder.setPayTime(DateUtils.getNowDate());
finalOrder.setPayType(ServiceConstants.PAY_TYPE_YJ);
finalOrder.setMark(mark);
finalOrder.setDepositDeduction(ServiceConstants.IS_DEPOSIT_DEDUCTION);
/** 更新押金订单*/
depositOrder.setDepositDeduction(ServiceConstants.IS_DEPOSIT_DEDUCTION);
int updateEtOrder1 = etOrderMapper.updateEtOrder(depositOrder);
if(updateEtOrder1 == 0){
throw new ServiceException("押金抵扣失败,更新押金订单失败");
}
if(afterDeductionFee.compareTo(BigDecimal.ZERO) > 0){
/** 退款剩余押金*/
Refund refund = wxPayService.refund(depositOrder, "押金抵扣退款",afterDeductionFee,IdUtils.getOrderNo("ref"));
/** 2.记录退款表 创建退款对象*/
depositOrder.setReason("押金抵扣退款");
EtRefund refund1= etOrderService.createRefund(depositOrder, afterDeductionFee, null, null, null, null, refund.getOutRefundNo(),ServiceConstants.REFUND_TYPE_DEPOSIT);
int i = etRefundService.insertEtRefund(refund1);
if(i == 0){
log.info("【押金抵扣】保存退款对象失败");
throw new ServiceException("【押金抵扣】,保存退款对象失败");
}
/** 更新用户余额*/
AsUser asUser = asUserService.selectUserById(depositOrder.getUserId());
if(asUser!=null){
// 更新用户并更新缓存
asUser.setBalance(BigDecimal.ZERO);
if (asUserService.updateUserProfile(asUser) > 0)
{
log.info("【押金抵扣成功】更新用户信息成功:"+ JSON.toJSON(asUser));
}else{
throw new ServiceException("【押金抵扣】,更新用户信息失败");
}
}
}
/** 押金抵扣后生成资金流水记录 */
callbackService.capitalFlowRecords(finalOrder,ServiceConstants.FLOW_TYPE_INCOME,ServiceConstants.ORDER_TYPE_RIDING,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_YJ);
}, autoRefundDeposit , TimeUnit.HOURS);
}
}
/**
* 计算订单费用
*/
@ -1567,6 +1698,10 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
// todo 自定义计费周期时刻 获取到自定义时刻判断骑行的这段时间是否在自定义时刻里 ____.___.___|___________|
// 如果不在
}else{
if(rentalUnit.equals(ServiceConstants.RENTAL_UNIT_DAY)){
}
}
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(order.getAreaId());

View File

@ -4,6 +4,8 @@ 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.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
@ -15,9 +17,10 @@ import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.wx.domain.NotifyEventType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SendAliSmsUtil;
import com.ruoyi.common.utils.SendSmsVo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.AttachVo;
@ -45,7 +48,10 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -118,6 +124,18 @@ public class CallbackServiceImpl implements CallbackService {
@Autowired
private CallbackService callbackService;
@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("${et.handlingCharge}")
// private String handlingCharge;
@ -178,6 +196,32 @@ public class CallbackServiceImpl implements CallbackService {
if(ServiceConstants.RETURN_VERIFY_YES.equals(area.getReturnVerify())){
logger.info("【微信支付回调】还车-----需要-----拍照审核");
order.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_AUDIT);//如果还车需要拍照审核状态为待审核
BigDecimal amount = order.getPayFee();
// 异步处理
scheduledExecutorService.schedule(() -> {
/** 发送一个短信给运营商*/
SysDept sysDept = wxPayService.getDeptObjByAreaId(order.getAreaId());
logger.info("【微信支付回调】还车拍照审核,获取到运营商:【{}】",JSON.toJSON(sysDept));
AsUser asUser1 = asUserMapper.selectUserById(sysDept.getAppUserId());
JSONObject jsonObject = new JSONObject();
jsonObject.put("amount",amount);
String phone = asUser1.getPhonenumber();
SendSmsVo sendSmsVo = new SendSmsVo();
sendSmsVo.setMobile(phone);
sendSmsVo.setTemplateCode(templateCode);
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));
}, 0 , TimeUnit.HOURS);
}else{
logger.info("【微信支付回调】还车-----不需要-----拍照审核");
order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END);
@ -190,7 +234,7 @@ public class CallbackServiceImpl implements CallbackService {
asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//还车后车辆正常运营
asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
// 新增资金流水记录
capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_INCOME,ServiceConstants.ORDER_TYPE_RIDING,ServiceConstants.OWNER_TYPE_OPERATOR,null);
capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_INCOME,ServiceConstants.ORDER_TYPE_RIDING,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_WX);
// 24小时后发起分账
scheduledExecutorService.schedule(() -> {
// 请求分账处理
@ -467,7 +511,7 @@ public class CallbackServiceImpl implements CallbackService {
* 资金流水记录
* */
@Override
public void capitalFlowRecords(EtOrder order,String type,String busType,String ownerType,SysUser user) {
public void capitalFlowRecords(EtOrder order,String type,String busType,String ownerType,SysUser user,String payType) {
EtCapitalFlow capitalFlow = new EtCapitalFlow();
if(ownerType.equals(ServiceConstants.OWNER_TYPE_OPERATOR)){//运营商
SysDept sysDept = wxPayService.getDeptObjByAreaId(order.getAreaId());
@ -495,6 +539,7 @@ public class CallbackServiceImpl implements CallbackService {
if(busType.equals(ServiceConstants.ORDER_TYPE_WITHDRAW)){//提现需要手续费不需要平台服务费
BigDecimal separateAccountFee = order.getPayFee();
capitalFlow.setPartnerDividend(BigDecimal.ZERO);
capitalFlow.setAmount(order.getPayFee().subtract(handlingCharge));
capitalFlow.setPlatformServiceFee(BigDecimal.ZERO);
capitalFlow.setOperatorDividend(separateAccountFee.negate());
if(StrUtil.isNotBlank(separateAccount) && separateAccount.equals("N")){
@ -504,7 +549,20 @@ public class CallbackServiceImpl implements CallbackService {
capitalFlow.setOperatorBalance(BigDecimal.ZERO);
}
logger.info("【微信支付回调--保存资金流水记录】 ==============支出=====================");
}else if(busType.equals(ServiceConstants.ORDER_TYPE_VEHICLE_DAMAGE)){
BigDecimal separateAccountFee = order.getPayFee();
capitalFlow.setAmount(order.getPayFee());
capitalFlow.setHandlingCharge(BigDecimal.ZERO);//手续费
capitalFlow.setPartnerDividend(BigDecimal.ZERO);// 合伙人分账
capitalFlow.setPlatformServiceFee(BigDecimal.ZERO);//平台服务费
capitalFlow.setOperatorDividend(separateAccountFee);
if(StrUtil.isNotBlank(separateAccount) && separateAccount.equals("N")){
capitalFlow.setOperatorBalance(sysDept.getBalance().add(separateAccountFee));
deptService.changeDeptBalance(separateAccountFee,sysDept.getDeptId());
}else{
capitalFlow.setOperatorBalance(BigDecimal.ZERO);
}
}else {
logger.info("【微信支付回调--保存资金流水记录】 ==============业务类型====================="+busType);
BigDecimal partnerDividend = BigDecimal.ZERO;
BigDecimal separateAccountFee = order.getPayFee().subtract(handlingCharge).subtract(platformServiceFee);
@ -548,7 +606,7 @@ public class CallbackServiceImpl implements CallbackService {
logger.info("【微信支付回调--保存资金流水记录】 ==============支出=====================");
}
}
capitalFlow.setPayType(ServiceConstants.PAY_TYPE_WX);
capitalFlow.setPayType(payType);
capitalFlow.setCreateTime(DateUtils.getNowDate());
logger.info("【微信支付回调】保存资金流水记录对象 : " + JSON.toJSONString(capitalFlow));
int i = etCapitalFlowService.insertEtCapitalFlow(capitalFlow);
@ -623,7 +681,7 @@ public class CallbackServiceImpl implements CallbackService {
logger.info("【微信支付回调--保存资金流水记录】 ==============支出=====================");
}
}
capitalFlow.setPayType(ServiceConstants.PAY_TYPE_WX);
capitalFlow.setPayType(payType);
capitalFlow.setCreateTime(DateUtils.getNowDate());
logger.info("【微信支付回调】保存资金流水记录对象 : " + JSON.toJSONString(capitalFlow));
int i = etCapitalFlowService.insertEtCapitalFlow(capitalFlow);
@ -649,7 +707,6 @@ public class CallbackServiceImpl implements CallbackService {
capitalFlow.setOwnerType(ownerType);
capitalFlow.setOwnerId(sysDept.getDeptId());
capitalFlow.setOwner(sysDept.getDeptName());
capitalFlow.setAmount(order.getPayFee());
String handlingCharge1 = sysDept.getHandlingCharge();
logger.info("【保存资金流水记录】 获取到配置手续费==============handlingCharge====================="+handlingCharge1);
@ -662,6 +719,7 @@ public class CallbackServiceImpl implements CallbackService {
logger.info("【保存资金流水记录】 计算出的平台服务费==============platformServiceFee====================="+platformServiceFee);
capitalFlow.setPlatformServiceFee(platformServiceFee);
capitalFlow.setHandlingCharge(handlingCharge);//手续费
capitalFlow.setAmount(order.getPayFee().subtract(handlingCharge));
BigDecimal separateAccountFee = order.getPayFee();
capitalFlow.setPartnerDividend(BigDecimal.ZERO);
capitalFlow.setPlatformServiceFee(BigDecimal.ZERO);

View File

@ -208,6 +208,19 @@ public class EtOperatingAreaServiceImpl extends ServiceImpl<EtOperatingAreaMappe
return i;
}
/**
* 修改运营区
*
* @param etOperatingArea 运营区
* @return 结果
*/
@Override
public int updateEtOperatingArea2(EtOperatingArea etOperatingArea)
{
int i = dao.updateById(etOperatingArea);
return i;
}
/**
* 批量删除运营区
*

View File

@ -434,7 +434,7 @@ public class EtOrderServiceImpl implements IEtOrderService
throw new ServiceException("押金抵扣失败,更新骑行订单失败");
}
/** 更新押金订单*/
depositOrder.setPayFee(afterDeductionFee);
// depositOrder.setPayFee(afterDeductionFee);
// depositOrder.setTotalFee(afterDeductionFee);
depositOrder.setDepositDeduction(ServiceConstants.IS_DEPOSIT_DEDUCTION);
int updateEtOrder1 = etOrderMapper.updateEtOrder(depositOrder);
@ -572,7 +572,8 @@ public class EtOrderServiceImpl implements IEtOrderService
if(!refunded){
/** 2.退剩余押金 = 押金 - 扣除金额*/
EtOrder depositOrder = getDepositOrder(etOrder.getUserId());
BigDecimal residualDeposit = depositOrder.getTotalFee().subtract(new BigDecimal(etOrder.getDeductionAmount()));
BigDecimal deductionAmount = new BigDecimal(etOrder.getDeductionAmount());
BigDecimal residualDeposit = depositOrder.getTotalFee().subtract(deductionAmount);//抵扣后的金额
Refund refund = wxPayService.refund(depositOrder, "还车审核通过后退押金",residualDeposit,IdUtils.getOrderNo("ref"));
/** 3.记录退款表 创建退款对象*/
depositOrder.setReason("还车审核通过后退押金");
@ -594,7 +595,11 @@ public class EtOrderServiceImpl implements IEtOrderService
throw new ServiceException("【还车审核通过】,更新用户信息失败");
}
}
if(deductionAmount.compareTo(BigDecimal.ZERO) > 0){//抵扣金额大于0时增加车损收入
/** 押金抵扣后生成资金流水记录 */
etOrder.setPayFee(deductionAmount);
callbackService.capitalFlowRecords(etOrder,ServiceConstants.FLOW_TYPE_INCOME,ServiceConstants.ORDER_TYPE_VEHICLE_DAMAGE,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_YJ);
}
}else{
log.info("【还车审核通过】当前用户押金已退款!!------不退押金");
}
@ -805,7 +810,7 @@ public class EtOrderServiceImpl implements IEtOrderService
indexAdminVo.setTotalOrderFee(etOrderMapper.getPayFee(null, null, null, null));//总订单金额
indexAdminVo.setTodayRefundFee(new BigDecimal(etOrderMapper.getTotalRefund(startDateStr,endDateStr,null)));// 今日退款金额
indexAdminVo.setTodayRefundFee(new BigDecimal(etOrderMapper.getTotalRefund(null,null,null)));// 总退款金额
indexAdminVo.setTotalRefundFee(new BigDecimal(etOrderMapper.getTotalRefund(null,null,null)));// 总退款金额
indexAdminVo.setUnpaidOrderCount(Integer.parseInt(etOrderMapper.getUnpaidOrder(null,null,null)));//待付款订单数
indexAdminVo.setUnpaidOrderFee(new BigDecimal(etOrderMapper.getTotalUnpaid(null,null,null)));//待付款订单金额
@ -1440,7 +1445,7 @@ public class EtOrderServiceImpl implements IEtOrderService
}
// 新增资金流水记录
etOrder1.setPayFee(refundAmount);
callbackService.capitalFlowRecords(etOrder1,ServiceConstants.FLOW_TYPE_DISBURSE,ServiceConstants.ORDER_TYPE_RIDING_REFUND,ServiceConstants.OWNER_TYPE_OPERATOR,null);
callbackService.capitalFlowRecords(etOrder1,ServiceConstants.FLOW_TYPE_DISBURSE,ServiceConstants.ORDER_TYPE_RIDING_REFUND,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_WX);
//todo 更新订单的payFee = totalFee - refundAmount
String outRefundNo = IdUtils.getOrderNo("ref");
/** 2.记录退款表 创建退款对象*/

View File

@ -150,7 +150,7 @@ public class EtWithdrawServiceImpl implements IEtWithdrawService
}
order.setAreaId(longs.get(0));
//记录资金流水
callbackService.capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_DISBURSE,ServiceConstants.ORDER_TYPE_WITHDRAW,ServiceConstants.OWNER_TYPE_OPERATOR,null);
callbackService.capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_DISBURSE,ServiceConstants.ORDER_TYPE_WITHDRAW,ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_WX);
}
}
return etWithdrawMapper.updateEtWithdraw(etWithdraw);

View File

@ -470,10 +470,10 @@ public class SysDeptServiceImpl implements ISysDeptService
* 6. 记录资金流水
*/
@Override
public int adminWithdraw(BigDecimal amount,Long appUserId) {
public int adminWithdraw(BigDecimal amount,SysDept sysDept,String method) {
String orderNo = IdUtils.getOrderNo("tx");
SysDept sysDept = deptMapper.selectDeptByAppUserId(appUserId);
AsUser asUser1 = asUserService.selectUserById(appUserId);
if(method.equals(ServiceConstants.WITHDRAW_METHOD_WX)){
AsUser asUser1 = asUserService.selectUserById(sysDept.getAppUserId());
log.info("【管理员提现】获取到运营商信息:【{}】", JSON.toJSON(sysDept));
if(ObjectUtil.isNull(sysDept)){
throw new RuntimeException("运营商未绑定app用户,请联系管理员添加【绑定微信用户】");
@ -489,6 +489,7 @@ public class SysDeptServiceImpl implements ISysDeptService
log.info("【审核通过】发起转账到零钱:{}",JSON.toJSONString(transferDetailInputs));
// todo 暂时先不发起真实提现 真正的提现是
// wxPayService.transfer(sysDept,orderNo,batchName,batchName,amount,1,transferDetailInputs);
}
//扣余额并记录资金流水
EtOrder order = new EtOrder();
order.setOrderNo(orderNo);
@ -496,7 +497,7 @@ public class SysDeptServiceImpl implements ISysDeptService
order.setTotalFee(amount);
List<Long> longs = etOperatingAreaService.selectAreaListByDeptId(sysDept.getDeptId());
if(longs.size() == 0){
throw new ServiceException("【提现】提现失败,未找到运营区,运营商id:"+sysDept.getDeptId());
throw new ServiceException("【提现】提现失败,该运营商id:"+sysDept.getDeptId()+"下未找到该运营区");
}
order.setAreaId(longs.get(0));
//记录资金流水
@ -515,7 +516,7 @@ public class SysDeptServiceImpl implements ISysDeptService
log.info("【提现失败】获取到提现流水信息:【{}】", JSON.toJSON(etCapitalFlow));
EtOrder order = new EtOrder();
order.setOrderNo(etCapitalFlow.getOrderNo());
order.setPayFee(etCapitalFlow.getAmount());
order.setPayFee(etCapitalFlow.getAmount().add(etCapitalFlow.getHandlingCharge()));
order.setTotalFee(etCapitalFlow.getAmount());
List<Long> longs = etOperatingAreaService.selectAreaListByDeptId(etCapitalFlow.getOwnerId());
if(longs.size() == 0){

View File

@ -76,6 +76,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
AND cf.create_time &lt;= #{params.endTime}
</if>
<if test="typeList != null">
AND cf.bus_type IN
<foreach item="item" index="index" collection="typeList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<!-- 数据范围过滤 -->
${params.dataScope}
order by cf.create_time desc

View File

@ -24,6 +24,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="productionTime != null "> and production_time = #{productionTime}</if>
<if test="instructions != null and instructions != ''"> and instructions = #{instructions}</if>
</where>
order by version
</select>
<select id="selectEtHardwareVersionById" parameterType="Long" resultMap="EtHardwareVersionResult">

View File

@ -22,6 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="version != null and version != ''"> and version = #{version}</if>
<if test="content != null and content != ''"> and content = #{content}</if>
</where>
order by version
</select>
<select id="selectEtSoftwareVersionById" parameterType="Long" resultMap="EtSoftwareVersionResult">