lianghongjie 1 tahun lalu
induk
melakukan
0d5c4cb91d

+ 2 - 2
src/dict/apis.ts

@@ -14,8 +14,8 @@ const Dict_Apis = {
   queentreeLocal: base,
   auth: `${baseURL}${baseVersion}/usercenter`,
   queentree: `${baseURL}${treeVersion}/assetcenter`,
-  // promotion: `${baseURL}${baseVersion}/promotion`,
-  promotion: `${localURL}/promotion`,
+  promotion: `${baseURL}${baseVersion}/promotion`,
+  // promotion: `${localURL}/promotion`,
 };
 
 export { Dict_Apis };

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

@@ -0,0 +1,34 @@
+import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
+import FormUI, { ColumnItem } from "@queenjs/components/FormUI";
+import { set } from "lodash";
+import { defineComponent } from "vue";
+import { any } from "vue-types";
+
+const styleColumns: ColumnItem[] = [
+  {
+    label: "内边距",
+    dataIndex: "layout.padding",
+    component: "Input",
+  },
+];
+
+export const PageForm = defineComponent({
+  props: {
+    component: any<DesignComp>().isRequired,
+  },
+  setup(props) {
+    function changeVal(e: { dataIndex: string; value: any }) {
+      set(props.component, e.dataIndex, e.value);
+    }
+
+    return () => {
+      const { layout } = props.component;
+      return (
+        <>
+          <div>页面样式</div>
+          <FormUI data={layout} columns={styleColumns} onChange={changeVal} />
+        </>
+      );
+    };
+  },
+});

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

@@ -0,0 +1,51 @@
+import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
+import { computed, defineComponent } from "vue";
+import { string } from "vue-types";
+import { useCompData } from ".";
+import { CompUI } from "../..";
+import { useEditor } from "../../../..";
+
+export const Component = defineComponent({
+  props: {
+    compId: string().isRequired,
+  },
+  setup(props, { slots }) {
+    const editor = useEditor();
+    const { helper } = editor;
+    const { children, layout } = useCompData(props.compId);
+
+    const compsGroup = computed(() => {
+      const normalArr: DesignComp[] = [];
+      const posArr: DesignComp[] = [];
+      children.default.forEach((id) => {
+        const comp = helper.findComp(id);
+        if (!comp) return;
+        if (comp.compKey === "Container") {
+          posArr.push(comp);
+        } else {
+          normalArr.push(comp);
+        }
+      });
+      return {
+        normalArr,
+        posArr,
+      };
+    });
+
+    return () => (
+      <div style={helper.parseLayoutToStyle(layout)}>
+        <div class="relative z-10">
+          {compsGroup.value.posArr.map((d) => {
+            const Comp: any = CompUI[d.compKey]?.Component;
+            return Comp ? <Comp key={d.id} compId={d.id} /> : undefined;
+          })}
+        </div>
+        {slots.Container?.(
+          compsGroup.value.normalArr.map((comp) => {
+            return slots.CompItem?.(comp);
+          })
+        )}
+      </div>
+    );
+  },
+});

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

@@ -0,0 +1,19 @@
+import { Dict_Imgs } from "@/dict";
+import { createCompHooks } from "../../defines/createCompHooks";
+import { PageForm } from "./PageForm";
+
+export { Component } from "./component";
+
+export const options = {
+  name: "页面",
+  thumbnail: Dict_Imgs.Default,
+};
+
+export const { createComp, useCompData } = createCompHooks({
+  value: {},
+  children: {
+    default: () => [] as string[],
+  },
+});
+
+export const Form = PageForm;

+ 11 - 3
src/modules/editor/components/CompUI/defines/createAttrsForm.tsx

@@ -1,6 +1,6 @@
 import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
 import FormUI, { ColumnItem } from "@queenjs/components/FormUI";
-import { set } from "lodash";
+import { isEmpty, set } from "lodash";
 import { defineComponent } from "vue";
 import { any } from "vue-types";
 import { GroupNumber } from "../formItems/GroupNumber";
