营销:适配商城装修组件【秒杀】(待重写)
							parent
							
								
									343b1fd5f6
								
							
						
					
					
						commit
						cfc04d9c82
					
				|  | @ -1,6 +1,6 @@ | |||
| import request from '@/sheep/request'; | ||||
| 
 | ||||
| export default { | ||||
| const SpuApi = { | ||||
|     // 获得商品 SPU 列表
 | ||||
|     getSpuList: (recommendType) => { | ||||
|         return request({ | ||||
|  | @ -34,3 +34,4 @@ export default { | |||
|         }); | ||||
|     } | ||||
| }; | ||||
| export default SpuApi; | ||||
|  |  | |||
|  | @ -0,0 +1,33 @@ | |||
| import request2 from "@/sheep/request2"; | ||||
| 
 | ||||
| const SeckillApi = { | ||||
|   // 获得秒杀时间段列表
 | ||||
|   getSeckillConfigList: () => { | ||||
|     return request2({ url: 'promotion/seckill-config/list', method: 'GET' }); | ||||
|   }, | ||||
| 
 | ||||
|   // 获得当前秒杀活动
 | ||||
|   getNowSeckillActivity: () => { | ||||
|     return request2({ url: 'promotion/seckill-activity/get-now', method: 'GET' }); | ||||
|   }, | ||||
| 
 | ||||
|   // 获得秒杀活动分页
 | ||||
|   getSeckillActivityPage: () => { | ||||
|     return request2({ url: 'promotion/seckill-activity/page', method: 'GET' }); | ||||
|   }, | ||||
| 
 | ||||
|   /** | ||||
|    * 获得秒杀活动明细 | ||||
|    * @param {number} id 秒杀活动编号 | ||||
|    * @return {*} | ||||
|    */ | ||||
|   getSeckillActivity: (id) => { | ||||
|     return request2({ | ||||
|       url: 'promotion/seckill-activity/get-detail', | ||||
|       method: 'GET', | ||||
|       params: { id } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export default SeckillApi; | ||||
|  | @ -34,11 +34,11 @@ | |||
|     <!-- 营销组件:拼团 --> | ||||
|     <s-groupon-block v-if="type === 'groupon'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:秒杀 --> | ||||
|     <s-seckill-block v-if="type === 'seckill'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:积分商城 --> | ||||
|     <s-score-block v-if="type === 'scoreGoods'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:小程序直播 --> | ||||
|     <s-live-block v-if="type === 'mplive'" :data="data" :styles="styles" /> | ||||
|     <s-seckill-block v-if="type === 'PromotionSeckill'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:积分商城(模式不一样,无法适配) --> | ||||
|     <s-score-block v-if="type === 'PromotionPoint'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:小程序直播(暂时没有这个功能) --> | ||||
|     <s-live-block v-if="type === 'MpLive'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:优惠券 --> | ||||
|     <s-coupon-block v-if="type === 'CouponCard'" :data="data" :styles="styles" /> | ||||
|     <!-- 营销组件:文章 --> | ||||
|  |  | |||
|  | @ -12,8 +12,8 @@ | |||
|         <s-goods-column | ||||
|           class="" | ||||
|           size="sl" | ||||
|           :goodsFields="productFields" | ||||
|           :tagStyle="badge" | ||||
|           :goodsFields="data.fields" | ||||
|           :tagStyle="data.badge" | ||||
|           :data="item" | ||||
|           :titleColor="data.fields.name?.color" | ||||
|           :subTitleColor="data.fields.introduction.color" | ||||
|  | @ -46,8 +46,8 @@ | |||
|           <s-goods-column | ||||
|             class="goods-md-box" | ||||
|             size="md" | ||||
|             :goodsFields="productFields" | ||||
|             :tagStyle="badge" | ||||
|             :goodsFields="data.fields" | ||||
|             :tagStyle="data.badge" | ||||
|             :data="item" | ||||
|             :titleColor="data.fields.name?.color" | ||||
|             :subTitleColor="data.fields.introduction.color" | ||||
|  | @ -76,8 +76,8 @@ | |||
|           <s-goods-column | ||||
|             class="goods-md-box" | ||||
|             size="md" | ||||
|             :goodsFields="productFields" | ||||
|             :tagStyle="badge" | ||||
|             :goodsFields="data.fields" | ||||
|             :tagStyle="data.badge" | ||||
|             :data="item" | ||||
|             :titleColor="data.fields.name?.color" | ||||
|             :subTitleColor="data.fields.introduction.color" | ||||
|  | @ -109,9 +109,9 @@ | |||
|         <s-goods-column | ||||
|           class="goods-card" | ||||
|           size="lg" | ||||
|           :goodsFields="productFields" | ||||
|           :goodsFields="data.fields" | ||||
|           :data="item" | ||||
|           :tagStyle="badge" | ||||
|           :tagStyle="data.badge" | ||||
|           :titleColor="data.fields.name?.color" | ||||
|           :subTitleColor="data.fields.introduction.color" | ||||
|           :topRadius="data.borderRadiusTop" | ||||
|  | @ -174,7 +174,8 @@ | |||
|       return { | ||||
|         background: `linear-gradient(to right, ${btnBuy.bgBeginColor}, ${btnBuy.bgEndColor})`, | ||||
|       }; | ||||
|     } else if (btnBuy.type === 'img') { | ||||
|     } | ||||
|     if (btnBuy.type === 'img') { | ||||
|       // 图片按钮 | ||||
|       return { | ||||
|         width: '54rpx', | ||||
|  | @ -185,26 +186,6 @@ | |||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   // 商品字段配置,todo @owen 字段名称与服务端对齐,这里先转换,后期重构时再修改 | ||||
|   const productFields = computed(()  => { | ||||
|     return { | ||||
|       title: props.data.fields.name, | ||||
|       subtitle: props.data.fields.introduction, | ||||
|       price: props.data.fields.price, | ||||
|       original_price: props.data.fields.marketPrice, | ||||
|       stock: props.data.fields.stock, | ||||
|       salesCount: props.data.fields.salesCount, | ||||
|     } | ||||
|   }) | ||||
| 
 | ||||
|   // 角标,todo @owen 规范命名,这里先转换,后期重构时再修改 | ||||
|   const badge = computed(() => { | ||||
|     return { | ||||
|       show: props.data.badge.show, | ||||
|       src: props.data.badge.imgUrl, | ||||
|     } | ||||
|   }) | ||||
| 
 | ||||
|   //region 商品瀑布流布局 | ||||
|   // 下一个要处理的商品索引 | ||||
|   let count = 0; | ||||
|  |  | |||
|  | @ -9,15 +9,15 @@ | |||
|       @tap="onClick" | ||||
|     > | ||||
|       <view v-if="tagStyle.show" class="tag-icon-box"> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src)"></image> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> | ||||
|       </view> | ||||
|       <image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit"></image> | ||||
|       <view | ||||
|         v-if="goodsFields.title?.show || goodsFields.price?.show" | ||||
|         v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show" | ||||
|         class="xs-goods-content ss-flex-col ss-row-around" | ||||
|       > | ||||
|         <view | ||||
|           v-if="goodsFields.title?.show" | ||||
|           v-if="goodsFields.title?.show || goodsFields.name?.show" | ||||
|           class="xs-goods-title ss-line-1" | ||||
|           :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]" | ||||
|         > | ||||
|  | @ -37,16 +37,16 @@ | |||
|     <!-- sm卡片:竖向紧凑,一行放三个,图上内容下 --> | ||||
|     <view v-if="size === 'sm'" class="sm-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick"> | ||||
|       <view v-if="tagStyle.show" class="tag-icon-box"> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src)"></image> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> | ||||
|       </view> | ||||
|       <image class="sm-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image> | ||||
| 
 | ||||
|       <view | ||||
|         v-if="goodsFields.title?.show || goodsFields.price?.show" | ||||
|         v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show" | ||||
|         class="sm-goods-content" | ||||
|         :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]" | ||||
|       > | ||||
|         <view v-if="goodsFields.title?.show" class="sm-goods-title ss-line-1 ss-m-b-16"> | ||||
|         <view v-if="goodsFields.title?.show || goodsFields.name?.show" class="sm-goods-title ss-line-1 ss-m-b-16"> | ||||
|           {{ data.title || data.name }} | ||||
|         </view> | ||||
|         <view | ||||
|  | @ -63,7 +63,7 @@ | |||
|     <!-- md卡片:竖向,一行放两个,图上内容下 --> | ||||
|     <view v-if="size === 'md'" class="md-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick"> | ||||
|       <view v-if="tagStyle.show" class="tag-icon-box"> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src)"></image> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> | ||||
|       </view> | ||||
|       <image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix"></image> | ||||
|       <view | ||||
|  | @ -71,14 +71,14 @@ | |||
|         :id="elId" | ||||
|       > | ||||
|         <view | ||||
|           v-if="goodsFields.title?.show" | ||||
|           v-if="goodsFields.title?.show || goodsFields.name?.show" | ||||
|           class="md-goods-title ss-line-1" | ||||
|           :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]" | ||||
|         > | ||||
|           {{ data.title || data.name }} | ||||
|         </view> | ||||
|         <view | ||||
|           v-if="goodsFields.subtitle?.show" | ||||
|           v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show" | ||||
|           class="md-goods-subtitle ss-m-t-16 ss-line-1" | ||||
|           :style="[{ color: subTitleColor, background: subTitleBackground }]" | ||||
|         > | ||||
|  | @ -135,7 +135,7 @@ | |||
|       @tap="onClick" | ||||
|     > | ||||
|       <view v-if="tagStyle.show" class="tag-icon-box"> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src)"></image> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> | ||||
|       </view> | ||||
|       <view v-if="seckillTag" class="seckill-tag ss-flex ss-row-center"> 秒杀 </view> | ||||
|       <view v-if="grouponTag" class="groupon-tag ss-flex ss-row-center"> | ||||
|  | @ -145,14 +145,14 @@ | |||
|       <view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20"> | ||||
|         <view> | ||||
|           <view | ||||
|             v-if="goodsFields.title?.show" | ||||
|             v-if="goodsFields.title?.show || goodsFields.name?.show" | ||||
|             class="lg-goods-title ss-line-2" | ||||
|             :style="[{ color: titleColor }]" | ||||
|           > | ||||
|             {{ data.title || data.name }} | ||||
|           </view> | ||||
|           <view | ||||
|             v-if="goodsFields.subtitle?.show" | ||||
|             v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show" | ||||
|             class="lg-goods-subtitle ss-m-t-10 ss-line-1" | ||||
|             :style="[{ color: subTitleColor, background: subTitleBackground }]" | ||||
|           > | ||||
|  | @ -201,7 +201,7 @@ | |||
|     <!-- sl卡片:竖向型,一行放一个,图片上内容下边 --> | ||||
|     <view v-if="size === 'sl'" class="sl-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick"> | ||||
|       <view v-if="tagStyle.show" class="tag-icon-box"> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src)"></image> | ||||
|         <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image> | ||||
|       </view> | ||||
| 
 | ||||
