mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 20:28:45 +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!"
 | 
					            class="cursor-pointer!"
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </div>
 | 
					        </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
 | 
					        <el-scrollbar
 | 
				
			||||||
          height="100%"
 | 
					          height="100%"
 | 
				
			||||||
@@ -70,6 +82,7 @@
 | 
				
			|||||||
          >
 | 
					          >
 | 
				
			||||||
            <template #item="{ element, index }">
 | 
					            <template #item="{ element, index }">
 | 
				
			||||||
              <ComponentContainer
 | 
					              <ComponentContainer
 | 
				
			||||||
 | 
					                v-if="!element.position || element.position === 'center'"
 | 
				
			||||||
                :component="element"
 | 
					                :component="element"
 | 
				
			||||||
                :active="selectedComponentIndex === index"
 | 
					                :active="selectedComponentIndex === index"
 | 
				
			||||||
                :can-move-up="index > 0"
 | 
					                :can-move-up="index > 0"
 | 
				
			||||||
@@ -91,6 +104,33 @@
 | 
				
			|||||||
            @click="handleTabBarSelected"
 | 
					            @click="handleTabBarSelected"
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </div>
 | 
					        </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>
 | 
					      </div>
 | 
				
			||||||
      <!-- 右侧属性面板 -->
 | 
					      <!-- 右侧属性面板 -->
 | 
				
			||||||
      <el-aside class="editor-right" width="350px" v-if="selectedComponent?.property">
 | 
					      <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
 | 
					  name: string
 | 
				
			||||||
  // 组件图标
 | 
					  // 组件图标
 | 
				
			||||||
  icon: string
 | 
					  icon: string
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   组件位置:
 | 
				
			||||||
 | 
					   top: 固定于手机顶部,例如 顶部的导航栏
 | 
				
			||||||
 | 
					   bottom: 固定于手机底部,例如 底部的菜单导航栏
 | 
				
			||||||
 | 
					   center: 位于手机中心,每个组件占一行,顺序向下排列
 | 
				
			||||||
 | 
					   空:同center
 | 
				
			||||||
 | 
					   fixed: 由组件自己决定位置,如弹窗位于手机中心、浮动按钮一般位于手机右下角
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  position: 'top' | 'bottom' | 'center' | '' | 'fixed'
 | 
				
			||||||
  // 组件属性
 | 
					  // 组件属性
 | 
				
			||||||
  property: T
 | 
					  property: T
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -102,7 +111,7 @@ export const PAGE_LIBS = [
 | 
				
			|||||||
  {
 | 
					  {
 | 
				
			||||||
    name: '基础组件',
 | 
					    name: '基础组件',
 | 
				
			||||||
    extended: true,
 | 
					    extended: true,
 | 
				
			||||||
    components: ['SearchBar', 'NoticeBar', 'MenuSwiper', 'MenuGrid', 'MenuList']
 | 
					    components: ['SearchBar', 'NoticeBar', 'MenuSwiper', 'MenuGrid', 'MenuList', 'Popover']
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    name: '图文组件',
 | 
					    name: '图文组件',
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user