goods.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. <template>
  2. <app-layout>
  3. <view v-if="!goods" class="u-goods-detail"></view>
  4. <template v-if="goods">
  5. <!--商品轮播图-->
  6. <app-banner
  7. :videoUrl="goods.video_url"
  8. :share="goods.share"
  9. :picList="goods.pic_url"
  10. :goods_id="goods_id"
  11. sign="miaosha"
  12. ></app-banner>
  13. <!-- 秒杀时间 -->
  14. <app-goods-time
  15. :day="day"
  16. :second="second"
  17. :minute="minute"
  18. :hour="hour"
  19. :theme="getTheme"
  20. :miaosha_status="miaosha_status"
  21. ></app-goods-time>
  22. <bd-info
  23. :theme="getTheme"
  24. :name="goods.name"
  25. :is-negotiable="goods.is_negotiable"
  26. :subtitle="goods.subtitle"
  27. :level-show="goods.level_show"
  28. :price="goods.price"
  29. :original-price="goods.original_price"
  30. :price-max="goods.price_max"
  31. :price-min="goods.price_min"
  32. :price-member-max="goods.price_member_max"
  33. :price-member-min="goods.price_member_min"
  34. :discount='discount'
  35. :is-vip-card-user="is_vip_card_user"
  36. :sales="goods.sales"
  37. :unit="goods.unit"
  38. :is-sales="goods.is_sales"
  39. :is-vip="is_vip"
  40. :flash-sale="flash_sale"
  41. :goods-id="goods.id"
  42. :extra-quick-share="goods.extra_quick_share"
  43. :app-share-pic="goods.app_share_pic"
  44. :app-share-title="goods.app_share_title"
  45. :poster-config="poster_config"
  46. :poster-generate="poster_generate"
  47. :has-poster-nav="true"
  48. v-bind:goods="goods"
  49. :share-url="url"
  50. @share="hShareAppMessage"
  51. :limit-buy="goods.limit_buy"
  52. :min-number="goods.min_number"
  53. >
  54. </bd-info>
  55. <bd-coupon @change="setCoupon" :theme="getTheme" :coupons="goods.goods_coupon_center"></bd-coupon>
  56. <bd-xbc
  57. :coAttr="is_open"
  58. :attr-list="selectAttr && selectAttr.attr_list"
  59. :type="goods.type"
  60. :guarantee-title="goods.guarantee_title"
  61. :guarantee-pic="goods.guarantee_pic"
  62. :param_content="goods.param_content"
  63. :param_name="goods.param_name"
  64. :services="goods.services"
  65. :attr-groups="goods.attr_groups"
  66. @openAttr="takeCart"
  67. ></bd-xbc>
  68. <bd-hc
  69. :integral="goods.goods_marketing_award.integral"
  70. :coupon="goods.goods_marketing_award.coupon"
  71. :card="goods.goods_marketing_award.card"
  72. :balance="goods.goods_marketing_award.balance"
  73. :theme="getTheme"
  74. ></bd-hc>
  75. <bd-kb
  76. :limit="goods.goods_marketing.limit"
  77. :express="goods.express"
  78. :shipping="goods.goods_marketing.shipping"
  79. :pickup="goods.goods_marketing.pickup"
  80. ></bd-kb>
  81. <bd-comments :goods-id="goods.id"></bd-comments>
  82. <bd-detail :detail="goods.detail"></bd-detail>
  83. <!-- 相关推荐 -->
  84. <app-related-suggestion-product :theme="getTheme" :list="list"></app-related-suggestion-product>
  85. <!-- 底部空格 -->
  86. <view class="safe-area-inset-bottom">
  87. <view class="u-bottom-height" :class="full_reduce ? 'u-bottom-height-1' : 'u-bottom-height-0'"></view>
  88. </view>
  89. <!-- 底部按钮 -->
  90. <view v-if="is_open == 1" class="safe-area-inset-bottom u-bottom-fixed">
  91. <view v-if="full_reduce">
  92. <app-goods-full-reduce
  93. :theme="getTheme"
  94. :full_reduce="full_reduce"
  95. >
  96. </app-goods-full-reduce>
  97. </view>
  98. <view class="bd-bottom dir-left-nowrap cross-center">
  99. <view class="bd-back dir-top-nowrap main-center cross-center box-grow-0" @click="router('/pages/index/index')">
  100. <image class="bd-icon" src="../../../static/image/icon/index.png"></image>
  101. <text class="bd-text">首页</text>
  102. </view>
  103. <bd-service :name="goods.name" :url="webUrl"></bd-service>
  104. <template v-if="goods.goods_stock > 0" >
  105. <template v-if="miaosha_status === 1">
  106. <view class="box-grow-1 dir-left-nowrap">
  107. <view class="bd-btn bd-btn-left bd-btn-half"
  108. @click="takeCart"
  109. :style="{'background': goods.buy_goods_auth ? getTheme.background_s_gradient_btn : '#999999','color': goods.buy_goods_auth ? getTheme.secondary_text : ''}">
  110. 加入购物车
  111. </view>
  112. <view @click="takeCart" class="bd-btn bd-btn-half bd-btn-right bd-btn-color"
  113. :style="{'background': goods.buy_goods_auth ? getTheme.background_gradient_btn : '#999999','color': goods.buy_goods_auth ? getTheme.main_text : ''}"
  114. >
  115. 立即购买
  116. </view>
  117. </view>
  118. </template>
  119. <view class="bd-btn bd-oversell-btn box-grow-1 bd-btn-color" v-else-if="miaosha_status === 2">
  120. 活动未开始
  121. </view>
  122. <view class="bd-btn bd-oversell-btn box-grow-1 bd-btn-color" v-else-if="miaosha_status === 0">
  123. 活动已结束
  124. </view>
  125. </template>
  126. <view class="box-grow-1 bd-btn bd-oversell-btn bd-btn-color" v-else>
  127. 已售罄
  128. </view>
  129. </view>
  130. </view>
  131. <!--商品规格-->
  132. <u-attr
  133. v-if="miaosha_status === 1"
  134. v-model="show"
  135. :theme="getTheme"
  136. :goods="goods"
  137. :checked="selectAttr"
  138. @check="attrtap"
  139. :leftFunc="true"
  140. @leftFunc="leftFunc"
  141. :rightFunc="true"
  142. @rightFunc="rightFunc"
  143. >
  144. </u-attr>
  145. </template>
  146. <app-close v-if="showClose" :modal="false" @update="getMall"></app-close>
  147. </app-layout>
  148. </template>
  149. <script>
  150. import { mapGetters, mapState } from 'vuex';
  151. import appBanner from '../../../components/page-component/goods/app-goods-banner.vue';
  152. import appGoodsTime from '../components/app-goods-time.vue';
  153. import appRelatedSuggestionProduct from '../../../components/page-component/app-related-suggestion-product/app-related-suggestion-product.vue';
  154. import appGoodsFullReduce from "../../../components/page-component/goods/app-goods-full-reduce";
  155. import uAttr from '../../../components/page-component/goods/u-attr.vue';
  156. import bdInfo from '@/components/page-component/goods/bd-info';
  157. import bdCoupon from '@/components/page-component/goods/bd-coupon.vue';
  158. import bdXbc from '@/components/page-component/goods/bd-xbc.vue';
  159. import bdKb from '@/components/page-component/goods/bd-kb.vue';
  160. import bdHc from '@/components/page-component/goods/bd-hc.vue';
  161. import bdDetail from '@/components/page-component/goods/bd-detail.vue';
  162. import bdComments from '@/components/page-component/goods/bd-comments.vue';
  163. import appClose from '@/components/basic-component/app-close/app-close.vue';
  164. import bdService from '@/components/page-component/goods/bd-service.vue';
  165. export default {
  166. name: 'goods',
  167. data() {
  168. return {
  169. showClose: false,
  170. is_open: 0,
  171. goods: null,
  172. full_reduce: null,
  173. cartShow: false,
  174. miaosha_status: -1,
  175. miaosha_time: 0,
  176. selectAttr: null,
  177. url: '',
  178. webUrl: '',
  179. show: false,
  180. list: [],
  181. miaosha_buy_count: 0,
  182. goods_id: -1,
  183. is_activity: 0,
  184. hour: 0,
  185. minute: 0,
  186. second: 0,
  187. day: 0,
  188. time: -1,
  189. is_vip_card_user: 0,
  190. discount: null,
  191. is_vip: false,
  192. loading: false,
  193. flash_sale: null,
  194. poster_config: this.$api.miaosha.poster_config,
  195. poster_generate: this.$api.miaosha.poster_generate,
  196. disable: 'disable',
  197. }
  198. },
  199. onLoad(options) { this.$commonLoad.onload(options);
  200. this.goods_id = options.id;
  201. this.webUrl = '/plugins/miaosha/goods/goods?id=' + options.id;
  202. if (options.is_activity) {
  203. this.is_activity = options.is_activity
  204. }
  205. // #ifdef MP-WEIXIN
  206. wx.showShareMenu({
  207. menus: ['shareAppMessage', 'shareTimeline']
  208. })
  209. // #endif
  210. },
  211. onShow() {
  212. this.showClose = false;
  213. setTimeout(()=>{
  214. this.showClose = true;
  215. })
  216. this.$showLoading();
  217. this.$nextTick(() => {
  218. let that = this;
  219. this.$request({
  220. url: this.$api.miaosha.goods_detail,
  221. data: {
  222. id: this.goods_id,
  223. is_activity: this.is_activity
  224. }
  225. }).then(response => {
  226. this.$hideLoading();
  227. if (response.code === 0) {
  228. let { detail, miaosha_status, miaosha_time, miaosha_buy_count } = response.data;
  229. this.goods = detail;
  230. if (detail.goods_activity) {
  231. this.full_reduce = detail.goods_activity.full_reduce;
  232. }
  233. this.flash_sale = detail.plugin_extra.flash_sale;
  234. this.miaosha_status = miaosha_status;
  235. this.miaosha_buy_count = miaosha_buy_count;
  236. this.loading = true;
  237. this.url = `${this.$api.miaosha.poster}&goods_id=${this.goods.id}`;
  238. this.poster_config = `${this.poster_config}&goods_id=${this.goods.id}`;
  239. this.poster_generate = `${this.poster_generate}&goods_id=${this.goods.id}`;
  240. this.getTime(miaosha_time);
  241. // #ifdef H5
  242. this.hShareAppMessage();
  243. // #endif
  244. } else {
  245. uni.showToast({
  246. title: response.msg,
  247. icon: 'none'
  248. })
  249. }
  250. this.$request({
  251. url: this.$api.goods.new_recommend,
  252. data: {
  253. goods_id: this.goods.id,
  254. }
  255. }).then(response => {
  256. if (response.code === 0) {
  257. this.list = response.data.list;
  258. if (that.goods.vip_card_appoint.discount) {
  259. that.is_vip = true;
  260. that.discount = that.goods.vip_card_appoint.discount
  261. }
  262. that.is_vip_card_user = that.goods.vip_card_appoint.is_vip_card_user
  263. }
  264. })
  265. });
  266. })
  267. },
  268. onHide() {
  269. clearInterval(this.time);
  270. },
  271. onUnload() {
  272. clearInterval(this.time);
  273. },
  274. computed: {
  275. ...mapGetters('mallConfig', {
  276. getTheme: 'getTheme',
  277. }),
  278. ...mapState({
  279. mall: state => state.mallConfig.mall,
  280. })
  281. },
  282. // #ifdef MP-WEIXIN
  283. onShareTimeline() {
  284. return this.$shareTimeline({
  285. title: this.goods.app_share_title ? this.goods.app_share_title : this.goods.name,
  286. query: {
  287. id: this.goods.id
  288. }
  289. });
  290. },
  291. // #endif
  292. // #ifdef MP
  293. onShareAppMessage() {
  294. return this.hShareAppMessage();
  295. },
  296. // #endif
  297. methods: {
  298. hShareAppMessage(s = false){
  299. return this.$shareAppMessage({
  300. path: '/plugins/miaosha/goods/goods',
  301. title: this.goods.app_share_title ? this.goods.app_share_title : this.goods.name,
  302. imageUrl: this.goods.app_share_pic ? this.goods.app_share_pic : this.goods.pic_url[0].pic_url,
  303. desc: this.goods.subtitle,
  304. params: {
  305. id: this.goods.id
  306. }
  307. },s);
  308. },
  309. getMall(e) {
  310. this.is_open = e.is_open;
  311. },
  312. async request({ url, data }) {
  313. const response = await this.$request({
  314. url: url,
  315. data: data,
  316. });
  317. if (response.code === 0) {
  318. return response.data;
  319. }
  320. },
  321. attrtap({item}) {
  322. this.selectAttr = item;
  323. },
  324. takeCart() {
  325. if (!this.goods.buy_goods_auth) {
  326. this.$tips.showToast({
  327. title: '您暂无权限购买该商品',
  328. icon: 'none'
  329. })
  330. return ;
  331. }
  332. this.show = true;
  333. },
  334. leftFunc(number) {
  335. this.$request({
  336. url: this.$api.miaosha.add_cart,
  337. method: 'post',
  338. data: {
  339. miaosha_goods_id: this.selectAttr.goods_id,
  340. attr_id: this.selectAttr.id,
  341. num: number
  342. }
  343. }).then(response => {
  344. uni.showToast({
  345. title: response.msg,
  346. icon: 'none'
  347. })
  348. });
  349. },
  350. rightFunc(data) {
  351. uni.navigateTo({
  352. url: `/pages/order-submit/order-submit?mch_list=${JSON.stringify([data])}&preview_url=${encodeURIComponent(this.$api.miaosha.order_preview)}&submit_url=${encodeURIComponent(this.$api.miaosha.order_submit)}`
  353. });
  354. },
  355. getTime(newValue) {
  356. newValue = newValue - 1;
  357. this.day = parseInt(newValue / 3600 / 24);
  358. this.hour = parseInt(newValue / 3600 % 24);
  359. this.minute = parseInt(newValue / 60 % 60);
  360. this.second = parseInt(newValue % 60);
  361. clearInterval(this.time);
  362. this.time = setInterval(() => {
  363. newValue = newValue - 1;
  364. if (newValue < 0) {
  365. clearInterval(this.time);
  366. }
  367. this.day = parseInt(newValue / 3600 / 24);
  368. this.hour = parseInt(newValue / 3600 % 24);
  369. this.minute = parseInt(newValue / 60 % 60);
  370. this.second = parseInt(newValue % 60);
  371. }, 1000);
  372. },
  373. setCoupon(index) {
  374. this.$set(this.goods.goods_coupon_center[index], 'is_receive', 1);
  375. },
  376. router(url) {
  377. uni.navigateTo({
  378. url: url
  379. })
  380. }
  381. },
  382. components: {
  383. 'app-banner': appBanner,
  384. 'app-goods-time': appGoodsTime,
  385. 'app-related-suggestion-product': appRelatedSuggestionProduct,
  386. uAttr,
  387. appGoodsFullReduce,
  388. bdInfo,
  389. bdCoupon,
  390. bdXbc,
  391. bdKb,
  392. bdHc,
  393. bdDetail,
  394. bdComments,
  395. appClose,
  396. bdService
  397. }
  398. }
  399. </script>
  400. <style scoped lang="scss">
  401. .app-goods {
  402. background-color: #f7f7f7;
  403. }
  404. .buttons {
  405. width: #{750rpx};
  406. height: #{110rpx};
  407. .app-home {
  408. width: 14%;
  409. height: #{110rpx};
  410. background-color: white;
  411. image {
  412. width: #{40rpx};
  413. height: #{40rpx};
  414. }
  415. text {
  416. font-size: #{18rpx};
  417. color: #707070;
  418. }
  419. }
  420. .app-button {
  421. width: 86%;
  422. height: #{110rpx};
  423. text-align: center;
  424. line-height: #{110rpx};
  425. .app-join-cart {
  426. height: #{110rpx};
  427. }
  428. .app-buy {
  429. height: #{110rpx};
  430. color: white;
  431. }
  432. .notStart {
  433. height: #{110rpx};
  434. background-color: #cccccc;
  435. color: #FFFFFF;
  436. }
  437. .app-over {
  438. height: #{110rpx};
  439. background: #666;
  440. color: #FFFFFF;
  441. }
  442. }
  443. }
  444. .text {
  445. color: #ffffff;
  446. }
  447. .u-bottom-fixed {
  448. position: fixed;
  449. bottom: 0;
  450. left: 0;
  451. width: 100%;
  452. z-index: 1602;
  453. background-color: #ffffff;
  454. }
  455. .u-bottom-height-0 {
  456. height: 110upx;
  457. }
  458. .u-bottom-height-1 {
  459. height: 190upx;
  460. }
  461. .goods-margin {
  462. margin-top: 20upx;
  463. }
  464. .bd-bottom {
  465. width: 750upx;
  466. height: 110upx;
  467. padding: 20upx 24upx;
  468. }
  469. .bd-back {
  470. width: 66upx;
  471. height: 100%;
  472. margin-right: 20upx;
  473. }
  474. .bd-icon {
  475. width: 30upx;
  476. height: 30upx;
  477. margin-bottom: 8upx;
  478. }
  479. .bd-text {
  480. font-size: 20upx;
  481. color: #888888;
  482. line-height: 1;
  483. }
  484. .bd-btn {
  485. text-align: center;
  486. line-height: 70upx;
  487. font-size: 28upx;
  488. border-radius: 35upx;
  489. }
  490. .bd-btn-left {
  491. border-top-right-radius: 0;
  492. border-bottom-right-radius: 0;
  493. }
  494. .bd-btn-right {
  495. border-top-left-radius: 0;
  496. border-bottom-left-radius: 0;
  497. }
  498. .bd-btn-half {
  499. width: 50%;
  500. }
  501. .bd-btn-color {
  502. color: #ffffff;
  503. }
  504. .bd-oversell-btn {
  505. background-color: #CDCDCD;
  506. }
  507. </style>