shenrongliang
2025-04-07 e7fbf453476e31d7d9cf15b64acb6052fca6d78d
Merge remote-tracking branch 'origin/master'
已修改3个文件
已添加1个文件
394 ■■■■ 文件已修改
easegen-front/src/views/chooseTemplate/index.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/digitalcourse/digitalhumans/DigitalHumansForm.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/digitalcourse/digitalhumans/LookDigitalHumansForm.vue 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/digitalcourse/digitalhumans/index.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/chooseTemplate/index.vue
@@ -175,7 +175,7 @@
          <div class="list">
            <div
              class="main-image-box"
              :style="{ width: viewSize.width + 'px', height: viewSize.height + 'px' }"
              :style="{ width: viewSize.width + 'px', height: viewSize.height + 'px',position: 'relative' }"
            >
              <!-- èƒŒæ™¯(必显示) -->
              <el-image
@@ -183,6 +183,7 @@
                class="background"
                :src="selectPPT.pictureUrl"
              />
              <!-- ç”»ä¸­ç”» -->
              <Vue3DraggableResizable
                v-if="selectPPT.innerPicture && selectPPT.innerPicture.src"
@@ -217,43 +218,48 @@
                  <Delete />
                </el-icon>
              </Vue3DraggableResizable>
              <Vue3DraggableResizable
                v-if="selectPPT.showDigitalHuman"
                :parent="false"
                :initW="PPTpositon.w"
                :initH="PPTpositon.h"
                @drag-move="onDragMove"
                v-model:x="PPTpositon.x"
                v-model:y="PPTpositon.y"
                v-model:w="PPTpositon.w"
                v-model:h="PPTpositon.h"
                v-model:active="PPTpositon.active"
                :draggable="true"
                :resizable="true"
                @activated="print('activated')"
                @deactivated="print('deactivated')"
                @drag-start="print('drag-start')"
                @resize-start="print('resize-start')"
                @dragging="print('dragging')"
                @resizing="print('resizing')"
                @drag-end="print('drag-end')"
                @resize-end="print('resize-end')"
                style="z-index: 2"
              >
                <el-image
                  class="minddle-host-image"
                  :src="selectHost ? selectHost.pictureUrl : ''"
                />
                <el-icon
                  v-if="PPTpositon.active"
                  size="20"
                  color="#409eff"
                  style="position: absolute; top: 5px; right: 5px; z-index: 4"
                  @click.stop="deleteDigitalHuman"
              <div style="width: 160%;height: 100%;position: absolute;top: 0;left: -30%">
                <Vue3DraggableResizable
                  v-if="selectPPT.showDigitalHuman"
                  :parent="true"
                  :initW="PPTpositon.w"
                  :initH="PPTpositon.h"
                  @drag-move="onDragMove"
                  v-model:x="PPTpositon.x"
                  v-model:y="PPTpositon.y"
                  v-model:w="PPTpositon.w"
                  v-model:h="PPTpositon.h"
                  v-model:active="PPTpositon.active"
                  :draggable="true"
                  :resizable="true"
                  @activated="print('activated')"
                  @deactivated="print('deactivated')"
                  @drag-start="print('drag-start')"
                  @resize-start="print('resize-start')"
                  @dragging="print('dragging')"
                  @resizing="print('resizing')"
                  @drag-end="print('drag-end')"
                  @resize-end="print('resize-end')"
                  style="z-index: 4"
                >
                  <Delete />
                </el-icon>
              </Vue3DraggableResizable>
                  <!--                {{PPTpositon.w}}{{PPTpositon.h}}-->
                  <el-image
                    class="minddle-host-image"
                    :src="selectHost ? selectHost.pictureUrl : ''"
                  />
                  <el-icon
                    v-if="PPTpositon.active"
                    size="20"
                    color="#409eff"
                    style="position: absolute; top: 5px; right: 5px; z-index: 4"
                    @click.stop="deleteDigitalHuman"
                  >
                    <Delete />
                  </el-icon>
                </Vue3DraggableResizable>
              </div>
            </div>
          </div>
          <el-card