|       <image class="sl-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image> | ||||
|  | @ -209,14 +209,14 @@ | |||
|       <view class="sl-goods-content"> | ||||
|         <view> | ||||
|           <view | ||||
|             v-if="goodsFields.title?.show" | ||||
|             v-if="goodsFields.title?.show || goodsFields.name?.show" | ||||
|             class="sl-goods-title ss-line-1" | ||||
|             :style="[{ color: titleColor }]" | ||||
|           > | ||||
|             {{ data.title || data.name }} | ||||
|           </view> | ||||
|           <view | ||||
|             v-if="goodsFields.subtitle?.show" | ||||
|             v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show" | ||||
|             class="sl-goods-subtitle ss-m-t-16" | ||||
|             :style="[{ color: subTitleColor, background: subTitleBackground }]" | ||||
|           > | ||||
|  | @ -307,12 +307,25 @@ | |||
|       type: [Array, Object], | ||||
|       default() { | ||||
|         return { | ||||
|           // 商品名称(旧) | ||||
|           title: { show: true }, | ||||
|           // 商品介绍(旧) | ||||
|           subtitle: { show: true }, | ||||
|           // 商品价格 | ||||
|           price: { show: true }, | ||||
|           // 市场价(旧) | ||||
|           original_price: { show: true }, | ||||
|           // 销量(旧) | ||||
|           sales: { show: true }, | ||||
|           // 库存 | ||||
|           stock: { show: true }, | ||||
|           // 商品名称(新) | ||||
|           name: { show: true }, | ||||
|           // 商品介绍(新) | ||||
|           introduction: { show: true }, | ||||
|           // 市场价(新) | ||||
|           marketPrice: { show: true }, | ||||
|           // 销量(新) | ||||
|           salesCount: { show: true }, | ||||
|         }; | ||||
|       }, | ||||
|  |  | |||
|  | @ -19,10 +19,10 @@ | |||
|         <s-goods-column | ||||
|           class="goods-card" | ||||
|           size="xs" | ||||
|           :goodsFields="productFields" | ||||
|           :tagStyle="tagStyle" | ||||
|           :goodsFields="data.fields" | ||||
|           :tagStyle="data.badge" | ||||
|           :data="item" | ||||
|           :titleColor="productFields.title?.color" | ||||
|           :titleColor="data.fields.name?.color" | ||||
|           :topRadius="data.borderRadiusTop" | ||||
|           :bottomRadius="data.borderRadiusBottom" | ||||
|           :titleWidth="(454 - marginRight * 2 - data.space * 2 - marginLeft * 2) / 2" | ||||
|  | @ -49,10 +49,10 @@ | |||
|         <s-goods-column | ||||
|           class="goods-card" | ||||
|           size="sm" | ||||
|           :goodsFields="productFields" | ||||
|           :tagStyle="tagStyle" | ||||
|           :goodsFields="data.fields" | ||||
|           :tagStyle="data.badge" | ||||
|           :data="item" | ||||
|           :titleColor="productFields.title?.color" | ||||
|           :titleColor="data.fields.name?.color" | ||||
|           :topRadius="data.borderRadiusTop" | ||||
|           :bottomRadius="data.borderRadiusBottom" | ||||
|           @click="sheep.$router.go('/pages/goods/index', { id: item.id })" | ||||
|  | @ -73,10 +73,10 @@ | |||
|             <s-goods-column | ||||
|               class="goods-card" | ||||
|               size="sm" | ||||
|               :goodsFields="productFields" | ||||
|               :tagStyle="tagStyle" | ||||
|               :goodsFields="data.fields" | ||||
|               :tagStyle="data.badge" | ||||
|               :data="item" | ||||
|               :titleColor="productFields.title?.color" | ||||
|               :titleColor="data.fields.name?.color" | ||||
|               :titleWidth="(750 - marginRight * 2 - data.space * 4 - marginLeft * 2) / 3" | ||||
|               @click="sheep.$router.go('/pages/goods/index', { id: item.id })" | ||||
|             ></s-goods-column> | ||||
|  | @ -105,7 +105,7 @@ | |||
|       default() {}, | ||||
|     }, | ||||
|   }); | ||||
|   const { layoutType, tagStyle, spuIds } = props.data; | ||||
|   const { layoutType, spuIds } = props.data; | ||||
|   let { marginLeft, marginRight } = props.styles; | ||||
|   const goodsList = ref([]); | ||||
|   onMounted(async () => { | ||||
|  | @ -114,26 +114,6 @@ | |||
|       goodsList.value = data; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   // 商品字段配置,todo @owen 字段名称与服务端对齐,这里先转换,后期重构时再修改 | ||||
|   const productFields = computed(()  => { | ||||
|     return { | ||||
|       title: props.data.fields.name, | ||||
|       subtitle: props.data.fields.introduction, | ||||
|       price: props.data.fields.price, | ||||
|       original_price: props.data.fields.marketPrice, | ||||
|       stock: props.data.fields.stock, | ||||
|       salesCount: props.data.fields.salesCount, | ||||
|     } | ||||
|   }) | ||||
| 
 | ||||
|   // 角标,todo @owen 规范命名,这里先转换,后期重构时再修改 | ||||
|   const badge = computed(() => { | ||||
|     return { | ||||
|       show: props.data.badge.show, | ||||
|       src: props.data.badge.imgUrl, | ||||
|     } | ||||
|   }) | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
|  |  | |||
|  | @ -1,14 +1,15 @@ | |||
| <!-- 装修组件 - 秒杀 --> | ||||
| <template> | ||||
|   <view> | ||||
|     <!-- 样式一:三列 - 上图下文 --> | ||||
|     <view | ||||
|       v-if="mode === 1" | ||||
|       v-if="layoutType === 'threeCol'" | ||||
|       class="goods-sm-box ss-flex ss-flex-wrap" | ||||
|       :style="[{ margin: '-' + data.space + 'rpx' }]" | ||||
|     > | ||||
|       <view | ||||
|         v-for="item in goodsList" | ||||
|         :key="item.id" | ||||
|         v-for="product in productList" | ||||
|         :key="product.id" | ||||
|         class="goods-card-box" | ||||
|         :style="[ | ||||
|           { | ||||
|  | @ -19,49 +20,49 @@ | |||
|         <s-goods-column | ||||
|           class="goods-card" | ||||
|           size="sm" | ||||
|           :goodsFields="goodsFields" | ||||
|           :goodsFields="data.fields" | ||||
|           :tagStyle="tagStyle" | ||||
|           :data="item" | ||||
|           :titleColor="goodsFields.title?.color" | ||||
|           :data="product" | ||||
|           :titleColor="data.fields.name?.color" | ||||
|           :topRadius="data.borderRadiusTop" | ||||
|           :bottomRadius="data.borderRadiusBottom" | ||||
|           @click=" | ||||
|             sheep.$router.go('/pages/goods/seckill', { | ||||
|               id: item.id, | ||||
|               id: product.id, | ||||
|               activity_id: props.data.activityId, | ||||
|             }) | ||||
|           " | ||||
|         ></s-goods-column> | ||||
|       </view> | ||||
|     </view> | ||||
|     <!-- 样式2 --> | ||||
|     <view class="goods-box" v-if="mode == 2"> | ||||
|     <!-- 样式二:一列 - 左图右文 --> | ||||
|     <view class="goods-box" v-if="layoutType === 'oneCol'"> | ||||
|       <view | ||||
|         class="goods-list" | ||||
|         v-for="(item, index) in goodsList" | ||||
|         v-for="(product, index) in productList" | ||||
|         :key="index" | ||||
|         :style="[{ marginBottom: space + 'px' }]" | ||||
|       > | ||||
|         <s-goods-column | ||||
|           class="goods-card" | ||||
|           size="lg" | ||||
|           :includes="goodsFields" | ||||
|           :goodsFields="data.fields" | ||||
|           :tagStyle="tagStyle" | ||||
|           :data="item" | ||||
|           :titleColor="goodsFields.title?.color" | ||||
|           :subTitleColor="goodsFields.subtitle.color" | ||||
|           :data="product" | ||||
|           :titleColor="data.fields.name?.color" | ||||
|           :subTitleColor="data.fields.introduction?.color" | ||||
|           :topRadius="data.borderRadiusTop" | ||||
|           :bottomRadius="data.borderRadiusBottom" | ||||
|           @click=" | ||||
|             sheep.$router.go('/pages/goods/seckill', { | ||||
|               id: item.id, | ||||
|               id: product.id, | ||||
|               activity_id: props.data.activityId, | ||||
|             }) | ||||
|           " | ||||
|         > | ||||
|           <template v-slot:cart> | ||||
|             <button class="ss-reset-button cart-btn" :style="[buyStyle]"> | ||||
|               {{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }} | ||||
|               {{ btnBuy?.type === 'text' ? btnBuy.text : '' }} | ||||
|             </button> | ||||
|           </template> | ||||
|         </s-goods-column> | ||||
|  | @ -72,14 +73,14 @@ | |||
| 
 | ||||
| <script setup> | ||||
|   /** | ||||
|    * 秒杀 | ||||
|    * | ||||
|    * @property {Array} list 											- 商品列表 | ||||
|    * | ||||
|    * 秒杀商品列表 | ||||
|    * | ||||
|    * @property {Array} list 商品列表 | ||||
|    */ | ||||
|   import { computed, onMounted, ref } from 'vue'; | ||||
|   import sheep from '@/sheep'; | ||||
|   import SeckillApi from "@/sheep/api/promotion/seckill"; | ||||
|   import SpuApi from "@/sheep/api/product/spu"; | ||||
| 
 | ||||
|   // 接收参数 | ||||
|   const props = defineProps({ | ||||
|  | @ -93,32 +94,35 @@ | |||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   let { mode, tagStyle, buyNowStyle, goodsFields, space } = props.data; | ||||
|   let { layoutType, tagStyle, btnBuy, space } = props.data; | ||||
|   let { marginLeft, marginRight } = props.styles; | ||||
| 
 | ||||
|   // 购买按钮样式 | ||||
|   const buyStyle = computed(() => { | ||||
|     let buyNowStyle = props.data.buyNowStyle; | ||||
|     if (buyNowStyle.mode == 1) { | ||||
|     let btnBuy = props.data.btnBuy; | ||||
|     if (btnBuy.type === 'text') { | ||||
|       return { | ||||
|         background: `linear-gradient(to right, ${buyNowStyle.color1}, ${buyNowStyle.color2})`, | ||||
|         background: `linear-gradient(to right, ${btnBuy.bgBeginColor}, ${btnBuy.bgEndColor})`, | ||||
|       }; | ||||
|     } | ||||
| 
 | ||||
|     if (buyNowStyle.mode == 2) { | ||||
|     if (btnBuy.type === 'img') { | ||||
|       return { | ||||
|         width: '54rpx', | ||||
|         height: '54rpx', | ||||
|         background: `url(${sheep.$url.cdn(buyNowStyle.src)}) no-repeat`, | ||||
|         background: `url(${sheep.$url.cdn(btnBuy.imgUrl)}) no-repeat`, | ||||
|         backgroundSize: '100% 100%', | ||||
|       }; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   const goodsList = ref([]); | ||||
|   // 商品列表 | ||||
|   const productList = ref([]); | ||||
|   // 查询秒杀活动商品 | ||||
|   onMounted(async () => { | ||||
|     let { data } = await sheep.$api.goods.activity({ activity_id: props.data.activityId }); | ||||
|     goodsList.value = data; | ||||
|     // todo:@owen 与Yudao结构不一致,待重构 | ||||
|     const { data: activity } = await SeckillApi.getSeckillActivity(props.data.activityId); | ||||
|     const { data: spu } = await SpuApi.getSpuDetail(activity.spuId) | ||||
|     productList.value = [spu]; | ||||
|   }); | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,49 +2,60 @@ import { ref } from 'vue'; | |||
| import dayjs from 'dayjs'; | ||||
| import $url from '@/sheep/url'; | ||||
| 
 | ||||
| // 格式化销量
 | ||||
| /** | ||||
|  * 格式化销量 | ||||
|  * @param {'exact' | string} type 格式类型:exact=精确值,其它=大致数量 | ||||
|  * @param {number} num 销量 | ||||
|  * @return {string} 格式化后的销量字符串 | ||||
|  */ | ||||
| export function formatSales(type, num) { | ||||
|   num = num + ''; | ||||
|   if (type === 'exact') { | ||||
|     return '已售' + num; | ||||
|   } else { | ||||
|     if (num < 10) { | ||||
|       return '销量≤10'; | ||||
|     } else { | ||||
|       let a = Math.pow(10, num.length - 1); | ||||
|       return '已售' + parseInt(num / a) * a + '+'; | ||||
|     } | ||||
|   } | ||||
|   let prefix = type!=='exact' && num<10 ? '销量': '已售'; | ||||
|   return formatNum(prefix, type, num) | ||||
| } | ||||
| 
 | ||||
| // 格式化兑换量
 | ||||
| /** | ||||
|  * 格式化兑换量 | ||||
|  * @param {'exact' | string} type 格式类型:exact=精确值,其它=大致数量 | ||||
|  * @param {number} num 销量 | ||||
|  * @return {string} 格式化后的销量字符串 | ||||
|  */ | ||||
| export function formatExchange(type, num) { | ||||
|   num = num + ''; | ||||
|   if (type === 'exact') { | ||||
|     return '已兑换' + num; | ||||
|   } else { | ||||
|     if (num < 10) { | ||||
|       return '已兑换≤10'; | ||||
|     } else { | ||||
|       let a = Math.pow(10, num.length - 1); | ||||
|       return '已兑换' + parseInt(num / a) * a + '+'; | ||||
|     } | ||||
|   } | ||||
|   return formatNum('已兑换', type, num) | ||||
| } | ||||
| 
 | ||||
| // 格式化库存
 | ||||
| 
 | ||||
| /** | ||||
|  * 格式化库存 | ||||
|  * @param {'exact' | any} type 格式类型:exact=精确值,其它=大致数量 | ||||
|  * @param {number} num 销量 | ||||
|  * @return {string} 格式化后的销量字符串 | ||||
|  */ | ||||
| export function formatStock(type, num) { | ||||
|   num = num + ''; | ||||
|   return formatNum('库存', type, num) | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 格式化数字 | ||||
|  * @param {string} prefix 前缀 | ||||
|  * @param {'exact' | string} type 格式类型:exact=精确值,其它=大致数量 | ||||
|  * @param {number} num 销量 | ||||
|  * @return {string} 格式化后的销量字符串 | ||||
|  */ | ||||
| export function formatNum(prefix, type, num) { | ||||
|   num = (num || 0); | ||||
|   // 情况一:精确数值
 | ||||
|   if (type === 'exact') { | ||||
|     return '库存' + num; | ||||
|   } else { | ||||
|     if (num < 10) { | ||||
|       return '库存≤10'; | ||||
|     } else { | ||||
|       let a = Math.pow(10, num.length - 1); | ||||
|       return '库存 ' + parseInt(num / a) * a + '+'; | ||||
|     } | ||||
|     return prefix + num; | ||||
|   } | ||||
|   // 情况二:小于等于 10
 | ||||
|   if (num < 10) { | ||||
|     return `${prefix}≤10`; | ||||
|   } | ||||
|   // 情况三:大于 10,除第一位外,其它位都显示为0
 | ||||
|   // 例如:100  - 199  显示为 100+
 | ||||
|   //      9000 - 9999 显示为 9000+
 | ||||
|   let pow = Math.pow(10, `${num}`.length - 1); | ||||
|   return `${prefix}${(num / pow) * pow}+`; | ||||
| } | ||||
| 
 | ||||
| // 格式化价格
 | ||||
|  | @ -52,49 +63,54 @@ export function formatPrice(e) { | |||
|   return e.length === 1 ? e[0] : e.join('~'); | ||||
| } | ||||
| 
 | ||||
| // 格式化商品轮播
 | ||||
| export function formatGoodsSwiper(list) { | ||||
|   let swiper = []; | ||||
|   list.forEach((item, key) => { | ||||
|     if (item.indexOf('.avi') !== -1 || item.indexOf('.mp4') !== -1) { | ||||
|       swiper.push({ | ||||
|         src: $url.cdn(item), | ||||
|         type: 'video', | ||||
|       }); | ||||
|     } else { | ||||
|       swiper.push({ | ||||
|         src: $url.cdn(item), | ||||
|         type: 'image', | ||||
|       }); | ||||
|     } | ||||
| // 视频格式后缀列表
 | ||||
| const VIDEO_SUFFIX_LIST = ['.avi', '.mp4'] | ||||
| /** | ||||
|  * 转换商品轮播的链接列表:根据链接的后缀,判断是视频链接还是图片链接 | ||||
|  * | ||||
|  * @param {string[]} urlList 链接列表 | ||||
|  * @return {{src: string, type: 'video' | 'image' }[]}  转换后的链接列表 | ||||
|  */ | ||||
| export function formatGoodsSwiper(urlList) { | ||||
|   return urlList.map((url, key) => { | ||||
|     const isVideo = VIDEO_SUFFIX_LIST.some(suffix => url.includes(suffix)); | ||||
|     const type = isVideo ? 'video' :'image' | ||||
|     const src = $url.cdn(url); | ||||
|     return { type, src } | ||||
|   }); | ||||
|   return swiper; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 格式化订单状态的颜色 | ||||
|  * @param type 订单类型 | ||||
|  * @return {string} 颜色的 class 名称 | ||||
|  */ | ||||
| export function formatOrderColor(type) { | ||||
|   if ( | ||||
|     type === 'apply_refund' || | ||||
|     type === 'groupon_ing' || | ||||
|     type === 'nocomment' || | ||||
|     type === 'noget' || | ||||
|     type === 'nosend' | ||||
|   ) { | ||||
|     return 'warning-color'; | ||||
|   } else if ( | ||||
|     type === 'closed' || | ||||
|     type === 'groupon_invalid' || | ||||
|     type === 'cancel' || | ||||
|     type === 'refund_agree' | ||||
|   ) { | ||||
|     return 'danger-color'; | ||||
|   } else if (type === 'completed') { | ||||
|     return 'success-color'; | ||||
|   } else if (type === 'unpaid') { | ||||
|     return 'info-color'; | ||||
|   switch (type) { | ||||
|     case 'apply_refund': | ||||
|     case 'groupon_ing': | ||||
|     case 'nocomment': | ||||
|     case 'noget': | ||||
|     case 'nosend': | ||||
|       return 'warning-color'; | ||||
|     case 'closed': | ||||
|     case 'groupon_invalid': | ||||
|     case 'cancel': | ||||
|     case 'refund_agree': | ||||
|       return 'danger-color'; | ||||
|     case 'completed': | ||||
|       return 'success-color'; | ||||
|     case 'unpaid': | ||||
|       return 'info-color'; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // 计算相隔时间
 | ||||
| /** | ||||
|  * 倒计时 | ||||
|  * @param toTime   截止时间 | ||||
|  * @param fromTime 起始时间,默认当前时间 | ||||
|  * @return {{s: string, ms: number, h: string, m: string}} 持续时间 | ||||
|  */ | ||||
| export function useDurationTime(toTime, fromTime = '') { | ||||
|   toTime = getDayjsTime(toTime); | ||||
|   if (fromTime === '') { | ||||
|  | @ -120,6 +136,11 @@ export function useDurationTime(toTime, fromTime = '') { | |||
|   }; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 转换为 Dayjs | ||||
|  * @param {any} time 时间 | ||||
|  * @return {dayjs.Dayjs} | ||||
|  */ | ||||
| function getDayjsTime(time) { | ||||
|   time = time.toString(); | ||||
|   if (time.indexOf('-') > 0) { | ||||
|  | @ -131,7 +152,7 @@ function getDayjsTime(time) { | |||
|     return dayjs(parseInt(time)); | ||||
|   } | ||||
|   if (time.length === 10) { | ||||
|     // 'unixtime'
 | ||||
|     // 'unixTime'
 | ||||
|     return dayjs.unix(parseInt(time)); | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 owen
						owen