Преглед изворни кода

冰排释冷、保温箱实时轨迹、历史轨迹

unknown пре 1 недеља
родитељ
комит
f0136babfe
55 измењених фајлова са 2369 додато и 459 уклоњено
  1. 11 27
      package-lock.json
  2. 1 1
      package.json
  3. 1 1
      public/index.html
  4. 8 0
      src/api/company.js
  5. 24 0
      src/api/incubator.js
  6. 4 5
      src/api/waybill.js
  7. 2 5
      src/assets/css/global.css
  8. 72 3
      src/assets/fonts/demo_index.html
  9. 15 3
      src/assets/fonts/iconfont.css
  10. 0 0
      src/assets/fonts/iconfont.js
  11. 21 0
      src/assets/fonts/iconfont.json
  12. BIN
      src/assets/fonts/iconfont.ttf
  13. BIN
      src/assets/fonts/iconfont.woff
  14. BIN
      src/assets/fonts/iconfont.woff2
  15. BIN
      src/assets/images/incubator.png
  16. BIN
      src/assets/images/truck.png
  17. 31 0
      src/assets/js/blockSort.js
  18. 1 0
      src/components/MapContainer.vue
  19. 7 3
      src/components/MapDelivery.vue
  20. 626 102
      src/components/centerControl.vue
  21. 20 4
      src/components/forms.vue
  22. 3 3
      src/components/mobileHumiture.vue
  23. 37 25
      src/components/orderDetails.vue
  24. 24 4
      src/components/tables.vue
  25. 3 0
      src/components/thermography.vue
  26. 3 3
      src/components/waybillInformation.vue
  27. 124 0
      src/config/deliveryman.js
  28. 166 0
      src/config/intendant.js
  29. 20 0
      src/config/salesman.js
  30. 1 3
      src/main.js
  31. 34 39
      src/router/generator-routers.js
  32. 1 0
      src/utils/request.js
  33. 23 4
      src/views/IceCreamFreezer/IceManagement.vue
  34. 15 5
      src/views/IceCreamFreezer/IceTracingManagement.vue
  35. 141 2
      src/views/IceCreamFreezer/freezer.js
  36. 74 1
      src/views/IceCreamFreezer/iceRaft.js
  37. 24 0
      src/views/IceCreamFreezer/store.js
  38. 24 20
      src/views/IceCreamFreezer/storeManagement.vue
  39. 17 1
      src/views/OrderManagement/completed.js
  40. 1 1
      src/views/OrderManagement/delivered.js
  41. 15 0
      src/views/OrderManagement/pendingOrder.vue
  42. 7 0
      src/views/OrderManagement/rejectionOrder.vue
  43. 1 1
      src/views/OrderManagement/uncertain.js
  44. 48 5
      src/views/OrderManagement/uncertainOrder.vue
  45. 217 109
      src/views/WaybillInquiry.vue
  46. 1 1
      src/views/common/topNav.vue
  47. 1 1
      src/views/login.vue
  48. 229 33
      src/views/newInquiry.vue
  49. 10 4
      src/views/page/statisticalManagement.vue
  50. 11 1
      src/views/system/CompanyManagement.vue
  51. 84 3
      src/views/system/IncubatorManagement.vue
  52. 63 0
      src/views/system/company.js
  53. 95 22
      src/views/system/incubator.js
  54. 3 2
      vue.config.js
  55. 5 12
      yarn.lock

+ 11 - 27
package-lock.json

@@ -8,6 +8,7 @@
       "name": "baozhida-logistics",
       "version": "0.1.0",
       "dependencies": {
+        "@amap/amap-jsapi-loader": "^1.0.1",
         "axios": "^1.6.8",
         "core-js": "^3.8.3",
         "crypto-js": "^4.2.0",
@@ -21,7 +22,6 @@
         "vue-amap": "^0.5.10",
         "vue-buffer": "^0.0.1",
         "vue-router": "^3.5.1",
-        "vue-seamless-scroll": "^1.1.23",
         "vuex": "^3.6.2"
       },
       "devDependencies": {
@@ -177,6 +177,11 @@
         "node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21"
       }
     },
+    "node_modules/@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=="
+    },
     "node_modules/@ampproject/remapping": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -4875,11 +4880,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/comutils": {
-      "version": "1.1.19",
-      "resolved": "https://registry.npmmirror.com/comutils/-/comutils-1.1.19.tgz",
-      "integrity": "sha512-JxXB67juILiwhdLwOsYyjUqwWEhHdObI0EClOPk+JDtEuTbac59s0pxGpfCBnNNQ5JommifmcMGneW/4Cg7YWw=="
-    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -12850,14 +12850,6 @@
       "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==",
       "license": "MIT"
     },
-    "node_modules/vue-seamless-scroll": {
-      "version": "1.1.23",
-      "resolved": "https://registry.npmmirror.com/vue-seamless-scroll/-/vue-seamless-scroll-1.1.23.tgz",
-      "integrity": "sha512-HBjUub8WwsKJzbFCrwKPDrZn4e+SSbkKgwWtjKtfLwesiFGwSsVxP44/Z6d3kpXy94qIFOiflJH6l0/9pj7SGA==",
-      "dependencies": {
-        "comutils": "^1.1.9"
-      }
-    },
     "node_modules/vue-style-loader": {
       "version": "4.1.3",
       "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
@@ -13624,6 +13616,11 @@
         "js-message": "1.0.7"
       }
     },
+    "@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=="
+    },
     "@ampproject/remapping": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -16883,11 +16880,6 @@
         }
       }
     },
-    "comutils": {
-      "version": "1.1.19",
-      "resolved": "https://registry.npmmirror.com/comutils/-/comutils-1.1.19.tgz",
-      "integrity": "sha512-JxXB67juILiwhdLwOsYyjUqwWEhHdObI0EClOPk+JDtEuTbac59s0pxGpfCBnNNQ5JommifmcMGneW/4Cg7YWw=="
-    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -22332,14 +22324,6 @@
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz",
       "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ=="
     },
-    "vue-seamless-scroll": {
-      "version": "1.1.23",
-      "resolved": "https://registry.npmmirror.com/vue-seamless-scroll/-/vue-seamless-scroll-1.1.23.tgz",
-      "integrity": "sha512-HBjUub8WwsKJzbFCrwKPDrZn4e+SSbkKgwWtjKtfLwesiFGwSsVxP44/Z6d3kpXy94qIFOiflJH6l0/9pj7SGA==",
-      "requires": {
-        "comutils": "^1.1.9"
-      }
-    },
     "vue-style-loader": {
       "version": "4.1.3",
       "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",

+ 1 - 1
package.json

@@ -8,6 +8,7 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@amap/amap-jsapi-loader": "^1.0.1",
     "axios": "^1.6.8",
     "core-js": "^3.8.3",
     "crypto-js": "^4.2.0",
@@ -21,7 +22,6 @@
     "vue-amap": "^0.5.10",
     "vue-buffer": "^0.0.1",
     "vue-router": "^3.5.1",
-    "vue-seamless-scroll": "^1.1.23",
     "vuex": "^3.6.2"
   },
   "devDependencies": {

+ 1 - 1
public/index.html

@@ -5,7 +5,7 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-    <title>宝智达冷链送药追溯平台</title>
+    <title>智配送安全追溯AI管理平台</title>
   </head>
   <body>
     <noscript>

+ 8 - 0
src/api/company.js

@@ -1,5 +1,13 @@
 import request from '@/utils/request'
 
+// 获取当前用户的公司
+export function getCompanyDept(parameter) {
+  return request({
+    url: '/api/company/dept',
+    method: 'get',
+    params: parameter
+  })
+}
 // 获取公司列表
 export function getCompany(parameter) {
   return request({

+ 24 - 0
src/api/incubator.js

@@ -69,3 +69,27 @@ export function addCoolerBoxImport(parameter) {
     data: parameter
   })
 }
+// 获取保温箱历史时间段
+export function getCoolerBoxLocus(parameter) {
+  return request({
+    url: '/api/cooler-box/locus',
+    method: 'post',
+    data: parameter
+  })
+}
+// 获取保温箱历史轨迹
+export function getHistoryLocus(parameter) {
+  return request({
+    url: '/api/cooler-box/historylocus',
+    method: 'post',
+    data: parameter
+  })
+}
+// 获取保温箱实时轨迹
+export function getNewlocus(parameter) {
+  return request({
+    url: '/api/cooler-box/newlocus',
+    method: 'get',
+    params: parameter
+  })
+}

+ 4 - 5
src/api/waybill.js

@@ -133,13 +133,12 @@ export function getUserStats(parameter) {
     data: parameter
   })
 }
-
-// 导出温湿度pdf
+// 下载pdf
 export function getTemperature(parameter) {
   return request({
-    url: '/api/waybill/temperature-pdf',
-    method: 'get',
+    url: '/api/address/export',
+    method: 'post',
     responseType: 'blob',
-    params: parameter
+    data: parameter
   })
 }

+ 2 - 5
src/assets/css/global.css

@@ -5,6 +5,7 @@ body,
 	height: 100%;
 	margin: 0;
 	padding: 0;
+	padding-right: 0 !important
 }
 
 .center_in {
@@ -51,10 +52,6 @@ body,
 		align-items: center;
 	}
 
-	.card_waybillquiry {
-		margin: 10px !important;
-	}
-
 	.Waybill_inquiry {
 		margin-left: 0px !important;
 		margin-bottom: 1.25rem;
@@ -101,6 +98,6 @@ body,
 	}
 }
 
-.el-form-item__label{
+.el-form-item__label {
 	flex: none;
 }

+ 72 - 3
src/assets/fonts/demo_index.html

@@ -55,6 +55,24 @@
           <ul class="icon_lists dib-box">
           
             <li class="dib">
+              <span class="icon iconfont">&#xe79c;</span>
+                <div class="name">轨迹0</div>
+                <div class="code-name">&amp;#xe79c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe64f;</span>
+                <div class="name">订单审核</div>
+                <div class="code-name">&amp;#xe64f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61a;</span>
+                <div class="name">统计分析</div>
+                <div class="code-name">&amp;#xe61a;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe725;</span>
                 <div class="name">药店</div>
                 <div class="code-name">&amp;#xe725;</div>
@@ -180,9 +198,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1728712647401') format('woff2'),
-       url('iconfont.woff?t=1728712647401') format('woff'),
-       url('iconfont.ttf?t=1728712647401') format('truetype');
+  src: url('iconfont.woff2?t=1731051259643') format('woff2'),
+       url('iconfont.woff?t=1731051259643') format('woff'),
+       url('iconfont.ttf?t=1731051259643') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -209,6 +227,33 @@
         <ul class="icon_lists dib-box">
           
           <li class="dib">
+            <span class="icon iconfont icon-guiji"></span>
+            <div class="name">
+              轨迹0
+            </div>
+            <div class="code-name">.icon-guiji
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dingdanshenhe"></span>
+            <div class="name">
+              订单审核
+            </div>
+            <div class="code-name">.icon-dingdanshenhe
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-tongjifenxi"></span>
+            <div class="name">
+              统计分析
+            </div>
+            <div class="code-name">.icon-tongjifenxi
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-yaodian"></span>
             <div class="name">
               药店
@@ -399,6 +444,30 @@
           
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-guiji"></use>
+                </svg>
+                <div class="name">轨迹0</div>
+                <div class="code-name">#icon-guiji</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dingdanshenhe"></use>
+                </svg>
+                <div class="name">订单审核</div>
+                <div class="code-name">#icon-dingdanshenhe</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tongjifenxi"></use>
+                </svg>
+                <div class="name">统计分析</div>
+                <div class="code-name">#icon-tongjifenxi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-yaodian"></use>
                 </svg>
                 <div class="name">药店</div>

+ 15 - 3
src/assets/fonts/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 4556741 */
-  src: url('@/assets/fonts/iconfont.woff2?t=1728712647401') format('woff2'),
-       url('@/assets/fonts/iconfont.woff?t=1728712647401') format('woff'),
-       url('@/assets/fonts/iconfont.ttf?t=1728712647401') format('truetype');
+  src: url('@/assets/fonts/iconfont.woff2?t=1731051259643') format('woff2'),
+       url('@/assets/fonts/iconfont.woff?t=1731051259643') format('woff'),
+       url('@/assets/fonts/iconfont.ttf?t=1731051259643') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,18 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-guiji:before {
+  content: "\e79c";
+}
+
+.icon-dingdanshenhe:before {
+  content: "\e64f";
+}
+
+.icon-tongjifenxi:before {
+  content: "\e61a";
+}
+
 .icon-yaodian:before {
   content: "\e725";
 }

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
src/assets/fonts/iconfont.js


+ 21 - 0
src/assets/fonts/iconfont.json

@@ -6,6 +6,27 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "8398567",
+      "name": "轨迹0",
+      "font_class": "guiji",
+      "unicode": "e79c",
+      "unicode_decimal": 59292
+    },
+    {
+      "icon_id": "7667233",
+      "name": "订单审核",
+      "font_class": "dingdanshenhe",
+      "unicode": "e64f",
+      "unicode_decimal": 58959
+    },
+    {
+      "icon_id": "10416462",
+      "name": "统计分析",
+      "font_class": "tongjifenxi",
+      "unicode": "e61a",
+      "unicode_decimal": 58906
+    },
+    {
       "icon_id": "5953784",
       "name": "药店",
       "font_class": "yaodian",

BIN
src/assets/fonts/iconfont.ttf


BIN
src/assets/fonts/iconfont.woff


BIN
src/assets/fonts/iconfont.woff2


BIN
src/assets/images/incubator.png


BIN
src/assets/images/truck.png


+ 31 - 0
src/assets/js/blockSort.js

@@ -131,3 +131,34 @@ export const frozenState = () => {
     value: '4',
   }]
 }
+
+export const radiolist = () => {
+  return [{
+    label: '现金',
+    value: 1,
+  }, {
+    label: '线上支付',
+    value: 2,
+  }, {
+    label: '银行卡',
+    value: 3,
+  }, {
+    label: '医保',
+    value: 4,
+  }, {
+    label: '其他',
+    value: 5,
+  }]
+}
+
+export const stateList = () => {
+  return [{
+    label: '已结清',
+    value: 1,
+    bgcolor: '#67C23A',
+  }, {
+    label: '未结清',
+    value: 2,
+    bgcolor: '#F56C6C',
+  }]
+}

+ 1 - 0
src/components/MapContainer.vue

@@ -81,6 +81,7 @@
           lineJoin: 'round',
           lineCap: 'round',
         });
