qinyan il y a 1 an
Parent
commit
aeb94a9d7a

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

@@ -48,7 +48,7 @@ export const Form = createAttrsForm([
     },
   },
   {
-    label: "是否内嵌3D",
+    label: "内嵌3D",
     dataIndex: "value.inline",
     component: "Switch",
   },

+ 41 - 0
src/modules/editor/components/Viewport/Slider/SliderLeft/Sources/EditVideoModal.tsx

@@ -0,0 +1,41 @@
+import { useResource } from "@/modules/resource";
+import { Button } from "ant-design-vue";
+import { defineComponent, reactive } from "vue";
+import { object } from "vue-types";
+
+export default defineComponent({
+  props: {
+    record: object().isRequired,
+  },
+  setup(props) {
+    const resource = useResource();
+    const state = reactive({
+      //
+    });
+
+    const submit = () => {
+      resource.actions.editVideo({
+        start: 13,
+        end: 15,
+        id: props.record._id,
+      });
+    };
+
+    return () => {
+      const { record } = props;
+      //   console.log("record: ", record);
+      return (
+        <div>
+          <div>
+            <video src={record.file?.url} class="w-full" controls />
+          </div>
+          <div>
+            <Button type="primary" onClick={submit}>
+              提交
+            </Button>
+          </div>
+        </div>
+      );
+    };
+  },
+});

+ 13 - 10
src/modules/editor/components/Viewport/Slider/SliderLeft/Sources.tsx → src/modules/editor/components/Viewport/Slider/SliderLeft/Sources/List.tsx

