瀏覽代碼

专题页分类&首页tab位置修改

viczhq 4 月之前
父節點
當前提交
dd50c2409f

+ 7 - 0
project.private.config.json

@@ -10,6 +10,13 @@
10 10
     "miniprogram": {
11 11
       "list": [
12 12
         {
13
+          "name": "pages/indexSub/seckillIndex/index",
14
+          "pathName": "pages/indexSub/seckillIndex/index",
15
+          "query": "isDirect=true&title=%E5%90%83%E5%96%9D%E7%8E%A9%E4%B9%90&id=128",
16
+          "launchMode": "default",
17
+          "scene": null
18
+        },
19
+        {
13 20
           "name": "pages/memberSub/productClassify/index",
14 21
           "pathName": "pages/memberSub/productClassify/index",
15 22
           "query": "",

+ 50 - 44
src/pages/index/index.jsx

@@ -1,14 +1,6 @@
1 1
 import Taro from "@tarojs/taro"; // 导入 Taro
2 2
 import { Component } from "react";
3
-import {
4
-  View,
5
-  Image,
6
-  Swiper,
7
-  SwiperItem,
8
-  Text,
9
-  Button,
10
-  ScrollView,
11
-} from "@tarojs/components";
3
+import { View, Image, Swiper, SwiperItem, Text } from "@tarojs/components";
12 4
 import { AtTabs } from "taro-ui";
13 5
 import { getHomeData, getProductList } from "../../service";
14 6
 import { getShareContent } from "../../common/share";
@@ -30,6 +22,7 @@ export default class Index extends Component {
30 22
     page: 1, // 添加页码
31 23
     totalPages: 1, // 添加总页数
32 24
     loading: false, // 添加加载状态
25
+    isTabFixed: false, // 添加新的状态控制吸顶
33 26
   };
34 27
   // 获取首页数据
35 28
   getHomeData = async () => {
@@ -52,30 +45,18 @@ export default class Index extends Component {
52 45
   };
53 46
   // 修改 tab 切换处理函数
54 47
   handleClick(value) {
48
+    // 添加回到顶部方法
49
+      Taro.pageScrollTo({
50
+        scrollTop: 500, // 滚动到顶部位置
51
+        duration: 200, // 滚动动画持续时间,单位 ms
52
+      });
55 53
     this.setState(
56 54
       {
57 55
         current: value,
58 56
         page: 1,
59 57
       },
60 58
       () => {
61
-        // 跳转到列表顶部
62
-        Taro.createSelectorQuery()
63
-          .select(".product-list-wrap")
64
-          .boundingClientRect()
65
-          .exec((res) => {
66
-            if (res[0]) {
67
-              const top = res[0].top;
68
-              Taro.pageScrollTo({
69
-                scrollTop: top - 40,
70
-                duration: 300,
71
-                complete: () => {
72
-                  this.getProductList(true);
73
-                },
74
-              });
75
-            } else {
76
-              console.warn("未找到 .product-list-wrap 元素");
77
-            }
78
-          });
59
+        this.getProductList(true);
79 60
       }
80 61
     );
81 62
   }
@@ -128,12 +109,30 @@ export default class Index extends Component {
128 109
       loading: false,
129 110
     }));
130 111
   };
112
+  // 添加页面滚动监听方法
113
+  onPageScroll = (e) => {
114
+    const { isTabFixed } = this.state;
115
+    // 获取 product-list-box 到顶部的距离
116
+    const query = Taro.createSelectorQuery();
117
+    query
118
+      .select(".product-list-box")
119
+      .boundingClientRect((rect) => {
120
+        if (rect) {
121
+          // 当元素顶部接触到屏幕顶部时切换状态
122
+          const shouldFix = rect.top <= 0;
123
+          if (shouldFix !== isTabFixed) {
124
+            this.setState({ isTabFixed: shouldFix });
125
+          }
126
+        }
127
+      })
128
+      .exec();
129
+  };
131 130
   // 配置分享内容
132 131
   onShareAppMessage() {
133 132
     return getShareContent();
134 133
   }
135 134
   render() {
136
-    const { homeData, productList, loading } = this.state;
135
+    const { homeData, productList, loading, isTabFixed } = this.state;
137 136
     return (
138 137
       <View className="index">
139 138
         <View
@@ -154,21 +153,6 @@ export default class Index extends Component {
154 153
           >
155 154
             <SearchBar value="" disabled={true} placeholder="点击搜索商品" />
156 155
           </View>
157
-          {/* tab分类 */}
158
-          <View className="tabs-list">
159
-            {homeData.tags && (
160
-              <AtTabs
161
-                current={this.state.current}
162
-                scroll
163
-                tabList={homeData.tags}
164
-                onClick={this.handleClick.bind(this)}
165
-              />
166
-            )}
167
-
168
-            <View className="tab-more">
169
-              <Image className="tab-more-img" />
170
-            </View>
171
-          </View>
172 156
           {/* 轮播图 */}
173 157
           <View className="banner-wrap">
174 158
             <Swiper
@@ -208,7 +192,29 @@ export default class Index extends Component {
208 192
         {/* 邀请人推荐 */}
209 193
         {/* <RecommendList /> */}
210 194
         {/* 商品列表 */}
211
-        <View className="product-list-wrap">
195
+        <View className="product-list-box">
196
+          {/* 修改 tab 分类样式 */}
197
+          <View
198
+            style={{
199
+              height: isTabFixed
200
+                ? Taro.navigationBarHeight + 80 + "px"
201
+                : "22px",
202
+            }}
203
+            className={`tabs-list ${isTabFixed ? "fixed" : ""}`}
204
+          >
205
+            {homeData.tags && (
206
+              <AtTabs
207
+                current={this.state.current}
208
+                scroll
209
+                tabList={homeData.tags}
210
+                onClick={this.handleClick.bind(this)}
211
+              />
212
+            )}
213
+
214
+            {/* <View className="tab-more">
215
+              <Image className="tab-more-img" />
216
+            </View> */}
217
+          </View>
212 218
           <ProductList
213 219
             productList={productList}
214 220
             loading={loading}

+ 93 - 72
src/pages/index/index.less

@@ -24,6 +24,8 @@
24 24
       width: 100%;
25 25
       display: flex;
26 26
       justify-content: center;
27
+      position: relative;
28
+      z-index: 1;
27 29
 
28 30
       .header-img {
29 31
         width: 100px;
@@ -32,78 +34,9 @@
32 34
       }
33 35
     }
34 36
 
35
-
36
-    .tabs-list {
37
-      box-sizing: border-box;
38
-      padding-left: 34px;
39
-      margin-top: 24px;
40
-      display: flex;
41
-      height: 40px;
42
-      overflow: hidden;
43
-      .tab-more {
44
-        width: 90px;
45
-        display: flex;
46
-        align-items: center;
47
-        padding: 0 22px 0 26px;
48
-        box-sizing: border-box;
49
-
50
-        .tab-more-img {
51
-          width: 28px;
52
-          height: 28px;
53
-        }
54
-      }
55
-
56
-      .at-tabs__header {
57
-        background-color: transparent;
58
-        height: 100%;
59
-        text-align: left;
60
-      }
61
-      .at-tabs__header::-webkit-scrollbar {
62
-        display: none; /* 隐藏滚动条 */
63
-      }
64
-      scroll-view ::-webkit-scrollbar {
65
-        appearance: none;
66
-        color: transparent;
67
-        display: none;
68
-        width: 0;
69
-        height: 0;
70
-      }
71
-      .at-tabs__item {
72
-        color: #000;
73
-        font-size: 26px;
74
-        padding: 0;
75
-        min-width: auto;
76
-        width: auto;
77
-        margin-right: 34px;
78
-        padding-bottom: 2px;
79
-        height: 100%;
80
-
81
-        &--active {
82
-          color: #000;
83
-          font-size: 28px;
84
-          font-weight: bold;
85
-        }
86
-
87
-        &:last-child {
88
-          margin-right: 0;
89
-        }
90
-      }
91
-
92
-      .at-tabs__item-underline {
93
-        background-color: #000;
94
-        height: 4px;
95
-        border-radius: 2px;
96
-        bottom: 0;
97
-      }
98
-
99
-      .at-tabs__underline {
100
-        width: auto;
101
-      }
102
-    }
103
-
104 37
     // 轮播图
105 38
     .banner-wrap {
106
-      margin-top: 18px;
39
+      margin-top: 24px;
107 40
 
108 41
       .banner-swiper {
109 42
         height: 350px;
@@ -138,9 +71,97 @@
138 71
       }
139 72
     }
140 73
   }
74
+  // tab分类
75
+  .tabs-list {
76
+    box-sizing: border-box;
77
+    padding-left: 34px;
78
+    display: flex;
79
+    overflow: hidden;
80
+    width: 100%;
81
+    background-color: #fff;
82
+    height: 44px;
83
+    &.fixed {
84
+      position: fixed;
85
+      top: 0;
86
+      left: 0;
87
+      z-index: 100;
88
+      height: 180px;
89
+      display: flex;
90
+      align-items: flex-end;
91
+      padding-bottom: 20px;
92
+      .at-tabs{
93
+        height: 40px;
94
+      }
95
+    }
96
+    .tab-more {
97
+      width: 90px;
98
+      display: flex;
99
+      align-items: center;
100
+      padding: 0 22px 0 26px;
101
+      box-sizing: border-box;
102
+
103
+      .tab-more-img {
104
+        width: 28px;
105
+        height: 28px;
106
+      }
107
+    }
108
+
109
+    .at-tabs__header {
110
+      background-color: transparent;
111
+      height: 100%;
112
+      text-align: left;
113
+    }
114
+    .at-tabs__header::-webkit-scrollbar {
115
+      display: none; /* 隐藏滚动条 */
116
+    }
117
+    scroll-view ::-webkit-scrollbar {
118
+      appearance: none;
119
+      color: transparent;
120
+      display: none;
121
+      width: 0;
122
+      height: 0;
123
+    }
124
+    .at-tabs__item {
125
+      color: #999999;
126
+      font-size: 26px;
127
+      padding: 0;
128
+      min-width: auto;
129
+      width: auto;
130
+      margin-right: 34px;
131
+      padding-bottom: 2px;
132
+      height: 100%;
133
+
134
+      &--active {
135
+        color: #FF8119;
136
+        font-size: 28px;
137
+        font-weight: bold;
138
+      }
139
+
140
+      &:last-child {
141
+        margin-right: 0;
142
+      }
143
+    }
144
+
145
+    .at-tabs__item-underline {
146
+      background-color: #FF8119;
147
+      height: 4px;
148
+      border-radius: 2px;
149
+      bottom: 0;
150
+    }
151
+
152
+    .at-tabs__underline {
153
+      width: auto;
154
+    }
155
+  }
141 156
   // 商品列表
142
-  .product-list-wrap {
143
-    margin-top: 0;
157
+  .product-list-box {
158
+    padding-top: 24px;
159
+    margin: 21px 16px 0;
160
+    background: #FFFFFF;
161
+    border-radius: 16px;
162
+    .product-list-wrap{
163
+      margin-top: 0;
164
+    }
144 165
   }
145 166
   // 添加浮动按钮样式
146 167
   .float-buttons {

+ 78 - 6
src/pages/indexSub/seckillIndex/index.jsx

@@ -7,9 +7,11 @@ import {
7 7
   getRecommendProductList,
8 8
   getShareJump,
9 9
   bindShareJump,
10
+  getFishMarketTags,
10 11
 } from "../../../service";
11 12
 import { handleLog } from "../../../common/track";
12 13
 import { getShareContent } from "../../../common/share";
14
+import { AtTabs } from "taro-ui";
13 15
 export default class Index extends Component {
14 16
   state = {
15 17
     title: "", // 页面标题
@@ -25,10 +27,22 @@ export default class Index extends Component {
25 27
     shareUserId: "", // 分享用户id
26 28
     img: "", // 图片
27 29
     isShowBack: false, // 是否显示返回
30
+    current: 0, // 当前选中的tab索引
31
+    tabList: [], // 标签列表
32
+    isTabFixed: false, // 添加新的状态来控制tab是否固定
28 33
   };
29 34
   componentDidMount() {
30
-    const { isDirect, isBanner, isShare, shareUserId, title, id, shareJump,shareType,isShowBack } =
31
-      Taro.getCurrentInstance().router.params || "";
35
+    const {
36
+      isDirect,
37
+      isBanner,
38
+      isShare,
39
+      shareUserId,
40
+      title,
41
+      id,
42
+      shareJump,
43
+      shareType,
44
+      isShowBack,
45
+    } = Taro.getCurrentInstance().router.params || "";
32 46
     let session_key = Taro.getStorageSync("session_key");
33 47
     this.setState(
34 48
       {
@@ -46,7 +60,7 @@ export default class Index extends Component {
46 60
           title: this.state.title || "鱼市",
47 61
         });
48 62
         if (isShare) {
49
-          Taro.hideHomeButton();//隐藏返回首页
63
+          Taro.hideHomeButton(); //隐藏返回首页
50 64
         }
51 65
         handleLog({
52 66
           event_type: isDirect
@@ -66,7 +80,7 @@ export default class Index extends Component {
66 80
           goods_id: 0,
67 81
           shareUserId: this.state.shareUserId,
68 82
         });
69
-        this.getRecommendProductList();
83
+        this.getFishMarketTags(); //获取标签
70 84
         // 获取分享跳转标识
71 85
         shareJump &&
72 86
           Taro.setStorage({
@@ -84,8 +98,18 @@ export default class Index extends Component {
84 98
       }
85 99
     );
86 100
   }
101
+  // 获取标签
102
+  getFishMarketTags = async () => {
103
+    let res = await getFishMarketTags();
104
+    res = res.map((item, index) => ({
105
+      title: item.name,
106
+    }));
107
+    this.setState({ tabList: res }, () => {
108
+      this.getRecommendProductList(); //获取商品
109
+    });
110
+  };
87 111
   // 获取推荐商品列表
88
-  getRecommendProductList = async () => {
112
+  getRecommendProductList = async (isRefresh = false) => {
89 113
     const { page } = this.state;
90 114
     this.setState({ loading: true });
91 115
 
@@ -93,10 +117,13 @@ export default class Index extends Component {
93 117
       tag_id: this.state.id,
94 118
       page,
95 119
       page_size: 10,
120
+      tag_name: this.state.tabList[this.state.current].title,
96 121
     });
97 122
 
98 123
     this.setState((prevState) => ({
99
-      productList: [...prevState.productList, ...res.goods_list],
124
+      productList: isRefresh
125
+        ? res.goods_list
126
+        : [...prevState.productList, ...res.goods_list],
100 127
       totalPages: res.total_pages,
101 128
       loading: false,
102 129
       isNoMore: res.total_pages <= page,
@@ -113,6 +140,41 @@ export default class Index extends Component {
113 140
     Taro.removeStorageSync("shareJump");
114 141
     Taro.removeStorageSync("shareType");
115 142
   };
143
+  // 点击标签页
144
+  handleClick(value) {
145
+    // 跳转到顶部
146
+    Taro.pageScrollTo({
147
+      scrollTop: 0,
148
+      duration: 300,
149
+    });
150
+    this.setState(
151
+      {
152
+        current: value,
153
+        page: 1,
154
+      },
155
+      () => {
156
+        this.getRecommendProductList(true);
157
+      }
158
+    );
159
+  }
160
+  // 添加页面滚动监听方法
161
+  onPageScroll = (e) => {
162
+    const { isTabFixed } = this.state;
163
+    // 获取 product-list-box 到顶部的距离
164
+    const query = Taro.createSelectorQuery();
165
+    query
166
+      .select(".product-list")
167
+      .boundingClientRect((rect) => {
168
+        if (rect) {
169
+          // 当元素顶部接触到屏幕顶部时切换状态
170
+          const shouldFix = rect.top <= 0;
171
+          if (shouldFix !== isTabFixed) {
172
+            this.setState({ isTabFixed: shouldFix });
173
+          }
174
+        }
175
+      })
176
+      .exec();
177
+  };
116 178
   // 配置分享内容
117 179
   onShareAppMessage(res) {
118 180
     let shareUserId = "";
@@ -145,11 +207,21 @@ export default class Index extends Component {
145 207
     }
146 208
   };
147 209
   render() {
210
+    const { isTabFixed } = this.state;
148 211
     return (
149 212
       <View className="index">
150 213
         <Image className="seckill" src={this.state.img} mode="widthFix" />
151 214
         {/* 商品列表 */}
152 215
         <View className="product-list">
216
+          {/* tabs切换 */}
217
+          <View className={`tabs ${isTabFixed ? "fixed" : ""}`}>
218
+            <AtTabs
219
+              scroll
220
+              current={this.state.current}
221
+              tabList={this.state.tabList}
222
+              onClick={this.handleClick.bind(this)}
223
+            ></AtTabs>
224
+          </View>
153 225
           <ProductList
154 226
             isSeckill={true}
155 227
             productList={this.state.productList}

+ 51 - 3
src/pages/indexSub/seckillIndex/index.less

@@ -1,13 +1,61 @@
1
-.index{
1
+.index {
2 2
     width: 100%;
3 3
     padding-bottom: 40px;
4 4
     box-sizing: border-box;
5 5
     background-color: #f9f9f9;
6
-    .seckill{
6
+
7
+    .seckill {
7 8
         width: 100%;
8 9
         height: 300px;
9 10
     }
10
-    .product-list{
11
+    // 顶部固定
12
+    .tabs {
13
+        width: 100%;
14
+        background: #fff;
15
+        z-index: 100;
16
+        
17
+        &.fixed {
18
+            position: fixed;
19
+            top: 0;
20
+            left: 0;
21
+        }
22
+
23
+        .at-tabs__item {
24
+            color: #787878;
25
+        }
26
+
27
+        .at-tabs__item--active {
28
+            color: #000000 !important;
29
+        }
30
+
31
+        .at-tabs__item-underline {
32
+            background-color: #f3e801;
33
+        }
34
+
35
+    }
36
+
37
+    scroll-view ::-webkit-scrollbar {
38
+        appearance: none;
39
+        color: transparent;
40
+        display: none;
41
+        width: 0;
42
+        height: 0;
43
+    }
44
+
45
+    .product-list {
46
+        background-color: #fff;
47
+        margin:0 16px;
11 48
         margin-top: -196px;
49
+        border-radius: 16px;
50
+        overflow: hidden;
51
+        z-index: 100;
52
+        position: relative;
53
+        .product-list-wrap{
54
+            margin: 0;
55
+        }
12 56
     }
57
+}
58
+
59
+.tabs-placeholder {
60
+    height: 80px; // 设置为tabs的实际高度
13 61
 }

+ 7 - 1
src/pages/memberSub/productClassify/index.jsx

@@ -21,6 +21,7 @@ export default class Index extends Component {
21 21
     tabList: [], // 所有闲鱼tags
22 22
     value: "", // 搜索
23 23
   };
24
+  // 点击标签页
24 25
   handleClick(value) {
25 26
     this.setState(
26 27
       {
@@ -69,6 +70,7 @@ export default class Index extends Component {
69 70
     this.setState(
70 71
       {
71 72
         tabList: res,
73
+        productList: [],
72 74
       },
73 75
       () => {
74 76
         this.getBrowseShopProductList(true);
@@ -81,7 +83,11 @@ export default class Index extends Component {
81 83
   };
82 84
   // 搜索
83 85
   handleSearch = () => {
84
-    this.getBrowseShopProductList(true);
86
+    this.setState({
87
+      page: 1,
88
+    },()=>{
89
+      this.getBrowseShopProductList(true);
90
+    })
85 91
   };
86 92
   // 添加商品
87 93
   onAddProduct = (productId, index) => {

+ 7 - 0
src/service/index.js

@@ -50,6 +50,13 @@ export const getAllTags = data =>
50 50
     method: 'POST',
51 51
     data,
52 52
   })
53
+  // 获取鱼市tags
54
+  export const getFishMarketTags = data =>
55
+  Request({
56
+    url: '/api/get_yushi_tags',
57
+    method: 'POST',
58
+    data,
59
+  })
53 60
 // 获取搜索商品列表
54 61
 export const getSearchProductList = data =>
55 62
   Request({