index.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. <template>
  2. <div>
  3. <view class='flash-sale'>
  4. <view class="saleBox"></view>
  5. <view class='header' v-if="timeList.length>0">
  6. <image :src='timeList[active].pic'></image>
  7. </view>
  8. <view class="seckillList acea-row row-between-wrapper">
  9. <view class="priceTag">
  10. <image src="/static/images/priceTag.png"></image>
  11. </view>
  12. <view class='timeLsit'>
  13. <scroll-view class="scroll-view_x" scroll-x scroll-with-animation :scroll-left="scrollLeft" style="width:auto;overflow:hidden;height:106rpx;" :scroll-into-view="intoindex">
  14. <block v-for="(item,index) in timeList" :key='index'>
  15. <view @tap='settimeList(item,index)' class='item' :class="active == index?'on':''" :id='"sort"+index'>
  16. <view class='time'>{{item.time}}</view>
  17. <view class="state">{{item.state}}</view>
  18. </view>
  19. </block>
  20. </scroll-view>
  21. </view>
  22. </view>
  23. <view class='list'>
  24. <block v-for="(item,index) in seckillList" :key='index'>
  25. <view class='item acea-row row-between-wrapper' @tap='goDetails(item)'>
  26. <view class='pictrue'>
  27. <image :src='item.image'></image>
  28. </view>
  29. <view class='text acea-row row-column-around'>
  30. <view class='name line1'>{{item.store_name}}</view>
  31. <view class='money'>¥
  32. <text class='num font-color'>{{item.price}}</text>
  33. <text class="y_money">¥{{item.ot_price}}</text>
  34. </view>
  35. <view class="limit">限量 <text class="limitPrice">{{item.stock}}{{item.unit_name || ''}}</text></view>
  36. <view class="progress">
  37. <view class='bg-reds' :style="'width:'+item.percent+';'"></view>
  38. <view class='piece'>已抢{{item.percent}}</view>
  39. </view>
  40. </view>
  41. <view class='grab bg-color' v-if="status == 1">马上抢</view>
  42. <view class='grab bg-color' v-else-if="status == 2">未开始</view>
  43. <view class='grab bg-color-hui' v-else>已结束</view>
  44. </view>
  45. </block>
  46. </view>
  47. </view>
  48. <view class='noCommodity' v-if="seckillList.length == 0 && (page != 1 || active== 0)">
  49. <view class='pictrue'>
  50. <image src='/static/images/noShopper.png'></image>
  51. </view>
  52. </view>
  53. <home></home>
  54. </div>
  55. </template>
  56. <script>
  57. import {
  58. getSeckillIndexTime,
  59. getSeckillList
  60. } from '../../../api/activity.js';
  61. import home from '@/components/home/index.vue'
  62. export default {
  63. components: {
  64. home
  65. },
  66. data() {
  67. return {
  68. seckillList: [],
  69. timeList: [],
  70. active: 5,
  71. scrollLeft: 0,
  72. interval: 0,
  73. status: 1,
  74. countDownHour: "00",
  75. countDownMinute: "00",
  76. countDownSecond: "00",
  77. page: 1,
  78. limit: 8,
  79. loading: false,
  80. loadend: false,
  81. pageloading: false,
  82. intoindex:''
  83. }
  84. },
  85. /**
  86. * 用户点击右上角分享
  87. */
  88. // #ifdef MP
  89. onShareAppMessage: function() {
  90. wx.showShareMenu({
  91. withShareTicket: true,
  92. menus: ['shareAppMessage', 'shareTimeline']
  93. })
  94. return {
  95. title: '秒杀活动',
  96. path: 'pages/activity/goods_seckill/index',
  97. }
  98. },
  99. onShareTimeline: function() {
  100. return {
  101. title: '秒杀活动',
  102. query: {
  103. key: ''
  104. },
  105. imageUrl: ''
  106. }
  107. },
  108. // #endif
  109. onLoad() {
  110. this.getSeckillConfig();
  111. },
  112. methods: {
  113. getSeckillConfig: function() {
  114. let that = this;
  115. getSeckillIndexTime().then(res => {
  116. that.timeList = res.data.seckillTime;
  117. that.active = res.data.seckillTimeIndex;
  118. that.$nextTick(()=>{
  119. that.intoindex = 'sort'+res.data.seckillTimeIndex
  120. })
  121. let time;
  122. that.timeList.map((item) => {
  123. time = item.start_time > 9 ? item.start_time + ':00' : '0' + item.start_time + ':00';
  124. item.time = time;
  125. })
  126. if (that.timeList.length) {
  127. // wxh.time(that.data.timeList[that.data.active].stop, that);
  128. that.scrollLeft = (that.active - 1.37) * 100
  129. setTimeout(function() {
  130. that.loading = true
  131. }, 2000);
  132. that.seckillList = [],
  133. that.page = 1
  134. that.status = that.timeList[that.active].status
  135. that.getSeckillList();
  136. }
  137. });
  138. },
  139. getSeckillList: function() {
  140. var that = this;
  141. var data = {
  142. page: that.page,
  143. limit: that.limit,
  144. start_time: that.timeList[that.active].start_time,
  145. end_time: that.timeList[that.active].end_time
  146. };
  147. if (that.loadend) return;
  148. if (that.pageloading) return;
  149. this.pageloading = true
  150. getSeckillList(data).then(res => {
  151. console.log(res);
  152. var seckillList = res.data.list;
  153. seckillList.map((item) => {
  154. item.percent = item.stock === 0 ? '0%' : (item.sales*100 / item.stock).toFixed(2) + '%';
  155. })
  156. var loadend = seckillList.length < that.limit;
  157. that.page++;
  158. that.seckillList = that.seckillList.concat(seckillList),
  159. that.page = that.page;
  160. that.pageloading = false;
  161. that.loadend = loadend;
  162. }).catch(err => {
  163. that.pageloading = false
  164. });
  165. },
  166. settimeList: function(item, index) {
  167. var that = this;
  168. this.active = index
  169. if (that.interval) {
  170. clearInterval(that.interval);
  171. that.interval = null
  172. }
  173. that.interval = 0,
  174. that.countDownHour = "00";
  175. that.countDownMinute = "00";
  176. that.countDownSecond = "00";
  177. that.status = that.timeList[that.active].status;
  178. that.loadend = false;
  179. that.page = 1;
  180. that.seckillList = [];
  181. // wxh.time(e.currentTarget.dataset.stop, that);
  182. that.getSeckillList();
  183. },
  184. goDetails(item) {
  185. uni.navigateTo({
  186. url: '/pages/activity/goods_seckill_details/index?id=' + item.product_id + '&time=' + item.stop
  187. })
  188. }
  189. },
  190. /**
  191. * 页面上拉触底事件的处理函数
  192. */
  193. onReachBottom: function() {
  194. this.getSeckillList();
  195. }
  196. }
  197. </script>
  198. <style lang="scss">
  199. page {
  200. background-color: #F5F5F5 !important;
  201. }
  202. .flash-sale .header {
  203. width: 710rpx;
  204. height: 300rpx;
  205. margin: -215rpx auto 0 auto;
  206. border-radius: 20rpx;
  207. }
  208. .flash-sale .header image {
  209. width: 100%;
  210. height: 100%;
  211. border-radius: 20rpx;
  212. }
  213. .flash-sale .seckillList {
  214. padding: 0 20rpx;
  215. }
  216. .flash-sale .seckillList .priceTag {
  217. width: 75rpx;
  218. height: 70rpx;
  219. }
  220. .flash-sale .seckillList .priceTag image {
  221. opacity: 1;
  222. }
  223. .flash-sale .seckillList .priceTag image {
  224. width: 100%;
  225. height: 100%;
  226. }
  227. .flash-sale .timeLsit {
  228. width: 610rpx;
  229. white-space: nowrap;
  230. margin: 10rpx 0;
  231. }
  232. .flash-sale .timeLsit .item {
  233. display: inline-block;
  234. font-size: 20rpx;
  235. color: #666;
  236. text-align: center;
  237. padding: 11rpx 0;
  238. box-sizing: border-box;
  239. height: 96rpx;
  240. margin-right: 35rpx;
  241. }
  242. .flash-sale .timeLsit .item .time {
  243. font-size: 36rpx;
  244. font-weight: 600;
  245. color: #333;
  246. }
  247. .flash-sale .timeLsit .item.on .time {
  248. color: #E93323;
  249. }
  250. .flash-sale .timeLsit .item.on .state {
  251. width: 90rpx;
  252. height: 30rpx;
  253. border-radius: 15rpx;
  254. background: linear-gradient(90deg, rgba(252, 25, 75, 1) 0%, rgba(252, 60, 32, 1) 100%);
  255. color: #fff;
  256. }
  257. .flash-sale .countDown {
  258. height: 92rpx;
  259. border-bottom: 1rpx solid #f0f0f0;
  260. margin-top: -14rpx;
  261. font-size: 28rpx;
  262. color: #282828;
  263. }
  264. .flash-sale .countDown .num {
  265. font-size: 28rpx;
  266. font-weight: bold;
  267. background-color: #ffcfcb;
  268. padding: 4rpx 7rpx;
  269. border-radius: 3rpx;
  270. }
  271. .flash-sale .countDown .text {
  272. font-size: 28rpx;
  273. color: #282828;
  274. margin-right: 13rpx;
  275. }
  276. .flash-sale .list .item {
  277. height: 230rpx;
  278. position: relative;
  279. width: 710rpx;
  280. margin: 0 auto 20rpx auto;
  281. background-color: #fff;
  282. border-radius: 20rpx;
  283. padding: 0 25rpx;
  284. }
  285. .flash-sale .list .item .pictrue {
  286. width: 180rpx;
  287. height: 180rpx;
  288. border-radius: 10rpx;
  289. }
  290. .flash-sale .list .item .pictrue image {
  291. width: 100%;
  292. height: 100%;
  293. border-radius: 10rpx;
  294. }
  295. .flash-sale .list .item .text {
  296. width: 460rpx;
  297. font-size: 30rpx;
  298. color: #333;
  299. height: 166rpx;
  300. }
  301. .flash-sale .list .item .text .name {
  302. width: 100%;
  303. }
  304. .flash-sale .list .item .text .money {
  305. font-size: 30rpx;
  306. color: #E93323;
  307. }
  308. .flash-sale .list .item .text .money .num {
  309. font-size: 40rpx;
  310. font-weight: 500;
  311. font-family: 'Guildford Pro';
  312. }
  313. .flash-sale .list .item .text .money .y_money {
  314. font-size: 24rpx;
  315. color: #999;
  316. text-decoration-line: line-through;
  317. margin-left: 15rpx;
  318. }
  319. .flash-sale .list .item .text .limit {
  320. font-size: 22rpx;
  321. color: #999;
  322. margin-bottom: 5rpx;
  323. }
  324. .flash-sale .list .item .text .limit .limitPrice {
  325. margin-left: 10rpx;
  326. }
  327. .flash-sale .list .item .text .progress {
  328. overflow: hidden;
  329. background-color: #FFEFEF;
  330. width: 260rpx;
  331. border-radius: 18rpx;
  332. height: 18rpx;
  333. position: relative;
  334. }
  335. .flash-sale .list .item .text .progress .bg-reds {
  336. width: 0;
  337. height: 100%;
  338. transition: width 0.6s ease;
  339. background: linear-gradient(90deg, rgba(233, 51, 35, 1) 0%, rgba(255, 137, 51, 1) 100%);
  340. }
  341. .flash-sale .list .item .text .progress .piece {
  342. position: absolute;
  343. left: 8%;
  344. transform: translate(0%, -50%);
  345. top: 49%;
  346. font-size: 16rpx;
  347. color: #FFB9B9;
  348. }
  349. .flash-sale .list .item .grab {
  350. font-size: 28rpx;
  351. color: #fff;
  352. width: 150rpx;
  353. height: 54rpx;
  354. border-radius: 27rpx;
  355. text-align: center;
  356. line-height: 54rpx;
  357. position: absolute;
  358. right: 30rpx;
  359. bottom: 30rpx;
  360. background: #bbbbbb;
  361. }
  362. .flash-sale .saleBox {
  363. width: 100%;
  364. height: 230rpx;
  365. background: rgba(233, 51, 35, 1);
  366. border-radius: 0 0 50rpx 50rpx;
  367. }
  368. </style>