goods.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <template>
  2. <view class="">
  3. <view class="content" v-cloak>
  4. <view class="shop-banner">
  5. <swiper class="swiper" :indicator-dots="false" :circular="true" :autoplay="true" :interval="3000"
  6. :duration="1000" indicator-color="rgba(255, 255, 255, 0.6)" indicator-active-color="#ffffff"
  7. @change="swiperChange">
  8. <swiper-item class="swiper-item" v-for="(item,index) in banner" :key="index">
  9. <image :src="item" mode="aspectFill"></image>
  10. </swiper-item>
  11. </swiper>
  12. <!-- 底部遮罩 -->
  13. <view class="banner-mask"></view>
  14. <!-- 数量 -->
  15. <view class="num-box">{{ activeBanner }}/{{ banner.length }}</view>
  16. </view>
  17. <!-- 详细信息 -->
  18. <view class="det-info" v-if="!!goosDetail">
  19. <view class="price-box">
  20. <view class="price">
  21. <text class="label">会员价</text>
  22. <text class="unit">¥</text>
  23. <text class="num">{{goosDetail.price||0}}</text>
  24. <text class="fs24 color-text2">零售价</text>
  25. <text class="old">¥{{goosDetail.otPrice||0}}</text>
  26. </view>
  27. <text class="fs24 color-text2">月售{{goosDetail.sales||0}}件</text>
  28. </view>
  29. <view class="name-box">
  30. {{goosDetail.productName||0}}
  31. </view>
  32. </view>
  33. </view>
  34. <view class="guige">
  35. <view class="safe-box">
  36. <text class="text">服务</text>
  37. <view class="box">
  38. <image class="mr20" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/userapp/images/safe.png" mode=""></image>
  39. <view class="mr30" v-for="(item,index) in serviceList" :key="index">
  40. <text>{{item}}</text>
  41. </view>
  42. </view>
  43. </view>
  44. </view>
  45. <!-- 购买人数、库存 -->
  46. <view class="det-box">
  47. <view class="title">图文详情</view>
  48. <view class="inner">
  49. <view v-html="goosDetail.description" style="font-size:0"></view>
  50. </view>
  51. </view>
  52. <!-- 底部按钮 -->
  53. <view class="btn-foot">
  54. <view class="menu-box">
  55. </view>
  56. <view class="btn-box">
  57. <view class="btn buy" @click="addCart('buy')">{{buyText}}</view>
  58. </view>
  59. </view>
  60. <!-- 选择产品规格弹窗 -->
  61. <popupBottom ref="popup" :visible.sync="specVisible" title=" " radius="32" maxHeight="800">
  62. <view class="product-spec">
  63. <view class="pro-info">
  64. <view class="img-box">
  65. <image :src="goosDetail.image ||'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/userapp/images/img.png'" mode="aspectFill"></image>
  66. </view>
  67. <view class="info-text">
  68. <view class="info-title">{{goosDetail.productName}}</view>
  69. <view class="price">
  70. <view class="label">会员价</view>
  71. <text class="unit">¥</text>
  72. <text class="num">{{ goosDetail.price}}</text>
  73. </view>
  74. <view class="desc-box">
  75. <text class="text">月售{{goosDetail.sales}}件</text>
  76. </view>
  77. </view>
  78. </view>
  79. <!-- 规格 -->
  80. <view class="spec-box">
  81. <view v-for="(item,index) in attrs" :key="index">
  82. <view class="title">{{item.attrName}}</view>
  83. <view class="spec-list">
  84. <view
  85. v-for="(subItem,subindex) in item.values"
  86. :key="subindex"
  87. :class="subindex==item.index?'item active':'item'"
  88. @click="choseSpec(index,subindex)">
  89. {{ subItem }}
  90. </view>
  91. </view>
  92. </view>
  93. </view>
  94. <view class="price-num">
  95. <view class="label">数量</view>
  96. <u-number-box bgColor="#f3f3f3" v-model="goodsNum" @change="goodsNumChange"></u-number-box>
  97. </view>
  98. <view class="sub-btn" @click="submit">确定</view>
  99. </view>
  100. </popupBottom>
  101. </view>
  102. </template>
  103. <script>
  104. import {liveGoodsDetail} from '@/api/living'
  105. import {
  106. liveOrderKey, // 生成订单key
  107. } from "@/api/order.js"
  108. import popupBottom from '@/components/px-popup-bottom/px-popup-bottom.vue'
  109. export default {
  110. components: {
  111. popupBottom
  112. },
  113. data() {
  114. return {
  115. banner: [],
  116. goodsId: null,
  117. totalNum: 1,
  118. orderKey: null,
  119. type: null,
  120. liveId: null,
  121. storeId: null,
  122. serviceList: ['品质保障', '隐私保护'],
  123. productId: null,
  124. goosDetail: null, //商品详情
  125. buyText: "立即购买",
  126. goodsNum: 0, //商品选择数量
  127. // 当前轮播的图片
  128. activeBanner: 1,
  129. // 规格弹窗
  130. specVisible: false,
  131. };
  132. },
  133. onLoad(options) {
  134. // console.log("商品详情options", options)
  135. if (options.productId) {
  136. this.productId = options.productId;
  137. }
  138. this.liveId = options.liveId
  139. this.goodsId = options.goodsId
  140. if (options.storeId) {
  141. this.storeId = options.storeId || ""
  142. } else {
  143. uni.showToast({
  144. title: "storeId不存在~",
  145. icon: "none"
  146. })
  147. }
  148. this.getliveGoods()
  149. },
  150. methods: {
  151. // swiper变化事件
  152. swiperChange(event) {
  153. this.activeBanner = event.detail.current + 1
  154. },
  155. doAddCart(type) {
  156. if (this.totalNum == 0) {
  157. uni.showToast({
  158. icon: 'none',
  159. title: "库存不足",
  160. });
  161. return;
  162. }
  163. var isBuy = type == "buy" ? 1 : 0;
  164. if (type == "buy") {
  165. this.getKey()
  166. } else {
  167. uni.showToast({
  168. icon: 'success',
  169. title: "添加成功",
  170. });
  171. }
  172. },
  173. // 获得key
  174. getKey() {
  175. liveOrderKey().then(res => {
  176. if (res.code == 200) {
  177. // console.log("下订单的key>>>>", res)
  178. this.orderKey = res.orderKey
  179. uni.navigateTo({
  180. url: '/pages_shopping/live/confirmCreateOrder?&orderKey=' + this.orderKey +
  181. '&liveId=' + this.liveId + '&goodsId=' + this.goodsId +
  182. '&productId=' + this.productId + '&totalNum=' + this
  183. .totalNum
  184. })
  185. } else {
  186. uni.showToast({
  187. title: res.msg,
  188. icon: 'none'
  189. });
  190. }
  191. },
  192. rej => {}
  193. );
  194. },
  195. // 选择商品数量
  196. goodsNumChange(e) {
  197. console.log('当前选择商品数量为: ' + e.value)
  198. this.totalNum = e.value
  199. },
  200. // 提交
  201. submit() {
  202. this.specVisible = false
  203. this.doAddCart(this.type);
  204. },
  205. // 加入购物车
  206. addCart(type) {
  207. this.type = type;
  208. this.specVisible = true
  209. },
  210. //商品详情
  211. getliveGoods() {
  212. if (!this.productId) return;
  213. uni.showLoading({
  214. title: '加载中'
  215. });
  216. liveGoodsDetail(this.productId).then(res => {
  217. uni.hideLoading()
  218. if (res.code == 200) {
  219. // console.log("小黄车 商品详情>>>>", res)
  220. this.goosDetail = res.data
  221. this.banner = res.data.sliderImage.split(',');
  222. } else {
  223. uni.showToast({
  224. title: res.msg,
  225. icon: 'none'
  226. });
  227. }
  228. },
  229. rej => {}
  230. );
  231. },
  232. }
  233. }
  234. </script>
  235. <style lang="scss">
  236. [v-cloak] {
  237. display: none;
  238. }
  239. .content {
  240. font-family: PingFang SC;
  241. }
  242. .shop-banner {
  243. height: 756rpx;
  244. background-color: #FFFFFF;
  245. position: relative;
  246. .swiper-item {
  247. box-sizing: border-box;
  248. position: relative;
  249. }
  250. .swiper,
  251. .swiper-item,
  252. .swiper-item image {
  253. width: 100%;
  254. height: 100%;
  255. }
  256. .banner-mask {
  257. width: 100%;
  258. height: 44rpx;
  259. position: absolute;
  260. left: 0;
  261. bottom: 0;
  262. z-index: 9;
  263. background-size: 20rpx 44rpx;
  264. background-repeat: repeat-x;
  265. }
  266. .num-box {
  267. width: 80rpx;
  268. height: 40rpx;
  269. line-height: 40rpx;
  270. text-align: center;
  271. font-size: 24rpx;
  272. color: #FFFFFF;
  273. background: rgba(0, 0, 0, .7);
  274. border-radius: 20rpx;
  275. position: absolute;
  276. right: 40rpx;
  277. bottom: 34rpx;
  278. z-index: 10;
  279. }
  280. }
  281. .guige {
  282. padding: 24rpx;
  283. border-radius: 16rpx;
  284. background: #fff;
  285. width: auto;
  286. font-size: 24rpx;
  287. color: #222426;
  288. margin: 24rpx;
  289. .safe-box {
  290. display: flex;
  291. align-items: center;
  292. padding-top: 24rpx;
  293. font-size: 24rpx;
  294. color: #222426;
  295. .text {
  296. color: #999999;
  297. margin-right: 40rpx;
  298. }
  299. .box {
  300. display: flex;
  301. align-items: center;
  302. image {
  303. width: 28rpx;
  304. height: 28rpx;
  305. margin-right: 10rpx;
  306. }
  307. view {
  308. display: flex;
  309. align-items: center;
  310. margin-right: 40rpx;
  311. &:last-child {
  312. margin-right: 0;
  313. image {
  314. margin-right: 0;
  315. }
  316. }
  317. }
  318. }
  319. }
  320. }
  321. .det-info {
  322. background: #FFFFFF;
  323. padding: 24rpx;
  324. margin: 24rpx;
  325. border-radius: 16rpx;
  326. .price-box {
  327. display: flex;
  328. align-items: flex-end;
  329. justify-content: space-between;
  330. .price {
  331. display: flex;
  332. align-items: flex-end;
  333. .label {
  334. font-weight: 500;
  335. font-size: 24rpx;
  336. color: #FF5030;
  337. line-height: 1.3;
  338. margin-right: 10rpx;
  339. }
  340. .unit {
  341. font-size: 26rpx;
  342. font-weight: bold;
  343. color: #FF6633;
  344. line-height: 1.3;
  345. }
  346. .num {
  347. font-size: 48rpx;
  348. font-weight: bold;
  349. color: #FF5030;
  350. margin-right: 20rpx;
  351. line-height: 1;
  352. }
  353. .old {
  354. font-size: 24rpx;
  355. font-family: PingFang SC;
  356. font-weight: 400;
  357. text-decoration: line-through;
  358. color: #898E91;
  359. margin-left: 10rpx;
  360. line-height: 1.3;
  361. }
  362. }
  363. }
  364. .name-box {
  365. font-size: 32rpx;
  366. font-weight: bold;
  367. color: #111111;
  368. line-height: 44rpx;
  369. margin-top: 32rpx;
  370. .tag {
  371. display: inline-block;
  372. padding: 2rpx 8rpx;
  373. height: 32rpx;
  374. background: #F5A623;
  375. border-radius: 4rpx;
  376. margin-right: 10rpx;
  377. font-weight: 400;
  378. font-size: 20rpx;
  379. color: #FFFFFF;
  380. line-height: 30rpx;
  381. float: left;
  382. margin-top: 7rpx;
  383. }
  384. }
  385. }
  386. .det-box {
  387. margin-top: 10rpx;
  388. background-color: #FFFFFF;
  389. padding: 24rpx;
  390. margin: 24rpx 24rpx 175rpx 24rpx;
  391. border-radius: 16rpx;
  392. .title {
  393. font-size: 32rpx;
  394. font-weight: bold;
  395. color: #333333;
  396. line-height: 60rpx;
  397. margin-bottom: 30rpx;
  398. padding-bottom: 24rpx;
  399. border-bottom: 1px solid #ECECEC;
  400. }
  401. .inner {
  402. margin-bottom: 100rpx;
  403. }
  404. }
  405. .btn-foot {
  406. box-sizing: border-box;
  407. width: 100%;
  408. height: 151rpx;
  409. background: #FFFFFF;
  410. padding: 0 24rpx;
  411. display: flex;
  412. align-items: center;
  413. justify-content: space-between;
  414. position: fixed;
  415. left: 0;
  416. bottom: 0;
  417. z-index: 99;
  418. .menu-box {
  419. display: flex;
  420. align-items: center;
  421. }
  422. .btn-box {
  423. display: flex;
  424. align-items: center;
  425. .btn {
  426. width: 200rpx;
  427. height: 88rpx;
  428. line-height: 88rpx;
  429. text-align: center;
  430. border-radius: 44rpx;
  431. margin-left: 20rpx;
  432. font-size: 28rpx;
  433. font-weight: bold;
  434. color: #FFFFFF;
  435. &:first-child {
  436. margin-left: 0;
  437. }
  438. &.buy {
  439. background: #2bc7b9;
  440. }
  441. }
  442. }
  443. }
  444. .product-spec {
  445. padding-bottom: 30rpx;
  446. .pro-info {
  447. display: flex;
  448. align-items: center;
  449. .img-box {
  450. width: 200rpx;
  451. height: 200rpx;
  452. background: #FFFFFF;
  453. border-radius: 16rpx;
  454. overflow: hidden;
  455. margin-right: 30rpx;
  456. image {
  457. width: 100%;
  458. height: 100%;
  459. }
  460. }
  461. .info-text {
  462. height: 200rpx;
  463. display: flex;
  464. flex-direction: column;
  465. justify-content: space-between;
  466. .info-title {
  467. font-family: PingFang SC;
  468. font-weight: 600;
  469. font-size: 28rpx;
  470. color: #222426;
  471. text-align: left;
  472. }
  473. .price {
  474. display: flex;
  475. align-items: flex-end;
  476. .label {
  477. font-weight: 500;
  478. font-size: 24rpx;
  479. color: #FF5030;
  480. line-height: 1.3;
  481. margin-right: 10rpx;
  482. }
  483. .unit {
  484. font-size: 32rpx;
  485. font-weight: bold;
  486. color: #FF6633;
  487. line-height: 1.2;
  488. margin-right: 10rpx;
  489. }
  490. .num {
  491. font-size: 50rpx;
  492. font-weight: bold;
  493. color: #FF6633;
  494. line-height: 1;
  495. }
  496. }
  497. .desc-box {
  498. display: flex;
  499. flex-direction: column;
  500. padding-bottom: 9rpx;
  501. .text {
  502. font-size: 26rpx;
  503. font-weight: 500;
  504. color: #999999;
  505. margin-top: 27rpx;
  506. line-height: 1;
  507. &:first-child {
  508. margin-top: 0;
  509. }
  510. }
  511. }
  512. }
  513. }
  514. .price-num {
  515. display: flex;
  516. align-items: center;
  517. justify-content: space-between;
  518. margin-top: 30rpx;
  519. .label {
  520. font-size: 36rpx;
  521. font-weight: bold;
  522. color: #111111;
  523. }
  524. }
  525. .sub-btn {
  526. width: 100%;
  527. height: 88rpx;
  528. line-height: 88rpx;
  529. text-align: center;
  530. font-size: 32rpx;
  531. font-weight: bold;
  532. color: #FFFFFF;
  533. background: #2BC7B9;
  534. border-radius: 44rpx;
  535. margin-top: 30rpx;
  536. }
  537. }
  538. </style>