package com.stylefeng.guns.modular.crossCity.server.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
|
import com.stylefeng.guns.core.util.ToolUtil;
|
import com.stylefeng.guns.modular.crossCity.dao.*;
|
import com.stylefeng.guns.modular.crossCity.model.*;
|
import com.stylefeng.guns.modular.crossCity.server.ILineSiteService;
|
import com.stylefeng.guns.modular.crossCity.server.IOrderCrossCityService;
|
import com.stylefeng.guns.modular.crossCity.warpper.LocationWarpper;
|
import com.stylefeng.guns.modular.crossCity.warpper.SiteWarpper;
|
import com.stylefeng.guns.modular.specialTrain.model.OrderPrivateCar;
|
import com.stylefeng.guns.modular.specialTrain.server.IOrderPrivateCarService;
|
import com.stylefeng.guns.modular.system.util.DateUtil;
|
import com.stylefeng.guns.modular.system.util.GDMapElectricFenceUtil;
|
import com.stylefeng.guns.modular.system.util.GDMapGeocodingUtil;
|
import com.stylefeng.guns.modular.system.util.ResultUtil;
|
import com.stylefeng.guns.modular.system.util.SystemException;
|
import com.stylefeng.guns.modular.system.util.model.GeoFencingPolygon;
|
import com.stylefeng.guns.modular.taxi.model.OrderTaxi;
|
import com.stylefeng.guns.modular.taxi.service.IOrderTaxiService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
|
@Service
|
public class LineSiteServiceImpl extends ServiceImpl<LineSiteMapper, LineSite> implements ILineSiteService {
|
|
@Resource
|
private LineSiteMapper lineSiteMapper;
|
|
@Resource
|
private SiteMapper siteMapper;
|
|
@Resource
|
private LineShiftDriverMapper lineShiftDriverMapper;
|
|
@Resource
|
private LineShiftMapper lineShiftMapper;
|
|
@Resource
|
private LocationMapper locationMapper;
|
|
@Resource
|
private DriverSelfTripMapper driverSelfTripMapper;
|
|
@Autowired
|
private DateUtil dateUtil;
|
|
@Autowired
|
private GDMapElectricFenceUtil gdMapElectricFenceUtil;
|
|
@Resource
|
private RedisTemplate<String, Object> redisTemplate;
|
|
@Autowired
|
private IOrderTaxiService orderTaxiService;
|
|
@Autowired
|
private IOrderPrivateCarService orderPrivateCarService;
|
|
@Autowired
|
private IOrderCrossCityService orderCrossCityService;
|
|
@Autowired
|
private MongoTemplate mongoTemplate;
|
|
@Autowired
|
private GDMapGeocodingUtil gdMapGeocodingUtil;
|
|
|
/**
|
* 根据线路id获取排班数据
|
* @param lineId
|
* @param day
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public List<Map<String, Object>> queryDriver(Integer lineId, String day, Integer driverId) throws Exception {
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
Calendar c = Calendar.getInstance();
|
c.setTime(new Date());
|
c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
|
c.set(Calendar.MILLISECOND, 0);
|
if(c.getTimeInMillis() > sdf.parse(day).getTime()){
|
throw new SystemException("日期不能小于当天");
|
}
|
List<Map<String, Object>> list = new ArrayList<>();
|
List<LineShift> lineShifts = lineShiftMapper.queryByLineId(lineId);
|
List<Map<String, Object>> s = lineSiteMapper.queryDriver(lineId, sdf.parse(day), driverId);
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(sdf.parse(day));
|
String vehicle = (String) redisTemplate.opsForValue().get("VEHICLE");
|
List<Integer> integers = new ArrayList<>();
|
if(ToolUtil.isNotEmpty(vehicle)){
|
integers = JSON.parseArray(vehicle).toJavaList(Integer.class);
|
}
|
for(LineShift lineShift : lineShifts){
|
boolean b = true;
|
String[] split = lineShift.getEndTime().split(":");
|
calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
|
calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
|
if(calendar.getTimeInMillis() < System.currentTimeMillis()){//结束时间小于当前时间不显示
|
continue;
|
}
|
|
Map<String, Object> data = new HashMap<>();
|
for(Map<String, Object> map : s){
|
//先判断司机是否在限制接单范围内
|
boolean bo = false;
|
for(Integer integer : integers){
|
if(integer.compareTo(Integer.valueOf(map.get("driverId").toString())) == 0){
|
bo = true;
|
break;
|
}
|
}
|
if(bo){
|
continue;
|
}
|
|
int i = orderTaxiService.selectCount(new EntityWrapper<OrderTaxi>().eq("driverId", map.get("driverId")).in("state", Arrays.asList(2, 3, 4, 5, 11)).eq("DATE_FORMAT(travelTime, '%Y-%m-%d')", day));
|
if(i > 0){
|
continue;
|
}
|
i = orderPrivateCarService.selectCount(new EntityWrapper<OrderPrivateCar>().eq("driverId", map.get("driverId")).in("state", Arrays.asList(2, 3, 4, 5, 11)).eq("DATE_FORMAT(travelTime, '%Y-%m-%d')", day));
|
if(i > 0){
|
continue;
|
}
|
List<OrderCrossCity> driverId1 = orderCrossCityService.queryListOrder(Integer.valueOf(map.get("driverId").toString()), lineShift.getId(), Arrays.asList(5), day);
|
if(driverId1.size() > 0){
|
continue;
|
}
|
if(Integer.valueOf(map.get("laveSeat").toString()) <= 0){
|
continue;
|
}
|
if(lineShift.getId().intValue() == Integer.valueOf(map.get("id").toString()).intValue()){
|
b = false;
|
BigDecimal price = getDefaultDestinationPrice(map);
|
map.put("price", price == null ? "0" : price.toPlainString());
|
data = map;
|
list.add(data);
|
}
|
}
|
if(b){
|
data.put("id", lineShift.getId());
|
data.put("startTime", lineShift.getStartTime() + "-" + lineShift.getEndTime());
|
list.add(data);
|
}
|
}
|
return list;
|
}
|
|
private BigDecimal getDefaultDestinationPrice(Map<String, Object> map) {
|
if (map == null) {
|
return null;
|
}
|
Integer totalSeat = map.get("totalSeat") == null ? null : Integer.valueOf(map.get("totalSeat").toString());
|
BigDecimal price = totalSeat != null && totalSeat == 6 ? getBigDecimal(map.get("defaultPrice7")) : getBigDecimal(map.get("defaultPrice5"));
|
return price == null ? getBigDecimal(map.get("defaultPrice5")) : price;
|
}
|
|
private BigDecimal getBigDecimal(Object value) {
|
if (value == null || ToolUtil.isEmpty(String.valueOf(value))) {
|
return null;
|
}
|
try {
|
return new BigDecimal(String.valueOf(value));
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
|
/**
|
* 根据司机排班数据id获取数据(剩余座位号和总座位数)
|
* @param id
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public Map<String, Object> querySeat(Integer id) throws Exception {
|
Map<String, Object> map = new HashMap<>();
|
LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(id);
|
map.put("totalNumber", lineShiftDriver.getTotalSeat());
|
map.put("number", lineShiftDriver.getLaveSeat());
|
map.put("content", lineShiftDriver.getLaveSeatNumber());
|
return map;
|
}
|
|
/**
|
* 获取线路班次及司机预约情况
|
* @param lineId
|
* @param time
|
* @param driverId
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public List<Map<String, Object>> queryLineShiftInfo(Integer lineId, String time, Integer driverId) throws Exception {
|
List<LineShift> lineShifts = lineShiftMapper.selectList(new EntityWrapper<LineShift>().eq("lineId", lineId).eq("state", 1).orderBy("startTime"));
|
List<Map<String, Object>> list = new ArrayList<>();
|
Map<String, Date> date = dateUtil.getStartAndEndDate(time);
|
for(LineShift lineShift : lineShifts){
|
Map<String, Object> map = new HashMap<>();
|
map.put("id", lineShift.getId());
|
map.put("time", lineShift.getStartTime() + "-" + lineShift.getEndTime());
|
map.put("state", 3);
|
List<LineShiftDriver> lineShiftDrivers = lineShiftDriverMapper.queryByDriver(lineShift.getId(), null, (null != date ? date.get("startTime") : null));
|
if(lineShiftDrivers.size() >= lineShift.getCarNum()){
|
map.put("state", 1);
|
}
|
lineShiftDrivers = lineShiftDriverMapper.queryByDriver(lineShift.getId(), driverId, (null != date ? date.get("startTime") : null));
|
if(lineShiftDrivers.size() > 0){
|
map.put("state", 2);
|
}
|
|
//判断时间(当天时间已经过了的班次)
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
if(time.trim().equals(sdf.format(new Date()))){
|
Calendar s = Calendar.getInstance();
|
String[] split = lineShift.getEndTime().split(":");
|
s.setTime(new Date());
|
s.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
|
s.set(Calendar.MINUTE, Integer.valueOf(split[1]));
|
if(s.getTimeInMillis() < System.currentTimeMillis()){
|
map.put("state", 1);
|
}
|
}
|
|
list.add(map);
|
}
|
return list;
|
}
|
|
|
|
/**
|
* 获取站点
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public List<SiteWarpper> querySite(Integer startSiteId) throws Exception {
|
List<Map<String, Object>> sites = null;
|
if(null == startSiteId){
|
sites = siteMapper.querySite(null);
|
}else{
|
sites = siteMapper.querySite(startSiteId);
|
}
|
Set<String> set = new HashSet<>();
|
for(Map<String, Object> site : sites) {
|
set.add(site.get("cityCode").toString());
|
}
|
|
List<SiteWarpper> list = new ArrayList<>();
|
for(String c : set){
|
SiteWarpper siteWarpper = new SiteWarpper();
|
List<Object> data = new ArrayList<>();
|
String name = "";
|
String code = "";
|
for(Map<String, Object> s : sites){
|
if(c.equals(s.get("cityCode").toString())){
|
Map<String, Object> map = new HashMap<>();
|
map.put("id", s.get("id"));
|
map.put("name", s.get("name").toString());
|
name = s.get("cityName").toString();
|
code = s.get("cityCode").toString();
|
if(null == s.get("lonLat")){
|
String location = gdMapGeocodingUtil.geocoding(name + s.get("name").toString());
|
map.put("lonLat", location);
|
Site site = new Site();
|
site.setId(Integer.valueOf(s.get("id").toString()));
|
site.setLonLat(location);
|
siteMapper.updateById(site);
|
}else{
|
map.put("lonLat", s.get("lonLat").toString());
|
}
|
data.add(map);
|
}
|
}
|
siteWarpper.setName(name);
|
siteWarpper.setCode(code);
|
siteWarpper.setSites(data);
|
list.add(siteWarpper);
|
}
|
return list;
|
}
|
|
|
/**
|
* 根据站点id获取地点区域
|
* @param siteId
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public List<Map<String, Object>> queryLocation(Integer siteId) throws Exception {
|
return locationMapper.queryLocation(siteId);
|
}
|
|
@Override
|
public ResultUtil<List<LocationWarpper>> querySelfLocation(Integer driverId, Integer lineShiftDriverId, Integer type) throws Exception {
|
if (driverId == null) {
|
return ResultUtil.tokenErr();
|
}
|
if (lineShiftDriverId == null || type == null) {
|
return ResultUtil.paranErr();
|
}
|
if (type != 1 && type != 2) {
|
return ResultUtil.error("type参数错误");
|
}
|
LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(lineShiftDriverId);
|
if (lineShiftDriver == null) {
|
return ResultUtil.error("班次信息不存在");
|
}
|
if (!driverId.equals(lineShiftDriver.getDriverId())) {
|
return ResultUtil.error("无权操作此班次");
|
}
|
if (lineShiftDriver.getCustomerId() == null) {
|
return ResultUtil.error("自主行程信息不存在");
|
}
|
DriverSelfTrip selfTrip = driverSelfTripMapper.selectById(lineShiftDriver.getCustomerId());
|
if (selfTrip == null || selfTrip.getState() == null || selfTrip.getState() != 1) {
|
return ResultUtil.error("自主行程信息不存在");
|
}
|
|
List<LocationWarpper> data = new ArrayList<>();
|
if (type == 1) {
|
if (selfTrip.getStartLon() == null || selfTrip.getStartLat() == null) {
|
return ResultUtil.error("上车点坐标不存在");
|
}
|
data.add(buildCircleLocation(selfTrip.getStartLon(), selfTrip.getStartLat()));
|
return ResultUtil.success(data);
|
}
|
|
if (ToolUtil.isEmpty(selfTrip.getDestJson())) {
|
return ResultUtil.success(data);
|
}
|
JSONArray array = JSON.parseArray(selfTrip.getDestJson());
|
if (array == null) {
|
return ResultUtil.success(data);
|
}
|
for (int i = 0; i < array.size(); i++) {
|
JSONObject item = array.getJSONObject(i);
|
if (item == null) {
|
continue;
|
}
|
Double endLon = item.getDouble("endLon");
|
Double endLat = item.getDouble("endLat");
|
if (endLon == null || endLat == null) {
|
continue;
|
}
|
data.add(buildCircleLocation(endLon, endLat));
|
}
|
return ResultUtil.success(data);
|
}
|
|
private LocationWarpper buildCircleLocation(Double lon, Double lat) {
|
LocationWarpper locationWarpper = new LocationWarpper();
|
locationWarpper.setType(2);
|
locationWarpper.setCoordinate(lon + "," + lat + ";3000");
|
locationWarpper.setProvince("");
|
locationWarpper.setProvinceCode("");
|
locationWarpper.setCity("");
|
locationWarpper.setCityCode("");
|
locationWarpper.setDistrict("");
|
locationWarpper.setDistrictCode("");
|
return locationWarpper;
|
}
|
|
@Override
|
public boolean selfAreaMonitoring(Integer driverId, Integer lineShiftDriverId, Integer type, String lonLat) throws Exception {
|
if (driverId == null || lineShiftDriverId == null || type == null || ToolUtil.isEmpty(lonLat)) {
|
return false;
|
}
|
if (type != 1 && type != 2) {
|
return false;
|
}
|
String[] pointArr = lonLat.split(",");
|
if (pointArr.length != 2) {
|
return false;
|
}
|
Double pointLon;
|
Double pointLat;
|
try {
|
pointLon = Double.valueOf(pointArr[0]);
|
pointLat = Double.valueOf(pointArr[1]);
|
} catch (Exception e) {
|
return false;
|
}
|
|
LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(lineShiftDriverId);
|
if (lineShiftDriver == null || !driverId.equals(lineShiftDriver.getDriverId()) || lineShiftDriver.getCustomerId() == null) {
|
return false;
|
}
|
DriverSelfTrip selfTrip = driverSelfTripMapper.selectById(lineShiftDriver.getCustomerId());
|
if (selfTrip == null || selfTrip.getState() == null || selfTrip.getState() != 1) {
|
return false;
|
}
|
|
if (type == 1) {
|
return isWithinCircle(selfTrip.getStartLon(), selfTrip.getStartLat(), pointLon, pointLat, 3000D);
|
}
|
|
if (ToolUtil.isEmpty(selfTrip.getDestJson())) {
|
return false;
|
}
|
JSONArray array = JSON.parseArray(selfTrip.getDestJson());
|
if (array == null || array.isEmpty()) {
|
return false;
|
}
|
for (int i = 0; i < array.size(); i++) {
|
JSONObject item = array.getJSONObject(i);
|
if (item == null) {
|
continue;
|
}
|
Double endLon = item.getDouble("endLon");
|
Double endLat = item.getDouble("endLat");
|
if (isWithinCircle(endLon, endLat, pointLon, pointLat, 3000D)) {
|
return true;
|
}
|
}
|
return false;
|
}
|
|
private boolean isWithinCircle(Double centerLon, Double centerLat, Double pointLon, Double pointLat, Double radiusMeter) {
|
if (centerLon == null || centerLat == null || pointLon == null || pointLat == null || radiusMeter == null) {
|
return false;
|
}
|
double earthRadius = 6371000D;
|
double lat1 = Math.toRadians(centerLat);
|
double lat2 = Math.toRadians(pointLat);
|
double deltaLat = lat2 - lat1;
|
double deltaLon = Math.toRadians(pointLon - centerLon);
|
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
|
+ Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
|
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
double distance = earthRadius * c;
|
return distance <= radiusMeter;
|
}
|
|
|
|
/**
|
* 判断点是都在区域范围内
|
* @param siteId
|
* @param code
|
* @param lonLat
|
* @return
|
* @throws Exception
|
*/
|
@Override
|
public boolean areaMonitoring(Integer siteId, Integer code, String lonLat) throws Exception {
|
List<Map<String, Object>> list = this.queryLocation(siteId);
|
String province = code.toString().substring(0, 2) + "0000";
|
String city = code.toString().substring(0, 4) + "00";
|
for(Map<String, Object> map : list){
|
if(Integer.valueOf(map.get("type").toString()) == 1){//行政区域
|
if(null != map.get("districtCode")){
|
if(code.toString().equals(map.get("districtCode").toString())){
|
return true;
|
}
|
continue;
|
}
|
if(null != map.get("cityCode")){
|
if(city.equals(map.get("cityCode").toString())){
|
return true;
|
}
|
continue;
|
}
|
if(null != map.get("provinceCode")){
|
if(province.equals(map.get("provinceCode").toString())){
|
return true;
|
}
|
continue;
|
}
|
}
|
if(Integer.valueOf(map.get("type").toString()) == 2){//电子围栏
|
String[] split = lonLat.split(",");
|
GeoJsonPoint point = new GeoJsonPoint(Double.valueOf(split[0]), Double.valueOf(split[1]));
|
Query query = Query.query(Criteria.where("geoJsonPolygon").intersects(point));
|
List<GeoFencingPolygon> geoFencingPolygons = mongoTemplate.find(query, GeoFencingPolygon.class);
|
List<Integer> s_sites = geoFencingPolygons.stream().map(GeoFencingPolygon::getSiteId).collect(Collectors.toList());
|
if(s_sites.contains(siteId)){
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
}
|