yangg 1 сар өмнө
parent
commit
3b86cd1a29

+ 49 - 25
pages/Personal/Personal.vue

@@ -56,12 +56,12 @@
 				<!-- 第一行 -->
 				<view class="form-row">
 					<view class="form-item">
-						<text class="label">姓名</text>
+						<text class="label required">姓名</text>
 						<input type="text" v-model="formData.name" placeholder="请输入姓名" :class="{'input-error': formErrors.name}" />
 						<text v-if="formErrors.name" class="error-message">{{formErrors.name}}</text>
 					</view>
 					<view class="form-item">
-						<text class="label">性别</text>
+						<text class="label required">性别</text>
 						<picker @change="bindGenderChange" :value="genderIndex" :range="genderOptions">
 							<view class="picker-text">{{ genderOptions[genderIndex] || '请选择性别' }}</view>
 						</picker>
@@ -75,7 +75,7 @@
 					</view>
 					<view class="form-row">
 					<view class="form-item">
-						<text class="label">手机号</text>
+						<text class="label required">手机号</text>
 						<input type="number" v-model="formData.phone" placeholder="请输入手机号" :class="{'input-error': formErrors.phone}" />
 						<text v-if="formErrors.phone" class="error-message">{{formErrors.phone}}</text>
 					</view>
@@ -88,7 +88,7 @@
 					</view> -->
 				</view>
 					<view class="form-item">
-						<text class="label">身份证号</text>
+						<text class="label required">身份证号</text>
 						<input type="idcard" v-model="formData.idCard" placeholder="请输入身份证号" :class="{'input-error': formErrors.idCard}" />
 						<text v-if="formErrors.idCard" class="error-message">{{formErrors.idCard}}</text>
 					</view>
@@ -99,7 +99,7 @@
 						</picker>
 					</view> -->
 					<view class="form-item">
-						<text class="label">民族</text>
+						<text class="label required">民族</text>
 						<picker @change="bindEthnicChange" :value="ethnicIndex" :range="ethnicOptions">
 							<view class="picker-text">{{ ethnicOptions[ethnicIndex] || '请选择民族' }}</view>
 						</picker>
@@ -116,7 +116,7 @@
 						<input type="digit" v-model="formData.weight" placeholder="请输入体重" />
 					</view>
 					<view class="form-item">
-						<text class="label">现居住地址</text>
+						<text class="label required">现居住地址</text>
 						<input type="text" v-model="formData.currentAddress" placeholder="请输入现居住地址" />
 					</view>
 					<!-- <view class="form-item">
@@ -196,7 +196,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">称谓</text>
+							<text class="label required">称谓</text>
 							<input 
 								type="text" 
 								v-model="familyMemberForm.relation" 
@@ -206,7 +206,7 @@
 							<text v-if="familyMemberErrors.relation" class="error-message">{{familyMemberErrors.relation}}</text>
 						</view>
 						<view class="form-item">
-							<text class="label">姓名</text>
+							<text class="label required">姓名</text>
 							<input 
 								type="text" 
 								v-model="familyMemberForm.name" 
@@ -230,7 +230,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">联系电话</text>
+							<text class="label required">联系电话</text>
 							<input 
 								type="number" 
 								v-model="familyMemberForm.phone" 
@@ -303,7 +303,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">起止时间</text>
+							<text class="label required">起止时间</text>
 							<view class="date-range">
 								<picker 
 									mode="date" 
@@ -330,7 +330,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">学校名称</text>
+							<text class="label required">学校名称</text>
 							<input 
 								type="text" 
 								v-model="educationForm.schoolName" 
@@ -340,7 +340,7 @@
 							<text v-if="educationErrors.schoolName" class="error-message">{{educationErrors.schoolName}}</text>
 						</view>
 						<view class="form-item">
-							<text class="label">专业</text>
+							<text class="label required">专业</text>
 							<input 
 								type="text" 
 								v-model="educationForm.major" 
@@ -353,7 +353,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">学历</text>
+							<text class="label required">学历</text>
 							<picker 
 								@change="bindDegreeChange" 
 								:value="degreeIndex" 
@@ -379,7 +379,7 @@
 			
 			<!-- 第四步:专业技能 -->
 			<view v-if="currentStep === 6" class="form-container">
-				<view class="section-title">专业技能</view>
+				<view class="section-title"><text class="required" style="margin-right: 4rpx;color: #ff4d4f;">*</text>专业技能</view>
 				<view class="skills-container">
 					<textarea 
 						v-model="formData.skills" 
@@ -389,7 +389,7 @@
 					></textarea>
 					<text v-if="formErrors.skills" class="error-message">{{formErrors.skills}}</text>
 				</view>
-				<view class="section-title">受过的培训</view>
+				<view class="section-title"><text class="required" style="margin-right: 4rpx;color: #ff4d4f;">*</text>受过的培训</view>
 				<view class="training-container">
 					<textarea 
 						v-model="formData.training" 
@@ -461,7 +461,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">起止时间</text>
+							<text class="label required">起止时间</text>
 							<view class="date-range">
 								<picker 
 									mode="date" 
@@ -488,7 +488,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">单位名称</text>
+							<text class="label required">单位名称</text>
 							<input 
 								type="text" 
 								v-model="workForm.companyName" 
@@ -498,7 +498,7 @@
 							<text v-if="workErrors.companyName" class="error-message">{{workErrors.companyName}}</text>
 						</view>
 						<view class="form-item">
-							<text class="label">单位人数</text>
+							<text class="label required">单位人数</text>
 							<input 
 								type="number" 
 								v-model="workForm.employeeCount" 
@@ -511,7 +511,7 @@
 					
 					<view class="form-row">
 						<view class="form-item">
-							<text class="label">任职部门</text>
+							<text class="label required">任职部门</text>
 							<input 
 								type="text" 
 								v-model="workForm.department" 
@@ -521,7 +521,7 @@
 							<text v-if="workErrors.department" class="error-message">{{workErrors.department}}</text>
 						</view>
 						<view class="form-item">
-							<text class="label">担任职务</text>
+							<text class="label required">担任职务</text>
 							<input 
 								type="text" 
 								v-model="workForm.position" 
