Forráskód Böngészése

级联搜索完成

vaecebyZ 1 éve
szülő
commit
d115d7a773

+ 9 - 0
api/shop.js

@@ -22,4 +22,13 @@ export function appSearch(data) {
 		url: '/zswl-cloud-shop/goodsInfo/appSearch',
 		data
 	})
+}
+
+// 获取商品分类
+export function getSearchTypeData(params) {
+  return request({
+    url: '/zswl-cloud-shop/goodsCate/data',
+    method: 'get',
+    params
+  })
 }

+ 233 - 0
components/zs-choose-tab-union/index.vue

@@ -0,0 +1,233 @@
+<template>
+  <view class="">
+    <view class="choose-tab" :style="{ position }">
+      <view class="tab-list">
+        <view
+          class="tab"
+          v-for="(item, index) in tabList"
+          :class="[chooseList[index] ? 'active' : '']"
+          :key="index"
+          @click="handleTab(item, index)"
+        >
+          <view>
+            {{ chooseList[index].cateName || item.cateName }}
+          </view>
+          <view>
+            <!-- {{ active }} -->
+            <u-icon
+              name="arrow-down"
+              size="12px"
+              v-if="active !== index"
+            ></u-icon>
+            <u-icon
+              v-if="active === index"
+              name="arrow-up"
+              size="12px"
+            ></u-icon>
+          </view>
+        </view>
+      </view>
+      <view class="box" v-show="show">
+        <view v-show="show" class="first">
+          <view
+            :class="[levelActive[0] == item.id ? 'active' : '', 'item']"
+            v-for="(item, index) in tabList[active].child"
+            :key="index"
+            @click="choose(item, 1)"
+          >
+            {{ item.cateName }}
+          </view>
+        </view>
+        <view v-show="show" v-if="level > 1" class="second">
+          <view
+            :class="[levelActive[1] == item.id ? 'activeL2' : '', 'item']"
+            v-for="(item, index) in clickObj.child"
+            :key="index"
+            @click="choose(item, 2)"
+          >
+            {{ item.cateName }}
+          </view>
+        </view>
+        <view v-show="show" v-if="level > 2" class="third"> </view>
+      </view>
+    </view>
+    <view
+      class="choose-modal"
+      :style="{ background: showModal ? 'rgba(0, 0, 0, .4)' : 'none' }"
+      v-show="show"
+      @click="show = false"
+    >
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    position: {
+      type: String,
+      default: "fixed",
+    },
+    showModal: {
+      type: Boolean,
+      default: true,
+    },
+    tabList: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    level: {
+      type: Number,
+      default: 1,
+    },
+  },
+  data() {
+    return {
+      show: false,
+      chooseList: ["", "", "", ""],
+      list: [],
+      clickObj: {},
+      levelActive: [null, null, null],
+      active: null,
+      secondList: [],
+      thirdList: [],
+    };
+  },
+  methods: {
+    handleTab(item, index) {
+      this.active = index;
+      this.clickObj = {};
+      // 如果存在已经选择过的数据
+      if (this.chooseList[index]) {
+        for (const e of this.tabList[index].child) {
+          // 根据ID定位到当前选择的对象
+          if (e.child && e.child.length) {
+            for (const i of e.child) {
+              if (i.id == this.chooseList[index].id) {
+                this.clickObj = e;
+                this.levelActive[1] = i.id;
+              }
+            }
+          } else {
+            if (e.id == this.chooseList[index].id) {
+              this.levelActive[0] = e.id;
+            }
+          }
+        }
+      }
+
+      this.$nextTick(() => {
+        this.show = !this.show;
+      });
+    },
+    choose(item, level) {
+      // console.log("item", item);
+
+      this.levelActive[level - 1] = item.id;
+      this.clickObj = item;
+
+      // 没有子级直接提交当前
+      if (level == this.level || !item.child || !item.child.length) {
+        this.show = false;
+        // 重复选择则取消
+        // console.log(
+        //   "this.chooseList",
+        //   this.chooseList,
+        //   "this.active",
+        //   this.active
+        // );
+        let id = this.chooseList[this.active]?.id || "";
+        if (item.id == id) {
+          this.chooseList[this.active] = "";
+          this.levelActive = [null, null, null];
+        } else {
+          this.chooseList[this.active] = item;
+        }
+        this.$emit("choose", this.chooseList);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.choose-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.4);
+  z-index: 99;
+}
+
+.choose-tab {
+  // position: fixed;
+  top: 0;
+  left: 0;
+  background-color: #fafafa;
+  overflow: hidden;
+  border-radius: 0rpx 0rpx 16rpx 16rpx;
+  width: 100%;
+  z-index: 100;
+  .tab-list {
+    display: flex;
+    align-items: center;
+    padding: 20rpx;
+    background: #fff;
+    .tab {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background: #f0f0f0;
+      border-radius: 8rpx 8rpx 8rpx 8rpx;
+      height: 40rpx;
+      line-height: 40rpx;
+      color: #222222;
+      font-size: 24rpx;
+      padding: 0 10rpx;
+      margin-right: 16rpx;
+    }
+  }
+
+  .box {
+    background: #fff;
+    display: flex;
+    justify-content: start;
+    padding: 10rpx;
+    .item {
+      max-height: 600rpx;
+      font-size: 30rpx;
+      overflow: auto;
+      color: #222222;
+      padding: 14rpx 24rpx;
+      width: 100%/3;
+    }
+    .first {
+      flex: 1;
+      background-color: #ffffff;
+    }
+    .second {
+      flex: 1;
+      background-color: #f7f7f7;
+    }
+    .third {
+      flex: 1;
+      background-color: #f2f2f2;
+    }
+  }
+  .active {
+    color: $uni-color-primary !important;
+    background-color: #f7f7f7;
+  }
+  .activeL2 {
+    color: $uni-color-primary !important;
+    background-color: #f2f2f2;
+  }
+  .activeL3 {
+    color: $uni-color-primary !important;
+  }
+}
+</style>

+ 5 - 1
components/zs-search/index.vue

@@ -1,6 +1,6 @@
 <template>
 	<view class="zs-search" :class="[fixed?'fixed':'']">
-		<input :class="[showPrefix?'input':'fullwidInput']" :style="{lineHeight:height+'rpx',height:height+'rpx',borderRadius:height / 2+'px',color:color,background:bgColor}" :type="type" v-model="value" :placeholder="placeholder" />
+		<input :readOnly="readOnly" :class="[showPrefix?'input':'fullwidInput']" :style="{lineHeight:height+'rpx',height:height+'rpx',borderRadius:height / 2+'px',color:color,background:bgColor}" :type="type" v-model="value" :placeholder="placeholder" />
 		<image v-if="showPrefix" class="icon" src="../../static/search.png" mode=""></image>
 		<button v-if="showBtn" class="btn" type="default" @click="search">搜索</button>
 	</view>
@@ -13,6 +13,10 @@
 				type: String,
 				default: 'text'
 			},
