liwei 1 year ago
parent
commit
f3a6fdcf52

+ 3 - 3
src/dict/apis.ts

@@ -1,5 +1,5 @@
 const baseURL = "https://www.infish.cn";
-// const localURL = "http://192.168.110.180:8890";
+const localURL = "http://192.168.110.180:8890";
 
 const baseVersion = "/cloud/v1";
 const treeVersion = "/tree/v1";
@@ -18,8 +18,8 @@ const Dict_Apis = {
   queentreeLocal: base,
   auth: `${baseURL}${baseVersion}/usercenter`,
   queentree: `${baseURL}${treeVersion}/assetcenter`,
-  promotion: `${baseURL}${baseVersion}/promotionv1`,
-  // promotion: `${localURL}/promotion`,
+  // promotion: `${baseURL}${baseVersion}/promotionv1`,
+  promotion: `${localURL}/promotion`,
 };
 
 export { Dict_Apis };

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

@@ -0,0 +1,106 @@
+import { Container, Draggable } from "vue-dndrop";
+import { any, bool, string } from "vue-types";
+
+import { useEditor } from "@/modules/editor";
+import { ICompKeys } from "@/modules/editor/typings";
+import { Empty, Image } from "@queenjs/ui";
+import { useReactive } from "@queenjs/use";
+import { defineUI, queenApi } from "queenjs";
+import { useAuth } from "@queenjs-modules/auth";
+import { Dropdown, Tag } from "ant-design-vue";
+import dayjs from "dayjs";
+import Menu from "./Menu";
+import { useResource } from "@/modules/resource";
+import { onMounted} from "vue";
+
+export default defineUI({
+
+  setup(props) {
+    const editor = useEditor();
+    const auth = useAuth();
+    const resource = useResource();
+    const listCtrl = resource.controls.CustCompListCtrl;
+    listCtrl.hasLimit = true;
+    onMounted(() =>  listCtrl.loadPage(1));
+
+    return () => {
+      //@ts-ignore
+      const isSys = (auth.store.userInfo.roles || []).indexOf("system") > -1;
+      if (listCtrl.state.list.length == 0) return <Empty />;
+
+      return (
+        <Container
+          class="space-y-10px scrollbar"
+          behaviour="copy"
+          group-name="canvas"
+          animation-duration={0}
+          get-child-payload={(index: number) => {
+            return listCtrl.state.list[index]._id;
+          }}
+        >
+          {listCtrl.state.list.map((item:any) => {
+            const items = ["删除"];
+
+            if (isSys) {
+              item.published ? items.push("取消发布") : items.push("发布平台");
+            }
+
+            return (
+              <Draggable>
+                <div
+                  class="text-center leading-50px bg-dark-50 rounded draggable-item relative"
+                  key={item.compKey}
+                  title={item.name}
+                >
+                  <Image
+                    class="w-full rounded"
+                    src={item.thumbnail}
+                    onClick={() => {
+                        editor.actions.clickCompUserToDesign(item._id)
+                    }
+                    }
+                    size={240}
+                  />
+
+                  {isSys && (
+                    <Tag
+                      color={item.published ? "green" : "#E88B00"}
+                      // color="rgba(0, 0, 0, 0.4)"
+                      class="absolute top-0 left-0 z-1 !rounded-none"
+                    >
+                      {item.published ? "已发布" : "未发布"}
+                    </Tag>
+                  )}
+                    <div class="item_footer rounded-b-4px flex items-center justify-between p-4px">
+                      <div class="flex-1 w-0">
+                        {/* <div class="text-white text-bold truncate">{record.title}</div> */}
+                        <div class="flex items-center text-opacity-60 text-white text-12px">
+                          {dayjs(item.createTime).format("YYYY.MM.DD")}
+                        </div>
+                      </div>
+                      <Menu
+                        items={items}
+                        onMenu={async (name) => {
+                          console.log("name", name);
+                          if (name == "删除") {
+                            await resource.actions.deleteCustomComp(item)
+                            listCtrl.fresh();
+
+                            queenApi.messageSuccess("删除成功!")
+                            return;
+                          }
+                          const pub = (name == "发布平台");
+                          await resource.actions.publishFrame(item, pub)
+                          item.published = pub;
+                        }}
+                      />
+                    </div>
+                </div>
+              </Draggable>
+            );
+          })}
+        </Container>
+      );
+    };
+  },
+});

