seckill.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. <template>
  2. <view class="container">
  3. <view class="top-img"><image src="http://shicai.liuniu946.com/static/img/img16.png"></image></view>
  4. <view class="switch-bar flex_item">
  5. <view class="switchList" @click="change(ls)" v-for="ls in switchList" v-bind:class="{ active_color: ls.id == checkid }">
  6. <view class="time">{{ workstarTime}}-{{workendTime}}</view>
  7. <view class="name">{{ ls.name }}</view>
  8. </view>
  9. </view>
  10. <view class="preferred_centent">
  11. <view class="tip flex">
  12. <view class="name">{{ tip }}</view>
  13. <view class="time flex_item" v-if="checkid == 1">
  14. <view class="flex_item" v-show="starting">
  15. <view>距开始</view>
  16. <uni-countdown color="#FFFFFF" background-color="#334432"
  17. :show-day="false"
  18. :hour="starthour"
  19. :minute="startminute"
  20. :second="startsecond">
  21. </uni-countdown>
  22. </view>
  23. <view class="flex_item" v-show="Timeing">
  24. <view>距结束</view>
  25. <uni-countdown color="#FFFFFF" background-color="#334432"
  26. :show-day="false"
  27. :hour="Timeinghour"
  28. :minute="Timeingminute"
  29. :second="Timeingsecond">
  30. </uni-countdown>
  31. </view>
  32. <!-- <view class="flex_item" v-show="end">
  33. <view>距结束</view>
  34. <uni-countdown color="#FFFFFF" background-color="#334432"
  35. :show-day="false"
  36. :hour="endhour"
  37. :minute="endminute"
  38. :second="endsecond">
  39. </uni-countdown>
  40. </view> -->
  41. </view>
  42. <view class="time flex_item" v-if="checkid == 2">
  43. <view>距开始</view>
  44. <uni-countdown color="#FFFFFF" background-color="#334432"
  45. :show-day="false"
  46. :hour="hour"
  47. :minute="minute"
  48. :second="second">
  49. </uni-countdown>
  50. </view>
  51. </view>
  52. <view class="flex_item preferred_item" v-for="item in list" @click="navToDetailPage(item)">
  53. <view class="tlist-img">
  54. <view class="img"><image :src="item.image" mode="scaleToFill"></image></view>
  55. <view class="stock flex_item">
  56. <image class="img" src="/static/img/img01.png" mode="scaleToFill"></image>
  57. <view class="stock-num clamp">库存剩{{ item.percent * 100 }}%</view>
  58. </view>
  59. </view>
  60. <view class="goods_name">
  61. <view class="goods_title clamp">{{ item.store_name }}</view>
  62. <view class="goods-height">
  63. <view class="goods_num clamp">{{ item.store_info }}</view>
  64. <view class="goods-tip" v-if="item.keyword != ''">
  65. <text v-for="lss in item.keyword">{{ lss }}</text>
  66. </view>
  67. </view>
  68. <view class="price flex">
  69. <view class="price_list">
  70. <view class="price-red">¥{{ item.price }}<text>/份</text></view>
  71. <view class="price-green">¥{{item.ot_price}}<text>市场价</text></view>
  72. </view>
  73. <view class="img position-relative" v-if="checkid == 1" @click.stop="Addcar(item)">
  74. <image src="/static/img/img21.png"></image>
  75. <view class="corner" v-if="item.cart_num > 0">
  76. <text>{{ item.cart_num }}</text>
  77. </view>
  78. </view>
  79. <view class="tomorrow" v-if="checkid == 2">明日开抢</view>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. <button open-type="share" class="shareDate">分享给好友</button>
  85. <!-- 返回按钮 -->
  86. <!-- <return-button></return-button> -->
  87. </view>
  88. </template>
  89. <script>
  90. import { cartAdd } from '@/api/product.js';
  91. import { getProducts } from '@/api/product.js';
  92. import { loadIndexs } from '@/api/index.js';
  93. import { saveUrl, interceptor } from '@/utils/loginUtils.js';
  94. import { mapState } from 'vuex';
  95. import uniCountdown from '@/components/uni-countdown/uni-countdown.vue';
  96. // 返回按钮
  97. // import returnButton from '@/pages/return/returnButton.vue';
  98. export default {
  99. computed: {
  100. ...mapState('user',['userInfo','hasLogin']),
  101. ...mapState(['addressData','addressPageShow'])
  102. },
  103. components: {
  104. uniCountdown,
  105. // returnButton
  106. },
  107. data() {
  108. return {
  109. bastList: '',
  110. switchList: [
  111. {
  112. id: 1,
  113. time: '08:00-17:00',
  114. name: '今日秒杀',
  115. sid: 100
  116. },
  117. {
  118. id: 2,
  119. time: '08:00-17:00',
  120. name: '明日预购',
  121. sid: 101
  122. }
  123. ],
  124. checkid: '1', //切换导航栏id
  125. list: '',
  126. tip: '抢购中先下单先得哦', //提示消息
  127. sid: 100, //商品切换导航栏类别id
  128. hour: 0,//距离明天8点开始时间
  129. minute: 0,
  130. second: 0,
  131. starting: false,//判断活动未开始
  132. Timeing:false,//判断活动进行中
  133. starthour:0,//距离今天开始时间
  134. startminute:0,
  135. startsecond:0,
  136. Timeinghour:0,//距离今天结束时间
  137. Timeingminute:0,
  138. Timeingsecond:0,
  139. workstarTime:'',
  140. workendTime:'',
  141. };
  142. },
  143. onLoad(option){
  144. // 判断是否登录
  145. if(!this.hasLogin){
  146. interceptor()
  147. }
  148. // 判断有无邀请人
  149. if (option.spread) {
  150. uni.setStorageSync('spread', option.spread);
  151. }
  152. saveUrl();
  153. },
  154. onShow() {
  155. this.loadData();
  156. this.Getlist();
  157. },
  158. //下拉刷新
  159. onPullDownRefresh() {
  160. let obj = this;
  161. //监听下拉刷新动作的执行方法,每次手动下拉刷新都会执行一次
  162. setTimeout(function() {
  163. obj.loadData();
  164. uni.stopPullDownRefresh(); //停止下拉刷新动画
  165. }, 1000);
  166. },
  167. methods: {
  168. // 请求商品列表
  169. async Getlist() {
  170. loadIndexs({})
  171. .then(({ data }) => {
  172. let arr = data.sell_time.split(',');
  173. this.workstarTime = arr[0];
  174. this.workendTime = arr[1];
  175. this.StartDate();
  176. this.GetDate();
  177. })
  178. .catch(e => {
  179. });
  180. },
  181. //分享
  182. onShareAppMessage(options){
  183.   // 设置菜单中的转发按钮触发转发事件时的转发内容
  184.   let shareObj = {
  185.     title: "点击进入秒杀榜", // 默认是小程序的名称(可以写slogan等)
  186.     path: '/pages/seckill/seckill?spread='+this.userInfo.uid, // 默认是当前页面,必须是以‘/’开头的完整路径
  187.     imageUrl: 'http://shicai.liuniu946.com/static/img/img41.jpg',
  188.     success: function(res){
  189.       // 转发成功之后的回调
  190.       if(res.errMsg == 'shareAppMessage:ok'){
  191.       }
  192.     },
  193.     fail: function(){
  194.       // 转发失败之后的回调
  195.       if(res.errMsg == 'shareAppMessage:fail cancel'){
  196.         // 用户取消转发
  197.       }else if(res.errMsg == 'shareAppMessage:fail'){
  198.         // 转发失败,其中 detail message 为详细失败信息
  199.       }
  200.     }
  201.   };
  202.   // 来自页面内的按钮的转发
  203. //   if( options.from == 'button' ){
  204. //     // 此处可以修改 shareObj 中的内容
  205. //     shareObj.path = '/pages/seckill/seckill';
  206. //   }
  207.   // 返回shareObj
  208. console.log(shareObj,'shareObj')
  209.   return shareObj;
  210. },
  211. //点击切换商品种类
  212. change(item) {
  213. let id = item.id;
  214. this.checkid = id;
  215. this.sid = item.sid;
  216. if (this.checkid == 1) {
  217. this.tip = '抢购中先下单先得哦';
  218. }
  219. if (this.checkid == 2) {
  220. this.tip = '明日好货敬请期待呢';
  221. }
  222. this.loadData();
  223. },
  224. StartDate() {
  225. let obj = this;
  226. console.log(obj.workstarTime)
  227. console.log(this.workendTime)
  228. // 获取当前时间
  229. let now = new Date();
  230. let year = now.getFullYear(); //得到年份
  231. let month = now.getMonth();//得到月份
  232. let date = now.getDate();//得到日期
  233. let hour = now.getHours();//得到小时
  234. let minu = now.getMinutes();//得到分钟
  235. let sec = now.getSeconds();//得到秒
  236. //获取早上开始营业的时间戳
  237. let aa = this.workstarTime.split(':');
  238. let bb = aa[0];
  239. let cc = aa[1];
  240. let dd = String(cc).split('');
  241. let ff = dd[0];
  242. let gg = dd[1];
  243. console.log(bb,ff,gg)
  244. let time1 = new Date(year,month,date,bb,ff,gg);
  245. let morning = time1.getTime();
  246. //获取现在时间的时间戳
  247. let time2 = new Date(year,month,date,hour,minu,sec);
  248. let present = time2.getTime();
  249. //获取晚上结束营业的时间戳
  250. let a = this.workendTime.split(':');
  251. let b = a[0];
  252. let c = a[1];
  253. let d = String(c).split('');
  254. let f = d[0];
  255. let g = d[1];
  256. console.log(b,f,g)
  257. let time3 = new Date(year,month,date,b,f,g);
  258. console.log(time1,'time1')
  259. console.log(time3,'time3')
  260. let night = time3.getTime();
  261. //现在时间大于结束时间,活动结束
  262. // if(present > time3){
  263. // console.log('现在时间大于结束时间,活动结束')
  264. // obj.end = true;
  265. // }
  266. //现在时间大于开始时间小于结束时间,活动进行中
  267. if(present < time3 && present > time1){
  268. console.log('现在时间大于开始时间小于结束时间,活动进行中')
  269. obj.Timeing = true;
  270. let starTime = time3 - present;
  271. let hours = Math.floor((starTime / 1000 / 60 / 60) % 24); //获取剩余小时数
  272. let minutes = Math.floor((starTime / 1000 / 60) % 60); //获取分钟
  273. let seconds = Math.floor((starTime / 1000) % 60); //获取秒数
  274. obj.Timeinghour = hours;
  275. obj.Timeingminute = minutes;
  276. obj.Timeingsecond = seconds;
  277. console.log('时间差是: '+ obj.Timeinghour + '小时, ' + obj.Timeingminute + '分钟, ' + obj.Timeingsecond + '秒','距离晚上22:00点结束');
  278. }
  279. //现在时间小于开始时间,活动还未开始
  280. if(present < time1){
  281. console.log('现在时间小于开始时间,活动还未开始')
  282. obj.starting = true;
  283. let starTime = time1 - present;
  284. let hours = Math.floor((starTime / 1000 / 60 / 60) % 24); //获取剩余小时数
  285. let minutes = Math.floor((starTime / 1000 / 60) % 60); //获取分钟
  286. let seconds = Math.floor((starTime / 1000) % 60); //获取秒数
  287. obj.starthour = hours;
  288. obj.startminute = minutes;
  289. obj.startsecond = seconds;
  290. console.log('时间差是: '+ obj.starthour + '小时, ' + obj.startminute + '分钟, ' + obj.startsecond + '秒','距离早上7:00点开始');
  291. }
  292. //现在时间距离第二天开始时间
  293. // day3.setTime(day3.getTime()+24*60*60*1000);
  294. // var s3 = day3.getFullYear()+"-" + (day3.getMonth()+1) + "-" + day3.getDate();
  295. },
  296. //获取明天早上7:00的时间戳
  297. GetDate(){
  298. let obj = this;
  299. let now = new Date();
  300. //现在时间转换成时间戳
  301. let nowTime = now.getTime();
  302. now.setTime(now.getTime()+24*60*60*1000);
  303. let time = obj.workstarTime;
  304. let data = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() + ' ' + time;
  305. data = data.replace(/-/g, '/');
  306. let time4 = new Date(data);
  307. let tomorrow = time4.getTime();
  308. let starTime = tomorrow - nowTime;
  309. let hours = Math.floor((starTime / 1000 / 60 / 60) % 24); //获取剩余小时数
  310. let minutes = Math.floor((starTime / 1000 / 60) % 60); //获取分钟
  311. let seconds = Math.floor((starTime / 1000) % 60); //获取秒数
  312. obj.hour = hours;
  313. obj.minute = minutes;
  314. obj.second = seconds;
  315. console.log('时间差是: '+ hours + '小时, ' + minutes + '分钟, ' + seconds + '秒','距离第二天6:40开始');
  316. },
  317. // 请求商品列表
  318. async loadData() {
  319. let obj = this;
  320. getProducts({
  321. type: 1,
  322. sid: obj.sid //分类id
  323. })
  324. .then(({ data }) => {
  325. obj.list = data;
  326. })
  327. .catch(err => {
  328. console.log(err);
  329. });
  330. },
  331. //加入购物车
  332. Addcar(item) {
  333. let obj = this;
  334. // let id = ls.id;
  335. // uni.navigateTo({
  336. // url: '/pages/product/product?id=' + id
  337. // });
  338. if(obj.checkid == 1){
  339. if(obj.start == true){
  340. this.$api.msg('未开始该活动!');
  341. return;
  342. }
  343. if(obj.Timeing== true){
  344. cartAdd({
  345. cartNum: '1', //商品数量
  346. uniqueId: '', //商品标签
  347. new: 0, //商品是否新增加到购物车1为不加入0为加入
  348. mer_id: '',
  349. productId: item.id //商品编号
  350. })
  351. .then(function(e) {
  352. uni.showToast({
  353. title: '成功加入购物车',
  354. type: 'top',
  355. duration: 500,
  356. icon: 'none'
  357. });
  358. obj.loadData();
  359. })
  360. .catch(e => {
  361. console.log(e);
  362. });
  363. return;
  364. }
  365. if(obj.end == true){
  366. this.$api.msg('该活动已结束!');
  367. return;
  368. }
  369. }else{
  370. this.$api.msg('未开始该活动!');
  371. return;
  372. }
  373. },
  374. //跳转商品详情页
  375. navToDetailPage(ls) {
  376. let obj = this;
  377. // let id = ls.id;
  378. // uni.navigateTo({
  379. // url: '/pages/product/product?id=' + id
  380. // });
  381. if(obj.checkid == 1){
  382. uni.showToast({
  383. title: obj.starting,
  384. type: 'top',
  385. duration: 500,
  386. icon: 'none'
  387. });
  388. if(obj.starting == true){
  389. this.$api.msg('未开始该活动!');
  390. return;
  391. }
  392. uni.showToast({
  393. title: obj.Timeing,
  394. type: 'top',
  395. duration: 500,
  396. icon: 'none'
  397. });
  398. if(obj.Timeing == true){
  399. let id = ls.id;
  400. uni.navigateTo({
  401. url: '/pages/product/product?id=' + id
  402. });
  403. return;
  404. }
  405. uni.showToast({
  406. title: obj.end,
  407. type: 'top',
  408. duration: 500,
  409. icon: 'none'
  410. });
  411. if(obj.end == true){
  412. alert(obj.end)
  413. this.$api.msg('该活动已结束!');
  414. return;
  415. }
  416. }else{
  417. this.$api.msg('未开始该活动!');
  418. }
  419. }
  420. }
  421. };
  422. </script>
  423. <style lang="scss">
  424. page {
  425. background: #ffffff;
  426. height: 100%;
  427. }
  428. .container {
  429. background: #ffffff;
  430. height: 100%;
  431. }
  432. .top-img {
  433. width: 100%;
  434. height: 220rpx;
  435. image {
  436. width: 100%;
  437. height: 100%;
  438. }
  439. }
  440. .switch-bar {
  441. width: 100%;
  442. font-size: 32rpx;
  443. .switchList {
  444. padding: 28rpx 0rpx;
  445. text-align: center;
  446. width: 50%;
  447. }
  448. .active_color {
  449. background: linear-gradient(270deg, #fe531e 0%, #fe9503 100%);
  450. color: #ffffff;
  451. }
  452. }
  453. .time{padding-right: 15rpx;}
  454. .preferred_centent {
  455. width: 100%;
  456. padding: 0rpx 25rpx;
  457. margin-bottom: 25rpx;
  458. padding-bottom: 80rpx !important;
  459. .tip {
  460. padding: 25rpx 0rpx;
  461. font-size: 28rpx;
  462. }
  463. .preferred_item {
  464. width: 100%;
  465. height: 100%;
  466. border-top: 1px solid #f0f0f0;
  467. padding: 25rpx 0rpx;
  468. position: relative;
  469. .tlist-img {
  470. width: 240rpx;
  471. position: relative;
  472. .img {
  473. width: 240rpx;
  474. height: 240rpx;
  475. image {
  476. width: 240rpx;
  477. height: 240rpx;
  478. }
  479. }
  480. .stock {
  481. margin-top: 13rpx;
  482. font-size: 26rpx;
  483. background: #fff1ee;
  484. width: 100%;
  485. color: #fb4912;
  486. padding: 6rpx 0;
  487. border-radius: 5rpx;
  488. justify-content: center;
  489. align-items: center;
  490. position: absolute;
  491. left: 0;
  492. bottom: 0;
  493. .img {
  494. width: 20rpx;
  495. height: 20rpx;
  496. flex-shrink: 0;
  497. }
  498. .stock-num {
  499. padding-left: 7rpx;
  500. font-size: 22rpx;
  501. border-radius: 5rpx;
  502. height: 32rpx;
  503. line-height: 32rpx;
  504. }
  505. }
  506. }
  507. .goods_name {
  508. padding-left: 25rpx;
  509. width: 65%;
  510. padding-right: 30rpx;
  511. .goods_title {
  512. white-space: nowrap;
  513. overflow: hidden;
  514. text-overflow: ellipsis;
  515. font-size: $font-base;
  516. color: $font-color-dark;
  517. font-weight: bold;
  518. }
  519. .goods-height{
  520. min-height: 120rpx;
  521. }
  522. .goods_num {
  523. font-size: 26rpx;
  524. color: #8f8f97;
  525. }
  526. .goods-tip {
  527. margin-bottom: -15rpx;
  528. text {
  529. border: 2rpx solid #ff1a27;
  530. color: #ff1a27;
  531. font-size: 20rpx;
  532. padding: 2rpx 8rpx;
  533. margin-right: 15rpx;
  534. border-radius: 7rpx;
  535. }
  536. }
  537. .price {
  538. font-size: 28rpx;
  539. position: relative;
  540. .price_list {
  541. .price-red {
  542. color: #ff1a27;
  543. font-weight: bold;
  544. font-size: 30rpx !important;
  545. text {
  546. color: #9699a0;
  547. font-size: 24rpx !important;
  548. font-weight: normal;
  549. padding: 0rpx 10rpx;
  550. // text-decoration: line-through;
  551. }
  552. }
  553. .price-green {
  554. color: #2dbd59;
  555. font-size: 26rpx !important;
  556. font-weight: bold;
  557. text {
  558. background:linear-gradient(45deg,rgba(21,197,52,1),rgba(21,197,52,1));
  559. color: #ffffff;
  560. padding: 0rpx 10rpx;
  561. border-radius: 7rpx;
  562. font-size: 24rpx !important;
  563. margin-left: 15rpx;
  564. }
  565. }
  566. }
  567. .img {
  568. width: 50rpx;
  569. height: 50rpx;
  570. position: absolute;
  571. right: 0;
  572. bottom: 0;
  573. image {
  574. width: 100%;
  575. height: 100%;
  576. }
  577. }
  578. .tomorrow{
  579. background: #29A66E;
  580. color: #FFFFFF;
  581. border-radius: 25rpx;
  582. padding: 10rpx 25rpx;
  583. }
  584. }
  585. }
  586. }
  587. }
  588. .shareDate{
  589. width: 100%;
  590. font-size: 28rpx;
  591. background: linear-gradient(270deg, #fe531e 0%, #fe9503 100%);
  592. padding: 25rpx 0rpx;
  593. line-height:1;
  594. text-align: center;
  595. color: #FFFFFF;
  596. position: fixed;
  597. bottom: 0;
  598. border: none;
  599. border-radius: 0rpx !important;
  600. }
  601. </style>