From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 201 insertions(+), 0 deletions(-)
diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue b/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue
new file mode 100644
index 0000000..3d34a3d
--- /dev/null
+++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue
@@ -0,0 +1,201 @@
+<template>
+ <div :class="`box-content min-h-30px w-full flex flex-row flex-wrap`" ref="containerRef">
+ <div
+ class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
+ :style="{
+ ...calculateSpace(index),
+ ...calculateWidth(),
+ borderTopLeftRadius: `${property.borderRadiusTop}px`,
+ borderTopRightRadius: `${property.borderRadiusTop}px`,
+ borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
+ borderBottomRightRadius: `${property.borderRadiusBottom}px`
+ }"
+ v-for="(spu, index) in spuList"
+ :key="index"
+ >
+ <!-- 瑙掓爣 -->
+ <div v-if="property.badge.show" class="absolute left-0 top-0 z-1 items-center justify-center">
+ <el-image fit="cover" :src="property.badge.imgUrl" class="h-26px w-38px" />
+ </div>
+ <!-- 鍟嗗搧灏侀潰鍥� -->
+ <div
+ :class="[
+ 'h-140px',
+ {
+ 'w-full': property.layoutType !== 'oneColSmallImg',
+ 'w-140px': property.layoutType === 'oneColSmallImg'
+ }
+ ]"
+ >
+ <el-image fit="cover" class="h-full w-full" :src="spu.picUrl" />
+ </div>
+ <div
+ :class="[
+ ' flex flex-col gap-8px p-8px box-border',
+ {
+ 'w-full': property.layoutType !== 'oneColSmallImg',
+ 'w-[calc(100%-140px-16px)]': property.layoutType === 'oneColSmallImg'
+ }
+ ]"
+ >
+ <!-- 鍟嗗搧鍚嶇О -->
+ <div
+ v-if="property.fields.name.show"
+ :class="[
+ 'text-14px ',
+ {
+ truncate: property.layoutType !== 'oneColSmallImg',
+ 'overflow-ellipsis line-clamp-2': property.layoutType === 'oneColSmallImg'
+ }
+ ]"
+ :style="{ color: property.fields.name.color }"
+ >
+ {{ spu.name }}
+ </div>
+ <!-- 鍟嗗搧绠�浠� -->
+ <div
+ v-if="property.fields.introduction.show"
+ class="truncate text-12px"
+ :style="{ color: property.fields.introduction.color }"
+ >
+ {{ spu.introduction }}
+ </div>
+ <div>
+ <!-- 浠锋牸 -->
+ <span
+ v-if="property.fields.price.show"
+ class="text-16px"
+ :style="{ color: property.fields.price.color }"
+ >
+ 锟{ fenToYuan(spu.price || Infinity) }}
+ </span>
+ <!-- 甯傚満浠� -->
+ <span
+ v-if="property.fields.marketPrice.show && spu.marketPrice"
+ class="ml-4px text-10px line-through"
+ :style="{ color: property.fields.marketPrice.color }"
+ >锟{ fenToYuan(spu.marketPrice) }}</span
+ >
+ </div>
+ <div class="text-12px">
+ <!-- 閿�閲� -->
+ <span
+ v-if="property.fields.salesCount.show"
+ :style="{ color: property.fields.salesCount.color }"
+ >
+ 宸插敭{{ (spu.salesCount || 0) + (spu.virtualSalesCount || 0) }}浠�
+ </span>
+ <!-- 搴撳瓨 -->
+ <span v-if="property.fields.stock.show" :style="{ color: property.fields.stock.color }">
+ 搴撳瓨{{ spu.stock || 0 }}
+ </span>
+ </div>
+ </div>
+ <!-- 璐拱鎸夐挳 -->
+ <div class="absolute bottom-8px right-8px">
+ <!-- 鏂囧瓧鎸夐挳 -->
+ <span
+ v-if="property.btnBuy.type === 'text'"
+ class="rounded-full p-x-12px p-y-4px text-12px text-white"
+ :style="{
+ background: `linear-gradient(to right, ${property.btnBuy.bgBeginColor}, ${property.btnBuy.bgEndColor}`
+ }"
+ >
+ {{ property.btnBuy.text }}
+ </span>
+ <!-- 鍥剧墖鎸夐挳 -->
+ <el-image
+ v-else
+ class="h-28px w-28px rounded-full"
+ fit="cover"
+ :src="property.btnBuy.imgUrl"
+ />
+ </div>
+ </div>
+ </div>
+</template>
+<script setup lang="ts">
+import { PromotionSeckillProperty } from './config'
+import * as ProductSpuApi from '@/api/mall/product/spu'
+import * as SeckillActivityApi from '@/api/mall/promotion/seckill/seckillActivity'
+import { fenToYuan } from '@/utils'
+
+/** 绉掓潃鍗$墖 */
+defineOptions({ name: 'PromotionSeckill' })
+// 瀹氫箟灞炴��
+const props = defineProps<{ property: PromotionSeckillProperty }>()
+// 鍟嗗搧鍒楄〃
+const spuList = ref<ProductSpuApi.Spu[]>([])
+const spuIdList = ref<number[]>([])
+const seckillActivityList = ref<SeckillActivityApi.SeckillActivityVO[]>([])
+
+watch(
+ () => props.property.activityIds,
+ async () => {
+ try {
+ // 鏂版坊鍔犵殑绉掓潃缁勪欢锛屾槸娌℃湁娲诲姩ID鐨�
+ const activityIds = props.property.activityIds
+ // 妫�鏌ユ椿鍔↖D鐨勬湁鏁堟��
+ if (Array.isArray(activityIds) && activityIds.length > 0) {
+ // 鑾峰彇绉掓潃娲诲姩璇︽儏鍒楄〃
+ seckillActivityList.value =
+ await SeckillActivityApi.getSeckillActivityListByIds(activityIds)
+
+ // 鑾峰彇绉掓潃娲诲姩鐨� SPU 璇︽儏鍒楄〃
+ spuList.value = []
+ spuIdList.value = seckillActivityList.value
+ .map((activity) => activity.spuId)
+ .filter((spuId): spuId is number => typeof spuId === 'number')
+ if (spuIdList.value.length > 0) {
+ spuList.value = await ProductSpuApi.getSpuDetailList(spuIdList.value)
+ }
+
+ // 鏇存柊 SPU 鐨勬渶浣庝环鏍�
+ seckillActivityList.value.forEach((activity) => {
+ // 鍖归厤spuId
+ const spu = spuList.value.find((spu) => spu.id === activity.spuId)
+ if (spu) {
+ // 璧嬪�兼椿鍔ㄤ环鏍硷紝鍝釜鏈�渚垮疁灏辫祴鍊煎摢涓�
+ spu.price = Math.min(activity.seckillPrice || Infinity, spu.price || Infinity)
+ }
+ })
+ }
+ } catch (error) {
+ console.error('鑾峰彇绉掓潃娲诲姩缁嗚妭鎴� SPU 缁嗚妭鏃跺嚭閿�:', error)
+ }
+ },
+ {
+ immediate: true,
+ deep: true
+ }
+)
+
+/**
+ * 璁$畻鍟嗗搧鐨勯棿璺�
+ * @param index 鍟嗗搧绱㈠紩
+ */
+const calculateSpace = (index: number) => {
+ // 鍟嗗搧鐨勫垪鏁�
+ const columns = props.property.layoutType === 'twoCol' ? 2 : 1
+ // 绗竴鍒楁病鏈夊乏杈硅窛
+ const marginLeft = index % columns === 0 ? '0' : props.property.space + 'px'
+ // 绗竴琛屾病鏈変笂杈硅窛
+ const marginTop = index < columns ? '0' : props.property.space + 'px'
+
+ return { marginLeft, marginTop }
+}
+
+// 瀹瑰櫒
+const containerRef = ref()
+// 璁$畻鍟嗗搧鐨勫搴�
+const calculateWidth = () => {
+ let width = '100%'
+ // 鍙屽垪鏃舵瘡鍒楃殑瀹藉害涓猴細锛堟�诲搴� - 闂磋窛锛�/ 2
+ if (props.property.layoutType === 'twoCol') {
+ width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`
+ }
+ return { width }
+}
+</script>
+
+<style scoped lang="scss"></style>
--
Gitblit v1.8.0