From 6500da411f234b8ad0ee493909d515bf9eeecdd5 Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期四, 16 十月 2025 19:28:27 +0800
Subject: [PATCH] 最新版本541200007

---
 admin/src/views/business/jkCustomer.vue                                                                       |   10 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchCustomerServiceImpl.java |  103 ++++++
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomerNavigation.java           |   17 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java               |    1 
 admin/src/components/business/OperaJkSketchLineListWindow.vue                                                 |   10 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketch.java                       |    3 
 admin/src/assets/icons/location-red.png                                                                       |    0 
 admin/src/components/business/OperaJkSketchResultWindow.vue                                                   |   63 +++-
 admin/package-lock.json                                                                                       |  165 +++++-----
 admin/src/assets/icons/location-blue.png                                                                      |    0 
 admin/package.json                                                                                            |    1 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchCustomerService.java          |    4 
 server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCustomerSimpleModel.java              |   17 +
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchLine.java                   |    2 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java       |   26 +
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java         |  265 +++++++++++++++++
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCustomerCloudController.java         |    7 
 admin/src/api/business/jkSketchCustomer.js                                                                    |    5 
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCloudController.java                 |   10 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchService.java                  |    6 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java                     |    2 
 admin/.env.development                                                                                        |    3 
 admin/src/components/business/OperaJkSketchLineMapWindow.vue                                                  |  176 +++++++++++
 23 files changed, 770 insertions(+), 126 deletions(-)

diff --git a/admin/.env.development b/admin/.env.development
index 80a0588..7ba1ab4 100644
--- a/admin/.env.development
+++ b/admin/.env.development
@@ -7,3 +7,6 @@
 # VUE_APP_API_URL  = 'http://10.50.250.253:8088/gateway_interface'
 
 
+#key锛�045542fc5f436b75e6c911c5c84ff8cd
+#瀵嗛挜锛�8bd38497f9aee2b75e7a888a4dfd1e6c
+VUE_APP_AMAP_KEY='045542fc5f436b75e6c911c5c84ff8cd'
diff --git a/admin/package-lock.json b/admin/package-lock.json
index 1e1e87e..161cec3 100644
--- a/admin/package-lock.json
+++ b/admin/package-lock.json
@@ -4,6 +4,11 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@amap/amap-jsapi-loader": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
+      "integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw=="
+    },
     "@babel/code-frame": {
       "version": "7.12.13",
       "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.12.13.tgz",
@@ -1886,6 +1891,63 @@
           "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
           "dev": true
         },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
         "ssri": {
           "version": "8.0.1",
           "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1617826515595&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
@@ -1893,6 +1955,28 @@
           "dev": true,
           "requires": {
             "minipass": "^3.1.1"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "vue-loader-v16": {
+          "version": "npm:vue-loader@16.8.3",
+          "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
+          "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chalk": "^4.1.0",
+            "hash-sum": "^2.0.0",
+            "loader-utils": "^2.0.0"
           }
         }
       }
@@ -14125,87 +14209,6 @@
           "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz",
           "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
           "dev": true
-        }
-      }
-    },
-    "vue-loader-v16": {
-      "version": "npm:vue-loader@16.8.3",
-      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
-      "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "chalk": "^4.1.0",
-        "hash-sum": "^2.0.0",
-        "loader-utils": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true,
-          "optional": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
-          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-          "dev": true,
-          "optional": true
-        },
-        "loader-utils": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
-          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
         }
       }
     },
diff --git a/admin/package.json b/admin/package.json
index b1d3572..d3c723e 100644
--- a/admin/package.json
+++ b/admin/package.json
@@ -13,6 +13,7 @@
     "fix": "eslint --ext .js,.vue src --fix"
   },
   "dependencies": {
+    "@amap/amap-jsapi-loader": "^1.0.1",
     "@riophae/vue-treeselect": "^0.4.0",
     "@wangeditor/editor": "^5.1.23",
     "@wangeditor/editor-for-vue": "^1.0.2",
diff --git a/admin/src/api/business/jkSketchCustomer.js b/admin/src/api/business/jkSketchCustomer.js
index 4ab690a..2672ca8 100644
--- a/admin/src/api/business/jkSketchCustomer.js
+++ b/admin/src/api/business/jkSketchCustomer.js
@@ -13,6 +13,11 @@
     trim: true
   })
 }
