Browse Source

Merge branch 'dev' of http://124.70.149.18:10880/lianghj/queenshow into dev

qinyan 1 year ago
parent
commit
1a0c43206f
32 changed files with 883 additions and 126 deletions
  1. 35 0
      src/modules/editor/components/CompUI/basicUI/Group/component.tsx
  2. 18 0
      src/modules/editor/components/CompUI/basicUI/Group/index.ts
  3. 1 1
      src/modules/editor/components/CompUI/basicUI/Image2/component.tsx
  4. 1 1
      src/modules/editor/components/CompUI/basicUI/Transfer/index.tsx
  5. 3 2
      src/modules/editor/components/CompUI/basicUI/Video/component.tsx
  6. 46 23
      src/modules/editor/components/CompUI/basicUI/View.tsx
  7. 14 4
      src/modules/editor/components/CompUI/basicUI/hooks.ts
  8. 3 1
      src/modules/editor/components/CompUI/basicUI/index.ts
  9. 1 1
      src/modules/editor/components/CompUI/customUI/Cards/Card11/component.tsx
  10. 1 1
      src/modules/editor/components/CompUI/customUI/Cards/CardList/component.tsx
  11. 1 1
      src/modules/editor/components/CompUI/customUI/Texts/Text1/component.tsx
  12. 3 4
      src/modules/editor/components/CompUI/defines/createCompHooks.ts
  13. 1 30
      src/modules/editor/components/CompUI/defines/createCompId.ts
  14. 5 0
      src/modules/editor/components/TipIcons/index.ts
  15. 28 3
      src/modules/editor/components/Viewport/Content/index.tsx
  16. 1 0
      src/modules/editor/components/Viewport/Slider/SliderLeft/CustomComps.tsx
  17. 2 18
      src/modules/editor/controllers/CompUICtrl/index.ts
  18. 46 0
      src/modules/editor/controllers/DragAddCtrl/index.ts
  19. 3 3
      src/modules/editor/controllers/HotKeyCtrl/GroupCtrl.ts
  20. 2 0
      src/modules/editor/controllers/TransferCtrl/index.ts
  21. 146 12
      src/modules/editor/module/actions/edit.ts
  22. 2 2
      src/modules/editor/module/actions/init.ts
  23. 19 2
      src/modules/editor/module/helpers/index.ts
  24. 2 0
      src/modules/editor/module/index.ts
  25. 7 14
      src/modules/editor/module/stores/index.ts
  26. 478 0
      src/modules/editor/objects/DesignTemp/creates/Matrix.ts
  27. 1 1
      src/modules/editor/objects/DesignTemp/creates/createCompStyle.ts
  28. 1 1
      src/modules/editor/objects/DesignTemp/index.ts
  29. 1 1
      src/modules/editor/objects/DesignTemp/versions/0.0.1.ts
  30. 3 0
      src/modules/editor/objects/Toolbars/CompToolbars.ts
  31. 7 0
      src/modules/editor/objects/Toolbars/default.ts
  32. 1 0
      src/typings/pro.d.ts

+ 35 - 0
src/modules/editor/components/CompUI/basicUI/Group/component.tsx

@@ -0,0 +1,35 @@
+import { defineComponent } from "vue";
+import { string } from "vue-types";
+import { useCompData } from ".";
+import { useEditor } from "../../../..";
+import { DesignComp } from "../../../../objects/DesignTemp/DesignComp";
+import { View } from "../View";
+import { CompUI } from "../..";
+
+export const Component = defineComponent({
+  props: {
+    compId: string().isRequired,
+  },
+  setup(props) {
+    const { helper, controls } = useEditor();
+    const { children } = useCompData(props.compId);
+    return () => (
+      <View compId={props.compId}>
+        <div>
+          {children.default?.map((compId) => {
+            const compItem = helper.findComp(compId) as DesignComp;
+            const Comp =
+              controls.compUICtrl.state.components.get(compItem.compKey)
+                ?.Component || CompUI.Container.Component;
+
+            return (
+              <div class="flex flex-col">
+                <Comp key={compItem.id} compId={compItem.id} />
+              </div>
+            );
+          })}
+        </div>
+      </View>
+    );
+  },
+});

+ 18 - 0
src/modules/editor/components/CompUI/basicUI/Group/index.ts

@@ -0,0 +1,18 @@
+import { createAttrsForm } from "../../defines/createAttrsForm";
+import { createCompHooks } from "../../defines/createCompHooks";
+
+export { Component } from "./component";
+
+export const options = {
+  name: "组合",
+  thumbnail: require("@/modules/editor/assets/icons/container.svg"),
+};
+
+export const { createComp, useCompData } = createCompHooks({
+  value: {},
+  children: {
+    default: () => [] as string[],
+  },
+});
+
+export const Form = createAttrsForm([]);

+ 1 - 1
src/modules/editor/components/CompUI/basicUI/Image2/component.tsx