+        that.map.setFitView(null, false, [150, 60, 100, 60]);
       },
       destroyMap() {
         this.map && this.map.destroy();

+ 7 - 3
src/components/MapDelivery.vue

@@ -99,15 +99,19 @@
 
           function calculateTime(distance, speed) {
             // 将距离从米转换为公里
+            let velocity = speed
+            if(distance < 900){
+              velocity = 10
+            }
             const distanceInKm = distance / 1000;
             // 计算所需时间(单位:小时)
-            const hours = distanceInKm / (speed / 60); // 因为速度是每小时多少公里,所以除以60转换为小时
-            return hours.toFixed(2); // 保留两位小数
+            const hours = distanceInKm / (velocity / 60); // 因为速度是每小时多少公里,所以除以60转换为小时
+            // return hours.toFixed(2); // 保留两位小数
+            return Math.round(hours); // 取整
           }
           const speed = 25; //骑行速度
           const timeMins = calculateTime(distance, speed);
           // console.log(`预计到达时间:约 ${timeMins} 分钟`);
-
           endMarker.setLabel({
             offset: new AMap.Pixel(0, -50),
             content: `<div class='info'><div class='headline_title'>药品正在路上</div><div class='card_tag'><div class='distance_title'>距您</div><div class='orange_title'>${distanceNum}</div><div class='line_card'>|</div><div class='orange_title'>${timeMins}分钟</div></div><div class='popper__arrow'></div></div>`,

+ 626 - 102
src/components/centerControl.vue

@@ -30,7 +30,7 @@
         <!--Waves end-->
       </template>
       <div class="card_control">
-        <div class="map_card">
+        <div class="map_card" v-loading="mapLoading">
           <div id="container"></div>
         </div>
         <div class="card_bottom_control" :class="logisticsFlag ? 'height_300' : 'height_30'">
@@ -42,39 +42,72 @@
             <div class="card_unpack_control">
               <div style="display: flex;align-items: center;">
                 <div style="width: 260px;margin-right: 10px;">
-                  <el-input v-model="input" placeholder="请输入内容"></el-input>
+                  <el-input size="small" v-model="input" placeholder="请输入内容"></el-input>
                 </div>
-                <el-date-picker v-model="value1" type="datetimerange" range-separator="至" start-placeholder="开始日期"
-                  end-placeholder="结束日期">
-                </el-date-picker>
+                <!-- <el-date-picker size="small" v-model="value1" type="datetimerange" range-separator="至"
+                  start-placeholder="开始日期" end-placeholder="结束日期">
+                </el-date-picker> -->
               </div>
-            </div>
-            <div class="card_table_grid">
-              <div class="item_index1 center_in">序号</div>
-              <div class="item_grid center_in" v-for="(item,index) in headerList" :key="index">
-                {{item.title}}
+              <div>
+                <el-button type="primary" size="small" @click="examine">查看实时数据</el-button>
               </div>
             </div>
-            <vue-seamless-scroll ref="vueSeamlessScroll" :data="tableData" :class-option="classOption" class="warp"
-              @mousewheel.native="handleScroll">
-              <div class="card_table_grid" v-for="(item, index) in tableData" :key="index">
-                <div class="item_index center_in">{{index + 1}}</div>
-                <div class="item_each center_in">{{item.name}}</div>
-                <div class="item_each center_in">{{item.sn}}</div>
-                <div class="item_each center_in">{{item.status}}</div>
-                <div class="item_each center_in">{{item.deviceData.T_t}}</div>
-                <div class="item_each center_in">{{item.deviceData.T_time}}</div>
+            <div class="history_warp">
+              <el-table ref="multipleTable" :data="tableData" height="calc(100% - 51px)" border style="width: 100%"
+                @selection-change="handleSelectionChange" @cell-click="selectIncubator" :key="currentId">
+                <el-table-column type="selection" width="55" v-if="currentId == 1"></el-table-column>
+                <el-table-column type="index" width="50" v-else></el-table-column>
+                <el-table-column prop="name" label="名称"></el-table-column>
+                <el-table-column prop="sn" label="SN"></el-table-column>
+                <el-table-column prop="status" label="状态"></el-table-column>
+                <el-table-column prop="T_t" label="当前地址"></el-table-column>
+                <el-table-column prop="T_t" label="最新温度"></el-table-column>
+                <el-table-column prop="T_time" label="最新记录时间"></el-table-column>
+              </el-table>
+              <div v-if="Total">
+                <pagination :total="Total" :currentPage="Pagination.PageIndex" @changeSize="changeSize"
+                  @changeCurrent="changeCurrent">
+                </pagination>
               </div>
-            </vue-seamless-scroll>
+            </div>
+          </div>
+          <div class="track_visit scale-up-tr" v-if="currentId == 2 && playbackControl">
+            <div class="playback">轨迹回放控制</div>
+            <div class="card_cartoon">
+              <div class="cartoo_title center_in margin_10" @click="startAnimation()">开始动画</div>
+              <div class="cartoo_title center_in" @click="pauseAnimation()">暂停动画</div>
+              <div class="cartoo_title center_in margin_10" @click="resumeAnimation()">继续动画</div>
+              <div class="cartoo_title center_in" @click="stopAnimation()">停止动画</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="card_right_information" v-if="currentId == 2">
+        <div class="hide_information center_in" v-if="!optionFlag && trackCircle" @click="reelect">
+          <span class="iconfont icon-guiji"></span>
+        </div>
+        <div class="information_card scale-up-tr" v-if="optionFlag && timeData.length > 0">
+          <div class="card_time_box" v-for="(item,index) in timeData" :key="index" @click="getTrack(item)">
+            <div class="sn_card_box">{{item.sn}}</div>
+            <div class="box_time">{{item.start_time}}</div>
+            <div class="box_time">{{item.end_time}}</div>
           </div>
         </div>
+        <div class="information_card" v-else-if="optionFlag && timeData.length == 0">
+          <el-empty description="暂无数据"></el-empty>
+        </div>
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-  import vueSeamlessScroll from "vue-seamless-scroll";
+  import {
+    getCoolerBoxLocus,
+    getHistoryLocus,
+    getNewlocus
+  } from '@/api/incubator'
+  import pagination from '@/components/pagination'
   export default {
     name: 'centerControl',
     props: {
@@ -85,7 +118,7 @@
       },
     },
     components: {
-      vueSeamlessScroll,
+      pagination,
     },
     data() {
       return {
@@ -105,68 +138,81 @@
         }],
         controlVisible: false,
         map: null,
-        headerList: [{
-          title: '名称'
-        }, {
-          title: 'SN'
-        }, {
-          title: '状态'
-        }, {
-          title: '最新温度'
-        }, {
-          title: '最新记录时间'
-        }]
+        currentId: 1,
+        incubatorData: [],
+        incubatorID: null,
+        optionFlag: false,
+        timeData: [],
+        polyline: null,
+        passedPolyline: null,
+        marker: null,
+        endMarker: null,
+        trackList: [],
+        trackPlayback: null,
+        playbackControl: false,
+        trackCircle: false,
+        Total: 100,
+        Pagination: {
+          PageIndex: 1,
+          PageSize: 10,
+        },
+
+        eventSource: [],
+        incubatorSn: [],
+        jointSn: [],
+        realTimeTrajectory: [],
+        carMarker: [],
+        mapLoading: false,
       }
     },
     computed: {
       classOption() {
         return {
           limitMoveNum: 10,
-          singleHeight: 30,
+          singleHeight: 42,
+          waitTime: 2000,
         };
       },
     },
     watch: {
       tableData: {
-        handler() {
-          // 数据更改时也要加
-          // this.$nextTick(() => {
-          //   this.$refs.vueSeamlessScroll.reset()
-          // })
+        handler(newVal) {
+          let arr = newVal
+          arr.forEach((item) => {
+            if (item.id == this.incubatorID) {
+              item.flag = true
+            } else {
+              item.flag = false
+            }
+          })
+          this.incubatorData = arr
         },
         immediate: true,
+        deep: true // 开启深度监听
       },
     },
     mounted() {
       // this.keyUpSearch()
     },
     methods: {
-      // 滚动代码
-      handleScroll(e) {
-        if (this.tableData.length > 10) {
-          // 改变组件内部 yPos 的值,这样html的translate(0, yPos)就会随之改变
-          // e.deltaY是滚动的距离
-          this.$refs.vueSeamlessScroll.yPos = this.$refs.vueSeamlessScroll.yPos - e.deltaY
-          // 如果是正数 说明是往上滚
-          if (this.$refs.vueSeamlessScroll.yPos > 0) {
-            this.$refs.vueSeamlessScroll.yPos = 0
-            return
-          }
-          // 如果yPos超过内部实际高度的一半则重新到顶部滚动
-          // 一半的原因是因为组件实际上创建了两个dom,以达到无缝衔接的效果
-          if (Math.abs(this.$refs.vueSeamlessScroll.yPos) > this.$refs.vueSeamlessScroll.realBoxHeight / 2) {
-            this.$refs.vueSeamlessScroll.yPos = 0
+      selectRol(event) {
+        if (this.currentId != event.id) {
+          if (event.id == 1) {
+            this.playbackControl = false
+            this.keyUpSearch()
+          } else {
+            this.historicalRoute()
           }
         }
-      },
-      selectRol(event) {
         this.list.forEach(item => {
           if (item.id == event.id) {
+            this.currentId = event.id
             item.flag = true
           } else {
             item.flag = false
           }
         })
+        this.$forceUpdate
       },
       // 展开收起
       getUnpack() {
@@ -175,22 +221,334 @@
       close() {
         this.controlVisible = false
       },
+      // 选择
+      handleSelectionChange(event) {
+        let arr = []
+        event.forEach(item => {
+          arr.push(item.sn)
+        })
+        this.incubatorSn = arr
+        // console.log(arr, 35)
+      },
+      // 查看实时数据
+      async examine() {
+        const that = this
+
+        function difference(arr1, arr2) {
+          return arr1.filter(item => !arr2.includes(item));
+        }
+        const uniqueToFirstArray = difference(that.incubatorSn, that.jointSn);
+        const uniqueToFirstArray1 = difference(that.jointSn, that.incubatorSn);
+        // console.log(uniqueToFirstArray, uniqueToFirstArray1, 999)
+        uniqueToFirstArray1.forEach(ique => {
+          that.jointSn = deleteElementById(that.jointSn, ique)
+
+          function deleteElementById(arr, id) {
+            return arr.filter((item) => item !== id);
+          }
+          that.eventSource[ique].close()
+          if (that.carMarker[ique].marker) {
+            that.carMarker[ique].marker.setMap(null)
+          }
+          if (that.carMarker[ique].polyline) {
+            that.carMarker[ique].polyline.setMap(null)
+          }
+          that.carMarker[ique] = null
+        })
+        that.jointSn = that.incubatorSn
+        const userData = localStorage.getItem('userList')
+        const deptId = JSON.parse(userData)
+        if (that.incubatorSn.length > 0) {
+          for (let i = 0; i < uniqueToFirstArray.length; i++) {
+            const T_sn = uniqueToFirstArray[i]
+            // 处理 SSE 流
+            that.mapLoading = true
+            that.eventSource[T_sn] = await new EventSource(
+              `http://182.43.247.65:6280/api/waybill/newlocus?T_sn=${T_sn}&id=${deptId.dept.id}`);
+            that.eventSource[T_sn].onopen = function(e) {
+              // console.log('Connection to SSE opened.', e);
+            };
+            that.eventSource[T_sn].onmessage = function(e) {
+              // console.log('Message from SSE stream:', e.data);
+              const arr = JSON.parse(e.data)
+              if (arr.code == 200) {
+                // 判断数组对象中是否存在该对象
+                let index = that.realTimeTrajectory.findIndex((item) => item.sn === arr.sn);
+                // 如果有就替换,没有就添加
+                if (index !== -1) {
+                  that.realTimeTrajectory.splice(index, 1, arr);
+                } else {
+                  that.realTimeTrajectory.push(arr);
+                }
+                that.realTimeTrajectory.forEach(event => {
+                  that.initMarker(event.data[0], event)
+                })
+              } else {
+                console.log(T_sn, that.jointSn, 23)
+                that.jointSn = deleteElementById(that.jointSn, T_sn)
+
+                function deleteElementById(arr, id) {
+                  return arr.filter((item) => item !== id);
+                }
+                that.$message.error(arr.msg);
+                that.eventSource[T_sn].close()
+              }
+              that.mapLoading = false
+            };
+            that.eventSource[T_sn].onerror = function(e) {
+              that.mapLoading = false
+              console.error('Error from SSE stream:', uniqueToFirstArray[i], e);
+            };
+          }
+        } else {
+          that.$message({
+            message: '请选择保温箱',
+            type: 'warning'
+          });
+        }
+      },
+      // 初始化坐标点的icon
+      initMarker(location, item) {
+        let latitude = location.T_site.split(',')
+        let dataList = item.data
+        var trackList = []
+        var positions = item.data
+        if (positions.length > 0) {
+          positions.forEach(item => {
+            if (item.T_site != '0,0' && item.T_site) {
+              const data = item.T_site.split(',')
+              let arrTrack = [Number(data[0]), Number(data[1])]
+              trackList.push(arrTrack)
+            }
+          })
+        }
+        // 生成坐标点icon
+        if (this.carMarker[item.sn]) {
+          if (this.carMarker[item.sn].marker) {
+            this.carMarker[item.sn].marker.setPosition([Number(latitude[0]), Number(latitude[1])])
+          }
+          if (this.carMarker[item.sn].polyline) {
+            this.carMarker[item.sn].polyline.setPath(trackList)
+          }
+        } else {
+          let icon = new AMap.Icon({
+            size: new AMap.Size(40, 45),
+            image: require(`@/assets/images/truck.png`),
+            imageSize: new AMap.Size(40, 45),
+          });
+          this.carMarker[item.sn] = {
+            marker: null,
+            polyline: null,
+          }
+          // 坐标点 生成方法
+          this.carMarker[item.sn].marker = new AMap.Marker({
+            icon: icon, // 坐标点图标
+            position: [Number(latitude[0]), Number(latitude[1])], // 左边点的经纬度
+            offset: new AMap.Pixel(0, -30) // 坐标点偏移量
+          });
+          // 点标记显示内容,HTML要素字符串
+          var markerContent = '' +
+            '<div class="incubator_card_map">' +
+            '   <div class="map_title_incu">保温箱1</div>' +
+            '   <div class="map_title_incu1">' + item.sn + '</div>' +
+            '   <div class="map_title_incu1">最新温度: <span>' + location.T_t + '</span></div>' +
+            '   <div class="map_title_incu2">记录时间: ' + location.T_time + '</div>' +
+            '   <div class="map_title_incu2">当前地址: ' + location.T_time + '</div>' +
+            '   <div class="map_arrows"></div>' +
+            '</div>';
+          this.carMarker[item.sn].marker.setLabel({
+            offset: new AMap.Pixel(-7, -68),
+            content: markerContent,
+            direction: 'center',
+          })
+          this.carMarker[item.sn].polyline = new AMap.Polyline({
+            map: this.map,
+            path: trackList,
+            showDir: true,
+            strokeColor: "#28F", //线颜色
+            strokeWeight: 10, //线宽
+            strokeStyle: "solid",
+            lineJoin: 'round',
+            lineCap: 'round',
+          });
+          this.carMarker[item.sn].marker.setMap(this.map)
+        }
+        this.map.setFitView(null, false, [150, 60, 100, 60])
+      },
       keyUpSearch() {
         var that = this
         // var positions = this.trackList;
         that.map = new AMap.Map("container", {
           resizeEnable: true,
-          zoom: 14,
-          center: [106.638415, 26.652217],
+          zoom: 2,
+        });
+        that.map.setFitView()
+      },
+      // 历史轨迹
+      historicalRoute() {
+        var that = this
+        that.map = new AMap.Map("container", {
+          resizeEnable: true,
+          zoom: 2,
         });
-        AMap.service(["AMap.PlaceSearch"], function() {
-          var placeSearch = new AMap.PlaceSearch({ //构造地点查询类
+        that.map.setFitView()
+      },
+      // 选择保温箱
+      selectIncubator(event) {
+        this.$refs.multipleTable.toggleRowSelection(event);
+        this.incubatorID = event.id
+        if (this.currentId == 2) {
+          event.flag = true
+          this.optionFlag = true
+          this.getBoxLocus(event.id)
+        }
+      },
+      // 重选时间段轨迹
+      reelect() {
+        this.optionFlag = true
+      },
+      // 获取保温箱历史时间段
+      getBoxLocus(boxID) {
+        getCoolerBoxLocus({
+          id: boxID,
+        }).then(res => {
+          if (res.code == 200 && res.data != null) {
+            this.timeData = res.data
+          } else {
+            this.timeData = []
+          }
+        })
+      },
+      // 获取保温箱历史轨迹
+      getTrack(event) {
+        if (this.marker) {
+          this.marker.stopMove();
+        }
+        getHistoryLocus({
+          sn: event.sn,
+          start_time: event.start_time,
+          end_time: event.end_time,
+          t_id: event.t_id,
+          page: 1,
+          page_z: 999,
+        }).then(res => {
+          if (res.code == 200) {
+            var trackList = []
+            var positions = res.data
+            if (positions.length > 0) {
+              positions.forEach(item => {
+                if (item.T_site != '0,0' && item.T_site) {
+                  const data = item.T_site.split(',')
+                  trackList.push(data)
+                }
+              })
+            }
+            if (this.polyline) {
+              this.polyline.setMap(null); // 移除轨迹
+            }
+            this.polyline = null
+            if (this.passedPolyline) {
+              this.passedPolyline.setMap(null)
+            }
+            this.passedPolyline = null
+            if (this.marker) {
+              this.marker.setMap(null)
+            }
+            this.marker = null
+            if (this.endMarker) {
+              this.endMarker.setMap(null)
+            }
+            this.endMarker = null
+            this.trackList = trackList
+            this.optionFlag = false
+            this.trackCircle = true
+            this.initMap(trackList)
+          }
+        })
+      },
+      // 历史轨迹
+      initMap(arr) {
+        // 聚焦到标记点位置的方法
+        // this.map.setZoomAndCenter(10, arr[0].split(','))
+        var marker, positions = arr
+        const that = this
+        setTimeout(() => {
+          // 地图渲染完成后修改zoom
+          that.map.setZoom(14);
+          const num = positions.length
+          // 创建一个 终点icon
+          var endIcon = new AMap.Icon({
+            size: new AMap.Size(25, 34),
+            image: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
+            imageSize: new AMap.Size(135, 40),
+            imageOffset: new AMap.Pixel(-95, -3)
+          });
+          if (positions.length > 0) {
+            // 终点
+            that.endMarker = new AMap.Marker({
+              position: positions[num - 1],
+              icon: endIcon,
+              offset: new AMap.Pixel(-13, -30),
+            });
+            that.map.add(that.endMarker);
+          }
+          var truckIcon = new AMap.Icon({
+            size: new AMap.Size(40, 45),
+            image: require(`@/assets/images/truck.png`),
+            imageSize: new AMap.Size(40, 45),
+          });
+          that.marker = new AMap.Marker({
             map: that.map,
-            panel: "result",
-            autoFitView: true
+            position: positions[0],
+            icon: truckIcon,
+            offset: new AMap.Pixel(-13, -23),
+            autoRotation: true,
           });
-        })
-        that.map.setFitView()
+          // 绘制轨迹
+          that.polyline = new AMap.Polyline({
+            map: that.map,
+            path: positions,
+            showDir: true,
+            strokeColor: "#28F", //线颜色
+            strokeWeight: 10, //线宽
+            strokeStyle: "solid",
+            lineJoin: 'round',
+            lineCap: 'round',
+          });
+          that.passedPolyline = new AMap.Polyline({
+            map: that.map,
+            strokeColor: "#AF5", //线颜色
+            strokeWeight: 10, //线宽
+            strokeOpacity: .7,
+            strokeStyle: "solid",
+            lineJoin: 'round',
+            lineCap: 'round',
+          });
+          that.map.add(that.polyline);
+          that.map.setFitView(null, false, [150, 60, 100, 60]);
+          that.marker.on("moving", function(e) {
+            that.passedPolyline.setPath(e.passedPath);
+          });
+          that.playbackControl = true
+        }, 500)
+      },
+      // 开始动画
+      startAnimation() {
+        var num = this.trackList.length * 3
+        this.optionFlag = false
+        this.marker.moveAlong(this.trackList, num);
+      },
+      // 暂停动画
+      pauseAnimation() {
+        this.marker.pauseMove();
+      },
+      // 继续动画
+      resumeAnimation() {
+        this.marker.resumeMove();
+      },
+      // 停止动画
+      stopAnimation() {
+        this.marker.stopMove();
       },
       destroyMap() {
         this.map && this.map.destroy();
@@ -242,13 +600,39 @@
       },
       // 弹窗关闭
       dialogClose() {
+        if (this.incubatorSn.length > 0) {
+          this.incubatorSn.forEach(item => {
+            this.eventSource[item].close()
+          })
+        }
+        this.map = null
+        this.currentId = 1
+        this.list.forEach((item) => {
+          if (item.id == 1) {
+            item.flag = true
+          } else {
+            item.flag = false
+          }
+        })
         this.logisticsFlag = true
-      }
+      },
+      changeSize(val) {
+        this.Pagination.PageSize = val
+      },
+      changeCurrent(val) {
+        this.Pagination.PageIndex = val
+      },
     }
   }
 </script>
 
 <style lang="scss" scoped>
+  ::v-deep .amap-marker-label {
+    border: unset !important;
+    padding: 0px !important;
+    background-color: unset !important;
+  }
+
   .center_control ::v-deep .el-dialog__header {
     padding: 0px !important;
   }
@@ -330,6 +714,8 @@
     flex-direction: column;
   }
 
+
+
   .map_card {
     width: 100%;
     // height: 100%;
@@ -351,16 +737,14 @@
   }
 
   .card_unpack_control {
-    padding: 0px 10px;
-    height: 50px;
+    padding: 0px 10px 5px 10px;
     display: flex;
     align-items: center;
     justify-content: space-between;
-    border-bottom: 1px solid #DCDFE6;
   }
 
-  .warp {
-    height: calc(100% - 81px);
+  .history_warp {
+    height: calc(100% - 35px);
     width: 100%;
     overflow: hidden;
   }
@@ -369,41 +753,10 @@
     transform: rotate(180deg);
   }
 
-  .card_table_grid {
-    display: flex;
-    align-items: center;
-    justify-content: space-around;
-    border-bottom: 1px solid #DCDFE6;
-    padding: 0px 10px;
-  }
-
-  .item_index1 {
-    width: 40px;
-    height: 30px;
-    font-size: 15px;
-    font-weight: bold;
-  }
-
-  .item_index {
-    width: 40px;
-  }
-
-  .item_grid {
-    flex: 1;
-    height: 30px;
-    font-size: 15px;
-    font-weight: bold;
-  }
-
-  .item_each {
-    flex: 1;
-    height: 40px;
-  }
-
   .header {
     position: relative;
     text-align: center;
-    background: linear-gradient(60deg, rgba(84, 58, 183, 1) 0%, rgba(0, 172, 193, 1) 100%);
+    background: linear-gradient(60deg, rgba(0, 172, 193, 1) 0%, rgba(84, 58, 183, 1) 100%);
     color: white;
   }
 
@@ -463,4 +816,175 @@
       font-size: 24px;
     }
   }
+
+  ::v-deep .incubator_card_map {
+    position: relative;
+    width: 180px;
+    background-color: #fff;
+    border: 1px solid #DCDFE6;
+    padding: 5px;
+    border-radius: 8px;
+  }
+
+  ::v-deep .map_title_incu {
+    font-size: 16px;
+    font-weight: 600;
+    margin-bottom: 4px;
+  }
+
+  ::v-deep .map_title_incu1 {
+    font-size: 14px;
+
+    span {
+      font-weight: bold;
+      color: #67C23A;
+    }
+  }
+
+  ::v-deep .map_title_incu2 {
+    font-size: 12px;
+    margin: 2px 0px;
+  }
+
+  ::v-deep .map_arrows {
+    position: absolute;
+    bottom: 0px;
+    left: 90px;
+  }
+
+  ::v-deep .map_arrows::before {
+    position: absolute;
+    content: '';
+    border-top: 11px #DCDFE6 solid;
+    border-left: 10px transparent solid;
+    border-right: 10px transparent solid;
+    border-bottom: 10px transparent solid;
+  }
+
+  ::v-deep .map_arrows::after {
+    position: absolute;
+    content: '';
+    border-top: 10px #fff solid;
+    border-left: 10px transparent solid;
+    border-right: 10px transparent solid;
+    border-bottom: 10px transparent solid;
+  }
+
+  .card_right_information {
+    position: absolute;
+    top: 60px;
+    right: 10px;
+  }
+
+  .information_card {
+    width: 260px;
+    max-height: 400px;
+    overflow: hidden auto;
+    border-radius: 5px;
+    background-color: #ffffff;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  }
+
+  .hide_information {
+    cursor: pointer;
+    width: 50px;
+    height: 50px;
+    background-color: #ffffff;
+    border-radius: 50%;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+    span {
+      color: #009efd;
+      font-size: 30px;
+    }
+  }
+
+  .track_visit {
+    position: absolute;
+    right: 10px;
+    top: -130px;
+    width: 240px;
+    height: auto;
+    background-color: #ffffff;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    padding: 10px;
+    border-radius: 5px;
+
+    .playback {
+      font-size: 15px;
+      padding-bottom: 10px;
+    }
+  }
+
+  .card_cartoon {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+  }
+
+  .cartoo_title {
+    cursor: pointer;
+    margin-bottom: 8px;
+    width: 7rem;
+    color: #25A5F7;
+    border: 1px solid #25A5F7;
+    border-radius: 30px;
+    padding: 2px 0px;
+  }
+
+  .margin_10 {
+    margin-right: 10px;
+  }
+
+  .card_time_box {
+    cursor: pointer;
+    padding: 6px 10px;
+    border-bottom: 1px solid #E4E7ED;
+  }
+
+  .sn_card_box {
+    font-size: 16px;
+    font-weight: bold;
+  }
+
+  .box_time {
+    font-size: 14px;
+  }
+
+  .scale-up-tr {
+    -webkit-animation: scale-up-tr 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
+    animation: scale-up-tr 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
+  }
+
+  @-webkit-keyframes scale-up-tr {
+    0% {
+      -webkit-transform: scale(0.5);
+      transform: scale(0.5);
+      -webkit-transform-origin: 100% 0%;
+      transform-origin: 100% 0%;
+    }
+
+    100% {
+      -webkit-transform: scale(1);
+      transform: scale(1);
+      -webkit-transform-origin: 100% 0%;
+      transform-origin: 100% 0%;
+    }
+  }
+
+  @keyframes scale-up-tr {
+    0% {
+      -webkit-transform: scale(0.5);
+      transform: scale(0.5);
+      -webkit-transform-origin: 100% 0%;
+      transform-origin: 100% 0%;
+    }
+
+    100% {
+      -webkit-transform: scale(1);
+      transform: scale(1);
+      -webkit-transform-origin: 100% 0%;
+      transform-origin: 100% 0%;
+    }
+  }
 </style>

+ 20 - 4
src/components/forms.vue

@@ -12,6 +12,14 @@
               :show-password="['newPassword','password'].includes(item.field) ? true : false"></el-input>
             <div class="unit_card" v-if="item.unit">{{item.unit}}</div>
           </el-form-item>
+          <!-- 开关 -->
+          <el-form-item class="card_independent" :label-width="item.labelWidth" :label="item.label" :prop="item.field"
+            :rules="detail ? item.rules : {}" v-if="item.type === 'switch'">
+            <div class="forms_switch">
+              <el-switch v-model="ruleForm[`${item.field}`]" active-color="#13ce66"
+                inactive-color="#ff4949"></el-switch>
+            </div>
+          </el-form-item>
           <!-- 扫描 -->
           <el-form-item class="card_independent" :label-width="item.labelWidth" :label="item.label" :prop="item.field"
             :rules="detail ? item.rules : {}" v-if="item.type === 'scan'">
@@ -511,6 +519,14 @@
     flex-direction: column;
   }
 
+  ::v-deep .el-form-item__label {
+    height: 40px !important;
+    display: flex !important;
+    align-items: center !important;
+    justify-content: flex-end !important;
+    line-height: unset !important;
+  }
+
   .card_fuel_gas ::v-deep .el-form-item__label {
     width: 150px !important;
     text-align: left;
@@ -521,10 +537,6 @@
     margin-bottom: 10px !important;
   }
 
-  .card_descriptions ::v-deep .el-form-item__label {
-    text-align: left;
-  }
-
   .card_fuel_gas ::v-deep .el-form-item__content {
     margin-left: 0px !important;
   }
@@ -606,4 +618,8 @@
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
     border-radius: 4px;
   }
+
+  .forms_switch {
+    height: 40px;
+  }
 </style>

+ 3 - 3
src/components/mobileHumiture.vue

@@ -1,11 +1,11 @@
 <template>
-  <div>
-    <!-- <div class="probe_card_mobile" v-if="probeList.length > 0">
+  <div style="width: 100%;">
+    <div class="probe_card_mobile" v-if="probeList.length > 0">
       <el-radio-group v-model="tabPosition" @change="tabClick">
         <el-radio-button :label="item.T_id" v-for="(item,index) in probeList"
           :key="index">{{item.T_name}}</el-radio-button>
       </el-radio-group>
-    </div> -->
+    </div>
     <div class="mobile_humiture" v-if="tableData.length > 0">
       <div class="card_humiture">
         <div class="headline_item w_wsd">温度(°C)</div>

+ 37 - 25
src/components/orderDetails.vue

@@ -18,7 +18,8 @@
                   <el-table-column align="center" prop="date" label="商品名称"></el-table-column>
                   <el-table-column align="center" prop="name" label="商品数量"></el-table-column>
                   <el-table-column align="center" prop="address" label="药品图片" width="180">
-                    <el-image style="width: 50px; height: 50px" :preview-src-list="['https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg']"
+                    <el-image style="width: 50px; height: 50px"
+                      :preview-src-list="['https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg']"
                       src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"></el-image>
                   </el-table-column>
                   <el-table-column align="center" prop="name" label="商品规格"></el-table-column>
@@ -26,11 +27,11 @@
                   <el-table-column align="center" prop="name" label="是否双通道药品" width="140"></el-table-column>
                 </el-table>
               </div>
-              <div class="grid-content bg-purple" v-else-if="item.field == 'status' && !mywaybill">
+              <div class="grid-content bg-purple" v-else-if="['status','paymentType','paymentStatus'].includes(item.field) && !mywaybill">
                 <div class="describe">{{item.title}}</div>
                 <div style="text-align: left;line-height: 19px;"
-                  :style="{color: filterColor(waybillData,WaybillType,item.field)}">
-                  {{waybillStatus(waybillData[`${item.field}`])}}
+                  :style="{color: filterColor(waybillData,item.options,item.field)}">
+                  {{waybillStatus(waybillData[`${item.field}`],item.options)}}
                 </div>
               </div>
               <div class="grid-content bg-purple" v-else-if="item.field == 'status' && mywaybill">
@@ -40,7 +41,8 @@
                   {{mywaybillStatus(waybillData)}}
                 </div>
               </div>
-              <div class="grid-content bg-purple1" v-else-if="item.field == 'tamperProofLabelImg'">
+              <div class="grid-content bg-purple1"
+                v-else-if="['tamperProofLabelImg','receiptImg','receiptsign'].includes(item.field)">
                 <div class="describe1">{{item.title}}</div>
                 <div class="card_item_image" v-for="(item1,index1) in getReceipt(waybillData[`${item.field}`])"
                   :key="index1" v-if="waybillData[`${item.field}`]">
@@ -63,7 +65,9 @@
 <script>
   import {
     WaybillStatus,
-    myOrder
+    myOrder,
+    radiolist,
+    stateList
   } from '@/assets/js/blockSort'
   import {
     encryptData,
@@ -83,19 +87,7 @@
     },
     data() {
       return {
-        tableData: [{
-          date: '2016-05-02',
-          name: '王小虎',
-          address: '上海市普陀区金沙江路 1518 弄'
-        }, {
-          date: '2016-05-04',
-          name: '王小虎',
-          address: '上海市普陀区金沙江路 1517 弄'
-        }, {
-          date: '2016-05-01',
-          name: '王小虎',
-          address: '上海市普陀区金沙江路 1519 弄'
-        }],
+        tableData: [],
         staffDialogVisible: false,
         list: [{
           title: '运单号:',
@@ -109,6 +101,7 @@
           title: '订单状态:',
           field: 'status',
           colWidth: 8,
+          options: WaybillStatus(),
         }, {
           title: '患者姓名:',
           field: 'consigneeAddressName',
@@ -172,11 +165,29 @@
         }, {
           title: '防拆标签图片:',
           field: 'tamperProofLabelImg',
-          colWidth: 8,
+          colWidth: 24,
         }, {
           title: '签收图片:',
-          field: 'tamperProofLabelImg',
-          colWidth: 16,
+          field: 'receiptImg',
+          colWidth: 12,
+        }, {
+          title: '客户签字图片:',
+          field: 'receiptsign',
+          colWidth: 12,
+        }, {
+          title: '支付方式:',
+          field: 'paymentType',
+          colWidth: 8,
+          options: radiolist(),
+        }, {
+          title: '支付状态:',
+          field: 'paymentStatus',
+          colWidth: 8,
+          options: stateList(),
+        }, {
+          title: '未结清备注:',
+          field: 'paymentremark',
+          colWidth: 8,
         }, {
           title: '服务评价:',
           field: 'assessContent',
@@ -190,7 +201,6 @@
           field: 'logistics',
           colWidth: 24,
         }, ],
-        WaybillType: WaybillStatus(),
         myOrder: myOrder(),
         userType: '',
       }
@@ -224,9 +234,9 @@
           window.open(href, "_blank");
         }
       },
-      waybillStatus(value) {
+      waybillStatus(value,list) {
         let label = ''
-        this.WaybillType.forEach(item => {
+        list.forEach(item => {
           if (item.value == value) {
             label = item.label
           }
@@ -322,6 +332,8 @@
   }
 
   .describe1 {
+    text-align: right;
+    width: 60px;
     flex: none;
     margin-right: 5px;
   }

+ 24 - 4
src/components/tables.vue

@@ -53,10 +53,19 @@
         <el-table-column :label="item.label" align="center" v-else-if="item.field == 'multistage'">
           <template v-for="(child,cgindex) in item.children">
             <el-table-column :prop="child.field" :label="child.label" :width="child.colWidth" :align="child.align">
+              <template slot-scope="scope">
+                <div v-if="child.field == 'suitableForColdTime'">≥{{scope.row[child.field]}}min</div>
+                <div
+                  v-else-if="child.field == 'iceRaftRecord.suitableForCold' && scope.row.iceRaftRecord.suitableForCold">
+                  {{nestedField(scope.row,child.field)}}℃
+                </div>
+                <div v-else>{{nestedField(scope.row,child.field)}}</div>
+              </template>
             </el-table-column>
           </template>
         </el-table-column>
-        <el-table-column :label="item.label" align="center" v-else-if="item.field == 'receiptImg'">
+        <el-table-column :label="item.label" align="center"
+          v-else-if="item.field == 'receiptImg' || item.field == 'receiptsign'">
           <template slot-scope="scope">
             <el-image style="width: 60px; height: 60px" :src="scope.row[item.field]"
               :preview-src-list="getImage(scope.row[item.field])"></el-image>
@@ -71,7 +80,7 @@
           </template>
         </el-table-column>
         <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
-          v-else-if="['userId','assignmentStatus', 'type', 'status', 'storeId', 'personCode', 'optType', 'corrosion', 'crackle', 'deform', 'damage', 'safeAnnex', 'gasPressure', 'bodyDeform', 'fillingLeak', 'bodyTemperature', 'filledLeak', 'warnSign', 'fillLabel', 'seal','addressType'].includes(item.field)">
+          v-else-if="['userId','paymentType','paymentStatus','assignmentStatus', 'type', 'status', 'storeId', 'personCode', 'optType', 'corrosion', 'crackle', 'deform', 'damage', 'safeAnnex', 'gasPressure', 'bodyDeform', 'fillingLeak', 'bodyTemperature', 'filledLeak', 'warnSign', 'fillLabel', 'seal','addressType'].includes(item.field)">
           <template slot-scope="scope">
             <div :style="{color: filterColor(scope.row,item.options,item.field)}">
               {{initDictvalueil(scope.row,item.options,item.field)}}
@@ -116,7 +125,7 @@
         <el-table-column :prop="item.field" :label="item.label" :width="item.colWidth" :align="item.align"
           v-else-if="item.field == 'freezeClaim'">
           <template slot-scope="scope">
-            <div v-if="scope.row.freezeClaim">≥{{scope.row.freezeClaim}}h</div>
+            <div v-if="scope.row[item.field]">≥{{scope.row[item.field]}}h</div>
             <div v-else-if="scope.row.iceRaftRecord">
               <span v-if="scope.row.iceRaftRecord.status">≥{{scope.row.iceRaftRecord.freezeClaim}}h</span>
             </div>
@@ -144,7 +153,7 @@
             <div>{{formatMinutes(scope.row[item.field]) || ''}}</div>
           </template>
         </el-table-column>
-        <el-table-column type="index" :fixed="item.boxhead ? true : false" width="80px" :label="item.label"
+        <el-table-column type="index" :fixed="item.boxhead ? true : false" :width="item.colWidth" :label="item.label"
           :align="item.align" v-else-if="item.field == 'index'">
         </el-table-column>
         <el-table-column type="selection" v-model="selectionList" :reserve-selection="true" width="55"
@@ -243,6 +252,17 @@
         arr.push(image)
         return arr
       },
+      // 嵌套字段
+      nestedField(event, type) {
+        let propertyName = type.split(".")
+        let name = ''
+        if (event[propertyName[0]] != undefined) {
+          if (event[propertyName[0]][propertyName[1]]) {
+            name = event[propertyName[0]][propertyName[1]]
+          }
+        }
+        return name
+      },
       // 文字匹配
       initDictvalue(value, list, type) {
         let propertyName = type.split(".")

+ 3 - 0
src/components/thermography.vue

@@ -91,6 +91,9 @@
     methods: {
       // 获取探头
       getProbe() {
+        this.checkAll = false
+        this.list = []
+        this.tableData = []
         getSensor({
           sn: this.waybillNo,
         }).then(res => {

+ 3 - 3
src/components/waybillInformation.vue

@@ -28,10 +28,10 @@
     <div class="order_headline" v-if="list.tamperProofLabelImg">请确定防拆标签完整</div>
     <div class="same_row_in" v-if="list.tamperProofLabelImg">
       <div v-for="(item,index) in getimagetamper(list)" :key="index">
-        <el-image class="img_antidismantle" :src="item" fit="fill"></el-image>
+        <el-image class="img_antidismantle" :src="item" :preview-src-list="[item]" fit="fill"></el-image>
       </div>
     </div>
-    <div class="sign_img" v-if="![3,4,5].includes(list.status)">
+    <div class="sign_img" v-if="![1,2,3,5,6].includes(list.status)">
       <div class="title_sign">签收 / 拒收图片</div>
       <el-upload class="sign_image_card" action="#" list-type="picture-card" :file-list="ruleForm.fileList"
         :http-request="(params) => singleUpload(params,'fileList')">
@@ -62,7 +62,7 @@
       <el-input type="textarea" :rows="2" placeholder="评价内容" v-model="textarea" v-else>
       </el-input>
     </div>
-    <div class="btn_order" v-if="![3,4,5].includes(list.status)">
+    <div class="btn_order" v-if="![1,2,3,5,6].includes(list.status)">
       <el-button style="width: 50%;" type="danger" plain @click="getTurnDown">拒绝收货</el-button>
       <el-button style="width: 50%;" type="primary" plain @click="getReceiving">确定收货</el-button>
     </div>

+ 124 - 0
src/config/deliveryman.js

@@ -0,0 +1,124 @@
+// 配送员菜单deliveryman
+export const deliverymanRouter = {
+  name: 'index',
+  path: '/',
+  component: () => import('@/views/common/Base'),
+  redirect: '/home',
+  children: [{
+      path: '/home',
+      name: 'home',
+      meta: {
+        icon: 'icon-shouye',
+        title: '首页'
+      },
+      component: () => import('@/views/page/Home'),
+    }, {
+      path: '/addressBook',
+      name: 'addressBook',
+      meta: {
+        icon: 'icon-cangku',
+        title: '患者薄管理'
+      },
+      component: () => import('@/views/system/addressBook'),
+    }, {
+      path: '/IceTracingManagement',
+      name: 'IceTracingManagement',
+      meta: {
+        icon: 'icon-iceTracing',
+        title: '冰排追溯管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/IceTracingManagement'),
+    }, {
+      path: '/IceManagement',
+      name: 'IceManagement',
+      meta: {
+        icon: 'icon-bingpaiguanli',
+        title: '冰排管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/IceManagement'),
+    }, {
+      path: '/FreezerManagement',
+      name: 'FreezerManagement',
+      meta: {
+        icon: 'icon-binggui',
+        title: '冷冻柜管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/FreezerManagement'),
+    }, {
+      path: '/IncubatorManagement',
+      name: 'IncubatorManagement',
+      meta: {
+        icon: 'icon-baowenxiangguanli',
+        title: '保温箱管理'
+      },
+      component: () => import('@/views/system/IncubatorManagement'),
+    },
+    {
+      path: '/OrderManagement',
+      name: 'OrderManagement',
+      meta: {
+        icon: 'icon-yundan',
+        title: '订单管理'
+      },
+      component: () => import('@/views/OrderManagement/index'),
+      redirect: '/OrderManagement/uncertainOrder',
+      children: [{
+        path: 'uncertainOrder',
+        name: 'uncertainOrder',
+        meta: {
+          icon: 'icon-yueduye-mulu',
+          title: '未确定订单'
+        },
+        component: () => import('@/views/OrderManagement/uncertainOrder.vue'),
+      }, {
+        path: 'reviewedOrder',
+        name: 'reviewedOrder',
+        meta: {
+          icon: 'icon-daishenhe',
+          title: '待审核订单'
+        },
+        component: () => import('@/views/OrderManagement/reviewedOrder.vue'),
+      }, {
+        path: 'pendingOrder',
+        name: 'pendingOrder',
+        meta: {
+          icon: 'icon-daipeisong',
+          title: '待配送订单'
+        },
+        component: () => import('@/views/OrderManagement/pendingOrder.vue'),
+      }, {
+        path: 'deliveryOrder',
+        name: 'deliveryOrder',
+        meta: {
+          icon: 'icon-peisongzhong',
+          title: '配送中订单'
+        },
+        component: () => import('@/views/OrderManagement/deliveryOrder.vue'),
+      }, {
+        path: 'completedOrder',
+        name: 'completedOrder',
+        meta: {
+          icon: 'icon-yiwanchengdingdan',
+          title: '已完成订单'
+        },
+        component: () => import('@/views/OrderManagement/completedOrder.vue'),
+      }, {
+        path: 'cancelledOrder',
+        name: 'cancelledOrder',
+        meta: {
+          icon: 'icon-yiquxiaodingdan',
+          title: '已取消订单'
+        },
+        component: () => import('@/views/OrderManagement/cancelledOrder.vue'),
+      }, {
+        path: 'rejectionOrder',
+        name: 'rejectionOrder',
+        meta: {
+          icon: 'icon-yiquxiaodingdan',
+          title: '已拒收订单'
+        },
+        component: () => import('@/views/OrderManagement/rejectionOrder.vue'),
+      }, ]
+    }
+  ]
+}

+ 166 - 0
src/config/intendant.js

@@ -0,0 +1,166 @@
+// 管理员菜单intendant
+export const intendantRouter = {
+  name: 'index',
+  path: '/',
+  component: () => import('@/views/common/Base'),
+  redirect: '/home',
+  children: [{
+      path: '/home',
+      name: 'home',
+      meta: {
+        icon: 'icon-shouye',
+        title: '首页'
+      },
+      component: () => import('@/views/page/Home'),
+    }, {
+      path: '/UserManagement',
+      name: 'UserManagement',
+      meta: {
+        icon: 'icon-yonghuguanli',
+        title: '用户管理'
+      },
+      component: () => import('@/views/system/UserManagement'),
+    }, {
+      path: '/addressBook',
+      name: 'addressBook',
+      meta: {
+        icon: 'icon-cangku',
+        title: '患者薄管理'
+      },
+      component: () => import('@/views/system/addressBook'),
+    }, {
+      path: '/storeManagement',
+      name: 'storeManagement',
+      meta: {
+        icon: 'icon-yaodian',
+        title: '门店管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/storeManagement'),
+    }, {
+      path: '/IceTracingManagement',
+      name: 'IceTracingManagement',
+      meta: {
+        icon: 'icon-iceTracing',
+        title: '冰排追溯管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/IceTracingManagement'),
+    }, {
+      path: '/IceManagement',
+      name: 'IceManagement',
+      meta: {
+        icon: 'icon-bingpaiguanli',
+        title: '冰排管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/IceManagement'),
+    }, {
+      path: '/FreezerManagement',
+      name: 'FreezerManagement',
+      meta: {
+        icon: 'icon-binggui',
+        title: '冷冻柜管理'
+      },
+      component: () => import('@/views/IceCreamFreezer/FreezerManagement'),
+    }, {
+      path: '/IncubatorManagement',
+      name: 'IncubatorManagement',
+      meta: {
+        icon: 'icon-baowenxiangguanli',
+        title: '保温箱管理'
+      },
+      component: () => import('@/views/system/IncubatorManagement'),
+    },
+    {
+      path: '/OrderManagement',
+      name: 'OrderManagement',
+      meta: {
+        icon: 'icon-yundan',
+        title: '订单管理'
+      },
+      component: () => import('@/views/OrderManagement/index'),
+      redirect: '/OrderManagement/uncertainOrder',
+      children: [{
+        path: 'uncertainOrder',
+        name: 'uncertainOrder',
+        meta: {
+          icon: 'icon-yueduye-mulu',
+          title: '未确定订单'
+        },
+        component: () => import('@/views/OrderManagement/uncertainOrder.vue'),
+      }, {
+        path: 'reviewedOrder',
+        name: 'reviewedOrder',
+        meta: {
+          icon: 'icon-daishenhe',
+          title: '待审核订单'
+        },
+        component: () => import('@/views/OrderManagement/reviewedOrder.vue'),
+      }, {
+        path: 'pendingOrder',
+        name: 'pendingOrder',
+        meta: {
+          icon: 'icon-daipeisong',
+          title: '待配送订单'
+        },
+        component: () => import('@/views/OrderManagement/pendingOrder.vue'),
+      }, {
+        path: 'deliveryOrder',
+        name: 'deliveryOrder',
+        meta: {
+          icon: 'icon-peisongzhong',
+          title: '配送中订单'
+        },
+        component: () => import('@/views/OrderManagement/deliveryOrder.vue'),
+      }, {
+        path: 'completedOrder',
+        name: 'completedOrder',
+        meta: {
+          icon: 'icon-yiwanchengdingdan',
+          title: '已完成订单'
+        },
+        component: () => import('@/views/OrderManagement/completedOrder.vue'),
+      }, {
+        path: 'cancelledOrder',
+        name: 'cancelledOrder',
+        meta: {
+          icon: 'icon-yiquxiaodingdan',
+          title: '已取消订单'
+        },
+        component: () => import('@/views/OrderManagement/cancelledOrder.vue'),
+      }, {
+        path: 'rejectionOrder',
+        name: 'rejectionOrder',
+        meta: {
+          icon: 'icon-yiquxiaodingdan',
+          title: '已拒收订单'
+        },
+        component: () => import('@/views/OrderManagement/rejectionOrder.vue'),
+      }, ]
+    }, {
+      path: '/OrderReview',
+      name: 'OrderReview',
+      meta: {
+        icon: 'icon-dingdanshenhe',
+        title: '订单审核'
+      },
+      component: () => import('@/views/OrderManagement/OrderReview'),
+    },
+    {
+      path: '/statisticalManagement',
+      name: 'statisticalManagement',
+      meta: {
+        icon: 'icon-tongjifenxi',
+        title: '统计分析管理'
+      },
+      component: () => import('@/views/page/statisticalManagement'),
+    },
+    // {
+    //   path: '/WaybillManagement',
+    //   name: 'WaybillManagement',
+    //   meta: {
+    //     icon: 'icon-yundanguanli',
+    //     title: '运单管理'
+    //   },
+    //   component: () => import('@/views/system/WaybillManagement'),
+    // }
+  ]
+}

+ 20 - 0
src/config/salesman.js

@@ -0,0 +1,20 @@
+// 销售员菜单salesman
+export const salesmanRouter = [{
+    path: '/login',
+    name: 'login',
+    component: () => import( /* webpackChunkName: "user" */ '@/views/login'),
+  }, {
+    path: '/WaybillInquiry',
+    name: 'WaybillInquiry',
+    component: () => import( /* webpackChunkName: "user" */ '@/views/WaybillInquiry'),
+  }, {
+    path: '/newInquiry',
+    name: 'newInquiry',
+    component: () => import( /* webpackChunkName: "user" */ '@/views/newInquiry'),
+  },
+  {
+    path: '/FourOhFour',
+    name: 'FourOhFour',
+    component: () => import( /* webpackChunkName: "fail" */ '@/views/FourOhFour')
+  }
+]

+ 1 - 3
src/main.js

@@ -26,9 +26,7 @@ Vue.prototype.$echarts = echarts;
 // 初始化vue-amap
 VueAMap.initAMapApiLoader({
   key: '7c0390cf6ae1cd6afeef85becf6fa515',
-  plugin: ['AMap.Geocoder', 'AMap.ReverseGeocode', 'AMap.Geolocation'], // 添加您需要的插件
-  v: '1.4.4', // 指定版本
-  uiVersion: '1.0'
+  plugin: ['AMap.Geocoder', 'AMap.ReverseGeocode', 'AMap.Geolocation', 'AMap.TrackBack'], // 添加您需要的插件
 });
 
 window._AMapSecurityConfig = {

+ 34 - 39
src/router/generator-routers.js

@@ -1,3 +1,9 @@
+import {
+  intendantRouter
+} from '@/config/intendant'
+import {
+  deliverymanRouter
+} from '@/config/deliveryman'
 // 前端未找到页面路由(固定不用改)
 const notFoundRouter = {
   name: 'FourOhFour',
@@ -47,30 +53,6 @@ const companyRouter = {
     }
   ]
 }
-const clientRouter = {
-  name: 'index',
-  path: '/',
-  component: () => import('@/views/common/Base'),
-  redirect: '/MyWaybill',
-  children: [{
-    path: '/MyWaybill',
-    name: 'MyWaybill',
-    meta: {
-      icon: 'icon-yundan',
-      title: '我的运单'
-    },
-    component: () => import('@/views/system/MyWaybill'),
-  }]
-}
-const userRouter = {
-  path: '/UserManagement',
-  name: 'UserManagement',
-  meta: {
-    icon: 'icon-yonghuguanli',
-    title: '用户管理'
-  },
-  component: () => import('@/views/system/UserManagement'),
-}
 // 根级菜单
 const rootRouter = {
   name: 'index',
@@ -204,7 +186,7 @@ const rootRouter = {
       path: '/OrderReview',
       name: 'OrderReview',
       meta: {
-        icon: 'icon-yundanguanli',
+        icon: 'icon-dingdanshenhe',
         title: '订单审核'
       },
       component: () => import('@/views/OrderManagement/OrderReview'),
@@ -213,7 +195,7 @@ const rootRouter = {
       path: '/statisticalManagement',
       name: 'statisticalManagement',
       meta: {
-        icon: 'icon-yundanguanli',
+        icon: 'icon-tongjifenxi',
         title: '统计分析管理'
       },
       component: () => import('@/views/page/statisticalManagement'),
@@ -238,28 +220,41 @@ const rootRouter = {
 export const generatorDynamicRouter = arrType => {
   return new Promise((resolve, reject) => {
     const routers = []
+    // if (arrType.userType == "sys") {
+    //   if (arrType.deptId === 0) {
+    //     routers.push(notFoundRouter)
+    //     routers.push(companyRouter)
+    //   } else {
+    //     function deleteObjectById(arr, name) {
+    //       return arr.filter(obj => obj.name !== name);
+    //     }
+    //     rootRouter.children = deleteObjectById(rootRouter.children, 'CompanyManagement')
+    //     routers.push(notFoundRouter)
+    //     routers.push(rootRouter)
+    //     if (arrType.type == 1) {
+    //       rootRouter.children = deleteObjectById(rootRouter.children, 'UserManagement')
+    //       rootRouter.children.splice(1, 0, userRouter)
+    //     } else {
+    //       rootRouter.children = deleteObjectById(rootRouter.children, 'UserManagement')
+    //     }
+    //   }
+    // } else {
+    //   routers.push(notFoundRouter)
+    //   routers.push(clientRouter)
+    // }
+    routers.push(notFoundRouter)
     if (arrType.userType == "sys") {
       if (arrType.deptId === 0) {
-        routers.push(notFoundRouter)
         routers.push(companyRouter)
       } else {
-        function deleteObjectById(arr, name) {
-          return arr.filter(obj => obj.name !== name);
-        }
-        rootRouter.children = deleteObjectById(rootRouter.children, 'CompanyManagement')
-        routers.push(notFoundRouter)
-        routers.push(rootRouter)
         if (arrType.type == 1) {
-          rootRouter.children = deleteObjectById(rootRouter.children, 'UserManagement')
-          rootRouter.children.splice(1, 0, userRouter)
+          routers.push(intendantRouter)
         } else {
-          rootRouter.children = deleteObjectById(rootRouter.children, 'UserManagement')
+          routers.push(deliverymanRouter)
         }
       }
-    } else {
-      routers.push(notFoundRouter)
-      routers.push(clientRouter)
     }
+    // console.log(routers, 243)
     resolve(routers)
   })
 }

+ 1 - 0
src/utils/request.js

@@ -10,6 +10,7 @@ import {
 } from '@/api/login'
 // 创建 axios 实例
 const Url = "https://colddelivery.coldbaozhida.com/cold_delivery"
+const token = localStorage.getItem('T_tokey')
 // const Url = "http://192.168.11.77:6280" //测试
 const request = axios.create({
   // API 请求的默认前缀

+ 23 - 4
src/views/IceCreamFreezer/IceManagement.vue

@@ -39,7 +39,9 @@
   import forms from '@/components/forms'
   import {
     formRules,
+    formRulesCold,
     employee,
+    employeeCold
   } from "./freezer.js";
   import {
     iceraftStatus
@@ -83,21 +85,32 @@
         Total: 0,
         tableData: [],
         operationType: '',
-        tableList: employee(),
+        tableList: [],
         staffTitle: '添加',
         staffDialogVisible: false,
-        formRuleList: formRules(),
+        formRuleList: [],
         ruleForm: {
           code: '',
           status: null,
           freezeClaim: '',
+          label: '',
+          suitableForColdTime: '',
         },
         confirmLoading: false,
         selectingData: {},
         iceTracing: true,
+        // 是否释冷
+        iceColdFlag: false,
       }
     },
     mounted() {
+      if (this.iceColdFlag) {
+        this.tableList = employeeCold()
+        this.formRuleList = formRulesCold()
+      } else {
+        this.tableList = employee()
+        this.formRuleList = formRules()
+      }
       this.getList()
     },
     methods: {
@@ -133,6 +146,8 @@
               codeList: arr,
               status: this.ruleForm.status,
               freezeClaim: Number(this.ruleForm.freezeClaim),
+              label: this.ruleForm.label,
+              suitableForColdTime: Number(this.ruleForm.suitableForColdTime),
             }
             addIceRaft(params).then(res => {
               if (res.code == 200) {
@@ -154,6 +169,8 @@
               code: this.ruleForm.code,
               status: this.ruleForm.status,
               freezeClaim: Number(this.ruleForm.freezeClaim),
+              label: this.ruleForm.label,
+              suitableForColdTime: Number(this.ruleForm.suitableForColdTime),
             }
             putIceRaft(params).then(res => {
               if (res.code == 200) {
@@ -174,7 +191,6 @@
         }
       },
       buttonData(row, type) {
-        this.formRuleList = formRules();
         this.selectingData = row
         this.operationType = type
         if (type == 'edit') {
@@ -186,6 +202,8 @@
               this.ruleForm.code = row.code
               this.ruleForm.status = row.status
               this.ruleForm.freezeClaim = row.freezeClaim
+              this.ruleForm.label = row.label
+              this.ruleForm.suitableForColdTime = row.suitableForColdTime
             })
           })
         } else if (type == 'logs') {
@@ -197,6 +215,8 @@
               this.ruleForm.code = row.code
               this.ruleForm.status = row.status
               this.ruleForm.freezeClaim = row.freezeClaim
+              this.ruleForm.label = row.label
+              this.ruleForm.suitableForColdTime = row.suitableForColdTime
             })
           })
           this.formRuleList.forEach((item, index) => {
@@ -207,7 +227,6 @@
         }
       },
       openModel(type) {
-        this.formRuleList = formRules();
         this.iceTracing = true
         this.staffTitle = '添加'
         this.staffDialogVisible = true

+ 15 - 5
src/views/IceCreamFreezer/IceTracingManagement.vue

@@ -15,7 +15,7 @@
     </div>
     <!-- 历史记录 -->
     <div class="card_history">
-      <el-dialog top="5vh" title="历史记录" :visible.sync="historyVisible" width="90%" :close-on-click-modal="false"
+      <el-dialog fullscreen title="历史记录" :visible.sync="historyVisible" :close-on-click-modal="false"
         @close="closeHistory">
         <tables :historyFlag="true" :tableList="historyList" :tableData="historyData" @buttonData="historyButton">
         </tables>
@@ -40,7 +40,7 @@
     <el-dialog :title="staffTitle" :visible.sync="staffDialogVisible" width="600px" :close-on-click-modal="false"
       @close="closeDialog">
       <forms ref="childRules" :formNewList="formRuleList" :ruleForm="ruleForm" :iceTracing="true" :iceBank="true"
-        labelWidth="100px" @handleScroll="handleScroll" @remoteMethod="remoteMethod">
+        labelWidth="120px" @handleScroll="handleScroll" @remoteMethod="remoteMethod">
       </forms>
       <span slot="footer" class="dialog-footer" v-if="operationType != 'logs'">
         <el-button plain @click="staffDialogVisible = false">取 消</el-button>
@@ -218,10 +218,13 @@
             trigger: 'blur'
           }],
           options: [],
-        }
+        },
+        // 是否释冷
+        iceColdFlag: false,
       }
     },
     beforeDestroy() {
+      console.log(2)
       clearInterval(this.timer); // 清除定时器
       this.timer = null;
     },
@@ -250,6 +253,8 @@
             this.Total = res.data.count
             this.timer = setTimeout(() => {
               this.getList();
+              clearInterval(this.timer); // 清除定时器
+              this.timer = null;
             }, 60000)
           }
         })
@@ -607,9 +612,11 @@
                 type: 'warning'
               });
               const precisePage = Math.ceil((this.historyTotal - 1) / this.historyPagination.PageSize)
-              this.historyPagination.PageIndex = this.historyPagination.PageIndex > precisePage ? precisePage : this
+              this.historyPagination.PageIndex = this.historyPagination.PageIndex > precisePage ? precisePage :
+                this
+                .historyPagination.PageIndex
+              this.historyPagination.PageIndex = this.historyPagination.PageIndex < 1 ? 1 : this
                 .historyPagination.PageIndex
-              this.historyPagination.PageIndex = this.historyPagination.PageIndex < 1 ? 1 : this.historyPagination.PageIndex
               this.getHistory()
               this.getList()
             }
@@ -663,4 +670,7 @@
 </script>
 
 <style lang="scss" scoped>
+  .card_history ::v-deep .el-dialog__body {
+    padding: 0px 20px !important;
+  }
 </style>

+ 141 - 2
src/views/IceCreamFreezer/freezer.js

@@ -11,6 +11,10 @@ export const employee = () => {
     label: '编号',
     align: 'center',
   }, {
+    field: 'label',
+    label: '冰排备注',
+    align: 'center',
+  }, {
     field: 'status',
     label: '状态',
     align: 'center',
@@ -42,7 +46,59 @@ export const employee = () => {
     }]
   }]
 }
