2 次代码提交 680b535342 ... 4e632be521

作者 SHA1 备注 提交日期
  学习?学个屁 4e632be521 基础业务接口 3 天之前
  学习?学个屁 8761d25ed3 场地预览页 1 周之前
共有 36 个文件被更改,包括 1501 次插入530 次删除
  1. 3 2
      src/components/sunui-upimg/sunui-upimg.vue
  2. 9 1
      src/pages.json
  3. 20 6
      src/pages/index/allInstructor/index.vue
  4. 36 2
      src/pages/index/attestation/index.vue
  5. 25 12
      src/pages/index/certifyingDetail/index.vue
  6. 110 48
      src/pages/index/courseDetail/index.vue
  7. 27 16
      src/pages/index/detail/components/course.vue
  8. 16 6
      src/pages/index/detail/components/instructor.vue
  9. 19 7
      src/pages/index/detail/components/venue.vue
  10. 118 50
      src/pages/index/detail/index.vue
  11. 130 42
      src/pages/index/gymDetail/components/popup.vue
  12. 205 81
      src/pages/index/gymDetail/index.vue
  13. 151 53
      src/pages/index/gymPay/index.vue
  14. 60 39
      src/pages/index/index.vue
  15. 37 24
      src/pages/index/instructorDetail/index.vue
  16. 23 0
      src/pages/index/mapPage/index.vue
  17. 2 2
      src/pages/index/search/index.vue
  18. 1 1
      src/pages/index/searchPage/components/events.vue
  19. 5 3
      src/pages/index/searchPage/index.vue
  20. 114 27
      src/pages/index/submitOrder/index.vue
  21. 42 2
      src/pages/index/toBeUsed/index.vue
  22. 149 43
      src/pages/index/training/index.vue
  23. 11 4
      src/pages/index/userList/index.vue
  24. 96 38
      src/pages/index/venue/index.vue
  25. 9 4
      src/pages/mine/accountSetting/index.vue
  26. 14 4
      src/pages/mine/feedback/index.vue
  27. 1 1
      src/pages/mine/feedbackRecord/index.vue
  28. 13 2
      src/pages/mine/index.vue
  29. 1 1
      src/pages/mine/mineComments/index.vue
  30. 10 4
      src/pages/mine/orderInfo/index.vue
  31. 23 4
      src/pages/mine/reviseNickname/index.vue
  32. 二进制
      src/static/qinggou.png
  33. 二进制
      src/static/snapped1.png
  34. 8 0
      src/styles/variables.less
  35. 2 1
      src/utils/http/index.ts
  36. 11 0
      src/utils/util/index.ts

+ 3 - 2
src/components/sunui-upimg/sunui-upimg.vue

@@ -10,7 +10,7 @@
 				</view>
 			</block>
 			<view v-show="upload_len < upload_count" hover-class="sunui-uploader-hover" class="sunui-uploader-inputbox" @click="chooseImage" :style="upload_img_wh">
-				<view><text class="iconfont icon-mn_shangchuantupian" style="color: #666;"></text></view>
+				<view><text class="iconfont icon-mn_shangchuantupian" style="color: #b9b9b9;"></text></view>	
 			</view>
 		</view>
 	</view>
@@ -277,7 +277,8 @@ const upload = function(options) {
 	position: relative;
 	margin-bottom: 16rpx;
 	box-sizing: border-box;
-	background-color: #ededed;
+	background-color: #FFFFFF;
+	border-radius: 32rpx;
 	display: flex;
 	flex-wrap: wrap;
 	align-items: center;

+ 9 - 1
src/pages.json

@@ -5,7 +5,9 @@
 			"style": {
 				"navigationBarBackgroundColor": "#FFF",
 				"navigationBarTitleText": "首页",
-				"navigationStyle": "custom"
+				"navigationStyle": "custom",
+				"enablePullDownRefresh": true,
+				"backgroundTextStyle": "dark"
 			}
 		}, {
 			"path": "pages/index/venue/index",
@@ -205,6 +207,12 @@
 				"navigationBarBackgroundColor": "#fff",
 				"navigationBarTitleText": "场馆全景"
 			}
+		},{
+			"path": "pages/index/mapPage/index",
+			"style": {
+				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTitleText": "导航"
+			}
 		},{
 			"path": "pages/mine/index",
 			"style": {

+ 20 - 6
src/pages/index/allInstructor/index.vue

@@ -1,19 +1,33 @@
 <template>
 	<view class="content">
-		<view class="a-instructor-card" v-for="item in 4" @click="to_instructor">
-			<image class="instructor-img" src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+		<view class="a-instructor-card" v-for="item in instructorList" :key="item.id" @click="to_instructor(item)">
+			<image class="instructor-img" :src="item.avatar" mode=""></image>
 			<view class="a-instructor-name">
-				<view class="name">詹姆四</view>
-				<view class="type">篮球</view>
+				<view class="name">{{item.realname}}</view>
+				<view class="type">{{item.trainingProgramsName}}</view>
 			</view>
 		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
-	const to_instructor=()=>{
+	import { ref, onMounted, computed } from 'vue'
+	import { onLoad, onReachBottom } from '@dcloudio/uni-app'
+	import { http } from '@/utils/http'
+	import zsEmpty from '@/components/zs-empty/index.vue'
+	onMounted(()=>{
+		get_findCoachList()
+	})
+	const to_instructor=(e)=>{
 		uni.navigateTo({
-			url:'/pages/index/instructorDetail/index'
+			url:`/pages/index/instructorDetail/index?id=${e.id}`
+		})
+	}
+	
+	const instructorList=ref()
+	const get_findCoachList=()=>{
+		http.get('/coachC/findCoachList',{loading:true}).then((res)=>{
+			instructorList.value=res.result
 		})
 	}
 </script>

+ 36 - 2
src/pages/index/attestation/index.vue

@@ -6,11 +6,17 @@
 			<view class="text">用于身份实名核验,反洗钱,资料将严格保密</view>
 		</view>
 		<view class="a-idcard-box">
-			<view class="front bg-image">
+			<view class="front" v-if="frontImg!=''"  @click="chooseImage(1)">
+				<image :src="frontImg" mode=""></image>
+			</view>
+			<view class="front bg-image" @click="chooseImage(1)" v-else>
 				<zzx-icon name="upload" size="30"></zzx-icon>
 				<view class="">上传人像面</view>
 			</view>
-			<view class="flip-side bg-image">
+			<view class="flip-side" v-if="flipSideImg!=''" @click="chooseImage(2)">
+				<image :src="flipSideImg" mode=""></image>
+			</view>
+			<view class="flip-side bg-image" v-else  @click="chooseImage(2)">
 				<zzx-icon name="upload" size="30"></zzx-icon>
 				<view class="">上传国徽面</view>
 			</view>
@@ -45,6 +51,24 @@
 		identityCard: '',
 		phone: ''
 	})
+	
+	const frontImg = ref('')
+	const flipSideImg=ref('')
+	const chooseImage = (e) => {
+		uni.chooseImage({
+			count: 1,
+			sizeType: ['original', 'compressed'],
+			sourceType: ['album', 'camera'],
+			success: function (res) {
+				if(e==1){
+					frontImg.value=res.tempFilePaths;
+				}else{
+					flipSideImg.value=res.tempFilePaths;
+				}
+			}
+		});
+	}
+	
 	const submit = () => {
 		http.post('/my/familyMembers/addFamilyMembers',{...formData.value},{loading:true}).then((res)=>{
 			TipsUtils.tips_toast(res.message)
@@ -119,6 +143,11 @@
 				align-items: center;
 				justify-content: center;
 				flex-direction: column;
+				&>image{
+					width: 100%;
+					height: 100%;
+					border-radius: 16rpx;
+				}
 			}
 			.flip-side{
 				width: 332rpx;
@@ -129,6 +158,11 @@
 				align-items: center;
 				justify-content: center;
 				flex-direction: column;
+				&>image{
+					width: 100%;
+					height: 100%;
+					border-radius: 16rpx;
+				}
 			}
 		}
 

+ 25 - 12
src/pages/index/certifyingDetail/index.vue

@@ -9,13 +9,13 @@
 			<view class="item-list">
 				<view class="item-text">无犯罪记录</view>
 				<view class="item-img">
-					<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="widthFix"></image>
+					<image :src="detailObj.certificateInnocence" mode="widthFix"></image>
 				</view>
 			</view>
 			<view class="item-list">
 				<view class="item-text">健康证</view>
 				<view class="item-img">
-					<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="widthFix"></image>
+					<image :src="detailObj.healthy" mode="widthFix"></image>
 				</view>
 			</view>
 		</view>
@@ -24,23 +24,36 @@
 				<zzx-icon name="idcard"></zzx-icon>
 				<view class="text">荣誉认证</view>
 			</view>
-			<view class="item-list">
-				<view class="item-text">篮球裁判三级</view>
-				<view class="item-img">
-					<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="widthFix"></image>
-				</view>
-			</view>
-			<view class="item-list">
-				<view class="item-text">优秀教师</view>
+			<view class="item-list" v-for="(item,index) in detailObj.honorImgList" :key="index">
+				<!-- <view class="item-text">篮球裁判三级</view> -->
 				<view class="item-img">
-					<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="widthFix"></image>
+					<image :src="item" mode="widthFix"></image>
 				</view>
 			</view>
 		</view>
 	</view>
 </template>
 
-<script>
+<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'
+	const cache = useCacheStore()
+	onLoad((option)=>{
+		detailId.value=option.id
+	})
+	onMounted(()=>{
+		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
+		})
+	}
 </script>
 <style>
 	page{

+ 110 - 48
src/pages/index/courseDetail/index.vue

@@ -1,19 +1,17 @@
 <template>
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
-		<image class="header-bg"
-			src="https://ts1.tc.mm.bing.net/th/id/R-C.a8553f142638e741396e386b43c2bca7?rik=dzSGk6XRsxAAsQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50062%2f5890.jpg_wh1200.jpg&ehk=BgxiqxvzoNQd0pZHWV4VPOMbYgqM76WDMt8RDzCjoYY%3d&risl=&pid=ImgRaw&r=0"
-			mode="widthFix"></image>
+		<image class="header-bg" :src="bannerList[0]" mode=""></image>
 		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" @click="RouterUtils.back()">
 			<zzx-icon name="back"></zzx-icon>
 		</view>
 		<view :style="{height:(statusBarHeight+70)+'px'}"></view>
 		<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">
 			<view class="swiper-inner">
-				<video src="https://vod.v.jstv.com/2025/05/09/JSTV_JSGGNEW_1746791056693_2lBi96K_114.mp4"></video>
-				<image v-for="item in 4"
-					src="https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650"
-					mode=""></image>
+				<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="item" mode=""></image>
 			</view>
 		</scroll-view>
 	</view>
@@ -21,22 +19,27 @@
 	<view class="header-info">
 		<view class="c-price-info">
 			<view class="price-info">
-				<view class="new-price">¥25.9</view>
-				<view class="old-price">¥80.9</view>
+				<view class="new-price">¥{{courseDetailInfo.sellingPrice}}</view>
+				<view class="old-price">¥{{courseDetailInfo.originalPrice}}</view>
 			</view>
-			<view class="sales">年售150</view>
+			<view class="sales">年售{{courseDetailInfo.sales}}</view>
 		</view>
 		<view class="c-name">
-			一对一篮球30分钟室内精品课程,一对一篮球
-			30分钟室内精品课程
+			{{courseDetailInfo.name}}
 		</view>
 		<view class="c-detail-info">
-			<view class="c-time">课时:05.06-05.31</view>
+			<view class="c-time">课时:{{courseDetailInfo.startTime}}-{{courseDetailInfo.endTime}}</view>
 			<view class="c-address">
-				<view class="">上课地点:观山湖区第十二小学</view>
+				<view class="">上课地点:{{courseDetailInfo.address}} | {{courseDetailInfo.km}} km</view>
 				<zzx-icon name="ashRight" size="10"></zzx-icon>
 			</view>
-			<view class="c-instructor">授课教练:杨锦新</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>
+			</view>
 		</view>
 		<view class="c-line"></view>
 		<view class="c-rules">限制:每人限购一张</view>
@@ -52,17 +55,13 @@
 		</uv-sticky>
 		<view class="c-tabbar">
 			<view class="c-tabbar-detail" id="detail">
-				详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容
-				详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容详情富文本内容
-				详情富文本内容详情富文本内容详情富文本内容详情富文本内容
+				<rich-text :nodes="courseDetailInfo.details"></rich-text>
 			</view>
 			<view class="c-notice" id="notice">
 				<view class="title">购买须知</view>
 				<view class="tips-text">
 					<view class="text">
-						<view class="">1.购买后,需按照课表按时上课;</view>
-						<view class="">2.如有特殊情况,需上传相关证明;</view>
-						<view class="">3.由于特殊情况耽误了课程,后续会发布补课表,集中补课</view>
+						<rich-text :nodes="courseDetailInfo.reminder"></rich-text>
 					</view>
 					<view class="more">
 						<text>查看更多</text>
@@ -73,12 +72,12 @@
 			<view class="c-schedule" id="schedule">
 				<view class="title">课程表</view>
 				<view class="list-card">
-					<view class="card-title">总共6节</view>
-					<view class="schedule-list" v-for="item in 5">
+					<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>05.06 17:00-19:00</text>
+							<text>{{item.startTime}}-{{item.endTime}}</text>
 						</view>
-						<view class="name">第一节:篮球热身运动</view>
+						<view class="name">{{item.name}}</view>
 					</view>
 					<view class="more">
 						<text>查看更多</text>
@@ -129,25 +128,36 @@
 			<view class="">分享</view>
 		</view>
 		<view class="c-buy-btn">
-			<view class="buy">
-				<view class="buy-text">直接购买</view>
+			<view class="buy" v-if="type==3">
+				<view class="buy-text">抢购</view>
 				<view class="buy-price">
-					<text>¥25.9</text>
+					<text>¥{{courseDetailInfo.sellingPrice}}</text>
 					<text>省10</text>
 				</view>
 			</view>
-			<view class="gratis" @click="toOrderPage">
-				免费试听
-			</view>
+			<block v-else>
+				<view class="buy">
+					<view class="buy-text">直接购买</view>
+					<view class="buy-price">
+						<text>¥{{courseDetailInfo.sellingPrice}}</text>
+						<text>省10</text>
+					</view>
+				</view>
+				<view class="gratis" @click="toOrderPage">
+					免费试听
+				</view>
+			</block>
 		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
 	import { ref, onMounted, getCurrentInstance, nextTick } from 'vue';
-	import { RouterUtils } from '@/utils/util';
+	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);
@@ -155,11 +165,19 @@
 	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()
 	})
 
 	// 获取所有模块的位置信息
@@ -171,7 +189,7 @@
 		});
 		query.exec((rects) => {
 			// 计算各模块相对于页面顶部的距离
-			sectionTops.value = rects.map((rect:any) => rect.top -130);
+			sectionTops.value = rects.map((rect : any) => rect.top - 130);
 		})
 	};
 
@@ -235,9 +253,25 @@
 			});
 		});
 	}
