Flex
2025-05-30 dd325aa187729f0b9e105a23e9d7454c76f823fc
Merge branch 'master' of http://yykjgit.sdyyst.com/r/easegen
已修改8个文件
223 ■■■■ 文件已修改
easegen-front/src/views/chooseTemplate/index.vue 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/dialogue/index.vue 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/digitalcourse/digitalhumans/LookDigitalHumansForm.vue 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/digitalcourse/digitalhumans/index.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/digitalcourse/template/TemplateForm.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/controller/admin/digitalhumans/vo/DigitalHumansRespVO.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceUtil.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/digitalhumans/DigitalHumansServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
easegen-front/src/views/chooseTemplate/index.vue
@@ -474,6 +474,7 @@
              }"
            />
          </div>
          <el-empty v-if="hostList.length==0" description="暂无数据" />
          <Pagination
            small="true"
            :total="total"
@@ -491,6 +492,10 @@
            class="template-item"
            v-for="(template, index) in templates"
            :key="index"
            :style="{
                width: '90%',
                maxWidth: '90%',
              }"
            @click="handleTemplateSelection(template)"
          >
            <div class="list-index" :style="template.isActive ? 'background: #409eff' : ''">
@@ -498,10 +503,11 @@
            </div>
            <el-image class="background" :src="template.previewImage" fit="contain" />
          </div>
          <el-empty v-if="templates.length==0" description="暂无数据" />
        </div>
        <div class="apply-all">
          <el-checkbox v-model="applyAllTemplate" :label="t('courseCenter.uploadAudio')" />
        </div>
<!--        <div class="apply-all">-->
<!--          <el-checkbox v-model="applyAllTemplate" :label="t('courseCenter.uploadAudio')" />-->
<!--        </div>-->
      </div>
      <!-- 背景设置 -->
      <div class="template-box template-right" v-if="showHeadImageTool">
@@ -780,18 +786,18 @@
    activeUrl: userActive,
    isActive: false
  },
  {
    name: t('courseCenter.background'),
    url: bg,
    activeUrl: bgActive,
    isActive: false
  },
  {
    name: t('courseCenter.pictureInPicture'),
    url: innerPicture,
    activeUrl: innerPictureActive,
    isActive: false
  }
  // {
  //   name: t('courseCenter.background'),
  //   url: bg,
  //   activeUrl: bgActive,
  //   isActive: false
  // },
  // {
  //   name: t('courseCenter.pictureInPicture'),
  //   url: innerPicture,
  //   activeUrl: innerPictureActive,
  //   isActive: false
  // }
])
const showHeadImageTool = ref(false)
@@ -1198,16 +1204,6 @@
    queryParams.posture = tabs3ActiveNum.value
    queryParams.status = 0
    let data = await pptTemplateApi.pageList(queryParams)
    if (data.list.length == 0) {
      queryParams.type = tabs1ActiveNum.value == '0' ? '1' : '0'
      tabs1ActiveNum.value = queryParams.type
      data = await pptTemplateApi.pageList(queryParams)
      if (data.list.length == 0) {
        message.error('没有有效的数字人,请联系管理员')
        return
      }
    }
    data.list.forEach((item) => {
      item.isActive = false
    })
