猎豆优选小程序

goodsDetail.vue 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <template>
  2. <view class="page-wrap u-skeleton">
  3. <!-- 顶部按钮 -->
  4. <image :style="{'top': `${statusBarHeight}px`}" class="back-btn" src="https://ld.726p.com/ldyx_static/imgs/btn-back.png" @click="onClickToBack" />
  5. <!-- S 轮播图 -->
  6. <view class="swiper-wrap">
  7. <u-swiper
  8. class="u-skeleton-fillet"
  9. :list="swiperList"
  10. height="750"
  11. mode="round"
  12. bg-color="transparent"
  13. />
  14. </view>
  15. <!-- E 轮播图 -->
  16. <view class="commission-price-view u-skeleton-fillet" v-if="user_level > 1 && goodsItem.commission_price > 0" @click="onClickCommission">猎豆优选专享,下单或分享可获{{goodsItem.commission_price}}元</view>
  17. <!-- S 商品信息 -->
  18. <view class="info-wrap con-block">
  19. <view class="tp-wrap u-skeleton-fillet">
  20. <view class="lt-wrap">
  21. <text class="price-title">{{goodsItem.is_coupon == 1 && goodsItem.coupon_price > 0 ? '券后价' : '' }} ¥</text>
  22. <text class="price">{{ goodsItem.discount_price }}</text>
  23. <text class="price-old">¥{{ goodsItem.price }}</text>
  24. </view>
  25. <view class="rt-wrap">
  26. <view class="salesVolume" v-if="goodsItem.volume > 100">销量{{ $NumberHandle({value:goodsItem.volume,comma:true}) }}+</view>
  27. </view>
  28. </view>
  29. <view class="bm-wrap u-skeleton-fillet">
  30. <image class="shop-icon" src="https://ld.726p.com/ldyx_static/imgs/icon-dy.png" />
  31. {{ goodsItem.title }}
  32. </view>
  33. </view>
  34. <!-- E 商品信息 -->
  35. <!-- S 店铺信息 -->
  36. <view class="shop-wrap con-block u-skeleton-fillet">
  37. <view class="lt-wrap">
  38. <image class="shop-img" :src="goodsItem.shop && goodsItem.shop.pic_path || 'https://ld.726p.com/ldyx_static/imgs/icon-dy.png'" />
  39. </view>
  40. <view class="rt-wrap">
  41. <view class="tp-wrap">
  42. <text class="shop-name">{{ goodsItem.shop_title }}</text>
  43. <view class="enter-wrap">
  44. </view>
  45. </view>
  46. <view class="point-wrap">
  47. <text>宝贝描述 {{ goodsItem.item_score || '-' }}</text>
  48. <text>服务态度 {{ goodsItem.service_score || '-' }}</text>
  49. <text>发货速度 {{ goodsItem.delivery_score || '-' }}</text>
  50. </view>
  51. </view>
  52. </view>
  53. <!-- E 店铺信息 -->
  54. <!-- S 相关推荐 -->
  55. <view class="recommend-wrap con-block u-skeleton-fillet">
  56. <view class="block-title">相关推荐</view>
  57. <view class="goods-list-wrap">
  58. <view v-for="item in recommendList" :key="item.goods_id" class="goods-item-wrap" @click="onClickGoodsItem(item)">
  59. <image class="goods-img" :src="item.img" />
  60. <view v-if="user_level > 1 && item.commission_price > 0" class="goods-commission">预估佣金 ¥{{ item.commission_price }}</view>
  61. <view class="goods-title">{{ item.title }}</view>
  62. <view class="goods-price">
  63. <text class="price">¥{{ item.discount_price }}</text>
  64. <text class="price-old">¥{{ item.price }}</text>
  65. </view>
  66. </view>
  67. </view>
  68. </view>
  69. <!-- E 相关推荐 -->
  70. <!-- S 宝贝详情 -->
  71. <template v-if="goodsItem.detail_pic && goodsItem.detail_pic.length">
  72. <view class="detail-wrap con-block u-skeleton-fillet">
  73. <view class="block-title">宝贝详情</view>
  74. <view class="content">
  75. <u-lazy-load v-for="(imgUrl, idx) in goodsItem.detail_pic" :key="idx" class="detail-pic" :image="imgUrl" img-mode="widthFix" />
  76. </view>
  77. </view>
  78. </template>
  79. <!-- E 宝贝详情 -->
  80. <!-- 底部按钮 -->
  81. <view class="footer-wrap u-skeleton-fillet" :style="{ 'padding-bottom': isIphoneX ? '66rpx' : '22rpx' }">
  82. <view class="btn-collect-wrap" v-if="goodsItem.is_favorites == 1" @click="onClickSetFavorites">
  83. <image class="btn-collect-img" src="https://ld.726p.com/ldyx_static/imgs/icon-collect-on.png" />
  84. <text class="btn-collect-text">已收藏</text>
  85. </view>
  86. <view class="btn-collect-wrap" v-else @click="onClickSetFavorites">
  87. <image class="btn-collect-img" src="https://ld.726p.com/ldyx_static/imgs/icon-collect.png" />
  88. <text class="btn-collect-text">收藏</text>
  89. </view>
  90. <!-- 已登录按钮 -->
  91. <view v-if="isLogin" class="btn-wrap">
  92. <view class="btn-item lt-btn" @click="onClickFXZQ">
  93. <text class="btn-text">{{ user_level == 1 ? '分享' : '分享赚钱' }}</text>
  94. </view>
  95. <view class="btn-item rt-btn" @click="onClickGWSQ">
  96. <text class="btn-text">购物省钱</text>
  97. </view>
  98. </view>
  99. <!-- 未登录按钮 -->
  100. <view v-else class="btn-wrap">
  101. <view class="btn-item lt-btn" @click="onClickZJGM">
  102. <text class="btn-text">直接购买</text>
  103. </view>
  104. <view class="btn-item rt-btn" @click="onClickFYJGM">
  105. <text class="btn-text">返佣金购买</text>
  106. </view>
  107. </view>
  108. </view>
  109. <!-- 回到顶部 -->
  110. <u-back-top :scroll-top="scrollTop" />
  111. <!-- 登录提醒 -->
  112. <loginRemind
  113. :show="loginRemindShow"
  114. :wordCommand="goodsItem.url_info&&goodsItem.url_info.dy_password"
  115. @callback="loginRemindCallback"
  116. />
  117. <!--骨架组件-->
  118. <u-skeleton :loading="skeletonLoading" :animation="true" bgColor="#FFF" />
  119. </view>
  120. </template>
  121. <script>
  122. import tbAuthorize from '../../commonMoudle/tbAuthorize.vue'
  123. import verticalGood from '@/components/verticalGood.vue'
  124. const app = getApp()
  125. const $router = app.globalData.$router
  126. export default {
  127. components: {
  128. tbAuthorize,
  129. verticalGood
  130. },
  131. data() {
  132. return {
  133. isIphoneX: app.globalData.isIphoneX,
  134. statusBarHeight: app.globalData.statusBarHeight,
  135. swiperList: [], // 轮播图列表(image指定图片路径,也可以通过name属性自定义)
  136. recommendList: [], // 相关推荐列表
  137. goods_id: '', // 商品id
  138. goodsParams: {}, // 商品参数(用于获取商品详情的相关参数 前一页面传入)
  139. goodsItem: { // 商品详情数据
  140. discount_price: '',
  141. price: '',
  142. volume: '',
  143. title: '',
  144. coupon_price: '',
  145. shop: {
  146. pic_path: '',
  147. title: '',
  148. delivery_score: '',
  149. item_score: '',
  150. service_score: '',
  151. },
  152. },
  153. isLogin: false, // 是否已登录
  154. canvasImg: '',
  155. qrcodeVal: '',
  156. qrcodeImg: '',
  157. posterInfo: {},
  158. user_level: uni.getStorageSync('userInfo') ?
  159. uni.getStorageSync('userInfo').user_level : '', // 当前用户等级
  160. scrollTop: 0,
  161. loginRemindShow: false,
  162. loginRemindMask: false,
  163. skeletonLoading: true,
  164. };
  165. },
  166. onPageScroll(e) {
  167. this.scrollTop = e.scrollTop;
  168. },
  169. onShow() {
  170. // 获取用户登录状态
  171. this.handleGetUserIsLogin()
  172. if (uni.getStorageSync('loginPageBack')){
  173. // 获取商品详情数据
  174. this.handleGetgoodsItem()
  175. uni.setStorageSync('loginPageBack',false)
  176. }
  177. },
  178. onLoad(options) {
  179. this.loginRemindMask = uni.getStorageSync('loginRemindMask')?true:false;
  180. const { goods_id = ''} = options
  181. // 接收前一页面传入的商品参数
  182. this.goods_id = decodeURIComponent(goods_id)
  183. this.goodsParams = {
  184. goods_id: decodeURIComponent(goods_id)
  185. }
  186. // 获取商品详情数据
  187. this.handleGetgoodsItem()
  188. },
  189. methods: {
  190. // 用户浏览信息上报
  191. async handleUserReport() {
  192. if (!this.isLogin) return false
  193. const { goods_id, is_coupon, coupon_price, price, discount_price, commission_rate, coupon_end_time, coupon_start_time, shop_type } = this.goodsItem
  194. try {
  195. const url = this.$api.goodsItem_record
  196. const params = { goods_id, is_coupon, coupon_price, price, discount_price, commission_rate, coupon_end_time, coupon_start_time, shop_type }
  197. await this.$postJSON(url, params)
  198. } catch (error) {
  199. console.log('error => ', error)
  200. }
  201. },
  202. // 获取用户登录状态
  203. handleGetUserIsLogin() {
  204. const userInfo = uni.getStorageSync('userInfo') || ''
  205. const user_id = uni.getStorageSync('user_id') || ''
  206. this.user_level = uni.getStorageSync('userInfo') ? uni.getStorageSync('userInfo').user_level : ''; // 当前用户等级
  207. if (userInfo && user_id) {
  208. this.isLogin = true
  209. } else {
  210. this.isLogin = false
  211. }
  212. },
  213. // 获取相关推荐列表
  214. async handleGetRecommendList() {
  215. try {
  216. uni.showLoading({ title: '加载中...', mask: true })
  217. const url = this.$api_dy.goodsRecommend
  218. const params = { third_cids: this.goodsItem.third_cid+'' }
  219. const { data: res = {} } = await this.$postJSON(url, params)
  220. if (res && res.errno == 0 && Array.isArray(res.rst)) {
  221. this.recommendList = res.rst.splice(0,3)
  222. } else {
  223. uni.showToast({ title: res.err || '操作失败', icon: 'none' })
  224. }
  225. } catch (error) {
  226. console.log('error => ', error)
  227. } finally {
  228. uni.hideLoading()
  229. }
  230. },
  231. // 获取商品详情数据
  232. async handleGetgoodsItem() {
  233. try {
  234. uni.showLoading({ title: '加载中...', mask: true })
  235. const url = this.$api_dy.goodsDetail
  236. const params = { product_id: this.goods_id }
  237. const { data: res = {} } = await this.$postJSON(url, params)
  238. if (res && res.errno == 0 && res.rst) {
  239. this.goodsItem = { ...res.rst }
  240. this.swiperList = res.rst.img_list.map(item => ({
  241. image: item
  242. }))
  243. // 用户浏览信息上报
  244. this.handleUserReport()
  245. // 获取相关推荐列表
  246. this.handleGetRecommendList()
  247. } else {
  248. uni.showToast({ title: res.err || '操作失败', icon: 'none' })
  249. }
  250. } catch (error) {
  251. console.log('error => ', error)
  252. } finally {
  253. this.skeletonLoading = false
  254. uni.hideLoading()
  255. }
  256. },
  257. // 监听点击"返回"
  258. onClickToBack() {
  259. let pages = getCurrentPages();
  260. if(pages.length <= 1){ // 没有上一页,去首页
  261. uni.reLaunch({
  262. url: '/pages/home/home'
  263. });
  264. }else {
  265. uni.navigateBack()
  266. }
  267. },
  268. // 监听跳转详情
  269. onClickGoodsItem(goodsItem) {
  270. try{ app.categoryNew_countBuy({type:0,path:'goodsItemTopRecommendAction'}) }catch(e){} ; // 数据上报
  271. const { goods_id = ''} = goodsItem
  272. const pages = getCurrentPages()
  273. const currentPageLength = pages.length
  274. // 微信小程序 页面栈限制 最多10页
  275. if (currentPageLength < 10) {
  276. uni.navigateTo({
  277. url: `/pages/subPackages/dy/goodsDetail?goods_id=${encodeURIComponent(goods_id)}`
  278. })
  279. } else {
  280. uni.redirectTo({
  281. url: `/pages/subPackages/dy/goodsDetail?goods_id=${encodeURIComponent(goods_id)}`
  282. })
  283. }
  284. },
  285. // 监听点击收藏
  286. onClickSetFavorites() {
  287. if (!this.isLogin) { // 未登录 => 去登录
  288. $router.navigateTo({
  289. url: '/pages/subPackages/login/loginPhone'
  290. })
  291. } else {
  292. this.handleSetFavorites()
  293. }
  294. },
  295. async handleSetFavorites() {
  296. const { goods_id, is_coupon, discount_price, price, coupon_price, commission_rate, coupon_end_time, coupon_start_time, shop_type } = this.goodsItem
  297. try {
  298. uni.showLoading({ title: '加载中...', mask: true })
  299. const url = this.$api.goodsItem_addFavorites
  300. const params = { goods_id, is_coupon, discount_price, price, coupon_price, commission_rate, coupon_end_time, coupon_start_time, shop_type }
  301. const { data: res } = await this.$postJSON(url, params)
  302. if (res && res.errno == 0) {
  303. // 设置成功 => 更新状态
  304. this.handleGetgoodsItem()
  305. } else {
  306. uni.showToast({ title: res.err || '操作失败', icon: 'none' })
  307. }
  308. } catch (error) {
  309. console.log('error => ', error)
  310. } finally {
  311. uni.hideLoading()
  312. }
  313. },
  314. // 监听点击“分享赚钱” => 判断是否授权(京东商品不需要授权) => 生成图片 => 分享图片
  315. async onClickFXZQ() {
  316. $router.navigateTo({
  317. url: `/pages/subPackages/dy/shareDetail?shop_type=${this.goodsItem.shop_type}&goods_id=${encodeURIComponent(this.goodsItem.goods_id)}`
  318. })
  319. },
  320. // 监听点击“购物省钱” => 判断是否授权(京东商品不需要授权) => 获取口令 => 复制口令
  321. async onClickGWSQ() {
  322. uni.setClipboardData({
  323. data: this.goodsItem.url_info.dy_password,
  324. success: () => {
  325. this.$u.toast('抖口令复制成功!请打开抖音APP领券下单~')
  326. }
  327. });
  328. },
  329. // 监听点击“直接购买” => 获取口令 => 复制口令
  330. async onClickZJGM() {
  331. try {
  332. if(!this.loginRemindMask){
  333. this.loginRemindShow = true;
  334. } else {
  335. uni.setClipboardData({
  336. data: this.goodsItem.url_info.dy_password,
  337. success: () => {
  338. this.$u.toast('抖口令复制成功!请打开抖音APP领券下单~')
  339. }
  340. });
  341. }
  342. } catch (error) {
  343. console.log('error => ', error)
  344. }
  345. },
  346. // 监听点击“返佣金购买” => 跳登录页面
  347. onClickFYJGM() {
  348. $router.navigateTo({
  349. url: '/pages/subPackages/login/loginPhone'
  350. })
  351. },
  352. // 监听点击“优惠券”
  353. onClickCoupon() {
  354. if (this.isLogin) { // 已登录 => 执行“购物省钱”按钮逻辑
  355. this.onClickGWSQ()
  356. } else { // 未登录 => 执行“直接购买”按钮逻辑
  357. this.onClickZJGM()
  358. }
  359. },
  360. // 监听点击“反佣金”
  361. onClickCommission() {
  362. $router.navigateTo({
  363. url: `/pages/subPackages/my/tqjs`
  364. })
  365. },
  366. // 登录提醒回调
  367. loginRemindCallback(val){
  368. this.loginRemindShow = false;
  369. }
  370. },
  371. }
  372. </script>
  373. <style lang="scss" scoped>
  374. @import '@/static/style/goodsDetail.scss';
  375. .detail-pic {
  376. vertical-align: middle; // 解决图片下边框缝隙问题
  377. width: 100%;
  378. }
  379. .navigator{
  380. color: #fff;
  381. width: 100%;
  382. text-align: center;
  383. line-height: 84rpx;
  384. }
  385. </style>