@@ -871,7 +871,7 @@ import { apiBaseUrl } from '@/common/config.js';
 				
 				if (!isValid) {
 					uni.showToast({
-						title: '请完善所有必填信息',
+						title: '请完善家庭成员信息',
 						icon: 'none'
 					});
 					return;
@@ -1019,7 +1019,7 @@ import { apiBaseUrl } from '@/common/config.js';
 				
 				if (!isValid) {
 					uni.showToast({
-						title: '请完善所有必填信息',
+						title: '请完善教育经历信息',
 						icon: 'none'
 					});
 					return;
@@ -1163,6 +1163,10 @@ import { apiBaseUrl } from '@/common/config.js';
 
 				// 如果验证不通过,直接返回
 				if (!isValid) {
+					uni.showToast({
+						title: '请完善工作经历信息',
+						icon: 'none'
+					});
 					return;
 				}
 
@@ -1610,7 +1614,8 @@ import { apiBaseUrl } from '@/common/config.js';
 						break;
 
 					case 3: // 家庭成员
-						if (this.familyMembers.length === 0) {
+					console.log(this.familyMembers.length);
+						if (this.familyMembers.length == 0) {
 							uni.showToast({
 								title: '请至少添加一位家庭成员',
 								icon: 'none'
@@ -1651,12 +1656,12 @@ import { apiBaseUrl } from '@/common/config.js';
 						break;
 				}
 
-				if (!isValid) {
+				/* if (!isValid) {
 					uni.showToast({
 						title: '请完善所有必填信息',
 						icon: 'none'
 					});
-				}
+				} */
 
 				return isValid;
 			},
@@ -2075,6 +2080,8 @@ import { apiBaseUrl } from '@/common/config.js';
 		margin-right: 10rpx;
 		display: block;
 		margin-bottom: 10rpx;
+		position: relative;
+		padding-left: 14rpx;  /* 为星号预留空间 */
 	}
 
 	input {
@@ -2760,5 +2767,22 @@ import { apiBaseUrl } from '@/common/config.js';
 	.form-item switch {
 		margin-top: 10rpx;
 	}
+
+	/* 修改必填项标签的样式 */
+	.label.required::before {
+	  content: '*';
+	  color: #ff4d4f;
+	  margin-right: 4rpx;
+	  position: absolute;
+	  left: 0;
+	  top: -4rpx;
+	}
+
+	/* 修改必填项标签的样式 */
+	/* .label.required::after {
+	  content: '*';
+	  color: #ff4d4f;
+	  margin-left: 4rpx;
+	} */
 </style>
 

+ 816 - 92
pages/interview-question/interview-question.vue

@@ -300,10 +300,11 @@ export default {
       showContinueQuestionButton: false, // 控制"继续提问"按钮显示
       showEndInterviewButton: false,     // 控制"结束面试"按钮显示
       questionRound: 0,                  // 当前提问轮次
-      maxQuestionRounds: 2,              // 最大提问轮次(可配置)
+      maxQuestionRounds: 1,              // 最大提问轮次(可配置)
       conversationHistory: [],           // 对话历史记录
       pendingAutoNavigation: false, // 标记是否有待处理的自动跳转
       hasTriedFallbackMethod: false, // 标记是否尝试过备选方法播放音频
+      hasShownTextFallbackToast: false, // 标记是否已显示文本回退提示
     }
   },
   onLoad(options) {
@@ -2871,7 +2872,11 @@ export default {
             'content-type': 'application/json' // 修改为JSON格式
           },
           success: (res) => {
-            this.handleAiInteractionResponse(res.data);
+            if (res.statusCode === 200) {
+              this.handleAiInteractionResponse(res.data);
+            } else {
+              this.handleAiInteractionError(res.data);
+            }
           },
           fail: (err) => {
             this.handleAiInteractionError(err);
@@ -2913,8 +2918,13 @@ export default {
 
     // 添加处理AI交互响应的方法
     handleAiInteractionResponse(data) {
+
       console.log('AI语音交互接口响应:', data);
-      
+       // 获取系统信息
+       const systemInfo = uni.getSystemInfoSync();
+      const isIOS = systemInfo.platform === 'ios';
+       // 标记正在播放AI语音
+       this.isPlayingAiVoice = true;
       // 隐藏加载提示
       uni.hideLoading();
       
@@ -2965,7 +2975,12 @@ export default {
           // 根据平台选择不同的播放方法
           if (isMiniProgram) {
             // 小程序环境使用原生API
-            this.playMiniProgramAudio();
+            if (isIOS) {
+              this.playIOSMiniProgramAudio();
+            } else {
+              this.playMiniProgramAudio();
+            }
+           /*  this.playMiniProgramAudio(); */
           } else {
             // H5/App环境使用通用方法
             this.playAiVoice();
@@ -3009,100 +3024,801 @@ export default {
     playAiVoice() {
       console.log('开始播放AI语音:', this.aiVoiceUrl);
       
+      // 重置错误提示标记
+      this.hasShownTextFallbackToast = false;
+      
       // 标记正在播放AI语音
       this.isPlayingAiVoice = true;
       
-      // 确保在播放期间不显示继续提问按钮
+      // 隐藏所有按钮
       this.showContinueQuestionButton = false;
       this.showEndInterviewButton = false;
       
+      // 显示AI回复文本作为字幕
+      this.currentSubtitle = this.aiText;
+      
       // 检查音频URL是否有效
       if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === '') {
-        console.error('无效的音频URL');
-        this.handleAudioPlaybackFailure();
+        console.error('无效的音频URL,直接显示文本');
+        this.useTextFallbackAndNavigate();
         return;
       }
       
-      try {
-        // 创建音频播放器
-        if (this.aiAudioPlayer) {
+      // 获取系统信息
+      const systemInfo = uni.getSystemInfoSync();
+      const isMiniProgram = systemInfo.uniPlatform && systemInfo.uniPlatform.startsWith('mp-');
+      const isIOS = systemInfo.platform === 'ios';
+      
+      // 根据平台选择播放方式
+      if (isMiniProgram) {
+        if (isIOS) {
+          this.playIOSMiniProgramAudio();
+        } else {
+          this.playMiniProgramAudio();
+        }
+      } else if (isIOS) {
+        this.playAiVoiceForIOS();
+      } else {
+        this.playAiVoiceForAndroid();
+      }
+    },
+
+    // 新增方法:文本回退并导航
+    useTextFallbackAndNavigate() {
+      console.log('使用文本回退并准备导航');
+      
+      // 标记播放结束
+      this.isPlayingAiVoice = false;
+      
+      // 显示友好提示
+      if (!this.hasShownTextFallbackToast) {
+        this.hasShownTextFallbackToast = true;
+        uni.showToast({
+          title: '为您显示文字回复',
+          icon: 'none',
+          duration: 2000
+        });
+      }
+      
+      // 显示完整文本
+      this.currentSubtitle = this.aiText || '抱歉,AI回复内容加载失败';
+      
+      // 给用户一定时间阅读文本后自动跳转
+      setTimeout(() => {
+        this.navigateToNextPage();
+      }, 5000); // 5秒后跳转
+    },
+
+    // 修改 handleIOSAudioPlaybackComplete 方法
+    handleIOSAudioPlaybackComplete() {
+      // 标记播放结束
+      this.isPlayingAiVoice = false;
+      
+      // 延迟清空字幕
+      setTimeout(() => {
+        this.currentSubtitle = '';
+      }, 1000);
+      
+      // 销毁音频播放器
+      if (this.aiAudioPlayer) {
+        try {
           this.aiAudioPlayer.destroy();
+        } catch (e) {
+          console.error('销毁iOS音频播放器失败:', e);
         }
+        this.aiAudioPlayer = null;
+      }
+      
+      // 直接导航到下一页
+      this.navigateToNextPage();
+    },
+
+    // 修改 playMiniProgramAudio 方法
+    playMiniProgramAudio() {
+      console.log('使用小程序原生音频API播放:', this.aiVoiceUrl);
+      
+      try {
+        const audioContext = wx.createInnerAudioContext();
         
-        // 重新创建音频上下文
-        this.aiAudioPlayer = uni.createInnerAudioContext();
+        audioContext.autoplay = true;
+        audioContext.src = this.aiVoiceUrl;
         
-        // 设置音频属性
-        this.aiAudioPlayer.autoplay = false;
-        this.aiAudioPlayer.obeyMuteSwitch = false;
+        audioContext.onPlay(() => {
+          console.log('AI语音开始播放');
+          this.currentSubtitle = this.aiText;
+        });
         
-        // 监听音频加载完成事件
-        this.aiAudioPlayer.onCanplay(() => {
-          console.log('音频已加载完成,准备播放');
-          // 获取音频时长
-          const duration = this.aiAudioPlayer.duration;
-          console.log('音频时长:', duration);
+        audioContext.onEnded(() => {
+          console.log('AI语音播放结束');
+          this.isPlayingAiVoice = false;
+          this.currentSubtitle = '';
+          audioContext.destroy();
           
-          // 开始播放
-          this.aiAudioPlayer.play();
+          // 播放结束后直接导航
+          this.navigateToNextPage();
+        });
+        
+        audioContext.onError((err) => {
+          console.error('AI语音播放错误:', err);
+          audioContext.destroy();
+          this.useTextFallbackAndNavigate();
         });
         
-        // 监听播放进度
-        this.aiAudioPlayer.onTimeUpdate(() => {
-          const currentTime = this.aiAudioPlayer.currentTime;
-          const duration = this.aiAudioPlayer.duration;
-          console.log(`播放进度: ${currentTime}/${duration}`);
+        // 设置超时处理
+        setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.warn('音频播放超时,使用文本回退');
+            this.useTextFallbackAndNavigate();
+          }
+        }, 5000);
+        
+      } catch (e) {
+        console.error('小程序播放AI语音失败:', e);
+        this.useTextFallbackAndNavigate();
+      }
+    },
+
+    // 新增方法:导航到下一页
+    navigateToNextPage() {
+      // 这里添加导航逻辑
+      console.log('准备导航到下一页');
+      
+      // 根据实际需求设置导航目标
+      uni.navigateTo({
+        url: '/pages/posture-guide/posture-guide',
+        fail: (err) => {
+          console.error('导航失败:', err);
+          // 导航失败时的处理
+          uni.showToast({
+            title: '页面跳转失败',
+            icon: 'none',
+            duration: 2000
+          });
+        }
+      });
+    },
+
+    // 新增方法:专门处理iOS小程序音频播放
+    playIOSMiniProgramAudio() {
+      console.log('iOS小程序环境:使用增强的音频处理方法');
+      
+      // 重置错误标记
+      this.hasShownTextFallbackToast = false;
+      
+      try {
+        // 创建音频上下文,使用wx API确保兼容性
+        const audioContext = wx.createInnerAudioContext();
+        
+        // iOS小程序优化配置
+        audioContext.autoplay = false;
+        audioContext.obeyMuteSwitch = true; // iOS遵循静音开关
+        audioContext.volume = 1.0;
+        
+        // 设置播放成功事件
+        audioContext.onPlay(() => {
+          console.log('iOS小程序音频开始播放');
+          this.currentSubtitle = this.aiText;
           
-          // 更新字幕显示
-          if (this.aiText) {
-            // 根据播放进度计算应该显示的文本部分
-            const textProgress = Math.floor((currentTime / duration) * this.aiText.length);
-            this.currentSubtitle = this.aiText.substring(0, textProgress);
+          uni.showToast({
+            title: '正在播放AI回复',
+            icon: 'none',
+            duration: 1500
+          });
+        });
+        
+        // 设置播放结束事件
+        audioContext.onEnded(() => {
+          console.log('iOS小程序音频播放结束');
+          this.handleIOSAudioComplete(audioContext);
+        });
+        
+        // 设置播放停止事件
+        audioContext.onStop(() => {
+          console.log('iOS小程序音频播放停止');
+          this.handleIOSAudioComplete(audioContext);
+        });
+        
+        // 重点:增强的iOS错误处理
+        audioContext.onError((err) => {
+          console.error('iOS小程序音频播放错误:', err);
+          this.handleIOSMiniProgramError(audioContext, err);
+        });
+        
+        // 先尝试预下载音频文件(iOS小程序推荐做法)
+        this.preloadIOSMiniProgramAudio(this.aiVoiceUrl)
+          .then((localPath) => {
+            console.log('iOS小程序音频预下载成功:', localPath);
+            audioContext.src = localPath;
+            
+          /*   // 设置播放超时
+            const playTimeout = setTimeout(() => {
+              if (this.isPlayingAiVoice) {
+                console.log('iOS小程序音频播放超时,使用文本回退');
+                clearTimeout(playTimeout);
+                this.handleIOSPlaybackTimeout(audioContext);
+              }
+            }, 5000);
+            */
+            // 尝试播放
+            audioContext.play(); 
+          })
+          .catch((error) => {
+            console.error('iOS小程序音频预下载失败:', error);
+            // 预下载失败,尝试直接播放
+            this.fallbackIOSMiniProgramPlay(audioContext);
+          });
+        
+      } catch (e) {
+        console.error('iOS小程序音频初始化失败:', e);
+        this.useIOSTextFallback();
+      }
+    },
+
+    // 新增方法:iOS小程序音频预下载
+    preloadIOSMiniProgramAudio(audioUrl) {
+      return new Promise((resolve, reject) => {
+        console.log('开始预下载iOS小程序音频:', audioUrl);
+        
+        uni.downloadFile({
+          url: audioUrl,
+          timeout: 15000, // 15秒超时
+          success: (res) => {
+            if (res.statusCode === 200) {
+              console.log('iOS小程序音频下载成功:', res.tempFilePath);
+              resolve(res.tempFilePath);
+            } else {
+              console.error('iOS小程序音频下载失败,状态码:', res.statusCode);
+              reject(new Error(`下载失败,状态码: ${res.statusCode}`));
+            }
+          },
+          fail: (err) => {
+            console.error('iOS小程序音频下载请求失败:', err);
+            reject(err);
           }
         });
+      });
+    },
+
+    // 新增方法:iOS小程序错误处理
+    handleIOSMiniProgramError(audioContext, error) {
+      console.error('处理iOS小程序音频错误:', error);
+      
+      // 销毁音频播放器
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error('销毁音频播放器失败:', e);
+        }
+      }
+      
+      // 根据错误类型显示不同的提示信息
+      let errorMessage = '音频播放异常,显示文字';
+      
+      if (error.errMsg && error.errMsg.includes('-11850')) {
+        console.log('iOS小程序检测到系统音频错误(-11850)');
+        errorMessage = '系统音频服务暂停,显示文字';
+      } else if (error.errCode === 10002) {
+        console.log('iOS小程序检测到errCode:10002,网络或资源问题');
+        errorMessage = '音频加载中断,显示文字';
+      } else if (error.errCode === 10001) {
+        console.log('iOS小程序检测到errCode:10001,系统错误');
+        errorMessage = '系统音频错误,显示文字';
+      } else if (error.errCode === 10003) {
+        console.log('iOS小程序检测到errCode:10003,文件错误');
+        errorMessage = '音频文件错误,显示文字';
+      } else if (error.errCode === 10004) {
+        console.log('iOS小程序检测到errCode:10004,格式不支持');
+        errorMessage = '音频格式不支持,显示文字';
+      }
+      
+      // 显示用户友好的错误提示
+      uni.showToast({
+        title: errorMessage,
+        icon: 'none',
+        duration: 2000
+      });
+      
+      // 使用文本回退
+      this.useIOSTextFallback();
+    },
+
+    // 新增方法:iOS小程序播放超时处理
+    handleIOSPlaybackTimeout(audioContext) {
+      console.log('iOS小程序音频播放超时处理');
+      
+      // 销毁音频播放器
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error('销毁超时音频播放器失败:', e);
+        }
+      }
+      
+      // 显示超时提示
+      uni.showToast({
+        title: '音频加载超时,显示文字',
+        icon: 'none',
+        duration: 2000
+      });
+      
+      // 使用文本回退
+      this.useIOSTextFallback();
+    },
+
+    // 新增方法:iOS小程序备选播放方法
+    fallbackIOSMiniProgramPlay(audioContext) {
+      console.log('iOS小程序使用备选播放方法');
+      
+      try {
+        // 直接设置原始URL
+        audioContext.src = this.aiVoiceUrl;
+        
+        // 设置较短的超时时间
+        const fallbackTimeout = setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.log('iOS小程序备选方法也超时');
+            clearTimeout(fallbackTimeout);
+            this.handleIOSPlaybackTimeout(audioContext);
+          }
+        }, 3000);
+        
+        // 尝试播放
+        audioContext.play();
+        
+      } catch (e) {
+        console.error('iOS小程序备选播放方法失败:', e);
+        this.handleIOSPlaybackTimeout(audioContext);
+      }
+    },
+
+    // 新增方法:统一的iOS音频完成处理
+    handleIOSAudioComplete(audioContext) {
+      console.log('iOS音频播放完成');
+      
+      // 标记播放结束
+      this.isPlayingAiVoice = false;
+      
+      // 延迟清空字幕,让用户有时间阅读
+      setTimeout(() => {
+        this.currentSubtitle = '';
+      }, 2000);
+      
+      // 销毁音频播放器
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error('销毁iOS音频播放器失败:', e);
+        }
+      }
+      
+      // 显示继续提问选项
+      this.showContinueQuestionOptions();
+      
+      // 检查是否需要自动跳转
+      this.checkPendingNavigation();
+    },
+
+    // 移除原来的 playMiniProgramAudioForIOS 方法,因为已经被新的 playIOSMiniProgramAudio 替代
+    // playMiniProgramAudioForIOS() 方法可以删除或注释掉
+
+    // 保留原有的 useIOSTextFallback 方法,但确保它能正确处理所有iOS场景
+    useIOSTextFallback() {
+      console.log('iOS使用文本回退方案');
+      
+      // 确保播放状态正确
+      this.isPlayingAiVoice = false;
+      
+      // 显示友好提示(如果还没有显示过)
+      if (!this.hasShownTextFallbackToast) {
+        this.hasShownTextFallbackToast = true;
+        uni.showToast({
+          title: '为您显示文字回复',
+          icon: 'none',
+          duration: 2000
+        });
+      }
+      
+      // 显示完整文本
+      this.currentSubtitle = this.aiText || '抱歉,AI回复内容加载失败';
+      
+      // 根据文本长度计算合适的阅读时间
+      const textLength = this.aiText ? this.aiText.length : 20;
+      const readingTime = Math.max(5000, Math.min(textLength * 100, 15000)); // 最少5秒,最多15秒
+      
+      console.log(`文本长度: ${textLength}, 预计阅读时间: ${readingTime}ms`);
+      
+      setTimeout(() => {
+        this.handleIOSAudioComplete(null);
+      }, readingTime);
+    },
+
+    // 添加新方法:iOS音频播放完成处理
+    handleIOSAudioPlaybackComplete() {
+      // 标记播放结束
+      this.isPlayingAiVoice = false;
+      
+      // 延迟清空字幕,让用户有时间阅读
+      setTimeout(() => {
+        this.currentSubtitle = '';
+      }, 2000);
+      
+      // 销毁音频播放器
+      if (this.aiAudioPlayer) {
+        try {
+          this.aiAudioPlayer.destroy();
+        } catch (e) {
+          console.error('销毁iOS音频播放器失败:', e);
+        }
+        this.aiAudioPlayer = null;
+      }
+      
+      // 显示继续提问选项
+      this.showContinueQuestionOptions();
+      
+      // 检查是否需要自动跳转
+      this.checkPendingNavigation();
+    },
+
+    // 添加新方法:iOS音频错误处理
+    handleIOSAudioError(error) {
+      console.error('iOS音频播放错误:', error);
+      
+      // 根据错误码进行不同处理
+      switch (error.errCode) {
+        case 10001:
+          console.log('iOS音频系统错误,尝试重新播放');
+          this.retryIOSAudioPlay();
+          break;
+        case 10002:
+          console.log('iOS音频网络错误,使用备选方案');
+          this.handleIOS10002Error();
+          break;
+        case 10003:
+          console.log('iOS音频文件错误,使用文本回退');
+          this.useIOSTextFallback();
+          break;
+        case 10004:
+          console.log('iOS音频格式不支持,使用文本回退');
+          this.useIOSTextFallback();
+          break;
+        default:
+          console.log('iOS音频未知错误,使用文本回退');
+          this.useIOSTextFallback();
+          break;
+      }
+    },
+
+    // 添加新方法:重试iOS音频播放
+    retryIOSAudioPlay() {
+      console.log('重试iOS音频播放');
+      
+      // 销毁当前播放器
+      if (this.aiAudioPlayer) {
+        try {
+          this.aiAudioPlayer.destroy();
+        } catch (e) {
+          console.error('销毁播放器失败:', e);
+        }
+        this.aiAudioPlayer = null;
+      }
+      
+      // 延迟后重试
+      setTimeout(() => {
+        this.fallbackIOSAudioPlay();
+      }, 1000);
+    },
+
+    // 添加新方法:iOS备选音频播放
+    fallbackIOSAudioPlay() {
+      console.log('iOS备选音频播放方案');
+      
+      try {
+        // 创建新的音频播放器
+        this.aiAudioPlayer = uni.createInnerAudioContext();
+        
+        // 使用更保守的设置
+        this.aiAudioPlayer.autoplay = true;
+        this.aiAudioPlayer.obeyMuteSwitch = true; // 遵循静音开关
+        this.aiAudioPlayer.volume = 0.8;
+        
+        // 直接使用原URL
+        this.aiAudioPlayer.src = this.aiVoiceUrl;
+        
+        // 设置简化的事件监听
+        this.aiAudioPlayer.onPlay(() => {
+          console.log('iOS备选方案:音频开始播放');
+          this.currentSubtitle = this.aiText;
+        });
         
-        // 监听播放结束事件
         this.aiAudioPlayer.onEnded(() => {
-          console.log('AI语音播放完成');
+          console.log('iOS备选方案:音频播放结束');
+          this.handleIOSAudioPlaybackComplete();
+        });
+        
+        this.aiAudioPlayer.onError((err) => {
+          console.error('iOS备选方案:音频播放错误:', err);
+          this.useIOSTextFallback();
+        });
+        
+        // 设置超时,如果5秒内没有开始播放,使用文本回退
+        setTimeout(() => {
+          if (this.isPlayingAiVoice && this.aiAudioPlayer) {
+            console.log('iOS音频播放超时,使用文本回退');
+            this.useIOSTextFallback();
+          }
+        }, 5000);
+        
+      } catch (e) {
+        console.error('iOS备选音频播放失败:', e);
+        this.useIOSTextFallback();
+      }
+    },
+
+    // 修改 playMiniProgramAudio 方法,添加iOS特殊处理
+    playMiniProgramAudio() {
+      console.log('使用小程序原生音频API播放:', this.aiVoiceUrl);
+      
+      // 标记正在播放AI语音
+      this.isPlayingAiVoice = true;
+      
+      // 确保在播放期间不显示继续提问按钮
+      this.showContinueQuestionButton = false;
+      this.showEndInterviewButton = false;
+      
+      // 检查音频URL是否有效
+      if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === '') {
+        console.error('无效的音频URL');
+        this.handleAudioPlaybackFailure();
+        return;
+      }
+      
+      // 检查平台
+      const systemInfo = uni.getSystemInfoSync();
+      const isIOS = systemInfo.platform === 'ios';
+      
+      // iOS小程序特殊处理
+      if (isIOS) {
+        this.playMiniProgramAudioForIOS();
+        return;
+      }
+      
+      // 非iOS平台的原有逻辑
+      try {
+        // 使用wx.createInnerAudioContext API (微信小程序)
+        const audioContext = wx.createInnerAudioContext();
+        
+        // 设置音频属性
+        audioContext.autoplay = false;
+        audioContext.obeyMuteSwitch = false; // 忽略静音开关
+        
+        // 监听播放开始事件
+        audioContext.onPlay(() => {
+          console.log('AI语音开始播放');
           
-          // 确保显示完整文本
-          this.currentSubtitle = this.aiText;
+          // 显示正在播放提示
+          uni.showToast({
+            title: '正在播放AI回复',
+            icon: 'none',
+            duration: 2000
+          });
+        });
+        
+        // 监听播放结束事件
+        audioContext.onEnded(() => {
+          console.log('AI语音播放结束');
           
-          // 延迟一段时间让用户看完最后的文本
-          setTimeout(() => {
-            // 标记播放结束
-            this.isPlayingAiVoice = false;
-            
-            // 清空字幕
-            this.currentSubtitle = '';
-            
-            // 销毁音频播放器
-            if (this.aiAudioPlayer) {
-              this.aiAudioPlayer.destroy();
-              this.aiAudioPlayer = null;
-            }
-            
-            // 播放结束后显示继续提问选项
-            this.showContinueQuestionOptions();
-            
-            // 检查是否需要自动跳转
-            this.checkPendingNavigation();
-          }, 2000); // 给用户2秒时间阅读最后的文本
+          // 标记播放结束
+          this.isPlayingAiVoice = false;
+          
+          // 清空字幕
+          this.currentSubtitle = '';
+          
+          // 销毁音频播放器
+          audioContext.destroy();
+          
+          // 播放结束后显示继续提问选项,而不是直接跳转
+          this.showContinueQuestionOptions();
         });
         
         // 监听播放错误事件
-        this.aiAudioPlayer.onError((err) => {
+        audioContext.onError((err) => {
           console.error('AI语音播放错误:', err);
-          this.handleAudioPlaybackError(err);
+          
+          // 标记播放结束
+          this.isPlayingAiVoice = false;
+          
+          // 清空字幕
+          this.currentSubtitle = '';
+          
+          // 销毁音频播放器
+          audioContext.destroy();
+          
+          // 播放错误时也显示继续提问选项
+          this.showContinueQuestionOptions();
         });
         
-        // 设置音频源并开始播放
-        this.aiAudioPlayer.src = this.aiVoiceUrl;
+        // 设置音频源
+        audioContext.src = this.aiVoiceUrl;
+        
+        // 添加超时处理,如果5秒内没有开始播放,则认为出错
+        const playTimeout = setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.warn('小程序音频播放超时,尝试备选方法');
+            this.tryMiniProgramFallbackAudioPlay();
+          }
+        }, 5000);
+        
+        // 延迟一小段时间再播放,确保src已经设置完成
+        setTimeout(() => {
+          audioContext.play();
+          // 播放开始后清除超时
+          clearTimeout(playTimeout);
+        }, 300);
+      } catch (e) {
+        console.error('小程序播放AI语音时发生错误:', e);
+        
+        // 标记播放结束
+        this.isPlayingAiVoice = false;
+        
+        // 显示错误提示
+        uni.showToast({
+          title: '音频播放失败,请查看文字回复',
+          icon: 'none',
+          duration: 2000
+        });
+        
+        // 使用文本显示方式作为备选方案
+        this.handleAudioPlaybackFailure();
+      }
+    },
+
+    // 添加新方法:iOS小程序音频播放
+    playMiniProgramAudioForIOS() {
+      console.log('iOS小程序环境:开始播放AI语音');
+      
+      // 重置错误标记
+      this.hasShownTextFallbackToast = false;
+      
+      try {
+        // 创建音频上下文
+        const audioContext = wx.createInnerAudioContext();
+        
+        // iOS小程序特殊配置
+        audioContext.autoplay = false;
+        audioContext.obeyMuteSwitch = true; // iOS上遵循静音开关
+        audioContext.volume = 1.0;
+        
+        // 设置错误处理
+        audioContext.onError((err) => {
+          console.error('iOS小程序音频播放错误:', err);
+          
+          // 检查具体错误类型
+          if (err.errMsg && err.errMsg.includes('-11850')) {
+            console.log('iOS小程序检测到系统音频错误(-11850)');
+            uni.showToast({
+              title: '系统音频暂停,显示文字',
+              icon: 'none',
+              duration: 2000
+            });
+          } else if (err.errCode === 10002) {
+            console.log('iOS小程序检测到errCode:10002,网络或资源问题');
+            uni.showToast({
+              title: '音频加载中断,显示文字',
+              icon: 'none',
+              duration: 2000
+            });
+          } else {
+            console.log('iOS小程序其他音频错误:', err.errCode);
+            uni.showToast({
+              title: '音频播放异常,显示文字',
+              icon: 'none',
+              duration: 2000
+            });
+          }
+          
+          this.useIOSMiniProgramTextFallback(audioContext);
+        });
+        
+        // 先尝试直接播放,如果失败再下载
+        audioContext.src = this.aiVoiceUrl;
+        
+        // 设置成功事件监听
+        audioContext.onPlay(() => {
+          console.log('iOS小程序音频开始播放');
+          this.currentSubtitle = this.aiText;
+          
+          uni.showToast({
+            title: '正在播放AI回复',
+            icon: 'none',
+            duration: 1500
+          });
+        });
+        
+        audioContext.onEnded(() => {
+          console.log('iOS小程序音频播放结束');
+          this.handleIOSMiniProgramAudioComplete(audioContext);
+        });
+        
+        // 设置较短的播放超时时间
+        const playTimeout = setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.log('iOS小程序音频播放超时,切换到文本显示');
+            clearTimeout(playTimeout);
+            this.useIOSMiniProgramTextFallback(audioContext);
+          }
+        }, 3000); // 缩短到3秒
+        
+        // 尝试播放
+        audioContext.play();
         
       } catch (e) {
-        console.error('播放AI语音时发生错误:', e);
-        this.handleAudioPlaybackError(e);
+        console.error('iOS小程序音频播放初始化失败:', e);
+        this.handleAudioPlaybackFailure();
+      }
+    },
+
+    // 添加新方法:iOS小程序音频播放完成
+    handleIOSMiniProgramAudioComplete(audioContext) {
+      this.isPlayingAiVoice = false;
+      
+      setTimeout(() => {
+        this.currentSubtitle = '';
+      }, 2000);
+      
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error('销毁iOS小程序音频播放器失败:', e);
+        }
+      }
+      
+      this.showContinueQuestionOptions();
+      this.checkPendingNavigation();
+    },
+
+    // 添加新方法:iOS小程序音频错误处理
+    handleIOSMiniProgramAudioError(audioContext, error) {
+      console.error('iOS小程序音频错误:', error);
+      
+      // 根据错误码处理
+      if (error.errCode === 10002) {
+        this.useIOSMiniProgramTextFallback(audioContext);
+      } else {
+        // 其他错误也使用文本回退
+        this.useIOSMiniProgramTextFallback(audioContext);
+      }
+    },
+
+    // 添加新方法:iOS小程序文本回退
+    useIOSMiniProgramTextFallback(audioContext) {
+      console.log('iOS小程序使用文本回退方案');
+      
+      // 销毁音频播放器
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error('销毁音频播放器失败:', e);
+        }
       }
