goods_seckill.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <template>
  2. <mescroll-body ref="mescrollRef" @init="mescrollInit" :up="upOption" @down="downCallback" @up="upCallback">
  3. <view class="goods-seckill">
  4. <view class="banner">
  5. <ad-swipers :pid="20" height="340rpx"></ad-swipers>
  6. </view>
  7. <view class="time-list">
  8. <scroll-view style="height: 120rpx; white-space: nowrap;" :scroll-into-view="'item-' + (active - 2)"
  9. scroll-x="true" scroll-with-animation="true">
  10. <view v-for="(item, index) in seckillTime" :key="index" :id="'item-' + index"
  11. class="time-item flex-col row-center col-center" :class="{active: index == active}"
  12. @tap="exchangeTime(index)">
  13. <view :class="'xl bold time'">{{ item.start_time }}</view>
  14. <view :class="'sm br60 state ' + ( item.status === 2 ? 'muted': '' )">
  15. {{ item.tips }}
  16. </view>
  17. </view>
  18. </scroll-view>
  19. </view>
  20. <view class="goods-list">
  21. <router-link v-for="(item, index) in seckillGoods" :key="index"
  22. :to="{path: '/pages/goods_details/goods_details', query: {id: item.goods_id}}">
  23. <view class="goods-item flex bg-white">
  24. <u-image width="180rpx" height="180rpx" border-radius="10rpx" :src="item.goods_image" />
  25. <view class="goods-info m-l-20">
  26. <view style="width: 490rpx" class="goods-name line-2 m-b-10">{{item.goods_name}}</view>
  27. <label class="sale-info xs primary br60">
  28. 已抢{{item.seckill_total}}件
  29. </label>
  30. <view class="info-footer flex row-between m-t-5">
  31. <view class="price">
  32. <price-format class="m-r-10" :price="item.seckill_price"
  33. :color="colorConfig.primary" :first-ize="34" :second-ize="26"
  34. :subscript-ize="26" />
  35. <price-format class="line-through" :price="item.goods_min_price"
  36. :color="colorConfig.muted" :first-ize="24" :second-ize="24"
  37. :subscript-ize="24" />
  38. </view>
  39. <button :class="'br60 white ' + (currentStatus == 2? ' bg-gray' : currentStatus == 1
  40. ? 'primary-btn' : 'border-btn' )" size="sm">
  41. {{currentStatus == 2? '已结束': currentStatus == 1 ? '立即抢购' : '未开始'}}</button>
  42. </view>
  43. </view>
  44. </view>
  45. </router-link>
  46. </view>
  47. </view>
  48. </mescroll-body>
  49. </template>
  50. <script>
  51. import {
  52. getSeckillTime,
  53. getSeckillGoods
  54. } from "@/api/activity";
  55. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins";
  56. export default {
  57. mixins: [MescrollMixin],
  58. data() {
  59. return {
  60. active: 0,
  61. upOption: {
  62. auto: false,
  63. empty: {
  64. use: true,
  65. icon: '/static/images/goods_null.png',
  66. tip: "暂无秒杀商品~",
  67. },
  68. },
  69. seckillTime: [],
  70. seckillGoods: []
  71. };
  72. },
  73. methods: {
  74. async downCallback(page) {
  75. this.seckillGoods = []
  76. await this.getSeckillTimeFun()
  77. this.mescroll.resetUpScroll();
  78. },
  79. upCallback(page) {
  80. let pageNum = page.num;
  81. let pageSize = page.size;
  82. const {seckillTime, active} = this
  83. if(!seckillTime.length) return this.mescroll.endSuccess(0,false)
  84. let id = seckillTime[active].id
  85. getSeckillGoods({
  86. page_no: pageNum,
  87. page_size: pageSize,
  88. seckill_id:id
  89. }).then(res => {
  90. let curPageData = res.data.lists;
  91. let hasNext = !!res.data.more;
  92. let curPageLen = curPageData.length;
  93. if (pageNum == 1) this.seckillGoods = [];
  94. this.seckillGoods = this.seckillGoods.concat(curPageData);
  95. this.mescroll.endSuccess(curPageLen, hasNext);
  96. }).catch(() => {
  97. this.mescroll.endErr()
  98. })
  99. },
  100. // 获取秒杀时间段
  101. getSeckillTimeFun() {
  102. return new Promise((resolve) => {
  103. getSeckillTime().then(({code, data}) => {
  104. if (code == 1) {
  105. // 抢购中
  106. let index = data.findIndex(item => item.status == 1);
  107. if (index == -1) {
  108. // 未开始
  109. index = data.findIndex(item => item.status == 0);
  110. }
  111. if(index == -1) {
  112. // 全部结束选中最后一个
  113. index = data.length - 1
  114. }
  115. this.seckillTime = data;
  116. this.$nextTick(function(){
  117. this.active = index
  118. resolve()
  119. })
  120. }
  121. })
  122. })
  123. },
  124. // 查看其他时间段
  125. exchangeTime(index) {
  126. this.active = index
  127. this.seckillGoods = []
  128. this.mescroll.resetUpScroll();
  129. },
  130. },
  131. computed: {
  132. currentStatus() {
  133. const {active, seckillTime} = this
  134. return seckillTime[active] && seckillTime[active].status
  135. }
  136. }
  137. };
  138. </script>
  139. <style lang="scss">
  140. .bg-gray {
  141. background-color: #CCCCCC !important;
  142. }
  143. .goods-seckill {
  144. .time-list {
  145. .time-item {
  146. display: inline-flex;
  147. width: 160rpx;
  148. height: 100%;
  149. &.active {
  150. .time {
  151. color: $-color-primary;
  152. }
  153. .state {
  154. color: $-color-white;
  155. background-color: $-color-primary;
  156. }
  157. }
  158. .state {
  159. padding: 0 10rpx;
  160. }
  161. }
  162. }
  163. .endtime-box {
  164. height: 100rpx;
  165. .line {
  166. width: 100rpx;
  167. height: 2rpx;
  168. background-color: #CCC;
  169. }
  170. }
  171. .goods-list {
  172. .goods-item {
  173. padding: 30rpx;
  174. .goods-info {
  175. flex: 1;
  176. width: 470rpx;
  177. .sale-info {
  178. padding: 4rpx 16rpx;
  179. background-color: #FFE9EB;
  180. }
  181. .info-footer {
  182. .btn {
  183. padding: 0 30rpx;
  184. }
  185. }
  186. }
  187. }
  188. }
  189. }
  190. .primary-btn {
  191. padding: 0 30rpx;
  192. background: linear-gradient(270deg,
  193. rgba(255, 44, 60, 1) 0%,
  194. rgba(249, 95, 47, 1) 100%);
  195. }
  196. .border-btn {
  197. padding: 0 30rpx;
  198. border: 1px solid $-color-primary;
  199. color: $-color-primary;
  200. }
  201. </style>