Explorar o código

Merge branch 'master' into feature_20240911_pc端无定位依然支持访问

zhujindu hai 1 ano
pai
achega
d427cdcdea
Modificáronse 37 ficheiros con 21631 adicións e 9031 borrados
  1. 2 1
      package.json
  2. 523 514
      src/api/index.js
  3. BIN=BIN
      src/assets/bfindex.png
  4. BIN=BIN
      src/assets/oderindex.png
  5. BIN=BIN
      src/assets/storeindex.png
  6. 48 24
      src/components/storeCode.vue
  7. 156 126
      src/components/uploadVNormal.vue
  8. 21 17
      src/components/zRadio.vue
  9. 32 23
      src/components/zRadiokz.vue
  10. 28 26
      src/main.js
  11. 166 0
      src/utils/TXApiFun.js
  12. 2 1
      src/utils/commonVant.js
  13. 832 465
      src/views/clew/clewent.vue
  14. 577 542
      src/views/deviceOutside/index.vue
  15. 606 466
      src/views/deviceOutside/suishenbangOutstoreVisit.vue
  16. 511 456
      src/views/deviceOutside/topStore.vue
  17. 3104 0
      src/views/deviceWithin/addStoreVisit copy.vue
  18. 2391 594
      src/views/deviceWithin/addStoreVisit.vue
  19. 334 312
      src/views/deviceWithin/index.vue
  20. 65 0
      src/views/deviceWithin/taskTips.vue
  21. 1272 389
      src/views/home/index.vue
  22. 249 0
      src/views/storeManagement/newTMap.vue
  23. 516 445
      src/views/storeManagement/storeDetail.vue
  24. 313 309
      src/views/storeManagement/storeEdit.vue
  25. 992 412
      src/views/week/daily.vue
  26. 939 361
      src/views/week/dailyApproval.vue
  27. 860 313
      src/views/week/dailyDetails.vue
  28. 993 429
      src/views/week/dailyHistoricalDetails.vue
  29. 729 372
      src/views/week/doubleHistoricalWeeklyDetils.vue
  30. 739 367
      src/views/week/doubleWeekly.vue
  31. 638 276
      src/views/week/doubleWeeklyApproval.vue
  32. 696 288
      src/views/week/doubleWeeklyDetils.vue
  33. 922 513
      src/views/week/weekly.vue
  34. 797 332
      src/views/week/weeklyApproval.vue
  35. 759 289
      src/views/week/weeklyApprovalDetils.vue
  36. 796 344
      src/views/week/weeklyHistoricalDetils.vue
  37. 23 25
      vue.config.js

+ 2 - 1
package.json

@@ -24,7 +24,8 @@
     "vue-baidu-map": "^0.21.22",
     "vue-jsonp": "^2.0.0",
     "vue-router": "^3.5.3",
-    "watermark-dom": "^2.3.0"
+    "watermark-dom": "^2.3.0",
+    "weixin-js-sdk": "^1.6.5"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.5.0",

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 523 - 514
src/api/index.js


BIN=BIN
src/assets/bfindex.png


BIN=BIN
src/assets/oderindex.png


BIN=BIN
src/assets/storeindex.png


+ 48 - 24
src/components/storeCode.vue

@@ -9,11 +9,11 @@
 </template>
 
 <script>