@@ -1956,8 +1962,8 @@
  const template = selectTemplate.value
  const pptList = applyAllTemplate.value ? PPTArr.value : [selectPPT.value]
  //数字人是统一生效的,先处理
  // æ•°å­—人是统一生效的,先处理
  console.log(template)
  pptList.forEach((item) => {
    // ä¿å­˜åŽŸå§‹ppt图片
    const originalPPT = item.innerPicture?.src || item.pictureUrl
@@ -1979,7 +1985,8 @@
          entityType: 1,
          originHeight: courseInfo.value.height,
          originWidth: courseInfo.value.width,
          entityId: 1
          entityId: 1,
          templateId: template.id,
        }
      }
    } else {
@@ -1988,7 +1995,17 @@
    }
    item.showDigitalHuman = template.showDigitalHuman
    // æ·»åŠ åŒæ­¥å®½é«˜çš„é€»è¾‘
    const targetTemplate = selectTemplate.value
    console.log(PPTArr)
    PPTArr.value.forEach((otherItem) => {
      if (otherItem.templateId === item.templateId) {
        otherItem.width = item.width
        otherItem.height = item.height
      }
    })
  })
  // æ•°å­—人位置也需要缩放
  PPTpositon.w = selectTemplate.value.humanW
  PPTpositon.h = selectTemplate.value.humanH
@@ -2059,7 +2076,7 @@
}
.minddle-host-image {
  z-index: 3;
  z-index: 5;
  width: 100%;
  height: 100%;
}
easegen-front/src/views/digitalcourse/digitalhumans/DigitalHumansForm.vue
@@ -47,13 +47,6 @@
      <el-form-item v-if="formData.useModel == 2" :label="t('digitalhumans.video')" prop="videoUrl">
        <!-- åŽŸæœ¬è‡ªå¸¦çš„è§†é¢‘ä¸Šä¼  -->
        <UploadFile v-if="!(formData.videoUrl || formData.fixVideoUrl)" v-model="formData.videoUrl" :fileType="['mp4','mov']" :limit="1" @on-success="handleFileSuccess('videoUrl', $event)"/>
        <!-- åŽæœŸæ·»åŠ çš„åŽ»é™¤ç»¿å¹•çš„ -->
        <!-- <div v-if="!(formData.videoUrl || formData.fixVideoUrl)" >
          <CES2 @start="StartCes" @Thnd="End" msg="Welcome to Your Vue.js App"/>
          <div style="color: red;" v-show="isUploading"  >
              å½“前正在处理并上传中,请耐心等待...
          </div>
        </div> -->
        <!-- åŽŸè§†é¢‘æ’­æ”¾å™¨ -->
        <!-- <video-player v-if="formData.videoUrl || formData.fixVideoUrl" :property="videoProperty"/> -->
         <!-- æ–°çš„视频播放器 -->