-
+export const employeeCold = () => {
+  return [{
+    field: 'index',
+    label: '序号',
+    align: 'center',
+  }, {
+    field: 'code',
+    label: '编号',
+    align: 'center',
+  }, {
+    field: 'label',
+    label: '冰排备注',
+    align: 'center',
+  }, {
+    field: 'status',
+    label: '状态',
+    align: 'center',
+    options: iceraftStatus()
+  }, {
+    field: 'freezeClaim',
+    label: '冷冻要求',
+    align: 'center',
+  }, {
+    field: 'suitableForCold',
+    label: '释冷温度',
+    align: 'center',
+  }, {
+    field: 'suitableForColdTime',
+    label: '释冷地点',
+    align: 'center',
+  }, {
+    field: 'action',
+    label: '操作',
+    colWidth: '260px',
+    align: 'center',
+    labelButton: [{
+      type: 'logs',
+      label: '详情',
+      icon: 'el-icon-tickets',
+      style: 'success',
+    }, {
+      type: 'edit',
+      label: '编辑',
+      icon: 'el-icon-edit',
+      style: 'primary',
+    }, {
+      type: 'del',
+      label: '删除',
+      icon: 'el-icon-delete',
+      style: 'danger',
+    }]
+  }]
+}
 export const formRules = () => {
   return [{
     field: 'code',
@@ -56,6 +112,17 @@ export const formRules = () => {
       trigger: 'blur'
     }]
   }, {
+    field: 'label',
+    label: '冰排备注',
+    placeholder: '请输入冰排备注',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '请输入冰排备注',
+      trigger: 'blur'
+    }]
+  }, {
     field: 'status',
     label: '状态',
     placeholder: '状态',
@@ -79,5 +146,77 @@ export const formRules = () => {
       message: '请输入冷冻时间',
       trigger: 'blur'
     }]