@@ -23,7 +23,9 @@ export const Sources = defineComponent({
       // sysImageListCtrl sysVideoListCtrl custImageListCtrl custVideoListCtrl
       if (props.sourceFrom == "user")
         return resource.controls[
-          props.sourceType === "Image" ? "custImageListCtrl" : "custVideoListCtrl"
+          props.sourceType === "Image"
+            ? "custImageListCtrl"
+            : "custVideoListCtrl"
         ];
       return resource.controls[
         props.sourceType === "Image" ? "sysImageListCtrl" : "sysVideoListCtrl"
@@ -58,22 +60,23 @@ export const Sources = defineComponent({
       const { sourceType } = props;
 
       return (
-        <div class={[ props.sourceFrom == "user" && "flex flex-col !px-0"]}>
-          {
-            props.sourceFrom == "user" &&   <Button
-                class="mt-12px mb-12px"
+        <div>
+          {props.sourceFrom == "user" && (
+            <div class="sticky top-0 pb-12px z-11 bg-[#262626]">
+              <Button
+                class="mt-5px"
                 block
                 type="primary"
                 onClick={async () => {
-                  await resource.actions.createMaterial()
+                  await resource.actions.createMaterial();
                   control.fresh();
                 }}
               >
                 上传素材
               </Button>
-          }
-
-          <div class={[ props.sourceFrom == "user" && "flex-grow overflow-x-hidden overflow-y-auto scrollbar"]}>
+            </div>
+          )}
+          <div>
             <Container
               class="grid grid-cols-2 gap-10px"
               behaviour="copy"
@@ -87,7 +90,7 @@ export const Sources = defineComponent({
               }}
             >
               {dataSource.map((item: any) => (
-                <Draggable>
+                <Draggable key={item._id}>
                   <SourceItem
                     class="draggable-item cursor-pointer"
                     record={item}

+ 18 - 3
src/modules/editor/components/Viewport/Slider/SliderLeft/SourceItem.tsx → src/modules/editor/components/Viewport/Slider/SliderLeft/Sources/SourceItem.tsx

@@ -1,12 +1,13 @@
 import Thumbnail from "@/components/Thumbnail";
 import { css, cx } from "@linaria/core";
 import { useAuth } from "@queenjs-modules/auth";
-import { IconMore } from "@queenjs/icons";
+import { IconEdit, IconMore } from "@queenjs/icons";
 import { Dropdown, Menu, Tag } from "ant-design-vue";
 import dayjs from "dayjs";
-import { defineUI } from "queenjs";
+import { defineUI, queenApi } from "queenjs";
 import { defineComponent, reactive } from "vue";
 import { any, bool, object } from "vue-types";
+import EditVideoModal from "./EditVideoModal";
 
 const VideoItem = defineComponent({
   props: {
@@ -18,6 +19,13 @@ const VideoItem = defineComponent({
       play: false,
     });
 
+    function showModal(record: any) {
+      queenApi.dialog(<EditVideoModal record={record} />, {
+        title: "编辑视频",
+        width: "800px",
+      });
+    }
+
     return () => {
       const { record } = props;
       const { play } = state;
@@ -25,11 +33,18 @@ const VideoItem = defineComponent({
       return (
         <div
           style={{ aspectRatio: 1.5 }}
-          class="overflow-hidden"
+          class="relative overflow-hidden"
           onMouseenter={() => (state.play = true)}
           onMouseleave={() => (state.play = false)}
           onClick={() => emit("click", record.file.url)}
         >
+          <IconEdit
+            class="absolute right-5px top-5px z-2 p-4px rounded-4px text-14px text-light-50 bg-dark-600 bg-opacity-60 transition hover:(bg-opacity-70)"
+            onClick={(e: any) => {
+              e.stopPropagation();
+              showModal(record);
+            }}
+          />
           {!play ? (
             <Thumbnail
               class="w-1/1 h-1/1"

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

@@ -24,7 +24,7 @@ import Comp3d from "./Comp3d";
 import CompsUser from "./CompsUser";
 import CustomComps from "./CustomComps";
 import Shapes from "./Shapes";
-import { Sources } from "./Sources";
+import { Sources } from "./Sources/List";
 import Templates from "./Templates";
 import Text from "./Text";
 

+ 40 - 5
src/modules/resource/actions/material.ts

@@ -1,4 +1,6 @@
+import { TimeController } from "@/controllers/TimeController";
 import { queenApi } from "queenjs";
+import Modal from "queenjs/adapter/vue/components/modal";
 import { ResourceModule } from "..";
 
 export const materialActions = ResourceModule.action({
@@ -30,12 +32,12 @@ export const materialActions = ResourceModule.action({
     // this.controls.materialListCtrl.fresh();
   },
 
-  publishMaterial(record: any, publish:boolean ) {
-    return this.https.publishResource({_id: record._id, published: publish});
+  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});
+
+  publishFrame(record: any, publish: boolean) {
+    return this.https.publishFrame({ _id: record._id, published: publish });
   },
 
   downloadMaterial(record) {
@@ -55,4 +57,37 @@ export const materialActions = ResourceModule.action({
     const url = `${location.origin}/index.html?host=${host}#/create/${record._id}`;
     location.href = url;
   },
+  async editVideo(data) {
+    queenApi.showLoading("正在处理……");
+    const res = await this.https.cutVideo(data);
+    const { url, jobId } = res.result;
+
+    const videoStatusCtrl = new TimeController({
+      delayTime: 1000,
+      durationTime: 3000,
+    });
+    videoStatusCtrl
+      .setLoop(async () => {
+        const { result } = await this.https.queryVideoStatus(jobId);
+        if (result === "SUCCEED") {
+          videoStatusCtrl.stop();
+          const souceObj: createSourceType = {
+            file: { url },
+            fileType: "video",
+            from: "cut",
+          };
+          await this.https.createResource(souceObj);
+          setTimeout(async () => {
+            await this.controls.custVideoListCtrl.loadPage(1);
+            Modal.clear();
+            queenApi.hideLoading();
+          }, 500);
+        } else if (result === "FAILED") {
+          videoStatusCtrl.stop();
+          queenApi.hideLoading();
+          queenApi.messageError("失败,重新提交!");
+        }
+      })
+      .start();
+  },
 });

+ 17 - 8
src/modules/resource/http.ts

@@ -5,19 +5,25 @@ export const http = ResourceModule.http({
   deleteResource(id: string) {
     return this.request(`/source/delete/${id}`, { method: "POST" });
   },
-  publishResource(data:any) {
-    return this.request(`sys/source/publish`, { method: "POST" , data});
+  publishResource(data: any) {
+    return this.request(`sys/source/publish`, { method: "POST", data });
   },
-  publishFrame(data:any) {
-    return this.request(`sys/frame/publish`, { method: "POST" , data});
+  publishFrame(data: any) {
+    return this.request(`sys/frame/publish`, { method: "POST", data });
   },
 
-  createResource(data: any) {
+  createResource(data: createSourceType) {
     return this.request("/source/create", { method: "POST", data });
   },
   updateResouce(data: any) {
     return this.request("/source/update", { method: "POST", data });
   },
+  cutVideo(data: { id: string; start: string; end: string }) {
+    return this.request("/video/cut", { method: "POST", data });
+  },
+  queryVideoStatus(id: string) {
+    return this.request(`/video/cut/${id}`, { method: "GET" });
+  },
 
   //   templates
   queryTplsDetail(id: string) {
@@ -41,10 +47,13 @@ export const http = ResourceModule.http({
     return this.request(`/h5/delete/${id}`, { method: "POST" });
   },
 
-  publishPromotion(id: string, publish: boolean) { 
-    return this.request("/sys/h5/publish", { method: "POST",  data:{_id: id, published: publish}});
+  publishPromotion(id: string, publish: boolean) {
+    return this.request("/sys/h5/publish", {
+      method: "POST",
+      data: { _id: id, published: publish },
+    });
   },
-  
+
   //   comp
   createComp(data: any) {
     return this.request("/frame/create", { method: "POST", data });

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

@@ -31,3 +31,10 @@ declare type compType = {
   updateTime?: string;
   _id: string;
 };
+
+declare type createSourceType = {
+  file: { url: any; size?: number };
+  fileType: "image" | "video" | "svg";
+  from: string;
+  isSvg?: boolean;
+};