@@ -2328,7 +2324,7 @@
    z-index: 1;
    width: 100%;
    height: 100%;
    background-color: #f0f1fa;
    //background-color: #f0f1fa;
  }
  .template-tool {
easegen-front/src/views/dialogue/index.vue
@@ -1,43 +1,69 @@
<template>
<div>
  <div class="remote-container"></div>
</div>
  <div>
    <div class="remote-container" classNamev>
    </div>
  </div>
</template>
<script>
import DUIX from 'duix-guiji-light'
import {getDuixSign} from "../../api/dialogue";
import * as pptTemplateApi from "../../api/pptTemplate";
import DUIX from 'duix-guiji-light';
import {getDuixSign} from "../../api/dialogue/index.ts";
export default {
  name: "index"
}
const tempConversationId ='dev-'+ Math.random().toString(36).substring(2, 11);
const duix = new DUIX()
  name: "index",
  mounted() {
    this.$nextTick(() => {
      this.initDuix();
    });
  },
  methods: {
  getDuixSign().then(res => {
    if (res.code === 200) {
      duix.init({
        sign: res.data.sign,
        containerLable: '.remote-container',
        conversationId: tempConversationId,
      })
    }
  })
duix.on('getDuixSign', () => {
  // start session
  duix.start({
    conversationId: tempConversationId,
    openAsr: true
  }).then(res => {
    console.info(res)
  })
})
    async initDuix() {
      // 1. 检查容器是否存在
      const container = document.querySelector('.remote-container');
      if (!container) {
        console.error("错误:未找到 .remote-container 元素");
        return;
      }
      // 2. 获取 Token
      let token;
      try {
        const res = await getDuixSign();
        token = res.data?.sign || res.sign || res;
        if (!token) throw new Error("Token 为空");
      } catch (err) {
        console.error("获取签名失败:", err);
        return;
      }
      // 3. 初始化 DUIX
      const duix = new DUIX();
      const conversationId = 'dev-'+ Math.random().toString(36).substring(2, 11);;
      try {
        await duix.init({
          sign: token,
          containerLable: '.remote-container', // 注意:可能是 containerLabel(检查拼写)
          conversationId: conversationId,
        });
        // 4. 监听事件
        duix.on('getDuixSign', () => {
          duix.start({conversationId, openAsr: true})
            .then(() => console.log("DUIX 启动成功"))
            .catch(err => console.error("DUIX 启动失败:", err));
        });
      } catch (initErr) {
        console.error("DUIX 初始化失败:", initErr);
      }
    },
  },
};
</script>
<style scoped>
.remote-container{
.remote-container {
  width: 500px;
  height: 500px;
  border: 1px solid red; /* 调试时高亮容器 */
}
</style>
easegen-front/src/views/digitalcourse/digitalhumans/LookDigitalHumansForm.vue
@@ -35,15 +35,15 @@
        </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-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">
          <!-- 原本自带的视频上传 -->
@@ -85,8 +85,9 @@
        </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>
        <el-button @click="submitForm" type="primary" :disabled="formLoading" :loading="isUploading" v-if="formType=='updata'">{{t('common.ok')}}</el-button>
        <el-button @click="dialogVisible = false" v-if="formType=='updata'">{{t('common.cancel')}}</el-button>
        <el-button @click="dialogVisible = false" v-if="formType=='detail'">关闭</el-button>
      </template>
    </Dialog>
  </template>
@@ -100,10 +101,10 @@
  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('') // 弹窗的标题
@@ -128,10 +129,10 @@
    status: undefined,
    isTransparent: undefined,
  })
  // 当前是否正在上传视频
  const isUploading = ref(false)
  const videoProperty = {
    videoUrl: '',
    posterUrl: '',
@@ -143,7 +144,7 @@
      height: 300
    }
  } as DiyComponent<VideoPlayerProperty>
  watch(()=> formData.value.videoUrl,(newVal,oldValue)=>{
    if (newVal && newVal.length > 0){
      videoProperty.videoUrl = formData.value.fixVideoUrl || newVal
@@ -164,12 +165,12 @@
    videoUrl: [{ required: true, message: '视频不能为空', trigger: 'blur' }]
  })
  const formRef = ref() // 表单 Ref
  const StartCes = () => {
    console.log( " ----- 开始 ----- " )
    isUploading.value = true
  }
  const End = (res)=>{
    const FileObject = {
      file:res
@@ -180,9 +181,9 @@
    } ).finally( res => {
      isUploading.value = false
    } )
  }
  /** 打开弹窗 */
  const open = async (type: string, id?: number) => {
    dialogVisible.value = true
@@ -202,7 +203,7 @@
    }
  }
  defineExpose({ open }) // 提供 open 方法,用于打开弹窗
  /** 提交表单 */
  const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  const submitForm = async () => {
@@ -226,7 +227,7 @@
      formLoading.value = false
    }
  }
  /** 重置表单 */
  const resetForm = () => {
    formData.value = {
@@ -254,9 +255,9 @@
      formData.value.videoUrl = response.data;
    }
  };
  // 修改默认的数字人视频模式为视频
  const InitHumMODEL = ()=>{
    let ModelList = getIntDictOptions( DICT_TYPE.USE_MODEL )
    for (let index = 0; index < ModelList.length; index++) {
@@ -266,6 +267,5 @@
      }
    }
  }
  </script>
