From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mall/promotion/combination/components/CombinationShowcase.vue |  158 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 158 insertions(+), 0 deletions(-)

diff --git a/src/views/mall/promotion/combination/components/CombinationShowcase.vue b/src/views/mall/promotion/combination/components/CombinationShowcase.vue
new file mode 100644
index 0000000..ba88434
--- /dev/null
+++ b/src/views/mall/promotion/combination/components/CombinationShowcase.vue
@@ -0,0 +1,158 @@
+<template>
+  <div class="flex flex-wrap items-center gap-8px">
+    <div
+      v-for="(combinationActivity, index) in Activitys"
+      :key="combinationActivity.id"
+      class="select-box spu-pic"
+    >
+      <el-tooltip :content="combinationActivity.name">
+        <div class="relative h-full w-full">
+          <el-image :src="combinationActivity.picUrl" class="h-full w-full" />
+          <Icon
+            v-show="!disabled"
+            class="del-icon"
+            icon="ep:circle-close-filled"
+            @click="handleRemoveActivity(index)"
+          />
+        </div>
+      </el-tooltip>
+    </div>
+    <el-tooltip content="閫夋嫨娲诲姩" v-if="canAdd">
+      <div class="select-box" @click="openCombinationActivityTableSelect">
+        <Icon icon="ep:plus" />
+      </div>
+    </el-tooltip>
+  </div>
+  <!-- 鎷煎洟娲诲姩閫夋嫨瀵硅瘽妗嗭紙琛ㄦ牸褰㈠紡锛� -->
+  <CombinationTableSelect
+    ref="combinationActivityTableSelectRef"
+    :multiple="limit != 1"
+    @change="handleActivitySelected"
+  />
+</template>
+<script lang="ts" setup>
+import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationActivity'
+import { propTypes } from '@/utils/propTypes'
+import { oneOfType } from 'vue-types'
+import { isArray } from '@/utils/is'
+import CombinationTableSelect from '@/views/mall/promotion/combination/components/CombinationTableSelect.vue'
+
+// 娲诲姩姗辩獥锛屼竴鑸敤浜庤淇椂浣跨敤
+// 鎻愪緵鍔熻兘锛氬睍绀烘椿鍔ㄥ垪琛ㄣ�佹坊鍔犳椿鍔ㄣ�佸垹闄ゆ椿鍔�
+defineOptions({ name: 'CombinationShowcase' })
+
+const props = defineProps({
+  modelValue: oneOfType<number | Array<number>>([Number, Array]).isRequired,
+  // 闄愬埗鏁伴噺锛氶粯璁や笉闄愬埗
+  limit: propTypes.number.def(Number.MAX_VALUE),
+  disabled: propTypes.bool.def(false)
+})
+
+// 璁$畻鏄惁鍙互娣诲姞
+const canAdd = computed(() => {
+  // 鎯呭喌涓�锛氱鐢ㄦ椂涓嶅彲浠ユ坊鍔�
+  if (props.disabled) return false
+  // 鎯呭喌浜岋細鏈寚瀹氶檺鍒舵暟閲忔椂锛屽彲浠ユ坊鍔�
+  if (!props.limit) return true
+  // 鎯呭喌涓夛細妫�鏌ュ凡娣诲姞鏁伴噺鏄惁灏忎簬闄愬埗鏁伴噺
+  return Activitys.value.length < props.limit
+})
+
+// 鎷煎洟娲诲姩鍒楄〃
+const Activitys = ref<CombinationActivityApi.CombinationActivityVO[]>([])
+
+watch(
+  () => props.modelValue,
+  async () => {
+    const ids = isArray(props.modelValue)
+      ? // 鎯呭喌涓�锛氬閫�
+        props.modelValue
+      : // 鎯呭喌浜岋細鍗曢��
+        props.modelValue
+        ? [props.modelValue]
+        : []
+    // 涓嶉渶瑕佽繑鏄�
+    if (ids.length === 0) {
+      Activitys.value = []
+      return
+    }
+    // 鍙湁娲诲姩鍙戠敓鍙樺寲涔嬪悗锛屾墠浼氭煡璇㈡椿鍔�
+    if (
+      Activitys.value.length === 0 ||
+      Activitys.value.some((combinationActivity) => !ids.includes(combinationActivity.id!))
+    ) {
+      Activitys.value = await CombinationActivityApi.getCombinationActivityListByIds(ids)
+    }
+  },
+  { immediate: true }
+)
+
+/** 娲诲姩琛ㄦ牸閫夋嫨瀵硅瘽妗� */
+const combinationActivityTableSelectRef = ref()
+// 鎵撳紑瀵硅瘽妗�
+const openCombinationActivityTableSelect = () => {
+  combinationActivityTableSelectRef.value.open(Activitys.value)
+}
+
+/**
+ * 閫夋嫨娲诲姩鍚庤Е鍙�
+ * @param activityVOs 閫変腑鐨勬椿鍔ㄥ垪琛�
+ */
+const handleActivitySelected = (
+  activityVOs:
+    | CombinationActivityApi.CombinationActivityVO
+    | CombinationActivityApi.CombinationActivityVO[]
+) => {
+  Activitys.value = isArray(activityVOs) ? activityVOs : [activityVOs]
+  emitActivityChange()
+}
+
+/**
+ * 鍒犻櫎娲诲姩
+ * @param index 娲诲姩绱㈠紩
+ */
+const handleRemoveActivity = (index: number) => {
+  Activitys.value.splice(index, 1)
+  emitActivityChange()
+}
+const emit = defineEmits(['update:modelValue', 'change'])
+const emitActivityChange = () => {
+  if (props.limit === 1) {
+    const combinationActivity = Activitys.value.length > 0 ? Activitys.value[0] : null
+    emit('update:modelValue', combinationActivity?.id || 0)
+    emit('change', combinationActivity)
+  } else {
+    emit(
+      'update:modelValue',
+      Activitys.value.map((combinationActivity) => combinationActivity.id)
+    )
+    emit('change', Activitys.value)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.select-box {
+  display: flex;
+  width: 60px;
+  height: 60px;
+  border: 1px dashed var(--el-border-color-darker);
+  border-radius: 8px;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+
+.spu-pic {
+  position: relative;
+}
+
+.del-icon {
+  position: absolute;
+  top: -10px;
+  right: -10px;
+  z-index: 1;
+  width: 20px !important;
+  height: 20px !important;
+}
+</style>

--
Gitblit v1.8.0