lianghongjie vor 1 Jahr
Ursprung
Commit
0045389259
24 geänderte Dateien mit 402 neuen und 201 gelöschten Zeilen
  1. 4 12
      src/modules/editor/components/CompUI/basicUI/Container/component.tsx
  2. 2 17
      src/modules/editor/components/CompUI/basicUI/Container/index.ts
  3. 1 0
      src/modules/editor/components/CompUI/basicUI/Image/component.tsx
  4. 2 2
      src/modules/editor/components/CompUI/basicUI/Page/PageForm.tsx
  5. 8 8
      src/modules/editor/components/CompUI/basicUI/Page/component.tsx
  6. 18 20
      src/modules/editor/components/CompUI/basicUI/Text/component.tsx
  7. 7 2
      src/modules/editor/components/CompUI/basicUI/Transfer/index.tsx
  8. 1 0
      src/modules/editor/components/CompUI/basicUI/index.ts
  9. 0 2
      src/modules/editor/components/CompUI/index.ts
  10. 4 2
      src/modules/editor/components/Viewport/Content/index.tsx
  11. 0 98
      src/modules/editor/components/Viewport/Slider/SliderLeft.tsx
  12. 51 0
      src/modules/editor/components/Viewport/Slider/SliderLeft/CustomComps.tsx
  13. 117 0
      src/modules/editor/components/Viewport/Slider/SliderLeft/index.tsx
  14. 9 6
      src/modules/editor/components/Viewport/Slider/SliderRight/CompTree.tsx
  15. 1 2
      src/modules/editor/components/Viewport/Slider/SliderRight/index.tsx
  16. 131 0
      src/modules/editor/controllers/CompUICtrl/index.ts
  17. 9 13
      src/modules/editor/controllers/TransferCtrl/index.ts
  18. 7 5
      src/modules/editor/module/actions/edit.ts
  19. 2 1
      src/modules/editor/module/index.ts
  20. 5 8
      src/modules/editor/module/stores/index.ts
  21. 1 1
      src/modules/editor/objects/Toolbars/CompToolbars.ts
  22. 1 0
      src/modules/editor/objects/Toolbars/TreeToolbars.ts
  23. 2 2
      src/modules/resource/actions/promotion.ts
  24. 19 0
      src/utils/index.ts

+ 4 - 12
src/modules/editor/components/CompUI/basicUI/Container/component.tsx

@@ -1,7 +1,6 @@
 import { defineComponent } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
-import { CompUI } from "../..";
 import { useEditor } from "../../../..";
 import { DesignComp } from "../../../../objects/DesignTemp/DesignComp";
 import { View } from "../View";
