|  |  | @ -191,6 +191,7 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | touchStartTime: 0, // 触摸开始时间 | 
			
		
	
		
			
				
					|  |  |  | touchStartY: 0, // 触摸开始Y坐标 | 
			
		
	
		
			
				
					|  |  |  | userScrollTimer: null, // 用户滚动检测定时器 | 
			
		
	
		
			
				
					|  |  |  | lastUserScrollTime: 0, // 最后一次用户滚动时间 | 
			
		
	
		
			
				
					|  |  |  | courseIdList: [], | 
			
		
	
		
			
				
					|  |  |  | bookTitle: '', | 
			
		
	
		
			
				
					|  |  |  | courseList: [ | 
			
		
	
	
		
			
				
					|  |  | @ -322,6 +323,9 @@ export default { | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 如果移动距离超过阈值,认为是滚动操作 | 
			
		
	
		
			
				
					|  |  |  | if (deltaY > 10) { | 
			
		
	
		
			
				
					|  |  |  | // 记录用户滚动时间 | 
			
		
	
		
			
				
					|  |  |  | this.lastUserScrollTime = Date.now(); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 如果当前正在自动滚动,立即停止 | 
			
		
	
		
			
				
					|  |  |  | if (this.isScrolling) { | 
			
		
	
		
			
				
					|  |  |  | console.log('🛑 检测到用户手动滚动,停止自动滚动'); | 
			
		
	
	
		
			
				
					|  |  | @ -345,14 +349,17 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | this.userScrollTimer = setTimeout(() => { | 
			
		
	
		
			
				
					|  |  |  | console.log('✋ 用户滚动操作结束,允许自动滚动'); | 
			
		
	
		
			
				
					|  |  |  | this.userScrollTimer = null; | 
			
		
	
		
			
				
					|  |  |  | }, 1000); // 1秒后允许自动滚动 | 
			
		
	
		
			
				
					|  |  |  | }, 500); // 减少到500ms,提高响应性 | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | console.log('👆 用户停止触摸屏幕'); | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 检查是否应该阻止自动滚动 | 
			
		
	
		
			
				
					|  |  |  | shouldPreventAutoScroll() { | 
			
		
	
		
			
				
					|  |  |  | return this.isUserTouching || this.userScrollTimer !== null; | 
			
		
	
		
			
				
					|  |  |  | // 降低敏感度:只有在用户正在触摸且最近有滚动行为时才阻止 | 
			
		
	
		
			
				
					|  |  |  | const now = Date.now(); | 
			
		
	
		
			
				
					|  |  |  | const recentUserScroll = this.userScrollTimer !== null && (now - this.lastUserScrollTime) < 1000; | 
			
		
	
		
			
				
					|  |  |  | return this.isUserTouching && recentUserScroll; | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 处理scroll-view滚动事件 | 
			
		
	
	
		
			
				
					|  |  | @ -368,9 +375,10 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | if (this.isScrolling) { | 
			
		
	
		
			
				
					|  |  |  | // 如果滚动差异很大,可能是用户手动滚动,中断自动滚动状态 | 
			
		
	
		
			
				
					|  |  |  | const scrollDifference = Math.abs(previousScrollTop - scrollTop); | 
			
		
	
		
			
				
					|  |  |  | if (scrollDifference > 100) { // 大幅度滚动,很可能是手动操作 | 
			
		
	
		
			
				
					|  |  |  | if (scrollDifference > 50) { // 调整阈值,避免误判 | 
			
		
	
		
			
				
					|  |  |  | console.log('🖐️ 检测到手动滚动,中断自动滚动状态'); | 
			
		
	
		
			
				
					|  |  |  | this.isScrolling = false; | 
			
		
	
		
			
				
					|  |  |  | this.lastUserScrollTime = Date.now(); // 记录手动滚动时间 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
	
		
			
				
					|  |  | @ -728,6 +736,8 @@ export default { | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 处理滚动到高亮文本 | 
			
		
	
		
			
				
					|  |  |  | onScrollToText(scrollData) { | 
			
		
	
		
			
				
					|  |  |  | console.log('📍 收到滚动请求:', scrollData); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 检查是否应该阻止自动滚动(用户正在手动操作) | 
			
		
	
		
			
				
					|  |  |  | if (this.shouldPreventAutoScroll()) { | 
			
		
	
		
			
				
					|  |  |  | console.log('🚫 用户正在手动滚动,跳过自动滚动到文本'); | 
			
		
	
	
		
			
				
					|  |  | @ -746,7 +756,7 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | this.performScrollToText(scrollData); | 
			
		
	
		
			
				
					|  |  |  | }, 100); // 100ms防抖延迟 | 
			
		
	
		
			
				
					|  |  |  | }, 50); // 减少防抖延迟,提高响应性 | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 执行滚动到高亮文本的具体逻辑 | 
			
		
	
	
		
			
				
					|  |  | @ -817,7 +827,52 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | this.isScrolling = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 等待DOM更新后再查找元素 | 
			
		
	
		
			
				
					|  |  |  | this.$nextTick(() => { | 
			
		
	
		
			
				
					|  |  |  | this.$nextTick(async () => { | 
			
		
	
		
			
				
					|  |  |  | try { | 
			
		
	
		
			
				
					|  |  |  | // 获取所有元素的真实位置信息 | 
			
		
	
		
			
				
					|  |  |  | const elementPositions = await this.getAllElementPositions(); | 
			
		
	
		
			
				
					|  |  |  | console.log('📏 获取到的元素位置信息:', elementPositions); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 计算精确的滚动位置 | 
			
		
	
		
			
				
					|  |  |  | const preciseScrollTop = await this.calculatePreciseScrollPosition(scrollData, elementPositions); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if (preciseScrollTop !== null) { | 
			
		
	
		
			
				
					|  |  |  | // 检查是否需要滚动(避免不必要的滚动) | 
			
		
	
		
			
				
					|  |  |  | const currentScroll = this.scrollTops[this.currentPage - 1] || 0; | 
			
		
	
		
			
				
					|  |  |  | const scrollDifference = Math.abs(preciseScrollTop - currentScroll); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if (scrollDifference > 20) { | 
			
		
	
		
			
				
					|  |  |  | this.$set(this.scrollTops, this.currentPage - 1, preciseScrollTop); | 
			
		
	
		
			
				
					|  |  |  | console.log('✅ 使用精确位置滚动:', { | 
			
		
	
		
			
				
					|  |  |  | selector, | 
			
		
	
		
			
				
					|  |  |  | preciseScrollTop, | 
			
		
	
		
			
				
					|  |  |  | currentPage: this.currentPage, | 
			
		
	
		
			
				
					|  |  |  | scrollDifference | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 滚动完成后重置状态 | 
			
		
	
		
			
				
					|  |  |  | setTimeout(() => { | 
			
		
	
		
			
				
					|  |  |  | resetScrollingState(); | 
			
		
	
		
			
				
					|  |  |  | }, 200); | 
			
		
	
		
			
				
					|  |  |  | } else { | 
			
		
	
		
			
				
					|  |  |  | resetScrollingState(); | 
			
		
	
		
			
				
					|  |  |  | console.log('📍 目标已在视野内,无需滚动'); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } else { | 
			
		
	
		
			
				
					|  |  |  | // 精确计算失败,使用原有的查询方法作为备用 | 
			
		
	
		
			
				
					|  |  |  | console.log('🔄 精确计算失败,使用备用查询方法'); | 
			
		
	
		
			
				
					|  |  |  | this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } catch (error) { | 
			
		
	
		
			
				
					|  |  |  | console.error('❌ 精确滚动计算失败:', error); | 
			
		
	
		
			
				
					|  |  |  | // 使用原有的查询方法作为备用 | 
			
		
	
		
			
				
					|  |  |  | this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 备用滚动方法(原有的查询方式) | 
			
		
	
		
			
				
					|  |  |  | fallbackScrollToText(selector, resetScrollingState, safetyTimeout) { | 
			
		
	
		
			
				
					|  |  |  | // 使用uni.createSelectorQuery获取元素位置 | 
			
		
	
		
			
				
					|  |  |  | const query = uni.createSelectorQuery().in(this); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
	
		
			
				
					|  |  | @ -855,13 +910,13 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | const currentScroll = this.scrollTops[this.currentPage - 1] || 0; | 
			
		
	
		
			
				
					|  |  |  | const scrollDifference = Math.abs(finalScrollTop - currentScroll); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if (scrollDifference > 30) { // 降低滚动阈值,提高响应性 | 
			
		
	
		
			
				
					|  |  |  | if (scrollDifference > 20) { // 进一步降低滚动阈值,提高响应性 | 
			
		
	
		
			
				
					|  |  |  | this.$set(this.scrollTops, this.currentPage - 1, finalScrollTop); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 滚动完成后重置状态 | 
			
		
	
		
			
				
					|  |  |  | setTimeout(() => { | 
			
		
	
		
			
				
					|  |  |  | resetScrollingState(); | 
			
		
	
		
			
				
					|  |  |  | }, 300); // 稍微减少等待时间 | 
			
		
	
		
			
				
					|  |  |  | }, 200); // 减少等待时间 | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | console.log('✅ 滚动到高亮文本:', { | 
			
		
	
		
			
				
					|  |  |  | selector, | 
			
		
	
	
		
			
				
					|  |  | @ -887,18 +942,18 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | // 尝试备用方案:直接滚动到页面顶部附近 | 
			
		
	
		
			
				
					|  |  |  | if (!targetRect) { | 
			
		
	
		
			
				
					|  |  |  | console.log('🔄 尝试备用滚动方案'); | 
			
		
	
		
			
				
					|  |  |  | const fallbackScrollTop = scrollData.highlightIndex * 100; // 简单估算位置 | 
			
		
	
		
			
				
					|  |  |  | this.$set(this.scrollTops, this.currentPage - 1, fallbackScrollTop); | 
			
		
	
		
			
				
					|  |  |  | // 改进备用方案:基于highlightIndex计算更准确的位置 | 
			
		
	
		
			
				
					|  |  |  | const estimatedPosition = this.calculateEstimatedScrollPosition(scrollData.highlightIndex); | 
			
		
	
		
			
				
					|  |  |  | this.$set(this.scrollTops, this.currentPage - 1, estimatedPosition); | 
			
		
	
		
			
				
					|  |  |  | setTimeout(() => { | 
			
		
	
		
			
				
					|  |  |  | resetScrollingState(); | 
			
		
	
		
			
				
					|  |  |  | }, 300); | 
			
		
	
		
			
				
					|  |  |  | }, 200); | 
			
		
	
		
			
				
					|  |  |  | } else { | 
			
		
	
		
			
				
					|  |  |  | // 立即重置状态 | 
			
		
	
		
			
				
					|  |  |  | resetScrollingState(); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 查找文本元素在页面中的实际索引 | 
			
		
	
	
		
			
				
					|  |  | @ -922,6 +977,141 @@ export default { | 
			
		
	
		
			
				
					|  |  |  | return -1; // 未找到 | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 获取所有页面元素的位置信息 | 
			
		
	
		
			
				
					|  |  |  | async getAllElementPositions() { | 
			
		
	
		
			
				
					|  |  |  | return new Promise((resolve) => { | 
			
		
	
		
			
				
					|  |  |  | const currentPageData = this.bookPages[this.currentPage - 1]; | 
			
		
	
		
			
				
					|  |  |  | if (!currentPageData || !Array.isArray(currentPageData)) { | 
			
		
	
		
			
				
					|  |  |  | resolve([]); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | const query = uni.createSelectorQuery().in(this); | 
			
		
	
		
			
				
					|  |  |  | const elementPositions = []; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 获取scroll-container的位置作为基准 | 
			
		
	
		
			
				
					|  |  |  | query.select('.scroll-container').boundingClientRect(); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 为每个元素添加查询 | 
			
		
	
		
			
				
					|  |  |  | currentPageData.forEach((item, index) => { | 
			
		
	
		
			
				
					|  |  |  | if (item && (item.type === 'text' || item.type === 'image' || item.type === 'video')) { | 
			
		
	
		
			
				
					|  |  |  | if (item.type === 'text') { | 
			
		
	
		
			
				
					|  |  |  | query.select(`#text-${index}`).boundingClientRect(); | 
			
		
	
		
			
				
					|  |  |  | } else if (item.type === 'image') { | 
			
		
	
		
			
				
					|  |  |  | query.select(`.image-container`).boundingClientRect(); | 
			
		
	
		
			
				
					|  |  |  | } else if (item.type === 'video') { | 
			
		
	
		
			
				
					|  |  |  | query.select(`.video-content`).boundingClientRect(); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | query.exec((res) => { | 
			
		
	
		
			
				
					|  |  |  | const containerRect = res[0]; | 
			
		
	
		
			
				
					|  |  |  | if (!containerRect) { | 
			
		
	
		
			
				
					|  |  |  | resolve([]); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 处理查询结果 | 
			
		
	
		
			
				
					|  |  |  | let resultIndex = 1; // 跳过第一个容器结果 | 
			
		
	
		
			
				
					|  |  |  | currentPageData.forEach((item, index) => { | 
			
		
	
		
			
				
					|  |  |  | if (item && (item.type === 'text' || item.type === 'image' || item.type === 'video')) { | 
			
		
	
		
			
				
					|  |  |  | const elementRect = res[resultIndex]; | 
			
		
	
		
			
				
					|  |  |  | if (elementRect) { | 
			
		
	
		
			
				
					|  |  |  | elementPositions.push({ | 
			
		
	
		
			
				
					|  |  |  | index: index, | 
			
		
	
		
			
				
					|  |  |  | type: item.type, | 
			
		
	
		
			
				
					|  |  |  | top: elementRect.top - containerRect.top, | 
			
		
	
		
			
				
					|  |  |  | height: elementRect.height, | 
			
		
	
		
			
				
					|  |  |  | bottom: elementRect.top - containerRect.top + elementRect.height | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | resultIndex++; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | resolve(elementPositions); | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 计算精确的滚动位置 | 
			
		
	
		
			
				
					|  |  |  | async calculatePreciseScrollPosition(scrollData, elementPositions) { | 
			
		
	
		
			
				
					|  |  |  | if (!elementPositions || elementPositions.length === 0) { | 
			
		
	
		
			
				
					|  |  |  | return null; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | let targetElementIndex = -1; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if (scrollData.segmentIndex !== undefined) { | 
			
		
	
		
			
				
					|  |  |  | // 分段音频情况 | 
			
		
	
		
			
				
					|  |  |  | targetElementIndex = scrollData.segmentIndex; | 
			
		
	
		
			
				
					|  |  |  | } else if (scrollData.highlightIndex !== undefined) { | 
			
		
	
		
			
				
					|  |  |  | // 普通音频情况,需要找到对应的文本元素 | 
			
		
	
		
			
				
					|  |  |  | targetElementIndex = this.findTextItemIndex(scrollData.highlightIndex); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if (targetElementIndex === -1) { | 
			
		
	
		
			
				
					|  |  |  | return null; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 查找目标元素的位置信息 | 
			
		
	
		
			
				
					|  |  |  | const targetElement = elementPositions.find(pos => pos.index === targetElementIndex && pos.type === 'text'); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if (!targetElement) { | 
			
		
	
		
			
				
					|  |  |  | console.warn('未找到目标元素位置信息:', targetElementIndex); | 
			
		
	
		
			
				
					|  |  |  | return null; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 计算滚动位置:让目标元素显示在屏幕上方1/4处 | 
			
		
	
		
			
				
					|  |  |  | const screenHeight = uni.getSystemInfoSync().windowHeight; | 
			
		
	
		
			
				
					|  |  |  | const offsetFromTop = screenHeight * 0.25; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 目标滚动位置 = 目标元素顶部位置 - 偏移量 | 
			
		
	
		
			
				
					|  |  |  | const targetScrollTop = Math.max(0, targetElement.top - offsetFromTop); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | console.log('🎯 精确滚动位置计算:', { | 
			
		
	
		
			
				
					|  |  |  | targetElementIndex, | 
			
		
	
		
			
				
					|  |  |  | targetElement, | 
			
		
	
		
			
				
					|  |  |  | screenHeight, | 
			
		
	
		
			
				
					|  |  |  | offsetFromTop, | 
			
		
	
		
			
				
					|  |  |  | targetScrollTop | 
			
		
	
		
			
				
					|  |  |  | }); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | return targetScrollTop; | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 计算估算的滚动位置(备用方案) | 
			
		
	
		
			
				
					|  |  |  | calculateEstimatedScrollPosition(highlightIndex) { | 
			
		
	
		
			
				
					|  |  |  | const currentPageData = this.bookPages[this.currentPage - 1]; | 
			
		
	
		
			
				
					|  |  |  | if (!currentPageData || !Array.isArray(currentPageData)) { | 
			
		
	
		
			
				
					|  |  |  | return highlightIndex * 80; // 基础估算 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 基于页面内容计算更准确的位置 | 
			
		
	
		
			
				
					|  |  |  | let estimatedHeight = 0; | 
			
		
	
		
			
				
					|  |  |  | let textCount = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | for (let i = 0; i < currentPageData.length && textCount <= highlightIndex; i++) { | 
			
		
	
		
			
				
					|  |  |  | const item = currentPageData[i]; | 
			
		
	
		
			
				
					|  |  |  | if (item && item.type === 'text' && item.content) { | 
			
		
	
		
			
				
					|  |  |  | if (textCount === highlightIndex) { | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | // 根据内容长度估算高度 | 
			
		
	
		
			
				
					|  |  |  | const contentLength = item.content.length; | 
			
		
	
		
			
				
					|  |  |  | estimatedHeight += Math.max(60, contentLength * 1.2); // 基础高度 + 内容长度因子 | 
			
		
	
		
			
				
					|  |  |  | textCount++; | 
			
		
	
		
			
				
					|  |  |  | } else if (item && item.type === 'image') { | 
			
		
	
		
			
				
					|  |  |  | estimatedHeight += 200; // 图片估算高度 | 
			
		
	
		
			
				
					|  |  |  | } else if (item && item.type === 'video') { | 
			
		
	
		
			
				
					|  |  |  | estimatedHeight += 300; // 视频估算高度 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | return Math.max(0, estimatedHeight - 100); // 留一些上边距 | 
			
		
	
		
			
				
					|  |  |  | }, | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | // 获取音色列表 拿第一个做默认的音色id | 
			
		
	
		
			
				
					|  |  |  | async getVoiceList() { | 
			
		
	
		
			
				
					|  |  |  | const voiceRes = await this.$api.music.list() | 
			
		
	
	
		
			
				
					|  |  | 
 |