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