Browse Source

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

liwei 1 year ago
parent
commit
b224f1a7e3

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

@@ -2,6 +2,7 @@ import { defineComponent } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
 import { useEditor } from "../../../..";
+import { useCompRef } from "../hooks";
 
 export const Component = defineComponent({
   props: {
@@ -11,10 +12,11 @@ export const Component = defineComponent({
     const editor = useEditor();
     const { helper } = editor;
     const { children, layout } = useCompData(props.compId);
+    const compRef = useCompRef(props.compId);
 
     return () => (
-      <div style={helper.createStyle(layout)}>
-        <div class="page-editing-content relative">
+      <div ref={compRef} style={helper.createStyle(layout)}>
+        <div class="relative">
           {slots.Container?.(
             children.default.map((compId) => {
               const comp = helper.findComp(compId);

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

@@ -7,15 +7,15 @@ import { IconMove, IconRotate } from "@/assets/icons";
 export const Transfer = defineComponent({
   setup() {
     const editor = useEditor();
-    const { store, controls } = editor;
+    const { store, controls, helper } = editor;
     const { transferCtrl } = controls;
     const { transferStyle } = transferCtrl;
 
     onMounted(() => {
       setTimeout(() => {
-        const pageEl = document.querySelector(".page-editing-content");
+        const pageEl = helper.findRootComp()?.$el;
         if (pageEl) {
-          transferCtrl.init(pageEl as HTMLElement);
+          transferCtrl.init(pageEl.firstChild as HTMLElement);
         }
       });
     });

+ 3 - 12
src/modules/editor/components/CompUI/basicUI/View.tsx

@@ -1,9 +1,10 @@
 import { css } from "@linaria/core";
-import { defineComponent, onMounted, ref } from "vue";
+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({
   props: {
@@ -11,18 +12,8 @@ export const View = defineComponent({
   },
   emits: ["dblclick"],
   setup(props, { slots, emit }) {
-    const compRef = ref();
     const { store, actions, helper, controls } = useEditor();
-
-    onMounted(() => {
-      const comp = helper.findComp(props.compId);
-      if (comp) {
-        Object.defineProperty(comp, "$el", {
-          value: compRef.value,
-          configurable: true,
-        });
-      }
-    });
+    const compRef = useCompRef(props.compId);
 
     return () => {
       const comp = helper.findComp(props.compId);

+ 17 - 0
src/modules/editor/components/CompUI/basicUI/hooks.ts

@@ -0,0 +1,17 @@
+import { useEditor } from "@/modules/editor";
+import { onMounted, ref } from "vue";
+
+export function useCompRef(compId: string) {
+  const compRef = ref();
+  const { helper } = useEditor();
+  onMounted(() => {
+    const comp = helper.findComp(compId);
+    if (comp) {
+      Object.defineProperty(comp, "$el", {
+        value: compRef.value,
+        configurable: true,
+      });
+    }
+  });
+  return compRef;
+}

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

@@ -29,7 +29,9 @@ export const CompTree = defineComponent({
             return {
               key: comp.id,
               title:
-                compUICtrl.state.components.get(comp.compKey)?.name || "未命名",
+                comp.title ||
+                compUICtrl.state.components.get(comp.compKey)?.name ||
+                "未命名",
               value: comp.id,
               children: getCompChildren(comp.getChildIds()),
             };
@@ -83,7 +85,9 @@ const CompNode = defineComponent({
       );
       const actions = TreeToolbars[comp.compKey] || TreeToolbars.default;
       const thumbnail =
-        comp.compKey === "Image" ? comp.value.url : compOpts?.thumbnail;
+        comp.compKey === "Image"
+          ? comp.value.url
+          : comp.thumbnail || compOpts?.thumbnail;
       return (
         <div class={nodeStyle}>
           <Image src={thumbnail} size={240} />

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

@@ -80,8 +80,9 @@ export class CompUICtrl extends ModuleControl<EditorModule> {
     Object.entries(result.compMap as Record<string, DesignComp>).forEach(
       ([key, comp]) => {
         if (key === "root") {
-          comp.compKey = compKey as any;
           idMap.set(key, nanoid());
+          comp.title = result.title;
+          comp.thumbnail = result.thumbnail;
         }
         const id = idMap.get(key) || nanoid();
         idMap.set(key, id);

+ 46 - 13
src/modules/editor/module/actions/edit.ts

@@ -1,4 +1,4 @@
-import { pick, set } from "lodash";
+import { cloneDeep, pick, set } from "lodash";
 import { Exception, queenApi } from "queenjs";
 import { EditorModule } from "..";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
@@ -49,28 +49,58 @@ export const editActions = EditorModule.action({
       this.store.deleteComp(compId);
     }
   },
-  // 保存容器为组件
-  saveAsComp(comp: DesignComp) {
-    // todo: 保存为组件
-    console.log("comp: ", comp);
-  },
+
   // 移动组件顺序
   moveComp(selIndex: number, targetIndex: number) {
     if (selIndex === targetIndex) return;
     this.store.moveComp(selIndex, targetIndex);
   },
 
-  // 保存项目
-  async saveDesign() {
-    // 清除无用组件
-    this.store.clearUnusedComps();
+  // 保存容器为组件
+  async saveAsComp(comp: DesignComp) {
+    try {
+      // 组件封面
+      const blob = await this.helper.screenshot({
+        element: comp.$el,
+      });
+      const thumbnail = URL.createObjectURL(blob);
+      const title = await queenApi.showInput({
+        title: "保存到我的组件",
+        defaultValue: this.controls.compUICtrl.state.components.get(
+          comp.compKey
+        )?.name,
+      });
+  
+      const data = {
+        title,
+        thumbnail,
+        compMap: cloneDeep(this.store.designData.compMap),
+      };
+      this.helper.clearUnusedComps(data.compMap, comp.id);
+      data.compMap.root = data.compMap[comp.id];
+      data.compMap.root.id = "root";
+      delete data.compMap[comp.id];
 
-    // 封面截屏
-    if (!this.store.designData.thumbnail) {
-      await this.actions.updateThumbnailByScreenshot();
+      queenApi.showLoading("保存中");
+      await this.controls.uploader.uploadBlobs(data);
+      await this.https.createComp(data);
+      queenApi.messageSuccess("保存成功");
+    } catch (error: any) {
+      throw Exception.error(error.toString());
+    } finally {
+      queenApi.hideLoading();
     }
+  },
 
+  // 保存项目
+  async saveDesign() {
     try {
+      // 清除无用组件
+      this.helper.clearUnusedComps(this.store.designData.compMap);
+      // 封面截屏
+      if (!this.store.designData.thumbnail) {
+        await this.actions.updateThumbnailByScreenshot();
+      }
       queenApi.showLoading("保存中");
       await this.controls.uploader.uploadBlobs(this.store.designData);
       await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"](
@@ -87,8 +117,11 @@ export const editActions = EditorModule.action({
   // 截屏保存封面
   async updateThumbnailByScreenshot(autoSave?: boolean) {
     try {
+      const rootComp = this.helper.findRootComp();
+      if (!rootComp) return;
       queenApi.showLoading("截屏中");
       const blob = await this.helper.screenshot({
+        element: rootComp.$el,
         ratio: this.store.isEditComp ? 0 : 1,
       });
       const thumbnail = URL.createObjectURL(blob);

+ 25 - 4
src/modules/editor/module/helpers/index.ts

@@ -62,9 +62,30 @@ export const helpers = EditorModule.helper({
     if (!this.helper.isCustomChildComp(comp)) return false;
     return true;
   },
-  async screenshot(options?: { ratio: number }): Promise<Blob> {
-    const dom = document.querySelector(".page-editing-content")
-      ?.parentElement as HTMLElement;
+
+  clearUnusedComps(compMap: Record<string, DesignComp>, rootId = "root") {
+    const used = new Set<string>();
+    const getUsedIds = (ids: string[]) => {
+      ids.forEach((id) => {
+        const comp = compMap[id];
+        if (!comp) return;
+        used.add(id);
+        getUsedIds(comp.getChildIds());
+      });
+      return used;
+    };
+    getUsedIds([rootId]);
+    Object.keys(compMap).forEach((compId) => {
+      if (!used.has(compId)) {
+        delete compMap[compId];
+      }
+    });
+  },
+  async screenshot(options: {
+    element: HTMLElement;
+    ratio?: number;
+  }): Promise<Blob> {
+    const dom = options.element;
 
     const transferEl = document.querySelector(".transfer") as
       | HTMLElement
@@ -73,7 +94,7 @@ export const helpers = EditorModule.helper({
       transferEl.style.display = "none";
     }
 
-    if (options?.ratio) {
+    if (options.ratio) {
       const result = await domtoimage.toJpeg(dom);
       const img = await new Promise<HTMLImageElement>((resolve) => {
         const image = new Image();

+ 3 - 0
src/modules/editor/module/https/index.ts

@@ -24,4 +24,7 @@ export const https = EditorModule.http({
       data,
     });
   },
+  createComp(data: any) {
+    return this.request("/frame/create", { method: "POST", data });
+  },
 });

+ 0 - 19
src/modules/editor/module/stores/index.ts

@@ -129,25 +129,6 @@ export const store = EditorModule.store({
       const [selComp] = pageCompIds.splice(selIndex, 1);
       pageCompIds.splice(targetIndex, 0, selComp);
     },
-    clearUnusedComps() {
-      const used = new Set<string>();
-      const getUsedIds = (ids: string[]) => {
-        ids.forEach((id) => {
-          const comp = this.helper.findComp(id);
-          if (!comp) return;
-          used.add(id);
-          getUsedIds(comp.getChildIds());
-        });
-        return used;
-      };
-      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];
-        }
-      });
-    },
     setTextEditingState(state: boolean) {
       this.store.textEditingState = state;
     },

+ 2 - 0
src/modules/editor/objects/DesignTemp/DesignComp.ts

@@ -7,6 +7,8 @@ export class DesignComp {
   declare pid: string; // pid 作为前端临时数据,不存储到服务器,在初始化时关联
   declare $el: HTMLElement; // $el 映射dom
   id = nanoid();
+  title = "";
+  thumbnail = "";
   compKey: ICompKeys = "Text";
   value: any = undefined;
   layout: Layout = {};