-  }]
+  },]
+}
+export const formRulesCold = () => {
+  return [{
+    field: 'code',
+    label: '编号',
+    placeholder: '请输入编号',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '请输入编号',
+      trigger: 'blur'
+    }]
+  }, {
+    field: 'label',
+    label: '冰排备注',
+    placeholder: '请输入冰排备注',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '请输入冰排备注',
+      trigger: 'blur'
+    }]
+  }, {
+    field: 'status',
+    label: '状态',
+    placeholder: '状态',
+    type: 'radio',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '选择状态',
+      trigger: 'change'
+    }],
+    options: iceraftStatus()
+  }, {
+    field: 'freezeClaim',
+    label: '冷冻要求',
+    placeholder: '请输入冷冻时间',
+    type: 'input',
+    colWidth: 24,
+    unit: '小时',
+    rules: [{
+      required: true,
+      message: '请输入冷冻时间',
+      trigger: 'blur'
+    }]
+  }, {
+    field: 'suitableForCold',
+    label: '释冷温度',
+    placeholder: '请输入冰排释冷温度',
+    type: 'input',
+    colWidth: 24,
+    unit: '℃',
+    rules: [{
+      required: true,
+      message: '请输入冰排释冷温度',
+      trigger: 'blur'
+    }]
+  }, {
+    field: 'suitableForColdTime',
+    label: '释冷地点',
+    placeholder: '请输入释冷地点',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '请输入释冷地点',
+      trigger: 'blur'
+    }]
+  }, ]
 }