+ 36 - 16
src/modules/editor/components/Viewport/Slider/SliderLeft/CustomComps.tsx

@@ -1,15 +1,16 @@
 import { Container, Draggable } from "vue-dndrop";
-import { any, string } from "vue-types";
+import { any, bool, string } from "vue-types";
 
 import { useEditor } from "@/modules/editor";
 import { ICompKeys } from "@/modules/editor/typings";
 import { Empty, Image } from "@queenjs/ui";
 import { useReactive } from "@queenjs/use";
-import { defineUI } from "queenjs";
+import { defineUI, queenApi } from "queenjs";
 import { useAuth } from "@queenjs-modules/auth";
 import { Dropdown, Tag } from "ant-design-vue";
 import dayjs from "dayjs";
 import Menu from "./Menu";
+import { useResource } from "@/modules/resource";
 
 export default defineUI({
   props: {
@@ -28,7 +29,12 @@ export default defineUI({
     }));
 
     return () => {
-      return <Comp components={state.currComps} />;
+      return (
+        <Comp
+          components={state.currComps}
+          taggable={props.compType == "user"}
+        />
+      );
     };
   },
 });
@@ -44,10 +50,13 @@ const Comp = defineUI({
         createTime?: string;
       }[]
     >().isRequired,
+
+    taggable: bool().def(false),
   },
   setup(props) {
     const editor = useEditor();
     const auth = useAuth();
+    const resource = useResource();
 
     return () => {
       //@ts-ignore
@@ -87,7 +96,7 @@ const Comp = defineUI({
                     size={240}
                   />
 
-                  {isSys && (
+                  {isSys && props.taggable && (
                     <Tag
                       color={item.published ? "green" : "#E88B00"}
                       // color="rgba(0, 0, 0, 0.4)"
@@ -97,20 +106,31 @@ const Comp = defineUI({
                     </Tag>
                   )}
 
-                  <div class="item_footer rounded-b-4px flex items-center justify-between p-4px">
-                    <div class="flex-1 w-0">
-                      {/* <div class="text-white text-bold truncate">{record.title}</div> */}
-                      <div class="flex items-center text-opacity-60 text-white text-12px">
-                        {dayjs(item.createTime).format("YYYY.MM.DD")}
+                  {props.taggable && (
+                    <div class="item_footer rounded-b-4px flex items-center justify-between p-4px">
+                      <div class="flex-1 w-0">
+                        {/* <div class="text-white text-bold truncate">{record.title}</div> */}
+                        <div class="flex items-center text-opacity-60 text-white text-12px">
+                          {dayjs(item.createTime).format("YYYY.MM.DD")}
+                        </div>
                       </div>
+                      <Menu
+                        items={items}
+                        onMenu={async (name) => {
+                          console.log("name", name);
+                          if (name == "删除") {
+                            await resource.actions.deleteCustomComp(item)
+                            // editor.controls.compUICtrl.
+                            queenApi.messageSuccess("删除成功!")
+                            return;
+                          }
+                          const pub = (name == "发布平台");
+                          await resource.actions.publishFrame(item, pub)
+                          item.published = pub;
+                        }}
+                      />
                     </div>
-                    <Menu
-                      items={items}
-                      onMenu={(name) => {
-                        console.log("name", name);
-                      }}
-                    />
-                  </div>
+                  )}
                 </div>
               </Draggable>
             );

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

@@ -17,7 +17,7 @@ export default defineComponent({
                     {
                          props.items.map(item=>(
                             <Menu.Item key={item}>
-                                <div onClick={() =>{ 
+                                <div onClick={(e) =>{
                                     emit("menu", item)
                                 }}>{item}</div>
                           </Menu.Item>

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

@@ -25,6 +25,7 @@ import Shapes from "./Shapes";
 import { Sources } from "./Sources";
 import Templates from "./Templates";
 import Text from "./Text";
+import CompsUser from "./CompsUser";
 
 const tabs = [
   {
@@ -86,8 +87,7 @@ const tabs = [
       },
       {
         title: "组合",
-        component: CustomComps,
-        props: { compType: "user" },
+        component: CompsUser,
       },
     ],
   },

+ 7 - 39
src/modules/editor/controllers/CompUICtrl/index.ts

@@ -24,6 +24,7 @@ interface CompItem {
   Form: any;
   published?: boolean;
   createTime?: string;
+  _id?: string;
   createComp: (...args: any) => DesignComp;
 }
 
@@ -59,12 +60,13 @@ export class CompUICtrl extends ModuleControl<EditorModule> {
     listCtrl.setCrudPrefix("/frame");
     listCtrl.state.size = 999;
     listCtrl.state.query = {type: "comp"};
-    
+
     await listCtrl.loadPage(1);
 
     listCtrl.state.list.forEach((d:any) => {
       const compItem: CompItem = {
         compKey: d._id,
+        _id: d._id,
         compType: "user",
         name: d.title,
         createTime: d.createTime,
@@ -78,48 +80,14 @@ export class CompUICtrl extends ModuleControl<EditorModule> {
     });
   }
 
-  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") {
-          idMap.set(key, nanoid());
-          comp.title = result.title;
-          comp.thumbnail = result.thumbnail;
-        }
-        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);
-    return nextCompMap[idMap.get("root") as string];
-  }
 
-  async createCompId(compKey: ICompKeys) {
+  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);
-      compId = comp.id;
-    } else {
-      compId = createCompId(compKey);
-      addCacheToMap(this.store.designData.compMap);
-    }
+    compId = createCompId(compKey);
+    addCacheToMap(this.store.designData.compMap);
+
     return compId;
   }
 }

+ 62 - 0
src/modules/editor/module/actions/edit.tsx

@@ -109,6 +109,68 @@ export const editActions = EditorModule.action({
     this.controls.cropCtrl.close();
   },
 
+ // 通过点击添加组件到画布
+ async clickCompUserToDesign(id: string) {
+  if (!this.store.currStreamCardId) {
+      queenApi.messageError("请先选中一个卡片");
+      return;
+  }
+
+  const { result } = await this.https.getCompDetail(id);
+
+
+  let yOffset = 0;
+  if (
+    this.store.currCompId != this.store.currStreamCardId &&
+    this.store.currCompId != "root"
+  ) {
+    const bound = this.helper.getCardCompBound(this.store.currCompId);
+    yOffset = bound.y + bound.h;
+  }
+
+  let currCard = this.store.currStreamCard;
+
+  //先创建卡片
+  const currCardIndex =  this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1;
+  const cardId = await this.store.insertDesignContent(
+    "Container",
+    currCardIndex
+  );
+    currCard = this.helper.findComp(cardId) as DesignComp;
+  
+    const comp =  this.store.addUserCard(result);
+
+    const compId = comp.id;
+    const childIds = [...(currCard.children.default || [])];
+    childIds.push(compId);
+    currCard.children.default = childIds;
+
+    const addedComp = this.store.compMap[compId];
+    addedComp.layout.position = "absolute";
+
+    const currComp = this.helper.findComp(compId) as DesignComp;
+ 
+    //添加组件到当前选中的组件下面
+    let xOffset = this.helper.designSizeToPx(
+      375 - (currComp.layout.size?.[0] || 750) / 2
+    );
+    const obj = new CompObject(currComp);
+    //没有选中组件添加到当前卡片最后
+    const children = currCard.children.default || [];
+    if (yOffset == 0 && children.length >= 2) {
+      const prevCompIndex = children.indexOf(compId) - 1;
+      const bound = this.helper.getCardCompBound(children[prevCompIndex]);
+      yOffset = bound.y + bound.h;
+    }
+    obj.worldTransform.translate(xOffset, yOffset);
+    currComp.layout.transformMatrix = obj.worldTransform.getMatrixStr();
+
+    this.actions.pickComp(compId);
+    this.helper.extendStreamCard(currCard.id);
+    this.controls.cropCtrl.close();
+},
+
+
   // 通过拖拽添加组件到画布
   async dragCompToDesign(event: MouseEvent, compKey: ICompKeys) {
     await this.actions.addCompToDesign(compKey);

+ 37 - 1
src/modules/editor/module/stores/index.ts

@@ -1,7 +1,10 @@
+import { nanoid } from "nanoid";
 import { EditorModule } from "..";
 import { DesignTemp } from "../../objects/DesignTemp";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
 import { EditorMode, ICompKeys } from "../../typings";
+import { eachValuesAndPathsDeep } from "@/utils";
+import { set } from "lodash";
 
 export const store = EditorModule.store({
   state: () => ({
@@ -107,13 +110,46 @@ export const store = EditorModule.store({
       this.store.designData.compMap.root.children.default = childIds;
       return compId;
     },
+
     async insertCompContainer(compKey: ICompKeys, container: DesignComp) {
-      const compId = await this.controls.compUICtrl.createCompId(compKey);
+      const compId = this.controls.compUICtrl.createCompId(compKey);
       const childIds = [...(container.children.default || [])];
       childIds.push(compId);
       container.children.default = childIds;
       return compId;
     },
+
+    addUserCard(detail:any) {
+        const { compMap } = this.store.designData;
+        const idMap = new Map<string, string>();
+        const nextCompMap: Record<string, DesignComp> = {};
+        Object.entries(detail.compMap as Record<string, DesignComp>).forEach(
+          ([key, comp]) => {
+            if (key === "root") {
+              idMap.set(key, nanoid());
+              comp.title = detail.title;
+              comp.thumbnail = detail.thumbnail;
+            }
+            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);
+        return nextCompMap[idMap.get("root") as string];
+    },
+
+
     setCurrComp(compId: string) {
       this.store.currCompId = compId;
       const comps = this.helper.getCompTrees(compId);

+ 4 - 0
src/modules/resource/actions/material.ts

@@ -33,6 +33,10 @@ export const materialActions = ResourceModule.action({
   publishMaterial(record: any, publish:boolean ) {
     return this.https.publishResource({_id: record._id, published: publish});
   },
+  
+  publishFrame(record: any, publish:boolean ) {
+    return this.https.publishFrame({_id: record._id, published: publish});
+  },
 
   downloadMaterial(record) {
     window.open(record.file.url);

+ 9 - 0
src/modules/resource/actions/promotion.tsx

@@ -28,6 +28,15 @@ export const promotionAction = ResourceModule.action({
     // this.controls.promotionListCtrl.fresh();
   },
 
+  async deleteCustomComp(record: any) {
+    const res = await queenApi.showConfirm({
+      content: `删除后无法恢复,确定要删除当前组合?`,
+      type: "danger",
+    });
+    if (!res) return;
+    await this.https.deleteComp(record._id);
+  },
+
   async createPromotion() {
     const title = await queenApi.showInput({
       title: "请输入标题",

+ 3 - 1
src/modules/resource/http.ts

@@ -8,7 +8,9 @@ export const http = ResourceModule.http({
   publishResource(data:any) {
     return this.request(`sys/source/publish`, { method: "POST" , data});
   },
-
+  publishFrame(data:any) {
+    return this.request(`sys/frame/publish`, { method: "POST" , data});
+  },
 
   createResource(data: any) {
     return this.request("/source/create", { method: "POST", data });

+ 11 - 0
src/modules/resource/index.ts

@@ -40,10 +40,13 @@ export class ResourceModule extends ModuleRoot {
     // 用户资源
     matImageListCtrl: new PageListController(this.config?.httpConfig),
     matVideoListCtrl: new PageListController(this.config?.httpConfig),
+    CustCompListCtrl: new PageListController(this.config?.httpConfig),
+
     // 平台资源
     sysImageListCtrl: new PageListController(this.config?.httpConfig),
     sysVideoListCtrl: new PageListController(this.config?.httpConfig),
     sysSvgListCtrl: new PageListController(this.config?.httpConfig),
+    sysCompListCtrl: new PageListController(this.config?.httpConfig),
   };
   natsBus = new BusController();
   treeController = new TreeController(this.natsBus);
@@ -86,6 +89,14 @@ export class ResourceModule extends ModuleRoot {
     this.controls.sysSvgListCtrl.state.size = 20;
     this.controls.sysSvgListCtrl.state.query = { fileType: "image" , isSvg: true};
 
+
+    this.controls.CustCompListCtrl.setCrudPrefix("/frame");
+    this.controls.CustCompListCtrl.state.size = 20;
+
+    this.controls.sysCompListCtrl.setCrudPrefix("sys/frame");
+    this.controls.sysCompListCtrl.state.size = 20;
+    this.controls.sysSvgListCtrl.state.query = { published: true};
+
     this.natsBus.init();
   }
 }