detail.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <template>
  2. <view>
  3. <u-navbar title="商品详情" :border="true" :placeholder="true" :autoBack="true" bgColor="#fff" />
  4. <view class="detail">
  5. <!-- 商品轮播 -->
  6. <view class="detail-swiper">
  7. <u-swiper :list="picUrlArr" height="375" radius="0" :indicator="true" :circular="true" indicatorMode="dot" indicatorActiveColor="#FA822C"></u-swiper>
  8. </view>
  9. <!-- 详情 -->
  10. <view class="detail-info flex">
  11. <view class="detail-info-left">
  12. <view class="detail-info-left__title ells-one">{{ info.title }}</view>
  13. <view class="detail-info-left__coin">
  14. <view class="content flex">
  15. <image src="../../static/public/goods_coin.png" mode=""></image>
  16. <view class="coin"><text>×</text>{{ info.exchangePrice }}</view>
  17. </view>
  18. <view class="txt" v-if="info.originPrice">原盲豆:<text>{{ info.originPrice }}</text></view>
  19. </view>
  20. <view class="detail-info-left__price">¥{{ $numberFormat(info.value) }}</view>
  21. </view>
  22. <view class="detail-info-right" v-show="false">销量:30个</view>
  23. </view>
  24. <view class="detail-goods">产品介绍</view>
  25. <view class="detail-description">
  26. <u-parse :content="description" :selectable="true"></u-parse>
  27. </view>
  28. <view style="detail-merchant" @click="toCompanyData" v-if="info.merchantInfo?true:false">
  29. <view class="detail-merchant-warp">
  30. <view class="detail-merchant-warp-one">商家信息</view>
  31. <view class="detail-merchant-warp-two">
  32. <view style="float: left;">前往查看</view>
  33. <u-icon style="float: right;" name="arrow-right" size="18"></u-icon>
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <view class="footer-fixed">
  39. <view class="footer-fixed-content flex">
  40. <!-- <button type="default">立即兑换</button> -->
  41. <view class="footer-fixed-content__coin flex">
  42. <text>我的盲豆:</text>
  43. <text>{{ initData.coinNum ? `${ initData.coinNum }个` : '--' }}</text>
  44. </view>
  45. <view class="footer-fixed-content__exchange flex" @click="exChange">
  46. <text>{{ info.exchangePrice }}个</text>
  47. <text>盲豆兑换</text>
  48. </view>
  49. <view class="footer-fixed-content__price flex" @click="purchase">
  50. <text>立即购买</text>
  51. </view>
  52. </view>
  53. </view>
  54. <!-- 兑换选择 -->
  55. <!-- 兑换成功 -->
  56. <u-popup :show="tipShow" mode="center">
  57. <view class="tip-show">
  58. <view class="flex tip-show-title">
  59. <u-icon name="checkmark-circle" color="#EB7009" size="24"></u-icon>
  60. <text>兑换成功,已放入仓库</text>
  61. </view>
  62. <view class="flex tip-show-btn">
  63. <view class="close" @click="tipShow = false">关闭</view>
  64. <navigator class="prize" :url="`/packagePrize/prize/index`" hover-class="navigator-hover"
  65. @click="tipShow = false">前往查看</navigator>
  66. </view>
  67. </view>
  68. </u-popup>
  69. <!-- 商品兑换 -->
  70. <exchange-popop
  71. :popup-show="exchangePopupShow"
  72. :detailInfo="info"
  73. :popup-info="payInfo"
  74. :sku-list-init="skuListInit"
  75. :sku-list-popup="skuList"
  76. @close="close"
  77. @success="exchangeSuccess"
  78. v-if="exchangePopupShow"
  79. />
  80. <!-- 商品购买 -->
  81. <purchase-popup
  82. :popup-show="purchasePopupShow"
  83. :detailInfo="info"
  84. :popup-info="payInfo"
  85. :sku-list-init="skuListInit"
  86. :sku-list-popup="skuList"
  87. @close="close"
  88. @success="purchaseSuccess"
  89. v-if="purchasePopupShow"
  90. />
  91. </view>
  92. </template>
  93. <script>
  94. import env from '../../config/env.js'
  95. import $http from '@/utils/request.js'
  96. import { formatRichText } from '@/utils/util.js'
  97. import ExchangePopop from '../components/exchange-popup/exchange-popup.vue'
  98. import PurchasePopup from '../components/purchase-popup/purchase-popup.vue'
  99. export default {
  100. components: {
  101. ExchangePopop,
  102. PurchasePopup
  103. },
  104. data() {
  105. return {
  106. goodsId: '',
  107. boxId: '',
  108. picUrlArr: [],
  109. info: {},
  110. prizeList: [],
  111. description: '',
  112. choiceShow: false,
  113. initData: {},
  114. orderNum: 1,
  115. skuList: [],
  116. skuListInit: [],
  117. payInfo: {},
  118. tipShow: false,
  119. exchangePopupShow: false,
  120. purchasePopupShow: false
  121. };
  122. },
  123. onLoad(opthios) {
  124. this.goodsId = opthios.id
  125. },
  126. onShow() {
  127. this.getDetail()
  128. if(uni.getStorageSync('token')) {
  129. this.getBean()
  130. }
  131. },
  132. methods: {
  133. getDetail() {
  134. uni.showLoading({
  135. title: '加载中'
  136. });
  137. $http.post('/api/v1/mp/user/exchange/goods/detail', {
  138. goodsId: this.goodsId,
  139. noToken: true
  140. }).then(res => {
  141. uni.hideLoading();
  142. if (res.code == 0) {
  143. this.info = res.data
  144. let picUrlArr = res.data.picUrl.split(',')
  145. picUrlArr.forEach(item => {
  146. this.picUrlArr.push(env.filePublic + item + '?imageView2/2/w/750')
  147. })
  148. // 处理富文本
  149. const description = res.data.description.replaceAll(".jpg\"", ".jpg?imageView2/2/w/750\"")
  150. .replaceAll(".jpeg\"", ".jpeg?imageView2/2/w/750\"").replaceAll(".png\"",
  151. ".png?imageView2/2/w/750\"");
  152. this.description = formatRichText(description);
  153. this.skuListInit = res.data.skuList
  154. if (res.data.skuList.length) {
  155. let skuProp = JSON.parse(res.data.skuProp)
  156. skuProp.forEach(item => {
  157. item.actionIndex = 0,
  158. item.txt = `${item.name}:${item.value[0]}`
  159. })
  160. let actionSku = skuProp.map(item => {
  161. return item.txt
  162. }).join(';')
  163. let sku = res.data.skuList.find(item => {
  164. return item.properties == actionSku
  165. })
  166. this.payInfo = {
  167. ...sku,
  168. exValue: sku.exchangePrice,
  169. price: sku.value,
  170. picUrl: env.filePublic + sku.picUrl
  171. }
  172. this.skuList = skuProp
  173. } else {
  174. this.payInfo = {
  175. ...res.data,
  176. price: this.info.value,
  177. exValue: this.info.exchangePrice,
  178. picUrl: this.picUrlArr[0]
  179. }
  180. }
  181. }
  182. }).catch(() => {
  183. uni.hideLoading();
  184. })
  185. },
  186. getBean() {
  187. uni.showLoading({
  188. title: '加载中'
  189. });
  190. $http.post('/api/v1/mp/user/mine/init', {}).then(res => {
  191. uni.hideLoading();
  192. if (res.code == 0) {
  193. this.initData = res.data
  194. }
  195. }).catch(() => {
  196. uni.hideLoading();
  197. })
  198. },
  199. exChange() {
  200. this.exchangePopupShow = true
  201. this.getBean()
  202. },
  203. purchase() {
  204. this.purchasePopupShow = true
  205. },
  206. close() {
  207. this.exchangePopupShow = false
  208. this.purchasePopupShow = false
  209. },
  210. exchangeSuccess() {
  211. this.close()
  212. this.tipShow = true
  213. this.getBean()
  214. this.getDetail()
  215. },
  216. purchaseSuccess() {
  217. this.close()
  218. },
  219. toCompanyData(){
  220. uni.navigateTo({
  221. url:`/packageGoods/goods/company?goodsId=${ this.goodsId }`
  222. })
  223. },
  224. }
  225. }
  226. </script>
  227. <style lang="scss" scoped>
  228. </style>
  229. <style lang="scss" scoped>
  230. .detail {
  231. padding-bottom: 180rpx;
  232. // 商品轮播
  233. &-swiper {
  234. background-color: #FFFFFF;
  235. }
  236. // 详情
  237. &-info {
  238. background-color: #fff;
  239. justify-content: space-between;
  240. padding: 34rpx;
  241. margin-bottom: 22rpx;
  242. &-left {
  243. flex: 1;
  244. &__title {
  245. font-size: 34rpx;
  246. line-height: 34rpx;
  247. height: 34rpx;
  248. overflow: hidden;
  249. margin-bottom: 26rpx;
  250. font-weight: bold;
  251. }
  252. &__coin {
  253. display: flex;
  254. line-height: 30rpx;
  255. margin-bottom: 26rpx;
  256. font-size: 26rpx;
  257. .content {
  258. color: #FA822C;
  259. margin-right: 34rpx;
  260. font-weight: bold;
  261. image {
  262. width: 34rpx;
  263. height: 30rpx;
  264. }
  265. text {
  266. font-weight: normal;
  267. }
  268. .coin {
  269. font-size: 30rpx;
  270. }
  271. }
  272. .txt {
  273. font-size: 26rpx;
  274. color: #666666;
  275. text-decoration: line-through;
  276. }
  277. }
  278. &__price {
  279. line-height: 24rpx;
  280. color: #666666;
  281. }
  282. }
  283. &-right {
  284. color: #666666;
  285. }
  286. }
  287. &-goods {
  288. height: 90rpx;
  289. text-align: center;
  290. line-height: 90rpx;
  291. font-weight: bold;
  292. font-size: 30rpx;
  293. background-color: #FFFFFF;
  294. }
  295. &-merchant {
  296. height: 88rpx;
  297. // text-align: center;
  298. line-height: 88rpx;
  299. font-weight: bold;
  300. background-color: #FFFFFF;
  301. &-warp {
  302. height: 88rpx;
  303. width: 100%;
  304. background-color: #ffffff;
  305. // margin-top: 10rpx;
  306. &-one {
  307. float: left;
  308. margin: 20rpx;
  309. font-weight: 600;
  310. }
  311. &-two {
  312. float: right;
  313. margin: 20rpx;
  314. font-weight: 600;
  315. }
  316. }
  317. }
  318. &-description {
  319. image {
  320. width: 100%;
  321. }
  322. }
  323. }
  324. .tip-show {
  325. width: 80vw;
  326. background-color: #FFFFFF;
  327. border-radius: 10rpx;
  328. padding: 60rpx 40rpx;
  329. &-title {
  330. margin-bottom: 64rpx;
  331. text {
  332. margin-left: 20rpx;
  333. }
  334. }
  335. &-btn {
  336. justify-content: space-around;
  337. .close {
  338. width: 160rpx;
  339. height: 60rpx;
  340. line-height: 60rpx;
  341. border-radius: 8rpx;
  342. color: rgba(235, 112, 9, 100);
  343. font-size: 28rpx;
  344. text-align: center;
  345. border: 1px solid rgba(235, 112, 9, 100);
  346. }
  347. .prize {
  348. width: 160rpx;
  349. height: 60rpx;
  350. line-height: 60rpx;
  351. border-radius: 8rpx;
  352. color: rgba(235, 112, 9, 100);
  353. font-size: 28rpx;
  354. text-align: center;
  355. background-color: rgba(235, 112, 9, 100);
  356. color: rgba(255, 255, 255, 100);
  357. font-size: 14px;
  358. }
  359. }
  360. }
  361. .footer-fixed {
  362. position: fixed;
  363. bottom: var(--window-bottom);
  364. left: 0;
  365. right: 0;
  366. z-index: 11;
  367. box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
  368. background: #fff;
  369. // 设置ios刘海屏底部横线安全区域
  370. padding-bottom: constant(safe-area-inset-bottom);
  371. padding-bottom: env(safe-area-inset-bottom);
  372. &-content {
  373. justify-content: flex-start;
  374. padding: 26rpx 20rpx 26rpx 0;
  375. background-color: #fff;
  376. &__coin {
  377. height: 100%;
  378. flex: 1;
  379. font-size: 30rpx;
  380. text:first-child {
  381. color: #999;
  382. }
  383. }
  384. &__exchange {
  385. height: 82rpx;
  386. flex-direction: column;
  387. padding: 0 44rpx;
  388. background: #FFFFFF;
  389. border: 1px solid #F9822C;
  390. border-radius: 41rpx;
  391. color: #F9822C;
  392. text {
  393. font-weight: normal;
  394. font-size: 26rpx;
  395. }
  396. text:last-child {
  397. font-weight: bold;
  398. font-size: 30rpx;
  399. line-height: 40rpx;
  400. }
  401. }
  402. &__price {
  403. height: 82rpx;
  404. font-size: 30rpx;
  405. font-weight: bold;
  406. padding: 0 44rpx;
  407. background: #F9822C;
  408. border-radius: 41rpx;
  409. color: #fff;
  410. margin-left: 24rpx;
  411. }
  412. }
  413. }
  414. </style>