-	
-	const toOrderPage=()=>{
-		RouterUtils.to_page('/pages/index/submitOrder/index')
+
+	const toOrderPage = () => {
+		RouterUtils.to_page(`/pages/index/gymPay/index?courseId=${courseId.value}&type=${type.value}`)
+	}
+
+	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
+		})
 	}
 </script>
 
@@ -248,6 +282,7 @@
 		.header-bg {
 			position: absolute;
 			width: 100%;
+			height: 432rpx;
 			z-index: -100;
 		}
 
@@ -346,6 +381,22 @@
 
 			.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%;
+					}
+				}
 			}
 		}
 
@@ -423,6 +474,8 @@
 			background: #FFFFFF;
 			border-radius: 32rpx;
 			padding: 20rpx;
+			font-size: 24rpx;
+			color: #222222;
 		}
 
 		.c-notice {
@@ -611,52 +664,61 @@
 			}
 		}
 	}
-	.c-bottom{
+
+	.c-bottom {
 		display: flex;
 		align-items: center;
 		justify-content: space-between;
 		position: fixed;
 		bottom: 0;
-		width:95%;
+		width: 95%;
 		padding: 20rpx;
 		background: #fff;
-		box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0,0,0,0.09);
+		box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0, 0, 0, 0.09);
 		border-radius: 32rpx 32rpx 0rpx 0rpx;
