doum
2025-09-17 e1ac26d7d749012a04afa8f98acf8607cbf0fbfe
最新版本541200007
已添加3个文件
已修改8个文件
577 ■■■■■ 文件已修改
admin/src/components/business/OperaPlatformWindow.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/platform.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/set/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/doc/月台自动加号数据库变动脚本.md 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/core/utils/DijkstraUtil.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/core/utils/GraphByMatrix.java 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/core/utils/TspSolver.java 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Platform.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/PlatformJob.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/PlatformJobServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaPlatformWindow.vue
@@ -35,11 +35,11 @@
      <el-form-item label="LED空闲文案:" prop="ledContent">
        <el-input type="text" v-model="form.ledContent" placeholder="请输入LED空闲文案" v-trim />
      </el-form-item>
      <el-form-item label="同时作业数量:" prop="workingNum">
        <el-input type="number" v-model="form.workingNum" placeholder="请输入同时作业数量" v-trim />
      <el-form-item label="同时叫号数量:" prop="workingNum">
        <el-input type="number" v-model="form.workingNum" placeholder="请输入同时叫号数量" v-trim />
      </el-form-item>
      <el-form-item label="同时准备作业数量:" prop="callReadyNum">
        <el-input type="number" v-model="form.callReadyNum" placeholder="请输入同时准备作业数量" v-trim />
      <el-form-item label="同时准备数量:" prop="callReadyNum">
        <el-input type="number" v-model="form.callReadyNum" placeholder="请输入同时准备数量" v-trim />
      </el-form-item>
      <el-form-item label="月台作业效率(万支/小时):" prop="workRate">
        <el-input type="number" v-model="form.workRate" placeholder="请输入月台作业效率(万支/小时)" v-trim />
@@ -93,7 +93,7 @@
      },
      // éªŒè¯è§„则
      rules: {
        workingNum: [{ required: true, validator: numRuleGtZero, message: '请输入同时作业数量,必须大于0! ', trigger: 'blur' }],
        workingNum: [{ required: true, validator: numRuleGtZero, message: '请输入同时叫号数量,必须大于0! ', trigger: 'blur' }],
        type: [{ required: true, message: '月台类型不能为空!', trigger: 'blur' }],
        sortnum: [{ required: true, message: '排序码不能为空!', trigger: 'blur' }]
      }
admin/src/views/platform/platform.vue
@@ -49,8 +49,8 @@
        </el-table-column>
        <el-table-column prop="groupName" label="所属月台组" fixed min-width="150px"></el-table-column>
        <el-table-column prop="sortnum" label="排序码" min-width="90px"></el-table-column>
        <el-table-column prop="workingNum" label="同时作业数量" min-width="120px"></el-table-column>
        <el-table-column prop="callReadyNum" label="同时准备作业数量" min-width="120px"></el-table-column>
        <el-table-column prop="workingNum" label="同时叫号数量" min-width="120px"></el-table-column>
        <el-table-column prop="callReadyNum" label="同时准备数量" min-width="120px"></el-table-column>
        <el-table-column prop="stayTimeoutAlarmTime" label="停留超时报警时间(分钟)" min-width="180px">
          <template scope="{row}">{{ row.stayTimeoutAlarmTime ? (row.stayTimeoutAlarmTime) : '-' }}</template>
        </el-table-column>
admin/src/views/platform/set/index.vue
@@ -25,13 +25,13 @@
      </el-table-column>
      <el-table-column
        prop="workingNum"
        label="同时作业数量"
        label="同时叫号数量"
        min-width="100"
        show-overflow-tooltip
      />
      <el-table-column
        prop="callReadyNum"
        label="同时准备车辆数"
        label="同时准备数量"
        min-width="100"
        show-overflow-tooltip
      />
