wujingjing
2025-04-09 dd58c1d3a27ba48a5df050aab7c586bb9b988914
src/components/chat/components/playBar/hook/useDigitalHuman.ts
@@ -1,10 +1,12 @@
import { nextTick, onDeactivated, onMounted, ref } from 'vue';
import { SignJWT } from 'jose';
import { nextTick, onDeactivated, onMounted, ref } from 'vue';
import { markdownToTxt } from 'markdown-to-txt';
import './libs/duix.js';
import { questionStreamByPost } from '/@/api/ai/chat';
import { activeGroupType, activeRoomId } from '/@/stores/chatRoom';
import { markdownToTxt } from 'markdown-to-txt';
import axios from 'axios';
import { ElMessage } from 'element-plus';
export type UseDigitalHumanProps = {
   container: string;
@@ -23,14 +25,42 @@
   // 是否已接口相应
   const isReceiveRes = ref(false);
   const humanIsLoading = ref(true);
   const digitalHumanIsShow = ref(false);
   const closeDigitalHuman = () => {
      digitalHumanIsShow.value = false;
      resetDuixStatus();
   };
   /**
    * 检查数字人是否可用
    */
   const checkIsUseable = async () => {
      const config = {
         method: 'get',
         url: `https://duix.guiji.ai/duix-openapi-v2/v1/getconcurrentNumber?appId=${duixConfig.appId}`,
         headers: {
            priority: 'u=1, i',
            sig: duixConfig.sign,
         },
      };
      const response = await axios(config);
      const data = response.data.data;
      const total = data.totalConcurrentNumber;
      const user = data.userConcurrentNumber;
      if (total === null || total === 0) {
         return false;
      }
      if (total !== null && total === user) {
         return false;
      }
      return true;
   };
   const resetDuixStatus = () => {
      humanIsLoading.value = true;
      isReceiveRes.value = false;
      // isSpeaking.value = false;
      digitalHumanIsShow.value = false;
@@ -46,7 +76,6 @@
         }
         return acc + mdText;
      }, '');
      console.log('🚀 ~ knowledgeText:', knowledgeText);
      // const conclusionText =
      //    item.conclusion
      //       ?.filter((item) => !!item.report)
@@ -58,6 +87,29 @@
   };
   let isWaitingSpeak = false;
   const speakContent = (content: string) => {
      // 打断之前的已收到xxx
      duix.break();
      isWaitingSpeak = false;
      duix.speak({
         content,
      });
   };
   const startDuix = () => {
      const conversationId = duixConfig.conversationId; // duix平台会话id
      duix
         .start({ conversationId, openAsr: true, wipeGreen: true })
         .then((res) => {
            console.info('start', res);
         })
         .catch((err) => {
            console.error('start error', err);
         });
   };
   const initDuix = () => {
      const sign = duixConfig.sign; // sign由服务端生成
      const conversationId = duixConfig.conversationId; // duix平台会话id
@@ -70,9 +122,7 @@
      duix.on('intialSucccess', () => {
         console.info('intialSucccess');
         // 此时初始化成功,可调用start
         duix.start({ conversationId, openAsr: true }).then((res) => {
            console.info('start', res);
         });
         startDuix();
      });
      duix.on('bye', (data) => {
         console.info('bye', data);
@@ -82,6 +132,7 @@
      });
      duix.on('show', () => {
         console.info('show');
         humanIsLoading.value = false;
         // 此时可确认视频已
         // (document.querySelector('#modal') as HTMLElement).style.display = 'none';
      });
@@ -96,7 +147,10 @@
         console.info('speakStart', data);
      });
      duix.on('speakEnd', (data) => {
         isReceiveRes.value = false;
         if (!isWaitingSpeak) {
            isReceiveRes.value = false;
            duix.openAsr().then((...a) => {});
         }
      });
      duix.on('speakSection', (data) => {
         console.info('speakSection', data);
@@ -106,18 +160,18 @@
      });
      duix.on('asrResult', (data) => {
         console.info('asrResult', data);
         if (isReceiveRes.value) {
            return;
         }
         duix.closeAsr().then((...a) => {});
         let hasResult = false;
         isReceiveRes.value = true;
         try {
            // isWaitingSpeak = true;
            // duix.speak({
            //    content: '已收到您的问题,正在思考中...请稍等',
            // });
            isWaitingSpeak = true;
            duix.speak({
               content: '已收到您的问题,正在思考中...请稍等',
            });
            questionStreamByPost(
               {
                  question: data,
@@ -130,26 +184,16 @@
                  if (chunkRes.mode === 'result' && chunkRes.value?.answer_type === 'knowledge') {
                     const plainText = getPlainText(chunkRes.value);
                     hasResult = true;
                     duix.speak({
                        content: plainText,
                     });
                  }
                  if (!chunkRes.value?.json_ok && chunkRes.value?.err_code === 'MESSAGE') {
                     speakContent(plainText);
                  } else if (!chunkRes.value?.json_ok && chunkRes.value?.err_code === 'MESSAGE') {
                     if (hasResult) return;
                     hasResult = true;
                     isWaitingSpeak = false;
                     duix.speak({
                        content: chunkRes.value.json_msg,
                     });
                     speakContent(chunkRes.value.json_msg);
                  }
                  if (chunkRes.mode === 'finish') {
                     if (!hasResult) {
                        isWaitingSpeak = false;
                        duix.speak({
                           content: '暂时无法口头描述你所说的问题',
                        });
                        speakContent('暂时无法口头描述你所说的问题');
                     } else {
                        hasResult = false;
                     }
@@ -177,20 +221,23 @@
   let hasInitDuix = false;
   let duix: any;
   const openDigitalHuman = () => {
   const openDigitalHuman = async () => {
      duixConfig.sign = await createSig(duixConfig.appId, duixConfig.appKey, 60 * 60 * duixConfig.expired);
      const isUsable = await checkIsUseable();
      if (!isUsable) {
         ElMessage.warning('"资源占用中,请检查后再试~"');
         return;
      }
      digitalHumanIsShow.value = true;
      nextTick(async () => {
         duixConfig.sign = await createSig(duixConfig.appId, duixConfig.appKey, 60 * 60 * duixConfig.expired);
      nextTick(() => {
         if (!hasInitDuix) {
            hasInitDuix = true;
            duix = new DUIX();
            initDuix();
         } else {
            duix.start({ conversationId: duixConfig.conversationId, openAsr: true }).then((res) => {
               console.info('start', res);
            });
            startDuix();
         }
      });
   };
@@ -222,5 +269,6 @@
      openDigitalHuman,
      isHumanTalking: isReceiveRes,
      closeDigitalHuman,
      humanIsLoading,
   };
};