Pārlūkot izejas kodu

学校场地课程流程

学习?学个屁 2 dienas atpakaļ
vecāks
revīzija
04601ac07d
33 mainītis faili ar 3111 papildinājumiem un 1650 dzēšanām
  1. 475 472
      src/pages/index/courseDetail/index.vue
  2. 116 106
      src/pages/index/detail/components/appraise.vue
  3. 86 75
      src/pages/index/detail/components/venue.vue
  4. 30 7
      src/pages/index/detail/index.vue
  5. 14 15
      src/pages/index/gymDetail/components/popup.vue
  6. 48 25
      src/pages/index/gymDetail/index.vue
  7. 7 3
      src/pages/index/gymPay/index.vue
  8. 2 3
      src/pages/index/index.vue
  9. 376 314
      src/pages/index/instructorDetail/index.vue
  10. 1 2
      src/pages/index/insure/index.vue
  11. 10 1
      src/pages/index/messageDetail/index.vue
  12. 1 0
      src/pages/index/signWebview/index.vue
  13. 620 341
      src/pages/index/submitOrder/index.vue
  14. 80 65
      src/pages/index/toBeUsed/index.vue
  15. 131 102
      src/pages/index/verificationRecord/index.vue
  16. 102 92
      src/pages/index/writeComments/index.vue
  17. 2 2
      src/pages/mine/feedbackRecord/index.vue
  18. 2 2
      src/pages/mine/mineComments/index.vue
  19. 43 0
      src/uni_modules/uni-data-select/changelog.md
  20. 562 0
      src/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
  21. 88 0
      src/uni_modules/uni-data-select/package.json
  22. 8 0
      src/uni_modules/uni-data-select/readme.md
  23. 25 0
      src/uni_modules/uni-load-more/changelog.md
  24. 5 0
      src/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json
  25. 8 0
      src/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js
  26. 5 0
      src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
  27. 5 0
      src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
  28. 117 0
      src/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
  29. 84 0
      src/uni_modules/uni-load-more/package.json
  30. 14 0
      src/uni_modules/uni-load-more/readme.md
  31. 2 2
      src/utils/http/index.ts
  32. 0 0
      src/utils/util/date.ts
  33. 42 21
      src/utils/util/index.ts

+ 475 - 472
src/pages/index/courseDetail/index.vue

@@ -1,43 +1,45 @@
 <template>
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
-		<image class="header-bg" :src="'http://192.168.1.166:8080/jeecg-boot/sys/common/static/'+bannerList[0]" mode=""></image>
-		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" @click="RouterUtils.back()">
+		<image class="header-bg" :src="'http://192.168.1.166:8080/jeecg-boot/sys/common/static/' + 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>
+		<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="courseDetailInfo.video">
-					<video v-for="(item,index) in videoList" :key="index" :src="item"></video>
+				<block v-if="courseDetailInfo.video">
+					<video v-for="(item, index) in videoList" :key="index" :src="item"></video>
 				</block>
-				<image @click="_previewImage(bannerList)" v-for="(item,index) in bannerList" :key="index" :src="'http://192.168.1.166:8080/jeecg-boot/sys/common/static/'+item" mode=""></image>
+				<image @click="_previewImage(bannerList, item)" v-for="(item, index) in bannerList" :key="index"
+					:src="'http://192.168.1.166:8080/jeecg-boot/sys/common/static/' + item" mode=""></image>
 			</view>
 		</scroll-view>
 	</view>
-	<view :style="{height:(statusBarHeight+34)+'px'}"></view>
+	<view :style="{ height: (statusBarHeight + 34) + 'px' }"></view>
 	<view class="header-info">
 		<view class="c-price-info">
 			<view class="price-info">
-				<view class="new-price">¥{{courseDetailInfo.sellingPrice}}</view>
-				<view class="old-price">¥{{courseDetailInfo.originalPrice}}</view>
+				<view class="new-price">¥{{ courseDetailInfo.sellingPrice }}</view>
+				<view class="old-price">¥{{ courseDetailInfo.originalPrice }}</view>
 			</view>
-			<view class="sales">年售{{courseDetailInfo.sales}}</view>
+			<view class="sales">年售{{ courseDetailInfo.sales }}</view>
 		</view>
 		<view class="c-name">
-			{{courseDetailInfo.name}}
+			{{ courseDetailInfo.name }}
 		</view>
 		<view class="c-detail-info">
-			<view class="c-time">课时:{{courseDetailInfo.startTime}}-{{courseDetailInfo.endTime}}</view>
+			<view class="c-time">课时:{{ courseDetailInfo.startTime }}-{{ courseDetailInfo.endTime }}</view>
 			<view class="c-address">
-				<view class="">上课地点:{{courseDetailInfo.address}} | {{courseDetailInfo.km}} km</view>
+				<view class="">上课地点:{{ courseDetailInfo.address }} | {{ courseDetailInfo.km }} km</view>
 				<zzx-icon name="ashRight" size="10"></zzx-icon>
 			</view>
 			<view class="c-instructor">
 				<view class="c-instructor-title">授课教练:</view>
 				<view class="c-instructor-name">
 					<image :src="courseDetailInfo.instructorAvatar" mode=""></image>
-					<view class="">{{courseDetailInfo.instructorName}}</view>
+					<view class="">{{ courseDetailInfo.instructorName }}</view>
 				</view>
 			</view>
 		</view>
@@ -47,9 +49,9 @@
 	<view class="content">
 		<uv-sticky offset-top="70">
 			<view class="detail-select">
-				<view :class="sel_index===index?'select-text':'notsel-text'" v-for="(item,index) in selectList"
+				<view :class="sel_index === index ? 'select-text' : 'notsel-text'" v-for="(item, index) in selectList"
 					:key="index" @click="sel_tab(index)">
-					<text>{{item}}</text>
+					<text>{{ item }}</text>
 				</view>
 			</view>
 		</uv-sticky>
@@ -72,12 +74,12 @@
 			<view class="c-schedule" id="schedule">
 				<view class="title">课程表</view>
 				<view class="list-card">
-					<view class="card-title">总共{{courseDetailInfo.courseDetail.length}}节</view>
+					<view class="card-title">总共{{ courseDetailInfo.courseDetail.length }}节</view>
 					<view class="schedule-list" v-for="item in courseDetailInfo.courseDetail" :key="item.id">
 						<view class="time">
-							<text>{{item.startTime}}-{{item.endTime}}</text>
+							<text>{{ item.startTime }}-{{ item.endTime }}</text>
 						</view>
-						<view class="name">{{item.name}}</view>
+						<view class="name">{{ item.name }}</view>
 					</view>
 					<!-- <view class="more">
 						<text>查看更多</text>
@@ -128,10 +130,10 @@
 			<view class="">分享</view>
 		</view>
 		<view class="c-buy-btn">
-			<view class="buy" v-if="type==3">
+			<view class="buy" v-if="type == 3">
 				<view class="buy-text">抢购</view>
 				<view class="buy-price">
-					<text>¥{{courseDetailInfo.sellingPrice}}</text>
+					<text>¥{{ courseDetailInfo.sellingPrice }}</text>
 					<text>省10</text>
 				</view>
 			</view>
@@ -139,7 +141,7 @@
 				<view class="buy" @click="toOrderPage(0)">
 					<view class="buy-text">直接购买</view>
 					<view class="buy-price">
-						<text>¥{{courseDetailInfo.sellingPrice}}</text>
+						<text>¥{{ courseDetailInfo.sellingPrice }}</text>
 						<text>省10</text>
 					</view>
 				</view>
@@ -152,583 +154,584 @@
 </template>
 
 <script lang="ts" setup>
-	import { ref, onMounted, getCurrentInstance, nextTick } from 'vue';
-	import { RouterUtils,_previewImage } from '@/utils/util';
-	import { http } from '@/utils/http'
-	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
-	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
-	import { useCacheStore } from '@/stores/cache'
-	const statusBarHeight = ref(0);
-	const sectionTops = ref<number[]>([]);
-	const isScrollingByTab = ref(false);
-	const scrollTimer = ref<any>(null);
-	const sel_index = ref(0);
-	const selectList = ref(['详情', '须知', '课表', '评价']);
-	const instance = getCurrentInstance();
-	const cache = useCacheStore()
-	const type=ref()
-	onLoad((option) => {
-		console.log(option);
-		courseId.value = option.id
-		type.value=option.type
-	})
-	onMounted(() => {
-		get_navheight()
-		nextTick(() => {
-			setTimeout(() => getSectionsTop(), 300);
-		});
-		get_courseInfo()
-	})
-
-	// 获取所有模块的位置信息
-	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.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);
+import { ref, onMounted, getCurrentInstance, nextTick } from 'vue';
+import { RouterUtils, _previewImage } from '@/utils/util';
+import { http } from '@/utils/http'
+import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
+import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+import { useCacheStore } from '@/stores/cache'
+const statusBarHeight = ref(0);
+const sectionTops = ref<number[]>([]);
+const isScrollingByTab = ref(false);
+const scrollTimer = ref<any>(null);
+const sel_index = ref(0);
+const selectList = ref(['详情', '须知', '课表', '评价']);
+const instance = getCurrentInstance();
+const cache = useCacheStore()
+const type = ref()
+onLoad((option) => {
+	console.log(option);
+	courseId.value = option.id
+	type.value = option.type
+})
+onMounted(() => {
+	get_navheight()
+	nextTick(() => {
+		setTimeout(() => getSectionsTop(), 300);
 	});
-	// 根据滚动位置更新激活的Tab
-	const updateActiveTab = (scrollTop : number) => {
-		const offset = 130;
-		const scrollPosition = scrollTop + offset;
-		let activeIndex = 0;
-		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;
+	get_courseInfo()
+})
+
+// 获取所有模块的位置信息
+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.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);
+});
+// 根据滚动位置更新激活的Tab
+const updateActiveTab = (scrollTop: number) => {
+	const offset = 130;
+	const scrollPosition = scrollTop + offset;
+	let activeIndex = 0;
+	for (let i = 0; i < sectionTops.value.length; i++) {
+		if (scrollPosition >= sectionTops.value[i]) {
+			activeIndex = i;
+		} else {
+			break; // 模块位置已排序,可提前结束
 		}
-	};
-	const get_navheight = () => {
-		const systemInfo = uni.getSystemInfoSync();
-		statusBarHeight.value = systemInfo.statusBarHeight || 0;
 	}
-	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();
+	if (sel_index.value !== activeIndex) {
+		sel_index.value = activeIndex;
 	}
-
-	const scrollToTop = () => {
-		return new Promise(resolve => {
-			uni.pageScrollTo({
-				scrollTop: 0,
-				duration: 0,
-				success: resolve
-			});
+};
+const get_navheight = () => {
+	const systemInfo = uni.getSystemInfoSync();
+	statusBarHeight.value = systemInfo.statusBarHeight || 0;
+}
+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);
+			}
 		});
-	}
-
-	const toOrderPage = (buyType : number) => {
-		RouterUtils.to_page(`/pages/index/gymPay/index?courseId=${courseId.value}&type=${type.value}&orderType=2&buyType=${buyType}`)
-	}
-
-	const courseId = ref()
-	const courseDetailInfo=ref()
-	const bannerList = ref([])
-	const videoList = ref([])
-	const get_courseInfo = () => {
-		http.get('/detail/getCourseInfo', { data: { id: courseId.value || '22222', latitude: cache.get('LAT'), longitude: cache.get('LON') }, loading: true }).then((res) => {
-			const startIndex = res.result.cover.indexOf('"') + 1;
-			const endIndex = res.result.cover.lastIndexOf('');
-			bannerList.value = res.result.cover.slice(startIndex, endIndex).split(',');
-			let videoIndex = res.result.video.indexOf('"') + 1;
-			let videoEndIndex = res.result.video.lastIndexOf('');
-			videoList.value = res.result.video.slice(videoIndex, videoEndIndex).split(',');
-			courseDetailInfo.value=res.result
-		})
-	}
+	}).exec();
+}
+
+const scrollToTop = () => {
+	return new Promise(resolve => {
+		uni.pageScrollTo({
+			scrollTop: 0,
+			duration: 0,
+			success: resolve
+		});
+	});
+}
+
+const toOrderPage = (buyType: number) => {
+	RouterUtils.to_page(`/pages/index/gymPay/index?courseId=${courseId.value}&type=${type.value}&orderType=2&buyType=${buyType}`)
+}
+
+const courseId = ref()
+const courseDetailInfo = ref()
+const bannerList = ref([])
+const videoList = ref([])
+const get_courseInfo = () => {
+	http.get('/detail/getCourseInfo', { data: { id: courseId.value || '22222', latitude: cache.get('LAT'), longitude: cache.get('LON') }, 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(',') : [];
+		courseDetailInfo.value = res.result
+	})
+}
 </script>
 
 <style lang="less" scoped>
