diff --git a/src/views/bigscreenDesigner/designer/index.vue b/src/views/bigscreenDesigner/designer/index.vue
index c00963b..43d12ef 100644
--- a/src/views/bigscreenDesigner/designer/index.vue
+++ b/src/views/bigscreenDesigner/designer/index.vue
@@ -27,7 +27,7 @@
v-for="(it, idx) in item.list"
:key="idx"
draggable="true"
- @dragstart="dragStart(it.code)"
+ @dragstart="dragStart(it.code, $event)"
@dragend="dragEnd()"
>
@@ -526,9 +526,14 @@ export default {
getPXUnderScale(px) {
return this.bigscreenScaleInWorkbench * px;
},
- dragStart(widgetCode) {
+ dragStart(widgetCode, evt) {
this.dragWidgetCode = widgetCode;
this.currentWidgetTotal = this.widgets.length; // 当前操作面板上有多少各组件
+ // 通过 dataTransfer 传递组件 code,便于 Tabs 等嵌套容器在 drop 时读取(不依赖父组件链)
+ if (evt && evt.dataTransfer) {
+ evt.dataTransfer.setData("application/x-widget-code", widgetCode);
+ evt.dataTransfer.effectAllowed = "copy";
+ }
},
dragEnd() {
/**
@@ -555,12 +560,48 @@ export default {
});
},
dragOver(evt) {
+ // 鼠标在 Tabs 标签内容区内时不处理,让 tab 内容区成为 drop 目标,避免工作台抢走
+ if (evt.target && evt.target.closest && (evt.target.closest(".tab-content") || evt.target.closest("[data-tab-content]"))) {
+ return;
+ }
evt.preventDefault();
evt.stopPropagation();
evt.dataTransfer.dropEffect = "copy";
},
// 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去
widgetOnDragged(evt) {
+ // 若落在 Tabs 标签内容区内,由 widgetTabs 自己处理,不在此处添加到主画布
+ if (evt.target && evt.target.closest && (evt.target.closest(".tab-content") || evt.target.closest("[data-tab-content]"))) {
+ return;
+ }
+ // 若落在 Tabs 组件的外层容器上(如 avue-draggable),委托给对应 Tabs 加入当前激活的 tab
+ const widgetsRef = this.$refs.widgets;
+ const widgetList = Array.isArray(widgetsRef) ? widgetsRef : (widgetsRef ? [widgetsRef] : []);
+ if (evt.target && widgetList.length) {
+ for (let i = 0; i < widgetList.length; i++) {
+ const w = widgetList[i];
+ if (!w || !w.$el || !w.$el.contains(evt.target)) continue;
+ if (this.widgets[i] && this.widgets[i].type === "widget-tabs") {
+ const findTabs = (comp) => {
+ if (!comp) return null;
+ if (typeof comp.addWidgetFromDrop === "function") return comp;
+ if (comp.$children && comp.$children.length) {
+ for (let j = 0; j < comp.$children.length; j++) {
+ const found = findTabs(comp.$children[j]);
+ if (found) return found;
+ }
+ }
+ return null;
+ };
+ const tabsComp = findTabs(w);
+ if (tabsComp) {
+ tabsComp.addWidgetFromDrop(evt);
+ return;
+ }
+ }
+ break;
+ }
+ }
let widgetType = this.dragWidgetCode;
// 获取结束坐标和列名
diff --git a/src/views/bigscreenDesigner/designer/tools/configure/form/widget-tabs.js b/src/views/bigscreenDesigner/designer/tools/configure/form/widget-tabs.js
new file mode 100644
index 0000000..efbc991
--- /dev/null
+++ b/src/views/bigscreenDesigner/designer/tools/configure/form/widget-tabs.js
@@ -0,0 +1,221 @@
+/*
+ * @Descripttion: Tabs标签组件
+ * @version:
+ * @Author: Devli
+ * @Date: 2024-01-01 00:00:00
+ * @LastEditors: Devli
+ * @LastEditTime: 2024-01-01 00:00:00
+ */
+export const widgetTabs = {
+ code: 'widget-tabs',
+ type: 'form',
+ tabName: '表单',
+ label: 'Tabs标签',
+ icon: 'iconkuangjia',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: 'Tabs标签',
+ },
+ {
+ type: 'el-select',
+ label: '标签位置',
+ name: 'tabPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'right', name: '右侧' },
+ { code: 'bottom', name: '底部' },
+ { code: 'left', name: '左侧' },
+ ],
+ value: 'top',
+ },
+ {
+ type: 'el-select',
+ label: '标签类型',
+ name: 'type',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: '', name: '默认' },
+ { code: 'border-card', name: '边框卡片' },
+ { code: 'card', name: '卡片' },
+ ],
+ value: '',
+ },
+ {
+ type: 'el-switch',
+ label: '可关闭',
+ name: 'closable',
+ required: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'el-switch',
+ label: '可添加',
+ name: 'addable',
+ required: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'el-switch',
+ label: '可拉伸',
+ name: 'stretch',
+ required: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'vue-color',
+ label: '标签字体颜色',
+ name: 'labelColor',
+ required: false,
+ placeholder: '',
+ value: '#303133',
+ },
+ {
+ type: 'vue-color',
+ label: '激活标签颜色',
+ name: 'activeColor',
+ required: false,
+ placeholder: '',
+ value: '#409EFF',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体字号',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ value: 14,
+ },
+ {
+ type: 'el-button',
+ label: '标签列表',
+ name: 'tabsList',
+ required: false,
+ placeholder: '',
+ value: [
+ { label: '标签一', name: 'tab1', content: '标签一的内容', children: [] },
+ { label: '标签二', name: 'tab2', content: '标签二的内容', children: [] },
+ { label: '标签三', name: 'tab3', content: '标签三的内容', children: [] },
+ ],
+ },
+ [
+ {
+ name: '组件联动',
+ list: [
+ {
+ type: 'componentLinkage',
+ label: '',
+ name: 'componentLinkage',
+ required: false,
+ value: []
+ }
+ ]
+ }
+ ]
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-input-number',
+ label: '刷新时间(毫秒)',
+ name: 'refreshTime',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'dynamicData',
+ value: 30000
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: '',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: [
+ { label: '标签一', name: 'tab1', content: '标签一的内容', children: [] },
+ { label: '标签二', name: 'tab2', content: '标签二的内容', children: [] },
+ { label: '标签三', name: 'tab3', content: '标签三的内容', children: [] },
+ ],
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: '',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'dynamicData',
+ chartType: 'widget-tabs',
+ dictKey: 'TABS_PROPERTIES',
+ value: '',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: '',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: '',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 300,
+ },
+ ],
+ }
+}
+
diff --git a/src/views/bigscreenDesigner/designer/tools/main.js b/src/views/bigscreenDesigner/designer/tools/main.js
index 12c98fd..a322fb2 100644
--- a/src/views/bigscreenDesigner/designer/tools/main.js
+++ b/src/views/bigscreenDesigner/designer/tools/main.js
@@ -13,6 +13,7 @@ import {widgetHref} from "./configure/texts/widget-href"
import {widgetTime} from "./configure/texts/widget-time"
import {widgetImage} from "./configure/texts/widget-image"
import {widgetButton} from "./configure/form/widget-button"
+import {widgetTabs} from "./configure/form/widget-tabs"
import {widgetSliders} from "./configure/texts/widget-slider"
import {widgetVideo} from "./configure/texts/widget-video"
import {widgetVideoMonitor} from "./configure/texts/widget-videoMonitor"
@@ -68,6 +69,7 @@ export const widgetTool = [
widgetTime,
widgetImage,
widgetButton,
+ widgetTabs,
// widgetSliders,
widgetVideo,
widgetVideoMonitor,
diff --git a/src/views/bigscreenDesigner/designer/widget/form/widgetTabs.vue b/src/views/bigscreenDesigner/designer/widget/form/widgetTabs.vue
new file mode 100644
index 0000000..8e5d41f
--- /dev/null
+++ b/src/views/bigscreenDesigner/designer/widget/form/widgetTabs.vue
@@ -0,0 +1,638 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/bigscreenDesigner/designer/widget/widget.vue b/src/views/bigscreenDesigner/designer/widget/widget.vue
index 084e9b1..bfe2251 100644
--- a/src/views/bigscreenDesigner/designer/widget/widget.vue
+++ b/src/views/bigscreenDesigner/designer/widget/widget.vue
@@ -20,6 +20,7 @@
import widgetHref from "./texts/widgetHref.vue";
import widgetText from "./texts/widgetText.vue";
import widgetButton from './form/widgetButton.vue';
+import widgetTabs from './form/widgetTabs.vue';
import WidgetMarquee from "./texts/widgetMarquee.vue";
import widgetTime from "./texts/widgetTime.vue";
import widgetImage from "./texts/widgetImage.vue";
@@ -72,6 +73,7 @@ export default {
widgetHref,
widgetText,
widgetButton,
+ widgetTabs,
widgetBorder,
widgetDecorateFlowLine,
widgetDecoration,