@@ -122,11 +122,11 @@
            format="HH:mm"
          />
        </el-form-item>
        <el-form-item label="同时作业数量">
        <el-form-item label="同时叫号数量">
          <el-input v-model="param.workingNum" class="w300"></el-input>
          <span class="ml10">个</span>
        </el-form-item>
        <el-form-item label="同时准备作业数量">
        <el-form-item label="同时准备数量">
          <el-input v-model="param.callReadyNum" class="w300"></el-input>
          <span class="ml10">个</span>
        </el-form-item>
server/doc/ÔĄ̂×Ô¶¯¼ÓºÅÊý¾Ý¿â±ä¶¯½Å±¾.md
@@ -13,9 +13,9 @@
 
ALTER TABLE `antaiwuliu`.`platform_job`
ADD COLUMN `TAG_VIRTUAL` int NULL COMMENT '是否标记虚拟月台组 0否 1是' AFTER `ORIGIN`,
ADD COLUMN `TAG_VIRTUAL_TIME` datetime NULL COMMENT '标记虚拟月台组时间' AFTER `TAG_VIRTUAL`,
ADD COLUMN `TAG_VIRTUAL_USER` int NULL COMMENT '标记虚拟月台组人员编码' AFTER `TAG_VIRTUAL_TIME`,
ADD COLUMN `TAG_VIRTUAL` int NULL COMMENT '是否更换月台组 0否 1是' AFTER `ORIGIN`,
ADD COLUMN `TAG_VIRTUAL_TIME` datetime NULL COMMENT '更换月台组时间' AFTER `TAG_VIRTUAL`,
ADD COLUMN `TAG_VIRTUAL_USER` int NULL COMMENT '更换月台组人员编码' AFTER `TAG_VIRTUAL_TIME`,
ADD COLUMN `CALL_WAY` int NULL COMMENT '叫号方式  0手动叫号 1自动叫号' AFTER `TAG_VIRTUAL_USER`,
ADD COLUMN `URGE_TIME` datetime(0) NULL DEFAULT NULL COMMENT '加急时间' AFTER `CALL_WAY`,
ADD COLUMN `URGE_USER` int NULL DEFAULT NULL COMMENT '加急人员编码' AFTER `URGE_TIME`;
server/system_service/pom.xml
@@ -335,5 +335,11 @@
            <type>pom</type>
            <scope>import</scope>
        </dependency>-->
         <dependency>
            <groupId>com.google.ortools</groupId>
            <artifactId>ortools-java</artifactId>
            <version>9.14.6206</version>
        </dependency>
    </dependencies>