+			readOnly:{
+				type: Boolean,
+				default: false
+			},
 			height: {
 				type: String,
 				default: '72'

+ 1 - 0
pages/index/index.vue

@@ -17,6 +17,7 @@
           style="margin-top: 10px"
           :showBtn="false"
           :showPrefix="false"
+          :readOnly="true"
           placeholder="请输入商品名称"
           height="80"
           bgColor="#F6F6F6"

+ 16 - 87
pages/index/searchResult.vue

@@ -1,7 +1,8 @@
 <template>
   <view class="searchResult">
-    <zs-choose-tab :tabList="tabList" @choose="chooseTab"></zs-choose-tab>
-
+    <!-- <zs-choose-tab :tabList="tabList" @choose="chooseTab"></zs-choose-tab> -->
+    <zs-choose-tab-union :level="2" :tabList="tabList" @choose="chooseTab">
+    </zs-choose-tab-union>
     <view class="goods-list">
       <zs-list class="store-box" mt="0" @load="loadMore" :status="status">
         <view class="left">
@@ -67,8 +68,7 @@
 </template>
 
 <script>
-import { appSearch } from "@/api/shop.js";
-import { getMenu } from "@/api/common.js";
+import { appSearch, getSearchTypeData } from "@/api/shop.js";
 export default {
   data() {
     return {
@@ -84,60 +84,12 @@ export default {
         goodsName: "",
         shopId: "",
         status: 3,
-				currentPage:0
+        currentPage: 0,
       },
       status: "more",
       list: [],
       list1: [],
-      tabList: [
-        // {
-        // 	id: 1,
-        // 	label: '区域',
-        // 	list: [
-
-        // 		{
-        // 			id: 1,
-        // 			label: '观山湖'
-        // 		},
-        // 		{
-        // 			id: 2,
-        // 			label: '白云区'
-        // 		},
-        // 		{
-        // 			id: 3,
-        // 			label: '花果山区'
-        // 		}
-        // 	]
-        // },
-        {
-          id: 1,
-          label: "全部分类",
-          list: [],
-        },
-
-        // {
-        // 	id: 1,
-        // 	label: '附近',
-        // 	list: [
-        // 		{
-        // 			id:5,
-        // 			label: '5KM'
-        // 		},
-        // 		{
-        // 			id:10,
-        // 			label: '10KM'
-        // 		},
-        // 		{
-        // 			id:20,
-        // 			label: '20KM'
-        // 		},
-        // 		{
-        // 			id:50,
-        // 			label: '50KM'
-        // 		}
-        // 	]
-        // },
-      ],
+      tabList: [],
     };
   },
   methods: {
@@ -154,26 +106,11 @@ export default {
       });
     },
     chooseTab(val) {
-      console.log(val);
-      this.query.range = val[2].id;
-      if (val[0]) {
-        this.query["location.lat"] = val[0].location.lat;
-        this.query["location.lon"] = val[0].location.lng;
-        this.query.range = 50;
-        this.query.district = val[0].label;
-      } else if (!val[0]) {
-        this.query["location.lat"] = this.location.latitude;
-        this.query["location.lon"] = this.location.longitude;
-        this.query.district = "";
-      }
-      if (val[1]) {
-        this.query.menuId = val[1].id;
-      } else if (!val[1]) {
-        this.query.menuId = "";
-      }
+      this.query.goodsName = val[0].cateName;
       this.query.pageCurrent = 1;
       this.status = "more";
       this.list = [];
+      this.list1 = [];
       this.search();
     },
     search() {
@@ -211,30 +148,22 @@ export default {
     loadMore() {
       this.search();
     },
-    // 金刚区
-    getMenu() {
-      getMenu({ currentPage: 1, pageSize: 10, status: 2 }).then((res) => {
-        if (res.state == "Success") {
-          let list = [];
-          res.content.records.map((item) => {
-            list.push({
-              id: item.id,
-              label: item.menuName,
-            });
-          });
-          // this.tabList[1].list = list;
-        }
+    getTabList() {
+      // 如果是栏目点进来则更新标题
+      getSearchTypeData().then((res) => {
+        this.tabList = res.content;
       });
     },
   },
   onLoad(options) {
-    let list = uni.getStorageSync("districtList") || "[]";
-    this.tabList[0].list = JSON.parse(list);
+    // let list = uni.getStorageSync("districtList") || "[]";
+    // this.tabList[0].list = JSON.parse(list);
     this.location = JSON.parse(uni.getStorageSync("location"));
     this.query.shopId = uni.getStorageSync("gdShopId");
     this.query["location.lat"] = this.location.latitude;
     this.query["location.lon"] = this.location.longitude;
     this.query.goodsName = options?.search || "";
+
     if (!this.query.goodsName) {
       this.query.columnName = options.column;
       uni.setNavigationBarTitle({
@@ -242,7 +171,7 @@ export default {
       });
     }
     this.search();
-    // this.getMenu();
+    this.getTabList();
   },
 };
 </script>