多租户商城-商户小程序端
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.

559 lines
15 KiB

2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <!--
  2. * @FileDescription: 商品信息包括活动信息优惠券
  3. * @Author: kahu
  4. * @Date: 2022/11/7
  5. * @LastEditors: kahu
  6. * @LastEditTime: 2022/11/7
  7. -->
  8. <template>
  9. <view class="prod-box">
  10. <!-- 商品详情 -->
  11. <swiper
  12. class="goodsImgswiper-box "
  13. :indicator-dots="true"
  14. :autoplay="true"
  15. >
  16. <swiper-item
  17. v-for="(imgItem, index) in productInfo.images"
  18. :key="index"
  19. >
  20. <image
  21. class="goodsImg default-img u-skeleton-fillet"
  22. :src="imgItem"
  23. onerror="this.src='url(https://wechat.hnthee.com/ceres-local-file/image/default.png) no-repeat center';this.οnerrοr=null"
  24. ></image>
  25. </swiper-item>
  26. </swiper>
  27. <!-- 分享 -->
  28. <view
  29. class="share-box flex-items-plus"
  30. @click="shareMenuShow"
  31. >
  32. <image
  33. class="share-img"
  34. src="https://wechat.hnthee.com/ceres-local-file/image/prod_share.png"
  35. ></image>
  36. <label class="fs24 mar-left-10 font-color-252744">分享</label>
  37. </view>
  38. <view class="goodgDes-box flex-start flex-column">
  39. <view
  40. v-if="skuSelect.activityType === 0"
  41. class="priceBuyNum-box flex-display u-skeleton-fillet flex-sp-between mar-left-30"
  42. >
  43. <view>
  44. <label class="fs32 font-color-F54639 fs-bold">¥</label>
  45. <label class="fs32 fs-bold font-color-F54639 mar-left-5">{{ skuSelect.price || 0 }}</label>
  46. <label class="fs20 font-color-90919C discountsPriceLine mar-left-20">¥ {{ skuSelect.originalPrice || 0 }}</label>
  47. </view>
  48. <label class="fs20 font-color-90919C mar-right-50">{{ productInfo.users || 0 }}{{$t('common.payticktip')}}</label>
  49. </view>
  50. <view
  51. v-else-if="skuSelect.activityType === 8"
  52. class="sceneMarketingBox"
  53. >
  54. <view class="flex-row-plus flex-items-plus mar-left-30 mar-top-10">
  55. <label class="fs30 font-color-FFF">¥</label>
  56. <label class="fs42 mar-left-5 font-color-FFF">{{ skuSelect.price || 0 }}</label>
  57. <label class="fs28 mar-left-10 discountsPriceLine font-color-CCC">¥
  58. {{ skuSelect.originalPrice || 0 }}</label>
  59. </view>
  60. <view class="sceneNameBox">{{ productInfo.sceneName }}</view>
  61. </view>
  62. <view
  63. v-else
  64. class="seckill-box"
  65. >
  66. <view
  67. class="flex-items flex-sp-between"
  68. v-if="skuSelect.activityType === 9 "
  69. >
  70. <view class="vipImg flex-items">
  71. <image
  72. class="vip-icon"
  73. src="https://ceres.zkthink.com/static/images/vipDetail.png"
  74. mode=""
  75. >
  76. </image>
  77. </view>
  78. <view class="flex-row-plus flex-items-plus mar-left-30 mar-top-10">
  79. <label class="fs30 font-color-FFF">¥</label>
  80. <label class="fs42 mar-left-5 font-color-FFF">{{ skuSelect.price || 0 }}</label>
  81. <label class="fs28 mar-left-10 discountsPriceLine font-color-999">¥
  82. {{ skuSelect.originalPrice || 0 }}
  83. </label>
  84. </view>
  85. </view>
  86. <view
  87. v-else
  88. class="flex-items flex-row flex-sp-between"
  89. >
  90. <view class="flex-column-plus">
  91. <image
  92. v-if="[2,4].includes(skuSelect.activityType)"
  93. class="seckill-icon"
  94. src="https://ceres.zkthink.com/static/images/seckillicon.png"
  95. mode=""
  96. ></image>
  97. <image
  98. v-if="[3,5].includes(skuSelect.activityType)"
  99. class="discount-icon"
  100. src="https://ceres.zkthink.com/static/images/discounticon.png"
  101. mode=""
  102. ></image>
  103. <image
  104. v-if="skuSelect.activityType === 1"
  105. class="spell-icon"
  106. src="https://ceres.zkthink.com/static/images/spellicon.png"
  107. mode=""
  108. ></image>
  109. <view class="flex-row-plus flex-items mar-top-10">
  110. <label class="fs30 font-color-FFF">¥</label>
  111. <label class="fs42 mar-left-5 font-color-FFF">{{ skuSelect.price || 0 }}</label>
  112. <label class="fs28 mar-left-10 discountsPriceLine font-color-999">¥
  113. {{ skuSelect.originalPrice || 0 }}
  114. </label>
  115. </view>
  116. </view>
  117. <view
  118. v-if="[1,2,3,4,5].includes(skuSelect.activityType)"
  119. class="countdown flex-column-plus"
  120. >
  121. <view v-if="timeActiveType">
  122. <label class="fs28">距离结束剩余</label>
  123. <view class="flex-row-plus fs34 flex-items-plus mar-top-10">
  124. <view class="countdown-box flex-items-plus">{{ activeTimeObj.day }}</view>
  125. <view class="font-color-999"></view>
  126. <view class="countdown-box flex-items-plus">{{ activeTimeObj.hour }}</view>
  127. <view class="font-color-999">:</view>
  128. <view class="countdown-box flex-items-plus">{{ activeTimeObj.min }}</view>
  129. <view class="font-color-999">:</view>
  130. <view class="countdown-box flex-items-plus">{{ activeTimeObj.sec }}</view>
  131. </view>
  132. </view>
  133. <view v-else>
  134. <label class="fs28 mar-right-20">即将开始{{ skuSelect.startTime }}</label>
  135. <!-- <view class="fs28 mar-right-20 mar-top-20">{{productInfo.startTime}}</view>-->
  136. </view>
  137. </view>
  138. </view>
  139. </view>
  140. <view class="nameContainer">
  141. <view class="goodsName-box overflowNoDot mar-top-20 u-skeleton-fillet">
  142. <label class="goodsName fs32">{{ productInfo.productName }}</label>
  143. </view>
  144. <view
  145. class="collectBox "
  146. @click="handleCollect"
  147. >
  148. <image
  149. v-if="productInfo.ifCollect === 1"
  150. class="store-icon"
  151. src="https://wechat.hnthee.com/ceres-local-file/image/prod_collect_active.png"
  152. ></image>
  153. <image
  154. v-else
  155. class="store-icon"
  156. src="https://wechat.hnthee.com/ceres-local-file/image/prod_collect_normal.png"
  157. >
  158. </image>
  159. </view>
  160. </view>
  161. <view
  162. v-if="markTools.length>0 || shopMarkTools.length>0"
  163. class="activity-box mar-top-10"
  164. @click="couponShowClick"
  165. >
  166. <label class="fs24 font-color-999">优惠</label>
  167. <view class="activity-content mar-left-30 flex-items flex-sp-between flex-row">
  168. <view
  169. class="fs20 overflow"
  170. style="width: 500rpx;"
  171. >
  172. {{ productInfo.couponSplicing }}
  173. </view>
  174. <view class="flex-items">
  175. <label class="fs24 font-color-C5AA7B">领券</label>
  176. <image
  177. class="coupon-arrow"
  178. src="https://ceres.zkthink.com/static/img/user/arrow.png"
  179. ></image>
  180. </view>
  181. </view>
  182. </view>
  183. </view>
  184. <!-- 分享弹出 -->
  185. <u-action-sheet
  186. :list="shareObj.actionList"
  187. v-model="shareObj.actionShow"
  188. @click="handleShareSelect"
  189. ></u-action-sheet>
  190. <shareSpell
  191. ref="shareSpell"
  192. @shareCancel="shareCancel"
  193. :url="shareObj.url"
  194. :img="shareObj.image"
  195. :title="shareObj.title"
  196. >
  197. </shareSpell>
  198. </view>
  199. </template>
  200. <script>
  201. import { TimeFormatting } from "../../../utils/timeUtil";
  202. import NET from "../../../utils/request";
  203. import API from "../../../config/api";
  204. import shareSpell from '../../../component/share.vue'
  205. export default {
  206. name: "GoodActivityDetail",
  207. components: {shareSpell},
  208. data() {
  209. return {
  210. // 活动倒计时
  211. timeDifference: 0,
  212. activeTimeObj: {
  213. day: '00',
  214. hour: '00',
  215. min: '00',
  216. sec: '00'
  217. },
  218. countdownInterval: null,
  219. // 分享
  220. shareObj: {
  221. url: '',
  222. image: '',
  223. title: '好友分享了一个很棒的商品',
  224. actionList: [
  225. {text: '生成分享海报'},
  226. {text: '邀请好友'}
  227. ],
  228. actionShow: false
  229. },
  230. }
  231. },
  232. props: {
  233. // 商品信息
  234. productInfo: {
  235. type: Object,
  236. default: () => ({})
  237. },
  238. // 当前选中的sku
  239. skuSelect: {
  240. type: Object,
  241. default: () => ({})
  242. },
  243. timeActiveType: {
  244. type: Boolean,
  245. default: () => false
  246. },
  247. markTools: {
  248. type: Array,
  249. default: () => ([])
  250. },
  251. shopMarkTools: {
  252. type: Array,
  253. default: () => ([])
  254. }
  255. },
  256. methods: {
  257. /**
  258. * 初始化活动倒计时
  259. * @param endTimestamp
  260. */
  261. handleGetCountDownNumber(endTimestamp) {
  262. endTimestamp = endTimestamp.substring(0, 19).replace(/-/g, '/');
  263. // 与当前时间的时间差(秒)
  264. const timeDifference = (new Date(endTimestamp).getTime() - new Date().getTime()) / 1000;
  265. this.timeDifference = timeDifference
  266. this.activeTimeObj = TimeFormatting(timeDifference)
  267. this.handleCountDown()
  268. },
  269. /**
  270. * 开始倒计时
  271. */
  272. handleCountDown() {
  273. if (this.countdownInterval) {
  274. return
  275. }
  276. this.countdownInterval = setInterval(() => {
  277. if (this.timeDifference <= 0) {
  278. clearInterval(this.countdownInterval)
  279. uni.showToast({
  280. title: "活动结束",
  281. duration: 2000,
  282. icon: 'none'
  283. })
  284. this.$emit('activityEnd', 0)
  285. } else {
  286. this.timeDifference--
  287. this.activeTimeObj = TimeFormatting(this.timeDifference)
  288. }
  289. }, 1000)
  290. },
  291. /**
  292. * 拉起父组件优惠券
  293. */
  294. couponShowClick() {
  295. this.$emit('couponClick')
  296. },
  297. /**
  298. * 收藏
  299. */
  300. handleCollect() {
  301. if (this.productInfo.ifCollect === 0) {
  302. NET.request(API.collect, {
  303. productId: parseInt(this.productInfo.productId)
  304. }, 'POST').then(res => {
  305. this.productInfo.ifCollect = 1
  306. uni.showToast({
  307. title: this.$t('common.collectsuccess'),
  308. icon: "success"
  309. })
  310. })
  311. } else {
  312. NET.request(API.cancelCollect, {
  313. ids: [this.productInfo.productId]
  314. }, 'PUT').then(res => {
  315. this.productInfo.ifCollect = 0
  316. uni.showToast({
  317. title: this.$t('common.cancelcollectsuccess'),
  318. icon: "success"
  319. })
  320. })
  321. }
  322. },
  323. /**
  324. * 海报分享
  325. */
  326. sharePoster() {
  327. let system = undefined
  328. // #ifdef APP-PLUS
  329. system = 1
  330. // #endif
  331. // #ifdef H5
  332. system = 3
  333. // #endif
  334. // #ifdef MP-WEIXIN
  335. system = 2
  336. // #endif
  337. // #ifdef MP-ALIPAY
  338. system = 4
  339. // #endif
  340. uni.showLoading({
  341. mask: true,
  342. title: '请稍候...'
  343. })
  344. NET.request(API.getSharePic, {
  345. productId: this.productInfo.productId,
  346. shopId: this.productInfo.shopId,
  347. skuId: this.skuSelect.skuId,
  348. terminal: system
  349. }, 'GET').then(res => {
  350. uni.hideLoading()
  351. // 推广商品
  352. uni.navigateTo({
  353. url: `/pages_category_page1/distributionModule/shareProduct?shareType=2&productImage=${ this.productInfo.images[0] }&shopId=${ this.productInfo.shopId }&productId=${ this.productInfo.productId }&skuId=${ this.skuSelect.skuId }&productName=${ this.productInfo.productName }&price=${ this.productInfo.price }&headImage=${ res.data.headImage }&shareName=${ res.data.name }&shareImg=${ res.data }`
  354. });
  355. }).catch(res => {
  356. uni.hideLoading()
  357. })
  358. },
  359. shareMenuShow() {
  360. this.shareObj.actionShow = true
  361. },
  362. shareCancel() {
  363. this.$refs.shareSpell.shareShow = false
  364. },
  365. handleShareSelect(index) {
  366. if (index === 0) {
  367. this.sharePoster()
  368. } else {
  369. this.shareObj.url = '/pages_category_page1/goodsModule/goodsDetails?shopId=' + this.productInfo.shopId + '&productId=' + this.productInfo.productId + '&skuId=' + this.skuSelect.skuId
  370. this.shareObj.image = this.productInfo.images[0]
  371. this.shareObj.title = `【cereshop】好友分享了一个好物给您!${ this.productInfo.productName }${ this.productInfo.price } `
  372. this.$refs.shareSpell.shareShow = true
  373. }
  374. },
  375. }
  376. }
  377. </script>
  378. <style
  379. lang="scss"
  380. scoped
  381. >
  382. .prod-box{
  383. display: flex;
  384. flex-direction: column;
  385. background-color: #FFFFFF;
  386. margin-left: 30rpx;
  387. margin-right: 30rpx;
  388. border-radius: 40rpx;
  389. justify-content: center;
  390. align-items: center;
  391. }
  392. .goodsImgswiper-box {
  393. width: 580rpx;
  394. height: 580rpx;
  395. border-radius: 60rpx;
  396. .goodsImg {
  397. width: 580rpx;
  398. height: 580rpx;
  399. border-radius: 60rpx;
  400. }
  401. }
  402. .share-box {
  403. width: 200upx;
  404. height: 60upx;
  405. position: absolute;
  406. top: 30upx;
  407. right: 0;
  408. z-index: 99;
  409. .share-img {
  410. width: 30rpx;
  411. height: 30rpx;
  412. }
  413. }
  414. .goodgDes-box {
  415. background-color: #FFFFFF;
  416. width: 100%;
  417. padding-bottom: 25upx;
  418. border-bottom-right-radius: 40rpx;
  419. border-bottom-left-radius: 40rpx;
  420. .priceBuyNum-box {
  421. width: 677upx;
  422. margin-top: 30upx;
  423. }
  424. .nameContainer {
  425. display: flex;
  426. .goodsName-box {
  427. width: 677upx;
  428. margin-left: 30rpx;
  429. .img618-cion {
  430. width: 70upx;
  431. height: 36upx;
  432. }
  433. }
  434. .collectBox {
  435. width: 80rpx;
  436. margin: 12rpx 30rpx 0 15rpx;
  437. display: flex;
  438. flex-direction: column;
  439. justify-content: center;
  440. align-items: center;
  441. }
  442. .store-icon {
  443. width: 68rpx;
  444. height: 68rpx;
  445. }
  446. }
  447. .discounts-box {
  448. margin-top: 20upx;
  449. .discounts-text {
  450. margin-left: 10upx;
  451. color: #FF7800;
  452. background-color: #FFE4CC;
  453. padding: 6upx 12upx;
  454. border-radius: 4upx;
  455. }
  456. }
  457. .activity-box {
  458. display: flex;
  459. flex-direction: row;
  460. justify-content: center;
  461. align-items: flex-end;
  462. border-top: 1upx solid #EDEDED;
  463. .activity-content {
  464. width: 614upx;
  465. padding-top: 20upx;
  466. .activity-text {
  467. color: #FF7700;
  468. border: 1upx solid #FF7700;
  469. padding: 6upx 23upx;
  470. }
  471. .coupon-arrow {
  472. width: 16upx;
  473. height: 24upx;
  474. margin-left: 15upx;
  475. }
  476. }
  477. }
  478. }
  479. .seckill-box {
  480. width: 100%;
  481. background: url("https://ceres.zkthink.com/static/images/storeTop_Img.png") no-repeat left top;
  482. padding: 35rpx 30rpx;
  483. .seckill-icon {
  484. width: 187rpx;
  485. height: 41rpx;
  486. background-size: contain;
  487. }
  488. .vip-icon {
  489. width: 187rpx;
  490. height: 41rpx;
  491. background-size: contain;
  492. }
  493. .discount-icon {
  494. width: 187rpx;
  495. height: 41rpx;
  496. background-size: contain;
  497. }
  498. .spell-icon {
  499. width: 182rpx;
  500. height: 37rpx;
  501. background-size: contain;
  502. margin-bottom: 20rpx;
  503. }
  504. .countdown {
  505. text-align: center;
  506. label {
  507. text-align: center;
  508. color: #CCCCCC;
  509. }
  510. }
  511. .countdown-box {
  512. padding: 0 8rpx;
  513. height: 48rpx;
  514. color: #FFEBC4;
  515. background-color: #525252;
  516. margin: 10rpx;
  517. }
  518. }
  519. </style>