index.jsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. import { Component } from "react";
  2. import { View, Text, Swiper, SwiperItem, Image } from "@tarojs/components";
  3. import { AtIcon } from "taro-ui";
  4. import {
  5. getProductDetail,
  6. getProductLikeList,
  7. getProductPromotion,
  8. getShareJump,
  9. bindShareJump,
  10. addLog,
  11. } from "../../../service";
  12. import { formatDate } from "../../../common/time";
  13. import { isDebounce } from "../../../common/debounce";
  14. import "./index.less";
  15. import Taro from "@tarojs/taro";
  16. import productDetailIcon from "../../../images/productDetail/productDetailIcon.png";
  17. import like from "../../../images/productDetail/like.png";
  18. import home from "../../../images/nav/home.png";
  19. import selfBuy from "../../../images/productDetail/selfBuy.png";
  20. import share from "../../../images/productDetail/share.png";
  21. import ProductCard from "../../../components/ProductCard"; //产品卡片
  22. import Modal from "../../../components/Modal"; //弹窗
  23. import ShareModal from "../../../components/shareModal"; //分享弹窗
  24. import SignModal from "../../../components/signModal"; //签约弹窗
  25. export default class Index extends Component {
  26. state = {
  27. id: "", //商品id
  28. isShare: false, //是否是分享
  29. isOpened: "", //是否打开弹窗
  30. productDetail: [], //商品详情
  31. productLikeList: [], //推荐商品列表
  32. productPromotion: [], //商品推广转链
  33. isHighCommission: false, //是否是高佣金页面
  34. isSeckill: false, //是否是秒杀页面
  35. shareJump: "", //分享跳转标识
  36. shareTitle: "", //分享标题
  37. shareUserId: "", //分享用户id
  38. };
  39. // 获取产品详情的方法
  40. fetchProductDetails = async (id) => {
  41. const res = await getProductDetail({
  42. goods_id: id,
  43. });
  44. this.setState({
  45. productDetail: res,
  46. });
  47. };
  48. // 获取猜你喜欢列表
  49. getProductLikeList = async () => {
  50. const res = await getProductLikeList();
  51. this.setState({
  52. productLikeList: res,
  53. });
  54. };
  55. // 获取商品推广转链
  56. getProductPromotion = async () => {
  57. const res = await getProductPromotion({
  58. goods_id: [this.state.id],
  59. item_id: [this.state.productDetail.item_id],
  60. });
  61. this.setState({
  62. productPromotion:
  63. res.alibaba_idle_affiliate_general_link_convert_response.result.result,
  64. });
  65. };
  66. componentDidMount() {
  67. // 隐藏右上角分享按钮
  68. Taro.hideShareMenu({
  69. menus: ["shareAppMessage", "shareTimeline"],
  70. });
  71. const { id, isShare, isHighCommission, isSeckill, shareJump, shareUserId } =
  72. Taro.getCurrentInstance().router.params;
  73. let session_key = Taro.getStorageSync("session_key");
  74. let userInfo = Taro.getStorageSync("userInfo");
  75. let isShowSign = Taro.getStorageSync("isShowSign");
  76. this.setState(
  77. {
  78. id,
  79. isShare,
  80. isHighCommission: isHighCommission === "true",
  81. isSeckill: isSeckill === "true",
  82. shareUserId: shareUserId,
  83. },
  84. () => {
  85. // 获取分享跳转标识
  86. shareJump &&
  87. Taro.setStorage({
  88. key: "shareJump",
  89. data: shareJump,
  90. });
  91. this.fetchProductDetails(id); //获取产品详情
  92. this.getProductLikeList(); //获取猜你喜欢列表
  93. if (session_key && shareJump) {
  94. this.bindShareJump(); //绑定分享跳转标识
  95. }
  96. if (this.state.isHighCommission || this.state.isSeckill) {
  97. this.handleLog("direct_to_product"); //埋点
  98. }
  99. }
  100. );
  101. // 判断是否显示签约弹窗
  102. if (session_key && isShowSign!==false && userInfo && userInfo.user_identity == 0) {
  103. this.setState({
  104. isOpened: "sign",
  105. });
  106. }
  107. }
  108. // 复制商品编号
  109. handleCopy = (text) => {
  110. Taro.setClipboardData({
  111. data: text,
  112. success: () => {
  113. Taro.showToast({
  114. title: "复制成功",
  115. icon: "success",
  116. });
  117. },
  118. });
  119. };
  120. // 添加跳转首页方法
  121. handleToHome = () => {
  122. Taro.switchTab({
  123. url: "/pages/index/index",
  124. });
  125. };
  126. // 立即购买
  127. handleBuy = async () => {
  128. if (!this.state.productPromotion.short_tpwd) {
  129. await this.getProductPromotion();
  130. }
  131. this.setState({
  132. isOpened: "self",
  133. });
  134. };
  135. // 埋点
  136. handleLog = (event_type) => {
  137. if (!isDebounce(500)) return; // 如果在300ms内重复触发,直接返回
  138. if (this.state.isHighCommission || this.state.isSeckill) {
  139. const dayid = formatDate(new Date(), "YYYY-MM-DD");
  140. const event_type_title =
  141. event_type == "share_product_link"
  142. ? "点击分享赚"
  143. : event_type == "direct_to_product"
  144. ? "进入商品详情页"
  145. : "进入商品详情页";
  146. let userId = "";
  147. if (Taro.getStorageSync("loginInfo")) {
  148. userId = Taro.getStorageSync("loginInfo").id;
  149. }
  150. // 构建ext对象,包含share_id
  151. let ext = "";
  152. if (this.state.shareUserId) {
  153. ext = JSON.stringify({
  154. share_users_id: this.state.shareUserId,
  155. });
  156. }
  157. addLog({
  158. users_id: userId || 0,
  159. goods_id: Number(this.state.id),
  160. event_type_title,
  161. event_type,
  162. dayid,
  163. ext,
  164. });
  165. }
  166. };
  167. // 分享
  168. openSharePopup = async () => {
  169. const res = await getShareJump({
  170. share_type: 1,
  171. share_id: this.state.id,
  172. });
  173. this.setState({
  174. shareJump: res.share_unique_value,
  175. isOpened: "share",
  176. });
  177. this.handleLog("share_product_link"); //埋点
  178. };
  179. // 绑定分享跳转标识
  180. bindShareJump = async () => {
  181. let shareJump = Taro.getStorageSync("shareJump");
  182. await bindShareJump({
  183. share_type: 1,
  184. share_unique_value: shareJump,
  185. });
  186. Taro.removeStorageSync("shareJump");
  187. };
  188. // 设置分享标题
  189. handleShareTitleChange = (newTitle) => {
  190. this.setState({
  191. shareTitle: newTitle,
  192. });
  193. };
  194. // 配置分享内容
  195. onShareAppMessage() {
  196. return {
  197. title: this.state.shareTitle || this.state.productDetail.item_title,
  198. path: `/pages/indexSub/productDetail/index?id=${this.state.id}&&isShare=true&&isHighCommission=${this.state.isHighCommission}&&isSeckill=${this.state.isSeckill}&&shareJump=${this.state.shareJump}`,
  199. imageUrl: this.state.productDetail.images[0].img,
  200. };
  201. }
  202. // 添加返回方法
  203. handleBack = () => {
  204. const pages = Taro.getCurrentPages();
  205. if (pages.length > 1) {
  206. Taro.navigateBack();
  207. } else {
  208. Taro.switchTab({
  209. url: "/pages/index/index",
  210. });
  211. }
  212. };
  213. render() {
  214. const { productDetail } = this.state;
  215. return (
  216. <View
  217. className="index"
  218. style={{ paddingTop: Taro.navigationBarHeight + "px" }}
  219. >
  220. {!this.state.isShare && (
  221. <View className="back-btn" onClick={this.handleBack}>
  222. <AtIcon value="chevron-left" size="24" color="#999999"></AtIcon>
  223. </View>
  224. )}
  225. {/* 轮播图 */}
  226. <Swiper className="swiper" autoplay circular>
  227. {productDetail.images &&
  228. productDetail.images.map((imageObj, index) => (
  229. <SwiperItem key={index}>
  230. <Image
  231. className="swiper-img"
  232. src={imageObj.img}
  233. mode="aspectFill"
  234. />
  235. </SwiperItem>
  236. ))}
  237. </Swiper>
  238. {/* 商品详情模块 */}
  239. <View className="product-info">
  240. {/* 商品名称 */}
  241. <Text className="product-name">
  242. <Text className="self-tag">
  243. {this.state.isHighCommission
  244. ? "高佣专项"
  245. : this.state.isSeckill
  246. ? "鱼市秒杀"
  247. : "自营"}
  248. </Text>
  249. {productDetail.item_title}
  250. </Text>
  251. {/* 价格和标签行 */}
  252. <View className="price-tag-row">
  253. {/* 价格区域 */}
  254. <View className="price-box">
  255. <Text className="current-price">
  256. <Text className="currency">¥</Text>
  257. {productDetail.reserve_price}
  258. </Text>
  259. {productDetail.original_price != "0.00" && (
  260. <Text className="original-price">
  261. ¥{productDetail.original_price}
  262. </Text>
  263. )}
  264. </View>
  265. {/* 标签区域 */}
  266. <View className="tag-box">
  267. <Text className="tag">
  268. 分享赚¥{productDetail.estimated_commission}
  269. </Text>
  270. </View>
  271. </View>
  272. {/* 分割线 */}
  273. <View className="divider" />
  274. {/* 商品编号行 */}
  275. <View className="product-number-row">
  276. <Text className="number-label">
  277. 商品编号:{productDetail.goods_number}
  278. </Text>
  279. <Text
  280. className="copy-btn"
  281. onClick={() => this.handleCopy("123456")}
  282. >
  283. 复制
  284. </Text>
  285. </View>
  286. </View>
  287. {/* 商品标签模块 */}
  288. <View className="product-tag-row">
  289. <View className="tag-item">
  290. <Image src={productDetailIcon} mode="aspectFit" />
  291. <Text className="tag-text">渔市商品</Text>
  292. </View>
  293. <View className="tag-item">
  294. <Image src={productDetailIcon} mode="aspectFit" />
  295. <Text className="tag-text">品质保证</Text>
  296. </View>
  297. <View className="tag-item">
  298. <Image src={productDetailIcon} mode="aspectFit" />
  299. <Text className="tag-text">无忧售后</Text>
  300. </View>
  301. </View>
  302. {/* 猜你喜欢 */}
  303. <View className="guess-you-like">
  304. <Image src={like} mode="aspectFit" />
  305. <Text className="title">猜你喜欢</Text>
  306. </View>
  307. {/* 猜你喜欢产品列表 */}
  308. <View className="product-card-list">
  309. {this.state.productLikeList.map((product) => (
  310. <ProductCard key={product.id} product={product} />
  311. ))}
  312. </View>
  313. {/* 底部购买模块 */}
  314. <View className="bottom-buy">
  315. <View onClick={this.handleToHome} className="bottom-buy-left">
  316. <Image src={home} mode="aspectFit" />
  317. <Text className="bottom-buy-text">首页</Text>
  318. </View>
  319. <View className="bottom-buy-right">
  320. {!this.state.isShare ? (
  321. <>
  322. <View
  323. onClick={this.openSharePopup}
  324. className="bottom-buy-right-self"
  325. >
  326. <Image src={share} mode="aspectFit" />
  327. <Text className="bottom-buy-text">分享赚</Text>
  328. </View>
  329. <View
  330. onClick={this.handleBuy}
  331. className="bottom-buy-right-share"
  332. >
  333. <Image src={selfBuy} mode="aspectFit" />
  334. <Text className="bottom-buy-text">自购省</Text>
  335. </View>
  336. </>
  337. ) : (
  338. <View onClick={this.handleBuy} className="bottom-buy-right-btn">
  339. <Text className="bottom-buy-text">立即购买</Text>
  340. </View>
  341. )}
  342. </View>
  343. </View>
  344. {/* 自购弹窗 */}
  345. <Modal
  346. title="咸鱼口令已复制"
  347. isOpened={this.state.isOpened == "self"}
  348. productPromotion={this.state.productPromotion}
  349. linkText={this.state.productPromotion.short_tpwd}
  350. id={this.state.id}
  351. shareUserId={this.state.shareUserId}
  352. isHighCommission={this.state.isHighCommission}
  353. isSeckill={this.state.isSeckill}
  354. />
  355. {/* 分享弹窗 */}
  356. {this.state.isOpened == "share" && (
  357. <ShareModal
  358. onClose={() => {
  359. this.setState({
  360. isOpened: "",
  361. shareTitle: productDetail.item_title,
  362. });
  363. }}
  364. isOpened={this.state.isOpened == "share"}
  365. product={this.state.productDetail}
  366. onShareTitleChange={this.handleShareTitleChange}
  367. />
  368. )}
  369. {/* 签约弹窗 */}
  370. <SignModal isOpened={this.state.isOpened == "sign"} onClose={() => {
  371. this.setState({
  372. isOpened: "",
  373. });
  374. }}/>
  375. </View>
  376. );
  377. }
  378. }