</project>
server/system_service/src/main/java/com/doumee/core/utils/DijkstraUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
package com.doumee.core.utils;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
public class DijkstraUtil {
    private Queue visited;
    int[] distance;
    public DijkstraUtil(int len) {
        // TODO Auto-generated constructor stub
        visited = new LinkedList();
        distance = new int[len];
    }
    private int getIndex(Queue q, int[] dis) {
        int k = -1;
        int min_num = Integer.MAX_VALUE;
        for (int i = 0; i < dis.length; i++) {
            if (!q.contains(i)) {
                if (dis[i] < min_num) {
                    min_num = dis[i];
                    k = i;
                }
            }
        }
        return k;
    }
    public void dijkstra(int[][] weight, Object[] str, int v) {
        HashMap path;
        path = new HashMap();
        for (int i = 0; i < str.length; i++)
            path.put(i, "");
        //初始化路径长度数组distance
        for (int i = 0; i < str.length; i++) {
            path.put(i, path.get(i) + "" + str[v]);
            if (i == v)
                distance[i] = 0;
            else if (weight[v][i] != -1) {
                distance[i] = weight[v][i];
                path.put(i, path.get(i) + "-->" + str[i]);
            } else
                distance[i] = Integer.MAX_VALUE;
        }
        visited.add(v);
        while (visited.size() < str.length) {
            int k = getIndex(visited, distance);//获取未访问点中距离源点最近的点
            visited.add(k);
            if (k != -1) {
                for (int j = 0; j < str.length; j++) {
                    //判断k点能够直接到达的点
                    if (weight[k][j] != -1) {
                        //通过遍历各点,比较是否有比当前更短的路径,有的话,则更新distance,并更新path。
                        if (distance[j] > distance[k] + weight[k][j]) {
                            distance[j] = distance[k] + weight[k][j];
                            path.put(j, path.get(k) + "-->" + str[j]);
                        }
                    }
                }
            }
        }
        for (int h = 0; h < str.length; h++) {
            System.out.printf(str[v] + "-->" + str[h] + ":" + distance[h] + " ");
            if (distance[h] == Integer.MAX_VALUE)
                System.out.print(str[v] + "-->" + str[h] + "之间没有可通行路径");
            else
                System.out.print(str[v] + "-" + str[h] + "之间有最短路径,具体路径为:" + path.get(h).toString());
            System.out.println();
        }
        visited.clear();
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
       /* int[][] weight = {
                {0, 10, 12, -1, -1, -1},
                {-1, 0, -1, 16, 25, -1},
                {4, 3, 0, 12, -1, 8},
                {-1, -1, -1, 0, 7, -1},
                {-1, -1, -1, -1, 0, -1},
                {-1, -1, -1, 2, -1, 0}};
        String[] str = {"V1", "V2", "V3", "V4", "V5", "V6"};
        int len = str.length;
        DijkstraUtil dijkstra = new DijkstraUtil(len);
        //依次让各点当源点,并调用dijkstra函数
        for (int i = 0; i < str.length; i++) {
            dijkstra.dijkstra(weight, str, i);
        }*/
        int[][] weight = {
                {0, 10, 5, 7, -1},
                {-1, 0, 4, 5, 10},
                {-1, 4, 0, 6, 5},
                {-1, 5, 6, 0, 7},
                {-1, -1, -1, -1, 0}};
        String[] str = {"A", "B", "C", "D", "E"};
        DijkstraUtil dijkstra = new DijkstraUtil(str.length);
        dijkstra.dijkstra(weight, str, 0);
    }
}
server/system_service/src/main/java/com/doumee/core/utils/GraphByMatrix.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,258 @@
package com.doumee.core.utils;
import java.util.*;
/**
 * æœ€çŸ­è·¯å¾„—Dijkstra算法和Floyd算法
 * Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。
 *
 * é—®é¢˜æè¿°ï¼šåœ¨æ— å‘图 G=(V,E) ä¸­ï¼Œå‡è®¾æ¯æ¡è¾¹ E[i] çš„长度为 w[i],找到由顶点 V0 åˆ°å…¶ä½™å„点的最短路径。(单源最短路径)
 */
