Bladeren bron

feat: 更新语音授权流程,登录去除默认密码,推荐问题防止重复点击

sunxiao 17 uur geleden
bovenliggende
commit
9900d96296
4 gewijzigde bestanden met toevoegingen van 120 en 19 verwijderingen
  1. 105 14
      src/components/chat/ChatInput.vue
  2. 5 0
      src/manifest.json
  3. 3 2
      src/pages/answer/index.vue
  4. 7 3
      src/pages/login/index.vue

+ 105 - 14
src/components/chat/ChatInput.vue

@@ -13,7 +13,7 @@ const showVolume = ref(false);
 const isLoad = ref(false);
 
 // 实时语音识别
-const manager = plugin.getRecordRecognitionManager();
+let manager = plugin.getRecordRecognitionManager();
 
 // 类型 input|voice
 const inpType = ref('input');
@@ -43,6 +43,39 @@ const onChangeInpType = () => {
   inpType.value = inpType.value === 'input' ? 'voice' : 'input';
 }
 
+// 权限申请
+const requestRecordAuth = () => {
+  uni.authorize({
+    scope: 'scope.record',
+    success: () => {
+      uni.showToast({
+        title: '授权成功',
+        icon: 'success'
+      });
+    },
+    fail: (err) => {
+      console.error('授权失败', err);
+      if (err.errMsg.includes('auth deny')) {
+        uni.showModal({
+          title: '提示',
+          content: '需要录音权限才能使用语音功能',
+          confirmText: '去设置',
+          success: (res) => {
+            if (res.confirm) {
+              uni.openSetting();
+            }
+          }
+        });
+      } else {
+        uni.showToast({
+          title: '获取麦克风权限失败',
+          icon: 'none'
+        });
+      }
+    }
+  });
+}
+
 const addManagerEventListener = () => {
   manager.onStop = (res) => {
     uni.hideLoading();
@@ -62,6 +95,7 @@ const addManagerEventListener = () => {
   }
   
   manager.onError = (res) => {
+    console.log( res );
     uni.hideLoading();
 
     isRecording.value = false;
@@ -73,23 +107,77 @@ const addManagerEventListener = () => {
 }
 
 // 开始录音
-const startRecording = () => {
+const startRecording = async () => {
   if ( modelLoading.value ) {
     return uni.showToast({ title: '当前有会话进行中', duration: 3000, icon: 'none' });
   };
   
-  uni.authorize({
-    scope: 'scope.record',
-    success() {
-      manager.start({ lang: "zh_CN", duration: 60000 })
+  uni.getSetting({
+    success: (res) => {
+      if (res.authSetting['scope.record']) {
+        manager.start({ lang: "zh_CN", duration: 60000 })
+      } else {
+        requestRecordAuth();
+      }
     },
-    fail() {
-      uni.showModal({
-        title: '提示',
-        content: '需要麦克风权限'
+    fail: (err) => {
+      console.error('获取设置失败', err);
+      uni.showToast({
+        title: '获取权限状态失败',
+        icon: 'none'
       });
     }
   });
+
+
+  // try {
+  //   // 检查权限状态
+  //   const setting = await new Promise((resolve, reject) => {
+  //     uni.getSetting({
+  //       success: resolve,
+  //       fail: reject
+  //     });
+  //   });
+    
+  //   if (setting.authSetting['scope.record']) {
+  //     // 已有权限,直接开始录音
+  //     manager.start({ lang: "zh_CN", duration: 60000 })
+  //   } else {
+  //     // 没有权限,申请权限
+  //     await new Promise((resolve, reject) => {
+  //       uni.authorize({
+  //         scope: 'scope.record',
+  //         success: resolve,
+  //         fail: reject
+  //       });
+  //     });
+      
+  //     // 权限申请成功后的处理
+  //     uni.showToast({
+  //       title: '授权成功',
+  //       icon: 'success'
+  //     });
+      
+  //     // 重新初始化录音管理器
+  //     manager = plugin.getRecordRecognitionManager();
+      
+  //     // 添加短暂延迟确保权限完全生效
+  //     await new Promise(resolve => setTimeout(resolve, 300));
+      
+  //     // 开始录音
+  //     manager.start({ lang: "zh_CN", duration: 60000 })
+  //   }
+  // } catch (err) {
+  //   console.error('录音启动失败', err);
+  //   // if (err.errMsg.includes('auth deny')) {
+  //   //   this.showAuthGuide();
+  //   // } else {
+  //   //   uni.showToast({
+  //   //     title: '启动录音失败: ' + err.errMsg,
+  //   //     icon: 'none'
+  //   //   });
+  //   // }
+  // }
 }
 
 function stopRecording() {
@@ -104,6 +192,8 @@ function stopRecording() {
 }
 
 onMounted(() => {
+
+
   addManagerEventListener();
   // 后面需要补充一个加载的loading
   setTimeout(() => {
@@ -124,8 +214,9 @@ onMounted(() => {
           </view>
         </view>
       </view>
-      <view class="vocie-btn_wrapper" @touchstart="startRecording" @touchend="stopRecording"
-        @touchcancel="stopRecording">
+      <!-- @touchstart="startRecording" @touchend="stopRecording"
+        @touchcancel="stopRecording" -->
+      <view class="vocie-btn_wrapper" >
         <view class="tips">{{ recordingTip }}</view>
         <view class="btn">
           <uni-icons type="sound" size="20" color="#777"></uni-icons>
@@ -153,9 +244,9 @@ onMounted(() => {
           v-show="inpType == 'input'"
         >
         </textarea>
-
+        <!--  -->
         <view class="chat-voice" v-show="inpType == 'voice'" @touchstart="startRecording" @touchend="stopRecording"
-          @touchcancel="stopRecording">
+        @touchcancel="stopRecording">
           <text>按住 说话</text>
         </view>
       </view>

+ 5 - 0
src/manifest.json

@@ -60,6 +60,11 @@
         "version": "latest",
         "provider": "wx069ba97219f66d99"
       }
+    },
+    "permission": {
+      "scope.record": {
+        "desc": "需要您的授权使用麦克风"
+      }
     }
   },
   "mp-alipay": {

+ 3 - 2
src/pages/answer/index.vue

@@ -182,6 +182,7 @@ const handleSubmit = async ({ showVal, question, selectedOption, realQuestion =
 
 // 处理推荐问题
 const handleWelcomeRecommend = ({ question, realQuestion }) => {
+  if (isLoading.value) return;
   handleSubmit({showVal: question, question, realQuestion});
 }
 
@@ -244,8 +245,8 @@ const getHelperList = async () => {
 
 // 初始化
 const init = async () => {
-  getHelperList();
-  reloadRecommend();
+  await getHelperList();
+  await reloadRecommend();
 }
 
 onMounted(() => {

+ 7 - 3
src/pages/login/index.vue

@@ -18,8 +18,8 @@ const userStore = useUserStore();
 const showPasswordIcon = ref(false);
 const loading = ref(false);
 const loginFormData = ref({
-  username: 'test11',
-  password: 'admin123',
+  username: '',
+  password: '',
   type: 0
 });
 
@@ -55,7 +55,11 @@ const handleSubmit = async () => {
         prevPage.$vm.init(); 
       }
       
-      uni.navigateBack({ delta: 1 });
+      uni.navigateTo({
+        url: `/pages/answer/index`
+      });
+
+      // uni.navigateBack({ delta: 1 });
     }, 2000)