+ 74 - 1
src/views/IceCreamFreezer/iceRaft.js

@@ -24,6 +24,38 @@ export const employee = () => {
     label: '出库时间',
     align: 'center',
   }, {
+    field: 'multistage',
+    label: '保温箱温湿度记录',
+    children: [{
+      field: 'reCheck.nickName',
+      label: '开始时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '结束时间',
+      align: 'center',
+    }, ]
+  }, {
+    field: 'multistage',
+    label: '冰排释冷',
+    children: [{
+      field: 'iceRaftRecord.outStorageTime',
+      label: '开始时间',
+      align: 'center',
+    }, {
+      field: 'iceRaftRecord.endForColdTime',
+      label: '结束时间',
+      align: 'center',
+    }, {
+      field: 'suitableForColdTime',
+      label: '释冷时间',
+      align: 'center',
+    }, {
+      field: 'iceRaftRecord.suitableForCold',
+      label: '释冷温度',
+      align: 'center',
+    }]
+  }, {
     field: 'location',
     label: '所在位置',
     align: 'center',
@@ -39,6 +71,7 @@ export const employee = () => {
     field: 'action',
     label: '操作',
     align: 'center',
+    colWidth: '90px',
     labelButton: [{
       type: 'logs',
       label: '历史记录',
@@ -67,6 +100,34 @@ export const historyRecord = () => {
     label: '出库时间',
     align: 'center',
   }, {
+    field: 'multistage',
+    label: '保温箱温湿度记录',
+    children: [{
+      field: 'reCheck.nickName',
+      label: '开始时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '结束时间',
+      align: 'center',
+    }, ]
+  }, {
+    field: 'multistage',
+    label: '冰排释冷',
+    children: [{
+      field: 'reCheck.nickName',
+      label: '开始时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '结束时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '释冷时间',
+      align: 'center',
+    }, ]
+  }, {
     field: 'location',
     label: '所在位置',
     align: 'center',
@@ -81,7 +142,7 @@ export const historyRecord = () => {
   }, {
     field: 'action',
     label: '操作',
-    colWidth: '240px',
+    colWidth: '160px',
     align: 'center',
     labelButton: [{
       type: 'edit',
@@ -142,6 +203,18 @@ export const freezerRules = () => {
     //   }],
     //   options: [],
     // },
+    // {
+    //   field: 'suitableForCold',
+    //   label: '冰排释冷温度',
+    //   placeholder: '请输入冰排释冷温度',
+    //   type: 'input',
+    //   colWidth: 24,
+    //   rules: [{
+    //     required: true,
+    //     message: '请输入冰排释冷温度',
+    //     trigger: 'blur'
+    //   }]
+    // },
     {
       field: 'code',
       label: '冰排编号',

+ 24 - 0
src/views/IceCreamFreezer/store.js

@@ -15,6 +15,10 @@ export const employee = () => {
     label: '门店详细地址',
     align: 'center',
   }, {
+    field: 'remark',
+    label: '备注',
+    align: 'center',
+  }, {
     field: 'action',
     label: '操作',
     colWidth: '260px',
@@ -61,5 +65,25 @@ export const formRules = () => {
       message: '请输入门店详细地址',
       trigger: 'blur'
     }]
+  }, {
+    field: 'coldKey',
+    label: '冷链3.0公司秘钥',
+    placeholder: '请输入冷链3.0公司秘钥',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '请输入冷链3.0公司秘钥',
+      trigger: 'blur'
+    }]
+  }, {
+    field: 'remark',
+    label: '备注',
+    placeholder: '请输入备注',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: false,
+    }]
   }, ]
 }

+ 24 - 20
src/views/IceCreamFreezer/storeManagement.vue

@@ -15,7 +15,7 @@
     </div>
     <el-dialog :title="staffTitle" :visible.sync="staffDialogVisible" width="600px" :close-on-click-modal="false"
       @close="closeDialog">
-      <forms ref="childRules" :formNewList="formRuleList" :ruleForm="ruleForm" labelWidth="120px">
+      <forms ref="childRules" :formNewList="formRuleList" :ruleForm="ruleForm" labelWidth="130px">
       </forms>
       <span slot="footer" class="dialog-footer" v-if="operationType != 'logs'">
         <el-button plain @click="staffDialogVisible = false">取 消</el-button>
@@ -27,11 +27,13 @@
 
 <script>
   import {
-    getAddress,
-    addAddress,
-    putAddress,
-    delAddress
-  } from '@/api/address'
+    getCompany,
+    getCompanyDetails,
+    addCompany,
+    putCompany,
+    delCompany,
+    getCompanyDept
+  } from '@/api/company'
   import actionBar from '@/components/actionBar'
   import tables from '@/components/tables'
   import pagination from '@/components/pagination'
@@ -52,7 +54,7 @@
       return {
         operateList: [{
           type: 'add',
-          title: '添加',
+          title: '添加门店',
           icon: 'el-icon-plus',
         }],
         formList: [{
@@ -78,15 +80,18 @@
         formRuleList: [],
         ruleForm: {
           name: '',
-          phone: '',
+          remark: '',
+          coldKey: '',
           address: '',
-          addressType: '',
         },
         confirmLoading: false,
         selectingData: {},
+        userList: {},
       }
     },
     mounted() {
+      const arr = localStorage.getItem('userList')
+      this.userList = JSON.parse(arr)
       this.getList()
     },
     methods: {
@@ -103,7 +108,7 @@
           pageSize: this.Pagination.PageSize,
           ...this.searchValue
         }
-        getAddress(params).then(res => {
+        getCompanyDept(params).then(res => {
           if (res.code == 200) {
             this.tableData = res.data.list
             this.Total = res.data.count
@@ -117,10 +122,10 @@
           if (this.operationType == 'add') {
             this.confirmLoading = true
             var params = {
+              parentId: this.userList.dept.id,
               ...this.ruleForm
             }
-            params.addressType = 'consignee'
-            addAddress(params).then(res => {
+            addCompany(params).then(res => {
               if (res.code == 200) {
                 this.$message({
                   message: '操作成功',
@@ -138,11 +143,11 @@
             var params = {
               id: this.selectingData.id,
               name: this.ruleForm.name,
-              phone: this.ruleForm.phone,
+              remark: this.ruleForm.remark,
+              coldKey: this.ruleForm.coldKey,
               address: this.ruleForm.address,
-              addressType: this.ruleForm.addressType,
             }
-            putAddress(params).then(res => {
+            putCompany(params).then(res => {
               if (res.code == 200) {
                 this.$message({
                   message: '操作成功',
@@ -171,9 +176,9 @@
           setTimeout(() => {
             this.$nextTick(() => {
               this.ruleForm.name = row.name
-              this.ruleForm.phone = row.phone
+              this.ruleForm.remark = row.remark
               this.ruleForm.address = row.address
-              this.ruleForm.addressType = row.addressType
+              this.ruleForm.coldKey = row.coldKey
             })
           })
         } else if (type == 'logs') {
@@ -196,12 +201,12 @@
       },
       // 删除该地址
       deleteUser(id) {
-        this.$confirm('此操作将永久删除该地址, 是否继续?', '提示', {
+        this.$confirm('此操作将永久删除该门店, 是否继续?', '提示', {
           confirmButtonText: '确定',
           cancelButtonText: '取消',
           type: 'warning'
         }).then(() => {
-          delAddress({
+          delCompany({
             id: id,
           }).then(res => {
             if (res.code == 200) {
@@ -209,7 +214,6 @@
                 message: '操作成功',
                 type: 'success'
               });
-
               const precisePage = Math.ceil((this.Total - 1) / this.Pagination.PageSize)
               this.Pagination.PageIndex = this.Pagination.PageIndex > precisePage ? precisePage : this
                 .Pagination.PageIndex

+ 17 - 1
src/views/OrderManagement/completed.js

@@ -1,6 +1,8 @@
 import {
   startStatus,
-  WaybillStatus
+  WaybillStatus,
+  radiolist,
+  stateList,
 } from '@/assets/js/blockSort'
 export const employee = () => {
   return [{
@@ -116,6 +118,20 @@ export const employee = () => {
     align: 'center',
     colWidth: '180px',
   }, {
+    field: 'paymentType',
+    label: '支付方式',
+    align: 'center',
+    options: radiolist(),
+  }, {
+    field: 'paymentStatus',
+    label: '支付状态',
+    align: 'center',
+    options: stateList(),
+  },{
+    field: 'paymentremark',
+    label: '未结清备注',
+    align: 'center',
+  }, {
     field: 'assessStar',
     label: '服务评价',
     align: 'center',

+ 1 - 1
src/views/OrderManagement/delivered.js

@@ -155,7 +155,7 @@ export const sendList = () => {
     label: '防拆标签图片',
     placeholder: '请上传防拆标签图片',
     type: 'upload',
-    colWidth: 12,
+    colWidth: 24,
     crosswise: true,
     rules: [{
       required: false,

+ 15 - 0
src/views/OrderManagement/pendingOrder.vue

@@ -263,6 +263,21 @@
           this.$refs.picture.prescriptionVisible = true
         } else if (type == 'sign') {
           this.sendDialogVisible = true
+          if (row.tamperProofLabelImg) {
+            var arr = row.tamperProofLabelImg.split(',')
+            var arr3 = []
+            arr.forEach((item, index) => {
+              var arr1 = {
+                url: '',
+              }
+              arr1.url = item
+              arr3.push(arr1)
+            })
+            this.sendRuleForm.fileList = arr3
+            this.sendRuleForm.tamperProofLabelImg = row.tamperProofLabelImg
+          }
+          // this.sendRuleForm.tamperProofLabelImg = row.tamperProofLabelImg
+          this.sendRuleForm.tamperProofLabel = row.tamperProofLabel
           var arr = await this.getUserList()
           this.sendRuleList.forEach(item => {
             if (item.field == 'reCheckId') {

+ 7 - 0
src/views/OrderManagement/rejectionOrder.vue

@@ -97,6 +97,12 @@
           name: 'food2.jpeg',
           url: 'https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg'
         }],
+        receiptsign: {
+          field: 'receiptsign',
+          label: '客户签字图片',
+          align: 'center',
+          colWidth: '180px',
+        },
         receiptImg: {
           field: 'receiptImg',
           label: '拒收图片',
@@ -114,6 +120,7 @@
       let arr = employee()
       const updatedItems = arr.filter(item => item.field !== 'unpackBtn');
       this.tableList = updatedItems
+      this.tableList.push(this.receiptsign)
       this.tableList.push(this.receiptImg)
       this.tableList.push(this.reasonRejection)
       this.getList()

+ 1 - 1
src/views/OrderManagement/uncertain.js

@@ -203,7 +203,7 @@ function validatePassword(rule, value, callback) {
 
 export const signList = () => {
   return [{
-    field: 'reCheckId',
+    field: 'storeId',
     type: 'searchSelect',
     label: '门店',
     placeholder: '请选择门店',

+ 48 - 5
src/views/OrderManagement/uncertainOrder.vue

@@ -22,8 +22,8 @@
     <!-- 处方 -->
     <prescriptionPicture ref="picture" :srcList="srcList" :fileList="fileList"></prescriptionPicture>
     <!-- 添加订单 -->
-    <el-dialog :title="staffTitle" :visible.sync="staffDialogVisible" width="800px" :close-on-click-modal="false"
-      @close="closePopup">
+    <el-dialog top="5vh" :title="staffTitle" :visible.sync="staffDialogVisible" width="800px"
+      :close-on-click-modal="false" @close="closePopup">
       <forms ref="userRules" :formNewList="personnelList" :ruleForm="personnelForm" labelWidth="80px"
         @remoteMethod="remoteSearch">
       </forms>
@@ -62,7 +62,8 @@
     </el-dialog>
     <el-dialog title="转门店" :visible.sync="signDialogVisible" width="500px" :close-on-click-modal="false"
       @close="closeDialog1">
-      <forms ref="signRules" :formNewList="signRuleList" :ruleForm="signRuleForm" labelWidth="80px">
+      <forms ref="signRules" :formNewList="signRuleList" :ruleForm="signRuleForm" labelWidth="80px"
+        @remoteMethod="remoteSearch">
       </forms>
       <span slot="footer" class="dialog-footer">
         <el-button plain @click="signDialogVisible = false">取 消</el-button>
@@ -85,6 +86,9 @@
   import {
     getUser
   } from '@/api/user'
+  import {
+    getCompanyDept
+  } from '@/api/company'
   import actionBar from '@/components/actionBar'
   import tables from '@/components/tables'
   import pagination from '@/components/pagination'
@@ -464,8 +468,8 @@
           arrOrderId.push(row.id)
           this.modifyOrderStatus(arrOrderId, 2)
         } else if (type == 'edit') {
-          this.getReviewerList()
-          this.getDelivererList()
+          // this.getReviewerList()
+          // this.getDelivererList()
           this.conserveFlag = false
           this.staffTitle = '编辑'
           this.staffDialogVisible = true
@@ -497,6 +501,7 @@
         } else if (type == 'sign') {
           this.signDialogVisible = true
           this.waybillNo = row.waybillNo
+          this.getAcquireStore()
         } else if (type == 'delOrder') {
           this.$confirm('此操作将永久删除该订单, 是否继续?', '提示', {
             confirmButtonText: '确定',
@@ -550,6 +555,7 @@
         }
       },
       remoteSearch(value, type) {
+        console.log(value, type, 234)
         this.delivererName = value
         if (type == 'deliveryId') {
           this.personnelList.forEach(item => {
@@ -565,6 +571,13 @@
             }
           })
           this.getReviewerList()
+        } else if (type == 'storeId') {
+          this.signRuleList.forEach(item => {
+            if (item.field == 'storeId') {
+              item.options = []
+            }
+          })
+          this.getAcquireStore()
         }
       },
       // 复核人
@@ -623,6 +636,36 @@
           }
         })
       },
+      // 获取门店
+      getAcquireStore() {
+        var params = {
+          page: 1,
+          pageSize: 999,
+          // type: 3,
+          name: this.delivererName,
+        }
+        getCompanyDept(params).then(res => {
+          // signRuleList
+          if (res.code == 200) {
+            let arr = res.data.list
+            let arrList = []
+            arr.forEach(item1 => {
+              var arrData = {
+                label: null,
+                value: null,
+              }
+              arrData.label = item1.name
+              arrData.value = item1.id
+              arrList.push(arrData)
+            })
+            this.signRuleList.forEach(item => {
+              if (item.field == 'storeId') {
+                item.options = item.options.concat(arrList)
+              }
+            })
+          }
+        })
+      },
       // 地址簿
       bookChangeSize(val) {
         this.bookPagination.PageSize = val

+ 217 - 109
src/views/WaybillInquiry.vue

@@ -2,50 +2,41 @@
   <!-- 运单查询 -->
   <!-- 查询单条温湿度数据 -->
   <div class="waybillquiry_home">
-    <div class="waybillquiry_head">
+    <div class="header">
+      <svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+        viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
+        <defs>
+          <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
+        </defs>
+        <g class="parallax">
+          <use xlink:href="#gentle-wave" x="48" y="0" fill="rgba(255,255,255,0.7" />
+          <use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.5)" />
+          <use xlink:href="#gentle-wave" x="48" y="5" fill="rgba(255,255,255,0.3)" />
+        </g>
+      </svg>
       <div class="card_waybillquiry">
         <el-image style="height: 45px;width: 45px;flex: none;" :src="require('@/assets/logo3.png')"></el-image>
-        <div class="head_title">宝智达冷链运单查询</div>
+        <div class="head_title">宝智达智配送安全追溯</div>
       </div>
-      <!-- <div class="Waybill_inquiry">
-        <span class="title_inquiry">运单查询:</span>
-        <div class="input_card_waybill">
-          <el-input placeholder="请输入内容" v-model="waybillNo" class="input-with-select">
-            <el-button slot="append" icon="el-icon-search" @click="getSearch">查询</el-button>
-          </el-input>
-        </div>
-      </div> -->
     </div>
     <div class="card_search">
-      <div :class="!deviceType ? 'card_table' : 'mobile_table'">
-        <el-tabs type="border-card" v-model="tabIndex" @tab-click="tabChange">
-          <el-tab-pane label="温湿度监控">
-            <div v-if="!deviceType">
-              <humitureSupervision ref="humiture" :waybillNo="waybillNo" :humitureList="humitureList"
-                :probeList="probeList" @selectiveRecord="selectiveRecord"></humitureSupervision>
-            </div>
-            <div v-else>
-              <div class="card_certain" v-for="(item,index) in humitureList">
-                <div class="card_humiture_quiry">
-                  <span class="supervision_title" style="font-weight: 600;">【{{item.title}}】</span>
-                  <span class="supervision_title1">{{item.startTime}}</span>
-                  <span class="supervision_title1">{{item.endTime}}</span>
-                </div>
-                <mobileHumiture ref="movement" :taskId="item.id" :waybillNo="waybillNo"
-                  :probeList="item.deviceSensorList">
-                </mobileHumiture>
-              </div>
-            </div>
-          </el-tab-pane>
-          <el-tab-pane label="物流跟踪">
-            <logisticsTracking :activities="activitiesList"></logisticsTracking>
-          </el-tab-pane>
-          <el-tab-pane label="轨迹查询">
-            <div class="track_waybill">
-              <map-container ref="mapTracing" :trackList="trackList" v-if="tabIndex == '2'"></map-container>
-            </div>
-          </el-tab-pane>
-        </el-tabs>
+      <div class="card_logistics_tab">
+        <div class="title_logist center_in" :class="item.flag ? 'activate_card' :''"
+          v-for="(item,index) in logisticsList" :key="index" @click="selective(item)">
+          {{item.title}}
+        </div>
+      </div>
+      <div v-if="currentId == 1">
+        <humitureSupervision ref="humiture" :waybillNo="waybillNo" :humitureList="humitureList" :probeList="probeList"
+          @selectiveRecord="selectiveRecord"></humitureSupervision>
+      </div>
+      <div v-if="currentId == 2">
+        <logisticsTracking :activities="activitiesList"></logisticsTracking>
+      </div>
+      <div class="track_waybill" v-if="currentId == 3">
+        <map-container ref="mapTracing" :trackList="trackList" v-if="waybillBasic.status == 5"></map-container>
+        <map-delivery ref="mapTracing1" :trackList="trackList" :waybillBasic="waybillBasic"
+          v-if="waybillBasic.status != 5"></map-delivery>
       </div>
     </div>
   </div>
@@ -53,6 +44,7 @@
 
 <script>
   import {
+    getWaybillNo,
     getWaybill,
     getWaybillTask,
     waybillTaskLocus,
@@ -61,6 +53,7 @@
   import humitureSupervision from '@/components/humitureSupervision'
   import mobileHumiture from '@/components/mobileHumiture'
   import MapContainer from '@/components/MapContainer'
+  import MapDelivery from '@/components/MapDelivery'
   import {
     WaybillStatus
   } from '@/assets/js/blockSort'
@@ -74,7 +67,8 @@
       logisticsTracking,
       humitureSupervision,
       mobileHumiture,
-      MapContainer
+      MapContainer,
+      MapDelivery
     },
     data() {
       return {
@@ -88,10 +82,25 @@
         probeList: [],
         trackList: [],
         deviceType: false,
+        waybillBasic: {},
+        logisticsList: [{
+          id: 1,
+          flag: true,
+          title: '温湿度监控'
+        }, {
+          id: 2,
+          flag: false,
+          title: '物流跟踪'
+        }, {
+          id: 3,
+          flag: false,
+          title: '轨迹查询'
+        }],
+        currentId: 1,
       }
     },
     created() {
-      document.title = '宝智达运单查询'
+      document.title = '宝智达智配送安全追溯'
 
       function isMobile() {
         let userAgentInfo = navigator.userAgent;
@@ -116,15 +125,6 @@
           this.myChart1.resize();
         });
       },
-      getSearch() {
-        if (this.tabIndex == 0 || this.tabIndex == '0') {
-          this.getTask()
-        } else if (this.tabIndex == 1 || this.tabIndex == '1') {
-          this.getList()
-        } else if (this.tabIndex == 2 || this.tabIndex == '2') {
-          this.getTaskLocus()
-        }
-      },
       getList() {
         getWaybill({
           waybillNo: this.waybillNo,
@@ -156,11 +156,22 @@
           }
         })
       },
+      // 获取运单基本信息
+      getInformation() {
+        getWaybillNo({
+          waybillNo: this.waybillNo,
+        }).then(res => {
+          if (res.code == 200) {
+            this.waybillBasic = res.data
+          }
+        })
+      },
       // 轨迹查询
       getTaskLocus() {
-        this.trackList = []
+        let that = this
+        that.trackList = []
         waybillTaskLocus({
-          waybillNo: this.waybillNo,
+          waybillNo: that.waybillNo,
         }).then(res => {
           if (res.code == 200) {
             let arrList = res.data
@@ -168,13 +179,19 @@
               arrList.forEach(item => {
                 if (item.T_site != '0,0' && item.T_site) {
                   const data = item.T_site.split(',')
-                  this.trackList.push(data)
+                  that.trackList.push(data)
                 }
               })
             }
-            this.$nextTick(() => {
+            that.$nextTick(() => {
               setTimeout(() => {
-                this.$refs.mapTracing.keyUpSearch()
+                if (that.currentId == 3) {
+                  if (that.waybillBasic.status == 5) {
+                    that.$refs.mapTracing.keyUpSearch()
+                  } else {
+                    that.$refs.mapTracing1.keyUpSearch()
+                  }
+                }
               }, 100)
             })
           }
@@ -187,6 +204,7 @@
         }).then(res => {
           if (res.code == 200) {
             let arrlist = []
+            console.log(res, 776)
             if (res.data.list) {
               arrlist = res.data.list
             }
@@ -200,13 +218,9 @@
               })
               this.humitureList = arrlist
               this.$nextTick(() => {
-                if (!this.deviceType) {
+                if (this.currentId == 1) {
                   this.$refs.humiture.selectType()
                   this.$refs.humiture.inverseData()
-                } else if (this.tabIndex == 1 || this.tabIndex == '1' && this.deviceType) {
-                  this.humitureList.forEach((item1, index) => {
-                    this.$refs.movement[index].getHumitureList()
-                  })
                 }
               })
             }
@@ -220,6 +234,27 @@
           this.$refs.humiture.inverseData()
         })
       },
+      // tab选择
+      async selective(event) {
+        if (this.currentId != event.id) {
+          if (event.id == 1) {
+            await this.getTask()
+          } else if (event.id == 2) {
+            await this.getList()
+          } else if (event.id == 3) {
+            await this.getInformation()
+            await this.getTaskLocus()
+          }
+        }
+        this.logisticsList.forEach(item => {
+          if (event.id == item.id) {
+            item.flag = true
+            this.currentId = event.id
+          } else {
+            item.flag = false
+          }
+        })
+      },
       reverseGeocode(longitude, latitude) {
         return new Promise((resolve, reject) => {
           var geocoder = new AMap.Geocoder({
@@ -234,31 +269,94 @@
           });
         })
       },
-      tabChange(value) {
-        this.getSearch()
-      }
     }
   }
 </script>
 
 <style lang="scss" scoped>
-  .waybillquiry_home {
-    display: flex;
-    justify-content: center;
-    flex-direction: column;
-    align-items: center;
+  .header {
+    position: relative;
+    width: 100%;
+    text-align: center;
+    background: linear-gradient(60deg, rgba(0, 172, 193, 1) 0%, rgba(84, 58, 183, 1) 100%);
+    color: white;
+    border-bottom: 1px solid #fff;
+  }
+
+  .waves {
+    position: relative;
+    width: 100%;
+    height: 70px;
+    margin-bottom: -4px;
+  }
+
+  .parallax>use {
+    animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
+  }
+
+  .parallax>use:nth-child(1) {
+    animation-delay: -2s;
+    animation-duration: 7s;
+  }
+
+  .parallax>use:nth-child(2) {
+    animation-delay: -3s;
+    animation-duration: 10s;
   }
 
-  .waybillquiry_head {
-    width: 95%;
+  .parallax>use:nth-child(3) {
+    animation-delay: -4s;
+    animation-duration: 13s;
+  }
+
+  .parallax>use:nth-child(4) {
+    animation-delay: -5s;
+    animation-duration: 20s;
+  }
+
+  @keyframes move-forever {
+    0% {
+      transform: translate3d(-90px, 0, 0);
+    }
+
+    100% {
+      transform: translate3d(85px, 0, 0);
+    }
+  }
+
+  /*Shrinking for mobile*/
+  @media (max-width: 768px) {
+    .waves {
+      height: 40px;
+      min-height: 40px;
+    }
+
+    .card_waybillquiry {
+      height: 40px;
+    }
+
+    .content {
+      height: 30vh;
+    }
+
+    h1 {
+      font-size: 24px;
+    }
+  }
+
+  .waybillquiry_home {
     display: flex;
-    flex-direction: column;
     justify-content: center;
+    flex-direction: column;
     align-items: center;
+    height: 100%;
   }
 
   .card_waybillquiry {
-    margin: 15px;
+    position: absolute;
+    top: 0;
+    left: 30px;
+    height: 70px;
     display: flex;
     align-items: center;
   }
@@ -274,66 +372,76 @@
     display: flex;
     flex-direction: column;
     width: 100%;
-    margin-bottom: 30px;
+    flex: 1;
   }
 
-  .Waybill_inquiry {
-    margin-left: 6.25rem;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin-bottom: 1.25rem;
-  }
-
-  .title_inquiry {
-    flex: none;
-    font-size: 18px;
-    font-weight: 500;
-    margin-right: 10px;
+  .card_table {
+    width: 100%;
   }
 
-  .input_card_waybill {
-    width: 500px;
+  .track_waybill {
+    width: 100%;
+    height: 100%;
   }
 
-  .card_table {
+  .mobile_table {
     width: 100%;
   }
 
-  .card_Einzelband {
-    width: 100%;
-    height: 100%;
-    display: flex;
-    justify-content: space-evenly;
+  .mobile_table ::v-deep .el-tabs--border-card>.el-tabs__content {
+    padding: 0px !important;
   }
 
-  .chart_card {
+  .card_logistics_tab {
     display: flex;
     align-items: center;
-    justify-content: center;
-    height: 500px;
+    background-color: #F5F7FA;
+    border-bottom: 1px solid #E4E7ED;
   }
 
-  #pie {
-    width: 300px;
-    height: 300px;
+  .title_logist {
+    cursor: pointer;
+    padding: 0 20px;
+    font-size: 14px;
+    height: 40px;
+    border-left: 1px solid transparent;
+    border-right: 1px solid transparent;
+    border-right-color: #F5F7FA;
+    border-left-color: #F5F7FA;
   }
 
-  #pie1 {
-    width: 300px;
-    height: 300px;
+  .title_logist:hover {
+    color: #409EFF;
   }
 
-  .track_waybill {
-    width: 100%;
-    height: 75vh;
+  .activate_card {
+    background-color: #fff;
+    color: #409EFF;
+    border-right-color: #DCDFE6;
+    border-left-color: #DCDFE6;
   }
 
-  .mobile_table {
+  .card_certain {
+    display: flex;
     width: 100%;
+    border-bottom: 1px solid #DCDFE6;
   }
 
-  .mobile_table ::v-deep .el-tabs--border-card>.el-tabs__content {
-    padding: 0px !important;
+  .card_humiture_quiry {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    padding-bottom: 10px;
+    border-right: 1px solid #DCDFE6;
+    padding-left: 10px;
+    padding-top: 10px;
+  }
+
+  .supervision_title {
+    font-size: 16px;
+  }
+
+  .supervision_title1 {
+    font-size: 15px;
   }
 </style>

+ 1 - 1
src/views/common/topNav.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="card_head">
     <el-image style="height: 35px;width: 35px;" :src="require('@/assets/logo3.png')"></el-image>
-    <div class="head_title">宝智达冷链送药追溯平台</div>
+    <div class="head_title">智配送安全追溯AI管理平台</div>
     <i class="card_unpack" :class="iconFlag ? 'el-icon-s-unfold' : 'el-icon-s-fold'" @click="getUnpack"></i>
   </div>
 </template>

+ 1 - 1
src/views/login.vue

@@ -3,7 +3,7 @@
     <div class="card_login_form">
       <div class="form_left center_in">
         <div class="form_login">
-          <h3>宝智达-冷链送药追溯平台</h3>
+          <h3>智配送安全追溯AI管理平台</h3>
           <div class="card_form">
             <el-input v-model="form.name" size="medium" placeholder="请输入账号"></el-input>
           </div>

+ 229 - 33
src/views/newInquiry.vue

@@ -1,14 +1,74 @@
 <template>
   <!-- 运单查询 -->
-  <div class="waybillquiry_home">
-    <div class="waybillquiry_head">
+  <div class="waybillquiry_home" :style="{height:currentId == 3?'100%':''}">
+    <!-- <div class="waybillquiry_head">
       <div class="card_waybillquiry">
         <el-image style="height: 45px;width: 45px;flex: none;" :src="require('@/assets/logo3.png')"></el-image>
-        <div class="head_title">宝智达冷链运单查询</div>
+        <div class="head_title">宝智达智配送安全追溯</div>
+      </div>
+    </div> -->
+    <div class="header">
+      <svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+        viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
+        <defs>
+          <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
+        </defs>
+        <g class="parallax">
+          <use xlink:href="#gentle-wave" x="48" y="0" fill="rgba(255,255,255,0.7" />
+          <use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.5)" />
+          <use xlink:href="#gentle-wave" x="48" y="5" fill="rgba(255,255,255,0.3)" />
+        </g>
+      </svg>
+      <div class="card_waybillquiry">
+        <el-image style="height: 30px;width: 30px;flex: none;" :src="require('@/assets/logo3.png')"></el-image>
+        <div class="head_title">宝智达智配送安全追溯</div>
       </div>
     </div>
+    <div style="width: 100%;height: 40px;"></div>
     <div class="card_search">
-      <div :class="!deviceType ? 'card_table' : 'mobile_table'">
+      <div class="card_logistics_tab">
+        <div class="title_logist center_in" :class="item.flag ? 'activate_card' :''"
+          v-for="(item,index) in logisticsList" :key="index" @click="selective(item)">
+          {{item.title}}
+        </div>
+      </div>
+      <div v-if="currentId == 1">
+        <waybillInformation ref="information" :list="waybillBasic" @getReceiving="getReceiving" @getSubmit="getSubmit">
+        </waybillInformation>
+      </div>
+      <div v-if="currentId == 2">
+        <div v-if="humitureList.length > 0">
+          <div class="card_certain" v-for="(item,index) in humitureList">
+            <div class="card_humiture_quiry">
+              <span class="supervision_title" style="font-weight: 600;">【{{item.title}}】</span>
+              <span class="supervision_title1">{{item.startTime}}</span>
+              <span class="supervision_title1">{{item.endTime}}</span>
+            </div>
+            <mobileHumiture ref="movement" :taskId="item.id" :waybillNo="waybillNo" :probeList="item.deviceSensorList">
+            </mobileHumiture>
+          </div>
+        </div>
+        <el-empty :image-size="100" description="暂无数据" v-else></el-empty>
+      </div>
+      <div style="height: 100%;" v-if="currentId == 3">
+        <div class="track_waybill">
+          <map-container ref="mapTracing" :trackList="trackList"
+            v-if="currentId == 3 && waybillBasic.status == 5"></map-container>
+          <map-delivery ref="mapTracing1" :trackList="trackList" :waybillBasic="waybillBasic"
+            v-if="currentId == 3 && waybillBasic.status != 5"></map-delivery>
+          <div class="card_logistics">
+            <div class="center_in" @click="clickImg">
+              <el-image :class="logisticsFlag ? '' : 'overturn'" style="height: 29px;width: 40px;flex: none;"
+                :src="require('@/assets/images/unfold.png')"></el-image>
+            </div>
+            <div v-if="logisticsFlag">
+              <div class="logistics_title">物流详情</div>
+              <logisticsTracking :activities="activitiesList"></logisticsTracking>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- <div :class="!deviceType ? 'card_table' : 'mobile_table'">
         <el-tabs type="border-card" v-model="tabIndex" @tab-click="tabChange">
           <el-tab-pane label="基本信息">
             <waybillInformation ref="information" :list="waybillBasic" @getReceiving="getReceiving"
@@ -49,7 +109,7 @@
             </div>
           </el-tab-pane>
         </el-tabs>
-      </div>
+      </div> -->
     </div>
   </div>
 </template>
@@ -101,10 +161,24 @@
         deviceType: false,
         waybillBasic: {},
         logisticsFlag: true,
+        logisticsList: [{
+          id: 1,
+          flag: true,
+          title: '基本信息'
+        }, {
+          id: 2,
+          flag: false,
+          title: '温湿度监控'
+        }, {
+          id: 3,
+          flag: false,
+          title: '轨迹查询'
+        }],
+        currentId: 1,
       }
     },
     created() {
-      document.title = '宝智达运单查询'
+      document.title = '宝智达智配送安全追溯'
 
       function isMobile() {
         let userAgentInfo = navigator.userAgent;
@@ -178,9 +252,10 @@
       },
       // 轨迹查询
       getTaskLocus() {
-        this.trackList = []
+        let that = this
+        that.trackList = []
         waybillTaskLocus({
-          waybillNo: this.waybillNo,
+          waybillNo: that.waybillNo,
         }).then(res => {
           if (res.code == 200) {
             let arrList = res.data
@@ -188,16 +263,18 @@
               arrList.forEach(item => {
                 if (item.T_site != '0,0' && item.T_site) {
                   const data = item.T_site.split(',')
-                  this.trackList.push(data)
+                  that.trackList.push(data)
                 }
               })
             }
-            this.$nextTick(() => {
+            that.$nextTick(() => {
               setTimeout(() => {
-                if (this.waybillBasic.status == 3) {
-                  this.$refs.mapTracing.keyUpSearch()
-                } else {
-                  this.$refs.mapTracing1.keyUpSearch()
+                if (that.currentId == 3) {
+                  if (that.waybillBasic.status == 5) {
+                    that.$refs.mapTracing.keyUpSearch()
+                  } else {
+                    that.$refs.mapTracing1.keyUpSearch()
+                  }
                 }
               }, 100)
             })
@@ -224,14 +301,19 @@
               })
               this.humitureList = arrlist
               this.$nextTick(() => {
-                if (!this.deviceType) {
-                  // this.$refs.humiture.selectType()
-                  // this.$refs.humiture.inverseData()
-                } else if (this.tabIndex == 1 || this.tabIndex == '1' && this.deviceType) {
+                if (this.currentId == 2) {
                   this.humitureList.forEach((item1, index) => {
                     this.$refs.movement[index].getHumitureList()
                   })
                 }
+                // if (!this.deviceType) {
+                //   // this.$refs.humiture.selectType()
+                //   // this.$refs.humiture.inverseData()
+                // } else if (this.currentId == 1 || this.tabIndex == '1' && this.deviceType) {
+                //   this.humitureList.forEach((item1, index) => {
+                //     this.$refs.movement[index].getHumitureList()
+                //   })
+                // }
               })
             }
           }
@@ -241,7 +323,7 @@
       getReceiving(value) {
         let params = {
           waybillNo: this.waybillBasic.waybillNo,
-          status: 3,
+          status: 5,
           receiptImg: value.images,
           rejectionReason: '',
           assessStar: value.assessStar,
@@ -272,7 +354,7 @@
       getSubmit(value) {
         let params = {
           waybillNo: this.waybillBasic.waybillNo,
-          status: 4,
+          status: 6,
           receiptImg: value.images,
           rejectionReason: value.reason,
           assessStar: value.assessStar,
@@ -327,6 +409,27 @@
       tabChange(value) {
         this.getSearch()
       },
+      // tab选择
+      async selective(event) {
+        if (this.currentId != event.id) {
+          if (event.id == 1) {
+            await this.getInformation()
+          } else if (event.id == 2) {
+            await this.getTask()
+          } else if (event.id == 3) {
+            await this.getList()
+            await this.getTaskLocus()
+          }
+        }
+        this.logisticsList.forEach(item => {
+          if (event.id == item.id) {
+            item.flag = true
+            this.currentId = event.id
+          } else {
+            item.flag = false
+          }
+        })
+      },
       clickImg() {
         if (this.logisticsFlag) {
           this.logisticsFlag = false
@@ -339,29 +442,92 @@
 </script>
 
 <style lang="scss" scoped>
-  .waybillquiry_home {
-    display: flex;
-    justify-content: center;
-    flex-direction: column;
-    align-items: center;
+  .header {
+    position: fixed;
+    top: 0;
+    width: 100%;
+    height: 40px;
+    text-align: center;
+    background: linear-gradient(60deg, rgba(0, 172, 193, 1) 0%, rgba(84, 58, 183, 1) 100%);
+    color: white;
   }
 
-  .waybillquiry_head {
-    width: 95%;
+  .waves {
+    position: relative;
+    width: 100%;
+    height: 40px;
+    margin-bottom: -7px;
+  }
+
+  .parallax>use {
+    animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
+  }
+
+  .parallax>use:nth-child(1) {
+    animation-delay: -2s;
+    animation-duration: 7s;
+  }
+
+  .parallax>use:nth-child(2) {
+    animation-delay: -3s;
+    animation-duration: 10s;
+  }
+
+  .parallax>use:nth-child(3) {
+    animation-delay: -4s;
+    animation-duration: 13s;
+  }
+
+  .parallax>use:nth-child(4) {
+    animation-delay: -5s;
+    animation-duration: 20s;
+  }
+
+  @keyframes move-forever {
+    0% {
+      transform: translate3d(-90px, 0, 0);
+    }
+
+    100% {
+      transform: translate3d(85px, 0, 0);
+    }
+  }
+
+  /*Shrinking for mobile*/
+  @media (max-width: 768px) {
+    .waves {
+      height: 40px;
+      min-height: 40px;
+    }
+
+    .content {
+      height: 30vh;
+    }
+
+    h1 {
+      font-size: 24px;
+    }
+  }
+
+  .waybillquiry_home {
     display: flex;
-    flex-direction: column;
     justify-content: center;
+    flex-direction: column;
     align-items: center;
+    // height: 100%;
   }
 
   .card_waybillquiry {
-    margin: 15px;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 10px;
     display: flex;
     align-items: center;
   }
 
   .head_title {
-    font-size: 24px;
+    font-size: 20px;
     font-weight: bold;
     color: rgb(35, 49, 105);
     margin-left: 10px;
@@ -370,8 +536,8 @@
   .card_search {
     display: flex;
     flex-direction: column;
-    width: 95%;
-    margin-bottom: 30px;
+    width: 100%;
+    flex: 1;
   }
 
   .Waybill_inquiry {
@@ -399,7 +565,7 @@
 
   .track_waybill {
     width: 100%;
-    height: 80vh !important;
+    height: 100% !important;
     position: relative;
   }
 
@@ -422,6 +588,7 @@
 
   .card_certain {
     padding-bottom: 10px;
+    border-bottom: 5px solid #f2f6fc;
   }
 
   .card_humiture_quiry {
@@ -453,4 +620,33 @@
   .overturn {
     transform: rotate(180deg);
   }
+
+  .card_logistics_tab {
+    display: flex;
+    align-items: center;
+    background-color: #F5F7FA;
+    border-bottom: 1px solid #E4E7ED;
+  }
+
+  .title_logist {
+    cursor: pointer;
+    padding: 0 20px;
+    font-size: 14px;
+    height: 40px;
+    border-left: 1px solid transparent;
+    border-right: 1px solid transparent;
+    border-right-color: #F5F7FA;
+    border-left-color: #F5F7FA;
+  }
+
+  .title_logist:hover {
+    color: #409EFF;
+  }
+
+  .activate_card {
+    background-color: #fff;
+    color: #409EFF;
+    border-right-color: #DCDFE6;
+    border-left-color: #DCDFE6;
+  }
 </style>

+ 10 - 4
src/views/page/statisticalManagement.vue

@@ -6,7 +6,7 @@
     <div class="card_content_interior">
       <div class="left_interior">
         <div style="display: flex;margin-bottom: 10px;">
-          <el-checkbox v-model="checked" @change="checkAll">全选</el-checkbox>
+          <el-checkbox :indeterminate="isIndeterminate" v-model="checked" @change="checkAll">全选</el-checkbox>
           <div class="title_invert center_in" @click="Inverse">反选</div>
         </div>
         <el-checkbox-group v-model="checkedList" @change="checkboxChange">
@@ -101,6 +101,7 @@
           code: '3155'
         }],
         tableList: employee(),
+        isIndeterminate: true,
       }
     },
     methods: {
@@ -113,6 +114,7 @@
       openModel(type) {},
       buttonData(row, type) {},
       checkboxChange(value) {
+        let checkedCount = value.length;
         for (let i = 0; i < this.list.length; i++) {
           let flag = value.includes(this.list[i].code);
           if (flag) {
@@ -121,7 +123,8 @@
             this.list[i].checked = false
           }
         }
-        this.checkedList = this.checkedList.concat(value);
+        this.checkedList = value;
+        this.isIndeterminate = checkedCount > 0 && checkedCount < this.list.length;
       },
       // 全选
       checkAll() {
@@ -134,6 +137,7 @@
             this.checkedList.push(item.code)
           }
         })
+        this.isIndeterminate = false;
       },
       // 反选
       Inverse() {
@@ -189,6 +193,7 @@
   .card_checkbox_analyse {
     width: 100%;
     padding: 10px 0px;
+    margin-right: 0px !important;
   }
 
   .analyse_title {
@@ -197,16 +202,17 @@
     flex-direction: column;
 
     .item_title1 {
-      font-size: 20px;
+      font-size: 16px;
     }
 
     .item_title2 {
-      font-size: 16px;
+      font-size: 14px;
       margin-top: 5px;
     }
   }
 
   .title_invert {
+    font-size: 14px;
     cursor: pointer;
     color: red;
     margin-left: 10px;

+ 11 - 1
src/views/system/CompanyManagement.vue

@@ -76,7 +76,14 @@
         staffTitle: '添加',
         staffDialogVisible: false,
         formRuleList: [],
-        ruleForm: {},
+        ruleForm: {
+          name: '',
+          companyAddress: '',
+          coldKey: '',
+          isIceReleaseCold: true,
+          isCoolerReleaseCold: true,
+          remark: '',
+        },
         confirmLoading: false,
 
         treeData: employee(),
@@ -141,6 +148,9 @@
               name: this.ruleForm.name,
               remark: this.ruleForm.remark,
               coldKey: this.ruleForm.coldKey,
+              companyAddress: this.ruleForm.companyAddress,
+              isIceReleaseCold: this.ruleForm.isIceReleaseCold,
+              isCoolerReleaseCold: this.ruleForm.isCoolerReleaseCold,
             }
             putCompany(params).then(res => {
               if (res.code == 200) {

+ 84 - 3
src/views/system/IncubatorManagement.vue

@@ -47,7 +47,7 @@
         </span>
       </el-dialog>
     </div>
-    <el-dialog :visible.sync="dialogVisible" width="80%" @close="temperatureClose">
+    <el-dialog top="5vh" :visible.sync="dialogVisible" width="80%" @close="temperatureClose">
       <template slot="title">
         <div style="display: flex;align-items: center;">
           <span style="margin-right: 10px;font-size: 20px;">温湿度记录</span>
@@ -60,6 +60,31 @@
       <thermography ref="thermo" :waybillNo="waybillNo" :timeData="timeQuantum"></thermography>
     </el-dialog>
     <centerControl ref="control" :tableData="tableData"></centerControl>
+    <div class="card_iceTracing">
+      <el-dialog fullscreen title="冰排追溯" :visible.sync="iceTracingVisible">
+        <div>
+          <div class="space_between_in" style="margin-bottom: 10px;">
+            <div>
+              <el-date-picker v-model="value1" type="datetimerange" range-separator="至" start-placeholder="开始日期"
+                end-placeholder="结束日期">
+              </el-date-picker>
+            </div>
+            <div style="display: flex;align-items: center;">
+              <el-button type="primary">导出Excel</el-button>
+              <el-button type="success" @click="download">下载PDF</el-button>
+            </div>
+          </div>
+          <tables :historyFlag="true" :tableList="historyList" :tableData="historyData">
+          </tables>
+          <!-- 分页 -->
+          <div v-if="historyTotal">
+            <pagination :total="historyTotal" :currentPage="historyPagination.PageIndex" @changeSize="historySize"
+              @changeCurrent="historyCurrent">
+            </pagination>
+          </div>
+        </div>
+      </el-dialog>
+    </div>
   </div>
 </template>
 
@@ -76,6 +101,9 @@
     getDevice,
     addCoolerBoxImport
   } from '@/api/incubator'
+  import {
+    getTemperature
+  } from '@/api/waybill'
   import actionBar from '@/components/actionBar'
   import tables from '@/components/tables'
   import pagination from '@/components/pagination'
@@ -85,7 +113,8 @@
   import {
     formRules,
     employee,
-    incubator
+    incubator,
+    historyRecord,
   } from "./incubator.js";
   import {
     startStatus,
@@ -217,6 +246,16 @@
         timer: null, //定时器名称
         dialogVisible: false,
         waybillNo: '',
+        iceTracingVisible: false,
+        value1: '',
+        // 历史记录
+        historyList: historyRecord(),
+        historyData: [],
+        historyTotal: 0,
+        historyPagination: {
+          PageIndex: 1,
+          PageSize: 10,
+        },
       }
     },
     beforeDestroy() {
@@ -229,6 +268,28 @@
       this.getList()
     },
     methods: {
+      download() {
+        getTemperature().then(response => {
+          if (response.fileName) {
+            this.pdfDialogVisible = false
+            //fileName = decodeURIComponent(filename);//对filename进行转码
+            let fileName = decodeURI(response.fileName);
+            if (window.navigator.msSaveOrOpenBlob) {
+              navigator.msSaveBlob(new Blob([response.data]), fileName);
+            } else {
+              let url = window.URL.createObjectURL(new Blob([response.data]));
+              let link = document.createElement('a');
+              link.style.display = 'none';
+              link.href = url;
+              link.setAttribute('download', fileName);
+              document.body.appendChild(link);
+              link.click();
+            }
+          } else {
+            this.$message.error('未获取到文件名');
+          }
+        })
+      },
       getTime(time) {
         var date = new Date(time)
         var y = date.getFullYear()
@@ -263,6 +324,8 @@
             this.Total = res.data.count
             this.timer = setTimeout(() => {
               this.getList();
+              clearInterval(this.timer); // 清除定时器
+              this.timer = null;
             }, 60000)
           }
         })
@@ -349,6 +412,9 @@
           this.$nextTick(() => {
             this.$refs.thermo.getProbe()
           })
+        } else if (type == 'ascend') {
+          console.log(23)
+          this.iceTracingVisible = true
         }
       },
       // 选择时间
@@ -365,7 +431,7 @@
         } else if (type == 'import') {
           this.importDialogVisible = true
           this.getDeviceList()
-        }else if(type == 'screen'){
+        } else if (type == 'screen') {
           this.$refs.control.controlVisible = true
           this.$nextTick(() => {
             setTimeout(() => {
@@ -472,6 +538,13 @@
         this.Paginationil.PageIndex = val
         this.getDeviceList()
       },
+      // 历史记录分页
+      historySize(val) {
+        this.historyPagination.PageSize = val
+      },
+      historyCurrent(val) {
+        this.historyPagination.PageIndex = val
+      },
       // 清空表单
       closeDialog() {
         this.formRuleList.forEach((item, index) => {
@@ -514,6 +587,14 @@
     padding: 0px 20px !important;
   }
 
+  .card_iceTracing ::v-deep .el-dialog__body {
+    padding: 10px 20px !important;
+  }
+
+  .card_iceTracing ::v-deep .el-dialog__headerbtn {
+    font-size: 25px !important;
+  }
+
   .card_incubat {
     padding-left: 15px;
     border-bottom: 1px solid #EBEEF5;

+ 63 - 0
src/views/system/company.js

@@ -7,6 +7,36 @@ export const employee = () => {
     label: '名称',
     align: 'left',
   }, {
+    field: 'companyAddress',
+    label: '地址',
+    align: 'center',
+  }, {
+    field: 'isIceReleaseCold',
+    label: '冰排释冷',
+    align: 'center',
+    options: [{
+      label: '已开启',
+      value: 1,
+      bgcolor: '#67C23A',
+    }, {
+      label: '已关闭',
+      value: 2,
+      bgcolor: '#F56C6C',
+    }]
+  }, {
+    field: 'isCoolerReleaseCold',
+    label: '保温箱预冷',
+    align: 'center',
+    options: [{
+      label: '已开启',
+      value: 1,
+      bgcolor: '#67C23A',
+    }, {
+      label: '已关闭',
+      value: 2,
+      bgcolor: '#F56C6C',
+    }]
+  }, {
     field: 'remark',
     label: '备注',
     align: 'center',
@@ -47,6 +77,17 @@ export const formRules = () => {
       trigger: 'blur'
     }]
   }, {
+    field: 'address',
+    label: '地址',
+    placeholder: '请输入地址',
+    type: 'input',
+    colWidth: 24,
+    rules: [{
+      required: true,
+      message: '请输入地址',
+      trigger: 'blur'
+    }]
+  }, {
     field: 'coldKey',
     label: '冷链3.0公司秘钥',
     placeholder: '请输入冷链3.0公司秘钥',
@@ -58,6 +99,28 @@ export const formRules = () => {
       trigger: 'blur'
     }]
   }, {
+    field: 'isIceReleaseCold',
+    label: '冰排释冷',
+    placeholder: '请选择冰排释冷',
+    type: 'switch',
+    colWidth: 8,
+    rules: [{
+      required: true,
+      message: '请选择冰排释冷',
+      trigger: 'blur'
+    }]
+  }, {
+    field: 'isCoolerReleaseCold',
+    label: '保温箱预冷',
+    placeholder: '请选择保温箱预冷',
+    type: 'switch',
+    colWidth: 12,
+    rules: [{
+      required: true,
+      message: '请选择保温箱预冷',
+      trigger: 'blur'
+    }]
+  }, {
     field: 'remark',
     label: '备注',
     placeholder: '请输入备注',

+ 95 - 22
src/views/system/incubator.js

@@ -1,5 +1,6 @@
 import {
-  startStatus
+  startStatus,
+  frozenState
 } from '@/assets/js/blockSort'
 
 export const incubator = () => {
@@ -43,29 +44,36 @@ export const employee = () => {
   }, {
     field: 'action',
     label: '操作',
-    colWidth: '270px',
+    colWidth: '360px',
     align: 'center',
     labelButton: [{
-      type: 'record',
-      label: '记录',
-      icon: 'el-icon-s-order',
-      style: 'primary',
-    },{
-      type: 'logs',
-      label: '详情',
-      icon: 'el-icon-tickets',
-      style: 'success',
-    }, {
-      type: 'edit',
-      label: '编辑',
-      icon: 'el-icon-edit',
-      style: 'primary',
-    }, {
-      type: 'del',
-      label: '删除',
-      icon: 'el-icon-delete',
-      style: 'danger',
-    }]
+        type: 'ascend',
+        label: '冰排追溯',
+        icon: 'el-icon-tickets',
+        style: 'success',
+      },
+      {
+        type: 'record',
+        label: '记录',
+        icon: 'el-icon-s-order',
+        style: 'primary',
+      }, {
+        type: 'logs',
+        label: '详情',
+        icon: 'el-icon-tickets',
+        style: 'success',
+      }, {
+        type: 'edit',
+        label: '编辑',
+        icon: 'el-icon-edit',
+        style: 'primary',
+      }, {
+        type: 'del',
+        label: '删除',
+        icon: 'el-icon-delete',
+        style: 'danger',
+      }
+    ]
   }]
 }
 
@@ -106,3 +114,68 @@ export const formRules = () => {
     options: startStatus()
   }]
 }
+
+export const historyRecord = () => {
+  return [{
+    field: 'selection',
+    label: '多选',
+    align: 'center',
+  }, {
+    field: 'code',
+    label: '编号',
+    align: 'center',
+  }, {
+    field: 'status',
+    label: '状态',
+    align: 'center',
+    options: frozenState()
+  }, {
+    field: 'inStorageTime',
+    label: '入库时间',
+    align: 'center',
+  }, {
+    field: 'outStorageTime',
+    label: '出库时间',
+    align: 'center',
+  }, {
+    field: 'multistage',
+    label: '保温箱温湿度记录',
+    children: [{
+      field: 'reCheck.nickName',
+      label: '开始时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '结束时间',
+      align: 'center',
+    }, ]
+  }, {
+    field: 'multistage',
+    label: '冰排释冷',
+    children: [{
+      field: 'reCheck.nickName',
+      label: '开始时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '结束时间',
+      align: 'center',
+    }, {
+      field: 'reCheck.phone',
+      label: '释冷时间',
+      align: 'center',
+    }, ]
+  }, {
+    field: 'location',
+    label: '所在位置',
+    align: 'center',
+  }, {
+    field: 'freezeClaim',
+    label: '冷冻要求',
+    align: 'center',
+  }, {
+    field: 'freezeDuration',
+    label: '冷冻时间',
+    align: 'center',
+  }]
+}

+ 3 - 2
vue.config.js

@@ -16,8 +16,9 @@ module.exports = defineConfig({
   devServer: {
     proxy: {
       '/api': {
-        target: 'https://colddelivery.coldbaozhida.com/cold_delivery',
-        // target: 'http://192.168.11.77:6280', //测试
+        // target: 'https://colddelivery.coldbaozhida.com/cold_delivery',
+        target: 'http://182.43.247.65:6280', //测试
+        // target: 'http://192.168.11.15:6280', //本地
         ws: false,
         changeOrigin: true,
         pathRewrite: {

+ 5 - 12
yarn.lock

@@ -16,6 +16,11 @@
     event-pubsub "4.3.0"
     js-message "1.0.7"
 
+"@amap/amap-jsapi-loader@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz"
+  integrity sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==
+
 "@ampproject/remapping@^2.2.0":
   version "2.3.0"
   resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz"
@@ -2621,11 +2626,6 @@ compression@^1.7.4:
     safe-buffer "5.1.2"
     vary "~1.1.2"
 
-comutils@^1.1.9:
-  version "1.1.19"
-  resolved "https://registry.npmmirror.com/comutils/-/comutils-1.1.19.tgz"
-  integrity sha512-JxXB67juILiwhdLwOsYyjUqwWEhHdObI0EClOPk+JDtEuTbac59s0pxGpfCBnNNQ5JommifmcMGneW/4Cg7YWw==
-
 concat-map@0.0.1:
   version "0.0.1"
   resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
@@ -6917,13 +6917,6 @@ vue-router@^3.5.1:
   resolved "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz"
   integrity sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==
 
-vue-seamless-scroll@^1.1.23:
-  version "1.1.23"
-  resolved "https://registry.npmmirror.com/vue-seamless-scroll/-/vue-seamless-scroll-1.1.23.tgz"
-  integrity sha512-HBjUub8WwsKJzbFCrwKPDrZn4e+SSbkKgwWtjKtfLwesiFGwSsVxP44/Z6d3kpXy94qIFOiflJH6l0/9pj7SGA==
-  dependencies:
-    comutils "^1.1.9"
-
 vue-style-loader@^4.1.0, vue-style-loader@^4.1.3:
   version "4.1.3"
   resolved "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz"

Неке датотеке нису приказане због велике количине промена