-		.c-share{
+
+		.c-share {
 			font-weight: bold;
 			font-size: 28rpx;
 			color: #222222;
 			text-align: center;
 		}
-		.c-buy-btn{
+
+		.c-buy-btn {
 			display: flex;
 			align-items: center;
 			gap: 16rpx;
-			.buy{
+
+			.buy {
 				width: 226rpx;
 				height: 100rpx;
 				background: #222222;
 				border-radius: 60rpx;
 				text-align: center;
-				.buy-text{
+
+				.buy-text {
 					margin-top: 8rpx;
 					font-weight: bold;
 					font-size: 32rpx;
 					color: #D3FD76;
 				}
-				.buy-price{
+
+				.buy-price {
 					color: #D3FD76;
-					&>text:first-child{
+
+					&>text:first-child {
 						font-weight: bold;
 						font-size: 28rpx;
 					}
-					&>text:last-child{
+
+					&>text:last-child {
 						margin-left: 6rpx;
 						font-size: 22rpx;
 					}
 				}
 			}
-			.gratis{
+
+			.gratis {
 				width: 226rpx;
 				height: 100rpx;
 				background: #D3FD76;
@@ -665,7 +727,7 @@
 				font-size: 32rpx;
 				color: #222222;
 				text-align: center;
-				line-height: 100rpx ;
+				line-height: 100rpx;
 			}
 		}
 	}

+ 27 - 16
src/pages/index/detail/components/course.vue

@@ -6,47 +6,58 @@
 		</view>
 		<view class="select-btn">
 			<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList" :key="index"
-				@click="select_btn(index)">{{item}}</view>
+				@click="select_btn(item,index)">{{item.name}}</view>
 		</view>
-		<view class="venue-card" v-for="item in 2" @click="toCOurseDetail">
-			<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+		<view class="venue-card" v-for="item in listData" :key="item.id" @click="toCourseDetail(item)">
+			<image :src="item.cover" mode=""></image>
 			<view class="venue-info">
 				<view class="info-title">
-					<view class="title textHidden">小班体适能+篮球衔接小班体适能+篮球衔接...</view>
-					<view class="sales">年售20</view>
+					<view class="title textHidden">{{item.name}}</view>
+					<view class="sales">年售{{item.salesYear}}</view>
 				</view>
 				<view class="type">
-					篮球、足球、羽毛球
+					上课地点:{{item.address}} | {{item.km||'--'}}km
+				</view>
+				<view class="type">
+					{{item.count||'0'}}课时 {{item.startTime}}-{{item.endTime}}
 				</view>
 				<view class="price">
-					<view class="">¥58.9</view>
-					<view class="">¥80.9</view>
+					<view class="">¥{{item.sellingPrice}}</view>
+					<view class="">¥{{item.originalPrice}}</view>
 				</view>
 				<view class="price-info">
 					<view class="sale">
-						已售33 98%好评
+						已售{{item.sales}} {{item.goodRate}}%好评
 					</view>
 					<view class="price-btn">免费试听</view>
 				</view>
 			</view>
 		</view>
-		<!-- <loading/> -->
+		<view class="not-data" v-if="listData.length<1">暂无数据</view>
 		<view class="more">查看更多</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
 	import { ref } from 'vue';
-	import loading from '@/components/zzx-loading/zzx-loading.vue';
-	const selectList = ref(['篮球', '羽毛球','乒乓球','网球']);
+	interface Props {
+		listData ?: any;
+		selectList?:any;
+	}
+	const props = withDefaults(defineProps<Props>(), {
+		listData: [],
+		selectList:[],
+	});
+	const emit = defineEmits(['change']);
 	const sel_btn=ref(0);
-	const select_btn=(i)=>{
+	const select_btn=(e,i)=>{
 		sel_btn.value=i
+		emit('change', e, i);
 	}
 	
-	const toCOurseDetail=()=>{
+	const toCourseDetail=(e)=>{
 		uni.navigateTo({
-			url:'/pages/index/courseDetail/index'
+			url:`/pages/index/courseDetail/index?id=${e.id}&type=1`
 		})
 	}
 </script>
@@ -115,7 +126,7 @@
 			}
 			.venue-info{
 				width: 430rpx;
-				height: 200rpx;
+				height: 260rpx;
 				border-bottom: 1rpx solid #F0F0F0;
 				.info-title{
 					display: flex;

+ 16 - 6
src/pages/index/detail/components/instructor.vue

@@ -1,25 +1,35 @@
 <template>
 	<view class="instructor-card">
 		<view class="card-title">
-			<view class="">教练(9)</view>
+			<view class="">教练({{instrctorList.length}})</view>
 			<zzx-icon name="right" size="12"></zzx-icon>
 		</view>
 		<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">
 			<view class="swiper-box">
-				<view class="swiper-inner" v-for="item in 12">
+				<view class="swiper-inner" v-for="item in instrctorList" :key="item.id">
 					<view class="header-img">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+						<image :src="item.avatar" mode=""></image>
 						<image src="/src/static/badge.png" mode=""></image>
 					</view>
-					<view class="instructor-name">詹姆斯</view>
-					<view class="instructor-specialty">篮球</view>
+					<view class="instructor-name">{{item.name}}</view>
+					<view class="instructor-specialty">
+						<text v-for="(category,index) in item.category" :key="index">{{category}}</text>
+					</view>
 				</view>
 			</view>
 		</scroll-view>
+		<zs-empty v-if="instrctorList.length<1"></zs-empty>
 	</view>
 </template>
 
-<script>
+<script lang="ts" setup>
+	import zsEmpty from '@/components/zs-empty/index.vue'
+	interface Props {
+		instrctorList ?: any;
+	}
+	const props = withDefaults(defineProps<Props>(), {
+		instrctorList: []
+	});
 </script>
 
 <style lang="less" scoped>

+ 19 - 7
src/pages/index/detail/components/venue.vue

@@ -1,18 +1,18 @@
 <template>
-	<view class="venue-card" v-for="item in 10">
-		<image src="https://img.shetu66.com/2023/06/13/1686646672844195.jpg" mode=""></image>
+	<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">指定时段免费畅玩</view>
-				<view class="sales">年售20</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>
 			</view>
 			<view class="price-info">
 				<view class="price">
-					<view class="">¥58.9</view>
-					<view class="">¥80.9</view>
+					<view class="">¥{{item.sellingPrice}}</view>
+					<view class="">¥{{item.originalPrice}}</view>
 				</view>
 				<view class="price-btn">免费预约</view>
 			</view>
@@ -21,6 +21,18 @@
 </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
+		})
+	}
 </script>
 
 <style lang="less" scoped>

+ 118 - 50
src/pages/index/detail/index.vue

@@ -1,58 +1,60 @@
 <template>
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
-		<image class="header-bg"
-			src="https://ts1.tc.mm.bing.net/th/id/R-C.a8553f142638e741396e386b43c2bca7?rik=dzSGk6XRsxAAsQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50062%2f5890.jpg_wh1200.jpg&ehk=BgxiqxvzoNQd0pZHWV4VPOMbYgqM76WDMt8RDzCjoYY%3d&risl=&pid=ImgRaw&r=0"
-			mode="widthFix"></image>
+		<image class="header-bg" :src="bannerList[0]" mode=""></image>
 		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" @click="RouterUtils.back()">
 			<zzx-icon name="back"></zzx-icon>
 		</view>
 		<view :style="{height:(statusBarHeight+70)+'px'}"></view>
 		<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">
 			<view class="swiper-inner">
-				<video src="https://vod.v.jstv.com/2025/05/09/JSTV_JSGGNEW_1746791056693_2lBi96K_114.mp4"></video>
-				<image v-for="item in 4"
-					src="https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650"
-					mode=""></image>
+				<block  v-if="detailInfo.video">
+					<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>
+				<!-- </view> -->
 			</view>
 		</scroll-view>
 	</view>
 	<view :style="{height:(statusBarHeight+34)+'px'}"></view>
 	<view class="header-info">
 		<view class="venue-name">
-			<view class="name">观山湖区第十二小学</view>
+			<view style="display: flex;gap: 20rpx;align-items: center;">
+				<view class="name">{{detailInfo.name}}</view>
+				<view class="open-status">{{detailInfo.runStatus?'开放中':'歇业中'}}</view>
+			</view>
 			<view class="star">
 				<zzx-icon name="star" size="12"></zzx-icon>
-				<text>4.8</text>
+				<text>{{detailInfo.goodRate}}</text>
 			</view>
 		</view>
 		<view class="open-time">
-			<view class="open-status">开放中</view>
 			<view class="time">
-				<view class="">教学日 10:00-22:00</view>
-				<view class="">非教学日 10:00-22:00</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>
 		</view>
 		<view class="venues-tags">
 			<view class="tags-box">
-				<view class="tags" v-for="item in 4">无烟环境</view>
+				<view class="tags" v-for="(item,index) in detailInfo.facilityInfo" :key="index">{{item}}</view>
 			</view>
-			<view class="more-info">
+<!-- 			<view class="more-info" @click="RouterUtils.to_page(`/pages/index/basisInfo/index`)">
 				<text>信息/设备设施</text>
 				<zzx-icon name="ashRight" size="10"></zzx-icon>
-			</view>
+			</view> -->
 		</view>
 		<view class="venues-address">
 			<view class="address">
 				<zzx-icon name="location" size="14"></zzx-icon>
-				<text>印象城购物中心6楼</text>
+				<text>{{detailInfo.address}}</text>
 			</view>
 			<view class="nav-phone">
-				<view class="nav">
+				<view class="nav" @click="openMap">
 					<zzx-icon name="navigation" size="14"></zzx-icon>
 					<view class="">导航</view>
 				</view>
-				<view class="phone">
+				<view class="phone" @click="openphone">
 					<zzx-icon name="phone" size="14"></zzx-icon>
 					<view class="">电话</view>
 				</view>
@@ -62,31 +64,34 @@
 	<view class="content">
 		<uv-sticky offset-top="74">
 			<view class="detail-select">
-				<view :class="sel_index===index?'select-text':'notsel-text'" v-for="(item,index) in selectList" :key="index"
-					@click="sel_tab(index)">
+				<view :class="sel_index===index?'select-text':'notsel-text'" v-for="(item,index) in selectList"
+					:key="index" @click="sel_tab(index)">
 					<text>{{item}}</text>
 				</view>
 			</view>
 		</uv-sticky>
-			<view class="toggle" v-if="sel_index===0">
-				<venue/>
-			</view>
-			<view class="toggle" v-else-if="sel_index===1">
-				<course/>
-			</view>
-			<view class="toggle" v-else-if="sel_index===2">
-				<instructor/>
-			</view>
-			<view class="toggle" v-else>
-				<appraise/>
-			</view>
+		<view class="toggle" v-if="sel_index===0">
+			<venue :listData="detailInfo.placeInfoMsgVO" />
+			<zs-empty v-if="detailInfo.placeInfoMsgVO.length<1"></zs-empty>
+		</view>
+		<view class="toggle" v-else-if="sel_index===1">
+			<course :selectList="allCategoryList" :listData="courseList" :laoding="courseLoading"  @change="onchange" />
+		</view>
+		<view class="toggle" v-else-if="sel_index===2">
+			<instructor :instrctorList="detailInfo.instructorVOList" />
+		</view>
+		<view class="toggle" v-else>
+			<appraise />
+		</view>
 	</view>
 </template>
 
 <script lang="ts" setup>
 	import { ref, onMounted } from 'vue';
-	import { RouterUtils } from '@/utils/util';
+	import { RouterUtils,_previewImage } from '@/utils/util';
+	import { http } from '@/utils/http'
 	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
+	import zsEmpty from '@/components/zs-empty/index.vue'
 	import venue from './components/venue.vue';
 	import course from './components/course.vue';
 	import instructor from './components/instructor.vue';
@@ -94,10 +99,15 @@
 	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
 	const statusBarHeight = ref(0);
 	const selectList = ref(['场地', '课程', '教练', '评价']);
-	const sel_index = ref(0)
-	onMounted(() => {
+	const sel_index = ref(0);
+	onLoad((option) => {
+		listId.value = option.id
 		get_navheight()
 	})
+	onMounted(() => {
+		get_placeInfo()
+		get_allCategory()
+	})
 	const get_navheight = () => {
 		const systemInfo = uni.getSystemInfoSync();
 		statusBarHeight.value = systemInfo.statusBarHeight || 0;
@@ -106,6 +116,67 @@
 	const sel_tab = (i) => {
 		sel_index.value = i
 	}
+
+	const listId = ref(0);
+	const detailInfo = ref({})
+	const bannerList = ref([])
+	const videoList = ref([])
+	const noTeachingDay=ref()
+	const teachingDay=ref()
+	const get_placeInfo = () => {
+		http.get('/detail/getPlaceInfo', { data: { id: listId.value }, loading: true }).then((res) => {
+			const startIndex = res.result.cover.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(',');
+			detailInfo.value = res.result
+			noTeachingDay.value=JSON.parse(res.result.noTeachingDay)
+			teachingDay.value=JSON.parse(res.result.teachingDay)
+		})
+	}
+
+	const openphone = () => {
+		uni.makePhoneCall({
+			phoneNumber: detailInfo.value.phone
+		});
+	}
+	
+	const openMap=()=>{
+		uni.openLocation({
+			latitude: detailInfo.value.latitude,
+			longitude: detailInfo.value.longitude,
+			name: detailInfo.value.name,
+			address: detailInfo.value.address,
+			success: function () {
+				console.log('success');
+			}
+		});
+	}
+	
+	
+	// 课程分类
+	const allCategoryList=ref([])
+	const categoryId=ref()
+	const get_allCategory=()=>{
+		http.get('/detail/getAllCategory', { data: { id: listId.value}}).then((res)=>{
+			categoryId.value=res.result[0].id
+			allCategoryList.value=res.result
+			get_courseList(categoryId.value)
+		})
+	}
+	const onchange=(e)=>{
+		get_courseList(e.id)
+	}
+	// 课程列表
+	const courseList=ref([])
+	const get_courseList=(categoryId)=>{
+		http.get('/detail/courseInfoVOList',{data:{categoryId:categoryId,id:listId.value},loading:true}).then((res)=>{
+			courseList.value=res.result
+		})
+	}
+	
 </script>
 
 <style lang="less" scoped>
@@ -115,6 +186,7 @@
 		.header-bg {
 			position: absolute;
 			width: 100%;
+			height: 432rpx;
 			z-index: -100;
 		}
 
@@ -144,8 +216,7 @@
 				gap: 14rpx;
 				height: 100%;
 
-				&>video,
-				&>image {
+				&>video ,&>image {
 					width: 220rpx;
 					height: 126rpx;
 					border-radius: 16rpx;
@@ -165,6 +236,11 @@
 			align-items: center;
 			justify-content: space-between;
 
+			.open-status {
+				width: 100rpx;
+				font-size: 24rpx;
+				color: #4DD951;
+			}
 			.name {
 				font-weight: 800;
 				font-size: 32rpx;
@@ -181,22 +257,13 @@
 		}
 
 		.open-time {
-			display: flex;
-			align-items: center;
-			gap: 20rpx;
 			margin-top: 20rpx;
-
-			.open-status {
-				font-size: 24rpx;
-				color: #4DD951;
-			}
-
 			.time {
-				display: flex;
-				align-items: center;
-				gap: 20rpx;
 				font-size: 24rpx;
 				color: #AAAAAA;
+				&>view{
+					margin-top: 20rpx;
+				}
 			}
 		}
 
@@ -268,7 +335,8 @@
 		gap: 60rpx;
 		margin-top: 20rpx;
 		height: 80rpx;
-		background-color:#F6F6F6;
+		background-color: #F6F6F6;
+
 		.select-text,
 		.notsel-text {
 			position: relative;

+ 130 - 42
src/pages/index/gymDetail/components/popup.vue

@@ -1,43 +1,53 @@
 <template>
 	<uni-popup ref="selectPopup" :safe-area="false" type="bottom">
-		<view class="header-text">开场前60分钟随时退</view>
+		<view class="header-text">开场前{{listData.earlyRefundTime||'--'}}分钟随时退</view>
 		<view class="select-popup">
 			<view class="pop-title">选择场次</view>
 			<view class="pop-date-list">
 				<scroll-view scroll-x="true" class="scroll-view_H">
-					<view class="scroll-view-item" v-for="(item,index) in 7" @click="sel_tab(index)">
-						<view class="today-time">今天(06-09)</view>
-						<view class="num">5场可订</view>
-						<view class="line" v-if="sel_index===index"></view>
+					<view class="scroll-view-item" v-for="(item,index) in listData.stadiumConcertsVOList" :key="index"
+						@click="sel_tab(item,index)">
+						<view class="today-time">{{item.weekDayAndDate}}</view>
+						<view class="num">{{item.noDayConcertsReservationNum||'0'}}场可订</view>
+						<view class="line" v-if="deteObj==index"></view>
 					</view>
 				</scroll-view>
 			</view>
 			<view class="gym-list">
 				<view class="time-list">
-					<view style="height: 26rpx;"></view>
-					<view class="item-time" v-for="(item,index) in time_list" :key="index">{{item}}</view>
+					<view class="time-title">时间段</view>
+					<block
+						v-for="(concert,index) in listData.stadiumConcertsVOList[0].concertsVOList[0].concertsDetailsVOList"
+						:key="index">
+						<view class="item-time">{{concert.startTime}}-{{concert.endTime}}</view>
+					</block>
 				</view>
 				<view class="table-list">
 					<scroll-view scroll-x="true" class="table-scroll">
-						<view class="father-list" v-for="item in 7">
-							<view class="father-title">羽毛球1</view>
-							<view class="children-list" v-for="item in 13">
-								<view class="item-card">¥35</view>
+						<view class="father-list" v-for="(conc,index) in itemList" :key="index"
+							style="vertical-align: top;">
+							<view class="father-title">{{conc.sitePlaceName}}</view>
+							<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)">
+									¥{{concert.price}}
+								</view>
 							</view>
 						</view>
 					</scroll-view>
 				</view>
 			</view>
-			<view class="select-list">
+			<view class="select-list" v-if="selArr.length>0">
 				<view class="select-title">已选场次</view>
 				<scroll-view scroll-x="true" class="select-scroll">
-					<view class="item-list" v-for="item in 7">
+					<view class="item-list" v-for="(item,index) in selArr" :key="index">
 						<view class="list-box">
 							<view class="list-text">
-								<view class="">16:00-17:00</view>
-								<view class="">羽毛球1</view>
+								<view class="">{{item.time}}</view>
+								<view class="">{{item.name}}</view>
 							</view>
-							<zzx-icon name="cancel" size="12"></zzx-icon>
+							<view @click="deleteSelarr(item)"> <zzx-icon name="cancel" size="12"></zzx-icon></view>
 						</view>
 					</view>
 				</scroll-view>
@@ -46,7 +56,7 @@
 			<view class="footer-submit">
 				<view class="f-price">
 					<view class="">总价</view>
-					<view class="">¥50.59</view>
+					<view class="">¥{{priceTotal.toFixed(2)}}</view>
 				</view>
 				<view class="f-btn" @click="submit_order">
 					<button>提交订单</button>
@@ -54,44 +64,44 @@
 			</view>
 		</view>
 	</uni-popup>
-	<view>
+	<view v-if="isopenDetail">
 		<uni-popup ref="orderPopup" :safe-area="false" type="bottom">
-			<view class="header-text">开场前60分钟随时退</view>
+			<view class="header-text">开场前{{previewgymOrderDetail.earlyRefundTime||'--'}}分钟随时退</view>
 			<view class="order-popup">
 				<view class="p-header-card">
 					<view class="p-school-info">
 						<zzx-icon name="pay-icon1" size="16"></zzx-icon>
-						<view class="name">观山湖区第十二小学</view>
+						<view class="name">{{previewgymOrderDetail.storeName}}</view>
 					</view>
 					<view class="p-title">羽毛球场地预定</view>
 					<view class="p-preset">
-						<view class="preset-info" v-for="item in 3">06-11(周三)11:00-12:00|羽毛球1</view>
+						<view class="preset-info" v-for="item in previewgymOrderDetail.timePeriod" :key="item.id">{{item.name}}</view>
 					</view>
 				</view>
 				<view class="p-price-card">
 					<view class="p-price">
-						<view class="text">商品总价(共3场)</view>
-						<view class="price"><text class="mini-text">¥</text>50.59</view>
+						<view class="text">商品总价(共{{previewgymOrderDetail.timePeriod.length}}场)</view>
+						<view class="price"><text class="mini-text">¥</text>{{previewgymOrderDetail.subtotal}}</view>
 					</view>
 					<view class="p-subtotal">
 						<text>小计</text>
-						<view class="total-price"><text class="mini-text">¥</text>50.59</view>
+						<view class="total-price"><text class="mini-text">¥</text>{{previewgymOrderDetail.totalPrice}}</view>
 					</view>
 				</view>
 				<view class="p-phone-card">
 					<view class="p-phone">
 						<view class="text">手机号码</view>
-						<view class="phone">159****2066</view>
+						<view class="phone">{{phoneHide(previewgymOrderDetail.mobile)}}</view>
 					</view>
 					<view class="tips">请通话畅通,商家需要联系您确认到店时间</view>
 				</view>
 				<view class="p-rules-card">
 					<view class="p-title">退改规则</view>
-					<view class="p-text">每场开场前<text>60分钟</text>可随时退改,之后不可退款。如您有疑问,可联系场馆。</view>
+					<view class="p-text">每场开场前<text>{{previewgymOrderDetail.earlyRefundTime}}分钟</text>可随时退改,之后不可退款。如您有疑问,可联系场馆。</view>
 				</view>
 				<view class="p-rules-card">
 					<view class="p-title">温馨提示</view>
-					<view class="p-text">场地仅限个人使用,培训、比赛或者其他商业活动可能需要额外收费,如有需求请提前联系商家咨询收费标准。</view>
+					<view class="p-text">{{previewgymOrderDetail.reminder}}</view>
 				</view>
 				<view class="p-remark">
 					<view class="title">备注</view>
@@ -100,7 +110,7 @@
 				<view style="height: 200rpx;"></view>
 				<view class="footer-pay">
 					<button hover-class="hover-style">
-						<view class="btn-price"><text class="mini-text">¥</text>50.59</view>
+						<view class="btn-price"><text class="mini-text">¥</text>{{previewgymOrderDetail.totalPrice}}</view>
 						<view class="btn-text">立即支付</view>
 					</button>
 				</view>
@@ -110,28 +120,88 @@
 </template>
 
 <script lang="ts" setup>
-	import { ref } from 'vue';
+	import { ref,onMounted, computed } from 'vue';
+	import { http } from '@/utils/http'
+	import { TipsUtils,phoneHide } from '@/utils/util';
+	interface Props {
+		listData ?: any;
+		itemList ?: any;
+		deteObj?:any
+	}
+	const props = withDefaults(defineProps<Props>(), {
+		listData: [],
+		itemList: [],
+		deteObj:null
+	});
 	const selectPopup = ref();
 	const orderPopup = ref()
 	const sel_index = ref(0);
-	const time_list = ref(['09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00'])
+	const time_list = ref([])
+	onMounted(()=>{
+		
+	})
 	const open = () => {
 		selectPopup.value.open()
 	}
 	defineExpose({
 		open
 	})
+	const emit = defineEmits(['change']);
+	const sel_tab = (e, i) => {
+		emit('change', e, i);
+	}
 
-	const sel_tab = (i) => {
-		sel_index.value = i
+	const selArr = ref([])
+	const selectItem = (item1, item2) => {
+		const existingIndex = selArr.value.findIndex(item => item.id === item2.id);
+		if (existingIndex !== -1) {
+			selArr.value.splice(existingIndex, 1);
+		} else {
+			selArr.value.push({
+				name: item1.sitePlaceName,
+				time: item2.startTime + '-' + item2.endTime,
+				price: item2.price,
+				id: item2.id
+			});
+		}
 	}
 
+	const isSelected = (concert) => {
+		return selArr.value.some(item => item.id === concert.id);
+	}
+
+	const priceTotal = computed(() => {
+		return selArr.value.reduce((total, item) => {
+			return total + item.price
+		}, 0)
+	})
+
+	const deleteSelarr = (item) => {
+		const index = selArr.value.findIndex(selItem => selItem.id === item.id);
+		if (index !== -1) {
+			selArr.value.splice(index, 1);
+		}
+	}
+	
 	const submit_order = () => {
-		selectPopup.value.close()
-		orderPopup.value.open()
-		// uni.navigateTo({
-		// 	url:'/pages/index/gymPay/index'
-		// })
+		if(selArr.value.length<1){
+			return TipsUtils.tips_toast('请选择场次')
+		}
+		get_previewOrderPlaceGymnasiumChartered()
+	}
+	
+	const previewgymOrderDetail=ref()
+	const isopenDetail = ref(false)
+	const get_previewOrderPlaceGymnasiumChartered=()=>{
+		const result = selArr.value.map(item => item.id).join(',')
+		http.get('/order/previewOrderPlaceGymnasiumChartered',{data:{rulesId:result},loading:true}).then((res)=>{
+			previewgymOrderDetail.value=res.result
+			isopenDetail.value=true
+			setTimeout(()=>{
+				selectPopup.value.close()
+				orderPopup.value.open()
+			},500)
+		})
 	}
 </script>
 
@@ -206,7 +276,16 @@
 			padding: 20rpx;
 
 			.time-list {
-				width: 100rpx;
+				width: 180rpx;
+
+				.time-title {
+					height: 60rpx;
+					line-height: 60rpx;
+					text-align: center;
+					font-weight: bold;
+					font-size: 24rpx;
+					color: #222222;
+				}
 
 				.item-time {
 					margin-bottom: 20rpx;
@@ -250,6 +329,10 @@
 								color: #222222;
 								text-align: center;
 								line-height: 54rpx;
+
+								&.selected {
+									background: #C8FF0C !important;
+								}
 							}
 						}
 					}
@@ -509,7 +592,8 @@
 			bottom: 0;
 			padding: 0 20rpx;
 			z-index: 9999;
-			&>button{
+
+			&>button {
 				width: 686rpx;
 				height: 100rpx;
 				background: #C8FF0C;
@@ -518,21 +602,25 @@
 				align-items: center;
 				justify-content: center;
 				gap: 10rpx;
+
 				&>button::after {
 					border: none;
 				}
-				.btn-price{
+
+				.btn-price {
 					font-weight: 800;
 					font-size: 48rpx;
 					color: #222222;
 				}
-				.btn-text{
+
+				.btn-text {
 					font-weight: bold;
 					font-size: 32rpx;
 					color: #222222;
 				}
 			}
-			.hover-style{
+
+			.hover-style {
 				color: #999999;
 			}
 		}

+ 205 - 81
src/pages/index/gymDetail/index.vue

@@ -1,51 +1,51 @@
 <template>
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
-		<image class="header-bg"
-			src="https://ts1.tc.mm.bing.net/th/id/R-C.a8553f142638e741396e386b43c2bca7?rik=dzSGk6XRsxAAsQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50062%2f5890.jpg_wh1200.jpg&ehk=BgxiqxvzoNQd0pZHWV4VPOMbYgqM76WDMt8RDzCjoYY%3d&risl=&pid=ImgRaw&r=0"
-			mode="widthFix"></image>
+		<image class="header-bg" :src="bannerList[0]" mode=""></image>
 		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" @click="RouterUtils.back()">
 			<zzx-icon name="back"></zzx-icon>
 		</view>
 		<view :style="{height:(statusBarHeight+70)+'px'}"></view>
 		<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">
 			<view class="swiper-inner">
-				<video src="https://vod.v.jstv.com/2025/05/09/JSTV_JSGGNEW_1746791056693_2lBi96K_114.mp4"></video>
-				<image v-for="item in 4"
-					src="https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650"
-					mode=""></image>
+				<block  v-if="detailInfo.video">
+					<video v-for="(item,index) in videoList" :key="index" :src="item"></video>
+				</block>
+				<image v-for="(item,index) in bannerList" :key="index" :src="item" mode=""></image>
 			</view>
 		</scroll-view>
 	</view>
 	<view :style="{height:(statusBarHeight+34)+'px'}"></view>
 	<view class="header-info">
 		<view class="venue-name">
-			<view class="name">观山湖区第十二小学</view>
+			<view style="display: flex;gap: 20rpx;align-items: center;">
+				<view class="name">{{detailInfo.name}}</view>
+				<view class="open-status">{{detailInfo.runStatus?'营业中':'歇业中'}}</view>
+			</view>
 			<view class="star">
 				<zzx-icon name="star" size="12"></zzx-icon>
-				<text>4.8</text>
+				<text>{{detailInfo.goodRate}}</text>
 			</view>
 		</view>
 		<view class="open-time">
-			<view class="open-status">开放中</view>
 			<view class="time">
-				<view class="">教学日 10:00-22:00</view>
-				<view class="">非教学日 10:00-22:00</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>
 		</view>
 		<view class="venues-tags">
 			<view class="tags-box">
-				<view class="tags" v-for="item in 4">无烟环境</view>
+				<view class="tags" v-for="(item,index) in detailInfo.facilityInfo" :key="index">{{item}}</view>
 			</view>
-			<view class="more-info" @click="RouterUtils.to_page('/pages/index/basisInfo/index')">
+<!-- 			<view class="more-info" @click="RouterUtils.to_page('/pages/index/basisInfo/index')">
 				<text>信息/设备设施</text>
 				<zzx-icon name="ashRight" size="10"></zzx-icon>
-			</view>
+			</view> -->
 		</view>
 		<view class="venues-address">
 			<view class="address">
 				<zzx-icon name="location" size="14"></zzx-icon>
-				<text>印象城购物中心6楼</text>
+				<text>{{detailInfo.address}}</text>
 			</view>
 			<view class="nav-phone">
 				<view class="nav" @click="open_map">
@@ -76,7 +76,7 @@
 						<view style="margin-bottom: 10rpx;">包场</view>
 					</view>
 					<view class="">
-						开场前60分钟随时退
+						开场前{{charteredList.earlyRefundTime}}分钟随时退
 					</view>
 					<view class="v-left" @click="RouterUtils.to_page('/pages/index/vr/index')">
 						<zzx-icon name="venue-icon2" size="14"></zzx-icon>
@@ -85,16 +85,17 @@
 				</view>
 				<view class="v-select-infocard">
 					<view class="select-btn">
-						<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList_btn"
-							:key="index" @click="select_btn(index)">{{item}}</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">
 						<scroll-view scroll-x="true" class="scroll-view_H">
-							<view class="item-card scroll-view-item_H" v-for="item in 6" @click="open_popup">
-								<view class="today">今天(03-04)</view>
-								<view class="time">最早19:00可订</view>
-								<view class="price">¥58起</view>
+							<view class="item-card scroll-view-item_H" v-for="(item,index) in charteredList.timeSlot" :key="item.id" @click="open_popup(item,index)">
+								<view class="today">{{item.dateLabel}}</view>
+								<view class="time">最早{{item.startTime}}可订</view>
+								<view class="price">¥{{item.sellingPrice}}起</view>
 							</view>
+							<view class="not-data" v-if="charteredList.timeSlot.length<1">暂无可选时间</view>
 						</scroll-view>
 					</view>
 				</view>
@@ -104,27 +105,26 @@
 					<zzx-icon name="venue-icon3" size="14"></zzx-icon>
 					<view class="">无固定场</view>
 				</view>
-				<view class="item-card" v-for="item in 2">
-					<image src="https://img.shetu66.com/2023/06/13/1686646672844195.jpg" mode=""></image>
+				<view class="item-card" v-for="(item,index) in detailInfo.placeInfoMsgVO" :key="item.id">
+					<image :src="item.cover" mode=""></image>
 					<view class="venue-info">
 						<view class="info-title">
-							<view class="title textHidden">指定时段免费畅玩</view>
-							<view class="sales">年售20</view>
+							<view class="title textHidden">{{item.name}}</view>
+							<view class="sales">年售{{item.sales}}</view>
 						</view>
-						<view class="type">
+<!-- 						<view class="type">
 							篮球、足球、羽毛球
-						</view>
+						</view> -->
 						<view class="price-info">
 							<view class="price">
-								<view class="">¥58.9</view>
-								<view class="">¥80.9</view>
-							</view>
-							<view class="price-btn" @click="RouterUtils.to_page('/pages/index/gymPay/index?type=1')">抢购
+								<view class="">¥{{item.sellingPrice}}</view>
+								<view class="">¥{{item.originalPrice}}</view>
 							</view>
+							<view class="price-btn" @click="RouterUtils.to_page(`/pages/index/gymPay/index?type=1&courseId=${item.id}`)">抢购</view>
 						</view>
 					</view>
 					<view class="card-tips">
-						<view class="item-tips">
+						<view class="item-tips" @click="buyTips(item)">
 							<text>购买须知</text>
 							<zzx-icon name="ashRight" size="10"></zzx-icon>
 						</view>
@@ -132,10 +132,10 @@
 							<text>服务保障</text>
 							<zzx-icon name="ashRight" size="10"></zzx-icon>
 						</view>
-						<view class="item-tips">
+<!-- 						<view class="item-tips">
 							<text>用户评价</text>
 							<zzx-icon name="ashRight" size="10"></zzx-icon>
-						</view>
+						</view> -->
 					</view>
 				</view>
 			</view>
@@ -146,48 +146,54 @@
 				<view class="">全平台每种类型的运动课程只可免费试听一次</view>
 			</view>
 			<view class="select-btn">
-				<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList_btn" :key="index"
-					@click="select_btn(index)">{{item}}</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>
-			<view class="venue-card" v-for="item in 2" @click="toCOurseDetail">
-				<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
-				<view class="venue-info">
-					<view class="info-title">
-						<view class="title textHidden">小班体适能+篮球衔接小班体适能+篮球衔接...</view>
-						<view class="sales">年售20</view>
-					</view>
-					<view class="type">
-						篮球、足球、羽毛球
-					</view>
-					<view class="price">
-						<view class="">¥58.9</view>
-						<view class="">¥80.9</view>
-					</view>
-					<view class="price-info">
-						<view class="sale">
-							已售33 98%好评
+			<block v-if="!courseLoading">
+				<view class="venue-card" v-for="item in courseList" :key="item.id" @click="toCOurseDetail">
+					<image :src="item.cover" mode=""></image>
+					<view class="venue-info">
+						<view class="info-title">
+							<view class="title textHidden">{{item.name}}</view>
+							<view class="sales">年售{{item.salesYear}}</view>
 						</view>
-						<view class="price-btn" @click="RouterUtils.to_page('/pages/index/courseDetail/index?type=2')">免费试听
+						<view class="type">
+							{{item.address}} {{item.km||'--'}}km
+						</view>
+						<view class="price">
+							<view class="">¥{{item.sellingPrice}}</view>
+							<view class="">¥{{item.originalPrice}}</view>
+						</view>
+						<view class="course-count">
+							{{item.period}}课时 {{item.startTime}}-{{item.endTime}}
+						</view>
+						<view class="price-info">
+							<view class="sale">
+								已售{{item.sales}} {{item.goodRate}}%好评
+							</view>
+							<view class="price-btn" @click="RouterUtils.to_page(`/pages/index/courseDetail/index?id=${item.id}&type=2`)">免费试听
+							</view>
 						</view>
 					</view>
 				</view>
-			</view>
-			<!-- <loading/> -->
+			</block>
+			<loading v-else/>
+			<view class="not-data" v-if="courseList.length<1&&!courseLoading">暂无数据</view>
 			<view class="more">查看更多</view>
 		</view>
 		<view class="instructor-card" id="schedule">
-			<view class="card-title">
-				<view class="">教练(9)</view>
+			<view class="card-title"  @click="RouterUtils.to_page('/pages/index/allInstructor/index')">
+				<view class="">教练({{detailInfo.instructorVOList.length}})</view>
 				<zzx-icon name="right" size="12"></zzx-icon>
 			</view>
 			<scroll-view class="header-swiper content" scroll-x="true" :show-scrollbar="false">
 				<view class="swiper-box">
-					<view class="swiper-inner" v-for="item in 12">
+					<view class="swiper-inner" v-for="item in detailInfo.instructorVOList" :key="item.id" @click="RouterUtils.to_page(`/pages/index/instructorDetail/index?id=${item.id}`)">
 						<view class="header-img">
-							<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+							<image :src="item.avatar" mode=""></image>
 							<image src="/src/static/badge.png" mode=""></image>
 						</view>
-						<view class="instructor-name">詹姆斯</view>
+						<view class="instructor-name">{{item.name}}</view>
 						<view class="instructor-specialty">篮球</view>
 					</view>
 				</view>
@@ -229,32 +235,46 @@
 		</view>
 	</view>
 	<view style="position: relative;z-index: 99999;">
-		<selPopup ref="openPopup" />
+		<selPopup :listData="placedata" :itemList="selItems" :deteObj="dateIndex" @change="onchange" ref="openPopup" />
 	</view>
+	<uni-popup ref="placeInfoPopup" :safe-area="false" type="bottom">
+		<view class="buyTips-box">
+			<view class="buyTips-title">购买须知</view>
+			<view class="rich-box" v-if="buyTipsObj">
+				<rich-text :nodes="buyTipsObj.reminder"></rich-text>
+			</view>
+		</view>
+	</uni-popup>
 </template>
 
 <script lang="ts" setup>
-	import { ref, onMounted, getCurrentInstance, nextTick } from 'vue';
+	import { ref, onMounted, getCurrentInstance, nextTick,computed } from 'vue';
 	import { RouterUtils } 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 loading from '@/components/zzx-loading/zzx-loading.vue';
 	import selPopup from './components/popup.vue';
 	const openPopup = ref(null);
+	const placeInfoPopup=ref()
 	const statusBarHeight = ref(0);
 	const sectionTops = ref<number[]>([]);
 	const isScrollingByTab = ref(false);
 	const scrollTimer = ref<any>(null);
 	const selectList = ref(['场地', '课程', '教练', '评价']);
 	const sel_index = ref(0);
-	const selectList_btn = ref(['篮球', '羽毛球', '乒乓球', '网球']);
 	const sel_btn = ref(0);
 	const instance = getCurrentInstance();
+	onLoad((option)=>{
+		listId.value = option.id
+	})
 	onMounted(() => {
 		get_navheight()
 		nextTick(() => {
 			setTimeout(() => getSectionsTop(), 300);
 		});
+		get_placeInfo()
+		get_allCategory()
 	})
 	const get_navheight = () => {
 		const systemInfo = uni.getSystemInfoSync();
@@ -262,7 +282,10 @@
 	}
 
 	// 打开选场弹窗
-	const open_popup = () => {
+	const dateIndex=ref()
+	const open_popup = (e,i) => {
+		dateIndex.value=i
+		get_placeInfoDetail(categoryId.value,i)
 		openPopup.value?.open()
 	}
 
@@ -354,9 +377,96 @@
 	// 拨打电话
 	const open_phone = () => {
 		uni.makePhoneCall({
-			phoneNumber: '028-87776666' //仅为示例
+			phoneNumber: detailInfo.value.phone
+		});
+	}
+	
+	// 详情信息
+	const listId = ref(0);
+	const detailInfo = ref({})
+	const bannerList = ref([])
+	const videoList = ref([])
+	const noTeachingDay=ref()
+	const teachingDay=ref()
+	const get_placeInfo = () => {
+		http.get('/detail/getPlaceInfo', { data: { id: listId.value }, loading: true }).then((res) => {
+			const startIndex = res.result.cover.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(',');
+			detailInfo.value = res.result
+			noTeachingDay.value=JSON.parse(res.result.noTeachingDay)
+			teachingDay.value=JSON.parse(res.result.teachingDay)
+		})
+	}
+	
+	// 课程分类
+	const allCategoryList=ref([])
+	const categoryId=ref()
+	const get_allCategory=()=>{
+		http.get('/detail/getAllCategory', { data: { id: listId.value}}).then((res)=>{
+			categoryId.value=res.result[0].id
+			allCategoryList.value=res.result
+			get_courseList(categoryId.value)
+			get_placeInfoNoFixation(categoryId.value)
+			get_placeInfoDetail(categoryId.value,'')
+		})
+	}
+	
+	// 课程列表
+	const courseList=ref([])
+	const courseLoading=ref(false)
+	const get_courseList=(categoryId)=>{
+		courseLoading.value=true
+		http.get('/detail/courseInfoVOList',{data:{categoryId:categoryId,id:listId.value}}).then((res)=>{
+			courseList.value=res.result
+			courseLoading.value=false
+		})
+	}
+	
+	// 课程切换
+	const selectallCategory=(e,i)=>{
+		sel_btn.value = i
+		get_courseList(e.id)
+	}
+	
+	// 包场切换
+	const selChartered=ref(0)
+	const selectChartered=(e,i)=>{
+		selChartered.value = i
+		get_placeInfoNoFixation(e.id)
+		get_placeInfoDetail(e.id,'')
+	}
+	
+	// 包场信息
+	const charteredList=ref()
+	const get_placeInfoNoFixation=(categoryId)=>{
+		http.get('/detail/getPlaceInfoNoFixation',{data:{categoryId:categoryId,id:listId.value},loading:true}).then((res)=>{
+			charteredList.value=res.result
+		})
+	}
+	
+	const buyTipsObj=ref()
+	const buyTips=(e)=>{
+		placeInfoPopup.value.open()
+		buyTipsObj.value=e
+	}
+	
+	const placedata=ref()
+	const selItems=ref()
+	const get_placeInfoDetail=(catId,dateIndex)=>{
+		http.get('/stadium/getPlaceInfo',{data:{siteId:listId.value ,categoryId:catId}}).then((res)=>{
+			placedata.value=res.result
+			selItems.value=res.result.stadiumConcertsVOList[dateIndex||0].concertsVOList
 		})
 	}
+	
+	const onchange=(e,i)=>{
+		selItems.value=e.concertsVOList
+		dateIndex.value=i
+	}
 </script>
 
 <style lang="less" scoped>
@@ -366,6 +476,7 @@
 		.header-bg {
 			position: absolute;
 			width: 100%;
+			height: 432rpx;
 			z-index: -100;
 		}
 
@@ -415,7 +526,10 @@
 			display: flex;
 			align-items: center;
 			justify-content: space-between;
-
+			.open-status {
+				font-size: 24rpx;
+				color: #4DD951;
+			}
 			.name {
 				font-weight: 800;
 				font-size: 32rpx;
@@ -432,22 +546,13 @@
 		}
 
 		.open-time {
-			display: flex;
-			align-items: center;
-			gap: 20rpx;
 			margin-top: 20rpx;
-
-			.open-status {
-				font-size: 24rpx;
-				color: #4DD951;
-			}
-
 			.time {
-				display: flex;
-				align-items: center;
-				gap: 20rpx;
 				font-size: 24rpx;
 				color: #AAAAAA;
+				&>view{
+					margin-top: 20rpx;
+				}
 			}
 		}
 
@@ -887,6 +992,10 @@
 						text-decoration: line-through;
 					}
 				}
+				.course-count{
+					font-size: 22rpx;
+					color: #AAAAAA;
+				}
 
 				.price-info {
 					display: flex;
@@ -1110,4 +1219,19 @@
 			}
 		}
 	}
+	.buyTips-box{
+		background: #F6F6F6;
+		border-radius: 32rpx 32rpx 0rpx 0rpx;
+		max-height: 1200rpx;
+		overflow: auto;
+		padding: 20rpx;
+		.buyTips-title{
+			text-align: center;
+			font-size: 28rpx;
+			font-weight: bold;
+		}
+		.rich-box{
+			margin-top: 20rpx;
+		}
+	}
 </style>

+ 151 - 53
src/pages/index/gymPay/index.vue

@@ -1,17 +1,17 @@
 <template>
+	<!-- 不同类型进入的type(1:学校课程;2:体育馆课程;3:教练课程) -->
 	<view class="content">
 		<view class="g-orderinfo-card">
 			<view class="g-shoping-info">
-				<image class="shoping-img" src="https://img.shetu66.com/2023/06/13/1686646672844195.jpg" mode="">
-				</image>
+				<image class="shoping-img" :src="previewCourseInfo.cover" mode=""></image>
 				<view class="shoping-info">
-					<view class="name">一对一篮球30分钟室内精品课程,一对一篮球30分</view>
+					<view class="name">{{previewCourseInfo.name}}</view>
 					<view class="price-info">
-						<view class="price"><text class="mini-text">¥</text>25.9</view>
+						<view class="price"><text class="mini-text">¥</text>{{previewCourseInfo.sellingPrice}}</view>
 						<view class="price-stepper">
-							<view class="minus">-</view>
-							<input type="number" />
-							<view class="add">+</view>
+							<view class="minus" @click="minusNum">-</view>
+							<input v-model="countTotal" disabled type="number" />
+							<view class="add" @click="addNum">+</view>
 						</view>
 					</view>
 				</view>
@@ -19,17 +19,20 @@
 			<view class="g-shoping-total">
 				<view class="total-price">
 					<view class="">商品总价(共1件)</view>
-					<view class="">¥25.9</view>
+					<view class="">¥{{previewCourseInfo.sellingPrice}}</view>
 				</view>
 				<view class="total-price">
-					<view class="">团购优惠</view>
-					<view class="">-¥25.90</view>
+					<view class="">
+						<text v-if="loadType==1||loadType==2">试听优惠</text>
+						<text v-if="loadType==3">团购优惠</text>
+					</view>
+					<view class="">-¥{{previewCourseInfo.discountPrice}}</view>
 				</view>
 			</view>
-			<view class="subtotal">小计 ¥125</view>
+			<view class="subtotal">小计 ¥{{previewCourseInfo.subtotal}}</view>
 		</view>
 		<!-- 无固定场进入 -->
-		<view class="g-buy-tips" v-if="loadType==1">
+		<view class="g-buy-tips" v-if="loadType==4">
 			<view class="tips-title">购买须知</view>
 			<view class="tips-info-card">
 				<view class="title">有效期</view>
@@ -46,7 +49,8 @@
 			</view>
 		</view>
 		<!-- 课程进入 -->
-		<view class="g-insurance-card" v-if="loadType==2">
+		 <!-- v-if="loadType==1||loadType==3" -->
+		<view class="g-insurance-card">
 			<view class="g-insurance-info">
 				<view class="insurance-type">
 					<view class="type-name">
@@ -68,6 +72,7 @@
 				<view class="price">¥6</view>
 			</view>
 		</view>
+		  <!-- v-if="loadType==1||loadType==3" -->
 		<view class="g-userinfo-card">
 			<view class="r-user">
 				<view class="user-title">用户信息</view>
@@ -75,27 +80,29 @@
 					<zzx-icon name="wechat" size="16"></zzx-icon>
 					<view style="margin-bottom: 8rpx;">邀请微信好友</view>
 					<zzx-icon name="ashRight" size="12"></zzx-icon>
+					<button class="g-share-btn" open-type="share"></button>
 				</view>
 			</view>
-			<view class="user-tags">张三</view>
-			<view class="r-user-list" v-for="item in 2">
-				<view class="minus-user">-</view>
+			<!-- <view class="user-tags">张三</view> -->
+			<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">张三</view>
-					<view class="id-num">身份证 51**************10</view>
+					<view class="name">{{item.fullName}}</view>
+					<view class="id-num">身份证 {{idCardHide(item.identityCard)}}</view>
 				</view>
 			</view>
-			<view class="g-adduser-btn">
+			<view class="g-adduser-btn" @click="toUserList">
 				<view class="add-icon">+</view>
 				<view class="add-text">添加用户</view>
 			</view>
 		</view>
+		  <!-- v-if="loadType==1" -->
 		<view class="g-usetips-card">
 			<view class="use-title">使用须知</view>
 			<view class="use-text">
-				<view class="item-text">1.购买后,需按照课表按时上课;</view>
-				<view class="item-text">2.如有特殊情况,需上传相关证明;</view>
-				<view class="item-text">3.由于特殊情况耽误了课程,后续会发布补课表,集中补课</view>
+				<view class="item-text">
+					<rich-text :nodes="previewCourseInfo.reminder"></rich-text>
+				</view>
 			</view>
 			<view class="use-tips-more" @click="RouterUtils.to_page('/pages/index/useNotice/index')">
 				<view class="more-text">查看更多</view>
@@ -106,12 +113,12 @@
 		<view class="footer footer-box">
 			<view class="footer-price">
 				<view class="total-price">合计:</view>
-				<view class="price"><text class="mini-text">¥</text>50.59</view>
-				<view class="discount">优惠¥22.59</view>
+				<view class="price"><text class="mini-text">¥</text>{{previewCourseInfo.totalPrice}}</view>
+				<view class="discount">优惠¥{{previewCourseInfo.totalDiscount}}</view>
 			</view>
 			<view class="footer-btn" @click="to_pay">
 				<button>
-					<view class="btn-price">¥57.8</view>
+					<view class="btn-price">¥{{previewCourseInfo.totalPrice}}</view>
 					<view class="btn-price">立即支付</view>
 				</button>
 			</view>
@@ -120,19 +127,83 @@
 </template>
 
 <script lang="ts" setup>
-	import { ref } from 'vue';
+	import { ref, onMounted,computed } from 'vue';
 	import { onLoad, onPageScroll } from '@dcloudio/uni-app';
-	import { RouterUtils } from '@/utils/util';
+	import { RouterUtils, TipsUtils,idCardHide } from '@/utils/util';
+	import { http } from '@/utils/http'
 	const select_insurance = ref(false);
-	const loadType=ref(1)
-	onLoad((options)=>{
-		loadType.value=options.type
-		
+	const loadType = ref(1)
+	onLoad((options) => {
+		console.log(options);
+		loadType.value = options.type
+		courseId.value = options.courseId
+	})
+	onMounted(() => {
+		get_previewOrderCourse()
+		get_userData()
 	})
 	
-	const to_pay=()=>{
+	
+	const to_pay = () => {
 		uni.navigateTo({
-			url:'/pages/index/cancelOrder/index'
+			url: '/pages/index/toBeUsed/index'
+		})
+	}
+	
+	const toUserList = () => {
+		RouterUtils.to_page('/pages/index/userList/index')
+	}
+	
+	const userData=ref()
+	const get_userData=()=>{
+		uni.$on('userData',function(data){
+			userData.value=data
+		})
+	}
+	
+	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 courseId = ref()
+	const previewCourseInfo = ref()
+	const get_previewOrderCourse = () => {
+		http.get('/order/previewOrderCourse', { data: { courseId: courseId.value }, loading: true }).then((res) => {
+			previewCourseInfo.value = res.result
+		})
+	}
+
+	const countTotal = ref(1)
+	const minusNum = () => {
+		if (countTotal.value > 1) {
+			countTotal.value--
+		}
+	}
+	
+	// const subtotal=computed(()=>{
+	// 	return (previewCourseInfo.value.subtotal*countTotal.value).toFixed(2)-previewCourseInfo.value.
+	// })
+
+	const addNum = () => {
+		get_checkCourseLimitNum(countTotal.value + 1)
+	}
+	
+	const get_checkCourseLimitNum = (targetNum) => {
+		http.get('/order/checkCourseLimitNum', {
+			data: {
+				courseId: courseId.value,
+				limitNum: targetNum
+			},
+			loading: true
+		}).then((res) => {
+			if (res.result === true) {
+				countTotal.value = targetNum
+			} else {
+				TipsUtils.tips_toast('超出可购数量')
+			}
 		})
 	}
 </script>
@@ -193,6 +264,7 @@
 							width: 80rpx;
 							font-size: 28rpx;
 							color: #222222;
+							text-align: center;
 						}
 
 						.add {
@@ -340,29 +412,40 @@
 		}
 	}
 
-	.g-userinfo-card{
+	.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;
 			}
-			.invite{
+
+			.invite {
 				display: flex;
 				align-items: center;
 				gap: 8rpx;
 				font-size: 24rpx;
 				color: #AAAAAA;
+				position: relative;
+				.g-share-btn{
+					position: absolute;
+					width: 200rpx;
+					height: 60rpx;
+					opacity: 0;
+				}
 			}
 		}
-		.user-tags{
+
+		.user-tags {
 			margin-top: 20rpx;
 			width: 112rpx;
 			height: 40rpx;
@@ -376,85 +459,99 @@
 			font-size: 28rpx;
 			color: #222222;
 		}
-		.r-user-list{
+
+		.r-user-list {
 			margin-top: 20rpx;
 			display: flex;
 			align-items: center;
 			gap: 20rpx;
 			border-top: 1rpx solid #F0F0F0;
 			height: 140rpx;
-			.minus-user{
+
+			.minus-user {
 				width: 30rpx;
 				height: 30rpx;
 				border-radius: 50%;
 				background: #FB5B5B;
 				text-align: center;
-				line-height:20rpx;
+				line-height: 20rpx;
 				font-weight: 600;
 				color: #fff;
 				font-size: 40rpx;
 			}
-			.r-list{
-				.name{
+
+			.r-list {
+				.name {
 					font-weight: bold;
 					font-size: 28rpx;
 					color: #222222;
 				}
-				.id-num{
+
+				.id-num {
 					font-size: 28rpx;
 					color: #222222;
 				}
 			}
 		}
-		.g-adduser-btn{
+
+		.g-adduser-btn {
 			display: flex;
 			height: 88rpx;
 			align-items: center;
 			justify-content: center;
 			gap: 20rpx;
 			border-top: 1rpx solid #F0F0F0;
-			.add-icon{
+
+			.add-icon {
 				width: 30rpx;
 				height: 30rpx;
 				border-radius: 50%;
 				background: #FDD143;
-				font-size:30rpx;
+				font-size: 30rpx;
 				font-weight: 600;
 				color: #fff;
 				text-align: center;
 				line-height: 20rpx;
 			}
-			.add-text{
+
+			.add-text {
 				font-size: 28rpx;
 				color: #FDD143;
 			}
 		}
 	}
-	.g-usetips-card{
+
+	.g-usetips-card {
 		margin-top: 20rpx;
 		padding: 20rpx;
 		background: #FFFFFF;
 		border-radius: 32rpx;
-		.use-title{
+
+		.use-title {
 			font-weight: bold;
 			font-size: 28rpx;
 			color: #222222;
 		}
-		.use-text{
+
+		.use-text {
 			font-size: 24rpx;
 			color: #222222;
-			.item-text{
+
+			.item-text {
 				margin-top: 20rpx;
 			}
 		}
-		.use-tips-more{
+
+		.use-tips-more {
 			margin-top: 20rpx;
-			.more-text{
+
+			.more-text {
 				text-align: center;
 				font-size: 24rpx;
 				color: #CCCCCC;
 			}
-			.use-line{
+
+			.use-line {
 				margin: auto;
 				margin-top: 10rpx;
 				width: 38rpx;
@@ -464,6 +561,7 @@
 			}
 		}
 	}
+
 	.footer {
 		left: 0;
 

+ 60 - 39
src/pages/index/index.vue

@@ -1,9 +1,9 @@
 <template>
 	<view class="nav-title"
 		:style="{height:navBarHeight+'px',opacity: navOpacity,transition: 'opacity 0.3s ease-in-out',background: backgroundColor }">
-		<view class="back-icon" :style="{paddingTop:statusBarHeight+'px'}">
+		<view class="back-icon" :style="{paddingTop:statusBarHeight+'px'}" @click="openSellocation">
 			<zzx-icon name="location" size="13"></zzx-icon>
-			<view class="location-text">富力中心A7</view>
+			<view class="location-text textHidden">{{addressName}}</view>
 			<zzx-icon name="right" size="10"></zzx-icon>
 		</view>
 	</view>
@@ -12,14 +12,15 @@
 		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" v-if="navOpacity==0"
 			@click="openSellocation">
 			<zzx-icon name="location" size="13"></zzx-icon>
-			<view class="location-text">富力中心A7</view>
+			<view class="location-text textHidden">{{addressName}}</view>
 			<zzx-icon name="right" size="10"></zzx-icon>
 		</view>
 		<view class="content" style="padding-top:180rpx;">
 			<view class="header-search">
-				<zzx-icon name="search" size="16"></zzx-icon>
-				<swiper class="i-search-swiper" :vertical="true" :circular="true" :autoplay="true" :interval="5000" :duration="1000" @click="gotoPage('/pages/index/search/index')" @change="transitionChange">
-					<swiper-item  v-for="(item,index) in searchList" :key="item.id">
+				<zzx-icon name="search" size="18"></zzx-icon>
+				<swiper class="i-search-swiper" :vertical="true" :circular="true" :autoplay="true" :interval="5000"
+					:duration="1000" @click="gotoPage('/pages/index/search/index')" @change="transitionChange">
+					<swiper-item v-for="(item,index) in searchList" :key="item.id">
 						<view class="">{{item.searchContent}}</view>
 					</swiper-item>
 				</swiper>
@@ -76,7 +77,7 @@
 		</view>
 		<zs-loading v-if="indexLoading"></zs-loading>
 		<view class="course-card" v-else>
-			<view class="commonweal" @click="gotoPage('/pages/index/training/index')">
+			<view class="commonweal" @click="gotoPage(`/pages/index/training/index?priceType=1`)">
 				<view class="commonweal-title">
 					<view class="title-left">
 						<image src="/src/static/gy-icon.png" mode=""></image>
@@ -91,7 +92,7 @@
 					</view>
 				</view>
 			</view>
-			<view class="audition" @click="gotoPage('/pages/index/training/index')">
+			<view class="audition" @click="gotoPage(`/pages/index/training/index?priceType=0`)">
 				<view class="audition-title">
 					<view class="title-left">
 						<image src="/src/static/st-icon.png" mode=""></image>
@@ -169,7 +170,8 @@
 						</view>
 						<view class="num">已售{{item.count||'0'}}</view>
 					</view>
-					<view class="more">更多课程</view>
+					<view class="more" @click="gotoPage(`/pages/index/instructorDetail/index?id=${item.id}`)">更多课程
+					</view>
 				</view>
 			</view>
 		</view>
@@ -184,7 +186,7 @@
 	import zzxNavbar from '@/components/zzx-navbar/zzx-navbar.vue';
 	import zsLoading from '@/components/zzx-loading/zzx-loading.vue'
 	import { ref, onMounted, computed } from 'vue'
-	import { onShow, onPageScroll } from '@dcloudio/uni-app';
+	import { onShow,onLoad, onPageScroll, onPullDownRefresh } from '@dcloudio/uni-app';
 	import { RouterUtils, TipsUtils } from '@/utils/util';
 	import { http } from '@/utils/http'
 	import { useCacheStore } from '@/stores/cache'
@@ -198,9 +200,14 @@
 	const navOpacity = ref(0);
 	const backgroundColor = ref('#D2FD73');
 	const instructorList = ref();
-	onShow(() => {
+	onLoad(() => {
 		get_location()
 	})
+	onPullDownRefresh(() => {
+		get_indexInfo()
+		get_message()
+		get_searchList()
+	})
 	onMounted(() => {
 		get_navheight()
 		get_indexInfo()
@@ -254,22 +261,27 @@
 			get_indexInfo()
 			get_message()
 			get_searchList()
+			get_userinfo()
 			TipsUtils.tips_toast('登录成功')
 		})
 	}
 
+	const get_userinfo = () => {
+		http.get('/user/getUserInfo', { loading: true }).then(res => {
+			cache.set('USER_INFO', res.result)
+		})
+	}
+
 	const get_location = () => {
 		uni.authorize({
 			scope: 'scope.userLocation',
 			success() {
 				uni.getLocation({
-					type: 'wgs84',
+					type: 'gcj02',
 					success: function (res) {
 						uni.hideLoading()
 						cache.set('LON', res.longitude)
 						cache.set('LAT', res.latitude)
-						// console.log('当前位置的经度:' + res.longitude);
-						// console.log('当前位置的纬度:' + res.latitude);
 					},
 					fail: function (err) {
 						if (err.errMsg === 'getFuzzyLocation:fail system permission denied') {
@@ -298,13 +310,13 @@
 	}
 
 	// 手动选择
+	const addressName = ref('选择定位')
 	const openSellocation = () => {
 		uni.chooseLocation({
 			success: function (res) {
-				console.log('位置名称:' + res.name);
-				console.log('详细地址:' + res.address);
-				console.log('纬度:' + res.latitude);
-				console.log('经度:' + res.longitude);
+				addressName.value = res.name
+				cache.set('LON', res.longitude)
+				cache.set('LAT', res.latitude)
 			},
 			fail(res) {
 				console.log(res);
@@ -316,14 +328,15 @@
 	// 首页基础信息
 	const gyCourseList = ref()
 	const stCourseList = ref()
-	const indexLoading=ref(true)
+	const indexLoading = ref(true)
 	const get_indexInfo = () => {
 		http.get('/home/homeInfo').then((res) => {
-			indexLoading.value=false
+			indexLoading.value = false
 			bannerList.value = res.result.bannerList
 			gyCourseList.value = res.result.courseList.filter(item => item.priceType === 0)
 			stCourseList.value = res.result.courseList.filter(item => item.priceType === 1)
 			instructorList.value = res.result.instructorList
+			uni.stopPullDownRefresh()
 		})
 	}
 
@@ -334,29 +347,29 @@
 			indexMsg.value = res.result
 		})
 	}
-	
+
 	// 搜索相关
-	const searchList=ref([])
-	const get_searchList=()=>{
-		http.get('/home/getHotSearch').then((res)=>{
-			searchList.value=res.result
+	const searchList = ref([])
+	const get_searchList = () => {
+		http.get('/home/getHotSearch').then((res) => {
+			searchList.value = res.result
 		})
 	}
-	const searchCurrent=ref()
-	const transitionChange=(e)=>{
-		searchCurrent.value=e.detail.current
+	const searchCurrent = ref()
+	const transitionChange = (e) => {
+		searchCurrent.value = e.detail.current
 	}
-	const searchInfoBtn=()=>{
-		if(searchList.value<1) return TipsUtils.tips_toast('请输入关键词')
-		let keyword=''
-		let venueType=null
-		if(searchList.value.length>1){
-			keyword=searchList.value[searchCurrent.value].searchContent
-			venueType=searchList.value[searchCurrent.value].venueType
-		}else{
-			searchList.value.map((item)=>{
-				keyword=item.searchContent
-				venueType=item.venueType
+	const searchInfoBtn = () => {
+		if (searchList.value < 1) return TipsUtils.tips_toast('请输入关键词')
+		let keyword = ''
+		let venueType = null
+		if (searchList.value.length > 1) {
+			keyword = searchList.value[searchCurrent.value].searchContent
+			venueType = searchList.value[searchCurrent.value].venueType
+		} else {
+			searchList.value.map((item) => {
+				keyword = item.searchContent
+				venueType = item.venueType
 			})
 		}
 		gotoPage(`/pages/index/searchPage/index?keyword=${keyword}&venueType=${venueType}`)
@@ -384,6 +397,10 @@
 			font-weight: 800;
 			font-size: 28rpx;
 			color: #222222;
+
+			.location-text {
+				max-width: 460rpx;
+			}
 		}
 	}
 
@@ -406,6 +423,10 @@
 			font-weight: 800;
 			font-size: 28rpx;
 			color: #222222;
+
+			.location-text {
+				max-width: 460rpx;
+			}
 		}
 
 		.header-search {

+ 37 - 24
src/pages/index/instructorDetail/index.vue

@@ -1,9 +1,7 @@
 <template>
 	<zzx-navbar :scrollable="true" :back="true" title="详情"></zzx-navbar>
 	<view class="detail-header">
-		<image class="header-bg"
-			src="https://ts1.tc.mm.bing.net/th/id/R-C.a8553f142638e741396e386b43c2bca7?rik=dzSGk6XRsxAAsQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50062%2f5890.jpg_wh1200.jpg&ehk=BgxiqxvzoNQd0pZHWV4VPOMbYgqM76WDMt8RDzCjoYY%3d&risl=&pid=ImgRaw&r=0"
-			mode="widthFix"></image>
+		<image class="header-bg" :src="detailObj.backgroundImg" mode="widthFix"></image>
 		<view class="back-icon" :style="{paddingTop:(statusBarHeight+10)+'px'}" @click="RouterUtils.back()">
 			<zzx-icon name="back"></zzx-icon>
 		</view>
@@ -13,40 +11,39 @@
 		<view class="i-info-card">
 			<view class="i-userinfo">
 				<view class="user-header">
-					<image class="header-img" src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+					<image class="header-img" :src="detailObj.avatar" mode=""></image>
 					<image class="header-badge" src="/src/static/badge.png" mode=""></image>
 				</view>
 				<view style="width: 220rpx;"></view>
 				<view class="user-name">
 					<view class="name-box">
-						<view class="name">詹姆四</view>
-						<view class="type">篮球</view>
+						<view class="name">{{detailObj.realname}}</view>
+						<view class="type">{{detailObj.trainingProgramsName}}</view>
 					</view>
 					<view class="sign" @click="to_certifying">
-						<text class="textHidden">已实名,无犯罪记录,健康证,足球裁判...</text>
+						<text class="textHidden">{{detailObj.headDisplay}}</text>
 						<zzx-icon name="ashRight" size="12"></zzx-icon>
 					</view>
 				</view>
 			</view>
 			<view class="i-sign">
-				运动执教,点燃每一个篮球梦
+				{{detailObj.teachingPhilosophy}}
 			</view>
 			<view class="i-skill">
-				擅长:体适能、足球、其他运动培训。体适能、足球、其他
-				运动培训。体适能、足球、其他运动培训。
+				{{detailObj.excelMsg}}
 			</view>
 			<view class="i-data-card">
 				<view class="item-data">
 					<view class="text">好评率</view>
-					<view class="num">99%</view>
+					<view class="num">{{detailObj.goodRate}}%</view>
 				</view>
 				<view class="item-data">
-					<view class="text">订单</view>
+					<view class="text">订单</view>
 					<view class="num">1659</view>
 				</view>
 				<view class="item-data">
 					<view class="text">授课人数</view>
-					<view class="num">9568</view>
+					<view class="num">{{detailObj.classesNumber||'0'}}</view>
 				</view>
 			</view>
 		</view>
@@ -57,26 +54,27 @@
 					<view class="tips-icon">!</view>
 					<view class="tips-text">全平台每种类型的运动课程只可免费试听一次</view>
 				</view>
-				<view class="card-list" v-for="item in 4">
-					<image class="card-img" src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+				<view class="card-list" v-for="item in detailObj.courseInfoVOList" :key="item.id">
+					<image class="card-img" :src="item.cover" mode=""></image>
 					<view class="i-list">
 						<view class="list-name">
-							<view class="name textHidden">1对1篮球30分钟室内钟室内</view>
-							<view class="num">年售20</view>
+							<view class="name textHidden">{{item.name}}</view>
+							<view class="num">年售{{item.annualSalesNum}}</view>
 						</view>
-						<view class="address">上课地点:观山湖区第十二小学 | 2.2km</view>
+						<view class="address">上课地点:{{item.address}} | {{item.km}}km</view>
 						<view class="list-price">
-							<view class="left-price">¥58.9</view>
-							<view class="right-price">¥80.9</view>
+							<view class="left-price">¥{{item.sellingPrice}}</view>
+							<view class="right-price">¥{{item.originalPrice}}</view>
 						</view>
-						<view class="sale-data">已售33 98%好评</view>
+						<view class="sale-data">已售{{item.saleNum}} {{item.goodRate}}%好评</view>
 						<view class="course-num">
-							<view class="number">6课时 05.28-08.18</view>
-							<view class="i-btn">抢购</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>
 		</view>
 		<view class="appraise-card">
@@ -119,11 +117,18 @@
 <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
+	})
 	onMounted(() => {
 		get_navheight()
+		get_findByCoachId()
 	})
 	const get_navheight = () => {
 		const systemInfo = uni.getSystemInfoSync();
@@ -132,7 +137,15 @@
 	
 	const to_certifying=()=>{
 		uni.navigateTo({
-			url:'/pages/index/certifyingDetail/index'
+			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
 		})
 	}
 </script>

+ 23 - 0
src/pages/index/mapPage/index.vue

@@ -0,0 +1,23 @@
+<template>
+	<view class="map-box">
+		<map @click="openMap"></map>
+	</view>
+</template>
+
+<script lang="ts" setup>
+	import { ref, onMounted } from 'vue';
+	const openMap=()=>{
+		uni.openLocation({
+			latitude: 39.909,
+			longitude: 116.39742,
+			name: 'Tencent Building',
+			address: '北京市海淀区西二旗大街27号',
+			success: function () {
+				console.log('success');
+			}
+		});
+	}
+</script>
+
+<style>
+</style>

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

@@ -1,7 +1,7 @@
 <template>
 	<view class="content">
 		<view class="header-search">
-			<zzx-icon name="search" size="16"></zzx-icon>
+			<zzx-icon name="search" size="18"></zzx-icon>
 			<input type="text" v-model="searchText" placeholder="搜索俱乐部名称" />
 			<view class="search-btn" @click="to_search">
 				搜索
@@ -45,7 +45,6 @@
 		if (historyList.value.length > 20) {
 			historyList.value.pop(); // 移除最后一条
 		}
-		//保存到缓存
 		cache.set('SEARCH_INFO', historyList.value);
 		RouterUtils.to_page(`/pages/index/searchPage/index?keyword=${keyword}`)
 		searchText.value = '';
@@ -80,6 +79,7 @@
 			width: 670rpx;
 			font-weight: bold;
 			font-size: 24rpx;
+			margin-bottom: 8rpx;
 		}
 
 		.search-btn {

+ 1 - 1
src/pages/index/searchPage/components/events.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="e-card-list" v-for="item in listData" :key="item.id	">
+	<view class="e-card-list" v-for="item in listData" :key="item.id">
 		<view class="e-events-info">
 			<view class="e-picture">
 				<image class="pic" :src="item.cover" mode=""></image>

+ 5 - 3
src/pages/index/searchPage/index.vue

@@ -22,7 +22,8 @@
 		<view class="s-search-list"  v-if="!searchLoading">
 			<!-- 场地 -->
 			<view v-if="sel_index==0">
-				<view class="s-venue-card" v-for="(venue,index) in searchList" :key="venue.id">
+				<!-- pages/index/gymDetail/index -->
+				<view class="s-venue-card" v-for="(venue,index) in searchList" :key="venue.id" @click="RouterUtils.to_page(`/pages/index/gymDetail/index`)">
 					<view class="s-venue-info">
 						<view class="venue-img">
 							<image :src="venue.cover" mode=""></image>
@@ -93,13 +94,14 @@
 	import { ref, onMounted } from 'vue';
 	import { onLoad,onReachBottom } from '@dcloudio/uni-app';
 	import { http } from '@/utils/http'
+	import {RouterUtils} from '@/utils/util'
 	import { useCacheStore } from '@/stores/cache'
 	import events from './components/events.vue'
 	import instructor from './components/instructor.vue'
 	import zsEmpty from '@/components/zs-empty/index.vue'
 	import zsLoading from '@/components/zzx-loading/zzx-loading.vue'
 	const cache = useCacheStore()
-	const selectList = ref(['距离', '好评'])
+	const selectList = ref()
 	const sel_index = ref(0);
 	const sel_btn = ref(0);
 	const keyword = ref();
@@ -160,7 +162,7 @@
 	
 	const searchLoading=ref(true)
 	const current=ref(1)
-	const get_searchInfo = (tagsVal=ref()) => {
+	const get_searchInfo = (tagsVal) => {
 		http.post('/home/search', { keyword: keyword.value, size: 10, current:current.value, venueType:String(tagsVal), longitude: cache.get('LON'), latitude: cache.get('LAT') }).then((res) => {
 			searchLoading.value=false
 			if(current.value==1){

+ 114 - 27
src/pages/index/submitOrder/index.vue

@@ -1,30 +1,34 @@
 <template>
 	<view class="s-header-card">
 		<zzx-icon name="location" size="14"></zzx-icon>
-		<text>观山湖区第十二小学</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="item-card" v-for="item in 3" @click="open_calendar">
-						<view class="day">今天</view>
-						<view class="date">04.23</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()">
+					更多日期
+				</view>
 			</view>
 		</view>
 		<view class="s-selecttime-card">
 			<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 8" @click="check_item(index)">
-						<view class="time">06:00-08:00</view>
-						<view class="allowance">余82</view>
-						<view class="price">¥95</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}}</view>
 					</view>
 				</scroll-view>
+				<view class="not-data" v-if="timeList.timeSlot.length<1">暂无可选时段</view>
 			</view>
 		</view>
 		<view class="g-insurance-card">
@@ -58,12 +62,12 @@
 					<zzx-icon name="ashRight" size="12"></zzx-icon>
 				</view>
 			</view>
-			<view class="user-tags">张三</view>
-			<view class="r-user-list" v-for="item in 2">
-				<view class="minus-user">-</view>
+			<!-- <view class="user-tags">张三</view> -->
+			<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">张三</view>
-					<view class="id-num">身份证 51**************10</view>
+					<view class="name">{{item.fullName}}</view>
+					<view class="id-num">身份证 {{idCardHide(item.identityCard)}}</view>
 				</view>
 			</view>
 			<view class="g-adduser-btn" @click="toUserList">
@@ -71,30 +75,89 @@
 				<view class="add-text">添加用户</view>
 			</view>
 		</view>
-		<view class="submit-btn">免费 立即预约</view>
+		<view class="submit-btn" @click="submitBooking">免费 立即预约</view>
 	</view>
-	<uni-calendar ref="calendar" :insert="false" @confirm="confirm" />
+	<uni-calendar ref="calendar" :insert="false" :date="selectInsurance" @confirm="confirm" />
 </template>
 
 <script lang="ts" setup>
-	import { ref } from 'vue';
-	import { RouterUtils } from '@/utils/util';
+	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)
+	const check_index=ref(0);
+	onLoad((option)=>{
+		placeId.value=option.id
+	})
+	onMounted(()=>{
+		get_previewTIme()
+		get_userData()
+	})
 	const toUserList = () => {
 		RouterUtils.to_page('/pages/index/userList/index')
 	}
 	
-	const open_calendar=()=>{
-		calendar.value.open()
+	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)=>{
-		console.log(e);
+		get_previewOrderPlaceSchool(e.fulldate)
 	}
-	
-	const check_item=(i)=>{
+	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 userData=ref([])
+	const get_userData=()=>{
+		uni.$on('userData',function(data){
+			userData.value=data
+		})
+	}
+	
+	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')
+		})
 	}
 </script>
 
@@ -124,11 +187,30 @@
 
 		.select-card-list {
 			margin-top: 20rpx;
-
+			display: flex;
+			align-items: center;
 			.scroll-view_H {
 				white-space: nowrap;
-				width: 100%;
-
+				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 {
 					margin-right: 16rpx;
 					display: inline-block;
@@ -139,7 +221,6 @@
 					font-size: 24rpx;
 					color: #222222;
 					text-align: center;
-
 					.day {
 						padding-top: 20rpx;
 					}
@@ -149,6 +230,12 @@
 					}
 				}
 			}
+			.more-date{
+				width: 200rpx;
+				font-size: 24rpx;
+				color: #FDD143;
+				text-align: center;
+			}
 		}
 	}
 

+ 42 - 2
src/pages/index/toBeUsed/index.vue

@@ -158,9 +158,18 @@
 			</view>
 		</view>
 		<view class="t-use-card">
-			<view class="use-tips">
+			<view class="use-tips t-contract-list">
 				<view class="title">电子合同</view>
-				<view class="text">该电子合同具有法律效力</view>
+				<view class="text contract-list">
+					<view class="item-no-sign">
+						<view class="sign-title">未签署:</view>
+						<view class="sign-name">张三</view>
+					</view>
+					<view class="item-sign">
+						<view class="sign-title">已签署:</view>
+						<view class="sign-name">李四</view>
+					</view>
+				</view>
 			</view>
 			<view class="check-all">
 				<text>查看详情</text>
@@ -709,6 +718,37 @@
 				color: #AAAAAA;
 			}
 		}
+		.t-contract-list{
+			.contract-list{
+				.item-no-sign{
+					display: flex;
+					align-items: center;
+					gap: 20rpx;
+					.sign-title{}
+					.sign-name{
+						padding: 4rpx 10rpx 4rpx 10rpx;
+						border-radius: 8rpx;
+						background: #F6F6F6;
+						font-size: 24rpx;
+						color: #AAAAAA;
+					}
+				}
+				.item-sign{
+					display: flex;
+					align-items: center;
+					gap: 20rpx;
+					margin-top: 20rpx;
+					.sign-title{}
+					.sign-name{
+						padding: 4rpx 10rpx 4rpx 10rpx;
+						border-radius: 8rpx;
+						background: #FDD143;
+						font-size: 24rpx;
+						color:#222222;
+					}
+				}
+			}
+		}
 
 		.check-all {
 			display: flex;

+ 149 - 43
src/pages/index/training/index.vue

@@ -8,44 +8,136 @@
 	<view style="height: 70rpx;"></view>
 	<view class="content">
 		<view class="select-btn">
-			<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList" :key="index" @click="select_btn(index)">{{item}}</view>
+			<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList" :key="index"
+				@click="select_btn(item,index)">{{item.text}}</view>
 		</view>
-		<view class="t-card-list" v-for="item in 3">
-			<view class="t-courseImg">
-				<image src="https://img95.699pic.com/photo/60010/7623.jpg_wh860.jpg" mode=""></image>
-			</view>
-			<view class="t-course">
-				<view class="c-title textHidden">1对1篮球30分钟室内精品30分钟室内精品</view>
-				<view class="c-address">上课地点观山湖区万达广场 | 2.2km</view>
-				<view class="c-price">¥25.9</view>
-				<view class="c-ratio">已售37  98%好评</view>
-				<view class="c-class">6课时 05.06-05.11</view>
-				<view class="c-icon">
-					<image src="/src/static/snapped.png" mode="widthFix"></image>
+		<block v-if="courseList.length>1">
+			<view class="t-card-list" v-for="item in courseList" :key="item.id" @click="RouterUtils.to_page(`/pages/index/courseDetail/index?id=${item.id}`)">
+				<view class="t-courseImg">
+					<image :src="item.cover" mode=""></image>
+				</view>
+				<view class="t-course">
+					<view class="c-title textHidden">{{item.name}}</view>
+					<view class="c-address" v-if="item.km">{{item.address}} | {{item.km.toFixed(2)}}km</view>
+					<view class="c-price">¥25.9
+						<text v-if="item.priceType==0"
+							style="font-size: 22rpx;color: #AAAAAA;text-decoration: line-through;">¥23.2</text>
+					</view>
+					<view class="c-ratio">已售{{item.saleNum||'0'}} {{item.goodRate}}%好评</view>
+					<view class="c-class">{{item.coursesNum}}课时 {{item.startTime}}-{{item.endTime}}</view>
+					<view class="c-icon">
+						<image v-if="item.priceType==1" src="/src/static/snapped.png" mode="widthFix"></image>
+						<block v-else>
+							<image v-if="item.isOneBuy" src="/src/static/snapped1.png" mode="widthFix"></image>
+							<image v-else src="/src/static/qinggou.png" mode="widthFix"></image>
+						</block>
+					</view>
 				</view>
 			</view>
-		</view>
+		</block>
+		<zs-empty v-else></zs-empty>
 	</view>
 </template>
 
 <script lang="ts" setup>
-	import { ref } from 'vue'
+	import { ref, onMounted, computed } from 'vue'
+	import { onLoad, onReachBottom } from '@dcloudio/uni-app'
+	import { http } from '@/utils/http'
+	import { useCacheStore } from '@/stores/cache'
+	import { RouterUtils } from '@/utils/util';
+	import zsEmpty from '@/components/zs-empty/index.vue'
+	const cache = useCacheStore()
 	const navbarList = ref([{
 		text: '全部'
 	}, {
-		text: '学校'
+		text: '免费课'
 	}, {
-		text: '体育馆'
+		text: '精品课'
 	}]);
-	const selectList=ref(['距离','好评','销量'])
+	// 132
+	const selectList = ref([{
+		text: '距离',
+		type: 1
+	}, {
+		text: '好评',
+		type: 3
+	}, {
+		text: '销量',
+		type: 2
+	}])
 	const sel_index = ref(0);
-	const sel_btn=ref(0);
-	
-	const select_btn=(i)=>{
-		sel_btn.value=i
+	const sel_btn = ref(0);
+	onLoad((option)=>{
+		priceType.value=option.priceType
+		if(option.priceType==1){
+			sel_index.value=1
+		}else if(option.priceType==0){
+			sel_index.value=2
+		}
+	})
+	onReachBottom(() => {
+		pageNo.value++
+		if (sel_index.value === 0) {
+			get_findByCourseList('', selectType.value)
+		} else if (sel_index.value === 1) {
+			get_findByCourseList(1, selectType.value)
+		} else if (sel_index.value === 2) {
+			get_findByCourseList('0', selectType.value)
+		}
+	})
+	onMounted(() => {
+		if(priceType.value){
+			get_findByCourseList(priceType.value, 1)
+		}else{
+			get_findByCourseList('', 1)
+		}
+	})
+	const selectType = ref(1)
+	const select_btn = (e, i) => {
+		selectType.value = e.type
+		if (sel_index.value === 0) {
+			get_findByCourseList('', e.type)
+		} else if (sel_index.value === 1) {
+			get_findByCourseList(1, e.type)
+		} else if (sel_index.value === 2) {
+			get_findByCourseList('0', e.type)
+		}
+		sel_btn.value = i
 	}
 	const select_nav = (i) => {
 		sel_index.value = i
+		sel_btn.value = 0
+		if (i === 0) {
+			get_findByCourseList('', 1)
+		} else if (i === 1) {
+			get_findByCourseList(1, 1)
+		} else if (i === 2) {
+			get_findByCourseList('0', 1)
+		}
+	}
+
+	// 获取列表
+	const courseList = ref()
+	const pageNo = ref(1)
+	const priceType=ref()
+	const get_findByCourseList = (priceType : any, orderByType : number) => {
+		http.get('/detail/findByCourseList', {
+			data: {
+				priceType: priceType,
+				longitude: cache.get('LON'),
+				latitude: cache.get('LAT'),
+				orderByType: orderByType,
+				pageNo: pageNo.value,
+				pageSize: 10
+
+			}, loading: true
+		}).then((res) => {
+			if (pageNo.value == 1) {
+				courseList.value = res.result.records
+			} else {
+				courseList.value = [...courseList.value, ...res.result.records]
+			}
+		})
 	}
 </script>
 
@@ -62,39 +154,43 @@
 		width: 100%;
 		top: 0;
 		z-index: 1000;
+
 		.navbar-list {
 			display: flex;
 			align-items: center;
 			gap: 10rpx;
-	
+
 			.list-text {
 				font-weight: bold;
 				font-size: 28rpx;
 				color: #222222;
 			}
-	
+
 			&>image {
 				width: 30rpx;
 				height: 30rpx;
 			}
 		}
 	}
-	.select-btn{
+
+	.select-btn {
 		display: flex;
 		align-items: center;
 		gap: 20rpx;
 		margin-top: 20rpx;
-		.distance{
+
+		.distance {
 			width: 92rpx;
 			height: 48rpx;
 			background: #222222;
 			border-radius: 8rpx;
 			font-size: 28rpx;
 			color: #C8FF0C;
-			line-height:48rpx;
+			line-height: 48rpx;
 			text-align: center;
 		}
-		.score{
+
+		.score {
 			width: 92rpx;
 			height: 48rpx;
 			background: #FFFFFF;
@@ -102,11 +198,12 @@
 			font-size: 28rpx;
 			color: #AAAAAA;
 			height: 48rpx;
-			line-height:48rpx;
+			line-height: 48rpx;
 			text-align: center;
 		}
 	}
-	.t-card-list{
+
+	.t-card-list {
 		padding: 20rpx;
 		background: #FFFFFF;
 		border-radius: 32rpx;
@@ -114,52 +211,61 @@
 		align-items: center;
 		gap: 20rpx;
 		margin-top: 20rpx;
-		.t-courseImg{
-			&>image{
+
+		.t-courseImg {
+			&>image {
 				width: 200rpx;
 				height: 200rpx;
 				border-radius: 32rpx;
 			}
 		}
-		.t-course{
+
+		.t-course {
 			position: relative;
-			.c-title{
+
+			.c-title {
 				width: 430rpx;
 				font-weight: 800;
 				font-size: 32rpx;
 				color: #222222;
 				line-height: 52rpx;
 			}
-			.c-address{
+
+			.c-address {
 				margin-top: 4rpx;
 				font-size: 22rpx;
 				color: #AAAAAA;
 			}
-			.c-price{
+
+			.c-price {
 				font-weight: 800;
 				font-size: 32rpx;
 				color: #FB5B5B;
 				height: 44rpx;
 				line-height: 44rpx;
 			}
-			.c-ratio{
+
+			.c-ratio {
 				font-size: 22rpx;
 				color: #222222;
 				height: 32rpx;
 				line-height: 32rpx;
 			}
-			.c-class{
+
+			.c-class {
 				font-size: 22rpx;
 				color: #AAAAAA;
 				height: 32rpx;
 				line-height: 32rpx;
 			}
-			.c-icon{
+
+			.c-icon {
 				position: absolute;
-				bottom:-30rpx;
-				right:-42rpx;
-				&>image{
-					width:161rpx;
+				bottom: -30rpx;
+				right: -42rpx;
+
+				&>image {
+					width: 161rpx;
 				}
 			}
 		}

+ 11 - 4
src/pages/index/userList/index.vue

@@ -25,7 +25,7 @@
 				</view>
 			</view>
 		</view>
-		<view class="u-select-btn">
+		<view class="u-select-btn" @click="confirmSelect">
 			<button hover-class="hover-btn">确认选择:{{selTotal}}人</button>
 		</view>
 	</view>
@@ -61,7 +61,7 @@
 	})
 
 	const get_userList = () => {
-		http.get('/my/familyMembers/findFamilyMembers', { data: { userId: userinfo.value.id, pageNo: pageNo.value, pageSize: 10 }, loading: true }).then((res) => {
+		http.get('/my/familyMembers/findFamilyMembers', { data: { userId: userinfo.value.id, pageNo: pageNo.value, pageSize:30 }, loading: true }).then((res) => {
 			res.result.records = res.result.records.map((item:any) => ({
 				...item,
 				selOut: false
@@ -73,19 +73,26 @@
 			}
 		})
 	}
-
+	
+	const selArr=ref([])
 	const selectUser = (item : any) => {
 		item.selOut = !item.selOut
 		if (item.selOut) {
 			selTotal.value++
+			selArr.value.push(item)
 		} else {
 			selTotal.value--
-		}
+			selArr.value = selArr.value.filter((i:any) => i.id != item.id)
+		} 
 	}
 
 	const addUser = () => {
 		RouterUtils.to_page('/pages/index/attestation/index');
 	}
+	const confirmSelect=()=>{
+		uni.$emit('userData',selArr.value)
+		uni.navigateBack()
+	}
 </script>
 
 <style lang="less" scoped>

+ 96 - 38
src/pages/index/venue/index.vue

@@ -1,6 +1,6 @@
 <template>
 	<view class="venue-navbar">
-		<view class="navbar-list" v-for="(item,index) in navbarList" :key="index" @click="select_nav(index)">
+		<view class="navbar-list" v-for="(item,index) in navbarList" :key="index" @click="select_nav(item,index)">
 			<view class="list-text">{{item.text}}</view>
 			<image :src="sel_index==index?'/static/notsel-icon.png':'/static/select-icon.png'" mode=""></image>
 		</view>
@@ -8,73 +8,131 @@
 	<view style="height: 70rpx;"></view>
 	<view class="content">
 		<view class="select-btn">
-			<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList" :key="index" @click="select_btn(index)">{{item}}</view>
+			<view :class="sel_btn===index?'distance':'score'" v-for="(item,index) in selectList" :key="index" @click="select_btn(item,index)">{{item.text}}</view>
 		</view>
-		<view class="venue-card" v-for="item in 10" @click="gotoDetail">
-			<view class="venues-image">
-				<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
-				<view class="e-badge">
-					<image src="/src/static/events-icon1.png" mode="widthFix"></image>
-					<view class="text">今日有票</view>
+		<view v-if="!searchLoading">
+			<view class="venue-card" v-for="item in dataList" @click="gotoDetail(item)" :key="item.id">
+				<view class="venues-image">
+					<image :src="item.cover" mode=""></image>
+					<view class="e-badge">
+						<image src="/src/static/events-icon1.png" mode="widthFix"></image>
+						<view class="text">{{item.ticketWhether?'今日有票':'暂无余票'}}</view>
+					</view>
 				</view>
-			</view>
-			<view class="venues-info">
-				<view class="venues-name">体育综合训练馆(观山湖店)</view>
-				<view class="venues-comments">
-					<view class="star">
-						<zzx-icon name="star" size="12"></zzx-icon>
-						<text>4.8</text>
+				<view class="venues-info">
+					<view class="venues-name">{{item.name}}</view>
+					<view class="venues-comments">
+						<view class="star">
+							<zzx-icon name="star" size="12"></zzx-icon>
+							<text>{{item.goodRate}}</text>
+						</view>
+						<view class="comment">
+							{{item.comments}}条评论
+						</view>
 					</view>
-					<view class="comment">
-						37条评论
+					<view class="venues-address">
+						{{item.address}} | {{item.km}}km
 					</view>
-				</view>
-				<view class="venues-address">
-					观山湖区万达广场 | 2.2km
-				</view>
-				<view class="venues-type">
-					<view class="type-tags" v-for="item in 4">
-						羽毛球
+					<view class="venues-type">
+						<view class="type-tags" v-for="(tags,index) in item.category" :key="index">
+							{{tags}}
+						</view>
 					</view>
 				</view>
 			</view>
 		</view>
+		<zs-loading v-else></zs-loading>
+		<zs-empty v-if="dataList.length<1&&!searchLoading"></zs-empty>
 	</view>
 </template>
 
 <script lang="ts" setup>
-	import { ref } from 'vue'
+	import { ref, onMounted, computed } from 'vue'
+	import { onLoad,onReachBottom } from '@dcloudio/uni-app'
+	import { http } from '@/utils/http'
+	import {RouterUtils} from '@/utils/util'
+	import { useCacheStore } from '@/stores/cache'
+	import zsEmpty from '@/components/zs-empty/index.vue'
+	import zsLoading from '@/components/zzx-loading/zzx-loading.vue'
+	const cache = useCacheStore()
 	const navbarList = ref([{
-		text: '全部'
+		text: '全部',
+		tagsVal:'0-1',
+		value:0
 	}, {
-		text: '学校'
+		text: '学校',
+		tagsVal:'1-1',
+		value:1
 	}, {
-		text: '体育馆'
+		text: '体育馆',
+		tagsVal:'2-1',
+		value:2
 	}]);
-	const selectList=ref(['距离','评分'])
+	const selectList=ref()
 	const sel_index = ref(0);
 	const sel_btn=ref(0);
-	
-	const select_btn=(i)=>{
+	onMounted(()=>{
+		get_dictType(0)
+		get_placeList('0-1')
+	})
+	onReachBottom(()=>{
+		current.value++
+		get_placeList(tagsVal.value||'0-1')
+	})
+	const select_btn=(e,i)=>{
+		searchLoading.value=true
 		sel_btn.value=i
+		get_placeList(e.value)
 	}
-	const select_nav = (i) => {
+	const select_nav = (e,i) => {
+		searchLoading.value=true
 		sel_index.value = i
+		sel_btn.value=0
+		tagsVal.value=e.tagsVal
+		get_dictType(e.value || 0)
+		get_placeList(e.tagsVal)
 	}
 	
-	const gotoDetail=()=>{
-		if(sel_index.value===0||sel_index.value===1){
-			console.log(sel_index.value);
+	const gotoDetail=(item)=>{
+		if(item.type==0){
 			uni.navigateTo({
-				url:'/pages/index/detail/index'
+				url:`/pages/index/detail/index?id=${item.id}`
 			})
 		}else{
-			console.log(sel_index.value);
 			uni.navigateTo({
-				url:'/pages/index/gymDetail/index'
+				url:`/pages/index/gymDetail/index?id=${item.id}`
 			})
 		}
 	}
+	
+	// 查询分类
+	const get_dictType = (type : number) => {
+		http.get('/common/getDictItems', { data: { dictCode: 'venue_type' } }).then(res => {
+			let arr = []
+			res.result.forEach((item) => {
+				let value = parseInt(item.value.split('-')[0])
+				item.text=item.text.split('-')[1]
+				if (type == value){
+					return arr.push(item)
+				}
+			})
+			selectList.value=arr
+		})
+	}
+	const dataList=ref()
+	const current=ref(1)
+	const searchLoading=ref(true)
+	const tagsVal=ref()
+	const get_placeList=(tagsVal)=>{
+		http.post('/home/getPlaceList',{size: 10, current:current.value, venueType:String(tagsVal), longitude: cache.get('LON'), latitude: cache.get('LAT')}).then((res)=>{
+			searchLoading.value=false
+			if(current.value==1){
+				dataList.value=res.result.records
+			}else{
+				dataList.value=[...dataList.value,...res.result.records]
+			}
+		})
+	}
 </script>
 
 <style lang="less" scoped>

+ 9 - 4
src/pages/mine/accountSetting/index.vue

@@ -11,10 +11,10 @@
 					<zzx-icon name="ashRight" size="10"></zzx-icon>
 				</view>
 			</view>
-			<view class="a-nickname-cell">
+			<view class="a-nickname-cell" @click="RouterUtils.to_page('/pages/mine/reviseNickname/index')">
 				<view class="a-nickname">昵称</view>
-				<view class="a-set-nickname" @click="RouterUtils.to_page('/pages/mine/reviseNickname/index')">
-					<view class="nickname">艾卡西亚大暴雨</view>
+				<view class="a-set-nickname">
+					<view class="nickname">{{userName}}</view>
 					<zzx-icon name="ashRight" size="10"></zzx-icon>
 				</view>
 			</view>
@@ -23,9 +23,14 @@
 </template>
 
 <script lang="ts" setup>
-	import { ref } from 'vue'
+	import { ref,computed } from 'vue'
 	import { RouterUtils } from '@/utils/util';
+	import { useCacheStore } from '@/stores/cache'
+	const cache = useCacheStore()
 	const tempFilePaths=ref()
+	const userName=computed(()=>{
+		return cache.get('USER_INFO').userName
+	})
 	const selectUpType = () => {
 		uni.chooseImage({
 			count: 1,

+ 14 - 4
src/pages/mine/feedback/index.vue

@@ -27,6 +27,7 @@
 		</view>
 		<view class="f-tips">
 			咨询问题可联系<text style="color: #222222;">在线客服</text>
+			<button class="contact-btn" open-type="contact"></button>
 		</view>
 		<view class="submit-btn" @click="submitFeedback">
 			提交
@@ -50,7 +51,7 @@
 		userId:userinfo.value.id,
 		feedbackType:0,
 		feedbackDescribed:'',
-		feedbackImg:'https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650,https://img.keaitupian.cn/newupload/08/1629449018344288.jpg,http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960'
+		feedbackImg:''
 	})
 
 	onMounted(()=>{
@@ -63,17 +64,17 @@
 	
 	// 查询分类
 	const get_dictType = () => {
-		http.get('/common/getDictItems', { data: { dictCode: 'feedback_type' } }).then(res => {
+		http.get('/common/getDictItems', { data: { dictCode: 'feedback_type' }}).then(res => {
 			issueType.value=res.result.reverse()
 		})
 	}
 	
 	const submitFeedback=()=>{
-		console.log({...formData.value});
 		http.post('/my/feedback/submitFeedback',{...formData.value},{loading:true}).then(res=>{
-			TipsUtils.tips_toast(res.message)
 			formData.value.feedbackDescribed=''
 			formData.value.feedbackImg=''
+			uni.navigateBack()
+			TipsUtils.tips_toast(res.message)
 		})
 	}
 </script>
@@ -168,6 +169,15 @@
 		font-weight: bold;
 		font-size: 24rpx;
 		color: #AAAAAA;
+		position: relative;
+		.contact-btn {
+			position: absolute;
+			width:160rpx;
+			top: -30rpx;
+			right:200rpx;
+			height: 70rpx;
+			opacity: 0;
+		}
 	}
 
 	.submit-btn {

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

@@ -7,7 +7,7 @@
 			<view class="f-user-info">
 				<view class="user-info">
 					<view class="user-header">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+						<image :src="item.avatar" mode=""></image>
 					</view>
 					<view class="user-name">{{item.userName}}</view>
 				</view>

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

@@ -20,8 +20,8 @@
 	<view style="height: 100rpx;"></view>
 	<view class="content">
 		<view class="m-mineinfo-card">
-			<view class="item-info" v-for="(item,idnex) in cardList" :key="index"
-				@click="RouterUtils.to_page('/pages/mine/orderInfo/index')">
+			<view class="item-info" v-for="(item,index) in cardList" :key="index"
+				@click="RouterUtils.to_page(`/pages/mine/orderInfo/index?selIndex=${index}`)">
 				<zzx-icon :name="item.icon" size="30"></zzx-icon>
 				<view class="item-text">{{item.name}}</view>
 			</view>
@@ -79,6 +79,9 @@
 		name: '售后',
 		icon: 'm-after-sales'
 	},])
+	onMounted(()=>{
+		get_userinfo()
+	})
 	onPageScroll((e) => { })
 
 	const submitLogin = () => {
@@ -94,9 +97,16 @@
 		http.get('/user/loginByCode', {data:{code:item}, loading: true }).then(res => {
 			cache.set('TOKEN',res.result.token)
 			cache.set('USER_INFO',res.result)
+			get_userinfo()
 			TipsUtils.tips_toast('登录成功')
 		})
 	}
+	
+	const get_userinfo=()=>{
+		http.get('/user/getUserInfo', { loading: true }).then(res => {
+			cache.set('USER_INFO',res.result)
+		})
+	}
 </script>
 
 <style>
@@ -133,6 +143,7 @@
 						transform: translate(-50%, -50%);
 						width: 160rpx;
 						height: 160rpx;
+						border-radius: 50%;
 					}
 
 					.user-nickname {

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

@@ -13,7 +13,7 @@
 			<view class="m-user-info">
 				<view class="user-info">
 					<view class="user-header">
-						<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+						<image :src="item.avatar" mode=""></image>
 					</view>
 					<view class="user-name">{{item.username}}</view>
 				</view>

+ 10 - 4
src/pages/mine/orderInfo/index.vue

@@ -10,18 +10,20 @@
 				<view class="order-name">场地:林旦综合运动馆</view>
 				<!-- 待付款 -->
 				<view class="order-status" v-if="selected==1">待支付(剩余14:23)</view>
-				<view class="item-order-status" v-if="selected==2">待使用</view>
+				<view class="item-order-status" style="color:#FB5B5B;" v-if="selected==2">待使用</view>
 				<view class="item-order-status" v-if="selected==3">已使用</view>
+				<view class="item-order-status" v-if="selected==4">已退款</view>
 			</view>
 			<view class="line"></view>
 			<view class="o-order-info">
 				<view class="item-info">
 					<!-- 多个商品 -->
-					<!-- 					<scroll-view class="scroll-view_H scroll-order" scroll-x="true">
+<!-- 					<scroll-view class="scroll-view_H scroll-order" scroll-x="true">
 						<view class="scroll-view-item_H scroll-order-item" v-for="item in 5">
 							<view class="item-order">
 								<view class="order-img">
-									<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode=""></image>
+									<image src="https://img.keaitupian.cn/newupload/08/1629449018344288.jpg" mode="">
+									</image>
 								</view>
 								<view class="order-name textHidden">参赛意外险参赛意外险</view>
 							</view>
@@ -65,10 +67,14 @@
 
 <script lang="ts" setup>
 	import { ref, onMounted } from 'vue'
+	import { onLoad } from '@dcloudio/uni-app';
 	import zsEmpty from '@/components/zs-empty/index.vue'
 	const selected = ref(0)
 	const orderTypeList = ref(['全部', '待付款', '待使用', '已使用', '退款/售后'])
-
+	
+	onLoad((option)=>{
+		selected.value=option.selIndex
+	})
 	const selectedItem = (i) => {
 		selected.value = i
 	}

+ 23 - 4
src/pages/mine/reviseNickname/index.vue

@@ -2,20 +2,39 @@
 	<view class="content">
 		<view class="r-nickname-card">
 			<view class="r-nickinput">
-				<input type="text" maxlength="10" placeholder="11111" />
+				<input type="text" v-model="username" maxlength="10" placeholder="请输入新昵称" />
 			</view>
-			<view class="r-clear-icon">
+			<view class="r-clear-icon" v-if="username!==''" @click="username=''">
 				<zzx-icon name="m-clear" size="16"></zzx-icon> 
 			</view>
 		</view>
 		<view class="r-tips">限2-10个汉字</view>
 	</view>
 	<view class="r-bottom-btn">
-		<view class="submit-btn">确定</view>
+		<view class="submit-btn" @click="submit">确定</view>
 	</view>
 </template>
 
-<script>
+<script lang="ts" setup>
+	import { ref, onMounted,computed } from 'vue'
+	import { http } from '@/utils/http'
+	import { RouterUtils, TipsUtils } from '@/utils/util';
+	import { useCacheStore } from '@/stores/cache'
+	const cache = useCacheStore()
+	const username=ref('')
+	const submit=()=>{
+		if(username.value=='') return TipsUtils.tips_toast('请输入昵称')
+		http.get('/user/updateUserInfo',{data:{nickName:username.value,avatarUrl:''},loading:true}).then((res)=>{
+			get_userinfo()
+		})
+	}
+	const get_userinfo=()=>{
+		http.get('/user/getUserInfo', { loading: true }).then(res => {
+			cache.set('USER_INFO',res.result)
+			TipsUtils.tips_toast('修改成功')
+			RouterUtils.back()
+		})
+	}
 </script>
 
 <style lang="less" scoped>

二进制
src/static/qinggou.png


二进制
src/static/snapped1.png


+ 8 - 0
src/styles/variables.less

@@ -29,4 +29,12 @@
  	}
 	.scroll-view-item_H {
 			display: inline-block;
+		}
+		
+		.not-data{
+			 height: 100rpx;
+			 text-align: center;
+			 font-size: 24rpx;
+			 color: #999999;
+			 line-height: 100rpx;
 		}

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

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

+ 11 - 0
src/utils/util/index.ts

@@ -170,4 +170,15 @@ export const idCardHide = (card : any) => {
 	const reg = /^(.{2})(?:\d+)(.{2})$/;
 	const maskedIdCard = card.replace(reg, '$1***********$2');
 	return maskedIdCard;
+}
+
+/**
+ * 手机号脱敏
+ * @param phone - 手机号字符串
+ * @returns 脱敏后的手机号字符串
+ */
+export const phoneHide = (phone : any) => {
+	const reg = /^(\d{3})\d{4}(\d{4})$/;
+	const maskedPhone = phone.replace(reg, '$1****$2');
+	return maskedPhone;
 }