1. 修复押金抵扣接口当骑行费大于等于押金时,没有记录资金流水bug

2. 运营商不能修改硬件版本号不能修改,管理员可修改
   3. 验证码登录增加openid(验证码登录问题)
   5. 删除管理员用户时,同时解绑app用户
   6. 删除运营商时,判断名下有运营区、 收费方式提示都不能删
   7. 财务隔离-合伙人和运营商只能看到自己的账变和余额
   8. 关闭运营商中的分账功能开关
   9. 优化设备未绑定运营区不能获取到心跳推送问题
This commit is contained in:
邱贞招 2024-08-19 10:14:05 +08:00
parent 666628f3e0
commit b76762a528
37 changed files with 646 additions and 320 deletions

View File

@ -1,19 +1,24 @@
package com.ruoyi.web.controller.IndexController;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.EtOperatingArea;
import com.ruoyi.system.domain.vo.IndexAdminVo;
import com.ruoyi.system.domain.vo.IndexVo;
import com.ruoyi.system.domain.vo.LeaderboardVo;
import com.ruoyi.system.service.IEtOperatingAreaService;
import com.ruoyi.system.service.IEtOrderService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
@ -32,19 +37,30 @@ public class IndexController extends BaseController
@Autowired
private IEtOperatingAreaService etOperatingAreaService;
@Resource
private ISysUserService sysUserService;
/**
* 根据token获取运营区列表后台
*/
@GetMapping("/getAreaList")
public AjaxResult getAreaList()
{
Long deptId;
List<EtOperatingArea> longs;
SysUser sysUser = sysUserService.selectUserById(getUserId());
if(getUserId() == 1){
deptId = null;
longs = etOperatingAreaService.selectAreaListByDeptId2(null,null);
}else{
deptId = getDeptId();
if(ObjectUtil.isNotNull(sysUser.getAreaId())){
longs = etOperatingAreaService.selectAreaListByDeptId2(null,sysUser.getAreaId());
}else{
if(ObjectUtil.isNotNull(sysUser.getDeptId())){
longs = etOperatingAreaService.selectAreaListByDeptId2(sysUser.getDeptId(),null);
}else{
throw new ServiceException("该用户都没有绑定运营区和运营商(至少绑定一个)");
}
}
}
List<EtOperatingArea> longs = etOperatingAreaService.selectAreaListByDeptId2(deptId);
logger.info("根据token获取运营区列表【{}】", JSON.toJSON(longs));
return success(longs);
}

View File

@ -607,10 +607,10 @@ public class AppController extends BaseController
* 修复押金抵扣资金流水
*/
@GetMapping(value = "/repair/deduction")
public AjaxResult repairDeduction(Long areaId)
public AjaxResult repairDeduction(String startDateStr,String endDateStr,Long areaId)
{
logger.info("【修复押金抵扣请求】区域id={}",areaId);
return toAjax(etOrderService.repairDeduction(areaId));
return toAjax(etOrderService.repairDeduction(startDateStr,endDateStr,areaId));
}
/**

View File

@ -878,13 +878,20 @@ public class AppVerifyController extends BaseController
throw new RuntimeException("用户【"+asUser1.getUserName()+"】未绑定系统用户");
}
SysUser sysUser = userService.selectUserById(asUser1.getSysUserId());
Long deptId;
List<EtOperatingArea> longs;
if(sysUser.isAdmin()){
deptId = null;
longs = etOperatingAreaService.selectAreaListByDeptId2(null,null);
}else{
deptId = sysUser.getDeptId();
if(ObjectUtil.isNotNull(sysUser.getAreaId())){
longs = etOperatingAreaService.selectAreaListByDeptId2(null,sysUser.getAreaId());
}else{
if(ObjectUtil.isNotNull(sysUser.getDeptId())){
longs = etOperatingAreaService.selectAreaListByDeptId2(sysUser.getDeptId(),null);
}else{
throw new ServiceException("该用户都没有绑定运营区和运营商(至少绑定一个)");
}
}
}
List<EtOperatingArea> longs = etOperatingAreaService.selectAreaListByDeptId2(deptId);
logger.info("根据token获取运营区列表【{}】", JSON.toJSON(longs));
return success(longs);
}
@ -1075,6 +1082,14 @@ public class AppVerifyController extends BaseController
@GetMapping("/flowList")
public TableDataInfo list(EtCapitalFlow etCapitalFlow)
{
if(ObjectUtil.isNotNull(etCapitalFlow.getAreaId())){
SysDept deptObjByAreaId = wxPayService.getDeptObjByAreaId(etCapitalFlow.getAreaId());
if(ObjectUtil.isNotNull(deptObjByAreaId)){
etCapitalFlow.setOwnerId(deptObjByAreaId.getDeptId());
etCapitalFlow.setOwnerType("1");
etCapitalFlow.setAreaId(null);
}
}
startPage();
List<EtCapitalFlow> list = etCapitalFlowService.selectEtCapitalFlowList(etCapitalFlow);
return getDataTable(list);
@ -1166,6 +1181,7 @@ public class AppVerifyController extends BaseController
/**
* 坐垫锁用mac
*/
@Log(title = "坐垫锁", businessType = BusinessType.UPDATE)
@PostMapping("/device/seatCushionLockByMac")
public AjaxResult seatCushionLockByMac(String mac)
{
@ -1208,4 +1224,36 @@ public class AppVerifyController extends BaseController
return error("修改密码异常,请联系管理员");
}
/**
* 根据token判断是运营商还是合伙人
* 判断类型
* 运营商才有资金
* 合伙人才有资金
*/
@GetMapping("/ownerType")
public AjaxResult ownerType()
{
AsUser asUser = getLoginUser().getAsUser();
AsUser asUser1 = asUserMapper.selectUserById(asUser.getUserId());
logger.info("根据token判断是运营商还是合伙人【{}】", JSON.toJSON(asUser1));
//
if(ObjectUtil.isNotNull(asUser1.getSysUserId())){
SysUser sysUser = userService.selectUserById(asUser1.getSysUserId());
if(sysUser.isAdmin()){
return success(OwnerVo.builder().ownerId(sysUser.getUserId()).ownerType("1").build());
}else{
if(ObjectUtil.isNotNull(sysUser)){
if("03".equals(sysUser.getUserType())){//合伙人
return success(OwnerVo.builder().ownerId(sysUser.getUserId()).ownerType("2").build());
}else if(asUser1.getRole().equals("9")){
return success(OwnerVo.builder().ownerId(sysUser.getDeptId()).ownerType("1").build());
}else {
return error("用户【"+asUser.getUserName()+"】无账户权限");
}
}
}
}
return error("用户"+asUser.getUserName()+"未绑定系统用户");
}
}

View File

