@tmagic/editor 1.4.4 → 1.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/style.css +2 -2
- package/dist/tmagic-editor.js +2393 -2242
- package/dist/tmagic-editor.umd.cjs +2403 -2248
- package/package.json +27 -27
- package/src/editorProps.ts +5 -1
- package/src/fields/DataSourceFieldSelect.vue +3 -41
- package/src/fields/EventSelect.vue +30 -9
- package/src/hooks/use-code-block-edit.ts +0 -2
- package/src/hooks/use-stage.ts +1 -1
- package/src/index.ts +1 -0
- package/src/initService.ts +12 -2
- package/src/layouts/workspace/viewer/Stage.vue +7 -6
- package/src/services/codeBlock.ts +77 -9
- package/src/services/dataSource.ts +53 -4
- package/src/services/editor.ts +2 -2
- package/src/services/props.ts +10 -5
- package/src/services/stageOverlay.ts +1 -0
- package/src/type.ts +1 -0
- package/src/utils/content-menu.ts +7 -3
- package/src/utils/data-source/index.ts +39 -3
- package/src/utils/editor.ts +16 -7
- package/types/components/CodeBlockEditor.vue.d.ts +21 -34
- package/types/components/CodeParams.vue.d.ts +2 -2
- package/types/components/ContentMenu.vue.d.ts +1 -1
- package/types/components/FloatingBox.vue.d.ts +41 -38
- package/types/components/ScrollViewer.vue.d.ts +1 -1
- package/types/components/ToolButton.vue.d.ts +4 -4
- package/types/components/Tree.vue.d.ts +2 -2
- package/types/editorProps.d.ts +5 -1
- package/types/fields/CodeLink.vue.d.ts +2 -2
- package/types/fields/DataSourceFields.vue.d.ts +32 -78
- package/types/fields/DataSourceInput.vue.d.ts +2 -2
- package/types/fields/DataSourceMethods.vue.d.ts +2 -2
- package/types/fields/DataSourceMocks.vue.d.ts +31 -76
- package/types/fields/KeyValue.vue.d.ts +2 -2
- package/types/fields/UISelect.vue.d.ts +2 -2
- package/types/hooks/use-code-block-edit.d.ts +18 -6
- package/types/hooks/use-data-source-edit.d.ts +18 -6
- package/types/hooks/use-data-source-method.d.ts +18 -6
- package/types/index.d.ts +1 -0
- package/types/layouts/CodeEditor.vue.d.ts +1 -1
- package/types/layouts/PropsPanel.vue.d.ts +14 -14
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +20 -30
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +6 -6
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +4 -4
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +6 -6
- package/types/services/codeBlock.d.ts +22 -2
- package/types/services/dataSource.d.ts +13 -1
- package/types/services/ui.d.ts +1 -1
- package/types/type.d.ts +1 -0
- package/types/utils/data-source/index.d.ts +3 -2
- package/types/utils/editor.d.ts +2 -0
|
@@ -510,362 +510,94 @@
|
|
|
510
510
|
}
|
|
511
511
|
});
|
|
512
512
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
rules: [
|
|
529
|
-
{
|
|
530
|
-
required: true,
|
|
531
|
-
message: "请输入名称"
|
|
513
|
+
const compose = (middleware, isAsync) => {
|
|
514
|
+
if (!Array.isArray(middleware))
|
|
515
|
+
throw new TypeError("Middleware 必须是一个数组!");
|
|
516
|
+
for (const fn of middleware) {
|
|
517
|
+
if (typeof fn !== "function")
|
|
518
|
+
throw new TypeError("Middleware 必须由函数组成!");
|
|
519
|
+
}
|
|
520
|
+
return (args, next) => {
|
|
521
|
+
let index = -1;
|
|
522
|
+
return dispatch(0);
|
|
523
|
+
function dispatch(i) {
|
|
524
|
+
if (i <= index) {
|
|
525
|
+
const error = new Error("next() 被多次调用");
|
|
526
|
+
if (isAsync) {
|
|
527
|
+
return Promise.reject(error);
|
|
532
528
|
}
|
|
533
|
-
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
name: "description",
|
|
537
|
-
text: "描述"
|
|
538
|
-
}
|
|
539
|
-
];
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
const HttpFormConfig = [
|
|
543
|
-
{
|
|
544
|
-
name: "autoFetch",
|
|
545
|
-
text: "自动请求",
|
|
546
|
-
type: "switch",
|
|
547
|
-
defaultValue: true
|
|
548
|
-
},
|
|
549
|
-
{
|
|
550
|
-
name: "responseOptions",
|
|
551
|
-
items: [
|
|
552
|
-
{
|
|
553
|
-
name: "dataPath",
|
|
554
|
-
text: "数据路径"
|
|
529
|
+
throw error;
|
|
555
530
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
text: "URL"
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
name: "method",
|
|
569
|
-
text: "Method",
|
|
570
|
-
type: "select",
|
|
571
|
-
options: [
|
|
572
|
-
{ text: "GET", value: "GET" },
|
|
573
|
-
{ text: "POST", value: "POST" },
|
|
574
|
-
{ text: "PUT", value: "PUT" },
|
|
575
|
-
{ text: "DELETE", value: "DELETE" }
|
|
576
|
-
]
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
name: "params",
|
|
580
|
-
type: "key-value",
|
|
581
|
-
defaultValue: {},
|
|
582
|
-
text: "参数"
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
name: "data",
|
|
586
|
-
type: "key-value",
|
|
587
|
-
defaultValue: {},
|
|
588
|
-
advanced: true,
|
|
589
|
-
text: "请求体"
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
name: "headers",
|
|
593
|
-
type: "key-value",
|
|
594
|
-
defaultValue: {},
|
|
595
|
-
text: "请求头"
|
|
531
|
+
index = i;
|
|
532
|
+
let fn = middleware[i];
|
|
533
|
+
if (i === middleware.length && next)
|
|
534
|
+
fn = next;
|
|
535
|
+
if (!fn) {
|
|
536
|
+
if (isAsync) {
|
|
537
|
+
return Promise.resolve();
|
|
538
|
+
}
|
|
539
|
+
return;
|
|
596
540
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
541
|
+
if (isAsync) {
|
|
542
|
+
try {
|
|
543
|
+
return Promise.resolve(fn(...args, dispatch.bind(null, i + 1)));
|
|
544
|
+
} catch (err) {
|
|
545
|
+
return Promise.reject(err);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
try {
|
|
549
|
+
return fn(...args, dispatch.bind(null, i + 1));
|
|
550
|
+
} catch (err) {
|
|
551
|
+
throw err;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
};
|
|
600
556
|
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
{
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
type: "data-source-fields",
|
|
613
|
-
defaultValue: () => []
|
|
614
|
-
}
|
|
615
|
-
]
|
|
616
|
-
},
|
|
617
|
-
{
|
|
618
|
-
title: "方法定义",
|
|
619
|
-
items: [
|
|
620
|
-
{
|
|
621
|
-
name: "methods",
|
|
622
|
-
type: "data-source-methods",
|
|
623
|
-
defaultValue: () => []
|
|
624
|
-
}
|
|
625
|
-
]
|
|
626
|
-
},
|
|
627
|
-
{
|
|
628
|
-
title: "事件配置",
|
|
629
|
-
display: false,
|
|
630
|
-
items: [
|
|
631
|
-
{
|
|
632
|
-
name: "events",
|
|
633
|
-
src: "datasource",
|
|
634
|
-
type: "event-select"
|
|
635
|
-
}
|
|
636
|
-
]
|
|
637
|
-
},
|
|
638
|
-
{
|
|
639
|
-
title: "mock数据",
|
|
640
|
-
items: [
|
|
641
|
-
{
|
|
642
|
-
name: "mocks",
|
|
643
|
-
type: "data-source-mocks",
|
|
644
|
-
defaultValue: () => []
|
|
645
|
-
}
|
|
646
|
-
]
|
|
647
|
-
},
|
|
648
|
-
{
|
|
649
|
-
title: "请求参数裁剪",
|
|
650
|
-
display: (formState, { model }) => model.type === "http",
|
|
651
|
-
items: [
|
|
652
|
-
{
|
|
653
|
-
name: "beforeRequest",
|
|
654
|
-
type: "vs-code",
|
|
655
|
-
parse: true,
|
|
656
|
-
height: "600px"
|
|
657
|
-
}
|
|
658
|
-
]
|
|
659
|
-
},
|
|
660
|
-
{
|
|
661
|
-
title: "响应数据裁剪",
|
|
662
|
-
display: (formState, { model }) => model.type === "http",
|
|
663
|
-
items: [
|
|
664
|
-
{
|
|
665
|
-
name: "afterResponse",
|
|
666
|
-
type: "vs-code",
|
|
667
|
-
parse: true,
|
|
668
|
-
height: "600px"
|
|
669
|
-
}
|
|
670
|
-
]
|
|
557
|
+
const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
|
|
558
|
+
const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
|
|
559
|
+
const doAction = (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
560
|
+
try {
|
|
561
|
+
let beforeArgs = args;
|
|
562
|
+
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
563
|
+
beforeArgs = beforeMethod(...beforeArgs) || [];
|
|
564
|
+
if (isError(beforeArgs))
|
|
565
|
+
throw beforeArgs;
|
|
566
|
+
if (!Array.isArray(beforeArgs)) {
|
|
567
|
+
beforeArgs = [beforeArgs];
|
|
671
568
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
return fillConfig$1(configs[type] || []);
|
|
569
|
+
}
|
|
570
|
+
let returnValue = fn(beforeArgs, sourceMethod.bind(scope));
|
|
571
|
+
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
572
|
+
returnValue = afterMethod(returnValue, ...beforeArgs);
|
|
573
|
+
if (isError(returnValue))
|
|
574
|
+
throw returnValue;
|
|
575
|
+
}
|
|
576
|
+
return returnValue;
|
|
577
|
+
} catch (error) {
|
|
578
|
+
throw error;
|
|
683
579
|
}
|
|
684
580
|
};
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
* // 请求方法 GET/POST
|
|
706
|
-
* method?: Method;
|
|
707
|
-
* }
|
|
708
|
-
*
|
|
709
|
-
* context:上下文对象
|
|
710
|
-
*
|
|
711
|
-
* interface Content {
|
|
712
|
-
* app: AppCore;
|
|
713
|
-
* dataSource: HttpDataSource;
|
|
714
|
-
* }
|
|
715
|
-
*
|
|
716
|
-
* return: HttpOptions
|
|
717
|
-
*/
|
|
718
|
-
|
|
719
|
-
// 此处的返回值会作为这个接口的入参
|
|
720
|
-
return options;
|
|
721
|
-
}`,
|
|
722
|
-
afterResponse: `(response, context) => {
|
|
723
|
-
/**
|
|
724
|
-
* 用户可以直接编写函数,在原始接口返回之后,会运行该函数,将这个函数的返回值作为该数据源接口的返回
|
|
725
|
-
|
|
726
|
-
* context:上下文对象
|
|
727
|
-
*
|
|
728
|
-
* interface Content {
|
|
729
|
-
* app: AppCore;
|
|
730
|
-
* dataSource: HttpDataSource;
|
|
731
|
-
* }
|
|
732
|
-
*
|
|
733
|
-
*/
|
|
734
|
-
|
|
735
|
-
// 此处的返回值会作为这个接口的返回值
|
|
736
|
-
return response;
|
|
737
|
-
}`,
|
|
738
|
-
...values
|
|
739
|
-
};
|
|
740
|
-
};
|
|
741
|
-
const getDisplayField = (dataSources, key) => {
|
|
742
|
-
const displayState = [];
|
|
743
|
-
const matches = key.matchAll(/\$\{([\s\S]+?)\}/g);
|
|
744
|
-
let index = 0;
|
|
745
|
-
for (const match of matches) {
|
|
746
|
-
if (typeof match.index === "undefined")
|
|
747
|
-
break;
|
|
748
|
-
displayState.push({
|
|
749
|
-
type: "text",
|
|
750
|
-
value: key.substring(index, match.index)
|
|
751
|
-
});
|
|
752
|
-
let dsText = "";
|
|
753
|
-
let ds;
|
|
754
|
-
let fields;
|
|
755
|
-
match[1].split(".").forEach((item, index2) => {
|
|
756
|
-
if (index2 === 0) {
|
|
757
|
-
ds = dataSources.find((ds2) => ds2.id === item);
|
|
758
|
-
dsText += ds?.title || item;
|
|
759
|
-
fields = ds?.fields;
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
762
|
-
const field = fields?.find((field2) => field2.name === item);
|
|
763
|
-
fields = field?.fields;
|
|
764
|
-
dsText += `.${field?.title || item}`;
|
|
765
|
-
});
|
|
766
|
-
displayState.push({
|
|
767
|
-
type: "var",
|
|
768
|
-
value: dsText
|
|
769
|
-
});
|
|
770
|
-
index = match.index + match[0].length;
|
|
771
|
-
}
|
|
772
|
-
if (index < key.length) {
|
|
773
|
-
displayState.push({
|
|
774
|
-
type: "text",
|
|
775
|
-
value: key.substring(index)
|
|
776
|
-
});
|
|
777
|
-
}
|
|
778
|
-
return displayState;
|
|
779
|
-
};
|
|
780
|
-
|
|
781
|
-
const compose = (middleware, isAsync) => {
|
|
782
|
-
if (!Array.isArray(middleware))
|
|
783
|
-
throw new TypeError("Middleware 必须是一个数组!");
|
|
784
|
-
for (const fn of middleware) {
|
|
785
|
-
if (typeof fn !== "function")
|
|
786
|
-
throw new TypeError("Middleware 必须由函数组成!");
|
|
787
|
-
}
|
|
788
|
-
return (args, next) => {
|
|
789
|
-
let index = -1;
|
|
790
|
-
return dispatch(0);
|
|
791
|
-
function dispatch(i) {
|
|
792
|
-
if (i <= index) {
|
|
793
|
-
const error = new Error("next() 被多次调用");
|
|
794
|
-
if (isAsync) {
|
|
795
|
-
return Promise.reject(error);
|
|
796
|
-
}
|
|
797
|
-
throw error;
|
|
798
|
-
}
|
|
799
|
-
index = i;
|
|
800
|
-
let fn = middleware[i];
|
|
801
|
-
if (i === middleware.length && next)
|
|
802
|
-
fn = next;
|
|
803
|
-
if (!fn) {
|
|
804
|
-
if (isAsync) {
|
|
805
|
-
return Promise.resolve();
|
|
806
|
-
}
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
if (isAsync) {
|
|
810
|
-
try {
|
|
811
|
-
return Promise.resolve(fn(...args, dispatch.bind(null, i + 1)));
|
|
812
|
-
} catch (err) {
|
|
813
|
-
return Promise.reject(err);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
try {
|
|
817
|
-
return fn(...args, dispatch.bind(null, i + 1));
|
|
818
|
-
} catch (err) {
|
|
819
|
-
throw err;
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
};
|
|
823
|
-
};
|
|
824
|
-
|
|
825
|
-
const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
|
|
826
|
-
const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
|
|
827
|
-
const doAction = (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
828
|
-
try {
|
|
829
|
-
let beforeArgs = args;
|
|
830
|
-
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
831
|
-
beforeArgs = beforeMethod(...beforeArgs) || [];
|
|
832
|
-
if (isError(beforeArgs))
|
|
833
|
-
throw beforeArgs;
|
|
834
|
-
if (!Array.isArray(beforeArgs)) {
|
|
835
|
-
beforeArgs = [beforeArgs];
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
let returnValue = fn(beforeArgs, sourceMethod.bind(scope));
|
|
839
|
-
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
840
|
-
returnValue = afterMethod(returnValue, ...beforeArgs);
|
|
841
|
-
if (isError(returnValue))
|
|
842
|
-
throw returnValue;
|
|
843
|
-
}
|
|
844
|
-
return returnValue;
|
|
845
|
-
} catch (error) {
|
|
846
|
-
throw error;
|
|
847
|
-
}
|
|
848
|
-
};
|
|
849
|
-
const doAsyncAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
850
|
-
try {
|
|
851
|
-
let beforeArgs = args;
|
|
852
|
-
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
853
|
-
beforeArgs = await beforeMethod(...beforeArgs) || [];
|
|
854
|
-
if (isError(beforeArgs))
|
|
855
|
-
throw beforeArgs;
|
|
856
|
-
if (!Array.isArray(beforeArgs)) {
|
|
857
|
-
beforeArgs = [beforeArgs];
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
|
|
861
|
-
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
862
|
-
returnValue = await afterMethod(returnValue, ...beforeArgs);
|
|
863
|
-
if (isError(returnValue))
|
|
864
|
-
throw returnValue;
|
|
865
|
-
}
|
|
866
|
-
return returnValue;
|
|
867
|
-
} catch (error) {
|
|
868
|
-
throw error;
|
|
581
|
+
const doAsyncAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
582
|
+
try {
|
|
583
|
+
let beforeArgs = args;
|
|
584
|
+
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
585
|
+
beforeArgs = await beforeMethod(...beforeArgs) || [];
|
|
586
|
+
if (isError(beforeArgs))
|
|
587
|
+
throw beforeArgs;
|
|
588
|
+
if (!Array.isArray(beforeArgs)) {
|
|
589
|
+
beforeArgs = [beforeArgs];
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
|
|
593
|
+
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
594
|
+
returnValue = await afterMethod(returnValue, ...beforeArgs);
|
|
595
|
+
if (isError(returnValue))
|
|
596
|
+
throw returnValue;
|
|
597
|
+
}
|
|
598
|
+
return returnValue;
|
|
599
|
+
} catch (error) {
|
|
600
|
+
throw error;
|
|
869
601
|
}
|
|
870
602
|
};
|
|
871
603
|
class BaseService extends events.EventEmitter {
|
|
@@ -941,590 +673,500 @@
|
|
|
941
673
|
}
|
|
942
674
|
}
|
|
943
675
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
"
|
|
949
|
-
"getFormValue",
|
|
950
|
-
"setFormValue",
|
|
951
|
-
"getFormEvent",
|
|
952
|
-
"setFormEvent",
|
|
953
|
-
"getFormMethod",
|
|
954
|
-
"setFormMethod",
|
|
955
|
-
"add",
|
|
956
|
-
"update",
|
|
957
|
-
"remove",
|
|
958
|
-
"createId"
|
|
959
|
-
]
|
|
960
|
-
};
|
|
961
|
-
class DataSource extends BaseService {
|
|
962
|
-
state = vue.reactive({
|
|
963
|
-
datasourceTypeList: [],
|
|
964
|
-
dataSources: [],
|
|
965
|
-
editable: true,
|
|
966
|
-
configs: {},
|
|
967
|
-
values: {},
|
|
968
|
-
events: {},
|
|
969
|
-
methods: {}
|
|
970
|
-
});
|
|
971
|
-
constructor() {
|
|
972
|
-
super(canUsePluginMethods$6.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
676
|
+
class Dep extends BaseService {
|
|
677
|
+
watcher = new dep.Watcher({ initialTargets: vue.reactive({}) });
|
|
678
|
+
removeTargets(type = dep.DepTargetType.DEFAULT) {
|
|
679
|
+
this.watcher.removeTargets(type);
|
|
680
|
+
this.emit("remove-target");
|
|
973
681
|
}
|
|
974
|
-
|
|
975
|
-
this.
|
|
682
|
+
getTargets(type = dep.DepTargetType.DEFAULT) {
|
|
683
|
+
return this.watcher.getTargets(type);
|
|
976
684
|
}
|
|
977
|
-
|
|
978
|
-
return this.
|
|
685
|
+
getTarget(id, type = dep.DepTargetType.DEFAULT) {
|
|
686
|
+
return this.watcher.getTarget(id, type);
|
|
979
687
|
}
|
|
980
|
-
|
|
981
|
-
|
|
688
|
+
addTarget(target) {
|
|
689
|
+
this.watcher.addTarget(target);
|
|
690
|
+
this.emit("add-target", target);
|
|
982
691
|
}
|
|
983
|
-
|
|
984
|
-
this.
|
|
692
|
+
removeTarget(id, type = dep.DepTargetType.DEFAULT) {
|
|
693
|
+
this.watcher.removeTarget(id, type);
|
|
694
|
+
this.emit("remove-target");
|
|
985
695
|
}
|
|
986
|
-
|
|
987
|
-
|
|
696
|
+
clearTargets() {
|
|
697
|
+
this.watcher.clearTargets();
|
|
988
698
|
}
|
|
989
|
-
|
|
990
|
-
this.
|
|
699
|
+
collect(nodes, deep = false, type) {
|
|
700
|
+
this.watcher.collect(nodes, deep, type);
|
|
701
|
+
this.emit("collected", nodes, deep);
|
|
991
702
|
}
|
|
992
|
-
|
|
993
|
-
return this.
|
|
703
|
+
clear(nodes) {
|
|
704
|
+
return this.watcher.clear(nodes);
|
|
994
705
|
}
|
|
995
|
-
|
|
996
|
-
this.
|
|
706
|
+
clearByType(type, nodes) {
|
|
707
|
+
return this.watcher.clearByType(type, nodes);
|
|
997
708
|
}
|
|
998
|
-
|
|
999
|
-
return this.
|
|
709
|
+
hasTarget(id, type = dep.DepTargetType.DEFAULT) {
|
|
710
|
+
return this.watcher.hasTarget(id, type);
|
|
1000
711
|
}
|
|
1001
|
-
|
|
1002
|
-
this.
|
|
712
|
+
hasSpecifiedTypeTarget(type = dep.DepTargetType.DEFAULT) {
|
|
713
|
+
return this.watcher.hasSpecifiedTypeTarget(type);
|
|
1003
714
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
715
|
+
}
|
|
716
|
+
const depService = new Dep();
|
|
717
|
+
|
|
718
|
+
const canUsePluginMethods$6 = {
|
|
719
|
+
async: [
|
|
720
|
+
"setPropsConfig",
|
|
721
|
+
"getPropsConfig",
|
|
722
|
+
"setPropsValue",
|
|
723
|
+
"getPropsValue",
|
|
724
|
+
"fillConfig",
|
|
725
|
+
"getDefaultPropsValue"
|
|
726
|
+
],
|
|
727
|
+
sync: ["createId", "setNewItemId"]
|
|
728
|
+
};
|
|
729
|
+
class Props extends BaseService {
|
|
730
|
+
state = vue.reactive({
|
|
731
|
+
propsConfigMap: {},
|
|
732
|
+
propsValueMap: {},
|
|
733
|
+
relateIdMap: {}
|
|
734
|
+
});
|
|
735
|
+
constructor() {
|
|
736
|
+
super([
|
|
737
|
+
...canUsePluginMethods$6.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
738
|
+
...canUsePluginMethods$6.sync.map((methodName) => ({ name: methodName, isAsync: false }))
|
|
739
|
+
]);
|
|
1012
740
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
this.emit("
|
|
1018
|
-
return config;
|
|
741
|
+
setPropsConfigs(configs) {
|
|
742
|
+
Object.keys(configs).forEach((type) => {
|
|
743
|
+
this.setPropsConfig(utils.toLine(type), configs[type]);
|
|
744
|
+
});
|
|
745
|
+
this.emit("props-configs-change");
|
|
1019
746
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
const index = dataSources.findIndex((ds) => ds.id === id);
|
|
1023
|
-
dataSources.splice(index, 1);
|
|
1024
|
-
this.emit("remove", id);
|
|
747
|
+
async fillConfig(config, labelWidth) {
|
|
748
|
+
return fillConfig(config, typeof labelWidth !== "function" ? labelWidth : "80px");
|
|
1025
749
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
750
|
+
async setPropsConfig(type, config) {
|
|
751
|
+
this.state.propsConfigMap[utils.toLine(type)] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
1028
752
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
753
|
+
/**
|
|
754
|
+
* 获取指点类型的组件属性表单配置
|
|
755
|
+
* @param type 组件类型
|
|
756
|
+
* @returns 组件属性表单配置
|
|
757
|
+
*/
|
|
758
|
+
async getPropsConfig(type) {
|
|
759
|
+
if (type === "area") {
|
|
760
|
+
return await this.getPropsConfig("button");
|
|
761
|
+
}
|
|
762
|
+
return lodashEs.cloneDeep(this.state.propsConfigMap[utils.toLine(type)] || await this.fillConfig([]));
|
|
763
|
+
}
|
|
764
|
+
setPropsValues(values) {
|
|
765
|
+
Object.keys(values).forEach((type) => {
|
|
766
|
+
this.setPropsValue(utils.toLine(type), values[type]);
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* 为指点类型组件设置组件初始值
|
|
771
|
+
* @param type 组件类型
|
|
772
|
+
* @param value 组件初始值
|
|
773
|
+
*/
|
|
774
|
+
async setPropsValue(type, value) {
|
|
775
|
+
this.state.propsValueMap[utils.toLine(type)] = value;
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* 获取指定类型的组件初始值
|
|
779
|
+
* @param type 组件类型
|
|
780
|
+
* @returns 组件初始值
|
|
781
|
+
*/
|
|
782
|
+
async getPropsValue(componentType, { inputEvent, ...defaultValue } = {}) {
|
|
783
|
+
const type = utils.toLine(componentType);
|
|
784
|
+
if (type === "area") {
|
|
785
|
+
const value = await this.getPropsValue("button");
|
|
786
|
+
value.className = "action-area";
|
|
787
|
+
value.text = "";
|
|
788
|
+
if (value.style) {
|
|
789
|
+
value.style.backgroundColor = "rgba(255, 255, 255, 0)";
|
|
790
|
+
}
|
|
791
|
+
return value;
|
|
792
|
+
}
|
|
793
|
+
const id = this.createId(type);
|
|
794
|
+
const defaultPropsValue = this.getDefaultPropsValue(type);
|
|
795
|
+
const data = this.setNewItemId(
|
|
796
|
+
lodashEs.cloneDeep({
|
|
797
|
+
type,
|
|
798
|
+
...defaultValue
|
|
799
|
+
})
|
|
800
|
+
);
|
|
801
|
+
return {
|
|
802
|
+
id,
|
|
803
|
+
...defaultPropsValue,
|
|
804
|
+
...lodashEs.mergeWith({}, lodashEs.cloneDeep(this.state.propsValueMap[type] || {}), data)
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
createId(type) {
|
|
808
|
+
return `${type}_${utils.guid()}`;
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* 将组件与组件的子元素配置中的id都设置成一个新的ID
|
|
812
|
+
* 如果没有相同ID并且force为false则保持不变
|
|
813
|
+
* @param {Object} config 组件配置
|
|
814
|
+
* @param {Boolean} force 是否强制设置新的ID
|
|
815
|
+
*/
|
|
816
|
+
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
817
|
+
setNewItemId(config, force = true) {
|
|
818
|
+
if (force || editorService.getNodeById(config.id)) {
|
|
819
|
+
const newId = this.createId(config.type || "component");
|
|
820
|
+
this.setRelateId(config.id, newId);
|
|
821
|
+
config.id = newId;
|
|
822
|
+
}
|
|
823
|
+
if (config.items && Array.isArray(config.items)) {
|
|
824
|
+
for (const item of config.items) {
|
|
825
|
+
this.setNewItemId(item);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
return config;
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* 获取默认属性配置
|
|
832
|
+
* @param type 组件类型
|
|
833
|
+
* @returns Object
|
|
834
|
+
*/
|
|
835
|
+
getDefaultPropsValue(type) {
|
|
836
|
+
return ["page", "container"].includes(type) ? {
|
|
837
|
+
type,
|
|
838
|
+
layout: "absolute",
|
|
839
|
+
style: {},
|
|
840
|
+
name: type,
|
|
841
|
+
items: []
|
|
842
|
+
} : {
|
|
843
|
+
type,
|
|
844
|
+
style: {},
|
|
845
|
+
name: type
|
|
846
|
+
};
|
|
1031
847
|
}
|
|
1032
848
|
resetState() {
|
|
1033
|
-
this.
|
|
849
|
+
this.state.propsConfigMap = {};
|
|
850
|
+
this.state.propsValueMap = {};
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* 替换关联ID
|
|
854
|
+
* @param originConfigs 原组件配置
|
|
855
|
+
* @param targetConfigs 待替换的组件配置
|
|
856
|
+
*/
|
|
857
|
+
replaceRelateId(originConfigs, targetConfigs) {
|
|
858
|
+
const relateIdMap = this.getRelateIdMap();
|
|
859
|
+
if (Object.keys(relateIdMap).length === 0)
|
|
860
|
+
return;
|
|
861
|
+
depService.clearByType(dep.DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
862
|
+
depService.collect(originConfigs, true, dep.DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
863
|
+
const target = depService.getTarget(dep.DepTargetType.RELATED_COMP_WHEN_COPY, dep.DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
864
|
+
if (!target)
|
|
865
|
+
return;
|
|
866
|
+
originConfigs.forEach((config) => {
|
|
867
|
+
const newId = relateIdMap[config.id];
|
|
868
|
+
const path = utils.getNodePath(newId, targetConfigs);
|
|
869
|
+
const targetConfig = path[path.length - 1];
|
|
870
|
+
if (!targetConfig)
|
|
871
|
+
return;
|
|
872
|
+
target.deps[config.id]?.keys?.forEach((fullKey) => {
|
|
873
|
+
const relateOriginId = utils.getValueByKeyPath(fullKey, config);
|
|
874
|
+
const relateTargetId = relateIdMap[relateOriginId];
|
|
875
|
+
if (!relateTargetId)
|
|
876
|
+
return;
|
|
877
|
+
utils.setValueByKeyPath(fullKey, relateTargetId, targetConfig);
|
|
878
|
+
});
|
|
879
|
+
if (config.items && Array.isArray(config.items)) {
|
|
880
|
+
this.replaceRelateId(config.items, targetConfigs);
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* 清除setNewItemId前后映射关系
|
|
886
|
+
*/
|
|
887
|
+
clearRelateId() {
|
|
888
|
+
this.state.relateIdMap = {};
|
|
1034
889
|
}
|
|
1035
890
|
destroy() {
|
|
1036
|
-
this.removeAllListeners();
|
|
1037
891
|
this.resetState();
|
|
892
|
+
this.removeAllListeners();
|
|
1038
893
|
this.removeAllPlugins();
|
|
1039
894
|
}
|
|
1040
895
|
usePlugin(options) {
|
|
1041
896
|
super.usePlugin(options);
|
|
1042
897
|
}
|
|
898
|
+
/**
|
|
899
|
+
* 获取setNewItemId前后映射关系
|
|
900
|
+
* @param oldId 原组件ID
|
|
901
|
+
* @returns 新旧ID映射
|
|
902
|
+
*/
|
|
903
|
+
getRelateIdMap() {
|
|
904
|
+
return this.state.relateIdMap;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* 记录setNewItemId前后映射关系
|
|
908
|
+
* @param oldId 原组件ID
|
|
909
|
+
* @param newId 分配的新ID
|
|
910
|
+
*/
|
|
911
|
+
setRelateId(oldId, newId) {
|
|
912
|
+
this.state.relateIdMap[oldId] = newId;
|
|
913
|
+
}
|
|
1043
914
|
}
|
|
1044
|
-
const
|
|
915
|
+
const propsService = new Props();
|
|
1045
916
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
{
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const styleTabConfig = {
|
|
1063
|
-
title: "样式",
|
|
1064
|
-
items: [
|
|
1065
|
-
{
|
|
1066
|
-
name: "style",
|
|
1067
|
-
items: [
|
|
1068
|
-
{
|
|
1069
|
-
type: "fieldset",
|
|
1070
|
-
legend: "位置",
|
|
1071
|
-
items: [
|
|
1072
|
-
{
|
|
1073
|
-
type: "data-source-field-select",
|
|
1074
|
-
name: "position",
|
|
1075
|
-
text: "固定定位",
|
|
1076
|
-
checkStrictly: false,
|
|
1077
|
-
dataSourceFieldType: ["string"],
|
|
1078
|
-
fieldConfig: {
|
|
1079
|
-
type: "checkbox",
|
|
1080
|
-
activeValue: "fixed",
|
|
1081
|
-
inactiveValue: "absolute",
|
|
1082
|
-
defaultValue: "absolute"
|
|
1083
|
-
}
|
|
1084
|
-
},
|
|
1085
|
-
{
|
|
1086
|
-
type: "data-source-field-select",
|
|
1087
|
-
name: "left",
|
|
1088
|
-
text: "left",
|
|
1089
|
-
checkStrictly: false,
|
|
1090
|
-
dataSourceFieldType: ["string", "number"],
|
|
1091
|
-
fieldConfig: {
|
|
1092
|
-
type: "text"
|
|
1093
|
-
}
|
|
1094
|
-
},
|
|
1095
|
-
{
|
|
1096
|
-
type: "data-source-field-select",
|
|
1097
|
-
name: "top",
|
|
1098
|
-
text: "top",
|
|
1099
|
-
checkStrictly: false,
|
|
1100
|
-
dataSourceFieldType: ["string", "number"],
|
|
1101
|
-
fieldConfig: {
|
|
1102
|
-
type: "text"
|
|
1103
|
-
},
|
|
1104
|
-
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedBottom"
|
|
1105
|
-
},
|
|
1106
|
-
{
|
|
1107
|
-
type: "data-source-field-select",
|
|
1108
|
-
name: "right",
|
|
1109
|
-
text: "right",
|
|
1110
|
-
checkStrictly: false,
|
|
1111
|
-
dataSourceFieldType: ["string", "number"],
|
|
1112
|
-
fieldConfig: {
|
|
1113
|
-
type: "text"
|
|
1114
|
-
}
|
|
1115
|
-
},
|
|
1116
|
-
{
|
|
1117
|
-
type: "data-source-field-select",
|
|
1118
|
-
name: "bottom",
|
|
1119
|
-
text: "bottom",
|
|
1120
|
-
checkStrictly: false,
|
|
1121
|
-
dataSourceFieldType: ["string", "number"],
|
|
1122
|
-
fieldConfig: {
|
|
1123
|
-
type: "text"
|
|
1124
|
-
},
|
|
1125
|
-
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedTop"
|
|
1126
|
-
}
|
|
1127
|
-
]
|
|
1128
|
-
},
|
|
1129
|
-
{
|
|
1130
|
-
type: "fieldset",
|
|
1131
|
-
legend: "盒子",
|
|
1132
|
-
items: [
|
|
1133
|
-
{
|
|
1134
|
-
type: "data-source-field-select",
|
|
1135
|
-
name: "width",
|
|
1136
|
-
text: "宽度",
|
|
1137
|
-
checkStrictly: false,
|
|
1138
|
-
dataSourceFieldType: ["string", "number"],
|
|
1139
|
-
fieldConfig: {
|
|
1140
|
-
type: "text"
|
|
1141
|
-
}
|
|
1142
|
-
},
|
|
1143
|
-
{
|
|
1144
|
-
type: "data-source-field-select",
|
|
1145
|
-
name: "height",
|
|
1146
|
-
text: "高度",
|
|
1147
|
-
checkStrictly: false,
|
|
1148
|
-
dataSourceFieldType: ["string", "number"],
|
|
1149
|
-
fieldConfig: {
|
|
1150
|
-
type: "text"
|
|
1151
|
-
}
|
|
1152
|
-
},
|
|
1153
|
-
{
|
|
1154
|
-
type: "data-source-field-select",
|
|
1155
|
-
text: "overflow",
|
|
1156
|
-
name: "overflow",
|
|
1157
|
-
checkStrictly: false,
|
|
1158
|
-
dataSourceFieldType: ["string"],
|
|
1159
|
-
fieldConfig: {
|
|
1160
|
-
type: "select",
|
|
1161
|
-
options: [
|
|
1162
|
-
{ text: "visible", value: "visible" },
|
|
1163
|
-
{ text: "hidden", value: "hidden" },
|
|
1164
|
-
{ text: "clip", value: "clip" },
|
|
1165
|
-
{ text: "scroll", value: "scroll" },
|
|
1166
|
-
{ text: "auto", value: "auto" },
|
|
1167
|
-
{ text: "overlay", value: "overlay" }
|
|
1168
|
-
]
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
]
|
|
1172
|
-
},
|
|
1173
|
-
{
|
|
1174
|
-
type: "fieldset",
|
|
1175
|
-
legend: "边框",
|
|
1176
|
-
items: [
|
|
1177
|
-
{
|
|
1178
|
-
type: "data-source-field-select",
|
|
1179
|
-
name: "borderWidth",
|
|
1180
|
-
text: "宽度",
|
|
1181
|
-
defaultValue: "0",
|
|
1182
|
-
checkStrictly: false,
|
|
1183
|
-
dataSourceFieldType: ["string", "number"],
|
|
1184
|
-
fieldConfig: {
|
|
1185
|
-
type: "text"
|
|
1186
|
-
}
|
|
1187
|
-
},
|
|
1188
|
-
{
|
|
1189
|
-
type: "data-source-field-select",
|
|
1190
|
-
name: "borderColor",
|
|
1191
|
-
text: "颜色",
|
|
1192
|
-
checkStrictly: false,
|
|
1193
|
-
dataSourceFieldType: ["string"],
|
|
1194
|
-
fieldConfig: {
|
|
1195
|
-
type: "text"
|
|
1196
|
-
}
|
|
1197
|
-
},
|
|
1198
|
-
{
|
|
1199
|
-
type: "data-source-field-select",
|
|
1200
|
-
name: "borderStyle",
|
|
1201
|
-
text: "样式",
|
|
1202
|
-
defaultValue: "none",
|
|
1203
|
-
checkStrictly: false,
|
|
1204
|
-
dataSourceFieldType: ["string"],
|
|
1205
|
-
fieldConfig: {
|
|
1206
|
-
type: "select",
|
|
1207
|
-
options: [
|
|
1208
|
-
{ text: "none", value: "none" },
|
|
1209
|
-
{ text: "hidden", value: "hidden" },
|
|
1210
|
-
{ text: "dotted", value: "dotted" },
|
|
1211
|
-
{ text: "dashed", value: "dashed" },
|
|
1212
|
-
{ text: "solid", value: "solid" },
|
|
1213
|
-
{ text: "double", value: "double" },
|
|
1214
|
-
{ text: "groove", value: "groove" },
|
|
1215
|
-
{ text: "ridge", value: "ridge" },
|
|
1216
|
-
{ text: "inset", value: "inset" },
|
|
1217
|
-
{ text: "outset", value: "outset" }
|
|
1218
|
-
]
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
]
|
|
1222
|
-
},
|
|
1223
|
-
{
|
|
1224
|
-
type: "fieldset",
|
|
1225
|
-
legend: "背景",
|
|
1226
|
-
items: [
|
|
1227
|
-
{
|
|
1228
|
-
type: "data-source-field-select",
|
|
1229
|
-
name: "backgroundImage",
|
|
1230
|
-
text: "背景图",
|
|
1231
|
-
checkStrictly: false,
|
|
1232
|
-
dataSourceFieldType: ["string"],
|
|
1233
|
-
fieldConfig: {
|
|
1234
|
-
type: "text"
|
|
1235
|
-
}
|
|
1236
|
-
},
|
|
1237
|
-
{
|
|
1238
|
-
type: "data-source-field-select",
|
|
1239
|
-
name: "backgroundColor",
|
|
1240
|
-
text: "背景颜色",
|
|
1241
|
-
checkStrictly: false,
|
|
1242
|
-
dataSourceFieldType: ["string"],
|
|
1243
|
-
fieldConfig: {
|
|
1244
|
-
type: "colorPicker"
|
|
1245
|
-
}
|
|
1246
|
-
},
|
|
1247
|
-
{
|
|
1248
|
-
type: "data-source-field-select",
|
|
1249
|
-
name: "backgroundRepeat",
|
|
1250
|
-
text: "背景图重复",
|
|
1251
|
-
defaultValue: "no-repeat",
|
|
1252
|
-
checkStrictly: false,
|
|
1253
|
-
dataSourceFieldType: ["string"],
|
|
1254
|
-
fieldConfig: {
|
|
1255
|
-
type: "select",
|
|
1256
|
-
options: [
|
|
1257
|
-
{ text: "repeat", value: "repeat" },
|
|
1258
|
-
{ text: "repeat-x", value: "repeat-x" },
|
|
1259
|
-
{ text: "repeat-y", value: "repeat-y" },
|
|
1260
|
-
{ text: "no-repeat", value: "no-repeat" },
|
|
1261
|
-
{ text: "inherit", value: "inherit" }
|
|
1262
|
-
]
|
|
1263
|
-
}
|
|
1264
|
-
},
|
|
1265
|
-
{
|
|
1266
|
-
type: "data-source-field-select",
|
|
1267
|
-
name: "backgroundSize",
|
|
1268
|
-
text: "背景图大小",
|
|
1269
|
-
defaultValue: "100% 100%",
|
|
1270
|
-
checkStrictly: false,
|
|
1271
|
-
dataSourceFieldType: ["string"],
|
|
1272
|
-
fieldConfig: {
|
|
1273
|
-
type: "text"
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
]
|
|
1277
|
-
},
|
|
1278
|
-
{
|
|
1279
|
-
type: "fieldset",
|
|
1280
|
-
legend: "字体",
|
|
1281
|
-
items: [
|
|
1282
|
-
{
|
|
1283
|
-
type: "data-source-field-select",
|
|
1284
|
-
name: "color",
|
|
1285
|
-
text: "颜色",
|
|
1286
|
-
checkStrictly: false,
|
|
1287
|
-
dataSourceFieldType: ["string"],
|
|
1288
|
-
fieldConfig: {
|
|
1289
|
-
type: "colorPicker"
|
|
1290
|
-
}
|
|
1291
|
-
},
|
|
1292
|
-
{
|
|
1293
|
-
type: "data-source-field-select",
|
|
1294
|
-
name: "fontSize",
|
|
1295
|
-
text: "大小",
|
|
1296
|
-
checkStrictly: false,
|
|
1297
|
-
dataSourceFieldType: ["string", "number"],
|
|
1298
|
-
fieldConfig: {
|
|
1299
|
-
type: "text"
|
|
1300
|
-
}
|
|
1301
|
-
},
|
|
1302
|
-
{
|
|
1303
|
-
type: "data-source-field-select",
|
|
1304
|
-
name: "fontWeight",
|
|
1305
|
-
text: "粗细",
|
|
1306
|
-
checkStrictly: false,
|
|
1307
|
-
dataSourceFieldType: ["string", "number"],
|
|
1308
|
-
fieldConfig: {
|
|
1309
|
-
type: "text"
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
]
|
|
1313
|
-
},
|
|
1314
|
-
{
|
|
1315
|
-
type: "fieldset",
|
|
1316
|
-
legend: "变形",
|
|
1317
|
-
name: "transform",
|
|
1318
|
-
items: [
|
|
1319
|
-
{
|
|
1320
|
-
type: "data-source-field-select",
|
|
1321
|
-
name: "rotate",
|
|
1322
|
-
text: "旋转角度",
|
|
1323
|
-
checkStrictly: false,
|
|
1324
|
-
dataSourceFieldType: ["string"],
|
|
1325
|
-
fieldConfig: {
|
|
1326
|
-
type: "text"
|
|
1327
|
-
}
|
|
1328
|
-
},
|
|
1329
|
-
{
|
|
1330
|
-
type: "data-source-field-select",
|
|
1331
|
-
name: "scale",
|
|
1332
|
-
text: "缩放",
|
|
1333
|
-
checkStrictly: false,
|
|
1334
|
-
dataSourceFieldType: ["number", "string"],
|
|
1335
|
-
fieldConfig: {
|
|
1336
|
-
type: "text"
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
]
|
|
1340
|
-
}
|
|
1341
|
-
]
|
|
1342
|
-
}
|
|
1343
|
-
]
|
|
1344
|
-
};
|
|
1345
|
-
const eventTabConfig = {
|
|
1346
|
-
title: "事件",
|
|
1347
|
-
items: [
|
|
1348
|
-
{
|
|
1349
|
-
name: "events",
|
|
1350
|
-
src: "component",
|
|
1351
|
-
labelWidth: "100px",
|
|
1352
|
-
type: "event-select"
|
|
1353
|
-
}
|
|
1354
|
-
]
|
|
1355
|
-
};
|
|
1356
|
-
const advancedTabConfig = {
|
|
1357
|
-
title: "高级",
|
|
1358
|
-
lazy: true,
|
|
1359
|
-
items: [
|
|
1360
|
-
{
|
|
1361
|
-
name: "created",
|
|
1362
|
-
text: "created",
|
|
1363
|
-
type: "code-select"
|
|
1364
|
-
},
|
|
1365
|
-
{
|
|
1366
|
-
name: "mounted",
|
|
1367
|
-
text: "mounted",
|
|
1368
|
-
type: "code-select"
|
|
1369
|
-
}
|
|
1370
|
-
]
|
|
1371
|
-
};
|
|
1372
|
-
const displayTabConfig = {
|
|
1373
|
-
title: "显示条件",
|
|
1374
|
-
display: (vm, { model }) => model.type !== "page",
|
|
1375
|
-
items: [
|
|
1376
|
-
{
|
|
1377
|
-
type: "groupList",
|
|
1378
|
-
name: "displayConds",
|
|
1379
|
-
titlePrefix: "条件组",
|
|
1380
|
-
expandAll: true,
|
|
1381
|
-
items: [
|
|
1382
|
-
{
|
|
1383
|
-
type: "table",
|
|
1384
|
-
name: "cond",
|
|
1385
|
-
items: [
|
|
1386
|
-
{
|
|
1387
|
-
type: "data-source-field-select",
|
|
1388
|
-
name: "field",
|
|
1389
|
-
value: "key",
|
|
1390
|
-
label: "字段",
|
|
1391
|
-
checkStrictly: false,
|
|
1392
|
-
dataSourceFieldType: ["string", "number", "boolean", "any"]
|
|
1393
|
-
},
|
|
1394
|
-
{
|
|
1395
|
-
type: "select",
|
|
1396
|
-
options: (mForm, { model }) => {
|
|
1397
|
-
const [id, ...fieldNames] = model.field;
|
|
1398
|
-
const ds = dataSourceService.getDataSourceById(id);
|
|
1399
|
-
let fields = ds?.fields || [];
|
|
1400
|
-
let type = "";
|
|
1401
|
-
(fieldNames || []).forEach((fieldName) => {
|
|
1402
|
-
const field = fields.find((f) => f.name === fieldName);
|
|
1403
|
-
fields = field?.fields || [];
|
|
1404
|
-
type = field?.type || "";
|
|
1405
|
-
});
|
|
1406
|
-
if (type === "array") {
|
|
1407
|
-
return arrayOptions;
|
|
1408
|
-
}
|
|
1409
|
-
if (type === "boolean") {
|
|
1410
|
-
return [
|
|
1411
|
-
{ text: "是", value: "is" },
|
|
1412
|
-
{ text: "不是", value: "not" }
|
|
1413
|
-
];
|
|
1414
|
-
}
|
|
1415
|
-
if (type === "number") {
|
|
1416
|
-
return [...eqOptions, ...numberOptions];
|
|
1417
|
-
}
|
|
1418
|
-
if (type === "string") {
|
|
1419
|
-
return [...arrayOptions, ...eqOptions];
|
|
1420
|
-
}
|
|
1421
|
-
return [...arrayOptions, ...eqOptions, ...numberOptions];
|
|
1422
|
-
},
|
|
1423
|
-
label: "条件",
|
|
1424
|
-
name: "op"
|
|
1425
|
-
},
|
|
1426
|
-
{
|
|
1427
|
-
label: "值",
|
|
1428
|
-
items: [
|
|
1429
|
-
{
|
|
1430
|
-
name: "value",
|
|
1431
|
-
type: (mForm, { model }) => {
|
|
1432
|
-
const [id, ...fieldNames] = model.field;
|
|
1433
|
-
const ds = dataSourceService.getDataSourceById(id);
|
|
1434
|
-
let fields = ds?.fields || [];
|
|
1435
|
-
let type = "";
|
|
1436
|
-
(fieldNames || []).forEach((fieldName) => {
|
|
1437
|
-
const field = fields.find((f) => f.name === fieldName);
|
|
1438
|
-
fields = field?.fields || [];
|
|
1439
|
-
type = field?.type || "";
|
|
1440
|
-
});
|
|
1441
|
-
if (type === "number") {
|
|
1442
|
-
return "number";
|
|
1443
|
-
}
|
|
1444
|
-
if (type === "boolean") {
|
|
1445
|
-
return "select";
|
|
1446
|
-
}
|
|
1447
|
-
return "text";
|
|
1448
|
-
},
|
|
1449
|
-
options: [
|
|
1450
|
-
{ text: "true", value: true },
|
|
1451
|
-
{ text: "false", value: false }
|
|
1452
|
-
],
|
|
1453
|
-
display: (vm, { model }) => !["between", "not_between"].includes(model.op)
|
|
1454
|
-
},
|
|
1455
|
-
{
|
|
1456
|
-
name: "range",
|
|
1457
|
-
type: "number-range",
|
|
1458
|
-
display: (vm, { model }) => ["between", "not_between"].includes(model.op)
|
|
1459
|
-
}
|
|
1460
|
-
]
|
|
1461
|
-
}
|
|
1462
|
-
]
|
|
1463
|
-
}
|
|
1464
|
-
]
|
|
917
|
+
class UndoRedo {
|
|
918
|
+
elementList;
|
|
919
|
+
listCursor;
|
|
920
|
+
listMaxSize;
|
|
921
|
+
constructor(listMaxSize = 20) {
|
|
922
|
+
const minListMaxSize = 2;
|
|
923
|
+
this.elementList = [];
|
|
924
|
+
this.listCursor = 0;
|
|
925
|
+
this.listMaxSize = listMaxSize > minListMaxSize ? listMaxSize : minListMaxSize;
|
|
926
|
+
}
|
|
927
|
+
pushElement(element) {
|
|
928
|
+
this.elementList.splice(this.listCursor, this.elementList.length - this.listCursor, lodashEs.cloneDeep(element));
|
|
929
|
+
this.listCursor += 1;
|
|
930
|
+
if (this.elementList.length > this.listMaxSize) {
|
|
931
|
+
this.elementList.shift();
|
|
932
|
+
this.listCursor -= 1;
|
|
1465
933
|
}
|
|
1466
|
-
]
|
|
1467
|
-
};
|
|
1468
|
-
const fillConfig = (config = [], labelWidth = "80px") => [
|
|
1469
|
-
{
|
|
1470
|
-
type: "tab",
|
|
1471
|
-
labelWidth,
|
|
1472
|
-
items: [
|
|
1473
|
-
{
|
|
1474
|
-
title: "属性",
|
|
1475
|
-
items: [
|
|
1476
|
-
// 组件类型,必须要有
|
|
1477
|
-
{
|
|
1478
|
-
text: "type",
|
|
1479
|
-
name: "type",
|
|
1480
|
-
type: "hidden"
|
|
1481
|
-
},
|
|
1482
|
-
// 组件id,必须要有
|
|
1483
|
-
{
|
|
1484
|
-
name: "id",
|
|
1485
|
-
type: "display",
|
|
1486
|
-
text: "id"
|
|
1487
|
-
},
|
|
1488
|
-
{
|
|
1489
|
-
name: "name",
|
|
1490
|
-
text: "组件名称"
|
|
1491
|
-
},
|
|
1492
|
-
...config
|
|
1493
|
-
]
|
|
1494
|
-
},
|
|
1495
|
-
{ ...styleTabConfig },
|
|
1496
|
-
{ ...eventTabConfig },
|
|
1497
|
-
{ ...advancedTabConfig },
|
|
1498
|
-
{ ...displayTabConfig }
|
|
1499
|
-
]
|
|
1500
934
|
}
|
|
1501
|
-
|
|
935
|
+
canUndo() {
|
|
936
|
+
return this.listCursor > 1;
|
|
937
|
+
}
|
|
938
|
+
// 返回undo后的当前元素
|
|
939
|
+
undo() {
|
|
940
|
+
if (!this.canUndo()) {
|
|
941
|
+
return null;
|
|
942
|
+
}
|
|
943
|
+
this.listCursor -= 1;
|
|
944
|
+
return this.getCurrentElement();
|
|
945
|
+
}
|
|
946
|
+
canRedo() {
|
|
947
|
+
return this.elementList.length > this.listCursor;
|
|
948
|
+
}
|
|
949
|
+
// 返回redo后的当前元素
|
|
950
|
+
redo() {
|
|
951
|
+
if (!this.canRedo()) {
|
|
952
|
+
return null;
|
|
953
|
+
}
|
|
954
|
+
this.listCursor += 1;
|
|
955
|
+
return this.getCurrentElement();
|
|
956
|
+
}
|
|
957
|
+
getCurrentElement() {
|
|
958
|
+
if (this.listCursor < 1) {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
return lodashEs.cloneDeep(this.elementList[this.listCursor - 1]);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
1502
964
|
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
965
|
+
class History extends BaseService {
|
|
966
|
+
state = vue.reactive({
|
|
967
|
+
pageSteps: {},
|
|
968
|
+
pageId: void 0,
|
|
969
|
+
canRedo: false,
|
|
970
|
+
canUndo: false
|
|
971
|
+
});
|
|
972
|
+
constructor() {
|
|
973
|
+
super([]);
|
|
974
|
+
this.on("change", this.setCanUndoRedo);
|
|
1506
975
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
976
|
+
reset() {
|
|
977
|
+
this.state.pageSteps = {};
|
|
978
|
+
this.resetPage();
|
|
979
|
+
}
|
|
980
|
+
resetPage() {
|
|
981
|
+
this.state.pageId = void 0;
|
|
982
|
+
this.state.canRedo = false;
|
|
983
|
+
this.state.canUndo = false;
|
|
984
|
+
}
|
|
985
|
+
changePage(page) {
|
|
986
|
+
if (!page)
|
|
987
|
+
return;
|
|
988
|
+
this.state.pageId = page.id;
|
|
989
|
+
if (!this.state.pageSteps[this.state.pageId]) {
|
|
990
|
+
const undoRedo = new UndoRedo();
|
|
991
|
+
undoRedo.pushElement({
|
|
992
|
+
data: page,
|
|
993
|
+
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
994
|
+
nodeId: page.id
|
|
995
|
+
});
|
|
996
|
+
this.state.pageSteps[this.state.pageId] = undoRedo;
|
|
997
|
+
}
|
|
998
|
+
this.setCanUndoRedo();
|
|
999
|
+
this.emit("page-change", this.state.pageSteps[this.state.pageId]);
|
|
1000
|
+
}
|
|
1001
|
+
resetState() {
|
|
1002
|
+
this.state.pageId = void 0;
|
|
1003
|
+
this.state.pageSteps = {};
|
|
1004
|
+
this.state.canRedo = false;
|
|
1005
|
+
this.state.canUndo = false;
|
|
1006
|
+
}
|
|
1007
|
+
push(state) {
|
|
1008
|
+
const undoRedo = this.getUndoRedo();
|
|
1009
|
+
if (!undoRedo)
|
|
1010
|
+
return null;
|
|
1011
|
+
undoRedo.pushElement(state);
|
|
1012
|
+
this.emit("change", state);
|
|
1013
|
+
return state;
|
|
1511
1014
|
}
|
|
1015
|
+
undo() {
|
|
1016
|
+
const undoRedo = this.getUndoRedo();
|
|
1017
|
+
if (!undoRedo)
|
|
1018
|
+
return null;
|
|
1019
|
+
const state = undoRedo.undo();
|
|
1020
|
+
this.emit("change", state);
|
|
1021
|
+
return state;
|
|
1022
|
+
}
|
|
1023
|
+
redo() {
|
|
1024
|
+
const undoRedo = this.getUndoRedo();
|
|
1025
|
+
if (!undoRedo)
|
|
1026
|
+
return null;
|
|
1027
|
+
const state = undoRedo.redo();
|
|
1028
|
+
this.emit("change", state);
|
|
1029
|
+
return state;
|
|
1030
|
+
}
|
|
1031
|
+
destroy() {
|
|
1032
|
+
this.resetState();
|
|
1033
|
+
this.removeAllListeners();
|
|
1034
|
+
this.removeAllPlugins();
|
|
1035
|
+
}
|
|
1036
|
+
getUndoRedo() {
|
|
1037
|
+
if (!this.state.pageId)
|
|
1038
|
+
return null;
|
|
1039
|
+
return this.state.pageSteps[this.state.pageId];
|
|
1040
|
+
}
|
|
1041
|
+
setCanUndoRedo() {
|
|
1042
|
+
const undoRedo = this.getUndoRedo();
|
|
1043
|
+
this.state.canRedo = undoRedo?.canRedo() || false;
|
|
1044
|
+
this.state.canUndo = undoRedo?.canUndo() || false;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
const historyService = new History();
|
|
1048
|
+
|
|
1049
|
+
var Protocol = /* @__PURE__ */ ((Protocol2) => {
|
|
1050
|
+
Protocol2["OBJECT"] = "object";
|
|
1051
|
+
Protocol2["JSON"] = "json";
|
|
1052
|
+
Protocol2["STRING"] = "string";
|
|
1053
|
+
Protocol2["NUMBER"] = "number";
|
|
1054
|
+
Protocol2["BOOLEAN"] = "boolean";
|
|
1055
|
+
return Protocol2;
|
|
1056
|
+
})(Protocol || {});
|
|
1057
|
+
const canUsePluginMethods$5 = {
|
|
1058
|
+
async: [],
|
|
1059
|
+
sync: ["getStorage", "getNamespace", "clear", "getItem", "removeItem", "setItem"]
|
|
1512
1060
|
};
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1061
|
+
class WebStorage extends BaseService {
|
|
1062
|
+
storage = globalThis.localStorage;
|
|
1063
|
+
namespace = "tmagic";
|
|
1064
|
+
constructor() {
|
|
1065
|
+
super(canUsePluginMethods$5.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* 获取数据存储对象,可以通过
|
|
1069
|
+
* const storageService = new StorageService();
|
|
1070
|
+
* storageService.usePlugin({
|
|
1071
|
+
* // 替换存储对象为 sessionStorage
|
|
1072
|
+
* async afterGetStorage(): Promise<Storage> {
|
|
1073
|
+
* return window.sessionStorage;
|
|
1074
|
+
* },
|
|
1075
|
+
* });
|
|
1076
|
+
*/
|
|
1077
|
+
getStorage() {
|
|
1078
|
+
return this.storage;
|
|
1079
|
+
}
|
|
1080
|
+
getNamespace() {
|
|
1081
|
+
return this.namespace;
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* 清理,支持storageService.usePlugin
|
|
1085
|
+
*/
|
|
1086
|
+
clear() {
|
|
1087
|
+
const storage = this.getStorage();
|
|
1088
|
+
storage.clear();
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* 获取存储项,支持storageService.usePlugin
|
|
1092
|
+
*/
|
|
1093
|
+
getItem(key, options = {}) {
|
|
1094
|
+
const storage = this.getStorage();
|
|
1095
|
+
const namespace = this.getNamespace();
|
|
1096
|
+
const { protocol = options.protocol, item } = this.getValueAndProtocol(
|
|
1097
|
+
storage.getItem(`${options.namespace || namespace}:${key}`)
|
|
1098
|
+
);
|
|
1099
|
+
if (item === null)
|
|
1100
|
+
return null;
|
|
1101
|
+
switch (protocol) {
|
|
1102
|
+
case "object" /* OBJECT */:
|
|
1103
|
+
return getConfig("parseDSL")(`(${item})`);
|
|
1104
|
+
case "json" /* JSON */:
|
|
1105
|
+
return JSON.parse(item);
|
|
1106
|
+
case "number" /* NUMBER */:
|
|
1107
|
+
return Number(item);
|
|
1108
|
+
case "boolean" /* BOOLEAN */:
|
|
1109
|
+
return Boolean(item);
|
|
1110
|
+
default:
|
|
1111
|
+
return item;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* 获取指定索引位置的key
|
|
1116
|
+
*/
|
|
1117
|
+
key(index) {
|
|
1118
|
+
const storage = this.getStorage();
|
|
1119
|
+
return storage.key(index);
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* 移除存储项,支持storageService.usePlugin
|
|
1123
|
+
*/
|
|
1124
|
+
removeItem(key, options = {}) {
|
|
1125
|
+
const storage = this.getStorage();
|
|
1126
|
+
const namespace = this.getNamespace();
|
|
1127
|
+
storage.removeItem(`${options.namespace || namespace}:${key}`);
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* 设置存储项,支持storageService.usePlugin
|
|
1131
|
+
*/
|
|
1132
|
+
setItem(key, value, options = {}) {
|
|
1133
|
+
const storage = this.getStorage();
|
|
1134
|
+
const namespace = this.getNamespace();
|
|
1135
|
+
let item = value;
|
|
1136
|
+
const protocol = options.protocol ? `${options.protocol}:` : "";
|
|
1137
|
+
if (typeof value === "string" /* STRING */ || typeof value === "number" /* NUMBER */) {
|
|
1138
|
+
item = `${protocol}${value}`;
|
|
1139
|
+
} else {
|
|
1140
|
+
item = `${protocol}${serialize(value)}`;
|
|
1141
|
+
}
|
|
1142
|
+
storage.setItem(`${options.namespace || namespace}:${key}`, item);
|
|
1516
1143
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
console.debug("magic editor: ", ...args);
|
|
1144
|
+
destroy() {
|
|
1145
|
+
this.removeAllListeners();
|
|
1146
|
+
this.removeAllPlugins();
|
|
1521
1147
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
if (process.env.NODE_ENV === "development") {
|
|
1525
|
-
console.error("magic editor: ", ...args);
|
|
1148
|
+
usePlugin(options) {
|
|
1149
|
+
super.usePlugin(options);
|
|
1526
1150
|
}
|
|
1527
|
-
|
|
1151
|
+
getValueAndProtocol(value) {
|
|
1152
|
+
let protocol = "";
|
|
1153
|
+
if (value === null) {
|
|
1154
|
+
return {
|
|
1155
|
+
item: value,
|
|
1156
|
+
protocol
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
const item = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
|
|
1160
|
+
protocol = $1;
|
|
1161
|
+
return $3;
|
|
1162
|
+
});
|
|
1163
|
+
return {
|
|
1164
|
+
protocol,
|
|
1165
|
+
item
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
const storageService = new WebStorage();
|
|
1528
1170
|
|
|
1529
1171
|
var ColumnLayout = /* @__PURE__ */ ((ColumnLayout2) => {
|
|
1530
1172
|
ColumnLayout2["LEFT"] = "left";
|
|
@@ -1593,6 +1235,8 @@
|
|
|
1593
1235
|
const UI_SELECT_MODE_EVENT_NAME = "ui-select";
|
|
1594
1236
|
|
|
1595
1237
|
const COPY_STORAGE_KEY = "$MagicEditorCopyData";
|
|
1238
|
+
const COPY_CODE_STORAGE_KEY = "$MagicEditorCopyCode";
|
|
1239
|
+
const COPY_DS_STORAGE_KEY = "$MagicEditorCopyDataSource";
|
|
1596
1240
|
const getPageList = (root) => {
|
|
1597
1241
|
if (!root)
|
|
1598
1242
|
return [];
|
|
@@ -1639,11 +1283,13 @@
|
|
|
1639
1283
|
height = 0;
|
|
1640
1284
|
}
|
|
1641
1285
|
const { height: parentHeight } = parentNode.style;
|
|
1286
|
+
const { scrollTop = 0, wrapperHeight } = stage.mask;
|
|
1287
|
+
const wrapperHeightDeal = utils.calcValueByFontsize(stage.renderer.getDocument(), wrapperHeight);
|
|
1288
|
+
const scrollTopDeal = utils.calcValueByFontsize(stage.renderer.getDocument(), scrollTop);
|
|
1642
1289
|
if (utils.isPage(parentNode)) {
|
|
1643
|
-
|
|
1644
|
-
return (wrapperHeight - height) / 2 + scrollTop;
|
|
1290
|
+
return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
|
|
1645
1291
|
}
|
|
1646
|
-
return (parentHeight - height) / 2;
|
|
1292
|
+
return (Math.min(parentHeight, wrapperHeightDeal) - height) / 2;
|
|
1647
1293
|
};
|
|
1648
1294
|
const getInitPositionStyle = (style = {}, layout) => {
|
|
1649
1295
|
if (layout === Layout.ABSOLUTE) {
|
|
@@ -1744,8 +1390,12 @@
|
|
|
1744
1390
|
const el = doc.getElementById(`${config.id}`);
|
|
1745
1391
|
const parentEl = doc.getElementById(`${parent.id}`);
|
|
1746
1392
|
const left = Number(config.style?.left) || 0;
|
|
1747
|
-
if (el && parentEl
|
|
1748
|
-
|
|
1393
|
+
if (el && parentEl) {
|
|
1394
|
+
const calcParentOffsetWidth = utils.calcValueByFontsize(doc, parentEl.offsetWidth);
|
|
1395
|
+
const calcElOffsetWidth = utils.calcValueByFontsize(doc, el.offsetWidth);
|
|
1396
|
+
if (calcElOffsetWidth + left > calcParentOffsetWidth) {
|
|
1397
|
+
return calcParentOffsetWidth - calcElOffsetWidth;
|
|
1398
|
+
}
|
|
1749
1399
|
}
|
|
1750
1400
|
return config.style.left;
|
|
1751
1401
|
};
|
|
@@ -1773,1421 +1423,1855 @@
|
|
|
1773
1423
|
}
|
|
1774
1424
|
};
|
|
1775
1425
|
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1426
|
+
const beforePaste = (position, config) => {
|
|
1427
|
+
if (!config[0]?.style)
|
|
1428
|
+
return config;
|
|
1429
|
+
const curNode = editorService.get("node");
|
|
1430
|
+
const { left: referenceLeft, top: referenceTop } = config[0].style;
|
|
1431
|
+
const pasteConfigs = config.map((configItem) => {
|
|
1432
|
+
const { offsetX = 0, offsetY = 0, ...positionClone } = position;
|
|
1433
|
+
let pastePosition = positionClone;
|
|
1434
|
+
if (!lodashEs.isEmpty(pastePosition) && curNode?.items) {
|
|
1435
|
+
pastePosition = getPositionInContainer(pastePosition, curNode.id);
|
|
1436
|
+
}
|
|
1437
|
+
if (pastePosition.left && configItem.style?.left) {
|
|
1438
|
+
pastePosition.left = configItem.style.left - referenceLeft + pastePosition.left;
|
|
1439
|
+
}
|
|
1440
|
+
if (pastePosition.top && configItem.style?.top) {
|
|
1441
|
+
pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
|
|
1442
|
+
}
|
|
1443
|
+
const pasteConfig = propsService.setNewItemId(configItem, false);
|
|
1444
|
+
if (pasteConfig.style) {
|
|
1445
|
+
const { left, top } = pasteConfig.style;
|
|
1446
|
+
if (typeof left === "number" || !!left && !isNaN(Number(left))) {
|
|
1447
|
+
pasteConfig.style.left = Number(left) + offsetX;
|
|
1448
|
+
}
|
|
1449
|
+
if (typeof top === "number" || !!top && !isNaN(Number(top))) {
|
|
1450
|
+
pasteConfig.style.top = Number(top) + offsetY;
|
|
1451
|
+
}
|
|
1452
|
+
pasteConfig.style = {
|
|
1453
|
+
...pasteConfig.style,
|
|
1454
|
+
...pastePosition
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
const root = editorService.get("root");
|
|
1458
|
+
if ((utils.isPage(pasteConfig) || utils.isPageFragment(pasteConfig)) && root) {
|
|
1459
|
+
pasteConfig.name = generatePageNameByApp(root, utils.isPage(pasteConfig) ? schema.NodeType.PAGE : schema.NodeType.PAGE_FRAGMENT);
|
|
1460
|
+
}
|
|
1461
|
+
return pasteConfig;
|
|
1462
|
+
});
|
|
1463
|
+
return pasteConfigs;
|
|
1464
|
+
};
|
|
1465
|
+
const getPositionInContainer = (position = {}, id) => {
|
|
1466
|
+
let { left = 0, top = 0 } = position;
|
|
1467
|
+
const parentEl = editorService.get("stage")?.renderer?.contentWindow?.document.getElementById(`${id}`);
|
|
1468
|
+
const parentElRect = parentEl?.getBoundingClientRect();
|
|
1469
|
+
left = left - (parentElRect?.left || 0);
|
|
1470
|
+
top = top - (parentElRect?.top || 0);
|
|
1471
|
+
return {
|
|
1472
|
+
left,
|
|
1473
|
+
top
|
|
1474
|
+
};
|
|
1475
|
+
};
|
|
1476
|
+
const getAddParent = (node) => {
|
|
1477
|
+
const curNode = editorService.get("node");
|
|
1478
|
+
let parentNode;
|
|
1479
|
+
if (utils.isPage(node)) {
|
|
1480
|
+
parentNode = editorService.get("root");
|
|
1481
|
+
} else if (curNode?.items) {
|
|
1482
|
+
parentNode = curNode;
|
|
1483
|
+
} else if (curNode?.id) {
|
|
1484
|
+
parentNode = editorService.getParentById(curNode.id, false);
|
|
1814
1485
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1486
|
+
return parentNode;
|
|
1487
|
+
};
|
|
1488
|
+
const getDefaultConfig = async (addNode, parentNode) => {
|
|
1489
|
+
const { type, inputEvent, ...config } = addNode;
|
|
1490
|
+
const layout = await editorService.getLayout(vue.toRaw(parentNode), addNode);
|
|
1491
|
+
const newNode = { ...vue.toRaw(await propsService.getPropsValue(type, config)) };
|
|
1492
|
+
newNode.style = getInitPositionStyle(newNode.style, layout);
|
|
1493
|
+
return newNode;
|
|
1494
|
+
};
|
|
1817
1495
|
|
|
1818
|
-
const canUsePluginMethods$
|
|
1496
|
+
const canUsePluginMethods$4 = {
|
|
1819
1497
|
async: [
|
|
1820
|
-
"
|
|
1821
|
-
"
|
|
1822
|
-
"
|
|
1823
|
-
"
|
|
1824
|
-
"
|
|
1825
|
-
"
|
|
1498
|
+
"getLayout",
|
|
1499
|
+
"highlight",
|
|
1500
|
+
"select",
|
|
1501
|
+
"multiSelect",
|
|
1502
|
+
"doAdd",
|
|
1503
|
+
"add",
|
|
1504
|
+
"doRemove",
|
|
1505
|
+
"remove",
|
|
1506
|
+
"doUpdate",
|
|
1507
|
+
"update",
|
|
1508
|
+
"sort",
|
|
1509
|
+
"copy",
|
|
1510
|
+
"paste",
|
|
1511
|
+
"doPaste",
|
|
1512
|
+
"doAlignCenter",
|
|
1513
|
+
"alignCenter",
|
|
1514
|
+
"moveLayer",
|
|
1515
|
+
"moveToContainer",
|
|
1516
|
+
"dragTo",
|
|
1517
|
+
"undo",
|
|
1518
|
+
"redo",
|
|
1519
|
+
"move"
|
|
1826
1520
|
],
|
|
1827
|
-
sync: [
|
|
1521
|
+
sync: []
|
|
1828
1522
|
};
|
|
1829
|
-
class
|
|
1523
|
+
class Editor extends BaseService {
|
|
1830
1524
|
state = vue.reactive({
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1525
|
+
root: null,
|
|
1526
|
+
page: null,
|
|
1527
|
+
parent: null,
|
|
1528
|
+
node: null,
|
|
1529
|
+
nodes: [],
|
|
1530
|
+
stage: null,
|
|
1531
|
+
stageLoading: true,
|
|
1532
|
+
highlightNode: null,
|
|
1533
|
+
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
1534
|
+
pageLength: 0,
|
|
1535
|
+
pageFragmentLength: 0,
|
|
1536
|
+
disabledMultiSelect: false
|
|
1834
1537
|
});
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
setPropsConfigs(configs) {
|
|
1842
|
-
Object.keys(configs).forEach((type) => {
|
|
1843
|
-
this.setPropsConfig(utils.toLine(type), configs[type]);
|
|
1844
|
-
});
|
|
1845
|
-
this.emit("props-configs-change");
|
|
1846
|
-
}
|
|
1847
|
-
async fillConfig(config, labelWidth) {
|
|
1848
|
-
return fillConfig(config, typeof labelWidth !== "function" ? labelWidth : "80px");
|
|
1849
|
-
}
|
|
1850
|
-
async setPropsConfig(type, config) {
|
|
1851
|
-
this.state.propsConfigMap[utils.toLine(type)] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
1852
|
-
}
|
|
1853
|
-
/**
|
|
1854
|
-
* 获取指点类型的组件属性表单配置
|
|
1855
|
-
* @param type 组件类型
|
|
1856
|
-
* @returns 组件属性表单配置
|
|
1857
|
-
*/
|
|
1858
|
-
async getPropsConfig(type) {
|
|
1859
|
-
if (type === "area") {
|
|
1860
|
-
return await this.getPropsConfig("button");
|
|
1861
|
-
}
|
|
1862
|
-
return lodashEs.cloneDeep(this.state.propsConfigMap[utils.toLine(type)] || await this.fillConfig([]));
|
|
1863
|
-
}
|
|
1864
|
-
setPropsValues(values) {
|
|
1865
|
-
Object.keys(values).forEach((type) => {
|
|
1866
|
-
this.setPropsValue(utils.toLine(type), values[type]);
|
|
1867
|
-
});
|
|
1868
|
-
}
|
|
1869
|
-
/**
|
|
1870
|
-
* 为指点类型组件设置组件初始值
|
|
1871
|
-
* @param type 组件类型
|
|
1872
|
-
* @param value 组件初始值
|
|
1873
|
-
*/
|
|
1874
|
-
async setPropsValue(type, value) {
|
|
1875
|
-
this.state.propsValueMap[utils.toLine(type)] = value;
|
|
1876
|
-
}
|
|
1877
|
-
/**
|
|
1878
|
-
* 获取指定类型的组件初始值
|
|
1879
|
-
* @param type 组件类型
|
|
1880
|
-
* @returns 组件初始值
|
|
1881
|
-
*/
|
|
1882
|
-
async getPropsValue(componentType, { inputEvent, ...defaultValue } = {}) {
|
|
1883
|
-
const type = utils.toLine(componentType);
|
|
1884
|
-
if (type === "area") {
|
|
1885
|
-
const value = await this.getPropsValue("button");
|
|
1886
|
-
value.className = "action-area";
|
|
1887
|
-
value.text = "";
|
|
1888
|
-
if (value.style) {
|
|
1889
|
-
value.style.backgroundColor = "rgba(255, 255, 255, 0)";
|
|
1890
|
-
}
|
|
1891
|
-
return value;
|
|
1892
|
-
}
|
|
1893
|
-
const id = this.createId(type);
|
|
1894
|
-
const defaultPropsValue = this.getDefaultPropsValue(type);
|
|
1895
|
-
const data = this.setNewItemId(
|
|
1896
|
-
lodashEs.cloneDeep({
|
|
1897
|
-
type,
|
|
1898
|
-
...defaultValue
|
|
1899
|
-
})
|
|
1538
|
+
isHistoryStateChange = false;
|
|
1539
|
+
constructor() {
|
|
1540
|
+
super(
|
|
1541
|
+
canUsePluginMethods$4.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
1542
|
+
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
|
1543
|
+
["select", "update", "moveLayer"]
|
|
1900
1544
|
);
|
|
1901
|
-
return {
|
|
1902
|
-
id,
|
|
1903
|
-
...defaultPropsValue,
|
|
1904
|
-
...lodashEs.mergeWith({}, lodashEs.cloneDeep(this.state.propsValueMap[type] || {}), data)
|
|
1905
|
-
};
|
|
1906
|
-
}
|
|
1907
|
-
createId(type) {
|
|
1908
|
-
return `${type}_${utils.guid()}`;
|
|
1909
1545
|
}
|
|
1910
1546
|
/**
|
|
1911
|
-
*
|
|
1912
|
-
*
|
|
1913
|
-
* @param
|
|
1914
|
-
* @param {Boolean} force 是否强制设置新的ID
|
|
1547
|
+
* 设置当前指点节点配置
|
|
1548
|
+
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength
|
|
1549
|
+
* @param value MNode
|
|
1915
1550
|
*/
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
this.
|
|
1921
|
-
config.id = newId;
|
|
1551
|
+
set(name, value) {
|
|
1552
|
+
const preValue = this.state[name];
|
|
1553
|
+
this.state[name] = value;
|
|
1554
|
+
if (name === "nodes" && Array.isArray(value)) {
|
|
1555
|
+
this.set("node", value[0]);
|
|
1922
1556
|
}
|
|
1923
|
-
if (
|
|
1924
|
-
|
|
1925
|
-
|
|
1557
|
+
if (name === "root") {
|
|
1558
|
+
if (Array.isArray(value)) {
|
|
1559
|
+
throw new Error("root 不能为数组");
|
|
1560
|
+
}
|
|
1561
|
+
if (value && lodashEs.isObject(value)) {
|
|
1562
|
+
const app = value;
|
|
1563
|
+
this.state.pageLength = getPageList(app).length || 0;
|
|
1564
|
+
this.state.pageFragmentLength = getPageFragmentList(app).length || 0;
|
|
1565
|
+
this.state.stageLoading = this.state.pageLength !== 0;
|
|
1566
|
+
} else {
|
|
1567
|
+
this.state.pageLength = 0;
|
|
1568
|
+
this.state.pageFragmentLength = 0;
|
|
1569
|
+
this.state.stageLoading = false;
|
|
1926
1570
|
}
|
|
1571
|
+
this.emit("root-change", value, preValue);
|
|
1927
1572
|
}
|
|
1928
|
-
return config;
|
|
1929
1573
|
}
|
|
1930
1574
|
/**
|
|
1931
|
-
*
|
|
1932
|
-
* @param
|
|
1933
|
-
* @returns
|
|
1575
|
+
* 获取当前指点节点配置
|
|
1576
|
+
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength'
|
|
1577
|
+
* @returns MNode
|
|
1934
1578
|
*/
|
|
1935
|
-
|
|
1936
|
-
return [
|
|
1937
|
-
type,
|
|
1938
|
-
layout: "absolute",
|
|
1939
|
-
style: {},
|
|
1940
|
-
name: type,
|
|
1941
|
-
items: []
|
|
1942
|
-
} : {
|
|
1943
|
-
type,
|
|
1944
|
-
style: {},
|
|
1945
|
-
name: type
|
|
1946
|
-
};
|
|
1947
|
-
}
|
|
1948
|
-
resetState() {
|
|
1949
|
-
this.state.propsConfigMap = {};
|
|
1950
|
-
this.state.propsValueMap = {};
|
|
1579
|
+
get(name) {
|
|
1580
|
+
return this.state[name];
|
|
1951
1581
|
}
|
|
1952
1582
|
/**
|
|
1953
|
-
*
|
|
1954
|
-
* @param
|
|
1955
|
-
* @param
|
|
1583
|
+
* 根据id获取组件、组件的父组件以及组件所属的页面节点
|
|
1584
|
+
* @param {number | string} id 组件id
|
|
1585
|
+
* @param {boolean} raw 是否使用toRaw
|
|
1586
|
+
* @returns {EditorNodeInfo}
|
|
1956
1587
|
*/
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
if (
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1588
|
+
getNodeInfo(id, raw = true) {
|
|
1589
|
+
let root = this.get("root");
|
|
1590
|
+
if (raw) {
|
|
1591
|
+
root = vue.toRaw(root);
|
|
1592
|
+
}
|
|
1593
|
+
const info = {
|
|
1594
|
+
node: null,
|
|
1595
|
+
parent: null,
|
|
1596
|
+
page: null
|
|
1597
|
+
};
|
|
1598
|
+
if (!root)
|
|
1599
|
+
return info;
|
|
1600
|
+
if (id === root.id) {
|
|
1601
|
+
info.node = root;
|
|
1602
|
+
return info;
|
|
1603
|
+
}
|
|
1604
|
+
const path = utils.getNodePath(id, root.items);
|
|
1605
|
+
if (!path.length)
|
|
1606
|
+
return info;
|
|
1607
|
+
path.unshift(root);
|
|
1608
|
+
info.node = path[path.length - 1];
|
|
1609
|
+
info.parent = path[path.length - 2];
|
|
1610
|
+
path.forEach((item) => {
|
|
1611
|
+
if (utils.isPage(item) || utils.isPageFragment(item)) {
|
|
1612
|
+
info.page = item;
|
|
1968
1613
|
return;
|
|
1969
|
-
|
|
1970
|
-
const relateOriginId = utils.getValueByKeyPath(fullKey, config);
|
|
1971
|
-
const relateTargetId = relateIdMap[relateOriginId];
|
|
1972
|
-
if (!relateTargetId)
|
|
1973
|
-
return;
|
|
1974
|
-
utils.setValueByKeyPath(fullKey, relateTargetId, targetConfig);
|
|
1975
|
-
});
|
|
1614
|
+
}
|
|
1976
1615
|
});
|
|
1616
|
+
return info;
|
|
1977
1617
|
}
|
|
1978
1618
|
/**
|
|
1979
|
-
*
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
this.
|
|
1986
|
-
|
|
1987
|
-
this.removeAllPlugins();
|
|
1988
|
-
}
|
|
1989
|
-
usePlugin(options) {
|
|
1990
|
-
super.usePlugin(options);
|
|
1991
|
-
}
|
|
1992
|
-
/**
|
|
1993
|
-
* 获取setNewItemId前后映射关系
|
|
1994
|
-
* @param oldId 原组件ID
|
|
1995
|
-
* @returns 新旧ID映射
|
|
1996
|
-
*/
|
|
1997
|
-
getRelateIdMap() {
|
|
1998
|
-
return this.state.relateIdMap;
|
|
1999
|
-
}
|
|
2000
|
-
/**
|
|
2001
|
-
* 记录setNewItemId前后映射关系
|
|
2002
|
-
* @param oldId 原组件ID
|
|
2003
|
-
* @param newId 分配的新ID
|
|
2004
|
-
*/
|
|
2005
|
-
setRelateId(oldId, newId) {
|
|
2006
|
-
this.state.relateIdMap[oldId] = newId;
|
|
2007
|
-
}
|
|
2008
|
-
}
|
|
2009
|
-
const propsService = new Props();
|
|
2010
|
-
|
|
2011
|
-
class UndoRedo {
|
|
2012
|
-
elementList;
|
|
2013
|
-
listCursor;
|
|
2014
|
-
listMaxSize;
|
|
2015
|
-
constructor(listMaxSize = 20) {
|
|
2016
|
-
const minListMaxSize = 2;
|
|
2017
|
-
this.elementList = [];
|
|
2018
|
-
this.listCursor = 0;
|
|
2019
|
-
this.listMaxSize = listMaxSize > minListMaxSize ? listMaxSize : minListMaxSize;
|
|
2020
|
-
}
|
|
2021
|
-
pushElement(element) {
|
|
2022
|
-
this.elementList.splice(this.listCursor, this.elementList.length - this.listCursor, lodashEs.cloneDeep(element));
|
|
2023
|
-
this.listCursor += 1;
|
|
2024
|
-
if (this.elementList.length > this.listMaxSize) {
|
|
2025
|
-
this.elementList.shift();
|
|
2026
|
-
this.listCursor -= 1;
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
canUndo() {
|
|
2030
|
-
return this.listCursor > 1;
|
|
2031
|
-
}
|
|
2032
|
-
// 返回undo后的当前元素
|
|
2033
|
-
undo() {
|
|
2034
|
-
if (!this.canUndo()) {
|
|
2035
|
-
return null;
|
|
2036
|
-
}
|
|
2037
|
-
this.listCursor -= 1;
|
|
2038
|
-
return this.getCurrentElement();
|
|
2039
|
-
}
|
|
2040
|
-
canRedo() {
|
|
2041
|
-
return this.elementList.length > this.listCursor;
|
|
2042
|
-
}
|
|
2043
|
-
// 返回redo后的当前元素
|
|
2044
|
-
redo() {
|
|
2045
|
-
if (!this.canRedo()) {
|
|
2046
|
-
return null;
|
|
2047
|
-
}
|
|
2048
|
-
this.listCursor += 1;
|
|
2049
|
-
return this.getCurrentElement();
|
|
2050
|
-
}
|
|
2051
|
-
getCurrentElement() {
|
|
2052
|
-
if (this.listCursor < 1) {
|
|
2053
|
-
return null;
|
|
2054
|
-
}
|
|
2055
|
-
return lodashEs.cloneDeep(this.elementList[this.listCursor - 1]);
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
|
|
2059
|
-
class History extends BaseService {
|
|
2060
|
-
state = vue.reactive({
|
|
2061
|
-
pageSteps: {},
|
|
2062
|
-
pageId: void 0,
|
|
2063
|
-
canRedo: false,
|
|
2064
|
-
canUndo: false
|
|
2065
|
-
});
|
|
2066
|
-
constructor() {
|
|
2067
|
-
super([]);
|
|
2068
|
-
this.on("change", this.setCanUndoRedo);
|
|
2069
|
-
}
|
|
2070
|
-
reset() {
|
|
2071
|
-
this.state.pageSteps = {};
|
|
2072
|
-
this.resetPage();
|
|
2073
|
-
}
|
|
2074
|
-
resetPage() {
|
|
2075
|
-
this.state.pageId = void 0;
|
|
2076
|
-
this.state.canRedo = false;
|
|
2077
|
-
this.state.canUndo = false;
|
|
2078
|
-
}
|
|
2079
|
-
changePage(page) {
|
|
2080
|
-
if (!page)
|
|
2081
|
-
return;
|
|
2082
|
-
this.state.pageId = page.id;
|
|
2083
|
-
if (!this.state.pageSteps[this.state.pageId]) {
|
|
2084
|
-
const undoRedo = new UndoRedo();
|
|
2085
|
-
undoRedo.pushElement({
|
|
2086
|
-
data: page,
|
|
2087
|
-
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
2088
|
-
nodeId: page.id
|
|
2089
|
-
});
|
|
2090
|
-
this.state.pageSteps[this.state.pageId] = undoRedo;
|
|
2091
|
-
}
|
|
2092
|
-
this.setCanUndoRedo();
|
|
2093
|
-
this.emit("page-change", this.state.pageSteps[this.state.pageId]);
|
|
2094
|
-
}
|
|
2095
|
-
resetState() {
|
|
2096
|
-
this.state.pageId = void 0;
|
|
2097
|
-
this.state.pageSteps = {};
|
|
2098
|
-
this.state.canRedo = false;
|
|
2099
|
-
this.state.canUndo = false;
|
|
2100
|
-
}
|
|
2101
|
-
push(state) {
|
|
2102
|
-
const undoRedo = this.getUndoRedo();
|
|
2103
|
-
if (!undoRedo)
|
|
2104
|
-
return null;
|
|
2105
|
-
undoRedo.pushElement(state);
|
|
2106
|
-
this.emit("change", state);
|
|
2107
|
-
return state;
|
|
1619
|
+
* 根据ID获取指点节点配置
|
|
1620
|
+
* @param id 组件ID
|
|
1621
|
+
* @param {boolean} raw 是否使用toRaw
|
|
1622
|
+
* @returns 组件节点配置
|
|
1623
|
+
*/
|
|
1624
|
+
getNodeById(id, raw = true) {
|
|
1625
|
+
const { node } = this.getNodeInfo(id, raw);
|
|
1626
|
+
return node;
|
|
2108
1627
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
1628
|
+
/**
|
|
1629
|
+
* 根据ID获取指点节点的父节点配置
|
|
1630
|
+
* @param id 组件ID
|
|
1631
|
+
* @param {boolean} raw 是否使用toRaw
|
|
1632
|
+
* @returns 指点组件的父节点配置
|
|
1633
|
+
*/
|
|
1634
|
+
getParentById(id, raw = true) {
|
|
1635
|
+
const { parent } = this.getNodeInfo(id, raw);
|
|
1636
|
+
return parent;
|
|
2116
1637
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
1638
|
+
/**
|
|
1639
|
+
* 只有容器拥有布局
|
|
1640
|
+
*/
|
|
1641
|
+
async getLayout(parent, node) {
|
|
1642
|
+
if (node && typeof node !== "function" && isFixed(node))
|
|
1643
|
+
return Layout.FIXED;
|
|
1644
|
+
if (parent.layout) {
|
|
1645
|
+
return parent.layout;
|
|
1646
|
+
}
|
|
1647
|
+
if (!parent.style?.position) {
|
|
1648
|
+
return Layout.RELATIVE;
|
|
1649
|
+
}
|
|
1650
|
+
return Layout.ABSOLUTE;
|
|
2124
1651
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
1652
|
+
/**
|
|
1653
|
+
* 选中指定节点(将指定节点设置成当前选中状态)
|
|
1654
|
+
* @param config 指定节点配置或者ID
|
|
1655
|
+
* @returns 当前选中的节点配置
|
|
1656
|
+
*/
|
|
1657
|
+
async select(config) {
|
|
1658
|
+
const { node, page, parent } = this.selectedConfigExceptionHandler(config);
|
|
1659
|
+
this.set("nodes", node ? [node] : []);
|
|
1660
|
+
this.set("page", page);
|
|
1661
|
+
this.set("parent", parent);
|
|
1662
|
+
if (page) {
|
|
1663
|
+
historyService.changePage(vue.toRaw(page));
|
|
1664
|
+
} else {
|
|
1665
|
+
historyService.resetState();
|
|
1666
|
+
}
|
|
1667
|
+
if (node?.id) {
|
|
1668
|
+
this.get("stage")?.renderer.runtime?.getApp?.()?.page?.emit(
|
|
1669
|
+
"editor:select",
|
|
1670
|
+
{
|
|
1671
|
+
node,
|
|
1672
|
+
page,
|
|
1673
|
+
parent
|
|
1674
|
+
},
|
|
1675
|
+
utils.getNodePath(node.id, this.get("root")?.items)
|
|
1676
|
+
);
|
|
1677
|
+
}
|
|
1678
|
+
this.emit("select", node);
|
|
1679
|
+
return node;
|
|
2129
1680
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
1681
|
+
async selectNextNode() {
|
|
1682
|
+
const node = vue.toRaw(this.get("node"));
|
|
1683
|
+
if (!node || utils.isPage(node) || node.type === schema.NodeType.ROOT)
|
|
1684
|
+
return node;
|
|
1685
|
+
const parent = vue.toRaw(this.getParentById(node.id));
|
|
1686
|
+
if (!parent)
|
|
1687
|
+
return node;
|
|
1688
|
+
const index = getNodeIndex(node.id, parent);
|
|
1689
|
+
const nextNode = parent.items[index + 1] || parent.items[0];
|
|
1690
|
+
await this.select(nextNode);
|
|
1691
|
+
this.get("stage")?.select(nextNode.id);
|
|
1692
|
+
return nextNode;
|
|
2134
1693
|
}
|
|
2135
|
-
|
|
2136
|
-
const
|
|
2137
|
-
|
|
2138
|
-
|
|
1694
|
+
async selectNextPage() {
|
|
1695
|
+
const root = vue.toRaw(this.get("root"));
|
|
1696
|
+
const page = vue.toRaw(this.get("page"));
|
|
1697
|
+
if (!page)
|
|
1698
|
+
throw new Error("page不能为空");
|
|
1699
|
+
if (!root)
|
|
1700
|
+
throw new Error("root不能为空");
|
|
1701
|
+
const index = getNodeIndex(page.id, root);
|
|
1702
|
+
const nextPage = root.items[index + 1] || root.items[0];
|
|
1703
|
+
await this.select(nextPage);
|
|
1704
|
+
this.get("stage")?.select(nextPage.id);
|
|
1705
|
+
return nextPage;
|
|
2139
1706
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
const canUsePluginMethods$4 = {
|
|
2152
|
-
async: [],
|
|
2153
|
-
sync: ["getStorage", "getNamespace", "clear", "getItem", "removeItem", "setItem"]
|
|
2154
|
-
};
|
|
2155
|
-
class WebStorage extends BaseService {
|
|
2156
|
-
storage = globalThis.localStorage;
|
|
2157
|
-
namespace = "tmagic";
|
|
2158
|
-
constructor() {
|
|
2159
|
-
super(canUsePluginMethods$4.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
1707
|
+
/**
|
|
1708
|
+
* 高亮指定节点
|
|
1709
|
+
* @param config 指定节点配置或者ID
|
|
1710
|
+
* @returns 当前高亮的节点配置
|
|
1711
|
+
*/
|
|
1712
|
+
highlight(config) {
|
|
1713
|
+
const { node } = this.selectedConfigExceptionHandler(config);
|
|
1714
|
+
const currentHighlightNode = this.get("highlightNode");
|
|
1715
|
+
if (currentHighlightNode === node)
|
|
1716
|
+
return;
|
|
1717
|
+
this.set("highlightNode", node);
|
|
2160
1718
|
}
|
|
2161
1719
|
/**
|
|
2162
|
-
*
|
|
2163
|
-
*
|
|
2164
|
-
*
|
|
2165
|
-
* // 替换存储对象为 sessionStorage
|
|
2166
|
-
* async afterGetStorage(): Promise<Storage> {
|
|
2167
|
-
* return window.sessionStorage;
|
|
2168
|
-
* },
|
|
2169
|
-
* });
|
|
1720
|
+
* 多选
|
|
1721
|
+
* @param ids 指定节点ID
|
|
1722
|
+
* @returns 加入多选的节点配置
|
|
2170
1723
|
*/
|
|
2171
|
-
|
|
2172
|
-
|
|
1724
|
+
multiSelect(ids) {
|
|
1725
|
+
const nodes = [];
|
|
1726
|
+
const idsUnique = lodashEs.uniq(ids);
|
|
1727
|
+
idsUnique.forEach((id) => {
|
|
1728
|
+
const { node } = this.getNodeInfo(id);
|
|
1729
|
+
if (!node)
|
|
1730
|
+
return;
|
|
1731
|
+
nodes.push(node);
|
|
1732
|
+
});
|
|
1733
|
+
this.set("nodes", nodes);
|
|
2173
1734
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
1735
|
+
selectRoot() {
|
|
1736
|
+
const root = this.get("root");
|
|
1737
|
+
if (!root)
|
|
1738
|
+
return;
|
|
1739
|
+
this.set("nodes", [root]);
|
|
1740
|
+
this.set("parent", null);
|
|
1741
|
+
this.set("page", null);
|
|
1742
|
+
this.set("stage", null);
|
|
1743
|
+
this.set("highlightNode", null);
|
|
1744
|
+
}
|
|
1745
|
+
async doAdd(node, parent) {
|
|
1746
|
+
const root = this.get("root");
|
|
1747
|
+
if (!root)
|
|
1748
|
+
throw new Error("root为空");
|
|
1749
|
+
const curNode = this.get("node");
|
|
1750
|
+
const stage = this.get("stage");
|
|
1751
|
+
if (!curNode)
|
|
1752
|
+
throw new Error("当前选中节点为空");
|
|
1753
|
+
if ((parent.type === schema.NodeType.ROOT || curNode?.type === schema.NodeType.ROOT) && !(utils.isPage(node) || utils.isPageFragment(node))) {
|
|
1754
|
+
throw new Error("app下不能添加组件");
|
|
1755
|
+
}
|
|
1756
|
+
if (parent.id !== curNode.id && !(utils.isPage(node) || utils.isPageFragment(node))) {
|
|
1757
|
+
const index = parent.items.indexOf(curNode);
|
|
1758
|
+
parent.items?.splice(index + 1, 0, node);
|
|
1759
|
+
} else {
|
|
1760
|
+
parent.items?.push(node);
|
|
1761
|
+
}
|
|
1762
|
+
const layout = await this.getLayout(vue.toRaw(parent), node);
|
|
1763
|
+
node.style = getInitPositionStyle(node.style, layout);
|
|
1764
|
+
await stage?.add({
|
|
1765
|
+
config: lodashEs.cloneDeep(node),
|
|
1766
|
+
parent: lodashEs.cloneDeep(parent),
|
|
1767
|
+
parentId: parent.id,
|
|
1768
|
+
root: lodashEs.cloneDeep(root)
|
|
1769
|
+
});
|
|
1770
|
+
const newStyle = fixNodePosition(node, parent, stage);
|
|
1771
|
+
if (newStyle && (newStyle.top !== node.style.top || newStyle.left !== node.style.left)) {
|
|
1772
|
+
node.style = newStyle;
|
|
1773
|
+
await stage?.update({ config: lodashEs.cloneDeep(node), parentId: parent.id, root: lodashEs.cloneDeep(root) });
|
|
1774
|
+
}
|
|
1775
|
+
this.addModifiedNodeId(node.id);
|
|
1776
|
+
return node;
|
|
2176
1777
|
}
|
|
2177
1778
|
/**
|
|
2178
|
-
*
|
|
1779
|
+
* 向指点容器添加组件节点
|
|
1780
|
+
* @param addConfig 将要添加的组件节点配置
|
|
1781
|
+
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
1782
|
+
* @returns 添加后的节点
|
|
2179
1783
|
*/
|
|
2180
|
-
|
|
2181
|
-
const
|
|
2182
|
-
|
|
1784
|
+
async add(addNode, parent) {
|
|
1785
|
+
const stage = this.get("stage");
|
|
1786
|
+
const addNodes = [];
|
|
1787
|
+
if (!Array.isArray(addNode)) {
|
|
1788
|
+
const { type, inputEvent, ...config } = addNode;
|
|
1789
|
+
if (!type)
|
|
1790
|
+
throw new Error("组件类型不能为空");
|
|
1791
|
+
addNodes.push({ ...vue.toRaw(await propsService.getPropsValue(type, config)) });
|
|
1792
|
+
} else {
|
|
1793
|
+
addNodes.push(...addNode);
|
|
1794
|
+
}
|
|
1795
|
+
const newNodes = await Promise.all(
|
|
1796
|
+
addNodes.map((node) => {
|
|
1797
|
+
const root = this.get("root");
|
|
1798
|
+
if ((utils.isPage(node) || utils.isPageFragment(node)) && root) {
|
|
1799
|
+
return this.doAdd(node, root);
|
|
1800
|
+
}
|
|
1801
|
+
const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(node);
|
|
1802
|
+
if (!parentNode)
|
|
1803
|
+
throw new Error("未找到父元素");
|
|
1804
|
+
return this.doAdd(node, parentNode);
|
|
1805
|
+
})
|
|
1806
|
+
);
|
|
1807
|
+
if (newNodes.length > 1) {
|
|
1808
|
+
const newNodeIds = newNodes.map((node) => node.id);
|
|
1809
|
+
stage?.multiSelect(newNodeIds);
|
|
1810
|
+
await this.multiSelect(newNodeIds);
|
|
1811
|
+
} else {
|
|
1812
|
+
await this.select(newNodes[0]);
|
|
1813
|
+
if (utils.isPage(newNodes[0])) {
|
|
1814
|
+
this.state.pageLength += 1;
|
|
1815
|
+
} else if (utils.isPageFragment(newNodes[0])) {
|
|
1816
|
+
this.state.pageFragmentLength += 1;
|
|
1817
|
+
} else {
|
|
1818
|
+
stage?.select(newNodes[0].id);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
if (!(utils.isPage(newNodes[0]) || utils.isPageFragment(newNodes[0]))) {
|
|
1822
|
+
this.pushHistoryState();
|
|
1823
|
+
}
|
|
1824
|
+
this.emit("add", newNodes);
|
|
1825
|
+
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
1826
|
+
}
|
|
1827
|
+
async doRemove(node) {
|
|
1828
|
+
const root = this.get("root");
|
|
1829
|
+
if (!root)
|
|
1830
|
+
throw new Error("root不能为空");
|
|
1831
|
+
const { parent, node: curNode } = this.getNodeInfo(node.id, false);
|
|
1832
|
+
if (!parent || !curNode)
|
|
1833
|
+
throw new Error("找不要删除的节点");
|
|
1834
|
+
const index = getNodeIndex(curNode.id, parent);
|
|
1835
|
+
if (typeof index !== "number" || index === -1)
|
|
1836
|
+
throw new Error("找不要删除的节点");
|
|
1837
|
+
parent.items?.splice(index, 1);
|
|
1838
|
+
const stage = this.get("stage");
|
|
1839
|
+
stage?.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
|
|
1840
|
+
const selectDefault = async (pages) => {
|
|
1841
|
+
if (pages[0]) {
|
|
1842
|
+
await this.select(pages[0]);
|
|
1843
|
+
stage?.select(pages[0].id);
|
|
1844
|
+
} else {
|
|
1845
|
+
this.selectRoot();
|
|
1846
|
+
historyService.resetPage();
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
const rootItems = root.items || [];
|
|
1850
|
+
if (utils.isPage(node)) {
|
|
1851
|
+
this.state.pageLength -= 1;
|
|
1852
|
+
await selectDefault(getPageList(root));
|
|
1853
|
+
} else if (utils.isPageFragment(node)) {
|
|
1854
|
+
this.state.pageFragmentLength -= 1;
|
|
1855
|
+
await selectDefault(getPageFragmentList(root));
|
|
1856
|
+
} else {
|
|
1857
|
+
await this.select(parent);
|
|
1858
|
+
stage?.select(parent.id);
|
|
1859
|
+
this.addModifiedNodeId(parent.id);
|
|
1860
|
+
}
|
|
1861
|
+
if (!rootItems.length) {
|
|
1862
|
+
this.resetModifiedNodeId();
|
|
1863
|
+
historyService.reset();
|
|
1864
|
+
}
|
|
2183
1865
|
}
|
|
2184
1866
|
/**
|
|
2185
|
-
*
|
|
1867
|
+
* 删除组件
|
|
1868
|
+
* @param {Object} node
|
|
2186
1869
|
*/
|
|
2187
|
-
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
);
|
|
2193
|
-
if (item === null)
|
|
2194
|
-
return null;
|
|
2195
|
-
switch (protocol) {
|
|
2196
|
-
case "object" /* OBJECT */:
|
|
2197
|
-
return getConfig("parseDSL")(`(${item})`);
|
|
2198
|
-
case "json" /* JSON */:
|
|
2199
|
-
return JSON.parse(item);
|
|
2200
|
-
case "number" /* NUMBER */:
|
|
2201
|
-
return Number(item);
|
|
2202
|
-
case "boolean" /* BOOLEAN */:
|
|
2203
|
-
return Boolean(item);
|
|
2204
|
-
default:
|
|
2205
|
-
return item;
|
|
1870
|
+
async remove(nodeOrNodeList) {
|
|
1871
|
+
const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
|
|
1872
|
+
await Promise.all(nodes.map((node) => this.doRemove(node)));
|
|
1873
|
+
if (!(utils.isPage(nodes[0]) || utils.isPageFragment(nodes[0]))) {
|
|
1874
|
+
this.pushHistoryState();
|
|
2206
1875
|
}
|
|
1876
|
+
this.emit("remove", nodes);
|
|
2207
1877
|
}
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
1878
|
+
async doUpdate(config) {
|
|
1879
|
+
const root = this.get("root");
|
|
1880
|
+
if (!root)
|
|
1881
|
+
throw new Error("root为空");
|
|
1882
|
+
if (!config?.id)
|
|
1883
|
+
throw new Error("没有配置或者配置缺少id值");
|
|
1884
|
+
const info = this.getNodeInfo(config.id, false);
|
|
1885
|
+
if (!info.node)
|
|
1886
|
+
throw new Error(`获取不到id为${config.id}的节点`);
|
|
1887
|
+
const node = lodashEs.cloneDeep(vue.toRaw(info.node));
|
|
1888
|
+
let newConfig = await this.toggleFixedPosition(vue.toRaw(config), node, root);
|
|
1889
|
+
newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), newConfig, (objValue, srcValue, key) => {
|
|
1890
|
+
if (typeof srcValue === "undefined" && Object.hasOwn(newConfig, key)) {
|
|
1891
|
+
return "";
|
|
1892
|
+
}
|
|
1893
|
+
if (lodashEs.isObject(srcValue) && Array.isArray(objValue)) {
|
|
1894
|
+
return srcValue;
|
|
1895
|
+
}
|
|
1896
|
+
if (Array.isArray(srcValue)) {
|
|
1897
|
+
return srcValue;
|
|
1898
|
+
}
|
|
1899
|
+
});
|
|
1900
|
+
if (!newConfig.type)
|
|
1901
|
+
throw new Error("配置缺少type值");
|
|
1902
|
+
if (newConfig.type === schema.NodeType.ROOT) {
|
|
1903
|
+
this.set("root", newConfig);
|
|
1904
|
+
return newConfig;
|
|
1905
|
+
}
|
|
1906
|
+
const { parent } = info;
|
|
1907
|
+
if (!parent)
|
|
1908
|
+
throw new Error("获取不到父级节点");
|
|
1909
|
+
const parentNodeItems = parent.items;
|
|
1910
|
+
const index = getNodeIndex(newConfig.id, parent);
|
|
1911
|
+
if (!parentNodeItems || typeof index === "undefined" || index === -1)
|
|
1912
|
+
throw new Error("更新的节点未找到");
|
|
1913
|
+
const newLayout = await this.getLayout(newConfig);
|
|
1914
|
+
const layout = await this.getLayout(node);
|
|
1915
|
+
if (Array.isArray(newConfig.items) && newLayout !== layout) {
|
|
1916
|
+
newConfig = setChildrenLayout(newConfig, newLayout);
|
|
1917
|
+
}
|
|
1918
|
+
parentNodeItems[index] = newConfig;
|
|
1919
|
+
const nodes = this.get("nodes");
|
|
1920
|
+
const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
1921
|
+
nodes.splice(targetIndex, 1, newConfig);
|
|
1922
|
+
this.set("nodes", [...nodes]);
|
|
1923
|
+
this.get("stage")?.update({
|
|
1924
|
+
config: lodashEs.cloneDeep(newConfig),
|
|
1925
|
+
parentId: parent.id,
|
|
1926
|
+
root: lodashEs.cloneDeep(root)
|
|
1927
|
+
});
|
|
1928
|
+
if (utils.isPage(newConfig) || utils.isPageFragment(newConfig)) {
|
|
1929
|
+
this.set("page", newConfig);
|
|
1930
|
+
}
|
|
1931
|
+
this.addModifiedNodeId(newConfig.id);
|
|
1932
|
+
return newConfig;
|
|
2214
1933
|
}
|
|
2215
1934
|
/**
|
|
2216
|
-
*
|
|
1935
|
+
* 更新节点
|
|
1936
|
+
* @param config 新的节点配置,配置中需要有id信息
|
|
1937
|
+
* @returns 更新后的节点配置
|
|
2217
1938
|
*/
|
|
2218
|
-
|
|
2219
|
-
const
|
|
2220
|
-
const
|
|
2221
|
-
|
|
1939
|
+
async update(config) {
|
|
1940
|
+
const nodes = Array.isArray(config) ? config : [config];
|
|
1941
|
+
const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
|
|
1942
|
+
if (newNodes[0]?.type !== schema.NodeType.ROOT) {
|
|
1943
|
+
this.pushHistoryState();
|
|
1944
|
+
}
|
|
1945
|
+
this.emit("update", newNodes);
|
|
1946
|
+
return Array.isArray(config) ? newNodes : newNodes[0];
|
|
2222
1947
|
}
|
|
2223
1948
|
/**
|
|
2224
|
-
*
|
|
1949
|
+
* 将id为id1的组件移动到id为id2的组件位置上,例如:[1,2,3,4] -> sort(1,3) -> [2,1,3,4]
|
|
1950
|
+
* @param id1 组件ID
|
|
1951
|
+
* @param id2 组件ID
|
|
1952
|
+
* @returns void
|
|
2225
1953
|
*/
|
|
2226
|
-
|
|
2227
|
-
const
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
const
|
|
2231
|
-
if (
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
if (value === null) {
|
|
2248
|
-
return {
|
|
2249
|
-
item: value,
|
|
2250
|
-
protocol
|
|
2251
|
-
};
|
|
2252
|
-
}
|
|
2253
|
-
const item = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
|
|
2254
|
-
protocol = $1;
|
|
2255
|
-
return $3;
|
|
1954
|
+
async sort(id1, id2) {
|
|
1955
|
+
const root = this.get("root");
|
|
1956
|
+
if (!root)
|
|
1957
|
+
throw new Error("root为空");
|
|
1958
|
+
const node = this.get("node");
|
|
1959
|
+
if (!node)
|
|
1960
|
+
throw new Error("当前节点为空");
|
|
1961
|
+
const parent = lodashEs.cloneDeep(vue.toRaw(this.get("parent")));
|
|
1962
|
+
if (!parent)
|
|
1963
|
+
throw new Error("父节点为空");
|
|
1964
|
+
const index2 = parent.items.findIndex((node2) => `${node2.id}` === `${id2}`);
|
|
1965
|
+
if (index2 < 0)
|
|
1966
|
+
return;
|
|
1967
|
+
const index1 = parent.items.findIndex((node2) => `${node2.id}` === `${id1}`);
|
|
1968
|
+
parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
|
|
1969
|
+
await this.update(parent);
|
|
1970
|
+
await this.select(node);
|
|
1971
|
+
this.get("stage")?.update({
|
|
1972
|
+
config: lodashEs.cloneDeep(node),
|
|
1973
|
+
parentId: parent.id,
|
|
1974
|
+
root: lodashEs.cloneDeep(root)
|
|
2256
1975
|
});
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
item
|
|
2260
|
-
};
|
|
1976
|
+
this.addModifiedNodeId(parent.id);
|
|
1977
|
+
this.pushHistoryState();
|
|
2261
1978
|
}
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
"doAdd",
|
|
2272
|
-
"add",
|
|
2273
|
-
"doRemove",
|
|
2274
|
-
"remove",
|
|
2275
|
-
"doUpdate",
|
|
2276
|
-
"update",
|
|
2277
|
-
"sort",
|
|
2278
|
-
"copy",
|
|
2279
|
-
"paste",
|
|
2280
|
-
"doPaste",
|
|
2281
|
-
"doAlignCenter",
|
|
2282
|
-
"alignCenter",
|
|
2283
|
-
"moveLayer",
|
|
2284
|
-
"moveToContainer",
|
|
2285
|
-
"dragTo",
|
|
2286
|
-
"undo",
|
|
2287
|
-
"redo",
|
|
2288
|
-
"move"
|
|
2289
|
-
],
|
|
2290
|
-
sync: []
|
|
2291
|
-
};
|
|
2292
|
-
class Editor extends BaseService {
|
|
2293
|
-
state = vue.reactive({
|
|
2294
|
-
root: null,
|
|
2295
|
-
page: null,
|
|
2296
|
-
parent: null,
|
|
2297
|
-
node: null,
|
|
2298
|
-
nodes: [],
|
|
2299
|
-
stage: null,
|
|
2300
|
-
stageLoading: true,
|
|
2301
|
-
highlightNode: null,
|
|
2302
|
-
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
2303
|
-
pageLength: 0,
|
|
2304
|
-
pageFragmentLength: 0,
|
|
2305
|
-
disabledMultiSelect: false
|
|
2306
|
-
});
|
|
2307
|
-
isHistoryStateChange = false;
|
|
2308
|
-
constructor() {
|
|
2309
|
-
super(
|
|
2310
|
-
canUsePluginMethods$3.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
2311
|
-
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
|
2312
|
-
["select", "update", "moveLayer"]
|
|
2313
|
-
);
|
|
1979
|
+
/**
|
|
1980
|
+
* 将组件节点配置存储到localStorage中
|
|
1981
|
+
* @param config 组件节点配置
|
|
1982
|
+
* @returns
|
|
1983
|
+
*/
|
|
1984
|
+
copy(config) {
|
|
1985
|
+
storageService.setItem(COPY_STORAGE_KEY, Array.isArray(config) ? config : [config], {
|
|
1986
|
+
protocol: Protocol.OBJECT
|
|
1987
|
+
});
|
|
2314
1988
|
}
|
|
2315
1989
|
/**
|
|
2316
|
-
*
|
|
2317
|
-
* @param
|
|
2318
|
-
* @
|
|
1990
|
+
* 复制时会带上组件关联的依赖
|
|
1991
|
+
* @param config 组件节点配置
|
|
1992
|
+
* @returns
|
|
2319
1993
|
*/
|
|
2320
|
-
|
|
2321
|
-
const
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
1994
|
+
copyWithRelated(config) {
|
|
1995
|
+
const copyNodes = Array.isArray(config) ? config : [config];
|
|
1996
|
+
depService.clearByType(dep.DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
1997
|
+
depService.collect(copyNodes, true, dep.DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
1998
|
+
const customTarget = depService.getTarget(
|
|
1999
|
+
dep.DepTargetType.RELATED_COMP_WHEN_COPY,
|
|
2000
|
+
dep.DepTargetType.RELATED_COMP_WHEN_COPY
|
|
2001
|
+
);
|
|
2002
|
+
if (customTarget) {
|
|
2003
|
+
Object.keys(customTarget.deps).forEach((nodeId) => {
|
|
2004
|
+
const node = this.getNodeById(nodeId);
|
|
2005
|
+
if (!node)
|
|
2006
|
+
return;
|
|
2007
|
+
customTarget.deps[nodeId].keys.forEach((key) => {
|
|
2008
|
+
const relateNodeId = lodashEs.get(node, key);
|
|
2009
|
+
const isExist = copyNodes.find((node2) => node2.id === relateNodeId);
|
|
2010
|
+
if (!isExist) {
|
|
2011
|
+
const relateNode = this.getNodeById(relateNodeId);
|
|
2012
|
+
if (relateNode) {
|
|
2013
|
+
copyNodes.push(relateNode);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
});
|
|
2325
2018
|
}
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2019
|
+
storageService.setItem(COPY_STORAGE_KEY, copyNodes, {
|
|
2020
|
+
protocol: Protocol.OBJECT
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
/**
|
|
2024
|
+
* 从localStorage中获取节点,然后添加到当前容器中
|
|
2025
|
+
* @param position 粘贴的坐标
|
|
2026
|
+
* @returns 添加后的组件节点配置
|
|
2027
|
+
*/
|
|
2028
|
+
async paste(position = {}) {
|
|
2029
|
+
const config = storageService.getItem(COPY_STORAGE_KEY);
|
|
2030
|
+
if (!Array.isArray(config))
|
|
2031
|
+
return;
|
|
2032
|
+
const node = this.get("node");
|
|
2033
|
+
let parent = null;
|
|
2034
|
+
if (config.length === 1 && config[0].id === node?.id) {
|
|
2035
|
+
parent = this.get("parent");
|
|
2036
|
+
if (parent?.type === schema.NodeType.ROOT) {
|
|
2037
|
+
parent = this.get("page");
|
|
2329
2038
|
}
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2039
|
+
}
|
|
2040
|
+
const pasteConfigs = await this.doPaste(config, position);
|
|
2041
|
+
propsService.replaceRelateId(config, pasteConfigs);
|
|
2042
|
+
return this.add(pasteConfigs, parent);
|
|
2043
|
+
}
|
|
2044
|
+
async doPaste(config, position = {}) {
|
|
2045
|
+
propsService.clearRelateId();
|
|
2046
|
+
const pasteConfigs = beforePaste(position, lodashEs.cloneDeep(config));
|
|
2047
|
+
return pasteConfigs;
|
|
2048
|
+
}
|
|
2049
|
+
async doAlignCenter(config) {
|
|
2050
|
+
const parent = this.getParentById(config.id);
|
|
2051
|
+
if (!parent)
|
|
2052
|
+
throw new Error("找不到父节点");
|
|
2053
|
+
const node = lodashEs.cloneDeep(vue.toRaw(config));
|
|
2054
|
+
const layout = await this.getLayout(parent, node);
|
|
2055
|
+
if (layout === Layout.RELATIVE) {
|
|
2056
|
+
return config;
|
|
2057
|
+
}
|
|
2058
|
+
if (!node.style)
|
|
2059
|
+
return config;
|
|
2060
|
+
const stage = this.get("stage");
|
|
2061
|
+
const doc = stage?.renderer.contentWindow?.document;
|
|
2062
|
+
if (doc) {
|
|
2063
|
+
const el = doc.getElementById(`${node.id}`);
|
|
2064
|
+
const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent;
|
|
2065
|
+
if (parentEl && el) {
|
|
2066
|
+
node.style.left = utils.calcValueByFontsize(doc, (parentEl.clientWidth - el.clientWidth) / 2);
|
|
2067
|
+
node.style.right = "";
|
|
2339
2068
|
}
|
|
2340
|
-
|
|
2069
|
+
} else if (parent.style && utils.isNumber(parent.style?.width) && utils.isNumber(node.style?.width)) {
|
|
2070
|
+
node.style.left = (parent.style.width - node.style.width) / 2;
|
|
2071
|
+
node.style.right = "";
|
|
2341
2072
|
}
|
|
2073
|
+
return node;
|
|
2342
2074
|
}
|
|
2343
2075
|
/**
|
|
2344
|
-
*
|
|
2345
|
-
* @param
|
|
2346
|
-
* @returns
|
|
2076
|
+
* 将指点节点设置居中
|
|
2077
|
+
* @param config 组件节点配置
|
|
2078
|
+
* @returns 当前组件节点配置
|
|
2347
2079
|
*/
|
|
2348
|
-
|
|
2349
|
-
|
|
2080
|
+
async alignCenter(config) {
|
|
2081
|
+
const nodes = Array.isArray(config) ? config : [config];
|
|
2082
|
+
const stage = this.get("stage");
|
|
2083
|
+
const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
|
|
2084
|
+
const newNode = await this.update(newNodes);
|
|
2085
|
+
if (newNodes.length > 1) {
|
|
2086
|
+
await stage?.multiSelect(newNodes.map((node) => node.id));
|
|
2087
|
+
} else {
|
|
2088
|
+
await stage?.select(newNodes[0].id);
|
|
2089
|
+
}
|
|
2090
|
+
return newNode;
|
|
2350
2091
|
}
|
|
2351
2092
|
/**
|
|
2352
|
-
*
|
|
2353
|
-
* @param
|
|
2354
|
-
* @param {boolean} raw 是否使用toRaw
|
|
2355
|
-
* @returns {EditorNodeInfo}
|
|
2093
|
+
* 移动当前选中节点位置
|
|
2094
|
+
* @param offset 偏移量
|
|
2356
2095
|
*/
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
if (raw) {
|
|
2360
|
-
root = vue.toRaw(root);
|
|
2361
|
-
}
|
|
2362
|
-
const info = {
|
|
2363
|
-
node: null,
|
|
2364
|
-
parent: null,
|
|
2365
|
-
page: null
|
|
2366
|
-
};
|
|
2096
|
+
async moveLayer(offset) {
|
|
2097
|
+
const root = this.get("root");
|
|
2367
2098
|
if (!root)
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2099
|
+
throw new Error("root为空");
|
|
2100
|
+
const parent = this.get("parent");
|
|
2101
|
+
if (!parent)
|
|
2102
|
+
throw new Error("父节点为空");
|
|
2103
|
+
const node = this.get("node");
|
|
2104
|
+
if (!node)
|
|
2105
|
+
throw new Error("当前节点为空");
|
|
2106
|
+
const brothers = parent.items || [];
|
|
2107
|
+
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
2108
|
+
const layout = await this.getLayout(parent, node);
|
|
2109
|
+
const isRelative = layout === Layout.RELATIVE;
|
|
2110
|
+
let offsetIndex;
|
|
2111
|
+
if (offset === LayerOffset.TOP) {
|
|
2112
|
+
offsetIndex = isRelative ? 0 : brothers.length;
|
|
2113
|
+
} else if (offset === LayerOffset.BOTTOM) {
|
|
2114
|
+
offsetIndex = isRelative ? brothers.length : 0;
|
|
2115
|
+
} else {
|
|
2116
|
+
offsetIndex = index + (isRelative ? -offset : offset);
|
|
2372
2117
|
}
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2118
|
+
if (offsetIndex > 0 && offsetIndex > brothers.length || offsetIndex < 0) {
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
brothers.splice(index, 1);
|
|
2122
|
+
brothers.splice(offsetIndex, 0, node);
|
|
2123
|
+
const grandparent = this.getParentById(parent.id);
|
|
2124
|
+
this.get("stage")?.update({
|
|
2125
|
+
config: lodashEs.cloneDeep(vue.toRaw(parent)),
|
|
2126
|
+
parentId: grandparent?.id,
|
|
2127
|
+
root: lodashEs.cloneDeep(root)
|
|
2128
|
+
});
|
|
2129
|
+
this.addModifiedNodeId(parent.id);
|
|
2130
|
+
this.pushHistoryState();
|
|
2131
|
+
this.emit("move-layer", offset);
|
|
2132
|
+
}
|
|
2133
|
+
/**
|
|
2134
|
+
* 移动到指定容器中
|
|
2135
|
+
* @param config 需要移动的节点
|
|
2136
|
+
* @param targetId 容器ID
|
|
2137
|
+
*/
|
|
2138
|
+
async moveToContainer(config, targetId) {
|
|
2139
|
+
const root = this.get("root");
|
|
2140
|
+
const { node, parent } = this.getNodeInfo(config.id, false);
|
|
2141
|
+
const target = this.getNodeById(targetId, false);
|
|
2142
|
+
const stage = this.get("stage");
|
|
2143
|
+
if (root && node && parent && stage) {
|
|
2144
|
+
const index = getNodeIndex(node.id, parent);
|
|
2145
|
+
parent.items?.splice(index, 1);
|
|
2146
|
+
await stage.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
|
|
2147
|
+
const layout = await this.getLayout(target);
|
|
2148
|
+
const newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), config, (objValue, srcValue) => {
|
|
2149
|
+
if (Array.isArray(srcValue)) {
|
|
2150
|
+
return srcValue;
|
|
2151
|
+
}
|
|
2152
|
+
});
|
|
2153
|
+
newConfig.style = getInitPositionStyle(newConfig.style, layout);
|
|
2154
|
+
target.items.push(newConfig);
|
|
2155
|
+
await stage.select(targetId);
|
|
2156
|
+
const targetParent = this.getParentById(target.id);
|
|
2157
|
+
await stage.update({ config: lodashEs.cloneDeep(target), parentId: targetParent?.id, root: lodashEs.cloneDeep(root) });
|
|
2158
|
+
await this.select(newConfig);
|
|
2159
|
+
stage.select(newConfig.id);
|
|
2160
|
+
this.addModifiedNodeId(target.id);
|
|
2161
|
+
this.addModifiedNodeId(parent.id);
|
|
2162
|
+
this.pushHistoryState();
|
|
2163
|
+
return newConfig;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
async dragTo(config, targetParent, targetIndex) {
|
|
2167
|
+
if (!targetParent || !Array.isArray(targetParent.items))
|
|
2168
|
+
return;
|
|
2169
|
+
const { parent, node: curNode } = this.getNodeInfo(config.id, false);
|
|
2170
|
+
if (!parent || !curNode)
|
|
2171
|
+
throw new Error("找不要删除的节点");
|
|
2172
|
+
const index = getNodeIndex(curNode.id, parent);
|
|
2173
|
+
if (typeof index !== "number" || index === -1)
|
|
2174
|
+
throw new Error("找不要删除的节点");
|
|
2175
|
+
if (parent.id === targetParent.id) {
|
|
2176
|
+
if (index === targetIndex)
|
|
2382
2177
|
return;
|
|
2178
|
+
if (index < targetIndex) {
|
|
2179
|
+
targetIndex -= 1;
|
|
2383
2180
|
}
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2181
|
+
}
|
|
2182
|
+
const layout = await this.getLayout(parent);
|
|
2183
|
+
const newLayout = await this.getLayout(targetParent);
|
|
2184
|
+
if (newLayout !== layout) {
|
|
2185
|
+
setLayout(config, newLayout);
|
|
2186
|
+
}
|
|
2187
|
+
parent.items?.splice(index, 1);
|
|
2188
|
+
targetParent.items?.splice(targetIndex, 0, config);
|
|
2189
|
+
const page = this.get("page");
|
|
2190
|
+
const root = this.get("root");
|
|
2191
|
+
const stage = this.get("stage");
|
|
2192
|
+
if (stage && page && root) {
|
|
2193
|
+
stage.update({
|
|
2194
|
+
config: lodashEs.cloneDeep(page),
|
|
2195
|
+
parentId: root.id,
|
|
2196
|
+
root: lodashEs.cloneDeep(root)
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
this.addModifiedNodeId(config.id);
|
|
2200
|
+
this.addModifiedNodeId(parent.id);
|
|
2201
|
+
this.pushHistoryState();
|
|
2202
|
+
this.emit("drag-to", { index, targetIndex, config, parent, targetParent });
|
|
2386
2203
|
}
|
|
2387
2204
|
/**
|
|
2388
|
-
*
|
|
2389
|
-
* @
|
|
2390
|
-
* @param {boolean} raw 是否使用toRaw
|
|
2391
|
-
* @returns 组件节点配置
|
|
2205
|
+
* 撤销当前操作
|
|
2206
|
+
* @returns 上一次数据
|
|
2392
2207
|
*/
|
|
2393
|
-
|
|
2394
|
-
const
|
|
2395
|
-
|
|
2208
|
+
async undo() {
|
|
2209
|
+
const value = historyService.undo();
|
|
2210
|
+
await this.changeHistoryState(value);
|
|
2211
|
+
return value;
|
|
2396
2212
|
}
|
|
2397
2213
|
/**
|
|
2398
|
-
*
|
|
2399
|
-
* @
|
|
2400
|
-
* @param {boolean} raw 是否使用toRaw
|
|
2401
|
-
* @returns 指点组件的父节点配置
|
|
2214
|
+
* 恢复到下一步
|
|
2215
|
+
* @returns 下一步数据
|
|
2402
2216
|
*/
|
|
2403
|
-
|
|
2404
|
-
const
|
|
2405
|
-
|
|
2217
|
+
async redo() {
|
|
2218
|
+
const value = historyService.redo();
|
|
2219
|
+
await this.changeHistoryState(value);
|
|
2220
|
+
return value;
|
|
2406
2221
|
}
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2222
|
+
async move(left, top) {
|
|
2223
|
+
const node = vue.toRaw(this.get("node"));
|
|
2224
|
+
if (!node || utils.isPage(node))
|
|
2225
|
+
return;
|
|
2226
|
+
const { style, id, type } = node;
|
|
2227
|
+
if (!style || !["absolute", "fixed"].includes(style.position))
|
|
2228
|
+
return;
|
|
2229
|
+
const update = (style2) => this.update({
|
|
2230
|
+
id,
|
|
2231
|
+
type,
|
|
2232
|
+
style: style2
|
|
2233
|
+
});
|
|
2234
|
+
if (top) {
|
|
2235
|
+
if (utils.isNumber(style.top)) {
|
|
2236
|
+
update({
|
|
2237
|
+
...style,
|
|
2238
|
+
top: Number(style.top) + Number(top),
|
|
2239
|
+
bottom: ""
|
|
2240
|
+
});
|
|
2241
|
+
} else if (utils.isNumber(style.bottom)) {
|
|
2242
|
+
update({
|
|
2243
|
+
...style,
|
|
2244
|
+
bottom: Number(style.bottom) - Number(top),
|
|
2245
|
+
top: ""
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2415
2248
|
}
|
|
2416
|
-
if (
|
|
2417
|
-
|
|
2249
|
+
if (left) {
|
|
2250
|
+
if (utils.isNumber(style.left)) {
|
|
2251
|
+
update({
|
|
2252
|
+
...style,
|
|
2253
|
+
left: Number(style.left) + Number(left),
|
|
2254
|
+
right: ""
|
|
2255
|
+
});
|
|
2256
|
+
} else if (utils.isNumber(style.right)) {
|
|
2257
|
+
update({
|
|
2258
|
+
...style,
|
|
2259
|
+
right: Number(style.right) - Number(left),
|
|
2260
|
+
left: ""
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2418
2263
|
}
|
|
2419
|
-
return Layout.ABSOLUTE;
|
|
2420
2264
|
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
this.set("
|
|
2429
|
-
this.set("
|
|
2430
|
-
this.set("
|
|
2431
|
-
|
|
2432
|
-
|
|
2265
|
+
resetState() {
|
|
2266
|
+
this.set("root", null);
|
|
2267
|
+
this.set("node", null);
|
|
2268
|
+
this.set("nodes", []);
|
|
2269
|
+
this.set("page", null);
|
|
2270
|
+
this.set("parent", null);
|
|
2271
|
+
this.set("stage", null);
|
|
2272
|
+
this.set("highlightNode", null);
|
|
2273
|
+
this.set("modifiedNodeIds", /* @__PURE__ */ new Map());
|
|
2274
|
+
this.set("pageLength", 0);
|
|
2275
|
+
}
|
|
2276
|
+
destroy() {
|
|
2277
|
+
this.removeAllListeners();
|
|
2278
|
+
this.resetState();
|
|
2279
|
+
this.removeAllPlugins();
|
|
2280
|
+
}
|
|
2281
|
+
resetModifiedNodeId() {
|
|
2282
|
+
this.get("modifiedNodeIds").clear();
|
|
2283
|
+
}
|
|
2284
|
+
usePlugin(options) {
|
|
2285
|
+
super.usePlugin(options);
|
|
2286
|
+
}
|
|
2287
|
+
addModifiedNodeId(id) {
|
|
2288
|
+
if (!this.isHistoryStateChange) {
|
|
2289
|
+
this.get("modifiedNodeIds").set(id, id);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
pushHistoryState() {
|
|
2293
|
+
const curNode = lodashEs.cloneDeep(vue.toRaw(this.get("node")));
|
|
2294
|
+
const page = this.get("page");
|
|
2295
|
+
if (!this.isHistoryStateChange && curNode && page) {
|
|
2296
|
+
historyService.push({
|
|
2297
|
+
data: lodashEs.cloneDeep(vue.toRaw(page)),
|
|
2298
|
+
modifiedNodeIds: this.get("modifiedNodeIds"),
|
|
2299
|
+
nodeId: curNode.id
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
this.isHistoryStateChange = false;
|
|
2303
|
+
}
|
|
2304
|
+
async changeHistoryState(value) {
|
|
2305
|
+
if (!value)
|
|
2306
|
+
return;
|
|
2307
|
+
this.isHistoryStateChange = true;
|
|
2308
|
+
await this.update(value.data);
|
|
2309
|
+
this.set("modifiedNodeIds", value.modifiedNodeIds);
|
|
2310
|
+
setTimeout(async () => {
|
|
2311
|
+
if (!value.nodeId)
|
|
2312
|
+
return;
|
|
2313
|
+
await this.select(value.nodeId);
|
|
2314
|
+
this.get("stage")?.select(value.nodeId);
|
|
2315
|
+
}, 0);
|
|
2316
|
+
this.emit("history-change", value.data);
|
|
2317
|
+
}
|
|
2318
|
+
async toggleFixedPosition(dist, src, root) {
|
|
2319
|
+
const newConfig = lodashEs.cloneDeep(dist);
|
|
2320
|
+
if (!utils.isPop(src) && newConfig.style?.position) {
|
|
2321
|
+
if (isFixed(newConfig) && !isFixed(src)) {
|
|
2322
|
+
newConfig.style = change2Fixed(newConfig, root);
|
|
2323
|
+
} else if (!isFixed(newConfig) && isFixed(src)) {
|
|
2324
|
+
newConfig.style = await Fixed2Other(newConfig, root, this.getLayout);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
return newConfig;
|
|
2328
|
+
}
|
|
2329
|
+
selectedConfigExceptionHandler(config) {
|
|
2330
|
+
let id;
|
|
2331
|
+
if (typeof config === "string" || typeof config === "number") {
|
|
2332
|
+
id = config;
|
|
2433
2333
|
} else {
|
|
2434
|
-
|
|
2334
|
+
id = config.id;
|
|
2435
2335
|
}
|
|
2436
|
-
if (
|
|
2437
|
-
|
|
2438
|
-
|
|
2336
|
+
if (!id) {
|
|
2337
|
+
throw new Error("没有ID,无法选中");
|
|
2338
|
+
}
|
|
2339
|
+
const { node, parent, page } = this.getNodeInfo(id);
|
|
2340
|
+
if (!node)
|
|
2341
|
+
throw new Error("获取不到组件信息");
|
|
2342
|
+
if (node.id === this.state.root?.id) {
|
|
2343
|
+
throw new Error("不能选根节点");
|
|
2344
|
+
}
|
|
2345
|
+
return {
|
|
2346
|
+
node,
|
|
2347
|
+
parent,
|
|
2348
|
+
page
|
|
2349
|
+
};
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
const editorService = new Editor();
|
|
2353
|
+
|
|
2354
|
+
function BaseFormConfig() {
|
|
2355
|
+
return [
|
|
2356
|
+
{
|
|
2357
|
+
name: "id",
|
|
2358
|
+
type: "hidden"
|
|
2359
|
+
},
|
|
2360
|
+
{
|
|
2361
|
+
name: "type",
|
|
2362
|
+
text: "类型",
|
|
2363
|
+
type: "hidden",
|
|
2364
|
+
defaultValue: "base"
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
2367
|
+
name: "title",
|
|
2368
|
+
text: "名称",
|
|
2369
|
+
rules: [
|
|
2439
2370
|
{
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2371
|
+
required: true,
|
|
2372
|
+
message: "请输入名称"
|
|
2373
|
+
}
|
|
2374
|
+
]
|
|
2375
|
+
},
|
|
2376
|
+
{
|
|
2377
|
+
name: "description",
|
|
2378
|
+
text: "描述"
|
|
2446
2379
|
}
|
|
2447
|
-
|
|
2448
|
-
|
|
2380
|
+
];
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
const HttpFormConfig = [
|
|
2384
|
+
{
|
|
2385
|
+
name: "autoFetch",
|
|
2386
|
+
text: "自动请求",
|
|
2387
|
+
type: "switch",
|
|
2388
|
+
defaultValue: true
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
name: "responseOptions",
|
|
2392
|
+
items: [
|
|
2393
|
+
{
|
|
2394
|
+
name: "dataPath",
|
|
2395
|
+
text: "数据路径"
|
|
2396
|
+
}
|
|
2397
|
+
]
|
|
2398
|
+
},
|
|
2399
|
+
{
|
|
2400
|
+
type: "fieldset",
|
|
2401
|
+
name: "options",
|
|
2402
|
+
legend: "HTTP 配置",
|
|
2403
|
+
items: [
|
|
2404
|
+
{
|
|
2405
|
+
name: "url",
|
|
2406
|
+
text: "URL"
|
|
2407
|
+
},
|
|
2408
|
+
{
|
|
2409
|
+
name: "method",
|
|
2410
|
+
text: "Method",
|
|
2411
|
+
type: "select",
|
|
2412
|
+
options: [
|
|
2413
|
+
{ text: "GET", value: "GET" },
|
|
2414
|
+
{ text: "POST", value: "POST" },
|
|
2415
|
+
{ text: "PUT", value: "PUT" },
|
|
2416
|
+
{ text: "DELETE", value: "DELETE" }
|
|
2417
|
+
]
|
|
2418
|
+
},
|
|
2419
|
+
{
|
|
2420
|
+
name: "params",
|
|
2421
|
+
type: "key-value",
|
|
2422
|
+
defaultValue: {},
|
|
2423
|
+
text: "参数"
|
|
2424
|
+
},
|
|
2425
|
+
{
|
|
2426
|
+
name: "data",
|
|
2427
|
+
type: "key-value",
|
|
2428
|
+
defaultValue: {},
|
|
2429
|
+
advanced: true,
|
|
2430
|
+
text: "请求体"
|
|
2431
|
+
},
|
|
2432
|
+
{
|
|
2433
|
+
name: "headers",
|
|
2434
|
+
type: "key-value",
|
|
2435
|
+
defaultValue: {},
|
|
2436
|
+
text: "请求头"
|
|
2437
|
+
}
|
|
2438
|
+
]
|
|
2449
2439
|
}
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2440
|
+
];
|
|
2441
|
+
|
|
2442
|
+
const fillConfig$1 = (config) => [
|
|
2443
|
+
...BaseFormConfig(),
|
|
2444
|
+
...config,
|
|
2445
|
+
{
|
|
2446
|
+
type: "tab",
|
|
2447
|
+
items: [
|
|
2448
|
+
{
|
|
2449
|
+
title: "数据定义",
|
|
2450
|
+
items: [
|
|
2451
|
+
{
|
|
2452
|
+
name: "fields",
|
|
2453
|
+
type: "data-source-fields",
|
|
2454
|
+
defaultValue: () => []
|
|
2455
|
+
}
|
|
2456
|
+
]
|
|
2457
|
+
},
|
|
2458
|
+
{
|
|
2459
|
+
title: "方法定义",
|
|
2460
|
+
items: [
|
|
2461
|
+
{
|
|
2462
|
+
name: "methods",
|
|
2463
|
+
type: "data-source-methods",
|
|
2464
|
+
defaultValue: () => []
|
|
2465
|
+
}
|
|
2466
|
+
]
|
|
2467
|
+
},
|
|
2468
|
+
{
|
|
2469
|
+
title: "事件配置",
|
|
2470
|
+
items: [
|
|
2471
|
+
{
|
|
2472
|
+
name: "events",
|
|
2473
|
+
src: "datasource",
|
|
2474
|
+
type: "event-select"
|
|
2475
|
+
}
|
|
2476
|
+
]
|
|
2477
|
+
},
|
|
2478
|
+
{
|
|
2479
|
+
title: "mock数据",
|
|
2480
|
+
items: [
|
|
2481
|
+
{
|
|
2482
|
+
name: "mocks",
|
|
2483
|
+
type: "data-source-mocks",
|
|
2484
|
+
defaultValue: () => []
|
|
2485
|
+
}
|
|
2486
|
+
]
|
|
2487
|
+
},
|
|
2488
|
+
{
|
|
2489
|
+
title: "请求参数裁剪",
|
|
2490
|
+
display: (formState, { model }) => model.type === "http",
|
|
2491
|
+
items: [
|
|
2492
|
+
{
|
|
2493
|
+
name: "beforeRequest",
|
|
2494
|
+
type: "vs-code",
|
|
2495
|
+
parse: true,
|
|
2496
|
+
height: "600px"
|
|
2497
|
+
}
|
|
2498
|
+
]
|
|
2499
|
+
},
|
|
2500
|
+
{
|
|
2501
|
+
title: "响应数据裁剪",
|
|
2502
|
+
display: (formState, { model }) => model.type === "http",
|
|
2503
|
+
items: [
|
|
2504
|
+
{
|
|
2505
|
+
name: "afterResponse",
|
|
2506
|
+
type: "vs-code",
|
|
2507
|
+
parse: true,
|
|
2508
|
+
height: "600px"
|
|
2509
|
+
}
|
|
2510
|
+
]
|
|
2511
|
+
}
|
|
2512
|
+
]
|
|
2462
2513
|
}
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
await this.select(nextPage);
|
|
2473
|
-
this.get("stage")?.select(nextPage.id);
|
|
2474
|
-
return nextPage;
|
|
2514
|
+
];
|
|
2515
|
+
const getFormConfig = (type, configs) => {
|
|
2516
|
+
switch (type) {
|
|
2517
|
+
case "base":
|
|
2518
|
+
return fillConfig$1([]);
|
|
2519
|
+
case "http":
|
|
2520
|
+
return fillConfig$1(HttpFormConfig);
|
|
2521
|
+
default:
|
|
2522
|
+
return fillConfig$1(configs[type] || []);
|
|
2475
2523
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
*/
|
|
2481
|
-
highlight(config) {
|
|
2482
|
-
const { node } = this.selectedConfigExceptionHandler(config);
|
|
2483
|
-
const currentHighlightNode = this.get("highlightNode");
|
|
2484
|
-
if (currentHighlightNode === node)
|
|
2485
|
-
return;
|
|
2486
|
-
this.set("highlightNode", node);
|
|
2524
|
+
};
|
|
2525
|
+
const getFormValue = (type, values) => {
|
|
2526
|
+
if (type !== "http") {
|
|
2527
|
+
return values;
|
|
2487
2528
|
}
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2529
|
+
return {
|
|
2530
|
+
beforeRequest: `(options, context) => {
|
|
2531
|
+
/**
|
|
2532
|
+
* 用户可以直接编写函数,在原始接口调用之前,会运行该函数,将这个函数的返回值作为该数据源接口的入参
|
|
2533
|
+
*
|
|
2534
|
+
* options: HttpOptions
|
|
2535
|
+
*
|
|
2536
|
+
* interface HttpOptions {
|
|
2537
|
+
* // 请求链接
|
|
2538
|
+
* url: string;
|
|
2539
|
+
* // query参数
|
|
2540
|
+
* params?: Record<string, string>;
|
|
2541
|
+
* // body数据
|
|
2542
|
+
* data?: Record<string, any>;
|
|
2543
|
+
* // 请求头
|
|
2544
|
+
* headers?: Record<string, string>;
|
|
2545
|
+
* // 请求方法 GET/POST
|
|
2546
|
+
* method?: Method;
|
|
2547
|
+
* }
|
|
2548
|
+
*
|
|
2549
|
+
* context:上下文对象
|
|
2550
|
+
*
|
|
2551
|
+
* interface Content {
|
|
2552
|
+
* app: AppCore;
|
|
2553
|
+
* dataSource: HttpDataSource;
|
|
2554
|
+
* }
|
|
2555
|
+
*
|
|
2556
|
+
* return: HttpOptions
|
|
2557
|
+
*/
|
|
2558
|
+
|
|
2559
|
+
// 此处的返回值会作为这个接口的入参
|
|
2560
|
+
return options;
|
|
2561
|
+
}`,
|
|
2562
|
+
afterResponse: `(response, context) => {
|
|
2563
|
+
/**
|
|
2564
|
+
* 用户可以直接编写函数,在原始接口返回之后,会运行该函数,将这个函数的返回值作为该数据源接口的返回
|
|
2565
|
+
|
|
2566
|
+
* context:上下文对象
|
|
2567
|
+
*
|
|
2568
|
+
* interface Content {
|
|
2569
|
+
* app: AppCore;
|
|
2570
|
+
* dataSource: HttpDataSource;
|
|
2571
|
+
* }
|
|
2572
|
+
*
|
|
2573
|
+
*/
|
|
2574
|
+
|
|
2575
|
+
// 此处的返回值会作为这个接口的返回值
|
|
2576
|
+
return response;
|
|
2577
|
+
}`,
|
|
2578
|
+
...values
|
|
2579
|
+
};
|
|
2580
|
+
};
|
|
2581
|
+
const getDisplayField = (dataSources, key) => {
|
|
2582
|
+
const displayState = [];
|
|
2583
|
+
const matches = key.matchAll(/\$\{([\s\S]+?)\}/g);
|
|
2584
|
+
let index = 0;
|
|
2585
|
+
for (const match of matches) {
|
|
2586
|
+
if (typeof match.index === "undefined")
|
|
2587
|
+
break;
|
|
2588
|
+
displayState.push({
|
|
2589
|
+
type: "text",
|
|
2590
|
+
value: key.substring(index, match.index)
|
|
2501
2591
|
});
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
const root = this.get("root");
|
|
2516
|
-
if (!root)
|
|
2517
|
-
throw new Error("root为空");
|
|
2518
|
-
const curNode = this.get("node");
|
|
2519
|
-
const stage = this.get("stage");
|
|
2520
|
-
if (!curNode)
|
|
2521
|
-
throw new Error("当前选中节点为空");
|
|
2522
|
-
if ((parent.type === schema.NodeType.ROOT || curNode?.type === schema.NodeType.ROOT) && !(utils.isPage(node) || utils.isPageFragment(node))) {
|
|
2523
|
-
throw new Error("app下不能添加组件");
|
|
2524
|
-
}
|
|
2525
|
-
if (parent.id !== curNode.id && !(utils.isPage(node) || utils.isPageFragment(node))) {
|
|
2526
|
-
const index = parent.items.indexOf(curNode);
|
|
2527
|
-
parent.items?.splice(index + 1, 0, node);
|
|
2528
|
-
} else {
|
|
2529
|
-
parent.items?.push(node);
|
|
2530
|
-
}
|
|
2531
|
-
const layout = await this.getLayout(vue.toRaw(parent), node);
|
|
2532
|
-
node.style = getInitPositionStyle(node.style, layout);
|
|
2533
|
-
await stage?.add({
|
|
2534
|
-
config: lodashEs.cloneDeep(node),
|
|
2535
|
-
parent: lodashEs.cloneDeep(parent),
|
|
2536
|
-
parentId: parent.id,
|
|
2537
|
-
root: lodashEs.cloneDeep(root)
|
|
2592
|
+
let dsText = "";
|
|
2593
|
+
let ds;
|
|
2594
|
+
let fields;
|
|
2595
|
+
match[1].split(".").forEach((item, index2) => {
|
|
2596
|
+
if (index2 === 0) {
|
|
2597
|
+
ds = dataSources.find((ds2) => ds2.id === item);
|
|
2598
|
+
dsText += ds?.title || item;
|
|
2599
|
+
fields = ds?.fields;
|
|
2600
|
+
return;
|
|
2601
|
+
}
|
|
2602
|
+
const field = fields?.find((field2) => field2.name === item);
|
|
2603
|
+
fields = field?.fields;
|
|
2604
|
+
dsText += `.${field?.title || item}`;
|
|
2538
2605
|
});
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
this.addModifiedNodeId(node.id);
|
|
2545
|
-
return node;
|
|
2606
|
+
displayState.push({
|
|
2607
|
+
type: "var",
|
|
2608
|
+
value: dsText
|
|
2609
|
+
});
|
|
2610
|
+
index = match.index + match[0].length;
|
|
2546
2611
|
}
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2612
|
+
if (index < key.length) {
|
|
2613
|
+
displayState.push({
|
|
2614
|
+
type: "text",
|
|
2615
|
+
value: key.substring(index)
|
|
2616
|
+
});
|
|
2617
|
+
}
|
|
2618
|
+
return displayState;
|
|
2619
|
+
};
|
|
2620
|
+
const getCascaderOptionsFromFields = (fields = [], dataSourceFieldType = ["any"]) => {
|
|
2621
|
+
const child = [];
|
|
2622
|
+
fields.forEach((field) => {
|
|
2623
|
+
if (!dataSourceFieldType.length) {
|
|
2624
|
+
dataSourceFieldType.push("any");
|
|
2625
|
+
}
|
|
2626
|
+
const children = getCascaderOptionsFromFields(field.fields, dataSourceFieldType);
|
|
2627
|
+
const item = {
|
|
2628
|
+
label: field.title || field.name,
|
|
2629
|
+
value: field.name,
|
|
2630
|
+
children
|
|
2631
|
+
};
|
|
2632
|
+
const fieldType = field.type || "any";
|
|
2633
|
+
if (dataSourceFieldType.includes("any") || dataSourceFieldType.includes(fieldType)) {
|
|
2634
|
+
child.push(item);
|
|
2635
|
+
return;
|
|
2563
2636
|
}
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
const root = this.get("root");
|
|
2567
|
-
if ((utils.isPage(node) || utils.isPageFragment(node)) && root) {
|
|
2568
|
-
return this.doAdd(node, root);
|
|
2569
|
-
}
|
|
2570
|
-
const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(node);
|
|
2571
|
-
if (!parentNode)
|
|
2572
|
-
throw new Error("未找到父元素");
|
|
2573
|
-
return this.doAdd(node, parentNode);
|
|
2574
|
-
})
|
|
2575
|
-
);
|
|
2576
|
-
if (newNodes.length > 1) {
|
|
2577
|
-
const newNodeIds = newNodes.map((node) => node.id);
|
|
2578
|
-
stage?.multiSelect(newNodeIds);
|
|
2579
|
-
await this.multiSelect(newNodeIds);
|
|
2580
|
-
} else {
|
|
2581
|
-
await this.select(newNodes[0]);
|
|
2582
|
-
if (utils.isPage(newNodes[0])) {
|
|
2583
|
-
this.state.pageLength += 1;
|
|
2584
|
-
} else if (utils.isPageFragment(newNodes[0])) {
|
|
2585
|
-
this.state.pageFragmentLength += 1;
|
|
2586
|
-
} else {
|
|
2587
|
-
stage?.select(newNodes[0].id);
|
|
2588
|
-
}
|
|
2637
|
+
if (!dataSourceFieldType.includes(fieldType) && !["array", "object", "any"].includes(fieldType)) {
|
|
2638
|
+
return;
|
|
2589
2639
|
}
|
|
2590
|
-
if (!
|
|
2591
|
-
|
|
2640
|
+
if (!children.length && ["object", "array", "any"].includes(field.type || "")) {
|
|
2641
|
+
return;
|
|
2592
2642
|
}
|
|
2593
|
-
|
|
2594
|
-
|
|
2643
|
+
child.push(item);
|
|
2644
|
+
});
|
|
2645
|
+
return child;
|
|
2646
|
+
};
|
|
2647
|
+
|
|
2648
|
+
const canUsePluginMethods$3 = {
|
|
2649
|
+
async: [],
|
|
2650
|
+
sync: [
|
|
2651
|
+
"getFormConfig",
|
|
2652
|
+
"setFormConfig",
|
|
2653
|
+
"getFormValue",
|
|
2654
|
+
"setFormValue",
|
|
2655
|
+
"getFormEvent",
|
|
2656
|
+
"setFormEvent",
|
|
2657
|
+
"getFormMethod",
|
|
2658
|
+
"setFormMethod",
|
|
2659
|
+
"add",
|
|
2660
|
+
"update",
|
|
2661
|
+
"remove",
|
|
2662
|
+
"createId"
|
|
2663
|
+
]
|
|
2664
|
+
};
|
|
2665
|
+
class DataSource extends BaseService {
|
|
2666
|
+
state = vue.reactive({
|
|
2667
|
+
datasourceTypeList: [],
|
|
2668
|
+
dataSources: [],
|
|
2669
|
+
editable: true,
|
|
2670
|
+
configs: {},
|
|
2671
|
+
values: {},
|
|
2672
|
+
events: {},
|
|
2673
|
+
methods: {}
|
|
2674
|
+
});
|
|
2675
|
+
constructor() {
|
|
2676
|
+
super(canUsePluginMethods$3.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
2595
2677
|
}
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
if (!root)
|
|
2599
|
-
throw new Error("root不能为空");
|
|
2600
|
-
const { parent, node: curNode } = this.getNodeInfo(node.id, false);
|
|
2601
|
-
if (!parent || !curNode)
|
|
2602
|
-
throw new Error("找不要删除的节点");
|
|
2603
|
-
const index = getNodeIndex(curNode.id, parent);
|
|
2604
|
-
if (typeof index !== "number" || index === -1)
|
|
2605
|
-
throw new Error("找不要删除的节点");
|
|
2606
|
-
parent.items?.splice(index, 1);
|
|
2607
|
-
const stage = this.get("stage");
|
|
2608
|
-
stage?.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
|
|
2609
|
-
const selectDefault = async (pages) => {
|
|
2610
|
-
if (pages[0]) {
|
|
2611
|
-
await this.select(pages[0]);
|
|
2612
|
-
stage?.select(pages[0].id);
|
|
2613
|
-
} else {
|
|
2614
|
-
this.selectRoot();
|
|
2615
|
-
historyService.resetPage();
|
|
2616
|
-
}
|
|
2617
|
-
};
|
|
2618
|
-
const rootItems = root.items || [];
|
|
2619
|
-
if (utils.isPage(node)) {
|
|
2620
|
-
this.state.pageLength -= 1;
|
|
2621
|
-
await selectDefault(getPageList(root));
|
|
2622
|
-
} else if (utils.isPageFragment(node)) {
|
|
2623
|
-
this.state.pageFragmentLength -= 1;
|
|
2624
|
-
await selectDefault(getPageFragmentList(root));
|
|
2625
|
-
} else {
|
|
2626
|
-
await this.select(parent);
|
|
2627
|
-
stage?.select(parent.id);
|
|
2628
|
-
this.addModifiedNodeId(parent.id);
|
|
2629
|
-
}
|
|
2630
|
-
if (!rootItems.length) {
|
|
2631
|
-
this.resetModifiedNodeId();
|
|
2632
|
-
historyService.reset();
|
|
2633
|
-
}
|
|
2678
|
+
set(name, value) {
|
|
2679
|
+
this.state[name] = value;
|
|
2634
2680
|
}
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
* @param {Object} node
|
|
2638
|
-
*/
|
|
2639
|
-
async remove(nodeOrNodeList) {
|
|
2640
|
-
const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
|
|
2641
|
-
await Promise.all(nodes.map((node) => this.doRemove(node)));
|
|
2642
|
-
if (!(utils.isPage(nodes[0]) || utils.isPageFragment(nodes[0]))) {
|
|
2643
|
-
this.pushHistoryState();
|
|
2644
|
-
}
|
|
2645
|
-
this.emit("remove", nodes);
|
|
2681
|
+
get(name) {
|
|
2682
|
+
return this.state[name];
|
|
2646
2683
|
}
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
const parentNodeItems = parent.items;
|
|
2679
|
-
const index = getNodeIndex(newConfig.id, parent);
|
|
2680
|
-
if (!parentNodeItems || typeof index === "undefined" || index === -1)
|
|
2681
|
-
throw new Error("更新的节点未找到");
|
|
2682
|
-
const newLayout = await this.getLayout(newConfig);
|
|
2683
|
-
const layout = await this.getLayout(node);
|
|
2684
|
-
if (Array.isArray(newConfig.items) && newLayout !== layout) {
|
|
2685
|
-
newConfig = setChildrenLayout(newConfig, newLayout);
|
|
2686
|
-
}
|
|
2687
|
-
parentNodeItems[index] = newConfig;
|
|
2688
|
-
const nodes = this.get("nodes");
|
|
2689
|
-
const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
2690
|
-
nodes.splice(targetIndex, 1, newConfig);
|
|
2691
|
-
this.set("nodes", [...nodes]);
|
|
2692
|
-
this.get("stage")?.update({
|
|
2693
|
-
config: lodashEs.cloneDeep(newConfig),
|
|
2694
|
-
parentId: parent.id,
|
|
2695
|
-
root: lodashEs.cloneDeep(root)
|
|
2696
|
-
});
|
|
2697
|
-
if (utils.isPage(newConfig) || utils.isPageFragment(newConfig)) {
|
|
2698
|
-
this.set("page", newConfig);
|
|
2699
|
-
}
|
|
2700
|
-
this.addModifiedNodeId(newConfig.id);
|
|
2684
|
+
getFormConfig(type = "base") {
|
|
2685
|
+
return getFormConfig(utils.toLine(type), this.get("configs"));
|
|
2686
|
+
}
|
|
2687
|
+
setFormConfig(type, config) {
|
|
2688
|
+
this.get("configs")[utils.toLine(type)] = config;
|
|
2689
|
+
}
|
|
2690
|
+
getFormValue(type = "base") {
|
|
2691
|
+
return getFormValue(utils.toLine(type), this.get("values")[type]);
|
|
2692
|
+
}
|
|
2693
|
+
setFormValue(type, value) {
|
|
2694
|
+
this.get("values")[utils.toLine(type)] = value;
|
|
2695
|
+
}
|
|
2696
|
+
getFormEvent(type = "base") {
|
|
2697
|
+
return this.get("events")[utils.toLine(type)] || [];
|
|
2698
|
+
}
|
|
2699
|
+
setFormEvent(type, value = []) {
|
|
2700
|
+
this.get("events")[utils.toLine(type)] = value;
|
|
2701
|
+
}
|
|
2702
|
+
getFormMethod(type = "base") {
|
|
2703
|
+
return this.get("methods")[utils.toLine(type)] || [];
|
|
2704
|
+
}
|
|
2705
|
+
setFormMethod(type, value = []) {
|
|
2706
|
+
this.get("methods")[utils.toLine(type)] = value;
|
|
2707
|
+
}
|
|
2708
|
+
add(config) {
|
|
2709
|
+
const newConfig = {
|
|
2710
|
+
...config,
|
|
2711
|
+
id: config.id && !this.getDataSourceById(config.id) ? config.id : this.createId()
|
|
2712
|
+
};
|
|
2713
|
+
this.get("dataSources").push(newConfig);
|
|
2714
|
+
this.emit("add", newConfig);
|
|
2701
2715
|
return newConfig;
|
|
2702
2716
|
}
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
this.emit("
|
|
2715
|
-
|
|
2717
|
+
update(config) {
|
|
2718
|
+
const dataSources = this.get("dataSources");
|
|
2719
|
+
const index = dataSources.findIndex((ds) => ds.id === config.id);
|
|
2720
|
+
dataSources[index] = lodashEs.cloneDeep(config);
|
|
2721
|
+
this.emit("update", config);
|
|
2722
|
+
return config;
|
|
2723
|
+
}
|
|
2724
|
+
remove(id) {
|
|
2725
|
+
const dataSources = this.get("dataSources");
|
|
2726
|
+
const index = dataSources.findIndex((ds) => ds.id === id);
|
|
2727
|
+
dataSources.splice(index, 1);
|
|
2728
|
+
this.emit("remove", id);
|
|
2729
|
+
}
|
|
2730
|
+
createId() {
|
|
2731
|
+
return `ds_${utils.guid()}`;
|
|
2732
|
+
}
|
|
2733
|
+
getDataSourceById(id) {
|
|
2734
|
+
return this.get("dataSources").find((ds) => ds.id === id);
|
|
2716
2735
|
}
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
* @param id1 组件ID
|
|
2720
|
-
* @param id2 组件ID
|
|
2721
|
-
* @returns void
|
|
2722
|
-
*/
|
|
2723
|
-
async sort(id1, id2) {
|
|
2724
|
-
const root = this.get("root");
|
|
2725
|
-
if (!root)
|
|
2726
|
-
throw new Error("root为空");
|
|
2727
|
-
const node = this.get("node");
|
|
2728
|
-
if (!node)
|
|
2729
|
-
throw new Error("当前节点为空");
|
|
2730
|
-
const parent = lodashEs.cloneDeep(vue.toRaw(this.get("parent")));
|
|
2731
|
-
if (!parent)
|
|
2732
|
-
throw new Error("父节点为空");
|
|
2733
|
-
const index2 = parent.items.findIndex((node2) => `${node2.id}` === `${id2}`);
|
|
2734
|
-
if (index2 < 0)
|
|
2735
|
-
return;
|
|
2736
|
-
const index1 = parent.items.findIndex((node2) => `${node2.id}` === `${id1}`);
|
|
2737
|
-
parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
|
|
2738
|
-
await this.update(parent);
|
|
2739
|
-
await this.select(node);
|
|
2740
|
-
this.get("stage")?.update({
|
|
2741
|
-
config: lodashEs.cloneDeep(node),
|
|
2742
|
-
parentId: parent.id,
|
|
2743
|
-
root: lodashEs.cloneDeep(root)
|
|
2744
|
-
});
|
|
2745
|
-
this.addModifiedNodeId(parent.id);
|
|
2746
|
-
this.pushHistoryState();
|
|
2736
|
+
resetState() {
|
|
2737
|
+
this.set("dataSources", []);
|
|
2747
2738
|
}
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
protocol: Protocol.OBJECT
|
|
2756
|
-
});
|
|
2739
|
+
destroy() {
|
|
2740
|
+
this.removeAllListeners();
|
|
2741
|
+
this.resetState();
|
|
2742
|
+
this.removeAllPlugins();
|
|
2743
|
+
}
|
|
2744
|
+
usePlugin(options) {
|
|
2745
|
+
super.usePlugin(options);
|
|
2757
2746
|
}
|
|
2758
2747
|
/**
|
|
2759
|
-
*
|
|
2748
|
+
* 复制时会带上组件关联的数据源
|
|
2760
2749
|
* @param config 组件节点配置
|
|
2761
2750
|
* @returns
|
|
2762
2751
|
*/
|
|
2763
2752
|
copyWithRelated(config) {
|
|
2764
2753
|
const copyNodes = Array.isArray(config) ? config : [config];
|
|
2765
|
-
depService.clearByType(dep.DepTargetType.
|
|
2766
|
-
depService.collect(copyNodes, true, dep.DepTargetType.
|
|
2767
|
-
const customTarget = depService.getTarget(
|
|
2768
|
-
|
|
2769
|
-
dep.DepTargetType.RELATED_COMP_WHEN_COPY
|
|
2770
|
-
);
|
|
2754
|
+
depService.clearByType(dep.DepTargetType.RELATED_DS_WHEN_COPY);
|
|
2755
|
+
depService.collect(copyNodes, true, dep.DepTargetType.RELATED_DS_WHEN_COPY);
|
|
2756
|
+
const customTarget = depService.getTarget(dep.DepTargetType.RELATED_DS_WHEN_COPY, dep.DepTargetType.RELATED_DS_WHEN_COPY);
|
|
2757
|
+
const copyData = [];
|
|
2771
2758
|
if (customTarget) {
|
|
2772
2759
|
Object.keys(customTarget.deps).forEach((nodeId) => {
|
|
2773
|
-
const node =
|
|
2760
|
+
const node = editorService.getNodeById(nodeId);
|
|
2774
2761
|
if (!node)
|
|
2775
2762
|
return;
|
|
2776
2763
|
customTarget.deps[nodeId].keys.forEach((key) => {
|
|
2777
|
-
const
|
|
2778
|
-
const isExist =
|
|
2764
|
+
const [relateDsId] = lodashEs.get(node, key);
|
|
2765
|
+
const isExist = copyData.find((dsItem) => dsItem.id === relateDsId);
|
|
2779
2766
|
if (!isExist) {
|
|
2780
|
-
const
|
|
2781
|
-
if (
|
|
2782
|
-
|
|
2767
|
+
const relateDs = this.getDataSourceById(relateDsId);
|
|
2768
|
+
if (relateDs) {
|
|
2769
|
+
copyData.push(relateDs);
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
});
|
|
2773
|
+
});
|
|
2774
|
+
}
|
|
2775
|
+
storageService.setItem(COPY_DS_STORAGE_KEY, copyData, {
|
|
2776
|
+
protocol: Protocol.OBJECT
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
/**
|
|
2780
|
+
* 粘贴数据源
|
|
2781
|
+
* @returns
|
|
2782
|
+
*/
|
|
2783
|
+
paste() {
|
|
2784
|
+
const dataSource = storageService.getItem(COPY_DS_STORAGE_KEY);
|
|
2785
|
+
dataSource.forEach((item) => {
|
|
2786
|
+
if (!this.getDataSourceById(item.id)) {
|
|
2787
|
+
this.add(item);
|
|
2788
|
+
}
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
const dataSourceService = new DataSource();
|
|
2793
|
+
|
|
2794
|
+
const arrayOptions = [
|
|
2795
|
+
{ text: "包含", value: "include" },
|
|
2796
|
+
{ text: "不包含", value: "not_include" }
|
|
2797
|
+
];
|
|
2798
|
+
const eqOptions = [
|
|
2799
|
+
{ text: "等于", value: "=" },
|
|
2800
|
+
{ text: "不等于", value: "!=" }
|
|
2801
|
+
];
|
|
2802
|
+
const numberOptions = [
|
|
2803
|
+
{ text: "大于", value: ">" },
|
|
2804
|
+
{ text: "大于等于", value: ">=" },
|
|
2805
|
+
{ text: "小于", value: "<" },
|
|
2806
|
+
{ text: "小于等于", value: "<=" },
|
|
2807
|
+
{ text: "在范围内", value: "between" },
|
|
2808
|
+
{ text: "不在范围内", value: "not_between" }
|
|
2809
|
+
];
|
|
2810
|
+
const styleTabConfig = {
|
|
2811
|
+
title: "样式",
|
|
2812
|
+
items: [
|
|
2813
|
+
{
|
|
2814
|
+
name: "style",
|
|
2815
|
+
items: [
|
|
2816
|
+
{
|
|
2817
|
+
type: "fieldset",
|
|
2818
|
+
legend: "位置",
|
|
2819
|
+
items: [
|
|
2820
|
+
{
|
|
2821
|
+
type: "data-source-field-select",
|
|
2822
|
+
name: "position",
|
|
2823
|
+
text: "固定定位",
|
|
2824
|
+
checkStrictly: false,
|
|
2825
|
+
dataSourceFieldType: ["string"],
|
|
2826
|
+
fieldConfig: {
|
|
2827
|
+
type: "checkbox",
|
|
2828
|
+
activeValue: "fixed",
|
|
2829
|
+
inactiveValue: "absolute",
|
|
2830
|
+
defaultValue: "absolute"
|
|
2831
|
+
}
|
|
2832
|
+
},
|
|
2833
|
+
{
|
|
2834
|
+
type: "data-source-field-select",
|
|
2835
|
+
name: "left",
|
|
2836
|
+
text: "left",
|
|
2837
|
+
checkStrictly: false,
|
|
2838
|
+
dataSourceFieldType: ["string", "number"],
|
|
2839
|
+
fieldConfig: {
|
|
2840
|
+
type: "text"
|
|
2841
|
+
}
|
|
2842
|
+
},
|
|
2843
|
+
{
|
|
2844
|
+
type: "data-source-field-select",
|
|
2845
|
+
name: "top",
|
|
2846
|
+
text: "top",
|
|
2847
|
+
checkStrictly: false,
|
|
2848
|
+
dataSourceFieldType: ["string", "number"],
|
|
2849
|
+
fieldConfig: {
|
|
2850
|
+
type: "text"
|
|
2851
|
+
},
|
|
2852
|
+
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedBottom"
|
|
2853
|
+
},
|
|
2854
|
+
{
|
|
2855
|
+
type: "data-source-field-select",
|
|
2856
|
+
name: "right",
|
|
2857
|
+
text: "right",
|
|
2858
|
+
checkStrictly: false,
|
|
2859
|
+
dataSourceFieldType: ["string", "number"],
|
|
2860
|
+
fieldConfig: {
|
|
2861
|
+
type: "text"
|
|
2862
|
+
}
|
|
2863
|
+
},
|
|
2864
|
+
{
|
|
2865
|
+
type: "data-source-field-select",
|
|
2866
|
+
name: "bottom",
|
|
2867
|
+
text: "bottom",
|
|
2868
|
+
checkStrictly: false,
|
|
2869
|
+
dataSourceFieldType: ["string", "number"],
|
|
2870
|
+
fieldConfig: {
|
|
2871
|
+
type: "text"
|
|
2872
|
+
},
|
|
2873
|
+
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedTop"
|
|
2874
|
+
}
|
|
2875
|
+
]
|
|
2876
|
+
},
|
|
2877
|
+
{
|
|
2878
|
+
type: "fieldset",
|
|
2879
|
+
legend: "盒子",
|
|
2880
|
+
items: [
|
|
2881
|
+
{
|
|
2882
|
+
type: "data-source-field-select",
|
|
2883
|
+
name: "width",
|
|
2884
|
+
text: "宽度",
|
|
2885
|
+
checkStrictly: false,
|
|
2886
|
+
dataSourceFieldType: ["string", "number"],
|
|
2887
|
+
fieldConfig: {
|
|
2888
|
+
type: "text"
|
|
2889
|
+
}
|
|
2890
|
+
},
|
|
2891
|
+
{
|
|
2892
|
+
type: "data-source-field-select",
|
|
2893
|
+
name: "height",
|
|
2894
|
+
text: "高度",
|
|
2895
|
+
checkStrictly: false,
|
|
2896
|
+
dataSourceFieldType: ["string", "number"],
|
|
2897
|
+
fieldConfig: {
|
|
2898
|
+
type: "text"
|
|
2899
|
+
}
|
|
2900
|
+
},
|
|
2901
|
+
{
|
|
2902
|
+
type: "data-source-field-select",
|
|
2903
|
+
text: "overflow",
|
|
2904
|
+
name: "overflow",
|
|
2905
|
+
checkStrictly: false,
|
|
2906
|
+
dataSourceFieldType: ["string"],
|
|
2907
|
+
fieldConfig: {
|
|
2908
|
+
type: "select",
|
|
2909
|
+
options: [
|
|
2910
|
+
{ text: "visible", value: "visible" },
|
|
2911
|
+
{ text: "hidden", value: "hidden" },
|
|
2912
|
+
{ text: "clip", value: "clip" },
|
|
2913
|
+
{ text: "scroll", value: "scroll" },
|
|
2914
|
+
{ text: "auto", value: "auto" },
|
|
2915
|
+
{ text: "overlay", value: "overlay" }
|
|
2916
|
+
]
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
]
|
|
2920
|
+
},
|
|
2921
|
+
{
|
|
2922
|
+
type: "fieldset",
|
|
2923
|
+
legend: "边框",
|
|
2924
|
+
items: [
|
|
2925
|
+
{
|
|
2926
|
+
type: "data-source-field-select",
|
|
2927
|
+
name: "borderWidth",
|
|
2928
|
+
text: "宽度",
|
|
2929
|
+
defaultValue: "0",
|
|
2930
|
+
checkStrictly: false,
|
|
2931
|
+
dataSourceFieldType: ["string", "number"],
|
|
2932
|
+
fieldConfig: {
|
|
2933
|
+
type: "text"
|
|
2934
|
+
}
|
|
2935
|
+
},
|
|
2936
|
+
{
|
|
2937
|
+
type: "data-source-field-select",
|
|
2938
|
+
name: "borderColor",
|
|
2939
|
+
text: "颜色",
|
|
2940
|
+
checkStrictly: false,
|
|
2941
|
+
dataSourceFieldType: ["string"],
|
|
2942
|
+
fieldConfig: {
|
|
2943
|
+
type: "text"
|
|
2944
|
+
}
|
|
2945
|
+
},
|
|
2946
|
+
{
|
|
2947
|
+
type: "data-source-field-select",
|
|
2948
|
+
name: "borderStyle",
|
|
2949
|
+
text: "样式",
|
|
2950
|
+
defaultValue: "none",
|
|
2951
|
+
checkStrictly: false,
|
|
2952
|
+
dataSourceFieldType: ["string"],
|
|
2953
|
+
fieldConfig: {
|
|
2954
|
+
type: "select",
|
|
2955
|
+
options: [
|
|
2956
|
+
{ text: "none", value: "none" },
|
|
2957
|
+
{ text: "hidden", value: "hidden" },
|
|
2958
|
+
{ text: "dotted", value: "dotted" },
|
|
2959
|
+
{ text: "dashed", value: "dashed" },
|
|
2960
|
+
{ text: "solid", value: "solid" },
|
|
2961
|
+
{ text: "double", value: "double" },
|
|
2962
|
+
{ text: "groove", value: "groove" },
|
|
2963
|
+
{ text: "ridge", value: "ridge" },
|
|
2964
|
+
{ text: "inset", value: "inset" },
|
|
2965
|
+
{ text: "outset", value: "outset" }
|
|
2966
|
+
]
|
|
2967
|
+
}
|
|
2783
2968
|
}
|
|
2784
|
-
|
|
2785
|
-
}
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
* 移动到指定容器中
|
|
2904
|
-
* @param config 需要移动的节点
|
|
2905
|
-
* @param targetId 容器ID
|
|
2906
|
-
*/
|
|
2907
|
-
async moveToContainer(config, targetId) {
|
|
2908
|
-
const root = this.get("root");
|
|
2909
|
-
const { node, parent } = this.getNodeInfo(config.id, false);
|
|
2910
|
-
const target = this.getNodeById(targetId, false);
|
|
2911
|
-
const stage = this.get("stage");
|
|
2912
|
-
if (root && node && parent && stage) {
|
|
2913
|
-
const index = getNodeIndex(node.id, parent);
|
|
2914
|
-
parent.items?.splice(index, 1);
|
|
2915
|
-
await stage.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
|
|
2916
|
-
const layout = await this.getLayout(target);
|
|
2917
|
-
const newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), config, (objValue, srcValue) => {
|
|
2918
|
-
if (Array.isArray(srcValue)) {
|
|
2919
|
-
return srcValue;
|
|
2969
|
+
]
|
|
2970
|
+
},
|
|
2971
|
+
{
|
|
2972
|
+
type: "fieldset",
|
|
2973
|
+
legend: "背景",
|
|
2974
|
+
items: [
|
|
2975
|
+
{
|
|
2976
|
+
type: "data-source-field-select",
|
|
2977
|
+
name: "backgroundImage",
|
|
2978
|
+
text: "背景图",
|
|
2979
|
+
checkStrictly: false,
|
|
2980
|
+
dataSourceFieldType: ["string"],
|
|
2981
|
+
fieldConfig: {
|
|
2982
|
+
type: "text"
|
|
2983
|
+
}
|
|
2984
|
+
},
|
|
2985
|
+
{
|
|
2986
|
+
type: "data-source-field-select",
|
|
2987
|
+
name: "backgroundColor",
|
|
2988
|
+
text: "背景颜色",
|
|
2989
|
+
checkStrictly: false,
|
|
2990
|
+
dataSourceFieldType: ["string"],
|
|
2991
|
+
fieldConfig: {
|
|
2992
|
+
type: "colorPicker"
|
|
2993
|
+
}
|
|
2994
|
+
},
|
|
2995
|
+
{
|
|
2996
|
+
type: "data-source-field-select",
|
|
2997
|
+
name: "backgroundRepeat",
|
|
2998
|
+
text: "背景图重复",
|
|
2999
|
+
defaultValue: "no-repeat",
|
|
3000
|
+
checkStrictly: false,
|
|
3001
|
+
dataSourceFieldType: ["string"],
|
|
3002
|
+
fieldConfig: {
|
|
3003
|
+
type: "select",
|
|
3004
|
+
options: [
|
|
3005
|
+
{ text: "repeat", value: "repeat" },
|
|
3006
|
+
{ text: "repeat-x", value: "repeat-x" },
|
|
3007
|
+
{ text: "repeat-y", value: "repeat-y" },
|
|
3008
|
+
{ text: "no-repeat", value: "no-repeat" },
|
|
3009
|
+
{ text: "inherit", value: "inherit" }
|
|
3010
|
+
]
|
|
3011
|
+
}
|
|
3012
|
+
},
|
|
3013
|
+
{
|
|
3014
|
+
type: "data-source-field-select",
|
|
3015
|
+
name: "backgroundSize",
|
|
3016
|
+
text: "背景图大小",
|
|
3017
|
+
defaultValue: "100% 100%",
|
|
3018
|
+
checkStrictly: false,
|
|
3019
|
+
dataSourceFieldType: ["string"],
|
|
3020
|
+
fieldConfig: {
|
|
3021
|
+
type: "text"
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
]
|
|
3025
|
+
},
|
|
3026
|
+
{
|
|
3027
|
+
type: "fieldset",
|
|
3028
|
+
legend: "字体",
|
|
3029
|
+
items: [
|
|
3030
|
+
{
|
|
3031
|
+
type: "data-source-field-select",
|
|
3032
|
+
name: "color",
|
|
3033
|
+
text: "颜色",
|
|
3034
|
+
checkStrictly: false,
|
|
3035
|
+
dataSourceFieldType: ["string"],
|
|
3036
|
+
fieldConfig: {
|
|
3037
|
+
type: "colorPicker"
|
|
3038
|
+
}
|
|
3039
|
+
},
|
|
3040
|
+
{
|
|
3041
|
+
type: "data-source-field-select",
|
|
3042
|
+
name: "fontSize",
|
|
3043
|
+
text: "大小",
|
|
3044
|
+
checkStrictly: false,
|
|
3045
|
+
dataSourceFieldType: ["string", "number"],
|
|
3046
|
+
fieldConfig: {
|
|
3047
|
+
type: "text"
|
|
3048
|
+
}
|
|
3049
|
+
},
|
|
3050
|
+
{
|
|
3051
|
+
type: "data-source-field-select",
|
|
3052
|
+
name: "fontWeight",
|
|
3053
|
+
text: "粗细",
|
|
3054
|
+
checkStrictly: false,
|
|
3055
|
+
dataSourceFieldType: ["string", "number"],
|
|
3056
|
+
fieldConfig: {
|
|
3057
|
+
type: "text"
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
]
|
|
3061
|
+
},
|
|
3062
|
+
{
|
|
3063
|
+
type: "fieldset",
|
|
3064
|
+
legend: "变形",
|
|
3065
|
+
name: "transform",
|
|
3066
|
+
items: [
|
|
3067
|
+
{
|
|
3068
|
+
type: "data-source-field-select",
|
|
3069
|
+
name: "rotate",
|
|
3070
|
+
text: "旋转角度",
|
|
3071
|
+
checkStrictly: false,
|
|
3072
|
+
dataSourceFieldType: ["string"],
|
|
3073
|
+
fieldConfig: {
|
|
3074
|
+
type: "text"
|
|
3075
|
+
}
|
|
3076
|
+
},
|
|
3077
|
+
{
|
|
3078
|
+
type: "data-source-field-select",
|
|
3079
|
+
name: "scale",
|
|
3080
|
+
text: "缩放",
|
|
3081
|
+
checkStrictly: false,
|
|
3082
|
+
dataSourceFieldType: ["number", "string"],
|
|
3083
|
+
fieldConfig: {
|
|
3084
|
+
type: "text"
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
]
|
|
2920
3088
|
}
|
|
2921
|
-
|
|
2922
|
-
newConfig.style = getInitPositionStyle(newConfig.style, layout);
|
|
2923
|
-
target.items.push(newConfig);
|
|
2924
|
-
await stage.select(targetId);
|
|
2925
|
-
const targetParent = this.getParentById(target.id);
|
|
2926
|
-
await stage.update({ config: lodashEs.cloneDeep(target), parentId: targetParent?.id, root: lodashEs.cloneDeep(root) });
|
|
2927
|
-
await this.select(newConfig);
|
|
2928
|
-
stage.select(newConfig.id);
|
|
2929
|
-
this.addModifiedNodeId(target.id);
|
|
2930
|
-
this.addModifiedNodeId(parent.id);
|
|
2931
|
-
this.pushHistoryState();
|
|
2932
|
-
return newConfig;
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
|
-
async dragTo(config, targetParent, targetIndex) {
|
|
2936
|
-
if (!targetParent || !Array.isArray(targetParent.items))
|
|
2937
|
-
return;
|
|
2938
|
-
const { parent, node: curNode } = this.getNodeInfo(config.id, false);
|
|
2939
|
-
if (!parent || !curNode)
|
|
2940
|
-
throw new Error("找不要删除的节点");
|
|
2941
|
-
const index = getNodeIndex(curNode.id, parent);
|
|
2942
|
-
if (typeof index !== "number" || index === -1)
|
|
2943
|
-
throw new Error("找不要删除的节点");
|
|
2944
|
-
if (parent.id === targetParent.id) {
|
|
2945
|
-
if (index === targetIndex)
|
|
2946
|
-
return;
|
|
2947
|
-
if (index < targetIndex) {
|
|
2948
|
-
targetIndex -= 1;
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
const layout = await this.getLayout(parent);
|
|
2952
|
-
const newLayout = await this.getLayout(targetParent);
|
|
2953
|
-
if (newLayout !== layout) {
|
|
2954
|
-
setLayout(config, newLayout);
|
|
2955
|
-
}
|
|
2956
|
-
parent.items?.splice(index, 1);
|
|
2957
|
-
targetParent.items?.splice(targetIndex, 0, config);
|
|
2958
|
-
const page = this.get("page");
|
|
2959
|
-
const root = this.get("root");
|
|
2960
|
-
const stage = this.get("stage");
|
|
2961
|
-
if (stage && page && root) {
|
|
2962
|
-
stage.update({
|
|
2963
|
-
config: lodashEs.cloneDeep(page),
|
|
2964
|
-
parentId: root.id,
|
|
2965
|
-
root: lodashEs.cloneDeep(root)
|
|
2966
|
-
});
|
|
2967
|
-
}
|
|
2968
|
-
this.addModifiedNodeId(config.id);
|
|
2969
|
-
this.addModifiedNodeId(parent.id);
|
|
2970
|
-
this.pushHistoryState();
|
|
2971
|
-
this.emit("drag-to", { index, targetIndex, config, parent, targetParent });
|
|
2972
|
-
}
|
|
2973
|
-
/**
|
|
2974
|
-
* 撤销当前操作
|
|
2975
|
-
* @returns 上一次数据
|
|
2976
|
-
*/
|
|
2977
|
-
async undo() {
|
|
2978
|
-
const value = historyService.undo();
|
|
2979
|
-
await this.changeHistoryState(value);
|
|
2980
|
-
return value;
|
|
2981
|
-
}
|
|
2982
|
-
/**
|
|
2983
|
-
* 恢复到下一步
|
|
2984
|
-
* @returns 下一步数据
|
|
2985
|
-
*/
|
|
2986
|
-
async redo() {
|
|
2987
|
-
const value = historyService.redo();
|
|
2988
|
-
await this.changeHistoryState(value);
|
|
2989
|
-
return value;
|
|
2990
|
-
}
|
|
2991
|
-
async move(left, top) {
|
|
2992
|
-
const node = vue.toRaw(this.get("node"));
|
|
2993
|
-
if (!node || utils.isPage(node))
|
|
2994
|
-
return;
|
|
2995
|
-
const { style, id, type } = node;
|
|
2996
|
-
if (!style || !["absolute", "fixed"].includes(style.position))
|
|
2997
|
-
return;
|
|
2998
|
-
const update = (style2) => this.update({
|
|
2999
|
-
id,
|
|
3000
|
-
type,
|
|
3001
|
-
style: style2
|
|
3002
|
-
});
|
|
3003
|
-
if (top) {
|
|
3004
|
-
if (utils.isNumber(style.top)) {
|
|
3005
|
-
update({
|
|
3006
|
-
...style,
|
|
3007
|
-
top: Number(style.top) + Number(top),
|
|
3008
|
-
bottom: ""
|
|
3009
|
-
});
|
|
3010
|
-
} else if (utils.isNumber(style.bottom)) {
|
|
3011
|
-
update({
|
|
3012
|
-
...style,
|
|
3013
|
-
bottom: Number(style.bottom) - Number(top),
|
|
3014
|
-
top: ""
|
|
3015
|
-
});
|
|
3016
|
-
}
|
|
3089
|
+
]
|
|
3017
3090
|
}
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
right: Number(style.right) - Number(left),
|
|
3029
|
-
left: ""
|
|
3030
|
-
});
|
|
3031
|
-
}
|
|
3091
|
+
]
|
|
3092
|
+
};
|
|
3093
|
+
const eventTabConfig = {
|
|
3094
|
+
title: "事件",
|
|
3095
|
+
items: [
|
|
3096
|
+
{
|
|
3097
|
+
name: "events",
|
|
3098
|
+
src: "component",
|
|
3099
|
+
labelWidth: "100px",
|
|
3100
|
+
type: "event-select"
|
|
3032
3101
|
}
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
this.removeAllPlugins();
|
|
3049
|
-
}
|
|
3050
|
-
resetModifiedNodeId() {
|
|
3051
|
-
this.get("modifiedNodeIds").clear();
|
|
3052
|
-
}
|
|
3053
|
-
usePlugin(options) {
|
|
3054
|
-
super.usePlugin(options);
|
|
3055
|
-
}
|
|
3056
|
-
addModifiedNodeId(id) {
|
|
3057
|
-
if (!this.isHistoryStateChange) {
|
|
3058
|
-
this.get("modifiedNodeIds").set(id, id);
|
|
3102
|
+
]
|
|
3103
|
+
};
|
|
3104
|
+
const advancedTabConfig = {
|
|
3105
|
+
title: "高级",
|
|
3106
|
+
lazy: true,
|
|
3107
|
+
items: [
|
|
3108
|
+
{
|
|
3109
|
+
name: "created",
|
|
3110
|
+
text: "created",
|
|
3111
|
+
type: "code-select"
|
|
3112
|
+
},
|
|
3113
|
+
{
|
|
3114
|
+
name: "mounted",
|
|
3115
|
+
text: "mounted",
|
|
3116
|
+
type: "code-select"
|
|
3059
3117
|
}
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3118
|
+
]
|
|
3119
|
+
};
|
|
3120
|
+
const displayTabConfig = {
|
|
3121
|
+
title: "显示条件",
|
|
3122
|
+
display: (vm, { model }) => model.type !== "page",
|
|
3123
|
+
items: [
|
|
3124
|
+
{
|
|
3125
|
+
type: "groupList",
|
|
3126
|
+
name: "displayConds",
|
|
3127
|
+
titlePrefix: "条件组",
|
|
3128
|
+
expandAll: true,
|
|
3129
|
+
items: [
|
|
3130
|
+
{
|
|
3131
|
+
type: "table",
|
|
3132
|
+
name: "cond",
|
|
3133
|
+
items: [
|
|
3134
|
+
{
|
|
3135
|
+
type: "data-source-field-select",
|
|
3136
|
+
name: "field",
|
|
3137
|
+
value: "key",
|
|
3138
|
+
label: "字段",
|
|
3139
|
+
checkStrictly: false,
|
|
3140
|
+
dataSourceFieldType: ["string", "number", "boolean", "any"]
|
|
3141
|
+
},
|
|
3142
|
+
{
|
|
3143
|
+
type: "select",
|
|
3144
|
+
options: (mForm, { model }) => {
|
|
3145
|
+
const [id, ...fieldNames] = model.field;
|
|
3146
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
3147
|
+
let fields = ds?.fields || [];
|
|
3148
|
+
let type = "";
|
|
3149
|
+
(fieldNames || []).forEach((fieldName) => {
|
|
3150
|
+
const field = fields.find((f) => f.name === fieldName);
|
|
3151
|
+
fields = field?.fields || [];
|
|
3152
|
+
type = field?.type || "";
|
|
3153
|
+
});
|
|
3154
|
+
if (type === "array") {
|
|
3155
|
+
return arrayOptions;
|
|
3156
|
+
}
|
|
3157
|
+
if (type === "boolean") {
|
|
3158
|
+
return [
|
|
3159
|
+
{ text: "是", value: "is" },
|
|
3160
|
+
{ text: "不是", value: "not" }
|
|
3161
|
+
];
|
|
3162
|
+
}
|
|
3163
|
+
if (type === "number") {
|
|
3164
|
+
return [...eqOptions, ...numberOptions];
|
|
3165
|
+
}
|
|
3166
|
+
if (type === "string") {
|
|
3167
|
+
return [...arrayOptions, ...eqOptions];
|
|
3168
|
+
}
|
|
3169
|
+
return [...arrayOptions, ...eqOptions, ...numberOptions];
|
|
3170
|
+
},
|
|
3171
|
+
label: "条件",
|
|
3172
|
+
name: "op"
|
|
3173
|
+
},
|
|
3174
|
+
{
|
|
3175
|
+
label: "值",
|
|
3176
|
+
items: [
|
|
3177
|
+
{
|
|
3178
|
+
name: "value",
|
|
3179
|
+
type: (mForm, { model }) => {
|
|
3180
|
+
const [id, ...fieldNames] = model.field;
|
|
3181
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
3182
|
+
let fields = ds?.fields || [];
|
|
3183
|
+
let type = "";
|
|
3184
|
+
(fieldNames || []).forEach((fieldName) => {
|
|
3185
|
+
const field = fields.find((f) => f.name === fieldName);
|
|
3186
|
+
fields = field?.fields || [];
|
|
3187
|
+
type = field?.type || "";
|
|
3188
|
+
});
|
|
3189
|
+
if (type === "number") {
|
|
3190
|
+
return "number";
|
|
3191
|
+
}
|
|
3192
|
+
if (type === "boolean") {
|
|
3193
|
+
return "select";
|
|
3194
|
+
}
|
|
3195
|
+
return "text";
|
|
3196
|
+
},
|
|
3197
|
+
options: [
|
|
3198
|
+
{ text: "true", value: true },
|
|
3199
|
+
{ text: "false", value: false }
|
|
3200
|
+
],
|
|
3201
|
+
display: (vm, { model }) => !["between", "not_between"].includes(model.op)
|
|
3202
|
+
},
|
|
3203
|
+
{
|
|
3204
|
+
name: "range",
|
|
3205
|
+
type: "number-range",
|
|
3206
|
+
display: (vm, { model }) => ["between", "not_between"].includes(model.op)
|
|
3207
|
+
}
|
|
3208
|
+
]
|
|
3209
|
+
}
|
|
3210
|
+
]
|
|
3211
|
+
}
|
|
3212
|
+
]
|
|
3070
3213
|
}
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3214
|
+
]
|
|
3215
|
+
};
|
|
3216
|
+
const fillConfig = (config = [], labelWidth = "80px") => [
|
|
3217
|
+
{
|
|
3218
|
+
type: "tab",
|
|
3219
|
+
labelWidth,
|
|
3220
|
+
items: [
|
|
3221
|
+
{
|
|
3222
|
+
title: "属性",
|
|
3223
|
+
items: [
|
|
3224
|
+
// 组件类型,必须要有
|
|
3225
|
+
{
|
|
3226
|
+
text: "type",
|
|
3227
|
+
name: "type",
|
|
3228
|
+
type: "hidden"
|
|
3229
|
+
},
|
|
3230
|
+
// 组件id,必须要有
|
|
3231
|
+
{
|
|
3232
|
+
name: "id",
|
|
3233
|
+
type: "display",
|
|
3234
|
+
text: "id"
|
|
3235
|
+
},
|
|
3236
|
+
{
|
|
3237
|
+
name: "name",
|
|
3238
|
+
text: "组件名称"
|
|
3239
|
+
},
|
|
3240
|
+
...config
|
|
3241
|
+
]
|
|
3242
|
+
},
|
|
3243
|
+
{ ...styleTabConfig },
|
|
3244
|
+
{ ...eventTabConfig },
|
|
3245
|
+
{ ...advancedTabConfig },
|
|
3246
|
+
{ ...displayTabConfig }
|
|
3247
|
+
]
|
|
3086
3248
|
}
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
} else if (!isFixed(newConfig) && isFixed(src)) {
|
|
3093
|
-
newConfig.style = await Fixed2Other(newConfig, root, this.getLayout);
|
|
3094
|
-
}
|
|
3095
|
-
}
|
|
3096
|
-
return newConfig;
|
|
3249
|
+
];
|
|
3250
|
+
|
|
3251
|
+
const log = (...args) => {
|
|
3252
|
+
if (process.env.NODE_ENV === "development") {
|
|
3253
|
+
console.log("magic editor: ", ...args);
|
|
3097
3254
|
}
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
} else {
|
|
3103
|
-
id = config.id;
|
|
3104
|
-
}
|
|
3105
|
-
if (!id) {
|
|
3106
|
-
throw new Error("没有ID,无法选中");
|
|
3107
|
-
}
|
|
3108
|
-
const { node, parent, page } = this.getNodeInfo(id);
|
|
3109
|
-
if (!node)
|
|
3110
|
-
throw new Error("获取不到组件信息");
|
|
3111
|
-
if (node.id === this.state.root?.id) {
|
|
3112
|
-
throw new Error("不能选根节点");
|
|
3113
|
-
}
|
|
3114
|
-
return {
|
|
3115
|
-
node,
|
|
3116
|
-
parent,
|
|
3117
|
-
page
|
|
3118
|
-
};
|
|
3255
|
+
};
|
|
3256
|
+
const info = (...args) => {
|
|
3257
|
+
if (process.env.NODE_ENV === "development") {
|
|
3258
|
+
console.info("magic editor: ", ...args);
|
|
3119
3259
|
}
|
|
3120
|
-
}
|
|
3121
|
-
const editorService = new Editor();
|
|
3122
|
-
|
|
3123
|
-
const beforePaste = (position, config) => {
|
|
3124
|
-
if (!config[0]?.style)
|
|
3125
|
-
return config;
|
|
3126
|
-
const curNode = editorService.get("node");
|
|
3127
|
-
const { left: referenceLeft, top: referenceTop } = config[0].style;
|
|
3128
|
-
const pasteConfigs = config.map((configItem) => {
|
|
3129
|
-
const { offsetX = 0, offsetY = 0, ...positionClone } = position;
|
|
3130
|
-
let pastePosition = positionClone;
|
|
3131
|
-
if (!lodashEs.isEmpty(pastePosition) && curNode?.items) {
|
|
3132
|
-
pastePosition = getPositionInContainer(pastePosition, curNode.id);
|
|
3133
|
-
}
|
|
3134
|
-
if (pastePosition.left && configItem.style?.left) {
|
|
3135
|
-
pastePosition.left = configItem.style.left - referenceLeft + pastePosition.left;
|
|
3136
|
-
}
|
|
3137
|
-
if (pastePosition.top && configItem.style?.top) {
|
|
3138
|
-
pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
|
|
3139
|
-
}
|
|
3140
|
-
const pasteConfig = propsService.setNewItemId(configItem, false);
|
|
3141
|
-
if (pasteConfig.style) {
|
|
3142
|
-
const { left, top } = pasteConfig.style;
|
|
3143
|
-
if (typeof left === "number" || !!left && !isNaN(Number(left))) {
|
|
3144
|
-
pasteConfig.style.left = Number(left) + offsetX;
|
|
3145
|
-
}
|
|
3146
|
-
if (typeof top === "number" || !!top && !isNaN(Number(top))) {
|
|
3147
|
-
pasteConfig.style.top = Number(top) + offsetY;
|
|
3148
|
-
}
|
|
3149
|
-
pasteConfig.style = {
|
|
3150
|
-
...pasteConfig.style,
|
|
3151
|
-
...pastePosition
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
const root = editorService.get("root");
|
|
3155
|
-
if ((utils.isPage(pasteConfig) || utils.isPageFragment(pasteConfig)) && root) {
|
|
3156
|
-
pasteConfig.name = generatePageNameByApp(root, utils.isPage(pasteConfig) ? schema.NodeType.PAGE : schema.NodeType.PAGE_FRAGMENT);
|
|
3157
|
-
}
|
|
3158
|
-
return pasteConfig;
|
|
3159
|
-
});
|
|
3160
|
-
return pasteConfigs;
|
|
3161
3260
|
};
|
|
3162
|
-
const
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
left = left - (parentElRect?.left || 0);
|
|
3167
|
-
top = top - (parentElRect?.top || 0);
|
|
3168
|
-
return {
|
|
3169
|
-
left,
|
|
3170
|
-
top
|
|
3171
|
-
};
|
|
3261
|
+
const warn = (...args) => {
|
|
3262
|
+
if (process.env.NODE_ENV === "development") {
|
|
3263
|
+
console.warn("magic editor: ", ...args);
|
|
3264
|
+
}
|
|
3172
3265
|
};
|
|
3173
|
-
const
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
if (utils.isPage(node)) {
|
|
3177
|
-
parentNode = editorService.get("root");
|
|
3178
|
-
} else if (curNode?.items) {
|
|
3179
|
-
parentNode = curNode;
|
|
3180
|
-
} else if (curNode?.id) {
|
|
3181
|
-
parentNode = editorService.getParentById(curNode.id, false);
|
|
3266
|
+
const debug = (...args) => {
|
|
3267
|
+
if (process.env.NODE_ENV === "development") {
|
|
3268
|
+
console.debug("magic editor: ", ...args);
|
|
3182
3269
|
}
|
|
3183
|
-
return parentNode;
|
|
3184
3270
|
};
|
|
3185
|
-
const
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
newNode.style = getInitPositionStyle(newNode.style, layout);
|
|
3190
|
-
return newNode;
|
|
3271
|
+
const error = (...args) => {
|
|
3272
|
+
if (process.env.NODE_ENV === "development") {
|
|
3273
|
+
console.error("magic editor: ", ...args);
|
|
3274
|
+
}
|
|
3191
3275
|
};
|
|
3192
3276
|
|
|
3193
3277
|
const _sfc_main$P = /* @__PURE__ */ vue.defineComponent({
|
|
@@ -3577,7 +3661,6 @@
|
|
|
3577
3661
|
if (!codeId.value)
|
|
3578
3662
|
return;
|
|
3579
3663
|
await codeBlockService?.setCodeDslById(codeId.value, values);
|
|
3580
|
-
design.tMagicMessage.success("代码块保存成功");
|
|
3581
3664
|
codeBlockEditor.value?.hide();
|
|
3582
3665
|
};
|
|
3583
3666
|
return {
|
|
@@ -3779,7 +3862,7 @@
|
|
|
3779
3862
|
const stage = new StageCore({
|
|
3780
3863
|
render: stageOptions.render,
|
|
3781
3864
|
runtimeUrl: stageOptions.runtimeUrl,
|
|
3782
|
-
zoom: zoom.value,
|
|
3865
|
+
zoom: stageOptions.zoom ?? zoom.value,
|
|
3783
3866
|
autoScrollIntoView: stageOptions.autoScrollIntoView,
|
|
3784
3867
|
isContainer: stageOptions.isContainer,
|
|
3785
3868
|
containerHighlightClassName: stageOptions.containerHighlightClassName,
|
|
@@ -4360,33 +4443,6 @@
|
|
|
4360
4443
|
return value[0].replace(utils.DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, "");
|
|
4361
4444
|
});
|
|
4362
4445
|
const dataSources = vue.computed(() => services?.dataSourceService.get("dataSources"));
|
|
4363
|
-
const getOptionChildren = (fields = [], dataSourceFieldType = ["any"]) => {
|
|
4364
|
-
const child = [];
|
|
4365
|
-
fields.forEach((field) => {
|
|
4366
|
-
if (!dataSourceFieldType.length) {
|
|
4367
|
-
dataSourceFieldType.push("any");
|
|
4368
|
-
}
|
|
4369
|
-
const children = getOptionChildren(field.fields, dataSourceFieldType);
|
|
4370
|
-
const item = {
|
|
4371
|
-
label: field.title || field.name,
|
|
4372
|
-
value: field.name,
|
|
4373
|
-
children
|
|
4374
|
-
};
|
|
4375
|
-
const fieldType = field.type || "any";
|
|
4376
|
-
if (dataSourceFieldType.includes("any") || dataSourceFieldType.includes(fieldType)) {
|
|
4377
|
-
child.push(item);
|
|
4378
|
-
return;
|
|
4379
|
-
}
|
|
4380
|
-
if (!dataSourceFieldType.includes(fieldType) && !["array", "object", "any"].includes(fieldType)) {
|
|
4381
|
-
return;
|
|
4382
|
-
}
|
|
4383
|
-
if (!children.length && ["object", "array", "any"].includes(field.type || "")) {
|
|
4384
|
-
return;
|
|
4385
|
-
}
|
|
4386
|
-
child.push(item);
|
|
4387
|
-
});
|
|
4388
|
-
return child;
|
|
4389
|
-
};
|
|
4390
4446
|
const cascaderConfig = vue.computed(() => {
|
|
4391
4447
|
const valueIsKey = props.config.value === "key";
|
|
4392
4448
|
return {
|
|
@@ -4397,7 +4453,7 @@
|
|
|
4397
4453
|
const options = dataSources.value?.map((ds) => ({
|
|
4398
4454
|
label: ds.title || ds.id,
|
|
4399
4455
|
value: valueIsKey ? ds.id : `${utils.DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${ds.id}`,
|
|
4400
|
-
children:
|
|
4456
|
+
children: getCascaderOptionsFromFields(ds.fields, props.config.dataSourceFieldType)
|
|
4401
4457
|
})) || [];
|
|
4402
4458
|
return options.filter((option) => option.children.length);
|
|
4403
4459
|
}
|
|
@@ -4449,7 +4505,6 @@
|
|
|
4449
4505
|
return (_ctx, _cache) => {
|
|
4450
4506
|
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$q, [
|
|
4451
4507
|
(vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(tagName.value), {
|
|
4452
|
-
style: { "width": "100%" },
|
|
4453
4508
|
config: showDataSourceFieldSelect.value || !_ctx.config.fieldConfig ? cascaderConfig.value : _ctx.config.fieldConfig,
|
|
4454
4509
|
model: _ctx.model,
|
|
4455
4510
|
name: _ctx.name,
|
|
@@ -5636,24 +5691,41 @@
|
|
|
5636
5691
|
const eventsService = services?.eventsService;
|
|
5637
5692
|
const codeBlockService = services?.codeBlockService;
|
|
5638
5693
|
const eventNameConfig = vue.computed(() => {
|
|
5694
|
+
const fieldType = props.config.src === "component" ? "select" : "cascader";
|
|
5639
5695
|
const defaultEventNameConfig = {
|
|
5640
5696
|
name: "name",
|
|
5641
5697
|
text: "事件",
|
|
5642
|
-
type:
|
|
5698
|
+
type: fieldType,
|
|
5643
5699
|
labelWidth: "40px",
|
|
5700
|
+
checkStrictly: true,
|
|
5701
|
+
valueSeparator: ".",
|
|
5644
5702
|
options: (mForm, { formValue }) => {
|
|
5645
5703
|
let events = [];
|
|
5646
5704
|
if (!eventsService || !dataSourceService)
|
|
5647
5705
|
return events;
|
|
5648
5706
|
if (props.config.src === "component") {
|
|
5649
5707
|
events = eventsService.getEvent(formValue.type);
|
|
5650
|
-
|
|
5708
|
+
return events.map((option) => ({
|
|
5709
|
+
text: option.label,
|
|
5710
|
+
value: option.value
|
|
5711
|
+
}));
|
|
5712
|
+
}
|
|
5713
|
+
if (props.config.src === "datasource") {
|
|
5651
5714
|
events = dataSourceService.getFormEvent(formValue.type);
|
|
5715
|
+
const dataSource = dataSourceService.getDataSourceById(formValue.id);
|
|
5716
|
+
const fields = dataSource?.fields || [];
|
|
5717
|
+
if (fields.length > 0) {
|
|
5718
|
+
return [
|
|
5719
|
+
...events,
|
|
5720
|
+
{
|
|
5721
|
+
label: "数据变化",
|
|
5722
|
+
value: utils.DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX,
|
|
5723
|
+
children: getCascaderOptionsFromFields(fields)
|
|
5724
|
+
}
|
|
5725
|
+
];
|
|
5726
|
+
}
|
|
5727
|
+
return events;
|
|
5652
5728
|
}
|
|
5653
|
-
return events.map((option) => ({
|
|
5654
|
-
text: option.label,
|
|
5655
|
-
value: option.value
|
|
5656
|
-
}));
|
|
5657
5729
|
}
|
|
5658
5730
|
};
|
|
5659
5731
|
return { ...defaultEventNameConfig, ...props.config.eventNameConfig };
|
|
@@ -8619,8 +8691,8 @@
|
|
|
8619
8691
|
const stage = services?.editorService?.get("stage");
|
|
8620
8692
|
const rect = menu.value.$el.getBoundingClientRect();
|
|
8621
8693
|
const parentRect = stage?.container?.getBoundingClientRect();
|
|
8622
|
-
const initialLeft = (rect.left || 0) - (parentRect?.left || 0);
|
|
8623
|
-
const initialTop = (rect.top || 0) - (parentRect?.top || 0);
|
|
8694
|
+
const initialLeft = utils.calcValueByFontsize(stage?.renderer.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / services.uiService.get("zoom");
|
|
8695
|
+
const initialTop = utils.calcValueByFontsize(stage?.renderer.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / services.uiService.get("zoom");
|
|
8624
8696
|
services?.editorService?.paste({ left: initialLeft, top: initialTop });
|
|
8625
8697
|
} else {
|
|
8626
8698
|
services?.editorService?.paste();
|
|
@@ -9617,7 +9689,10 @@
|
|
|
9617
9689
|
class: "m-editor-sidebar-content",
|
|
9618
9690
|
key: config.$key ?? index
|
|
9619
9691
|
}, [
|
|
9620
|
-
config && !vue.unref(floatBoxStates)[config.$key]?.status ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(config.component), vue.mergeProps({
|
|
9692
|
+
config && !vue.unref(floatBoxStates)[config.$key]?.status ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(config.component), vue.mergeProps({
|
|
9693
|
+
key: 0,
|
|
9694
|
+
ref_for: true
|
|
9695
|
+
}, config.props || {}, vue.toHandlers(config?.listeners || {})), vue.createSlots({ _: 2 }, [
|
|
9621
9696
|
config.$key === "component-list" || config.slots?.componentListPanelHeader ? {
|
|
9622
9697
|
name: "component-list-panel-header",
|
|
9623
9698
|
fn: vue.withCtx(() => [
|
|
@@ -9750,7 +9825,10 @@
|
|
|
9750
9825
|
}, {
|
|
9751
9826
|
body: vue.withCtx(() => [
|
|
9752
9827
|
vue.createElementVNode("div", _hoisted_5$1, [
|
|
9753
|
-
config && vue.unref(floatBoxStates)[config.$key].status ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(config.component), vue.mergeProps({
|
|
9828
|
+
config && vue.unref(floatBoxStates)[config.$key].status ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(config.component), vue.mergeProps({
|
|
9829
|
+
key: 0,
|
|
9830
|
+
ref_for: true
|
|
9831
|
+
}, config.props || {}, vue.toHandlers(config?.listeners || {})), null, 16)) : vue.createCommentVNode("", true)
|
|
9754
9832
|
])
|
|
9755
9833
|
]),
|
|
9756
9834
|
_: 2
|
|
@@ -10571,17 +10649,17 @@
|
|
|
10571
10649
|
position = "absolute";
|
|
10572
10650
|
top = e.clientY - containerRect.top + scrollTop;
|
|
10573
10651
|
left = e.clientX - containerRect.left + scrollLeft;
|
|
10574
|
-
if (parentEl
|
|
10652
|
+
if (parentEl) {
|
|
10575
10653
|
const { left: parentLeft, top: parentTop } = StageCore.getOffset(parentEl);
|
|
10576
|
-
left = left -
|
|
10577
|
-
top = top -
|
|
10654
|
+
left = left - parentLeft * zoom.value;
|
|
10655
|
+
top = top - parentTop * zoom.value;
|
|
10578
10656
|
}
|
|
10579
10657
|
}
|
|
10580
10658
|
config.data.style = {
|
|
10581
10659
|
...style,
|
|
10582
10660
|
position,
|
|
10583
|
-
top: top / zoom.value,
|
|
10584
|
-
left: left / zoom.value
|
|
10661
|
+
top: utils.calcValueByFontsize(doc, top / zoom.value),
|
|
10662
|
+
left: utils.calcValueByFontsize(doc, left / zoom.value)
|
|
10585
10663
|
};
|
|
10586
10664
|
config.data.inputEvent = e;
|
|
10587
10665
|
services?.editorService.add(config.data, parent);
|
|
@@ -10712,7 +10790,7 @@
|
|
|
10712
10790
|
|
|
10713
10791
|
const canUsePluginMethods$1 = {
|
|
10714
10792
|
async: ["setCodeDslById", "setEditStatus", "setCombineIds", "setUndeleteableList", "deleteCodeDslByIds"],
|
|
10715
|
-
sync: []
|
|
10793
|
+
sync: ["setCodeDslByIdSync"]
|
|
10716
10794
|
};
|
|
10717
10795
|
class CodeBlock extends BaseService {
|
|
10718
10796
|
state = vue.reactive({
|
|
@@ -10723,7 +10801,10 @@
|
|
|
10723
10801
|
paramsColConfig: void 0
|
|
10724
10802
|
});
|
|
10725
10803
|
constructor() {
|
|
10726
|
-
super(
|
|
10804
|
+
super([
|
|
10805
|
+
...canUsePluginMethods$1.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
10806
|
+
...canUsePluginMethods$1.sync.map((methodName) => ({ name: methodName, isAsync: false }))
|
|
10807
|
+
]);
|
|
10727
10808
|
}
|
|
10728
10809
|
/**
|
|
10729
10810
|
* 设置活动的代码块dsl数据源
|
|
@@ -10763,17 +10844,29 @@
|
|
|
10763
10844
|
* @returns {void}
|
|
10764
10845
|
*/
|
|
10765
10846
|
async setCodeDslById(id, codeConfig) {
|
|
10847
|
+
this.setCodeDslByIdSync(id, codeConfig, true);
|
|
10848
|
+
}
|
|
10849
|
+
/**
|
|
10850
|
+
* 为了兼容历史原因
|
|
10851
|
+
* 设置代码块ID和代码内容到源dsl
|
|
10852
|
+
* @param {Id} id 代码块id
|
|
10853
|
+
* @param {CodeBlockContent} codeConfig 代码块内容配置信息
|
|
10854
|
+
* @param {boolean} force 是否强制写入,默认true
|
|
10855
|
+
* @returns {void}
|
|
10856
|
+
*/
|
|
10857
|
+
setCodeDslByIdSync(id, codeConfig, force = true) {
|
|
10766
10858
|
const codeDsl = this.getCodeDsl();
|
|
10767
10859
|
if (!codeDsl) {
|
|
10768
10860
|
throw new Error("dsl中没有codeBlocks");
|
|
10769
10861
|
}
|
|
10770
|
-
|
|
10771
|
-
|
|
10862
|
+
if (codeDsl[id] && !force)
|
|
10863
|
+
return;
|
|
10864
|
+
const codeConfigProcessed = lodashEs.cloneDeep(codeConfig);
|
|
10865
|
+
if (codeConfigProcessed.content) {
|
|
10772
10866
|
const parseDSL = getConfig("parseDSL");
|
|
10773
|
-
if (typeof
|
|
10774
|
-
|
|
10867
|
+
if (typeof codeConfigProcessed.content === "string") {
|
|
10868
|
+
codeConfigProcessed.content = parseDSL(codeConfigProcessed.content);
|
|
10775
10869
|
}
|
|
10776
|
-
codeConfigProcessed.content = codeConfig.content;
|
|
10777
10870
|
}
|
|
10778
10871
|
const existContent = codeDsl[id] || {};
|
|
10779
10872
|
codeDsl[id] = {
|
|
@@ -10885,6 +10978,51 @@
|
|
|
10885
10978
|
return newId;
|
|
10886
10979
|
return await this.getUniqueId();
|
|
10887
10980
|
}
|
|
10981
|
+
/**
|
|
10982
|
+
* 复制时会带上组件关联的代码块
|
|
10983
|
+
* @param config 组件节点配置
|
|
10984
|
+
* @returns
|
|
10985
|
+
*/
|
|
10986
|
+
copyWithRelated(config) {
|
|
10987
|
+
const copyNodes = Array.isArray(config) ? config : [config];
|
|
10988
|
+
depService.clearByType(dep.DepTargetType.RELATED_CODE_WHEN_COPY);
|
|
10989
|
+
depService.collect(copyNodes, true, dep.DepTargetType.RELATED_CODE_WHEN_COPY);
|
|
10990
|
+
const customTarget = depService.getTarget(
|
|
10991
|
+
dep.DepTargetType.RELATED_CODE_WHEN_COPY,
|
|
10992
|
+
dep.DepTargetType.RELATED_CODE_WHEN_COPY
|
|
10993
|
+
);
|
|
10994
|
+
const copyData = {};
|
|
10995
|
+
if (customTarget) {
|
|
10996
|
+
Object.keys(customTarget.deps).forEach((nodeId) => {
|
|
10997
|
+
const node = editorService.getNodeById(nodeId);
|
|
10998
|
+
if (!node)
|
|
10999
|
+
return;
|
|
11000
|
+
customTarget.deps[nodeId].keys.forEach((key) => {
|
|
11001
|
+
const relateCodeId = lodashEs.get(node, key);
|
|
11002
|
+
const isExist = Object.keys(copyData).find((codeId) => codeId === relateCodeId);
|
|
11003
|
+
if (!isExist) {
|
|
11004
|
+
const relateCode = this.getCodeContentById(relateCodeId);
|
|
11005
|
+
if (relateCode) {
|
|
11006
|
+
copyData[relateCodeId] = relateCode;
|
|
11007
|
+
}
|
|
11008
|
+
}
|
|
11009
|
+
});
|
|
11010
|
+
});
|
|
11011
|
+
}
|
|
11012
|
+
storageService.setItem(COPY_CODE_STORAGE_KEY, copyData, {
|
|
11013
|
+
protocol: Protocol.OBJECT
|
|
11014
|
+
});
|
|
11015
|
+
}
|
|
11016
|
+
/**
|
|
11017
|
+
* 粘贴代码块
|
|
11018
|
+
* @returns
|
|
11019
|
+
*/
|
|
11020
|
+
paste() {
|
|
11021
|
+
const codeDsl = storageService.getItem(COPY_CODE_STORAGE_KEY);
|
|
11022
|
+
Object.keys(codeDsl).forEach((codeId) => {
|
|
11023
|
+
this.setCodeDslByIdSync(codeId, codeDsl[codeId], false);
|
|
11024
|
+
});
|
|
11025
|
+
}
|
|
10888
11026
|
resetState() {
|
|
10889
11027
|
this.state.codeDsl = null;
|
|
10890
11028
|
this.state.editable = true;
|
|
@@ -11226,6 +11364,7 @@
|
|
|
11226
11364
|
createStage(stageOptions = {}) {
|
|
11227
11365
|
return useStage({
|
|
11228
11366
|
...stageOptions,
|
|
11367
|
+
zoom: 1,
|
|
11229
11368
|
runtimeUrl: "",
|
|
11230
11369
|
autoScrollIntoView: false,
|
|
11231
11370
|
render: async (stage) => {
|
|
@@ -11655,7 +11794,17 @@
|
|
|
11655
11794
|
dataSourceService.on("update", dataSourceUpdateHandler);
|
|
11656
11795
|
dataSourceService.on("remove", dataSourceRemoveHandler);
|
|
11657
11796
|
if (props.collectorOptions && !depService.hasTarget(dep.DepTargetType.RELATED_COMP_WHEN_COPY)) {
|
|
11658
|
-
depService.addTarget(dep.
|
|
11797
|
+
depService.addTarget(dep.createRelatedTargetForCopy(props.collectorOptions, dep.DepTargetType.RELATED_COMP_WHEN_COPY));
|
|
11798
|
+
}
|
|
11799
|
+
if (props.collectorOptionsForCode && !depService.hasTarget(dep.DepTargetType.RELATED_CODE_WHEN_COPY)) {
|
|
11800
|
+
depService.addTarget(
|
|
11801
|
+
dep.createRelatedTargetForCopy(props.collectorOptionsForCode, dep.DepTargetType.RELATED_CODE_WHEN_COPY)
|
|
11802
|
+
);
|
|
11803
|
+
}
|
|
11804
|
+
if (props.collectorOptionsForDataSource && !depService.hasTarget(dep.DepTargetType.RELATED_DS_WHEN_COPY)) {
|
|
11805
|
+
depService.addTarget(
|
|
11806
|
+
dep.createRelatedTargetForCopy(props.collectorOptionsForDataSource, dep.DepTargetType.RELATED_DS_WHEN_COPY)
|
|
11807
|
+
);
|
|
11659
11808
|
}
|
|
11660
11809
|
vue.onBeforeUnmount(() => {
|
|
11661
11810
|
depService.off("add-target", targetAddHandler);
|
|
@@ -11706,6 +11855,8 @@
|
|
|
11706
11855
|
codeOptions: {},
|
|
11707
11856
|
disabledDragStart: { type: Boolean },
|
|
11708
11857
|
collectorOptions: {},
|
|
11858
|
+
collectorOptionsForCode: {},
|
|
11859
|
+
collectorOptionsForDataSource: {},
|
|
11709
11860
|
guidesOptions: {},
|
|
11710
11861
|
disabledMultiSelect: { type: Boolean },
|
|
11711
11862
|
disabledPageFragment: { type: Boolean },
|
|
@@ -11911,11 +12062,13 @@
|
|
|
11911
12062
|
}
|
|
11912
12063
|
};
|
|
11913
12064
|
|
|
11914
|
-
Object.defineProperty(exports,
|
|
12065
|
+
Object.defineProperty(exports, "DepTargetType", {
|
|
11915
12066
|
enumerable: true,
|
|
11916
12067
|
get: () => dep.DepTargetType
|
|
11917
12068
|
});
|
|
11918
12069
|
exports.CODE_DRAFT_STORAGE_KEY = CODE_DRAFT_STORAGE_KEY;
|
|
12070
|
+
exports.COPY_CODE_STORAGE_KEY = COPY_CODE_STORAGE_KEY;
|
|
12071
|
+
exports.COPY_DS_STORAGE_KEY = COPY_DS_STORAGE_KEY;
|
|
11919
12072
|
exports.COPY_STORAGE_KEY = COPY_STORAGE_KEY;
|
|
11920
12073
|
exports.CodeBlockEditor = _sfc_main$J;
|
|
11921
12074
|
exports.CodeBlockList = _sfc_main$l;
|
|
@@ -11937,6 +12090,7 @@
|
|
|
11937
12090
|
exports.DragType = DragType;
|
|
11938
12091
|
exports.EventSelect = _sfc_main$E;
|
|
11939
12092
|
exports.Fixed2Other = Fixed2Other;
|
|
12093
|
+
exports.FloatingBox = _sfc_main$N;
|
|
11940
12094
|
exports.H_GUIDE_LINE_STORAGE_KEY = H_GUIDE_LINE_STORAGE_KEY;
|
|
11941
12095
|
exports.Icon = _sfc_main$U;
|
|
11942
12096
|
exports.KeyBindingCommand = KeyBindingCommand;
|
|
@@ -11975,6 +12129,7 @@
|
|
|
11975
12129
|
exports.generatePageName = generatePageName;
|
|
11976
12130
|
exports.generatePageNameByApp = generatePageNameByApp;
|
|
11977
12131
|
exports.getAddParent = getAddParent;
|
|
12132
|
+
exports.getCascaderOptionsFromFields = getCascaderOptionsFromFields;
|
|
11978
12133
|
exports.getConfig = getConfig;
|
|
11979
12134
|
exports.getDefaultConfig = getDefaultConfig;
|
|
11980
12135
|
exports.getDisplayField = getDisplayField;
|