+export function allMapList (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkSketchCustomer/allMapList', data, {
+    trim: true
+  })
+}
 
 // 瀵煎嚭Excel
 export function exportExcel (data) {
diff --git a/admin/src/assets/icons/location-blue.png b/admin/src/assets/icons/location-blue.png
new file mode 100644
index 0000000..9bda0ac
--- /dev/null
+++ b/admin/src/assets/icons/location-blue.png
Binary files differ
diff --git a/admin/src/assets/icons/location-red.png b/admin/src/assets/icons/location-red.png
new file mode 100644
index 0000000..27ab5df
--- /dev/null
+++ b/admin/src/assets/icons/location-red.png
Binary files differ
diff --git a/admin/src/components/business/OperaJkSketchLineListWindow.vue b/admin/src/components/business/OperaJkSketchLineListWindow.vue
index 41d89d8..276d2a3 100644
--- a/admin/src/components/business/OperaJkSketchLineListWindow.vue
+++ b/admin/src/components/business/OperaJkSketchLineListWindow.vue
@@ -17,7 +17,7 @@
       <div style="display: flex;margin-top: 20px" class="orange">
         <div style="flex: 1" >绾胯矾鍘熷鎬昏矾绋嬶細
           <span  v-if="(model.originDistance ||0) > 0 ||  (model.status||0) != 0" class="red" style="font-weight: bold"> {{((model.originDistance ||0)/1000).toFixed(2)}}</span>
-          <span  v-if="(model.originDistance ||0) == 0 && (model.status||0) == 0"  class="blue" style="font-weight: bold;cursor: pointer" @click="initDistance"> 鐐瑰嚮鑾峰彇 </span> 鍏噷锛�
+          <span  v-if="(model.originDistance ||0) == 0 && (model.status||0) == 0"  class="blue" style="font-weight: bold;cursor: pointer" @click="initDistance"> 鐐瑰嚮鑾峰彇 </span> 鍏噷锛�
           <span v-if="model.status ==2">浼樺寲鍚庢�昏矾绋�:<span class="green" style="font-weight: bold"> {{((model.distance ||0)/1000).toFixed(2)}} </span> 鍏噷</span>
         </div>
       </div>
@@ -40,12 +40,13 @@
           </el-table-column>
           <el-table-column
               label="鎿嶄綔"
-              min-width="120"
+              min-width="160"
               align="center"
               fixed="right"
           >
             <template slot-scope="{row}">
               <el-button type="text" @click="$refs.operaJkSketchCustomerWindow.open('绾胯矾瀹㈡埛鏄庣粏鈥斺��', row)" icon="el-icon-view"  >鏌ョ湅瀹㈡埛</el-button>
+              <el-button type="text" @click="$refs.operaJkSketchLineMapWindow.open('绾胯矾瀹㈡埛浜ら�氳矾绾库�斺��', row)" icon="el-icon-view"  >浜ら�氳矾绾�</el-button>
             </template>
           </el-table-column>
         </el-table>
@@ -55,6 +56,7 @@
       <el-button @click="visible=false">杩斿洖</el-button>
     </template>
     <OperaJkSketchCustomerWindow ref="operaJkSketchCustomerWindow"  />
+    <OperaJkSketchLineMapWindow ref="operaJkSketchLineMapWindow"  />
   </GlobalWindow>
 </template>
 
@@ -62,11 +64,12 @@
 import BaseOpera from '@/components/base/BaseOpera'
 import GlobalWindow from '@/components/common/GlobalWindow'
 import OperaJkSketchCustomerWindow from '@/components/business/OperaJkSketchCustomerWindow'
+import OperaJkSketchLineMapWindow from '@/components/business/OperaJkSketchLineMapWindow'
 import { initOriginDistance } from '@/api/business/jkSketch'
 export default {
   name: 'OperaJkSketchLineWindow',
   extends: BaseOpera,
-  components: { GlobalWindow, OperaJkSketchCustomerWindow },
+  components: { GlobalWindow, OperaJkSketchCustomerWindow ,OperaJkSketchLineMapWindow},
   data () {
     return {
       // 琛ㄥ崟鏁版嵁
@@ -103,6 +106,7 @@
         if(res){
           that.model.originDistance = res.originDistance
           that.model.distance = res.distance
+          that.loadList()
         }
       })
     },
diff --git a/admin/src/components/business/OperaJkSketchLineMapWindow.vue b/admin/src/components/business/OperaJkSketchLineMapWindow.vue
new file mode 100644
index 0000000..ba6a6ed
--- /dev/null
+++ b/admin/src/components/business/OperaJkSketchLineMapWindow.vue
@@ -0,0 +1,176 @@
+<template>
+  <GlobalWindow
+    :title="title"
+    width="100%"
+    :visible.sync="visible"
+  >
+    <div id="container"></div>
+    <div id="panel" style='position: absolute; right: 10px;top: 10px;height: 480px;width: 300px;z-index: 100;overflow: auto;'></div>
+    <template   v-slot:footer>
+      <el-button @click="visible=false">杩斿洖</el-button>
+    </template>
+  </GlobalWindow>
+</template>
+
+<script>
+import BaseOpera from '@/components/base/BaseOpera'
+import GlobalWindow from '@/components/common/GlobalWindow'
+import AMapLoader from '@amap/amap-jsapi-loader'
+import blueIcon from '@/assets/icons/location-blue.png'
+import redIcon from '@/assets/icons/location-red.png'
+export default {
+  name: 'OperaJkSketchMapWindow',
+  extends: BaseOpera,
+  components: { GlobalWindow },
+  data () {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      visible: false,
+      title: '',
+      dataList: [],
+      locations: [],
+      map: null,
+      model: {
+      }
+    }
+  },
+  created () {
+    this.config({
+      module: '浜ゆ帶-绾胯矾浼樺寲绾胯矾瀹㈡埛璁板綍淇℃伅琛�',
+      api: '/business/jkSketchCustomer',
+      'field.id': 'id',
+      'field.main': 'id'
+    })
+  },
+  methods: {
+    open (title, row) {
+      this.title = title + (row.lineName)
+      this.visible = true
+      this.dataList = []
+      this.model = row
+      this.locations = []
+      this.initAMap()
+    },
+    loadCustomer () {
+      var that = this
+      this.api.allMapList({
+        sketchLineId: this.model.id
+      }).then(res => {
+        that.dataList = res || []
+        that.locations = []
+        that.dataList.forEach((item, index) => {
+          var allsteps = []
+          allsteps.push([item.startLogitude, item.startLatitude])
+          const steps = (item.steps || '').split(';')
+          if (index != that.dataList.length - 1 || true) {
+            steps.forEach(item1 => {
+              const ll = (item1 || '').split(',')
+              allsteps.push(ll)
+            })
+            allsteps.push([item.endLogitude, item.endLatitude])
+          }
+          try {
+            /*  console.log(item)
+                var driving = new AMap.Driving({
+                  map: that.map,
+                  panel: 'panel'
+                })
+                driving.search(new AMap.LngLat(item.startLogitude, item.startLatitude), new AMap.LngLat(item.endLogitude, item.endLatitude), function (status, result) {
+                  if (status === 'complete') {
+                    console.log('缁樺埗椹捐溅璺嚎瀹屾垚')
+                  } else {
+                    console.error('鑾峰彇椹捐溅鏁版嵁澶辫触锛�' + result)
+                  }
+                }) */
+          } catch (e) {
+
+          }
+          var color = index === that.dataList.length - 1 ? '#a10e0e' : '#157713'
+          var polyline = new AMap.Polyline({
+            path: [allsteps],
+            isOutline: true,
+            outlineColor: color || '#157713',
+            borderWeight: 1,
+            strokeColor: color || '#157713',
+            strokeOpacity: 1,
+            strokeWeight: 2,
+            // 鎶樼嚎鏍峰紡杩樻敮鎸� 'dashed'
+            strokeStyle: 'solid',
+            // strokeStyle鏄痙ashed鏃舵湁鏁�
+            strokeDasharray: [10, 5],
+            lineJoin: 'round',
+            lineCap: 'round',
+            zIndex: 100
+          })
+
+          that.map.add([polyline])
+          that.map.setFitView()
+
+          const icon = new AMap.Icon({
+            size: new AMap.Size(30, 50), // 鍥炬爣灏哄
+            image: index === 0 ? redIcon : blueIcon
+          })
+
+          var marker = new AMap.Marker({
+            position: new AMap.LngLat(item.startLogitude, item.startLatitude),
+            icon: index === 0 ? redIcon : blueIcon,
+            anchor: 'bottom-center',
+            offset: new AMap.Pixel(0, 0)
+          })
+          var title = (index == 0 ? '鍥尯' : (index + '.' + item.name + (' ' + item.location || ''))) + '锛�' + (index != that.dataList.length - 1 ? '璺濅笅涓�绔欙細' : '杩斿洖鍥尯锛�') + ((item.distance || 0) / 1000) + '鍏噷'
+          marker.setTitle(title)
+          var contnet = '<div>' + (index == 0 ? '鍥尯' : (index + '.' + item.name)) + '</div>'
+          marker.setLabel({
+            direction: 'right',
+            offset: new AMap.Pixel(0, 0),
+            content: contnet
+          })
+          marker.setMap(that.map)
+          // that.locations.push(allsteps)
+        })
+      })
+    },
+    initAMap () {
+      var that = this
+      AMapLoader.load({
+        key: process.env.VUE_APP_AMAP_KEY,
+        version: '2.0',
+        plugins: ['AMap.ToolBar', 'AMap.Driving'],
+        AMapUI: {
+          version: '1.1',
+          plugins: []
+        },
+        Loca: {
+          version: '2.0' // 鏁版嵁鍙鍖�
+        }
+      }).then((AMap) => {
+        that.map = new AMap.Map('container', {
+          viewMode: '2D', // 榛樿浣跨敤 2D 妯″紡
+          zoom: 20, // 鍒濆鍖栧湴鍥惧眰绾�
+          center: [118.39, 31.28] // 鍒濆鍖栧湴鍥句腑蹇冪偣
+        })
+        this.loadCustomer()
+      }).catch(e => {
+        console.log(e)
+      })
+    },
+    getRandomColor (index, total) {
+      const r = 21
+      // const g = 80 +(index*50/total);
+      const g = 120
+      const b = 19
+      return `rgb(${r}, ${g}, ${b})`
+    }
+  }
+}
+</script>
+<style>
+#container {
+  padding: 0px;
+  margin: 0px;
+  width: 100%;
+  height: 90%;
+  position: absolute;
+}
+
+</style>
diff --git a/admin/src/components/business/OperaJkSketchResultWindow.vue b/admin/src/components/business/OperaJkSketchResultWindow.vue
index 961e82f..ed5e3ed 100644
--- a/admin/src/components/business/OperaJkSketchResultWindow.vue
+++ b/admin/src/components/business/OperaJkSketchResultWindow.vue
@@ -28,12 +28,16 @@
           <el-table-column prop="dateInfo" label="閫佽揣鏃ユ湡" min-width="130px"></el-table-column>
           <el-table-column prop="lineName" label="閫佽揣绾胯矾" min-width="130px">  </el-table-column>
           <el-table-column prop="orderNum" label="瀹㈡埛鏁�(鎴�)" min-width="130px"> </el-table-column>
