<template>
	<view class="page">
		<!-- #ifdef APP -->
		<statusBar></statusBar>
		<!-- #endif -->
		
		<!-- 导航栏 -->
		<uni-nav-bar 
			:fixed="true" 
			:statusBar="true" 
			:border="false"
			title="AI销冠系统" 
			leftIcon="left" 
			@clickLeft="goBack"
			color="#333"
			backgroundColor="#FFFFFF">
		</uni-nav-bar>
		
		<view class="content">
			<!-- 标签页 -->
			<view class="tabs" :style="{ top: computedNavbarTop || navbarTop }">
				<view 
					class="tab-item" 
					:class="{ active: activeTab === 'customer' }"
					@click="switchTab('customer')">
					<text>客户列表</text>
				</view>
				<view 
					class="tab-item" 
					:class="{ active: activeTab === 'service' }"
					@click="switchTab('service')">
					<text>服务记录</text>
				</view>
			</view>
			
			<!-- 服务记录列表 -->
			<ServiceList 
				v-if="activeTab === 'service'"
				class="service-list-container"
				:style="{ top: computedContentTop || contentTop }"
				:list="serviceList"
				:total="serviceListTotal"
				@itemClick="viewDetail"
				@filterClick="refreshServiceList"
				@reachBottom="onServiceListReachBottom"
				@menuAction="handleMenuAction"
				@updateItem="handleUpdateItem" />
			
			<!-- 客户列表 -->
			<CustomerList 
				v-if="activeTab === 'customer'"
				class="customer-list-container"
				:style="{ top: computedContentTop || contentTop }"
				@itemClick="viewCustomerDetail" />
		</view>
		
		<!-- 客户档案弹窗 -->
		<CustomerProfileModal 
			ref="customerProfileModal"
			:profile="currentCustomerProfile"
			@close="onCustomerProfileClose" />
		
		<!-- 录音列表弹窗 -->
		<uni-popup ref="audioListPopup" type="bottom" :mask-click="false">
			<view class="audio-list-modal">
				<!-- 顶部栏 -->
				<view class="modal-header">
					<view class="modal-close" @click="closeAudioList">
						<uni-icons type="close" size="24" color="#333"></uni-icons>
					</view>
					<text class="modal-title">录音列表（{{ audioSegmentsList.length }}）</text>
					<view style="width: 48rpx;"></view>
				</view>
				<!-- 录音列表内容 -->
				<scroll-view class="audio-list-content" scroll-y enable-flex>
					<view 
						class="audio-list-item" 
						v-for="(item, index) in audioSegmentsList" 
						:key="index">
						<view class="audio-item-header">
							<view class="audio-play-btn" @click.stop="toggleAudioPlay(item, index)">
								<text class="audio-play-text" :class="playingAudioId === (item.id || item.segmentId) ? 'audio-play-text--playing' : ''">
									{{ playingAudioId === (item.id || item.segmentId) ? '暂停' : '播放' }}
								</text>
							</view>
							<text class="audio-item-name">{{ formatAudioFileName(item.audioFileOriginalName) }}</text>
						</view>
						<view class="audio-item-info">
							<text class="audio-item-text" v-if="item.recordingText">{{ truncateText(item.recordingText, 30) }}</text>
							<view class="audio-item-transcribe" v-else>
								<view 
									class="transcribe-btn" 
									:class="{ 'transcribe-btn--loading': transcribingIds.includes(item.id || item.segmentId) }"
									@click.stop="transcribeAudio(item, index)">
									<text v-if="!transcribingIds.includes(item.id || item.segmentId)">转文本</text>
									<text v-else>处理中...</text>
								</view>
							</view>
						</view>
						<view class="audio-item-meta">
							<text class="audio-meta-item" v-if="item.endTime">{{ formatDateTime(item.endTime) }}</text>
							<text class="audio-meta-item" v-if="item.duration">{{ formatDuration(item.duration) }}</text>
							<text class="audio-meta-item" v-if="item.deviceNo">{{ item.deviceNo }}</text>
						</view>
					</view>
					<view class="audio-list-empty" v-if="!audioSegmentsLoading && audioSegmentsList.length === 0">
						<text>暂无录音记录</text>
					</view>
				</scroll-view>
			</view>
		</uni-popup>
		
		<!-- 录音文本内容弹框（放在录音列表弹框之后，确保层级更高） -->
		<uni-popup ref="textModalPopup" type="center" :mask-click="true" @change="onTextModalChange" class="text-modal-popup">
			<view class="text-modal">
				<view class="text-modal-header">
					<text class="text-modal-title">录音文本内容</text>
					<view class="text-modal-close" @click="closeTextModal">
						<uni-icons type="close" size="24" color="#333"></uni-icons>
					</view>
				</view>
				<scroll-view class="text-modal-content" scroll-y>
					<text class="text-modal-text">{{ currentRecordingText || '暂无录音文本' }}</text>
				</scroll-view>
			</view>
		</uni-popup>
		
		<!-- 服务记录详情弹窗 -->
		<uni-popup ref="serviceDetailPopup" type="bottom" :mask-click="false">
			<view class="service-detail-modal">
				<!-- 顶部栏 -->
				<view class="modal-header">
					<view class="modal-close" @click="closeDetail">
						<uni-icons type="close" size="24" color="#333"></uni-icons>
					</view>
					<text class="modal-title">{{ currentServiceDetail.title }}</text>
					<view class="modal-share" @click="shareDetail">
						<uni-icons type="forward" size="20" color="#333"></uni-icons>
					</view>
				</view>
				
				<!-- 日期时间 -->
				<view class="modal-date">
					<text>{{ currentServiceDetail.date }}</text>
				</view>
				
				<!-- AI总结横幅 -->
				<view class="modal-banner">
					<view class="banner-left">
						<view class="banner-icon">
							<uni-icons type="loop" size="18" color="#007AFF"></uni-icons>
						</view>
					<text class="banner-text">AI总结提炼关键, 为销售减负</text>
				</view>
			</view>
				
				<!-- 音频播放器 -->
				<view class="audio-player">
					<view class="play-btn" @click="togglePlay">
						<uni-icons :type="isPlaying ? 'pause-filled' : 'play-filled'" size="24" color="#007AFF"></uni-icons>
					</view>
					<view class="progress-bar">
						<view class="progress-line">
							<view class="progress-dot"></view>
						</view>
					</view>
					<text class="audio-time">00:00:00/00:00:00</text>
					<view class="speed-btn">
						<text>DD 1.0</text>
					</view>
				</view>
				
				<!-- 标签页 -->
				<view class="detail-tabs">
					<view 
						class="detail-tab-item" 
						:class="{ active: activeDetailTab === 'summary' }"
						@click="switchDetailTab('summary')">
						<text>会话总结</text>
					</view>
					<view 
						class="detail-tab-item" 
						:class="{ active: activeDetailTab === 'todo' }"
						@click="switchDetailTab('todo')">
						<text>智能待办</text>
					</view>
					<view 
						class="detail-tab-item" 
						:class="{ active: activeDetailTab === 'chapter' }"
						@click="switchDetailTab('chapter')">
						<text>章节概要</text>
					</view>
					<view 
						class="detail-tab-item" 
						:class="{ active: activeDetailTab === 'performance' }"
						@click="switchDetailTab('performance')">
						<text>服务表现</text>
					</view>
				</view>
				
				<!-- 会话总结内容 -->
				<ConversationSummaryFurniture 
					v-if="activeDetailTab === 'summary'"
					:serviceItem="currentServiceDetail"
					:key="`summary-${currentServiceDetail.id || currentServiceDetail.rawData?.id || Date.now()}`" />
				
				<!-- 服务表现内容 -->
				<scroll-view class="detail-content" scroll-y v-if="activeDetailTab === 'performance'">
					<view class="performance-score">
						<text class="score-label">本次服务评分</text>
						<text class="score-value">{{ performanceData.totalScore }}</text>
					</view>
					<view 
						class="performance-category" 
						v-for="(category, categoryIndex) in performanceData.categories" 
						:key="categoryIndex">
						<view class="category-header" @click="toggleCategory(categoryIndex)">
							<view class="category-left">
								<view class="category-bullet" :class="category.completed ? 'bullet-blue' : 'bullet-gray'"></view>
								<text class="category-name">{{ category.name }}</text>
							</view>
							<uni-icons 
								:type="category.expanded ? 'up' : 'down'" 
								size="16" 
								color="#999">
							</uni-icons>
						</view>
						<view class="category-content" v-if="category.expanded">
							<!-- AI横幅（如果有） -->
							<view class="performance-banner" v-if="category.showBanner">
								<view class="banner-left">
									<view class="banner-icon">
										<uni-icons type="loop" size="18" color="#007AFF"></uni-icons>
									</view>
									<text class="banner-text">AI总结提炼关键,为销售减负</text>
								</view>
							</view>
							<!-- 音频播放器（如果有） -->
							<view class="performance-audio" v-if="category.showAudio">
								<view class="audio-player">
									<view class="play-btn" @click="togglePlay">
										<uni-icons :type="isPlaying ? 'pause-filled' : 'play-filled'" size="24" color="#007AFF"></uni-icons>
									</view>
									<view class="progress-bar">
										<view class="progress-line">
											<view class="progress-dot"></view>
										</view>
									</view>
									<text class="audio-time">00:00:00/00:00:00</text>
									<view class="speed-btn">
										<text>DD 1.0</text>
									</view>
								</view>
							</view>
							<!-- 子项列表 -->
							<view 
								class="performance-item" 
								v-for="(item, itemIndex) in category.items" 
								:key="itemIndex"
								:class="{ 'item-completed': item.completed }">
								<view class="item-content" @click="toggleItem(categoryIndex, itemIndex)">
									<view class="item-left">
										<text class="item-name">{{ item.name }}</text>
										<text class="item-status" :class="item.completed ? 'status-completed' : 'status-missing'" v-if="!item.completed">
											{{ item.completed ? '已完成' : '未提及' }}
										</text>
										<text class="item-points">+{{ item.points }}分</text>
									</view>
									<uni-icons type="down" size="16" color="#999"></uni-icons>
								</view>
							</view>
						</view>
					</view>
				</scroll-view>
				
				<!-- 智能待办内容 -->
				<scroll-view class="detail-content" scroll-y v-if="activeDetailTab === 'todo'">
					<view class="todo-list" v-if="todoList.length > 0">
						<view 
							class="todo-item" 
							v-for="(item, index) in todoList" 
							:key="index"
							:class="{ 
								'todo-completed': item.status && (item.status.includes('完成') || item.status === '已完成'),
								'todo-clickable': isTodoPending(item.status)
							}">
							<view class="todo-header">
								<view class="todo-title-wrapper">
									<view class="todo-status-dot" :class="getTodoStatusClass(item.status)"></view>
									<text class="todo-title">{{ item.todoTitle || item.title || '待办事项' }}</text>
								</view>
								<view class="todo-status-wrapper" v-if="isTodoPending(item.status)">
									<text 
										class="todo-status todo-status-clickable" 
										:class="getTodoStatusTextClass(item.status)"
										:id="'todo-status-' + index"
										@click.stop="toggleTodoMenu(index, $event)">
										{{ item.status || '待处理' }}
										<uni-icons type="down" size="14" color="#FF9800" style="margin-left: 4rpx;"></uni-icons>
									</text>
								</view>
								<text 
									v-else
									class="todo-status" 
									:class="getTodoStatusTextClass(item.status)">
									{{ item.status || '待处理' }}
								</text>
							</view>
							<view class="todo-content" v-if="item.todoContent || item.content || item.description">
								<text>{{ item.todoContent || item.content || item.description }}</text>
							</view>
							<view class="todo-meta">
								<text class="todo-meta-item" v-if="item.ownerName">所属人：{{ item.ownerName }}</text>
								<text class="todo-meta-item" v-if="item.ownerPhone">电话：{{ item.ownerPhone }}</text>
								<text class="todo-meta-item" v-if="item.PendingDate || item.pendingDate">待办：{{ formatDateTime(item.PendingDate || item.pendingDate) }}</text>
							</view>
						</view>

						
					</view>
					<view class="empty-detail" v-else>
						<text>暂无待办事项</text>
					</view>
				</scroll-view>
				
				<!-- 下拉菜单（移到modal层级，避免被遮挡） -->
				<view 
					class="todo-menu-mask" 
					v-if="activeTodoMenuIndex !== null"
					@click="closeTodoMenu">
				</view>
				<view 
					class="todo-menu-fixed" 
					v-if="activeTodoMenuIndex !== null"
					:style="todoMenuStyle"
					@click.stop>
					<view class="todo-menu-item" @click="handleTodoComplete(currentTodoItem, activeTodoMenuIndex)">
						<text>处理完成</text>
					</view>
					<view class="todo-menu-item" @click="handleTodoDelay(currentTodoItem, activeTodoMenuIndex)">
						<text>延期处理</text>
					</view>
				</view>
				
				<!-- 章节概要内容 -->
				<scroll-view class="detail-content" scroll-y v-if="activeDetailTab === 'chapter'">
					<view class="chapter-summary-list" v-if="chapterSummaryList.length > 0">
						<view 
							class="chapter-summary-item" 
							v-for="(item, index) in chapterSummaryList" 
							:key="index">
							<view class="chapter-summary-title">
								<text>{{ item.title || `章节${index + 1}` }}</text>
							</view>
							<view class="chapter-summary-section" v-if="item.customerConcerns">
								<view class="chapter-summary-label">
									<text>客户疑虑</text>
								</view>
								<view class="chapter-summary-content">
									<text>{{ item.customerConcerns }}</text>
								</view>
							</view>
							<view class="chapter-summary-section" v-if="item.answer">
								<view class="chapter-summary-label">
									<text>回答</text>
								</view>
								<view class="chapter-summary-content">
									<text>{{ item.answer }}</text>
								</view>
							</view>
						</view>
					</view>
					<view class="empty-detail" v-else>
						<text>暂无章节概要内容</text>
					</view>
				</scroll-view>
				
				<!-- 其他标签页内容 -->
				<scroll-view class="detail-content" scroll-y v-if="activeDetailTab !== 'summary' && activeDetailTab !== 'performance' && activeDetailTab !== 'todo' && activeDetailTab !== 'chapter'">
					<view class="empty-detail">
						<text>{{ getDetailTabName(activeDetailTab) }}内容</text>
					</view>
				</scroll-view>
				
				<!-- 底部客户信息 -->
				<view class="modal-footer" @click="viewCustomer">
					<uni-icons type="person" size="20" color="#666"></uni-icons>
					<text class="footer-label">客户:</text>
					<text class="footer-customer">{{ currentServiceDetail.customerName }}</text>
					<uni-icons type="right" size="16" color="#999"></uni-icons>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	// #ifdef APP
	import statusBar from "@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar";
	// #endif
	import CustomerList from './components/CustomerList.vue';
	import ServiceList from './components/ServiceList.vue';
	import CustomerProfileModal from './components/CustomerProfileModal.vue';
	import ConversationSummaryFurniture from './components/ConversationSummaryFurniture.vue';
	import { initCustomerProfile, initSummaryList, initPerformanceData } from '@/pages/furniture_customer/utils/dataInit.js';
	import { getApiUrl, API_BASE_URL } from '@/common/config.js';
	
	export default {
		// #ifdef APP
		components: {
			statusBar
		},
		// #endif
		components: {
			CustomerList,
			ServiceList,
			CustomerProfileModal,
			ConversationSummaryFurniture
		},
		data() {
			// 动态计算导航栏高度
			const systemInfo = uni.getSystemInfoSync();
			const statusBarHeight = systemInfo.statusBarHeight || 20; // 默认20px
			const navbarHeight = 44; // navbar高度44px
			// 转换为rpx：1px = 2rpx（在375px设计稿下）
			const statusBarHeightRpx = statusBarHeight * 2;
			const navbarHeightRpx = navbarHeight * 2;
			const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
			
			return {
				navbarTop: totalNavbarHeight + 'rpx', // tab栏距离顶部的距离
				contentTop: (totalNavbarHeight + 72) + 'rpx', // 内容区域距离顶部的距离（tab栏高度72rpx）
				activeTab: 'customer',
				activeDetailTab: 'summary',
				isPlaying: false,
				currentServiceDetail: {
					title: '',
					date: '',
					duration: '',
					description: '',
					customerName: ''
				},
				currentCustomerProfile: {
					name: '',
					intent: '',
					serviceCount: 0,
					lastService: '',
					phone: '',
					serviceStaff: '',
					wechatStatus: '',
					address: '',
					source: '',
					followStage: '',
					systemTags: [],
					customTags: [],
					intentDescription: ''
				},
				summaryList: [],
				furnitureAnalysisList: [], // 家具意向分析数据
				productCategoryList: [], // 产品类别列表
				activeProductCategory: '', // 当前选中的产品类别
				productRequirementMap: {}, // 产品需求映射 {categoryKey: {rows: [...]}}
				summarySentence: '', // 一句话总结
				dealKeyPoints: '', // 成交关键点
				performanceData: {
					totalScore: 81,
					categories: []
				},
				serviceList: [],
				serviceListTotal: 0,
				serviceListPage: {
					current: 1,
					size: 10
				},
				todoList: [], // 待办事项列表
				todoListPage: {
					current: 1,
					size: 10
				},
				todoListTotal: 0, // 待办事项总数
				activeTodoMenuIndex: null, // 当前打开的下拉菜单索引
				todoMenuStyle: {}, // 下拉菜单样式（用于fixed定位）
				currentTodoItem: null, // 当前操作的待办事项
				chapterSummaryList: [], // 章节概要列表，包含summary1, summary2, summary3
				audioSegmentsList: [], // 录音分段列表
				audioSegmentsLoading: false, // 录音分段加载状态
				playingAudioId: null, // 当前正在播放的录音ID
				innerAudioContext: null, // 音频播放器实例
				currentAudioUrl: null, // 当前音频URL（用于清理Blob URL）
				showTextModal: false, // 是否显示文本内容弹框
				currentRecordingText: '', // 当前显示的录音文本内容
				transcribingIds: [] // 正在转文本的录音ID列表
			}
		},
		computed: {
			// 当前选中的产品需求
			currentProductRequirement() {
				if (!this.activeProductCategory) return null;
				return this.productRequirementMap[this.activeProductCategory] || null;
			},
			// 计算导航栏和内容区域的位置（使用计算属性确保响应式）
			computedNavbarTop() {
				const systemInfo = uni.getSystemInfoSync();
				const statusBarHeight = systemInfo.statusBarHeight || 20;
				const navbarHeight = 44;
				const statusBarHeightRpx = statusBarHeight * 2;
				const navbarHeightRpx = navbarHeight * 2;
				const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
				return totalNavbarHeight + 'rpx';
			},
			computedContentTop() {
				const systemInfo = uni.getSystemInfoSync();
				const statusBarHeight = systemInfo.statusBarHeight || 20;
				const navbarHeight = 44;
				const statusBarHeightRpx = statusBarHeight * 2;
				const navbarHeightRpx = navbarHeight * 2;
				const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
				return (totalNavbarHeight + 72) + 'rpx'; // tab栏高度72rpx
			}
		},
		onLoad(options = {}) {
			console.log('[FurnitureCustomer][onLoad] 页面加载');
			this.applyIncomingTab(options?.tab);
			// 更新导航栏位置
			this.updateNavbarPosition();
			// 加载服务记录列表
			if (this.activeTab === 'service') {
				this.loadServiceList();
			}
		},
		onShow() {
			console.log('[FurnitureCustomer][onShow] 页面显示');
			// 每次页面显示时都重新计算导航栏位置，确保通过导航菜单进入时也能正确显示
			// 使用 $nextTick 确保DOM更新后再设置样式
			this.$nextTick(() => {
				this.updateNavbarPosition();
				// 再次延迟更新，确保样式已应用
				setTimeout(() => {
					this.updateNavbarPosition();
					console.log('[FurnitureCustomer][onShow] 延迟更新后的位置:', {
						navbarTop: this.navbarTop,
						contentTop: this.contentTop
					});
				}, 50);
			});
		},
		onReady() {
			// 页面渲染完成后，检查tab栏是否显示
			console.log('[FurnitureCustomer][onReady] 页面渲染完成');
			console.log('[FurnitureCustomer][onReady] activeTab:', this.activeTab);
			console.log('[FurnitureCustomer][onReady] navbarTop:', this.navbarTop);
			console.log('[FurnitureCustomer][onReady] contentTop:', this.contentTop);
			
			// 再次更新导航栏位置，确保渲染后位置正确
			this.updateNavbarPosition();

			// 页面加载后的URL隐藏初始化：只在用户导航时执行
			this.initUrlHidingAfterPageLoad();
			
			const systemInfo = uni.getSystemInfoSync();
			console.log('[FurnitureCustomer][onReady] 系统信息:', {
				statusBarHeight: systemInfo.statusBarHeight,
				windowHeight: systemInfo.windowHeight,
				screenHeight: systemInfo.screenHeight
			});
			
			// 检查tab栏元素是否存在和可见
			// #ifdef MP-WEIXIN
			setTimeout(() => {
				const query = uni.createSelectorQuery().in(this);
				query.select('.tabs').boundingClientRect((data) => {
					console.log('[FurnitureCustomer][onReady] tab栏元素信息:', data);
					if (!data) {
						console.error('[FurnitureCustomer][onReady] tab栏元素未找到！');
					} else {
						console.log('[FurnitureCustomer][onReady] tab栏位置:', {
							top: data.top,
							left: data.left,
							width: data.width,
							height: data.height,
							expectedTop: this.navbarTop,
							isVisible: data.width > 0 && data.height > 0,
							isOnScreen: data.top >= 0 && data.top < systemInfo.windowHeight
						});
						
						// 如果tab栏不可见，强制更新位置
						if (data.width === 0 || data.height === 0 || data.top < 0) {
							console.warn('[FurnitureCustomer][onReady] tab栏不可见，强制更新位置');
							this.updateNavbarPosition();
							this.$forceUpdate();
						}
					}
				}).exec();
			}, 100);
			// #endif
		},
		onUnload() {
			// 组件销毁时，清理音频播放器
			if (this.innerAudioContext) {
				try {
					this.innerAudioContext.stop();
					this.innerAudioContext.destroy();
				} catch (e) {
					console.error('销毁音频播放器失败:', e);
				}
				this.innerAudioContext = null;
			}
			// #ifdef H5
			// 清理Blob URL，释放内存
			if (this.currentAudioUrl && this.currentAudioUrl.startsWith('blob:')) {
				try {
					URL.revokeObjectURL(this.currentAudioUrl);
				} catch (e) {
					console.error('清理Blob URL失败:', e);
				}
			}
			// #endif
			this.currentAudioUrl = null;
			this.playingAudioId = null;
		},
		methods: {
			applyIncomingTab(tab) {
				const allowedTabs = ['service', 'customer'];
				if (!allowedTabs.includes(tab)) {
					return;
				}
				this.activeTab = tab;
			},
			// 计算并更新导航栏和内容区域的位置
			updateNavbarPosition() {
				console.log('[FurnitureCustomer][updateNavbarPosition] 开始更新导航栏位置');
				const systemInfo = uni.getSystemInfoSync();
				const statusBarHeight = systemInfo.statusBarHeight || 20; // 默认20px
				const navbarHeight = 44; // navbar高度44px
				// 转换为rpx：1px = 2rpx（在375px设计稿下）
				const statusBarHeightRpx = statusBarHeight * 2;
				const navbarHeightRpx = navbarHeight * 2;
				const totalNavbarHeight = statusBarHeightRpx + navbarHeightRpx;
				
				const navbarTop = totalNavbarHeight + 'rpx';
				const contentTop = (totalNavbarHeight + 72) + 'rpx'; // tab栏高度72rpx
				
				console.log('[FurnitureCustomer][updateNavbarPosition] 更新导航栏位置:', {
					statusBarHeight: statusBarHeight,
					navbarHeight: navbarHeight,
					totalNavbarHeight: totalNavbarHeight,
					navbarTop: navbarTop,
					contentTop: contentTop,
					currentNavbarTop: this.navbarTop,
					currentContentTop: this.contentTop
				});
				
				// 强制更新，确保响应式数据变化被检测到
				this.$set(this, 'navbarTop', navbarTop);
				this.$set(this, 'contentTop', contentTop);
				
				// 在微信小程序中，可能需要强制更新视图
				// #ifdef MP-WEIXIN
				this.$forceUpdate();
				// #endif
			},
			goBack() {
				// 检查页面栈，如果当前是第一个页面，则不能返回
				const pages = getCurrentPages();
				if (pages.length <= 1) {
					// 如果是第一个页面，不执行返回操作
					// 对于 tabBar 页面，通常不需要返回按钮，或者可以隐藏返回按钮
					console.log('[FurnitureCustomer][goBack] 当前是第一个页面，无法返回');
					return;
				}
				uni.navigateBack({
					fail: (err) => {
						console.error('[FurnitureCustomer][goBack] 返回失败:', err);
						// 如果返回失败，可能是页面栈问题，忽略错误
					}
				});
			},
			switchTab(tab) {
				this.activeTab = tab;
				// 切换到服务记录标签页时，如果列表为空则加载数据
				if (tab === 'service' && this.serviceList.length === 0) {
					this.loadServiceList();
				}
				// 客户列表数据由 CustomerList 组件自己管理，不需要在这里加载
			},
			// 刷新服务记录列表
			refreshServiceList(filterParams = {}) {
				// 重置分页到第一页
				this.serviceListPage.current = 1;
				// 重新加载数据，传递查询参数
				this.loadServiceList(filterParams);
			},
			// 服务记录列表到底部加载更多
			onServiceListReachBottom() {
				// 如果已经加载全部数据，则不再请求
				if (this.serviceList.length >= this.serviceListTotal) {
					return;
				}
				// 下一页
				this.serviceListPage.current += 1;
				this.loadServiceList();
			},
			async viewDetail(item) {
				// 查看详情
				this.currentServiceDetail = { ...item };
				// 重置待办事项列表
				this.todoList = [];
				this.todoListTotal = 0;
				// 重置章节概要列表
				this.chapterSummaryList = [];
				// 如果当前标签页是智能待办，加载待办事项
				if (this.activeDetailTab === 'todo') {
					this.loadTodoList();
				}
				// 如果当前标签页是章节概要，加载章节概要数据
				if (this.activeDetailTab === 'chapter') {
					this.loadChapterSummary();
				}
				// 如果当前标签页是服务表现，加载服务表现数据
				if (this.activeDetailTab === 'performance') {
					this.loadPerformanceData();
				}
				// 会话总结数据由"会话总结家具"组件自动加载
				this.$refs.serviceDetailPopup.open();
			},
			// 处理菜单操作
			async handleMenuAction({ action, item }) {
				console.log('父组件收到菜单操作:', action, item);
				switch (action) {
					case 'view':
						// 查看详情：打开详情弹窗 
						this.viewDetail(item);
						break;
					case 'analysis':
						// AI分析：已经在 ServiceList 组件中处理，这里不需要处理
						break;
					case 'audio':
						// 录音详情：加载录音分段列表
						await this.loadAudioSegments(item);
						break;
					case 'delete':
						// 删除服务记录
						await this.deleteServiceRecord(item);
						break;
					default:
						console.warn('未知的菜单操作:', action);
				}
			},
			// 处理列表项更新
			handleUpdateItem({ recordId, data }) {
				// 在列表中找到对应的项并更新
				const index = this.serviceList.findIndex(serviceItem => 
					(serviceItem.id || serviceItem.rawData?.id) === recordId
				);
				if (index !== -1) {
					this.$set(this.serviceList, index, data);
				}
			},
			// 删除服务记录
			async deleteServiceRecord(item) {
				console.log('删除服务记录，item:', item);
				// 显示确认对话框
				const res = await new Promise((resolve) => {
					uni.showModal({
						title: '确认删除',
						content: '确定要删除这条服务记录吗？删除后无法恢复。',
						confirmText: '删除',
						confirmColor: '#FF3B30',
						cancelText: '取消',
						success: (result) => {
							resolve(result.confirm);
						},
						fail: () => {
							resolve(false);
						}
					});
				});
				
				if (!res) {
					return; // 用户取消删除
				}
				
				try {
					// 获取要删除的记录ID
					const recordId = item.id || item.rawData?.id;
					if (!recordId) {
						uni.showToast({
							title: '无法获取记录ID',
							icon: 'none'
						});
						return;
					}
					
					// 调用删除接口：/api/audioManagement/delete/{id}
					const url = getApiUrl(`/api/audioManagement/delete/${recordId}`);
					
					// 获取认证信息
					let tenantId = '';
					let token = '';
					try {
						tenantId = uni.getStorageSync('backend-tenant-id') || '';
						token = uni.getStorageSync('backend-token') || '';
					} catch (e) {
						console.error('获取认证信息失败:', e);
					}
					
					// 构建请求头
					const headers = {
						'Content-Type': 'application/json'
					};
					if (token) {
						headers['Authorization'] = `Bearer ${token}`;
					}
					if (tenantId) {
						headers['X-Tenant-Id'] = tenantId;
					}
					
					const deleteRes = await uni.request({
						url: url,
						method: 'DELETE',
						header: headers,
						timeout: 10000
					});
					
					if (deleteRes.statusCode === 200 && deleteRes.data && deleteRes.data.success) {
						uni.showToast({
							title: '删除成功',
							icon: 'success'
						});
						// 刷新列表
						this.serviceListPage.current = 1;
						this.serviceList = [];
						await this.loadServiceList();
					} else {
						uni.showToast({
							title: deleteRes.data?.message || '删除失败',
							icon: 'none'
						});
					}
				} catch (error) {
					console.error('删除服务记录失败:', error);
					uni.showToast({
						title: `删除失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none'
					});
				}
			},
			// 加载录音分段列表
			async loadAudioSegments(item) {
				try {
					// 获取parentId，从item的rawData中获取id，或者直接使用id
					const parentId = item.rawData?.id || item.id;
					if (!parentId) {
						uni.showToast({
							title: '无法获取录音ID',
							icon: 'none'
						});
						return;
					}
					
					this.audioSegmentsLoading = true;
					this.audioSegmentsList = [];
					
					uni.showLoading({
						title: '加载中...'
					});
					
					// 调用接口：/api/audioManagementSegments/listByParentId?parentId={parentId}
					const url = `${getApiUrl('/api/audioManagementSegments/listByParentId')}?parentId=${parentId}`;
					
					// 获取认证信息
					let tenantId = '';
					let token = '';
					try {
						tenantId = uni.getStorageSync('backend-tenant-id') || '';
						token = uni.getStorageSync('backend-token') || '';
					} catch (e) {
						console.error('获取认证信息失败:', e);
					}
					
					// 构建请求头
					const headers = {
						'Content-Type': 'application/json'
					};
					if (token) {
						headers['Authorization'] = `Bearer ${token}`;
					}
					if (tenantId) {
						headers['X-Tenant-Id'] = tenantId;
					}
					
					const res = await uni.request({
						url: url,
						method: 'GET',
						header: headers,
						timeout: 10000
					});
					
					uni.hideLoading();
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						const segments = res.data.data || [];
						console.log('录音分段列表:', segments);
						
						// 存储分段数据
						this.audioSegmentsList = segments;
						this.audioSegmentsLoading = false;
						
						// 打开录音列表弹窗
						this.$refs.audioListPopup.open();
					} else {
						uni.showToast({
							title: res.data?.message || '获取录音分段失败',
							icon: 'none'
						});
					}
				} catch (error) {
					uni.hideLoading();
					this.audioSegmentsLoading = false;
					console.error('获取录音分段列表失败:', error);
					uni.showToast({
						title: `获取录音分段失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none'
					});
				}
			},
			// 关闭录音列表弹窗
			closeAudioList() {
				// 关闭弹窗时，如果正在播放，先停止播放
				if (this.playingAudioId) {
					this.stopAudioPlay({ id: this.playingAudioId });
				}
				this.$refs.audioListPopup.close();
			},
			// 切换录音播放/暂停
			async toggleAudioPlay(item, index) {
				try {
					// 获取录音ID（可能是 id 或 segmentId）
					const audioId = item.id || item.segmentId;
					if (!audioId) {
						console.warn('录音项缺少ID:', item);
						uni.showToast({
							title: '无法获取录音ID',
							icon: 'none'
						});
						return;
					}
					
					
					
					// 如果点击的是当前正在播放的录音，则暂停
					if (this.playingAudioId === audioId) {
						await this.stopAudioPlay(item);
					} else {
						// 如果其他录音正在播放，先停止
						if (this.playingAudioId) {
							await this.stopAudioPlay({ id: this.playingAudioId });
						}
						// 显示文本内容弹框
					this.currentRecordingText = item.recordingText || '';
					this.showTextModal = true;
					this.$refs.textModalPopup.open();
						// 开始播放新的录音
						await this.startAudioPlay(item);
					}
				} catch (error) {
					console.error('切换播放状态失败:', error);
					uni.showToast({
						title: '操作失败',
						icon: 'none'
					});
				}
			},
			// 关闭文本内容弹框
			closeTextModal() {
				this.showTextModal = false;
				this.currentRecordingText = '';
				this.$refs.textModalPopup.close();
			},
			// 文本弹框状态变化
			onTextModalChange(e) {
				if (!e.show) {
					// 弹框关闭时，清除状态
					this.showTextModal = false;
					this.currentRecordingText = '';
				}
			},
			// 开始播放录音
			async startAudioPlay(item) {
				try {
					// 获取录音ID（可能是 id 或 segmentId）
					const audioId = item.id || item.segmentId;
					if (!audioId) {
						console.warn('录音项缺少ID:', item);
						uni.showToast({
							title: '无法获取录音ID',
							icon: 'none'
						});
						return;
					}
					
					// 如果已有播放器正在播放，先停止
					if (this.innerAudioContext) {
						this.innerAudioContext.stop();
						this.innerAudioContext.destroy();
						this.innerAudioContext = null;
					}
					
					uni.showLoading({
						title: '加载中...'
					});
					
					// 获取认证信息
					let tenantId = '';
					let token = '';
					try {
						tenantId = uni.getStorageSync('backend-tenant-id') || '';
						token = uni.getStorageSync('backend-token') || '';
					} catch (e) {
						console.error('获取认证信息失败:', e);
					}
					
					// 构建请求URL
					// 根据后端接口定义：@PostMapping("/playSegmentById") 使用 @PathVariable String id
					// 如果使用 @PathVariable，路径应该是 /playSegmentById/{id}
					// 先尝试路径参数方式：/api/audioManagementSegments/playSegmentById/{id}
					const url = getApiUrl(`/api/audioManagementSegments/playSegmentById/${audioId}`);
					
					console.log('请求音频URL:', url);
					console.log('音频ID:', audioId);
					
					// 构建请求头（参考其他请求的实现方式）
					const headers = {
						'Content-Type': 'application/json'
					};
					if (token) {
						headers['Authorization'] = `Bearer ${token}`;
					}
					if (tenantId) {
						headers['X-Tenant-Id'] = tenantId;
					}
					
					console.log('请求头:', headers);
					
					// 由于后端接口是POST方式，且需要传递header，而innerAudioContext无法设置请求头
					// 所以先通过uni.request获取音频数据，然后转换为可播放的URL
					const res = await uni.request({
						url: url,
						method: 'POST',
						header: headers,
						responseType: 'arraybuffer', // 接收二进制数据
						timeout: 30000 // 音频文件可能较大，增加超时时间
					});
					
					console.log('响应状态码:', res.statusCode);
					console.log('响应头:', res.header);
					
					if (res.statusCode !== 200) {
						console.error('请求失败，状态码:', res.statusCode);
						console.error('响应数据:', res.data);
						// 如果是404，可能是路径不对，尝试其他方式
						if (res.statusCode === 404) {
							throw new Error(`接口路径不存在(404)，请检查后端接口路径是否正确。当前URL: ${url}`);
						}
						throw new Error(`请求失败，状态码: ${res.statusCode}`);
					}
					
					// 从响应头获取Content-Type，确定音频格式
					// 如果响应头中没有Content-Type，默认使用audio/mpeg
					let audioType = 'audio/mpeg';
					if (res.header && res.header['Content-Type']) {
						audioType = res.header['Content-Type'];
					} else if (res.header && res.header['content-type']) {
						audioType = res.header['content-type'];
					}
					
					// 将arraybuffer转换为base64或blob URL
					// #ifdef H5
					// H5平台：使用Blob URL
					const blob = new Blob([res.data], { type: audioType });
					const audioUrl = URL.createObjectURL(blob);
					// #endif
					
					// #ifndef H5
					// 非H5平台：使用base64
					const base64 = uni.arrayBufferToBase64(res.data);
					const audioUrl = `data:${audioType};base64,${base64}`;
					// #endif
					
					// 保存audioUrl到组件实例，以便在回调中清理
					this.currentAudioUrl = audioUrl;
					
					// 创建音频播放器实例
					const innerAudioContext = uni.createInnerAudioContext();
					innerAudioContext.src = audioUrl;
					
					// 监听播放事件
					innerAudioContext.onPlay(() => {
						console.log('开始播放音频');
						uni.hideLoading();
						this.playingAudioId = audioId;
						uni.showToast({
							title: '开始播放',
							icon: 'success',
							duration: 1000
						});
					});
					
					// 监听播放错误
					innerAudioContext.onError((error) => {
						console.error('音频播放错误:', error);
						uni.hideLoading();
						this.playingAudioId = null;
						innerAudioContext.destroy();
						this.innerAudioContext = null;
						// #ifdef H5
						// 清理Blob URL，释放内存
						if (this.currentAudioUrl && this.currentAudioUrl.startsWith('blob:')) {
							URL.revokeObjectURL(this.currentAudioUrl);
						}
						// #endif
						this.currentAudioUrl = null;
						uni.showToast({
							title: '播放失败，请检查网络或音频文件',
							icon: 'none',
							duration: 2000
						});
					});
					
					// 监听播放结束
					innerAudioContext.onEnded(() => {
						console.log('音频播放结束');
						this.playingAudioId = null;
						innerAudioContext.destroy();
						this.innerAudioContext = null;
						// #ifdef H5
						// 清理Blob URL，释放内存
						if (this.currentAudioUrl && this.currentAudioUrl.startsWith('blob:')) {
							URL.revokeObjectURL(this.currentAudioUrl);
						}
						// #endif
						this.currentAudioUrl = null;
					});
					
					// 监听播放暂停
					innerAudioContext.onPause(() => {
						console.log('音频播放暂停');
						this.playingAudioId = null;
					});
					
					// 存储播放器实例
					this.innerAudioContext = innerAudioContext;
					
					// 开始播放
					innerAudioContext.play();
					
				} catch (error) {
					uni.hideLoading();
					console.error('播放录音失败:', error);
					if (this.innerAudioContext) {
						this.innerAudioContext.destroy();
						this.innerAudioContext = null;
					}
					this.playingAudioId = null;
					uni.showToast({
						title: `播放失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none',
						duration: 2000
					});
				}
			},
			// 停止播放录音
			async stopAudioPlay(item) {
				try {
					// 停止音频播放器
					if (this.innerAudioContext) {
						this.innerAudioContext.stop();
						this.innerAudioContext.destroy();
						this.innerAudioContext = null;
					}
					
					// 清除播放状态
					this.playingAudioId = null;
					
					uni.showToast({
						title: '已停止',
						icon: 'success',
						duration: 1000
					});
				} catch (error) {
					// 即使出错，也清除播放状态
					if (this.innerAudioContext) {
						try {
							this.innerAudioContext.stop();
							this.innerAudioContext.destroy();
						} catch (e) {
							console.error('销毁音频播放器失败:', e);
						}
						this.innerAudioContext = null;
					}
					this.playingAudioId = null;
					console.error('停止播放失败:', error);
					uni.showToast({
						title: '已停止',
						icon: 'success',
						duration: 1000
					});
				}
			},
			// 转文本
			async transcribeAudio(item, index) {
				try {
					// 获取录音ID（可能是 id 或 segmentId）
					const audioId = item.id || item.segmentId;
					if (!audioId) {
						uni.showToast({
							title: '无法获取录音ID',
							icon: 'none'
						});
						return;
					}
					
					// 如果正在转文本，则不再处理
					if (this.transcribingIds.includes(audioId)) {
						return;
					}
					
					// 添加到转文本列表
					this.transcribingIds.push(audioId);
					
					// 调用转文本接口：/api/audioManagementSegments/transcribe/{id}
					const url = getApiUrl(`/api/audioManagementSegments/transcribe/${audioId}`);
					
					// 获取认证信息
					let tenantId = '';
					let token = '';
					try {
						tenantId = uni.getStorageSync('backend-tenant-id') || '';
						token = uni.getStorageSync('backend-token') || '';
					} catch (e) {
						console.error('获取认证信息失败:', e);
					}
					
					// 构建请求头
					const headers = {
						'Content-Type': 'application/json'
					};
					if (token) {
						headers['Authorization'] = `Bearer ${token}`;
					}
					if (tenantId) {
						headers['X-Tenant-Id'] = tenantId;
					}
					
					const res = await uni.request({
						url: url,
						method: 'POST',
						header: headers,
						timeout: 30000 // 转文本可能需要较长时间
					});
					
					// 从转文本列表中移除
					const idIndex = this.transcribingIds.indexOf(audioId);
					if (idIndex > -1) {
						this.transcribingIds.splice(idIndex, 1);
					}
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						uni.showToast({
							title: res.data.message || '转文本请求已提交',
							icon: 'success',
							duration: 2000
						});
						
						// 如果返回了更新后的数据，更新列表中的该项
						if (res.data.data) {
							// 更新列表中的该项
							this.$set(this.audioSegmentsList, index, {
								...item,
								...res.data.data
							});
						} else {
							// 如果没有返回数据，可以刷新整个列表
							// 或者等待用户手动刷新
							// 这里先不自动刷新，因为转文本是后台处理
						}
					} else {
						uni.showToast({
							title: res.data?.message || '转文本请求失败',
							icon: 'none',
							duration: 2000
						});
					}
				} catch (error) {
					// 从转文本列表中移除
					const audioId = item.id || item.segmentId;
					const idIndex = this.transcribingIds.indexOf(audioId);
					if (idIndex > -1) {
						this.transcribingIds.splice(idIndex, 1);
					}
					
					console.error('转文本失败:', error);
					uni.showToast({
						title: `转文本失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none',
						duration: 2000
					});
				}
			},
			// 格式化时长（秒转换为时分秒）
			formatDuration(seconds) {
				if (!seconds) return '00:00:00';
				const hours = Math.floor(seconds / 3600);
				const minutes = Math.floor((seconds % 3600) / 60);
				const secs = seconds % 60;
				return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
			},
			// 格式化日期时间
			formatDateTime(dateTime) {
				if (!dateTime) return '';
				const date = new Date(dateTime);
				const year = date.getFullYear();
				const month = String(date.getMonth() + 1).padStart(2, '0');
				const day = String(date.getDate()).padStart(2, '0');
				const hours = String(date.getHours()).padStart(2, '0');
				const minutes = String(date.getMinutes()).padStart(2, '0');
				const seconds = String(date.getSeconds()).padStart(2, '0');
				return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
			},
			// 格式化录音文件名：只显示第一个中划线之后和最后一个中划线之前的内容
			formatAudioFileName(fileName) {
				if (!fileName) return '未命名录音';
				// 找到第一个中划线的位置
				const firstDashIndex = fileName.indexOf('-');
				if (firstDashIndex === -1) {
					// 如果没有中划线，直接返回原文件名
					return fileName;
				}
				// 找到最后一个中划线的位置
				const lastDashIndex = fileName.lastIndexOf('-');
				if (firstDashIndex === lastDashIndex) {
					// 如果只有一个中划线，返回中划线之后的内容
					return fileName.substring(firstDashIndex + 1);
				}
				// 返回第一个中划线之后到最后一个中划线之前的内容
				return fileName.substring(firstDashIndex + 1, lastDashIndex);
			},
			// 截断文本，只显示指定长度
			truncateText(text, maxLength) {
				if (!text) return '';
				if (text.length <= maxLength) return text;
				return text.substring(0, maxLength) + '...';
			},
			closeDetail() {
				this.$refs.serviceDetailPopup.close();
			},
			shareDetail() {
				// 分享详情
				uni.showToast({
					title: '分享功能',
					icon: 'none'
				});
			},
			togglePlay() {
				this.isPlaying = !this.isPlaying;
			},
			switchDetailTab(tab) {
				this.activeDetailTab = tab;
				// 切换到智能待办标签页时，加载待办事项数据
				if (tab === 'todo') {
					this.loadTodoList();
				}
				// 切换到章节概要标签页时，加载章节概要数据
				if (tab === 'chapter') {
					this.loadChapterSummary();
				}
				// 切换到服务表现标签页时，加载服务表现数据
				if (tab === 'performance') {
					this.loadPerformanceData();
				}
			},
			getDetailTabName(tab) {
				const names = {
					'todo': '智能待办',
					'chapter': '章节概要',
					'performance': '服务表现'
				};
				return names[tab] || '';
			},
			initSummaryList(item) {
				this.summaryList = initSummaryList(item);
				this.performanceData = initPerformanceData();
			},
			// 加载家具意向分析数据
			async loadFurnitureAnalysis(item) {
				try {
					// 获取parentId，从rawData中获取id
					const parentId = item.rawData?.id || item.id;
					if (!parentId) {
						console.warn('无法获取parentId');
						this.furnitureAnalysisList = [];
						return;
					}
					
					// 统一使用 getApiUrl，根据 env.js 配置自动切换环境
					const url = `${getApiUrl('/api/audioTextAnalysisFurniture/byParentId')}?parentId=${parentId}`;
					
					const res = await uni.request({
						url: url,
						method: 'GET',
						timeout: 10000
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						this.furnitureAnalysisList = res.data.data || [];
						// 如果有数据，更新summaryList显示家具意向分析
						if (this.furnitureAnalysisList.length > 0) {
							this.updateSummaryWithFurnitureData();
						}
					} else {
						console.warn('获取家具意向分析失败:', res.data?.message || '未知错误');
						this.furnitureAnalysisList = [];
					}
				} catch (error) {
					console.error('获取家具意向分析失败:', error);
					this.furnitureAnalysisList = [];
				}
			},
			// 用家具意向分析数据更新会话总结
			updateSummaryWithFurnitureData() {
				if (this.furnitureAnalysisList.length === 0) return;
				
				// 从第一个家具意向分析数据中提取关键信息
				const firstItem = this.furnitureAnalysisList[0];
				
				// 构建会话总结列表，显示客户类型、家庭结构、一句话总结
				const summaryItems = [];
				
				// 客户类型
				if (firstItem.customerType) {
					summaryItems.push({
						label: '客户类型',
						value: firstItem.customerType,
						rawData: firstItem
					});
				}
				
				// 家庭结构
				if (firstItem.familyStructure) {
					summaryItems.push({
						label: '家庭结构',
						value: firstItem.familyStructure,
						rawData: firstItem
					});
				}
				
				// 一句话总结（单独存储，不在summaryList中）
				if (firstItem.summarySentence) {
					this.summarySentence = firstItem.summarySentence;
				}
				
				// 成交关键点（可以从数据中提取或生成）
				if (firstItem.dealKeyPoints) {
					this.dealKeyPoints = firstItem.dealKeyPoints;
				} else if (firstItem.summarySentence) {
					// 如果数据中没有成交关键点，可以从一句话总结中提取关键信息
					// 提取关键词：活动优惠、搭配、环保、安全、交付、退换、服务等
					const keyWords = [];
					const summary = firstItem.summarySentence;
					if (summary.includes('优惠') || summary.includes('活动')) {
						keyWords.push('活动优惠');
					}
					if (summary.includes('搭配')) {
						keyWords.push('整套搭配');
					}
					if (summary.includes('环保')) {
						keyWords.push('环保');
					}
					if (summary.includes('安全')) {
						keyWords.push('安全');
					}
					if (summary.includes('交付') || summary.includes('周期')) {
						keyWords.push('快速交付');
					}
					if (summary.includes('退换') || summary.includes('服务')) {
						keyWords.push('无忧退换服务');
					}
					if (keyWords.length > 0) {
						this.dealKeyPoints = keyWords.join('，');
					}
				}
				
				// 如果提取到了数据，更新summaryList
				if (summaryItems.length > 0) {
					this.summaryList = summaryItems;
				}
				
				// 构建产品需求清单
				this.buildProductRequirementList(firstItem);
			},
			// 构建产品需求清单（固定显示所有产品类别）
			buildProductRequirementList(data) {
				const categories = [
					{ key: 'sofa', name: '沙发', field: 'sofa' },
					{ key: 'bed', name: '床', field: 'bedAndMattress' },
					{ key: 'mattress', name: '床垫', field: 'bedAndMattress' },
					{ key: 'dining_table', name: '餐桌椅', field: 'diningTable' },
					{ key: 'tea_table', name: '茶几', field: 'teaTable' },
					{ key: 'tv_cabinet', name: '电视柜', field: 'tvCabinet' },
					{ key: 'study_desk', name: '学习桌', field: 'studyDesk' },
					{ key: 'cabinet', name: '橱柜', field: 'cabinet' },
					{ key: 'wine_cabinet', name: '酒柜', field: 'wineCabinet' },
					{ key: 'master_bedroom_cabinet', name: '主卧衣柜', field: 'masterBedroomCabinet' },
					{ key: 'secondary_bedroom_cabinet', name: '次卧衣柜', field: 'secondaryBedroomCabinet' },
					{ key: 'shoe_cabinet', name: '鞋柜', field: 'shoeCabinet' },
					{ key: 'custom', name: '定制家居', field: null }
				];
				
				const requirementMap = {};
				const categoryList = [];
				
				categories.forEach(category => {
					// 检查是否有该产品的数据
					let hasData = false;
					let productData = null;
					
					if (category.key === 'bed' || category.key === 'mattress') {
						// 床和床垫共用bedAndMattress字段
						const fieldValue = data.bedAndMattress || data.bed_and_mattress || '';
						if (fieldValue && fieldValue.trim()) {
							hasData = true;
							productData = this.parseProductJson(fieldValue);
						}
					} else if (category.key === 'custom') {
						// 定制家居：暂时跳过，因为各个定制产品已有单独类别
						// 如果需要显示定制家居汇总，可以在这里添加逻辑
						hasData = false;
					} else {
						// 尝试驼峰命名和蛇形命名
						const fieldValue = data[category.field] || data[this.toSnakeCase(category.field)] || '';
						if (fieldValue && fieldValue.trim()) {
							hasData = true;
							productData = this.parseProductJson(fieldValue);
						}
					}
					
					// 只有当有数据时才添加到列表中
					if (hasData) {
						categoryList.push({ key: category.key, name: category.name });
						
						// 构建产品需求行
						const rows = this.buildProductDimensionRows(productData, data, category.key);
						requirementMap[category.key] = { rows };
					}
				});
				
				this.productRequirementMap = requirementMap;
				this.productCategoryList = categoryList;
				
				if (categoryList.length > 0) {
					this.activeProductCategory = categoryList[0].key;
				}
			},
			// 解析产品JSON字符串
			parseProductJson(jsonString) {
				if (!jsonString || typeof jsonString !== 'string') {
					return null;
				}
				
				try {
					const parsed = JSON.parse(jsonString);
					return parsed;
				} catch (error) {
					console.warn('解析产品JSON失败:', error, jsonString);
					return null;
				}
			},
			// 驼峰转蛇形命名
			toSnakeCase(str) {
				if (!str) return '';
				// 在大写字母前加下划线，然后转小写，最后去掉开头的下划线
				return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
			},
			// 切换产品类别
			switchProductCategory(categoryKey) {
				this.activeProductCategory = categoryKey;
			},
			// 获取产品类别名称
			getProductCategoryName(categoryKey) {
				const category = this.productCategoryList.find(item => item.key === categoryKey);
				return category ? category.name : '';
			},
			// 获取所有产品类别名称（用于意向产品清单显示）
			getProductCategoryNames() {
				return this.productCategoryList.map(item => item.name).join('，');
			},
			parseProductAttributes(productKey, requirementText, data) {
				const attributes = {};
				const text = (requirementText || '').trim();
				if (!text) return attributes;
				
				const matchFirst = (pattern) => {
					const result = text.match(pattern);
					return result ? result[0] : '';
				};
				
				switch (productKey) {
					case 'sofa':
						attributes.type = matchFirst(/(L型|L形|一字型|U型|U形|带贵妃榻|贵妃榻|三人位|四人位|转角|组合)/);
						attributes.material = matchFirst(/(真皮|科技布|布艺|布|皮质|皮革|实木|板式|棉麻|绒布)/);
						attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m|平米|平方米)/);
						attributes.color = matchFirst(/(米白|白色|灰色|黑色|棕色|蓝色|绿色|暖色调|冷色调|灰白色系)/);
						attributes.style = matchFirst(/(现代简约|简约现代|现代|北欧|中式|美式|欧式|工业风|原木风|简约|极简)/);
						if (text.includes('储物') || text.includes('收纳')) attributes.feature = '储物';
						if (text.includes('好打理')) attributes.remark = '要求好打理';
						break;
					case 'bed':
						attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
						attributes.material = matchFirst(/(实木|板式|软包|皮质|布艺)/);
						attributes.style = data.decorationStyle || '';
						if (text.includes('主卧')) attributes.remark = '主卧';
						break;
					case 'mattress':
						attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
						attributes.material = matchFirst(/(弹簧|记忆棉|乳胶|椰棕|海绵)/);
						if (text.includes('分区支撑')) attributes.softness = '分区支撑（兼顾软硬需求）';
						else if (text.includes('偏软') || text.includes('软')) attributes.softness = '偏软';
						else if (text.includes('偏硬') || text.includes('硬')) attributes.softness = '偏硬';
						break;
					case 'dining_table':
						if (text.includes('伸缩')) attributes.type = '可伸缩';
						const rangeMatch = text.match(/(\d+\.?\d*)\s*[-~到]\s*(\d+\.?\d*)\s*米/);
						if (rangeMatch) attributes.size = `${rangeMatch[1]}-${rangeMatch[2]}米`;
						else attributes.size = matchFirst(/(\d+\.?\d*)\s*米/);
						attributes.chairCount = matchFirst(/(\d+)\s*把/);
						if (text.includes('舒适')) attributes.feature = '舒适型';
						attributes.style = data.decorationStyle || '';
						break;
					case 'tea_table':
						if (text.includes('抽屉')) attributes.type = '带抽屉';
						if (text.includes('储物') || text.includes('收纳')) attributes.feature = '储物';
						attributes.style = data.decorationStyle || '';
						break;
					case 'tv_cabinet':
						if (text.includes('组合')) attributes.type = '组合式';
						if (text.includes('储物')) attributes.feature = '储物';
						attributes.style = data.decorationStyle || '';
						break;
					case 'study_desk':
						if (text.includes('可调节') || text.includes('调节高度')) attributes.type = '可调节高度';
						if (text.includes('成长')) attributes.feature = '适应孩子成长';
						break;
					case 'wine_cabinet':
						if (text.includes('恒温')) attributes.feature = '恒温';
						const capacity = text.match(/(\d+)[-~到](\d+)\s*瓶|(\d+)\s*瓶/);
						if (capacity) {
							if (capacity[1] && capacity[2]) attributes.capacity = `${capacity[1]}-${capacity[2]}瓶`;
							else if (capacity[3]) attributes.capacity = `${capacity[3]}瓶`;
						}
						break;
					case 'master_bedroom_cabinet':
					case 'secondary_bedroom_cabinet':
						if (text.includes('定制') || text.includes('整墙')) attributes.type = text.includes('整墙') ? '整墙定制' : '定制';
						attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
						if (text.includes('衣帽间')) attributes.feature = '带衣帽间';
						if (text.includes('主卧')) attributes.remark = '主卧';
						if (text.includes('次卧')) attributes.remark = '次卧';
						break;
					case 'shoe_cabinet':
						if (text.includes('窄款') || text.includes('高型')) attributes.type = '窄款高型';
						attributes.size = matchFirst(/(\d+\.?\d*)\s*(米|m)/);
						if (text.includes('带座') || text.includes('可坐')) attributes.feature = '带座功能';
						if (text.includes('收纳空间')) attributes.remark = '大容量收纳';
						break;
					default:
						attributes.description = text;
						break;
				}
				
				if (!attributes.style && data && data.decorationStyle) attributes.style = data.decorationStyle;
				if (!attributes.color && data && data.decorationStyle) {
					const color = data.decorationStyle.match(/(米白|白色|灰色|黑色|棕色|蓝色|暖色调|冷色调|灰白色系|原木色)/);
					if (color) attributes.color = color[0];
				}
				if (!attributes.description && text) attributes.description = text;
				return attributes;
			},
			buildProductDimensionRows(productData = null, data = {}, categoryKey = '') {
				const dimensionLabels = [
					{ key: 'styleColor', label: '偏好风格与颜色', field: 'preferenceStyleAndColor' },
					{ key: 'material', label: '材质偏好', field: 'materialPreference' },
					{ key: 'focus', label: '客户重点关注', field: 'customerFocusAreas' },
					{ key: 'price', label: '价格敏感度', field: 'priceSensitivity' },
					{ key: 'campaign', label: '活动参与度', field: 'activityParticipation' },
					{ key: 'ordered', label: '客户疑虑点', field: 'customerConcerns' },
					{ key: 'service', label: '交付服务', field: 'deliveryService' },
					{ key: 'competitor', label: '竞品反馈', field: 'competitorFeedback' },
					{ key: 'delivery', label: '交付周期', field: 'deliveryCycle' },
					{ key: 'appearance', label: '产品颜值', field: 'productAppearance' }
				];
				
				// 判断productData是否是解析后的JSON对象
				// 通过检查是否包含后端返回的JSON字段来判断
				const isParsedJson = productData && 
					typeof productData === 'object' && 
					!Array.isArray(productData) && 
					productData !== null &&
					('preferenceStyleAndColor' in productData || 
					 'materialPreference' in productData || 
					 'customerConcerns' in productData);
				
				const getValue = (field) => {
					if (isParsedJson) {
						// 从解析后的JSON对象中获取字段
						const value = productData[field];
						// 如果值是字符串，去除首尾空格；如果是其他类型，转为字符串
						if (value === null || value === undefined || value === '') {
							return '暂无信息';
						}
						if (typeof value === 'string') {
							const trimmed = value.trim();
							return trimmed || '暂无信息';
						}
						return String(value) || '暂无信息';
					} else {
						// 向后兼容：从data对象中获取，或使用默认值
						// 这里productData可能是旧的attributes对象或null
						const attributes = productData || {};
						
						switch (field) {
							case 'preferenceStyleAndColor':
								const parts = [];
								if (attributes.style) parts.push(attributes.style);
								if (attributes.color) parts.push(attributes.color);
								if (parts.length === 0 && data.decorationStyle) parts.push(data.decorationStyle);
								return parts.join(' / ') || '暂无信息';
							case 'materialPreference':
								return attributes.material || '暂无信息';
							case 'customerFocusAreas':
								return attributes.feature || attributes.remark || '暂无信息';
							case 'priceSensitivity':
								return data.priceSensitivity || '暂无信息';
							case 'activityParticipation':
								return data.campaignPreference || data.activityParticipation || '暂无信息';
							case 'customerConcerns':
								return attributes.description || '暂无信息';
							case 'deliveryService':
								return data.serviceExpectation || '暂无信息';
							case 'competitorFeedback':
								return data.competitorFeedback || '暂无信息';
							case 'deliveryCycle':
								return data.deliveryCycle || '暂无信息';
							case 'productAppearance':
								return data.appearancePreference || attributes.style || '暂无信息';
							default:
								return '暂无信息';
						}
					}
				};
				
				return dimensionLabels.map(item => ({
					label: item.label,
					content: getValue(item.field) || '暂无信息'
				}));
			},
			toggleCategory(index) {
				this.performanceData.categories[index].expanded = !this.performanceData.categories[index].expanded;
			},
			toggleItem(categoryIndex, itemIndex) {
				// 可以在这里添加展开子项详情的逻辑
				console.log('查看子项详情', categoryIndex, itemIndex);
			},
			viewSummaryDetail(item) {
				// 查看总结详情
				console.log('查看总结详情', item);
			},
			viewCustomer() {
				// 查看客户详情
				this.closeDetail();
				this.switchTab('customer');
			},
			viewCustomerDetail(item) {
				// 查看客户详情
				this.currentCustomerProfile = initCustomerProfile(item);
				this.$refs.customerProfileModal.open();
			},
			// 加载待办事项列表
			async loadTodoList(params = {}) {
				try {
					// 获取parentId，从当前服务记录的rawData中获取id
					const parentId = this.currentServiceDetail.rawData?.id || this.currentServiceDetail.id;
					if (!parentId) {
						console.warn('无法获取parentId，无法加载待办事项');
						this.todoList = [];
						this.todoListTotal = 0;
						return;
					}
					
					const queryParams = {
						current: this.todoListPage.current,
						size: this.todoListPage.size,
						parentId: parentId
					};
					
					// 添加其他查询参数
					if (params.status) {
						queryParams.status = params.status;
					}
					if (params.todoTitle) {
						queryParams.todoTitle = params.todoTitle;
					}
					if (params.ownerName) {
						queryParams.ownerName = params.ownerName;
					}
					if (params.ownerPhone) {
						queryParams.ownerPhone = params.ownerPhone;
					}
					if (params.createStartTime) {
						queryParams.createStartTime = params.createStartTime;
					}
					if (params.createEndTime) {
						queryParams.createEndTime = params.createEndTime;
					}
					if (params.updateStartTime) {
						queryParams.updateStartTime = params.updateStartTime;
					}
					if (params.updateEndTime) {
						queryParams.updateEndTime = params.updateEndTime;
					}
					
					// 构建查询参数
					const queryString = Object.keys(queryParams)
						.filter(key => queryParams[key] !== null && queryParams[key] !== undefined && queryParams[key] !== '')
						.map(key => `${key}=${encodeURIComponent(queryParams[key])}`)
						.join('&');
					
					// 统一使用 getApiUrl，根据 env.js 配置自动切换环境
					const baseUrl = getApiUrl('/api/todoItem/list');
					const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
					
					const res = await uni.request({
						url: url,
						method: 'GET',
						timeout: 10000
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						this.todoList = res.data.data || [];
						this.todoListTotal = res.data.total || 0;
					} else {
						console.warn('获取待办事项失败:', res.data?.message || '未知错误');
						this.todoList = [];
						this.todoListTotal = 0;
						uni.showToast({
							title: res.data?.message || '获取待办事项失败',
							icon: 'none'
						});
					}
				} catch (error) {
					console.error('获取待办事项失败:', error);
					this.todoList = [];
					this.todoListTotal = 0;
					uni.showToast({
						title: `获取待办事项失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none',
						duration: 3000
					});
				}
			},
			// 获取待办事项状态样式类
			getTodoStatusClass(status) {
				if (!status) return 'status-pending';
				if (status.includes('完成') || status === '已完成') {
					return 'status-completed';
				}
				if (status.includes('进行') || status === '进行中') {
					return 'status-processing';
				}
				if (status.includes('待') || status === '待处理') {
					return 'status-pending';
				}
				return 'status-pending';
			},
			// 获取待办事项状态文本样式类
			getTodoStatusTextClass(status) {
				if (!status) return 'status-text-pending';
				if (status.includes('完成') || status === '已完成') {
					return 'status-text-completed';
				}
				if (status.includes('进行') || status === '进行中') {
					return 'status-text-processing';
				}
				if (status.includes('待') || status === '待处理') {
					return 'status-text-pending';
				}
				return 'status-text-pending';
			},
			// 格式化日期时间
			formatDateTime(dateTimeStr) {
				if (!dateTimeStr) return '';
				try {
					const date = new Date(dateTimeStr);
					const year = date.getFullYear();
					const month = String(date.getMonth() + 1).padStart(2, '0');
					const day = String(date.getDate()).padStart(2, '0');
					const hours = String(date.getHours()).padStart(2, '0');
					const minutes = String(date.getMinutes()).padStart(2, '0');
					return `${year}-${month}-${day} ${hours}:${minutes}`;
				} catch (error) {
					console.warn('格式化日期时间失败:', error);
					return dateTimeStr;
				}
			},
			// 判断待办事项是否为待处理状态
			isTodoPending(status) {
				if (!status) return true;
				return status.includes('待') || status === '待处理' || status === '待处理';
			},
			// 切换待办事项下拉菜单
			toggleTodoMenu(index, event) {
				if (this.activeTodoMenuIndex === index) {
					this.activeTodoMenuIndex = null;
					this.currentTodoItem = null;
					this.todoMenuStyle = {};
				} else {
					this.activeTodoMenuIndex = index;
					this.currentTodoItem = this.todoList[index];
					
					// 计算下拉菜单位置
					this.$nextTick(() => {
						const query = uni.createSelectorQuery().in(this);
						query.select(`#todo-status-${index}`).boundingClientRect((rect) => {
							if (rect) {
								// 获取窗口信息
								uni.getSystemInfo({
									success: (res) => {
										// 计算下拉菜单位置：在状态标签下方，右对齐
										// rpx转px: 1rpx = 屏幕宽度 / 750
										const rpxToPx = res.windowWidth / 750;
										const menuWidth = 200 * rpxToPx; // 菜单宽度
										const right = res.windowWidth - rect.right;
										const top = rect.bottom + 4;
										
										this.todoMenuStyle = {
											right: `${right}px`,
											top: `${top}px`,
											width: `${menuWidth}px`
										};
									}
								});
							}
						}).exec();
					});
				}
			},
			// 关闭待办事项下拉菜单
			closeTodoMenu() {
				this.activeTodoMenuIndex = null;
				this.currentTodoItem = null;
				this.todoMenuStyle = {};
			},
			// 处理完成待办事项
			async handleTodoComplete(item, index) {
				this.closeTodoMenu();
				
				const todoId = item.id;
				if (!todoId) {
					uni.showToast({
						title: '待办事项ID不存在',
						icon: 'none'
					});
					return;
				}
				
				try {
					// 统一使用 getApiUrl，根据 env.js 配置自动切换环境
					const url = getApiUrl('/api/todoItem/updateTodoStatus');
					
					const res = await uni.request({
						url: url,
						method: 'POST',
						data: {
							id: todoId
						},
						timeout: 10000,
						header: {
							'Content-Type': 'application/json'
						}
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						uni.showToast({
							title: '处理完成',
							icon: 'success'
						});
						// 刷新待办事项列表
						await this.loadTodoList();
					} else {
						uni.showToast({
							title: res.data?.message || '处理失败',
							icon: 'none'
						});
					}
				} catch (error) {
					console.error('处理待办事项失败:', error);
					uni.showToast({
						title: `处理失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none',
						duration: 3000
					});
				}
			},
			// 延期处理待办事项
			async handleTodoDelay(item, index) {
				this.closeTodoMenu();
				
				const todoId = item.id;
				if (!todoId) {
					uni.showToast({
						title: '待办事项ID不存在',
						icon: 'none'
					});
					return;
				}
				
				try {
					// 统一使用 getApiUrl，根据 env.js 配置自动切换环境
					const url = getApiUrl('/api/todoItem/delayProcessTodo');
					
					const res = await uni.request({
						url: url,
						method: 'POST',
						data: {
							id: todoId
						},
						timeout: 10000,
						header: {
							'Content-Type': 'application/json'
						}
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						uni.showToast({
							title: '已延期3天',
							icon: 'success'
						});
						// 刷新待办事项列表
						await this.loadTodoList();
					} else {
						uni.showToast({
							title: res.data?.message || '延期失败',
							icon: 'none'
						});
					}
				} catch (error) {
					console.error('延期待办事项失败:', error);
					uni.showToast({
						title: `延期失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none',
						duration: 3000
					});
				}
			},
			onCustomerProfileClose() {
				// 客户档案关闭回调
			},
			// 加载章节概要数据
			async loadChapterSummary() {
				try {
					// 获取parentId，从当前服务记录的rawData中获取id
					const parentId = this.currentServiceDetail.rawData?.id || this.currentServiceDetail.id;
					if (!parentId) {
						console.warn('无法获取parentId，无法加载章节概要');
						this.chapterSummaryList = [];
						return;
					}
					
					// 统一使用 getApiUrl，根据 env.js 配置自动切换环境
					const url = `${getApiUrl('/api/audioTextAnalysisFurniture/byParentId')}?parentId=${parentId}`;
					
					const res = await uni.request({
						url: url,
						method: 'GET',
						timeout: 10000
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						const data = res.data.data || [];
						// 构建章节概要列表，提取summary1, summary2, summary3
						const summaryList = [];
						
						// 如果返回的是数组，取第一个元素
						const item = Array.isArray(data) && data.length > 0 ? data[0] : data;
						
						if (item) {
							// 解析summary1（JSON字符串）
							if (item.summary1) {
								try {
									const summary1Data = typeof item.summary1 === 'string' 
										? JSON.parse(item.summary1) 
										: item.summary1;
									if (summary1Data && (summary1Data.customerConcerns || summary1Data.answer)) {
										summaryList.push({
											title: '章节1',
											customerConcerns: summary1Data.customerConcerns || '',
											answer: summary1Data.answer || ''
										});
									}
								} catch (error) {
									console.warn('解析summary1失败:', error);
								}
							}
							
							// 解析summary2（JSON字符串）
							if (item.summary2) {
								try {
									const summary2Data = typeof item.summary2 === 'string' 
										? JSON.parse(item.summary2) 
										: item.summary2;
									if (summary2Data && (summary2Data.customerConcerns || summary2Data.answer)) {
										summaryList.push({
											title: '章节2',
											customerConcerns: summary2Data.customerConcerns || '',
											answer: summary2Data.answer || ''
										});
									}
								} catch (error) {
									console.warn('解析summary2失败:', error);
								}
							}
							
							// 解析summary3（JSON字符串）
							if (item.summary3) {
								try {
									const summary3Data = typeof item.summary3 === 'string' 
										? JSON.parse(item.summary3) 
										: item.summary3;
									if (summary3Data && (summary3Data.customerConcerns || summary3Data.answer)) {
										summaryList.push({
											title: '章节3',
											customerConcerns: summary3Data.customerConcerns || '',
											answer: summary3Data.answer || ''
										});
									}
								} catch (error) {
									console.warn('解析summary3失败:', error);
								}
							}
						}
						
						this.chapterSummaryList = summaryList;
					} else {
						console.warn('获取章节概要失败:', res.data?.message || '未知错误');
						this.chapterSummaryList = [];
					}
				} catch (error) {
					console.error('获取章节概要失败:', error);
					this.chapterSummaryList = [];
				}
			},
			// 加载服务表现数据
			async loadPerformanceData() {
				try {
					// 获取parentId，从当前服务记录的rawData中获取id
					const parentId = this.currentServiceDetail.rawData?.id || this.currentServiceDetail.id;
					if (!parentId) {
						console.warn('无法获取parentId，无法加载服务表现数据');
						// 使用默认数据
						this.performanceData = initPerformanceData();
						return;
					}
					
					// 统一使用 getApiUrl，根据 env.js 配置自动切换环境
					const url = `${getApiUrl('/api/audioTextAnalysisSop/listByParentId')}?parentId=${parentId}`;
					
					const res = await uni.request({
						url: url,
						method: 'GET',
						timeout: 10000
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						const data = res.data.data;
						// 如果返回的是数组，取第一个元素
						const sopData = Array.isArray(data) && data.length > 0 ? data[0] : data;
						if (sopData) {
							// 将后端数据转换为前端需要的格式
							this.performanceData = this.convertSopDataToPerformanceData(sopData);
						} else {
							console.warn('服务表现数据为空');
							// 使用默认数据
							this.performanceData = initPerformanceData();
						}
					} else {
						console.warn('获取服务表现数据失败:', res.data?.message || '未知错误');
						// 使用默认数据
						this.performanceData = initPerformanceData();
					}
				} catch (error) {
					console.error('获取服务表现数据失败:', error);
					// 使用默认数据
					this.performanceData = initPerformanceData();
				}
			},
			// 将后端SOP数据转换为前端performanceData格式
			convertSopDataToPerformanceData(sopData) {
				// 判断分数是否完成（分数大于等于60分认为完成）
				const isCompleted = (score) => score !== null && score !== undefined && score >= 60;
				
				// 收集所有子项的分数用于计算总分
				const allScores = [
					sopData.greetingIceBreaking,
					sopData.brandIntroduction,
					sopData.goldenThreeQuestions,
					sopData.needsGuidance,
					sopData.serviceProgression,
					sopData.reassuranceHandbook,
					sopData.threeLevelPricing,
					sopData.objectionHandling,
					sopData.activityImplantation,
					sopData.closingCooperation,
					sopData.proactiveWechatAdd,
					sopData.politeFarewell
				].filter(score => score !== null && score !== undefined);
				
				// 计算总分：优先使用后端返回的comprehensiveScore，如果没有则计算所有子项的平均分
				let totalScore = sopData.comprehensiveScore || sopData.comprehensive_score;
				if (totalScore === null || totalScore === undefined) {
					// 如果后端没有返回总分，则计算所有子项的平均分
					if (allScores.length > 0) {
						const sum = allScores.reduce((acc, score) => acc + score, 0);
						totalScore = Math.round(sum / allScores.length);
					} else {
						totalScore = 0;
					}
				}
				
				// 构建分类和子项数据
				const categories = [
					{
						name: '迎宾探寻',
						completed: isCompleted(sopData.greetingIceBreaking) || isCompleted(sopData.brandIntroduction),
						expanded: true,
						showBanner: false,
						showAudio: false,
						items: [
							{ 
								name: '破冰', 
								completed: isCompleted(sopData.greetingIceBreaking), 
								points: sopData.greetingIceBreaking || 0 
							},
							{ 
								name: '品牌介绍', 
								completed: isCompleted(sopData.brandIntroduction), 
								points: sopData.brandIntroduction || 0 
							}
						]
					},
					{
						name: '展厅体验',
						completed: isCompleted(sopData.goldenThreeQuestions) || isCompleted(sopData.needsGuidance),
						expanded: true,
						showBanner: false,
						showAudio: false,
						items: [
							{ 
								name: '黄金三问', 
								completed: isCompleted(sopData.goldenThreeQuestions), 
								points: sopData.goldenThreeQuestions || 0 
							},
							{ 
								name: '需求引导', 
								completed: isCompleted(sopData.needsGuidance), 
								points: sopData.needsGuidance || 0 
							}
						]
					},
					{
						name: '落座规划',
						completed: isCompleted(sopData.serviceProgression) || isCompleted(sopData.reassuranceHandbook),
						expanded: true,
						showBanner: false,
						showAudio: false,
						items: [
							{ 
								name: '服务递进', 
								completed: isCompleted(sopData.serviceProgression), 
								points: sopData.serviceProgression || 0 
							},
							{ 
								name: 'SGS放心手册', 
								completed: isCompleted(sopData.reassuranceHandbook), 
								points: sopData.reassuranceHandbook || 0 
							}
						]
					},
					{
						name: '方案报价',
						completed: isCompleted(sopData.threeLevelPricing),
						expanded: true,
						showBanner: false,
						showAudio: false,
						items: [
							{ 
								name: '三级报价', 
								completed: isCompleted(sopData.threeLevelPricing), 
								points: sopData.threeLevelPricing || 0 
							}
						]
					},
					{
						name: '促单成交',
						completed: isCompleted(sopData.objectionHandling),
						expanded: true,
						showBanner: false,
						showAudio: false,
						items: [
							{ 
								name: '解答异议', 
								completed: isCompleted(sopData.objectionHandling), 
								points: sopData.objectionHandling || 0 
							}
						]
					},
					{
						name: '送客跟进',
						completed: isCompleted(sopData.activityImplantation) || 
								   isCompleted(sopData.closingCooperation) || 
								   isCompleted(sopData.proactiveWechatAdd) || 
								   isCompleted(sopData.politeFarewell),
						expanded: true,
						showBanner: false,
						showAudio: false,
						items: [
							{ 
								name: '活动植入', 
								completed: isCompleted(sopData.activityImplantation), 
								points: sopData.activityImplantation || 0 
							},
							{ 
								name: '压单配合', 
								completed: isCompleted(sopData.closingCooperation), 
								points: sopData.closingCooperation || 0 
							},
							{ 
								name: '主动添加微信', 
								completed: isCompleted(sopData.proactiveWechatAdd), 
								points: sopData.proactiveWechatAdd || 0 
							},
							{ 
								name: '邀约量尺时间', 
								completed: false, 
								points: 0 
							},
							{ 
								name: '礼貌道别', 
								completed: isCompleted(sopData.politeFarewell), 
								points: sopData.politeFarewell || 0 
							}
						]
					}
				];
				
				return {
					totalScore: totalScore,
					categories: categories
				};
			},
			// 加载服务记录列表
			async loadServiceList(params = {}) {
				try {
					// 构建查询参数对象（后端使用 @RequestParam，参数需要作为 URL 查询参数传递）
					const queryParams = {
						current: this.serviceListPage.current,
						size: this.serviceListPage.size,
						serviceStatus: '服务结束'  // 默认搜索条件：服务结束
					};
					
					// 添加查询参数：所属销售姓名和客户姓名
					const trimmedSalesName = params.salesName?.trim();
					const trimmedCustomerName = params.customerName?.trim();
					if (trimmedSalesName) {
						queryParams.salesName = trimmedSalesName;
					}
					if (trimmedCustomerName) {
						queryParams.customerName = trimmedCustomerName;
					}
					
					// 将参数转换为 URL 查询字符串（因为后端使用 @RequestParam）
					const queryString = Object.keys(queryParams)
						.filter(key => queryParams[key] !== null && queryParams[key] !== undefined && queryParams[key] !== '')
						.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
						.join('&');
					
					// 调试：打印请求参数
					console.log('服务记录查询参数:', JSON.stringify(queryParams));
					console.log('查询字符串:', queryString);
					
					// 后端使用 @RequestParam，参数需要作为 URL 查询参数传递
					const baseUrl = getApiUrl('/api/audioManagement/list');
					const url = queryString ? `${baseUrl}?${queryString}` : baseUrl;
					
					// 获取认证信息
					let tenantId = '';
					let token = '';
					try {
						tenantId = uni.getStorageSync('backend-tenant-id') || '';
						token = uni.getStorageSync('backend-token') || '';
					} catch (e) {
						console.error('获取认证信息失败:', e);
					}
					
					// 构建请求头（参考接待页面的实现方式）
					const headers = {
						'Content-Type': 'application/json'
					};
					if (token) {
						headers['Authorization'] = `Bearer ${token}`;
					}
					if (tenantId) {
						headers['X-Tenant-Id'] = tenantId;
					}
					
					const res = await uni.request({
						url,
						method: 'POST',
						data: {},  // POST 请求体为空，参数都在 URL 查询字符串中
						header: headers,
						timeout: 10000
					});
					
					if (res.statusCode === 200 && res.data && res.data.success) {
						// 转换后端数据为页面需要的格式
						const mappedList = res.data.data.map(item => {
							const extensionFromName = () => {
								const n = item.audioFileOriginalName;
								if (n && typeof n === 'string') {
									const i = n.lastIndexOf('.');
									if (i !== -1 && i < n.length - 1) return n.slice(i + 1);
								}
								return null;
							};
							// 列表展示时间：按需求优先显示更新时间，兼容多种命名，最后退回开始/创建时间
							const recordingStartRaw =
								item.updateTime ||
								item.update_time ;
							let formattedTime = '';
							if (recordingStartRaw) {
								const date = new Date(recordingStartRaw);
								if (!Number.isNaN(date.getTime())) {
									const year = date.getFullYear();
									const month = String(date.getMonth() + 1).padStart(2, '0');
									const day = String(date.getDate()).padStart(2, '0');
									const hours = String(date.getHours()).padStart(2, '0');
									const minutes = String(date.getMinutes()).padStart(2, '0');
									const seconds = String(date.getSeconds()).padStart(2, '0');
									formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
								}
							}

							return {
							id: item.id,
							title: `${item.salesName || ''}的服务记录`,
							date: formattedTime ? `更新时间：${formattedTime}` : '',
							description: item.summary || '',
							customerName: item.customerName || '',
							recordingName: item.recordingName || '', // 记录名称
							duration: item.duration,
							audioFileExtension: item.audioFileExtension != null && item.audioFileExtension !== ''
								? item.audioFileExtension
								: extensionFromName(),
							recordingText: item.recordingText || '',
							// 保留原始数据，用于详情页
							rawData: item
						};
						});
						// 分页：第一页或刷新时重置，其他情况追加
						if (this.serviceListPage.current === 1) {
							this.serviceList = mappedList;
						} else {
							this.serviceList = this.serviceList.concat(mappedList);
						}
						this.serviceListTotal = res.data.total || 0;
					} else {
						uni.showToast({
							title: res.data.message || '获取服务记录失败',
							icon: 'none'
						});
					}
				} catch (error) {
					console.error('获取服务记录失败:', error);
					uni.showToast({
						title: `获取服务记录失败: ${error.errMsg || error.message || '未知错误'}`,
						icon: 'none',
						duration: 3000
					});
				}
			},

			// 页面加载后的URL隐藏初始化：只在用户导航时执行
			initUrlHidingAfterPageLoad() {
				// #ifdef H5
				console.log('[FurnitureCustomer][initUrlHidingAfterPageLoad] 开始页面加载后URL隐藏初始化');

				// 路径映射
				this.urlPathMap = {
					'pages-subpackage/furniture_customer/furniture_customer': '/customer',
					'pages/furniture_reception/furniture_reception': '/reception',
					'pages/ai_qa/ai_qa': '/ai-qa',
					'pages/ai_analysis/ai_analysis': '/ai-analysis',
					'pages/xixi/xixi': '/xixi',
					'pages/ucenter/ucenter': '/profile'
				};

				// 策略：只在用户明确进行页面导航时才隐藏URL
				// 避免在页面刷新或直接访问时执行，以防止空白页面

				// 监听tabBar切换事件（用户主动导航）
				this.setupTabNavigationHiding();

				// 监听浏览器前进后退（用户主动导航）
				this.setupBrowserNavigationHiding();

				console.log('[FurnitureCustomer][initUrlHidingAfterPageLoad] URL隐藏系统已准备，只在用户导航时激活');
				// #endif
			},

			// 设置tab导航时的URL隐藏
			setupTabNavigationHiding() {
				// #ifdef H5
				console.log('[FurnitureCustomer][setupTabNavigationHiding] 设置tab导航监听');

				// 监听uni-app的页面显示事件（当通过tabBar切换到此页面时）
				if (typeof uni !== 'undefined' && uni.on) {
					uni.on('onShow', () => {
						console.log('[FurnitureCustomer][setupTabNavigationHiding] 页面显示事件触发，可能是tab切换');
						// 延迟检查，确保是tab切换而不是页面刷新
						setTimeout(() => {
							this.attemptUrlHidingForCurrentPage();
						}, 300);
					});
				}

				console.log('[FurnitureCustomer][setupTabNavigationHiding] tab导航监听已设置');
				// #endif
			},

			// 设置浏览器导航时的URL隐藏
			setupBrowserNavigationHiding() {
				// #ifdef H5
				console.log('[FurnitureCustomer][setupBrowserNavigationHiding] 设置浏览器导航监听');

				// 监听前进后退按钮
				window.addEventListener('popstate', () => {
					console.log('[FurnitureCustomer][setupBrowserNavigationHiding] 浏览器前进后退事件');
					setTimeout(() => {
						this.attemptUrlHidingForCurrentPage();
					}, 200);
				});

				console.log('[FurnitureCustomer][setupBrowserNavigationHiding] 浏览器导航监听已设置');
				// #endif
			},

			// 为当前页面尝试URL隐藏
			attemptUrlHidingForCurrentPage() {
				// #ifdef H5
				try {
					const pages = getCurrentPages();
					if (pages.length === 0) {
						console.log('[FurnitureCustomer][attemptUrlHidingForCurrentPage] 页面栈为空，跳过');
						return;
					}

					const currentPage = pages[pages.length - 1];
					const currentPath = currentPage.route;

					if (!currentPath) {
						console.log('[FurnitureCustomer][attemptUrlHidingForCurrentPage] 页面路径为空，跳过');
						return;
					}

					// 只为当前页面的路径执行URL隐藏
					if (currentPath === 'pages-subpackage/furniture_customer/furniture_customer' && this.urlPathMap[currentPath]) {
						const shortPath = this.urlPathMap[currentPath];
						const currentPathname = window.location.pathname;

						if (currentPathname !== shortPath) {
							console.log(`[FurnitureCustomer][attemptUrlHidingForCurrentPage] 执行URL隐藏: ${currentPathname} -> ${shortPath}`);

							// 使用try-catch包装history操作
							try {
								const newUrl = `${window.location.origin}${shortPath}`;
								window.history.replaceState(null, '', newUrl);
								console.log('[FurnitureCustomer][attemptUrlHidingForCurrentPage] URL隐藏成功');
							} catch (historyError) {
								console.warn('[FurnitureCustomer][attemptUrlHidingForCurrentPage] history操作失败:', historyError);
							}
						} else {
							console.log('[FurnitureCustomer][attemptUrlHidingForCurrentPage] URL已经是隐藏状态');
						}
					}
				} catch (error) {
					console.warn('[FurnitureCustomer][attemptUrlHidingForCurrentPage] URL隐藏尝试失败:', error);
				}
				// #endif
			}

		}
	}
</script>

<style>
	page {
		background-color: #F5F5F5;
	}
	
	.page {
		min-height: 100vh;
		background-color: #F5F5F5;
	}
	
	.content {
		padding-top: 0; /* 移除padding-top，因为tab页和scroll-view都使用绝对定位 */
		margin-top: 0;
		position: relative;
		/* #ifndef MP-WEIXIN */
		min-height: 100vh; /* 确保content有足够高度 */
		/* #endif */
		/* #ifdef MP-WEIXIN */
		/* 微信小程序：确保内容容器铺满整个视口，底部导航栏是 fixed 定位，不占用文档流 */
		height: 100vh !important;
		min-height: 100vh !important;
		max-height: 100vh !important;
		/* #endif */
	}
	
	/* 隐藏导航栏占位区域，避免产生空白 */
	::v-deep .uni-navbar__placeholder {
		display: none !important;
	}
	
	/* 标签页 - 使用绝对定位紧贴导航栏 */
	.tabs {
		display: flex !important; /* 强制显示 */
		visibility: visible !important; /* 强制可见 */
		opacity: 1 !important; /* 强制不透明 */
		background-color: #FFFFFF;
		border-bottom: 1px solid #E0E0E0;
		padding: 0 16rpx;
		margin-top: 0;
		position: fixed; /* 改为fixed定位，确保始终可见 */
		/* 导航栏高度：statusBar + navbar，动态计算 */
		/* 使用内联样式动态设置top值 */
		left: 0;
		right: 0;
		z-index: 999; /* 提高z-index确保在最上层 */
		height: 72rpx; /* 明确设置标签页高度 */
		box-sizing: border-box;
		align-items: center;
		/* 确保tab栏始终可见 */
		will-change: top; /* 优化渲染性能 */
	}
	
	.tab-item {
		padding: 24rpx 32rpx;
		position: relative;
	}
	
	.tab-item text {
		font-size: 30rpx;
		color: #666;
	}
	
	.tab-item.active text {
		color: #333;
		font-weight: 500;
	}
	
	.tab-item.active::after {
		content: '';
		position: absolute;
		bottom: 0;
		left: 32rpx;
		right: 32rpx;
		height: 4rpx;
		background-color: #007AFF;
		border-radius: 2rpx;
	}
	
	/* 服务记录列表容器 */
	/* 标签管理列表区：使用绝对定位，与服务状态列表保持一致 */
	.tag-list {
		/* 使用绝对定位，从tab页底部开始，到底部导航栏结束 */
		position: absolute;
		/* top值通过内联样式动态设置 */
		left: 0;
		right: 0;
		/* #ifndef MP-WEIXIN */
		bottom: 96rpx; /* H5环境：底部导航栏高度 */
		/* #endif */
		/* #ifdef MP-WEIXIN */
		/* 微信小程序：底部导航栏是 fixed 定位，不占用文档流，容器可以延伸到视口底部 */
		bottom: 0 !important;
		/* #endif */
		background-color: #F5F5F5;
		padding: 24rpx 16rpx 0 16rpx;
		padding-bottom: 0 !important; /* 确保底部没有padding */
		box-sizing: border-box;
	}
	
	.service-list-container,
	.customer-list-container {
		/* 兼容旧样式，但使用新的 tag-list 样式 */
		position: absolute;
		left: 0;
		right: 0;
		/* #ifndef MP-WEIXIN */
		bottom: 96rpx;
		/* #endif */
		/* #ifdef MP-WEIXIN */
		bottom: 0 !important;
		/* #endif */
	}
	
	/* 列表头部 */
	.list-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 24rpx 32rpx;
		background-color: #FFFFFF;
		border-bottom: 1px solid #F0F0F0;
	}
	
	.total {
		font-size: 28rpx;
		color: #666;
	}
	
	.filter-btn {
		padding: 8rpx 16rpx;
		background-color: #F5F5F5;
		border-radius: 8rpx;
	}
	
	.filter-btn text {
		font-size: 24rpx;
		color: #666;
	}
	
	/* 服务记录列表 */
	.service-list {
		height: calc(100vh - 420rpx);
		background-color: #FFFFFF;
	}
	
	.service-item {
		padding: 32rpx;
		border-bottom: 1px solid #F0F0F0;
		background-color: #FFFFFF;
	}
	
	.service-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 16rpx;
	}
	
	.service-title {
		font-size: 32rpx;
		font-weight: 500;
		color: #333;
	}
	
	.service-actions {
		display: flex;
		align-items: center;
	}
	
	.archive-text {
		font-size: 26rpx;
		color: #999;
		margin-right: 8rpx;
	}
	
	.service-meta {
		display: flex;
		align-items: center;
		margin-bottom: 16rpx;
	}
	
	.service-date {
		font-size: 24rpx;
		color: #999;
		margin-right: 16rpx;
	}
	
	.service-duration {
		font-size: 24rpx;
		color: #999;
	}
	
	.service-content {
		margin-bottom: 24rpx;
	}
	
	.service-desc {
		font-size: 28rpx;
		color: #666;
		line-height: 1.6;
	}
	
	.service-customer {
		display: flex;
		align-items: center;
		margin-bottom: 16rpx;
	}
	
	.customer-avatar {
		width: 64rpx;
		height: 64rpx;
		background-color: #2196F3;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 16rpx;
	}
	
	.avatar-text {
		font-size: 32rpx;
		color: #FFFFFF;
		font-weight: 500;
	}
	
	.customer-name {
		font-size: 28rpx;
		color: #333;
	}
	
	.ai-tag {
		padding-top: 16rpx;
		border-top: 1px solid #F0F0F0;
	}
	
	.ai-tag text {
		font-size: 24rpx;
		color: #999;
	}
	
	/* 服务记录详情弹窗 */
	.service-detail-modal {
		background-color: #FFFFFF;
		border-radius: 32rpx 32rpx 0 0;
		max-height: 90vh;
		display: flex;
		flex-direction: column;
		overflow: hidden;
	}
	
	.modal-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 32rpx;
		border-bottom: 1px solid #F0F0F0;
	}
	
	.modal-close,
	.modal-share {
		width: 48rpx;
		height: 48rpx;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	
	.modal-title {
		font-size: 36rpx;
		font-weight: 600;
		color: #333;
		flex: 1;
		text-align: center;
	}
	
	.modal-date {
		padding: 16rpx 32rpx;
	}
	
	.modal-date text {
		font-size: 24rpx;
		color: #999;
	}
	
	.modal-banner {
		background-color: #E3F2FD;
		padding: 24rpx 32rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin: 0 32rpx 24rpx;
		border-radius: 16rpx;
	}
	
	.modal-banner .banner-left {
		display: flex;
		align-items: center;
		flex: 1;
	}
	
	.modal-banner .banner-icon {
		width: 40rpx;
		height: 40rpx;
		background-color: #FFFFFF;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 12rpx;
	}
	
	.modal-banner .banner-text {
		font-size: 26rpx;
		color: #1976D2;
		flex: 1;
	}
	
	.modal-banner .banner-right {
		font-size: 28rpx;
		color: #1976D2;
		font-weight: 500;
		margin-left: 16rpx;
	}
	
	/* 音频播放器 */
	.audio-player {
		display: flex;
		align-items: center;
		padding: 24rpx 32rpx;
		margin: 0 32rpx 24rpx;
		background-color: #F5F5F5;
		border-radius: 16rpx;
	}
	
	.play-btn {
		width: 48rpx;
		height: 48rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 16rpx;
	}
	
	.progress-bar {
		flex: 1;
		height: 4rpx;
		background-color: #E0E0E0;
		border-radius: 2rpx;
		margin: 0 16rpx;
		position: relative;
	}
	
	.progress-line {
		width: 30%;
		height: 100%;
		background-color: #007AFF;
		border-radius: 2rpx;
		position: relative;
	}
	
	.progress-dot {
		position: absolute;
		right: -8rpx;
		top: 50%;
		transform: translateY(-50%);
		width: 16rpx;
		height: 16rpx;
		background-color: #007AFF;
		border-radius: 50%;
		border: 2rpx solid #FFFFFF;
	}
	
	.audio-time {
		font-size: 24rpx;
		color: #666;
		margin-right: 16rpx;
		min-width: 200rpx;
	}
	
	.speed-btn {
		padding: 8rpx 16rpx;
		background-color: #FFFFFF;
		border-radius: 8rpx;
		border: 1px solid #E0E0E0;
	}
	
	.speed-btn text {
		font-size: 24rpx;
		color: #333;
	}
	
	/* 详情标签页 */
	.detail-tabs {
		display: flex;
		background-color: #FFFFFF;
		border-bottom: 1px solid #E0E0E0;
		padding: 0 32rpx;
		overflow-x: auto;
		position: sticky;
		top: 0;
		z-index: 10;
		flex-shrink: 0;
	}
	
	.detail-tab-item {
		padding: 24rpx 16rpx;
		position: relative;
		white-space: nowrap;
		margin-right: 32rpx;
	}
	
	.detail-tab-item text {
		font-size: 28rpx;
		color: #666;
	}
	
	.detail-tab-item.active text {
		color: #333;
		font-weight: 500;
	}
	
	.detail-tab-item.active::after {
		content: '';
		position: absolute;
		bottom: 0;
		left: 16rpx;
		right: 16rpx;
		height: 4rpx;
		background-color: #007AFF;
		border-radius: 2rpx;
	}
	
	/* 详情内容 */
	.detail-content {
		flex: 1;
		padding: 24rpx 32rpx;
		background-color: #FFFFFF;
		overflow-y: auto;
		min-height: 0;
	}
	
	.summary-item {
		padding: 24rpx 0;
		border-bottom: 1px solid #F0F0F0;
		display: flex;
		flex-direction: column;
		position: relative;
		padding-right: 40rpx;
	}
	
	.summary-item:last-child {
		border-bottom: none;
	}
	
	.summary-label {
		margin-bottom: 12rpx;
	}
	
	.summary-label text {
		font-size: 28rpx;
		color: #666;
		font-weight: 500;
	}
	
	.summary-value {
		flex: 1;
	}
	
	.summary-value text {
		font-size: 28rpx;
		color: #333;
		line-height: 1.6;
	}
	
	.summary-item uni-icons {
		position: absolute;
		right: 0;
		top: 50%;
		transform: translateY(-50%);
	}
	
	.empty-detail {
		padding: 80rpx 0;
		text-align: center;
	}
	
	.empty-detail text {
		font-size: 28rpx;
		color: #999;
	}
	
	/* 底部客户信息 */
	.modal-footer {
		display: flex;
		align-items: center;
		padding: 24rpx 32rpx;
		border-top: 1px solid #F0F0F0;
		background-color: #FFFFFF;
	}
	
	.footer-label {
		font-size: 28rpx;
		color: #666;
		margin: 0 8rpx 0 12rpx;
	}
	
	.footer-customer {
		font-size: 28rpx;
		color: #1976D2;
		flex: 1;
	}
	
	/* 服务表现样式 */
	.performance-score {
		text-align: center;
		padding: 40rpx 32rpx;
		background-color: #FFFFFF;
		border-bottom: 1px solid #F0F0F0;
	}
	
	.score-label {
		display: block;
		font-size: 28rpx;
		color: #666;
		margin-bottom: 16rpx;
	}
	
	.score-value {
		display: block;
		font-size: 72rpx;
		font-weight: 600;
		color: #007AFF;
	}
	
	.performance-category {
		background-color: #FFFFFF;
		border-bottom: 1px solid #F0F0F0;
	}
	
	.category-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 32rpx;
	}
	
	.category-left {
		display: flex;
		align-items: center;
		flex: 1;
	}
	
	.category-bullet {
		width: 16rpx;
		height: 16rpx;
		border-radius: 50%;
		margin-right: 16rpx;
	}
	
	.bullet-blue {
		background-color: #007AFF;
	}
	
	.bullet-gray {
		background-color: #999;
	}
	
	.category-name {
		font-size: 30rpx;
		color: #333;
		font-weight: 500;
	}
	
	.category-content {
		padding: 0 32rpx 32rpx;
	}
	
	.performance-banner {
		background-color: #E3F2FD;
		padding: 24rpx 32rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 24rpx;
		border-radius: 16rpx;
	}
	
	.performance-banner .banner-left {
		display: flex;
		align-items: center;
		flex: 1;
	}
	
	.performance-banner .banner-icon {
		width: 40rpx;
		height: 40rpx;
		background-color: #FFFFFF;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 12rpx;
	}
	
	.performance-banner .banner-text {
		font-size: 26rpx;
		color: #1976D2;
		flex: 1;
	}
	
	.performance-banner .banner-right {
		font-size: 28rpx;
		color: #1976D2;
		font-weight: 500;
		margin-left: 16rpx;
	}
	
	.performance-audio {
		margin-bottom: 24rpx;
	}
	
	.performance-audio .audio-player {
		margin: 0;
	}
	
	.performance-item {
		margin-bottom: 16rpx;
	}
	
	.performance-item.item-completed {
		background-color: #E8F5E9;
		border-radius: 12rpx;
		padding: 16rpx;
	}
	
	.item-content {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 16rpx 0;
	}
	
	.item-left {
		display: flex;
		align-items: center;
		flex: 1;
		flex-wrap: wrap;
		gap: 12rpx;
	}
	
	.item-name {
		font-size: 28rpx;
		color: #333;
		margin-right: 16rpx;
	}
	
	.item-status {
		font-size: 24rpx;
		padding: 4rpx 12rpx;
		border-radius: 8rpx;
	}
	
	.status-completed {
		background-color: #4CAF50;
		color: #FFFFFF;
	}
	
	.status-missing {
		background-color: #F5F5F5;
		color: #999;
	}
	
	.item-points {
		font-size: 24rpx;
		color: #007AFF;
		font-weight: 500;
		margin-left: 8rpx;
	}
	
	/* 产品类别标签页 */
	.product-category-tabs {
		background-color: #FFFFFF;
		border-bottom: 1px solid #E0E0E0;
		margin-bottom: 24rpx;
		padding: 0;
	}
	
	.category-tabs-scroll {
		white-space: nowrap;
		width: 100%;
	}
	
	.category-tabs-wrapper {
		display: inline-flex;
		padding: 0 32rpx;
	}
	
	.category-tab-item {
		padding: 24rpx 16rpx;
		position: relative;
		margin-right: 32rpx;
		white-space: nowrap;
	}
	
	.category-tab-item text {
		font-size: 28rpx;
		color: #666;
	}
	
	.category-tab-item.active text {
		color: #333;
		font-weight: 500;
	}
	
	.category-tab-item.active::after {
		content: '';
		position: absolute;
		bottom: 0;
		left: 16rpx;
		right: 16rpx;
		height: 4rpx;
		background-color: #007AFF;
		border-radius: 2rpx;
	}
	
	/* 产品需求清单表格 */
	.product-requirement-table {
		background-color: #FFFFFF;
		padding: 0;
	}
	
	.requirement-title {
		padding: 24rpx 32rpx;
		font-size: 32rpx;
		font-weight: 600;
		color: #333;
		border-bottom: 1px solid #F0F0F0;
	}
	
	.requirement-table {
		padding: 0 32rpx 24rpx;
	}
	
	.requirement-row {
		display: flex;
		padding: 24rpx 0;
		border-bottom: 1px solid #F0F0F0;
	}
	
	.requirement-row:last-child {
		border-bottom: none;
	}
	
	.requirement-label {
		min-width: 200rpx;
		width: 200rpx;
		padding-right: 24rpx;
	}
	
	.requirement-label text {
		font-size: 28rpx;
		color: #666;
		font-weight: 500;
	}
	
	.requirement-content {
		flex: 1;
	}
	
	.requirement-content text {
		font-size: 28rpx;
		color: #333;
		line-height: 1.6;
	}
	
	/* 待办事项列表 */
	.todo-list {
		padding: 0;
	}
	
	.todo-item {
		padding: 32rpx;
		border-bottom: 1px solid #F0F0F0;
		background-color: #FFFFFF;
	}
	
	.todo-item:last-child {
		border-bottom: none;
	}
	
	.todo-item.todo-completed {
		background-color: #F5F5F5;
		opacity: 0.8;
	}
	
	.todo-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 16rpx;
	}
	
	.todo-title-wrapper {
		display: flex;
		align-items: center;
		flex: 1;
	}
	
	.todo-status-dot {
		width: 16rpx;
		height: 16rpx;
		border-radius: 50%;
		margin-right: 12rpx;
		flex-shrink: 0;
	}
	
	.todo-status-dot.status-pending {
		background-color: #FF9800;
	}
	
	.todo-status-dot.status-processing {
		background-color: #2196F3;
	}
	
	.todo-status-dot.status-completed {
		background-color: #4CAF50;
	}
	
	.todo-title {
		font-size: 32rpx;
		font-weight: 500;
		color: #333;
		flex: 1;
	}
	
	.todo-status {
		font-size: 24rpx;
		padding: 6rpx 16rpx;
		border-radius: 12rpx;
		white-space: nowrap;
	}
	
	.todo-status.status-text-pending {
		background-color: #FFF3E0;
		color: #FF9800;
	}
	
	.todo-status.status-text-processing {
		background-color: #E3F2FD;
		color: #2196F3;
	}
	
	.todo-status.status-text-completed {
		background-color: #E8F5E9;
		color: #4CAF50;
	}
	
	.todo-status-wrapper {
		position: relative;
		z-index: 10;
	}
	
	.todo-status-clickable {
		display: flex;
		align-items: center;
	}
	
	.todo-item.todo-clickable .todo-status-clickable {
		position: relative;
	}
	
	.todo-menu-fixed {
		position: fixed;
		background-color: #FFFFFF;
		border-radius: 8rpx;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
		z-index: 10000;
		overflow: hidden;
	}
	
	.todo-menu-item {
		padding: 24rpx 32rpx;
		border-bottom: 1px solid #F0F0F0;
		transition: background-color 0.2s;
	}
	
	.todo-menu-fixed .todo-menu-item:last-child {
		border-bottom: none;
	}
	
	.todo-menu-item:active {
		background-color: #F5F5F5;
	}
	
	.todo-menu-item text {
		font-size: 28rpx;
		color: #333;
	}
	
	.todo-menu-mask {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.01);
		z-index: 9999;
	}
	
	.todo-content {
		margin-bottom: 16rpx;
		padding: 16rpx;
		background-color: #F5F5F5;
		border-radius: 8rpx;
	}
	
	.todo-content text {
		font-size: 28rpx;
		color: #666;
		line-height: 1.6;
	}
	
	.todo-meta {
		display: flex;
		flex-wrap: wrap;
		gap: 16rpx;
	}
	
	.todo-meta-item {
		font-size: 24rpx;
		color: #999;
	}
	
	/* 章节概要样式 */
	.chapter-summary-list {
		padding: 0;
	}
	
	.chapter-summary-item {
		background-color: #FFFFFF;
		border-radius: 16rpx;
		padding: 32rpx;
		margin-bottom: 24rpx;
		border: 1px solid #F0F0F0;
	}
	
	.chapter-summary-item:last-child {
		margin-bottom: 0;
	}
	
	.chapter-summary-title {
		margin-bottom: 24rpx;
		padding-bottom: 16rpx;
		border-bottom: 2px solid #007AFF;
	}
	
	.chapter-summary-title text {
		font-size: 32rpx;
		font-weight: 600;
		color: #333;
	}
	
	.chapter-summary-section {
		margin-bottom: 24rpx;
	}
	
	.chapter-summary-section:last-child {
		margin-bottom: 0;
	}
	
	.chapter-summary-label {
		margin-bottom: 12rpx;
	}
	
	.chapter-summary-label text {
		font-size: 28rpx;
		font-weight: 500;
		color: #666;
	}
	
	.chapter-summary-content {
		background-color: #F5F5F5;
		border-radius: 12rpx;
		padding: 20rpx;
	}
	
	.chapter-summary-content text {
		font-size: 28rpx;
		color: #333;
		line-height: 1.8;
	}
	
	/* 录音列表弹窗样式 */
	.audio-list-modal {
		background-color: #FFFFFF;
		border-radius: 32rpx 32rpx 0 0;
		max-height: 90vh;
		height: 90vh;
		display: flex;
		flex-direction: column;
		overflow: hidden;
	}
	
	.audio-list-content {
		flex: 1;
		padding: 24rpx 32rpx;
		box-sizing: border-box;
		background-color: #F5F5F5;
		min-height: 0; /* 配合 flex: 1 使用，确保可以滚动 */
		height: 100%;
	}
	
	.audio-list-item {
		background-color: #FFFFFF;
		border-radius: 16rpx;
		padding: 32rpx;
		margin-bottom: 24rpx;
		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
	}
	
	.audio-item-header {
		margin-bottom: 16rpx;
		display: flex;
		align-items: center;
	}
	
	.audio-play-btn {
		min-width: 80rpx;
		height: 56rpx;
		padding: 0 20rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 16rpx;
		cursor: pointer;
		border-radius: 8rpx;
		transition: background-color 0.2s;
		flex-shrink: 0;
		background-color: #F5F5F5;
		position: relative;
		z-index: 1;
	}
	
	.audio-play-btn:active {
		background-color: #E0E0E0;
	}
	
	.audio-play-text {
		font-size: 24rpx;
		color: #2A68FF;
		font-weight: 500;
		line-height: 1;
	}
	
	.audio-play-text--playing {
		color: #FF3B30;
	}
	
	.audio-item-name {
		font-size: 32rpx;
		font-weight: 500;
		color: #333;
		flex: 1;
	}
	
	.audio-item-info {
		margin-bottom: 16rpx;
	}
	
	.audio-item-text {
		font-size: 28rpx;
		color: #666;
		line-height: 1.6;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		display: block;
	}
	
	.audio-item-text--empty {
		color: #999;
		font-style: italic;
	}
	
	.audio-item-transcribe {
		display: flex;
		align-items: center;
	}
	
	.transcribe-btn {
		padding: 12rpx 24rpx;
		background-color: #007AFF;
		border-radius: 8rpx;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
		transition: background-color 0.2s, opacity 0.2s;
	}
	
	.transcribe-btn:active {
		background-color: #0056CC;
	}
	
	.transcribe-btn--loading {
		opacity: 0.6;
		background-color: #999;
		cursor: not-allowed;
	}
	
	.transcribe-btn text {
		font-size: 26rpx;
		color: #FFFFFF;
		font-weight: 500;
	}
	
	.audio-item-meta {
		display: flex;
		flex-wrap: nowrap;
		gap: 16rpx;
		padding-top: 16rpx;
		border-top: 1px solid #F0F0F0;
		align-items: center;
	}
	
	.audio-meta-item {
		font-size: 24rpx;
		color: #999;
		white-space: nowrap;
		flex-shrink: 0;
	}
	
	.audio-list-empty {
		padding: 48rpx 0;
		text-align: center;
		color: #999;
		font-size: 28rpx;
	}
	
	/* 录音文本内容弹框样式 */
	/* 提高文本内容弹框的层级，确保显示在录音列表弹框上方 */
	/* 通过深度选择器覆盖uni-popup的z-index */
	.text-modal-popup {
		z-index: 1000 !important;
	}
	
	.text-modal-popup .uni-popup {
		z-index: 1000 !important;
	}
	
	.text-modal {
		width: 100%;
		height: 80vh;
		max-height: 80vh;
		background-color: #FFFFFF;
		border-radius: 24rpx;
		display: flex;
		flex-direction: column;
		overflow: hidden;
		box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
		position: relative;
	}
	
	.text-modal-header {
		padding: 32rpx;
		border-bottom: 1px solid #F0F0F0;
		display: flex;
		align-items: center;
		justify-content: space-between;
		flex-shrink: 0;
	}
	
	.text-modal-title {
		font-size: 32rpx;
		font-weight: 600;
		color: #333;
	}
	
	.text-modal-close {
		width: 48rpx;
		height: 48rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
		border-radius: 50%;
		transition: background-color 0.2s;
	}
	
	.text-modal-close:active {
		background-color: #F5F5F5;
	}
	
	.text-modal-content {
		flex: 1;
		height: 0;
		min-height: 0;
		box-sizing: border-box;
	}
	
	.text-modal-text {
		font-size: 28rpx;
		color: #333;
		line-height: 1.8;
		white-space: pre-wrap;
		word-wrap: break-word;
		word-break: break-all;
		display: block;
		padding: 32rpx;
		box-sizing: border-box;
	}

</style>