public class GraphByMatrix {
    public static final boolean UNDIRECTED_GRAPH = false;//无向图标志
    public static final boolean DIRECTED_GRAPH = true;//有向图标志
    public static final boolean ADJACENCY_MATRIX = true;//邻接矩阵实现
    public static final boolean ADJACENCY_LIST = false;//邻接表实现
    public static final int MAX_VALUE = Integer.MAX_VALUE;
    private boolean graphType;
    private boolean method;
    private int vertexSize;
    private int matrixMaxVertex;
    //存储所有顶点信息的一维数组
    private Object[] vertexesArray;
    //存储图中顶点之间关联关系的二维数组,及边的关系
    private int[][] edgesMatrix;
    // è®°å½•第i个节点是否被访问过
    private boolean[] visited;
    /**
     * @param graphType å›¾çš„类型:有向图/无向图
     * @param method    å›¾çš„实现方式:邻接矩阵/邻接表
     */
    public GraphByMatrix(boolean graphType, boolean method, int size) {
        this.graphType = graphType;
        this.method = method;
        this.vertexSize = 0;
        this.matrixMaxVertex = size;
        if (this.method) {
            visited = new boolean[matrixMaxVertex];
            vertexesArray = new Object[matrixMaxVertex];
            edgesMatrix = new int[matrixMaxVertex][matrixMaxVertex];
            //对数组进行初始化,顶点间没有边关联的值为Integer类型的最大值
            for (int row = 0; row < edgesMatrix.length; row++) {
                for (int column = 0; column < edgesMatrix.length; column++) {
                    edgesMatrix[row][column] = MAX_VALUE;
                }
            }
        }
    }
    /********************最短路径****************************/
    //计算一个顶点到其它一个顶点的最短距离
    public void Dijkstra(Object obj) throws Exception {
        Dijkstra(getVertexIndex(obj));
    }
    public void Dijkstra(int v0) {
        int[] dist = new int[matrixMaxVertex];
        int[] prev = new int[matrixMaxVertex];
        //初始化visited、dist和path
        for (int i = 0; i < vertexSize; i++) {
            //一开始假定取直达路径最短
            dist[i] = edgesMatrix[v0][i];
            visited[i] = false;
            //直达情况下的最后经由点就是出发点
            if (i != v0 && dist[i] < MAX_VALUE)
                prev[i] = v0;
            else
                prev[i] = -1; //无直达路径
        }
        //初始时源点v0∈visited集,表示v0 åˆ°v0的最短路径已经找到
        visited[v0] = true;
        // ä¸‹æ¥å‡è®¾ç»ç”±ä¸€ä¸ªç‚¹ä¸­è½¬åˆ°è¾¾å…¶ä½™å„点,会近些,验证之
        // å†å‡è®¾ç»ç”±ä¸¤ä¸ªç‚¹ä¸­è½¬,会更近些,验证之,.....
        // ç›´åˆ°ç©·ä¸¾å®Œæ‰€æœ‰å¯èƒ½çš„中转点
        int minDist;
        int v = 0;
        for (int i = 1; i < vertexSize; i++) {
            //挑一个距离最近经由点,下标装入 v
            minDist = MAX_VALUE;
            for (int j = 0; j < vertexSize; j++) {
                if ((!visited[j]) && dist[j] < minDist) {
                    v = j;                             // ç»ç”±é¡¶ç‚¹j中转则距离更短
                    minDist = dist[j];
                }
            }
            visited[v] = true;
            /*顶点v并入S,由v0到达v顶点的最短路径为min.
              å‡å®šç”±v0到v,再由v直达其余各点,更新当前最后一个经由点及距离*/
            for (int j = 0; j < vertexSize; j++) {
                if ((!visited[j]) && edgesMatrix[v][j] < MAX_VALUE) {
                    if (minDist + edgesMatrix[v][j] <= dist[j]) {
                        //如果多经由一个v点到达j点的 æœ€çŸ­è·¯å¾„反而要短,就更新
                        dist[j] = minDist + edgesMatrix[v][j];
                        prev[j] = v;                    //经由点的序号
                    }
                }
            }
        }
        for (int i = 1; i < matrixMaxVertex; i++) {
            System.out.println("**" + vertexesArray[v0] + "-->" +vertexesArray[i] + " çš„æœ€çŸ­è·¯å¾„是:" + dist[i]);
        }
    }
    //获取顶点值在数组里对应的索引
    private int getVertexIndex(Object obj) throws Exception {
        int index = -1;
        for (int i = 0; i < vertexSize; i++) {
            if (vertexesArray[i].equals(obj)) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            throw new Exception("没有这个值!");
        }
        return index;
    }
    /**
     * å•源最短路径算法,用于计算一个节点到其他!!所有节点!!的最短路径
     */
    public void Dijkstra2(int v0) {
        // LinkedList实现了Queue接口 FIFO
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < vertexSize; i++) {
            visited[i] = false;
        }
        List<Map<String,Object>> result = new ArrayList<>();
        //这个循环是为了确保每个顶点都被遍历到
        int lastRow =0;
        for (int i = 0; i < vertexSize; i++) {
            if (!visited[i]) {
                queue.add(i);
                visited[i] = true;
                while (!queue.isEmpty()) {
                    int row = queue.remove();
                    Map<String,Object> map = new HashMap<>();
                    map.put("name", vertexesArray[row]);
                    map.put("row", row);
                    int tempDis =0;
                    if(row>0){
                        tempDis  = edgesMatrix[lastRow][row];
                        lastRow =row;
                    }
                    map.put("dis", tempDis);
                    result.add(map);
                    System.out.print(vertexesArray[row] + "-->");
                    for (int k = getMin(row); k >= 0; k = getMin(row)) {
                        if (!visited[k]) {
                            queue.add(k);
                            visited[k] = true;
                        }
                    }
                }
            }
        }
        System.out.println("");
        int totalDis =0;
        for(Map<String,Object> c :result){
            totalDis +=  (Integer) c.get("dis");
            System.out.print( c.get("name") + "--"+c.get("dis")+"-->");
        }
        System.out.println("");
        System.out.println("最短距离"+totalDis);
    }
    private int getMin( int row) {
        int minDist = MAX_VALUE;
        int index = 0;
        for (int j = 0; j < vertexSize; j++) {
            if ((!visited[j]) && edgesMatrix[row][j] < minDist) {
                minDist = edgesMatrix[row][j];
                index = j;
            }
        }
        if (index == 0) {
            return -1;
        }
        return index;
    }
    public boolean addVertex(Object val) {
        assert (val != null);
        vertexesArray[vertexSize] = val;
        vertexSize++;
        return true;
    }
    public boolean addEdge(int vnum1, int vnum2, int weight) {
        assert (vnum1 >= 0 && vnum2 >= 0 && vnum1 != vnum2 && weight >= 0);
        //有向图
        if (graphType) {
            edgesMatrix[vnum1][vnum2] = weight;
        } else {
            edgesMatrix[vnum1][vnum2] = weight;
            edgesMatrix[vnum2][vnum1] = weight;
        }
        return true;
    }
    public static void main(String[] args) throws Exception {
        GraphByMatrix graph = new GraphByMatrix(GraphByMatrix.DIRECTED_GRAPH, GraphByMatrix.ADJACENCY_MATRIX, 9);
        graph.addVertex("A");//0
        graph.addVertex("B");//1
        graph.addVertex("C");//2
        graph.addVertex("D");//3
        graph.addVertex("E");//4
        //A->B、C、D
        graph.addEdge(0, 1,10);
        graph.addEdge(0, 2,5);
        graph.addEdge(0, 3,7);
        //B->C、D、E
        graph.addEdge(1, 2,4);
        graph.addEdge(1, 3,5);
        graph.addEdge(1, 4,10);
        //C->B、D、E
        graph.addEdge(2, 1,4);
        graph.addEdge(2, 3,6);
        graph.addEdge(2, 4,5);
        //D->B、C、E
        graph.addEdge(3, 1,5);
        graph.addEdge(3, 2,6);
        graph.addEdge(3, 4,7);
        graph.Dijkstra(0);
        System.out.println();
        graph.Dijkstra("C");
        System.out.println();
        graph.Dijkstra2(0);
        System.out.println();
    }
}
server/system_service/src/main/java/com/doumee/core/utils/TspSolver.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,158 @@
package com.doumee.core.utils;
import com.google.ortools.Loader;
import com.google.ortools.constraintsolver.*;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TspSolver {
    public static void main(String[] args) throws Exception {
        // åˆå§‹åŒ–数据模型
        Loader.loadNativeLibraries();
        DataModel data = new DataModel();
        data.initDataList();//构造数据
        long start =System.currentTimeMillis();
        System.out.println("=============start=========="+start);
        //创建求解器manager对象,初始化求解器数据
        RoutingIndexManager manager =  new RoutingIndexManager(data.distanceMatrix.length, data.vehicleNumber, data.depot);
        // åˆå§‹åŒ–求解器
        RoutingModel routing = new RoutingModel(manager);
//        // æ³¨å†Œå›žè°ƒå‡½æ•°
        final int transitCallbackIndex =
                routing.registerTransitCallback((long fromIndex, long toIndex) -> {
                    int fromNode = manager.indexToNode(fromIndex);
                    int toNode = manager.indexToNode(toIndex);
                    return data.distanceMatrix[fromNode][toNode];
                });
        // å®šä¹‰å›žè°ƒå‡½æ•°è‡³æ¯æ¡è·¯çº¿
        routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
        // å¢žåŠ è·ç¦»ç»´åº¦çº¦æŸ
        routing.addDimension(transitCallbackIndex, 0, 30000,
                true,
                "Distance");
        RoutingDimension distanceDimension = routing.getMutableDimension("Distance");
        distanceDimension.setGlobalSpanCostCoefficient(100);
//        // æ·»åŠ å®¹é‡é™åˆ¶
        final int demandCallbackIndex = routing.registerUnaryTransitCallback((long fromIndex) -> {
            int fromNode = manager.indexToNode(fromIndex);
            return data.demands[fromNode];
        });
        routing.addDimensionWithVehicleCapacity(demandCallbackIndex, 0, data.vehicleCapacities, true, "Capacity");
        Solver solver = routing.solver();
        //设置搜索方法
        RoutingSearchParameters searchParameters =
                main.defaultRoutingSearchParameters()
                        .toBuilder()
                        .setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC)
                        .build();
        // æ‰§è¡Œç®—法
        Assignment solution = routing.solveWithParameters(searchParameters);
        // æ‰“印路线
        printSolution(data, routing, manager, solution);
        long end =System.currentTimeMillis();
        System.out.println("=============end=========="+end);
        System.out.println("=============耗时=========="+(end -start)+"(ms)"+(end -start)/1000 +"s"+(end -start)/60/1000 +"m");
    }
    static void printSolution(
            DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) {
        long maxRouteDistance = 0;
        for (int i = 0; i < data.vehicleNumber; ++i) {
            long index = routing.start(i);
            log.info("Route for Vehicle " + i + ":");
            long routeDistance = 0;
            int routeDemand = 0;
            String route = "";
            while (!routing.isEnd(index)) {
                route += manager.indexToNode(index) + " -> ";
                routeDemand += data.demands[manager.indexToNode(index)];
                long previousIndex = index;
                index = solution.value(routing.nextVar(index));
                routeDistance += routing.getArcCostForVehicle(previousIndex, index, i);
            }
            log.info(route + manager.indexToNode(index));
            log.info("Distance of the route: " + routeDistance + "m"+"  Capacity of the route:"+routeDemand+"/"+data.vehicleCapacities[i]);
            maxRouteDistance = Math.max(routeDistance, maxRouteDistance);
        }
        log.info("Maximum of the route distances: " + maxRouteDistance + "m");
    }
    static class DataModel {
        //距离矩阵
        public int lenght;
        //最大车辆限制
        public  int vehicleNumber;
        //起点
        public static final int depot = 0;
        //每一个点的商品的数量
        public   long[] demands;
        //车辆最大容载
        public   long[] vehicleCapacities ;
        public   long[][] distanceMatrix ;
        public   void initDataList(){
            lenght = 500;
            vehicleNumber = 8;
            demands = new long[lenght];
            vehicleCapacities =new long[vehicleNumber];
            distanceMatrix =  new long[lenght][lenght];
            int total0 =0;
            for (int i = 0; i <vehicleNumber ; i++) {
                long tem = (long) (Math.random() * 1000 + 20000);
                vehicleCapacities[i] = tem;
                total0+=tem;
                System.out.print(tem+" ,");
            }
            System.out.println( "\ntotal Capacity:"+total0+"=====================");
            long total = 0;
            for (int i = 0; i <lenght ; i++) {
                long tem =  (int)(Math.random()*100+100);
                demands[i] =tem;
                total+=tem;
                System.out.print(tem+" ,");
                for (int j = 0; j <lenght ; j++) {
                    if(i == j){
                        distanceMatrix[i][j] =0;
                    }
                    if(i<j){
                        distanceMatrix[i][j] =(int)(Math.random()*1000+1);
                        distanceMatrix[j][i] =    distanceMatrix[i][j];
                    }
                }
            }
            System.out.println( "\ntotal Demands:"+total+"=====================");
        }
       /* public final long[][] distanceMatrix = {
                {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
                {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
                {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
                {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
                {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
                {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
                {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
                {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
                {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
                {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
                {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
                {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
                {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
                {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
                {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
                {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
                {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0},
        };*/
    }
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Platform.java
@@ -94,11 +94,11 @@
    @ExcelColumn(name="工作结束时间")
    private String endTime;
    @ApiModelProperty(value = "同时作业数量", example = "1")
    @ExcelColumn(name="同时作业数量")
    @ApiModelProperty(value = "同时叫号数量", example = "1")
    @ExcelColumn(name="同时叫号数量")
    private Integer workingNum;
    @ApiModelProperty(value = "同时准备作业数量", example = "1")
    @ExcelColumn(name="同时准备作业数量")
    @ApiModelProperty(value = "同时准备叫号数量", example = "1")
    @ExcelColumn(name="同时准备叫号数量")
    private Integer callReadyNum;
    @ApiModelProperty(value = "作业超时报警时间(秒)", example = "1")
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/PlatformJob.java
@@ -246,11 +246,11 @@
    @ApiModelProperty(value = "签到序号", example = "1")
    private Integer signNum;
    @ApiModelProperty(value = "是否标记虚拟月台组 0否 1是", example = "1")
    @ApiModelProperty(value = "是否更换过月台组 0否 1是", example = "1")
    private Integer  tagVirtual;
    @ApiModelProperty(value = "标记虚拟月台组时间", example = "1")
    @ApiModelProperty(value = "更换过月台组时间", example = "1")
    private Date  tagVirtualTime;
    @ApiModelProperty(value = "标记虚拟月台组人员编码", example = "1")
    @ApiModelProperty(value = "更换过月台组人员编码", example = "1")
    private Integer  tagVirtualUser;
    @ApiModelProperty(value = "叫号方式  0手动叫号 1自动叫号", example = "1")
    private Integer  callWay;
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/PlatformJobServiceImpl.java
@@ -2494,11 +2494,16 @@
        BeanUtils.copyProperties(model,platformJob);
        platformJob.setPlatformGroupId(param.getPlatformGroupId());
        platformJob.setEditDate(new Date());
        platformJob.setTagVirtual(Constants.ONE);
        platformJob.setTagVirtualUser(platformJob.getEditor());
        platformJob.setTagVirtualTime(platformJob.getEditDate());
        platformJob.setEditor(loginUser.getId());
       int flag =  platformJobMapper.update(null,new UpdateWrapper<PlatformJob>().lambda()
                .set(PlatformJob::getEditDate,platformJob.getEditDate())
                .set(PlatformJob::getTagVirtualTime,platformJob.getTagVirtualTime())
                .set(PlatformJob::getEditor,platformJob.getEditor())
                .set(PlatformJob::getPlatformGroupId,param.getPlatformGroupId())
                .set(PlatformJob::getTagVirtualUser,platformJob.getEditor())
                .set(PlatformJob::getPlatformId,null)//置空分配的月台信息
                .in(PlatformJob::getStatus,Constants.PlatformJobStatus.WAIT_CONFIRM.getKey(),
                        Constants.PlatformJobStatus.WART_SIGN_IN.getKey(),