seckill.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <template>
  2. <!-- 秒杀列表 -->
  3. <view :style="[boxStyle]" v-if="spikeList.length > 0">
  4. <view :style="[boxContentStyle]">
  5. <!-- 秒杀头部 -->
  6. <view class="w-full h-96 px-24 flex-between-center bg-cover" :style="[headerStyle]">
  7. <view class="flex-y-center">
  8. <text class="fs-32 lh-44rpx fw-500" v-if="titleConfig">{{titleTxtConfig}}</text>
  9. <image :src="titleImg" class="w-140 h-32" v-else></image>
  10. <text class="fs-26 text--w111-999 lh-36rpx pl-20" :style="[tipsColor]">距离结束</text>
  11. <countDown
  12. :is-day="false"
  13. tip-text=" "
  14. day-text=" "
  15. hour-text=":"
  16. minute-text=":"
  17. second-text=" "
  18. :datatime="datatime"
  19. :bgColor="numberBgColor"
  20. :colors="numberColor"
  21. :dotColor="dotColor"></countDown>
  22. </view>
  23. <view class="flex-y-center fs-24 text--w111-999" :style="[headerBntColor]"
  24. @tap="goPage('/pages/activity/goods_seckill/index')">
  25. <text>{{rightBntTxt}}</text>
  26. <text class="iconfont icon-ic_rightarrow fs-24"></text>
  27. </view>
  28. </view>
  29. <!-- 单列 -->
  30. <view class="pt-32 pr-20 pb-32 pl-20 bg--w111-fff" :style="[contentBox]"
  31. v-if="goodStyleConfig == 0">
  32. <view class="w-full flex justify-between item"
  33. v-for="(item,index) in spikeList" :key="index"
  34. @tap="goDetails(item)">
  35. <easy-loadimage
  36. :image-src="item.image"
  37. :border-src="item.activity_image"
  38. width="240rpx"
  39. height="240rpx"
  40. :borderRadius="imgStyle"></easy-loadimage>
  41. <view class="flex-1 flex-col justify-between pl-20 h-240">
  42. <view>
  43. <view class="w-full fs-28 h-80 lh-40rpx line2" :style="[productStyle]"
  44. v-if="checkboxInfo.includes(0)">{{item.title}}</view>
  45. <view class="w-full flex-y-center mt-20">
  46. <view class="progress relative">
  47. <view class="active" :style="{'width': item.percent +'%',background:progressBgColor}"></view>
  48. <image src="@/static/img/lightning.png" class="lightning"
  49. :style="{left: item.percent == 100 ? '107px' : item.percent +'%'}"></image>
  50. </view>
  51. <text class="fs-22 lh-30rpx pl-12" :style="{color: priceColor}">{{item.percent +'%'}}</text>
  52. </view>
  53. </view>
  54. <view class="flex justify-between items-end">
  55. <view class="flex-col">
  56. <baseMoney
  57. :money="item.price"
  58. symbolSize="24"
  59. integerSize="36"
  60. decimalSize="36" weight
  61. :color="priceColor"
  62. preFix="秒杀价"
  63. preFixSize="24"
  64. :textColor="priceColor"
  65. v-if="checkboxInfo.includes(2)"></baseMoney>
  66. <text class="text-line fs-28 text--w111-999 pt-14 Regular"
  67. v-if="checkboxInfo.includes(3)"
  68. :style="[otPriceColor]">¥{{item.ot_price.toString().split('.')[1] ? item.ot_price : item.ot_price + '.00'}}</text>
  69. </view>
  70. <view class='w-144 h-56 rd-30rpx flex-center fs-24 text--w111-fff'
  71. v-if="!showBtn" :style="[btnBgColor]">去抢购</view>
  72. </view>
  73. </view>
  74. </view>
  75. </view>
  76. <!-- 两列 -->
  77. <view class="grid-column-2 grid-gap-22rpx pt-32 pr-20 pb-32 pl-20" v-if="goodStyleConfig == 1">
  78. <view v-for="(item,index) in spikeList" :key="index"
  79. @tap="goDetails(item)">
  80. <easy-loadimage
  81. :image-src="item.image"
  82. :border-src="item.activity_image"
  83. width="100%"
  84. height="324rpx"
  85. :borderRadius="imgStyle"></easy-loadimage>
  86. <view class="w-full line1 mt-16 fs-28 lh-40rpx"
  87. :style="[productStyle]" v-if="checkboxInfo.includes(0)">{{item.title}}</view>
  88. <view class="flex justify-between items-end mt-10">
  89. <view class="flex-col">
  90. <baseMoney
  91. :money="item.price"
  92. symbolSize="24"
  93. integerSize="36"
  94. decimalSize="36"
  95. weight
  96. :color="priceColor"
  97. v-if="checkboxInfo.includes(2)"></baseMoney>
  98. <text class="text-line fs-28 text--w111-999 pt-14 Regular"
  99. v-if="checkboxInfo.includes(3)" :style="[otPriceColor]"
  100. >¥{{item.ot_price.toString().split('.')[1] ? item.ot_price : item.ot_price + '.00'}}</text>
  101. </view>
  102. <view class='w-144 h-56 rd-30rpx flex-center fs-24 text--w111-fff bg--w111-E93323'
  103. v-if="!showBtn" :style="[btnBgColor]">去抢购</view>
  104. </view>
  105. </view>
  106. </view>
  107. <!-- 三列 -->
  108. <view class="grid-column-3 grid-gap-18rpx pt-32 pr-20 pb-32 pl-20" v-if="goodStyleConfig == 2">
  109. <view v-for="(item,index) in spikeList" :key="index"
  110. @tap="goDetails(item)">
  111. <easy-loadimage
  112. :image-src="item.image"
  113. :border-src="item.activity_image"
  114. width="100%"
  115. height="212rpx"
  116. :borderRadius="imgStyle"></easy-loadimage>
  117. <view class="w-full line1 mt-16 fs-26" :style="[productStyle]"
  118. v-if="checkboxInfo.includes(0)">{{item.title}}</view>
  119. <view class="price-box flex-center relative">
  120. <baseMoney :money="item.price"
  121. symbolSize="24"
  122. integerSize="36"
  123. decimalSize="36"
  124. weight
  125. color="#ffffff"
  126. v-if="checkboxInfo.includes(2)"></baseMoney>
  127. <image src="@/static/img/shandian.png" class="shandian"></image>
  128. </view>
  129. <view class="text-line fs-24 text--w111-999 Regular lh-32rpx mt-10"
  130. :style="[otPriceColor]" v-if="checkboxInfo.includes(3)"
  131. >¥{{item.ot_price.toString().split('.')[1] ? item.ot_price : item.ot_price + '.00'}}</view>
  132. </view>
  133. </view>
  134. <!-- 滑动 -->
  135. <scroll-view scroll-x="true" show-scrollbar="false"
  136. class="white-nowrap vertical-middle w-full pt-32 pb-32"
  137. v-if="goodStyleConfig == 3">
  138. <view class="inline-block ml-20" v-for="(item,index) in spikeList" :key="index"
  139. @tap="goDetails(item)">
  140. <easy-loadimage
  141. :image-src="item.image"
  142. :border-src="item.activity_image"
  143. width="224rpx"
  144. height="224rpx"
  145. :borderRadius="imgStyle"></easy-loadimage>
  146. <view class="w-222 line1 mt-16 fs-26" :style="[productStyle]"
  147. v-if="checkboxInfo.includes(0)">{{item.title}}</view>
  148. <view class="flex justify-between items-end mt-16">
  149. <view>
  150. <baseMoney :money="item.price"
  151. symbolSize="24"
  152. integerSize="36"
  153. decimalSize="36"
  154. weight
  155. :color="priceColor"
  156. v-if="checkboxInfo.includes(2)"></baseMoney>
  157. <view class="text-line fs-24 text--w111-999 Regular lh-32rpx"
  158. :style="[otPriceColor]" v-if="checkboxInfo.includes(3)"
  159. >¥{{item.ot_price.toString().split('.')[1] ? item.ot_price : item.ot_price + '.00'}}</view>
  160. </view>
  161. <view class="qiang flex-center fs-24 text--w111-fff"
  162. v-if="!showBtn" :style="[btnBgColor]">抢</view>
  163. </view>
  164. </view>
  165. </scroll-view>
  166. </view>
  167. </view>
  168. </template>
  169. <script>
  170. import countDown from '@/components/countDown';
  171. import {
  172. getSeckillIndexTime,
  173. getSeckillList
  174. } from '@/api/activity.js';
  175. export default {
  176. options: {
  177. styleIsolation: 'shared' ,
  178. },
  179. name: 'seckill',
  180. components:{
  181. countDown
  182. },
  183. props: {
  184. dataConfig: {
  185. type: Object,
  186. default: () => {}
  187. },
  188. isSortType:{
  189. type: String | Number,
  190. default:0
  191. }
  192. },
  193. data() {
  194. return {
  195. datatime:'',
  196. spikeList: [],
  197. seckillTimeIndex:0,
  198. seckillTime: [],
  199. };
  200. },
  201. computed:{
  202. boxStyle(){
  203. return {
  204. padding: `${this.dataConfig.topConfig.val * 2}rpx ${this.dataConfig.prConfig.val * 2}rpx ${this.dataConfig.bottomConfig.val * 2}rpx`,
  205. marginTop: `${this.dataConfig.mbConfig.val * 2}rpx`,
  206. background: this.dataConfig.bottomBgColor.color[0].item,
  207. }
  208. },
  209. boxContentStyle() {
  210. let borderRadius = `${this.dataConfig.fillet.val * 2}rpx`;
  211. if (this.dataConfig.fillet.type) {
  212. borderRadius =
  213. `${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx ${this.dataConfig.fillet.valList[2].val * 2}rpx ${this.dataConfig.fillet.valList[3].val * 2}rpx`;
  214. }
  215. return {
  216. borderRadius,
  217. background: `linear-gradient(90deg, ${this.dataConfig.moduleColor.color[0].item} 0%, ${this.dataConfig.moduleColor.color[1].item} 100%)`,
  218. };
  219. },
  220. contentBox(){
  221. let br = `${this.dataConfig.fillet.val * 2}rpx`,
  222. borderRadius= '',
  223. imgBgUrl = this.dataConfig.imgBgConfig.url;
  224. if (this.dataConfig.fillet.type){
  225. borderRadius = `0 0 ${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx`
  226. }else{
  227. borderRadius = `0 0 ${br} ${br}`
  228. }
  229. return {
  230. borderRadius,
  231. }
  232. },
  233. /*商品模板*/
  234. goodStyleConfig(){
  235. return this.dataConfig.goodStyleConfig.tabVal
  236. },
  237. styleConfig(){
  238. return this.dataConfig.styleConfig.tabVal
  239. },
  240. headerStyle(){
  241. let br = `${this.dataConfig.fillet.val * 2}rpx`,
  242. borderRadius= '',
  243. imgBgUrl = this.dataConfig.imgBgConfig.url;
  244. if (this.dataConfig.fillet.type){
  245. borderRadius = `${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx 0 0`
  246. }else{
  247. borderRadius = `${br} ${br} 0 0`
  248. }
  249. return {
  250. backgroundImage: this.styleConfig ? 'url(' + imgBgUrl + ')' : `linear-gradient(90deg,${this.dataConfig.headerBgColor.color[0].item} 0%,${this.dataConfig.headerBgColor.color[0].item} 100%)`,
  251. borderRadius,
  252. }
  253. },
  254. /*标题是文本还是图片*/
  255. titleConfig(){
  256. return this.dataConfig.titleConfig.tabVal
  257. },
  258. /*标题文本*/
  259. titleTxtConfig(){
  260. return this.dataConfig.titleTxtConfig.value
  261. },
  262. /*标题图片*/
  263. titleImg(){
  264. return this.styleConfig ? this.titleUrl : this.titleColorUrl
  265. },
  266. titleColorUrl(){
  267. return this.dataConfig.imgColorConfig.url
  268. },
  269. titleUrl(){
  270. return this.dataConfig.imgConfig.url
  271. },
  272. /*标题提示文字*/
  273. tipsColor(){
  274. return {
  275. color: this.styleConfig ? this.dataConfig.tipsColor.color[0].item : this.dataConfig.tipsColor2.color[0].item
  276. }
  277. },
  278. /*头部按钮文本*/
  279. rightBntTxt(){
  280. return this.dataConfig.rightBntConfig.value
  281. },
  282. /*头部按钮样式*/
  283. headerBntColor(){
  284. return {
  285. color: this.styleConfig ? this.dataConfig.headerBntColor.color[0].item : this.dataConfig.headerBntColor2.color[0].item,
  286. fontSize: `${this.dataConfig.bntNumber.val * 2}rpx`
  287. }
  288. },
  289. /*商品图片圆角样式*/
  290. imgStyle(){
  291. let borderRadius = `${this.dataConfig.filletImg.val * 2}rpx`;
  292. if (this.dataConfig.filletImg.type) {
  293. borderRadius =
  294. `${this.dataConfig.filletImg.valList[0].val * 2}rpx ${this.dataConfig.filletImg.valList[1].val * 2}rpx ${this.dataConfig.filletImg.valList[2].val * 2}rpx ${this.dataConfig.filletImg.valList[3].val * 2}rpx`;
  295. }
  296. return borderRadius
  297. },
  298. /*商品名称样式*/
  299. productStyle(){
  300. return {
  301. color: this.dataConfig.goodsNameColor.color[0].item,
  302. fontWeight: this.dataConfig.goodsName.tabVal ? 'normal' : '500'
  303. }
  304. },
  305. /* 展示信息 */
  306. checkboxInfo(){
  307. return this.dataConfig.checkboxInfo.type
  308. },
  309. /* 价格颜色 */
  310. priceColor(){
  311. return this.dataConfig.toneConfig.tabVal ? this.dataConfig.seckillPriceColor.color[0].item : 'var(--view-theme)'
  312. },
  313. /* 原价颜色 */
  314. otPriceColor(){
  315. return this.dataConfig.goodsPriceColor.color[0].item
  316. },
  317. showBtn(){
  318. return this.dataConfig.seckillConfig.tabVal
  319. },
  320. /* 按钮颜色 */
  321. btnBgColor(){
  322. return {
  323. background: this.dataConfig.toneConfig.tabVal ? `linear-gradient(90deg,${this.dataConfig.goodsBntColor.color[1].item} 0%,${this.dataConfig.goodsBntColor.color[0].item} 100%)`: 'linear-gradient(90deg, var(--view-gradient) 0%, var(--view-theme) 100%)'
  324. }
  325. },
  326. progressBgColor(){
  327. return this.dataConfig.toneConfig.tabVal ? `linear-gradient(90deg,${this.dataConfig.progressColor.color[0].item} 0%,${this.dataConfig.progressColor.color[1].item} 100%)`: 'linear-gradient(45deg, var(--view-gradient) 0%, var(--view-theme) 100%)'
  328. },
  329. /*倒计时背景色*/
  330. numberBgColor(){
  331. return this.styleConfig ? this.dataConfig.numberBgColor.color[0].item : this.dataConfig.numberBgColor2.color[0].item
  332. },
  333. numberColor(){
  334. return this.styleConfig ? this.dataConfig.numberColor.color[0].item : this.dataConfig.numberColor2.color[0].item
  335. },
  336. dotColor(){
  337. return this.styleConfig ? this.dataConfig.numberBgColor.color[0].item : this.dataConfig.numberBgColor2.color[0].item
  338. },
  339. /*商品数量*/
  340. numberConfig(){
  341. return this.dataConfig.numberConfig.val
  342. }
  343. },
  344. mounted() {
  345. this.getSeckillIndexTime();
  346. },
  347. methods: {
  348. goPage(url){
  349. uni.navigateTo({
  350. url
  351. })
  352. },
  353. goDetails(item){
  354. uni.navigateTo({
  355. url: '/pages/activity/goods_details/index?id=' + item.id + '&type=1&time_id=' + this.timeList[this.active].id
  356. })
  357. },
  358. getSeckillIndexTime() {
  359. let limit = this.$config.LIMIT;
  360. let params = {
  361. page: 1,
  362. limit: this.numberConfig>=limit?limit:this.numberConfig,
  363. type: 'index'
  364. }
  365. getSeckillIndexTime().then(res => {
  366. this.timeList = res.data.seckillTime;
  367. this.active = res.data.seckillTimeIndex;
  368. if (res.data.seckillTimeIndex === -1) {
  369. return;
  370. }
  371. this.datatime = res.data.seckillTime[res.data.seckillTimeIndex].stop
  372. let id = res.data.seckillTime[res.data.seckillTimeIndex].id
  373. getSeckillList(id, params).then(({data}) => {
  374. this.spikeList = data
  375. })
  376. })
  377. },
  378. }
  379. }
  380. </script>
  381. <style lang="scss" scoped>
  382. .Regular{
  383. font-family: 'Regular';
  384. }
  385. ::v-deep .styleAll{
  386. padding: 0 8rpx;
  387. border-radius: 4rpx;
  388. font-size: 24rpx;
  389. line-height: 40rpx;
  390. }
  391. .bg-cover{
  392. background-size: cover;
  393. }
  394. .item ~ .item{
  395. margin-top: 32rpx;
  396. }
  397. .progress{
  398. width:240rpx;
  399. height: 24rpx;
  400. border-radius: 12rpx;
  401. background-color: rgba(253, 240, 237, 1);
  402. .active{
  403. height: 24rpx;
  404. border-radius: 12rpx;
  405. background: linear-gradient(45deg, #FF7931 0%, #E93323 100%);
  406. }
  407. .lightning{
  408. position: absolute;
  409. top: -2rpx;
  410. width: 28rpx;
  411. height: 28rpx;
  412. }
  413. }
  414. .price-box{
  415. width: 150rpx;
  416. height: 44rpx;
  417. background: linear-gradient(45deg, var(--view-gradient) 0%, var(--view-theme) 100%);
  418. border-radius: 0px 8rpx 8rpx 0px;
  419. margin: 20rpx 0 0 10rpx;
  420. .shandian{
  421. position: absolute;
  422. width: 24rpx;
  423. height: 44rpx;
  424. top: 0;
  425. left: -10rpx;
  426. }
  427. }
  428. .qiang{
  429. width: 66rpx;
  430. height: 40rpx;
  431. background: linear-gradient(45deg, #FF7931 0%, #E93323 100%);
  432. border-radius: 0px 22rpx 22rpx 0px;
  433. position: relative;
  434. &:before{
  435. content:'';
  436. position: absolute;
  437. top: 0;
  438. left: -10rpx;
  439. width: 24rpx;
  440. height: 40rpx;
  441. background-image: url('@/static/img/shandian.png');
  442. background-size: cover;
  443. }
  444. }
  445. </style>