easegen-front/src/views/digitalcourse/digitalhumans/index.vue
@@ -161,6 +161,23 @@
          >
            {{t('digitalhumans.handle')}}
          </el-button>
          <el-button
            link
            type="primary"
            @click="OpenLookformRef('detail', scope.row.id)"
            v-hasPermi="['digitalcourse:digital-humans:delete']"
          >
            {{t('digitalhumans.view')}}
          </el-button>
          <el-button
            link
            type="primary"
            @click="OpenLookformRef('updata', scope.row.id)"
            v-hasPermi="['digitalcourse:digital-humans:delete']"
          >
            修改
          </el-button>
          <el-button
            :disabled="scope.row.status == 3 || scope.row.status == 6"
            link
@@ -169,14 +186,6 @@
            v-hasPermi="['digitalcourse:digital-humans:delete']"
          >
            {{ t('action.del') }}
          </el-button>
          <el-button
            link
            type="primary"
            @click="OpenLookformRef('detail', scope.row.id)"
            v-hasPermi="['digitalcourse:digital-humans:delete']"
          >
            {{t('digitalhumans.view')}}
          </el-button>
        </template>
      </el-table-column>
easegen-front/src/views/digitalcourse/template/TemplateForm.vue
@@ -96,7 +96,6 @@
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item :label="t('template.digitalPeopleWidth')" prop="humanW">
            <el-input type="number" disabled v-model="formData.humanW" :placeholder="t('common.inputText') + t('template.digitalPeopleWidth')" />
@@ -119,8 +118,6 @@
            <el-input type="number" v-model="formData.humanY" :placeholder="t('common.inputText') + t('template.leftPositionDigitalPeople')" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
@@ -134,14 +131,6 @@
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('common.ok') }}</el-button>
yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/controller/admin/digitalhumans/vo/DigitalHumansRespVO.java
@@ -104,4 +104,5 @@
    //过期时间
    private Date expireDate;
}
    private Integer isTransparent;
}
yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceUtil.java
@@ -170,10 +170,10 @@
                // 当没有人像时,视频放在 cover 的下层
                builder = new ProcessBuilder(
                        "ffmpeg",
                        "-i", cover1,     // 背景图 1
                        "-i", substring1, // 视频(含音频)
                        "-i", cover1,     // 背景图 2
                        "-i", cover,      // PPT 内容
                        "-loop", "1", "-i", cover1,     // 背景图1(动态持续)
                        "-i", substring1,               // 视频(含音频)
                        "-loop", "1", "-i", cover1,     // 背景图2(动态持续)
                        "-loop", "1", "-i", cover,      // PPT 内容(动态持续)
                        "-filter_complex",
                        "[0:v]scale=" + Math.round(scene.getBackground().getWidth()) + ":" + Math.round(scene.getBackground().getHeight()) + "[bg1];" +
                                "[1:v]scale=" + Math.round(scene.getComponents().get(0).getWidth()) + ":" + Math.round(scene.getComponents().get(0).getHeight()) + "[v1];" +
yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/digitalhumans/DigitalHumansServiceImpl.java
@@ -137,7 +137,7 @@
    }
    @Override
    public PageResult<DigitalHumansDO> getDigitalHumansPage(DigitalHumansPageReqVO pageReqVO) {
        if(pageReqVO.getType()==1){
        if(pageReqVO.getType() != null && pageReqVO.getType()==1){
            //查询非公共数字人,只能查询自己的,公共数字人,可以查询所有的
            if (WebFrameworkUtils.getLoginUserId() != 1) pageReqVO.setCreator(String.valueOf(WebFrameworkUtils.getLoginUserId()));
        }