+      
+      // 确保播放状态正确
+      this.isPlayingAiVoice = false;
+      
+      // 显示完整文本
+      this.currentSubtitle = this.aiText || '抱歉,AI回复内容加载失败';
+      
+      // 根据文本长度计算阅读时间
+      const textLength = this.aiText ? this.aiText.length : 20;
+      const readingTime = Math.max(6000, Math.min(textLength * 120, 18000)); // 最少6秒,最多18秒
+      
+      setTimeout(() => {
+        this.handleIOSMiniProgramAudioComplete(null);
+      }, readingTime);
     },
 
     // 添加新方法:处理音频播放错误
@@ -3574,35 +4290,13 @@ export default {
       // 清空字幕
       this.currentSubtitle = '';
       
-      // 如果未达到最大提问轮次,显示继续提问按钮
-      if (this.questionRound < this.maxQuestionRounds) {
-        this.showContinueQuestionButton = true;
-        this.showEndInterviewButton = true;
-        
-        // 显示提示
-        uni.showToast({
-          title: `第${this.questionRound}轮提问完成`,
-          icon: 'none',
-          duration: 2000
-        });
-      } else {
-        // 如果已达到最大提问轮次,自动执行跳转逻辑
-        this.showContinueQuestionButton = false;
-        this.showEndInterviewButton = false;
-        
-        // 检查是否正在播放AI语音或上传视频
-        if (this.isPlayingAiVoice || this.isUploading) {
-          console.log('等待AI回复或上传完成后再跳转');
-          
-          // 设置一个标志,表示需要在AI回复和上传完成后跳转
-          this.pendingAutoNavigation = true;
-        } else {
-          // 如果没有正在进行的AI回复或上传,延迟3秒后自动跳转
-          setTimeout(() => {
-            this.navigateToNextPage();
-          }, 3000);
-        }
-      }
+      // 直接跳转到下一页,不再显示继续提问按钮
+      console.log('准备跳转到下一页面');
+      
+      // 延迟3秒后跳转,给用户一些时间查看状态
+      setTimeout(() => {
+        this.navigateToNextPage();
+      }, 3000);
       
       // 确保所有录制状态被重置
       this.isRecording = false;
@@ -3796,6 +4490,36 @@ export default {
       }
       
       return false;
+    },
+
+    // 修改文本回退方法
+    useIOSTextFallback() {
+      console.log('切换到文本显示模式');
+      
+      this.isPlayingAiVoice = false;
+      
+      if (!this.hasShownTextFallbackToast) {
+        this.hasShownTextFallbackToast = true;
+        uni.showToast({
+          title: '已切换为文字显示',
+          icon: 'none',
+          duration: 2000
+        });
+      }
+      
+      // 显示AI回复文本
+      this.currentSubtitle = this.aiText || '抱歉,无法获取AI回复内容';
+      
+      // 根据文本长度计算阅读时间
+      const textLength = this.aiText ? this.aiText.length : 20;
+      const readingTime = Math.max(8000, Math.min(textLength * 150, 20000)); // 最少8秒,最多20秒
+      
+      console.log(`文本长度: ${textLength}字,预计阅读时间: ${readingTime/1000}秒`);
+      
+      // 等待用户阅读完成后再跳转
+      setTimeout(() => {
+        this.navigateToNextPage();
+      }, readingTime);
     }
   }
 }

