goods.vue 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. <template>
  2. <app-layout>
  3. <view v-if="!goods" class="u-goods-detail"></view>
  4. <template v-if="goods">
  5. <!--商品轮播图-->
  6. <app-goods-banner
  7. v-bind:pic-list="goods.pic_url"
  8. v-bind:share="goods.share"
  9. v-bind:video-url="goods.video_url"
  10. v-bind:goods_id="goodsId"
  11. ></app-goods-banner>
  12. <view>
  13. <bd-info
  14. :theme="getTheme"
  15. :name="name"
  16. :is-negotiable="is_negotiable"
  17. :subtitle="subtitle"
  18. :flash-sale="flash_sale"
  19. :level-show="level_show"
  20. :price="price"
  21. :original-price="original_price"
  22. :price-max="price_max"
  23. :price-min="price_min"
  24. :price-member-max="price_member_max"
  25. :price-member-min="price_member_min"
  26. :discount='discount'
  27. :is-vip-card-user="is_vip_card_user"
  28. :sales="sales"
  29. :is-vip="is_vip"
  30. :unit="unit"
  31. :is-sales="is_sales"
  32. :goods-id="goodsId"
  33. :extra-quick-share="extra_quick_share"
  34. :app-share-pic="app_share_pic ? app_share_pic: goods.pic_url[0].pic_url"
  35. :app-share-title="app_share_title ? app_share_title : name"
  36. :poster-config="poster_config + `&goods_id=` + goodsId"
  37. :poster-generate="poster_generate + `&goods_id=` + goodsId"
  38. :has-poster-nav="true"
  39. v-bind:goods="goods"
  40. @share="hShareAppMessage"
  41. @quickShare="quickShare"
  42. :limit-buy="limit_buy"
  43. :min-number="min_number"
  44. :origin_icon="origin_icon"
  45. :origin_name="origin_name"
  46. :goods_type="goods_type"
  47. :trade_name="trade_name"
  48. :brand_logo="brand_logo"
  49. :brand_name="brand_name"
  50. ></bd-info>
  51. </view>
  52. <!--商品优惠券-->
  53. <bd-coupon @change="setCoupon" :theme="getTheme" :coupons="goods_coupon_center"></bd-coupon>
  54. <!--商品规格-->
  55. <bd-xbc
  56. :coAttr="is_open == 1 && exchangeStatus ==null ? 1 : 0"
  57. :attr-list="checked && checked.attr_list"
  58. :type="goodsType"
  59. :guarantee-title="guarantee_title"
  60. :guarantee-pic="guarantee_pic"
  61. :param_content="param_content"
  62. :param_name="param_name"
  63. :services="services"
  64. :attr-groups="attr_groups"
  65. :goods-stock="goods_num"
  66. @openAttr="clickAttr"
  67. ></bd-xbc>
  68. <!--商品信息-->
  69. <bd-hc
  70. :integral="goods_marketing_award.integral"
  71. :coupon="goods_marketing_award.coupon"
  72. :card="goods_marketing_award.card"
  73. :balance="goods_marketing_award.balance"
  74. :theme="getTheme"
  75. ></bd-hc>
  76. <bd-kb
  77. :limit="goods_marketing.limit"
  78. :express="express"
  79. :shipping="goods_marketing.shipping"
  80. :pickup="goods_marketing.pickup"
  81. ></bd-kb>
  82. <!--套餐组合-->
  83. <view @click="toComposition" class="goods-composition" v-if="composition && composition.list.length > 0">
  84. <view class="goods-composition-title">套餐组合</view>
  85. <uni-swiper-dot :current="current" :theme="getTheme" :info="composition.list" mode="customize">
  86. <swiper @change="change" class="goods-composition-swiper" :current="current" :autoplay="true">
  87. <swiper-item v-for="item in composition.list" :key="item.id">
  88. <app-composition :theme="getTheme" @click="toComposition(item)" @look="toComposition(item)" :item="item"></app-composition>
  89. </swiper-item>
  90. </swiper>
  91. </uni-swiper-dot>
  92. <view class="goods-composition-more main-between cross-center">
  93. <view>更多套餐组合</view>
  94. <image src="/static/image/icon/arrow-right.png"></image>
  95. </view>
  96. </view>
  97. <bd-comments :goods-id="goodsId"></bd-comments>
  98. <!--商品详情-->
  99. <bd-detail :detail="detail"></bd-detail>
  100. <!--相关推荐-->
  101. <app-goods-recommend :sureCart="true" :theme="getTheme" :goods-list="recommend_list"></app-goods-recommend>
  102. <!--空格区域-->
  103. <view class="safe-area-inset-bottom u-bottom">
  104. <view class="u-bottom-height" :class="uBottomHeight"></view>
  105. </view>
  106. <!--底部按钮-->
  107. <view v-if="is_open == 1" class="safe-area-inset-bottom u-bottom-fixed">
  108. <view v-if="full_reduce && exchangeStatus == null">
  109. <app-goods-full-reduce
  110. :theme="getTheme"
  111. :full_reduce="full_reduce"
  112. :sign="goodsType === 'goods' ? '' : 1"
  113. >
  114. </app-goods-full-reduce>
  115. </view>
  116. <view v-if="exchangeStatus == null && sell_time > 0">
  117. <app-sell-tip :time="sell_time" @changeTime="changeTime"></app-sell-tip>
  118. </view>
  119. <view class="bd-bottom u-bottom-height-0 cross-center dir-left-nowrap" >
  120. <template v-if="exchangeStatus == null">
  121. <view class="bd-back dir-top-nowrap main-center cross-center box-grow-0" @click="back">
  122. <image class="bd-icon" src="../../static/image/icon/index.png"></image>
  123. <text class="bd-text">首页</text>
  124. </view>
  125. <template v-if="is_negotiable !== 1">
  126. <bd-service :name="name" :url="sendPath"></bd-service>
  127. </template>
  128. <view class="bd-back dir-top-nowrap main-center cross-center box-grow-0" @click="setFavorite">
  129. <image class="bd-icon" :src="favorite ? '../../static/image/icon/icon-favorite-active.png' : '../../static/image/icon/icon-favorite.png'"></image>
  130. <text class="bd-text">收藏</text>
  131. </view>
  132. <template v-if="is_negotiable !== 1">
  133. <view class="box-grow-1 bd-btn bd-btn-color " :class="[disableBtn]" v-if="goods_num === 0 || is_finish_sell">
  134. {{is_finish_sell ? '商品已下架' : '已售罄'}}
  135. </view>
  136. <view class="box-grow-1 dir-left-nowrap" v-else>
  137. <!-- <view v-if="goods.type === 'goods'"
  138. @click="clickAttr(0)"
  139. :style="{'background': !goods || goods.buy_goods_auth ? getTheme.background_s_gradient_btn : '#999999','color': !goods || goods.buy_goods_auth ? getTheme.secondary_text : '#ffffff'}"
  140. :class="['bd-btn', leftTip
  141. ]"
  142. >
  143. 加入购物车
  144. </view> -->
  145. <view v-if="goods.type === 'goods'"
  146. @click="clickAttr(0)"
  147. :style="{'background': getTheme.background_s_gradient_btn,'color': getTheme.secondary_text}"
  148. :class="['bd-btn', leftTip
  149. ]"
  150. >
  151. 加入购物车
  152. </view>
  153. <view :class="[goods.type === 'goods' ? 'bd-btn-right bd-btn-half' : 'box-grow-1']" v-if="!(isTip == 0 && sell_time > 0)">
  154. <app-jump-button form>
  155. <!-- <view
  156. @click="clickAttr(1)"
  157. :style="{'background': goods.buy_goods_auth ? getTheme.background_gradient_btn : '#999999','color': goods.buy_goods_auth ? getTheme.main_text : ''}"
  158. :class="['bd-btn', 'bd-btn-color', 'box-grow-1', goods.type === 'goods' ? 'bd-btn-right' : '']"
  159. >{{rightRemindText}}
  160. </view>
  161. -->
  162. <view
  163. @click="clickAttr(1)"
  164. :style="{'background': getTheme.background_gradient_btn ,'color':getTheme.main_text}"
  165. :class="['bd-btn', 'bd-btn-color', 'box-grow-1', goods.type === 'goods' ? 'bd-btn-right' : '']"
  166. >{{rightRemindText}}
  167. </view>
  168. </app-jump-button>
  169. </view>
  170. </view>
  171. </template>
  172. <view class="box-grow-1 dir-left-nowrap bd-btn-tel" v-else>
  173. <block v-for="(item, index) in good_negotiable" :key="index">
  174. <view class="tel"
  175. v-if="item === 'contact_tel'"
  176. @click="makePhoneCall(mall.setting.contact_tel)"
  177. :style="{'background': good_negotiable.length === 1 ? getTheme.background_gradient_btn : getTheme.background_s_gradient_btn,'color': good_negotiable.length === 2 ? getTheme.color : ''}"
  178. :class="[good_negotiable.length === 1 ? 'all-radius all-width text ' : '', good_negotiable.length === 3 ? 'bd-three-one text ' : '', good_negotiable.length === 2 ? 'bd-btn-half' : '']"
  179. >
  180. 联系电话
  181. </view>
  182. <!-- #ifndef MP-TOUTIAO || MP-ALIPAY || H5 -->
  183. <button v-else-if="item === 'contact'"
  184. open-type="contact"
  185. show-message-card
  186. :send-message-title="name"
  187. :send-message-path="sendPath"
  188. :style="contactBtnStyle"
  189. class="contact" :class="contactBtn">
  190. 客服
  191. </button>
  192. <!-- #endif -->
  193. <view class="service"
  194. v-else-if="item === 'contact_web'"
  195. @click="router('/pages/web/web?url=' + encodeURIComponent(mall.setting.web_service_url))"
  196. :style="{'background': good_negotiable.length !== 3 ? getTheme.background_gradient_btn : '','color': good_negotiable.length === 1 ? getTheme.secondary_text : ''}"
  197. :class="good_negotiable.length === 3 ? 'default-bakground bd-three-one ' : good_negotiable.length === 2 ? 'bd-btn-half text ' : ' all-radius all-width '" >
  198. 客服
  199. </view>
  200. </block>
  201. </view>
  202. </template>
  203. <template v-else>
  204. <view v-if="exchangeStatus == 0" @click="toExchange" class="box-grow-1 bd-exchange" :style="{'background': getTheme.background_gradient_o}">
  205. 立即领取
  206. </view>
  207. <view class="box-grow-1 bd-exchange bd-over" v-else-if="exchangeStatus == 1">
  208. 已领取
  209. </view>
  210. </template>
  211. </view>
  212. </view>
  213. <!--快捷导航-->
  214. <app-quick-navigation></app-quick-navigation>
  215. <u-attr
  216. v-if="is_negotiable === 0 && exchangeStatus ==null"
  217. v-model="attrShow"
  218. :goods="goods"
  219. :theme="getTheme"
  220. :checked="checked"
  221. @check="check"
  222. >
  223. </u-attr>
  224. </template>
  225. <app-close v-if="showClose" :modal="false" @update="getMall"></app-close>
  226. </app-layout>
  227. </template>
  228. <script>
  229. import {mapGetters, mapState} from "vuex";
  230. import appGoodsBanner from "../../components/page-component/goods/app-goods-banner.vue";
  231. import appGoodsRecommend from "../../components/page-component/app-goods-recommend/app-goods-recommend.vue";
  232. import appQuickNavigation from "../../components/page-component/app-quick-navigation/app-quick-navigation.vue";
  233. import appComposition from'../../components/basic-component/app-composition/app-composition.vue';
  234. import uniSwiperDot from '../../components/basic-component/uni-swiper-dot/uni-swiper-dot';
  235. import uAttr from '../../components/page-component/goods/u-attr.vue';
  236. import appGoodsFullReduce from '../../components/page-component/goods/app-goods-full-reduce.vue';
  237. import bdInfo from '@/components/page-component/goods/bd-info';
  238. import bdCoupon from '@/components/page-component/goods/bd-coupon.vue';
  239. import bdXbc from '@/components/page-component/goods/bd-xbc.vue';
  240. import bdKb from '@/components/page-component/goods/bd-kb.vue';
  241. import bdHc from '@/components/page-component/goods/bd-hc.vue';
  242. import bdDetail from '@/components/page-component/goods/bd-detail.vue';
  243. import bdComments from '@/components/page-component/goods/bd-comments.vue';
  244. import appClose from '@/components/basic-component/app-close/app-close.vue';
  245. import bdService from '@/components/page-component/goods/bd-service.vue';
  246. import bdFlashSale from '@/components/page-component/goods/bd-flash-sale.vue';
  247. import appSellTip from '@/components/page-component/goods/app-sell-tip.vue';
  248. import goodsMixin from '@/core/goods-mixin.js';
  249. export default {
  250. name: "goods",
  251. mixins: [goodsMixin],
  252. components: {
  253. appGoodsBanner,
  254. 'app-goods-recommend': appGoodsRecommend,
  255. 'app-quick-navigation': appQuickNavigation,
  256. 'app-composition': appComposition,
  257. appClose,
  258. uniSwiperDot,
  259. appGoodsFullReduce,
  260. uAttr,
  261. bdInfo,
  262. bdCoupon,
  263. bdXbc,
  264. bdKb,
  265. bdHc,
  266. bdDetail,
  267. bdComments,
  268. bdService,
  269. bdFlashSale,
  270. appSellTip
  271. },
  272. data() {
  273. return {
  274. showClose: false,
  275. is_open: 0,
  276. goods: null,
  277. selectAttr: null,
  278. recommend_list: null,
  279. is_vip: false,
  280. is_vip_card_user: 0,
  281. current: 0,
  282. discount: null,
  283. attrShow: false,
  284. shareData: null,
  285. contact_tel:'',
  286. contact: '',
  287. contact_web:'',
  288. sendPath: '',
  289. poster_config: this.$api.goods.poster,
  290. poster_generate: this.$api.poster.goods_new,
  291. // 限时抢购
  292. flash_sale: null,
  293. checked: null,
  294. // 商品服务
  295. services: null,
  296. // 商品详情
  297. detail: null,
  298. // 商品ID
  299. goodsId: null,
  300. // 套餐组合
  301. composition: null,
  302. autoplay: true,
  303. full_reduce: null,
  304. goods_marketing_award: null,
  305. express: null,
  306. goods_marketing: null,
  307. exchangeStatus: null,
  308. exchange: null,
  309. price: null,
  310. level_show: null,
  311. sales: null,
  312. unit: null,
  313. is_sales: null,
  314. extra_quick_share: null,
  315. price_max: null,
  316. price_min: null,
  317. price_member_max: null,
  318. price_member_min: null,
  319. original_price: null,
  320. subtitle: null,
  321. is_negotiable: null,
  322. name: null,
  323. app_share_pic: null,
  324. app_share_title: null,
  325. goodsType: null,
  326. favorite: null,
  327. goods_coupon_center: null,
  328. guarantee_title: null,
  329. guarantee_pic: null,
  330. param_content: null,
  331. param_name: null,
  332. attr_groups: null,
  333. goods_num: null,
  334. good_stock: null,
  335. min_number: null,
  336. limit_buy: null,
  337. disable: 'disable',
  338. sell_time: 0,
  339. template_message_list: [],
  340. is_finish_sell: false,
  341. origin_icon:null,
  342. origin_name:null,
  343. goods_type:0,
  344. trade_name:null,
  345. brand_logo:null,
  346. brand_name:null
  347. };
  348. },
  349. computed: {
  350. ...mapState({
  351. mall: state => state.mallConfig.mall,
  352. gConfig: state => state.gConfig,
  353. isTip: state => state.mallConfig.mall.setting.is_remind_sell_time
  354. }),
  355. ...mapGetters('mallConfig', {
  356. getTheme: 'getTheme',
  357. }),
  358. good_negotiable: function() {
  359. let good_negotiable = this.mall.setting.good_negotiable;
  360. this.contact_tel = '';
  361. this.contact = '';
  362. this.contact_web = '';
  363. let arr = [];
  364. for (let i = 0; i < good_negotiable.length; i++) {
  365. if (good_negotiable[i] === 'contact_tel') {
  366. this.contact_tel = 'contact_tel';
  367. }
  368. // #ifndef MP-TOUTIAO || MP-ALIPAY || H5
  369. if (good_negotiable[i] === 'contact') {
  370. this.contact = 'contact';
  371. }
  372. // #endif
  373. if (good_negotiable[i] === 'contact_web') {
  374. this.contact_web = 'contact_web';
  375. }
  376. }
  377. if (this.contact_tel) {
  378. arr.push(this.contact_tel);
  379. }
  380. if (this.contact) {
  381. arr.push(this.contact);
  382. }
  383. if (this.contact_web) {
  384. arr.push(this.contact_web);
  385. }
  386. return arr;
  387. },
  388. contactBtnStyle: function() {
  389. const len = this.good_negotiable.length;
  390. const theme = this.getTheme.key;
  391. if (len === 3 && (theme === 'a' || theme === 'b' || theme === 'f')) {
  392. return `background:${this.getTheme.background_gradient_btn}`;
  393. } else if (len === 3 && !(theme === 'a' || theme === 'b' || theme === 'f')) {
  394. return `background:${this.getTheme.background_gradient_btn};color:${this.getTheme.background_s}`;
  395. } if (len === 2 && (theme === 'a' || theme === 'b' || theme === 'f') && !this.contact_tel) {
  396. return `background:${this.getTheme.background_s_gradient_btn};`;
  397. } else if (len === 2 && (theme === 'a' || theme === 'b' || theme === 'f') && this.contact_tel) {
  398. return `background:${this.getTheme.background}`;
  399. } else if (len === 2 && !(theme === 'a' || theme === 'b' || theme === 'f') && !this.contact_tel) {
  400. return `background:${this.getTheme.background_s_gradient_btn};color:${this.getTheme.background_s}`;
  401. } else if (len === 2 && !(theme === 'a' || theme === 'b' || theme === 'f') && this.contact_tel) {
  402. return `background:${this.getTheme.background_gradient_btn};color:${this.getTheme.background_s}`;
  403. } else {
  404. return `background:${this.getTheme.background_gradient_btn}`;
  405. }
  406. },
  407. uBottomHeight() {
  408. if (this.full_reduce && this.sell_time > 0) {
  409. return 'u-bottom-height-2';
  410. } else if (this.full_reduce || this.sell_time > 0) {
  411. return 'u-bottom-height-1';
  412. } else {
  413. return 'u-bottom-height-0';
  414. }
  415. },
  416. leftTip() {
  417. let leftTip = '';
  418. if (!(this.isTip == 0 && this.sell_time > 0)) {
  419. leftTip = 'bd-btn-left bd-btn-half';
  420. } else {
  421. leftTip = 'box-grow-1';
  422. }
  423. return this.goods && this.goods.type === 'goods' ? leftTip : '';
  424. },
  425. disableBtn() {
  426. return this.is_finish_sell ? 'btn-finish-sell' : 'bd-oversell-btn';
  427. },
  428. contactBtn: function() {
  429. const len = this.good_negotiable.length;
  430. const theme = this.getTheme.key;
  431. if (len === 3 && (theme === 'a' || theme === 'b' || theme === 'f')) {
  432. return `text bd-three-one bd-no-radius `;
  433. } else if (len === 3 && !(theme === 'a' || theme === 'b' || theme === 'f')) {
  434. return `bd-three-one bd-no-radius `;
  435. } if (len === 2 && (theme === 'a' || theme === 'b' || theme === 'f') && !this.contact_tel) {
  436. return `text bd-btn-half bd-content-radius-0`;
  437. } else if (len === 2 && (theme === 'a' || theme === 'b' || theme === 'f') && this.contact_tel) {
  438. return `bd-btn-half bd-content-radius-1`;
  439. } else if (len === 2 && !(theme === 'a' || theme === 'b' || theme === 'f') && !this.contact_tel) {
  440. return `bd-btn-half bd-content-radius-0`;
  441. } else if (len === 2 && !(theme === 'a' || theme === 'b' || theme === 'f') && this.contact_tel) {
  442. return `bd-btn-half bd-content-radius-1`;
  443. } else {
  444. return `text all-width all-radius `;
  445. }
  446. }
  447. },
  448. onLoad(options) { this.$commonLoad.onload(options);
  449. // #ifdef MP-WEIXIN
  450. wx.showShareMenu({
  451. menus: ['shareAppMessage', 'shareTimeline']
  452. })
  453. // #endif
  454. if (this.isLogin) {
  455. this.$store.dispatch('user/info');
  456. }
  457. this.goodsId = options.id;
  458. // #ifndef MP-ALIPAY
  459. this.loadData(this.goodsId, options);
  460. // #endif
  461. this.sendPath = '/pages/goods/goods?id=' + options.id;
  462. console.log(this.sendPath)
  463. if(options && options.exchange) {
  464. this.exchangeStatus = options.exchange;
  465. this.exchange = options;
  466. }
  467. },
  468. onShow() {
  469. this.autoplay = true;
  470. this.showClose = false;
  471. setTimeout(()=>{
  472. this.showClose = true;
  473. // #ifdef MP-ALIPAY
  474. this.loadData(this.goodsId, this.exchange);
  475. // #endif
  476. });
  477. },
  478. onHidden() {
  479. this.autoplay = false;
  480. },
  481. // #ifdef MP-WEIXIN
  482. onShareTimeline() {
  483. // 分享朋友圈beta
  484. return this.$shareTimeline({
  485. title: this.app_share_title ? this.app_share_title : this.name,
  486. imageUrl: this.goods.pic_url[0].pic_url,
  487. query: {
  488. id: this.goodsId
  489. }
  490. });
  491. },
  492. // #endif
  493. methods: {
  494. hShareAppMessage(s = false) {
  495. return this.$shareAppMessage({
  496. title: this.app_share_title ? this.app_share_title : this.name,
  497. imageUrl: this.app_share_pic ? this.app_share_pic : this.goods.pic_url[0].pic_url,
  498. path: '/pages/goods/goods',
  499. desc: this.subtitle,
  500. params: {
  501. id: this.goodsId
  502. }
  503. }, s);
  504. },
  505. getMall(e) {
  506. this.is_open = e.is_open;
  507. },
  508. toExchange() {
  509. let mch_list = [{
  510. mch_id: 0,
  511. goods_list: [{
  512. id: this.exchange.id,
  513. attr: this.exchange.attr,
  514. num: this.exchange.goods_num,
  515. cat_id: 0,
  516. goods_attr_id: this.exchange.attr_id
  517. }],
  518. code: this.exchange.code,
  519. token: this.exchange.token,
  520. }];
  521. let url = `/pages/order-submit/order-submit?mch_list=${JSON.stringify(mch_list)}`;
  522. url += `&preview_url=${encodeURIComponent(this.$api.exchange.exchange_preview)}&submit_url=${encodeURIComponent(this.$api.exchange.exchange_submit)}&plugin=exchange`;
  523. uni.navigateTo({
  524. url: url
  525. })
  526. },
  527. // 规格选择
  528. check({item}) {
  529. this.checked = item;
  530. },
  531. change(e) {
  532. if(e.detail.source === 'touch') {
  533. this.current = e.detail.current;
  534. }
  535. if(e.detail.source === 'autoplay') {
  536. this.current = e.detail.current;
  537. }
  538. },
  539. quickShare(info) {
  540. this.shareData = info;
  541. //#ifdef H5
  542. this.$shareAppMessage(this.shareData, true);
  543. // #endif
  544. },
  545. toComposition(item) {
  546. let id = item.id > 0 ? item.id : this.composition.list[0].id
  547. uni.navigateTo({
  548. url: this.composition.url + '?goods_id=' + this.goodsId + '&composition_id=' + id
  549. })
  550. },
  551. loadData(id, options) {
  552. return new Promise((resolve, reject) => {
  553. this.$showLoading();
  554. this.$request({
  555. url: this.$api.goods.detail,
  556. data: {
  557. id: id,
  558. plugin: options && options.exchange ? 'exchange' : 'mall'
  559. }
  560. }).then(response => {
  561. this.$hideLoading();
  562. if (response.code === 0) {
  563. let { services,
  564. detail, name,
  565. vip_card_appoint, plugin_extra, id,
  566. goods_activity, goods_marketing_award,
  567. goods_marketing, express,
  568. price, sales,
  569. level_show, is_sales, unit, extra_quick_share,
  570. price_max, price_min, price_member_max,
  571. price_member_min, original_price, subtitle,
  572. is_negotiable, app_share_title,
  573. app_share_pic, type, favorite, goods_coupon_center,
  574. guarantee_title, guarantee_pic, param_content,
  575. param_name, attr_groups, goods_num, good_stock,
  576. min_number, limit_buy, sell_time, template_message_list,
  577. is_finish_sell,origin_icon,origin_name,goods_type,trade_name,brand_logo,brand_name
  578. } = response.data.goods;
  579. uni.setNavigationBarTitle({
  580. title: name
  581. });
  582. this.name = name;
  583. this.app_share_pic = app_share_pic;
  584. this.app_share_title = app_share_title;
  585. this.goods = response.data.goods;
  586. this.services = services;
  587. this.detail = detail;
  588. this.goodsId = id;
  589. this.flash_sale = plugin_extra.flash_sale;
  590. this.composition = plugin_extra.composition;
  591. this.goods_marketing_award = goods_marketing_award;
  592. this.goods_marketing = goods_marketing;
  593. this.express = express;
  594. this.price = price;
  595. this.level_show = level_show;
  596. this.sales = sales;
  597. this.unit = unit;
  598. this.is_sales = is_sales;
  599. this.price_max = price_max;
  600. this.price_min = price_min;
  601. this.price_member_max = price_member_max;
  602. this.price_member_min = price_member_min;
  603. this.original_price = original_price;
  604. this.subtitle = subtitle;
  605. this.is_negotiable = is_negotiable;
  606. this.extra_quick_share = extra_quick_share;
  607. this.goodsType = type;
  608. this.favorite = favorite;
  609. this.goods_coupon_center = goods_coupon_center;
  610. this.guarantee_title = guarantee_title;
  611. this.param_content = param_content;
  612. this.guarantee_pic = guarantee_pic;
  613. this.attr_groups = attr_groups;
  614. this.param_name = param_name;
  615. this.goods_num = goods_num;
  616. this.good_stock = good_stock;
  617. this.min_number = min_number;
  618. this.limit_buy = limit_buy;
  619. this.sell_time = sell_time;
  620. this.template_message_list = template_message_list;
  621. this.is_finish_sell = is_finish_sell;
  622. this.origin_icon = origin_icon;
  623. this.origin_name = origin_name;
  624. this.goods_type = goods_type;
  625. this.trade_name = trade_name;
  626. this.brand_logo = brand_logo;
  627. this.brand_name = brand_name;
  628. if (goods_activity) {
  629. this.full_reduce = goods_activity.full_reduce;
  630. }
  631. if(vip_card_appoint.discount || vip_card_appoint.discount === '0.00') {
  632. this.is_vip = true;
  633. this.discount = vip_card_appoint.discount
  634. }
  635. this.is_vip_card_user = vip_card_appoint.is_vip_card_user;
  636. this.loadRecommend();
  637. // #ifdef H5
  638. this.hShareAppMessage();
  639. // #endif
  640. resolve();
  641. } else {
  642. uni.showToast({
  643. title: response.msg,
  644. icon: 'none'
  645. });
  646. reject();
  647. }
  648. }).catch(() => {
  649. reject();
  650. this.$hideLoading();
  651. });
  652. });
  653. },
  654. onAttr(data) {
  655. this.selectAttr = data;
  656. },
  657. loadRecommend() {
  658. this.$request({
  659. url: this.$api.goods.new_recommend,
  660. data: {
  661. goods_id: this.goodsId,
  662. type: 'goods'
  663. }
  664. }).then(response => {
  665. if (response.code === 0) {
  666. this.recommend_list = response.data.list;
  667. }
  668. });
  669. },
  670. back() {
  671. uni.reLaunch({
  672. url: '/pages/index/index'
  673. });
  674. },
  675. setFavorite() {
  676. let url = this.$api.user.favorite_add;
  677. let favorite = true;
  678. if (this.favorite) {
  679. url = this.$api.user.favorite_remove;
  680. favorite = false;
  681. }
  682. this.favorite = favorite;
  683. this.$request({
  684. url: url,
  685. data: {
  686. goods_id: this.goodsId
  687. }
  688. }).then(response => {
  689. if (response.code === 0) {
  690. } else {
  691. uni.showModal({
  692. title: '提示',
  693. content: response.msg,
  694. showCancel: false
  695. });
  696. }
  697. });
  698. },
  699. clickAttr(data) {
  700. if (data === 1 && this.sell_time > 0) {
  701. this.rightTip();
  702. return ;
  703. }
  704. if (!this.goods.buy_goods_auth) {
  705. // this.$tips.showToast({
  706. // title: '您暂无权限购买该商品',
  707. // icon: 'none'
  708. // });
  709. uni.showModal({
  710. title: '提示',
  711. content: '加入会员购买商品哦~亲~',
  712. success: function (res) {
  713. if (res.confirm) {
  714. uni.navigateTo({
  715. open_type: 'navigate',
  716. url: '/pages/member/index/index'
  717. })
  718. }
  719. }
  720. })
  721. return;
  722. }
  723. if (this.goods.type === 'ecard' && data === 0) {
  724. this.$tips.showToast({
  725. title: '虚拟商品不允许加入购物车',
  726. icon: 'none'
  727. });
  728. return;
  729. }
  730. this.attrShow = true;
  731. },
  732. setCoupon(index) {
  733. this.$set(this.goods_coupon_center[index], 'is_receive', 1);
  734. },
  735. router(url) {
  736. uni.navigateTo({
  737. url: url
  738. })
  739. },
  740. makePhoneCall(number) {
  741. uni.makePhoneCall({
  742. phoneNumber: number
  743. });
  744. },
  745. changeTime(time) {
  746. this.sell_time = time;
  747. this.goods.sell_time = time;
  748. }
  749. },
  750. // #ifdef MP
  751. onShareAppMessage(object) {
  752. if (object.from === 'button' && this.shareData) {
  753. return this.$shareAppMessage(this.shareData);
  754. }
  755. return this.hShareAppMessage();
  756. },
  757. // #endif
  758. }
  759. </script>
  760. <style scoped lang="scss">
  761. .goods-composition {
  762. width: 702upx;
  763. margin: 20upx 20upx 0 20upx;
  764. padding: 20rpx;
  765. background-color: #fff;
  766. border-radius: 15upx;
  767. .goods-composition-title {
  768. font-size: 28rpx;
  769. color: #353535;
  770. margin-bottom: 20rpx;
  771. }
  772. .goods-composition-swiper {
  773. height: 194rpx;
  774. }
  775. .goods-composition-more {
  776. margin: 20rpx auto 4rpx auto;
  777. width: 226rpx;
  778. padding: 0 24rpx;
  779. height: 56rpx;
  780. line-height: 54rpx;
  781. border-radius: 28rpx;
  782. border: 2rpx solid #bbbbbb;
  783. font-size: 24rpx;
  784. color: #999999;
  785. image {
  786. width: #{12rpx};
  787. height: #{22rpx};
  788. }
  789. }
  790. }
  791. .goods-name {
  792. padding: 24upx 24upx 0 24upx;
  793. background-color: #ffffff;
  794. color: #353535;
  795. font-size: 32upx;
  796. line-height: 42upx;
  797. }
  798. .goods-subtitle {
  799. padding: #{24rpx 24rpx 0 24rpx};
  800. font-size: 24rpx;
  801. background-color: #ffffff;
  802. color: #999999;
  803. }
  804. .price {
  805. padding-top: #{24rpx};
  806. background-color: #ffffff;
  807. }
  808. .vip-card {
  809. padding-bottom: #{20rpx};
  810. background-color: #fff;
  811. }
  812. .attr {
  813. background-color: #f7f7f7;
  814. }
  815. .bottom {
  816. width: 100%;
  817. height: #{110rpx};
  818. }
  819. .bd-bottom {
  820. width: 750upx;
  821. height: 110upx;
  822. padding: 20upx 24upx;
  823. }
  824. .bd-back {
  825. width: 66upx;
  826. height: 100%;
  827. margin-right: 20upx;
  828. }
  829. .bd-icon {
  830. width: 30upx;
  831. height: 30upx;
  832. margin-bottom: 8upx;
  833. }
  834. .bd-text {
  835. font-size: 20upx;
  836. color: #888888;
  837. line-height: 1;
  838. }
  839. .bd-btn {
  840. text-align: center;
  841. line-height: 70upx;
  842. font-size: 28upx;
  843. border-radius: 35upx;
  844. }
  845. .bd-btn-left {
  846. border-top-right-radius: 0;
  847. border-bottom-right-radius: 0;
  848. }
  849. .bd-btn-right {
  850. border-top-left-radius: 0;
  851. border-bottom-left-radius: 0;
  852. }
  853. .bd-btn-half {
  854. width: 50%;
  855. }
  856. .bd-btn-color {
  857. color: #ffffff;
  858. }
  859. .bd-oversell-btn {
  860. background-color: #CDCDCD;
  861. }
  862. .bd-content-radius-0 {
  863. border-radius: 35upx 0 0 35upx;
  864. }
  865. .bd-content-radius-1 {
  866. border-radius:0 35upx 35upx 0;
  867. }
  868. .bd-btn-tel {
  869. font-size: 26upx;
  870. >view {
  871. line-height: 70upx;
  872. text-align: center;
  873. }
  874. .tel {
  875. border-top-left-radius: 35upx;
  876. border-bottom-left-radius: 35upx;
  877. }
  878. .contact {
  879. padding: 0;
  880. font-size: 26upx;
  881. height: 70upx;
  882. line-height: 70upx;
  883. margin: 0;
  884. border: none;
  885. }
  886. .service {
  887. border-top-right-radius: 35upx;
  888. border-bottom-right-radius: 35upx;
  889. }
  890. .all-radius {
  891. border-radius: 35upx;
  892. }
  893. .all-width {
  894. width: 100%;
  895. }
  896. .bd-three-one {
  897. width: calc(100%/3);
  898. }
  899. .bd-no-radius {
  900. border-radius: 0;
  901. }
  902. }
  903. .bd-exchange {
  904. line-height: 70upx;
  905. font-size: #{28rpx};
  906. text-align: center;
  907. color: #fff;
  908. border-radius: 35upx;
  909. &.bd-over {
  910. background: #e9e9e9;
  911. color: #999999;
  912. }
  913. }
  914. .text {
  915. color: #ffffff;
  916. }
  917. .default-bakground {
  918. background-color: #446dfd;
  919. color: #ffffff;
  920. }
  921. .u-bottom-fixed {
  922. position: fixed;
  923. bottom: 0;
  924. left: 0;
  925. width: 100%;
  926. z-index: 1500;
  927. background-color: #ffffff;
  928. box-shadow: 0 -1rpx 20rpx -15rpx #353535;
  929. }
  930. .u-bottom-height-0 {
  931. height: 110upx;
  932. }
  933. .u-bottom-height-1 {
  934. height: 190upx;
  935. }
  936. .u-bottom-height-2 {
  937. height: 270upx;
  938. }
  939. .goods-margin {
  940. margin-top: 20upx;
  941. }
  942. .bd-goods {
  943. margin: 24 upx 24 upx 24 upx 24 upx;
  944. }
  945. .ecard-text {
  946. color: #999999;
  947. }
  948. .bd-content {
  949. padding: 0;
  950. display: block;
  951. background-color: #ffffff;
  952. }
  953. .bd-content-view {
  954. width:100%;
  955. height: 100%;
  956. }
  957. .btn-finish-sell {
  958. background: linear-gradient(to right, rgba(153, 153, 153, 1), rgba(153, 153, 153, 0.7)) ;
  959. }
  960. </style>