u-flash-sale.vue 10 KB

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