mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 12:18:43 +08:00 
			
		
		
		
	营销:适配商城装修组件【弹窗广告】
This commit is contained in:
		
							
								
								
									
										26
									
								
								src/components/DiyEditor/components/mobile/Popover/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/components/DiyEditor/components/mobile/Popover/config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
import { DiyComponent } from '@/components/DiyEditor/util'
 | 
			
		||||
 | 
			
		||||
/** 弹窗广告属性 */
 | 
			
		||||
export interface PopoverProperty {
 | 
			
		||||
  list: PopoverItemProperty[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PopoverItemProperty {
 | 
			
		||||
  // 图片地址
 | 
			
		||||
  imgUrl: string
 | 
			
		||||
  // 跳转连接
 | 
			
		||||
  url: string
 | 
			
		||||
  // 显示类型:仅显示一次、每次启动都会显示
 | 
			
		||||
  showType: 'once' | 'always'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 定义组件
 | 
			
		||||
export const component = {
 | 
			
		||||
  id: 'Popover',
 | 
			
		||||
  name: '弹窗广告',
 | 
			
		||||
  icon: 'carbon:popup',
 | 
			
		||||
  position: 'fixed',
 | 
			
		||||
  property: {
 | 
			
		||||
    list: [{ showType: 'once' }]
 | 
			
		||||
  }
 | 
			
		||||
} as DiyComponent<PopoverProperty>
 | 
			
		||||
							
								
								
									
										38
									
								
								src/components/DiyEditor/components/mobile/Popover/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/components/DiyEditor/components/mobile/Popover/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div
 | 
			
		||||
    v-for="(item, index) in property.list"
 | 
			
		||||
    :key="index"
 | 
			
		||||
    class="absolute bottom-50% right-50% h-454px w-292px border-1px border-gray border-rounded-4px border-solid bg-white p-1px"
 | 
			
		||||
    :style="{
 | 
			
		||||
      zIndex: 100 + index + (activeIndex === index ? 100 : 0),
 | 
			
		||||
      marginRight: `${-146 - index * 20}px`,
 | 
			
		||||
      marginBottom: `${-227 - index * 20}px`
 | 
			
		||||
    }"
 | 
			
		||||
    @click="handleActive(index)"
 | 
			
		||||
  >
 | 
			
		||||
    <el-image :src="item.imgUrl" fit="contain" class="h-full w-full">
 | 
			
		||||
      <template #error>
 | 
			
		||||
        <div class="h-full w-full flex items-center justify-center">
 | 
			
		||||
          <Icon icon="ep:picture" />
 | 
			
		||||
        </div>
 | 
			
		||||
      </template>
 | 
			
		||||
    </el-image>
 | 
			
		||||
    <div class="absolute right-1 top-1 text-12px">{{ index + 1 }}</div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { PopoverProperty } from './config'
 | 
			
		||||
 | 
			
		||||
/** 弹窗广告 */
 | 
			
		||||
defineOptions({ name: 'Popover' })
 | 
			
		||||
// 定义属性
 | 
			
		||||
defineProps<{ property: PopoverProperty }>()
 | 
			
		||||
 | 
			
		||||
// 处理选中
 | 
			
		||||
const activeIndex = ref(0)
 | 
			
		||||
const handleActive = (index: number) => {
 | 
			
		||||
  activeIndex.value = index
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <el-form label-width="80px" :model="formData">
 | 
			
		||||
    <Draggable v-model="formData.list" :empty-item="{ showType: 'once' }">
 | 
			
		||||
      <template #default="{ element, index }">
 | 
			
		||||
        <el-form-item label="图片" :prop="`list[${index}].imgUrl`">
 | 
			
		||||
          <UploadImg v-model="element.imgUrl" height="56px" width="56px" />
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="跳转链接" :prop="`list[${index}].url`">
 | 
			
		||||
          <AppLinkInput v-model="element.url" />
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="显示次数" :prop="`list[${index}].showType`">
 | 
			
		||||
          <el-radio-group v-model="element.showType">
 | 
			
		||||
            <el-tooltip content="只显示一次,下次打开时不显示" placement="bottom">
 | 
			
		||||
              <el-radio label="once">一次</el-radio>
 | 
			
		||||
            </el-tooltip>
 | 
			
		||||
            <el-tooltip content="每次打开时都会显示" placement="bottom">
 | 
			
		||||
              <el-radio label="always">不限</el-radio>
 | 
			
		||||
            </el-tooltip>
 | 
			
		||||
          </el-radio-group>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
      </template>
 | 
			
		||||
    </Draggable>
 | 
			
		||||
  </el-form>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { PopoverProperty } from './config'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
 | 
			
		||||
// 弹窗广告属性面板
 | 
			
		||||
defineOptions({ name: 'PopoverProperty' })
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{ modelValue: PopoverProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
@@ -47,6 +47,18 @@
 | 
			
		||||
            class="cursor-pointer!"
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- 绝对定位的组件:例如 弹窗、浮动按钮等 -->
 | 
			
		||||
        <div
 | 
			
		||||
          v-for="(component, index) in pageComponents"
 | 
			
		||||
          :key="index"
 | 
			
		||||
          @click="handleComponentSelected(component, index)"
 | 
			
		||||
        >
 | 
			
		||||
          <component
 | 
			
		||||
            v-if="component.position === 'fixed' && selectedComponent?.uid === component.uid"
 | 
			
		||||
            :is="component.id"
 | 
			
		||||
            :property="component.property"
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- 手机页面编辑区域 -->
 | 
			
		||||
        <el-scrollbar
 | 
			
		||||
          height="100%"
 | 
			
		||||
@@ -70,6 +82,7 @@
 | 
			
		||||
          >
 | 
			
		||||
            <template #item="{ element, index }">
 | 
			
		||||
              <ComponentContainer
 | 
			
		||||
                v-if="!element.position || element.position === 'center'"
 | 
			
		||||
                :component="element"
 | 
			
		||||
                :active="selectedComponentIndex === index"
 | 
			
		||||
                :can-move-up="index > 0"
 | 
			
		||||
@@ -91,6 +104,33 @@
 | 
			
		||||
            @click="handleTabBarSelected"
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- 固定布局的组件 操作按钮区 -->
 | 
			
		||||
        <div class="fixed-component-action-group">
 | 
			
		||||
          <el-tag
 | 
			
		||||
            v-if="showPageConfig"
 | 
			
		||||
            size="large"
 | 
			
		||||
            :effect="selectedComponent?.uid === pageConfigComponent.uid ? 'dark' : 'plain'"
 | 
			
		||||
            :type="selectedComponent?.uid === pageConfigComponent.uid ? '' : 'info'"
 | 
			
		||||
            @click="handleComponentSelected(pageConfigComponent)"
 | 
			
		||||
          >
 | 
			
		||||
            <Icon :icon="pageConfigComponent.icon" :size="12" />
 | 
			
		||||
            <span>{{ pageConfigComponent.name }}</span>
 | 
			
		||||
          </el-tag>
 | 
			
		||||
          <template v-for="(component, index) in pageComponents" :key="index">
 | 
			
		||||
            <el-tag
 | 
			
		||||
              v-if="component.position === 'fixed'"
 | 
			
		||||
              size="large"
 | 
			
		||||
              closable
 | 
			
		||||
              :effect="selectedComponent?.uid === component.uid ? 'dark' : 'plain'"
 | 
			
		||||
              :type="selectedComponent?.uid === component.uid ? '' : 'info'"
 | 
			
		||||
              @click="handleComponentSelected(component)"
 | 
			
		||||
              @close="handleDeleteComponent(index)"
 | 
			
		||||
            >
 | 
			
		||||
              <Icon :icon="component.icon" :size="12" />
 | 
			
		||||
              <span>{{ component.name }}</span>
 | 
			
		||||
            </el-tag>
 | 
			
		||||
          </template>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <!-- 右侧属性面板 -->
 | 
			
		||||
      <el-aside class="editor-right" width="350px" v-if="selectedComponent?.property">
 | 
			
		||||
@@ -485,6 +525,31 @@ $toolbar-height: 42px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /* 固定布局的组件 操作按钮区 */
 | 
			
		||||
      .fixed-component-action-group {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        top: 0;
 | 
			
		||||
        right: 16px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        gap: 8px;
 | 
			
		||||
 | 
			
		||||
        :deep(.el-tag) {
 | 
			
		||||
          box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
          border: none;
 | 
			
		||||
          .el-tag__content {
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            justify-content: flex-start;
 | 
			
		||||
 | 
			
		||||
            .el-icon {
 | 
			
		||||
              margin-right: 4px;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,15 @@ export interface DiyComponent<T> {
 | 
			
		||||
  name: string
 | 
			
		||||
  // 组件图标
 | 
			
		||||
  icon: string
 | 
			
		||||
  /*
 | 
			
		||||
   组件位置:
 | 
			
		||||
   top: 固定于手机顶部,例如 顶部的导航栏
 | 
			
		||||
   bottom: 固定于手机底部,例如 底部的菜单导航栏
 | 
			
		||||
   center: 位于手机中心,每个组件占一行,顺序向下排列
 | 
			
		||||
   空:同center
 | 
			
		||||
   fixed: 由组件自己决定位置,如弹窗位于手机中心、浮动按钮一般位于手机右下角
 | 
			
		||||
  */
 | 
			
		||||
  position: 'top' | 'bottom' | 'center' | '' | 'fixed'
 | 
			
		||||
  // 组件属性
 | 
			
		||||
  property: T
 | 
			
		||||
}
 | 
			
		||||
@@ -102,7 +111,7 @@ export const PAGE_LIBS = [
 | 
			
		||||
  {
 | 
			
		||||
    name: '基础组件',
 | 
			
		||||
    extended: true,
 | 
			
		||||
    components: ['SearchBar', 'NoticeBar', 'MenuSwiper', 'MenuGrid', 'MenuList']
 | 
			
		||||
    components: ['SearchBar', 'NoticeBar', 'MenuSwiper', 'MenuGrid', 'MenuList', 'Popover']
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '图文组件',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user