ZaiZai %!s(int64=2) %!d(string=hai) anos
pai
achega
91cb997a74

+ 2 - 0
src/api/modules/api.js

@@ -0,0 +1,2 @@
+import {httpApi} from "../request/httpApi";
+export const appApi = (form) => httpApi(form, false);

+ 8 - 0
src/api/modules/using/query.js

@@ -45,4 +45,12 @@ async getarchiveQueryPage(form, msg = true) {
             params: form,
         }, msg);
     },
+    //语音搜索接口
+    async micSearchInfo(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-archive/archivesauto/search-info',
+            method: 'post',
+            data: form,
+        }, msg);
+    },
 }

BIN=BIN
src/assets/view/mic.gif


+ 73 - 0
src/styles/page/using/query.scss

@@ -84,6 +84,24 @@
             border-color: var(--el-button-disabled-border-color);
         }
     }
+    .hc-icon-mic {
+        color: var(--hc-text-color);
+        position: absolute;
+        top: 2px;
+        right: 102px;
+        height: 61px;
+        width: 61px;
+        border-radius: 4px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 28px;
+        cursor: pointer;
+        transition: .1s;
+        &:hover {
+            background: #071c8c;
+        }
+    }
 }
 
 //筛选搜索
@@ -215,3 +233,58 @@
         height: 100%;
     }
 }
+
+.el-dialog.hc-media-recorder-dialog {
+    --el-dialog-margin-top: 30vh;
+    .el-dialog__header {
+        padding: 10px 20px;
+        padding-bottom: 10px !important;
+        border-color: #EEEEEE !important;
+        .el-dialog__title {
+            color: #464646;
+        }
+        .el-dialog__headerbtn {
+            right: 6px;
+            width: 32px;
+            height: 32px;
+        }
+    }
+    .el-dialog__body {
+        padding: 10px;
+    }
+    .el-dialog__footer {
+        display: none;
+    }
+    .hc-media-recorder-box {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        img {
+            width: 300px;
+        }
+        .content-box {
+            position: absolute;
+            width: 140px;
+            height: 60px;
+            text-align: center;
+            color: #464646;
+            .shut-down-icon {
+                font-size: 24px;
+                margin-bottom: 14px;
+            }
+            .time-box {
+                position: relative;
+                .time {
+                    color: #FFAF75;
+                }
+            }
+        }
+    }
+}
+
+html.dark {
+    .el-dialog.hc-media-recorder-dialog {
+        --el-dialog-bg-color: #ffffff !important;
+    }
+}

+ 6 - 0
src/styles/theme/using/query.scss

@@ -13,6 +13,12 @@ html.dark {
                 color: white;
             }
         }
+        .hc-query-input-box .hc-icon-mic {
+            color: var(--hc-text-color);
+            &:hover {
+                background: #071c8c;
+            }
+        }
         .hc-gather-card-box {
             background: #0A1450;
             .hc-card-item-box {

+ 104 - 0
src/views/using/query.vue

@@ -38,6 +38,9 @@
                         </div>
                     </template>
                 </el-input>
+                <div class="hc-icon-mic" @click="transcribeClick">
+                    <HcIcon name="mic" :fill="isMicShow"/>
+                </div>
             </div>
 
             <div class="hc-query-filtering-collapse-box">
@@ -386,6 +389,29 @@
            <HcNoData v-if="nodeTreeArr.length==0"/>
         </HcDialog>
 
+        <!--语音识别-->
+        <HcDialog ui="hc-media-recorder-dialog"
+                  bgColor="#fff"
+                  title="语音识别搜索"
+                  :show="isMicShow"
+                  widths="360px"
+                  saveText="确认"
+                  @close="transcribeClick"
+        >
+            <div class="hc-media-recorder-box" @click="transcribeClick">
+                <img :src="imageViewMic" alt="">
+                <div class="content-box">
+                    <div class="shut-down-icon">
+                        <HcIcon name="shut-down"/>
+                    </div>
+                    <div class="time-box">
+                        <span class="time">{{micTime}}</span>
+                        <span> / 01:00</span>
+                    </div>
+                </div>
+            </div>
+        </HcDialog>
+
     </div>
 </template>
 
@@ -399,6 +425,7 @@ import tuningApi from "~api/archiveConfig/tuning.js";
 import imageViewGui from "~src/assets/view/gui.png";
 import imageViewGui1 from "~src/assets/view/gui1.png";
 import imageViewGui2 from "~src/assets/view/gui2.png";
+import imageViewMic from "~src/assets/view/mic.gif";
 
 //变量
 const useAppState = useAppStore()
@@ -1435,6 +1462,83 @@ const guiInfoData = ref([])
 const guiFileInfo = (item) => {
     guiInfoCurKey.value = item
 }
+
+//语音
+const isMicShow = ref(false)
+const mediaRecorderRef = ref(null)
+const micTime = ref('00:00')
+const micTimeRef = ref(null)
+const transcribeClick = async () => {
+    if (isMicShow.value) { //停止录音
+        mediaRecorderRef.value?.stop()
+        mediaRecorderRef.value = null
+        isMicShow.value = false
+        clearTimeout(micTimeRef.value);
+        micTimeRef.value = null
+        micTime.value = '00:00'
+    } else {
+        const stream = await getUserMedia()
+        if (stream === false) return false;
+        isMicShow.value = true
+        startRecorder(stream)
+    }
+}
+
+//开始录音
+const startRecorder = (stream) => {
+    let mediaRecorder = new MediaRecorder(stream);
+    mediaRecorderRef.value = mediaRecorder
+    //开始录音
+    mediaRecorder.start();
+    setMicTimeFormat() //开始计时
+    // 录音结束时,停止并下载录音文件
+    mediaRecorder.addEventListener("dataavailable", event => {
+        clearTimeout(micTimeRef.value);
+        micTimeRef.value = null
+        let audioFile = new Blob([event.data], { type: "audio/wav" });
+        transcribeApi(audioFile)
+    });
+}
+
+//发起请求
+const transcribeApi = async (file) => {
+    let formData = new FormData();
+    formData.append("file", file);
+    const { error, code, data } = await archiveQueryApi.micSearchInfo(formData)
+    console.log(data)
+}
+
+//获取录音权限
+const getUserMedia = () => {
+    return new Promise((resolve) => {
+        navigator.mediaDevices.getUserMedia({
+            audio: true
+        }).then(stream => {
+            resolve(stream)
+        }).catch(err => {
+            console.log(err)
+            resolve(false)
+        });
+    })
+}
+
+//设置时间格式
+const setMicTimeFormat = () => {
+    let startNum = 0
+    micTime.value = '00:00'
+    micTimeRef.value = setInterval(() => {
+        if (startNum < 60) {
+            startNum++
+            let min = Math.floor(startNum / 60) //分
+            let sec = Math.floor(startNum % 60) //秒
+            min = min < 10 ? '0' + min : min
+            sec = sec < 10 ? '0' + sec : sec
+            micTime.value = `${min}:${sec}`
+        } else {
+            transcribeClick()
+        }
+    },1000)
+}
 </script>
 
 <style lang="scss" scoped>