doum
7 天以前 aee5abdde781ab426771f2024d57e3429aa2b95a
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java
@@ -1,12 +1,15 @@
package com.doumee.service.business.impl;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.annotation.excel.ExcelImporter;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.tsp.*;
import com.doumee.core.utils.*;
import com.doumee.core.utils.tsp.TspSolver;
import com.doumee.core.utils.tsp.TspSolverSolutions;
import com.doumee.core.wms.model.response.WmsBaseDataResponse;
import com.doumee.core.wms.model.response.WmsBaseResponse;
import com.doumee.dao.admin.request.JkOrdersImport;
import com.doumee.dao.business.*;
import com.doumee.dao.business.model.*;
@@ -19,8 +22,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import netscape.javascript.JSObject;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
@@ -50,6 +53,8 @@
    private JkSketchCustomerMapper jkSketchCustomerMapper;
    @Autowired
    private JkCustomerMapper jkCustomerMapper;
    @Autowired
    private JkCustomerNavigationMapper jkCustomerNavigationMapper;
    @Autowired
    private JkLineMapper jkLineMapper;
@@ -95,11 +100,11 @@
        if( model.getDateInfo() ==  null){
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"该线路日期信息不正确,不支持优化!");
        }
       if(Constants.equalsInteger(Constants.ZERO,jkSketch.getForceUpdate()) && Constants.equalsInteger(model.getStatus(),Constants.ONE)){
        if(Constants.equalsInteger(Constants.ZERO,jkSketch.getForceUpdate()) && Constants.equalsInteger(model.getStatus(),Constants.ONE)){
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"该线路存在正在优化中,请耐心等待优化完成或者选择强制优化操作!");
        }
         if(  jkSketch.getLineIdList() ==null || jkSketch.getLineIdList().size()==0 ){
        if(  jkSketch.getLineIdList() ==null || jkSketch.getLineIdList().size()==0 ){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"请选择有效合理的线路进行优化操作!");
        }
        //当前所有线路(符合条件的线路)
@@ -114,7 +119,6 @@
            totalCus += Constants.formatIntegerNum(line.getMaxCustomer());//总客户量
            totalNum += Constants.formatIntegerNum(line.getMaxOrder());//总送货量
        }
        if( totalCus < Constants.formatIntegerNum(model.getOrderNum())  ){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"该线路订单客户数量超过了线路总客户量限制,无法进行优化!");
        }