@ -21,6 +21,7 @@ import com.ruoyi.web.controller.iot.domain.BodyObj;
import com.ruoyi.web.controller.iot.domain.LogEntry;
import com.ruoyi.web.controller.iot.util.Util;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.locationtech.jts.geom.Geometry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -145,12 +146,7 @@ public class ReceiveController {
String devName = (String)jsonObject.get("dev_name");
/*异步更新在线状态*/
AsDevice asDevice = asDeviceService.selectAsDeviceByMac(devName);
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);
asynchronousUpdateOnlineStatus(asDevice);
if(IotConstants.ONENET_LOCATION.equals(jsonObject.get("ds_id")) && ObjectUtil.isNotNull(jsonObject.get("value"))){
LogEntry logEntry = JSONObject.parseObject(msg, LogEntry.class);
log.info("logEntry转换后的对象: logEntry---【{}】" , JSON.toJSONString(logEntry));
@ -169,232 +165,39 @@ public class ReceiveController {
if(ObjectUtil.isNull(device)){
throw new ServiceException("未找到车辆信息");
}
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(device.getAreaId());
if(ObjectUtil.isNotNull(device)){
BigDecimal lon = new BigDecimal(value.getLon());
BigDecimal lat = new BigDecimal(value.getLat());
log.info("WGS84经纬度未计算" + lon + "---" + lat);
// 除以100
lon = lon.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
lat = lat.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
log.info("WGS84经纬度除以100后" + lon + "---" + lat);
// 取出lon中后面的小数点
String[] lonStr = getDecimalPart(lon);
String[] latStr = getDecimalPart(lat);
log.info("WGS84经纬度截取小数点" + lonStr[0] + "---" + lonStr[1] + "---"+ latStr[0]+"---"+ latStr[1]);
// 再将结果乘以5/3
String lon2 = "0."+ lonStr[1];
String lat2 = "0."+ latStr[1];
BigDecimal lons = new BigDecimal(lon2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
BigDecimal lats = new BigDecimal(lat2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
BigDecimal lo = new BigDecimal(lonStr[0]).add(lons);
BigDecimal la = new BigDecimal(latStr[0]).add(lats);
log.info("WGS84经纬度计算后" + lo + "---" + la);
lo = lo.setScale(8, RoundingMode.HALF_UP);
la = la.setScale(8, RoundingMode.HALF_UP);
log.info("WGS84经纬度保留8为小数" + lo + "---" + la);
double[] doubles = GpsCoordinateUtils.calWGS84toGCJ02(la.doubleValue(), lo.doubleValue());
lat = new BigDecimal(doubles[0]).setScale(8, RoundingMode.HALF_UP);
lon = new BigDecimal(doubles[1]).setScale(8, RoundingMode.HALF_UP);
// 坐标转换 WGS84 GCJ02
double[] doubles = coordinateConvert(value);
BigDecimal lat = new BigDecimal(doubles[0]).setScale(8, RoundingMode.HALF_UP);
BigDecimal lon = new BigDecimal(doubles[1]).setScale(8, RoundingMode.HALF_UP);
log.info("转换后的GCJ02经纬度" + lon + "---" + lat);
if(BigDecimal.ZERO.compareTo(lon) != 0 && BigDecimal.ZERO.compareTo(lat) != 0){
device.setLatitude(lat.toString());
device.setLongitude(lon.toString());
Integer bat = value.getBat();
BigDecimal divide = new BigDecimal(bat).divide(new BigDecimal(10));
log.info("保存电压:" + divide);
device.setVoltage(divide.toString());//电压
// 根据电压计算续航里程
EtModel model = etModelService.selectEtModelByModelId(device.getModelId());
Integer remainingMileage = 0;
if(StrUtil.isNotBlank(device.getVoltage())){
remainingMileage = CommonUtil.getRemainingMileage(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage(), model.getFullEndurance());
}
Integer electricQuantity = CommonUtil.getElectricQuantity(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage());//电量百分百
device.setRemainingMileage(remainingMileage);
device.setRemainingPower(electricQuantity.toString());
device.setLastTime(DateUtils.getNowDate());
device.setLastLocationTime(DateUtils.getNowDate());
device.setGps("1");
// 信号强度
device.setSignalStrength(value.getCsq());
device.setSatellites(value.getS());
device.setQuality(value.getQ());
int i = asDeviceService.updateLocation(device);
// 计算电量和里程后更新设备
int i = updateDevice(value, device, lon, lat);
if(i>0){
log.info("更新定位成功==========================>" +logEntry.getDevName());
/** 2. 判断是否在禁行区内
* 如果在 根据配置禁行区内断电配置进行断电
**/
String isAdminUnlocking = device.getIsAdminUnlocking();// 是否是管理员开锁0-1-
boolean noRidingArea = asDeviceService.isNoRidingArea(device.getSn(), device.getAreaId());
if(noRidingArea){
String noRidingOutage = area.getNoRidingOutage();
if (noRidingOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 禁行区内断电
log.info("禁行区内断电命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "禁行区内断电",null,null);
device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
int updateAsDevice = asDeviceService.updateAsDevice(device);
if (updateAsDevice > 0) {
log.info("禁行区内断电--更新设备锁状态成功SN" + device.getSn());
}
}
}else{
//是否在禁行区20米范围内
boolean inPolygon = asDeviceService.isNoRidingAreaWithTolerance(device.getSn(), device.getAreaId(),30);
if (inPolygon && !isAdminUnlocking.equals("1")) {
log.info("距离禁行区20米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY2, "距离禁行区30米内",null,null);
}
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(device.getAreaId());
if(ObjectUtil.isNotNull(area)){
/** 2. 判断是否在禁行区内 如果在, 根据配置‘禁行区内断电配置’进行断电 **/
String isAdminUnlocking = device.getIsAdminUnlocking();// 是否是管理员开锁0-1-
boolean noRidingArea = isNoRidingArea(value, device, area, isAdminUnlocking);
/** 3.超出运营区外断电*/
outAreaOutage(value, device, lon, lat, area, isAdminUnlocking, noRidingArea);
/** 4.优化线路和锁同步关锁 */
optimizeRouteAndLockSynchronization(msg, asDevice, logEntry, value, device, lon, lat);
/** 5.低电量 生成换电工单*/
replacementOrder(device, area);
}
/** 3.超出运营区外断电*/
boolean isAreaZone = asDeviceService.isAreaZone(device.getSn(), area);
if(!isAreaZone){
//是否在30米范围内
boolean inPolygon = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), GeoUtils.fromWkt(area.getBoundary()), 60);
if(inPolygon && !isAdminUnlocking.equals("1")){
//在20米范围内发报警
log.info("超出运营区30米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY3, "超出运营区30米内",null,null);
}else{
//超出运营区外断电
String areaOutOutage = area.getAreaOutOutage();
if (areaOutOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 超出营运区断电
log.info("超出营运区断电命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "超出营运区断电",null,null);
device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
int updateAsDevice = asDeviceService.updateAsDevice(device);
if (updateAsDevice > 0) {
log.info("禁行区内断电--更新设备锁状态成功SN" + device.getSn());
}
}
}
}else{
// 判断该车辆是否在进行中的订单,并且车辆的锁状态是关状态是骑行中
Boolean inOrderBySn = etOrderService.isInOrderBySn(device.getSn());
if (inOrderBySn && ServiceConstants.VEHICLE_STATUS_IN_USING.equals(device.getStatus()) && ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus())) { // 有正在骑行的订单给车辆上电
if(!noRidingArea){
log.info("返回营运区上电,有正在骑行的订单,给车辆上电--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5, "返回营运区上电",null,null);
// 更新车辆状态和锁状态
/** 3.更新车辆状态*/
device.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN);
device.setStatus(ServiceConstants.VEHICLE_STATUS_IN_USING);
device.setIsAdminUnlocking("0");
int i1 = asDeviceService.updateAsDevice(device);
if(i1>1){
log.info("【返回营运区上电】更新车辆状态成功");
}
}
}
}
/** 4.行程线路添加更新订单中的trip_route字段 */
Integer status = value.getStatus();
if(status == 1){//上电运行
log.info("上电运行:" +logEntry.getDevName());
if(BigDecimal.ZERO.compareTo(lon) != 0 && BigDecimal.ZERO.compareTo(lat) != 0){
//获取当前正在骑行中的订单
EtOrder etOrder = etOrderService.getCurrentOrder(device.getSn());
if(ObjectUtil.isNotNull(etOrder)){
JSONArray jsonArray;
if(StrUtil.isNotBlank(etOrder.getTripRouteStr())){
jsonArray = JSON.parseArray(etOrder.getTripRouteStr());
}else{
jsonArray = new JSONArray();
}
JSONArray newPoint = new JSONArray();
newPoint.add(lon);
newPoint.add(lat);
// 优化轨迹如果获取到的定位与最后一个定位相同则不添加
optimizeRoute(jsonArray, newPoint,lon,lat,etOrder);
}else{
long currentTime = System.currentTimeMillis();
long lastTime = lastCommandTime.get();// 上一次命令时间5分账内不再执行 车辆锁同步关锁 命令
long difference = System.currentTimeMillis() - logEntry.getAt();
log.info("当前时间戳:【"+System.currentTimeMillis()+"】,消息时间:【"+logEntry.getAt()+"】,时间差:【"+difference+"");
if (difference < 60 * 1000 && ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus())) {// 消息时间和当前时间时间差在1分钟内且锁状态为关闭则发送命令
if (currentTime - lastTime >= COMMAND_COOLDOWN_MS) {
asDeviceService.sendCommand(asDevice.getMac(), Token.getToken(), IotConstants.COMMAND_CLOSE + IotConstants.COMMAND_FREQUENCY_3600, "车辆锁同步关锁", null, null, msg);
}
}
}
}
}
/** 6.低电量 生成换电工单*/
Integer replacementOrder = area.getAutoReplacementOrder();
Boolean aBoolean = etAdminOrderService.checkOrderUnique(device.getSn());
if (Integer.parseInt(device.getRemainingPower()) < replacementOrder && !aBoolean) {
/** 生成换电工单 */
EtAdminOrder adminOrder = new EtAdminOrder();
adminOrder.setDeviceMac(device.getMac());
adminOrder.setSn(device.getSn());
adminOrder.setBeforeElectric(Integer.parseInt(device.getRemainingPower()));
adminOrder.setOrderNo(IdUtils.getOrderNo("hd"));
adminOrder.setAreaId(area.getAreaId());
adminOrder.setStatus(ServiceConstants.REPLACEMENT_ELECTRICITY_STATUS_UNDER_WAY);
adminOrder.setIsEffective(ServiceConstants.REPLACEMENT_ELECTRICITY_IS_EFFECTIVE_YES);
SysUser sysUser = sysUserService.selectUserByUserName("wx");//获取用户名为wx的维修人员
adminOrder.setAdminId(sysUser.getUserId());
adminOrder.setAdminName(sysUser.getUserName());
adminOrder.setLatitude(device.getLatitude());
adminOrder.setLongitude(device.getLongitude());
adminOrder.setType("2");
// String location = device.getLongitude() + ","+device.getLatitude();
// adminOrder.setAddress(CommonUtil.getAddressByGeo(location));
int i1 = etAdminOrderService.insertEtAdminOrder(adminOrder);
if (i1 > 0) {
log.info("生成换电工单成功");
}else{
throw new ServiceException("生成换电工单失败");
}
/** 改变车辆状态 */
// device.setStatus(ServiceConstants.VEHICLE_STATUS_IN_OFFLINE);
if (asDeviceService.updateAsDevice(device) > 0) {
log.info("车辆状态改成换电中");
}else{
throw new ServiceException("车辆状态更新失败");
}
}
// /** TODO 7.运营边界判断 几米判断? 3 播报运营边界 play2@ 是否靠近运营区边界*/
// boolean isCloseToTheBoundary = asDeviceService.isCloseToTheBoundary(device.getSn(), area);
// if(isCloseToTheBoundary){
// //发送超出营运区播报指令
// asDeviceService.sendCommand(device.getMac(), Token.getToken(),IotConstants.COMMAND_PLAY2,"靠近营运边界播报");
// }
}else{
log.info("更新定位失败:" +logEntry.getDevName());
}
}else{
log.info("----------------未获取到定位,保存电压等数值----------------" +logEntry.getDevName());
Integer bat = value.getBat();
BigDecimal divide = new BigDecimal(bat).divide(new BigDecimal(10));
log.info("保存电压:" + divide);
device.setVoltage(divide.toString());//电压
// 根据电压计算续航里程
EtModel model = etModelService.selectEtModelByModelId(device.getModelId());
Integer remainingMileage = 0;
if(StrUtil.isNotBlank(device.getVoltage())){
remainingMileage = CommonUtil.getRemainingMileage(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage(), model.getFullEndurance());
}
Integer electricQuantity = CommonUtil.getElectricQuantity(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage());//电量百分百
device.setRemainingMileage(remainingMileage);
device.setRemainingPower(electricQuantity.toString());
device.setLastTime(DateUtils.getNowDate());
device.setGps("0");
device.setSignalStrength(value.getCsq());
device.setSatellites(0);
device.setQuality(value.getQ());
int i = asDeviceService.updateLocation(device);
if(i>0){
log.info("未获取到定位===============保存电压等数值成功===========>" +logEntry.getDevName());
}
log.info("----------------无定位更新设备----------------" + logEntry.getDevName());
noLocationUpdateDevice(logEntry, value, device);
}
}else{
log.info("未找到车辆对象:" +logEntry.getDevName());
}
}
}else {
log.info("receive方法验证签名错误: signature error");
@ -405,13 +208,233 @@ public class ReceiveController {
}
}
/** 无定位更新设备 */
private void noLocationUpdateDevice(LogEntry logEntry, LogEntry.LocationValue value, AsDevice device) {
Integer bat = value.getBat();
BigDecimal divide = new BigDecimal(bat).divide(new BigDecimal(10));
log.info("保存电压:" + divide);
device.setVoltage(divide.toString());//电压
// 根据电压计算续航里程
EtModel model = etModelService.selectEtModelByModelId(device.getModelId());
Integer remainingMileage = 0;
if(StrUtil.isNotBlank(device.getVoltage())){
remainingMileage = CommonUtil.getRemainingMileage(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage(), model.getFullEndurance());
}
Integer electricQuantity = CommonUtil.getElectricQuantity(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage());//电量百分百
device.setRemainingMileage(remainingMileage);
device.setRemainingPower(electricQuantity.toString());
device.setLastTime(DateUtils.getNowDate());
device.setGps("0");
device.setSignalStrength(value.getCsq());
device.setSatellites(0);
device.setQuality(value.getQ());
int i = asDeviceService.updateLocation(device);
if(i>0){
log.info("未获取到定位===============保存电压等数值成功===========>" + logEntry.getDevName());
}
}
/** 计算电量和里程后更新设备*/
private int updateDevice(LogEntry.LocationValue value, AsDevice device, BigDecimal lon, BigDecimal lat) {
device.setLatitude(lat.toString());
device.setLongitude(lon.toString());
Integer bat = value.getBat();
BigDecimal divide = new BigDecimal(bat).divide(new BigDecimal(10));
log.info("保存电压:" + divide);
device.setVoltage(divide.toString());//电压
// 根据电压计算续航里程
EtModel model = etModelService.selectEtModelByModelId(device.getModelId());
Integer remainingMileage = 0;
if(StrUtil.isNotBlank(device.getVoltage())){
remainingMileage = CommonUtil.getRemainingMileage(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage(), model.getFullEndurance());
}
Integer electricQuantity = CommonUtil.getElectricQuantity(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage());//电量百分百
device.setRemainingMileage(remainingMileage);
device.setRemainingPower(electricQuantity.toString());
device.setLastTime(DateUtils.getNowDate());
device.setLastLocationTime(DateUtils.getNowDate());
device.setGps("1");
// 信号强度
device.setSignalStrength(value.getCsq());
device.setSatellites(value.getS());
device.setQuality(value.getQ());
int i = asDeviceService.updateLocation(device);
return i;
}
/** 坐标转换 */
@NotNull
private double[] coordinateConvert(LogEntry.LocationValue value) {
BigDecimal lon = new BigDecimal(value.getLon());
BigDecimal lat = new BigDecimal(value.getLat());
log.info("WGS84经纬度未计算" + lon + "---" + lat);
// 除以100
lon = lon.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
lat = lat.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
log.info("WGS84经纬度除以100后" + lon + "---" + lat);
// 取出lon中后面的小数点
String[] lonStr = getDecimalPart(lon);
String[] latStr = getDecimalPart(lat);
log.info("WGS84经纬度截取小数点" + lonStr[0] + "---" + lonStr[1] + "---"+ latStr[0]+"---"+ latStr[1]);
// 再将结果乘以5/3
String lon2 = "0."+ lonStr[1];
String lat2 = "0."+ latStr[1];
BigDecimal lons = new BigDecimal(lon2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
BigDecimal lats = new BigDecimal(lat2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
BigDecimal lo = new BigDecimal(lonStr[0]).add(lons);
BigDecimal la = new BigDecimal(latStr[0]).add(lats);
log.info("WGS84经纬度计算后" + lo + "---" + la);
lo = lo.setScale(8, RoundingMode.HALF_UP);
la = la.setScale(8, RoundingMode.HALF_UP);
log.info("WGS84经纬度保留8为小数" + lo + "---" + la);
double[] doubles = GpsCoordinateUtils.calWGS84toGCJ02(la.doubleValue(), lo.doubleValue());
return doubles;
}
/** 超出运营区断电*/
private void outAreaOutage(LogEntry.LocationValue value, AsDevice device, BigDecimal lon, BigDecimal lat, EtOperatingArea area, String isAdminUnlocking, boolean noRidingArea) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
boolean isAreaZone = asDeviceService.isAreaZone(device.getSn(), area);
if(!isAreaZone){
//是否在30米范围内
boolean inPolygon = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), GeoUtils.fromWkt(area.getBoundary()), 60);
if(inPolygon && !isAdminUnlocking.equals("1")){
//在20米范围内发报警
log.info("超出运营区30米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY3, "超出运营区30米内",null,null);
}else{
//超出运营区外断电
String areaOutOutage = area.getAreaOutOutage();
if (areaOutOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 超出营运区断电
log.info("超出营运区断电命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "超出营运区断电",null,null);
device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
int updateAsDevice = asDeviceService.updateAsDevice(device);
if (updateAsDevice > 0) {
log.info("禁行区内断电--更新设备锁状态成功SN" + device.getSn());
}
}
}
}else{
// 判断该车辆是否在进行中的订单,并且车辆的锁状态是关状态是骑行中
Boolean inOrderBySn = etOrderService.isInOrderBySn(device.getSn());
if (inOrderBySn && ServiceConstants.VEHICLE_STATUS_IN_USING.equals(device.getStatus()) && ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus())) { // 有正在骑行的订单给车辆上电
if(!noRidingArea){
log.info("返回营运区上电,有正在骑行的订单,给车辆上电--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5, "返回营运区上电",null,null);
// 更新车辆状态和锁状态
/** 3.更新车辆状态*/
device.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN);
device.setStatus(ServiceConstants.VEHICLE_STATUS_IN_USING);
device.setIsAdminUnlocking("0");
int i1 = asDeviceService.updateAsDevice(device);
if(i1>1){
log.info("【返回营运区上电】更新车辆状态成功");
}
}
}
}
}
/* 禁行区内断电*/
private boolean isNoRidingArea(LogEntry.LocationValue value, AsDevice device, EtOperatingArea area, String isAdminUnlocking) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
boolean noRidingArea = asDeviceService.isNoRidingArea(device.getSn(), device.getAreaId());
if(noRidingArea){
String noRidingOutage = area.getNoRidingOutage();
if (noRidingOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 禁行区内断电
log.info("禁行区内断电命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "禁行区内断电",null,null);
device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
int updateAsDevice = asDeviceService.updateAsDevice(device);
if (updateAsDevice > 0) {
log.info("禁行区内断电--更新设备锁状态成功SN" + device.getSn());
}
}
}else{
//是否在禁行区20米范围内
boolean inPolygon = asDeviceService.isNoRidingAreaWithTolerance(device.getSn(), device.getAreaId(),30);
if (inPolygon && !isAdminUnlocking.equals("1")) {
log.info("距离禁行区20米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY2, "距离禁行区30米内",null,null);
}
}
return noRidingArea;
}
private void optimizeRouteAndLockSynchronization(String msg, AsDevice asDevice, LogEntry logEntry, LogEntry.LocationValue value, AsDevice device, BigDecimal lon, BigDecimal lat) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
Integer status = value.getStatus();
if(status == 1){//上电运行
log.info("上电运行:" + logEntry.getDevName());
if(BigDecimal.ZERO.compareTo(lon) != 0 && BigDecimal.ZERO.compareTo(lat) != 0){
//获取当前正在骑行中的订单
EtOrder etOrder = etOrderService.getCurrentOrder(device.getSn());
if(ObjectUtil.isNotNull(etOrder)){
JSONArray jsonArray;
if(StrUtil.isNotBlank(etOrder.getTripRouteStr())){
jsonArray = JSON.parseArray(etOrder.getTripRouteStr());
}else{
jsonArray = new JSONArray();
}
JSONArray newPoint = new JSONArray();
newPoint.add(lon);
newPoint.add(lat);
// 优化轨迹如果获取到的定位与最后一个定位相同则不添加
optimizeRoute(jsonArray, newPoint, lon, lat,etOrder);
}else{
long currentTime = System.currentTimeMillis();
long lastTime = lastCommandTime.get();// 上一次命令时间5分账内不再执行 车辆锁同步关锁 命令
long difference = System.currentTimeMillis() - logEntry.getAt();
log.info("当前时间戳:【"+System.currentTimeMillis()+"】,消息时间:【"+ logEntry.getAt()+"】,时间差:【"+difference+"");
if (difference < 60 * 1000 && ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus())) {// 消息时间和当前时间时间差在1分钟内且锁状态为关闭则发送命令
if (currentTime - lastTime >= COMMAND_COOLDOWN_MS) {
asDeviceService.sendCommand(asDevice.getMac(), Token.getToken(), IotConstants.COMMAND_CLOSE + IotConstants.COMMAND_FREQUENCY_3600, "车辆锁同步关锁", null, null, msg);
}
}
}
}
}
}
private void replacementOrder(AsDevice device, EtOperatingArea area) {
Integer replacementOrder = area.getAutoReplacementOrder();
Boolean aBoolean = etAdminOrderService.checkOrderUnique(device.getSn());
if (Integer.parseInt(device.getRemainingPower()) < replacementOrder && !aBoolean) {
/** 生成换电工单 */
EtAdminOrder adminOrder = new EtAdminOrder();
adminOrder.setDeviceMac(device.getMac());
adminOrder.setSn(device.getSn());
adminOrder.setBeforeElectric(Integer.parseInt(device.getRemainingPower()));
adminOrder.setOrderNo(IdUtils.getOrderNo("hd"));
adminOrder.setAreaId(area.getAreaId());
adminOrder.setStatus(ServiceConstants.REPLACEMENT_ELECTRICITY_STATUS_UNDER_WAY);
adminOrder.setIsEffective(ServiceConstants.REPLACEMENT_ELECTRICITY_IS_EFFECTIVE_YES);
SysUser sysUser = sysUserService.selectUserByUserName("wx");//获取用户名为wx的维修人员
adminOrder.setAdminId(sysUser.getUserId());
adminOrder.setAdminName(sysUser.getUserName());
adminOrder.setLatitude(device.getLatitude());
adminOrder.setLongitude(device.getLongitude());
adminOrder.setType("2");
int i1 = etAdminOrderService.insertEtAdminOrder(adminOrder);
if (i1 > 0) {
log.info("生成换电工单成功");
}else{
throw new ServiceException("生成换电工单失败");
}
/** 改变车辆状态 */
if (asDeviceService.updateAsDevice(device) > 0) {
log.info("车辆状态改成换电中");
}else{
throw new ServiceException("车辆状态更新失败");
}
}
}
/**
* 异步更新在线状态
*/
private void asynchronousUpdateOnlineStatus(AsDevice device,String verStr) {
if(StrUtil.isNotBlank(verStr)){
device.setVersion(verStr);
}
private void asynchronousUpdateOnlineStatus(AsDevice device) {
//开异步线程1.更新在线状态 2.记录在线离线日志
scheduledExecutorService.schedule(() -> {
if(device.getOnlineStatus().equals(ServiceConstants.VEHICLE_STATUS_OFFLINE)){

View File

@ -142,6 +142,12 @@ public class EtOperatingAreaController extends BaseController
@DeleteMapping("/{areaIds}")
public AjaxResult remove(@PathVariable Long[] areaIds)
{
for (Long areaId:areaIds) {
if (etOperatingAreaService.checkDeptExistDevice(areaId))
{
return warn("运营区【"+areaId+"】下存在车辆,不允许删除");
}
}
return toAjax(etOperatingAreaService.deleteEtOperatingAreaByAreaIds(areaIds));
}
@ -162,7 +168,7 @@ public class EtOperatingAreaController extends BaseController
public AjaxResult selectAreaListByDeptId(@PathVariable("deptId") Long deptId)
{
AjaxResult ajax = AjaxResult.success();
ajax.put("areaList", etOperatingAreaService.selectAreaListByDeptId2(deptId));
ajax.put("areaList", etOperatingAreaService.selectAreaListByDeptId2(deptId,null));
EtModel model = new EtModel();
model.setOperator(deptId);
ajax.put("modelList", etModelMapper.selectEtModelList(model));

View File

@ -1,15 +1,18 @@
package com.ruoyi.web.controller.system;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.EtOperatingArea;
import com.ruoyi.system.domain.vo.ReconciliationVo;
import com.ruoyi.system.service.IEtOperatingAreaService;
import com.ruoyi.system.service.IEtOrderService;
import com.ruoyi.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -18,6 +21,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
@ -38,6 +42,9 @@ public class EtReconciliationControllor extends BaseController {
@Autowired
private IEtOperatingAreaService etOperatingAreaService;
@Resource
private ISysUserService sysUserService;
/**
* 查询对账列表
*/
@ -63,13 +70,20 @@ public class EtReconciliationControllor extends BaseController {
@GetMapping("/getAreaList")
public AjaxResult getAreaList()
{
SysUser user = getLoginUser().getUser();
logger.info("【后台根据token获取运营区列表】获取当前登录用户【{}】", JSON.toJSON(user));
List<EtOperatingArea> longs;
if(user.isAdmin()){
longs = etOperatingAreaService.selectAreaListByDeptId2(null);
SysUser sysUser = sysUserService.selectUserById(getUserId());
if(getUserId() == 1){
longs = etOperatingAreaService.selectAreaListByDeptId2(null,null);
}else{
longs = etOperatingAreaService.selectAreaListByDeptId2(user.getDeptId());
if(ObjectUtil.isNotNull(sysUser.getAreaId())){
longs = etOperatingAreaService.selectAreaListByDeptId2(null,sysUser.getAreaId());
}else{
if(ObjectUtil.isNotNull(sysUser.getDeptId())){
longs = etOperatingAreaService.selectAreaListByDeptId2(sysUser.getDeptId(),null);
}else{
throw new ServiceException("该用户都没有绑定运营区和运营商(至少绑定一个)");
}
}
}
logger.info("根据token获取运营区列表【{}】", JSON.toJSON(longs));
return success(longs);

View File

@ -224,6 +224,14 @@ public class SysDeptController extends BaseController
{
return warn("运营商存在用户,不允许删除");
}
if (deptService.checkDeptExistArea(deptId))
{
return warn("运营商下存在运营区,不允许删除");
}
if (deptService.checkDeptExistFeeRule(deptId))
{
return warn("运营商下存在收费方式,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}

View File

@ -64,8 +64,8 @@ public class SysDept extends BaseEntity
/** 手续费 */
private String handlingCharge;
/** 是否开启分账 */
private String isProfitSharing;
// /** 是否开启分账 */
// private String isProfitSharing;
/** 是否有独立支付账户 */
private String separateAccount;
@ -130,6 +130,10 @@ public class SysDept extends BaseEntity
/** 可提现金额 */
public BigDecimal withdrawableAmount;
public void setPlatformServiceFee(String platformServiceFee) {
this.platformServiceFee = platformServiceFee;
}
public BigDecimal getWithdrawableAmount() {
return withdrawableAmount;
}
@ -246,17 +250,17 @@ public class SysDept extends BaseEntity
this.appName = appName;
}
public void setPlatformServiceFee(String platformServiceFee) {
this.platformServiceFee = platformServiceFee;
}
public String getIsProfitSharing() {
return isProfitSharing;
}
public void setIsProfitSharing(String isProfitSharing) {
this.isProfitSharing = isProfitSharing;
}
// public void setPlatformServiceFee(String platformServiceFee) {
// this.platformServiceFee = platformServiceFee;
// }
//
// public String getIsProfitSharing() {
// return isProfitSharing;
// }
//
// public void setIsProfitSharing(String isProfitSharing) {
// this.isProfitSharing = isProfitSharing;
// }
public String getAppid() {
return appid;

View File

@ -0,0 +1,17 @@
package com.ruoyi.system.domain.vo;
import lombok.Builder;
import lombok.Data;
/**
* 合伙人Vo
* */
@Data
@Builder
public class OwnerVo {
/** 合伙人id */
private Long ownerId;
/** 合伙人类型 */
private String ownerType;
}

View File

@ -180,4 +180,9 @@ public interface AsUserMapper
* 解绑系统用户
*/
int unbindSystemUser(AsUser user);
/**
* 解绑系统用户
*/
int unbindSystemUserBySysUserId(Long sysUserId);
}

View File

@ -63,6 +63,8 @@ public interface EtCapitalFlowMapper
EtCapitalFlow selectEtCapitalFlowByOutTradeNo(String outTradeNo);
List<EtCapitalFlow> selectEtCapitalFlowByOrderNo(String orderNo);
/**
* 已提现金额
*

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.system.domain.EtOperatingArea;
import org.apache.ibatis.annotations.Param;
/**
* 运营区Mapper接口
@ -43,7 +44,7 @@ public interface EtOperatingAreaMapper extends BaseMapper<EtOperatingArea>
* @param deptId 用户ID
* @return 选中运营区ID列表
*/
List<EtOperatingArea> selectAreaListByDeptId2(Long deptId);
List<EtOperatingArea> selectAreaListByDeptId2(@Param("deptId") Long deptId,@Param("areaId") Long areaId);
//
// /**
// * 新增运营区

View File

@ -291,5 +291,5 @@ public interface EtOrderMapper
// Integer getAppCount();
List<EtOrder> selectDeductionList(Long areaId);
List<EtOrder> selectDeductionList(@Param("startDateStr") String startDateStr , @Param("endDateStr") String endDateStr,@Param("areaId") Long areaId);
}

View File

@ -147,4 +147,20 @@ public interface SysDeptMapper
BigDecimal selectAllBalance();
/**
* 查询部门是否存在用户
*
* @param deptId 部门ID
* @return 结果
*/
public int checkDeptExistArea(Long deptId);
/**
* 查询部门是否存在收费方式
*
* @param deptId 部门ID
* @return 结果
*/
public int checkDeptExistFeeRule(Long deptId);
}

View File

@ -69,6 +69,14 @@ public interface SysUserMapper
*/
public int updateUser(SysUser user);
/**
* 修改用户信息
*
* @param user 用户信息
* @return 结果
*/
public int updateUser2(SysUser user);
/**
* 修改用户头像
*

View File

@ -2,10 +2,12 @@ package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.EtCapitalFlow;
import com.ruoyi.system.domain.EtOperatingArea;
import com.ruoyi.system.domain.EtOrder;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
/**
* 订单支付回调 service
@ -36,7 +38,7 @@ public interface CallbackService {
* @param payType 支付方式
* @return void
*/
public void capitalFlowRecords(EtOrder order, String type, String busType, String ownerType, SysUser user, String payType);
public EtCapitalFlow capitalFlowRecords(EtOrder order, String type, String busType, String ownerType, SysUser user, String payType);
/**
* 新增资金流水记录
@ -56,6 +58,6 @@ public interface CallbackService {
* @param area 运营区域
* @return boolean
*/
public boolean dividendHandle(String transactionId, EtOrder order, EtOperatingArea area);
public boolean dividendHandle(String transactionId, EtOrder order, EtOperatingArea area, BigDecimal dividendAmount);
}

View File

@ -226,6 +226,11 @@ public interface IAsUserService
*/
int unbindSystemUser(AsUser user);
/**
* 根据系统用户解绑
*/
int unbindSystemUserBySysUserId(Long sysUserId);
/**
* 实名认证
*

View File

@ -28,6 +28,14 @@ public interface IEtCapitalFlowService
*/
public EtCapitalFlow selectEtCapitalFlowByOutTradeNo(String outTradeNo);
/**
* 根据订单号查询资金流水
*
* @param orderNo 订单号
* @return 资金流水
*/
public List<EtCapitalFlow> selectEtCapitalFlowByOrderNo(String orderNo);
/**
* 查询资金流水列表
*

View File

@ -119,5 +119,13 @@ public interface IEtOperatingAreaService extends IService<EtOperatingArea>
* @param deptId 用户ID
* @return 选中运营区ID列表
*/
public List<EtOperatingArea> selectAreaListByDeptId2(Long deptId);
public List<EtOperatingArea> selectAreaListByDeptId2(Long deptId,Long areaId);
/**
* 查询部门是否存在车辆
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
public boolean checkDeptExistDevice(Long deptId);
}

View File

@ -202,7 +202,7 @@ public interface IEtOrderService
/**
* 修复押金抵扣
*/
int repairDeduction(Long areaId);
int repairDeduction(String startDateStr,String endDateStr,Long areaId);
/**
* 还车审核通过

View File

@ -93,6 +93,22 @@ public interface ISysDeptService
*/
public boolean checkDeptExistUser(Long deptId);
/**
* 查询部门是否存在运营区
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
public boolean checkDeptExistArea(Long deptId);
/**
* 查询部门是否存在收费方式
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
public boolean checkDeptExistFeeRule(Long deptId);
/**
* 校验部门名称是否唯一
*

View File

@ -633,12 +633,14 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
nearbyVehicle = Integer.parseInt(nearbyVehicles);
}
for (AsDevice device : allDevices) {
double deviceLon = Double.parseDouble(device.getLongitude());
double deviceLat = Double.parseDouble(device.getLatitude());
double distance = GeoUtils.calculateDistance(targetLat, targetLon, deviceLat, deviceLon);
if(StrUtil.isNotBlank(device.getLongitude()) && StrUtil.isNotBlank(device.getLatitude())){
double deviceLon = Double.parseDouble(device.getLongitude());
double deviceLat = Double.parseDouble(device.getLatitude());
double distance = GeoUtils.calculateDistance(targetLat, targetLon, deviceLat, deviceLon);
if (distance <= nearbyVehicle) {
nearbyDevices.add(device);
if (distance <= nearbyVehicle) {
nearbyDevices.add(device);
}
}
}
return nearbyDevices;

View File

@ -548,6 +548,18 @@ public class AsUserServiceImpl implements IAsUserService
return asUserMapper.unbindSystemUser(user);
}
/**
* 根据系统用户解绑
*/
@Transactional
@Override
public int unbindSystemUserBySysUserId(Long sysUserId) {
// 删除用户缓存
Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.APP_LOGIN_TOKEN_KEY + "*");
redisCache.deleteObject(keys);
return asUserMapper.unbindSystemUserBySysUserId(sysUserId);
}
/**
* 实名认证
*/

View File

@ -226,9 +226,11 @@ 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,ServiceConstants.PAY_TYPE_WX);
// 24小时后发起分账
dividendHandle(transactionId, order, area);
EtCapitalFlow capitalFlow = capitalFlowRecords(order, ServiceConstants.FLOW_TYPE_INCOME, ServiceConstants.ORDER_TYPE_RIDING, ServiceConstants.OWNER_TYPE_OPERATOR, null, ServiceConstants.PAY_TYPE_WX);
// 发起分账
// BigDecimal dividendAmount= order.getPayFee().subtract(capitalFlow.getHandlingCharge()).subtract(capitalFlow.getPlatformServiceFee());//分账金额订单实际支付金额-平台服务费-支付手续费
// logger.info("=================【微信支付回调】分账金额=================={}",dividendAmount);
// dividendHandle(transactionId, order, area,dividendAmount);
logger.info("=================【微信支付回调】4444444==================");
}else if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_APPOINTMENT)){
logger.info("【微信支付回调】取消预约支付");
@ -400,9 +402,10 @@ public class CallbackServiceImpl implements CallbackService {
* 1.根据订单号查询分账记录如果有记录直接返回
* 2.根据区域id查询合伙人列表根据合伙人分红比例分账保存分账明细表
* 3.请求分账
* 分账金额dividendAmount 分账金额订单实际支付金额-平台服务费-支付手续费
*/
@Override
public boolean dividendHandle(String transactionId, EtOrder order, EtOperatingArea area) {
public boolean dividendHandle(String transactionId, EtOrder order, EtOperatingArea area, BigDecimal dividendAmount) {
List<EtDividendDetail> etDividendDetails = dividendDetailService.selectEtDividendDetailByOrderNo(order.getOrderNo());
if(ObjectUtil.isNotNull(etDividendDetails) && etDividendDetails.size()>0){
return true;
@ -426,39 +429,25 @@ public class CallbackServiceImpl implements CallbackService {
EtDividendDetail etDividendDetail = new EtDividendDetail();
AsUser asUser1 = asUserMapper.selectUserById(sysUser1.getAppUserId());
if(asUser1!=null && asUser1.getWxopenid()!=null){
BigDecimal dividendAmount = BigDecimal.ZERO;
logger.info("=============系统用户sysUser1============"+JSON.toJSONString(sysUser1));
CreateOrderReceiver receiver = new CreateOrderReceiver();
receiver.setType(ReceiverType.PERSONAL_OPENID.name());
receiver.setAccount(asUser1.getWxopenid());
String dividendItem = sysUser1.getDividendItem();
logger.info("=================分账项目dividendItem=================="+dividendItem);
if(dividendItem.contains("1")){
logger.info("=================骑行费(骑行费+预约费)==================");
dividendAmount = dividendAmount.add(order.getRidingFee().add(order.getAppointmentFee()));//1-骑行费骑行费+预约费
}
if(dividendItem.contains("2")){
logger.info("=================调度费(调度费+停车点外调度费)==================");
dividendAmount = dividendAmount.add(order.getManageFee().add(order.getDispatchFee()));//2-调度费调度费+停车点外调度费
}
logger.info("=================分账金额dividendAmount=================="+dividendAmount);
logger.info("=================分账金额(订单实际支付金额-平台服务费-支付手续费dividendAmount=================="+dividendAmount);
BigDecimal divide = new BigDecimal(sysUser1.getDividendProportion()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
logger.info("=================分账比例%=================="+divide);
BigDecimal multiply = dividendAmount.multiply(divide);
logger.info(sysUser1.getUserName()+"分账比例:"+sysUser1.getDividendProportion()+"%,分账金额:"+multiply);
receiver.setAmount(multiply.multiply(new BigDecimal(100)).longValue());
receiver.setDescription(area.getAreaName()+"共享电动车自动分账");
// receivers.add(receiver);
etDividendDetail.setAreaId(area.getAreaId());
etDividendDetail.setType(ServiceConstants.PROFITSHARING_TYPE_PARTNER);
etDividendDetail.setPartnerId(sysUser1.getUserId());
etDividendDetail.setOrderNo(order.getOrderNo());
etDividendDetail.setTotalAmount(order.getTotalFee());
etDividendDetail.setTotalAmount(order.getPayFee());
etDividendDetail.setCreateTime(DateUtils.getNowDate());
etDividendDetail.setDividendProportion(sysUser1.getDividendProportion());
etDividendDetail.setDividendAmount(multiply);
etDividendDetail.setDividendItem(dividendItem);
logger.info("【微信支付回调】保存分账明细 === " + JSON.toJSONString(etDividendDetail));
int i = dividendDetailService.insertEtDividendDetail(etDividendDetail);
if(i==0){
@ -599,7 +588,7 @@ public class CallbackServiceImpl implements CallbackService {
* 资金流水记录
* */
@Override
public void capitalFlowRecords(EtOrder order,String type,String busType,String ownerType,SysUser user,String payType) {
public EtCapitalFlow 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());
@ -656,20 +645,20 @@ public class CallbackServiceImpl implements CallbackService {
BigDecimal separateAccountFee = order.getPayFee().subtract(handlingCharge).subtract(platformServiceFee);
logger.info("【微信支付回调--保存资金流水记录】 ==============扣掉手续费和服务费之后的金额,这个金额拿来分账====================="+separateAccountFee);
BigDecimal operatorDividend = separateAccountFee;
if(sysDept.getIsProfitSharing().equals("true")){//需要分账
logger.info("【微信支付回调--保存资金流水记录】 ==============需要分账====================="+sysDept.getIsProfitSharing());
//获取所有合伙人列表
SysUser sysUser = new SysUser();
sysUser.setUserType("03");
sysUser.setAreaId(order.getAreaId());
List<SysUser> sysUsers = userMapper.selectUserList(sysUser);
double totalDividendProportion = sysUsers.stream()
.mapToDouble(SysUser::getDividendProportion)
.sum();//算出总的分成比例
BigDecimal decimal = new BigDecimal(totalDividendProportion).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
partnerDividend = operatorDividend.multiply(decimal);
operatorDividend = operatorDividend.subtract(partnerDividend);
}
// if(sysDept.getIsProfitSharing().equals("true")){//需要分账
// logger.info("【微信支付回调--保存资金流水记录】 ==============需要分账====================="+sysDept.getIsProfitSharing());
//获取所有合伙人列表
SysUser sysUser = new SysUser();
sysUser.setUserType("03");
sysUser.setAreaId(order.getAreaId());
List<SysUser> sysUsers = userMapper.selectUserList(sysUser);
double totalDividendProportion = sysUsers.stream()
.mapToDouble(SysUser::getDividendProportion)
.sum();//算出总的分成比例
BigDecimal decimal = new BigDecimal(totalDividendProportion).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
partnerDividend = operatorDividend.multiply(decimal);
operatorDividend = operatorDividend.subtract(partnerDividend);
// }
logger.info("【微信支付回调--保存资金流水记录】 ==============partnerDividend====================="+partnerDividend);
logger.info("【微信支付回调--保存资金流水记录】 ==============operatorDividend====================="+operatorDividend);
if(type.equals(ServiceConstants.FLOW_TYPE_INCOME)){
@ -751,6 +740,7 @@ public class CallbackServiceImpl implements CallbackService {
logger.info("【微信支付回调】保存资金流水记录成功");
}
}
return capitalFlow;
}
/**

View File

@ -46,6 +46,17 @@ public class EtCapitalFlowServiceImpl implements IEtCapitalFlowService
return etCapitalFlowMapper.selectEtCapitalFlowByOutTradeNo(outTradeNo);
}
/**
* 根据订单号查询资金流水
*
* @param orderNo 订单号
* @return 资金流水
*/
@Override
public List<EtCapitalFlow> selectEtCapitalFlowByOrderNo(String orderNo) {
return etCapitalFlowMapper.selectEtCapitalFlowByOrderNo(orderNo);
}
/**
* 查询资金流水列表
*

View File

@ -68,7 +68,7 @@ public class EtModelServiceImpl implements IEtModelService
Integer allNum = asDeviceService.selectCountByModelId(modelId);
etModel.setDeviceNum(allNum);
if(ObjectUtil.isNotNull(etModel.getOperator())){
List<EtOperatingArea> areaList = etOperatingAreaService.selectAreaListByDeptId2(etModel.getOperator());
List<EtOperatingArea> areaList = etOperatingAreaService.selectAreaListByDeptId2(etModel.getOperator(),null);
etModel.setAreaList(areaList);
}
}

View File

@ -387,8 +387,21 @@ public class EtOperatingAreaServiceImpl extends ServiceImpl<EtOperatingAreaMappe
* @return 选中运营区ID列表
*/
@Override
public List<EtOperatingArea> selectAreaListByDeptId2(Long deptId) {
return dao.selectAreaListByDeptId2(deptId);
public List<EtOperatingArea> selectAreaListByDeptId2(Long deptId,Long areaId) {
return dao.selectAreaListByDeptId2(deptId,areaId);
}
/**
* 查询运营区是否存在车辆
*
* @param areaId 区域id
* @return 结果 true 存在 false 不存在
*/
@Override
public boolean checkDeptExistDevice(Long areaId)
{
Integer result = asDeviceService.selectCountByAreaId(areaId);
return result > 0;
}

View File

@ -479,8 +479,8 @@ public class EtOrderServiceImpl implements IEtOrderService
*/
@Override
@Transactional
public int repairDeduction(Long areaId) {
List<EtOrder> orders = etOrderMapper.selectDeductionList(areaId);
public int repairDeduction(String startDateStr,String endDateStr,Long areaId) {
List<EtOrder> orders = etOrderMapper.selectDeductionList(startDateStr, endDateStr,areaId);
for (EtOrder order : orders) {
// 找出所有骑行费大于押金的订单把骑行费改成押金
if(order.getMark().contains("大于")){
@ -1503,13 +1503,13 @@ public class EtOrderServiceImpl implements IEtOrderService
if(ServiceConstants.ORDER_PAY_STATUS_NON_PAYMENT.equals(etOrder1.getPaid())){
throw new ServiceException("订单未支付,不能退款");
}
// 根据分账明细退款
// if(dividendDetailService.isDividendComputedByOrderNo(etOrder.getOrderNo())){
// throw new ServiceException("订单【{}】已经分账,不能退款");
// }
// 根据分账明细查询
List<EtDividendDetail> etDividendDetails = dividendDetailService.selectEtDividendDetailByOrderNo(etOrder.getOrderNo());
// boolean dividendComputedByOrderNo = dividendDetailService.isDividendComputedByOrderNo(etOrder.getOrderNo());
// List<EtCapitalFlow> etCapitalFlows = etCapitalFlowService.selectEtCapitalFlowByOrderNo(etOrder.getOrderNo());
// for (EtCapitalFlow etCapitalFlow : etCapitalFlows) {
// if(etCapitalFlow.getOwnerType().equals("1")){
// etCapitalFlow.
// }
// }
SysDept sysDept = wxPayService.getDeptObjByAreaId(etOrder1.getAreaId());
BigDecimal subtract = sysDept.getBalance().subtract(etOrder1.getTotalFee());
if(subtract.compareTo(BigDecimal.ZERO) <= 0 && sysDept.getSeparateAccount().equals("N")){

View File

@ -252,6 +252,33 @@ public class SysDeptServiceImpl implements ISysDeptService
return result > 0;
}
/**
* 查询部门是否存在运营区
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
@Override
public boolean checkDeptExistArea(Long deptId)
{
int result = deptMapper.checkDeptExistArea(deptId);
return result > 0;
}
/**
* 查询部门是否存在收费方式
*
* @param deptId 部门ID
* @return 结果 true 存在 false 不存在
*/
@Override
public boolean checkDeptExistFeeRule(Long deptId)
{
int result = deptMapper.checkDeptExistFeeRule(deptId);
return result > 0;
}
/**
* 校验部门名称是否唯一
*

View File

@ -438,7 +438,7 @@ public class SysUserServiceImpl implements ISysUserService
// }
//根据运营区id查询运营商id 运营商与运营区是一对多关系
setOperatorId(user);
return userMapper.updateUser(user);
return userMapper.updateUser2(user);
}
/**
@ -636,6 +636,8 @@ public class SysUserServiceImpl implements ISysUserService
{
checkUserAllowed(new SysUser(userId));
checkUserDataScope(userId);
// 删除app用户绑定关系
asUserService.unbindSystemUserBySysUserId(userId);
}
// 删除用户与角色关联
userRoleMapper.deleteUserRole(userIds);

View File

@ -105,12 +105,13 @@ public class WxPayService implements IWxPayService {
// 获取JSAPI所需参数
PrepayRequest request = new PrepayRequest();
request.setAmount(getAmount(order.getPayFee()));
String outTradeNo;
if(StrUtil.isBlank(order.getOutTradeNo())){
outTradeNo = IdUtils.getOrderNo("wx");
}else{
outTradeNo = order.getOutTradeNo();
}
// String outTradeNo;
// if(StrUtil.isBlank(order.getOutTradeNo())){
// outTradeNo = IdUtils.getOrderNo("wx");
// }else{
// outTradeNo = order.getOutTradeNo();
// }
String outTradeNo = IdUtils.getOrderNo("wx");
order.setOutTradeNo(outTradeNo);
order.setLocking("1");
int updateEtOrder = etOrderService.updateEtOrder(order);

View File

@ -279,6 +279,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update et_user set sys_user_id = null,role = null where user_id = #{userId}
</update>
<update id="unbindSystemUserBySysUserId">
update et_user set sys_user_id = null,role = null where sys_user_id = #{sysUserId}
</update>
<delete id="deleteUserById" parameterType="Long">
update et_user set del_flag = '2' where user_id = #{userId}
</delete>

View File

@ -60,6 +60,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
1 = 1
<if test="areaId != null "> and cf.area_id = #{areaId}</if>
<if test="orderNo != null and orderNo != ''"> and cf.order_no = #{orderNo}</if>
<if test="ownerId != null and ownerId != ''"> and cf.owner_id = #{ownerId}</if>
<if test="ownerType != null and ownerType != ''"> and cf.owner_type = #{ownerType}</if>
<if test="outTradeNo != null and outTradeNo != ''"> and cf.out_trade_no = #{outTradeNo}</if>
<if test="type != null and type != ''"> and cf.type = #{type}</if>
<if test="busType != null and busType != ''"> and cf.bus_type = #{busType}</if>
@ -96,6 +98,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where out_trade_no = #{outTradeNo}
</select>
<select id="selectEtCapitalFlowByOrderNo" resultMap="EtCapitalFlowResult">
<include refid="selectEtCapitalFlowVo"/>
where order_no = #{orderNo}
</select>
<select id="getWithdrawnFee" resultType="java.math.BigDecimal">
select COALESCE(SUM(amount), 0) from et_capital_flow f
where f.bus_type = '5'

View File

@ -110,6 +110,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join sys_dept d on d.dept_id = ad.dept_id
<where>
<if test="deptId != null"> and d.dept_id = #{deptId}</if>
<if test="areaId != null"> and a.area_id = #{areaId}</if>
</where>
</select>

View File

@ -599,7 +599,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select id="selectDeductionList" resultType="com.ruoyi.system.domain.EtOrder" parameterType="long">
select * from et_order o where o.pay_type = 'yj' and o.area_id = #{areaId}
select * from et_order o
<where>
<if test="areaId != null"> and o.area_id = #{areaId}</if>
<if test="startDateStr != null and startDateStr != ''">
AND date_format(o.pay_time,'%y%m%d') &gt;= date_format(#{startDateStr},'%y%m%d')
</if>
<if test="endDateStr != null and endDateStr != ''">
AND date_format(o.pay_time,'%y%m%d') &lt;= date_format(#{endDateStr},'%y%m%d')
</if>
AND o.pay_type = 'yj'
</where>
</select>
<insert id="insertEtOrder" parameterType="EtOrder" useGeneratedKeys="true" keyProperty="orderId">

View File

@ -18,7 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="parentName" column="parent_name" />
<result property="platformServiceFee" column="platform_service_fee" />
<result property="handlingCharge" column="handling_charge" />
<result property="isProfitSharing" column="is_profit_sharing" />
<!-- <result property="isProfitSharing" column="is_profit_sharing" />-->
<result property="separateAccount" column="separate_account" />
<result property="isUsePlatformApp" column="is_use_platform_app" />
<result property="domain" column="domain" />
@ -121,6 +121,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select count(1) from sys_user where dept_id = #{deptId} and del_flag = '0'
</select>
<select id="checkDeptExistArea" parameterType="Long" resultType="int">
select count(1) from et_operating_area a
LEFT JOIN et_area_dept ad ON ad.area_id = a.area_id
LEFT JOIN sys_dept d ON d.dept_id = ad.dept_id
where d.dept_id = #{deptId}
</select>
<select id="checkDeptExistFeeRule" parameterType="Long" resultType="int">
select count(1) from et_fee_rule where dept_id = #{deptId} and is_deleted = 0
</select>
<select id="hasChildByDeptId" parameterType="Long" resultType="int">
select count(1) from sys_dept
where del_flag = '0' and parent_id = #{deptId} limit 1
@ -158,7 +169,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="platformServiceFee != null and platformServiceFee != ''">platform_service_fee,</if>
<if test="handlingCharge != null and handlingCharge != ''">handling_charge,</if>
<if test="isProfitSharing != null and isProfitSharing != ''">is_profit_sharing,</if>
<!-- <if test="isProfitSharing != null and isProfitSharing != ''">is_profit_sharing,</if>-->
<if test="separateAccount != null and separateAccount != ''">separate_account,</if>
<if test="isUsePlatformApp != null and isUsePlatformApp != ''">is_use_platform_app,</if>
<if test="domain != null and domain != ''">domain,</if>
@ -189,7 +200,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="platformServiceFee != null and platformServiceFee != ''">#{platformServiceFee},</if>
<if test="handlingCharge != null and handlingCharge != ''">#{handlingCharge},</if>
<if test="isProfitSharing != null and isProfitSharing != ''">#{isProfitSharing},</if>
<!-- <if test="isProfitSharing != null and isProfitSharing != ''">#{isProfitSharing},</if>-->
<if test="separateAccount != null and separateAccount != ''">#{separateAccount},</if>
<if test="isUsePlatformApp != null and isUsePlatformApp != ''">#{isUsePlatformApp},</if>
<if test="domain != null and domain != ''">#{domain},</if>
@ -224,7 +235,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="platformServiceFee != null and platformServiceFee != ''">platform_service_fee = #{platformServiceFee},</if>
<if test="handlingCharge != null and handlingCharge != ''">handling_charge = #{handlingCharge},</if>
<if test="isProfitSharing != null and isProfitSharing != ''">is_profit_sharing = #{isProfitSharing},</if>
<!-- <if test="isProfitSharing != null and isProfitSharing != ''">is_profit_sharing = #{isProfitSharing},</if>-->
<if test="separateAccount != null and separateAccount != ''">separate_account = #{separateAccount},</if>
<if test="isUsePlatformApp != null and isUsePlatformApp != ''">is_use_platform_app = #{isUsePlatformApp},</if>
<if test="domain != null and domain != ''">domain = #{domain},</if>

View File

@ -233,6 +233,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where user_id = #{userId}
</update>
<update id="updateUser2" parameterType="SysUser">
update sys_user
<set>
<if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
<if test="userName != null and userName != ''">user_name = #{userName},</if>
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
<if test="userType != null and userType != ''">user_type = #{userType},</if>
<if test="email != null ">email = #{email},</if>
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
<if test="sex != null and sex != ''">sex = #{sex},</if>
<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
<if test="password != null and password != ''">password = #{password},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if>
<if test="loginDate != null">login_date = #{loginDate},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
area_id = #{areaId},
<if test="dividendProportion != null">dividend_proportion = #{dividendProportion},</if>
<if test="dividendItem != null">dividend_item = #{dividendItem},</if>
<if test="appUserId != null">app_user_id = #{appUserId},</if>
<if test="cooperationTime != null">cooperation_time = #{cooperationTime},</if>
<if test="dividendStatus != null">dividend_status = #{dividendStatus},</if>
update_time = sysdate()
</set>
where user_id = #{userId}
</update>
<update id="updateUserStatus" parameterType="SysUser">
update sys_user set status = #{status} where user_id = #{userId}
</update>