-import axios from "axios";
-import { getOptionByResult } from "@/api/index";
+import axios from 'axios';
+import { getOptionByResult } from '@/api/index';
 
 export default {
-  name: "uploadImg",
+  name: 'storeCode',
   props: {
     index: {
       type: Number,
@@ -21,7 +21,7 @@ export default {
     },
     tid: {
       type: String,
-      default: "",
+      default: '',
     },
     cid: {
       type: Number,
@@ -29,35 +29,51 @@ export default {
     },
     code: {
       type: String,
-      default: "",
+      default: '',
     },
     index1: {
       type: [String, Number],
-      default: "",
+      default: '',
     },
     index2: {
       type: [String, Number],
-      default: "",
+      default: '',
     },
     index3: {
       type: [String, Number],
-      default: "",
+      default: '',
     },
     index4: {
       type: [String, Number],
-      default: "",
+      default: '',
+    },
+    index5: {
+      type: [String, Number],
+      default: '',
+    },
+    index6: {
+      type: [String, Number],
+      default: '',
+    },
+    index7: {
+      type: [String, Number],
+      default: '',
+    },
+    index8: {
+      type: [String, Number],
+      default: '',
     },
     taskId: {
       type: String,
-      default: "",
+      default: '',
     },
     collectionId: {
       type: String,
-      default: "",
+      default: '',
     },
     type: {
       type: String,
-      default: "",
+      default: '',
     },
     insert: {
       type: Boolean,
@@ -67,7 +83,7 @@ export default {
   data() {
     return {
       shows: false,
-      url: "",
+      url: '',
     };
   },
   methods: {
@@ -76,11 +92,13 @@ export default {
       let that = this;
       let wx = this.wx;
       let qiyeData;
+      console.log(that.code);
+      debugger;
 
       const instance = axios.create();
-      instance.defaults.headers.common["userId"] = localStorage.getItem("loginName");
+      instance.defaults.headers.common['userId'] = localStorage.getItem('loginName');
       instance
-        .get(process.env.VUE_APP_BASE_API + "mobile/wx/ticket", {
+        .get(process.env.VUE_APP_BASE_API + 'mobile/wx/ticket', {
           params: {
             url: url,
           },
@@ -95,22 +113,24 @@ export default {
               timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
               nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
               signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
-              jsApiList: ["ready", "scanQRCode"],
+              jsApiList: ['ready', 'scanQRCode'],
             });
             wx.ready(function () {
               wx.scanQRCode({
-                desc: "scanQRCode desc",
+                desc: 'scanQRCode desc',
                 needResult: 1,
-                scanType: ["barCode"],
+                scanType: ['barCode'],
                 success: function (res) {
+                  console.log(res);
                   var result = res.resultStr;
+                  console.log(result);
                   var success = false;
-                  if (that.code == result && that.code != "" && that.code != null) {
+                  if (that.code == result && that.code != '' && that.code != null) {
                     success = true;
                   }
                   let loading1 = that.$toast.loading({
                     duration: 0,
-                    message: "数据加载中...",
+                    message: '数据加载中...',
                     forbidClick: true,
                   });
                   getOptionByResult({
@@ -120,25 +140,29 @@ export default {
                   }).then((response) => {
                     loading1.clear();
                     if (response.code == 200) {
-                      that.$emit("newcode", {
+                      that.$emit('newcode', {
                         cid: response.data.collectionId,
                         cpid: response.data.collectionOptionId,
                         nocpid: response.data.diffCollectionOptionId,
                         type: that.type,
                         index: that.index,
-                        code: that.code + "," + result,
+                        code: that.code + ',' + result,
                         success: success,
                         index1: that.index1,
                         index2: that.index2,
                         index3: that.index3,
                         index4: that.index4,
+                        index5: that.index5,
+                        index6: that.index6,
+                        index7: that.index7,
+                        index8: that.index8,
                       });
                     }
                   });
                 },
                 error: function (res) {
-                  if (res.errMsg.indexOf("function_not_exist") > 0) {
-                    alert("版本过低请升级");
+                  if (res.errMsg.indexOf('function_not_exist') > 0) {
+                    alert('版本过低请升级');
                   }
                 },
               });

+ 156 - 126
src/components/uploadVNormal.vue

@@ -1,77 +1,94 @@
 <template>
   <div class="questionNamep">
     <div class="cameraDiv" @click="uploadImg">
-      <van-icon class="photo photos" name="photograph" size="22px" color="#969696"/>
+      <van-icon class="photo photos" name="photograph" size="22px" color="#969696" />
     </div>
     <div id="allmap"></div>
   </div>
 </template>
 
 <script>
-import {addstorePhoto, addVisitsPosition} from "@/api/index";
-import axios from "axios";
+import { addstorePhoto, addVisitsPosition } from '@/api/index';
+import axios from 'axios';
 
 export default {
   name: 'uploadImg',
   props: {
     uploadid: {
       type: String,
-      default: ''
+      default: '',
     },
     storeGroupId: {
       type: String,
-      default: ''
+      default: '',
     },
     parentCollectionId: {
       type: String,
-      default: ''
+      default: '',
     },
     secondCollectionId: {
       type: String,
-      default: ''
-    }, firstCollectionId: {
+      default: '',
+    },
+    firstCollectionId: {
+      type: String,
+      default: '',
+    },
+    fourthCollectionId: {
       type: String,
-      default: ''
+      default: '',
+    },
+    thirdCollectionId: {
+      type: String,
+      default: '',
     },
     visitsId: {
       type: String,
-      default: ''
+      default: '',
     },
     taskId: {
       type: String,
-      default: ''
+      default: '',
     },
     collectionId: {
       type: String,
-      default: ''
+      default: '',
     },
     objectType: {
       type: String,
-      default: ''
+      default: '',
     },
     type: {
       type: Number,
-      default: 1
+      default: 1,
     },
     imgArr: {
       type: Array,
       default() {
-        return []
-      }
+        return [];
+      },
     },
     visitModel: {
       type: String,
-      default: '1'
+      default: '1',
+    },
+    deviceCode: {
+      type: String,
+      default: '',
+    },
+    putInCode: {
+      type: String,
+      default: '',
     },
   },
   data() {
     return {
       shows: false,
-      url: ""
-    }
+      url: '',
+    };
   },
   methods: {
-    uploadImg(){
+    uploadImg() {
       var map = new TMap.Map('allmap', {
         zoom: 14,
         center: new TMap.LatLng(39.986785, 116.301012),
@@ -84,132 +101,146 @@ export default {
       });
       markers.setGeometries([]);
 
-      if (this.objectType == "" || this.objectType == null) {
-        this.$toast("请选择类型!")
-        return
+      if (this.objectType == '' || this.objectType == null) {
+        this.$toast('请选择类型!');
+        return;
       }
       let url = window.location.href;
       let that = this;
-      let wx = this.wx
-      let qiyeData
-      let addressesRemark=""
+      let wx = this.wx;
+      let qiyeData;
+      let addressesRemark = '';
       const instance = axios.create();
-      instance.defaults.headers.common['userId'] = localStorage.getItem("loginName");
-      instance.get(process.env.VUE_APP_BASE_API + 'mobile/wx/ticket',
-          {
-            params: {
-              url: url
-            }
-          }).then(response => {
-        if (response.status == 200) {
-          qiyeData = response.data.data;
-          wx.config({
-            beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
-            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
-            appId: qiyeData.appId, // 必填,企业微信的corpID
-            timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
-            nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
-            signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
-            jsApiList: ["ready", "chooseImage","uploadImage","getLocation"] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
-          });
-          wx.ready(function () {
-            wx.getLocation({
-              type: 'gcj02',
-              success: function (res) {
-                var location = new TMap.LatLng(res.latitude, res.longitude);
-                map.setCenter(location);
-                markers.updateGeometries([
-                  {
-                    id: 'main', // 点标注数据数组
-                    position: location,
-                  },
-                ]);
-                geocoder
-                    .getAddress({ location: location })
-                    .then(function(result){
-                      var addresses=result.result.formatted_addresses
-                      addressesRemark=addresses.recommend
-                    },function(err){
-                      addressesRemark=""
-                    })
-              },
-              fail: function () {
-                that.$dialog.alert({
-                  message: 'GPS未开启',
-                })
-              }
+      instance.defaults.headers.common['userId'] = localStorage.getItem('loginName');
+      instance
+        .get(process.env.VUE_APP_BASE_API + 'mobile/wx/ticket', {
+          params: {
+            url: url,
+          },
+        })
+        .then((response) => {
+          if (response.status == 200) {
+            qiyeData = response.data.data;
+            wx.config({
+              beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
+              debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
+              appId: qiyeData.appId, // 必填,企业微信的corpID
+              timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
+              nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
+              signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
+              jsApiList: ['ready', 'chooseImage', 'uploadImage', 'getLocation'], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
+            });
+            wx.ready(function () {
+              wx.getLocation({
+                type: 'gcj02',
+                success: function (res) {
+                  var location = new TMap.LatLng(res.latitude, res.longitude);
+                  map.setCenter(location);
+                  markers.updateGeometries([
+                    {
+                      id: 'main', // 点标注数据数组
+                      position: location,
+                    },
+                  ]);
+                  geocoder.getAddress({ location: location }).then(
+                    function (result) {
+                      var addresses = result.result.formatted_addresses;
+                      addressesRemark = addresses.recommend;
+                    },
+                    function (err) {
+                      addressesRemark = '';
+                    }
+                  );
+                },
+                fail: function () {
+                  that.$dialog.alert({
+                    message: 'GPS未开启',
+                  });
+                },
               });
-            wx.chooseImage({
-              count: 1,
-              sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
-              sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有
-              defaultCameraMode: "normal", //表示进入拍照界面的默认模式,目前有normal与batch两种选择,normal表示普通单拍模式,batch表示连拍模式,不传该参数则为normal模式。从3.0.26版本开始支持front和batch_front两种值,其中front表示默认为前置摄像头单拍模式,batch_front表示默认为前置摄像头连拍模式。(注:用户进入拍照界面仍然可自由切换两种模式)
-              isSaveToAlbum:0,
-              success: function (res) {
-                var localIds=""
-                if(res.localIds!=undefined){
-                  localIds= res.localIds[0]
-                }else{
-                  localIds=res.localId
-                }
-                wx.uploadImage({
-                  localId: localIds, // 需要上传的图片的本地ID,由chooseImage接口获得
-                  isShowProgressTips: 1, // 默认为1,显示进度提示
-                  success: function (res) {
-                    that.uploadImagev(res.serverId,addressesRemark)
+              wx.chooseImage({
+                count: 1,
+                sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
+                sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有
+                defaultCameraMode: 'normal', //表示进入拍照界面的默认模式,目前有normal与batch两种选择,normal表示普通单拍模式,batch表示连拍模式,不传该参数则为normal模式。从3.0.26版本开始支持front和batch_front两种值,其中front表示默认为前置摄像头单拍模式,batch_front表示默认为前置摄像头连拍模式。(注:用户进入拍照界面仍然可自由切换两种模式)
+                isSaveToAlbum: 0,
+                success: function (res) {
+                  var localIds = '';
+                  if (res.localIds != undefined) {
+                    localIds = res.localIds[0];
+                  } else {
+                    localIds = res.localId;
                   }
-                });
-              }
+                  wx.uploadImage({
+                    localId: localIds, // 需要上传的图片的本地ID,由chooseImage接口获得
+                    isShowProgressTips: 1, // 默认为1,显示进度提示
+                    success: function (res) {
+                      that.uploadImagev(res.serverId, addressesRemark);
+                    },
+                  });
+                },
+              });
             });
-          })
-        }
-      });
+          }
+        });
     },
-    uploadImagev(meidaId,addressesRemark){
+    uploadImagev(meidaId, addressesRemark) {
       var that = this;
-      var parentCollectionId=null
-      if(that.parentCollectionId!=null&&that.parentCollectionId!="null"){
-        parentCollectionId=that.parentCollectionId
+      var parentCollectionId = null;
+      if (that.parentCollectionId != null && that.parentCollectionId != 'null') {
+        parentCollectionId = that.parentCollectionId;
+      }
+      var secondCollectionId = null;
+      if (that.secondCollectionId != null && that.secondCollectionId != 'null') {
+        secondCollectionId = that.secondCollectionId;
       }
-      var secondCollectionId=null
-      if(that.secondCollectionId!=null&&that.secondCollectionId!="null"){
-        secondCollectionId=that.secondCollectionId
+      var firstCollectionId = null;
+      if (that.firstCollectionId != null && that.firstCollectionId != 'null') {
+        firstCollectionId = that.firstCollectionId;
       }
-      var firstCollectionId=null
-      if(that.firstCollectionId!=null&&that.firstCollectionId!="null"){
-        firstCollectionId=that.firstCollectionId
+      var fourthCollectionId = null;
+      if (that.fourthCollectionId != null && that.fourthCollectionId != 'null') {
+        fourthCollectionId = that.fourthCollectionId;
       }
-      var form={
-        mediaId:meidaId,
-        collectionItemId:that.collectionId,
-        objectType:that.objectType,
-        storeGroupId:that.storeGroupId,
-        taskId:that.taskId,
-        visitsId:localStorage.getItem('visitId'),
-        visitModel:that.visitModel,
-        visitSource:"1",
-        locationRemark:addressesRemark,
-        parentCollectionId:parentCollectionId,
-        secondCollectionId:secondCollectionId,
-        firstCollectionId:firstCollectionId,
+      var thirdCollectionId = null;
+      if (that.thirdCollectionId != null && that.thirdCollectionId != 'null') {
+        thirdCollectionId = that.thirdCollectionId;
       }
+      var form = {
+        mediaId: meidaId,
+        collectionItemId: that.collectionId,
+        objectType: that.objectType,
+        storeGroupId: that.storeGroupId,
+        taskId: that.taskId,
+        visitsId: localStorage.getItem('visitId'),
+        visitModel: that.visitModel,
+        visitSource: '1',
+        locationRemark: addressesRemark,
+        parentCollectionId: parentCollectionId,
+        secondCollectionId: secondCollectionId,
+        firstCollectionId: firstCollectionId,
+        fourthCollectionId: fourthCollectionId,
+        thirdCollectionId: thirdCollectionId,
+        deviceCode: that.deviceCode, //设备编号
+        putInCode: that.putInCode, //投放编号
+      };
       var loind1 = that.$toast.loading({
         duration: 0,
         message: '上传中...',
         forbidClick: true,
       });
-      addstorePhoto(form).then(res=>{
+      addstorePhoto(form).then((res) => {
         if (res.code == 200) {
           loind1.clear();
-          that.$toast("上传成功!")
-          that.$emit('newimgarr', {fileUrl: res.data.url, id: res.data.fileId, type: 2});
+          that.$toast('上传成功!');
+          that.$emit('newimgarr', { fileUrl: res.data.url, id: res.data.fileId, type: 2 });
         } else {
-          that.$toast("上传失败!")
+          that.$toast('上传失败!');
         }
-      })
-    }
+      });
+    },
   },
-}
+};
 </script>
 <style lang="scss" scoped>
 .questionNamep {
@@ -239,12 +270,11 @@ export default {
       z-index: 89;
     }
   }
-
 }
-#allmap{
+#allmap {
   width: 10px;
   height: 10px;
   left: -1000px;
   position: relative;
 }
-</style>
+</style>

+ 21 - 17
src/components/zRadio.vue

@@ -17,26 +17,28 @@
 
 <script>
 export default {
-  name: "zSelect",
+  name: 'zSelect',
   props: {
-    radio: "",
-    textc: "",
+    radio: '',
+    textc: '',
     zRadiocolumns: [],
-    answerType: "",
-    collectionType: "",
-    childindex: "",
-    childindex1: "",
-    childindex2: "",
-    childIndex4: "",
-    childindex3: "",
-    childindex5: "",
-    childindex6: "",
-    childindex7: "",
+    answerType: '',
+    collectionType: '',
+    childindex: '',
+    childindex1: '',
+    childindex2: '',
+    childIndex4: '',
+    childindex3: '',
+    childindex5: '',
+    childindex6: '',
+    childindex7: '',
+    childindex8: '',
+    childindex9: '',
   },
   data() {
     return {
       radioChange: false,
-      zradioc: "",
+      zradioc: '',
     };
   },
   created() {
@@ -67,14 +69,16 @@ export default {
         childindex5: this.childindex5,
         childindex6: this.childindex6,
         childindex7: this.childindex7,
+        childindex8: this.childindex8,
+        childindex9: this.childindex9,
       };
-      this.$emit("input", value);
-      this.$emit("zSelectVal", datalist);
+      this.$emit('input', value);
+      this.$emit('zSelectVal', datalist);
     },
     radioclick(val) {
       if (!val) {
         if (!this.radioChange) {
-          this.zradioc = "";
+          this.zradioc = '';
         }
         this.radioChange = false;
       }

+ 32 - 23
src/components/zRadiokz.vue

@@ -3,7 +3,13 @@
     <div class="checkbox">
       <van-radio-group v-model="zradioc" @change="radiofn">
         <div>
-        <van-radio :name="item.customerClueOptionId+''" @click="radioclick" v-for="(item,index) in zRadiocolumns" :key="index">{{item.customerClueOption}}</van-radio>
+          <van-radio
+            :name="item.customerClueOptionId + ''"
+            @click="radioclick"
+            v-for="(item, index) in zRadiocolumns"
+            :key="index"
+            >{{ item.customerClueOption }}</van-radio
+          >
         </div>
       </van-radio-group>
     </div>
@@ -12,53 +18,56 @@
 
 <script>
 export default {
-  name: "zSelect",
+  name: 'zSelect',
   props: {
-    radio: "",
-    textc: "",
+    radio: '',
+    textc: '',
     zRadiocolumns: [],
-    answerType: "",
-    collectionType: "",
-    Tindex:0
+    answerType: '',
+    collectionType: '',
+    Tindex: 0,
   },
   data() {
     return {
       radioChange: false,
-      zradioc: this.radio
-    }
+      zradioc: this.radio,
+    };
   },
   methods: {
     radiofn(value) {
       this.radioChange = true;
-      var typeval =[...this.zRadiocolumns]
+      let customerClueOption = '';
+      var typeval = [...this.zRadiocolumns];
       for (var k = 0; k < this.zRadiocolumns.length; k++) {
-        typeval[k].value="N"
+        typeval[k].value = 'N';
         if (this.zRadiocolumns[k].customerClueOptionId == value) {
-          typeval[k].value="Y"
+          typeval[k].value = 'Y';
+          customerClueOption = this.zRadiocolumns[k].customerClueOption;
         }
       }
       let datalist = {
         id: this.textc,
-        Tindex:this.Tindex,
-        value: typeval
-      }
+        Tindex: this.Tindex,
+        value: typeval,
+        customerClueOption,
+      };
       this.$emit('zSelectVal', datalist);
     },
     radioclick() {
       if (!this.radioChange) {
-        this.zradioc = ""
+        this.zradioc = '';
       }
-      this.radioChange = false
+      this.radioChange = false;
     },
-  }
-}
+  },
+};
 </script>
 
 <style scoped>
 .van-f-red {
   color: red;
   width: 4px;
-  display: inline-block
+  display: inline-block;
 }
 
 .zSelect .z-cell {
@@ -67,14 +76,14 @@ export default {
 }
 
 .checkbox .van-radio {
-  padding-bottom: 10px
+  padding-bottom: 10px;
 }
 </style>
 <style>
 .checkbox .van-radio__icon {
   border: 1px solid #333;
   border-radius: 80px;
-  width: 1em
+  width: 1em;
 }
 
 .checkbox .van-radio__icon .van-icon {
@@ -97,4 +106,4 @@ export default {
 .checkbox .van-radio__icon--checked {
   border: 1px solid #1989fa;
 }
-</style>
+</style>

+ 28 - 26
src/main.js

@@ -1,7 +1,7 @@
-import Vue from "vue";
-import App from "./App.vue";
-import router from "./router";
-import "@/assets/styles/index.css";
+import Vue from 'vue';
+import App from './App.vue';
+import router from './router';
+import '@/assets/styles/index.css';
 import {
   parseTime,
   selectDictLabelu,
@@ -13,23 +13,25 @@ import {
   Micrometer,
   weeklyTimeDivision,
   gcj02BD,
-} from "@/utils/index";
-import { toastLoading } from "@/utils/commonVant";
-import "@vant/touch-emulator";
+} from '@/utils/index';
+import { toastLoading } from '@/utils/commonVant';
+import '@vant/touch-emulator';
 Vue.config.productionTip = false;
-import Vant from "vant";
-import { Toast } from "vant";
-import "vant/lib/index.css";
-import ClipboardJS from "clipboard";
+import Vant from 'vant';
+import { Toast } from 'vant';
+import 'vant/lib/index.css';
+import ClipboardJS from 'clipboard';
 Vue.use(Vant);
-import ElTable from "element-ui/lib/table";
-import "element-ui/lib/theme-chalk/table.css";
-import "element-ui/lib/theme-chalk/icon.css";
-import ElTableColumn from "element-ui/lib/table-column";
-import ElPopover from "element-ui/lib/popover";
-import "element-ui/lib/theme-chalk/table-column.css";
-import "element-ui/lib/theme-chalk/popover.css";
-import Vconsole from "vconsole";
+import ElTable from 'element-ui/lib/table';
+import 'element-ui/lib/theme-chalk/table.css';
+import 'element-ui/lib/theme-chalk/icon.css';
+import ElTableColumn from 'element-ui/lib/table-column';
+import ElPopover from 'element-ui/lib/popover';
+import 'element-ui/lib/theme-chalk/table-column.css';
+import 'element-ui/lib/theme-chalk/popover.css';
+import Vconsole from 'vconsole';
+// import wx from 'weixin-js-sdk';
+
 Vue.use(ElTable);
 Vue.use(ElTableColumn);
 Vue.use(ElPopover);
@@ -47,16 +49,16 @@ Vue.prototype.wx = wx;
 Vue.prototype.parseTimeParagraph = parseTimeParagraph;
 Vue.prototype.Micrometer = Micrometer;
 Vue.prototype.Toast = Toast;
-var clipboard = new ClipboardJS(".btn");
-clipboard.on("success", function (e) {
-  Toast("编码复制成功!");
+var clipboard = new ClipboardJS('.btn');
+clipboard.on('success', function (e) {
+  Toast('编码复制成功!');
 });
 
-clipboard.on("error", function (e) {
-  Toast("编码复制失败!");
+clipboard.on('error', function (e) {
+  Toast('编码复制失败!');
 });
 
-const isProd = process.env.NODE_ENV !== "production";
+const isProd = process.env.NODE_ENV !== 'production';
 if (isProd) {
   const vConsole = new Vconsole();
   Vue.use(vConsole);
@@ -65,4 +67,4 @@ if (isProd) {
 new Vue({
   router,
   render: (h) => h(App),
-}).$mount("#app");
+}).$mount('#app');

+ 166 - 0
src/utils/TXApiFun.js

@@ -0,0 +1,166 @@
+import Vue from 'vue'
+import { getTicket } from '@/api/index'
+import { toastLoading } from '@/utils/commonVant'
+import { CJ02BD, gcj02BD } from '@/utils/index'
+import { jsonp } from 'vue-jsonp'
+// 微信JSSDK实例
+const wx = Vue.prototype.wx
+// 腾讯位置服务 key
+const TxMapKey = 'WLCBZ-HRM6L-YOMPV-ME62B-AQOG6-JUBW6'
+
+/**
+ * 获取当前定位 调用之前确保当前页面已经授权(getTicketFun)
+ * */
+export function getPosition() {
+  return new Promise((resolve, reject) => {
+    toastLoading(0, '定位中...', true)
+    // 本地开发 test 环境时跳过获取定位功能 模拟定位
+    if (process.env.NODE_ENV === 'test') {
+      let resData = {
+        latitude: 34.615684509277344,
+        longitude: 112.4474105834961,
+      }
+      // 定位坐标转换 腾讯转百度
+      let TXisBD = CJ02BD(resData.latitude, resData.longitude)
+      localStorage.setItem('lat', TXisBD.lat)
+      localStorage.setItem('lon', TXisBD.lon)
+      toastLoading().clear()
+      resolve({ TXisBD, resData })
+    } else {
+      // let url = window.location.href;
+      // //  获取签名
+      // getTicket({ url: url }).then((response) => {
+      //   console.log(response);
+      //   toastLoading().clear();
+      //   if (response.code == 200) {
+      //     let qiyeData = response.data;
+      //     wx.config({
+      //       beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
+      //       debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
+      //       appId: qiyeData.appId, // 必填,企业微信的corpID
+      //       timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
+      //       nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
+      //       signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
+      //       jsApiList: ["ready", "getLocation"], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
+      //     });
+      wx.ready(() => {
+        wx.getLocation({
+          type: 'gcj02',
+          success: (resData) => {
+            toastLoading().clear()
+            console.log('处理前')
+            console.log(resData.latitude, resData.longitude)
+            // 定位坐标转换 腾讯转百度
+            let TXisBD = CJ02BD(resData.latitude, resData.longitude)
+            console.log('处理后')
+            console.log(TXisBD)
+            localStorage.setItem('lat', TXisBD.lat)
+            localStorage.setItem('lon', TXisBD.lon)
+            resolve({ TXisBD, resData })
+          },
+          fail: () => {
+            toastLoading().clear()
+            reject('GPS未开启')
+          },
+          complete: () => {
+            toastLoading().clear()
+          },
+        })
+      })
+      wx.error((err) => {
+        toastLoading().clear()
+        console.log(err)
+        reject('定位失败,请开启企微定位权限')
+      })
+      // } else {
+      //   toastLoading().clear();
+      //   reject("获取签名失败");
+      // }
+      // });
+    }
+  })
+}
+
+/**
+ *当前页面授权 一个url只需要授权一次,wx.config 调用多次,只有第一次会调用成功,后面的都会走失败
+ * @param {*object} jsApiList //授权接口列表
+ * @param {*String} getLocation //获取定位
+ */
+export function getTicketFun(jsApiList = ['getLocation']) {
+  return new Promise((resolve, reject) => {
+    // 当前页面
+    let url = window.location.href
+    //  获取签名
+    getTicket({ url: url }).then((response) => {
+      console.log(response)
+      toastLoading().clear()
+      if (response.code == 200) {
+        let qiyeData = response.data
+        wx.config({
+          beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
+          debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
+          appId: qiyeData.appId, // 必填,企业微信的corpID
+          timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
+          nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
+          signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
+          jsApiList: ['ready', ...jsApiList], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
+        })
+        resolve('获取签名成功')
+      } else {
+        console.log('获取签名失败')
+        reject('获取签名失败')
+      }
+    })
+  })
+}
+/**
+ * 地点搜索 获取500米范围poi点
+ * @param {*object} location //当前位置
+ * @param {*number} radius //搜索半径
+ * @param {*number} auto_extend //是否自动扩大范围 0 不扩大
+ * @returns
+ */
+export function getMapPoi(location, radius = 500, auto_extend = 0) {
+  return new Promise((resolve, reject) => {
+    let api =
+      'https://apis.map.qq.com/ws/place/v1/search?page_size=10&page_index=1&orderby=_distance&output=jsonp'
+    let boundary = `&boundary=nearby(${location.latitude},${location.longitude},${radius},${auto_extend})`
+    let key = `&key=${TxMapKey}`
+    jsonp(api + boundary + key)
+      .then((res) => {
+        console.log(res)
+        resolve(res)
+      })
+      .catch((err) => {
+        console.log(err)
+        reject(err)
+      })
+  })
+}
+
+/**
+ * 关键词搜索 在当前城市范围内搜索
+ * @param {*object} location //当前位置
+ * @param {*string} keywordValue //关键字
+ * @returns
+ */
+export function getkeywordPoi(location, keywordValue) {
+  return new Promise((resolve, reject) => {
+    let keyword = keywordValue ? '&keyword=' + encodeURI(keywordValue) : ''
+    // 关键词搜索
+    let api =
+      'https://apis.map.qq.com/ws/place/v1/suggestion?output=jsonp&page_size=10&region_fix=1'
+    let key = `&key=${TxMapKey}`
+    let locationPos = `&location=${location.latitude},${location.longitude}`
+    jsonp(api + locationPos + keyword + key)
+      .then((res) => {
+        console.log(keyword)
+        console.log(res)
+        resolve(res)
+      })
+      .catch((err) => {
+        console.log(err)
+        reject(err)
+      })
+  })
+}

+ 2 - 1
src/utils/commonVant.js

@@ -1,3 +1,4 @@
+import { Toast } from "vant";
 /**
  *
  * @param {*number} duration //展示时长(ms),值为 0 时,toast 不会消失
@@ -6,7 +7,7 @@
  * @returns
  */
 export function toastLoading(duration = 0, message = "加载中...", forbidClick = true) {
-  return this.$toast.loading({
+  return Toast.loading({
     duration: duration,
     message: message,
     forbidClick: forbidClick,

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 832 - 465
src/views/clew/clewent.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 577 - 542
src/views/deviceOutside/index.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 606 - 466
src/views/deviceOutside/suishenbangOutstoreVisit.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 511 - 456
src/views/deviceOutside/topStore.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 3104 - 0
src/views/deviceWithin/addStoreVisit copy.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2391 - 594
src/views/deviceWithin/addStoreVisit.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 334 - 312
src/views/deviceWithin/index.vue


+ 65 - 0
src/views/deviceWithin/taskTips.vue

@@ -0,0 +1,65 @@
+<template>
+  <div class="tips">
+    <span class="examples" v-if="examplePhoto" @click="openExamplesImg(examplePhoto)">示例</span>
+    <span class="phone">
+      <van-icon name="phone" size="18px" /><a :href="'tel:' + contactPhone" class="call">{{
+        contactPhone
+      }}</a>
+    </span>
+  </div>
+</template>
+
+<script>
+import { ImagePreview } from 'vant';
+export default {
+  props: {
+    contactPhone: {
+      type: [String, Number],
+      default: '',
+    },
+    examplePhoto: {
+      type: [String, Number],
+      default: '',
+    },
+  },
+  data() {
+    return {};
+  },
+  methods: {
+    // 点击查看示例图片
+    openExamplesImg(examplePhoto) {
+      if (!examplePhoto) return;
+      ImagePreview([examplePhoto]);
+      // this.examplePhotoImg = examplePhoto;
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.tips {
+  //   position: absolute;
+  //   right: 0;
+  //   top: 11px;
+  display: inline;
+  //   height: 25px;
+  //   line-height: 25px;
+  .examples {
+    margin: 0 10px;
+    background: rgb(255, 151, 106);
+    color: #fff;
+    padding: 2px 4px;
+    border-radius: 2px 2px 8px 2px;
+    font-size: 14px;
+  }
+  .phone {
+    display: inline-block;
+    i {
+      vertical-align: -2px;
+    }
+    a {
+      color: #0057ba;
+      text-decoration: underline;
+    }
+  }
+}
+</style>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1272 - 389
src/views/home/index.vue


+ 249 - 0
src/views/storeManagement/newTMap.vue

@@ -0,0 +1,249 @@
+<template>
+  <div class="newTMap">
+    <div id="allmap1" style="height: 100%; width: 100%"></div>
+    <div
+      style="position: fixed; z-index: 99999; top: 0; width: 100%; background-color: white"
+      v-if="showmap">
+      <form action="/">
+        <van-search
+          v-model="searchValue"
+          left-icon="search"
+          @input="searchFn"
+          placeholder="请输入搜索关键词">
+        </van-search>
+      </form>
+      <div style="height: 200px; overflow: hidden" v-if="searchSHow">
+        <div style="height: 100px; min-height: 200px; overflow-y: scroll; padding: 12px">
+          <div
+            v-for="(itme, index) in mapsearchlist"
+            :key="index"
+            style="border-bottom: 1px solid #eee"
+            @click="addressFn(itme)">
+            <p>{{ itme.title }}</p>
+            <p>{{ itme.address }}</p>
+            <p>距离:{{ itme._distance }}米</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="mapaddress" v-if="showmap">
+      <div class="title">
+        <span @click="showmap = false" style="float: left"
+          ><van-icon name="cross" size="16"
+        /></span>
+        <p class="titleText">附近地址信息</p>
+        <span style="float: right" @click="confirmMap">确定</span>
+      </div>
+      <div class="listBox">
+        <van-radio-group v-model="addresssb" @change="mapselect" v-if="shows">
+          <van-radio :name="index" v-for="(item, index) in maplist" :key="index"
+            ><p style="margin: 4px 0; font-weight: bold">
+              {{ item.title }}
+            </p>
+            <p style="margin: 4px 0">{{ item.address }}</p>
+            <p style="margin: 4px 0">距离:{{ item._distance }}米</p>
+          </van-radio>
+        </van-radio-group>
+        <br />
+        <br />
+        <br />
+        <br />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getMapPoi, getkeywordPoi } from '@/utils/TXApiFun';
+
+export default {
+  data() {
+    return {
+      searchValue: '',
+      searchSHow: false,
+      mapsearchlist: [],
+      showmap: false,
+      addresssb: '',
+      shows: true,
+      maplist: [],
+    };
+  },
+  methods: {
+    initMap(mapPointlist) {
+      //创建map对象,初始化地图
+      let latlng = {
+        lat: this.pLat,
+        lon: this.pLot,
+      };
+      /* eslint-disable */
+      let center = new TMap.LatLng(latlng.lat, latlng.lon);
+      this.map = new TMap.Map('allmap1', {
+        center: center, //设置地图中心点坐标
+        zoom: 17, //设置地图缩放级别
+        // viewMode: "3D",
+        // pitch: 43.5, //设置俯仰角
+        // rotation: 45, //设置地图旋转角度
+      });
+      this.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.SCALE); //移除比例尺控件
+      this.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ROTATION); //移除旋转控件
+      this.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM); //移除控件缩放
+      /* eslint-enable */
+      // 添加标记点 初始化中心点
+      this.initPointMultiMarker(this.map, center);
+      // 添加搜索出的poi点
+      this.addMarkerLayer(this.map, mapPointlist);
+      this.map.on('click', this.clickMap);
+    },
+    initPointMultiMarker(mapNode, center) {
+      let initPoint = {
+        id: 'marker',
+        styleId: 'marker',
+        position: center,
+      };
+      /* eslint-disable */
+      new TMap.MultiMarker({
+        id: 'pointId',
+        map: mapNode,
+        geometries: [initPoint],
+        styles: {
+          marker: new TMap.MarkerStyle({
+            width: 32,
+            height: 40,
+            anchor: { x: 16, y: 32 },
+            src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker-pink.png',
+          }),
+        },
+      });
+      /* eslint-enable */
+    },
+    addMarkerLayer(mapNode, mapPointlist) {
+      /* eslint-disable */
+      let len = mapPointlist.length;
+      if (!len) return;
+      let markerLayerArr = [];
+      for (let i = 0; i < len; i++) {
+        markerLayerArr.push({
+          id: mapPointlist[i].id,
+          styleId: 'marker',
+          position: new TMap.LatLng(mapPointlist[i].location.lat, mapPointlist[i].location.lng),
+        });
+      }
+      new TMap.MultiMarker({
+        id: 'otherPointId',
+        map: mapNode,
+        geometries: markerLayerArr,
+        styles: {
+          marker: new TMap.MarkerStyle({
+            width: 32,
+            height: 40,
+            anchor: { x: 16, y: 32 },
+            src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker_blue.png',
+          }),
+        },
+      });
+      // markerLayer.add(markerLayerArr);
+      /* eslint-enable */
+    },
+    // 点击事件处理方法
+    clickMap(evt) {
+      var lat = evt.latLng.getLat().toFixed(6);
+      var lng = evt.latLng.getLng().toFixed(6);
+      console.log('您点击的的坐标是:' + lat + ',' + lng);
+    },
+    mapBindEvent(map) {
+      // 监听地图平移开始
+      map.on('pan', () => {
+        console.log('监听地图平移开始');
+      });
+      // 监听地图平移结束
+      map.on('panend', () => {
+        console.log('监听地图平移结束');
+      });
+    },
+    searchFn() {
+      this.searchSHow = false;
+      console.log(this.searchValue);
+      getkeywordPoi({ latitude: this.pLat, longitude: this.pLot }, this.searchValue).then((res) => {
+        // 不显示下拉选择
+        if (!res.data.length && !this.searchValue) {
+          this.searchSHow = false;
+        } else {
+          this.searchSHow = true;
+        }
+        // 联想下拉选
+        this.mapsearchlist = res.data;
+        // // 赋值底部列表数据
+        // this.maplist = res.data;
+      });
+    },
+    addressFn(val) {
+      var that = this;
+      setTimeout(() => {
+        /* eslint-disable */
+        that.searchSHow = false;
+        that.map.setCenter(new TMap.LatLng(val.location.lat, val.location.lng));
+        that.markers1.updateGeometries([
+          {
+            id: 'marker',
+            styleId: 'marker',
+            position: new TMap.LatLng(val.location.lat, val.location.lng),
+          },
+        ]);
+        that.maplist = [];
+        // 地点搜索 获取500米范围poi点
+        getMapPoi({ latitude: this.pLat, longitude: this.pLot }).then((res) => {
+          console.log(res);
+          that.maplist = res.data;
+          that.marker.setGeometries([]);
+          setTimeout(() => {
+            for (let p = 0; p < res.data.length; p++) {
+              that.marker.updateGeometries([
+                {
+                  id: res.data[p].id,
+                  position: new TMap.LatLng(res.data[p].location.lat, res.data[p].location.lng),
+                },
+              ]);
+            }
+          });
+        });
+        // 清楚选中状态
+        that.addresssb = -1;
+        /* eslint-enable */
+      });
+    },
+    confirmMap() {
+      console.log(this.maplist);
+      console.log(this.addresssb);
+      if (this.addresssb > -1) {
+        this.list.addressLine = this.maplist[this.addresssb].address;
+        this.lon = this.myLat;
+        this.lat = this.myLon;
+        this.poiAddress = this.maplist[this.addresssb].address;
+        this.poiLat = this.maplist[this.addresssb].location.lat;
+        this.poiLon = this.maplist[this.addresssb].location.lng;
+        this.poiId = this.maplist[this.addresssb].id;
+        this.poiName = this.maplist[this.addresssb].title;
+        this.showmap = false;
+      }
+    },
+    mapselect(val) {
+      /* eslint-disable */
+      this.searchSHow = false;
+      if (val > -1) {
+        this.markers.updateGeometries([
+          {
+            id: 'markers1',
+            styleId: 'abc',
+            position: new TMap.LatLng(
+              this.maplist[val].location.lat,
+              this.maplist[val].location.lng
+            ),
+          },
+        ]);
+      }
+      /* eslint-enable */
+    },
+  },
+};
+</script>
+<style scoped lang="scss"></style>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 516 - 445
src/views/storeManagement/storeDetail.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 313 - 309
src/views/storeManagement/storeEdit.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 992 - 412
src/views/week/daily.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 939 - 361
src/views/week/dailyApproval.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 860 - 313
src/views/week/dailyDetails.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 993 - 429
src/views/week/dailyHistoricalDetails.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 729 - 372
src/views/week/doubleHistoricalWeeklyDetils.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 739 - 367
src/views/week/doubleWeekly.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 638 - 276
src/views/week/doubleWeeklyApproval.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 696 - 288
src/views/week/doubleWeeklyDetils.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 922 - 513
src/views/week/weekly.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 797 - 332
src/views/week/weeklyApproval.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 759 - 289
src/views/week/weeklyApprovalDetils.vue


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 796 - 344
src/views/week/weeklyHistoricalDetils.vue


+ 23 - 25
vue.config.js

@@ -1,15 +1,15 @@
-'use strict'
-const path = require('path')
+"use strict";
+const path = require("path");
 function resolve(dir) {
-  return path.join(__dirname, dir)
+  return path.join(__dirname, dir);
 }
-const name = process.env.VUE_APP_TITLE || '门店拜访' // 网页标题
-const port = process.env.port || process.env.npm_config_port || 80 // 端口
+const name = process.env.VUE_APP_TITLE || "门店拜访"; // 网页标题
+const port = 8888; // 端口
 module.exports = {
   // publicPath: process.env.NODE_ENV === "production" ? "/mobile/" : "/",
   publicPath: "/mobile/",
-  outputDir: 'mobile',
-  assetsDir: 'static',
+  outputDir: "mobile",
+  assetsDir: "static",
   lintOnSave: false,
   productionSourceMap: false,
   devServer: {
@@ -20,31 +20,29 @@ module.exports = {
         target: process.env.VUE_APP_Target,
         changeOrigin: true,
         pathRewrite: {
-          ['^' + process.env.VUE_APP_BASE_API]:process.env.VUE_APP_BASE_API+''
-        }
+          ["^" + process.env.VUE_APP_BASE_API]: process.env.VUE_APP_BASE_API + "",
+        },
       },
     },
-    disableHostCheck: true
+    disableHostCheck: true,
   },
   configureWebpack: {
     name: name,
     resolve: {
       alias: {
-        '@': resolve('src')
-      }
-    }
+        "@": resolve("src"),
+      },
+    },
   },
   chainWebpack(config) {
-    config.plugins.delete('preload') // TODO: need test
-    config.plugins.delete('prefetch') // TODO: need test
-    config.when(process.env.NODE_ENV !== 'development',
-      config => {
-        config.optimization.runtimeChunk('single'),
+    config.plugins.delete("preload"); // TODO: need test
+    config.plugins.delete("prefetch"); // TODO: need test
+    config.when(process.env.NODE_ENV !== "development", (config) => {
+      config.optimization.runtimeChunk("single"),
         {
-          from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
-          to: './' //到根目录下
-        }
-      }
-    )
-  }
-}
+          from: path.resolve(__dirname, "./public/robots.txt"), //防爬虫文件
+          to: "./", //到根目录下
+        };
+    });
+  },
+};