@@ -11,20 +10,13 @@ export const Component = defineComponent({
     compId: string().isRequired,
   },
   setup(props) {
-    const { store, helper } = useEditor();
-    const { value, children } = useCompData(props.compId);
+    const { helper, controls } = useEditor();
+    const { children } = useCompData(props.compId);
     return () => (
-      <View
-        compId={props.compId}
-        style={{
-          position: "absolute",
-          top: helper.designToNaturalSize(value.position[1]),
-          left: helper.designToNaturalSize(value.position[0]),
-        }}
-      >
+      <View compId={props.compId}>
         {children.default.map((compId) => {
           const compItem = helper.findComp(compId) as DesignComp;
-          const Comp = CompUI[compItem.compKey].Component;
+          const Comp = controls.compUICtrl.state.components.get(compItem.compKey)?.Component;
           return <Comp key={compItem.id} compId={compItem.id} />;
         })}
       </View>

+ 2 - 17
src/modules/editor/components/CompUI/basicUI/Container/index.ts

@@ -1,7 +1,6 @@
 import { Dict_Imgs } from "@/dict";
 import { createAttrsForm } from "../../defines/createAttrsForm";
 import { createCompHooks } from "../../defines/createCompHooks";
-import { GroupNumber } from "../../formItems/GroupNumber";
 
 export { Component } from "./component";
 
@@ -11,24 +10,10 @@ export const options = {
 };
 
 export const { createComp, useCompData } = createCompHooks({
-  value: {
-    position: [0, 0],
-  },
-  layout: {
-    size: [200, 200],
-  },
+  value: {},
   children: {
     default: () => [] as string[],
   },
 });
 
-export const Form = createAttrsForm([
-  {
-    label: "坐标",
-    dataIndex: "value.position",
-    component: GroupNumber,
-    props: {
-      labels: ["X", "Y"],
-    },
-  },
-]);
+export const Form = createAttrsForm([]);

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

@@ -40,6 +40,7 @@ export const Component = defineComponent({
 
       return (
         <View
+          class="overflow-hidden"
           compId={props.compId}
           onDblclick={store.isEditMode ? changeVal : undefined}
         >

+ 2 - 2
src/modules/editor/components/CompUI/basicUI/Page/PageForm.tsx

@@ -7,7 +7,7 @@ import { any } from "vue-types";
 const styleColumns: ColumnItem[] = [
   {
     label: "内边距",
-    dataIndex: "layout.padding",
+    dataIndex: "padding",
     component: "Input",
   },
 ];
@@ -18,7 +18,7 @@ export const PageForm = defineComponent({
   },
   setup(props) {
     function changeVal(e: { dataIndex: string; value: any }) {
-      set(props.component, e.dataIndex, e.value);
+      set(props.component.layout, e.dataIndex, e.value);
     }
 
     return () => {

+ 8 - 8
src/modules/editor/components/CompUI/basicUI/Page/component.tsx

@@ -12,16 +12,16 @@ export const Component = defineComponent({
     const { helper } = editor;
     const { children, layout } = useCompData(props.compId);
 
-    console.log(children);
-
     return () => (
       <div style={helper.createStyle(layout)}>
-        {slots.Container?.(
-          children.default.map((compId) => {
-            const comp = helper.findComp(compId);
-            return slots.CompItem?.(comp);
-          })
-        )}
+        <div class="page-content relative">
+          {slots.Container?.(
+            children.default.map((compId) => {
+              const comp = helper.findComp(compId);
+              return slots.CompItem?.(comp);
+            })
+          )}
+        </div>
       </div>
     );
   },

+ 18 - 20
src/modules/editor/components/CompUI/basicUI/Text/component.tsx

@@ -7,7 +7,7 @@ import { FontColor, FontFamily, FontSize } from "@ckeditor/ckeditor5-font";
 import { Link } from "@ckeditor/ckeditor5-link";
 import { Paragraph } from "@ckeditor/ckeditor5-paragraph";
 import { css } from "@linaria/core";
-import { defineComponent, reactive } from "vue";
+import { defineComponent } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
@@ -53,40 +53,30 @@ export const Component = defineComponent({
       },
     };
 
-    const state = reactive({
-      editing: false,
-    });
-
     let editorInstance: InlineEditor;
 
     return () => (
       <View
-        class={[state.editing && "drag-disable"]}
+        class={[textStyle, store.currCompId === props.compId && "drag-disable"]}
+        style={{ ["--text-len"]: comp?.value.length }}
         compId={props.compId}
-        onDblclick={() => {
-          if (store.isEditMode) {
-            state.editing = true;
-            editorInstance.disableReadOnlyMode("editor");
-            editorInstance.focus();
-          }
-        }}
       >
         <ckeditor
           class={textStyle}
           editor={InlineEditor}
-          onBlur={(e: any, editor: InlineEditor) => {
-            state.editing = false;
-            editor.enableReadOnlyMode("editor");
+          onBlur={() => {
             if (comp) {
-              comp.value = editor.getData();
+              comp.value = editorInstance.getData();
             } else {
-              emit("update:value", editor.getData());
+              emit("update:value", editorInstance.getData());
             }
           }}
           onReady={(editor: InlineEditor) => {
             editorInstance = editor;
             editor.setData(comp?.value || props.value);
-            editor.enableReadOnlyMode("editor");
+            if (store.isPreview) {
+              editor.enableReadOnlyMode("editor");
+            }
           }}
           config={config}
         />
@@ -100,11 +90,19 @@ const textStyle = css`
   p {
     margin: 0;
   }
-  &.ck.ck-editor__editable_inline {
+  .ck.ck-editor__editable_inline {
+    pointer-events: none;
+
     > :last-child,
     > :first-child {
       margin-top: 0;
       margin-bottom: 0;
     }
   }
+
+  &.drag-disable {
+    .ck.ck-editor__editable_inline {
+      pointer-events: auto;
+    }
+  }
 `;

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

@@ -36,7 +36,10 @@ export const Transfer = defineComponent({
 
     onMounted(() => {
       setTimeout(() => {
-        transferCtrl.init();
+        const pageEl = document.querySelector(".page-content");
+        if (pageEl) {
+          transferCtrl.init(pageEl as HTMLElement);
+        }
       });
     });
 
@@ -50,6 +53,8 @@ export const Transfer = defineComponent({
 
     return () => {
       const comp = store.currComp;
+      const toolbarOpts =
+        CompToolbars[store.currComp.compKey] || CompToolbars.default;
       return (
         transferStyle.width && (
           <div
@@ -73,7 +78,7 @@ export const Transfer = defineComponent({
               onMousedown={(e) => transferCtrl.mousedown(e, "resize")}
             ></div>
             <div class={toolbarStyle}>
-              {CompToolbars.default.map((item, i) => {
+              {toolbarOpts.map((item) => {
                 return item.getVisible.call(editor, comp) ? (
                   <item.component
                     class="p-4px"

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

@@ -1,4 +1,5 @@
 export * as Container from "./Container";
+export * as Page from "./Page";
 export * as Image from "./Image";
 export * as Text from "./Text";
 export * as Video from "./Video";

+ 0 - 2
src/modules/editor/components/CompUI/index.ts

@@ -1,9 +1,7 @@
 import * as basicUI from "./basicUI";
 import * as customUI from "./customUI";
-import * as Page from "./basicUI/Page";
 
 export const CompUI = {
-  Page,
   ...basicUI,
   ...customUI,
 };

+ 4 - 2
src/modules/editor/components/Viewport/Content/index.tsx

@@ -11,7 +11,7 @@ import { Transfer } from "../../CompUI/basicUI/Transfer";
 export default defineUI({
   setup() {
     const editor = useEditor();
-    const { store, actions, helper, components } = editor;
+    const { store, actions, helper, components, controls } = editor;
 
     const hotKeyCtrl = new HotKeyCtrl(editor);
     hotKeyCtrl.init();
@@ -55,7 +55,9 @@ export default defineUI({
               );
             },
             CompItem(comp: DesignComp) {
-              const Comp = CompUI[comp.compKey]?.Component;
+              const Comp = controls.compUICtrl.state.components.get(
+                comp.compKey
+              )?.Component;
               return (
                 <Draggable class="!flex flex-col">
                   <Comp compId={comp.id} />

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

@@ -1,98 +0,0 @@
-import { useEditor } from "@/modules/editor";
-import { ICompKeys } from "@/modules/editor/typings";
-import { Radio } from "ant-design-vue";
-import { defineUI } from "queenjs";
-import { Container, Draggable } from "vue-dndrop";
-import { css } from "@linaria/core";
-import * as basicUI from "../../CompUI/basicUI";
-import * as customUI from "../../CompUI/customUI";
-import { useRoute } from "vue-router";
-
-export default defineUI({
-  setup() {
-    const editor = useEditor();
-    const r = useRoute();
-
-    return () => (
-      <div class="h-full flex flex-col">
-      
-        <div class="p-16px border-bottom !border-2px" onClick={()=>{
-            editor.jumpIndexHtml();
-        }}>资源中心</div>
-        
-
-        <div class="m-16px flex-1 flex flex-col h-0">
-          <Radio.Group>
-            <Radio.Button>模板</Radio.Button>
-            <Radio.Button>组件</Radio.Button>
-          </Radio.Group>
-          <div class="text-16px font-bold my-16px">基础组件</div>
-          <Container
-            class={basicStyle}
-            orientation="horizontal"
-            behaviour="copy"
-            group-name="canvas"
-            get-child-payload={(index: number) => {
-              return Object.keys(basicUI)[index];
-            }}
-          >
-            {Object.entries(basicUI).map(([compKey, uiOpt]) => {
-              return (
-                <Draggable key={compKey}>
-                  <div
-                    class="draggable-item text-center"
-                    onClick={() =>
-                      editor.actions.addCompToDesign(compKey as ICompKeys)
-                    }
-                  >
-                    <img
-                      class="w-full rounded-2px pointer-events-none"
-                      src={uiOpt.options.thumbnail}
-                      alt="封面图"
-                    />
-                    {uiOpt.options.name}
-                  </div>
-                </Draggable>
-              );
-            })}
-          </Container>
-          <div class="text-16px font-bold my-16px">模块组件</div>
-          <Container
-            class="-mx-16px p-16px space-y-10px flex-1 scrollbar"
-            behaviour="copy"
-            group-name="canvas"
-            get-child-payload={(index: number) => {
-              return Object.keys(customUI)[index];
-            }}
-          >
-            {Object.entries(customUI).map(([compKey, uiOpt]) => {
-              return (
-                <Draggable>
-                  <div
-                    class="text-center leading-50px bg-dark-50 rounded draggable-item"
-                    key={compKey}
-                    onClick={() =>
-                      editor.actions.addCompToDesign(compKey as ICompKeys)
-                    }
-                  >
-                    <img
-                      class="w-full rounded pointer-events-none"
-                      src={uiOpt.options.thumbnail}
-                      alt="封面图"
-                    />
-                    {/* {uiOpt.options.name} */}
-                  </div>
-                </Draggable>
-              );
-            })}
-          </Container>
-        </div>
-      </div>
-    );
-  },
-});
-
-const basicStyle = css`
-  margin: -10px;
-  border-spacing: 10px;
-`;

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

@@ -0,0 +1,51 @@
+import { useEditor } from "@/modules/editor";
+import { ICompKeys } from "@/modules/editor/typings";
+import { defineUI } from "queenjs";
+import { Container, Draggable } from "vue-dndrop";
+import { any } from "vue-types";
+
+export default defineUI({
+  props: {
+    components: any<
+      {
+        compKey: string;
+        name: string;
+        thumbnail: string;
+      }[]
+    >().isRequired,
+  },
+  setup(props) {
+    const editor = useEditor();
+    return () => (
+      <Container
+        class="space-y-10px scrollbar"
+        behaviour="copy"
+        group-name="canvas"
+        get-child-payload={(index: number) => {
+          return props.components[index].compKey;
+        }}
+      >
+        {props.components.map((item) => {
+          return (
+            <Draggable>
+              <div
+                class="text-center leading-50px bg-dark-50 rounded draggable-item"
+                key={item.compKey}
+                title={item.name}
+                onClick={() =>
+                  editor.actions.addCompToDesign(item.compKey as ICompKeys)
+                }
+              >
+                <img
+                  class="w-full rounded pointer-events-none"
+                  src={item.thumbnail}
+                  alt="封面图"
+                />
+              </div>
+            </Draggable>
+          );
+        })}
+      </Container>
+    );
+  },
+});

+ 117 - 0
src/modules/editor/components/Viewport/Slider/SliderLeft/index.tsx

@@ -0,0 +1,117 @@
+import { useEditor } from "@/modules/editor";
+import { ICompKeys } from "@/modules/editor/typings";
+import { css } from "@linaria/core";
+import { Radio } from "ant-design-vue";
+import { defineUI } from "queenjs";
+import { Container, Draggable } from "vue-dndrop";
+import CustomComps from "./CustomComps";
+import { useReactive } from "@queenjs/use";
+
+export default defineUI({
+  setup() {
+    const editor = useEditor();
+    const { compUICtrl } = editor.controls;
+    compUICtrl.init();
+
+    const tabs = [
+      { label: "模块组件", value: "senior" },
+      { label: "我的组件", value: "user" },
+    ];
+
+    const state = useReactive(() => ({
+      currTabType: "senior",
+      basicComps() {
+        return Array.from(compUICtrl.state.components.values()).filter(
+          (item) => item.compType === "basic" && item.compKey !== "Page"
+        );
+      },
+      currComps() {
+        return Array.from(compUICtrl.state.components.values()).filter(
+          (item) => state.currTabType === item.compType
+        );
+      },
+    }));
+
+    return () => (
+      <div class="h-full flex flex-col">
+        <div
+          class="p-16px border-bottom !border-2px"
+          onClick={() => {
+            editor.jumpIndexHtml();
+          }}
+        >
+          资源中心
+        </div>
+
+        <div class="m-16px flex-1 flex flex-col h-0">
+          <Radio.Group>
+            <Radio.Button>模板</Radio.Button>
+            <Radio.Button>组件</Radio.Button>
+          </Radio.Group>
+          <div class="text-16px font-bold my-16px">基础组件</div>
+          <Container
+            class={basicStyle}
+            orientation="horizontal"
+            behaviour="copy"
+            group-name="canvas"
+            get-child-payload={(index: number) => {
+              return state.basicComps[index].compKey;
+            }}
+          >
+            {state.basicComps.map((item) => {
+              return (
+                <Draggable key={item.compKey}>
+                  <div
+                    class="draggable-item text-center"
+                    onClick={() =>
+                      editor.actions.addCompToDesign(item.compKey as ICompKeys)
+                    }
+                  >
+                    <img
+                      class="w-full rounded-2px pointer-events-none"
+                      src={item.thumbnail}
+                      alt="封面图"
+                    />
+                    {item.name}
+                  </div>
+                </Draggable>
+              );
+            })}
+          </Container>
+          <div class={tabStyle}>
+            {tabs.map((item) => {
+              return (
+                <span
+                  class={[state.currTabType === item.value && "checked"]}
+                  onClick={() => (state.currTabType = item.value)}
+                >
+                  {item.label}
+                </span>
+              );
+            })}
+          </div>
+          <CustomComps
+            class="flex-1 -mx-16px p-16px"
+            components={state.currComps}
+          />
+        </div>
+      </div>
+    );
+  },
+});
+
+const basicStyle = css`
+  margin: -10px;
+  border-spacing: 10px;
+`;
+
+const tabStyle = css`
+  @apply text-16px my-16px space-x-10px;
+
+  span {
+    cursor: pointer;
+    &.checked {
+      font-weight: bold;
+    }
+  }
+`;

+ 9 - 6
src/modules/editor/components/Viewport/Slider/SliderRight/CompTree.tsx

@@ -1,3 +1,4 @@
+import { TreeToolbars } from "@/modules/editor/objects/Toolbars";
 import { css } from "@linaria/core";
 import { useReactive } from "@queenjs/use";
 import { Tree } from "ant-design-vue";
@@ -5,8 +6,6 @@ import { defineComponent } from "vue";
 import { string } from "vue-types";
 import { useEditor } from "../../../..";
 import { DesignComp } from "../../../../objects/DesignTemp/DesignComp";
-import { CompUI } from "../../../CompUI";
-import { TreeToolbars } from "@/modules/editor/objects/Toolbars";
 
 type TreeItem = {
   key: string;
@@ -17,7 +16,8 @@ type TreeItem = {
 
 export const CompTree = defineComponent({
   setup() {
-    const { store, actions, helper } = useEditor();
+    const { store, actions, helper, controls } = useEditor();
+    const { compUICtrl } = controls;
     const state = useReactive(() => ({
       expandedKeys() {
         const comps = helper.getCompTrees(store.currCompId);
@@ -30,7 +30,8 @@ export const CompTree = defineComponent({
             const comp = helper.findComp(id) as DesignComp;
             return {
               key: comp.id,
-              title: CompUI[comp.compKey].options.name,
+              title:
+                compUICtrl.state.components.get(comp.compKey)?.name || "未命名",
               value: comp.id,
               children: getCompChildren(comp.getChildIds()),
             };
@@ -73,10 +74,12 @@ const CompNode = defineComponent({
     const comp = editor.helper.findComp(props.id);
     return () => {
       if (!comp) return;
-      const compOpts = CompUI[comp.compKey].options;
+      const compOpts = editor.controls.compUICtrl.state.components.get(
+        comp.compKey
+      );
       const actions = TreeToolbars[comp.compKey] || TreeToolbars.default;
       const thumbnail =
-        comp.compKey === "Image" ? comp.value.url : compOpts.thumbnail;
+        comp.compKey === "Image" ? comp.value.url : compOpts?.thumbnail;
       return (
         <div class={nodeStyle}>
           <img src={thumbnail} />

+ 1 - 2
src/modules/editor/components/Viewport/Slider/SliderRight/index.tsx

@@ -1,7 +1,6 @@
 import { defineUI } from "queenjs";
 import { h } from "vue";
 import { useEditor } from "../../../..";
-import { CompUI } from "../../../CompUI";
 import { CompTree } from "./CompTree";
 
 export default defineUI({
@@ -16,7 +15,7 @@ export default defineUI({
           <div class="p-16px border-bottom !border-2px">设置栏</div>
           <div class="flex-1 p-16px scrollbar">
             {currComp?.compKey
-              ? h(CompUI[currComp.compKey].Form, { component: currComp })
+              ? h(editor.controls.compUICtrl.state.components.get(currComp.compKey)?.Form, { component: currComp })
               : null}
           </div>
           <div class="p-16px border-bottom !border-2px border-top">组件树</div>

+ 131 - 0
src/modules/editor/controllers/CompUICtrl/index.ts

@@ -0,0 +1,131 @@
+import { Dict_Imgs } from "@/dict";
+import { eachValuesAndPathsDeep, mapValuesDeep } from "@/utils";
+import { PageListController } from "@queenjs/controllers";
+import { set } from "lodash";
+import { nanoid } from "nanoid";
+import { Exception, ModuleControl } from "queenjs";
+import { reactive } from "vue";
+import * as basicUI from "../../components/CompUI/basicUI";
+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";
+import { ICompKeys } from "../../typings";
+
+interface CompItem {
+  compKey: string;
+  compType: "basic" | "senior" | "user";
+  name: string;
+  thumbnail: string;
+  Component: any;
+  Form: any;
+  createComp: (...args: any) => DesignComp;
+}
+
+export class CompUICtrl extends ModuleControl<EditorModule> {
+  state = reactive({
+    components: new Map<string, CompItem>(),
+  });
+  init() {
+    this.initDefaultUI();
+    this.initUserUI();
+  }
+  private initDefaultUI() {
+    Object.entries({ ...basicUI, ...customUI }).forEach(([key, value]) => {
+      this.state.components.set(key, {
+        compKey: key,
+        compType: (basicUI as any)[key] ? "basic" : "senior",
+        name: value.options.name,
+        thumbnail: value.options.thumbnail,
+        Component: value.Component,
+        Form: value.Form,
+        createComp: value.createComp,
+      });
+    });
+  }
+  private async initUserUI() {
+    const listCtrl = new PageListController<
+      { _id: string; title: string; thumbnail: string },
+      any
+    >(this.module.config.httpConfig);
+    listCtrl.setCrudPrefix("/frame");
+    listCtrl.state.size = 999;
+    await listCtrl.loadPage(1);
+
+    listCtrl.state.list.forEach((d) => {
+      const compItem: CompItem = {
+        compKey: d._id,
+        compType: "user",
+        name: d.title,
+        thumbnail: d.thumbnail || Dict_Imgs.Default,
+        Component: basicUI.Container.Component,
+        Form: basicUI.Container.Form,
+        createComp: basicUI.Container.createComp,
+      };
+      this.state.components.set(d._id, compItem);
+    });
+  }
+
+  async initUserCompDetail(compKey: string) {
+    const { compMap } = this.store.designData;
+    const { result } = await this.https.getCompDetail(compKey);
+    const idMap = new Map<string, string>();
+    const nextCompMap: Record<string, DesignComp> = {};
+    Object.entries(result.compMap as Record<string, DesignComp>).forEach(
+      ([key, comp]) => {
+        if (key === "root") {
+          comp.compKey = compKey as any;
+          idMap.set(key, compKey);
+        }
+        const id = idMap.get(key) || nanoid();
+        idMap.set(key, id);
+        comp.id = id;
+        eachValuesAndPathsDeep(
+          comp.children,
+          (v) => typeof v === "string",
+          (v, paths) => {
+            const id = idMap.get(v) || nanoid();
+            idMap.set(v, id);
+            set(comp.children, paths, id);
+          }
+        );
+        nextCompMap[id] = new DesignComp(comp);
+      }
+    );
+    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) {
+    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);
+    }
+    return compId;
+  }
+}

+ 9 - 13
src/modules/editor/controllers/TransferCtrl/index.ts

@@ -36,10 +36,10 @@ export class TransferCtrl extends ModuleControl<EditorModule> {
     transform: "",
   });
 
-  init() {
+  init(pageEl: HTMLElement) {
     this.currComp = this.module.store.currComp;
     this.compEl = this.currComp.$el;
-    this.pageEl = findPageContent(this.compEl) as HTMLElement;
+    this.pageEl = pageEl;
     this.observe();
   }
 
@@ -82,10 +82,15 @@ export class TransferCtrl extends ModuleControl<EditorModule> {
         }
       });
     });
-    this.currObserver.observe(this.compEl, { attributes: true });
+    this.currObserver.observe(this.compEl, {
+      attributes: true,
+      childList: true,
+      subtree: true,
+      characterDataOldValue: true,
+    });
   }
 
-  initStyle() {
+   initStyle() {
     const rect = this.compEl.getBoundingClientRect();
     const pageRect = this.pageEl.getBoundingClientRect();
     this.transferStyle.width = rect.width + "px";
@@ -104,12 +109,3 @@ export class TransferCtrl extends ModuleControl<EditorModule> {
     this.currObserver?.disconnect();
   }
 }
-
-function findPageContent(el?: HTMLElement): HTMLElement | undefined {
-  if (!el) return;
-  if (el.classList.contains("dndrop-container")) {
-    return el;
-  } else if (el.parentElement) {
-    return findPageContent(el.parentElement);
-  }
-}

+ 7 - 5
src/modules/editor/module/actions/edit.ts

@@ -1,17 +1,16 @@
 import { Exception, queenApi } from "queenjs";
 import { EditorModule } from "..";
-import { ICompKeys } from "../../typings";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
-import { CompUI } from "../../components/CompUI";
+import { ICompKeys } from "../../typings";
 
 export const editActions = EditorModule.action({
   // 添加组件到画布
-  addCompToDesign(compKey: ICompKeys, index?: number) {
+  async addCompToDesign(compKey: ICompKeys, index?: number) {
     let compId: string;
     if (index === undefined && this.store.currComp?.compKey === "Container") {
-      compId = this.store.insertCompContainer(compKey, this.store.currComp);
+      compId = await this.store.insertCompContainer(compKey, this.store.currComp);
     } else {
-      compId = this.store.insertDesignContent(compKey, index);
+      compId = await this.store.insertDesignContent(compKey, index);
     }
     this.actions.pickComp(compId);
   },
@@ -85,5 +84,8 @@ export const editActions = EditorModule.action({
   //
   setCompAlign(comp: DesignComp, align: string) {
     comp.layout.alignSelf = align;
+    if (comp.layout.transform?.x) {
+      comp.layout.transform.x = 0;
+    }
   },
 });

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

@@ -1,6 +1,7 @@
 import { Dict_Apis } from "@/dict";
 import { ModuleRoot } from "queenjs";
 import components from "../components";
+import { CompUICtrl } from "../controllers/CompUICtrl";
 import { HistoryCtrl } from "../controllers/HistoryCtrl";
 import { ImagePickController } from "../controllers/ImagePickerController";
 import { editActions } from "./actions/edit";
@@ -9,7 +10,6 @@ import { initActions } from "./actions/init";
 import { helpers } from "./helpers";
 import { https } from "./https";
 import { store } from "./stores";
-import { TransferCtrl } from "../controllers/TransferCtrl";
 
 export class EditorModule extends ModuleRoot {
   config = this.setConfig({
@@ -27,6 +27,7 @@ export class EditorModule extends ModuleRoot {
   controls = {
     historyCtrl: new HistoryCtrl(this),
     pickCtrl: new ImagePickController(),
+    compUICtrl: new CompUICtrl(this),
   };
 
   onReady() {

+ 5 - 8
src/modules/editor/module/stores/index.ts

@@ -1,7 +1,6 @@
 import { EditorModule } from "..";
 import {
-  addCacheToMap,
-  createCompId,
+  addCacheToMap
 } from "../../components/CompUI/defines/createCompId";
 import { DesignTemp } from "../../objects/DesignTemp";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
@@ -43,17 +42,15 @@ export const store = EditorModule.store({
     initDesignData(data: Partial<DesignTemp>) {
       this.store.designData = new DesignTemp(data);
     },
-    insertDesignContent(compKey: ICompKeys, index?: number) {
+    async insertDesignContent(compKey: ICompKeys, index?: number) {
       const { pageCompIds } = this.store;
       index === undefined && (index = pageCompIds.length);
-      const compId = createCompId(compKey);
-      addCacheToMap(this.store.designData.compMap, "root");
+      const compId = await this.controls.compUICtrl.createCompId(compKey, "root");
       pageCompIds.splice(index, 0, compId);
       return compId;
     },
-    insertCompContainer(compKey: ICompKeys, container: DesignComp) {
-      const compId = createCompId(compKey);
-      addCacheToMap(this.store.designData.compMap, container.id);
+    async insertCompContainer(compKey: ICompKeys, container: DesignComp) {
+      const compId = await this.controls.compUICtrl.createCompId(compKey, container.id);
       container.children.default || (container.children.default = []);
       container.children.default.push(compId);
       return compId;

+ 1 - 1
src/modules/editor/objects/Toolbars/CompToolbars.ts

@@ -7,7 +7,7 @@ export const CompToolbars: ICompToolbars = {
     toolbars.layerUp,
     toolbars.layerDown,
     toolbars.clearTransform,
-    toolbars.fullWidth,
+    // toolbars.fullWidth,
     toolbars.align,
     toolbars.delete,
   ],

+ 1 - 0
src/modules/editor/objects/Toolbars/TreeToolbars.ts

@@ -6,6 +6,7 @@ export const TreeToolbars: ICompToolbars = {
       return comp.isPostioned;
     }),
     toolbars.visible,
+    toolbars.delete,
   ],
   Page: [],
 };

+ 2 - 2
src/modules/resource/actions/promotion.ts

@@ -47,12 +47,12 @@ export const promotionAction = ResourceModule.action({
     const res = await this.https.createComp({ title });
     console.log(location.host, location.host == "www.infish.cn")
     if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshow/eidtComp.html#/?id=${res.result}`;
+      const url = `${location.origin}/projects/queenshow/editor.html#/?id=${res.result}&mode=editComp`;
       location.href = url;
       return;
     }
 
-    const url = `${location.origin}/eidtComp.html#/?id=${res.result}`;
+    const url = `${location.origin}/editor.html#/?id=${res.result}&mode=editComp`;
     location.href = url;
   },
 

+ 19 - 0
src/utils/index.ts

@@ -16,3 +16,22 @@ export function mapValuesDeep<T>(
   mapItem(obj);
   return arr;
 }
+
+export function eachValuesAndPathsDeep(
+  obj: any,
+  isItem: (v: any) => boolean,
+  itemHandle: (v: any, paths: string[]) => void,
+  paths: string[] = []
+) {
+  if (isItem(obj)) {
+    itemHandle(obj, paths);
+  } else if (obj instanceof Array) {
+    obj.forEach((item, i) =>
+    eachValuesAndPathsDeep(item, isItem, itemHandle, [...paths, i.toString()])
+    );
+  } else if (obj instanceof Object) {
+    Object.entries(obj).map(([key, item]) => {
+      eachValuesAndPathsDeep(item, isItem, itemHandle, [...paths, key]);
+    });
+  }
+}