-          <el-table-column prop="totalNum" label="閫佽揣閲�(鏉�)" min-width="130px"></el-table-column>
+          <el-table-column prop="totalNum" label="閫佽揣閲�/鏈�澶ч噺(鏉�)" min-width="130px">
+            <template slot-scope="{row}">
+             {{row.totalNum ||0}} / {{row.maxOrder || 0}}
+            </template>
+          </el-table-column>
           <el-table-column prop="carCode" label="杞︾墝鍙�" min-width="100px"></el-table-column>
           <el-table-column prop="memberName" label="閫佽揣鍙告満" min-width="100px"></el-table-column>
           <el-table-column prop="distance" label="鎬昏矾绋�(鍏噷)" min-width="100px">
             <template slot-scope="{row}">
-              {{((row.distance ||0)/1000).toFixed(2)}}
+             {{((row.distance ||0)/1000).toFixed(2)}}(璋冩暣鍓�)
             </template>
           </el-table-column>
           <el-table-column
@@ -42,11 +46,11 @@
               align="left"
               fixed="right"
           >
-            <template slot-scope="{row}">
+            <template slot-scope="{row}" v-if="dataList.length>1">
               <el-button type="text" @click="updateDo(row)" icon="el-icon-edit"   style="color: #0d68ff" v-if="!updating" >寰皟</el-button>
               <template v-else-if="updating &&  currentRow.id ===row.id" >
                 <el-button type="text" style="color: #13ce66"  >鏈溅</el-button>
-                <el-button type="text" @click="cancelDo(row)"  icon="el-icon-delete"  style="color: red" >鍙栨秷</el-button>
+                <el-button type="text" @click="cancelDo(row)"  icon="el-icon-circle-close"  style="color: red" >鍙栨秷</el-button>
               </template>
               <el-button type="text" @click="addDo(row)" icon="el-icon-plus"  style="color: red" v-else-if="updating &&  currentRow.id !==row.id" >鍔犲叆</el-button>
             </template>
@@ -60,7 +64,8 @@
       <div>
         <p class="tip-warn"><i class="el-icon-warning"></i>鎿嶄綔璇存槑锛�<br>
           1.璇烽�夋嫨鑻ュ共瀹㈡埛淇℃伅锛岀偣鍑讳笂杩板叾浠栫嚎璺悗鐨�<span class="red">銆愬姞鍏ャ��</span>鎸夐挳锛屽皢閫変腑鐨勫鎴风Щ鍔犲埌瀵瑰簲绾胯矾涓�;<br>
-            2.鐐瑰嚮鏈溅绾胯矾鍚庣殑<span class="red">銆愬彇娑堛��</span>鎸夐挳锛屽彲鎾ら攢鏈溅寰皟鎿嶄綔;<br>
+          2.鐐瑰嚮鏈溅绾胯矾鍚庣殑<span class="red">銆愬彇娑堛��</span>鎸夐挳锛屽彲鎾ら攢鏈溅寰皟鎿嶄綔;<br>
+          3.缁忚繃璋冩暣鍚庣殑绾胯矾璺▼鏁拌绛夊緟鎻愪氦鍚庢煡鐪�;<br>
         </p>
         <el-table  :data="paginatedData" stripe  @selection-change="handleSelectionChange">>
           <el-table-column type="selection" width="55"></el-table-column>
@@ -87,6 +92,7 @@
     </div>
     <template   v-slot:footer>
       <el-button @click="confirmDo" type="primary" v-if="buttonName!==''">{{ buttonName||'纭' }}</el-button>
+      <el-button @click="resetData" type="danger" v-if="buttonName!==''">鎾ら攢鎵�鏈夎皟鏁�</el-button>
       <el-button @click="visible=false">杩斿洖</el-button>
     </template>
   </GlobalWindow>
@@ -96,6 +102,7 @@
 import BaseOpera from '@/components/base/BaseOpera'
 import GlobalWindow from '@/components/common/GlobalWindow'
 import { allList as customerList } from '@/api/business/jkSketchCustomer'
+import { updateSketchLine } from '@/api/business/jkSketch'
 export default {
   name: 'OperaJkSketchLineWindow',
   extends: BaseOpera,
@@ -104,11 +111,13 @@
     return {
       // 琛ㄥ崟鏁版嵁
       updating: false,
+      edited: false,
       currentRow: null,
       model: {
       },
       buttonName: '',
       dataList: [],
+      originDataList: [],
       currentPage: 1,
       pageSize: 10,
       totalItems: 0, // 鎬绘暟鎹潯鐩暟
@@ -131,8 +140,28 @@
     }
   },
   methods: {
+    resetData () {
+      this.buttonName = ''
+      this.cancelDo()
+      this.loadList()
+    },
     confirmDo () {
-
+      this.isWorking = true
+      updateSketchLine({
+        id: this.model.id,
+        sketchLineList: this.dataList
+      })
+        .then(() => {
+          this.visible = false
+          this.$tip.apiSuccess('绾胯矾璋冩暣宸插畬鎴愶紒')
+          this.$emit('success')
+        })
+        .catch(e => {
+          // this.$tip.apiFailed(e)
+        })
+        .finally(() => {
+          this.isWorking = false
+        })
     },
     open (title, target) {
       this.title = title + target.categoryName
@@ -153,7 +182,7 @@
       this.selectRows = []
       this.updating = true
     },
-    cancelDo (row) {
+    cancelDo () {
       this.selectRows = []
       this.currentRow = null
       this.updating = false
@@ -177,22 +206,22 @@
           tarray.push(item)
         }
       })
