| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351 | <template>	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>	<view class="detail-header">		<image class="header-bg" :src="bannerList[0]" mode="">		</image>		<view class="back-icon" :style="{ paddingTop: (statusBarHeight + 10) + 'px' }" @click="RouterUtils.back()">			<zzx-icon name="back"></zzx-icon>		</view>		<view :style="{ height: (statusBarHeight + 70) + 'px' }"></view>		<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">			<view class="swiper-inner">				<block v-if="detailInfo.video">					<video v-for="(item, index) in videoList" :key="index" :src="item"></video>				</block>				<image v-for="(item, index) in bannerList" :key="index" :src="item" mode=""></image>			</view>		</scroll-view>	</view>	<view :style="{ height: (statusBarHeight + 34) + 'px' }"></view>	<view class="header-info">		<view class="venue-name">			<view>				<view class="name">{{ detailInfo.name }}</view>				<view class="open-status-info">					<view class="open-status">{{ detailInfo.runStatus ? '营业中' : '歇业中' }}</view>					<view class="open-time-info">{{ detailInfo?.startTime }}-{{ detailInfo?.endTime }}</view>				</view>			</view>			<view class="star">				<uni-rate :readonly="true" :allowHalf="true" size="16" :value="detailInfo.goodRate" />				<text>{{ detailInfo.goodRate || '0.0' }}</text>			</view>		</view>		<view class="open-time" v-if="teachingDay">			<view class="time">				<view>教学日 <text style="margin-right: 14rpx;" v-for="(item, index) in teachingDay.data" :key="index">{{					item.startTime + '-' + item.endTime || '--' }}</text></view>				<view class="">非教学日 <text style="margin-right: 14rpx;" v-for="(item, index) in noTeachingDay.data"						:key="index">{{ item.startTime + '-' + item.endTime || '--' }}</text></view>			</view>		</view>		<view class="venues-tags">			<view class="tags-box">				<view class="tags" v-for="(item, index) in detailInfo.facilityInfo" :key="index">{{ item }}</view>			</view>			<!-- 			<view class="more-info" @click="RouterUtils.to_page('/pages/index/basisInfo/index')">				<text>信息/设备设施</text>				<zzx-icon name="ashRight" size="10"></zzx-icon>			</view> -->		</view>		<view class="venues-address">			<view class="address">				<zzx-icon name="location" size="14"></zzx-icon>				<text>{{ detailInfo.address }}</text>			</view>			<view class="nav-phone">				<view class="nav" @click="open_map">					<zzx-icon name="navigation" size="14"></zzx-icon>					<view class="">导航</view>				</view>				<view class="phone" @click="open_phone">					<zzx-icon name="phone" size="14"></zzx-icon>					<view class="">电话</view>				</view>			</view>		</view>	</view>	<view class="content">		<uv-sticky offset-top="74">			<view class="detail-select">				<view :class="sel_index === index ? 'select-text' : 'notsel-text'" v-for="(item, index) in selectList"					:key="index" @click="sel_tab(index)">					<text>{{ item }}</text>				</view>			</view>		</uv-sticky>		<view id="detail">			<view class="venue-select-card">				<view class="v-caed-header">					<view class="v-left">						<zzx-icon name="venue-icon1" size="14"></zzx-icon>						<view style="margin-bottom: 10rpx;">包场</view>					</view>					<view class="" v-if="charteredList">						开场前{{ charteredList.earlyRefundTime }}分钟随时退					</view>					<view class="v-left" @click="checkedVr">						<zzx-icon name="venue-icon2" size="14"></zzx-icon>						<view style="margin-bottom: 10rpx;">VR实景</view>					</view>				</view>				<view class="v-select-infocard">					<view class="select-btn">						<view :class="selChartered === index ? 'distance' : 'score'"							v-for="(item, index) in allCategoryList" :key="item.id"							@click="selectChartered(item, index)">{{ item.name }}</view>					</view>					<view class="info-card-list">						<scroll-view scroll-x="true" class="scroll-view_H">							<view class="item-card scroll-view-item_H" v-for="(item, index) in charteredList?.timeSlot"								:key="item.id" @click="open_popup(item, index)">								<view class="today">{{ item.dateLabel }}</view>								<view class="time">最早{{ item.startTime }}可订</view>								<view class="price" v-if="item.sellingPrice">¥{{ item.sellingPrice?.toFixed(2) }}起								</view>							</view>							<view class="not-data" v-if="charteredList?.timeSlot?.length < 1">暂无可选时间</view>						</scroll-view>					</view>				</view>				<view class="not-data" v-if="charteredList?.length < 1">暂无场地数据</view>			</view>			<view class="venue-card">				<view class="card-title">					<zzx-icon name="venue-icon3" size="14"></zzx-icon>					<view class="">无固定场</view>				</view>				<view class="item-card" v-for="(item, index) in detailInfo.placeInfoMsgVO" :key="item.id">					<image :src="item.cover" mode=""></image>					<view class="venue-info">						<view class="info-title">							<view class="title textHidden">{{ item.name }}</view>							<view class="sales">年售{{ item.sales }}</view>						</view>						<!-- 						<view class="type">							篮球、足球、羽毛球						</view> -->						<view class="price-info">							<view class="price">								<view class="" v-if="item.sellingPrice">¥{{ item?.sellingPrice?.toFixed(2) }}</view>								<view class="" v-if="item.originalPrice">¥{{ item?.originalPrice?.toFixed(2) }}</view>							</view>							<view class="price-btn"								@click="RouterUtils.to_page(`/pages/index/gymPay/index?type=1&placeId=${item.id}`)">抢购							</view>						</view>					</view>					<view class="card-tips">						<view class="item-tips" @click="buyTips(item)">							<text>购买须知</text>							<zzx-icon name="ashRight" size="10"></zzx-icon>						</view>						<view class="item-tips" @click="serveTips(item)">							<text>服务保障</text>							<zzx-icon name="ashRight" size="10"></zzx-icon>						</view>						<!-- 						<view class="item-tips">							<text>用户评价</text>							<zzx-icon name="ashRight" size="10"></zzx-icon>						</view> -->					</view>				</view>				<view class="not-data" v-if="detailInfo.placeInfoMsgVO?.length < 1">暂无场地数据</view>			</view>		</view>		<view class="course-card" id="notice">			<view class="course-tips">				<view class="">!</view>				<view class="">全平台每种类型的运动课程只可免费试听一次</view>			</view>			<view class="select-btn">				<view :class="sel_btn === index ? 'distance' : 'score'" v-for="(item, index) in allCourseCategoryList"					:key="item.id" @click="selectallCategory(item, index)">{{ item.name }}</view>			</view>			<block v-if="!courseLoading">				<view class="venue-card" v-for="item in courseList" :key="item.id" @click="toCOurseDetail">					<image :src="item.cover" mode=""></image>					<view class="venue-info">						<view class="info-title">							<view class="title textHidden">{{ item.name }}</view>							<view class="sales">年售{{ item.salesYear }}</view>						</view>						<view class="type">							{{ item.address }} {{ item.km || '--' }}km						</view>						<view class="price">							<view class="" v-if="item?.sellingPrice">¥{{ item?.sellingPrice?.toFixed(2) }}</view>							<view class="" v-if="item?.originalPrice">¥{{ item?.originalPrice?.toFixed(2) }}</view>						</view>						<view class="course-count">							{{ item.period }}课时 {{ item.startTime }}-{{ item.endTime }}						</view>						<view class="price-info">							<view class="sale">								已售{{ item.sales }} {{ item.goodRate }}%好评							</view>							<view class="price-btn"								@click="RouterUtils.to_page(`/pages/index/courseDetail/index?id=${item.id}&type=2`)">								{{ item.hasDiscount ? '免费试听' : '立即购买' }}							</view>						</view>					</view>				</view>			</block>			<loading v-else />			<view class="not-data" v-if="courseList?.length == 0 && !courseLoading">暂无数据</view>			<!-- <view class="more">查看更多</view> -->		</view>		<view class="instructor-card" id="schedule">			<view class="card-title" @click="RouterUtils.to_page('/pages/index/allInstructor/index')">				<view class="">教练({{ detailInfo.instructorVOList?.length }})</view>				<zzx-icon name="right" size="12"></zzx-icon>			</view>			<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">				<view class="swiper-box">					<view class="swiper-inner" v-for="item in detailInfo.instructorVOList" :key="item.id"						@click="RouterUtils.to_page(`/pages/index/instructorDetail/index?id=${item.id}`)">						<view class="header-img">							<image :src="item.avatar" mode=""></image>							<image src="/src/static/badge.png" mode=""></image>						</view>						<view class="instructor-name textHidden">{{ item.name }}</view>						<view class="instructor-specialty textHidden">							<text v-for="(category, index) in item.category" :key="index">{{ category }},</text>						</view>					</view>				</view>			</scroll-view>		</view>		<view class="appraise-card" id="appraise">			<view class="appraise-title">				<view class="title">评价</view>				<view class="comments">					<view class="a-star">						<zzx-icon name="star" size="10"></zzx-icon>						<text v-if="appraiseList?.averageScore">{{ appraiseList?.averageScore?.toFixed(1) }}</text>					</view>					<view class="a-text">| {{ appraiseList.scoreNum }}人评论</view>				</view>			</view>			<view class="appraise-info" v-for="item in appraiseList.records" :key="item.id">				<view class="a-user-info">					<view class="info">						<image :src="item.avatar" mode=""></image>						<view class="name">{{ item.username }}</view>					</view>					<view class="time">{{ DateUtils.formatDateToMMDD(item.createTime) }}</view>				</view>				<view class="a-score">					<text>{{ item.score?.toFixed(1) }}</text>					<uni-rate :readonly="true" size="16" :value="item.score" />				</view>				<view class="a-content">					{{ item.evaluateContent }}				</view>				<scroll-view class="scroll-view_H" scroll-x="true" :show-scrollbar="false" v-if="item.images != ''">					<view class="scroll-view-item_H uni-bg-red" v-for="(img, idx) in item.images.split(',')" :key="idx">						<image @click="_previewImage(item.images.split(','), img)" :src="img" mode=""></image>					</view>				</scroll-view>			</view>		</view>	</view>	<view style="position: relative;z-index: 99999;">		<selPopup ref="openPopup" :listData="placedata" :itemList="selItems" :deteObj="dateIndex"			:deteSelIndex="selIndex" @changes="onchange" />		<uni-popup ref="placeInfoPopup" :safe-area="false" type="bottom">			<view class="buyTips-box">				<view class="buyTips-title">购买须知</view>				<view class="rich-box" v-if="buyTipsObj">					<rich-text :nodes="buyTipsObj.reminder"></rich-text>				</view>			</view>		</uni-popup>		<uni-popup ref="salesPopup" :safe-area="false" type="bottom">			<view class="buyTips-box">				<view class="buyTips-title">服务保障</view>				<view class="rich-box">{{ salesTipsText }}</view>			</view>		</uni-popup>	</view></template><script lang="ts" setup>import { ref, onMounted, getCurrentInstance, nextTick } from 'vue';import { RouterUtils, DateUtils, _previewImage, TipsUtils } from '@/utils/util';import { http } from '@/utils/http'import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';import { onLoad, onPageScroll, onReachBottom } from '@dcloudio/uni-app';import loading from '@/components/zzx-loading/zzx-loading.vue';import selPopup from './components/popup.vue';import { useCacheStore } from '@/stores/cache'const cache = useCacheStore()const placeInfoPopup = ref()const statusBarHeight = ref(0);const sectionTops = ref<number[]>([]);const isScrollingByTab = ref(false);const scrollTimer = ref<any>(null);const selectList = ref(['场地', '课程', '教练', '评价']);const sel_index = ref(0);const sel_btn = ref(0);const instance = getCurrentInstance();onLoad((option) => {	listId.value = option.id	appraiseFormData.value.siteId = option.id})onReachBottom(() => {	appraiseFormData.value.pageNo++	getFindByOrderPage()})onMounted(() => {	get_navheight()	nextTick(() => {		setTimeout(() => getSectionsTop(), 300);	});	get_placeInfo()	get_allCategory()	get_allCourseCategory()	getFindByOrderPage()})const get_navheight = () => {	const systemInfo = uni.getSystemInfoSync();	statusBarHeight.value = systemInfo.statusBarHeight || 0;}// 打开选场弹窗const dateIndex = ref()const selIndex = ref()const openPopup = ref(null);const open_popup = async (e, i) => {	selIndex.value = i	dateIndex.value = e	get_placeInfoDetail(categoryId.value, i)	await nextTick()	openPopup.value?.opens()	console.log(openPopup.value, 'openPopup');}// vrconst checkedVr = () => {	if (detailInfo.value.vr) {		RouterUtils.to_page(`/pages/index/vr/index?vrImg=${detailInfo.value.vr}`)	} else {		TipsUtils.tips_toast('场馆暂未上传VR图片')	}}// 获取所有模块的位置信息const getSectionsTop = () => {	const ids = ['detail', 'notice', 'schedule', 'appraise'];	const query = uni.createSelectorQuery().in(instance.proxy);	ids.forEach(id => {		query.select(`#${id}`).boundingClientRect();	});	query.exec((rects) => {		// 添加空值检查		sectionTops.value = rects			.filter((rect: any) => rect !== null)			.map((rect: any) => rect.top - 130);	})};//滚动事件onPageScroll((e) => {	if (isScrollingByTab.value) return;	if (scrollTimer.value) return;	scrollTimer.value = setTimeout(() => {		updateActiveTab(e.scrollTop);		scrollTimer.value = null;	}, 100);});// 根据滚动位置更新激活的Tabconst updateActiveTab = (scrollTop: number) => {	const offset = 130;	const scrollPosition = scrollTop + offset;	let activeIndex = 0;	if (!sectionTops.value || !Array.isArray(sectionTops.value)) {		return	}	for (let i = 0; i < sectionTops.value.length; i++) {		if (scrollPosition >= sectionTops.value[i]) {			activeIndex = i;		} else {			break; // 模块位置已排序,可提前结束		}	}	if (sel_index.value !== activeIndex) {		sel_index.value = activeIndex;	}};const sel_tab = async (i: number) => {	isScrollingByTab.value = true; // 标记为Tab点击触发的滚动	sel_index.value = i;	const ids = ['detail', 'notice', 'schedule', 'appraise'];	const id = ids[i];	await scrollToTop();	await nextTick();	const query = uni.createSelectorQuery().in(instance.proxy);	query.select(`#${id}`).boundingClientRect(data => {		if (!data) return;		uni.pageScrollTo({			scrollTop: data.top - 130,			duration: 500,			complete: () => {				setTimeout(() => {					isScrollingByTab.value = false;				}, 300);			}		});	}).exec();}// 滚动到顶部const scrollToTop = () => {	return new Promise(resolve => {		uni.pageScrollTo({			scrollTop: 0,			duration: 0,			success: resolve		});	});}// 打开地图const open_map = () => {	uni.openLocation({		latitude: detailInfo.value.latitude || 0,		longitude: detailInfo.value.longitude || 0,		name: detailInfo.value.name,		address: detailInfo.value.address,		success: function () {			console.log('success');		}	});}// 拨打电话const open_phone = () => {	uni.makePhoneCall({		phoneNumber: detailInfo.value.phone	});}// 详情信息const listId = ref(0);const detailInfo = ref({})const bannerList = ref([])const videoList = ref([])const noTeachingDay = ref()const teachingDay = ref()const get_placeInfo = () => {	http.get('/detail/getPlaceInfo', { data: { id: listId.value }, loading: true }).then((res) => {		const startIndex = res.result.cover ? res.result.cover.indexOf('"') + 1 : 0;		const endIndex = res.result.cover ? res.result.cover.lastIndexOf('') : 0;		bannerList.value = res.result.cover ? res.result.cover.slice(startIndex, endIndex).split(',') : [];		let videoIndex = res.result.video ? res.result.video.indexOf('"') + 1 : 0;		let videoEndIndex = res.result.video ? res.result.video.lastIndexOf('') : 0;		videoList.value = res.result.video ? res.result.video.slice(videoIndex, videoEndIndex).split(',') : [];		detailInfo.value = res.result		noTeachingDay.value = JSON.parse(res.result.noTeachingDay)		teachingDay.value = JSON.parse(res.result.teachingDay)	})}// 场地分类const allCategoryList = ref([])const categoryId = ref()const get_allCategory = () => {	http.get('/detail/getAllCategory', { data: { id: listId.value } }).then((res) => {		if (!res.result || res.result.length == 0) return		categoryId.value = res.result[0].id		allCategoryList.value = res.result		get_placeInfoNoFixation(categoryId.value)	})}// 课程分类const allCourseCategoryList = ref([])const categoryCourseId = ref()const get_allCourseCategory = () => {	http.get('/detail/getAllCourseCategory', { data: { id: listId.value } }).then((res) => {		categoryCourseId.value = res.result[0].id		allCourseCategoryList.value = res.result		get_courseList(categoryCourseId.value)	})}// 课程列表const courseList = ref([])const courseLoading = ref(false)const get_courseList = (categoryId: string) => {	courseLoading.value = true	http.get('/detail/courseInfoVOList', { data: { categoryId: categoryId, id: listId.value, longitude: cache.get('LON') || 0, latitude: cache.get('LAT') || 0 } }).then((res) => {		courseLoading.value = false		courseList.value = res.result	})}// 课程切换const selectallCategory = (e, i) => {	sel_btn.value = i	get_courseList(e.id)}// 包场切换const selChartered = ref(0)const selectChartered = (e, i) => {	console.log(e, i, '包场切换');	categoryId.value = e.id	selChartered.value = i	get_placeInfoNoFixation(e.id)	get_placeInfoDetail(e.id, '')}// 包场信息const charteredList = ref([])const get_placeInfoNoFixation = (categoryId) => {	http.get('/detail/getPlaceInfoNoFixation', { data: { categoryId: categoryId, id: listId.value }, loading: true }).then((res) => {		charteredList.value = res.result	})}const buyTipsObj = ref()const buyTips = (e) => {	placeInfoPopup.value.open()	buyTipsObj.value = e}const salesPopup = ref()const salesTipsText = ref('')const serveTips = (e) => {	salesPopup.value.open()	if (e.sales === 0) {		salesTipsText.value = '未消费随时退款,过期未消费自动退款。'	} else if (e.sales === 2) {		salesTipsText.value = '不支退款,请慎重考虑后购买。'	}}const placedata = ref()const selItems = ref()const get_placeInfoDetail = (catId: any, dateIndex: any) => {	http.get('/stadium/getPlaceInfo', { data: { siteId: listId.value, categoryId: catId }, loading: true }).then((res) => {		placedata.value = res.result		selItems.value = res.result?.stadiumConcertsVOList[dateIndex]?.concertsVOList	})}const onchange = (e, i) => {	selItems.value = e?.concertsVOList	selIndex.value = i}// 获取评价const appraiseFormData = ref({	siteId: null,	pageNo: 1,	pageSize: 10})const appraiseList = ref([])const getFindByOrderPage = () => {	http.get('/my/evaluate/findByOrderPage', { data: appraiseFormData.value, loading: true }).then((res) => {		if (appraiseFormData.value.pageNo == 1) {			appraiseList.value = res.result		} else {			appraiseList.value = [...appraiseList.value, ...res.result]		}	})}</script><style lang="less" scoped>.detail-header {	position: relative;	.header-bg {		position: absolute;		width: 100%;		height: 432rpx;		z-index: -100;	}	.back-icon {		position: absolute;		left: 20rpx;		z-index: 9999;	}	.header-swiper {		position: absolute;		width: 740rpx;		white-space: nowrap;		overflow: hidden;		/* 隐藏滚动条 */		/deep/ ::-webkit-scrollbar {			display: none;			width: 0 !important;			height: 0 !important;			background: transparent;		}		.swiper-inner {			display: inline-flex;			align-items: center;			gap: 14rpx;			height: 100%;			&>video,			&>image {				width: 220rpx;				height: 126rpx;				border-radius: 16rpx;				flex-shrink: 0;			}		}	}}.header-info {	padding: 20rpx;	background: #FFFFFF;	border-radius: 16rpx 16rpx 0rpx 0rpx;	.venue-name {		display: flex;		align-items: center;		justify-content: space-between;		.open-status-info {			margin-top: 20rpx;			display: flex;			align-items: center;			gap: 20rpx;			.open-status {				font-size: 24rpx;				color: #4DD951;			}			.open-time-info {				font-size: 24rpx;				color: #AAAAAA;			}		}		.name {			font-weight: 800;			font-size: 32rpx;			color: #222222;		}		.star {			display: flex;			align-items: center;			gap: 10rpx;			font-size: 28rpx;			color: #FDD143;		}	}	.open-time {		margin-top: 20rpx;		.time {			font-size: 24rpx;			color: #AAAAAA;			&>view {				margin-top: 20rpx;			}		}	}	.venues-tags {		display: flex;		align-items: center;		justify-content: space-between;		margin-top: 20rpx;		.tags-box {			display: flex;			flex-wrap: wrap;			gap: 10rpx;			.tags {				padding: 8rpx 16rpx;				font-size: 24rpx;				color: #222222;				background: #F5F5F5;				border-radius: 8rpx;			}		}		.more-info {			display: flex;			align-items: center;			font-size: 24rpx;			gap: 6rpx;			color: #AAAAAA;		}	}	.venues-address {		display: flex;		align-items: center;		justify-content: space-between;		margin-top: 20rpx;		background: #F9F9F9;		border-radius: 16rpx;		padding: 20rpx;		.address {			display: flex;			align-items: center;			gap: 10rpx;			font-weight: bold;			font-size: 24rpx;			color: #222222;		}		.nav-phone {			display: flex;			align-items: center;			gap: 20rpx;			text-align: center;			.nav,			.phone {				font-size: 22rpx;				color: #222222;			}		}	}}.detail-select {	display: flex;	align-items: center;	gap: 60rpx;	margin-top: 20rpx;	height: 80rpx;	background-color: #F6F6F6;	.select-text,	.notsel-text {		position: relative;		transition: all 0.3s ease;	}	.select-text {		font-weight: 800;		font-size: 32rpx;		color: #222222;		position: relative;	}	.notsel-text {		font-size: 32rpx;		color: #AAAAAA;	}	.select-text::after {		position: absolute;		content: '';		width: 40rpx;		height: 20rpx;		background-color: #C8FF0C;		border-radius: 4rpx;		left: 050%;		transform: translateX(-50%);		bottom: -16rpx;		transition: all 0.3s ease;		opacity: 1;	}	.notsel-text::after {		content: '';		position: absolute;		left: 50%;		bottom: -16rpx;		width: 0;		height: 20rpx;		background-color: #C8FF0C;		border-radius: 4rpx;		transform: translateX(-50%);		opacity: 0;		transition: all 0.3s ease;	}}.venue-select-card {	padding: 20rpx;	background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);	border-radius: 32rpx;	.v-caed-header {		display: flex;		align-items: center;		justify-content: space-around;		height: 80rpx;		font-size: 24rpx;		color: #AAAAAA;		border-bottom: 2rpx solid #F0F0F0;		.v-left {			display: flex;			align-items: center;			gap: 10rpx;		}	}	.v-select-infocard {		.select-btn {			display: flex;			align-items: center;			gap: 20rpx;			margin-top: 20rpx;			.distance {				width: 92rpx;				height: 36rpx;				background: #C8FF0C;				border-radius: 8rpx;				font-size: 24rpx;				color: #222222;				line-height: 34rpx;				text-align: center;			}			.score {				width: 92rpx;				height: 36rpx;				background: #F5F5F5;				border-radius: 8rpx;				font-size: 24rpx;				color: #AAAAAA;				line-height: 34rpx;				text-align: center;			}		}		.info-card-list {			margin-top: 20rpx;			.scroll-view_H {				white-space: nowrap;				width: 100%;				.item-card {					width: 200rpx;					height: 132rpx;					padding: 20rpx;					background: #F6F6F6;					border-radius: 16rpx;					display: inline-block;					margin-right: 16rpx;					.today {						font-size: 24rpx;						color: #222222;					}					.time {						margin-top: 12rpx;						font-size: 24rpx;						color: #222222;					}					.price {						margin-top: 12rpx;						font-weight: bold;						font-size: 28rpx;						color: #FB5B5B;					}				}			}		}	}}.venue-card {	padding: 20rpx;	background: #FFFFFF;	border-radius: 32rpx;	margin-top: 20rpx;	.card-title {		display: flex;		align-items: center;		gap: 10rpx;		font-size: 24rpx;		color: #AAAAAA;		&>view {			margin-bottom: 10rpx;		}	}	.item-card {		margin-top: 20rpx;		display: flex;		align-items: center;		flex-wrap: wrap;		gap: 20rpx;		&>image {			width: 200rpx;			height: 200rpx;			border-radius: 32rpx;		}		.venue-info {			width: 430rpx;			.info-title {				display: flex;				align-items: center;				justify-content: space-between;				.title {					width: 340rpx;					font-weight: 800;					font-size: 32rpx;					color: #222222;				}				.sales {					font-size: 22rpx;					color: #AAAAAA;				}			}			.type {				margin-top: 16rpx;				font-size: 24rpx;				color: #AAAAAA;			}			.price-info {				display: flex;				align-items: center;				justify-content: space-between;				margin-top: 16rpx;				.price {					display: flex;					align-items: center;					gap: 20rpx;					&>view:nth-child(1) {						font-weight: bold;						font-size: 28rpx;						color: #FB5B5B;					}					&>view:nth-child(2) {						font-size: 22rpx;						color: #AAAAAA;						text-decoration: line-through;					}				}				.price-btn {					width: 152rpx;					height: 48rpx;					background: #C8FF0C;					border-radius: 8rpx;					font-weight: bold;					font-size: 28rpx;					color: #222222;					text-align: center;					line-height: 48rpx;				}			}		}		.card-tips {			display: flex;			align-items: center;			gap: 40rpx;			flex-basis: 100%;			height: 60rpx;			border-bottom: 1rpx solid #F0F0F0;			.item-tips {				display: flex;				align-items: center;				gap: 10rpx;				font-size: 22rpx;				color: #222222;			}		}	}}.course-card {	padding: 20rpx;	background: #FFFFFF;	border-radius: 32rpx;	margin-top: 20rpx;	.course-tips {		display: flex;		align-items: center;		gap: 10rpx;		font-size: 24rpx;		color: #999999;		&>view:first-child {			width: 32rpx;			height: 32rpx;			background: #FFA347;			border-radius: 50%;			display: flex;			justify-content: center;			align-items: center;			color: #FFFFFF;		}	}	.select-btn {		display: flex;		align-items: center;		gap: 20rpx;		margin-top: 20rpx;		.distance {			width: 92rpx;			height: 36rpx;			background: #C8FF0C;			border-radius: 8rpx;			font-size: 24rpx;			color: #222222;			line-height: 34rpx;			text-align: center;		}		.score {			width: 92rpx;			height: 36rpx;			background: #F5F5F5;			border-radius: 8rpx;			font-size: 24rpx;			color: #AAAAAA;			line-height: 34rpx;			text-align: center;		}	}	.venue-card {		display: flex;		align-items: center;		gap: 20rpx;		margin-top: 20rpx;		&>image {			width: 200rpx;			height: 200rpx;			border-radius: 32rpx;		}		.venue-info {			width: 430rpx;			height: 220rpx;			border-bottom: 1rpx solid #F0F0F0;			padding-bottom: 10rpx;			.info-title {				display: flex;				align-items: center;				justify-content: space-between;				.title {					width: 340rpx;					font-weight: 800;					font-size: 32rpx;					color: #222222;				}				.sales {					font-size: 22rpx;					color: #AAAAAA;				}			}			.type {				margin-top: 16rpx;				font-size: 24rpx;				color: #AAAAAA;			}			.price {				display: flex;				align-items: center;				gap: 20rpx;				margin-top: 16rpx;				&>view:nth-child(1) {					font-weight: bold;					font-size: 28rpx;					color: #FB5B5B;				}				&>view:nth-child(2) {					font-size: 22rpx;					color: #AAAAAA;					text-decoration: line-through;				}			}			.course-count {				font-size: 22rpx;				color: #AAAAAA;			}			.price-info {				display: flex;				align-items: center;				justify-content: space-between;				.sale {					font-size: 24rpx;					color: #AAAAAA;				}				.price-btn {					width: 152rpx;					height: 48rpx;					background: #C8FF0C;					border-radius: 8rpx;					font-weight: bold;					font-size: 28rpx;					color: #222222;					text-align: center;					line-height: 48rpx;				}			}		}	}	.more {		margin: auto;		width: 100rpx;		margin-top: 20rpx;		text-align: center;		font-size: 24rpx;		color: #CCCCCC;		position: relative;	}	.more::after {		position: absolute;		bottom: -10rpx;		left: 25rpx;		content: '';		width: 38rpx;		height: 4rpx;		border-radius: 2rpx;		background-color: #CCCCCC;	}}.instructor-card {	padding: 20rpx;	background: #FFFFFF;	border-radius: 32rpx;	margin-top: 20rpx;	overflow: hidden;	.card-title {		display: flex;		align-items: center;		justify-content: space-between;		font-weight: 800;		font-size: 32rpx;		color: #222222;	}	.header-swiper {		margin-top: 24rpx;		width: 700rpx;		white-space: nowrap;		overflow: hidden;		/* 隐藏滚动条 */		/deep/ ::-webkit-scrollbar {			display: none;			width: 0 !important;			height: 0 !important;			background: transparent;		}		.swiper-box {			display: flex;			align-items: center;			gap: 44rpx;			.swiper-inner {				width: 100rpx;				text-align: center;				.header-img {					position: relative;					image {						width: 100rpx;						height: 100rpx;						border-radius: 50%;						&:nth-child(2) {							position: absolute;							bottom: 0;							right: 0;							width: 36rpx;							height: 36rpx;						}					}				}				.instructor-name {					width: 120rpx;					font-size: 28rpx;					font-weight: 600;				}				.instructor-specialty {					width: 120rpx;					font-size: 22rpx;					color: #AAAAAA;				}			}		}	}}.appraise-card {	padding: 20rpx;	background: #FFFFFF;	border-radius: 32rpx;	margin-top: 20rpx;	.appraise-title {		display: flex;		align-items: center;		justify-content: space-between;		.title {			font-weight: 800;			font-size: 32rpx;			color: #222222;		}		.comments {			display: flex;			align-items: center;			gap: 16rpx;			.a-star {				font-size: 24rpx;				color: #FDD143;			}			.a-text {				font-size: 24rpx;				color: #AAAAAA;			}		}	}	.appraise-info {		margin-top: 20rpx;		.a-user-info {			display: flex;			align-items: center;			justify-content: space-between;			.info {				display: flex;				align-items: center;				gap: 20rpx;				&>image {					width: 60rpx;					height: 60rpx;					border-radius: 50%;				}				.name {					font-weight: bold;					font-size: 24rpx;					color: #222222;				}			}			.time {				font-size: 24rpx;				color: #AAAAAA;			}		}		.a-score {			font-size: 24rpx;			color: #AAAAAA;			display: flex;			align-items: center;			gap: 20rpx;			margin-top: 20rpx;		}		.a-content {			margin-top: 20rpx;			font-size: 28rpx;			color: #222222;		}		.scroll-view_H {			white-space: nowrap;			width: 100%;			height: 220rpx;			margin-top: 20rpx;			border-bottom: 1rpx solid #F0F0F0;			.scroll-view-item_H {				display: inline-block;				text-align: center;				margin-right: 14rpx;				&>image {					width: 202rpx;					height: 200rpx;					background: #D8D8D8;					border-radius: 32rpx;				}			}		}	}}.buyTips-box {	background: #F6F6F6;	border-radius: 32rpx 32rpx 0rpx 0rpx;	max-height: 1200rpx;	overflow: auto;	padding: 20rpx;	.buyTips-title {		text-align: center;		font-size: 28rpx;		font-weight: bold;	}	.rich-box {		margin-top: 20rpx;	}}</style>
 |