u-miaosha.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <template>
  2. <u-index-plugins url="/plugins/miaosha/advance/advance">
  3. <template v-slot:u-top-name>
  4. <view class="cross-center u-top">
  5. <image class="u-icon" :src="appImg.icon_home_miaosha"></image>
  6. <view class="box-grow-1 u-name">整点秒杀</view>
  7. <template v-if="newData.open_date">
  8. <view :class="timer ? 'box-grow-0' : 'box-grow-1'">{{newData.str}}</view>
  9. <view class="box-grow-1 dir-left-nowrap u-time-box" v-if="timer">
  10. <view class="main-center cross-center u-time">{{timer.hour}}</view>
  11. <view class="main-center cross-center u-symbol">:</view>
  12. <view class="main-center cross-center u-time">{{timer.min}}</view>
  13. <view class="main-center cross-center u-symbol">:</view>
  14. <view class="main-center cross-center u-time">{{timer.sec}}</view>
  15. </view>
  16. </template>
  17. </view>
  18. </template>
  19. <template v-slot:u-body>
  20. <view v-if="style === '1'" class="dir-left-nowrap">
  21. <view v-for="(goods, index) in goodsList" v-bind:key="index" class="u-goods dir-top-nowrap box-grow-0" v-on:click="router(goods)">
  22. <view class="u-cover-box">
  23. <view class="u-out-dialog" v-if="isShowStock(goods)">
  24. <image class="u-pic" :src="appSetting.is_use_stock == '1' ? appImg.plugins_out : appSetting.sell_out_pic"></image>
  25. </view>
  26. <image class="box-grow-0 u-cover" v-bind:src="goods.cover_pic"></image>
  27. </view>
  28. <view class="box-grow-0 u-goods-name t-omit-two ">
  29. {{goods.name}}
  30. </view>
  31. <view class="box-grow-1 u-content dir-top-nowrap main-right">
  32. <view class="u-margin" v-if="isShowMemPrice(goods)">
  33. <app-member-price
  34. :theme="theme"
  35. v-bind:price="goods.level_price"
  36. ></app-member-price>
  37. </view>
  38. <view class="u-margin" v-if="isShowVip(goods)">
  39. <app-sup-vip
  40. v-bind:is_vip_card_user="goods.vip_card_appoint.is_vip_card_user"
  41. v-bind:discount="goods.vip_card_appoint.discount"
  42. ></app-sup-vip>
  43. </view>
  44. <view v-bind:class="[theme.color, 'dir-left-nowrap', 'u-price-box', 't-omit']">
  45. <text class="u-price">{{goods.price_content}}</text>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. <view v-if="style === '2'">
  51. <u-ordinary-list :theme-object="theme" :showBuyBtn="false" :theme="getTheme" :list-style="2" :list="newData.list"></u-ordinary-list>
  52. </view>
  53. </template>
  54. </u-index-plugins>
  55. </template>
  56. <script>
  57. import {mapGetters, mapState} from 'vuex';
  58. import uIndexPlugins from '../u-index-plugins/u-index-plugins.vue';
  59. import uOrdinaryList from '@/components/page-component/u-goods-list/u-ordinary-list.vue';
  60. export default {
  61. name: "u-miaosha",
  62. props: {
  63. value: {
  64. type: Object,
  65. default() {
  66. return {
  67. open_date: null,
  68. list: []
  69. };
  70. }
  71. },
  72. pageHide: Boolean,
  73. theme: Object,
  74. index: Number,
  75. page_id: Number,
  76. is_required: Boolean,
  77. appImg: {
  78. type: Object,
  79. default: function() {
  80. return {
  81. plugins_out: ''
  82. }
  83. }
  84. },
  85. appSetting: {
  86. type: Object,
  87. default: function() {
  88. return {
  89. is_show_stock: 1,
  90. sell_out_pic: '',
  91. is_use_stock: 1
  92. }
  93. }
  94. }
  95. },
  96. data() {
  97. return {
  98. style: '1',
  99. goods_num: 20,
  100. newData: {
  101. },
  102. timer: null,
  103. time: null,
  104. is_vip: true,
  105. tempList: [],
  106. goodsList: [],
  107. timeOut: 0
  108. };
  109. },
  110. components: {
  111. uIndexPlugins,
  112. uOrdinaryList
  113. },
  114. computed: {
  115. ...mapGetters('mallConfig', {
  116. getTheme: 'getTheme',
  117. })
  118. },
  119. beforeDestroy() {
  120. clearInterval(this.time);
  121. clearTimeout(this.timeOut);
  122. },
  123. watch: {
  124. pageHide: {
  125. handler(v) {
  126. if (v) {
  127. clearInterval(this.time);
  128. clearTimeout(this.timeOut);
  129. return ;
  130. }
  131. },
  132. immediate: true
  133. },
  134. 'newData': {
  135. handler(newVal) {
  136. if (this.$validation.isEmpty(newVal)) return;
  137. this.tempList = this.cloneData(newVal.list);
  138. this.splitData();
  139. },
  140. immediate: true
  141. }
  142. },
  143. methods: {
  144. // 是否展示会员价
  145. isShowMemPrice(goods) {
  146. return goods.is_level === 1 && goods.is_negotiable !== 1 ? 1 : 0;
  147. },
  148. // 是否展示超级会员价
  149. isShowVip(goods) {
  150. return goods.vip_card_appoint && goods.vip_card_appoint.discount > 0 && goods.is_negotiable !== 1 ? 1 : 0;
  151. },
  152. // 是否展示售罄
  153. isShowStock(goods) {
  154. return this.appSetting.is_show_stock === 1 && goods.goods_stock === 0 ? 1: 0;
  155. },
  156. router(goods) {
  157. this.$emit('router', goods);
  158. },
  159. loadData() {
  160. let para = {
  161. type: this.page_id === 0 ? 'mall' : 'diy',
  162. key: 'miaosha',
  163. page_id: this.page_id,
  164. index: this.index
  165. }
  166. if(this.goods_num) {
  167. para.goods_num = this.goods_num
  168. }
  169. this.$request({
  170. url: this.$api.index.extra,
  171. data: para
  172. }).then(e => {
  173. if (e.code === 0 && e.data) {
  174. this.newData = e.data;
  175. this.newData.str = '00:00:00 点场';
  176. let timenow = new Date();//获取当前时间
  177. if ((new Date(this.newData.open_date)).getDate() != timenow.getDate()) {
  178. this.newData.str = '预告 ' + this.newData.open_date + ' ' + this.newData.open_time + '点场';
  179. } else if (this.newData.open_time != timenow.getHours()) {
  180. this.newData.str = '预告 ' + this.newData.open_time + '点场';
  181. } else {
  182. let timelog = this.newData.date_time * 1000 - timenow.getTime();//时间差的所有毫秒数
  183. this.time = setInterval(() => {
  184. timelog -= 1000;
  185. this.newData.str = this.newData.open_time + '点场';
  186. if (timelog <= 0) {
  187. clearInterval(this.time);
  188. return;
  189. }
  190. let hour = parseInt((timelog / 1000 / 60 / 60));
  191. let min = parseInt((timelog / 1000 / 60) % 60);
  192. let sec = parseInt((timelog / 1000) % 60);
  193. this.timer = {
  194. hour: hour < 10 ? "0" + hour : hour,
  195. min: min < 10 ? "0" + min : min,
  196. sec: sec < 10 ? "0" + sec : sec
  197. };
  198. }, 1000);
  199. }
  200. }
  201. })
  202. },
  203. // 复制而不是引用对象和数组
  204. cloneData(data) {
  205. return JSON.parse(JSON.stringify(data));
  206. },
  207. // 循环载入
  208. splitData() {
  209. if (!this.tempList.length) return;
  210. let item = this.tempList[0];
  211. this.goodsList.push(item);
  212. this.tempList.splice(0, 1);
  213. if (this.tempList.length) {
  214. this.timeOut = setTimeout(() => {
  215. this.splitData();
  216. }, 200);
  217. }
  218. },
  219. },
  220. mounted() {
  221. let storage = this.$storage.getStorageSync('INDEX_MALL');
  222. this.style = storage.home_pages[this.index].style;
  223. this.goods_num = storage.home_pages[this.index].goods_num;
  224. this.loadData();
  225. }
  226. }
  227. </script>
  228. <style scoped lang="scss">
  229. @import url('./index.scss');
  230. .u-icon {
  231. width: 46upx;
  232. height: 46upx;
  233. margin-right: 16upx;
  234. }
  235. .u-top {
  236. font-size: 24upx;
  237. color: #999999;
  238. }
  239. .u-name {
  240. color: #ff8831;
  241. font-size: 28upx;
  242. margin-right: 20upx;
  243. }
  244. .u-time-box {
  245. margin-left: #{23rpx};
  246. }
  247. .u-symbol {
  248. width: 20upx;
  249. height: 34upx;
  250. }
  251. .u-time {
  252. width: 32upx;
  253. height: 34upx;
  254. font-size: 20upx;
  255. color: #ffffff;
  256. border-radius: 4upx;
  257. background-color: #4c4c4c;
  258. }
  259. </style>