@@ -51,7 +51,7 @@ export const Component = defineComponent({
                 ? value.url
                 : value.url + "?editMode=" + store.isEditMode
             }
-            onLoad={() => {
+            onLoad={(e) => {
               if (helper.isCurrComp(props.compId)) {
                 controls.transferCtrl.initStyle();
               }

+ 1 - 1
src/modules/editor/components/CompUI/basicUI/Transfer/index.tsx

@@ -29,7 +29,7 @@ export const Transfer = defineComponent({
     return () => {
       const comp = transferCtrl.currComp;
       const toolbarOpts =
-        CompToolbars[transferCtrl.currComp.compKey] || CompToolbars.default;
+        CompToolbars[transferCtrl.currComp?.compKey] || CompToolbars.default;
 
       // const showTransfer =
       //   store.isEditComp || store.pageCompIds.includes(comp.id);

+ 3 - 2
src/modules/editor/components/CompUI/basicUI/Video/component.tsx

@@ -30,10 +30,11 @@ export const Component = defineComponent({
         <View class={rootCls} compId={props.compId}>
           <video
             class="w-full object-cover"
-            src={value.url}
             style={{ aspectRatio: value.ratio }}
             {...options}
-          />
+          >
+            <source src={value.url}></source>
+          </video>
           {store.isEditMode && (
             <IconPicture class={btnCls} onClick={changeVal} />
           )}

+ 46 - 23
src/modules/editor/components/CompUI/basicUI/View.tsx

@@ -1,9 +1,9 @@
+import { IconAdd, IconMove } from "@/assets/icons";
 import { css } from "@linaria/core";
+import { IconDelete } from "@queenjs/icons";
 import { defineComponent } from "vue";
 import { string } from "vue-types";
 import { useEditor } from "../../..";
-import { IconMove, IconClear, IconAdd} from "@/assets/icons";
-import {IconDelete} from "@queenjs/icons";
 import { useCompRef } from "./hooks";
 
 export const View = defineComponent({
@@ -18,12 +18,17 @@ export const View = defineComponent({
     return () => {
       const comp = helper.findComp(props.compId);
       if (!comp) return store.isEditMode ? <div>无效组件</div> : null;
-      const isStreamCard = helper.isStreamCard(props.compId)
+      const isStreamCard = helper.isStreamCard(props.compId);
+      const isGroupComp = helper.isGroupComp(props.compId);
 
       return (
         <div
           ref={compRef}
-          class={[viewStyle, store.isEditMode && editCompStyle]}
+          class={[
+            viewStyle,
+            store.isEditMode && editCompStyle,
+            isGroupComp && groupCompCls,
+          ]}
           style={helper.createStyle(comp.layout)}
           // onClick={(e) => {
           //   e.stopPropagation();
@@ -33,30 +38,44 @@ export const View = defineComponent({
           // }}
           onDblclick={() => emit("dblclick")}
         >
-          <div onMousedown={(e) => {
+          <div
+            onMousedown={(e) => {
+              if (helper.isGroupCompChild(props.compId)) return;
+
               e.stopPropagation();
               if (store.isEditMode) {
                 actions.pickComp(props.compId);
-                if (!helper.isStreamCard(props.compId) ) {
-                  controls.transferCtrl.mousedown(e, "move",  store.currComp)
-                }               
+                if (!helper.isStreamCard(props.compId)) {
+                  controls.transferCtrl.mousedown(e, "move", store.currComp);
+                }
               }
-            }}>
+            }}
+            onMousemove={(e) => {
+              if (
+                !store.isEditMode ||
+                !controls.dragAddCtrl.dragingCompKey ||
+                !helper.isStreamCard(props.compId)
+              )
+                return;
+              actions.pickComp(props.compId);
+            }}
+          >
             {slots.default?.()}
           </div>
-        
-          {
-            store.isEditMode && isStreamCard && <div class="hudop">
-              {
-                store.streamCardIds.length > 1 &&  <IconMove class="draganchor" />
-              }
-              {
-                 store.streamCardIds.length > 1 && <IconDelete onClick={()=>actions.removeStreamCard(props.compId) }/>
-              }
-              <IconAdd onClick={()=>actions.addCompToDesign("Container")} />
+
+          {store.isEditMode && isStreamCard && (
+            <div class="hudop">
+              {store.streamCardIds.length > 1 && (
+                <IconMove class="draganchor" />
+              )}
+              {store.streamCardIds.length > 1 && (
+                <IconDelete
+                  onClick={() => actions.removeStreamCard(props.compId)}
+                />
+              )}
+              <IconAdd onClick={() => actions.addCompToDesign("Container")} />
             </div>
-          }
-          
+          )}
         </div>
       );
     };
@@ -73,7 +92,7 @@ const viewStyle = css`
     height: 100%;
   }
 
-  .hudop{
+  .hudop {
     position: absolute;
     top: 0px;
     left: -46px;
@@ -85,7 +104,7 @@ const viewStyle = css`
     width: 28px;
     align-items: center;
     border-radius: 4px;
-    .inficon{
+    .inficon {
       padding: 8px;
     }
     z-index: 1000;
@@ -97,3 +116,7 @@ const editCompStyle = css`
     outline: 2px dashed @inf-primary-color;
   }
 `;
+
+const groupCompCls = css`
+  outline: 2px solid @inf-primary-color !important;
+`;

+ 14 - 4
src/modules/editor/components/CompUI/basicUI/hooks.ts

@@ -1,15 +1,25 @@
 import { useEditor } from "@/modules/editor";
-import { onMounted, ref } from "vue";
+import { onMounted, ref, inject, provide } from "vue";
 
 export function useCompRef(compId: string) {
   const compRef = ref();
   const { helper } = useEditor();
+
+  const parentId = compId !== "root" ? inject("compParentId") : "";
+  provide("compParentId", compId);
+  
   onMounted(() => {
     const comp = helper.findComp(compId);
     if (comp) {
-      Object.defineProperty(comp, "$el", {
-        value: compRef.value,
-        configurable: true,
+      Object.defineProperties(comp, {
+        $el: {
+          value: compRef.value,
+          configurable: true,
+        },
+        pid: {
+          value: parentId,
+          configurable: true,
+        },
       });
     }
   });

+ 3 - 1
src/modules/editor/components/CompUI/basicUI/index.ts

@@ -1,6 +1,8 @@
 export * as Container from "./Container";
-export * as Page from "./Page";
+export * as Group from "./Group";
 export * as Image from "./Image2";
+export * as Page from "./Page";
 export * as Text from "./Text";
 export * as Video from "./Video";
 export * as Web3D from "./Web3D";
+

+ 1 - 1
src/modules/editor/components/CompUI/customUI/Cards/Card11/component.tsx

@@ -10,7 +10,7 @@ export const Component = createUIComp({
   },
   setup(props) {
     const { children, value } = useCompData(props.compId);
-    const createList = useCreateChild("list", props.compId);
+    const createList = useCreateChild("list");
 
     watch(
       () => [value.columns],

+ 1 - 1
src/modules/editor/components/CompUI/customUI/Cards/CardList/component.tsx

@@ -12,7 +12,7 @@ export const Component = createUIComp({
   setup(props) {
     const { helper } = useEditor();
     const { value, children } = useCompData(props.compId);
-    const createList = useCreateChild("list", props.compId);
+    const createList = useCreateChild("list");
 
     watch(
       () => [value.total],

+ 1 - 1
src/modules/editor/components/CompUI/customUI/Texts/Text1/component.tsx

@@ -13,7 +13,7 @@ export const Component = createUIComp({
   setup(props) {
     const { helper } = useEditor();
     const { value, children } = useCompData(props.compId);
-    const createList = useCreateChild("list", props.compId);
+    const createList = useCreateChild("list");
 
     watch(
       () => [value.columns],

+ 3 - 4
src/modules/editor/components/CompUI/defines/createCompHooks.ts

@@ -15,7 +15,6 @@ type IOptions<T, C> = {
 export function createCompHooks<T, C extends { [name: string]: AnyFun }>(
   defaultOpts: IOptions<T, C>
 ) {
-
   function createComp(opts: any) {
     const defData: any = cloneDeep(defaultOpts);
     if (defData.children) {
@@ -23,7 +22,7 @@ export function createCompHooks<T, C extends { [name: string]: AnyFun }>(
         defData.children[key] = fn(defData);
       });
     }
-    const options = defaultsDeep(opts, defData)
+    const options = defaultsDeep(opts, defData);
 
     return new DesignComp(options);
   }
@@ -38,11 +37,11 @@ export function createCompHooks<T, C extends { [name: string]: AnyFun }>(
     };
   }
 
-  function useCreateChild<T extends keyof C>(key: T, compId: string) {
+  function useCreateChild<T extends keyof C>(key: T) {
     const editor = useEditor();
     const createChild: any = (...args: any) => {
       const result = (defaultOpts as any).children[key](defaultOpts, ...args);
-      addCacheToMap(editor.store.designData.compMap, compId);
+      addCacheToMap(editor.store.designData.compMap);
       return result;
     };
     return createChild as C[T];

+ 1 - 30
src/modules/editor/components/CompUI/defines/createCompId.ts

@@ -1,22 +1,12 @@
 import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
 import { CompUI } from "..";
-import { mapValuesDeep } from "@/utils";
-import { Exception } from "queenjs";
 
 const cacheCompMap = new Map<string, DesignComp>();
 
-export function addCacheToMap(
-  obj: Record<string, DesignComp>,
-  parentId: string
-) {
-  let lastComp: DesignComp | undefined;
+export function addCacheToMap(obj: Record<string, DesignComp>) {
   cacheCompMap.forEach((comp) => {
     obj[comp.id] = comp;
-    lastComp = comp;
   });
-  if (lastComp) {
-    setCompPid(lastComp, parentId);
-  }
   cacheCompMap.clear();
 }
 
@@ -29,24 +19,5 @@ export function createCompId(
   );
   cacheCompMap.set(comp.id, comp);
 
-  const childIds = mapValuesDeep(
-    comp.children,
-    (v) => typeof v === "string",
-    (v: string) => v
-  );
-
-  childIds.forEach((id) => {
-    const childComp = cacheCompMap.get(id);
-    if (!childComp) {
-      throw Exception.error("无效的childCompId");
-    }
-    setCompPid(childComp, comp.id);
-  });
   return comp.id;
 }
-
-export function setCompPid(comp: DesignComp, pid: string) {
-  Object.defineProperty(comp, "pid", {
-    value: pid,
-  });
-}

+ 5 - 0
src/modules/editor/components/TipIcons/index.ts

@@ -10,6 +10,7 @@ import {
 } from "@/assets/icons";
 import {
   IconCamera,
+  IconClose,
   IconCube,
   IconDelete,
   IconEyeOff,
@@ -79,4 +80,8 @@ export const TipIcons = {
     icons: [IconSave],
     tips: ["保存为组件"],
   }),
+  CancelGroup: createTipIcon({
+    icons: [IconClose],
+    tips: ["取消打组"],
+  }),
 };

+ 28 - 3
src/modules/editor/components/Viewport/Content/index.tsx

@@ -2,12 +2,13 @@ import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
 import { css } from "@linaria/core";
 import { defineUI } from "queenjs";
 import { onUnmounted, reactive, onMounted , ref} from "vue";
-import { Container, Draggable } from "vue-dndrop";
+import { Container, Draggable, vueDndrop } from "vue-dndrop";
 import { useEditor } from "../../..";
 import { HotKeyCtrl } from "../../../controllers/HotKeyCtrl";
 import { CompUI } from "../../CompUI";
 import { Transfer } from "../../CompUI/basicUI/Transfer";
 import { StreamCardTransfer } from "../../CompUI/basicUI/Transfer/streamCard";
+import { DragAddCtrl } from "@/modules/editor/controllers/DragAddCtrl";
 
 export default defineUI({
   setup() {
@@ -18,6 +19,7 @@ export default defineUI({
     hotKeyCtrl.init();
     onUnmounted(() => {
       hotKeyCtrl.destroy();
+
     });
 
     const state = reactive({
@@ -26,7 +28,8 @@ export default defineUI({
 
     const NotFoundComp = () => <div>无效的组件</div>;
     const flagRef = ref();
-
+    const containRef = ref();
+    
     return () => {
       const pageRoot = helper.findRootComp();
       if (!pageRoot) return;
@@ -47,10 +50,32 @@ export default defineUI({
                   return (
                     <>
                       <Container
+                        behaiver = "drop-zone"
+                       
                         class={store.isEditPage ? "!min-h-750px" : ""}
-                        group-name="canvas"
+
                         drag-handle-selector=".draganchor"
+                        drop-placeholder={false}
+                        animation-duration={0}
+                        ref={containRef}
+                        should-accept-drop={(sourceContainerOptions:any, payload:any)=>{
+                          console.log("sourceContainerOptions:any, payload:any", sourceContainerOptions, payload)
+                          if (sourceContainerOptions.groupName != "canvas") return false
+                          controls.dragAddCtrl.updateCompKey(payload)
+                          return false;
+                        }}
+
+                        drop-not-allowed = {
+                          (p:any)=>{
+                            console.log("p", p)
+                          }
+                        }
+                        
+
                         onDrop={(e: any) => {
+                          console.log( e );
+                          return
+
                           if (e.payload) {
                             actions.addCompToDesign(e.payload, e.addedIndex);
                           } else {

+ 1 - 0
src/modules/editor/components/Viewport/Slider/SliderLeft/CustomComps.tsx

@@ -22,6 +22,7 @@ export default defineUI({
         class="space-y-10px scrollbar"
         behaviour="copy"
         group-name="canvas"
+        animation-duration={0}
         get-child-payload={(index: number) => {
           return props.components[index].compKey;
         }}

+ 2 - 18
src/modules/editor/controllers/CompUICtrl/index.ts

@@ -10,7 +10,6 @@ import * as customUI from "../../components/CompUI/customUI";
 import {
   addCacheToMap,
   createCompId,
-  setCompPid,
 } from "../../components/CompUI/defines/createCompId";
 import { EditorModule } from "../../module";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
@@ -100,34 +99,19 @@ export class CompUICtrl extends ModuleControl<EditorModule> {
       }
     );
     Object.assign(compMap, nextCompMap);
-    Object.values(nextCompMap).forEach((comp) => {
-      const childIds = mapValuesDeep(
-        comp.children,
-        (v) => typeof v === "string",
-        (v: string) => v
-      );
-      childIds.forEach((id) => {
-        const childComp = nextCompMap[id];
-        if (!childComp) {
-          throw Exception.error("无效的childCompId");
-        }
-        setCompPid(childComp, comp.id);
-      });
-    });
     return nextCompMap[idMap.get("root") as string];
   }
 
-  async createCompId(compKey: ICompKeys, parentCompId: string) {
+  async createCompId(compKey: ICompKeys) {
     let compId = "";
     const compItem = this.state.components.get(compKey);
     if (!compItem) throw Exception.error("无效的组件");
     if (compItem.compType === "user") {
       const comp = await this.initUserCompDetail(compKey);
-      setCompPid(comp, parentCompId);
       compId = comp.id;
     } else {
       compId = createCompId(compKey);
-      addCacheToMap(this.store.designData.compMap, parentCompId);
+      addCacheToMap(this.store.designData.compMap);
     }
     return compId;
   }

+ 46 - 0
src/modules/editor/controllers/DragAddCtrl/index.ts

@@ -0,0 +1,46 @@
+import { ModuleControl } from "queenjs";
+import { EditorModule } from "../../module";
+
+export class DragAddCtrl extends ModuleControl<EditorModule> {
+    dragingCompKey = ""
+
+    _cancel?:()=>void
+    _mouseUping = false
+
+    updateCompKey(k:string) {
+        if (this._mouseUping) return;
+
+        const isSame = (k == this.dragingCompKey);
+        this.dragingCompKey = k;
+        if (!isSame && k) {
+            if (this._cancel) this._cancel();
+            this._cancel = this.initEvent();
+        }
+    }
+
+    initEvent() {
+        const scope = this;
+
+        function mouseup(e:MouseEvent) {
+            console.log("mouseup=>", scope.dragingCompKey)
+            scope._mouseUping = true;
+            setTimeout(() => {
+                scope._mouseUping = false;
+            }, 400);
+
+            if (scope._cancel) scope._cancel();
+
+            if (!scope.dragingCompKey ) return;
+            scope.actions.addCompToDesign(scope.dragingCompKey as any)
+            scope.dragingCompKey = "";
+          
+        }
+
+        document.addEventListener("mouseup", mouseup)
+
+        return ()=> {
+            document.removeEventListener("mouseup", mouseup)
+            scope._cancel = undefined;
+        }
+    }
+}

+ 3 - 3
src/modules/editor/controllers/HotKeyCtrl/GroupCtrl.ts

@@ -6,14 +6,14 @@ export class GroupActionCtrl extends ModuleControl<EditorModule> {
     document.body.addEventListener("keydown", this.enableGroupMode);
   }
   enableGroupMode = (event: KeyboardEvent) => {
-    if (event.key === "Control") {
-      this.store.setGroupMode(true);
+    if (event.key === "Control" && !this.store.groupModeStatus) {
+      this.actions.enableGroupMode();
       document.body.addEventListener("keyup", this.disableGroupMode);
     }
   };
   disableGroupMode = (event: KeyboardEvent) => {
     if (event.key === "Control") {
-      this.store.setGroupMode(false);
+      this.actions.disableGroupMode();
       document.body.removeEventListener("keyup", this.disableGroupMode);
     }
   };

+ 2 - 0
src/modules/editor/controllers/TransferCtrl/index.ts

@@ -103,6 +103,8 @@ export class TransferCtrl extends ModuleControl<EditorModule> {
   }
 
   initStyle() {
+    if (!this.compEl) return;
+    
     const rect = this.compEl.getBoundingClientRect();
     const pageRect = this.pageEl.getBoundingClientRect();
 

+ 146 - 12
src/modules/editor/module/actions/edit.ts

@@ -3,6 +3,7 @@ import { Exception, queenApi } from "queenjs";
 import { EditorModule } from "..";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
 import { ICompKeys, Layout } from "../../typings";
+import { Matrix } from "../../objects/DesignTemp/creates/Matrix";
 
 export const editActions = EditorModule.action({
   // 添加组件到画布
@@ -13,7 +14,7 @@ export const editActions = EditorModule.action({
     }
 
     if (compKey == "Container") {
-      index = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1
+      index = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1;
       const compId = await this.store.insertDesignContent(compKey, index);
       this.actions.pickComp(compId);
       return;
@@ -38,8 +39,25 @@ export const editActions = EditorModule.action({
   },
   // 切换当前组件
   pickComp(compId: string) {
-    if (this.store.groupModeStatus) {
-      this.store.groupIds.push(compId);
+    const { store, helper } = this;
+    // 组合模式下,切换组件
+    if (store.currCompId && store.groupModeStatus) {
+      const enableGroupIds = helper
+        .findParentComp(compId)
+        ?.getChildIds() as string[];
+      const comps = helper.getCompTrees(compId);
+      while (comps.length) {
+        const comp = comps.pop() as DesignComp;
+        const index = store.groupIds.indexOf(comp.id);
+        if (index >= 0) {
+          const groupIds = [...store.groupIds];
+          groupIds.splice(index, 1);
+          store.setGroupIds(groupIds);
+        } else if (enableGroupIds.includes(comp.id)) {
+          store.groupIds.push(comp.id);
+          return;
+        }
+      }
       return;
     }
     // let nextCompId = compId;
@@ -47,6 +65,9 @@ export const editActions = EditorModule.action({
     //   const comps = this.helper.getCompTrees(compId);
     //   nextCompId = comps[1].id;
     // }
+    if (this.store.currCompId == compId) {
+      return;
+    }
     this.store.currCompId = "";
     this.store.currStreamCardId = "";
     this.store.setCurrComp(compId);
@@ -70,20 +91,19 @@ export const editActions = EditorModule.action({
   },
 
   async removeStreamCard(compId: string) {
-    
-    await queenApi.showConfirm({title:"删除", content:"确认删除当前内容?"})
+    await queenApi.showConfirm({ title: "删除", content: "确认删除当前内容?" });
 
     if (this.store.streamCardIds.length < 2) {
       return;
     }
     let nextCard = this.store.currStreamCardId;
     if (compId == this.store.currStreamCardId) {
-        const i = this.store.streamCardIds.indexOf(compId)
-        nextCard = this.store.streamCardIds[i+1]
-        if (!nextCard) {
-          nextCard = this.store.streamCardIds[i-1]
-        }
-    } 
+      const i = this.store.streamCardIds.indexOf(compId);
+      nextCard = this.store.streamCardIds[i + 1];
+      if (!nextCard) {
+        nextCard = this.store.streamCardIds[i - 1];
+      }
+    }
     this.store.deleteComp(compId);
     this.store.setCurrComp(nextCard);
   },
@@ -162,7 +182,7 @@ export const editActions = EditorModule.action({
         ratio: this.store.isEditComp ? 0 : 1,
       });
       const thumbnail = URL.createObjectURL(blob);
-      this.store.updateDesignThumbnail(thumbnail);
+      this.store.setDesignThumbnail(thumbnail);
 
       if (autoSave) {
         await this.controls.uploader.uploadBlobs(this.store.designData);
@@ -227,4 +247,118 @@ export const editActions = EditorModule.action({
       comp.layout.transform.x = 0;
     }
   },
+
+  // 开启组合模式
+  enableGroupMode() {
+    this.store.setGroupIds(
+      this.store.currCompId ? [this.store.currCompId] : []
+    );
+    this.store.setGroupMode(true);
+  },
+  // 关闭组合模式
+  async disableGroupMode() {
+    const groupId = await this.actions.combineGroupComps();
+    if (groupId) {
+      this.store.setCurrComp(groupId);
+    }
+    this.store.setGroupIds([]);
+    this.store.setGroupMode(false);
+  },
+  // 合并组件
+  async combineGroupComps() {
+    const { helper, store } = this;
+    const { groupIds } = store;
+    if (groupIds.length < 2) return;
+    const compsRect: Record<
+      string,
+      { t: number; l: number; r: number; b: number }
+    > = {};
+    const parentComp = helper.findParentComp(groupIds[0]) as DesignComp;
+    const parentRect = parentComp.$el.getBoundingClientRect();
+    groupIds.forEach((id) => {
+      const comp = helper.findComp(id) as DesignComp;
+      const itemRect = comp.$el.getBoundingClientRect();
+      compsRect[id] = {
+        t: itemRect.top - parentRect.top,
+        l: itemRect.left - parentRect.left,
+        r: itemRect.right - parentRect.left,
+        b: itemRect.bottom - parentRect.top,
+      };
+    });
+
+    const confVals = Object.values(compsRect);
+    const groupConf = {
+      t: Math.min(...confVals.map((d) => d.t)),
+      l: Math.min(...confVals.map((d) => d.l)),
+      r: Math.max(...confVals.map((d) => d.r)),
+      b: Math.max(...confVals.map((d) => d.b)),
+    };
+
+    const groupId = await this.store.insertCompContainer("Group", parentComp);
+
+    const groupComp = helper.findComp(groupId) as DesignComp;
+
+    groupComp.layout = {
+      size: [
+        helper.pxToDesignSize(groupConf.r - groupConf.l),
+        helper.pxToDesignSize(groupConf.b - groupConf.t),
+      ],
+      position: "absolute",
+      transform: {
+        x: helper.pxToDesignSize(groupConf.l),
+        y: helper.pxToDesignSize(groupConf.t),
+      },
+    };
+
+    groupIds.forEach((id) => {
+      const comp = helper.findComp(id) as DesignComp;
+      comp.layout.transform || (comp.layout.transform = {});
+      comp.layout.transform.x =
+        (comp.layout.transform.x || 0) - (groupComp.layout.transform?.x || 0);
+
+      comp.layout.transform.y =
+        (comp.layout.transform.y || 0) - (groupComp.layout.transform?.y || 0);
+    });
+
+    groupComp.children.default = parentComp.children.default?.filter((d) =>
+      groupIds.includes(d)
+    );
+    parentComp.children.default = parentComp.children.default?.filter(
+      (d) => !groupIds.includes(d)
+    );
+
+    return groupId;
+  },
+  // 取消打组
+  cancelGroupComps(groupComp: DesignComp) {
+    const { helper } = this;
+    const groupIds = groupComp.children.default as string[];
+
+    const parentComp = helper.findParentComp(groupComp.id) as DesignComp;
+
+    const parentMatrix = new Matrix();
+
+    groupIds.forEach((id) => {
+      const comp = helper.findComp(id) as DesignComp;
+
+      parentMatrix.setFormDiv(parentComp.$el);
+
+      const compMatrix = new Matrix();
+      compMatrix.setFormDiv(comp.$el);
+      compMatrix.multipy(parentMatrix);
+
+      comp.layout.transform || (comp.layout.transform = {});
+      comp.layout.transform.x = helper.pxToDesignSize(compMatrix.getX());
+      comp.layout.transform.y = helper.pxToDesignSize(compMatrix.getY());
+      comp.layout.transform.s = compMatrix.getScale();
+      comp.layout.transform.r = compMatrix.getRotate();
+    });
+
+    const childIds = [...(parentComp.children.default as string[])];
+
+    const groupIndex = childIds.findIndex((id) => groupComp.id === id);
+    childIds.splice(groupIndex, 1, ...groupIds);
+
+    parentComp.children.default = childIds;
+  },
 });

+ 2 - 2
src/modules/editor/module/actions/init.ts

@@ -22,7 +22,7 @@ export const initActions = EditorModule.action({
     const ret = await this.https[
       this.store.isEditComp ? "getCompDetail" : "getDesignDetail"
     ](id);
-    this.store.initDesignData(ret.result);
+    this.store.setDesignData(ret.result);
   },
   // 切换模式
   switchMode(v: EditorMode) {
@@ -31,5 +31,5 @@ export const initActions = EditorModule.action({
 
   onViewReady() {
     this.store.currStreamCardId = this.store.streamCardIds[0];
-  }
+  },
 });

+ 19 - 2
src/modules/editor/module/helpers/index.ts

@@ -8,15 +8,32 @@ export const helpers = EditorModule.helper({
   designToNaturalSize(value: number) {
     return parseFloat((value / 100).toFixed(2)) + "rem";
   },
+  pxToDesignSize(value: number) {
+    return value * 2;
+  },
   findComp(compId: string) {
     const { compMap } = this.store.designData;
     const comp = compMap[compId];
     if (comp) return comp;
   },
   isStreamCard(compId: string) {
-    return this.store.streamCardIds.indexOf(compId) > -1
+    return this.store.streamCardIds.indexOf(compId) > -1;
+  },
+  isGroupComp(compId: string) {
+    return this.store.groupIds.indexOf(compId) > -1;
+  },
+  isGroupCompChild(compId: string) {
+    const comps = this.helper.getCompTrees(compId);
+    comps.pop();
+    while (comps.length) {
+      const comp = comps.pop() as DesignComp;
+      if (comp.compKey === "Group") {
+        return true;
+      }
+    }
+    return false;
   },
-  
+
   findParentComp(compId: string): DesignComp | undefined {
     const comp = this.helper.findComp(compId);
     if (comp) return this.helper.findComp(comp.pid);

+ 2 - 0
src/modules/editor/module/index.ts

@@ -13,6 +13,7 @@ import { initActions } from "./actions/init";
 import { helpers } from "./helpers";
 import { https } from "./https";
 import { store } from "./stores";
+import { DragAddCtrl } from "../controllers/DragAddCtrl";
 
 export class EditorModule extends ModuleRoot {
   config = this.setConfig({
@@ -37,6 +38,7 @@ export class EditorModule extends ModuleRoot {
       dir: "queenshow",
     }),
     transferCtrl: new TransferCtrl(this),
+    dragAddCtrl: new DragAddCtrl(this),
     streamCardTransferCtrl: new TransferCtrl(this),
     historyCtrl: new HistoryCtrl(this),
     pickCtrl: new ImagePickController(),

+ 7 - 14
src/modules/editor/module/stores/index.ts

@@ -50,29 +50,22 @@ export const store = EditorModule.store({
     },
     setGroupMode(status: boolean) {
       this.store.groupModeStatus = status;
-      this.store.groupIds = [];
-      if (this.store.currCompId) {
-        this.store.groupIds.push(this.store.currCompId);
-      }
     },
-    initDesignData(data: Partial<DesignTemp>) {
+    setGroupIds(ids: string[]) {
+      this.store.groupIds = ids;
+    },
+    setDesignData(data: Partial<DesignTemp>) {
       this.store.designData = new DesignTemp(data);
     },
     async insertDesignContent(compKey: ICompKeys, index?: number) {
       const { pageCompIds } = this.store;
       index === undefined && (index = pageCompIds.length);
-      const compId = await this.controls.compUICtrl.createCompId(
-        compKey,
-        "root"
-      );
+      const compId = await this.controls.compUICtrl.createCompId(compKey);
       pageCompIds.splice(index, 0, compId);
       return compId;
     },
     async insertCompContainer(compKey: ICompKeys, container: DesignComp) {
-      const compId = await this.controls.compUICtrl.createCompId(
-        compKey,
-        container.id
-      );
+      const compId = await this.controls.compUICtrl.createCompId(compKey);
       container.children.default || (container.children.default = []);
       container.children.default.push(compId);
       return compId;
@@ -148,7 +141,7 @@ export const store = EditorModule.store({
     setTextEditingState(state: boolean) {
       this.store.textEditingState = state;
     },
-    updateDesignThumbnail(url: string) {
+    setDesignThumbnail(url: string) {
       this.store.designData.thumbnail = url;
     },
   },

+ 478 - 0
src/modules/editor/objects/DesignTemp/creates/Matrix.ts

@@ -0,0 +1,478 @@
+export class Matrix {
+  a = 1;
+  b = 0;
+  c = 0;
+  d = 1;
+  e = 0;
+  f = 0;
+
+  setFormDiv(div: HTMLElement) {
+    let transformMatrix = window
+      .getComputedStyle(div)
+      .getPropertyValue("transform");
+    if (!transformMatrix || transformMatrix === "none") {
+      transformMatrix = "matrix(1,0,0,1,0,0)";
+    }
+    const values = transformMatrix.split("(")[1].split(")")[0].split(",");
+    this.a = +values[0];
+    this.b = +values[1];
+    this.c = +values[2];
+    this.d = +values[3];
+    this.e = +values[4];
+    this.f = +values[5];
+  }
+
+  apply(div: HTMLElement) {
+    const b = this.b;
+    const a = this.a;
+    const angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
+
+    // 计算缩放比例
+    const scaleX = Math.sqrt(a * a + b * b);
+    // const scaleY = Math.sqrt(c*c + d*d);
+
+    // 计算平移距离
+    const translateX = this.e;
+    const translateY = this.f;
+    //console.log('angle:', angle, 'scaleX:', scaleX, 'scaleY:', scaleY, 'translateX:', translateX, 'translateY:', translateY)
+
+    div.style.transform = `translateX(${translateX}rem) translateY(${translateY}rem) rotate(${angle}deg) scale(${scaleX})`;
+
+    return this;
+  }
+
+  getX() {
+    return this.e;
+  }
+
+  getY() {
+    return this.f;
+  }
+
+  getRotate() {
+    const b = this.b;
+    const a = this.a;
+    return Math.round(Math.atan2(b, a) * (180 / Math.PI));
+  }
+
+  getScale() {
+    const b = this.b;
+    const a = this.a;
+
+    return Math.sqrt(a * a + b * b);
+  }
+
+  // /**
+  //  * Flips the horizontal values.
+  //  */
+  // flipX() {
+  //   this.transform(-1, 0, 0, 1, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Flips the vertical values.
+  //  */
+  // flipY() {
+  //   this.transform(1, 0, 0, -1, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Short-hand to reset current matrix to an identity matrix.
+  //  */
+  // reset() {
+  //   this.a = this.d = 1;
+  //   this.b = this.c = this.e = this.f = 0;
+  //   this._setCtx();
+  //   return this;
+  // }
+
+  // /**
+  //  * Rotates current matrix accumulative by angle.
+  //  * @param {number} angle - angle in radians
+  //  */
+  // rotate(angle) {
+  //   var cos = Math.cos(angle),
+  //     sin = Math.sin(angle);
+  //   this.transform(cos, sin, -sin, cos, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Helper method to make a rotation based on an angle in degrees.
+  //  * @param {number} angle - angle in degrees
+  //  */
+  // rotateDeg(angle) {
+  //   this.rotate(angle * 0.017453292519943295);
+  //   return this;
+  // }
+
+  // /**
+  //  * Scales current matrix accumulative.
+  //  * @param {number} sx - scale factor x (1 does nothing)
+  //  * @param {number} sy - scale factor y (1 does nothing)
+  //  */
+  // scale(sx, sy) {
+  //   this.transform(sx, 0, 0, sy, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Scales current matrix on x axis accumulative.
+  //  * @param {number} sx - scale factor x (1 does nothing)
+  //  */
+  // scaleX(sx) {
+  //   this.transform(sx, 0, 0, 1, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Scales current matrix on y axis accumulative.
+  //  * @param {number} sy - scale factor y (1 does nothing)
+  //  */
+  // scaleY(sy) {
+  //   this.transform(1, 0, 0, sy, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Apply skew to the current matrix accumulative.
+  //  * @param {number} sx - amount of skew for x
+  //  * @param {number} sy - amount of skew for y
+  //  */
+  // skew(sx, sy) {
+  //   this.transform(1, sy, sx, 1, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Apply skew for x to the current matrix accumulative.
+  //  * @param {number} sx - amount of skew for x
+  //  */
+  // skewX(sx) {
+  //   this.transform(1, 0, sx, 1, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Apply skew for y to the current matrix accumulative.
+  //  * @param {number} sy - amount of skew for y
+  //  */
+  // skewY(sy) {
+  //   this.transform(1, sy, 0, 1, 0, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Set current matrix to new absolute matrix.
+  //  * @param {number} a - scale x
+  //  * @param {number} b - skew y
+  //  * @param {number} c - skew x
+  //  * @param {number} d - scale y
+  //  * @param {number} e - translate x
+  //  * @param {number} f - translate y
+  //  */
+  // setTransform(a, b, c, d, e, f) {
+  //   this.a = a;
+  //   this.b = b;
+  //   this.c = c;
+  //   this.d = d;
+  //   this.e = e;
+  //   this.f = f;
+  //   this._setCtx();
+
+  //   return this;
+  // }
+
+  // /**
+  //  * Translate current matrix accumulative.
+  //  * @param {number} tx - translation for x
+  //  * @param {number} ty - translation for y
+  //  */
+  // translate(tx, ty) {
+  //   this.transform(1, 0, 0, 1, tx, ty);
+  //   return this;
+  // }
+
+  // /**
+  //  * Translate current matrix on x axis accumulative.
+  //  * @param {number} tx - translation for x
+  //  */
+  // translateX(tx) {
+  //   this.transform(1, 0, 0, 1, tx, 0);
+  //   return this;
+  // }
+
+  // /**
+  //  * Translate current matrix on y axis accumulative.
+  //  * @param {number} ty - translation for y
+  //  */
+  // translateY(ty) {
+  //   this.transform(1, 0, 0, 1, 0, ty);
+  //   return this;
+  // }
+
+  multipy(m2: Matrix) {
+    return this.transform(m2.a, m2.b, m2.c, m2.d, m2.e, m2.f);
+  }
+
+  /**
+   * Multiplies current matrix with new matrix values.
+   * @param {number} a2 - scale x
+   * @param {number} b2 - skew y
+   * @param {number} c2 - skew x
+   * @param {number} d2 - scale y
+   * @param {number} e2 - translate x
+   * @param {number} f2 - translate y
+   */
+  transform(
+    a2: number,
+    b2: number,
+    c2: number,
+    d2: number,
+    e2: number,
+    f2: number
+  ) {
+    const a1 = this.a,
+      b1 = this.b,
+      c1 = this.c,
+      d1 = this.d,
+      e1 = this.e,
+      f1 = this.f;
+
+    /* matrix order (canvas compatible):
+     * ace
+     * bdf
+     * 001
+     */
+    this.a = a1 * a2 + c1 * b2;
+    this.b = b1 * a2 + d1 * b2;
+    this.c = a1 * c2 + c1 * d2;
+    this.d = b1 * c2 + d1 * d2;
+    this.e = a1 * e2 + c1 * f2 + e1;
+    this.f = b1 * e2 + d1 * f2 + f1;
+
+    return this;
+  }
+
+  // /**
+  //  * Get an inverse matrix of current matrix. The method returns a new
+  //  * matrix with values you need to use to get to an identity matrix.
+  //  * Context from parent matrix is not applied to the returned matrix.
+  //  * @returns {Matrix}
+  //  */
+  getInverse() {
+    const a = this.a,
+      b = this.b,
+      c = this.c,
+      d = this.d,
+      e = this.e,
+      f = this.f,
+      m = new Matrix(),
+      dt = a * d - b * c;
+
+    m.a = d / dt;
+    m.b = -b / dt;
+    m.c = -c / dt;
+    m.d = a / dt;
+    m.e = (c * f - d * e) / dt;
+    m.f = -(a * f - b * e) / dt;
+
+    return m;
+  }
+
+  // /**
+  //  * Interpolate this matrix with another and produce a new matrix.
+  //  * t is a value in the range [0.0, 1.0] where 0 is this instance and
+  //  * 1 is equal to the second matrix. The t value is not constrained.
+  //  *
+  //  * Context from parent matrix is not applied to the returned matrix.
+  //  *
+  //  * @param {Matrix} m2 - the matrix to interpolate with.
+  //  * @param {number} t - interpolation [0.0, 1.0]
+  //  * @returns {Matrix} - new instance with the interpolated result
+  //  */
+  // interpolate(m2, t) {
+  //   var m = new Matrix();
+
+  //   m.a = this.a + (m2.a - this.a) * t;
+  //   m.b = this.b + (m2.b - this.b) * t;
+  //   m.c = this.c + (m2.c - this.c) * t;
+  //   m.d = this.d + (m2.d - this.d) * t;
+  //   m.e = this.e + (m2.e - this.e) * t;
+  //   m.f = this.f + (m2.f - this.f) * t;
+
+  //   return m;
+  // }
+
+  // /**
+  //  * Apply current matrix to x and y point.
+  //  * Returns a point object.
+  //  *
+  //  * @param {number} x - value for x
+  //  * @param {number} y - value for y
+  //  * @returns {{x: number, y: number}} A new transformed point object
+  //  */
+  // applyToPoint(x, y) {
+  //   return {
+  //     x: x * this.a + y * this.c + this.e,
+  //     y: x * this.b + y * this.d + this.f,
+  //   };
+  // }
+
+  // /**
+  //  * Apply current matrix to array with point objects or point pairs.
+  //  * Returns a new array with points in the same format as the input array.
+  //  *
+  //  * A point object is an object literal:
+  //  *
+  //  * {x: x, y: y}
+  //  *
+  //  * so an array would contain either:
+  //  *
+  //  * [{x: x1, y: y1} {x: x2, y: y2} ... {x: xn, y: yn}]
+  //  *
+  //  * or
+  //  * [x1, y1, x2, y2, ... xn, yn]
+  //  *
+  //  * @param {Array} points - array with point objects or pairs
+  //  * @returns {Array} A new array with transformed points
+  //  */
+  // applyToArray(points) {
+  //   var i = 0,
+  //     p,
+  //     l,
+  //     mxPoints = [];
+
+  //   if (typeof points[0] === "number") {
+  //     l = points.length;
+
+  //     while (i < l) {
+  //       p = this.applyToPoint(points[i++], points[i++]);
+  //       mxPoints.push(p.x, p.y);
+  //     }
+  //   } else {
+  //     for (; (p = points[i]); i++) {
+  //       mxPoints.push(this.applyToPoint(p.x, p.y));
+  //     }
+  //   }
+
+  //   return mxPoints;
+  // }
+
+  // /**
+  //  * Apply current matrix to a typed array with point pairs. Although
+  //  * the input array may be an ordinary array, this method is intended
+  //  * for more performant use where typed arrays are used. The returned
+  //  * array is regardless always returned as a Float32Array.
+  //  *
+  //  * @param {*} points - (typed) array with point pairs
+  //  * @returns {Float32Array} A new array with transformed points
+  //  */
+  // applyToTypedArray(points) {
+  //   var i = 0,
+  //     p,
+  //     l = points.length,
+  //     mxPoints = new Float32Array(l);
+
+  //   while (i < l) {
+  //     p = this.applyToPoint(points[i], points[i + 1]);
+  //     mxPoints[i++] = p.x;
+  //     mxPoints[i++] = p.y;
+  //   }
+
+  //   return mxPoints;
+  // }
+
+  // /**
+  //  * Apply to any canvas 2D context object. This does not affect the
+  //  * context that optionally was referenced in constructor unless it is
+  //  * the same context.
+  //  * @param {CanvasRenderingContext2D} context
+  //  */
+  // applyToContext(context) {
+  //   context.setTransform(this.a, this.b, this.c, this.d, this.e, this.f);
+  //   return this;
+  // }
+
+  // /**
+  //  * Returns true if matrix is an identity matrix (no transforms applied).
+  //  * @returns {boolean} True if identity (not transformed)
+  //  */
+  // isIdentity() {
+  //   return (
+  //     this._isEqual(this.a, 1) &&
+  //     this._isEqual(this.b, 0) &&
+  //     this._isEqual(this.c, 0) &&
+  //     this._isEqual(this.d, 1) &&
+  //     this._isEqual(this.e, 0) &&
+  //     this._isEqual(this.f, 0)
+  //   );
+  // }
+
+  // /**
+  //  * Compares current matrix with another matrix. Returns true if equal
+  //  * (within epsilon tolerance).
+  //  * @param {Matrix} m - matrix to compare this matrix with
+  //  * @returns {boolean}
+  //  */
+  // isEqual(m) {
+  //   return (
+  //     this._isEqual(this.a, m.a) &&
+  //     this._isEqual(this.b, m.b) &&
+  //     this._isEqual(this.c, m.c) &&
+  //     this._isEqual(this.d, m.d) &&
+  //     this._isEqual(this.e, m.e) &&
+  //     this._isEqual(this.f, m.f)
+  //   );
+  // }
+
+  // /**
+  //  * Compares floating point values with some tolerance (epsilon)
+  //  * @param {number} f1 - float 1
+  //  * @param {number} f2 - float 2
+  //  * @returns {boolean}
+  //  * @private
+  //  */
+  // _isEqual(f1, f2) {
+  //   return Math.abs(f1 - f2) < 1e-14;
+  // }
+
+  // /**
+  //  * Apply current absolute matrix to context if defined, to sync it.
+  //  * @private
+  //  */
+  // _setCtx() {
+  //   if (this.context)
+  //     this.context.setTransform(this.a, this.b, this.c, this.d, this.e, this.f);
+  // }
+}
+
+//streamCard 0, 0, 750, 800
+
+// const item1 = document.createElement("div");
+// //child1.style.transform  200, 200
+
+// const item2 = document.createElement("div");
+// //child1.style.transform  300, 200
+
+// const parentDiv = document.createElement("div");
+// //child1.style.transform  200,200 widht 0
+
+// const parentMtx = new Matrix(parentDiv);
+// const parentInverMtx = parentMtx.getInverse();
+
+// //group
+// const item1Mtx = new Matrix(item1);
+// item1Mtx.multipy(parentInverMtx);
+
+// item1Mtx.appy();
+// parentDiv.append(item1);
+
+// //ungroup
+// const item1Mtx1 = new Matrix(item1);
+// const parentMtx2 = new Matrix(parentDiv);
+
+// item1Mtx1.multipy(parentMtx2);
+// item1Mtx1.appy();

+ 1 - 1
src/modules/editor/objects/DesignTemp/creates/createCompStyle.ts

@@ -31,7 +31,7 @@ export function createCompStyle(module: EditorModule, layout: Layout) {
       transform.translateX = designToNaturalSize(layout.transform.x);
     }
     if (layout.transform.y) {
-      style.marginTop = designToNaturalSize(layout.transform.y);
+      transform.translateY = designToNaturalSize(layout.transform.y);
     }
     if (layout.transform.r) {
       transform.rotate = layout.transform.r + "deg";

+ 1 - 1
src/modules/editor/objects/DesignTemp/index.ts

@@ -26,7 +26,7 @@ export class DesignTemp {
       const childIds = comp.getChildIds();
       childIds.forEach((cid) => {
         const childComp = this.compMap[cid];
-        Object.defineProperty(childComp, "pid", { value: comp.id });
+        // Object.defineProperty(childComp, "pid", { value: comp.id });
       });
     });
   }

+ 1 - 1
src/modules/editor/objects/DesignTemp/versions/0.0.1.ts

@@ -15,7 +15,7 @@ export function dataTransform(data: any) {
       comp.children = CompUI[comp.compKey].createComp({
         compKey: comp.compKey,
       }).children;
-      addCacheToMap(compMap, comp.id);
+      addCacheToMap(compMap);
     }
   });
 

+ 3 - 0
src/modules/editor/objects/Toolbars/CompToolbars.ts

@@ -11,4 +11,7 @@ export const CompToolbars: ICompToolbars = {
     toolbars.align,
     toolbars.delete,
   ],
+  Group: [
+    toolbars.cancelGroup,
+  ]
 };

+ 7 - 0
src/modules/editor/objects/Toolbars/default.ts

@@ -145,4 +145,11 @@ export const toolbars = createToolbars({
       this.actions.saveAsComp(comp);
     },
   },
+  // 取消打组
+  cancelGroup: {
+    component: TipIcons.CancelGroup,
+    onClick(comp) {
+      this.actions.cancelGroupComps(comp);
+    },
+  }
 });

+ 1 - 0
src/typings/pro.d.ts

@@ -18,4 +18,5 @@ declare type TableListResult<T> = Promise<{
 declare module "vue-dndrop" {
   export const Container: any;
   export const Draggable: any;
+  export const vueDndrop: any;
 }