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/ProductCard/index.vue | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 170 insertions(+), 0 deletions(-)
diff --git a/src/components/DiyEditor/components/mobile/ProductCard/index.vue b/src/components/DiyEditor/components/mobile/ProductCard/index.vue
new file mode 100644
index 0000000..93f6e07
--- /dev/null
+++ b/src/components/DiyEditor/components/mobile/ProductCard/index.vue
@@ -0,0 +1,170 @@
+<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 && property.badge.imgUrl"
+ 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 as any) }}
+ </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 { ProductCardProperty } from './config'
+import * as ProductSpuApi from '@/api/mall/product/spu'
+import { fenToYuan } from '../../../../../utils'
+
+/** 鍟嗗搧鍗$墖 */
+defineOptions({ name: 'ProductCard' })
+// 瀹氫箟灞炴��
+const props = defineProps<{ property: ProductCardProperty }>()
+// 鍟嗗搧鍒楄〃
+const spuList = ref<ProductSpuApi.Spu[]>([])
+watch(
+ () => props.property.spuIds,
+ async () => {
+ spuList.value = await ProductSpuApi.getSpuDetailList(props.property.spuIds)
+ },
+ {
+ 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