Ver Fonte

feat: 添加素材

dx há 3 meses atrás
pai
commit
1801c3c719

+ 9 - 0
src/api/interactVideo/videoManage.js

@@ -45,3 +45,12 @@ export function interactionVideoDel(interactionIds) {
     method: "delete",
   });
 }
+
+// 修改视频互动基本信息与素材关联
+export function updateMaterialInfo(data) {
+  return request({
+    url: `/interactionVideo/update/materialInfo`,
+    method: "post",
+    data,
+  });
+}

+ 332 - 0
src/views/interactVideo/videoManage/addSouce.vue

@@ -0,0 +1,332 @@
+<template>
+  <div>
+    <el-dialog
+      title="添加素材"
+      v-model="materialOpen"
+      width="1200"
+      append-to-body
+      destroy-on-close
+    >
+      <el-form :model="form" ref="dataForm" label-width="110px" inline>
+        <el-row :gutter="10">
+          <el-col :span="6">
+            <el-form-item label="素材" prop="selectMaterial">
+              <el-radio-group v-model="form.selectMaterial">
+                <el-radio :label="1">选择已有素材</el-radio>
+                <el-radio :label="2" @click="uploadSource">上传素材</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" v-show="form.selectMaterial == 1">
+            <el-form-item label="">
+              <!-- 列表 -->
+              <el-table
+                border
+                row-key="materialId"
+                v-loading="loading"
+                :data="libraryList"
+                @selection-change="handleSelectionChange"
+              >
+                <el-table-column
+                  type="selection"
+                  width="100"
+                  align="center"
+                  :reserve-selection="true"
+                />
+                <el-table-column
+                  type="index"
+                  label="序号"
+                  width="100"
+                  align="center"
+                />
+                <el-table-column
+                  prop="materialName"
+                  label="素材名称"
+                  align="center"
+                />
+                <!-- 素材类型,0-视频、1-图片 -->
+                <el-table-column
+                  prop="materialType"
+                  label="素材类型"
+                  align="center"
+                >
+                  <template #default="{ row }">
+                    {{ libraryType[row.materialType] }}
+                  </template>
+                </el-table-column>
+                <!-- 0=未发布,1=发布 -->
+                <el-table-column prop="status" label="状态" align="center">
+                  <template #default="{ row }">
+                    {{ libraryStatus[row.status] }}
+                  </template>
+                </el-table-column>
+              </el-table>
+              <pagination
+                v-show="total > 0"
+                :total="total"
+                v-model:page="queryParams.pageNum"
+                v-model:limit="queryParams.pageSize"
+                @pagination="getList"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button
+            type="primary"
+            :loading="confirmLoading"
+            @click="dialogSubmit"
+            >确 定</el-button
+          >
+          <el-button :loading="confirmLoading" @click="dialogCancel"
+            >取 消</el-button
+          >
+        </div>
+      </template>
+    </el-dialog>
+
+    <el-dialog title="新增素材" v-model="addSourceOpen" width="800">
+      <el-form
+        :model="materialForm"
+        ref="materialFormRef"
+        :rules="materialRules"
+        label-width="100"
+      >
+        <el-form-item label="素材名称" prop="materialName">
+          <el-input
+            v-model="materialForm.materialName"
+            placeholder="请输入素材名称"
+          />
+        </el-form-item>
+        <el-form-item label="素材类型" prop="materialType">
+          <el-select
+            v-model="materialForm.materialType"
+            placeholder="请选择素材类型"
+          >
+            <el-option :value="0" label="视频" />
+            <el-option :value="1" label="图片" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="素材文件">
+          <el-upload
+            ref="uploadRef"
+            action=""
+            :file-list="materialForm.fileList"
+            :on-change="uploadChange"
+            :on-remove="uploadRemove"
+            :auto-upload="false"
+            :limit="1"
+          >
+            <template #trigger>
+              <el-button type="primary">选择文件</el-button>
+            </template>
+            <template #tip>
+              <div class="el-upload__tip">仅支持上传图片或视频文件</div>
+            </template>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button
+            type="primary"
+            :loading="materialConfirmLoading"
+            @click="sourceAdd"
+            >确 定</el-button
+          >
+          <el-button :loading="materialConfirmLoading" @click="sourceAddCancel"
+            >取 消</el-button
+          >
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="FormFields">
+import {
+  getLibraryList,
+  libraryAdd,
+} from "@/api/interactVideo/sourceMaterialManage";
+import { updateMaterialInfo } from "@/api/interactVideo/videoManage";
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  open: {
+    type: Boolean,
+    default: false,
+  },
+  baseInfo: {
+    type: Object,
+    default: {
+      interactionId: undefined,
+      interactionName: undefined,
+      materialIds: [],
+      remark: undefined,
+    },
+  },
+});
+const emits = defineEmits(["close"]);
+const materialOpen = ref(false);
+const confirmLoading = ref(false);
+const loading = ref(false);
+const libraryList = ref([]);
+const total = ref(0);
+const materialConfirmLoading = ref(false);
+const addSourceOpen = ref(false);
+const ids = ref([]);
+const uploadId = ref([]);
+const data = reactive({
+  form: {
+    nodeType: "root-node",
+    selectMaterial: 1,
+  },
+  materialForm: {
+    materialName: undefined,
+    materialType: undefined,
+    fileList: [],
+  },
+  materialRules: {
+    materialName: [
+      { required: true, message: "素材名称不能为空", trigger: "blur" },
+    ],
+    materialType: [
+      { required: true, message: "素材类型不能为空", trigger: "change" },
+    ],
+  },
+  libraryType: {
+    0: "视频",
+    1: "图片",
+  },
+  libraryStatus: {
+    0: "未发布",
+    1: "已发布",
+  },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+
+const {
+  form,
+  libraryType,
+  libraryStatus,
+  queryParams,
+  materialRules,
+  materialForm,
+} = toRefs(data);
+
+watchEffect(() => {
+  if (props.open) {
+    materialOpen.value = true;
+    form.value = {
+      selectMaterial: 1,
+    };
+    getList();
+  } else {
+    materialOpen.value = false;
+  }
+});
+
+// 互动视频新增并关联素材
+function dialogSubmit() {
+  proxy.$refs["dataForm"].validate((valid) => {
+    if (valid) {
+      // 判断选中素材id和上传素材id是否为空
+      if (ids.value.length == 0 && uploadId.value.length == 0) {
+        proxy.$modal.msgError("请选择素材");
+        return;
+      }
+      confirmLoading.value = true;
+      const params = {
+        materialIds: ids.value,
+        ...props.baseInfo,
+      };
+      updateMaterialInfo(params)
+        .then((res) => {
+          // 新增成功后拿到id跳转互动视频节点编辑
+          if (res.code == 200) {
+            proxy.$modal.msgSuccess("添加成功");
+            dialogCancel();
+          }
+        })
+        .finally(() => {
+          confirmLoading.value = false;
+        });
+      confirmLoading.value = true;
+    }
+  });
+}
+function dialogCancel() {
+  emits("close", false);
+  confirmLoading.value = false;
+}
+
+/** 查询素材列表 */
+function getList() {
+  loading.value = true;
+  getLibraryList(queryParams.value).then((response) => {
+    libraryList.value = response.rows;
+    total.value = response.total;
+    loading.value = false;
+  });
+}
+// 选中素材id
+function handleSelectionChange(selection) {
+  ids.value = selection.map((item) => item.materialId);
+}
+
+// 素材新增
+function uploadSource() {
+  addSourceOpen.value = true;
+  materialForm.value = {
+    materialName: undefined,
+    materialType: 0,
+    fileList: [],
+  };
+}
+function sourceAdd() {
+  const formData = new FormData();
+  proxy.$refs["materialFormRef"].validate((valid) => {
+    if (valid) {
+      materialConfirmLoading.value = true;
+      const { materialName, materialType, fileList } = materialForm.value;
+      formData.append("materialName", materialName);
+      formData.append("materialType", materialType);
+      fileList.forEach((file) => {
+        formData.append("file", file.raw);
+      });
+      libraryAdd(formData)
+        .then((res) => {
+          if (res.code == 200) {
+            proxy.$modal.msgSuccess("新增成功");
+            uploadId.value.push(res.data);
+            addSourceOpen.value = false;
+          }
+        })
+        .finally(() => {
+          materialConfirmLoading.value = false;
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    }
+  });
+}
+// 取消素材新增
+function sourceAddCancel() {
+  materialConfirmLoading.value = false;
+  addSourceOpen.value = false;
+}
+
+// 文件上传回调
+function uploadChange(file) {
+  materialForm.value.fileList.push(file);
+}
+
+function uploadRemove() {
+  materialForm.value.fileList = [];
+}
+</script>

+ 17 - 7
src/views/interactVideo/videoManage/formFields.vue

@@ -6,6 +6,7 @@
       v-model="materialOpen"
       width="1200"
       append-to-body
+      destroy-on-close
     >
       <el-form
         :model="form"
@@ -245,14 +246,23 @@ const {
   materialForm,
 } = toRefs(data);
 
-watchEffect(() => {
-  if (props.open) {
-    materialOpen.value = true;
-    getList();
-  } else {
-    materialOpen.value = false;
+watch(
+  () => props.open,
+  (val) => {
+    if (val) {
+      materialOpen.value = true;
+      form.value = {
+        interactionName: "",
+        nodeType: "root-node",
+        selectMaterial: 1,
+        remark: "",
+      };
+      getList();
+    } else {
+      materialOpen.value = false;
+    }
   }
-});
+);
 
 // 互动视频新增并关联素材
 function dialogSubmit() {

+ 37 - 9
src/views/interactVideo/videoManage/videoOperation.vue

@@ -3,9 +3,11 @@
   <div class="app-container">
     <div style="display: flex">
       <el-button type="primary" @click="formSubmit">保存</el-button>
+      <el-button type="primary" @click="addSource">添加素材</el-button>
       <el-button type="info" @click="videoView">视频预览</el-button>
-      <el-button @click="returnList">取消</el-button>
+      <el-button @click="returnList">返回</el-button>
     </div>
+    <!-- 节点模块编辑 -->
     <div class="border_box">
       <InteractiveVideoEditor
         ref="editorRef"
@@ -14,7 +16,13 @@
         :imageSources="imageSources"
       />
     </div>
-    <el-dialog title="视频预览" v-model="videoViewOpen" width="1200">
+    <!-- 视频预览 -->
+    <el-dialog
+      title="视频预览"
+      v-model="videoViewOpen"
+      width="1200"
+      destroy-on-close
+    >
       <XGVideoViewer
         :question="videoDetail.data.question"
         :options="videoDetail.data.optionsList"
@@ -25,6 +33,13 @@
         @onClickOption="onClickOption"
       />
     </el-dialog>
+
+    <!-- 添加素材 -->
+    <AddSouce
+      :open="materialOpen"
+      :baseInfo="interactionVideoInfo"
+      @close="formFieldsClose"
+    />
   </div>
 </template>
 
@@ -41,6 +56,7 @@ import {
 } from "@/hooks/transformGraphdata";
 import InteractiveVideoEditor from "@/components/InteractiveVideoEditor";
 import XGVideoViewer from "@/components/XGVideoViewer";
+import AddSouce from "./addSouce.vue";
 import { watchEffect } from "vue";
 
 const { proxy } = getCurrentInstance();
@@ -68,10 +84,8 @@ const graphData = ref({
     optionsList: [],
   },
 });
-/**
- * 视频ID变化,则获取相关素材以及节点数据
- */
-watchEffect(() => {
+// 获取视频基本节点信息、素材信息
+function getInitData() {
   // 获取互动视频基本信息以及节点
   getInteractionVideoDetail(interactionId).then((res) => {
     if (res.code == 200) {
@@ -101,7 +115,13 @@ watchEffect(() => {
         };
       });
   });
-});
+}
+/**
+ * 视频ID变化,则获取相关素材以及节点数据
+ */
+watchEffect(() => {
+  getInitData();
+}, [interactionId]);
 
 // 关闭当前页签
 function returnList() {
@@ -117,7 +137,6 @@ function formSubmit() {
   }).then((res) => {
     if (res.code == 200) {
       proxy.$modal.msgSuccess(res.msg);
-      returnList();
     }
   });
 }
@@ -128,7 +147,7 @@ const videoDetail = ref({});
 
 function videoView() {
   videoDetail.value = graphData.value;
-  if (!videoDetail.value.data.url) {
+  if (!videoDetail.value.data.url || !videoDetail.value.data.uri) {
     proxy.$modal.msgError("暂无可播放视频,可添加视频素材后预览");
     return;
   }
@@ -140,6 +159,15 @@ const onClickOption = (option) => {
     (i) => i.id == option.nodeId
   )[0];
 };
+
+const materialOpen = ref(false);
+function addSource() {
+  materialOpen.value = true;
+}
+function formFieldsClose() {
+  materialOpen.value = false;
+  getInitData();
+}
 </script>
 
 <style>