-      if(tarray.length === 0){
+      if (tarray.length === 0) {
         this.$message.error('瀵逛笉璧凤紝鏈溅绾胯矾鑷冲皯鐣欏瓨涓�涓鎴蜂俊鎭紝鏃犳硶鍏ㄩ儴娓呯┖锛�')
         return
       }
-      var rArray =  row.customerList || []
-      rArray = rArray.push(...this.selectRows)
+      var rArray = [...row.customerList || []]
+      rArray.push(...this.selectRows)
       let ttNum = 0
       rArray.forEach(item => {
         ttNum += (item.totalNum || 0)
       })
-      if(tarray.length >= (row.maxCustomer||0)){
-        this.$message.error('瀵逛笉璧凤紝鍔犲叆鐨勭嚎璺渶澶ф敮鎸�'+ (row.maxOrderNum||0) + '瀹㈡埛锛�')
+      if (tarray.length >= (row.maxCustomer || 0)) {
+        this.$message.error('瀵逛笉璧凤紝鍔犲叆鐨勭嚎璺渶澶ф敮鎸�' + (row.maxCustomer || 0) + '瀹㈡埛锛�')
         return
       }
-      if(ttNum >= (row.maxOrder||0)){
-        this.$message.error('瀵逛笉璧凤紝鍔犲叆鐨勭嚎璺渶澶ф敮鎸�'+ (row.maxOrder||0) + '閫佽揣閲忥紒')
+      if (ttNum >= (row.maxOrder || 0)) {
+        this.$message.error('瀵逛笉璧凤紝鍔犲叆鐨勭嚎璺渶澶ф敮鎸�' + (row.maxOrder || 0) + '閫佽揣閲忥紝褰撳墠鏂规锛�' + ttNum)
         return
       }
       this.currentRow.customerList = tarray
@@ -204,6 +233,9 @@
       this.currentRow = null
       this.updating = false
       this.buttonName = '淇濆瓨璋冩暣寮�濮嬩紭鍖�'
+
+      console.log(this.dataList)
+      console.log(this.originDataList)
     },
     handleSelectionChange (rows) {
       this.selectRows = rows
@@ -229,7 +261,8 @@
       this.api.allList({
         sketchId: this.model.id
       }).then(res => {
-        this.dataList = res
+        this.dataList = [...(res || [])]
+        this.originDataList = JSON.parse(JSON.stringify(res||[]));
         this.loadCustomerList()
       })
     },
diff --git a/admin/src/views/business/jkCustomer.vue b/admin/src/views/business/jkCustomer.vue
index 813fd6b..3e63429 100644
--- a/admin/src/views/business/jkCustomer.vue
+++ b/admin/src/views/business/jkCustomer.vue
@@ -31,8 +31,9 @@
       </el-form-item>
       <el-form-item label="浜ら�氳鍒掔姸鎬�" prop="distanceStatus">
         <el-select v-model="searchForm.distanceStatus" clearable filterable placeholder="璇烽�夋嫨浜ら�氳鍒掔姸鎬�"  @change="search">
-          <el-option  :value="0" label="鏈畬鎴�"></el-option>
-          <el-option  :value="1" label="宸插畬鎴�"></el-option>
+          <el-option  :value="2" label="鏈畾浣�"></el-option>
+          <el-option  :value="0" label="鏈鍒�"></el-option>
+          <el-option  :value="1" label="宸茶鍒�"></el-option>
         </el-select>
       </el-form-item>
       <section>
@@ -68,8 +69,9 @@
         <el-table-column prop="sortno" label="搴忓彿" min-width="100px"></el-table-column>
         <el-table-column prop="distanceStatus" label="浜ら�氳鍒掔姸鎬�" min-width="100px" align="center">
           <template slot-scope="{row}">
-            <span v-if="row.distanceStatus === 1" class="green">宸插畬鎴�</span>
-            <span v-else class="blue">鏈畬鎴�</span>
+            <span v-if="row.distanceStatus === 2" class="red">鏈畾浣�</span>
+            <span v-else-if="row.distanceStatus === 1" class="green">宸茶鍒�</span>
+            <span v-else class="blue">鏈鍒�</span>
           </template>
         </el-table-column>
         <el-table-column prop="editDate" label="鏇存柊鏃堕棿" min-width="140px"></el-table-column>
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCloudController.java
index 34800e7..d3e69ca 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCloudController.java
@@ -75,6 +75,16 @@
         return ApiResponse.success(null);
     }
 
+    @ApiOperation("鏍规嵁ID淇敼")
+    @PostMapping("/updateSketchLine")
+    @CloudRequiredPermission("business:jksketch:update")
+    public ApiResponse updateSketchLine(@RequestBody JkSketch jkSketch, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkSketch.setLoginUserInfo(this.getLoginUser(token));
+        JkSketch model = jkSketchService.updateSketchLine(jkSketch);
+        jkSketchService.startEditSketchLineAsync(model);//寮傛浼樺寲
+        return ApiResponse.success(null);
+    }
+
     @ApiOperation("鏍规嵁ID閲嶆柊璁$畻褰撳墠绾胯矾鐨勮窛绂�")
     @PostMapping("/initOriginDistance")
     @CloudRequiredPermission("business:jksketch:update")
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCustomerCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCustomerCloudController.java
index 3bfdf73..88c55c9 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCustomerCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkSketchCustomerCloudController.java
@@ -5,6 +5,7 @@
 import com.doumee.core.annotation.excel.ExcelExporter;
 import com.doumee.core.annotation.pr.PreventRepeat;
 import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.JkCustomerNavigation;
 import com.doumee.dao.business.model.JkSketchCustomer;
 import com.doumee.service.business.JkSketchCustomerService;
 import com.doumee.service.business.third.model.ApiResponse;
@@ -81,6 +82,12 @@
     public ApiResponse<List<JkSketchCustomer>> allList (@RequestBody JkSketchCustomer pageWrap) {
         return ApiResponse.success(jkSketchCustomerService.findList(pageWrap));
     }
+    @ApiOperation("鍒楄〃鏌ヨ")
+    @PostMapping("/allMapList")
+    @CloudRequiredPermission("business:jksketchcustomer:query")
+    public ApiResponse<List<JkCustomerNavigation> > allMapList (@RequestBody JkSketchCustomer pageWrap) {
+        return ApiResponse.success(jkSketchCustomerService.allMapList(pageWrap));
+    }
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCustomerSimpleModel.java b/server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCustomerSimpleModel.java
new file mode 100644
index 0000000..2588927
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCustomerSimpleModel.java
@@ -0,0 +1,17 @@
+package com.doumee.core.tsp;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+@Slf4j
+@Data
+public class DistanceCustomerSimpleModel {
+     private long distance;
+     private List<String> locations;
+     private String polyline;
+     private Integer startId;
+     private Integer endId;
+
+}
\ No newline at end of file
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java
index cf21153..d9f55d4 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomer.java
@@ -89,7 +89,7 @@
     @ApiModelProperty(value = "鐘舵�� 0姝e父 绂佺敤", example = "1")
     //@ExcelColumn(name="鐘舵�� 0姝e父 绂佺敤")
     private Integer status;
-    @ApiModelProperty(value = "璺濈璁$畻鐘舵�� 0鏈绠� 1宸茶绠�", example = "1")
+    @ApiModelProperty(value = "璺濈璁$畻鐘舵�� 0鏈绠� 1宸茶绠� 2鏈畾浣�", example = "1")
     //@ExcelColumn(name="鐘舵�� 0姝e父 绂佺敤")
     private Integer distanceStatus;
     @ApiModelProperty(value = "瀹㈡埛闂磋窛绂婚泦鍚�", example = "1")
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomerNavigation.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomerNavigation.java
index c83b38f..e431477 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomerNavigation.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCustomerNavigation.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -68,24 +69,28 @@
     @ExcelColumn(name="閫斿緞缁忕含搴﹂泦鍚堬紝鍒嗗彿闅斿紑")
     private String steps;
 
-    @ApiModelProperty(value = "缁村害", example = "1")
+    @ApiModelProperty(value = "璧风偣绾害", example = "1")
     @ExcelColumn(name="缁村害")
     private BigDecimal startLatitude;
 
-    @ApiModelProperty(value = "瀹㈡埛搴忓彿", example = "1")
+    @ApiModelProperty(value = "缁堢偣绾害", example = "1")
     @ExcelColumn(name="瀹㈡埛搴忓彿")
     private BigDecimal endLatitude;
 
-    @ApiModelProperty(value = "閫佽揣璺嚎缂栫爜锛堝叧鑱攋k_line)", example = "1")
-    @ExcelColumn(name="閫佽揣璺嚎缂栫爜锛堝叧鑱攋k_line)")
+    @ApiModelProperty(value = "璧风偣缁忓害", example = "1")
     private BigDecimal startLogitude;
 
-    @ApiModelProperty(value = "鐘舵�� 0姝e父 绂佺敤", example = "1")
-    @ExcelColumn(name="鐘舵�� 0姝e父 绂佺敤")
+    @ApiModelProperty(value = "缁堢偣缁忓害", example = "1")
     private BigDecimal endLogitude;
 
     @ApiModelProperty(value = "璧锋鐐笽D缁勫悎锛坰tartId-endId)")
     @ExcelColumn(name="璧锋鐐笽D缁勫悎锛坰tartId-endId)")
     private String idIndex;
+    @ApiModelProperty(value = "瀹㈡埛鍚嶇О")
+    @TableField(exist = false)
+    private String name;
+    @ApiModelProperty(value = "瀹㈡埛鍦板潃")
+    @TableField(exist = false)
+    private String location;
 
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketch.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketch.java
index 38b8f3e..802fafc 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketch.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketch.java
@@ -118,6 +118,9 @@
     @ApiModelProperty(value = "绾胯矾闆嗗悎", example = "1")
     @TableField(exist = false)
     List<JkLine> lineList;
+    @ApiModelProperty(value = "绾胯矾闆嗗悎(璋冩暣鍚庯級", example = "1")
+    @TableField(exist = false)
+    List<JkSketchLine> sketchLineList;
     @ApiModelProperty(value = "绾胯矾缂栫爜闆嗗悎", example = "1")
     @TableField(exist = false)
     List<Integer> lineIdList;
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java
index 26240d5..04530d7 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchCustomer.java
@@ -146,4 +146,5 @@
     @ApiModelProperty(value = "鍚岀彮缁勯棿瀹㈡埛浣嶇疆璺濈鏁扮粍锛孾{a:12,b:100},{a:13,b:200},...],a锛氬鎴风紪鐮侊紝b锛氫笌瀹㈡埛a涔嬮棿鐨勮窛绂�")
     @TableField(exist = false)
     private List<DistanceMapParam> distanceMapParamList;
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchLine.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchLine.java
index b785c86..9b951b7 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchLine.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkSketchLine.java
@@ -85,6 +85,8 @@
     private Date dateInfo;
 
 
+    @ApiModelProperty(value = "浜ら�氳鍒掓槑缁嗭紙json鏁扮粍闆嗗悎锛�", example = "1")
+    private String steps;
     @ApiModelProperty(value = "杞︾墝鍙�", example = "1")
     @TableField(exist = false)
     private String carCode;
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchCustomerService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchCustomerService.java
index 355b865..124eafb 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchCustomerService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchCustomerService.java
@@ -1,5 +1,6 @@
 package com.doumee.service.business;
 
+import com.doumee.dao.business.model.JkCustomerNavigation;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.dao.business.model.JkSketchCustomer;
@@ -78,7 +79,8 @@
      * @return List<JkSketchCustomer>
      */
     List<JkSketchCustomer> findList(JkSketchCustomer jkSketchCustomer);
-  
+    List<JkCustomerNavigation>  allMapList(JkSketchCustomer jkSketchCustomer);
+
     /**
      * 鍒嗛〉鏌ヨ
      *
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchService.java
index 45c1a3c..9254770 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkSketchService.java
@@ -38,7 +38,7 @@
      * @param jkSketch 瀹炰綋瀵硅薄
      */
     void delete(JkSketch jkSketch);
-
+    void initAyncsJob();
     /**
      * 鎵归噺涓婚敭鍒犻櫎
      *
@@ -108,4 +108,8 @@
     void distanceCustomer(Category model );
 
     Category   checkDataValid(JkSketch model);
+
+    JkSketch updateSketchLine(JkSketch jkSketch);
+
+    void startEditSketchLineAsync(JkSketch model);
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java
index acd94f9..5cb15bf 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCustomerServiceImpl.java
@@ -111,6 +111,12 @@
                 .set(JkCustomer::getLatitude,jkCustomer.getLatitude())
                 .set(JkCustomer::getLongitude,jkCustomer.getLongitude())
                 .set(JkCustomer::getEditor,jkCustomer.getLoginUserInfo().getId())
+                .set(JkCustomer::getStartDistance,null)
+                .set(JkCustomer::getEndDistance,null)
+                .set(JkCustomer::getStartSteps,null)
+                .set(JkCustomer::getEndSteps,null)
+                .set(JkCustomer::getDistanceStatus,Constants.ZERO)
+                .set(JkCustomer::getDistance,null)
                 .set(JkCustomer::getEditDate,new Date())
                 .eq(JkCustomer::getId,jkCustomer.getId())
         );
@@ -237,10 +243,10 @@
         try {
             LambdaQueryWrapper<JkCustomer> queryWrapper = new LambdaQueryWrapper<>();
             queryWrapper.isNotNull(JkCustomer::getLocation);
-            queryWrapper.isNotNull(JkCustomer::getLocation);
             queryWrapper.and(wrapper ->{
                 wrapper.isNull(JkCustomer::getLatitude)
-                        .or().isNull(JkCustomer::getLongitude); });
+                        .or().isNull(JkCustomer::getLongitude)
+                        .or().eq(JkCustomer::getDistanceStatus,Constants.TWO);});
             //鏌ヨ鍏ㄩ儴鏈夊湴鍧�锛屼絾鏄病鏈夌粡绾害鐨勫鎴蜂俊鎭�
             List<JkCustomer>  list = jkCustomerMapper.selectList(queryWrapper);
             if(list ==null || list.size()==0){
@@ -269,13 +275,18 @@
                             jkCustomerMapper.update(null,new UpdateWrapper<JkCustomer>().lambda()
                                     .set(JkCustomer::getLatitude,c.getLatitude())
                                     .set(JkCustomer::getLongitude,c.getLongitude())
+                                    .set(JkCustomer::getStartDistance,null)
+                                    .set(JkCustomer::getEndDistance,null)
+                                    .set(JkCustomer::getStartSteps,null)
+                                    .set(JkCustomer::getEndSteps,null)
+                                    .set(JkCustomer::getDistanceStatus,Constants.ZERO)
+                                    .set(JkCustomer::getDistance,null)
                                     .set(JkCustomer::getEditDate,new Date())
                                     .eq(JkCustomer::getId,c.getId())
                             );
                         }
                     }else{
-                        log.error("鏇存柊浜ゆ帶涓績瀹㈡埛缁忕含搴︿俊鎭�=====鑾峰彇json=========="+json);
-                        log.error("鏇存柊浜ゆ帶涓績瀹㈡埛缁忕含搴︿俊鎭�=====鑾峰彇澶辫触=========="+urlStr+c.getName()+"-"+c.getLocation());
+                        log.error("鏇存柊浜ゆ帶涓績瀹㈡埛缁忕含搴︿俊鎭�=====鑾峰彇json=========="+urlStr+"\n"+c.getName()+"\n"+json);
                     }
                 }catch (Exception e){
                     log.error("鏇存柊浜ゆ帶涓績瀹㈡埛缁忕含搴︿俊鎭�=====澶辫触=========="+c.getName()+"-"+c.getLocation());
@@ -394,10 +405,17 @@
             tModel.setCreator(loginUserInfo.getId());
             tModel.setCreateDate(new Date());
             tModel.setIsnew(Constants.ONE);
+            tModel.setDistanceStatus(Constants.TWO);//闇�瑕侀噸鏂板畾浣�
             tModel.setStatus(Constants.ZERO);
             tModel.setDistanceStatus(Constants.ZERO);
             newList.add(tModel);
         }else{
+            if(StringUtils.isBlank(model.getLocation()) ||
+                    StringUtils.equals(tModel.getLocation().replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]","")
+                    ,model.getLocation().replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]",""))){
+                //濡傛灉浣嶇疆淇℃伅鍙戠敓鍙樺寲
+                tModel.setDistanceStatus(Constants.TWO);//闇�瑕侀噸鏂板畾浣�
+            }
             tModel.setIsnew(Constants.ZERO);
             updateList.add(tModel);
         }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchCustomerServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchCustomerServiceImpl.java
index 467a4b4..338bd2e 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchCustomerServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchCustomerServiceImpl.java
@@ -1,6 +1,9 @@
 package com.doumee.service.business.impl;
 
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.biz.system.SystemDictDataBiz;
 import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.JkCustomerNavigationMapper;
 import com.doumee.dao.business.model.*;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
@@ -17,7 +20,9 @@
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -29,7 +34,11 @@
 public class JkSketchCustomerServiceImpl implements JkSketchCustomerService {
 
     @Autowired
+    private SystemDictDataBiz systemDictDataBiz;
+    @Autowired
     private JkSketchCustomerMapper jkSketchCustomerMapper;
+    @Autowired
+    private JkCustomerNavigationMapper jkCustomerNavigationMapper;
 
     @Override
     public Integer create(JkSketchCustomer jkSketchCustomer) {
@@ -82,6 +91,100 @@
         return jkSketchCustomerMapper.selectOne(wrapper);
     }
 
+    /**
+     * 鏌ヨ鍏ㄩ儴浜ら�氳鍒掕矾绾�
+     * @param jkSketchCustomer
+     * @return
+     */
+    @Override
+    public List<JkCustomerNavigation>  allMapList(JkSketchCustomer jkSketchCustomer) {
+        List<JkCustomerNavigation> list = new ArrayList<>();
+        MPJLambdaWrapper<JkSketchCustomer> queryWrapper = new MPJLambdaWrapper<>();
+        jkSketchCustomer.setIsdeleted(Constants.ZERO);
+        queryWrapper.selectAll(JkSketchCustomer.class )
+                .selectAs(JkCustomer::getName,JkSketchCustomer::getName)
+                .selectAs(JkCustomer::getCode,JkSketchCustomer::getCode)
+                .selectAs(JkCustomer::getStartDistance,JkSketchCustomer::getStartDistance)
+                .selectAs(JkCustomer::getEndDistance,JkSketchCustomer::getEndDistance)
+                .selectAs(JkCustomer::getLatitude,JkSketchCustomer::getLatitude)
+                .selectAs(JkCustomer::getLongitude,JkSketchCustomer::getLongitude)
+                .selectAs(JkCustomer::getStartSteps,JkSketchCustomer::getStartSteps)
+                .selectAs(JkCustomer::getEndSteps,JkSketchCustomer::getEndSteps)
+                .selectAs(JkCustomer::getLocation,JkSketchCustomer::getLocation)
+                .leftJoin(JkCustomer.class,JkCustomer::getId,JkSketchCustomer::getCustomerId ) ;
+        queryWrapper.eq( JkSketchCustomer::getSketchLineId,jkSketchCustomer.getSketchLineId())
+                    .eq( JkSketchCustomer::getIsdeleted,Constants.ZERO);
+
+        BigDecimal cLatitude =new BigDecimal(0);
+        BigDecimal cLongitude =new BigDecimal(0);
+
+        String comLocation = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.COMPANY_LOCATION).getCode();
+        try {
+            String[] ss = comLocation.split(",");
+            cLongitude = new BigDecimal(ss[0]);
+            cLatitude =  new BigDecimal(ss[1]);
+        }catch (Exception e){
+        }
+        List<JkSketchCustomer> allList =  jkSketchCustomerMapper.selectJoinList(JkSketchCustomer.class,queryWrapper);
+        if(allList !=null && allList.size()>0){
+            JkCustomerNavigation startmodel = new JkCustomerNavigation();
+            startmodel.setStartId(-1);
+            startmodel.setName("鍥尯");
+            startmodel.setStartLatitude(cLatitude);
+            startmodel.setStartLogitude(cLongitude);
+            startmodel.setEndLatitude(allList.get(0).getLatitude());
+            startmodel.setEndLogitude(allList.get(0).getLongitude());
+            startmodel.setDistance(allList.get(0).getStartDistance());
+            startmodel.setSteps(allList.get(0).getStartSteps());
+            if(StringUtils.isBlank(startmodel.getSteps())){
+                startmodel.setSteps(comLocation +";"+allList.get(0).getLongitude()+","+allList.get(0).getLatitude());
+            }
+            list.add(startmodel);
+
+            for (int i = 0; i < allList.size(); i++) {
+                if(allList.size() == i+1){
+                    JkCustomerNavigation endmodel = new JkCustomerNavigation();
+                    endmodel.setStartId(-1);
+                    endmodel.setLocation(allList.get(i).getLocation());
+                    endmodel.setName(allList.get(i).getName());
+                    endmodel.setSteps(allList.get(i).getEndSteps());
+                    endmodel.setStartLatitude(allList.get(i).getLatitude());
+                    endmodel.setStartLogitude(allList.get(i).getLongitude());
+                    endmodel.setDistance(allList.get(0).getEndDistance());
+                    endmodel.setEndLatitude(cLatitude);
+                    endmodel.setEndLogitude(cLongitude);
+                    if(StringUtils.isBlank(startmodel.getSteps())){
+                        startmodel.setSteps(allList.get(i).getLongitude()+","+allList.get(i).getLatitude()+";"+comLocation);
+                    }
+                    list.add(endmodel);
+                    break;
+                }
+                JkSketchCustomer start = allList.get(i);
+                JkSketchCustomer end = allList.get(i+1);
+                JkCustomerNavigation tt = jkCustomerNavigationMapper.selectOne(new QueryWrapper<JkCustomerNavigation>().lambda()
+                        .eq(JkCustomerNavigation::getIsdeleted,Constants.ZERO)
+                        .eq(JkCustomerNavigation::getIdIndex, allList.get(i).getCustomerId()+"-"+ allList.get(i+1).getCustomerId())
+                        .orderByDesc(JkCustomerNavigation::getId)
+                        .last("limit 1")
+                );
+                if(tt==null){
+                    //鍙湁璧锋鐐�
+                    tt = new JkCustomerNavigation();
+                    tt.setStartLatitude(start.getLatitude());
+                    tt.setStartLogitude(start.getLongitude());
+                    tt.setEndLatitude(end.getLatitude());
+                    tt.setEndLogitude(end.getLongitude());
+                }
+                tt.setLocation(allList.get(i).getLocation());
+                tt.setName(allList.get(i).getName());
+                if(StringUtils.isBlank(tt.getSteps())){
+                    tt.setSteps(start.getLongitude()+","+end.getLatitude()+";"+end.getLongitude()+","+end.getLatitude());
+                }
+                list.add(tt);
+            }
+        }
+        return list;
+    }
     @Override
     public List<JkSketchCustomer> findList(JkSketchCustomer jkSketchCustomer) {
         MPJLambdaWrapper<JkSketchCustomer> queryWrapper = new MPJLambdaWrapper<>();
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java
index c7ef282..437120d 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java
@@ -33,6 +33,7 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.PostConstruct;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.Date;
@@ -85,6 +86,22 @@
     public void delete(JkSketch jkSketch) {
         UpdateWrapper<JkSketch> deleteWrapper = new UpdateWrapper<>(jkSketch);
         jkSketchMapper.delete(deleteWrapper);
+    }
+
+
+    @Override
+    @PostConstruct
+    public void initAyncsJob() {
+        //閲嶇疆浜ら�氳鍒掑拰绾胯矾瑙勫垝鐨勫紓姝ヤ换鍔$姸鎬�
+        jkSketchMapper.update(null,new UpdateWrapper<JkSketch>().lambda()
+                .set(JkSketch::getStatus,Constants.THREE)
+                .eq(JkSketch::getIsdeleted,Constants.ZERO)
+                .eq(JkSketch::getStatus,Constants.ONE));
+        categoryMapper.update(null,new UpdateWrapper<Category>().lambda()
+                .set(Category::getStatus,Constants.ZERO)
+                .eq(Category::getType,Constants.FOUR)
+                .eq(Category::getIsdeleted,Constants.ZERO)
+                .eq(Category::getStatus,Constants.TWO));
     }
 
     @Override
@@ -142,6 +159,77 @@
         jkSketchMapper.updateById(model);
         return model;
     }
