goods.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <template>
  2. <app-layout>
  3. <view v-if="!goods" class="u-goods-detail"></view>
  4. <view v-if="goods">
  5. <app-goods-banner :pic-list="goods.pic_url"
  6. :share="goods.share"
  7. :goods_id="goods.id"
  8. :video-url="goods.video_url"
  9. ></app-goods-banner>
  10. <view class="other-info">
  11. <view class="t-omit-two goods-name">{{goods.name}}</view>
  12. <view v-if="goods.subtitle" class="goods-subtitle">
  13. <view class="t-omit-three">{{goods.subtitle}}</view>
  14. </view>
  15. <view class='price main-between'>
  16. <view>
  17. <view :style="{'color': getTheme.color}">
  18. {{goods.integralMallGoods.integral_num}}积分
  19. <template v-if="goods.price > 0">+¥{{goods.price}}元</template>
  20. </view>
  21. <view class='original' v-if="isUnderlinePrice == 1">¥{{goods.original_price}}</view>
  22. </view>
  23. <view @click="shareClick" :style="{'background-color': getTheme.background}" class="share dir-left-nowrap main-center cross-center">
  24. <image class="share-image box-grow-0" src="/static/image/icon/icon-share-white.png"></image>
  25. <view class="share-text box-grow-0">分享</view>
  26. </view>
  27. </view>
  28. <view>
  29. <bd-info-extra :goods="goods" :theme="getTheme" :unit="goods.unit" :min-number="goods.min_number" :limit-buy="goods.limit_buy"></bd-info-extra>
  30. </view>
  31. </view>
  32. <!--商品优惠券-->
  33. <bd-coupon @change="setCoupon" :theme="getTheme" :coupons="goods.goods_coupon_center"></bd-coupon>
  34. <bd-xbc
  35. :coAttr="is_open"
  36. :attr-list="selectAttr && selectAttr.attr_list"
  37. :type="goods.type"
  38. :guarantee-title="goods.guarantee_title"
  39. :guarantee-pic="goods.guarantee_pic"
  40. :param_content="goods.param_content"
  41. :param_name="goods.param_name"
  42. :services="goods.services"
  43. :attr-groups="goods.attr_groups"
  44. :goods-stock="goods.goods_stock"
  45. @openAttr="clickAttr"
  46. ></bd-xbc>
  47. <!--商品信息-->
  48. <bd-hc
  49. :integral="goods.goods_marketing_award.integral"
  50. :coupon="goods.goods_marketing_award.coupon"
  51. :card="goods.goods_marketing_award.card"
  52. :balance="goods.goods_marketing_award.balance"
  53. :theme="getTheme"
  54. ></bd-hc>
  55. <bd-kb
  56. :limit="goods.goods_marketing.limit"
  57. :express="goods.express"
  58. :shipping="goods.goods_marketing.shipping"
  59. :pickup="goods.goods_marketing.pickup"
  60. ></bd-kb>
  61. <bd-detail :detail="goods.detail"></bd-detail>
  62. <!-- 底部空格 -->
  63. <view class="safe-area-inset-bottom">
  64. <view class="u-bottom-height"></view>
  65. </view>
  66. <view v-if="is_open == 1" class="safe-area-inset-bottom u-bottom-fixed">
  67. <view class="bd-bottom dir-left-nowrap cross-center">
  68. <view class="bd-back dir-top-nowrap main-center cross-center box-grow-0" @click="back">
  69. <image class="bd-icon" src="/static/image/icon/index.png"></image>
  70. <text class="bd-text">首页</text>
  71. </view>
  72. <bd-service :name="goods.name" :url="webUrl"></bd-service>
  73. <view v-if="goods.goods_stock === 0" class="box-grow-1 bd-btn bd-oversell-btn bd-btn-color" >
  74. 已售罄
  75. </view>
  76. <view
  77. v-else
  78. @click="clickAttr"
  79. :style="{'background': goods.buy_goods_auth ? getTheme.background_gradient_btn : '#999999'}"
  80. class="bd-btn box-grow-1 bd-btn-color">
  81. 立即兑换
  82. </view>
  83. </view>
  84. </view>
  85. </view>
  86. <app-close v-if="showClose" :modal="false" @update="getMall"></app-close>
  87. <app-share-qr-code
  88. v-if="goods && goods.id > 0"
  89. v-model="shareShow"
  90. :url="shareUrl"
  91. :has-poster-nav="true"
  92. :poster-config="poster_config + `&goods_id=` + goods.id"
  93. :poster-generate="poster_generate + `&goods_id=` + goods.id"
  94. :goods="goods"
  95. @share="hShareAppMessage"
  96. ></app-share-qr-code>
  97. <u-attr
  98. v-if="goods && goods.id > 0"
  99. v-model="attrShow"
  100. :theme="getTheme"
  101. :checked="selectAttr"
  102. :goods="goods"
  103. @check="onAttr"
  104. :rightFunc="true"
  105. @rightFunc="rightFunc"
  106. :is_show_left="false"
  107. rightText="立即兑换"
  108. sign="integral_mall"
  109. >
  110. <view slot="priceBefore" >
  111. <template v-if="selectAttr">
  112. {{selectAttr.extra.value}}{{selectAttr.extra.name}}
  113. </template>
  114. </view>
  115. </u-attr>
  116. </app-layout>
  117. </template>
  118. <script>
  119. import {mapGetters, mapState} from "vuex";
  120. import appGoodsBanner from "../../../components/page-component/goods/app-goods-banner.vue";
  121. import appRecommendedProduct from "../../../components/page-component/app-recommended-product/app-recommended-product.vue";
  122. import appShareQrCode from '../../../components/page-component/app-share-qr-code-poster/app-share-qr-code-poster.vue';
  123. import uAttr from '../../../components/page-component/goods/u-attr.vue';
  124. import appClose from '@/components/basic-component/app-close/app-close.vue';
  125. import bdInfo from '@/components/page-component/goods/bd-info';
  126. import bdCoupon from '@/components/page-component/goods/bd-coupon.vue';
  127. import bdXbc from '@/components/page-component/goods/bd-xbc.vue';
  128. import bdKb from '@/components/page-component/goods/bd-kb.vue';
  129. import bdHc from '@/components/page-component/goods/bd-hc.vue';
  130. import bdDetail from '@/components/page-component/goods/bd-detail.vue';
  131. import bdService from '@/components/page-component/goods/bd-service.vue';
  132. import bdInfoExtra from '@/components/page-component/goods/bd-info-extra.vue';
  133. export default {
  134. name: "goods",
  135. components: {
  136. appGoodsBanner,
  137. appShareQrCode,
  138. appRecommendedProduct,
  139. uAttr,
  140. appClose,
  141. bdInfo,
  142. bdCoupon,
  143. bdXbc,
  144. bdKb,
  145. bdHc,
  146. bdDetail,
  147. bdService,
  148. bdInfoExtra
  149. },
  150. data() {
  151. return {
  152. showClose: false,
  153. is_open: 0,
  154. goods: null,
  155. selectAttr: null,
  156. recommend_list: null,
  157. shareShow: false,
  158. shareUrl: null,
  159. attrShow: false,
  160. loading: false,
  161. webUrl: '',
  162. poster_config: this.$api.integral_mall.poster_config,
  163. poster_generate: this.$api.integral_mall.poster_generate,
  164. disable: 'disable'
  165. };
  166. },
  167. computed: {
  168. ...mapState({
  169. mall: state => state.mallConfig.mall,
  170. isUnderlinePrice: state => state.mallConfig.mall.setting.is_underline_price,
  171. }),
  172. ...mapGetters('mallConfig', {
  173. getTheme: 'getTheme',
  174. })
  175. },
  176. onShow() {
  177. this.showClose = false;
  178. setTimeout(()=>{
  179. this.showClose = true;
  180. })
  181. },
  182. onLoad(options) { this.$commonLoad.onload(options);
  183. this.webUrl = '/plugins/integral_mall/goods/goods?goods_id=' + options.goods_id;
  184. // #ifdef MP-WEIXIN
  185. wx.showShareMenu({
  186. menus: ['shareAppMessage', 'shareTimeline']
  187. })
  188. // #endif
  189. this.loadData(options.goods_id);
  190. },
  191. // #ifdef MP-WEIXIN
  192. onShareTimeline() {
  193. // 分享朋友圈beta
  194. return this.$shareTimeline({
  195. title: this.goods.app_share_title ? this.goods.app_share_title: this.goods.name,
  196. imageUrl: this.goods.pic_url[0].pic_url,
  197. query: {
  198. goods_id: this.goods.id
  199. } // 此处填写页面的参数
  200. });
  201. },
  202. // #endif
  203. // #ifdef MP
  204. onShareAppMessage() {
  205. return this.hShareAppMessage();
  206. },
  207. // #endif
  208. methods: {
  209. hShareAppMessage(s= false){
  210. return this.$shareAppMessage({
  211. title: this.goods.app_share_title ? this.goods.app_share_title: this.goods.name,
  212. imageUrl: this.goods.app_share_pic ? this.goods.app_share_pic: this.goods.cover_pic,
  213. path: "/plugins/integral_mall/goods/goods",
  214. desc: this.goods.subtitle,
  215. params: {
  216. goods_id: this.goods.id
  217. }
  218. }, s);
  219. },
  220. getMall(e) {
  221. this.is_open = e.is_open;
  222. },
  223. loadData(id) {
  224. this.$showLoading();
  225. this.$request({
  226. url: this.$api.integral_mall.goods_detail,
  227. data: {
  228. id: id
  229. }
  230. }).then(response => {
  231. this.$hideLoading();
  232. let {code, data, msg} = response;
  233. if (code === 0) {
  234. this.goods = data.detail;
  235. this.shareUrl = this.$api.integral_mall.poster + '&goods_id=' + id;
  236. this.goods.id = id;
  237. this.loading = true;
  238. // #ifdef H5
  239. this.hShareAppMessage();
  240. // #endif
  241. } else {
  242. uni.showModal({
  243. title: '提示',
  244. content: msg,
  245. showCancel: false
  246. });
  247. }
  248. }).catch(() => {
  249. this.$hideLoading();
  250. });
  251. },
  252. onAttr({item}) {
  253. this.selectAttr = item;
  254. },
  255. shareClick() {
  256. this.shareShow = true;
  257. },
  258. back() {
  259. uni.redirectTo({
  260. url: '/pages/index/index'
  261. });
  262. },
  263. clickAttr() {
  264. if (!this.goods.buy_goods_auth) {
  265. this.$tips.showToast({
  266. title: '您暂无权限购买该商品',
  267. icon: 'none'
  268. });
  269. return;
  270. }
  271. this.attrShow = true;
  272. },
  273. setCoupon(index) {
  274. this.$set(this.goods.goods_coupon_center[index], 'is_receive', 1);
  275. },
  276. rightFunc: function(data) {
  277. uni.navigateTo({
  278. url: `/pages/order-submit/order-submit?mch_list=${JSON.stringify([data])}&preview_url=${encodeURIComponent(this.$api.integral_mall.order_preview)}&submit_url=${encodeURIComponent(this.$api.integral_mall.order_submit)}`
  279. });
  280. }
  281. }
  282. }
  283. </script>
  284. <style scoped lang="scss">
  285. .preventTouchMove{
  286. top: 0;
  287. left: 0;
  288. width: 100%;
  289. overflow: hidden;
  290. position: fixed;
  291. z-index: 0;
  292. }
  293. .other-info {
  294. width: 702upx;
  295. background-color: #fff;
  296. padding: #{20rpx};
  297. margin: 24upx 24upx 0 24upx;
  298. border-radius: 15upx;
  299. }
  300. .goods-name {
  301. background-color: #ffffff;
  302. color: #353535;
  303. font-size: 32upx;
  304. line-height: 42upx;
  305. margin-top: 5upx;
  306. }
  307. .goods-subtitle {
  308. margin-top: 23upx;
  309. font-size: 24upx;
  310. line-height: 34upx;
  311. color: #999999;
  312. margin-bottom: 20upx;
  313. }
  314. .attr {
  315. background-color: #f7f7f7;
  316. }
  317. .recommend {
  318. .recommend-title {
  319. margin: #{40rpx} 0 #{32rpx} 0;
  320. font-size: $uni-font-size-weak-one;
  321. color: $uni-general-color-two;
  322. .border {
  323. border-top: #{1rpx} solid #bbbbbb;
  324. height: 0;
  325. width: #{40rpx};
  326. margin: 0 #{24rpx};
  327. }
  328. image {
  329. width: #{24rpx};
  330. height: #{24rpx};
  331. display: block;
  332. margin-right: #{12rpx};
  333. }
  334. }
  335. }
  336. .u-bottom-height {
  337. height: 110upx;
  338. }
  339. .bd-bottom {
  340. width: 750upx;
  341. height: 110upx;
  342. padding: 20upx 24upx;
  343. }
  344. .bd-back {
  345. width: 66upx;
  346. height: 100%;
  347. margin-right: 20upx;
  348. }
  349. .bd-icon {
  350. width: 30upx;
  351. height: 30upx;
  352. margin-bottom: 8upx;
  353. }
  354. .bd-text {
  355. font-size: 20upx;
  356. color: #888888;
  357. line-height: 1;
  358. }
  359. .bd-btn {
  360. text-align: center;
  361. line-height: 70upx;
  362. font-size: 28upx;
  363. border-radius: 35upx;
  364. }
  365. .bd-btn-left {
  366. border-top-right-radius: 0;
  367. border-bottom-right-radius: 0;
  368. }
  369. .bd-btn-right {
  370. border-top-left-radius: 0;
  371. border-bottom-left-radius: 0;
  372. }
  373. .bd-btn-half {
  374. width: 50%;
  375. }
  376. .bd-btn-color {
  377. color: #ffffff;
  378. }
  379. .bd-oversell-btn {
  380. background-color: #CDCDCD;
  381. }
  382. .comments {
  383. margin-bottom: #{20rpx};
  384. background-color: #ffffff;
  385. }
  386. .detail {
  387. background-color: #ffffff;
  388. image {
  389. width: 100%;
  390. height: #{80rpx};
  391. display: block;
  392. }
  393. }
  394. .price {
  395. font-size: #{40rpx};
  396. color: #ff4544;
  397. font-family: DIN;
  398. background-color: #fff;
  399. position: relative;
  400. }
  401. //.price image {
  402. // height: #{44rpx};
  403. // width: #{44rpx};
  404. // display: block;
  405. // float: left;
  406. // margin-right: #{16rpx};
  407. //}
  408. .share {
  409. height: #{48rpx};
  410. border-radius: #{40rpx} 0 0 #{40rpx};
  411. padding: 0 #{14rpx};
  412. width: #{103rpx};
  413. margin-right: #{-20rpx};
  414. .share-image {
  415. width: #{22rpx};
  416. height: #{22rpx};
  417. }
  418. .share-text {
  419. font-size: #{22rpx};
  420. color: #ffffff;
  421. margin-left: #{10rpx};
  422. }
  423. }
  424. .original {
  425. background-color: #fff;
  426. text-decoration: line-through;
  427. color: #888;
  428. height: #{60rpx};
  429. line-height: #{60rpx};
  430. font-size: #{24rpx};
  431. }
  432. .u-bottom-fixed {
  433. position: fixed;
  434. bottom: 0;
  435. left: 0;
  436. width: 100%;
  437. z-index: 1602;
  438. background-color: #ffffff;
  439. }
  440. </style>