index.jsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import React, {
  2. useState,
  3. useEffect,
  4. forwardRef,
  5. useImperativeHandle,
  6. } from "react";
  7. import { View, Text, Image, Button } from "@tarojs/components";
  8. import { AtCheckbox, AtActivityIndicator } from "taro-ui";
  9. import { setShareContent } from "../../../common/share";
  10. import Taro from "@tarojs/taro";
  11. import "./index.less";
  12. import joinStoreBg from "../../../images/index/jionStore.png";
  13. import joinStoreAc from "../../../images/index/joinStoreAc.png";
  14. import saveMoneyBg from "../../../images/index/save-money.png";
  15. import shareEarnBg from "../../../images/index/share-earn.png";
  16. import seckillIcon from "../../../images/seckill/seckillIcon.png";
  17. const ProductList = forwardRef((props, ref) => {
  18. const {
  19. productList, // 商品列表数据
  20. loading, // 加载状态
  21. isSeckill, // 是否秒杀页面使用
  22. isManagement, // 是否管理页面使用
  23. isManagementStatus, // 是否管理状态
  24. isProductClassify, // 是否分类页面使用
  25. isSelectAll, // 是否全选
  26. onAddProduct, // 添加商品方法
  27. onDeleteProductSelect, // 删除商品选中id数组
  28. isNoMore, // 是否没有更多
  29. onShareProduct, // 分享商品方法
  30. } = props;
  31. const [selectedProducts, setSelectedProducts] = useState([]); // 商品选择状态
  32. // 监听选中状态变化
  33. useEffect(() => {
  34. // 每当 selectedProducts 变化时,调用父组件的回调
  35. onDeleteProductSelect && onDeleteProductSelect(selectedProducts);
  36. }, [selectedProducts]);
  37. // 监听 isSelectAll 的变化
  38. useEffect(() => {
  39. if (isSelectAll) {
  40. // 如果 isSelectAll 为 true,选中所有商品
  41. setSelectedProducts(productList.map((product) => product.id));
  42. } else {
  43. // 如果 isSelectAll 为 false,取消所有选中
  44. setSelectedProducts([]);
  45. }
  46. }, [isSelectAll]);
  47. // 定义 clearSelectedItems 方法
  48. useImperativeHandle(ref, () => ({
  49. clearSelectedItems: () => {
  50. setSelectedProducts([]);
  51. },
  52. }));
  53. // 跳转产品详情
  54. const toDetail = (id) => {
  55. if (isManagementStatus) {
  56. selectProduct(id);
  57. } else {
  58. Taro.navigateTo({
  59. url: `/pages/indexSub/productDetail/index?id=${id}`,
  60. });
  61. }
  62. };
  63. // 单选
  64. const selectProduct = (productId) => {
  65. setSelectedProducts((prevSelected) => {
  66. const isSelected = prevSelected.includes(productId);
  67. if (isSelected) {
  68. // 如果已经选中,则取消选择
  69. return prevSelected.filter((id) => id !== productId);
  70. } else {
  71. // 如果未选中,则添加到选中列
  72. return [...prevSelected, productId];
  73. }
  74. });
  75. };
  76. // 添加商品
  77. const addProduct = (productId, is_collected, index) => {
  78. // 是否添加到我的商店(is_collected:为true已添加)
  79. if (is_collected) {
  80. return;
  81. } else {
  82. // 调用父组件的方法
  83. onAddProduct && onAddProduct(productId, index);
  84. }
  85. };
  86. // 分享商品
  87. const shareProduct = (product, e) => {
  88. e.stopPropagation(); // 防止事件穿透
  89. props.onShareProduct && props.onShareProduct();
  90. setShareContent({
  91. title: product.item_title,
  92. path: `/pages/indexSub/productDetail/index?id=${product.id}&&isShare=${true}`,
  93. imageUrl: product.image_url,
  94. });
  95. };
  96. return (
  97. <View className="product-list-wrap">
  98. {isSeckill && (
  99. <View className="seckill-icon">
  100. <Image src={seckillIcon} mode="aspectFit" />
  101. <Text>每日疯抢 限时秒杀</Text>
  102. </View>
  103. )}
  104. {productList.map((product, index) => (
  105. <View key={product.id}>
  106. <View onClick={() => toDetail(product.id)} className="product-item">
  107. {isManagement && isManagementStatus && (
  108. <AtCheckbox
  109. options={[{ value: product.id.toString(), label: "" }]} // 确保每个复选框的 options 是独立的
  110. selectedList={selectedProducts.map((id) => id.toString())}
  111. onChange={(selectedList) => selectProduct(product.id)} // 传递当前 product.id
  112. />
  113. )}
  114. <View className="right">
  115. <Image
  116. className="product-img"
  117. src={product.image_url}
  118. mode="aspectFill"
  119. />
  120. <View className="product-info">
  121. <View
  122. className="product-name"
  123. style={{ WebkitBoxOrient: "vertical" }}
  124. >
  125. <Text className="self-tag">
  126. {!isSeckill ? "自营" : "鱼市��杀"}
  127. </Text>
  128. {product.item_title}
  129. </View>
  130. <View className="price-line">
  131. <View className="price-info">
  132. <Text className="symbol">¥</Text>
  133. <Text className="price">{product.reserve_price}</Text>
  134. {product.original_price != "0.00" && (
  135. <Text className="original-price">
  136. ¥{product.original_price}
  137. </Text>
  138. )}
  139. </View>
  140. {isProductClassify && (
  141. <View
  142. onClick={(e) => {
  143. e.stopPropagation();
  144. addProduct(product.id, product.is_collected, index);
  145. }}
  146. className="add-btn"
  147. >
  148. {product.is_collected ? (
  149. <Image
  150. className="join-store-bg"
  151. src={joinStoreBg}
  152. mode="aspectFit"
  153. />
  154. ) : (
  155. <Image
  156. className="join-store-bg"
  157. src={joinStoreAc}
  158. mode="aspectFit"
  159. />
  160. )}
  161. <Text className="btn-text">加入小店</Text>
  162. </View>
  163. )}
  164. </View>
  165. <View className="profit-line">
  166. <View className="save-money">
  167. <Image className="bg" src={saveMoneyBg} mode="aspectFit" />
  168. <View className="content">
  169. <Text className="label">自购省</Text>
  170. <Text className="money">
  171. ¥{product.estimated_commission}
  172. </Text>
  173. </View>
  174. </View>
  175. <View className="share-earn">
  176. <Image className="bg" src={shareEarnBg} mode="aspectFit" />
  177. <View className="content">
  178. <Button
  179. openType="share"
  180. onClick={(e) => shareProduct(product, e)} // 传递事件对象
  181. >
  182. <Text className="label">分享赚</Text>
  183. <Text className="money">
  184. ¥{product.estimated_commission}
  185. </Text>
  186. </Button>
  187. </View>
  188. </View>
  189. </View>
  190. </View>
  191. </View>
  192. </View>
  193. {index !== productList.length - 1 && (
  194. <View className="divider"></View>
  195. )}
  196. </View>
  197. ))}
  198. {loading && (
  199. <View className="loading">
  200. <AtActivityIndicator
  201. content="加载中..."
  202. isOpened={loading}
  203. mode="center"
  204. color="#fdf764"
  205. />
  206. </View>
  207. )}
  208. {isNoMore && <View className="no-more">没有更多了~</View>}
  209. </View>
  210. );
  211. });
  212. ProductList.defaultProps = {
  213. isSeckill: false,
  214. productList: [],
  215. loading: false,
  216. isManagement: false,
  217. isManagementStatus: false,
  218. isProductClassify: false,
  219. isSelectAll: false,
  220. isNoMore: false,
  221. onAddProduct: () => {}, // 添加商品方法
  222. onDeleteProductSelect: () => {}, // 删除商品选中id数组
  223. onShareProduct: () => {}, // 分享商品方法
  224. };
  225. export default ProductList;