@@ -105,7 +98,6 @@
import {VideoPlayerProperty} from "@/components/DiyEditor/components/mobile/VideoPlayer/config";
import { useUpload } from '@/components/UploadFile/src/useUpload'
import { el } from 'element-plus/es/locale';
import CES2 from './CES2.vue'
import { any } from 'vue-types';
const { t } = useI18n() // å›½é™…化
easegen-front/src/views/digitalcourse/digitalhumans/LookDigitalHumansForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,271 @@
<template>
    <Dialog :title="dialogTitle" v-model="dialogVisible">
      <el-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        label-width="120px"
        v-loading="formLoading"
      >
        <el-form-item :label="t('digitalhumans.name')" prop="name">
          <el-input v-model="formData.name" :placeholder="t('common.inputText') + t('digitalhumans.name')" />
        </el-form-item>
        <el-form-item :label="t('digitalhumans.code')" prop="code" v-if="false" > // å½“前数字人视频的编码类型
          <el-input v-model="formData.code" :placeholder="t('common.inputText') + t('digitalhumans.code')" />
        </el-form-item>
        <el-form-item :label="t('digitalhumans.gender')" prop="gender">
          <el-select v-model="formData.gender" :placeholder="t('common.selectText')+t('digitalhumans.gender')">
            <el-option
              v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('digitalhumans.useModel')" prop="useModel" v-if="false" > //数字人模式选择框
          <el-select v-model="formData.useModel" :placeholder="t('common.selectText')+t('digitalhumans.useModel')">
            <el-option
              v-for="dict in getIntDictOptions(DICT_TYPE.USE_MODEL)"
              :key="dict.value"
              :label="dict.label"
              :value="Number(dict.value)"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="背景样式" prop="isTransparent">
          <el-select v-model="formData.isTransparent" placeholder="请选择是否去除背景">
            <el-option value="1" label="透明背景"/>
            <el-option value="2" label="绿幕背景"/>
          </el-select>
        </el-form-item>
        <el-form-item v-if="formData.useModel == 1" :label="t('digitalhumans.picture')" prop="pictureUrl">
          <UploadImg v-if="formData" v-model="formData.fixPictureUrl" />
          <UploadImg v-else v-model="formData.pictureUrl" />
        </el-form-item>
        <!-- <el-form-item v-if="formData.useModel == 2" :label="t('digitalhumans.video')" prop="videoUrl"> -->
        <el-form-item v-if="false" :label="t('digitalhumans.video')" prop="videoUrl">
          <!-- åŽŸæœ¬è‡ªå¸¦çš„è§†é¢‘ä¸Šä¼  -->
          <UploadFile v-if="!(formData.videoUrl || formData.fixVideoUrl)" v-model="formData.videoUrl" :fileType="['mp4','mov']" :limit="1" @on-success="handleFileSuccess('videoUrl', $event)"/>
          <!-- åŽŸè§†é¢‘æ’­æ”¾å™¨ -->
          <!-- <video-player v-if="formData.videoUrl || formData.fixVideoUrl" :property="videoProperty"/> -->
           <!-- æ–°çš„视频播放器 -->
          <VideoPlayerMov  v-if="formData.videoUrl || formData.fixVideoUrl" :property="videoProperty"/>
        </el-form-item>
  <!--      <el-form-item :label="抠图标识" prop="matting">
          <el-select v-model="formData.matting" :placeholder="请选择抠图标识">
            <el-option
              v-for="dict in getIntDictOptions(DICT_TYPE.DIGITALCOURSE_DIGITALHUMAN_MATTING)"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>-->
        <el-form-item :label="t('digitalhumans.posture')" prop="posture">
          <el-select v-model="formData.posture" :placeholder="t('common.selectText') + t('digitalhumans.posture')">
            <el-option
              v-for="dict in getIntDictOptions(DICT_TYPE.DIGITALCOURSE_DIGITALHUMAN_POSTURE)"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('digitalhumans.type')" prop="type">
          <el-select v-model="formData.type" :placeholder="t('common.selectText') + t('digitalhumans.type')">
            <el-option
              v-for="dict in getIntDictOptions(DICT_TYPE.DIGITALCOURSE_DIGITALHUMAN_TYPE)"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="submitForm" type="primary" :disabled="formLoading" :loading="isUploading" >{{t('common.ok')}}</el-button>
        <el-button @click="dialogVisible = false">{{t('common.cancel')}}</el-button>
      </template>
    </Dialog>
  </template>
  <script setup lang="ts">
  import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
  import * as DigitalHumansApi from '@/api/digitalcourse/digitalhumans'
  import VideoPlayer from "@/components/DiyEditor/components/mobile/VideoPlayer/index.vue";
  import VideoPlayerMov from "@/components/DiyEditor/components/mobile/VideoPlayer_mov/index.vue";
  import {DiyComponent} from "@/components/DiyEditor/util";
  import {VideoPlayerProperty} from "@/components/DiyEditor/components/mobile/VideoPlayer/config";
  import { useUpload } from '@/components/UploadFile/src/useUpload'
  import { el } from 'element-plus/es/locale';
  import { any } from 'vue-types';
  const { t } = useI18n() // å›½é™…化
  const message = useMessage() // æ¶ˆæ¯å¼¹çª—
  const { uploadUrl, httpRequest } = useUpload() //上传方法
  const dialogVisible = ref(false) // å¼¹çª—的是否展示
  const dialogTitle = ref('') // å¼¹çª—的标题
  const formLoading = ref(false) // è¡¨å•的加载中:1)修改时的数据加载;2)提交的按钮禁用
  const formType = ref('') // è¡¨å•的类型:create - æ–°å¢žï¼›update - ä¿®æ”¹
  const formData = ref({
    id: undefined,
    expireStatus: undefined,
    finishTime: undefined,
    gender: undefined,
    matting: undefined,
    name: undefined,
    code: undefined,
    pictureUrl: undefined,
    posture: undefined,
    snapshotHeight: undefined,
    snapshotUrl: undefined,
    snapshotWidth: undefined,
    type: undefined,
    useGeneralModel: undefined,
    useModel: undefined,
    status: undefined,
    isTransparent: undefined,
  })
  // å½“前是否正在上传视频
  const isUploading = ref(false)
  const videoProperty = {
    videoUrl: '',
    posterUrl: '',
    autoplay: false,
    style: {
      bgType: 'color',
      bgColor: '#fff',
      marginBottom: 8,
      height: 300
    }
  } as DiyComponent<VideoPlayerProperty>
  watch(()=> formData.value.videoUrl,(newVal,oldValue)=>{
    if (newVal && newVal.length > 0){
      videoProperty.videoUrl = formData.value.fixVideoUrl || newVal
    }
  })
  const formRules = reactive({
    gender: [{ required: true, message: '性别不能为空', trigger: 'change' }],
    name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
    pictureUrl: [{ required: true, message: '图片URL不能为空', trigger: 'blur' }],
    posture: [{ required: true, message: '姿势不能为空', trigger: 'change' }],
    snapshotHeight: [{ required: true, message: '快照高度不能为空', trigger: 'blur' }],
    snapshotUrl: [{ required: true, message: '快照URL不能为空', trigger: 'blur' }],
    snapshotWidth: [{ required: true, message: '快照宽度不能为空', trigger: 'blur' }],
    type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
    useGeneralModel: [{ required: true, message: '使用通用模型不能为空', trigger: 'change' }],
    isTransparent: [{ required: true, message: '是否去除背景不能为空', trigger: 'change' }],
    status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
    videoUrl: [{ required: true, message: '视频不能为空', trigger: 'blur' }]
  })
  const formRef = ref() // è¡¨å• Ref
  const StartCes = () => {
    console.log( " ----- å¼€å§‹ ----- " )
    isUploading.value = true
  }
  const End = (res)=>{
    const FileObject = {
      file:res
    }
    httpRequest( FileObject ).then( response =>{
      console.log(response)
      formData.value.videoUrl = response.data;
    } ).finally( res => {
      isUploading.value = false
    } )
  }
  /** æ‰“开弹窗 */
  const open = async (type: string, id?: number) => {
    dialogVisible.value = true
    dialogTitle.value = t('action.' + type)
    formType.value = type
    resetForm()
    // ä¿®æ”¹æ—¶ï¼Œè®¾ç½®æ•°æ®
    if (id) {
      formLoading.value = true
      try {
        formData.value = await DigitalHumansApi.getDigitalHumans(id)
      } finally {
        formLoading.value = false
      }
    }else{
      InitHumMODEL()
    }
  }
  defineExpose({ open }) // æä¾› open æ–¹æ³•,用于打开弹窗
  /** æäº¤è¡¨å• */
  const emit = defineEmits(['success']) // å®šä¹‰ success äº‹ä»¶ï¼Œç”¨äºŽæ“ä½œæˆåŠŸåŽçš„å›žè°ƒ
  const submitForm = async () => {
    // æ ¡éªŒè¡¨å•
    await formRef.value.validate()
    // æäº¤è¯·æ±‚
    formLoading.value = true
    try {
      const data = formData.value as unknown as DigitalHumansApi.DigitalHumansVO
      if (formType.value === 'create') {
        await DigitalHumansApi.createDigitalHumans(data)
        message.success(t('common.createSuccess'))
      } else {
        await DigitalHumansApi.updateDigitalHumans(data)
        message.success(t('common.updateSuccess'))
      }
      dialogVisible.value = false
      // å‘送操作成功的事件
      emit('success')
    } finally {
      formLoading.value = false
    }
  }
  /** é‡ç½®è¡¨å• */
  const resetForm = () => {
    formData.value = {
      id: undefined,
      expireStatus: undefined,
      finishTime: undefined,
      gender: undefined,
      matting: undefined,
      name: undefined,
      code: undefined,
      pictureUrl: undefined,
      posture: undefined,
      snapshotHeight: undefined,
      snapshotUrl: undefined,
      snapshotWidth: undefined,
      type: undefined,
      useGeneralModel: undefined,
      useModel: undefined,
      status: undefined,
    }
    formRef.value?.resetFields()
  }
  const handleFileSuccess = (fileType,response) => {
    if (fileType === 'videoUrl') {
      formData.value.videoUrl = response.data;
    }
  };
  // ä¿®æ”¹é»˜è®¤çš„æ•°å­—人视频模式为视频
  const InitHumMODEL = ()=>{
    let ModelList = getIntDictOptions( DICT_TYPE.USE_MODEL )
    for (let index = 0; index < ModelList.length; index++) {
      const element = ModelList[index];
      if( element.label === "视频" ){
        formData.value.useModel = Number( element.value )
      }
    }
  }
  </script>