-	.detail-header {
-		position: relative;
+.detail-header {
+	position: relative;
+
+	.header-bg {
+		position: absolute;
+		width: 100%;
+		height: 432rpx;
+		z-index: -100;
+	}
 
-		.header-bg {
-			position: absolute;
-			width: 100%;
-			height: 432rpx;
-			z-index: -100;
-		}
+	.back-icon {
+		position: absolute;
+		left: 20rpx;
+		z-index: 9999;
+	}
 
-		.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;
 		}
 
-		.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;
-				}
+		.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;
+.header-info {
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 16rpx 16rpx 0rpx 0rpx;
 
-		.c-price-info {
+	.c-price-info {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+
+		.price-info {
 			display: flex;
 			align-items: center;
-			justify-content: space-between;
+			gap: 20rpx;
 
-			.price-info {
-				display: flex;
-				align-items: center;
-				gap: 20rpx;
-
-				.new-price {
-					font-weight: 800;
-					font-size: 48rpx;
-					color: #FB5B5B;
-				}
-
-				.old-price {
-					font-size: 24rpx;
-					color: #AAAAAA;
-					text-decoration: line-through;
-				}
+			.new-price {
+				font-weight: 800;
+				font-size: 48rpx;
+				color: #FB5B5B;
 			}
 
-			.sales {
+			.old-price {
 				font-size: 24rpx;
 				color: #AAAAAA;
+				text-decoration: line-through;
 			}
 		}
 
-		.c-name {
-			margin-top: 44rpx;
-			font-weight: 800;
-			font-size: 32rpx;
-			color: #222222;
-		}
-
-		.c-detail-info {
+		.sales {
 			font-size: 24rpx;
 			color: #AAAAAA;
+		}
+	}
 
-			.c-time {
-				margin-top: 20rpx;
-			}
+	.c-name {
+		margin-top: 44rpx;
+		font-weight: 800;
+		font-size: 32rpx;
+		color: #222222;
+	}
 
-			.c-address {
-				display: flex;
-				align-items: center;
-				justify-content: space-between;
-				margin-top: 20rpx;
-			}
+	.c-detail-info {
+		font-size: 24rpx;
+		color: #AAAAAA;
 
-			.c-instructor {
-				margin-top: 20rpx;
-				display: flex;
-				align-items: center;
-				gap: 20rpx;
-				font-size: 24rpx;
-				color: #AAAAAA;
-				.c-instructor-title{
-					
-				}
-				.c-instructor-name{
-					text-align: center;
-					&>image{
-						width: 60rpx;
-						height: 60rpx;
-						border-radius: 50%;
-					}
-				}
-			}
+		.c-time {
+			margin-top: 20rpx;
 		}
 
-		.c-line {
-			border: 1rpx solid #F0F0F0;
+		.c-address {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
 			margin-top: 20rpx;
 		}
 
-		.c-rules {
+		.c-instructor {
 			margin-top: 20rpx;
+			display: flex;
+			align-items: center;
+			gap: 20rpx;
 			font-size: 24rpx;
-			color: #222222;
+			color: #AAAAAA;
+
+			.c-instructor-title {}
+
+			.c-instructor-name {
+				text-align: center;
+
+				&>image {
+					width: 60rpx;
+					height: 60rpx;
+					border-radius: 50%;
+				}
+			}
 		}
 	}
 
-	.detail-select {
-		display: flex;
-		align-items: center;
-		gap: 60rpx;
+	.c-line {
+		border: 1rpx solid #F0F0F0;
 		margin-top: 20rpx;
-		height: 80rpx;
-		background-color: #F6F6F6;
+	}
 
-		.select-text,
-		.notsel-text {
-			position: relative;
-			transition: all 0.3s ease;
-		}
+	.c-rules {
+		margin-top: 20rpx;
+		font-size: 24rpx;
+		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;
+	}
 
-		.select-text {
-			font-weight: 800;
+	.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;
+	}
+}
+
+.c-tabbar {
+	margin-top: 10rpx;
+
+	.c-tabbar-detail {
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		padding: 20rpx;
+		font-size: 24rpx;
+		color: #222222;
+	}
+
+	.c-notice {
+		margin-top: 20rpx;
+
+		.title {
+			font-weight: bold;
 			font-size: 32rpx;
 			color: #222222;
-			position: relative;
 		}
 
-		.notsel-text {
-			font-size: 32rpx;
-			color: #AAAAAA;
-		}
+		.tips-text {
+			margin-top: 20rpx;
+			background: #FFFFFF;
+			border-radius: 32rpx;
+			padding: 20rpx;
 
-		.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;
-		}
+			.text {
+				font-size: 24rpx;
+				color: #222222;
 
-		.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;
+				&>view {
+					margin-top: 20rpx;
+				}
+			}
+
+			.more {
+				margin-top: 20rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				gap: 20rpx;
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
 		}
 	}
 
-	.c-tabbar {
-		margin-top: 10rpx;
+	.c-schedule {
+		.title {
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #222222;
+		}
 
-		.c-tabbar-detail {
+		.list-card {
+			margin-top: 20rpx;
 			background: #FFFFFF;
 			border-radius: 32rpx;
 			padding: 20rpx;
 			font-size: 24rpx;
 			color: #222222;
-		}
 
-		.c-notice {
-			margin-top: 20rpx;
-
-			.title {
-				font-weight: bold;
-				font-size: 32rpx;
-				color: #222222;
-			}
+			.card-title {}
 
-			.tips-text {
+			.schedule-list {
 				margin-top: 20rpx;
-				background: #FFFFFF;
-				border-radius: 32rpx;
-				padding: 20rpx;
 
-				.text {
-					font-size: 24rpx;
-					color: #222222;
+				.time {
+					border-left: 8rpx solid #D3FD76;
 
-					&>view {
-						margin-top: 20rpx;
+					&>text {
+						margin-left: 20rpx;
 					}
 				}
 
-				.more {
+				.name {
+					margin-left: 20rpx;
 					margin-top: 20rpx;
-					display: flex;
-					align-items: center;
-					justify-content: center;
-					gap: 20rpx;
-					font-size: 24rpx;
-					color: #AAAAAA;
 				}
 			}
-		}
 
-		.c-schedule {
-			.title {
-				font-weight: bold;
-				font-size: 32rpx;
-				color: #222222;
-			}
-
-			.list-card {
+			.more {
 				margin-top: 20rpx;
-				background: #FFFFFF;
-				border-radius: 32rpx;
-				padding: 20rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				gap: 20rpx;
 				font-size: 24rpx;
-				color: #222222;
+				color: #AAAAAA;
+			}
+		}
+	}
 
-				.card-title {}
+	.appraise-card {
+		padding: 20rpx;
+		background: #FFFFFF;
+		border-radius: 32rpx;
+		margin-top: 20rpx;
 
-				.schedule-list {
-					margin-top: 20rpx;
+		.appraise-title {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
 
-					.time {
-						border-left: 8rpx solid #D3FD76;
+			.title {
+				font-weight: 800;
+				font-size: 32rpx;
+				color: #222222;
+			}
 
-						&>text {
-							margin-left: 20rpx;
-						}
-					}
+			.comments {
+				display: flex;
+				align-items: center;
+				gap: 16rpx;
 
-					.name {
-						margin-left: 20rpx;
-						margin-top: 20rpx;
-					}
+				.a-star {
+					font-size: 24rpx;
+					color: #FDD143;
 				}
 
-				.more {
-					margin-top: 20rpx;
-					display: flex;
-					align-items: center;
-					justify-content: center;
-					gap: 20rpx;
+				.a-text {
 					font-size: 24rpx;
 					color: #AAAAAA;
 				}
 			}
 		}
 
-		.appraise-card {
-			padding: 20rpx;
-			background: #FFFFFF;
-			border-radius: 32rpx;
+		.appraise-info {
 			margin-top: 20rpx;
 
-			.appraise-title {
+			.a-user-info {
 				display: flex;
 				align-items: center;
 				justify-content: space-between;
 
-				.title {
-					font-weight: 800;
-					font-size: 32rpx;
-					color: #222222;
-				}
-
-				.comments {
+				.info {
 					display: flex;
 					align-items: center;
-					gap: 16rpx;
+					gap: 20rpx;
 
-					.a-star {
-						font-size: 24rpx;
-						color: #FDD143;
+					&>image {
+						width: 60rpx;
+						height: 60rpx;
+						border-radius: 50%;
 					}
 
-					.a-text {
+					.name {
+						font-weight: bold;
 						font-size: 24rpx;
-						color: #AAAAAA;
+						color: #222222;
 					}
 				}
+
+				.time {
+					font-size: 24rpx;
+					color: #AAAAAA;
+				}
 			}
 
-			.appraise-info {
+			.a-score {
+				font-size: 24rpx;
+				color: #AAAAAA;
+				display: flex;
+				align-items: center;
+				gap: 20rpx;
 				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-content {
+				margin-top: 20rpx;
+				font-size: 28rpx;
+				color: #222222;
+			}
 
-				.a-score {
-					font-size: 24rpx;
-					color: #AAAAAA;
-					display: flex;
-					align-items: center;
-					gap: 20rpx;
-					margin-top: 20rpx;
-				}
+			.scroll-view_H {
+				white-space: nowrap;
+				width: 100%;
+				height: 220rpx;
+				margin-top: 20rpx;
+				border-bottom: 1rpx solid #F0F0F0;
 
-				.a-content {
-					margin-top: 20rpx;
-					font-size: 28rpx;
-					color: #222222;
-				}
+				.scroll-view-item_H {
+					display: inline-block;
+					text-align: center;
+					margin-right: 14rpx;
 
-				.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;
-						}
+					&>image {
+						width: 202rpx;
+						height: 200rpx;
+						background: #D8D8D8;
+						border-radius: 32rpx;
 					}
 				}
 			}
 		}
 	}
+}
+
+.c-bottom {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	position: fixed;
+	bottom: 0;
+	width: 95%;
+	padding: 20rpx;
+	background: #fff;
+	box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0, 0, 0, 0.09);
+	border-radius: 32rpx 32rpx 0rpx 0rpx;
+
+	.c-share {
+		font-weight: bold;
+		font-size: 28rpx;
+		color: #222222;
+		text-align: center;
+	}
 
-	.c-bottom {
+	.c-buy-btn {
 		display: flex;
 		align-items: center;
-		justify-content: space-between;
-		position: fixed;
-		bottom: 0;
-		width: 95%;
-		padding: 20rpx;
-		background: #fff;
-		box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0, 0, 0, 0.09);
-		border-radius: 32rpx 32rpx 0rpx 0rpx;
+		gap: 16rpx;
 
-		.c-share {
-			font-weight: bold;
-			font-size: 28rpx;
-			color: #222222;
+		.buy {
+			width: 226rpx;
+			height: 100rpx;
+			background: #222222;
+			border-radius: 60rpx;
 			text-align: center;
-		}
 
-		.c-buy-btn {
-			display: flex;
-			align-items: center;
-			gap: 16rpx;
+			.buy-text {
+				margin-top: 8rpx;
+				font-weight: bold;
+				font-size: 32rpx;
+				color: #D3FD76;
+			}
 
-			.buy {
-				width: 226rpx;
-				height: 100rpx;
-				background: #222222;
-				border-radius: 60rpx;
-				text-align: center;
+			.buy-price {
+				color: #D3FD76;
 
-				.buy-text {
-					margin-top: 8rpx;
+				&>text:first-child {
 					font-weight: bold;
-					font-size: 32rpx;
-					color: #D3FD76;
+					font-size: 28rpx;
 				}
 
-				.buy-price {
-					color: #D3FD76;
-
-					&>text:first-child {
-						font-weight: bold;
-						font-size: 28rpx;
-					}
-
-					&>text:last-child {
-						margin-left: 6rpx;
-						font-size: 22rpx;
-					}
+				&>text:last-child {
+					margin-left: 6rpx;
+					font-size: 22rpx;
 				}
 			}
+		}
 
-			.gratis {
-				width: 226rpx;
-				height: 100rpx;
-				background: #D3FD76;
-				border-radius: 60rpx;
-				font-weight: bold;
-				font-size: 32rpx;
-				color: #222222;
-				text-align: center;
-				line-height: 100rpx;
-			}
+		.gratis {
+			width: 226rpx;
+			height: 100rpx;
+			background: #D3FD76;
+			border-radius: 60rpx;
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #222222;
+			text-align: center;
+			line-height: 100rpx;
 		}
 	}
+}
 </style>

+ 116 - 106
src/pages/index/detail/components/appraise.vue

@@ -1,148 +1,158 @@
 <template>
-	<view class="appraise-card">
-		<view class="appraise-title">
-			<view class="title">评价</view>
-			<view class="comments">
-				<view class="a-star">
-					<zzx-icon name="star" size="10"></zzx-icon>
-					<text>4.8</text>
+		<view class="appraise-card">
+			<view class="appraise-title">
+				<view class="title">评价</view>
+				<view class="comments">
+					<view class="a-star">
+						<zzx-icon name="star" size="10"></zzx-icon>
+						<text>{{ listData.averageScore }}</text>
+					</view>
+					<view class="a-text">| {{ listData.scoreNum }}人评论</view>
 				</view>
-				<view class="a-text">| 37人评论</view>
 			</view>
-		</view>
-		<view class="appraise-info" v-for="item in 5" @click="check_detail">
-			<view class="a-user-info">
-				<view class="info">
-					<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
-					<view class="name">詹姆斯</view>
+			<view class="appraise-info" v-for="item in listData.records" :key="item.id" @click="check_detail">
+				<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="time">03-20</view>
-			</view>
-			<view class="a-score">
-				<text>4.0</text>
-				<uni-rate :readonly="true" size="16" :value="2" />
-			</view>
-			<view class="a-content">
-				詹姆四对孩子很有耐心,也非常照顾小朋友的情绪,
-				值得推荐!
-			</view>
-			<scroll-view class="scroll-view_H" scroll-x="true" :show-scrollbar="false">
-				<view class="scroll-view-item_H uni-bg-red" v-for="item in 5">
-					<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+				<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>
+				<scroll-view class="scroll-view_H" scroll-x="true" :show-scrollbar="false">
+					<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 class="not-data" v-if="!listData.records.length">暂无评价数据</view>
 		</view>
-	</view>
 </template>
 
 <script lang="ts" setup>
-const check_detail=()=>{
+import { _previewImage } from '@/utils/util';
+
+interface Props {
+	listData?: any;
+}
+const props = withDefaults(defineProps<Props>(), {
+	listData: [],
+});
+const check_detail = () => {
 	uni.navigateTo({
-		url:'/pages/index/commentsDetail/index'
+		url: '/pages/index/commentsDetail/index'
 	})
 }
 </script>
 
 <style lang="less" scoped>
-	.appraise-card {
-		padding: 20rpx;
-		background: #FFFFFF;
-		border-radius: 32rpx;
-		margin-top: 20rpx;
+.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;
+		}
 
-		.appraise-title {
+		.comments {
 			display: flex;
 			align-items: center;
-			justify-content: space-between;
+			gap: 16rpx;
 
-			.title {
-				font-weight: 800;
-				font-size: 32rpx;
-				color: #222222;
+			.a-star {
+				font-size: 24rpx;
+				color: #FDD143;
 			}
 
-			.comments {
-				display: flex;
-				align-items: center;
-				gap: 16rpx;
-
-				.a-star {
-					font-size: 24rpx;
-					color: #FDD143;
-				}
-
-				.a-text {
-					font-size: 24rpx;
-					color: #AAAAAA;
-				}
+			.a-text {
+				font-size: 24rpx;
+				color: #AAAAAA;
 			}
 		}
+	}
 
-		.appraise-info {
-			margin-top: 20rpx;
+	.appraise-info {
+		margin-top: 20rpx;
+
+		.a-user-info {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
 
-			.a-user-info {
+			.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;
-					}
+				gap: 20rpx;
+
+				&>image {
+					width: 60rpx;
+					height: 60rpx;
+					border-radius: 50%;
 				}
 
-				.time {
+				.name {
+					font-weight: bold;
 					font-size: 24rpx;
-					color: #AAAAAA;
+					color: #222222;
 				}
 			}
 
-			.a-score {
+			.time {
 				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;
-			}
+		.a-score {
+			font-size: 24rpx;
+			color: #AAAAAA;
+			display: flex;
+			align-items: center;
+			gap: 20rpx;
+			margin-top: 20rpx;
+		}
 
-			.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;
-						}
-					}
+		.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;
+				}
 			}
 		}
 	}
+}
 </style>

+ 86 - 75
src/pages/index/detail/components/venue.vue

@@ -1,18 +1,18 @@
 <template>
-	<view class="venue-card" v-for="(item,index) in listData" :key="index" @click="venuePreview(item)">
+	<view class="venue-card" v-for="(item, index) in listData" :key="index" @click="venuePreview(item)">
 		<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 class="title textHidden">{{ item.name }}</view>
+				<view class="sales">年售{{ item.sales }}</view>
 			</view>
 			<view class="type">
-				<text v-for="(category,index) in item.category" :key="index">{{category}}</text>
+				<text v-for="(category, index) in item.category" :key="index">{{ category }}</text>
 			</view>
 			<view class="price-info">
 				<view class="price">
-					<view class="">¥{{item.sellingPrice}}</view>
-					<view class="">¥{{item.originalPrice}}</view>
+					<view class="">¥{{ item.sellingPrice||'0.00' }}</view>
+					<!-- <view class="">¥{{ item.originalPrice }}</view> -->
 				</view>
 				<view class="price-btn">免费预约</view>
 			</view>
@@ -21,88 +21,99 @@
 </template>
 
 <script lang="ts" setup>
-	interface Props {
-		listData ?: any;
-	}
-	const props = withDefaults(defineProps<Props>(), {
-		listData: []
-	});
-	
-	const venuePreview = (item: any) => {
-		uni.navigateTo({
-			url: '/pages/index/submitOrder/index?id=' + item.id
-		})
-	}
+interface Props {
+	listData?: any;
+}
+const props = withDefaults(defineProps<Props>(), {
+	listData: []
+});
+
+const venuePreview = (item: any) => {
+	uni.navigateTo({
+		url: '/pages/index/submitOrder/index?id=' + item.id
+	})
+}
 </script>
 
 <style lang="less" scoped>
-	.venue-card{
-		padding: 20rpx;
-		background: #FFFFFF;
+.venue-card {
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+	display: flex;
+	align-items: center;
+	gap: 20rpx;
+	margin-top: 20rpx;
+
+	&>image {
+		width: 200rpx;
+		height: 200rpx;
 		border-radius: 32rpx;
-		display: flex;
-		align-items: center;
-		gap: 20rpx;
-		margin-top: 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;
-				}
+	}
+
+	.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;
 			}
-			.type{
-				margin-top: 16rpx;
-				font-size: 24rpx;
+
+			.sales {
+				font-size: 22rpx;
 				color: #AAAAAA;
 			}
-			.price-info{
+		}
+
+		.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;
-				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;
+				gap: 20rpx;
+
+				&>view:nth-child(1) {
 					font-weight: bold;
 					font-size: 28rpx;
-					color: #222222;
-					text-align: center;
-					line-height: 48rpx;
+					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;
 			}
 		}
 	}
+}
 </style>

+ 30 - 7
src/pages/index/detail/index.vue

@@ -12,8 +12,8 @@
 					<video v-for="(item, index) in videoList" :key="index" :src="item"></video>
 				</block>
 				<!-- <view class="swiper-image-box"> -->
-				<image @click="_previewImage(bannerList)" v-for="(item, index) in bannerList" :key="index" :src="item"
-					mode=""></image>
+				<image @click="_previewImage(bannerList, item)" v-for="(item, index) in bannerList" :key="index"
+					:src="item" mode=""></image>
 				<!-- </view> -->
 			</view>
 		</scroll-view>
@@ -32,8 +32,8 @@
 		</view>
 		<view class="open-time">
 			<view class="time" v-if="teachingDay">
-				<view>教学日 <text style="margin-right: 14rpx;" v-for="(item, index) in teachingDay.data"
-						:key="index">{{ item.startTime + '-' + item.endTime || '--' }}</text></view>
+				<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>
@@ -84,7 +84,7 @@
 			<instructor :instrctorList="detailInfo.instructorVOList" />
 		</view>
 		<view class="toggle" v-else>
-			<appraise />
+			<appraise :listData="appraiseList" />
 		</view>
 	</view>
 </template>
@@ -99,7 +99,7 @@ import venue from './components/venue.vue';
 import course from './components/course.vue';
 import instructor from './components/instructor.vue';
 import appraise from './components/appraise.vue';
-import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+import { onLoad, onReachBottom } from '@dcloudio/uni-app';
 import { useCacheStore } from '@/stores/cache'
 const cache = useCacheStore()
 const statusBarHeight = ref(0);
@@ -107,11 +107,17 @@ const selectList = ref(['场地', '课程', '教练', '评价']);
 const sel_index = ref(0);
 onLoad((option) => {
 	listId.value = option.id
+	appraiseFormData.value.siteId = option.id
 	get_navheight()
 })
+onReachBottom(() => {
+	appraiseFormData.value.pageNo++
+	getFindByOrderPage()
+})
 onMounted(() => {
 	get_placeInfo()
 	get_allCategory()
+	getFindByOrderPage()
 })
 const get_navheight = () => {
 	const systemInfo = uni.getSystemInfoSync();
@@ -177,11 +183,28 @@ const onchange = (e) => {
 // 课程列表
 const courseList = ref([])
 const get_courseList = (categoryId) => {
-	http.get('/detail/courseInfoVOList', { data: { categoryId: categoryId, id: listId.value, longitude:cache.get('LON'), latitude:cache.get('LAT') }, loading: true }).then((res) => {
+	http.get('/detail/courseInfoVOList', { data: { categoryId: categoryId, id: listId.value, longitude: cache.get('LON'), latitude: cache.get('LAT') }, loading: true }).then((res) => {
 		courseList.value = res.result
 	})
 }
 
+// 获取评价
+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>

+ 14 - 15
src/pages/index/gymDetail/components/popup.vue

@@ -30,10 +30,10 @@
 							<view class="children-list" v-for="(concert, index) in conc.concertsDetailsVOList"
 								:key="index">
 								<view class="item-card" :class="{ selected: isSelected(concert) }"
-									@click="selectItem(conc, concert)" v-if="concert.concertStatus==0">
+									@click="selectItem(conc, concert)" v-if="concert.concertStatus == 0">
 									¥{{ concert.price }}
 								</view>
-								<view class="item-card" style="color: #AAA;" v-if="concert.concertStatus==1">
+								<view class="item-card" style="color: #AAA;" v-if="concert.concertStatus == 1">
 									已选
 								</view>
 							</view>
@@ -128,7 +128,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onMounted, computed, nextTick } from 'vue';
+import { ref, onMounted, computed } from 'vue';
 import { http } from '@/utils/http'
 import { TipsUtils, phoneHide, RouterUtils } from '@/utils/util';
 interface Props {
@@ -139,14 +139,11 @@ interface Props {
 const props = withDefaults(defineProps<Props>(), {
 	listData: [],
 	itemList: [],
-	deteObj: null
+	deteObj: null,
 });
 const selectPopup = ref();
-const orderPopup = ref()
-const sel_index = ref(0);
-const time_list = ref([])
+const orderPopup = ref();
 onMounted(() => {
-
 })
 const open = () => {
 	selectPopup.value.open()
@@ -155,8 +152,11 @@ defineExpose({
 	open
 })
 const emit = defineEmits(['change']);
+const weekDayDate=ref()
+weekDayDate.vaue = computed(() => props.listData.stadiumConcertsVOList?.[props.deteObj]);
 const sel_tab = (e, i) => {
 	emit('change', e, i);
+	weekDayDate.value=e.weekDayDate
 }
 
 const selArr = ref([])
@@ -205,15 +205,14 @@ const get_previewOrderPlaceGymnasiumChartered = () => {
 	http.get('/order/previewOrderPlaceGymnasiumChartered', { data: { rulesId: result }, loading: true }).then((res) => {
 		previewgymOrderDetail.value = res.result
 		isopenDetail.value = true
-		orderFormData.value.productIds = res.result.timePeriod.map(item => item.id).join(',')
+		orderFormData.value.productIds = res.result.timePeriod.map(item => `${item.id}|${weekDayDate.value}`).join(',')
 		orderFormData.value.amount = res.result.timePeriod.length
-		nextTick(() => {
+		setTimeout(() => {
 			selectPopup.value.close()
-			orderPopup.value && orderPopup.value.open()
-		})
+			orderPopup.value && orderPopup.value.open();
+		},500)
 	})
 }
-
 // 提交订单
 const orderFormData = ref({
 	type: 0,
@@ -223,7 +222,7 @@ const orderFormData = ref({
 })
 const submitOrder = () => {
 	http.post('/order/createOrder', orderFormData.value, { loading: true }).then((res) => {
-		RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${res.result.orderId}&orderType=0`)
+		RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${res.result.orderId}&orderType=${orderFormData.value.orderType}`)
 	})
 }
 </script>
@@ -299,7 +298,7 @@ const submitOrder = () => {
 		padding: 20rpx;
 
 		.time-list {
-			width:180rpx;
+			width: 180rpx;
 
 			.time-title {
 				height: 60rpx;

+ 48 - 25
src/pages/index/gymDetail/index.vue

@@ -1,7 +1,8 @@
 <template>
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
-		<image class="header-bg" :src="'http://192.168.1.166:8080/jeecg-boot/sys/common/static/' + bannerList[0]" mode="">
+		<image class="header-bg" :src="'http://192.168.1.166:8080/jeecg-boot/sys/common/static/' + bannerList[0]"
+			mode="">
 		</image>
 		<view class="back-icon" :style="{ paddingTop: (statusBarHeight + 10) + 'px' }" @click="RouterUtils.back()">
 			<zzx-icon name="back"></zzx-icon>
@@ -31,8 +32,8 @@
 		</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>教学日 <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>
@@ -82,16 +83,16 @@
 					<view class="" v-if="charteredList">
 						开场前{{ charteredList.earlyRefundTime }}分钟随时退
 					</view>
-					<view class="v-left"
-						@click="RouterUtils.to_page(`/pages/index/vr/index?vrImg=${detailInfo.vr}`)">
+					<view class="v-left" @click="RouterUtils.to_page(`/pages/index/vr/index?vrImg=${detailInfo.vr}`)">
 						<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 :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" v-if="charteredList">
 						<scroll-view scroll-x="true" class="scroll-view_H">
@@ -155,8 +156,8 @@
 				<view class="">全平台每种类型的运动课程只可免费试听一次</view>
 			</view>
 			<view class="select-btn">
-				<view :class="sel_btn === index ? 'distance' : 'score'" v-for="(item, index) in allCategoryList" :key="item.id"
-					@click="selectallCategory(item, index)">{{ item.name }}</view>
+				<view :class="sel_btn === index ? 'distance' : 'score'" v-for="(item, index) in allCategoryList"
+					: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">
@@ -217,30 +218,29 @@
 				<view class="comments">
 					<view class="a-star">
 						<zzx-icon name="star" size="10"></zzx-icon>
-						<text>4.8</text>
+						<text>{{ appraiseList.averageScore }}</text>
 					</view>
-					<view class="a-text">| 37人评论</view>
+					<view class="a-text">| {{ appraiseList.scoreNum }}人评论</view>
 				</view>
 			</view>
-			<view class="appraise-info" v-for="item in 5">
+			<view class="appraise-info" v-for="item in appraiseList.records" :key="item.id">
 				<view class="a-user-info">
 					<view class="info">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
-						<view class="name">詹姆斯</view>
+						<image :src="item.avatar" mode=""></image>
+						<view class="name">{{ item.username }}</view>
 					</view>
-					<view class="time">03-20</view>
+					<view class="time">{{ DateUtils.formatDateToMMDD(item.createTime) }}</view>
 				</view>
 				<view class="a-score">
-					<text>4.0</text>
-					<uni-rate :readonly="true" size="16" :value="2" />
+					<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">
-					<view class="scroll-view-item_H uni-bg-red" v-for="item in 5">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					<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>
@@ -266,11 +266,11 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onMounted, getCurrentInstance, nextTick, computed } from 'vue';
-import { RouterUtils } from '@/utils/util';
+import { ref, onMounted, getCurrentInstance, nextTick } from 'vue';
+import { RouterUtils, DateUtils, _previewImage } from '@/utils/util';
 import { http } from '@/utils/http'
 import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
-import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+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'
@@ -287,6 +287,11 @@ 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()
@@ -295,6 +300,7 @@ onMounted(() => {
 	});
 	get_placeInfo()
 	get_allCategory()
+	getFindByOrderPage()
 })
 const get_navheight = () => {
 	const systemInfo = uni.getSystemInfoSync();
@@ -437,7 +443,7 @@ const courseList = ref([])
 const courseLoading = ref(false)
 const get_courseList = (categoryId) => {
 	courseLoading.value = true
-	http.get('/detail/courseInfoVOList', { data: { categoryId: categoryId, id: listId.value, longitude:cache.get('LON'), latitude:cache.get('LAT') }}).then((res) => {
+	http.get('/detail/courseInfoVOList', { data: { categoryId: categoryId, id: listId.value, longitude: cache.get('LON'), latitude: cache.get('LAT') } }).then((res) => {
 		courseList.value = res.result
 		courseLoading.value = false
 	})
@@ -496,6 +502,23 @@ const onchange = (e, i) => {
 	selItems.value = e.concertsVOList
 	dateIndex.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>

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

@@ -230,7 +230,7 @@ const toUserList = () => {
 	RouterUtils.to_page('/pages/index/userList/index')
 }
 
-const userData = ref()
+const userData = ref([])
 const get_userData = () => {
 	uni.$on('userData', function (data) {
 		userData.value = data
@@ -382,7 +382,8 @@ const submitOrder = () => {
 	if (!placeId.value) {
 		if (!userData.value) return TipsUtils.tips_toast('请添加用户信息')
 		if (userData.value.length < countTotal.value) return TipsUtils.tips_toast(`请至少选择${countTotal.value}人`)
-		orderFormData.value.orderType = ''
+		if(userData.value.length > countTotal.value) return TipsUtils.tips_toast(`最多选择${countTotal.value}人`)
+		orderFormData.value.orderType = 5
 		orderFormData.value.type = 2
 	} else {
 		orderFormData.value.type = 0
@@ -392,8 +393,11 @@ const submitOrder = () => {
 	if (!insureData.value || insureData.value.length === 0) {
 		delete data.insureOrderInfoForm;
 	}
+	if(!userData||userData.value.length === 0){
+		delete data.familyIds
+	}
 	http.post('/order/createOrder', data, { loading: true }).then((res) => {
-		RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${res.result.orderId}&orderType=${loadType.value}`)
+		RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${res.result.orderId}&orderType=${orderFormData.value.orderType}`)
 	})
 }
 </script>

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

@@ -125,7 +125,7 @@
 				<view class="i-card-list"
 					:style="{background:index % 2=== 0?'linear-gradient(179deg, #FFD5FB 0%, #FFFFFF 40%)':'linear-gradient( 179deg, #F2FFBE 0%, #FFFFFF 40%)'}"
 					v-for="(item,index) in instructorList" :key="item.id">
-					<view class="i-info" @click="gotoPage('/pages/index/instructorDetail/index')">
+					<view class="i-info" @click="gotoPage(`/pages/index/instructorDetail/index?id=${item.id}`)">
 						<view class="header" :style="{background:index % 2=== 0?'#FFB8F9':'#C8FF0C'}">
 							<image class="head-img" :src="item.avatar" mode=""></image>
 							<image class="head-tag" src="/src/static/badge.png" mode=""></image>
@@ -667,7 +667,6 @@
 	.hot-instructor {
 		margin-top: 20rpx;
 		position: relative;
-
 		.i-title {
 			display: flex;
 			align-items: center;
@@ -733,7 +732,7 @@
 				border-radius: 32rpx;
 				padding: 20rpx;
 				width: 670rpx;
-				height: 480rpx;
+				max-height: 480rpx;
 			}
 
 			.i-info {

+ 376 - 314
src/pages/index/instructorDetail/index.vue

@@ -2,10 +2,10 @@
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
 		<image class="header-bg" :src="detailObj.backgroundImg" mode="widthFix"></image>
-		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" @click="RouterUtils.back()">
+		<view class="back-icon" :style="{ paddingTop: (statusBarHeight + 10) + 'px' }" @click="RouterUtils.back()">
 			<zzx-icon name="back"></zzx-icon>
 		</view>
-		<view :style="{height:(statusBarHeight+100)+'px'}"></view>
+		<view :style="{ height: (statusBarHeight + 100) + 'px' }"></view>
 	</view>
 	<view class="content">
 		<view class="i-info-card">
@@ -17,33 +17,33 @@
 				<view style="width: 220rpx;"></view>
 				<view class="user-name">
 					<view class="name-box">
-						<view class="name">{{detailObj.realname}}</view>
-						<view class="type">{{detailObj.trainingProgramsName}}</view>
+						<view class="name">{{ detailObj.realname }}</view>
+						<view class="type">{{ detailObj.trainingProgramsName }}</view>
 					</view>
 					<view class="sign" @click="to_certifying">
-						<text class="textHidden">{{detailObj.headDisplay}}</text>
+						<text class="textHidden">{{ detailObj.headDisplay }}</text>
 						<zzx-icon name="ashRight" size="12"></zzx-icon>
 					</view>
 				</view>
 			</view>
 			<view class="i-sign">
-				{{detailObj.teachingPhilosophy}}
+				{{ detailObj.teachingPhilosophy }}
 			</view>
 			<view class="i-skill">
-				{{detailObj.excelMsg}}
+				{{ detailObj.excelMsg }}
 			</view>
 			<view class="i-data-card">
 				<view class="item-data">
 					<view class="text">好评率</view>
-					<view class="num">{{detailObj.goodRate}}%</view>
+					<view class="num">{{ detailObj.goodRate }}%</view>
 				</view>
 				<view class="item-data">
 					<view class="text">订单数</view>
-					<view class="num">1659</view>
+					<view class="num">{{ detailObj.orderNumber }}</view>
 				</view>
 				<view class="item-data">
 					<view class="text">授课人数</view>
-					<view class="num">{{detailObj.classesNumber||'0'}}</view>
+					<view class="num">{{ detailObj.classesNumber || '0' }}</view>
 				</view>
 			</view>
 		</view>
@@ -58,23 +58,25 @@
 					<image class="card-img" :src="item.cover" mode=""></image>
 					<view class="i-list">
 						<view class="list-name">
-							<view class="name textHidden">{{item.name}}</view>
-							<view class="num">年售{{item.annualSalesNum}}</view>
+							<view class="name textHidden">{{ item.name }}</view>
+							<view class="num">年售{{ item.annualSalesNum }}</view>
 						</view>
-						<view class="address">上课地点:{{item.address}} | {{item.km}}km</view>
+						<view class="address">上课地点:{{ item.address }} | {{ item.km }}km</view>
 						<view class="list-price">
-							<view class="left-price">¥{{item.sellingPrice}}</view>
-							<view class="right-price">¥{{item.originalPrice}}</view>
+							<view class="left-price">¥{{ item.sellingPrice }}</view>
+							<view class="right-price">¥{{ item.originalPrice }}</view>
 						</view>
-						<view class="sale-data">已售{{item.saleNum}} {{item.goodRate}}%好评</view>
+						<view class="sale-data">已售{{ item.saleNum }} {{ item.goodRate }}%好评</view>
 						<view class="course-num">
-							<view class="number">{{item.coursesNum}}课时 {{item.startTime}}-{{item.endTime}}</view>
-							<view class="i-btn" @click="RouterUtils.to_page(`/pages/index/courseDetail/index?id=${item.id}&type=3`)">抢购</view>
+							<view class="number">{{ item.coursesNum }}课时 {{ item.startTime }}-{{ item.endTime }}</view>
+							<view class="i-btn"
+								@click="RouterUtils.to_page(`/pages/index/courseDetail/index?id=${item.id}&type=3`)">抢购
+							</view>
 						</view>
 						<view style="height: 24rpx;"></view>
 					</view>
 				</view>
-				<view class="not-data" v-if="detailObj.courseInfoVOList.length<1">暂无课程数据</view>
+				<view class="not-data" v-if="detailObj.courseInfoVOList.length < 1">暂无课程数据</view>
 			</view>
 		</view>
 		<view class="appraise-card">
@@ -83,376 +85,436 @@
 				<view class="comments">
 					<view class="a-star">
 						<zzx-icon name="star" size="10"></zzx-icon>
-						<text>4.8</text>
+						<text>{{ appraiseList.averageScore }}</text>
 					</view>
-					<view class="a-text">| 37人评论</view>
+					<view class="a-text">| {{ appraiseList.scoreNum }}人评论</view>
 				</view>
 			</view>
-			<view class="appraise-info" v-for="item in 5">
+			<view class="appraise-info" v-for="item in appraiseList.records" :key="item.id">
 				<view class="a-user-info">
 					<view class="info">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
-						<view class="name">詹姆斯</view>
+						<image :src="item.avatar" mode=""></image>
+						<view class="name">{{ item.username }}</view>
 					</view>
-					<view class="time">03-20</view>
+					<view class="time">{{ DateUtils.formatDateToMMDD(item.createTime) }}</view>
 				</view>
 				<view class="a-score">
-					<text>4.0</text>
-					<uni-rate :readonly="true" size="16" :value="2" />
+					<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">
-					<view class="scroll-view-item_H uni-bg-red" v-for="item in 5">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					<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 class="not-data" v-if="!appraiseList.records.length">暂无评价数据</view>
 		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
-	import { ref, onMounted } from 'vue';
-	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
-	import { http } from '@/utils/http'
-	import { useCacheStore } from '@/stores/cache'
-	import { RouterUtils } from '@/utils/util';
-	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
-	const cache = useCacheStore()
-	const statusBarHeight = ref(0);
-	onLoad((option)=>{
-		detailId.value=option.id
+import { ref, onMounted } from 'vue';
+import { onLoad, onReachBottom } from '@dcloudio/uni-app';
+import { http } from '@/utils/http'
+import { useCacheStore } from '@/stores/cache'
+import { RouterUtils, _previewImage } from '@/utils/util';
+import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
+const cache = useCacheStore()
+const statusBarHeight = ref(0);
+onLoad((option) => {
+	detailId.value = option.id
+	appraiseFormData.value.instructorId = option.id
+})
+onReachBottom(() => {
+	appraiseFormData.value.pageNo++
+	getFindByOrderPage()
+})
+onMounted(() => {
+	get_navheight()
+	get_findByCoachId()
+	getFindByOrderPage()
+})
+const get_navheight = () => {
+	const systemInfo = uni.getSystemInfoSync();
+	statusBarHeight.value = systemInfo.statusBarHeight || 0;
+}
+
+const to_certifying = () => {
+	uni.navigateTo({
+		url: `/pages/index/certifyingDetail/index?id=${detailId.value}`
 	})
-	onMounted(() => {
-		get_navheight()
-		get_findByCoachId()
+}
+
+const detailId = ref()
+const detailObj = ref()
+const get_findByCoachId = () => {
+	http.get('/coachC/findByCoachId', { data: { id: detailId.value, longitude: cache.get('LON'), latitude: cache.get('LAT') }, loading: true }).then((res) => {
+		detailObj.value = res.result
 	})
-	const get_navheight = () => {
-		const systemInfo = uni.getSystemInfoSync();
-		statusBarHeight.value = systemInfo.statusBarHeight || 0;
-	}
-	
-	const to_certifying=()=>{
-		uni.navigateTo({
-			url:`/pages/index/certifyingDetail/index?id=${detailId.value}`
-		})
-	}
-	
-	const detailId=ref()
-	const detailObj=ref()
-	const get_findByCoachId=()=>{
-		http.get('/coachC/findByCoachId',{data:{id:detailId.value,longitude:cache.get('LON'),latitude:cache.get('LAT')},loading:true}).then((res)=>{
-			detailObj.value=res.result
-		})
-	}
+}
+
+// 获取评价
+const appraiseFormData = ref({
+	instructorId: 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%;
-			z-index: -100;
+.detail-header {
+	position: relative;
+
+	.header-bg {
+		position: absolute;
+		width: 100%;
+		z-index: -100;
+	}
+
+	.back-icon {
+		position: absolute;
+		left: 20rpx;
+		z-index: 9999;
+	}
+}
+
+.i-info-card {
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+
+	.i-userinfo {
+		display: flex;
+		align-items: center;
+
+		.user-header {
+			position: relative;
+
+			.header-img {
+				position: absolute;
+				top: -110rpx;
+				width: 160rpx;
+				height: 160rpx;
+				border-radius: 50%;
+			}
+
+			.header-badge {
+				position: absolute;
+				left: 120rpx;
+				width: 36rpx;
+				height: 36rpx;
+			}
 		}
-	
-		.back-icon {
-			position: absolute;
-			left: 20rpx;
-			z-index: 9999;
+
+		.user-name {
+			.name-box {
+				display: flex;
+				align-items: center;
+				gap: 20rpx;
+
+				.name {
+					font-weight: bold;
+					font-size: 32rpx;
+					color: #222222;
+				}
+
+				.type {
+					font-size: 28rpx;
+					color: #AAAAAA;
+				}
+			}
+
+			.sign {
+				margin-top: 20rpx;
+				width: 430rpx;
+				display: flex;
+				align-items: center;
+				gap: 10rpx;
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
 		}
 	}
-	.i-info-card{
+
+	.i-sign {
+		margin-top: 24rpx;
+		font-weight: bold;
+		font-size: 28rpx;
+		color: #222222;
+	}
+
+	.i-skill {
+		margin-top: 24rpx;
+		font-size: 24rpx;
+		color: #222222;
+	}
+
+	.i-data-card {
 		padding: 20rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+		background: #F9F9F9;
+		border-radius: 32rpx;
+		margin-top: 20rpx;
+
+		.item-data {
+			.text {
+				font-size: 24rpx;
+				color: #AAAAAA;
+			}
+
+			.num {
+				margin-top: 16rpx;
+				font-weight: bold;
+				font-size: 32rpx;
+				color: #222222;
+			}
+		}
+	}
+}
+
+.i-course-list {
+	margin-top: 20rpx;
+
+	.i-title {
+		font-weight: 800;
+		font-size: 32rpx;
+		color: #222222;
+	}
+
+	.i-course-card {
 		background: #FFFFFF;
 		border-radius: 32rpx;
-		.i-userinfo{
+		padding: 20rpx;
+		margin-top: 20rpx;
+
+		.card-tips {
 			display: flex;
 			align-items: center;
-			.user-header{
-				position: relative;
-				.header-img{
-					position: absolute;
-					top: -110rpx;
-					width: 160rpx;
-					height: 160rpx;
-					border-radius:50%;
-				}
-				.header-badge{
-					position: absolute;
-					left:120rpx;
-					width: 36rpx;
-					height: 36rpx;
-				}
+			gap: 12rpx;
+			font-size: 24rpx;
+			color: #AAAAAA;
+
+			.tips-icon {
+				width: 24rpx;
+				height: 24rpx;
+				border-radius: 50%;
+				background: #FFA347;
+				font-size: 18rpx;
+				color: #fff;
+				text-align: center;
+				line-height: 24rpx;
 			}
-			.user-name{
-				.name-box{
+		}
+
+		.card-list {
+			margin-top: 20rpx;
+			display: flex;
+			align-items: center;
+			gap: 20rpx;
+
+			.card-img {
+				width: 200rpx;
+				height: 200rpx;
+				border-radius: 32rpx;
+			}
+
+			.i-list {
+				border-bottom: 1rpx solid #F0F0F0;
+
+				.list-name {
 					display: flex;
 					align-items: center;
-					gap: 20rpx;
-					.name{
-						font-weight: bold;
+					justify-content: space-between;
+
+					.name {
+						width: 360rpx;
+						font-weight: 800;
 						font-size: 32rpx;
 						color: #222222;
 					}
-					.type{
-						font-size: 28rpx;
+
+					.num {
+						font-size: 22rpx;
 						color: #AAAAAA;
 					}
 				}
-				.sign{
-					margin-top: 20rpx;
-					width: 430rpx;
+
+				.address {
+					width: 440rpx;
+					margin-top: 10rpx;
+					font-size: 22rpx;
+					color: #AAAAAA;
+				}
+
+				.list-price {
 					display: flex;
 					align-items: center;
-					gap: 10rpx;
-					font-size: 24rpx;
-					color: #AAAAAA;
+					gap: 20rpx;
+					margin-top: 10rpx;
+
+					.left-price {
+						font-weight: bold;
+						font-size: 28rpx;
+						color: #FB5B5B;
+					}
+
+					.right-price {
+						font-size: 22rpx;
+						color: #AAAAAA;
+					}
 				}
-			}
-		}
-		.i-sign{
-			margin-top: 24rpx;
-			font-weight: bold;
-			font-size: 28rpx;
-			color: #222222;
-		}
-		.i-skill{
-			margin-top: 24rpx;
-			font-size: 24rpx;
-			color: #222222;
-		}
-		.i-data-card{
-			padding: 20rpx;
-			display: flex;
-			align-items: center;
-			justify-content: space-around;
-			background: #F9F9F9;
-			border-radius: 32rpx;
-			margin-top: 20rpx;
-			.item-data{
-				.text{
+
+				.sale-data {
+					margin-top: 10rpx;
 					font-size: 24rpx;
 					color: #AAAAAA;
 				}
-				.num{
-					margin-top: 16rpx;
-					font-weight: bold;
-					font-size: 32rpx;
-					color: #222222;
+
+				.course-num {
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					margin-top: 10rpx;
+
+					.number {
+						font-size: 24rpx;
+						color: #AAAAAA;
+					}
+
+					.i-btn {
+						width: 152rpx;
+						height: 48rpx;
+						background: #C8FF0C;
+						border-radius: 8rpx;
+						font-weight: bold;
+						font-size: 28rpx;
+						color: #222222;
+						text-align: center;
+						line-height: 48rpx;
+					}
 				}
 			}
 		}
 	}
-	.i-course-list{
-		margin-top: 20rpx;
-		.i-title{
+}
+
+.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;
 		}
-		.i-course-card{
-			background: #FFFFFF;
-			border-radius: 32rpx;
-			padding: 20rpx;
-			margin-top: 20rpx;
-			.card-tips{
-				display: flex;
-				align-items: center;
-				gap: 12rpx;
+
+		.comments {
+			display: flex;
+			align-items: center;
+			gap: 16rpx;
+
+			.a-star {
 				font-size: 24rpx;
-				color: #AAAAAA;
-				.tips-icon{
-					width: 24rpx;
-					height: 24rpx;
-					border-radius: 50%;
-					background: #FFA347;
-					font-size: 18rpx;
-					color: #fff;
-					text-align: center;
-					line-height: 24rpx;
-				}
+				color: #FDD143;
 			}
-			.card-list{
-				margin-top: 20rpx;
-				display: flex;
-				align-items: center;
-				gap: 20rpx;
-				.card-img{
-					width: 200rpx;
-					height: 200rpx;
-					border-radius: 32rpx;
-				}
-				.i-list{
-					border-bottom: 1rpx solid #F0F0F0;
-					.list-name{
-						display: flex;
-						align-items: center;
-						justify-content: space-between;
-						.name{
-							width: 360rpx;
-							font-weight: 800;
-							font-size: 32rpx;
-							color: #222222;
-						}
-						.num{
-							font-size: 22rpx;
-							color: #AAAAAA;
-						}
-					}
-					.address{
-						width:440rpx;
-						margin-top: 10rpx;
-						font-size: 22rpx;
-						color: #AAAAAA;
-					}
-					.list-price{
-						display: flex;
-						align-items: center;
-						gap: 20rpx;
-						margin-top: 10rpx;
-						.left-price{
-							font-weight: bold;
-							font-size: 28rpx;
-							color: #FB5B5B;
-						}
-						.right-price{
-							font-size: 22rpx;
-							color: #AAAAAA;
-						}
-					}
-					.sale-data{
-						margin-top: 10rpx;
-						font-size: 24rpx;
-						color: #AAAAAA;
-					}
-					.course-num{
-						display: flex;
-						align-items: center;
-						justify-content: space-between;
-						margin-top: 10rpx;
-						.number{
-							font-size: 24rpx;
-							color: #AAAAAA;
-						}
-						.i-btn{
-							width: 152rpx;
-							height: 48rpx;
-							background: #C8FF0C;
-							border-radius: 8rpx;
-							font-weight: bold;
-							font-size: 28rpx;
-							color: #222222;
-							text-align: center;
-							line-height: 48rpx;
-						}
-					}
-				}
+
+			.a-text {
+				font-size: 24rpx;
+				color: #AAAAAA;
 			}
 		}
 	}
-	.appraise-card {
-		padding: 20rpx;
-		background: #FFFFFF;
-		border-radius: 32rpx;
+
+	.appraise-info {
 		margin-top: 20rpx;
-	
-		.appraise-title {
+
+		.a-user-info {
 			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 {
+
+			.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;
-					}
+				gap: 20rpx;
+
+				&>image {
+					width: 60rpx;
+					height: 60rpx;
+					border-radius: 50%;
 				}
-	
-				.time {
+
+				.name {
+					font-weight: bold;
 					font-size: 24rpx;
-					color: #AAAAAA;
+					color: #222222;
 				}
 			}
-	
-			.a-score {
+
+			.time {
 				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;
-						}
-					}
+		}
+
+		.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;
+				}
 			}
 		}
 	}
+}
 </style>

+ 1 - 2
src/pages/index/insure/index.vue

@@ -91,8 +91,6 @@ import ZzxIcon from '@/components/zzx-icon/zzx-icon.vue';
 const priceDataList = ref<any[]>([]);
 onLoad((option) => {
   priceDataList.value = JSON.parse(option.priceDataList || '[]')
-  console.log(priceDataList.value,'携带数据');
-
 })
 onMounted(() => {
   get_userData()
@@ -125,6 +123,7 @@ const bindDateChange = (e: any) => {
 }
 
 const submitData = ref<any[]>([])
+const insureId = ref()
 const submitInfo = () => {
   if (!insureuserData.value) return TipsUtils.tips_toast('请添加被保人信息')
   if (selectDate.value == '选择日期') return TipsUtils.tips_toast('请选择日期')

+ 10 - 1
src/pages/index/messageDetail/index.vue

@@ -23,9 +23,18 @@
 	})
 
 	const messageInfo = ref()
+	// 自动为 img 标签添加自适应样式
+	const fixImgStyle = (html: string) => {
+		if (!html) return html;
+		return html.replace(/<img/gi, '<img style="max-width:100%;height:auto;display:block;"');
+	};
 	const get_magDetail = () => {
 		http.get('/home/getMsgInfo', { data: { id: msgId.value },loading:true }).then(res => {
-			messageInfo.value=res.result
+			// 处理 msgContent 字段
+			if (res.result && res.result.msgContent) {
+				res.result.msgContent = fixImgStyle(res.result.msgContent);
+			}
+			messageInfo.value = res.result;
 		})
 	}
 </script>

+ 1 - 0
src/pages/index/signWebview/index.vue

@@ -7,6 +7,7 @@ import { onLoad } from '@dcloudio/uni-app';
 import { ref } from 'vue';
 const url =ref()
 onLoad((options) => {
+  console.log(options)
   url.value= options.url || '';
 })
 </script>

+ 620 - 341
src/pages/index/submitOrder/index.vue

@@ -1,16 +1,18 @@
 <template>
 	<view class="s-header-card">
 		<zzx-icon name="location" size="14"></zzx-icon>
-		<text>{{timeList.name}}</text>
+		<text>{{ timeList.name }}</text>
 	</view>
 	<view class="content">
 		<view class="s-selectdate-card">
 			<view class="s-title">选择日期</view>
 			<view class="select-card-list">
 				<scroll-view class="scroll-view_H" scroll-x="true">
-					<view :class="selIndex===index?'item-card-select':'item-card'" :style="{backgroundColor:item.inventory<1?'#fefefe':'',color:item.inventory<1?'#dddddd':''}" v-for="(item,index) in dateList" @click="open_calendar(item,index)">
-						<view class="day">{{item.namedDay}}</view>
-						<view class="date">{{item.day.slice(5)}}</view>
+					<view :class="selIndex === index ? 'item-card-select' : 'item-card'"
+						:style="{ backgroundColor: item.inventory < 1 ? '#fefefe' : '', color: item.inventory < 1 ? '#dddddd' : '' }"
+						v-for="(item, index) in dateList" @click="open_calendar(item, index)">
+						<view class="day">{{ item.namedDay }}</view>
+						<view class="date">{{ item.day.slice(5) }}</view>
 					</view>
 				</scroll-view>
 				<view class="more-date" @click="calendar.open()">
@@ -22,36 +24,68 @@
 			<view class="s-title">选择时段</view>
 			<view class="select-card-list">
 				<scroll-view class="scroll-view_H" scroll-x="true">
-					<view class="item-card" :style="{background: `${check_index==index?'#F0FFBB':'#F6F6F6'}`}" v-for="(item,index) in timeList.timeSlot" @click="check_item(item,index)">
-						<view class="time">{{item.name}}</view>
-						<view class="allowance">余{{item.inventory}}</view>
-						<view class="price">¥{{item.price}}</view>
+					<view class="item-card" :style="{ background: `${check_index == index ? '#F0FFBB' : '#F6F6F6'}` }"
+						v-for="(item, index) in timeList.timeSlot" @click="check_item(item, index)">
+						<view class="time">{{ item.name }}</view>
+						<view class="allowance">余{{ item.inventory }}</view>
+						<view class="price">¥{{ item.price||'0.00' }}</view>
 					</view>
 				</scroll-view>
-				<view class="not-data" v-if="timeList.timeSlot.length<1">暂无可选时段</view>
+				<view class="not-data" v-if="timeList.timeSlot.length < 1">暂无可选时段</view>
 			</view>
 		</view>
-		<view class="g-insurance-card">
-			<view class="g-insurance-info">
-				<view class="insurance-type">
-					<view class="type-name">
-						<view class="name">意外险</view>
-						<view class="tips">不支持退款</view>
+		<view class="r-insurance" v-for="item in insureIdList" :key="item.id">
+			<view class="r-insurance-infobox">
+				<view class="r-image-box">
+					<image :src="item.coverImg" mode=""></image>
+				</view>
+				<view class="r-insurance-title">
+					<view class="r-insurance-name">
+						<view class="r-name">{{ item.name }}</view>
+						<view class="r-tags">不支持退款</view>
 					</view>
-					<view class="insurance-more">
-						<text>查看详情</text>
-						<zzx-icon name="ashRight" size="12"></zzx-icon>
+					<view class="r-insurance-desc" v-for="(desc, index) in item.insuranceObvious" :key="index">
+						<text v-for="([key, value], idx) in Object.entries(desc)" :key="key + idx">{{ key }}, {{
+							value }};</text>
+					</view>
+					<view class="r-insurance-type">保险公司:{{ item.insuranceName_dictText }}</view>
+					<view class="r-insurance-price">
+						<view class="r-price">¥{{ insurePrice }}/天·人</view>
+						<view class="r-insurance-btn" v-if="insureData.length < 1"
+							@click="gotoInsuracePage(item, item.priceDataList)">去投保
+						</view>
 					</view>
-				</view>
-				<view class="insurance-num" @click="select_insurance=!select_insurance">
-					<view class="">¥3/人×1份(意外事故10万,社保内医疗1万)</view>
-					<zzx-icon :name="select_insurance?'selected' : 'unchecked'" size="14"></zzx-icon>
 				</view>
 			</view>
-			<view class="insurance-total">
-				<view class="text">保险总价(共2件)</view>
-				<view class="price">¥6</view>
-			</view>
+			<view class="line" v-if="insureData.length > 0 && insureId == item.id"></view>
+			<blcok v-if="insureData.length > 0 && insureId == item.id">
+				<view class="r-insurance-adduser" v-for="(insureUser, index) in insureData" :key="index">
+					<view class="r-adduser-btn">
+						<view class="r-celar" @click="clearUser">清除</view>
+						<view class="r-edit"
+							@click="RouterUtils.to_page(`/pages/index/insure/index?priceDataList=${JSON.stringify(item.priceDataList)}`)">
+							修改</view>
+					</view>
+					<view class="r-userinfo-list">
+						<view class="r-userinfo-item">
+							<view class="r-item-title">被保人</view>
+							<view class="r-item-info">{{ insureUser.userData.length }}人(<text
+									v-for="user in insureUser.userData" :key="user.id">{{ user.fullName }},</text>)
+							</view>
+						</view>
+						<view class="r-userinfo-item">
+							<view class="r-item-title">生效时间</view>
+							<view class="r-item-info">{{ insureUser.slectObj.day }}天({{ insureUser.startDate }}-{{
+								insureUser.endDate }})
+							</view>
+						</view>
+						<view class="r-userinfo-item">
+							<view class="r-item-title">保费总金额</view>
+							<view class="r-item-info">¥{{ insureUser.totalPrice }}</view>
+						</view>
+					</view>
+				</view>
+			</blcok>
 		</view>
 		<view class="g-userinfo-card">
 			<view class="r-user">
@@ -66,8 +100,8 @@
 			<view class="r-user-list" v-for="item in userData" :key="item.id">
 				<view class="minus-user" @click="deleteUser(item)">-</view>
 				<view class="r-list">
-					<view class="name">{{item.fullName}}</view>
-					<view class="id-num">身份证 {{idCardHide(item.identityCard)}}</view>
+					<view class="name">{{ item.fullName }}</view>
+					<view class="id-num">身份证 {{ idCardHide(item.identityCard) }}</view>
 				</view>
 			</view>
 			<view class="g-adduser-btn" @click="toUserList">
@@ -78,407 +112,652 @@
 		<view class="submit-btn" @click="submitBooking">免费 立即预约</view>
 	</view>
 	<uni-calendar ref="calendar" :insert="false" :date="selectInsurance" @confirm="confirm" />
+	<uni-popup ref="insurePopup" type="center">
+		<view class="r-center-popup" v-if="agreementContent">
+			<view class="r-popup-title">{{ agreementContent.protocolName }}</view>
+			<view class="r-popup-content">
+				<rich-text :nodes="agreementContent.protocolContent"></rich-text>
+			</view>
+			<view class="r-popup-footer">
+				<view class="r-popup-needbtn" @click="toNeed">我需要购买保险</view>
+				<view class="r-popup-refusebtn" @click="toRefuse">我拒绝购买保险</view>
+				<view class="r-popup-checkbox" @click="select_insurance = !select_insurance">
+					<zzx-icon :name="select_insurance ? 'selected' : 'unchecked'" size="14"></zzx-icon>
+					<text>我已认真阅读及确认</text>
+				</view>
+			</view>
+		</view>
+	</uni-popup>
 </template>
 
 <script lang="ts" setup>
-	import { ref,onMounted } from 'vue';
-	import { RouterUtils,TipsUtils,idCardHide } from '@/utils/util';
-	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
-	import { http } from '@/utils/http'
-	const calendar=ref();
-	const check_index=ref(0);
-	onLoad((option)=>{
-		placeId.value=option.id
-	})
-	onMounted(()=>{
-		get_previewTIme()
-		get_userData()
+import { ref, onMounted } from 'vue';
+import { RouterUtils, TipsUtils, idCardHide } from '@/utils/util';
+import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+import { http } from '@/utils/http'
+const calendar = ref();
+const check_index = ref(0);
+onLoad((option) => {
+	placeId.value = option.id
+	orderFormData.value.productIds = option.id
+})
+onMounted(() => {
+	get_previewTIme()
+	get_userData()
+	getInsureData()
+})
+const toUserList = () => {
+	RouterUtils.to_page('/pages/index/userList/index')
+}
+
+const selIndex = ref(0)
+const selectInsurance = ref()
+const open_calendar = (e, i) => {
+	if (e.inventory < 1) return TipsUtils.tips_toast('该天暂无库存')
+	selectInsurance.value = e.day
+	selIndex.value = i
+	get_previewOrderPlaceSchool(e.day)
+}
+// 日历回调确认
+const confirm = (e) => {
+	get_previewOrderPlaceSchool(e.fulldate)
+}
+const rulesId = ref()
+const check_item = (e, i) => {
+	check_index.value = i
+	rulesId.value = e.id
+	orderFormData.value.productIds = e.id
+}
+
+// 预览时间选项
+const dateList = ref()
+const get_previewTIme = () => {
+	http.get('/order/previewOrderPlaceSchoolTime', { data: { placeId: placeId.value }, loading: true }).then((res) => {
+		dateList.value = res.result
+		get_previewOrderPlaceSchool(res.result[0].day)
 	})
-	const toUserList = () => {
-		RouterUtils.to_page('/pages/index/userList/index')
-	}
-	
-	const selIndex=ref(0)
-	const selectInsurance=ref()
-	const open_calendar=(e,i)=>{
-		if(e.inventory<1) return TipsUtils.tips_toast('该天暂无库存')
-		selectInsurance.value=e.day
-		selIndex.value=i
-		get_previewOrderPlaceSchool(e.day)
-	}
-	// 日历回调确认
-	const confirm=(e)=>{
-		get_previewOrderPlaceSchool(e.fulldate)
-	}
-	const check_item=(e,i)=>{
-		check_index.value=i
-		rulesId.value=e.id
-		
-	}
-	
-	// 预览时间选项
-	const dateList=ref()
-	const get_previewTIme=()=>{
-		http.get('/order/previewOrderPlaceSchoolTime',{data:{placeId:placeId.value},loading:true}).then((res)=>{
-			dateList.value=res.result
-			get_previewOrderPlaceSchool(res.result[0].day)
-		})
-	}
-	
-	// 场地信息预览
-	const placeId=ref()
-	const timeList=ref()
-	const get_previewOrderPlaceSchool=(startTime)=>{
-		http.get('/order/previewOrderPlaceSchool',{data:{placeId:placeId.value,startTime:startTime},loading:true}).then((res)=>{
-			timeList.value=res.result
-			rulesId.value=res.result.timeSlot[0].id
+}
+
+// 场地信息预览
+const placeId = ref()
+const timeList = ref()
+const insureIdList = ref([])  // 保险列表
+const insurePrice = ref() // 保险价格
+const get_previewOrderPlaceSchool = (startTime) => {
+	http.get('/order/previewOrderPlaceSchool', { data: { placeId: placeId.value, startTime: startTime }, loading: true }).then((res) => {
+		timeList.value = res.result
+		rulesId.value = res.result.timeSlot[0].id
+		orderFormData.value.productIds = res.result.timeSlot[0].id
+		res.result.insureIdList.map((item: any) => {
+			item.insuranceObvious = JSON.parse(item.insuranceObvious)
+			item.insuranceObvious = [item.insuranceObvious]
+			item.priceDataList.map((item2: any) => {
+				if (item2.insureDay === 1) {
+					insurePrice.value = item2.insurePrice
+				}
+			})
 		})
+		insureIdList.value = res.result.insureIdList
+	})
+}
+
+const insureData = ref([])
+const getInsureData = () => {
+	uni.$on('insureData', function (data) {
+		insureData.value = data
+		console.log(insureData.value, '投保人信息');
+		orderFormData.value.insureOrderInfoForm.assertStartTime = insureData.value[0].startDate
+		orderFormData.value.insureOrderInfoForm.assertEndTime = insureData.value[0].endDate
+		orderFormData.value.insureOrderInfoForm.insurePriceId = insureData.value[0].slectObj.id
+		if (data.length > 0) {
+			let familyMembersIds = data[0].userData.map(item => item.id)
+			orderFormData.value.insureOrderInfoForm.familyMembersIds = familyMembersIds.join(',')
+		} else {
+			orderFormData.value.insureOrderInfoForm.familyMembersIds = []
+		}
+	})
+}
+
+const clearUser = async () => {
+	let res: any = await TipsUtils.tips_alert('确定清除投保人信息吗?', true)
+	if (res.confirm) {
+		insureData.value = []
 	}
-	
-	const userData=ref([])
-	const get_userData=()=>{
-		uni.$on('userData',function(data){
-			userData.value=data
-		})
+}
+
+const priceDataListData = ref([])
+const insureId = ref()
+const gotoInsuracePage = (e1: any, e2: any) => {
+	insureId.value = e1.id
+	getFindByType(e1.insuranceName)
+	priceDataListData.value = e2
+	orderFormData.value.insureOrderInfoForm.insureId = e1.id
+}
+
+const agreementContent = ref()
+const insurePopup = ref()
+const getFindByType = (insuranceName: any) => {
+	http.get('/my/feedback/findByType', { data: { insuranceName: insuranceName, protocolType: 0 }, loading: true }).then((res: any) => {
+		agreementContent.value = res.result
+		insurePopup.value.open()
+	})
+}
+
+const select_insurance = ref(false)
+const toNeed = () => {
+	if (!select_insurance.value) return TipsUtils.tips_toast('请先阅读并同意协议')
+	RouterUtils.to_page(`/pages/index/insure/index?priceDataList=${JSON.stringify(priceDataListData.value)}&insureId=${insureId.value}`)
+	insurePopup.value.close()
+}
+
+const toRefuse = () => {
+	if (select_insurance.value) {
+		insurePopup.value.close()
+	} else {
+		TipsUtils.tips_toast('请先阅读并同意协议')
 	}
-	
-	const deleteUser=async(e)=>{
-		let res = await TipsUtils.tips_alert('确定删除该用户吗?',true)
-		if(res.confirm){
-			userData.value=userData.value.filter(user=>user.id!==e.id)
+}
+const userData = ref([])
+const get_userData = () => {
+	uni.$on('userData', function (data) {
+		userData.value = data
+		if (data.length > 0) {
+			let familyIds = data.map(item => item.id)
+			orderFormData.value.familyIds = familyIds.join(',')
+		} else {
+			orderFormData.value.familyIds = []
 		}
+	})
+}
+
+const deleteUser = async (e) => {
+	let res = await TipsUtils.tips_alert('确定删除该用户吗?', true)
+	if (res.confirm) {
+		userData.value = userData.value.filter(user => user.id !== e.id)
 	}
-	
-	const rulesId=ref()
-	const submitBooking=()=>{
-		if(!rulesId.value) return TipsUtils.tips_toast('请选择时段')
-		if(userData.value.length<1) return TipsUtils.tips_toast('请添加用户')
-		let userIds=userData.value.map(item=>item.id).join(',')
-		rulesId.value=rulesId.value.toString()
-		http.get('/order/createOrderPlaceSchool',{data:{rulesId:rulesId.value,userIds:userIds},loading:true}).then((res)=>{
-			RouterUtils.to_page('/pages/index/toBeUsed/index')
-		})
+}
+
+let orderFormData = ref({
+	type: 0,
+	orderType: 0,
+	productIds: null,
+	familyIds: '',
+	insureOrderInfoForm: {
+		insureId: '',
+		assertStartTime: '',
+		assertEndTime: '',
+		insurePriceId: '',
+		familyMembersIds: '',
 	}
+})
+const submitBooking = () => {
+	let data = { ...orderFormData.value };
+	if (!insureData.value || insureData.value.length === 0) {
+		delete data.insureOrderInfoForm;
+	}
+	http.post('/order/createOrder', data, { loading: true }).then((res) => {
+		RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${res.result.orderId}&orderType=${orderFormData.value.orderType}`)
+	})
+}
 </script>
 
 <style lang="less" scoped>
-	.s-header-card {
-		background: #fff;
-		padding: 20rpx;
-		display: flex;
-		align-items: center;
-		gap: 10rpx;
+.s-header-card {
+	background: #fff;
+	padding: 20rpx;
+	display: flex;
+	align-items: center;
+	gap: 10rpx;
+	font-weight: bold;
+	font-size: 28rpx;
+	color: #222222;
+}
+
+.s-selectdate-card {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);
+	border-radius: 32rpx;
+
+	.s-title {
 		font-weight: bold;
 		font-size: 28rpx;
 		color: #222222;
 	}
 
-	.s-selectdate-card {
+	.select-card-list {
 		margin-top: 20rpx;
-		padding: 20rpx;
-		background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);
-		border-radius: 32rpx;
+		display: flex;
+		align-items: center;
 
-		.s-title {
-			font-weight: bold;
-			font-size: 28rpx;
-			color: #222222;
-		}
+		.scroll-view_H {
+			white-space: nowrap;
+			width: 90%;
 
-		.select-card-list {
-			margin-top: 20rpx;
-			display: flex;
-			align-items: center;
-			.scroll-view_H {
-				white-space: nowrap;
-				width: 90%;
-				.item-card-select{
-					margin-right: 16rpx;
-					display: inline-block;
-					width: 104rpx;
-					height: 120rpx;
-					background: #F0FFBB;
-					border-radius: 16rpx;
-					font-size: 24rpx;
-					color: #222222;
-					text-align: center;
-					
-					.day {
-						padding-top: 20rpx;
-					}
-					
-					.date {
-						margin-top: 12rpx;
-					}
+			.item-card-select {
+				margin-right: 16rpx;
+				display: inline-block;
+				width: 104rpx;
+				height: 120rpx;
+				background: #F0FFBB;
+				border-radius: 16rpx;
+				font-size: 24rpx;
+				color: #222222;
+				text-align: center;
+
+				.day {
+					padding-top: 20rpx;
 				}
-				.item-card {
-					margin-right: 16rpx;
-					display: inline-block;
-					width: 104rpx;
-					height: 120rpx;
-					background: #F6F6F6;
-					border-radius: 16rpx;
-					font-size: 24rpx;
-					color: #222222;
-					text-align: center;
-					.day {
-						padding-top: 20rpx;
-					}
 
-					.date {
-						margin-top: 12rpx;
-					}
+				.date {
+					margin-top: 12rpx;
 				}
 			}
-			.more-date{
-				width: 200rpx;
+
+			.item-card {
+				margin-right: 16rpx;
+				display: inline-block;
+				width: 104rpx;
+				height: 120rpx;
+				background: #F6F6F6;
+				border-radius: 16rpx;
 				font-size: 24rpx;
-				color: #FDD143;
+				color: #222222;
 				text-align: center;
+
+				.day {
+					padding-top: 20rpx;
+				}
+
+				.date {
+					margin-top: 12rpx;
+				}
 			}
 		}
+
+		.more-date {
+			width: 200rpx;
+			font-size: 24rpx;
+			color: #FDD143;
+			text-align: center;
+		}
+	}
+}
+
+.s-selecttime-card {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);
+	border-radius: 32rpx;
+
+	.s-title {
+		font-weight: bold;
+		font-size: 28rpx;
+		color: #222222;
 	}
 
-	.s-selecttime-card {
+	.select-card-list {
 		margin-top: 20rpx;
-		padding: 20rpx;
-		background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);
-		border-radius: 32rpx;
 
-		.s-title {
-			font-weight: bold;
-			font-size: 28rpx;
-			color: #222222;
-		}
+		.scroll-view_H {
+			white-space: nowrap;
+			width: 100%;
 
-		.select-card-list {
-			margin-top: 20rpx;
+			.item-card {
+				margin-right: 16rpx;
+				display: inline-block;
+				width: 220rpx;
+				height: 172rpx;
+				background: #F6F6F6;
+				border-radius: 16rpx;
+				text-align: center;
 
-			.scroll-view_H {
-				white-space: nowrap;
-				width: 100%;
-
-				.item-card {
-					margin-right: 16rpx;
-					display: inline-block;
-					width: 220rpx;
-					height: 172rpx;
-					background: #F6F6F6;
-					border-radius: 16rpx;
-					text-align: center;
+				.time {
+					margin-top: 30rpx;
+					font-size: 24rpx;
+					color: #222222;
+				}
+
+				.allowance {
+					margin-top: 12rpx;
+					font-size: 24rpx;
+					color: #222222;
+				}
 
-					.time {
-						margin-top: 30rpx;
-						font-size: 24rpx;
-						color: #222222;
-					}
-
-					.allowance {
-						margin-top: 12rpx;
-						font-size: 24rpx;
-						color: #222222;
-					}
-
-					.price {
-						margin-top: 12rpx;
-						font-weight: bold;
-						font-size: 28rpx;
-						color: #FB5B5B;
-					}
+				.price {
+					margin-top: 12rpx;
+					font-weight: bold;
+					font-size: 28rpx;
+					color: #FB5B5B;
 				}
 			}
 		}
 	}
-	.g-insurance-card {
-		background: #FFFFFF;
-		border-radius: 32rpx;
-		padding: 20rpx;
-		margin-top: 20rpx;
-	
-		.g-insurance-info {
-			.insurance-type {
+}
+
+.r-insurance {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+
+	.r-insurance-infobox {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		gap: 20rpx;
+		margin-bottom: 20rpx;
+
+		.r-image-box {
+			&>image {
+				width: 200rpx;
+				height: 200rpx;
+				border-radius: 32rpx;
+			}
+		}
+
+		.r-insurance-title {
+			.r-insurance-name {
 				display: flex;
 				align-items: center;
-				justify-content: space-between;
-	
-				.type-name {
-					display: flex;
-					align-items: center;
-					gap: 10rpx;
-	
-					.name {
-						font-weight: bold;
-						font-size: 28rpx;
-						color: #222222;
-					}
-	
-					.tips {
-						width: 136rpx;
-						height: 36rpx;
-						background: #FDD143;
-						border-radius: 8rpx;
-						font-size: 22rpx;
-						color: #222222;
-						text-align: center;
-						line-height: 36rpx;
-					}
+				gap: 16rpx;
+
+				.r-name {
+					font-weight: 800;
+					font-size: 28rpx;
+					color: #222222;
 				}
-	
-				.insurance-more {
-					display: flex;
-					align-items: center;
-					gap: 10rpx;
-	
-					&>text {
-						margin-bottom: 4rpx;
-						font-size: 24rpx;
-						color: #AAAAAA;
-					}
+
+				.r-tags {
+					width: 136rpx;
+					height: 36rpx;
+					background: #FDD143;
+					border-radius: 8rpx;
+					font-size: 22rpx;
+					color: #222222;
+					text-align: center;
+					line-height: 36rpx;
 				}
 			}
-	
-			.insurance-num {
-				margin-top: 16rpx;
-				display: flex;
-				align-items: center;
-				justify-content: space-between;
+
+			.r-insurance-desc {
+				width: 440rpx;
+				margin-top: 10rpx;
 				font-size: 24rpx;
 				color: #AAAAAA;
 			}
-		}
-	
-		.insurance-total {
-			margin-top: 20rpx;
-			border-top: 1rpx solid #F0F0F0;
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			height: 88rpx;
-	
-			.text {
-				font-size: 28rpx;
-				color: #222222;
+
+			.r-insurance-type {
+				margin-top: 10rpx;
+				font-size: 24rpx;
+				color: #AAAAAA;
 			}
-	
-			.price {
-				font-weight: bold;
-				font-size: 28rpx;
-				color: #FB5B5B;
+
+			.r-insurance-price {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+
+				.r-price {
+					font-weight: bold;
+					font-size: 28rpx;
+					color: #FB5B5B;
+				}
+
+				.r-insurance-btn {
+					width: 200rpx;
+					height: 68rpx;
+					background: #C8FF0C;
+					border-radius: 60rpx;
+					font-weight: bold;
+					font-size: 28rpx;
+					color: #222222;
+					text-align: center;
+					line-height: 68rpx;
+				}
 			}
 		}
 	}
 
-	.g-userinfo-card {
-		margin-top: 20rpx;
-		padding: 20rpx;
-		background: #FFFFFF;
+	.r-insurance-adduser {
+		background: #F6F6F6;
 		border-radius: 32rpx;
+		padding: 20rpx;
+		margin-top: 20rpx;
 
-		.r-user {
+		.r-adduser-btn {
 			display: flex;
 			align-items: center;
-			justify-content: space-between;
+			justify-content: flex-end;
+			gap: 20rpx;
 
-			.user-title {
+			.r-celar {
+				width: 192rpx;
+				height: 60rpx;
+				background: #FFFFFF;
+				border-radius: 60rpx;
+				border: 2rpx solid #FB5B5B;
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #FB5B5B;
+				text-align: center;
+				line-height: 68rpx;
+			}
+
+			.r-edit {
+				width: 200rpx;
+				height: 68rpx;
+				background: #C8FF0C;
+				border-radius: 60rpx;
 				font-weight: bold;
 				font-size: 28rpx;
 				color: #222222;
+				text-align: center;
+				line-height: 68rpx;
 			}
+		}
 
-			.invite {
+		.r-userinfo-list {
+			.r-userinfo-item {
 				display: flex;
 				align-items: center;
-				gap: 8rpx;
-				font-size: 24rpx;
-				color: #AAAAAA;
+				justify-content: space-between;
+				margin-top: 20rpx;
+
+				.r-item-title {
+					font-size: 28rpx;
+					color: #AAAAAA;
+				}
+
+				.r-item-info {
+					font-size: 28rpx;
+					color: #222222;
+				}
 			}
 		}
+	}
+}
 
-		.user-tags {
-			margin-top: 20rpx;
-			width: 112rpx;
-			height: 40rpx;
-			background: #FDD143;
-			border-radius: 8rpx;
-			line-height: 40rpx;
+.g-userinfo-card {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+
+	.r-user {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+
+		.user-title {
 			font-weight: bold;
 			font-size: 28rpx;
 			color: #222222;
-			text-align: center;
-			font-size: 28rpx;
-			color: #222222;
 		}
 
-		.r-user-list {
-			margin-top: 20rpx;
+		.invite {
 			display: flex;
 			align-items: center;
-			gap: 20rpx;
-			border-top: 1rpx solid #F0F0F0;
-			height: 140rpx;
-
-			.minus-user {
-				width: 30rpx;
-				height: 30rpx;
-				border-radius: 50%;
-				background: #FB5B5B;
-				text-align: center;
-				line-height: 20rpx;
-				font-weight: 600;
-				color: #fff;
-				font-size: 40rpx;
-			}
+			gap: 8rpx;
+			font-size: 24rpx;
+			color: #AAAAAA;
+		}
+	}
 
-			.r-list {
-				.name {
-					font-weight: bold;
-					font-size: 28rpx;
-					color: #222222;
-				}
+	.user-tags {
+		margin-top: 20rpx;
+		width: 112rpx;
+		height: 40rpx;
+		background: #FDD143;
+		border-radius: 8rpx;
+		line-height: 40rpx;
+		font-weight: bold;
+		font-size: 28rpx;
+		color: #222222;
+		text-align: center;
+		font-size: 28rpx;
+		color: #222222;
+	}
 
-				.id-num {
-					font-size: 28rpx;
-					color: #222222;
-				}
-			}
+	.r-user-list {
+		margin-top: 20rpx;
+		display: flex;
+		align-items: center;
+		gap: 20rpx;
+		border-top: 1rpx solid #F0F0F0;
+		height: 140rpx;
+
+		.minus-user {
+			width: 30rpx;
+			height: 30rpx;
+			border-radius: 50%;
+			background: #FB5B5B;
+			text-align: center;
+			line-height: 20rpx;
+			font-weight: 600;
+			color: #fff;
+			font-size: 40rpx;
 		}
 
-		.g-adduser-btn {
-			display: flex;
-			height: 88rpx;
-			align-items: center;
-			justify-content: center;
-			gap: 20rpx;
-			border-top: 1rpx solid #F0F0F0;
-
-			.add-icon {
-				width: 30rpx;
-				height: 30rpx;
-				border-radius: 50%;
-				background: #FDD143;
-				font-size: 30rpx;
-				font-weight: 600;
-				color: #fff;
-				text-align: center;
-				line-height: 20rpx;
+		.r-list {
+			.name {
+				font-weight: bold;
+				font-size: 28rpx;
+				color: #222222;
 			}
 
-			.add-text {
+			.id-num {
 				font-size: 28rpx;
-				color: #FDD143;
+				color: #222222;
 			}
 		}
 	}
-	.submit-btn{
-		margin-top: 20rpx;
-		width:100%;
-		height: 100rpx;
-		background: #C8FF0C;
-		border-radius: 60rpx;
+
+	.g-adduser-btn {
+		display: flex;
+		height: 88rpx;
+		align-items: center;
+		justify-content: center;
+		gap: 20rpx;
+		border-top: 1rpx solid #F0F0F0;
+
+		.add-icon {
+			width: 30rpx;
+			height: 30rpx;
+			border-radius: 50%;
+			background: #FDD143;
+			font-size: 30rpx;
+			font-weight: 600;
+			color: #fff;
+			text-align: center;
+			line-height: 20rpx;
+		}
+
+		.add-text {
+			font-size: 28rpx;
+			color: #FDD143;
+		}
+	}
+}
+
+.submit-btn {
+	margin-top: 20rpx;
+	width: 100%;
+	height: 100rpx;
+	background: #C8FF0C;
+	border-radius: 60rpx;
+	font-weight: bold;
+	font-size: 32rpx;
+	color: #222222;
+	text-align: center;
+	line-height: 100rpx;
+}
+
+.r-center-popup {
+	width: 646rpx;
+	max-height: 1000rpx;
+	background: #F6F6F6;
+	border-radius: 32rpx;
+	padding: 20rpx;
+
+	.r-popup-title {
 		font-weight: bold;
 		font-size: 32rpx;
 		color: #222222;
 		text-align: center;
-		line-height: 100rpx;
 	}
+
+	.r-popup-content {
+		margin-top: 28rpx;
+		font-size: 28rpx;
+		color: #222222;
+		max-height: 600rpx;
+		overflow: auto;
+	}
+
+	.r-popup-footer {
+		margin-top: 20rpx;
+
+		.r-popup-needbtn {
+			margin: auto;
+			width: 598rpx;
+			height: 100rpx;
+			background: #C8FF0C;
+			border-radius: 60rpx;
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #222222;
+			text-align: center;
+			line-height: 100rpx;
+		}
+
+		.r-popup-refusebtn {
+			margin: auto;
+			margin-top: 24rpx;
+			width: 598rpx;
+			height: 100rpx;
+			background: #f0eeee;
+			border-radius: 60rpx;
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #AAAAAA;
+			text-align: center;
+			line-height: 100rpx;
+		}
+
+		.r-popup-checkbox {
+			margin-top: 20rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			gap: 16rpx;
+			font-size: 24rpx;
+			color: #AAAAAA;
+
+			&>text {
+				margin-bottom: 8rpx;
+			}
+		}
+	}
+}
 </style>

+ 80 - 65
src/pages/index/toBeUsed/index.vue

@@ -1,42 +1,44 @@
-<!-- 订单类型orderType:1;2体育馆课程进入 -->
+<!-- 订单类型orderType:0-学校 1-包场 2-无固定场 3-个人赛 4-团队赛 5-课程 -->
 <template>
-	<view class="content">
+	<view class="content" v-if="!loading">
 		<view class="t-header">
-			<view class="title">{{ orderDetailInfo.orderStatus }}</view>
-			<view class="time" v-for="item in orderDetailInfo.proInfoList" :key="item.id"><text>{{ item.ticketNo
-			}}</text>{{ orderDetailInfo.orderStatus }}<text
-					v-if="orderDetailInfo.orderStatus == '待使用'">,请按课表到上课地点按时上课。</text></view>
+			<view class="title">{{ orderDetailInfo?.orderStatus }}</view>
+			<view class="time" v-for="item in orderDetailInfo?.proInfoList" :key="item.id">
+				<text>{{ item.ticketNo }}</text>
+				<text v-if="orderDetailInfo?.orderStatus">{{ orderDetailInfo?.orderStatus }}</text>
+				<text v-if="orderDetailInfo?.orderStatus == '待使用'">,请按课表到上课地点按时上课。</text>
+			</view>
 		</view>
-		<view class="t-booking-card" v-if="orderPageInfo.orderType != 2">
+		<view class="t-booking-card" v-if="orderPageInfo?.orderType == 3">
 			<view class="booking-text">
 				<view class="b-title">请您提前联系场馆进行预约</view>
 				<view class="b-text">请提前一天预约>场馆确认>到馆消费</view>
 			</view>
 			<view class="booking-btn">立即预约</view>
 		</view>
-		<!-- 场 -->
-		<view class="c-scheduled-card" v-if="orderPageInfo.orderType == 0">
+		<!-- 场 -->
+		<view class="c-scheduled-card" v-if="orderPageInfo?.orderType == 0||orderPageInfo?.orderType==1">
 			<view class="title">预定信息</view>
 			<view class="schedule-address">
 				<view class="text">场馆</view>
-				<view class="name">体育馆综合训练馆(观山湖店)</view>
+				<view class="name">{{ orderDetailInfo?.siteName }}</view>
 			</view>
 			<view class="schedule-address">
 				<view class="text">场次</view>
 				<view class="">
-					<view class="time-box" v-for="item in 3">
-						<view class="time">06-11(周三)11:00-12:00|羽毛球1</view>
-						<view class="status">已退款</view>
+					<view class="time-box" v-for="item in orderDetailInfo?.proInfoList" :key="item.id">
+						<view class="time">{{item.useDateStr}} {{ item.frameTimeStr }} {{ item.productName }}</view>
+						<view class="status" v-if="orderPageInfo?.orderType == 1">已退款</view>
 					</view>
 				</view>
 			</view>
 		</view>
-		<view class="t-shoping-card">
-			<view class="venue-address" v-if="orderPageInfo.orderType != 2">
+		<view class="t-shoping-card" v-if="orderPageInfo?.orderType == 2 || orderPageInfo?.orderType == 5">
+			<view class="venue-address" v-if="orderPageInfo?.orderType == 2">
 				<view class="address">
 					<zzx-icon name="venue-icon4" size="14"></zzx-icon>
-					<view class="name">{{ orderDetailInfo.siteName }}</view>
-					<view class="venue-tags">{{ orderDetailInfo.runStatus == 0 ? '营业中' : '休息中' }}</view>
+					<view class="name">{{ orderDetailInfo?.siteName }}</view>
+					<view class="venue-tags">{{ orderDetailInfo?.runStatus == 0 ? '营业中' : '休息中' }}</view>
 				</view>
 				<view class="check-all">
 					<text>查看所有可用场馆</text>
@@ -44,28 +46,28 @@
 				</view>
 			</view>
 			<view class="t-shoping-info">
-				<image class="shoping-img" :src="orderDetailInfo.appCourses.cover" mode="">
+				<image class="shoping-img" :src="orderDetailInfo?.appCourses?.cover" mode="">
 				</image>
 				<view class="shoping-info">
-					<view class="name">{{ orderDetailInfo.appCourses.name }}</view>
+					<view class="name">{{ orderDetailInfo?.appCourses?.name }}</view>
 					<view class="shoping-price" @click="pricePopup.open()">
-						<view class="price">¥{{ orderDetailInfo.totalPrice }}</view>
+						<view class="price">¥{{ orderDetailInfo?.totalPrice }}</view>
 						<view class="text">
 							<text>实付</text>
 							<text class="mini-text">¥</text>
-							<text class="price-big">{{ orderDetailInfo.price }}</text>
+							<text class="price-big">{{ orderDetailInfo?.price }}</text>
 							<zzx-icon name="ashRight" size="10"></zzx-icon>
 						</view>
 					</view>
 				</view>
 			</view>
 			<view class="t-shoping-address"
-				@click="RouterUtils.to_page(`/pages/index/verificationRecord/index?orderId=${orderDetailInfo.id}&ticketNo=${orderDetailInfo.proInfoList[0].ticketNo}`)">
-				<view class="address">上课地点:{{ orderDetailInfo.courseSiteAddress }}</view>
+				@click="RouterUtils.to_page(`/pages/index/verificationRecord/index?orderId=${orderDetailInfo?.id}&proInfoList=${JSON.stringify(orderDetailInfo?.proInfoList)}`)">
+				<view class="address">上课地点:{{ orderDetailInfo?.courseSiteAddress }}</view>
 				<view class="course-time">
-					<text>{{ orderDetailInfo.appCourses.classNum }}课时
-						{{ DateUtils.formatDateToMMDD(orderDetailInfo.appCourses.startTime) + '-' +
-							DateUtils.formatDateToMMDD(orderDetailInfo.appCourses.endTime) }}</text>
+					<text>{{ orderDetailInfo?.appCourses?.classNum }}课时
+						{{ DateUtils.formatDateToMMDD(orderDetailInfo?.appCourses?.startTime) + '-' +
+							DateUtils.formatDateToMMDD(orderDetailInfo?.appCourses?.endTime) }}</text>
 					<zzx-icon name="ashRight" size="10"></zzx-icon>
 				</view>
 			</view>
@@ -74,24 +76,29 @@
 			</view>
 		</view>
 		<!-- 待使用展示 -->
-		<view class="t-qrcode-card" v-if="orderPageInfo.orderType == 2||orderPageInfo.orderType == 0">
-			<view class="qrcode-box">
-				<view class="item-qrcode">
-					<uv-qrcode ref="qrcode" size="100px" :value="orderDetailInfo.id"></uv-qrcode>
+		<view class="t-qrcode-card" v-if="orderPageInfo?.orderType == 2 || orderPageInfo?.orderType == 0|| orderPageInfo?.orderType == 5|| orderPageInfo?.orderType == 1">
+			<block v-if="orderDetailInfo?.orSchoolCourse!=1">
+				<view class="qrcode-box">
+					<view class="item-qrcode">
+						<uv-qrcode ref="qrcode" size="100px" :value="orderDetailInfo?.id"></uv-qrcode>
+					</view>
 				</view>
-			</view>
-			<view class="download-qrcode" @click="download_qrcode">下载到手机</view>
+				<view class="download-qrcode" @click="download_qrcode">下载到手机</view>
+			</block>
+			<view v-else style="color: #222;font-size: 26rpx;">通过学校门口闸机时,通过人脸自动核验</view>
 			<view class="t-todeused">
 				<view class="todeused">
 					<view class="text">待使用</view>
-					<view class="time">{{ orderDetailInfo.appCourses.endTime }} 到期</view>
+					<view class="time" v-if="orderDetailInfo?.appCourses?.endTime||orderDetailInfo?.endTime">{{ orderDetailInfo?.appCourses?.endTime||orderDetailInfo?.endTime }} 到期</view>
 				</view>
-				<view class="order-num" v-for="item in orderDetailInfo.proInfoList" :key="item.id">{{ item.ticketNo }}
+				<view class="order-num" v-for="item in orderDetailInfo?.proInfoList" :key="item.id">
+					<text>{{ item.ticketNo }}&nbsp;&nbsp; {{ item.userName }}</text>
+					<zzx-icon name="ashRight" size="12"></zzx-icon>
 				</view>
 			</view>
 		</view>
 		<!-- 已使用已过期展示 -->
-		<view class="t-qrcode-card" v-if="orderPageInfo.orderType == 0">
+		<view class="t-qrcode-card" v-if="orderPageInfo?.orderType == 1">
 			<view class="t-todeused" v-for="item in 2" style="border-bottom: 1rpx solid #F0F0F0;">
 				<view class="todeused">
 					<view class="item-todeused">
@@ -107,7 +114,7 @@
 			</view>
 		</view>
 		<!-- 学校场地预定订单详情展示 -->
-		<view class="t-scheduled-card" v-if="orderPageInfo.orderType != 2">
+		<view class="t-scheduled-card" v-if="orderPageInfo?.orderType == 2">
 			<view class="s-title">预定信息</view>
 			<view class="t-scheduled-list">
 				<view class="item-list">
@@ -131,7 +138,7 @@
 		<view class="t-address-card">
 			<view class="address">
 				<zzx-icon name="location"></zzx-icon>
-				<view class="">{{ orderDetailInfo.courseSiteAddress }}</view>
+				<view class="">{{ orderDetailInfo?.courseSiteAddress||orderDetailInfo?.schoolAddress }}</view>
 			</view>
 			<view class="nav-info">
 				<view class="nav" @click="open_map">
@@ -147,14 +154,14 @@
 		<view class="t-use-card">
 			<view class="use-tips">
 				<view class="title">使用须知</view>
-				<view class="text">{{ orderDetailInfo.reminder }}</view>
+				<view class="text">{{ orderDetailInfo?.reminder }}</view>
 			</view>
 			<!-- <view class="check-all">
 				<text>查看全部</text>
 				<zzx-icon name="ashRight" size="12"></zzx-icon>
 			</view> -->
 		</view>
-		<view class="t-use-card" v-if="orderPageInfo.orderType != 2">
+		<view class="t-use-card" v-if="orderPageInfo?.orderType == 0">
 			<view class="use-tips">
 				<view class="title">参赛意外险</view>
 				<view class="text">实际付款:6元(3元/份×2)</view>
@@ -164,13 +171,14 @@
 				<zzx-icon name="ashRight" size="12"></zzx-icon>
 			</view>
 		</view>
-		<view class="t-use-card" v-if="orderPageInfo.orderType == 2">
+		<view class="t-use-card" v-if="orderPageInfo?.orderType == 2">
 			<view class="use-tips t-contract-list">
 				<view class="title">电子合同</view>
 				<view class="text contract-list">
 					<view class="item-no-sign">
 						<view class="sign-title">未签署:</view>
-						<view class="sign-name"  v-for="item in notSignList" :key="item.id" @click="checkSign(item)">{{ item.fullName }}</view>
+						<view class="sign-name" v-for="item in notSignList" :key="item.id" @click="checkSign(item)">{{
+							item.fullName }}</view>
 					</view>
 					<view class="item-sign">
 						<view class="sign-title">已签署:</view>
@@ -187,46 +195,48 @@
 			<view class="title">订单信息</view>
 			<view class="info-list">
 				<view class="item-left">实际付款</view>
-				<view class="item-right">¥{{ orderDetailInfo.price }}</view>
+				<view class="item-right">¥{{ orderDetailInfo?.price }}</view>
 			</view>
 			<view class="info-list">
 				<view class="item-left">手机号码</view>
-				<view class="item-right">{{ orderDetailInfo.phoneNumber }}</view>
+				<view class="item-right">{{ orderDetailInfo?.phoneNumber||orderDetailInfo?.phone }}</view>
 			</view>
 			<view class="info-list">
 				<view class="item-left">订单编号</view>
-				<view class="item-right">{{ orderDetailInfo.orderCode }}</view>
+				<view class="item-right">{{ orderDetailInfo?.orderCode }}</view>
 			</view>
 			<view class="info-list">
 				<view class="item-left">下单时间</view>
-				<view class="item-right">{{ orderDetailInfo.createTime }}</view>
+				<view class="item-right">{{ orderDetailInfo?.createTime }}</view>
 			</view>
 			<view class="info-list">
 				<view class="item-left">付款时间</view>
-				<view class="item-right">{{ orderDetailInfo.payTime || '--' }}</view>
+				<view class="item-right">{{ orderDetailInfo?.payTime || '--' }}</view>
 			</view>
 		</view>
 		<!-- 已使用展示 -->
-		<view class="appraise-btn" @click="RouterUtils.to_page(`/pages/index/writeComments/index?siteId=${orderDetailInfo.addressSiteId}&orderId=${orderDetailInfo.id}`)">
+		<view class="appraise-btn"
+			@click="RouterUtils.to_page(`/pages/index/writeComments/index?siteId=${orderDetailInfo?.addressSiteId}&orderId=${orderDetailInfo?.id}`)">
 			写评价
 		</view>
 	</view>
+	<zs-loading v-else></zs-loading>
 	<!-- 价格详情弹窗 -->
 	<uni-popup ref="pricePopup" :safe-area="false" type="bottom">
-		<view class="price-detail">
+		<view class="price-detail" v-if="orderDetailInfo">
 			<view class="price-title">价格明细</view>
 			<view class="price-list">
 				<view class="price-total">
 					<view class="text">商品总价(共2件)</view>
-					<view class="price">¥{{ orderDetailInfo.totalPrice }}</view>
+					<view class="price">¥{{ orderDetailInfo?.totalPrice }}</view>
 				</view>
 				<view class="price-total">
 					<view class="text">团购优惠</view>
-					<view class="price">-¥{{ orderDetailInfo.tdiscounts || '0' }}</view>
+					<view class="price">-¥{{ orderDetailInfo?.tdiscounts || '0' }}</view>
 				</view>
 				<view class="price-total">
 					<view class="text">实付金额</view>
-					<view class="price">¥{{ orderDetailInfo.price }}</view>
+					<view class="price">¥{{ orderDetailInfo?.price }}</view>
 				</view>
 			</view>
 		</view>
@@ -300,6 +310,8 @@ import { ref, onMounted } from 'vue';
 import { TipsUtils, RouterUtils, DateUtils } from '@/utils/util'
 import { onLoad } from '@dcloudio/uni-app';
 import { http } from '@/utils/http'
+import zsLoading from '@/components/zzx-loading/zzx-loading.vue'
+
 const qrcode = ref();
 const pricePopup = ref()  //价格
 const refundPopup = ref()  //退款
@@ -307,7 +319,7 @@ const selected = ref(false)
 const orderPageInfo = ref()
 onLoad((option) => {
 	orderPageInfo.value = option
-	console.log(orderPageInfo.value);
+	console.log(option, '路由参数');
 })
 onMounted(() => {
 	getOrderDetailInfo()
@@ -321,7 +333,7 @@ const download_qrcode = () => {//下载二维码
 		},
 		fail: (err) => {
 			console.log(err);
-			
+
 			uni.hideLoading()
 		}
 	});
@@ -351,6 +363,7 @@ const open_phone = () => {
 
 // 订单状态 0-待付款 1-待使用 2-已使用 3-已到期 4-已取消 5-退款中 6已退款
 const orderDetailInfo = ref()
+const loading = ref(true)
 const getOrderDetailInfo = (() => {
 	http.get('/order/queryOrderInfo', { data: { orderId: orderPageInfo.value.orderId }, loading: true }).then((res) => {
 		switch (res.result.orderStatus) {
@@ -378,6 +391,8 @@ const getOrderDetailInfo = (() => {
 				break;
 		}
 		orderDetailInfo.value = res.result
+		loading.value = false
+		console.log(loading.value, '---加载');
 		getQueryWaitSignList(res.result.id)
 	})
 })
@@ -387,8 +402,8 @@ const notSignList = ref([]) // 未签署
 const signList = ref([]) // 已签署
 const getQueryWaitSignList = (orderId: string) => {
 	http.get('/esign/queryWaitSignList', { data: { orderId: orderId }, loading: true }).then((res) => {
-		notSignList.value = res.result.filter((item:any) => item.isSign == 0)
-		signList.value = res.result.filter((item:any) => item.isSign == 1)
+		notSignList.value = res.result.filter((item: any) => item.isSign == 0)
+		signList.value = res.result.filter((item: any) => item.isSign == 1)
 		queryWaitSignList.value = res.result
 	})
 }
@@ -399,7 +414,7 @@ const checkSign = (e) => {
 }
 
 // 查询授权
-const get_UserIdentityInfo = (familyId:string) => {
+const get_UserIdentityInfo = (familyId: string) => {
 	http.get('/esign/getUserIdentityInfo', { data: { familyId: familyId }, loading: true }).then((res) => {
 		if (res.result) {
 			get_createSign(familyId)
@@ -410,23 +425,23 @@ const get_UserIdentityInfo = (familyId:string) => {
 }
 
 // 发起签署
-const get_createSign = (familyId:string) => {
-	http.get('/esign/createSign', { data: { orderCode: orderDetailInfo.value.orderCode,familyId:familyId }, loading: true }).then((res) => {
-		getSignUrl()
+const get_createSign = (familyId: string) => {
+	http.get('/esign/createSign', { data: { orderCode: orderDetailInfo.value.orderCode, familyId: familyId }, loading: true }).then((res) => {
+		getSignUrl(res.result)
 	})
 }
 
 // 未授权跳转链接
-const getAuthUrl = (familyId:string) => {
-	http.get('/esign/getAuthUrl', {data:{familyId: familyId}, loading: true }).then((res) => {
-		RouterUtils.to_page(`/pages/index/signWebview/index?url=${encodeURIComponent(res.result)}`)
+const getAuthUrl = (familyId: string) => {
+	http.get('/esign/getAuthUrl', { data: { familyId: familyId }, loading: true }).then((res) => {
+		RouterUtils.to_page(`/pages/index/signWebview/index?url=${res.result}`)
 	})
 }
 
 // 获取签署链接
-const getSignUrl = () => {
-	http.get('/esign/getSignUrl', { data: { signFlowId: '8d143f604578435db064c04ddaa1fc48' }, loading: true }).then((res) => {
-		RouterUtils.to_page(`/pages/index/signWebview/index?url=${encodeURIComponent(res.result)}`)
+const getSignUrl = (signFlowId: string) => {
+	http.get('/esign/getSignUrl', { data: { signFlowId: signFlowId }, loading: true }).then((res) => {
+		RouterUtils.to_page(`/pages/index/signWebview/index?url=${res.result}`)
 	})
 }
 </script>

+ 131 - 102
src/pages/index/verificationRecord/index.vue

@@ -1,110 +1,108 @@
 <template>
 	<view class="content">
 		<view class="v-header-card">
-			<text>0017 1712 5994 杨锦新</text>
-			<view class="header-icon-box">
-				<zzx-icon name="up" size="12"></zzx-icon>
-			</view>
+			<uni-data-select v-model="selectValue" :localdata="range" @change="selectChange"></uni-data-select>
 		</view>
-		<uv-sticky offset-top="-14">
-			<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 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>
-		</uv-sticky>
+		</view>
 		<view class="normal-course-list">
 			<view id="normalCourse" v-if="sel_index === 0">
-				<view class="list-header">
-					<view class="total">总共<text style="color: #222;">6</text>节</view>
-					<view class="total">已核销<text style="color: #222;">6</text>节</view>
-					<view class="total">未核销<text style="color: #222;">6</text>节</view>
+				<view class="list-header" v-if="detailList[0]">
+					<view class="total">总共<text style="color: #222;">{{ detailList[0].coursesTotal }}</text>节</view>
+					<view class="total">已核销<text style="color: #222;">{{ detailList[0].verifyNum }}</text>节</view>
+					<view class="total">未核销<text style="color: #222;">{{ detailList[0].unVerifyNum }}</text>节</view>
 				</view>
-				<view class="v-list-card" v-for="item in 4">
-					<view class="list-ard">
-						<view class="card-info">
-							<view class="time">
-								<text>05.06 17:00-19:00</text>
+				<block v-if="detailList[0]">
+					<view class="v-list-card" v-for="(item, index) in detailList[0].recordList" :key="item.id">
+						<view class="list-ard">
+							<view class="card-info">
+								<view class="time" v-if="detailList">
+									<text>{{ DateUtils.formatDateToMMDD(item.coursesStartTime) }} {{
+										DateUtils.formatDateToHHmm(item.coursesStartTime) }}-{{
+											DateUtils.formatDateToHHmm(item.coursesEndTime) }}</text>
+								</view>
+								<view class="name">
+									第{{ index + 1 }}节:{{ item.coursesName }}
+								</view>
 							</view>
-							<view class="name">
-								第一节:篮球热身运动
+							<view class="card-status">
+								<view class="status-btn" v-if="item.verifyStatus == 1">已核销</view>
+								<view class="status-btn-not" v-else>未核销</view>
+								<view :class="[rotateArr[index] ? 'icon-tans' : 'status-icon']"
+									@click="toggleFold(index)">
+									<zzx-icon name="up" size="12"></zzx-icon>
+								</view>
 							</view>
 						</view>
-						<view class="card-status">
-							<view class="status-btn">已核销</view>
-							<!-- <view class="status-btn-not">未核销</view>  -->
-							<view :class="[rotate ? 'icon-tans' : 'status-icon']" @click="rotate = !rotate">
-								<zzx-icon name="up" size="12"></zzx-icon>
+						<view class="v-list-fold"
+							:style="{ height: rotateArr[index] ? `${(4 * 84) - 20}rpx` : '0', borderTop: rotateArr[index] ? '1rpx solid #F0F0F0' : 'none' }">
+							<view class="item-fold">
+								<view class="text">核验人</view>
+								<view class="name">{{ item.verifyUserName || '--' }}</view>
+							</view>
+							<view class="item-fold">
+								<view class="text">核验照片</view>
+								<image :src="item.verifyImage" mode=""></image>
+							</view>
+							<view class="item-fold">
+								<view class="text">核验时间</view>
+								<view class="name">{{ item.verifyTime || '--' }}</view>
 							</view>
 						</view>
 					</view>
-
-					<view class="v-list-fold"
-						:style="{ height: rotate ? `${(4 * 84) - 20}rpx` : '0', borderTop: rotate ? '1rpx solid #F0F0F0' : 'none' }">
-						<view class="item-fold">
-							<view class="text">核验人</view>
-							<view class="name">杨锦新</view>
-						</view>
-						<view class="item-fold">
-							<view class="text">核验照片</view>
-							<image src="https://img.shetu66.com/2023/06/13/1686646672844195.jpg" mode=""></image>
-						</view>
-						<view class="item-fold">
-							<view class="text">核验时间</view>
-							<view class="name">2025-05-02 16:14:56</view>
-						</view>
-					</view>
-				</view>
+				</block>
 			</view>
 			<view id="lessons" v-if="sel_index === 1">
-				<view class="v-lessons-list">
-					<!-- <view class="title">补课</view> -->
-					<view class="list-header">
-						<view class="total">总共<text style="color: #222;">6</text>节</view>
-						<view class="total">已核销<text style="color: #222;">6</text>节</view>
-						<view class="total">未核销<text style="color: #222;">6</text>节</view>
-					</view>
-					<view class="v-lessons-card">
-						<view class="v-list-card" v-for="item in 4">
-							<view class="list-ard">
-								<view class="card-info">
-									<view class="time">
-										<text>05.06 17:00-19:00</text>
-									</view>
-									<view class="name">
-										第一节:篮球热身运动
-									</view>
+				<!-- <view class="title">补课</view> -->
+				<view class="list-header" v-if="detailList[1]">
+					<view class="total">总共<text style="color: #222;">{{ detailList[1].coursesTotal }}</text>节</view>
+					<view class="total">已核销<text style="color: #222;">{{ detailList[1].verifyNum }}</text>节</view>
+					<view class="total">未核销<text style="color: #222;">{{ detailList[1].unVerifyNum }}</text>节</view>
+				</view>
+				<view class="v-lessons-card" v-if="detailList[1]">
+					<view class="v-list-card" v-for="(item, index) in detailList[1].recordList" :key="item.id">
+						<view class="list-ard">
+							<view class="card-info">
+								<view class="time">
+									<text>{{ DateUtils.formatDateToMMDD(item.coursesStartTime) }} {{
+										DateUtils.formatDateToHHmm(item.coursesStartTime) }}-{{
+											DateUtils.formatDateToHHmm(item.coursesEndTime) }}</text>
 								</view>
-								<view class="card-status">
-									<view class="status-btn">已核销</view>
-									<!-- <view class="status-btn-not">未核销</view>  -->
-									<view :class="[rotate ? 'icon-tans' : 'status-icon']" @click="rotate = !rotate">
-										<zzx-icon name="up" size="12"></zzx-icon>
-									</view>
+								<view class="name">
+									第{{ index + 1 }}节:{{ item.coursesName }}
 								</view>
 							</view>
-
-							<view class="v-list-fold"
-								:style="{ height: rotate ? `${(4 * 84) - 20}rpx` : '0', borderTop: rotate ? '1rpx solid #F0F0F0' : 'none' }">
-								<view class="item-fold">
-									<view class="text">核验人</view>
-									<view class="name">杨锦新</view>
-								</view>
-								<view class="item-fold">
-									<view class="text">核验照片</view>
-									<image src="https://img.shetu66.com/2023/06/13/1686646672844195.jpg" mode="">
-									</image>
-								</view>
-								<view class="item-fold">
-									<view class="text">核验时间</view>
-									<view class="name">2025-05-02 16:14:56</view>
+							<view class="card-status">
+								<view class="status-btn" v-if="item.verifyStatus == 1">已核销</view>
+								<view class="status-btn-not" v-else>未核销</view>
+								<view :class="[rotateArr[index] ? 'icon-tans' : 'status-icon']"
+									@click="toggleFold(index)">
+									<zzx-icon name="up" size="12"></zzx-icon>
 								</view>
 							</view>
 						</view>
-						<view class="item-tips-text">补课表暂未排出</view>
+						<view class="v-list-fold"
+							:style="{ height: rotateArr[index] ? `${(4 * 84) - 20}rpx` : '0', borderTop: rotateArr[index] ? '1rpx solid #F0F0F0' : 'none' }">
+							<view class="item-fold">
+								<view class="text">核验人</view>
+								<view class="name">{{ item.verifyUserName || '--' }}</view>
+							</view>
+							<view class="item-fold">
+								<view class="text">核验照片</view>
+								<image :src="item.verifyImage" mode=""></image>
+							</view>
+							<view class="item-fold">
+								<view class="text">核验时间</view>
+								<view class="name">{{ item.verifyTime || '--' }}</view>
+							</view>
+						</view>
 					</view>
 				</view>
+				<view class="item-tips-text" v-else>补课表暂未排出</view>
 			</view>
 		</view>
 	</view>
@@ -113,16 +111,26 @@
 <script lang="ts" setup>
 import { ref, onMounted } from 'vue';
 import { onLoad, onPageScroll } from '@dcloudio/uni-app';
+import { TipsUtils, DateUtils } from '@/utils/util'
 import { http } from '@/utils/http'
-const rotate = ref(false);  //核销折叠控制
+// const rotate = ref(false);  //核销折叠控制
+const rotateArr = ref<boolean[]>([]); // 每条折叠控制
 const selectList = ref(['正常课', '补课']);
 const sel_index = ref(0);
-onLoad((options)=>{
+const range = ref([])
+const selectValue = ref(0)
+onLoad((options) => {
 	console.log(options)
-	formData.value=options
+	formData.value.orderId = options.orderId
+	proInfoList.value = JSON.parse(options.proInfoList)
+	range.value = proInfoList.value.map((item:any,index:number) => ({
+		value: index,
+		text: `${item.ticketNo} ${item.userName}`
+	}))
+	formData.value.ticketNo = proInfoList.value[0].ticketNo
 })
-onMounted(()=>{
-getOrderVerifyRecords()
+onMounted(() => {
+	getOrderVerifyRecords()
 })
 onPageScroll((e) => {
 
@@ -131,26 +139,47 @@ const sel_tab = async (i: number) => {
 	sel_index.value = i;
 }
 
-const formData=ref({})
-const getOrderVerifyRecords=()=>{
-	http.get('/order/queryOrderVerifyRecords',{data:formData.value,loading:true}).then((res)=>{
-
+const formData = ref({
+	orderId: null,
+	ticketNo: null
+})
+const proInfoList = ref([])  //使用人信息
+const detailList = ref([]) //核销列表
+const getOrderVerifyRecords = () => {
+	http.get('/order/queryOrderVerifyRecords', { data: formData.value, loading: true }).then((res) => {
+		detailList.value = res.result
+		if (detailList.value && detailList.value[0] && detailList.value[0].recordList) {
+			rotateArr.value = detailList.value[0].recordList.map(() => false)
+		} else {
+			rotateArr.value = []
+		}
 	})
 }
 
+// 切换折叠
+const toggleFold = (idx: number) => {
+	rotateArr.value = rotateArr.value.map((v, i) => i === idx ? !v : false)
+}
+
+const selectChange = (e) => {
+	const value = e;
+	const item = range.value.find((item: any) => item.value === value);
+	const text = item ? item.text : '';
+	const number = text.split(' ')[0];
+	formData.value.ticketNo = number;
+	console.log(formData.value.ticketNo);
+	getOrderVerifyRecords()
+}
 </script>
 
 <style lang="less" scoped>
 .v-header-card {
 	margin-top: 20rpx;
-	display: flex;
-	align-items: center;
-	gap: 20rpx;
 	font-size: 28rpx;
 	color: #222222;
 	background: #FFFFFF;
 	border-radius: 16rpx;
-	padding: 20rpx;
+	padding: 6rpx;
 
 	.header-icon-box {
 		transform: rotate(180deg)
@@ -442,13 +471,13 @@ const getOrderVerifyRecords=()=>{
 					}
 				}
 			}
-
-			.item-tips-text {
-				font-size: 24rpx;
-				color: #AAAAAA;
-				text-align: center;
-			}
 		}
 	}
+
+	.item-tips-text {
+		font-size: 24rpx;
+		color: #AAAAAA;
+		text-align: center;
+	}
 }
 </style>

+ 102 - 92
src/pages/index/writeComments/index.vue

@@ -5,18 +5,19 @@
 			<view class="w-star">
 				<view class="">综合评价</view>
 				<uni-rate size="16" :value="formData.score" @change="onRateChange" />
-				<view class="star">{{formData.score}}</view>
+				<view class="star">{{ formData.score }}</view>
 			</view>
 		</view>
 		<view class="w-content-card">
 			<textarea v-model="formData.evaluateContent" id="" cols="30" rows="10" maxlength="150"></textarea>
 			<view class="">
-				<sunui-upimg :url="upPicUrl" ref="upload1" title="店铺logo" @upload="handleLoaded1" @change="handleChange1"></sunui-upimg>
+				<sunui-upimg :url="upPicUrl" ref="upload1" title="店铺logo" @upload="handleLoaded1"
+					@change="handleChange1"></sunui-upimg>
 			</view>
 		</view>
 		<view class="w-anonymity">
-			<view class="select-anonymity">
-				<zzx-icon name="selected" size="14"></zzx-icon>
+			<view class="select-anonymity" @click="formData.isAnonymous = formData.isAnonymous === 1 ? 0 : 1">
+				<zzx-icon :name="formData.isAnonymous==0 ? 'selected' : 'unchecked'" size="14"></zzx-icon>
 				<view class="">匿名评价</view>
 			</view>
 			<view class="anonymity-tips">
@@ -28,107 +29,116 @@
 </template>
 
 <script lang="ts" setup>
-	import { ref, onMounted, computed } from 'vue';
-	import { onLoad } from '@dcloudio/uni-app';
-	import { RouterUtils, TipsUtils } from '@/utils/util';
-	import { http } from '@/utils/http';
-	onLoad((options)=>{
-		console.log(options);
-		formData.value.siteId=options.siteId
-		formData.value.orderId=options.orderId
-	})
-	const formData=ref({
-		score:0,
-		evaluateContent:'',
-		images:'https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650,https://img.keaitupian.cn/newupload/08/1629449018344288.jpg',
-		siteId:null,
-		orderId:null,
-	})
-	const upPicUrl=ref()
-	const onRateChange=(e)=>{
-		formData.value.score=e.value
-	}
-	
-	const handleLoaded1=(e)=>{
-	}
-	const handleChange1=(e)=>{
-	}
-	const publish=()=>{
-		http.post('/my/evaluate/submitFeedback',formData.value,{loading:true}).then((res)=>{
-			TipsUtils.tips_toast(res.message)
-			formData.value.score=0
-			formData.value.evaluateContent=''
-			uni.navigateTo({
-				url:'/pages/index/commentsSuccess/index'
-			})
+import { ref, onMounted, computed } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { RouterUtils, TipsUtils } from '@/utils/util';
+import { http } from '@/utils/http';
+onLoad((options) => {
+	console.log(options);
+	formData.value.siteId = options.siteId
+	formData.value.orderId = options.orderId
+})
+const formData = ref({
+	score: 0,
+	evaluateContent: '',
+	images: 'https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650,https://img.keaitupian.cn/newupload/08/1629449018344288.jpg',
+	siteId: null,
+	orderId: null,
+	isAnonymous: 0,
+})
+const upPicUrl = ref()
+const onRateChange = (e) => {
+	formData.value.score = e.value
+}
+
+const handleLoaded1 = (e) => {
+}
+const handleChange1 = (e) => {
+}
+const publish = () => {
+	http.post('/my/evaluate/submitFeedback', formData.value, { loading: true }).then((res) => {
+		TipsUtils.tips_toast(res.message)
+		formData.value.score = 0
+		formData.value.evaluateContent = ''
+		uni.navigateTo({
+			url: '/pages/index/commentsSuccess/index'
 		})
-	}
+	})
+}
 </script>
 
 <style>
-	page{
-		background: linear-gradient( 180deg, #FBFFEE 0%, #F6F6F6 100%);
-	}
+page {
+	background: linear-gradient(180deg, #FBFFEE 0%, #F6F6F6 100%);
+}
 </style>
 <style lang="less" scoped>
-	.w-header-card{
-		margin-top: 20rpx;
-		padding: 20rpx;
-		background: #FFFFFF;
-		border-radius: 32rpx;
-		.w-title{
-			font-weight: bold;
-			font-size: 32rpx;
-			color: #222222;
-		}
-		.w-star{
-			margin-top: 20rpx;
-			display: flex;
-			align-items: center;
-			gap: 10rpx;
-			font-weight: bold;
-			font-size: 28rpx;
-			color: #222222;
-			.star{
-				font-weight: bold;
-				font-size: 28rpx;
-				color: #FDD143;
-			}
-		}
+.w-header-card {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+
+	.w-title {
+		font-weight: bold;
+		font-size: 32rpx;
+		color: #222222;
 	}
-	.w-content-card{
+
+	.w-star {
 		margin-top: 20rpx;
-		padding: 20rpx;
-		background: #FFFFFF;
-		border-radius: 32rpx;
-	}
-	.w-anonymity{
 		display: flex;
 		align-items: center;
-		justify-content: space-between;
-		margin-top: 20rpx;
-		.select-anonymity{
-			display: flex;
-			align-items: center;
-			gap: 10rpx;
-			font-size: 28rpx;
-			color: #222222;
-		}
-		.anonymity-tips{
+		gap: 10rpx;
+		font-weight: bold;
+		font-size: 28rpx;
+		color: #222222;
+
+		.star {
+			font-weight: bold;
 			font-size: 28rpx;
-			color: #AAAAAA;
+			color: #FDD143;
 		}
 	}
-	.appraise-btn {
-		margin-top: 24rpx;
-		width: 686rpx;
-		height: 100rpx;
-		background: #C8FF0C;
-		border-radius: 60rpx;
-		font-weight: bold;
-		font-size: 32rpx;
+}
+
+.w-content-card {
+	margin-top: 20rpx;
+	padding: 20rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx;
+}
+
+.w-anonymity {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-top: 20rpx;
+
+	.select-anonymity {
+		display: flex;
+		align-items: center;
+		gap: 10rpx;
+		font-size: 28rpx;
 		color: #222222;
-		text-align: center;
-		line-height: 100rpx;
 	}
+
+	.anonymity-tips {
+		font-size: 28rpx;
+		color: #AAAAAA;
+	}
+}
+
+.appraise-btn {
+	margin-top: 24rpx;
+	width: 686rpx;
+	height: 100rpx;
+	background: #C8FF0C;
+	border-radius: 60rpx;
+	font-weight: bold;
+	font-size: 32rpx;
+	color: #222222;
+	text-align: center;
+	line-height: 100rpx;
+}
 </style>

+ 2 - 2
src/pages/mine/feedbackRecord/index.vue

@@ -18,9 +18,9 @@
 				{{item.feedbackDescribed}}
 			</view>
 			<view class="user-picture">
-				<scroll-view class="scroll-view_H" scroll-x="true" @click="_previewImage(item.feedbackImgList)">
+				<scroll-view class="scroll-view_H" scroll-x="true">
 					<view class="scroll-view-item_H" v-for="(img,index) in item.feedbackImgList" :key="index">
-						<image :src="img" mode=""></image>
+						<image @click="_previewImage(item.feedbackImgList,img)" :src="img" mode=""></image>
 					</view>
 				</scroll-view>
 			</view>

+ 2 - 2
src/pages/mine/mineComments/index.vue

@@ -27,9 +27,9 @@
 				{{item.evaluateContent}}
 			</view>
 			<view class="user-picture">
-				<scroll-view class="scroll-view_H" scroll-x="true" @click="_previewImage(item.imageList)">
+				<scroll-view class="scroll-view_H" scroll-x="true">
 					<view class="scroll-view-item_H" v-for="(iamge,index) in item.imageList" :key="index">
-						<image :src="iamge" mode=""></image>
+						<image @click="_previewImage(item.imageList,iamge)" :src="iamge" mode=""></image>
 					</view>
 				</scroll-view>
 			</view>

+ 43 - 0
src/uni_modules/uni-data-select/changelog.md

@@ -0,0 +1,43 @@
+## 1.0.10(2025-04-14)
+- 修复 清除按钮不展示问题
+## 1.0.9(2025-03-26)
+- 优化 默认背景为白色与整体组件保持风格统一
+## 1.0.8(2024-03-28)
+- 修复 在vue2下:style动态绑定导致编译失败的bug
+## 1.0.7(2024-01-20)
+- 修复 长文本回显超过容器的bug,超过容器部分显示省略号
+## 1.0.6(2023-04-12)
+- 修复 微信小程序点击时会改变背景颜色的 bug
+## 1.0.5(2023-02-03)
+- 修复 禁用时会显示清空按钮
+## 1.0.4(2023-02-02)
+- 优化 查询条件短期内多次变更只查询最后一次变更后的结果
+- 调整 内部缓存键名调整为 uni-data-select-lastSelectedValue
+## 1.0.3(2023-01-16)
+- 修复 不关联服务空间报错的问题
+## 1.0.2(2023-01-14)
+- 新增  属性 `format` 可用于格式化显示选项内容
+## 1.0.1(2022-12-06)
+- 修复  当where变化时,数据不会自动更新的问题
+## 0.1.9(2022-09-05)
+- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
+## 0.1.8(2022-08-29)
+- 修复 点击的位置不准确
+## 0.1.7(2022-08-12)
+- 新增 支持 disabled 属性
+## 0.1.6(2022-07-06)
+- 修复 pc端宽度异常的bug
+## 0.1.5
+- 修复 pc端宽度异常的bug
+## 0.1.4(2022-07-05)
+- 优化 显示样式
+## 0.1.3(2022-06-02)
+- 修复 localdata 赋值不生效的 bug
+- 新增 支持  uni.scss 修改颜色
+- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
+## 0.1.2(2022-05-08)
+- 修复 当 value 为 0 时选择不生效的 bug
+## 0.1.1(2022-05-07)
+- 新增 记住上次的选项(仅 collection 存在时有效)
+## 0.1.0(2022-04-22)
+- 初始化

+ 562 - 0
src/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue

@@ -0,0 +1,562 @@
+<template>
+	<view class="uni-stat__select">
+		<span v-if="label" class="uni-label-text hide-on-phone">{{ label + ':' }}</span>
+		<view class="uni-stat-box" :class="{ 'uni-stat__actived': current }">
+			<view class="uni-select" :class="{ 'uni-select--disabled': disabled }">
+				<view class="uni-select__input-box" @click="toggleSelector">
+					<view v-if="current" class="uni-select__input-text">{{ textShow }}</view>
+					<view v-else class="uni-select__input-text uni-select__input-placeholder">{{ typePlaceholder }}</view>
+					<view key="clear-button" v-if="current && clear && !disabled" @click.stop="clearVal">
+						<uni-icons type="clear" color="#c0c4cc" size="24" />
+					</view>
+					<view key="arrow-button" v-else>
+						<uni-icons :type="showSelector ? 'top' : 'bottom'" size="14" color="#999" />
+					</view>
+				</view>
+				<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
+				<view class="uni-select__selector" :style="getOffsetByPlacement" v-if="showSelector">
+					<view :class="placement == 'bottom' ? 'uni-popper__arrow_bottom' : 'uni-popper__arrow_top'"></view>
+					<scroll-view scroll-y="true" class="uni-select__selector-scroll">
+						<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0">
+							<text>{{ emptyTips }}</text>
+						</view>
+						<view v-else class="uni-select__selector-item" v-for="(item, index) in mixinDatacomResData"
+							:key="index" @click="change(item)">
+							<text
+								:class="{ 'uni-select__selector__disabled': item.disable }">{{ formatItemName(item) }}</text>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+/**
+ * DataChecklist 数据选择器
+ * @description 通过数据渲染的下拉框组件
+ * @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select
+ * @property {String} value 默认值
+ * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
+ * @property {Boolean} clear 是否可以清空已选项
+ * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
+ * @property {String} label 左侧标题
+ * @property {String} placeholder 输入框的提示文字
+ * @property {Boolean} disabled 是否禁用
+ * @property {String} placement 弹出位置
+ * 	@value top   		顶部弹出
+ * 	@value bottom		底部弹出(default)
+ * @event {Function} change  选中发生变化触发
+ */
+
+export default {
+	name: "uni-data-select",
+	mixins: [uniCloud.mixinDatacom || {}],
+	props: {
+		localdata: {
+			type: Array,
+			default() {
+				return []
+			}
+		},
+		value: {
+			type: [String, Number],
+			default: ''
+		},
+		modelValue: {
+			type: [String, Number],
+			default: ''
+		},
+		label: {
+			type: String,
+			default: ''
+		},
+		placeholder: {
+			type: String,
+			default: '请选择'
+		},
+		emptyTips: {
+			type: String,
+			default: '无选项'
+		},
+		clear: {
+			type: Boolean,
+			default: true
+		},
+		defItem: {
+			type: Number,
+			default: 0
+		},
+		disabled: {
+			type: Boolean,
+			default: false
+		},
+		// 格式化输出 用法 field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
+		format: {
+			type: String,
+			default: ''
+		},
+		placement: {
+			type: String,
+			default: 'bottom'
+		}
+	},
+	data() {
+		return {
+			showSelector: false,
+			current: '',
+			mixinDatacomResData: [],
+			apps: [],
+			channels: [],
+			cacheKey: "uni-data-select-lastSelectedValue",
+		};
+	},
+	created() {
+		this.debounceGet = this.debounce(() => {
+			this.query();
+		}, 300);
+		if (this.collection && !this.localdata.length) {
+			this.debounceGet();
+		}
+	},
+	computed: {
+		typePlaceholder() {
+			const text = {
+				'opendb-stat-app-versions': '版本',
+				'opendb-app-channels': '渠道',
+				'opendb-app-list': '应用'
+			}
+			const common = this.placeholder
+			const placeholder = text[this.collection]
+			return placeholder ?
+				common + placeholder :
+				common
+		},
+		valueCom() {
+			// #ifdef VUE3
+			return this.modelValue;
+			// #endif
+			// #ifndef VUE3
+			return this.value;
+			// #endif
+		},
+		textShow() {
+			// 长文本显示
+			let text = this.current;
+			return text;
+		},
+		getOffsetByPlacement() {
+			switch (this.placement) {
+				case 'top':
+					return "bottom:calc(100% + 12px);";
+				case 'bottom':
+					return "top:calc(100% + 12px);";
+			}
+		}
+	},
+
+	watch: {
+		localdata: {
+			immediate: true,
+			handler(val, old) {
+				if (Array.isArray(val) && old !== val) {
+					this.mixinDatacomResData = val
+				}
+			}
+		},
+		valueCom(val, old) {
+			this.initDefVal()
+		},
+		mixinDatacomResData: {
+			immediate: true,
+			handler(val) {
+				if (val.length) {
+					this.initDefVal()
+				}
+			}
+		},
+
+	},
+	methods: {
+		debounce(fn, time = 100) {
+			let timer = null
+			return function (...args) {
+				if (timer) clearTimeout(timer)
+				timer = setTimeout(() => {
+					fn.apply(this, args)
+				}, time)
+			}
+		},
+		// 执行数据库查询
+		query() {
+			this.mixinDatacomEasyGet();
+		},
+		// 监听查询条件变更事件
+		onMixinDatacomPropsChange() {
+			if (this.collection) {
+				this.debounceGet();
+			}
+		},
+		initDefVal() {
+			let defValue = ''
+			if ((this.valueCom || this.valueCom === 0) && !this.isDisabled(this.valueCom)) {
+				defValue = this.valueCom
+			} else {
+				let strogeValue
+				if (this.collection) {
+					strogeValue = this.getCache()
+				}
+				if (strogeValue || strogeValue === 0) {
+					defValue = strogeValue
+				} else {
+					let defItem = ''
+					if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) {
+						defItem = this.mixinDatacomResData[this.defItem - 1].value
+					}
+					defValue = defItem
+				}
+				if (defValue || defValue === 0) {
+					this.emit(defValue)
+				}
+			}
+			const def = this.mixinDatacomResData.find(item => item.value === defValue)
+			this.current = def ? this.formatItemName(def) : ''
+		},
+
+		/**
+		 * @param {[String, Number]} value
+		 * 判断用户给的 value 是否同时为禁用状态
+		 */
+		isDisabled(value) {
+			let isDisabled = false;
+
+			this.mixinDatacomResData.forEach(item => {
+				if (item.value === value) {
+					isDisabled = item.disable
+				}
+			})
+
+			return isDisabled;
+		},
+
+		clearVal() {
+			this.emit('')
+			this.current = ''
+			if (this.collection) {
+				this.removeCache()
+			}
+		},
+		change(item) {
+			if (!item.disable) {
+				this.showSelector = false
+				this.current = this.formatItemName(item)
+				this.emit(item.value)
+			}
+		},
+		emit(val) {
+			this.$emit('input', val)
+			this.$emit('update:modelValue', val)
+			this.$emit('change', val)
+			if (this.collection) {
+				this.setCache(val);
+			}
+		},
+		toggleSelector() {
+			if (this.disabled) {
+				return
+			}
+
+			this.showSelector = !this.showSelector
+		},
+		formatItemName(item) {
+			let {
+				text,
+				value,
+				channel_code
+			} = item
+			channel_code = channel_code ? `(${channel_code})` : ''
+
+			if (this.format) {
+				// 格式化输出
+				let str = "";
+				str = this.format;
+				for (let key in item) {
+					str = str.replace(new RegExp(`{${key}}`, "g"), item[key]);
+				}
+				return str;
+			} else {
+				return this.collection.indexOf('app-list') > 0 ?
+					`${text}(${value})` :
+					(
+						text ?
+							text :
+							`未命名${channel_code}`
+					)
+			}
+		},
+		// 获取当前加载的数据
+		getLoadData() {
+			return this.mixinDatacomResData;
+		},
+		// 获取当前缓存key
+		getCurrentCacheKey() {
+			return this.collection;
+		},
+		// 获取缓存
+		getCache(name = this.getCurrentCacheKey()) {
+			let cacheData = uni.getStorageSync(this.cacheKey) || {};
+			return cacheData[name];
+		},
+		// 设置缓存
+		setCache(value, name = this.getCurrentCacheKey()) {
+			let cacheData = uni.getStorageSync(this.cacheKey) || {};
+			cacheData[name] = value;
+			uni.setStorageSync(this.cacheKey, cacheData);
+		},
+		// 删除缓存
+		removeCache(name = this.getCurrentCacheKey()) {
+			let cacheData = uni.getStorageSync(this.cacheKey) || {};
+			delete cacheData[name];
+			uni.setStorageSync(this.cacheKey, cacheData);
+		},
+	}
+}
+</script>
+
+<style lang="scss">
+$uni-base-color: #6a6a6a !default;
+$uni-main-color: #333 !default;
+$uni-secondary-color: #909399 !default;
+$uni-border-3: #e5e5e5;
+
+/* #ifndef APP-NVUE */
+@media screen and (max-width: 500px) {
+	.hide-on-phone {
+		display: none;
+	}
+}
+
+/* #endif */
+.uni-stat__select {
+	display: flex;
+	align-items: center;
+	// padding: 15px;
+	/* #ifdef H5 */
+	cursor: pointer;
+	/* #endif */
+	width: 100%;
+	flex: 1;
+	box-sizing: border-box;
+}
+
+.uni-stat-box {
+	background-color: #fff;
+	width: 100%;
+	flex: 1;
+}
+
+.uni-stat__actived {
+	width: 100%;
+	flex: 1;
+	// outline: 1px solid #2979ff;
+}
+
+.uni-label-text {
+	font-size: 14px;
+	font-weight: bold;
+	color: $uni-base-color;
+	margin: auto 0;
+	margin-right: 5px;
+}
+
+.uni-select {
+	font-size: 14px;
+	//border: 1px solid $uni-border-3;
+	box-sizing: border-box;
+	border-radius: 4px;
+	padding: 0 5px;
+	padding-left: 10px;
+	position: relative;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	user-select: none;
+	/* #endif */
+	flex-direction: row;
+	align-items: center;
+	//border-bottom: solid 1px $uni-border-3;
+	width: 100%;
+	flex: 1;
+	height: 35px;
+	&--disabled {
+		background-color: #f5f7fa;
+		cursor: not-allowed;
+	}
+}
+
+.uni-select__label {
+	font-size: 16px;
+	// line-height: 22px;
+	height: 35px;
+	padding-right: 10px;
+	color: $uni-secondary-color;
+}
+
+.uni-select__input-box {
+	height: 35px;
+	width: 0px;
+	position: relative;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex: 1;
+	flex-direction: row;
+	align-items: center;
+}
+
+.uni-select__input {
+	flex: 1;
+	font-size: 14px;
+	height: 22px;
+	line-height: 22px;
+}
+
+.uni-select__input-plac {
+	font-size: 14px;
+	color: $uni-secondary-color;
+}
+
+.uni-select__selector {
+	/* #ifndef APP-NVUE */
+	box-sizing: border-box;
+	/* #endif */
+	position: absolute;
+	left: 0;
+	width: 100%;
+	background-color: #FFFFFF;
+	border: 1px solid #EBEEF5;
+	border-radius: 6px;
+	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+	z-index: 3;
+	padding: 4px 0;
+}
+
+.uni-select__selector-scroll {
+	/* #ifndef APP-NVUE */
+	max-height: 200px;
+	box-sizing: border-box;
+	/* #endif */
+}
+
+/* #ifdef H5 */
+@media (min-width: 768px) {
+	.uni-select__selector-scroll {
+		max-height: 600px;
+	}
+}
+
+/* #endif */
+
+.uni-select__selector-empty,
+.uni-select__selector-item {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	cursor: pointer;
+	/* #endif */
+	line-height: 35px;
+	font-size: 14px;
+	text-align: center;
+	/* border-bottom: solid 1px $uni-border-3; */
+	padding: 0px 10px;
+}
+
+.uni-select__selector-item:hover {
+	background-color: #f9f9f9;
+}
+
+.uni-select__selector-empty:last-child,
+.uni-select__selector-item:last-child {
+	/* #ifndef APP-NVUE */
+	border-bottom: none;
+	/* #endif */
+}
+
+.uni-select__selector__disabled {
+	opacity: 0.4;
+	cursor: default;
+}
+
+/* picker 弹出层通用的指示小三角 */
+.uni-popper__arrow_bottom,
+.uni-popper__arrow_bottom::after,
+.uni-popper__arrow_top,
+.uni-popper__arrow_top::after,
+{
+position: absolute;
+display: block;
+width: 0;
+height: 0;
+border-color: transparent;
+border-style: solid;
+border-width: 6px;
+}
+
+.uni-popper__arrow_bottom {
+	filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+	top: -6px;
+	left: 10%;
+	margin-right: 3px;
+	border-top-width: 0;
+	border-bottom-color: #EBEEF5;
+}
+
+.uni-popper__arrow_bottom::after {
+	content: " ";
+	top: 1px;
+	margin-left: -6px;
+	border-top-width: 0;
+	border-bottom-color: #fff;
+}
+
+.uni-popper__arrow_top {
+	filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+	bottom: -6px;
+	left: 10%;
+	margin-right: 3px;
+	border-bottom-width: 0;
+	border-top-color: #EBEEF5;
+}
+
+.uni-popper__arrow_top::after {
+	content: " ";
+	bottom: 1px;
+	margin-left: -6px;
+	border-bottom-width: 0;
+	border-top-color: #fff;
+}
+
+
+.uni-select__input-text {
+	// width: 280px;
+	width: 100%;
+	color: $uni-main-color;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	-o-text-overflow: ellipsis;
+	overflow: hidden;
+}
+
+.uni-select__input-placeholder {
+	color: $uni-base-color;
+	font-size: 12px;
+}
+
+.uni-select--mask {
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	right: 0;
+	left: 0;
+	z-index: 2;
+}
+</style>

+ 88 - 0
src/uni_modules/uni-data-select/package.json

@@ -0,0 +1,88 @@
+{
+  "id": "uni-data-select",
+  "displayName": "uni-data-select 下拉框选择器",
+  "version": "1.0.10",
+  "description": "通过数据驱动的下拉框选择器",
+  "keywords": [
+    "uni-ui",
+    "select",
+    "uni-data-select",
+    "下拉框",
+    "下拉选"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.1"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-load-more"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+            "app-vue": "y",
+            "app-nvue": "n",
+            "app-harmony": "u",
+            "app-uvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+        "QQ": "u",
+        "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 8 - 0
src/uni_modules/uni-data-select/readme.md

@@ -0,0 +1,8 @@
+## DataSelect 下拉框选择器
+> **组件名:uni-data-select**
+> 代码块: `uDataSelect`
+
+当选项过多时,使用下拉菜单展示并选择内容
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-select)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 25 - 0
src/uni_modules/uni-load-more/changelog.md

@@ -0,0 +1,25 @@
+## 1.3.6(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.5(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.4(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.3(2022-01-20)
+- 新增 showText属性 ,是否显示文本
+## 1.3.2(2022-01-19)
+- 修复 nvue 平台下不显示文本的bug
+## 1.3.1(2022-01-19)
+- 修复 微信小程序平台样式选择器报警告的问题
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
+## 1.2.1(2021-08-24)
+- 新增 支持国际化
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.8(2021-05-12)
+- 新增 组件示例地址
+## 1.1.7(2021-03-30)
+- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
+## 1.1.6(2021-02-05)
+- 调整为uni_modules目录规范

+ 5 - 0
src/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json

@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "Pull up to show more",
+	"uni-load-more.contentrefresh": "loading...",
+	"uni-load-more.contentnomore": "No more data"
+}

+ 8 - 0
src/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js

@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}

+ 5 - 0
src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json

@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "上拉显示更多",
+	"uni-load-more.contentrefresh": "正在加载...",
+	"uni-load-more.contentnomore": "没有更多数据了"
+}

+ 5 - 0
src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json

@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "上拉顯示更多",
+	"uni-load-more.contentrefresh": "正在加載...",
+	"uni-load-more.contentnomore": "沒有更多數據了"
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 117 - 0
src/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue


+ 84 - 0
src/uni_modules/uni-load-more/package.json

@@ -0,0 +1,84 @@
+{
+  "id": "uni-load-more",
+  "displayName": "uni-load-more 加载更多",
+  "version": "1.3.6",
+  "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "加载更多",
+    "load-more"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 14 - 0
src/uni_modules/uni-load-more/readme.md

@@ -0,0 +1,14 @@
+
+
+### LoadMore 加载更多
+> **组件名:uni-load-more**
+> 代码块: `uLoadMore`
+
+
+用于列表中,做滚动加载使用,展示 loading 的各种状态。
+
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+

+ 2 - 2
src/utils/http/index.ts

@@ -179,8 +179,8 @@ export class HttpClient {
 
 // 创建实例
 export const http = new HttpClient({
-  // baseURL: 'http://192.168.1.34:8080/jeecg-boot/app',
-  baseURL: 'http://192.168.1.166:8080/jeecg-boot/app',
+  baseURL: 'http://192.168.1.34:8080/jeecg-boot/app',
+  // baseURL: 'http://192.168.1.166:8080/jeecg-boot/app',
   // baseURL: 'http://192.168.0.11:8080/jeecg-boot/app',
   headers: {
     'Content-Type': 'application/json'

+ 0 - 0
src/utils/util/date.ts


+ 42 - 21
src/utils/util/index.ts

@@ -123,12 +123,32 @@ export class DateUtils {
 	 * @param dateString - 日期字符串
 	 * @returns MM-DD 格式的日期字符串
 	 */
-	static formatDateToMMDD(dateString: any) {
-		const date = new Date(dateString);
-		const month = (date.getMonth() + 1).toString().padStart(2, '0');
-		const day = date.getDate().toString().padStart(2, '0');
-		return `${month}-${day}`;
+static formatDateToMMDD(dateString: any) {
+	let str = dateString;
+	if (typeof str === 'string' && str.indexOf('T') === -1 && str.indexOf(' ') > 0) {
+		str = str.replace(' ', 'T');
+	}
+	const date = new Date(str);
+	const month = (date.getMonth() + 1).toString().padStart(2, '0');
+	const day = date.getDate().toString().padStart(2, '0');
+	return `${month}-${day}`;
+}
+
+	/**
+	 * 日期字符串转为HH:mm格式
+	 * @param dateString - 日期字符串
+	 * @returns HH:mm 格式的时间字符串
+	 */
+static formatDateToHHmm(dateString: any) {
+	let str = dateString;
+	if (typeof str === 'string' && str.indexOf('T') === -1 && str.indexOf(' ') > 0) {
+		str = str.replace(' ', 'T');
 	}
+	const date = new Date(str);
+	const hours = date.getHours().toString().padStart(2, '0');
+	const minutes = date.getMinutes().toString().padStart(2, '0');
+	return `${hours}:${minutes}`;
+}
 
 	/**
 	 * 
@@ -159,22 +179,23 @@ export const randomColor = (): string => {
  * 预览图片
  * @param url - 图片地址
  */
-export const _previewImage = (url: any) => {
-	uni.previewImage({
-		urls: url,
-		longPressActions: {
-			itemList: ['发送给朋友', '保存图片', '收藏'],
-			success: function (data) {
-				uni.showToast({
-					title: '操作成功',
-					icon: 'none'
-				})
-			},
-			fail: function (err) {
-				console.log(err.errMsg);
-			}
-		}
-	});
+export const _previewImage = (urls: any, current: string) => {
+    uni.previewImage({
+        urls,
+        current, // 指定当前图片
+        longPressActions: {
+            itemList: ['发送给朋友', '保存图片', '收藏'],
+            success: function (data) {
+                uni.showToast({
+                    title: '操作成功',
+                    icon: 'none'
+                })
+            },
+            fail: function (err) {
+                console.log(err.errMsg);
+            }
+        }
+    });
 }
 
 /**

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels