index.jsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import Taro from "@tarojs/taro"; // 导入 Taro
  2. import { Component } from "react";
  3. import {
  4. View,
  5. Image,
  6. Swiper,
  7. SwiperItem,
  8. Text,
  9. Button,
  10. } from "@tarojs/components";
  11. import { AtTabs } from "taro-ui";
  12. import { getHomeData, getProductList } from "../../service";
  13. import { getShareContent } from "../../common/share";
  14. import "./index.less";
  15. import Skeleton from "../../components/skeleton"; //骨架屏
  16. import SearchBar from "../../components/index/SearchBar"; //搜索框
  17. import CategoryList from "../../components/index/CategoryList"; //分类列表
  18. import OperationArea from "../../components/index/OperationArea"; //运营区域
  19. import RecommendList from "../../components/index/RecommendList"; //邀请人推荐
  20. import ProductList from "../../components/index/ProductList"; //商品列表
  21. import myStoreIcon from "../../images/index/myStore.png";
  22. import backTopIcon from "../../images/index/back-top.png";
  23. export default class Index extends Component {
  24. state = {
  25. current: 0, // 添加当前选中的tab索引
  26. homeData: {}, // 首页数据
  27. bannerList: [],
  28. productList: [], // 添加商品列表
  29. page: 1, // 添加页码
  30. totalPages: 1, // 添加总页数
  31. loading: false, // 添加加载状态
  32. };
  33. // 获取首页数据
  34. getHomeData = async () => {
  35. const res = await getHomeData();
  36. res.tags = res.tags.map((item, index) => ({
  37. title: item.name,
  38. }));
  39. this.setState({ homeData: res }, () => {
  40. this.getProductList(true);
  41. });
  42. };
  43. // 修改 tab 切换处理函数
  44. handleClick(value) {
  45. this.setState(
  46. {
  47. current: value,
  48. page: 1,
  49. },
  50. () => {
  51. // 跳转到列表顶部
  52. Taro.createSelectorQuery()
  53. .select(".product-list-wrap")
  54. .boundingClientRect()
  55. .exec((res) => {
  56. if (res[0]) {
  57. const top = res[0].top;
  58. Taro.pageScrollTo({
  59. scrollTop: top - 40,
  60. duration: 300,
  61. });
  62. this.getProductList(true);
  63. } else {
  64. console.warn("未找到 .product-list-wrap 元素");
  65. }
  66. });
  67. }
  68. );
  69. }
  70. componentDidShow() {
  71. this.getHomeData(); //获取首页数据
  72. }
  73. // 添加回到顶部方法
  74. handleBackTop = () => {
  75. Taro.pageScrollTo({
  76. scrollTop: 0,
  77. duration: 300,
  78. });
  79. };
  80. // 页面上拉触底
  81. onReachBottom = () => {
  82. const { page, totalPages, loading } = this.state;
  83. if (page < totalPages && !loading) {
  84. this.setState(
  85. (prevState) => ({ page: prevState.page + 1 }),
  86. () => this.getProductList()
  87. );
  88. }
  89. };
  90. // 获取商品列表
  91. getProductList = async (isRefresh) => {
  92. const { page } = this.state;
  93. this.setState({ loading: true });
  94. const res = await getProductList({
  95. tag_name: this.state.homeData.tags[this.state.current].title,
  96. page,
  97. page_size: 10,
  98. });
  99. this.setState((prevState) => ({
  100. productList: isRefresh
  101. ? res.goods_list
  102. : [...prevState.productList, ...res.goods_list],
  103. totalPages: res.total_pages,
  104. loading: false,
  105. }));
  106. };
  107. // 配置分享内容
  108. onShareAppMessage() {
  109. return getShareContent();
  110. }
  111. render() {
  112. const { homeData, productList, loading } = this.state;
  113. return (
  114. <View className="index">
  115. <View
  116. className="header"
  117. style={{ paddingTop: Taro.navigationBarHeight + "px" }}
  118. >
  119. <View className="header-content">
  120. <Image
  121. mode="heightFix"
  122. className="header-img"
  123. src="https://video-img.fyshark.com/1731495433480WechatIMG674.jpg"
  124. />
  125. </View>
  126. {/* 搜索框包裹盒子 */}
  127. <View
  128. className="search-bar-container"
  129. onClick={() => Taro.navigateTo({ url: "/pages/search/index" })}
  130. >
  131. <SearchBar value="" disabled={true} placeholder="点击搜索商品" />
  132. </View>
  133. {/* tab分类 */}
  134. <View className="tabs-list">
  135. {homeData.tags && (
  136. <AtTabs
  137. current={this.state.current}
  138. scroll
  139. tabList={homeData.tags}
  140. onClick={this.handleClick.bind(this)}
  141. />
  142. )}
  143. <View className="tab-more">
  144. <Image className="tab-more-img" />
  145. </View>
  146. </View>
  147. {/* 轮播图 */}
  148. <View className="banner-wrap">
  149. <Swiper
  150. className="banner-swiper"
  151. circular
  152. autoplay
  153. indicatorDots
  154. indicatorColor="#e8e8e8"
  155. indicatorActiveColor="#ffffff"
  156. >
  157. {homeData.banner &&
  158. homeData.banner.map((item) => (
  159. <SwiperItem className="banner-item" key={item.id}>
  160. <Image
  161. className="banner-img"
  162. src={item.img}
  163. mode="aspectFill"
  164. />
  165. </SwiperItem>
  166. ))}
  167. </Swiper>
  168. </View>
  169. </View>
  170. {/* 骨架屏 */}
  171. <Skeleton
  172. isSkeletonShow={!homeData.banner && !productList.length > 0}
  173. />
  174. {/* 分类列表组件 */}
  175. {homeData.icon && <CategoryList categoryList={homeData.icon} />}
  176. {/* 运营区域 */}
  177. {homeData.recommend && <OperationArea recommend={homeData.recommend} />}
  178. {/* 邀请人推荐 */}
  179. {/* <RecommendList /> */}
  180. {/* 商品列表 */}
  181. <View className="product-list-wrap">
  182. <ProductList
  183. productList={productList}
  184. loading={loading}
  185. onShareProduct={this.handleShare}
  186. />
  187. </View>
  188. {/* 添加浮动按钮 */}
  189. <View className="float-buttons">
  190. <View
  191. className="float-btn"
  192. onClick={() =>
  193. Taro.navigateTo({
  194. url: `/pages/memberSub/storeManagement/index?isManager=${true}`,
  195. })
  196. }
  197. >
  198. <Image className="my-shop-bg" src={myStoreIcon} mode="aspectFit" />
  199. <Text>我的{"\n"}小店</Text>
  200. </View>
  201. <View className="float-btn" onClick={this.handleBackTop}>
  202. <Image className="back-top" src={backTopIcon} mode="aspectFit" />
  203. </View>
  204. </View>
  205. {/* 分享弹窗 */}
  206. </View>
  207. );
  208. }
  209. }