easegen-front/src/views/digitalcourse/digitalhumans/index.vue
@@ -173,7 +173,7 @@
          <el-button
            link
            type="primary"
            @click="openForm('detail', scope.row.id)"
            @click="OpenLookformRef('detail', scope.row.id)"
            v-hasPermi="['digitalcourse:digital-humans:delete']"
          >
            {{t('digitalhumans.view')}}
@@ -190,8 +190,10 @@
    />
  </ContentWrap>
  <!-- è¡¨å•弹窗:添加/修改 -->
  <!-- è¡¨å•弹窗:添加 -->
  <DigitalHumansForm ref="formRef" @success="getList" />
  <!-- è¡¨å•弹窗:修改 -->
  <LookDigitalHumansForm ref="LookformRef" @success="getList" />
  <!-- å¤„理 -->
  <AuditForm ref="auditFormRef" @success="getList" />
</template>
@@ -203,6 +205,7 @@
import download from '@/utils/download'
import * as DigitalHumansApi from '@/api/digitalcourse/digitalhumans'
import DigitalHumansForm from './DigitalHumansForm.vue'
import LookDigitalHumansForm from './LookDigitalHumansForm.vue'
import AuditForm from './AuditForm.vue'
import { useUserStoreWithOut } from '@/store/modules/user'
const userStore = useUserStoreWithOut() // ç”¨æˆ·ä¿¡æ¯ç¼“å­˜
@@ -260,13 +263,20 @@
  handleQuery()
}
/** æ·»åŠ /修改操作 */
/** æ·»åŠ æ“ä½œ */
const formRef = ref()
const auditFormRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}
/* ä¿®æ”¹æ“ä½œ */
const LookformRef = ref()
const OpenLookformRef = ( type: string, id?:number ) => {
  LookformRef.value.open( type, id )
}
const openAuditForm = (type: string, id?: number) => {
  auditFormRef.value.open(type, id)
}