小程序端工程代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

997 lines
32 KiB

  1. <template>
  2. <view :class="productConClass">
  3. <view v-if="storeInfo.id">
  4. <!-- 轮播图 -->
  5. <product-con-swiper :img-urls="storeInfo.sliderImageArr"></product-con-swiper>
  6. <!-- 商品信息描述 -->
  7. <view class="wrapper">
  8. <view class="share acea-row row-between row-bottom">
  9. <view class="money font-color-red" v-if="!isIntegral">
  10. <text></text>
  11. <text class="num">{{ attr.productSelect.price || storeInfo.price }}</text>
  12. <text class="vip-money" v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0">{{ attr.productSelect.vipPrice || storeInfo.vipPrice }}</text>
  13. <image :src="`${$VUE_APP_RESOURCES_URL}/images/vip.png`" class="image" v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0" />
  14. </view>
  15. <view class="money font-color-red" v-if="isIntegral">
  16. <text class="num">{{ attr.productSelect.integral || storeInfo.integral }}积分</text>
  17. </view>
  18. <view class="iconfont icon-fenxiang" @click="listenerActionSheet"></view>
  19. </view>
  20. <view class="introduce">{{ storeInfo.storeName }}</view>
  21. <view class="label acea-row row-between-wrapper">
  22. <text v-if="!isIntegral">原价:{{ storeInfo.otPrice }}</text>
  23. <text>库存:{{ storeInfo.stock }}{{ storeInfo.unitName }}</text>
  24. <text>销量:{{ storeInfo.sales }}{{ storeInfo.unitName }}</text>
  25. </view>
  26. <view class="coupon acea-row row-between-wrapper" @click="couponTap" v-if="couponList.length">
  27. <text class="hide line1">
  28. <text>优惠券</text>
  29. <text class="activity" v-for="(item, couponListEq) in couponList" :key="couponListEq">{{ item.useMinPrice }}{{ item.couponPrice }}</text>
  30. </text>
  31. <view class="iconfont icon-jiantou"></view>
  32. </view>
  33. </view>
  34. <!-- 运费 -->
  35. <div class="attribute acea-row row-between-wrapper">
  36. <div>
  37. 运费
  38. <span class="atterTxt">{{ tempName }}</span>
  39. </div>
  40. </div>
  41. <!-- 规格 -->
  42. <view class="attribute acea-row row-between-wrapper" @click="selecAttrTap">
  43. <view>
  44. <text>{{ attrTxt }}</text>
  45. <text class="atterTxt">{{ attrValue }}</text>
  46. </view>
  47. <view class="iconfont icon-jiantou"></view>
  48. </view>
  49. <!-- 门店信息 -->
  50. <view class="store-info" v-if="systemStore">
  51. <view class="title acea-row row-between-wrapper">
  52. <view>门店信息</view>
  53. <text @click="goStoreList()" class="praise">
  54. 更多
  55. <text class="iconfont icon-jiantou"></text>
  56. </text>
  57. </view>
  58. <view class="info acea-row row-between-wrapper">
  59. <view class="picTxt acea-row row-between-wrapper">
  60. <view class="pictrue">
  61. <image :src="systemStore.image" />
  62. </view>
  63. <view class="text">
  64. <view class="name line1">{{ systemStore.name }}</view>
  65. <view class="address acea-row row-middle" @click="showChang(systemStore)">
  66. <text class="addressTxt">{{ systemStore.address }}</text>
  67. <text class="iconfont icon-youjian"></text>
  68. </view>
  69. </view>
  70. <view class="addressBox">
  71. <a class="iconfont icon-dadianhua01 font-color-red phone" @click="telPhone(systemStore.phone)"></a>
  72. <view class="addressTxt corlor-yshop">距离{{ systemStore.distance }}千米</view>
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. <!-- 用户评价 -->
  78. <view class="userEvaluation" v-if="replyCount">
  79. <view class="title acea-row row-between-wrapper">
  80. <view>用户评价({{ replyCount }})</view>
  81. <text @click="goEvaluateList(id)" class="praise">
  82. <text class="font-color-red">{{ replyChance }}%</text>好评率
  83. <text class="iconfont icon-jiantou"></text>
  84. </text>
  85. </view>
  86. <user-evaluation :reply="reply"></user-evaluation>
  87. </view>
  88. <!-- 商品推荐 -->
  89. <!-- <view class="superior">
  90. <view class="title acea-row row-center-wrapper">
  91. <image :src="`${$VUE_APP_RESOURCES_URL}/images/ling.png`" />
  92. <text class="titleTxt">优品推荐</text>
  93. <image :src="`${$VUE_APP_RESOURCES_URL}/images/ling.png`" />
  94. </view>
  95. <template>
  96. <view class="slider-banner banner">
  97. <swiper :options="swiperRecommend" v-if="goodList.length > 0">
  98. <swiper-slide v-for="(item, eq2) in goodList" :key="eq2">
  99. <view class="list acea-row row-middle">
  100. <view class="item" v-for="val in item.list" :key="val.image">
  101. <view class="pictrue">
  102. <image :src="val.image" />
  103. </view>
  104. <view class="name line1">{{ val.store_name }}}</view>
  105. <view class="money font-color-red">¥{{ val.price }}</view>
  106. </view>
  107. </view>
  108. </swiper-slide>
  109. <view class="swiper-pagination" slot="pagination"></view>
  110. </swiper>
  111. </view>
  112. </template>
  113. </view> -->
  114. <!-- 商品详情 -->
  115. <view class="product-intro">
  116. <text class="title"><text>产品介绍</text></text>
  117. <view class="conter" v-html="storeInfo.description"></view>
  118. </view>
  119. <view style="height: 100rpx"></view>
  120. <!-- 操作栏 -->
  121. <view class="footer acea-row row-between-wrapper">
  122. <!-- #ifdef MP-WEIXIN -->
  123. <view class="item">
  124. <button open-type="contact" class="contacButton">
  125. <view style="padding-bottom: 8rpx" class="item">
  126. <view class="iconfont icon-kefu"></view>
  127. <text>客服</text>
  128. </view>
  129. </button>
  130. </view>
  131. <!-- #endif -->
  132. <view class="item" @click="goHome">
  133. <view class="iconfont icon-shouye-xianxing"></view>
  134. <text>首页</text>
  135. </view>
  136. <view class="item" @click="setCollect" v-if="storeInfo.userCollect">
  137. <view class="iconfont icon-shoucang1"></view>
  138. <text>收藏</text>
  139. </view>
  140. <view class="item" @click="setCollect" v-if="!storeInfo.userCollect">
  141. <view class="iconfont icon-shoucang"></view>
  142. <text>收藏</text>
  143. </view>
  144. <view @click="goShoppingCart()" v-if="animated" class="item animated bounceIn">
  145. <view class="iconfont icon-gouwuche1">
  146. <text class="num bg-color-red" v-if="CartCount > 0">{{ CartCount }}</text>
  147. </view>
  148. <text>购物车</text>
  149. </view>
  150. <view @click="goShoppingCart()" class="item animated" v-if="!animated">
  151. <view class="iconfont icon-gouwuche1">
  152. <text class="num bg-color-red" v-if="CartCount > 0">{{ CartCount }}</text>
  153. </view>
  154. <text>购物车</text>
  155. </view>
  156. <view class="bnt acea-row">
  157. <view class="joinCart" @click="joinCart">
  158. <text>加入购物车</text>
  159. </view>
  160. <view class="buy" @click="tapBuy">
  161. <text>立即购买</text>
  162. </view>
  163. </view>
  164. </view>
  165. <!-- 优惠券 -->
  166. <CouponPop v-on:changeFun="changeFun" :coupon="coupon"></CouponPop>
  167. <!-- 商品规格弹窗 -->
  168. <ProductWindow :isIntegral="isIntegral" v-on:changeFun="changeFun" :attr="attr" :cartNum="cart_num"></ProductWindow>
  169. <!-- 分享海报 -->
  170. <StorePoster v-on:setPosterImageStatus="setPosterImageStatus" :posterImageStatus="posterImageStatus" :posterData="posterData" :goodId="id"></StorePoster>
  171. <!-- 分享弹窗 -->
  172. <ShareInfo v-on:setShareInfoStatus="setShareInfoStatus" :shareInfoStatus="shareInfoStatus"></ShareInfo>
  173. <view class="generate-posters acea-row row-middle on" v-if="posters">
  174. <view class="item" @click="setPosterImageStatus">
  175. <view class="iconfont icon-haibao"></view>
  176. <view>生成海报</view>
  177. </view>
  178. </view>
  179. <view class="generate-posters acea-row row-middle" v-if="!posters">
  180. <view class="item" @click="setPosterImageStatus">
  181. <view class="iconfont icon-haibao"></view>
  182. <view>生成海报</view>
  183. </view>
  184. </view>
  185. <view class="mask" @touchmove.prevent @click="listenerActionClose" v-show="posters"></view>
  186. <view class="posterCanvasWarp">
  187. <canvas class="posterCanvas" canvas-id="myCanvas"></canvas>
  188. </view>
  189. </view>
  190. </view>
  191. </template>
  192. <script>
  193. // import { swiper, swiperSlide } from "vue-awesome-swiper";
  194. import ProductConSwiper from '@/components/ProductConSwiper'
  195. import UserEvaluation from '@/components/UserEvaluation'
  196. import CouponPop from '@/components/CouponPop'
  197. import ProductWindow from '@/components/ProductWindow'
  198. import StorePoster from '@/components/StorePoster'
  199. import ShareInfo from '@/components/ShareInfo'
  200. import { getProductDetail, postCartAdd, getCartCount, getProductCode } from '@/api/store'
  201. import { getCoupon, getCollectAdd, getCollectDel, getUserInfo } from '@/api/user'
  202. import cookie from '@/utils/store/cookie'
  203. import { isWeixin, PosterCanvas, handleQrCode, handleUrlParam, getCurrentPageUrlWithArgs } from '@/utils'
  204. import { wechatEvevt } from '@/libs/wechat'
  205. import { imageBase64 } from '@/api/public'
  206. import { mapGetters } from 'vuex'
  207. export default {
  208. name: 'GoodsCon',
  209. components: {
  210. // swiper,
  211. // swiperSlide,
  212. ProductConSwiper,
  213. UserEvaluation,
  214. CouponPop,
  215. ProductWindow,
  216. StorePoster,
  217. ShareInfo,
  218. },
  219. data: function() {
  220. return {
  221. shareInfoStatus: false,
  222. weixinStatus: false,
  223. mapShow: false,
  224. mapKey: '',
  225. posterData: {
  226. image: '',
  227. title: '',
  228. price: '',
  229. code: '',
  230. },
  231. posterImageStatus: false,
  232. animated: false,
  233. coupon: {
  234. coupon: false,
  235. list: [],
  236. },
  237. attr: {
  238. cartAttr: false,
  239. productAttr: [],
  240. productSelect: {},
  241. },
  242. isOpen: false, //是否打开属性组件
  243. productValue: [],
  244. id: 0,
  245. storeInfo: {},
  246. couponList: [],
  247. attrTxt: '请选择',
  248. attrValue: '',
  249. cart_num: 1, //购买数量
  250. replyCount: '',
  251. replyChance: '',
  252. reply: [],
  253. priceName: 0,
  254. CartCount: 0,
  255. posters: false,
  256. banner: [{}, {}],
  257. swiperRecommend: {
  258. pagination: {
  259. el: '.swiper-pagination',
  260. clickable: true,
  261. },
  262. autoplay: false,
  263. loop: false,
  264. speed: 1000,
  265. observer: true,
  266. observeParents: true,
  267. },
  268. goodList: [],
  269. systemStore: {},
  270. qqmapsdk: null,
  271. productConClass: 'product-con',
  272. tempName: '全国包邮',
  273. isIntegral: false,
  274. }
  275. },
  276. computed: mapGetters(['isLogin', 'location']),
  277. mounted: function() {
  278. this.$store.commit('get_to', 'goodcon')
  279. let url = handleQrCode()
  280. if (!url) {
  281. url = handleUrlParam(getCurrentPageUrlWithArgs())
  282. }
  283. const token = cookie.get('login_status')
  284. if (url && url.id) {
  285. this.id = url.id
  286. let urlSpread = parseInt(url.spread)
  287. if (urlSpread) {
  288. cookie.set('spread', urlSpread)
  289. }
  290. } else {
  291. this.id = this._route.query.id
  292. }
  293. this.isIntegral = url.isIntegral == 'true'
  294. if (!token) {
  295. this.productCon()
  296. return
  297. }
  298. this.coupons()
  299. this.productCon()
  300. this.setOpenShare()
  301. },
  302. watch: {
  303. posterImageStatus(status) {
  304. console.log(status)
  305. if (status) {
  306. this.productConClass = 'noscroll product-con'
  307. } else {
  308. this.productConClass = 'product-con'
  309. }
  310. },
  311. },
  312. methods: {
  313. onShareAppMessage: function() {
  314. return {
  315. title: this.storeInfo.storeName,
  316. imageUrl: this.storeInfo.image,
  317. path: 'pages/shop/GoodsCon/index?id=' + this.storeInfo.id + '&spread=' + uni.getStorageSync('uid') + '&pageType=good&codeType=routine',
  318. success(res) {
  319. uni.showToast({
  320. title: '分享成功',
  321. })
  322. },
  323. fail(res) {
  324. uni.showToast({
  325. title: '分享失败',
  326. icon: 'none',
  327. })
  328. },
  329. }
  330. },
  331. goHome() {
  332. this.$yrouter.switchTab('/pages/home/index')
  333. },
  334. goShoppingCart() {
  335. this.$yrouter.switchTab('/pages/shop/ShoppingCart/index')
  336. },
  337. goCustomerList() {
  338. this.$yrouter.push({
  339. path: '/pages/user/CustomerList/index',
  340. })
  341. },
  342. goStoreList() {
  343. this.$yrouter.push({
  344. path: '/pages/shop/StoreList/index',
  345. })
  346. },
  347. goEvaluateList(id) {
  348. this.$yrouter.push({
  349. path: '/pages/shop/EvaluateList/index',
  350. query: {
  351. id,
  352. },
  353. })
  354. },
  355. telPhone(phoneNumber) {
  356. uni.makePhoneCall({
  357. phoneNumber: phoneNumber,
  358. fail() {
  359. console.log('取消拨打')
  360. },
  361. })
  362. },
  363. showChang: function(data) {
  364. this.$yrouter.push({
  365. path: '/pages/map/index',
  366. query: data,
  367. })
  368. },
  369. updateTitle() {
  370. // document.title = this.storeInfo.storeName || this.$yroute.meta.title;
  371. },
  372. setShareInfoStatus: function() {
  373. this.shareInfoStatus = !this.shareInfoStatus
  374. this.posters = false
  375. },
  376. shareCode: function() {
  377. var that = this
  378. getProductCode(that.id).then(res => {
  379. that.posterData.code = res.data.code
  380. that.listenerActionSheet()
  381. })
  382. },
  383. setPosterImageStatus: function() {
  384. this.posterImageStatus = !this.posterImageStatus
  385. this.posters = false
  386. },
  387. //产品详情接口;
  388. productCon: function() {
  389. let that = this
  390. let from = this.location
  391. if (this.$deviceType == 'app') {
  392. from.from = 'app'
  393. }
  394. uni.showLoading({
  395. title: '加载中',
  396. mask: true,
  397. })
  398. getProductDetail(that.id, from)
  399. .then(res => {
  400. res.data.storeInfo.description = res.data.storeInfo.description.replace(/\<img/gi, '<img style="max-width:100%;height:auto;"')
  401. that.$set(that, 'storeInfo', res.data.storeInfo)
  402. // 给 attr 赋值,将请求回来的规格赋值给 attr
  403. that.$set(that.attr, 'productAttr', res.data.productAttr)
  404. that.$set(that, 'productValue', res.data.productValue)
  405. that.$set(that, 'replyCount', res.data.replyCount)
  406. that.$set(that, 'replyChance', res.data.replyChance)
  407. that.reply = res.data.reply ? [res.data.reply] : []
  408. that.$set(that, 'reply', that.reply)
  409. that.$set(that, 'priceName', res.data.priceName)
  410. that.$set(that, 'tempName', res.data.tempName)
  411. that.posterData.image = that.storeInfo.image
  412. if (that.storeInfo.storeName.length > 30) {
  413. that.posterData.title = that.storeInfo.storeName.substring(0, 30) + '...'
  414. } else {
  415. that.posterData.title = that.storeInfo.storeName
  416. }
  417. that.posterData.price = that.storeInfo.price
  418. that.posterData.code = that.storeInfo.codeBase
  419. that.systemStore = res.data.systemStore
  420. let good_list = res.data.goodList || []
  421. let goodArray = []
  422. let count = Math.ceil(good_list.length / 6)
  423. for (let i = 0; i < count; i++) {
  424. var list = good_list.slice(i * 6, 6)
  425. if (list.length)
  426. goodArray.push({
  427. list: list,
  428. })
  429. }
  430. that.mapKay = res.data.mapKay
  431. that.$set(that, 'goodList', goodArray)
  432. that.updateTitle()
  433. that.DefaultSelect()
  434. that.getCartCount()
  435. })
  436. .catch(err => {
  437. uni.showToast({
  438. title: err.msg || err.response.data.msg || err.response.data.message,
  439. icon: 'none',
  440. duration: 2000,
  441. })
  442. })
  443. .finally(() => {
  444. uni.hideLoading()
  445. })
  446. },
  447. //默认选中属性;
  448. DefaultSelect: function() {
  449. let productAttr = this.attr.productAttr
  450. let value = []
  451. for (let i = 0; i < productAttr.length; i++) {
  452. this.$set(productAttr[i], 'index', 0)
  453. value.push(productAttr[i].attrValueArr[0])
  454. }
  455. //sort();排序函数:数字-英文-汉字;
  456. let productSelect = this.productValue[value.sort().join(',')]
  457. if (productSelect && productAttr.length) {
  458. this.$set(this.attr.productSelect, 'store_name', this.storeInfo.storeName)
  459. this.$set(this.attr.productSelect, 'image', productSelect.image)
  460. this.$set(this.attr.productSelect, 'price', productSelect.price)
  461. this.$set(this.attr.productSelect, 'stock', productSelect.stock)
  462. this.$set(this.attr.productSelect, 'unique', productSelect.unique)
  463. this.$set(this.attr.productSelect, 'integral', productSelect.integral)
  464. this.$set(this.attr.productSelect, 'cart_num', 1)
  465. this.$set(this, 'attrValue', value.sort().join(','))
  466. this.$set(this, 'attrTxt', '已选择')
  467. } else if (!productSelect && productAttr.length) {
  468. this.$set(this.attr.productSelect, 'store_name', this.storeInfo.storeName)
  469. this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
  470. this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
  471. this.$set(this.attr.productSelect, 'integral', this.storeInfo.integral)
  472. this.$set(this.attr.productSelect, 'stock', 0)
  473. this.$set(this.attr.productSelect, 'unique', '')
  474. this.$set(this.attr.productSelect, 'cart_num', 0)
  475. this.$set(this, 'attrValue', '')
  476. this.$set(this, 'attrTxt', '请选择')
  477. } else if (!productSelect && !productAttr.length) {
  478. this.$set(this.attr.productSelect, 'store_name', this.storeInfo.storeName)
  479. this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
  480. this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
  481. this.$set(this.attr.productSelect, 'stock', this.storeInfo.stock)
  482. this.$set(this.attr.productSelect, 'integral', this.storeInfo.integral)
  483. this.$set(this.attr.productSelect, 'unique', this.storeInfo.unique || '')
  484. this.$set(this.attr.productSelect, 'cart_num', 1)
  485. this.$set(this, 'attrValue', '')
  486. this.$set(this, 'attrTxt', '请选择')
  487. }
  488. },
  489. //购物车;
  490. ChangeCartNum: function(changeValue) {
  491. //changeValue:是否 加|减
  492. //获取当前变动属性
  493. let productSelect = this.productValue[this.attrValue]
  494. //如果没有属性,赋值给商品默认库存
  495. if (productSelect === undefined && !this.attr.productAttr.length) {
  496. productSelect = this.attr.productSelect
  497. }
  498. //无属性值即库存为0;不存在加减;
  499. if (productSelect === undefined) return
  500. let stock = productSelect.stock || 0
  501. let num = this.attr.productSelect
  502. if (changeValue) {
  503. num.cart_num++
  504. if (num.cart_num > stock) {
  505. this.$set(this.attr.productSelect, 'cart_num', stock)
  506. this.$set(this, 'cart_num', stock)
  507. } else {
  508. this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
  509. this.$set(this, 'cart_num', num.cart_num)
  510. }
  511. } else {
  512. num.cart_num--
  513. if (num.cart_num < 1) {
  514. this.$set(this.attr.productSelect, 'cart_num', 1)
  515. this.$set(this, 'cart_num', 1)
  516. } else {
  517. this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
  518. this.$set(this, 'cart_num', num.cart_num)
  519. }
  520. }
  521. },
  522. //将父级向子集多次传送的函数合二为一;
  523. changeFun: function(opt) {
  524. if (typeof opt !== 'object') opt = {}
  525. let action = opt.action || ''
  526. let value = opt.value === undefined ? '' : opt.value
  527. this[action] && this[action](value)
  528. },
  529. //打开优惠券插件;
  530. couponTap: function() {
  531. let that = this
  532. that.coupons()
  533. that.coupon.coupon = true
  534. },
  535. changecoupon: function(msg) {
  536. this.coupon.coupon = msg
  537. this.coupons()
  538. },
  539. currentcoupon: function(res) {
  540. let that = this
  541. that.coupon.coupon = false
  542. that.$set(that.coupon.list[res], 'is_use', true)
  543. },
  544. //可领取优惠券接口;
  545. coupons: function() {
  546. let that = this,
  547. q = {
  548. page: 1,
  549. limit: 20,
  550. }
  551. getCoupon(q).then(res => {
  552. that.$set(that, 'couponList', res.data || [])
  553. that.$set(that.coupon, 'list', res.data)
  554. })
  555. },
  556. //打开属性插件;
  557. selecAttrTap: function() {
  558. this.attr.cartAttr = true
  559. this.isOpen = true
  560. },
  561. changeattr: function(msg) {
  562. // 修改了规格
  563. console.log(msg)
  564. this.attr.cartAttr = msg
  565. this.isOpen = false
  566. },
  567. //选择属性;
  568. ChangeAttr: function(res) {
  569. // 修改了规格
  570. let productSelect = this.productValue[res.value]
  571. console.log(productSelect)
  572. if (productSelect) {
  573. this.attr.productAttr[res.indexw].index = res.indexn
  574. this.$set(this.attr.productSelect, 'image', productSelect.image)
  575. this.$set(this.attr.productSelect, 'price', productSelect.price)
  576. this.$set(this.attr.productSelect, 'stock', productSelect.stock)
  577. this.$set(this.attr.productSelect, 'unique', productSelect.unique)
  578. this.$set(this.attr.productSelect, 'integral', productSelect.integral)
  579. this.$set(this.attr.productSelect, 'cart_num', 1)
  580. this.$set(this, 'attrValue', res.value)
  581. this.$set(this, 'attrTxt', '已选择')
  582. } else {
  583. this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
  584. this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
  585. this.$set(this.attr.productSelect, 'integral', this.storeInfo.price)
  586. this.$set(this.attr.productSelect, 'stock', 0)
  587. this.$set(this.attr.productSelect, 'unique', '')
  588. this.$set(this.attr.productSelect, 'cart_num', 0)
  589. this.$set(this, 'attrValue', '')
  590. this.$set(this, 'attrTxt', '请选择')
  591. }
  592. },
  593. //收藏商品
  594. setCollect: function() {
  595. let that = this,
  596. id = that.storeInfo.id,
  597. category = 'collect'
  598. if (that.storeInfo.userCollect) {
  599. getCollectDel(id, category).then(function() {
  600. that.storeInfo.userCollect = !that.storeInfo.userCollect
  601. })
  602. } else {
  603. getCollectAdd(id, category).then(function() {
  604. that.storeInfo.userCollect = !that.storeInfo.userCollect
  605. })
  606. }
  607. },
  608. // 点击加入购物车按钮
  609. joinCart: function() {
  610. //0=加入购物车
  611. this.goCat(0)
  612. },
  613. // 加入购物车;
  614. goCat: function(news) {
  615. let that = this,
  616. productSelect = that.productValue[this.attrValue]
  617. //打开属性
  618. if (that.attrValue) {
  619. //默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
  620. that.attr.cartAttr = !that.isOpen ? true : false
  621. } else {
  622. if (that.isOpen) that.attr.cartAttr = true
  623. else that.attr.cartAttr = !that.attr.cartAttr
  624. }
  625. //只有关闭属性弹窗时进行加入购物车
  626. if (that.attr.cartAttr === true && that.isOpen === false) return (that.isOpen = true)
  627. //如果有属性,没有选择,提示用户选择
  628. if (that.attr.productAttr.length && productSelect === undefined && that.isOpen === true) {
  629. uni.showToast({
  630. title: '产品库存不足,请选择其它',
  631. icon: 'none',
  632. duration: 2000,
  633. })
  634. return
  635. }
  636. let q = {
  637. productId: that.id,
  638. cartNum: that.attr.productSelect.cart_num,
  639. new: news,
  640. uniqueId: that.attr.productSelect !== undefined ? that.attr.productSelect.unique : '',
  641. }
  642. postCartAdd(q)
  643. .then(function(res) {
  644. console.log(res)
  645. that.isOpen = false
  646. that.attr.cartAttr = false
  647. if (news) {
  648. if (!res.data) {
  649. uni.showToast({
  650. title: res.msg || res.data.msg || res.data.message,
  651. icon: 'none',
  652. duration: 2000,
  653. })
  654. return
  655. }
  656. that.$yrouter.push({
  657. path: '/pages/order/OrderSubmission/index',
  658. query: {
  659. id: res.data.cartId,
  660. isIntegral: that.isIntegral,
  661. },
  662. })
  663. } else {
  664. uni.showToast({
  665. title: '添加购物车成功',
  666. icon: 'success',
  667. duration: 2000,
  668. complete: () => {
  669. that.getCartCount(true)
  670. },
  671. })
  672. }
  673. })
  674. .catch(error => {
  675. console.log(error)
  676. that.isOpen = false
  677. uni.showToast({
  678. title: error.msg || error.response.data.msg || error.response.data.message,
  679. icon: 'none',
  680. duration: 2000,
  681. })
  682. })
  683. },
  684. //获取购物车数量
  685. getCartCount: function(isAnima) {
  686. let that = this
  687. const isLogin = that.isLogin
  688. if (isLogin) {
  689. getCartCount({
  690. numType: 0,
  691. }).then(res => {
  692. that.CartCount = res.data.count
  693. //加入购物车后重置属性
  694. if (isAnima) {
  695. that.animated = true
  696. setTimeout(function() {
  697. that.animated = false
  698. }, 500)
  699. }
  700. })
  701. }
  702. },
  703. //立即购买;
  704. tapBuy: function() {
  705. // 1=直接购买
  706. this.goCat(1)
  707. },
  708. listenerActionSheet: function() {
  709. if (isWeixin() === true) {
  710. this.weixinStatus = true
  711. }
  712. this.posters = true
  713. },
  714. listenerActionClose: function() {
  715. this.posters = false
  716. },
  717. setOpenShare: function() {
  718. var data = this.storeInfo
  719. var href = this.location.href
  720. if (this.$deviceType == 'weixin') {
  721. if (this.isLogin) {
  722. getUserInfo().then(res => {
  723. href = href.indexOf('?') === -1 ? href + '?spread=' + res.data.uid : href + '&spread=' + res.data.uid
  724. var configAppMessage = {
  725. desc: data.storeInfo,
  726. title: data.storeName,
  727. link: href,
  728. imgUrl: data.image,
  729. }
  730. wechatEvevt(['updateAppMessageShareData', 'updateTimelineShareData'], configAppMessage)
  731. .then(res => {})
  732. .catch(res => {
  733. if (res.is_ready) {
  734. res.wx.updateAppMessageShareData(configAppMessage)
  735. res.wx.updateTimelineShareData(configAppMessage)
  736. }
  737. })
  738. })
  739. } else {
  740. var configAppMessage = {
  741. desc: data.storeInfo,
  742. title: data.storeName,
  743. link: href,
  744. imgUrl: data.image,
  745. }
  746. wechatEvevt(['updateAppMessageShareData', 'updateTimelineShareData'], configAppMessage)
  747. .then(res => {})
  748. .catch(res => {
  749. if (res.is_ready) {
  750. res.wx.updateAppMessageShareData(configAppMessage)
  751. res.wx.updateTimelineShareData(configAppMessage)
  752. }
  753. })
  754. }
  755. }
  756. },
  757. },
  758. }
  759. </script>
  760. <style scoped lang="less">
  761. .geoPage {
  762. position: fixed;
  763. width: 100%;
  764. height: 100%;
  765. top: 0;
  766. z-index: 10000;
  767. }
  768. .product-con .store-info {
  769. margin-top: 0.2 * 100rpx;
  770. background-color: #fff;
  771. }
  772. .product-con .store-info .title {
  773. padding: 0 0.3 * 100rpx;
  774. font-size: 0.28 * 100rpx;
  775. color: #282828;
  776. height: 0.8 * 100rpx;
  777. line-height: 0.8 * 100rpx;
  778. border-bottom: 0.01 * 100rpx solid #f5f5f5;
  779. }
  780. .product-con .store-info .info {
  781. padding: 0 0.3 * 100rpx;
  782. height: 1.26 * 100rpx;
  783. }
  784. .product-con .store-info .info .picTxt {
  785. width: 100%;
  786. display: flex;
  787. align-items: center;
  788. }
  789. .product-con .store-info .info .picTxt .pictrue {
  790. width: 0.76 * 100rpx;
  791. height: 0.76 * 100rpx;
  792. margin-right: 0.2 * 100rpx;
  793. }
  794. .product-con .store-info .info .picTxt .pictrue image {
  795. width: 100%;
  796. height: 100%;
  797. border-radius: 0.06 * 100rpx;
  798. }
  799. .product-con .store-info .info .picTxt .text {
  800. flex: 1;
  801. }
  802. .product-con .store-info .info .picTxt .text .name {
  803. font-size: 0.3 * 100rpx;
  804. color: #282828;
  805. }
  806. .product-con .store-info .info .picTxt .text .address {
  807. font-size: 0.24 * 100rpx;
  808. color: #666;
  809. margin-top: 0.03 * 100rpx;
  810. }
  811. .product-con .store-info .info .picTxt .text .address .iconfont {
  812. color: #707070;
  813. font-size: 0.18 * 100rpx;
  814. margin-left: 0.1 * 100rpx;
  815. }
  816. .product-con .store-info .info .picTxt .addressBox {
  817. display: flex;
  818. flex-direction: column;
  819. align-items: flex-end;
  820. }
  821. .product-con .store-info .info .picTxt .addressBox .iconfont {
  822. font-size: 0.4 * 100rpx;
  823. }
  824. .product-con .store-info .info .picTxt .addressBox .addressTxt {
  825. font-size: 0.24 * 100rpx;
  826. color: #eb3729;
  827. }
  828. .product-con .store-info .praise {
  829. font-size: 0.28 * 100rpx;
  830. color: #808080;
  831. }
  832. .product-con .store-info .praise .iconfont {
  833. font-size: 0.28 * 100rpx;
  834. }
  835. .product-con .superior {
  836. background-color: #fff;
  837. margin-top: 0.2 * 100rpx;
  838. }
  839. .product-con .superior .title {
  840. height: 0.98 * 100rpx;
  841. }
  842. .product-con .superior .title image {
  843. width: 0.3 * 100rpx;
  844. height: 0.3 * 100rpx;
  845. }
  846. .product-con .superior .title .titleTxt {
  847. margin: 0 0.2 * 100rpx;
  848. font-size: 0.3 * 100rpx;
  849. background-image: linear-gradient(to right, #f57a37 0%, #f21b07 100%);
  850. background-image: -webkit-linear-gradient(to right, #f57a37 0%, #f21b07 100%);
  851. background-image: -moz-linear-gradient(to right, #f57a37 0%, #f21b07 100%);
  852. -webkit-background-clip: text;
  853. -webkit-text-fill-color: transparent;
  854. }
  855. .product-con .superior .slider-banner {
  856. width: 6.9 * 100rpx;
  857. margin: 0 auto;
  858. padding-bottom: 0.2 * 100rpx;
  859. }
  860. .product-con .superior .slider-banner .list {
  861. width: 100%;
  862. padding-bottom: 0.2 * 100rpx;
  863. }
  864. .product-con .superior .slider-banner .list .item {
  865. width: 2.15 * 100rpx;
  866. margin: 0 0.22 * 100rpx 0.3 * 100rpx 0;
  867. font-size: 0.26 * 100rpx;
  868. }
  869. .product-con .superior .slider-banner .list .item:nth-of-type(3n) {
  870. margin-right: 0;
  871. }
  872. .product-con .superior .slider-banner .list .item .pictrue {
  873. width: 100%;
  874. height: 2.15 * 100rpx;
  875. }
  876. .product-con .superior .slider-banner .list .item .pictrue image {
  877. width: 100%;
  878. height: 100%;
  879. border-radius: 0.06 * 100rpx;
  880. }
  881. .product-con .superior .slider-banner .list .item .name {
  882. color: #282828;
  883. margin-top: 0.12 * 100rpx;
  884. }
  885. .product-con .superior .slider-banner .swiper-pagination-bullet {
  886. background-color: #999;
  887. }
  888. .product-con .superior .slider-banner .swiper-pagination-bullet-active {
  889. background-color: #e93323;
  890. }
  891. .mask {
  892. -webkit-filter: blur(2px);
  893. -moz-filter: blur(2px);
  894. -ms-filter: blur(2px);
  895. filter: blur(2px);
  896. }
  897. .product-con .product-intro .conter view {
  898. width: 100% !important;
  899. }
  900. .generate-posters {
  901. width: 100%;
  902. height: 1.7 * 100rpx;
  903. background-color: #fff;
  904. position: fixed;
  905. left: 0;
  906. bottom: 0;
  907. z-index: 99;
  908. transform: translate3d(0, 100%, 0);
  909. -webkit-transform: translate3d(0, 100%, 0);
  910. -ms-transform: translate3d(0, 100%, 0);
  911. -moz-transform: translate3d(0, 100%, 0);
  912. -o-transform: translate3d(0, 100%, 0);
  913. transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  914. -webkit-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  915. -moz-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  916. -o-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  917. }
  918. .generate-posters.on {
  919. transform: translate3d(0, 0, 0);
  920. -webkit-transform: translate3d(0, 0, 0);
  921. -ms-transform: translate3d(0, 0, 0);
  922. -moz-transform: translate3d(0, 0, 0);
  923. -o-transform: translate3d(0, 0, 0);
  924. }
  925. .generate-posters .item {
  926. flex: 50%;
  927. -webkit-flex: 50%;
  928. -ms-flex: 50%;
  929. text-align: center;
  930. }
  931. .generate-posters .item .iconfont {
  932. font-size: 0.8 * 100rpx;
  933. color: #5eae72;
  934. }
  935. .generate-posters .item .iconfont.icon-haibao {
  936. color: #5391f1;
  937. }
  938. .noscroll {
  939. height: 100%;
  940. overflow: hidden;
  941. }
  942. </style>