@@ -162,8 +162,16 @@ export function createAttrsForm(valueColumns: ColumnItem[]) {
               columns={layoutColumns}
               onChange={changeVal}
             />
-            <div>组件背景</div>
-            <FormUI data={component} columns={bgColumns} onChange={changeVal} />
+            {!isEmpty(component?.background) ? (
+              <>
+                <div>组件背景</div>
+                <FormUI
+                  data={component}
+                  columns={bgColumns}
+                  onChange={changeVal}
+                />
+              </>
+            ) : null}
           </div>
         );
       };

+ 1 - 0
src/modules/editor/components/CompUI/defines/createCompHooks.ts

@@ -34,6 +34,7 @@ export function createCompHooks<T, C extends { [name: string]: AnyFun }>(
     return comp as {
       value: T;
       children: { [name in keyof C]: ReturnType<C[name]> };
+      layout: Layout;
     };
   }
 

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

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

+ 1 - 1
src/modules/editor/components/Preview/index.tsx

@@ -7,7 +7,7 @@ export default defineUI({
     const { store } = useEditor();
     return () => (
       <div>
-        {store.designData.content.map((id) => {
+        {store.pageCompIds.map((id) => {
           const compKey = store.designData.compMap[id]?.compKey;
           const Comp: any = CompUI[compKey]?.Component;
           return Comp && <Comp key={id} compId={id} />;

+ 34 - 55
src/modules/editor/components/Viewport/Content/index.tsx

@@ -1,17 +1,16 @@
 import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
 import { css } from "@linaria/core";
 import { defineUI } from "queenjs";
-import { computed, onUnmounted } from "vue";
+import { onUnmounted } from "vue";
 import { Container, Draggable } from "vue-dndrop";
 import { useEditor } from "../../..";
 import { HotKeyCtrl } from "../../../controllers/HotKeyCtrl";
 import { CompUI } from "../../CompUI";
-import ErrorComp from "../../CompUI/placeHoder";
 
 export default defineUI({
   setup() {
     const editor = useEditor();
-    const { store, actions, helper } = editor;
+    const { actions, helper } = editor;
 
     const hotKeyCtrl = new HotKeyCtrl(editor);
     hotKeyCtrl.init();
@@ -19,61 +18,41 @@ export default defineUI({
       hotKeyCtrl.destroy();
     });
 
-    const compsGroup = computed(() => {
-      const normalArr: DesignComp[] = [];
-      const posArr: DesignComp[] = [];
-      store.designData.content.forEach((id) => {
-        const comp = helper.findComp(id);
-        if (!comp) return;
-        if (comp.compKey === "Container") {
-          posArr.push(comp);
-        } else {
-          normalArr.push(comp);
-        }
-      });
-      console.log(normalArr, posArr);
-      return {
-        normalArr,
-        posArr,
-      };
-    });
-
-    return () => (
-      <div class={contentStyle}>
-        <div class="relative z-10">
-          {compsGroup.value.posArr.map((d) => {
-            const Comp: any = CompUI[d.compKey]?.Component;
-            return Comp ? <Comp key={d.id} compId={d.id} /> : undefined;
-          })}
-        </div>
-        {store.isEditMode ? (
-          <Container
-            class="!min-h-750px"
-            group-name="canvas"
-            style={store.designData.pageStyle}
-            onDrop={(e: any) => {
-              if (e.payload) {
-                actions.addCompToDesign(e.payload, e.addedIndex);
-              } else {
-                actions.moveComp(e.removedIndex, e.addedIndex);
-              }
-            }}
-            non-drag-area-selector={".drag-disable"}
-          >
-            {compsGroup.value.normalArr.map((d) => {
-              const Comp: any = CompUI[d.compKey]?.Component || ErrorComp;
+    return () => {
+      const pageRoot = helper.findRootComp();
+      return pageRoot ? (
+        <CompUI.Page.Component class={contentStyle} compId={pageRoot.id}>
+          {{
+            Container(children: any) {
+              return (
+                <Container
+                  class="!min-h-750px"
+                  group-name="canvas"
+                  onDrop={(e: any) => {
+                    if (e.payload) {
+                      actions.addCompToDesign(e.payload, e.addedIndex);
+                    } else {
+                      actions.moveComp(e.removedIndex, e.addedIndex);
+                    }
+                  }}
+                  non-drag-area-selector={".drag-disable"}
+                >
+                  {children}
+                </Container>
+              );
+            },
+            CompItem(comp: DesignComp) {
+              const Comp = CompUI[comp.compKey].Component;
               return (
-                <Draggable key={d.id}>
-                  <Comp compId={d.id} />
+                <Draggable>
+                  <Comp compId={comp.id} />
                 </Draggable>
               );
-            })}
-          </Container>
-        ) : (
-          <editor.components.Preview />
-        )}
-      </div>
-    );
+            },
+          }}
+        </CompUI.Page.Component>
+      ) : null;
+    };
   },
 });
 

+ 39 - 0
src/modules/editor/components/Viewport/Slider/SliderRight/CompTree.tsx

@@ -0,0 +1,39 @@
+import { useEditor } from "@/modules/editor";
+import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
+import { useReactive } from "@queenjs/use";
+import { Tree } from "ant-design-vue";
+import { defineComponent } from "vue";
+import { CompUI } from "../../../CompUI";
+
+export const CompTree = defineComponent({
+  setup() {
+    const { store, actions, helper } = useEditor();
+    const state = useReactive(() => ({
+      treeData() {
+        const { pageCompIds } = store;
+        const rootComp = helper.findRootComp();
+        return [
+          {
+            key: rootComp?.id || "",
+            title: "页面",
+            children: pageCompIds.map((id) => {
+              const comp = helper.findComp(id) as DesignComp;
+              return {
+                key: comp.id,
+                title: CompUI[comp.compKey].options.name,
+                value: comp.id,
+              };
+            }),
+          },
+        ];
+      },
+    }));
+    return () => (
+      <Tree
+        treeData={state.treeData}
+        selectedKeys={[store.currCompId]}
+        onSelect={(ids) => actions.pickComp(ids[0] as string)}
+      ></Tree>
+    );
+  },
+});

+ 8 - 3
src/modules/editor/components/Viewport/Slider/SliderRight.tsx → src/modules/editor/components/Viewport/Slider/SliderRight/index.tsx

@@ -1,12 +1,13 @@
 import { useEditor } from "@/modules/editor";
 import { defineUI } from "queenjs";
 import { h } from "vue";
-import { CompUI } from "../../CompUI";
-import { createAttrsForm } from "../../CompUI/defines/createAttrsForm";
+import { CompUI } from "../../../CompUI";
+import { createAttrsForm } from "../../../CompUI/defines/createAttrsForm";
+import { CompTree } from "./CompTree";
 
 export default defineUI({
   setup() {
-    const editor = useEditor()
+    const editor = useEditor();
 
     return () => {
       const { currComp } = editor.store;
@@ -22,6 +23,10 @@ export default defineUI({
               { component: currComp }
             )}
           </div>
+          <div class="p-16px border-top border-bottom  !border-2px">组件树</div>
+          <div class="h-300px py-20px scrollbar">
+            <CompTree />
+          </div>
         </div>
       );
     };

+ 1 - 2
src/modules/editor/defines/DesignTemp/DesignComp.ts

@@ -3,13 +3,12 @@ import { Background, ICompKeys, Layout } from "../../typings";
 import { cloneDeep } from "lodash";
 
 export class DesignComp {
-  declare pid: string;
   id = nanoid();
   compKey: ICompKeys = "Text";
   value: any = undefined;
   layout: Layout = {};
   background: Background = {};
-  children: Record<string, any> = {};
+  children: Record<string, any> & { default?: string[] } = {};
 
   constructor(data?: Partial<DesignComp>) {
     if (!data) return;

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

@@ -7,7 +7,7 @@ export class DesignTemp {
   _id!: string;
   title = "";
   pageStyle?: any;
-  content: string[] = [];
+  // content: string[] = [];
   compMap: { [compId: string]: DesignComp } = {};
 
   constructor(data?: Partial<DesignTemp>) {

+ 12 - 0
src/modules/editor/defines/DesignTemp/versions/0.0.1.ts

@@ -6,6 +6,7 @@ import { DesignComp } from "../DesignComp";
 
 export function dataTransform(data: any) {
   data.compMap || (data.compMap = {});
+
   deepEachComp(data.content, (...args: any[]) => {
     const comp = args.pop();
     set(data.content, args.join("."), comp.id);
@@ -17,6 +18,17 @@ export function dataTransform(data: any) {
       addCacheToMap(data.compMap);
     }
   });
+
+  if (!data.compMap.root) {
+    data.compMap.root = CompUI.Page.createComp({
+      id: "root",
+      compKey: "Page",
+      layout: data.pageStyle,
+      children: {
+        default: data.content,
+      },
+    });
+  }
   return data;
 }
 

+ 5 - 1
src/modules/editor/helpers/index.ts

@@ -1,5 +1,6 @@
 import { EditorModule } from "..";
 import { DesignComp } from "../defines/DesignTemp/DesignComp";
+import { Layout } from "../typings";
 
 export const helpers = EditorModule.helper({
   designToNaturalSize(value: number) {
@@ -20,7 +21,7 @@ export const helpers = EditorModule.helper({
     );
     return parentComp;
   },
-  findRootComp() {
+  findRootComp(): DesignComp | undefined {
     return this.store.designData.compMap["root"];
   },
   getCompChildIds(comp: DesignComp) {
@@ -36,4 +37,7 @@ export const helpers = EditorModule.helper({
     }
     return getIds(comp.children);
   },
+  parseLayoutToStyle(layout: Layout): any {
+    return layout;
+  },
 });

+ 20 - 17
src/modules/editor/stores/index.ts

@@ -20,6 +20,9 @@ export const store = EditorModule.store({
     currComp(state) {
       return state.designData.compMap[state.currCompId];
     },
+    pageCompIds(state): string[] {
+      return state.designData.compMap.root?.children.default || [];
+    },
   },
   actions: {
     setCompData(id: string, data: any) {
@@ -32,10 +35,11 @@ export const store = EditorModule.store({
       this.store.designData = new DesignTemp(data);
     },
     insertDesignContent(compKey: ICompKeys, index?: number) {
-      index === undefined && (index = this.store.designData.content.length);
+      const { pageCompIds } = this.store;
+      index === undefined && (index = pageCompIds.length);
       const compId = createCompId(compKey);
       addCacheToMap(this.store.designData.compMap);
-      this.store.designData.content.splice(index, 0, compId);
+      pageCompIds.splice(index, 0, compId);
       return compId;
     },
     insertCompContainer(compKey: ICompKeys, container: DesignComp) {
@@ -49,20 +53,18 @@ export const store = EditorModule.store({
       this.store.currCompId = compId;
     },
     deleteComp(compId: string) {
-      const { content, compMap } = this.store.designData;
+      const { compMap } = this.store.designData;
       const parentComp = this.helper.findParentComp(compId);
       let deleteOK = false;
       if (parentComp) {
-        // 只能删除children中以compId作为key的组件
-        if (parentComp.children?.[compId]) {
-          delete parentComp.children[compId];
-          deleteOK = true;
-        }
-      } else {
-        const index = content.findIndex((id) => id === compId);
-        if (index >= 0) {
-          content.splice(index, 1);
-          deleteOK = true;
+        const ids = parentComp.children.default;
+        // 只能删除children.default中的组件
+        if (ids?.includes(compId)) {
+          const index = ids.findIndex((id) => id === compId);
+          if (index >= 0) {
+            ids.splice(index, 1);
+            deleteOK = true;
+          }
         }
       }
 
@@ -75,9 +77,9 @@ export const store = EditorModule.store({
       }
     },
     moveComp(selIndex: number, targetIndex: number) {
-      const { content } = this.store.designData;
-      const [selComp] = content.splice(selIndex, 1);
-      content.splice(targetIndex, 0, selComp);
+      const { pageCompIds } = this.store;
+      const [selComp] = pageCompIds.splice(selIndex, 1);
+      pageCompIds.splice(targetIndex, 0, selComp);
     },
     clearUnusedComps() {
       const used = new Set<string>();
@@ -90,7 +92,8 @@ export const store = EditorModule.store({
         });
         return used;
       };
-      getUsedIds(this.store.designData.content);
+      const rootId = (this.helper.findRootComp() as DesignComp).id;
+      getUsedIds([rootId]);
       Object.keys(this.store.designData.compMap).forEach((compId) => {
         if (!used.has(compId)) {
           delete this.store.designData.compMap[compId];