+
+    @Override
+    public  JkSketch updateSketchLine(JkSketch jkSketch) {
+        JkSketch model = jkSketchMapper.selectById(jkSketch.getId());
+        if(model == null ||Constants.equalsInteger(model.getIsdeleted(),Constants.ONE)){
+            throw  new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        if(  jkSketch.getSketchLineList() ==null || jkSketch.getSketchLineList().size()==0 ){
+            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"璇锋寜瑕佹眰璋冩暣浼樺寲鏂规锛�");
+        }
+        if(Constants.equalsInteger(model.getStatus(),Constants.ONE)){
+            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠绾胯矾姝e瓨鍦ㄤ紭鍖栦换鍔★紝璇疯�愬績绛夊緟浼樺寲瀹屾垚鍐嶈繘琛岃璋冩暣鎿嶄綔锛�");
+        }
+
+        //褰撳墠鎵�鏈夌嚎璺�(绗﹀悎鏉′欢鐨勭嚎璺級
+        List<JkSketchLine> lineList =  jkSketchLineMapper.selectJoinList(JkSketchLine.class,new MPJLambdaWrapper<JkSketchLine>()
+                .selectAll(JkSketchLine.class )
+                .selectAs(JkLine::getName,JkSketchLine::getLineName)
+                .selectAs(JkLine::getMaxOrder,JkSketchLine::getMaxOrder)
+                .selectAs(JkLine::getMaxCustomer,JkSketchLine::getMaxCustomer)
+                .leftJoin(JkLine.class,JkLine::getId,JkOrders::getLineId )
+                .eq(JkSketchLine::getSketchId,jkSketch.getId())
+                .eq(JkSketchLine::getIsdeleted,Constants.ZERO));
+        if(lineList ==null ||lineList.size() ==0){
+            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠绾胯矾涓嶆弧瓒充紭鍖栨柟妗堣皟鏁存潯浠讹紒");
+        }
+        for(JkSketchLine line :lineList){
+            JkSketchLine lineParam =getLineParamById(line.getId(),jkSketch.getSketchLineList());
+            if(lineParam == null){
+                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"璇峰熀浜庣幇鏈夌嚎璺繘琛屾柟妗堣皟鏁达紝绾胯矾銆�"+line.getLineName()+"銆戠嚎璺厤缃笉姝g‘锛�");
+            }
+            if(lineParam.getCustomerList() == null || lineParam.getCustomerList().size() == 0 ){
+                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"璇峰熀浜庣幇鏈夌嚎璺繘琛屾柟妗堣皟鏁达紝绾胯矾銆�"+line.getLineName()+"銆戝鎴蜂俊鎭笉鑳戒负绌猴紒");
+            }
+            Integer totalCus = 0;
+            BigDecimal totalNum =new BigDecimal(0);
+            for(JkSketchCustomer customer :lineParam.getCustomerList()){
+                 totalCus += 1;//鎬诲鎴烽噺
+                 totalNum = totalNum.add(Constants.formatBigdecimal(customer.getTotalNum()));//鎬婚�佽揣閲�
+                 customer.setSketchLineId(line.getId());
+            }
+            if( totalCus > Constants.formatIntegerNum(line.getMaxCustomer()) ){
+                throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"绾胯矾銆�"+line.getLineName()+"銆戠嚎璺鍗曞鎴锋暟閲忚秴杩囦簡绾胯矾鎬诲鎴烽噺闄愬埗锛屾棤娉曡繘琛岃皟鏁达紒");
+            }
+            if( totalNum.doubleValue() > Constants.formatIntegerNum(line.getMaxOrder())){
+                throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"绾胯矾銆�"+line.getLineName()+"銆戣鍗曢�佽揣閲忚秴杩囦簡绾胯矾鎬婚�佽揣閲忛檺鍒讹紝鏃犳硶杩涜璋冩暣锛�");
+            }
+            lineParam.setTotalNum(totalNum);
+            lineParam.setOrderNum(totalCus);
+        }
+        model.setSketchLineList(jkSketch.getSketchLineList());//绾胯矾淇℃伅
+        model.setStatus(Constants.ONE);
+        model.setEditDate(new Date());
+        model.setEditor(jkSketch.getLoginUserInfo().getId());
+        model.setPlanLineDate(model.getEditDate());
+        model.setPlanLineUserId(jkSketch.getLoginUserInfo().getId());
+        model.setJobId(UUID.randomUUID().toString());
+        redisTemplate.opsForValue().set(Constants.RedisKeys.JKLINE_JOB+model.getJobId(),true );//鍋氬紓姝ュ鐞�
+        jkSketchMapper.updateById(model);
+        return model;
+    }
+
+    private JkSketchLine getLineParamById(Integer id, List<JkSketchLine> sketchLineList) {
+        for(JkSketchLine line: sketchLineList){
+            if(Constants.equalsInteger(line.getId(),id)){
+                return line;
+            }
+        }
+        return  null;
+    }
+
     @Override
     public JkSketch initOriginDistance(JkSketch jkSketch ) {
         JkSketch model = jkSketchMapper.selectById(jkSketch.getId());
@@ -344,7 +432,7 @@
         }
         String errorMsg ="";
         for(JkCustomer c1 : customerList){
-            if(c1.getLatitude()==null || c1.getLongitude() ==null){
+            if(c1.getLatitude()==null || c1.getLongitude() ==null || Constants.equalsInteger(c1.getDistanceStatus(),Constants.TWO)){
                 errorMsg += c.getName()+"-"+c.getName()+" | ";
             }
         }
@@ -367,13 +455,17 @@
             long[] vehicleCapacities1=new long[lineList.size()];//姣忚締杞︾殑鏈�澶ц鍗曢噺闄愬埗
             long[] demands1 = new long[customerList.size()+1]; //鍚勪釜鐐圭殑璁㈠崟閲�
             long[][] distanceMatrix1 = new long[customerList.size()+1][customerList.size()+1];
+            distanceMatrix1[0][0] = 0;
             demands1[0] =0;//鍘熺偣
             for (int i = 0; i < customerList.size(); i++) {
                 List<DistanceMapParam>  disList =  customerList.get(i).getDistanceMapParamList();
-                distanceMatrix1[0][i] =  disList.get(0).getDistance();
-                distanceMatrix1[i][0] = disList.get(disList.size() -1).getDistance();
+                distanceMatrix1[0][i+1] =  disList.get(0).getDistance();
+                distanceMatrix1[i+1][0] = disList.get(disList.size() -1).getDistance();
                 demands1[i+1] = Constants.formatBigdecimal( customerList.get(i).getTotalNum()).longValue();  //鍚勪釜鐐圭殑璁㈠崟閲�
-                for (int j = 0; j< disList.size()-2; j++) {
+                for (int j = 0; j < customerList.size(); j++) {
+                    distanceMatrix1[i+1][j+1] =disList.get(j+1).getDistance() ;
+                }
+               /* for (int j = 0; j< disList.size()-2; j++) {
                     if(j+1 >=10){
                         break;
                     }
@@ -382,7 +474,7 @@
                     }else{
                         distanceMatrix1[i+1][j+1]  = 1l;
                     }
-                }
+                }*/
             }
             for (int i = 0; i < lineList.size(); i++) {
                 vehicleCapacities1[i] = lineList.get(i).getMaxOrder();//姣忚締杞︾殑鏈�澶ц鍗曢噺闄愬埗
@@ -402,6 +494,149 @@
         }
 
     }
+    @Override
+    @Async
+    public  void startEditSketchLineAsync(JkSketch model) {
+        boolean success = true;
+        int totalDistance = 0;
+        List<JkSketchLine> lineList = model.getSketchLineList();
+        try {
+            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)
+                    .orderByAsc(JkSketchCustomer::getSortnum);
+            List<JkSketchCustomer> customerList = jkSketchCustomerMapper.selectJoinList(JkSketchCustomer.class,queryWrapper);
+            if(customerList == null ||customerList.size() ==0){
+                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"璇ョ嚎璺鎴蜂俊鎭负绌猴紝涓嶆弧瓒充紭鍖栨潯浠讹紒");
+            }
+
+            int totalNum = 0;
+            for(JkSketchLine line : lineList){
+                //瀹屽杽绾胯矾瀹㈡埛浼樺寲鍙傛暟
+                List<JkSketchCustomer> customerListParam =  line.getCustomerList() ;
+                if(customerListParam ==null || customerListParam.size()==0){
+                    throw  new BusinessException(ResponseStatus.BAD_REQUEST);
+                }
+                initSketchCustomerListParam(line.getCustomerList(),customerList) ;
+                totalNum += customerListParam.size();
+            }
+            if(totalNum != Constants.formatIntegerNum(model.getOrderNum())){
+                throw  new BusinessException(ResponseStatus.BAD_REQUEST);
+            }
+            for(JkSketchLine line : lineList){
+                //閫愪釜璺嚎浼樺寲
+                List<JkSketchCustomer> customerListParam =  line.getCustomerList() ;
+                TspSolver.DataModel dataModel = new TspSolver.DataModel();
+                int vehicleNumber1 = 1;//绾胯矾鏁伴噺
+                long[] vehicleCapacities1=new long[]{line.getMaxOrder()};//姣忚締杞︾殑鏈�澶ц鍗曢噺闄愬埗
+                long[] demands1 = new long[customerListParam.size()+1]; //鍚勪釜鐐圭殑璁㈠崟閲�
+                long[][] distanceMatrix1 = new long[customerListParam.size()+1][customerListParam.size()+1];
+                distanceMatrix1[0][0] = 0;
+                demands1[0] =0;//鍘熺偣
+                for (int i = 0; i < customerListParam.size(); i++) {
+                    List<DistanceMapParam>  disList =  customerListParam.get(i).getDistanceMapParamList();
+                    distanceMatrix1[0][i+1] =  disList.get(0).getDistance();
+                    distanceMatrix1[i+1][0] = disList.get(disList.size() -1).getDistance();
+                    demands1[i+1] = Constants.formatBigdecimal( customerListParam.get(i).getTotalNum()).longValue();  //鍚勪釜鐐圭殑璁㈠崟閲�
+                    for (int j = 0; j < customerListParam.size(); j++) {
+                        distanceMatrix1[i+1][j+1] =disList.get(j+1).getDistance() ;
+                    }
+
+                }
+                //鏋勯�犱紭鍖栨暟鎹ā鍨�
+                dataModel.initDataInfo(vehicleNumber1,demands1,vehicleCapacities1,distanceMatrix1);
+                TspSolver.startSearch(dataModel);
+                if(dataModel.getSolutions()==null || dataModel.getSolutions().size()==0){
+                    throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"绾胯矾銆�"+line.getLineName()+"銆戣皟鏁村け璐� 锛屾湭鑾峰緱鏈�浼樹氦閫氳鍒掓柟妗堬紒");
+                }
+                TspSolverSolutions so = dataModel.getSolutions().get(0);
+                List<Integer> routes = so.getRouteIndex();
+                totalDistance += so.getDistance();
+                if(routes.size() <=2) {
+                    throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"绾胯矾銆�"+line.getLineName()+"銆戣皟鏁村け璐� 锛屾湭鑾峰緱鏈�浼樹氦閫氳鍒掓柟妗堬紒");
+                }
+                //鏈夋晥璺緞
+                for (Integer cIndex : routes){
+                    if(cIndex ==0){
+                        continue; //璧峰鐐逛笉澶勭悊
+                    }
+                    JkSketchCustomer customer = customerListParam.get(cIndex-1);
+                    customer.setSortnum(cIndex-1);
+                }
+                line.setDistance(so.getDistance());
+            }
+
+        }catch (Exception e){
+            e.printStackTrace();
+            success =false;
+        }finally {
+            if(success){
+                List<JkSketchCustomer> allList = new ArrayList<>();
+                for(JkSketchLine line : lineList){
+                    allList.addAll(line.getCustomerList());
+                }
+                jkSketchLineMapper.updateById(lineList);
+                jkSketchCustomerMapper.updateById(allList);
+            }
+            jkSketchMapper.update(null,new UpdateWrapper<JkSketch>().lambda()
+                    .eq(JkSketch::getId,model.getId() )
+                    .eq(JkSketch::getJobId,model.getJobId() )
+                    .set(success,JkSketch::getDistance,totalDistance)
+                    .set(JkSketch::getPlanLineInfo,success?"鏈�杩戜竴娆$嚎璺皟鏁存垚鍔�":"鏈�杩戜竴娆$嚎璺皟鏁村け璐ワ紒")
+                    .set(JkSketch::getStatus,success?Constants.TWO:Constants.THREE)
+                    .set(JkSketch::getPlanLineEndDate,new Date()));
+        }
+
+    }
+
+    private List<JkSketchCustomer> initSketchCustomerListParam(List<JkSketchCustomer> customerList, List<JkSketchCustomer> customerList1) {
+        for(JkSketchCustomer param : customerList){
+            for(JkSketchCustomer model : customerList1){
+              if(Constants.equalsInteger(model.getId(),param.getId())){
+                  param.setLatitude(model.getLatitude());
+                  param.setLongitude(model.getLongitude());
+                  param.setStartDistance(model.getStartDistance());
+                  param.setEndDistance(model.getEndDistance());
+                  param.setDistanceJson(model.getDistanceJson());
+              }
+            }
+        }
+        for(JkSketchCustomer c : customerList){
+            List<DistanceMapParam> tmpList = new ArrayList<>();
+            List<DistanceMapParam> distanceMapParamList  = getListFromJsonStr(c.getDistanceJson());
+            DistanceMapParam t0 = new DistanceMapParam();
+            t0.setId(-2);//琛ㄧず杩斿洖鍥尯
+            t0.setDistance(Constants.formatLongNum(c.getStartDistance()) );
+            tmpList.add(t0);
+            for(JkSketchCustomer cm : customerList){
+                //瀹㈡埛鍜屽鎴蜂箣闂寸殑璺濈淇℃伅
+                DistanceMapParam t = new DistanceMapParam();
+                t.setId(cm.getCustomerId());
+                t.setDistance(0);
+                DistanceMapParam param = getParamByCustomerIds( cm.getCustomerId(),distanceMapParamList);
+                if(param!=null){//濡傛灉涔嬪墠宸茬粡鑾峰彇杩�
+                    t = param;
+                }
+                tmpList.add(t);
+            }
+            DistanceMapParam tt = new DistanceMapParam();
+            tt.setId(-2);//琛ㄧず杩斿洖鍥尯
+            tt.setDistance(Constants.formatLongNum(c.getEndDistance()));
+            tmpList.add(tt);
+            c.setDistanceMapParamList(tmpList);
+        }
+        return  customerList;
+    }
+
 
     private void initCustomerDistance( List<JkSketchLine> lineList,JkSketch model,boolean updateLineDistance) {
         List<JkSketchCustomer> customerList = model.getCustomerList();
@@ -443,13 +678,22 @@
             for (JkSketchLine line :lineList){
                 long lineDistance = 0;
                 List<JkSketchCustomer> customers = getCustomerListByLineId(line.getId(),customerList);
+                int index =0;
                 for(JkSketchCustomer c : customers){
-                    lineDistance+= Constants.formatLongNum(c.getStartDistance());
-                    lineDistance+= Constants.formatLongNum(c.getEndDistance());
-                    for(JkSketchCustomer cm : customers){
+                    if(index ==0){
+                        lineDistance+= Constants.formatLongNum(c.getStartDistance());
+                    }
+                    if(index == customers.size()-1){
+                        lineDistance+= Constants.formatLongNum(c.getEndDistance());
+                        break;
+                    }
+                    DistanceMapParam param = getParamByCustomerIds( customers.get(index+1).getCustomerId(),getListFromJsonStr(c.getDistanceJson()));
+                    lineDistance += param.getDistance();
+                    index++;
+                  /*  for(JkSketchCustomer cm : customers){
                         DistanceMapParam param = getParamByCustomerIds( cm.getCustomerId(),getListFromJsonStr(c.getDistanceJson()));
                         lineDistance += param.getDistance();
-                    }
+                    }*/
                 }
                 if(updateLineDistance && Constants.equalsInteger(model.getStatus(),Constants.ZERO) ){
                     line.setDistance(lineDistance);
@@ -503,10 +747,11 @@
         if(solutions!=null && solutions.size()>0){
             for(TspSolverSolutions so : solutions){
                 List<Integer> routes = so.getRouteIndex();
+                totalDistance+= so.getDistance();
                 if(routes.size() <=2) {
                     continue;//鏃犲鎴风殑闈炴湁鏁堣矾绾�
                 }
-                totalDistance+= so.getDistance();
+//                totalDistance+= so.getDistance();
                 JkLine  line =model.getLineList().get(so.getLineIndex());
                 JkSketchLine tModel =  new JkSketchLine();
                 tModel.setSketchId(model.getId());

--
Gitblit v1.9.3