Jelajahi Sumber

Merge branch 'feature_20250313_计划内增加筛选,未拜访列表添加加入计划内操作' into release

zhujindu 8 bulan lalu
induk
melakukan
f6364a8501

+ 325 - 0
src/components/filtrate.vue

@@ -0,0 +1,325 @@
+<template>
+  <div class="filtrate">
+    <van-popup v-model="showFilter" position="bottom" class="textsize" @close="closePopup">
+      <van-row
+        style="
+          width: 100%;
+          z-index: 998;
+          background-color: #fff;
+          border-bottom: 1px solid #ccc;
+          height: 50px;
+        ">
+        <van-col span="3" style="text-align: center; margin: 14px 0" @click="closePopup(false)">
+          <van-icon name="cross" size="20" color="#909399" />
+        </van-col>
+        <van-col span="13"> </van-col>
+        <van-col span="4" style="text-align: center; line-height: 36px" @click="onConfirm">
+          <div style="color: #0057ba">
+            <van-button type="info" size="small" color="#0057ba">筛选</van-button>
+          </div></van-col
+        >
+        <van-col span="4" style="text-align: center; line-height: 36px" @click="onsets">
+          <van-button type="default" size="small" style="height: 28px">重置</van-button>
+        </van-col>
+      </van-row>
+      <div class="searchcheck" @touchmove="handleTouch">
+        <p class="searchchecktitle">&nbsp;经销商</p>
+        <van-row>
+          <van-col span="24">
+            <div @click="moreTypeShowFn">
+              <van-field
+                style="
+                  margin-top: -6px;
+                  border-radius: 6px;
+                  border: 1px solid #ccc;
+                  overflow: hidden;
+                "
+                readonly
+                v-model="chainName"
+                label=""
+                placeholder="请选择经销商" />
+            </div>
+          </van-col>
+        </van-row>
+        <p class="searchchecktitle" @click="otherbqShow = !otherbqShow">
+          &nbsp;门店标签<van-icon name="arrow-down" style="float: right" />
+        </p>
+        <van-checkbox-group v-model="storeLabelTypes" direction="horizontal">
+          <div v-if="otherbqShow" style="width: 100%">
+            <div class="checkbox" v-for="(item, index) in StoreLabels" :key="index">
+              <van-checkbox :name="item.dictValue">{{ item.dictLabel }}</van-checkbox>
+            </div>
+            <div style="height: 2px; background-color: #f5f5f5; width: 100%; clear: both"></div>
+          </div>
+        </van-checkbox-group>
+        <van-checkbox-group v-model="result" direction="horizontal">
+          <p class="searchchecktitle" @click="otherkkdShow = !otherkkdShow">
+            &nbsp;可控店<van-icon name="arrow-down" style="float: right" />
+          </p>
+          <div v-if="otherkkdShow">
+            <div v-for="(item, index) in storeTypeLists" :key="index" class="checkbox1">
+              <div v-if="item.groupType == 'kkd'" class="child">
+                <van-checkbox :name="item.dictValue">{{ item.dictLabel }}</van-checkbox>
+              </div>
+            </div>
+          </div>
+          <div style="height: 2px; background-color: #f5f5f5; width: 100%; clear: both"></div>
+          <p class="searchchecktitle" @click="otherfxdShow = !otherfxdShow">
+            &nbsp;分销店<van-icon name="arrow-down" style="float: right" />
+          </p>
+          <div v-if="otherfxdShow" style="margin: 0 14px; width: 100%">
+            <div style="height: 2px; background-color: #f5f5f5; width: 100%; clear: both"></div>
+            <p class="searchchecktitle1" @click="otherfxdShow1 = !otherfxdShow1">
+              金牌店<van-icon name="arrow-down" style="float: right" />
+            </p>
+            <div v-if="otherfxdShow1">
+              <div v-for="(item1, index1) in storeTypeLists" :key="200 + index1" class="checkbox1">
+                <div v-if="item1.groupType == 'fxd' && item1.remark == 'jp'" class="child">
+                  <van-checkbox :name="item1.dictValue">{{ item1.dictLabel }}</van-checkbox>
+                </div>
+              </div>
+              <div style="height: 2px; background-color: #f5f5f5; width: 100%; clear: both"></div>
+            </div>
+            <p class="searchchecktitle1" @click="otherfxdShow2 = !otherfxdShow2">
+              同城分销店<van-icon name="arrow-down" style="float: right" />
+            </p>
+            <div v-if="otherfxdShow2">
+              <div
+                v-for="(itemlj, indexlj) in storeTypeLists"
+                :key="400 + indexlj"
+                class="checkbox1">
+                <div v-if="itemlj.groupType == 'fxd' && itemlj.remark == 'tcfx'" class="child">
+                  <van-checkbox :name="itemlj.dictValue">{{ itemlj.dictLabel }}</van-checkbox>
+                </div>
+              </div>
+              <div style="clear: both"></div>
+            </div>
+          </div>
+          <div style="height: 2px; background-color: #f5f5f5; width: 100%; clear: both"></div>
+          <p class="searchchecktitle" @click="otherShow = !otherShow">
+            &nbsp;其他 <van-icon name="arrow-down" style="float: right" />
+          </p>
+          <div v-if="otherShow">
+            <div v-for="(item2, index2) in storeTypeLists" :key="100 + index2" class="checkbox1">
+              <div v-if="item2.groupType == 'other'" class="child">
+                <van-checkbox :name="item2.dictValue">{{ item2.dictLabel }}</van-checkbox>
+              </div>
+            </div>
+          </div>
+        </van-checkbox-group>
+      </div>
+    </van-popup>
+    <van-popup v-model="moreTypeShow" position="bottom" style="height: 80%">
+      <van-row style="background-color: #f5f5f5">
+        <van-col span="20">
+          <van-field
+            left-icon="search"
+            style="margin-top: 2px; border-radius: 6px; overflow: hidden"
+            v-model="CustomerName"
+            label=""
+            placeholder="请输入关键词"
+            clearable />
+        </van-col>
+        <van-col span="4" style="text-align: center; line-height: 48px" @click="getCustomer">
+          <div style="background-color: #0057ba; color: #fff">搜索</div></van-col
+        >
+      </van-row>
+      <van-picker
+        show-toolbar
+        :columns="chainsData"
+        value-key="chainName"
+        @confirm="onConfirmChainsList"
+        @cancel="moreTypeShow = false"
+        visible-item-count="10" />
+    </van-popup>
+  </div>
+</template>
+<script>
+import { getCustomerList, getStoreLabels, getStoreTypeListlp } from '@/api/index';
+export default {
+  name: 'filtrate',
+  props: {
+    showFilter: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  watch: {
+    showFilter: {
+      handler(val) {
+        // this.CustomerName = '';
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  data() {
+    return {
+      CustomerName: '',
+      storeCategoryList: '',
+      storeLabelTypes: [],
+      chainName: '',
+      chainCode: '',
+      chainsData: [],
+      moreTypeShow: false,
+      otherShow: false,
+      otherbqShow: true,
+      StoreLabels: [],
+      result: [],
+      otherkkdShow: true,
+      storeTypeLists: [],
+      otherfxdShow: true,
+      otherfxdShow1: true,
+      otherfxdShow2: true,
+    };
+  },
+  activated() {
+    var postType = localStorage.getItem('postType');
+    if (postType == 'GZ') {
+      this.otherShow = true;
+    } else {
+      this.otherShow = false;
+    }
+  },
+  created() {},
+  mounted() {
+    this.getStoreLabels();
+    this.getStoreTypeList();
+  },
+  methods: {
+    closePopup(flag = false) {
+      // flag 是否筛选列表
+      let params = {};
+      if (flag) {
+        params = {
+          chainCode: this.chainCode ? this.chainCode : '',
+          storeLabelTypes: this.storeLabelTypes.join(','),
+          storeCategoryList: this.storeCategoryList,
+        };
+      }
+      this.$emit('closePopup', flag, params);
+    },
+    handleTouch(e) {
+      e._isScroller = true;
+    },
+    onsets() {
+      this.result = [];
+      this.storeLabelTypes = [];
+      this.storeCategoryList = this.result.join(',');
+      this.chainName = '';
+      this.chainCode = '';
+      this.closePopup(true);
+    },
+    moreTypeShowFn() {
+      this.moreTypeShow = true;
+      this.getCustomer();
+    },
+    getCustomer() {
+      getCustomerList({ name: this.CustomerName }).then((request) => {
+        this.chainsData = request.data;
+        this.chainsData.push({});
+        this.chainsData.pop();
+      });
+    },
+    onConfirm(value) {
+      this.storeCategoryList = this.result.join(',');
+      this.onSearchm();
+    },
+    onSearchm() {
+      var StoreLabelsArr = [];
+      for (var k = 0; k < this.storeLabelTypes.length; k++) {
+        for (var k1 = 0; k1 < this.StoreLabels.length; k1++) {
+          if (this.StoreLabels[k1].dictValue == this.storeLabelTypes[k]) {
+            StoreLabelsArr.push(this.StoreLabels[k1].dictLabel);
+          }
+        }
+      }
+      var storeCategoryList = [];
+      for (var q = 0; q < this.result.length; q++) {
+        for (var q1 = 0; q1 < this.storeTypeLists.length; q1++) {
+          if (this.storeTypeLists[q1].dictValue == this.result[q]) {
+            storeCategoryList.push(this.storeTypeLists[q1].dictLabel);
+          }
+        }
+      }
+      localStorage.setItem('outvstoreName', this.storeName);
+      localStorage.setItem('outvchainName', this.chainName);
+      localStorage.setItem('outvstoreLabelTypes', this.storeLabelTypes);
+      localStorage.setItem('outvstoreCategoryList', this.result);
+      localStorage.setItem('outvchainCode', this.chainCode);
+      this.closePopup(true);
+    },
+    onConfirmChainsList(value) {
+      if (value.chainName != undefined) {
+        this.chainName = value.chainName;
+        this.chainCode = value.chainCode;
+      }
+      this.showPickerChainsList = false;
+      this.moreTypeShow = false;
+    },
+    getStoreLabels() {
+      getStoreLabels().then((res) => {
+        this.StoreLabels = res.data;
+      });
+    },
+    getStoreTypeList() {
+      getStoreTypeListlp({}).then((res) => {
+        this.storeTypeLists = res.data;
+        this.storeTypeList = res.data;
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.filtrate {
+  .textsize {
+    font-size: 14px;
+    /* overflow: hidden; */
+    display: flex;
+    flex-direction: column;
+    .searchcheck {
+      flex: 1;
+      overflow-y: auto;
+      margin-bottom: 50px;
+    }
+  }
+
+  .searchcheck {
+    padding: 0 10px 10px;
+  }
+  .searchcheck .van-checkbox {
+    /*width: 44%;*/
+    padding-bottom: 10px;
+  }
+  .searchcheck .checkbox {
+    font-size: 14px;
+    display: inline-block;
+    width: 50%;
+    line-height: 28px;
+  }
+  .searchcheck .checkbox .van-checkbox {
+    margin-bottom: 2px;
+  }
+  .searchcheck .checkbox1 {
+    font-size: 14px;
+    float: left;
+    line-height: 28px;
+    width: 50%;
+  }
+  .searchcheck .checkbox1 .child {
+    width: 100%;
+  }
+  .searchcheck {
+    /* height: 93vh;
+  overflow-y: auto; */
+  }
+  .searchchecktitle {
+    width: 100%;
+    margin: 20px 0;
+    font-size: 16px;
+    border-left: 3px solid #0057ba;
+    line-height: 18px;
+  }
+}
+</style>

+ 30 - 8
src/views/deviceWithin/index.vue

@@ -2,7 +2,11 @@
   <div class="bgcolor deviceWithin">
     <div class="navBarTOP">
       <!--        顶部条-->
-      <van-nav-bar class="navBar" title="计划内"> </van-nav-bar>
+      <van-nav-bar class="navBar" title="计划内">
+        <template #right>
+          <span @click="searchFn">筛选<van-icon name="arrow-down" /></span>
+        </template>
+      </van-nav-bar>
       <div class="searchDiv">
         <van-search
           v-model="storeName"
@@ -355,6 +359,8 @@
         @confirm="dateeconfirm"
         @cancel="show = false" />
     </van-popup>
+    <!-- 筛选模块 -->
+    <filtrate v-show="showFilter" :showFilter="showFilter" @closePopup="closePopup"></filtrate>
     <tab-bar tabBarActive="deviceWithin"></tab-bar>
   </div>
 </template>
@@ -390,9 +396,10 @@ import xmgj from '@/assets/xmgj.png';
 import { getOrderUrlByStoreId } from '@/api/inventory';
 import { checkStoreAddressByStoreCode } from '@/api/visitstore';
 import { getPosition, getTicketFun } from '@/utils/TXApiFun';
+import filtrate from '@/components/filtrate';
 export default {
   name: 'deviceWithin',
-  components: { tabBar },
+  components: { tabBar, filtrate },
   data() {
     return {
       xmgj: xmgj,
@@ -443,6 +450,9 @@ export default {
       endShow: false,
       visitEndId: '',
       customerVisits: true,
+      // 筛选模块
+      showFilter: false,
+      filterParams: {},
     };
   },
   watch: {
@@ -477,6 +487,16 @@ export default {
     );
   },
   methods: {
+    closePopup(flag, filterParams) {
+      this.showFilter = false;
+      if (flag) {
+        this.filterParams = filterParams;
+        this.onSearch();
+      }
+    },
+    searchFn() {
+      this.showFilter = true;
+    },
     handleTouch(e) {
       e._isScroller = true;
     },
@@ -679,23 +699,25 @@ export default {
       this.endShow = false;
       this.toastLoading(0, '加载中...', true);
       localStorage.removeItem('visitId');
-      getPosition(true)
+      getPosition(true, true)
         .then((res) => {
           let { TXisBD } = res;
           this.getUserInPlanListFun(TXisBD);
         })
         .catch((error) => {
-          this.$dialog.alert({
-            message: error,
-          });
+          this.getUserInPlanListFun();
+          // this.$dialog.alert({
+          //   message: error,
+          // });
         });
     },
     getUserInPlanListFun(TXisBD) {
       getUserInPlanList({
         storeName: this.storeName.trim(),
         genDate: this.genDate,
-        lat: TXisBD.lat,
-        lon: TXisBD.lon,
+        lat: TXisBD ? TXisBD.lat : '',
+        lon: TXisBD ? TXisBD.lon : '',
+        ...this.filterParams,
       }).then((res) => {
         this.toastLoading().clear();
         if (res.code == 200) {

+ 52 - 21
src/views/home/hintTabPage/noVisit.vue

@@ -23,6 +23,14 @@
                   <div class="distance" v-if="item.storeLonExist">
                     (距离{{ Micrometer(item.distance) }}m)
                   </div>
+                  <div class="bottomBtnBox">
+                    <div class="toVisit joinVisit">
+                      <span @click="storeJoinVisit(item)" v-if="item.joinInPlan">加入计划内</span>
+                    </div>
+                    <div class="toVisit" @click="storeVisit(item)">
+                      进入拜访 <van-icon name="arrow" />
+                    </div>
+                  </div>
                 </div>
                 <div class="itemRight">
                   <div
@@ -37,9 +45,6 @@
                       size="32" />
                     {{ item.stateString == '未拜访' ? '未拜访' : '' }}
                   </div>
-                  <div class="toVisit" @click="storeVisit(item)">
-                    进入拜访 <van-icon name="arrow" />
-                  </div>
                 </div>
               </div>
             </template>
@@ -56,6 +61,7 @@ import {
   mobileReposition,
   checkVisit,
   addVisitsPosition,
+  joinInPlan,
 } from '@/api/index';
 import { checkStoreAddressByStoreCode } from '@/api/visitstore';
 import { getPosition, getTicketFun } from '@/utils/TXApiFun';
@@ -369,6 +375,21 @@ export default {
           });
         });
     },
+    // 加入计划内
+    storeJoinVisit(val) {
+      this.toastLoading(0, '加载中...', true);
+      joinInPlan({ storeId: val.storeId }).then((res) => {
+        this.toastLoading().clear();
+        if (res.code == 200) {
+          this.$set(val, 'joinInPlan', false);
+        } else {
+          this.$dialog.alert({
+            title: '系统提示',
+            message: res.msg,
+          });
+        }
+      });
+    },
     onClickLeft() {
       this.$router.go(-1);
     },
@@ -388,11 +409,13 @@ export default {
       margin: 10px 0;
       border-radius: 5px;
       display: flex;
+      position: relative;
       .storeName {
         font-size: 15px;
         font-weight: bold;
         color: #333;
         padding: 3px 0;
+        width: 80%;
       }
       .address,
       .distance {
@@ -401,17 +424,36 @@ export default {
         padding: 3px 0;
       }
       .distance {
-        padding-left: 12px;
+        // padding-left: 12px;
       }
       .itemLeft {
         flex: 1;
+        .bottomBtnBox {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          .toVisit {
+            height: 32px;
+            font-size: 15px;
+            color: #1989fa;
+            display: flex;
+            align-items: center;
+            white-space: nowrap;
+          }
+          .joinVisit {
+            span {
+              display: inline-block;
+              border-radius: 20px;
+              padding: 5px 10px;
+              background: #1989fa;
+              color: #fff;
+            }
+          }
+        }
       }
       .itemRight {
-        width: 25%;
-        display: flex;
-        flex-direction: column;
-        justify-content: space-between;
-        align-items: end;
+        position: absolute;
+        right: 0;
         .statstext {
           background-color: #0057ba;
           padding: 2px 6px 2px 12px;
@@ -419,24 +461,13 @@ export default {
           border-top-left-radius: 60px;
           color: #fff;
           width: 60px;
-          margin-right: -8px;
+          // margin-right: -8px;
           /* overflow: hidden; */
           white-space: nowrap;
           .van-icon__image {
             height: 0.7em;
           }
         }
-        .toVisit {
-          height: 40%;
-          font-size: 15px;
-          color: #1989fa;
-          width: 100%;
-          display: flex;
-          align-items: center;
-          justify-content: end;
-          /* overflow: hidden; */
-          white-space: nowrap;
-        }
       }
     }
   }