@@ -139,6 +143,7 @@
    @Async
    public void startUpdateLineAsync(JkSketch model) {
        try {
            initCustomerDistance(model);
            List<JkSketchCustomer> customerList = model.getCustomerList();
            List<JkLine> lineList = model.getLineList();
            TspSolver.DataModel dataModel = new TspSolver.DataModel();
@@ -147,25 +152,17 @@
            long[] demands1 = new long[customerList.size()+1]; //各个点的订单量
            long[][] distanceMatrix1 = new long[customerList.size()+1][customerList.size()+1];
            demands1[0] =0;//原点
            double cLatitude =0;
            double cLongitude =0;
            String location = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.COMPANY_LOCATION).getCode();
            try {
                String[] ss = location.split(",");
                cLongitude = Double.parseDouble(ss[0]);
                cLatitude = Double.parseDouble(ss[1]);
            }catch (Exception e){
            }
            for (int i = 0; i < customerList.size(); i++) {
                distanceMatrix1[0][i] =  DistanceCalculator.calculateDistance(cLatitude,cLongitude,customerList.get(i).getLatitude().doubleValue(),customerList.get(i).getLongitude().doubleValue())/1000;
                distanceMatrix1[i][0] = distanceMatrix1[0][i];
                List<DistanceMapParam>  disList =  customerList.get(i).getDistanceMapParamList();
                distanceMatrix1[0][i] =  disList.get(0).getDistance();
                distanceMatrix1[i][0] = disList.get(disList.size() -1).getDistance();
                demands1[i+1] = Constants.formatBigdecimal( customerList.get(i).getTotalNum()).longValue();  //各个点的订单量
                List<Map<String,Object>> disList = customerList.get(i).getDistanceList();
                for (int j = 0; j< disList.size(); j++) {
                    if(disList.size()>j){
                        distanceMatrix1[i+1][j+1]  = (Long) disList.get(j).get("b")/1000;//构造距离矩阵
                for (int j = 0; j< disList.size()-2; j++) {
                    if(j+1 >=10){
                        break;
                    }
                    if(disList.size()>j+1){
                        distanceMatrix1[i+1][j+1]  = disList.get(j+1).getDistance()/1000;//构造距离矩阵
                    }else{
                        distanceMatrix1[i+1][j+1]  = 1l;
                    }
@@ -188,6 +185,141 @@
                    .set(JkSketch::getPlanLineEndDate,new Date()));
        }
    }
    private void initCustomerDistance(JkSketch model) {
        String url = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.GAODE_DISTANCE_GEOAPI_URL).getCode();
        List<JkCustomer> updateCustomerList = new ArrayList<>();
        List<JkCustomerNavigation> navigationList = new ArrayList<>();
        List<JkSketchCustomer> customerList = model.getCustomerList();
        Date date = new Date();
        BigDecimal cLatitude =new BigDecimal(0);
        BigDecimal cLongitude =new BigDecimal(0);
        String location = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.COMPANY_LOCATION).getCode();
        try {
            String[] ss = location.split(",");
            cLongitude = new BigDecimal(ss[0]);
            cLatitude =  new BigDecimal(ss[1]);
        }catch (Exception e){
        }
        for(JkSketchCustomer c : customerList){
            List<DistanceMapParam> tmpList = new ArrayList<>();
            List<DistanceMapParam> distanceMapParamList  = getListFromJsonStr(c.getDistanceJson());
            boolean isNew = false;
            JkCustomer u =new JkCustomer();
            DistanceMapParam t0 = new DistanceMapParam();
            t0.setId(-2);//表示返回园区
            t0.setDistance(Constants.formatLongNum(c.getStartDistance()) );
            if(Constants.formatLongNum(c.getStartDistance()) <= 0){
                //园区前往该客户的距离,如果之前未获取过
                isNew = true;
                JkSketchCustomer start = new JkSketchCustomer();
                start.setId(-1);
                start.setLongitude(cLongitude);
                start.setLatitude(cLatitude);
                DistanceModel dm = DistanceCalculator.calculateDistanceGaode(url,start,c);
                c.setStartDistance(dm.getDistance() );
                t0.setDistance(dm.getDistance());
                u.setStartDistance(dm.getDistance());
                if(dm.getLocations().size()>0){
                    //如果有路径信息
                    u.setStartSteps(dm.getPolyline());
                }
            }
            tmpList.add(t0);
            for(JkSketchCustomer cm : customerList){
                //客户和客户之间的距离信息
                DistanceMapParam t = new DistanceMapParam();
                t.setId(cm.getId());
                DistanceMapParam param = getParamByCustomerIds( cm.getId(),distanceMapParamList);
                if(param!=null){//如果之前已经获取过
                    t = param;
                }else{
                    JkCustomerNavigation navigation = new JkCustomerNavigation();
                    navigation.setStartId(c.getId());
                    navigation.setEndId(cm.getId());
                    navigation.setIsdeleted(Constants.ZERO);
                    navigation.setCreateDate(date);
                    navigation.setEditDate(date);
                    navigation.setEndLatitude(cm.getLatitude());
                    navigation.setEndLogitude(cm.getLongitude());
                    navigation.setStartLatitude(c.getLatitude());
                    navigation.setStartLogitude(c.getLongitude());
                    isNew = true;
                    if(Constants.equalsInteger(c.getCustomerId(),cm.getCustomerId())){
                        t.setDistance(0l);
                    }else{
                        DistanceModel dm = DistanceCalculator.calculateDistanceGaode(url,c,cm);
                        t.setDistance(dm.getDistance() );
                        if(dm.getLocations().size()>0){
                            //如果有路径信息
                            navigation.setSteps(dm.getPolyline());
                        }
                    }
                    navigation.setIdIndex(c.getId()+"-"+cm.getId());
                    navigation.setDistance(t.getDistance());
                    navigationList.add(navigation);
                }
                tmpList.add(t);
            }
            DistanceMapParam tt = new DistanceMapParam();
            tt.setId(-2);//表示返回园区
            tt.setDistance(Constants.formatLongNum(c.getEndDistance()));
            if(Constants.formatLongNum(c.getEndDistance()) <= 0){
                //该客户返回园区的距离 ,如果之前未获取过
                isNew = true;
                JkSketchCustomer start = new JkSketchCustomer();
                start.setId(-1);
                start.setLongitude(cLongitude);
                start.setLatitude(cLatitude);
                DistanceModel dm = DistanceCalculator.calculateDistanceGaode(url,c,start);
                c.setEndDistance(dm.getDistance() );
                tt.setDistance(dm.getDistance());
                u.setEndDistance(dm.getDistance());
                if(dm.getLocations().size()>0){
                    //如果有路径信息
                    u.setEndSteps(dm.getPolyline());
                }
            }
            tmpList.add(tt);
            if(isNew){//
                u.setId(c.getCustomerId());
                u.setDistance(JSONObject.toJSONString(tmpList));
                updateCustomerList.add(u);
            }
            c.setDistanceMapParamList(tmpList);
        }
        if(updateCustomerList.size()>0){
            for(JkCustomer c : updateCustomerList){
                jkCustomerMapper.updateById(c);//更新客户与其他点之间的距离
            }
        }
        if(navigationList.size()>0){
            jkCustomerNavigationMapper.insert(navigationList);
        }
    }
    private DistanceMapParam getParamByCustomerIds(  Integer id1, List<DistanceMapParam> distanceMapParamList) {
        if(distanceMapParamList!=null){
            for(DistanceMapParam p :distanceMapParamList){
                if(Constants.equalsInteger(p.getId(),id1)){
                    return p;
                }
            }
        }
        return null;
    }
    private List<DistanceMapParam> getListFromJsonStr(String distanceJson) {
        try {
            return  JSONObject.parseObject(distanceJson, new TypeReference<List<DistanceMapParam>>(){}.getType());
        }catch (Exception e){
        }
        return new ArrayList<>();
    }
    private void dealSearchSolution(JkSketch model, TspSolver.DataModel dataModel) {
@@ -221,7 +353,7 @@
                tModel.setCustomerList( new ArrayList<>());
                //有效路径
                for (Integer cIndex : routes){
                    if(cIndex ==0 || cIndex == routes.size()-1){
                    if(cIndex ==0){
                        continue; //起始点不处理
                    }
                    JkSketchCustomer customer = model.getCustomerList().get(cIndex-1);
@@ -239,9 +371,7 @@
                    cModel.setSketchId(model.getId());
                    cModel.setCustomerId(customer.getCustomerId());
                    tModel.getCustomerList().add(cModel);
                    if(cIndex ==0 || cIndex == routes.size()-1){
                        continue; //起始点不处理
                    }
                }
            }
        }
@@ -287,13 +417,15 @@
    }
    private   List<JkSketchCustomer>  checkJketchCustomerLocation(JkSketch model) {
        MPJLambdaWrapper<JkSketchCustomer> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(JkSketchCustomer.class )
                .selectAs(JkCustomer::getName,JkSketchCustomer::getName)
                .selectAs(JkCustomer::getCode,JkSketchCustomer::getCode)
                .selectAs(JkCustomer::getDistance,JkSketchCustomer::getDistanceJson)
                .selectAs(JkCustomer::getLongitude,JkSketchCustomer::getLongitude)
                .selectAs(JkCustomer::getLatitude,JkSketchCustomer::getLatitude)
                .selectAs(JkCustomer::getStartDistance,JkSketchCustomer::getStartDistance)
                .selectAs(JkCustomer::getEndDistance,JkSketchCustomer::getEndDistance)
                .leftJoin(JkCustomer.class,JkCustomer::getId,JkSketchCustomer::getCustomerId )
                .eq(JkSketchCustomer::getSketchId, model.getId())
                .eq(JkSketchCustomer::getIsdeleted,Constants.ZERO)
@@ -311,7 +443,7 @@
        if(StringUtils.isNotBlank(errorMsg)){
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"该线路客户:"+errorMsg+"定位信息不完整,不满足优化条件!");
        }
        for(JkSketchCustomer c : customerList){
       /* for(JkSketchCustomer c : customerList){
            List<Map<String,Object>> tmpList = new ArrayList<>();
            for(JkSketchCustomer cm : customerList){
                Map<String,Object> t = new HashMap<>();
@@ -321,7 +453,7 @@
                }else{
                    t.put("b", DistanceCalculator.calculateDistance(
                            Constants.formatBigdecimal(c.getLatitude()).doubleValue(),
                            Constants.formatBigdecimal(c.getLatitude()).doubleValue(),
                            Constants.formatBigdecimal(c.getLongitude()).doubleValue(),
                            Constants.formatBigdecimal(cm.getLatitude()).doubleValue(),
                            Constants.formatBigdecimal(cm.getLongitude()).doubleValue()));
                }
@@ -329,8 +461,8 @@
            }
            c.setDistanceList(tmpList);
        }
        if(Constants.equalsInteger(Constants.ZERO,model.getStatus())){
        */
        /*if(Constants.equalsInteger(Constants.ZERO,model.getStatus())){
            //如果是未优化状态,计算原始距离
            long totalDistance = 0;
            MPJLambdaWrapper<JkSketchLine> queryWrapper1 = new MPJLambdaWrapper<>();
@@ -359,7 +491,8 @@
                                        ,Constants.formatBigdecimal(c.getLatitude()).doubleValue()
                                        ,Constants.formatBigdecimal(c.getLongitude()).doubleValue());
                            }else{
                                totalDistance += DistanceCalculator.calculateDistance(Constants.formatBigdecimal(c.getLatitude()).doubleValue()
                                totalDistance += DistanceCalculator.calculateDistance(
                                         Constants.formatBigdecimal(c.getLatitude()).doubleValue()
                                        ,Constants.formatBigdecimal(c.getLongitude()).doubleValue()
                                        ,Constants.formatBigdecimal(last.getLatitude()).doubleValue()
                                        ,Constants.formatBigdecimal(last.getLongitude()).doubleValue());
@@ -377,7 +510,7 @@
            }
            model.setOriginDistance(totalDistance);
        }
        }*/
        return customerList;
    }