+ 8 - 9
unpackage/dist/dev/mp-weixin/pages/Personal/Personal.js

@@ -273,7 +273,7 @@ const _sfc_main = {
       }
       if (!isValid) {
         common_vendor.index.showToast({
-          title: "请完善所有必填信息",
+          title: "请完善家庭成员信息",
           icon: "none"
         });
         return;
@@ -398,7 +398,7 @@ const _sfc_main = {
       }
       if (!isValid) {
         common_vendor.index.showToast({
-          title: "请完善所有必填信息",
+          title: "请完善教育经历信息",
           icon: "none"
         });
         return;
@@ -516,6 +516,10 @@ const _sfc_main = {
         isValid = false;
       }
       if (!isValid) {
+        common_vendor.index.showToast({
+          title: "请完善工作经历信息",
+          icon: "none"
+        });
         return;
       }
       if (this.isEditingWork) {
@@ -918,7 +922,8 @@ const _sfc_main = {
           }
           break;
         case 3:
-          if (this.familyMembers.length === 0) {
+          console.log(this.familyMembers.length);
+          if (this.familyMembers.length == 0) {
             common_vendor.index.showToast({
               title: "请至少添加一位家庭成员",
               icon: "none"
@@ -955,12 +960,6 @@ const _sfc_main = {
           }
           break;
       }
-      if (!isValid) {
-        common_vendor.index.showToast({
-          title: "请完善所有必填信息",
-          icon: "none"
-        });
-      }
       return isValid;
     },
     // Add method to fetch user data

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/Personal/Personal.wxml


+ 19 - 0
unpackage/dist/dev/mp-weixin/pages/Personal/Personal.wxss

@@ -40,6 +40,8 @@
 		margin-right: 10rpx;
 		display: block;
 		margin-bottom: 10rpx;
+		position: relative;
+		padding-left: 14rpx;  /* 为星号预留空间 */
 }
 input {
 		font-size: 28rpx;
@@ -637,3 +639,20 @@ input {
 .form-item switch {
 		margin-top: 10rpx;
 }
+
+	/* 修改必填项标签的样式 */
+.label.required::before {
+	  content: '*';
+	  color: #ff4d4f;
+	  margin-right: 4rpx;
+	  position: absolute;
+	  left: 0;
+	  top: -4rpx;
+}
+
+	/* 修改必填项标签的样式 */
+	/* .label.required::after {
+	  content: '*';
+	  color: #ff4d4f;
+	  margin-left: 4rpx;
+	} */

+ 566 - 61
unpackage/dist/dev/mp-weixin/pages/interview-question/interview-question.js

@@ -144,14 +144,16 @@ const _sfc_main = {
       // 控制"结束面试"按钮显示
       questionRound: 0,
       // 当前提问轮次
-      maxQuestionRounds: 2,
+      maxQuestionRounds: 1,
       // 最大提问轮次(可配置)
       conversationHistory: [],
       // 对话历史记录
       pendingAutoNavigation: false,
       // 标记是否有待处理的自动跳转
-      hasTriedFallbackMethod: false
+      hasTriedFallbackMethod: false,
       // 标记是否尝试过备选方法播放音频
+      hasShownTextFallbackToast: false
+      // 标记是否已显示文本回退提示
     };
   },
   onLoad(options) {
@@ -1950,7 +1952,11 @@ const _sfc_main = {
             // 修改为JSON格式
           },
           success: (res) => {
-            this.handleAiInteractionResponse(res.data);
+            if (res.statusCode === 200) {
+              this.handleAiInteractionResponse(res.data);
+            } else {
+              this.handleAiInteractionError(res.data);
+            }
           },
           fail: (err) => {
             this.handleAiInteractionError(err);
@@ -1986,6 +1992,9 @@ const _sfc_main = {
     // 添加处理AI交互响应的方法
     handleAiInteractionResponse(data) {
       console.log("AI语音交互接口响应:", data);
+      const systemInfo = common_vendor.index.getSystemInfoSync();
+      const isIOS = systemInfo.platform === "ios";
+      this.isPlayingAiVoice = true;
       common_vendor.index.hideLoading();
       this.hasTriedFallbackMethod = false;
       if (data && data.success) {
@@ -2004,8 +2013,8 @@ const _sfc_main = {
           this.aiVoiceUrl = aiVoiceUrl.startsWith("http") ? aiVoiceUrl : `${common_config.apiBaseUrl}${aiVoiceUrl}`;
           console.log("AI语音URL:", this.aiVoiceUrl);
           this.currentSubtitle = this.aiText;
-          const systemInfo = common_vendor.index.getSystemInfoSync();
-          const isMiniProgram = systemInfo.uniPlatform && systemInfo.uniPlatform.startsWith("mp-");
+          const systemInfo2 = common_vendor.index.getSystemInfoSync();
+          const isMiniProgram = systemInfo2.uniPlatform && systemInfo2.uniPlatform.startsWith("mp-");
           const isUnsupportedFormat = this.checkUnsupportedAudioFormat(this.aiVoiceUrl);
           if (isUnsupportedFormat && isMiniProgram) {
             console.warn("检测到小程序不支持的音频格式,直接使用文本显示");
@@ -2013,7 +2022,11 @@ const _sfc_main = {
             return;
           }
           if (isMiniProgram) {
-            this.playMiniProgramAudio();
+            if (isIOS) {
+              this.playIOSMiniProgramAudio();
+            } else {
+              this.playMiniProgramAudio();
+            }
           } else {
             this.playAiVoice();
           }
@@ -2043,59 +2056,547 @@ const _sfc_main = {
     // 添加新方法:播放AI语音
     playAiVoice() {
       console.log("开始播放AI语音:", this.aiVoiceUrl);
+      this.hasShownTextFallbackToast = false;
       this.isPlayingAiVoice = true;
       this.showContinueQuestionButton = false;
       this.showEndInterviewButton = false;
+      this.currentSubtitle = this.aiText;
       if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
-        console.error("无效的音频URL");
-        this.handleAudioPlaybackFailure();
+        console.error("无效的音频URL,直接显示文本");
+        this.useTextFallbackAndNavigate();
         return;
       }
-      try {
-        if (this.aiAudioPlayer) {
+      const systemInfo = common_vendor.index.getSystemInfoSync();
+      const isMiniProgram = systemInfo.uniPlatform && systemInfo.uniPlatform.startsWith("mp-");
+      const isIOS = systemInfo.platform === "ios";
+      if (isMiniProgram) {
+        if (isIOS) {
+          this.playIOSMiniProgramAudio();
+        } else {
+          this.playMiniProgramAudio();
+        }
+      } else if (isIOS) {
+        this.playAiVoiceForIOS();
+      } else {
+        this.playAiVoiceForAndroid();
+      }
+    },
+    // 新增方法:文本回退并导航
+    useTextFallbackAndNavigate() {
+      console.log("使用文本回退并准备导航");
+      this.isPlayingAiVoice = false;
+      if (!this.hasShownTextFallbackToast) {
+        this.hasShownTextFallbackToast = true;
+        common_vendor.index.showToast({
+          title: "为您显示文字回复",
+          icon: "none",
+          duration: 2e3
+        });
+      }
+      this.currentSubtitle = this.aiText || "抱歉,AI回复内容加载失败";
+      setTimeout(() => {
+        this.navigateToNextPage();
+      }, 5e3);
+    },
+    // 修改 handleIOSAudioPlaybackComplete 方法
+    handleIOSAudioPlaybackComplete() {
+      this.isPlayingAiVoice = false;
+      setTimeout(() => {
+        this.currentSubtitle = "";
+      }, 1e3);
+      if (this.aiAudioPlayer) {
+        try {
           this.aiAudioPlayer.destroy();
+        } catch (e) {
+          console.error("销毁iOS音频播放器失败:", e);
         }
-        this.aiAudioPlayer = common_vendor.index.createInnerAudioContext();
-        this.aiAudioPlayer.autoplay = false;
-        this.aiAudioPlayer.obeyMuteSwitch = false;
-        this.aiAudioPlayer.onCanplay(() => {
-          console.log("音频已加载完成,准备播放");
-          const duration = this.aiAudioPlayer.duration;
-          console.log("音频时长:", duration);
-          this.aiAudioPlayer.play();
+        this.aiAudioPlayer = null;
+      }
+      this.navigateToNextPage();
+    },
+    // 修改 playMiniProgramAudio 方法
+    playMiniProgramAudio() {
+      console.log("使用小程序原生音频API播放:", this.aiVoiceUrl);
+      try {
+        const audioContext = common_vendor.wx$1.createInnerAudioContext();
+        audioContext.autoplay = true;
+        audioContext.src = this.aiVoiceUrl;
+        audioContext.onPlay(() => {
+          console.log("AI语音开始播放");
+          this.currentSubtitle = this.aiText;
         });
-        this.aiAudioPlayer.onTimeUpdate(() => {
-          const currentTime = this.aiAudioPlayer.currentTime;
-          const duration = this.aiAudioPlayer.duration;
-          console.log(`播放进度: ${currentTime}/${duration}`);
-          if (this.aiText) {
-            const textProgress = Math.floor(currentTime / duration * this.aiText.length);
-            this.currentSubtitle = this.aiText.substring(0, textProgress);
-          }
+        audioContext.onEnded(() => {
+          console.log("AI语音播放结束");
+          this.isPlayingAiVoice = false;
+          this.currentSubtitle = "";
+          audioContext.destroy();
+          this.navigateToNextPage();
         });
-        this.aiAudioPlayer.onEnded(() => {
-          console.log("AI语音播放完成");
+        audioContext.onError((err) => {
+          console.error("AI语音播放错误:", err);
+          audioContext.destroy();
+          this.useTextFallbackAndNavigate();
+        });
+        setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.warn("音频播放超时,使用文本回退");
+            this.useTextFallbackAndNavigate();
+          }
+        }, 5e3);
+      } catch (e) {
+        console.error("小程序播放AI语音失败:", e);
+        this.useTextFallbackAndNavigate();
+      }
+    },
+    // 新增方法:导航到下一页
+    navigateToNextPage() {
+      console.log("准备导航到下一页");
+      common_vendor.index.navigateTo({
+        url: "/pages/posture-guide/posture-guide",
+        fail: (err) => {
+          console.error("导航失败:", err);
+          common_vendor.index.showToast({
+            title: "页面跳转失败",
+            icon: "none",
+            duration: 2e3
+          });
+        }
+      });
+    },
+    // 新增方法:专门处理iOS小程序音频播放
+    playIOSMiniProgramAudio() {
+      console.log("iOS小程序环境:使用增强的音频处理方法");
+      this.hasShownTextFallbackToast = false;
+      try {
+        const audioContext = common_vendor.wx$1.createInnerAudioContext();
+        audioContext.autoplay = false;
+        audioContext.obeyMuteSwitch = true;
+        audioContext.volume = 1;
+        audioContext.onPlay(() => {
+          console.log("iOS小程序音频开始播放");
           this.currentSubtitle = this.aiText;
-          setTimeout(() => {
-            this.isPlayingAiVoice = false;
-            this.currentSubtitle = "";
-            if (this.aiAudioPlayer) {
-              this.aiAudioPlayer.destroy();
-              this.aiAudioPlayer = null;
+          common_vendor.index.showToast({
+            title: "正在播放AI回复",
+            icon: "none",
+            duration: 1500
+          });
+        });
+        audioContext.onEnded(() => {
+          console.log("iOS小程序音频播放结束");
+          this.handleIOSAudioComplete(audioContext);
+        });
+        audioContext.onStop(() => {
+          console.log("iOS小程序音频播放停止");
+          this.handleIOSAudioComplete(audioContext);
+        });
+        audioContext.onError((err) => {
+          console.error("iOS小程序音频播放错误:", err);
+          this.handleIOSMiniProgramError(audioContext, err);
+        });
+        this.preloadIOSMiniProgramAudio(this.aiVoiceUrl).then((localPath) => {
+          console.log("iOS小程序音频预下载成功:", localPath);
+          audioContext.src = localPath;
+          audioContext.play();
+        }).catch((error) => {
+          console.error("iOS小程序音频预下载失败:", error);
+          this.fallbackIOSMiniProgramPlay(audioContext);
+        });
+      } catch (e) {
+        console.error("iOS小程序音频初始化失败:", e);
+        this.useIOSTextFallback();
+      }
+    },
+    // 新增方法:iOS小程序音频预下载
+    preloadIOSMiniProgramAudio(audioUrl) {
+      return new Promise((resolve, reject) => {
+        console.log("开始预下载iOS小程序音频:", audioUrl);
+        common_vendor.index.downloadFile({
+          url: audioUrl,
+          timeout: 15e3,
+          // 15秒超时
+          success: (res) => {
+            if (res.statusCode === 200) {
+              console.log("iOS小程序音频下载成功:", res.tempFilePath);
+              resolve(res.tempFilePath);
+            } else {
+              console.error("iOS小程序音频下载失败,状态码:", res.statusCode);
+              reject(new Error(`下载失败,状态码: ${res.statusCode}`));
             }
-            this.showContinueQuestionOptions();
-            this.checkPendingNavigation();
-          }, 2e3);
+          },
+          fail: (err) => {
+            console.error("iOS小程序音频下载请求失败:", err);
+            reject(err);
+          }
+        });
+      });
+    },
+    // 新增方法:iOS小程序错误处理
+    handleIOSMiniProgramError(audioContext, error) {
+      console.error("处理iOS小程序音频错误:", error);
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error("销毁音频播放器失败:", e);
+        }
+      }
+      let errorMessage = "音频播放异常,显示文字";
+      if (error.errMsg && error.errMsg.includes("-11850")) {
+        console.log("iOS小程序检测到系统音频错误(-11850)");
+        errorMessage = "系统音频服务暂停,显示文字";
+      } else if (error.errCode === 10002) {
+        console.log("iOS小程序检测到errCode:10002,网络或资源问题");
+        errorMessage = "音频加载中断,显示文字";
+      } else if (error.errCode === 10001) {
+        console.log("iOS小程序检测到errCode:10001,系统错误");
+        errorMessage = "系统音频错误,显示文字";
+      } else if (error.errCode === 10003) {
+        console.log("iOS小程序检测到errCode:10003,文件错误");
+        errorMessage = "音频文件错误,显示文字";
+      } else if (error.errCode === 10004) {
+        console.log("iOS小程序检测到errCode:10004,格式不支持");
+        errorMessage = "音频格式不支持,显示文字";
+      }
+      common_vendor.index.showToast({
+        title: errorMessage,
+        icon: "none",
+        duration: 2e3
+      });
+      this.useIOSTextFallback();
+    },
+    // 新增方法:iOS小程序播放超时处理
+    handleIOSPlaybackTimeout(audioContext) {
+      console.log("iOS小程序音频播放超时处理");
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error("销毁超时音频播放器失败:", e);
+        }
+      }
+      common_vendor.index.showToast({
+        title: "音频加载超时,显示文字",
+        icon: "none",
+        duration: 2e3
+      });
+      this.useIOSTextFallback();
+    },
+    // 新增方法:iOS小程序备选播放方法
+    fallbackIOSMiniProgramPlay(audioContext) {
+      console.log("iOS小程序使用备选播放方法");
+      try {
+        audioContext.src = this.aiVoiceUrl;
+        const fallbackTimeout = setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.log("iOS小程序备选方法也超时");
+            clearTimeout(fallbackTimeout);
+            this.handleIOSPlaybackTimeout(audioContext);
+          }
+        }, 3e3);
+        audioContext.play();
+      } catch (e) {
+        console.error("iOS小程序备选播放方法失败:", e);
+        this.handleIOSPlaybackTimeout(audioContext);
+      }
+    },
+    // 新增方法:统一的iOS音频完成处理
+    handleIOSAudioComplete(audioContext) {
+      console.log("iOS音频播放完成");
+      this.isPlayingAiVoice = false;
+      setTimeout(() => {
+        this.currentSubtitle = "";
+      }, 2e3);
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error("销毁iOS音频播放器失败:", e);
+        }
+      }
+      this.showContinueQuestionOptions();
+      this.checkPendingNavigation();
+    },
+    // 移除原来的 playMiniProgramAudioForIOS 方法,因为已经被新的 playIOSMiniProgramAudio 替代
+    // playMiniProgramAudioForIOS() 方法可以删除或注释掉
+    // 保留原有的 useIOSTextFallback 方法,但确保它能正确处理所有iOS场景
+    useIOSTextFallback() {
+      console.log("iOS使用文本回退方案");
+      this.isPlayingAiVoice = false;
+      if (!this.hasShownTextFallbackToast) {
+        this.hasShownTextFallbackToast = true;
+        common_vendor.index.showToast({
+          title: "为您显示文字回复",
+          icon: "none",
+          duration: 2e3
+        });
+      }
+      this.currentSubtitle = this.aiText || "抱歉,AI回复内容加载失败";
+      const textLength = this.aiText ? this.aiText.length : 20;
+      const readingTime = Math.max(5e3, Math.min(textLength * 100, 15e3));
+      console.log(`文本长度: ${textLength}, 预计阅读时间: ${readingTime}ms`);
+      setTimeout(() => {
+        this.handleIOSAudioComplete(null);
+      }, readingTime);
+    },
+    // 添加新方法:iOS音频播放完成处理
+    handleIOSAudioPlaybackComplete() {
+      this.isPlayingAiVoice = false;
+      setTimeout(() => {
+        this.currentSubtitle = "";
+      }, 2e3);
+      if (this.aiAudioPlayer) {
+        try {
+          this.aiAudioPlayer.destroy();
+        } catch (e) {
+          console.error("销毁iOS音频播放器失败:", e);
+        }
+        this.aiAudioPlayer = null;
+      }
+      this.showContinueQuestionOptions();
+      this.checkPendingNavigation();
+    },
+    // 添加新方法:iOS音频错误处理
+    handleIOSAudioError(error) {
+      console.error("iOS音频播放错误:", error);
+      switch (error.errCode) {
+        case 10001:
+          console.log("iOS音频系统错误,尝试重新播放");
+          this.retryIOSAudioPlay();
+          break;
+        case 10002:
+          console.log("iOS音频网络错误,使用备选方案");
+          this.handleIOS10002Error();
+          break;
+        case 10003:
+          console.log("iOS音频文件错误,使用文本回退");
+          this.useIOSTextFallback();
+          break;
+        case 10004:
+          console.log("iOS音频格式不支持,使用文本回退");
+          this.useIOSTextFallback();
+          break;
+        default:
+          console.log("iOS音频未知错误,使用文本回退");
+          this.useIOSTextFallback();
+          break;
+      }
+    },
+    // 添加新方法:重试iOS音频播放
+    retryIOSAudioPlay() {
+      console.log("重试iOS音频播放");
+      if (this.aiAudioPlayer) {
+        try {
+          this.aiAudioPlayer.destroy();
+        } catch (e) {
+          console.error("销毁播放器失败:", e);
+        }
+        this.aiAudioPlayer = null;
+      }
+      setTimeout(() => {
+        this.fallbackIOSAudioPlay();
+      }, 1e3);
+    },
+    // 添加新方法:iOS备选音频播放
+    fallbackIOSAudioPlay() {
+      console.log("iOS备选音频播放方案");
+      try {
+        this.aiAudioPlayer = common_vendor.index.createInnerAudioContext();
+        this.aiAudioPlayer.autoplay = true;
+        this.aiAudioPlayer.obeyMuteSwitch = true;
+        this.aiAudioPlayer.volume = 0.8;
+        this.aiAudioPlayer.src = this.aiVoiceUrl;
+        this.aiAudioPlayer.onPlay(() => {
+          console.log("iOS备选方案:音频开始播放");
+          this.currentSubtitle = this.aiText;
+        });
+        this.aiAudioPlayer.onEnded(() => {
+          console.log("iOS备选方案:音频播放结束");
+          this.handleIOSAudioPlaybackComplete();
         });
         this.aiAudioPlayer.onError((err) => {
+          console.error("iOS备选方案:音频播放错误:", err);
+          this.useIOSTextFallback();
+        });
+        setTimeout(() => {
+          if (this.isPlayingAiVoice && this.aiAudioPlayer) {
+            console.log("iOS音频播放超时,使用文本回退");
+            this.useIOSTextFallback();
+          }
+        }, 5e3);
+      } catch (e) {
+        console.error("iOS备选音频播放失败:", e);
+        this.useIOSTextFallback();
+      }
+    },
+    // 修改 playMiniProgramAudio 方法,添加iOS特殊处理
+    playMiniProgramAudio() {
+      console.log("使用小程序原生音频API播放:", this.aiVoiceUrl);
+      this.isPlayingAiVoice = true;
+      this.showContinueQuestionButton = false;
+      this.showEndInterviewButton = false;
+      if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
+        console.error("无效的音频URL");
+        this.handleAudioPlaybackFailure();
+        return;
+      }
+      const systemInfo = common_vendor.index.getSystemInfoSync();
+      const isIOS = systemInfo.platform === "ios";
+      if (isIOS) {
+        this.playMiniProgramAudioForIOS();
+        return;
+      }
+      try {
+        const audioContext = common_vendor.wx$1.createInnerAudioContext();
+        audioContext.autoplay = false;
+        audioContext.obeyMuteSwitch = false;
+        audioContext.onPlay(() => {
+          console.log("AI语音开始播放");
+          common_vendor.index.showToast({
+            title: "正在播放AI回复",
+            icon: "none",
+            duration: 2e3
+          });
+        });
+        audioContext.onEnded(() => {
+          console.log("AI语音播放结束");
+          this.isPlayingAiVoice = false;
+          this.currentSubtitle = "";
+          audioContext.destroy();
+          this.showContinueQuestionOptions();
+        });
+        audioContext.onError((err) => {
           console.error("AI语音播放错误:", err);
-          this.handleAudioPlaybackError(err);
+          this.isPlayingAiVoice = false;
+          this.currentSubtitle = "";
+          audioContext.destroy();
+          this.showContinueQuestionOptions();
         });
-        this.aiAudioPlayer.src = this.aiVoiceUrl;
+        audioContext.src = this.aiVoiceUrl;
+        const playTimeout = setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.warn("小程序音频播放超时,尝试备选方法");
+            this.tryMiniProgramFallbackAudioPlay();
+          }
+        }, 5e3);
+        setTimeout(() => {
+          audioContext.play();
+          clearTimeout(playTimeout);
+        }, 300);
       } catch (e) {
-        console.error("播放AI语音时发生错误:", e);
-        this.handleAudioPlaybackError(e);
+        console.error("小程序播放AI语音时发生错误:", e);
+        this.isPlayingAiVoice = false;
+        common_vendor.index.showToast({
+          title: "音频播放失败,请查看文字回复",
+          icon: "none",
+          duration: 2e3
+        });
+        this.handleAudioPlaybackFailure();
+      }
+    },
+    // 添加新方法:iOS小程序音频播放
+    playMiniProgramAudioForIOS() {
+      console.log("iOS小程序环境:开始播放AI语音");
+      this.hasShownTextFallbackToast = false;
+      try {
+        const audioContext = common_vendor.wx$1.createInnerAudioContext();
+        audioContext.autoplay = false;
+        audioContext.obeyMuteSwitch = true;
+        audioContext.volume = 1;
+        audioContext.onError((err) => {
+          console.error("iOS小程序音频播放错误:", err);
+          if (err.errMsg && err.errMsg.includes("-11850")) {
+            console.log("iOS小程序检测到系统音频错误(-11850)");
+            common_vendor.index.showToast({
+              title: "系统音频暂停,显示文字",
+              icon: "none",
+              duration: 2e3
+            });
+          } else if (err.errCode === 10002) {
+            console.log("iOS小程序检测到errCode:10002,网络或资源问题");
+            common_vendor.index.showToast({
+              title: "音频加载中断,显示文字",
+              icon: "none",
+              duration: 2e3
+            });
+          } else {
+            console.log("iOS小程序其他音频错误:", err.errCode);
+            common_vendor.index.showToast({
+              title: "音频播放异常,显示文字",
+              icon: "none",
+              duration: 2e3
+            });
+          }
+          this.useIOSMiniProgramTextFallback(audioContext);
+        });
+        audioContext.src = this.aiVoiceUrl;
+        audioContext.onPlay(() => {
+          console.log("iOS小程序音频开始播放");
+          this.currentSubtitle = this.aiText;
+          common_vendor.index.showToast({
+            title: "正在播放AI回复",
+            icon: "none",
+            duration: 1500
+          });
+        });
+        audioContext.onEnded(() => {
+          console.log("iOS小程序音频播放结束");
+          this.handleIOSMiniProgramAudioComplete(audioContext);
+        });
+        const playTimeout = setTimeout(() => {
+          if (this.isPlayingAiVoice) {
+            console.log("iOS小程序音频播放超时,切换到文本显示");
+            clearTimeout(playTimeout);
+            this.useIOSMiniProgramTextFallback(audioContext);
+          }
+        }, 3e3);
+        audioContext.play();
+      } catch (e) {
+        console.error("iOS小程序音频播放初始化失败:", e);
+        this.handleAudioPlaybackFailure();
+      }
+    },
+    // 添加新方法:iOS小程序音频播放完成
+    handleIOSMiniProgramAudioComplete(audioContext) {
+      this.isPlayingAiVoice = false;
+      setTimeout(() => {
+        this.currentSubtitle = "";
+      }, 2e3);
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error("销毁iOS小程序音频播放器失败:", e);
+        }
       }
+      this.showContinueQuestionOptions();
+      this.checkPendingNavigation();
+    },
+    // 添加新方法:iOS小程序音频错误处理
+    handleIOSMiniProgramAudioError(audioContext, error) {
+      console.error("iOS小程序音频错误:", error);
+      if (error.errCode === 10002) {
+        this.useIOSMiniProgramTextFallback(audioContext);
+      } else {
+        this.useIOSMiniProgramTextFallback(audioContext);
+      }
+    },
+    // 添加新方法:iOS小程序文本回退
+    useIOSMiniProgramTextFallback(audioContext) {
+      console.log("iOS小程序使用文本回退方案");
+      if (audioContext) {
+        try {
+          audioContext.destroy();
+        } catch (e) {
+          console.error("销毁音频播放器失败:", e);
+        }
+      }
+      this.isPlayingAiVoice = false;
+      this.currentSubtitle = this.aiText || "抱歉,AI回复内容加载失败";
+      const textLength = this.aiText ? this.aiText.length : 20;
+      const readingTime = Math.max(6e3, Math.min(textLength * 120, 18e3));
+      setTimeout(() => {
+        this.handleIOSMiniProgramAudioComplete(null);
+      }, readingTime);
     },
     // 添加新方法:处理音频播放错误
     handleAudioPlaybackError(error) {
@@ -2424,26 +2925,10 @@ const _sfc_main = {
       }
       this.questionRound++;
       this.currentSubtitle = "";
-      if (this.questionRound < this.maxQuestionRounds) {
-        this.showContinueQuestionButton = true;
-        this.showEndInterviewButton = true;
-        common_vendor.index.showToast({
-          title: `第${this.questionRound}轮提问完成`,
-          icon: "none",
-          duration: 2e3
-        });
-      } else {
-        this.showContinueQuestionButton = false;
-        this.showEndInterviewButton = false;
-        if (this.isPlayingAiVoice || this.isUploading) {
-          console.log("等待AI回复或上传完成后再跳转");
-          this.pendingAutoNavigation = true;
-        } else {
-          setTimeout(() => {
-            this.navigateToNextPage();
-          }, 3e3);
-        }
-      }
+      console.log("准备跳转到下一页面");
+      setTimeout(() => {
+        this.navigateToNextPage();
+      }, 3e3);
       this.isRecording = false;
       if (this.recordingTimer) {
         clearInterval(this.recordingTimer);
@@ -2558,6 +3043,26 @@ const _sfc_main = {
         return unsupportedFormats.includes(extension);
       }
       return false;
+    },
+    // 修改文本回退方法
+    useIOSTextFallback() {
+      console.log("切换到文本显示模式");
+      this.isPlayingAiVoice = false;
+      if (!this.hasShownTextFallbackToast) {
+        this.hasShownTextFallbackToast = true;
+        common_vendor.index.showToast({
+          title: "已切换为文字显示",
+          icon: "none",
+          duration: 2e3
+        });
+      }
+      this.currentSubtitle = this.aiText || "抱歉,无法获取AI回复内容";
+      const textLength = this.aiText ? this.aiText.length : 20;
+      const readingTime = Math.max(8e3, Math.min(textLength * 150, 2e4));
+      console.log(`文本长度: ${textLength}字,预计阅读时间: ${readingTime / 1e3}秒`);
+      setTimeout(() => {
+        this.navigateToNextPage();
+      }, readingTime);
     }
   }
 };

+ 1 - 1
unpackage/dist/dev/mp-weixin/project.config.json

@@ -18,7 +18,7 @@
     }
   },
   "compileType": "miniprogram",
-  "libVersion": "3.7.11",
+  "libVersion": "3.8.7",
   "appid": "wxc9655eeaa3223b75",
   "projectname": "interview_uni",
   "condition": {

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно