feat(pc-decorate): 优化PC楼层装修组件自适应高度、支持可视化热区图绘制及编辑器交互修复

- fix(editor): 修复点击返回页面列表 autoSaveTimer is not defined 运行时错误,优化回退逻辑
- feat(hotzone): PC 端热区图接入可视化组件,支持拖拽画框、拉伸缩放与百分比自适应
- fix(floor-height): 商品宫格、宫格楼层、横幅楼层、商品条等默认行高改为自适应撑开,防止商品溢出截断
- fix(video): 修正视频组件默认行高与播放器高度对齐为 450px,避免底部遮挡
- fix(freelayout): 统一自由排版默认高度与后台画布高度为 450px,消除底部空白
- feat(adaptive): 频道宫格、品牌墙、优惠券等集合类组件支持动态行高与 autoCompTypes 弹性包裹
- refactor(preset): 优化双端 double11Preset 预设模板,清理遗留固定行高
This commit is contained in:
pikachu1995@126.com
2026-10-30 09:27:21 +08:00
parent ccf243f31a
commit ce11f50942
10 changed files with 210 additions and 71 deletions

View File

@@ -12,7 +12,7 @@
class="component-cell" class="component-cell"
:style="getComponentCellStyle(comp.componentStyle, row.rowStyle, row.components ? row.components.length : 1)" :style="getComponentCellStyle(comp.componentStyle, row.rowStyle, row.components ? row.components.length : 1, comp.type)"
> >
@@ -69,6 +69,10 @@ const props = defineProps({
const hasAutoComp = computed(() => {
return Array.isArray(props.row.components) && props.row.components.some(c => ['goodsGrid', 'gridFloor', 'bannerFloor', 'goodsBar', 'channelFloor', 'goodsList', 'recommendFeed', 'articleContent', 'brandWall', 'channelGrid', 'couponList'].includes(c?.type));
});
const rowWrapperStyle = computed(() => { const rowWrapperStyle = computed(() => {
const s = props.row.rowStyle || {}; const s = props.row.rowStyle || {};
const style = {}; const style = {};
@@ -96,8 +100,12 @@ const rowWrapperStyle = computed(() => {
const h = String(s.height).trim(); const h = String(s.height).trim();
if (h && Number(h) > 0) { if (h && Number(h) > 0) {
const hVal = /^\d+$/.test(h) ? `${h}px` : h; const hVal = /^\d+$/.test(h) ? `${h}px` : h;
style.height = hVal; if (hasAutoComp.value) {
style.minHeight = hVal; style.minHeight = hVal;
} else {
style.height = hVal;
style.minHeight = hVal;
}
} }
} }
@@ -164,8 +172,12 @@ const rowInnerFlexStyle = computed(() => {
const h = String(s.height).trim(); const h = String(s.height).trim();
if (h && Number(h) > 0) { if (h && Number(h) > 0) {
const hVal = /^\d+$/.test(h) ? `${h}px` : h; const hVal = /^\d+$/.test(h) ? `${h}px` : h;
styleObj.height = hVal; if (hasAutoComp.value) {
styleObj.minHeight = hVal; styleObj.minHeight = hVal;
} else {
styleObj.height = hVal;
styleObj.minHeight = hVal;
}
} }
} }
@@ -175,7 +187,8 @@ const rowInnerFlexStyle = computed(() => {
function getComponentCellStyle(style, rowStyle = {}, totalComps = 1) { function getComponentCellStyle(style, rowStyle = {}, totalComps = 1, compType = '') {
const isAutoHeightComp = compType && ['goodsGrid', 'gridFloor', 'bannerFloor', 'goodsBar', 'channelFloor', 'goodsList', 'recommendFeed', 'articleContent', 'brandWall', 'channelGrid', 'couponList'].includes(compType);
if (!style) return { flex: '1 1 0%' }; if (!style) return { flex: '1 1 0%' };
@@ -185,8 +198,12 @@ function getComponentCellStyle(style, rowStyle = {}, totalComps = 1) {
const rh = String(rowStyle.height).trim(); const rh = String(rowStyle.height).trim();
if (rh && Number(rh) > 0) { if (rh && Number(rh) > 0) {
const rhVal = /^\d+$/.test(rh) ? `${rh}px` : rh; const rhVal = /^\d+$/.test(rh) ? `${rh}px` : rh;
s.height = rhVal; if (isAutoHeightComp) {
s.minHeight = rhVal; s.minHeight = rhVal;
} else {
s.height = rhVal;
s.minHeight = rhVal;
}
} }
} }
const gap = Number(rowStyle?.gap) || 0; const gap = Number(rowStyle?.gap) || 0;

View File

@@ -7,10 +7,10 @@
:key="idx" :key="idx"
class="zone-link" class="zone-link"
:style="{ :style="{
top: `${zone.top || 0}%`, top: `${zone.top !== undefined ? zone.top : ((zone.topPer || 0) * 100)}%`,
left: `${zone.left || 0}%`, left: `${zone.left !== undefined ? zone.left : ((zone.leftPer || 0) * 100)}%`,
width: `${zone.width || 10}%`, width: `${zone.width !== undefined ? zone.width : ((zone.widthPer || 0.1) * 100)}%`,
height: `${zone.height || 10}%` height: `${zone.height !== undefined ? zone.height : ((zone.heightPer || 0.1) * 100)}%`
}" }"
:title="zone.title" :title="zone.title"
@click="handleClickZone(zone)" @click="handleClickZone(zone)"
@@ -68,7 +68,7 @@ const customStyle = computed(() => {
}); });
function handleClickZone(zone) { function handleClickZone(zone) {
const url = zone?.url ? String(zone.url).trim() : ''; const url = (zone?.url || zone?.link) ? String(zone.url || zone.link).trim() : '';
if (!url) return; if (!url) return;
if (/^https?:\/\//i.test(url)) { if (/^https?:\/\//i.test(url)) {
window.open(url, '_blank'); window.open(url, '_blank');

View File

@@ -724,7 +724,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
0, 0,
0 0
], ],
"height": 180 "height": 220
}, },
"components": [ "components": [
{ {
@@ -901,6 +901,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
"backgroundColor": "transparent" "backgroundColor": "transparent"
}, },
"options": { "options": {
"height": 450,
"elements": [ "elements": [
{ {
"type": "badge", "type": "badge",
@@ -979,7 +980,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 560 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1061,7 +1062,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 560 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1140,7 +1141,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 620 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1249,7 +1250,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 420 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1404,7 +1405,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 360 "height": 450
}, },
"components": [ "components": [
{ {
@@ -1417,6 +1418,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
}, },
"options": { "options": {
"videoUrl": "https://vjs.zencdn.net/v/oceans.mp4", "videoUrl": "https://vjs.zencdn.net/v/oceans.mp4",
"height": 450,
"coverUrl": "https://lilishop-pc.oss-cn-beijing.aliyuncs.com/static/video/video_cover.png", "coverUrl": "https://lilishop-pc.oss-cn-beijing.aliyuncs.com/static/video/video_cover.png",
"url": "/goodsList?brand=1", "url": "/goodsList?brand=1",
"title": "双11全球狂欢发布盛典 · 年度旗舰好物真实开箱测评", "title": "双11全球狂欢发布盛典 · 年度旗舰好物真实开箱测评",
@@ -1481,7 +1483,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 220 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1656,7 +1658,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 980 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1810,7 +1812,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 1270 "height": ""
}, },
"components": [ "components": [
{ {

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="flag" v-model="flag"
width="800px" :width="width"
:close-on-click-modal="false" :close-on-click-modal="false"
title="绘制热区" title="绘制热区"
top="120px" top="120px"
@@ -26,6 +26,13 @@
import { ref } from "vue"; import { ref } from "vue";
import hotzone from "./components/Hotzone.vue"; import hotzone from "./components/Hotzone.vue";
const props = defineProps({
width: {
type: String,
default: "800px",
},
});
const emit = defineEmits(["changeZone", "closeFlag"]); const emit = defineEmits(["changeZone", "closeFlag"]);
const flag = ref(false); const flag = ref(false);

View File

@@ -29,6 +29,10 @@
<div class="hotzone-preview-box" v-if="options.imageUrl"> <div class="hotzone-preview-box" v-if="options.imageUrl">
<img :src="options.imageUrl" alt="hotzone" class="img-preview" /> <img :src="options.imageUrl" alt="hotzone" class="img-preview" />
<div class="preview-actions-bar"> <div class="preview-actions-bar">
<el-button size="small" type="primary" @click="handleOpenHotzone">
<el-icon class="mr-4"><Aim /></el-icon>
绘制热区
</el-button>
<el-button size="small" type="primary" plain @click="handleSelectImage"> <el-button size="small" type="primary" plain @click="handleSelectImage">
<el-icon class="mr-4"><Picture /></el-icon> <el-icon class="mr-4"><Picture /></el-icon>
更换底图 更换底图
@@ -46,6 +50,9 @@
<div class="section-title flex-between"> <div class="section-title flex-between">
<span>热区列表 ({{ options.zones?.length || 0 }})</span> <span>热区列表 ({{ options.zones?.length || 0 }})</span>
<div class="header-action-group"> <div class="header-action-group">
<el-button type="primary" plain size="small" @click="handleOpenHotzone">
<el-icon class="mr-4"><Aim /></el-icon> 绘制热区
</el-button>
<el-button link type="primary" size="small" @click="handleAddZone"> <el-button link type="primary" size="small" @click="handleAddZone">
<el-icon><Plus /></el-icon> 添加热区 <el-icon><Plus /></el-icon> 添加热区
</el-button> </el-button>
@@ -204,16 +211,25 @@
</div> </div>
<div class="empty-zones-box" v-else> <div class="empty-zones-box" v-else>
<span>暂无热区,请点击右上角“添加热区”</span> <span>暂无热区,可点击“绘制热区”在底图上拖拽画热区</span>
<div class="mt-8">
<el-button type="primary" size="small" @click="handleOpenHotzone">
<el-icon class="mr-4"><Aim /></el-icon> 立即绘制热区
</el-button>
</div>
</div> </div>
</div> </div>
<!-- 绘制热区弹窗(复用移动端热区绘制器) -->
<hotzone ref="hotzoneDialogRef" width="960px" @changeZone="handleChangeZone" />
</div> </div>
</template> </template>
<script setup> <script setup>
import { inject } from 'vue'; import { ref, inject } from 'vue';
import { Plus, Delete, Link, Picture, Close, Top, Bottom } from '@element-plus/icons-vue'; import { Plus, Delete, Link, Picture, Close, Top, Bottom, Aim } from '@element-plus/icons-vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox, ElMessage } from 'element-plus';
import hotzone from '@/components/hotzone';
const props = defineProps({ const props = defineProps({
component: { component: {
@@ -298,6 +314,68 @@ function handleAddZone() {
height: 35 height: 35
}); });
} }
const hotzoneDialogRef = ref(null);
// 绘制热区弹窗打开
function handleOpenHotzone() {
const imgUrl = props.options.imageUrl || '';
if (!imgUrl) {
ElMessage.warning('请先输入或选择热区底图');
return;
}
const zoneInfo = (props.options.zones || []).map((z, idx) => {
const leftPer = z.leftPer !== undefined ? z.leftPer : (Number(z.left) || 0) / 100;
const topPer = z.topPer !== undefined ? z.topPer : (Number(z.top) || 0) / 100;
const widthPer = z.widthPer !== undefined ? z.widthPer : (Number(z.width) || 20) / 100;
const heightPer = z.heightPer !== undefined ? z.heightPer : (Number(z.height) || 20) / 100;
const link = z.url || z.link || '';
return {
...z,
leftPer,
topPer,
widthPer,
heightPer,
link,
title: z.title || `热区 ${idx + 1}`,
type: z.type || 'other'
};
});
if (hotzoneDialogRef.value) {
hotzoneDialogRef.value.open({
img: imgUrl,
zoneInfo
});
}
}
// 热区绘制器变更回调
function handleChangeZone(zoneList) {
if (!Array.isArray(zoneList)) return;
props.options.zones = zoneList.map((z, idx) => {
const leftVal = z.leftPer !== undefined ? z.leftPer * 100 : (z.left !== undefined ? z.left : 0);
const topVal = z.topPer !== undefined ? z.topPer * 100 : (z.top !== undefined ? z.top : 0);
const widthVal = z.widthPer !== undefined ? z.widthPer * 100 : (z.width !== undefined ? z.width : 20);
const heightVal = z.heightPer !== undefined ? z.heightPer * 100 : (z.height !== undefined ? z.height : 20);
const linkVal = z.link || z.url || '';
const titleVal = z.title || `热区 ${idx + 1}`;
return {
...z,
title: titleVal,
url: linkVal,
link: linkVal,
left: Math.round(leftVal * 10) / 10,
top: Math.round(topVal * 10) / 10,
width: Math.round(widthVal * 10) / 10,
height: Math.round(heightVal * 10) / 10,
type: z.type || 'other'
};
});
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -299,7 +299,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'channelGrid', type: 'channelGrid',
defaultRowHeight: 120, defaultRowHeight: '',
name: '频道宫格', name: '频道宫格',
group: 'navigation', group: 'navigation',
icon: 'Grid', icon: 'Grid',
@@ -431,7 +431,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'brandWall', type: 'brandWall',
defaultRowHeight: 220, defaultRowHeight: '',
name: '品牌图', name: '品牌图',
group: 'media', group: 'media',
icon: 'Medal', icon: 'Medal',
@@ -513,7 +513,7 @@ export const COMPONENT_DEFINITIONS = [
defaultOptions: { defaultOptions: {
height: 320, height: 450,
elements: [] elements: []
@@ -532,7 +532,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'promoGroup', type: 'promoGroup',
defaultRowHeight: 180, defaultRowHeight: 220,
name: '活动卡组', name: '活动卡组',
@@ -567,13 +567,14 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'video', type: 'video',
defaultRowHeight: 360, defaultRowHeight: 450,
name: '视频', name: '视频',
group: 'media', group: 'media',
icon: 'VideoCamera', icon: 'VideoCamera',
description: '品牌宣传与商品视频播放', description: '品牌宣传与商品视频播放',
defaultOptions: { defaultOptions: {
videoUrl: '', videoUrl: '',
height: 450,
coverUrl: 'https://lilishop-pc.oss-cn-beijing.aliyuncs.com/static/video/video_cover.png', coverUrl: 'https://lilishop-pc.oss-cn-beijing.aliyuncs.com/static/video/video_cover.png',
url: '', url: '',
autoPlay: false, autoPlay: false,
@@ -597,7 +598,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'goodsList', type: 'goodsList',
defaultRowHeight: 980, defaultRowHeight: '',
name: '商品列表', name: '商品列表',
@@ -727,7 +728,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'gridFloor', type: 'gridFloor',
defaultRowHeight: 560, defaultRowHeight: '',
name: '宫格楼层', name: '宫格楼层',
@@ -843,7 +844,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'goodsGrid', type: 'goodsGrid',
defaultRowHeight: 420, defaultRowHeight: '',
name: '商品宫格', name: '商品宫格',
group: 'commerce', group: 'commerce',
icon: 'Menu', icon: 'Menu',
@@ -922,7 +923,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'bannerFloor', type: 'bannerFloor',
defaultRowHeight: 560, defaultRowHeight: '',
name: '横幅楼层', name: '横幅楼层',
@@ -964,7 +965,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'goodsBar', type: 'goodsBar',
defaultRowHeight: 280, defaultRowHeight: '',
name: '商品条', name: '商品条',
@@ -1001,7 +1002,7 @@ export const COMPONENT_DEFINITIONS = [
}, },
{type: 'channelFloor', {type: 'channelFloor',
defaultRowHeight: 620, defaultRowHeight: '',
name: '频道楼层', name: '频道楼层',
@@ -1045,7 +1046,7 @@ export const COMPONENT_DEFINITIONS = [
{ {
type: 'recommendFeed', type: 'recommendFeed',
defaultRowHeight: 1270, defaultRowHeight: '',
name: '推荐商品', name: '推荐商品',
@@ -1120,7 +1121,7 @@ export const COMPONENT_DEFINITIONS = [
}, },
{ {
type: 'couponList', type: 'couponList',
defaultRowHeight: 160, defaultRowHeight: '',
name: '优惠券', name: '优惠券',

View File

@@ -225,7 +225,7 @@
:class="{ 'is-row-selected': isCurrentRowSelected(row.id) }" :class="{ 'is-row-selected': isCurrentRowSelected(row.id) }"
:style="getRowWrapperStyle(row.rowStyle)" :style="getRowWrapperStyle(row.rowStyle, row.components)"
@click.stop="handleSelectRow(row, rIndex)" @click.stop="handleSelectRow(row, rIndex)"
@@ -289,14 +289,14 @@
group="pc-row-components" group="pc-row-components"
item-key="id" item-key="id"
class="row-components-flex" class="row-components-flex"
:style="getRowFlexStyle(row.rowStyle)" :style="getRowFlexStyle(row.rowStyle, row.components)"
@change="markDirty" @change="markDirty"
> >
<template #item="{ element: comp, index: cIndex }"> <template #item="{ element: comp, index: cIndex }">
<div <div
class="canvas-comp-wrap" class="canvas-comp-wrap"
:class="{ 'is-selected': selectedCompId === comp.id }" :class="{ 'is-selected': selectedCompId === comp.id }"
:style="getCompWrapperStyle(comp.componentStyle, row.rowStyle, row.components ? row.components.length : 1)" :style="getCompWrapperStyle(comp.componentStyle, row.rowStyle, row.components ? row.components.length : 1, comp.type)"
@click.stop="handleSelectComp(row, rIndex, comp)" @click.stop="handleSelectComp(row, rIndex, comp)"
> >
<!-- 选中的组件左上角名称标识徽标(万米魔方设计) --> <!-- 选中的组件左上角名称标识徽标(万米魔方设计) -->
@@ -800,11 +800,19 @@ function clearSelection() {
function normalizeRows(list) { function normalizeRows(list) {
if (!Array.isArray(list)) return []; if (!Array.isArray(list)) return [];
const autoCompTypes = ['goodsGrid', 'gridFloor', 'bannerFloor', 'goodsBar', 'channelFloor', 'goodsList', 'recommendFeed', 'articleContent', 'brandWall', 'channelGrid', 'couponList'];
const legacyHeights = [40, '40', 280, '280', 420, '420', 560, '560', 620, '620', 980, '980', 1270, '1270'];
const normalized = []; const normalized = [];
list.forEach(r => { list.forEach(r => {
if (!r) return; if (!r) return;
if (r.rowStyle && (r.rowStyle.height === 40 || r.rowStyle.height === "40")) { if (r.rowStyle) {
r.rowStyle.height = ""; if (r.rowStyle.height === 40 || r.rowStyle.height === "40") {
r.rowStyle.height = "";
}
const hasAutoComp = Array.isArray(r.components) && r.components.some(c => autoCompTypes.includes(c?.type));
if (hasAutoComp && legacyHeights.includes(r.rowStyle.height)) {
r.rowStyle.height = "";
}
} }
normalized.push(r); normalized.push(r);
}); });
@@ -1252,7 +1260,8 @@ function getCompIcon(type) {
// 计算行样式 // 计算行样式
function getRowWrapperStyle(style) { function getRowWrapperStyle(style, components = []) {
const hasAutoComp = Array.isArray(components) && components.some(c => ['goodsGrid', 'gridFloor', 'bannerFloor', 'goodsBar', 'channelFloor', 'goodsList', 'recommendFeed', 'articleContent', 'brandWall', 'channelGrid', 'couponList'].includes(c?.type));
if (!style) return { width: '100%' }; if (!style) return { width: '100%' };
const s = {}; const s = {};
@@ -1280,8 +1289,12 @@ function getRowWrapperStyle(style) {
const h = String(style.height).trim(); const h = String(style.height).trim();
if (h && Number(h) > 0) { if (h && Number(h) > 0) {
const hVal = /^\d+$/.test(h) ? `${h}px` : h; const hVal = /^\d+$/.test(h) ? `${h}px` : h;
s.height = hVal; if (hasAutoComp) {
s.minHeight = hVal; s.minHeight = hVal;
} else {
s.height = hVal;
s.minHeight = hVal;
}
} }
} }
@@ -1318,7 +1331,8 @@ function getRowWrapperStyle(style) {
return s; return s;
} }
function getRowFlexStyle(style) { function getRowFlexStyle(style, components = []) {
const hasAutoComp = Array.isArray(components) && components.some(c => ['goodsGrid', 'gridFloor', 'bannerFloor', 'goodsBar', 'channelFloor', 'goodsList', 'recommendFeed', 'articleContent', 'brandWall', 'channelGrid', 'couponList'].includes(c?.type));
if (!style) return { display: 'flex', flexDirection: 'row', flexWrap: 'nowrap', width: '100%', height: '100%' }; if (!style) return { display: 'flex', flexDirection: 'row', flexWrap: 'nowrap', width: '100%', height: '100%' };
const s = { const s = {
display: 'flex', display: 'flex',
@@ -1333,8 +1347,12 @@ function getRowFlexStyle(style) {
const h = String(style.height).trim(); const h = String(style.height).trim();
if (h && Number(h) > 0) { if (h && Number(h) > 0) {
const hVal = /^\d+$/.test(h) ? `${h}px` : h; const hVal = /^\d+$/.test(h) ? `${h}px` : h;
s.height = hVal; if (hasAutoComp) {
s.minHeight = hVal; s.minHeight = hVal;
} else {
s.height = hVal;
s.minHeight = hVal;
}
} }
} }
if (style.gap !== undefined && style.gap !== '') { if (style.gap !== undefined && style.gap !== '') {
@@ -1348,7 +1366,8 @@ function getRowFlexStyle(style) {
// 计算组件外层样式 // 计算组件外层样式
function getCompWrapperStyle(style, rowStyle = {}, totalComps = 1) { function getCompWrapperStyle(style, rowStyle = {}, totalComps = 1, compType = '') {
const isAutoHeightComp = compType && ['goodsGrid', 'gridFloor', 'bannerFloor', 'goodsBar', 'channelFloor', 'goodsList', 'recommendFeed', 'articleContent', 'brandWall', 'channelGrid', 'couponList'].includes(compType);
if (!style) return {}; if (!style) return {};
@@ -1358,8 +1377,12 @@ function getCompWrapperStyle(style, rowStyle = {}, totalComps = 1) {
const rh = String(rowStyle.height).trim(); const rh = String(rowStyle.height).trim();
if (rh && Number(rh) > 0) { if (rh && Number(rh) > 0) {
const rhVal = /^\d+$/.test(rh) ? `${rh}px` : rh; const rhVal = /^\d+$/.test(rh) ? `${rh}px` : rh;
s.height = rhVal; if (isAutoHeightComp) {
s.minHeight = rhVal; s.minHeight = rhVal;
} else {
s.height = rhVal;
s.minHeight = rhVal;
}
} }
} }
const gap = Number(rowStyle?.gap) || 0; const gap = Number(rowStyle?.gap) || 0;
@@ -1612,7 +1635,11 @@ function goBack() {
} else { } else {
router.push('/pcFloor'); if (window.history.state?.back) {
router.go(-1);
} else {
window.close();
}
} }
@@ -1643,6 +1670,8 @@ function goBack() {
} }
let autoSaveTimer = null;
onMounted(() => { onMounted(() => {
const id = route.query.id; const id = route.query.id;
@@ -1671,7 +1700,10 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
if (autoSaveTimer) clearInterval(autoSaveTimer); if (autoSaveTimer) {
clearInterval(autoSaveTimer);
autoSaveTimer = null;
}
}); });

View File

@@ -724,7 +724,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
0, 0,
0 0
], ],
"height": 180 "height": 220
}, },
"components": [ "components": [
{ {
@@ -901,6 +901,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
"backgroundColor": "transparent" "backgroundColor": "transparent"
}, },
"options": { "options": {
"height": 450,
"elements": [ "elements": [
{ {
"type": "badge", "type": "badge",
@@ -979,7 +980,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 560 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1061,7 +1062,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 560 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1140,7 +1141,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 620 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1249,7 +1250,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 420 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1404,7 +1405,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 360 "height": 450
}, },
"components": [ "components": [
{ {
@@ -1417,6 +1418,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
}, },
"options": { "options": {
"videoUrl": "https://vjs.zencdn.net/v/oceans.mp4", "videoUrl": "https://vjs.zencdn.net/v/oceans.mp4",
"height": 450,
"coverUrl": "https://lilishop-pc.oss-cn-beijing.aliyuncs.com/static/video/video_cover.png", "coverUrl": "https://lilishop-pc.oss-cn-beijing.aliyuncs.com/static/video/video_cover.png",
"url": "/goodsList?brand=1", "url": "/goodsList?brand=1",
"title": "双11全球狂欢发布盛典 · 年度旗舰好物真实开箱测评", "title": "双11全球狂欢发布盛典 · 年度旗舰好物真实开箱测评",
@@ -1481,7 +1483,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 220 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1656,7 +1658,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 980 "height": ""
}, },
"components": [ "components": [
{ {
@@ -1810,7 +1812,7 @@ export const DOUBLE11_PAGE_DOCUMENT = {
16 16
], ],
"borderRadius": "8px", "borderRadius": "8px",
"height": 1270 "height": ""
}, },
"components": [ "components": [
{ {

View File

@@ -23,7 +23,7 @@ const props = defineProps({
const customStyle = computed(() => { const customStyle = computed(() => {
const s = props.componentStyle || {}; const s = props.componentStyle || {};
return { return {
height: `${props.options?.height || 260}px`, height: `${props.options?.height || 450}px`,
backgroundColor: s.backgroundColor || '#f8fafc', backgroundColor: s.backgroundColor || '#f8fafc',
borderRadius: Array.isArray(s.radius) borderRadius: Array.isArray(s.radius)
? `${s.radius[0]}px ${s.radius[1]}px ${s.radius[2]}px ${s.radius[3]}px` ? `${s.radius[0]}px ${s.radius[1]}px ${s.radius[2]}px ${s.radius[3]}px`

View File

@@ -7,10 +7,10 @@
:key="idx" :key="idx"
class="zone-mask" class="zone-mask"
:style="{ :style="{
top: `${zone.top || 0}%`, top: `${zone.top !== undefined ? zone.top : ((zone.topPer || 0) * 100)}%`,
left: `${zone.left || 0}%`, left: `${zone.left !== undefined ? zone.left : ((zone.leftPer || 0) * 100)}%`,
width: `${zone.width || 10}%`, width: `${zone.width !== undefined ? zone.width : ((zone.widthPer || 0.1) * 100)}%`,
height: `${zone.height || 10}%` height: `${zone.height !== undefined ? zone.height : ((zone.heightPer || 0.1) * 100)}%`
}" }"
> >
<span class="zone-label">{{ zone.title || `热区 ${idx + 1}` }}</span> <span class="zone-label">{{ zone.title || `热区 ${idx + 1}` }}</span>