贾宇博 недель назад: 3
Родитель
Сommit
3e974d03da
51 измененных файлов с 2052 добавлено и 12616 удалено
  1. 32 10
      api/userList.js
  2. 33 19
      api/volunteerDetailsApi/details.js
  3. 91 99
      components/Client/new_file.vue
  4. 6 7
      components/Services/services.vue
  5. 84 48
      components/its-calendar/its-calendar.vue
  6. 3 1
      config.js
  7. 7 1
      manifest.json
  8. 65 14
      pages.json
  9. 1 3
      pages/UserSelection.vue
  10. 193 177
      pages/classify.vue
  11. 68 53
      pages/common/classify/orderlist.vue
  12. 2 0
      pages/common/orderList/listItem.vue
  13. 213 196
      pages/index.vue
  14. 1 2
      pages/login.vue
  15. 355 0
      pages/mallMenu.vue
  16. 7 2
      pages_classify/components/PositioningMap/index.vue
  17. 177 37
      pages_classify/pages/handle/index.vue
  18. 35 5
      pages_classify/pages/order/index.vue
  19. 89 50
      pages_classify/pages/orderItem/orderdetails.vue
  20. 152 0
      pages_classify/pages/orderItem/userComment.vue
  21. 0 11332
      pages_home/components/cc-selectDity/areaBak240404.js
  22. 0 332
      pages_home/components/cc-selectDity/cc-selectDityBak.vue
  23. 50 14
      pages_home/components/cust-form/index.vue
  24. 0 4
      pages_home/components/volunteerSide/adresss.vue
  25. 78 57
      pages_home/pages/Volunteerside/goodsDetails.vue
  26. 89 36
      pages_home/pages/client/details.vue
  27. 11 6
      pages_home/pages/details/index.vue
  28. 21 1
      pages_home/pages/register/data.js
  29. 3 1
      pages_home/pages/register/index.vue
  30. 30 32
      pages_mine/components/setupUser/Add.vue
  31. 45 58
      pages_mine/pages/selectAddress/edit.vue
  32. 1 0
      pages_mine/pages/selectAddress/index.vue
  33. 49 19
      pages_mine/pages/wallet/index.vue
  34. BIN
      static/Tioimages/15-旅游服务-01.png
  35. BIN
      static/Tioimages/休闲娱乐.png
  36. BIN
      static/Tioimages/其他服务.png
  37. BIN
      static/Tioimages/旅游服务.png
  38. BIN
      static/Tioimages/父母体检.png
  39. BIN
      static/Tioimages/福利商城_购物车.png
  40. BIN
      static/Tioimages/购物商城.png
  41. BIN
      static/images/tabbar/class.png
  42. BIN
      static/images/tabbar/class_.png
  43. BIN
      static/images/tabbar/home.png
  44. BIN
      static/images/tabbar/home_.png
  45. BIN
      static/images/tabbar/mine.png
  46. BIN
      static/images/tabbar/mine_.png
  47. BIN
      static/images/tabbar/work.png
  48. BIN
      static/images/tabbar/work_.png
  49. 0 0
      static/sdk/qqmap-wx-jssdk.js
  50. 0 0
      static/sdk/qqmap-wx-jssdk.min.js
  51. 61 0
      utils/adress.js

+ 32 - 10
api/userList.js

@@ -2,19 +2,41 @@ import request from '../utils/request'
 
 //用户订单列表
 export function userMainOrderList(data) {
-    return request({
-        url: `/core/users/orders/mainOrderList`,
-        method: 'get',
-        params: data
-    })
+	return request({
+		url: `/core/users/orders/mainOrderList`,
+		method: 'get',
+		params: data
+	})
 }
 
 
 // 用户订单列表详情
-
 export function orderInfomainOrderId(mainOrderId) {
-  return request({
-    url: `/core/users/orders/orderInfo/${mainOrderId}`,
-    method: 'get',
-  })
+	return request({
+		url: `/core/users/orders/orderInfo/${mainOrderId}`,
+		method: 'get',
+	})
+}
+
+//获取用户订单列表状态
+export function systemDictdaTalist() {
+	return request({
+		url: `/system/dict/data/list`,
+		method: 'get',
+		params: {
+			pageNum: 1,
+			pageSize: 10,
+			dictType: 'order_status'
+		}
+	})
 }
+
+// 用户评价小订单
+
+export function usersUserFinishOrder(data) {
+	return request({
+		url: `/core/users/orders/userFinishOrder`,
+		method: 'post',
+		data:data
+	})
+}

+ 33 - 19
api/volunteerDetailsApi/details.js

@@ -1,31 +1,35 @@
 import upload from '@/utils/upload'
 import request from '@/utils/request'
-
+const lrr_service_category = 'service_category';
 
 // 获取选择项健值第一项
-export function typeOptionSelect(params = {}) {
-	return request({
-		url: '/system/dict/data/list',
-		method: 'get',
-		params
-	})
-}
-
-// 获取选择项健值第二项
-export function dictListlrRstudy(params = {}) {
-	return request({
-		url: '/system/dict/data/list',
-		method: 'get',
-		params
-	})
-}
+// export function typeOptionSelect(params = {}) {
+// 	return request({
+// 		url: '/system/dict/data/list',
+// 		method: 'get',
+// 		params
+// 	})
+// }
+
+// // 获取选择项健值第二项
+// export function dictListlrRstudy(params = {}) {
+// 	return request({
+// 		url: '/system/dict/data/list',
+// 		method: 'get',
+// 		params
+// 	})
+// }
 
 // 获取选择项健值第三项
-export function dictListlrData(params = {}) {
+export function dictListlrData(params) {
 	return request({
 		url: '/system/dict/data/list',
 		method: 'get',
-		params
+		params:{
+			pageNum: 1,
+			pageSize: 10,
+			dictType: lrr_service_category,
+		}
 	})
 }
 
@@ -103,3 +107,13 @@ export function volunteerSeachgetTreeList(params) {
 	params:params,
   });
 }
+
+
+// 获取服务类型健值
+export function volunteerDataList(params) {
+  return request({
+    url: 'system/dict/data/list',  
+    method: 'get',
+	params:params,
+  });
+}

+ 91 - 99
components/Client/new_file.vue

@@ -3,36 +3,35 @@
 		<template>
 			<view class="Wrapper-grid">
 				<view class="serve-title client-title" v-if="userType == 2">注册专区</view>
-				<swiper :indicator-dots="true" class="swiper" v-if="serveiceList && serveiceList.length > 0">
-					<swiper-item>
-						<up-grid :border="false" col="5" @click="handleGridClick">
-							<up-grid-item v-for="(item, index) in serveiceList.slice(0,10)" :key="index"
-								:custom-style="custmoStyle">
-								<view class="grid-box">
-									<view class="grid-icon">
-										<image :src="item.icon" class="service-img" mode="aspectFit" />
-									</view>
-
-									<text class="grid-text">{{ item.name }}</text>
-								</view>
-							</up-grid-item>
-						</up-grid>
-					</swiper-item>
-					<swiper-item>
-						<up-grid :border="false" col="5" @click="handleGridClick">
-							<up-grid-item v-for="(item, index) in serveiceList.slice(10,serveiceList.length)" :key="index"
-								:custom-style="custmoStyle">
-								<view class="grid-box">
-									<view class="grid-icon">
-										<image :src="item.icon" class="service-img" mode="aspectFit" />
-									</view>
-
-									<text class="grid-text">{{ item.name }}</text>
-								</view>
-							</up-grid-item>
-						</up-grid>
-					</swiper-item>
-				</swiper>
+				<!-- <swiper :indicator-dots="true" class="swiper" v-if="serveiceList && serveiceList.length > 0"> -->
+				<!-- <swiper-item> -->
+				<up-grid :border="false" col="5">
+					<up-grid-item v-for="(item, index) in serveiceList.slice(0,10)" :key="index"
+						:custom-style="custmoStyle" @click="handleGridClick(item)">
+						<view class="grid-box">
+							<view class="grid-icon">
+								<image :src="item.icon" class="service-img" mode="aspectFit" />
+							</view>
+							<text class="grid-text">{{ item.name }}</text>
+						</view>
+					</up-grid-item>
+				</up-grid>
+				<!-- </swiper-item> -->
+				<!-- <swiper-item> -->
+				<up-grid :border="false" col="5">
+					<up-grid-item v-for="(item, index) in serveiceList.slice(10,serveiceList.length)" :key="index"
+						:custom-style="custmoStyle" @click="handleGridClick(item)">
+						<view class="grid-box">
+							<view class="grid-icon">
+								<image :src="item.icon" class="service-img" mode="aspectFit" />
+							</view>
+
+							<text class="grid-text">{{ item.name }}</text>
+						</view>
+					</up-grid-item>
+				</up-grid>
+				<!-- </swiper-item> -->
+				<!-- </swiper> -->
 
 				<up-toast ref="uToastRef" />
 			</view>
@@ -53,9 +52,6 @@
 		computed,
 		provide
 	} from 'vue';
-	// import {
-	// 	typeOptionSelect
-	// } from "@/api/volunteerDetailsApi/details.js"
 	import {
 		workDate,
 		getDataTime,
@@ -63,6 +59,7 @@
 	} from '@/api/volunteer.js'
 	import {
 		volunteerSeachgetTreeList,
+		volunteerDataList
 	} from "@/api/volunteerDetailsApi/details.js"
 	import Calendar from '../../components/uni-calendar/components/uni-calendar/uni-calendar.vue'
 
@@ -83,25 +80,24 @@
 	const selected = ref([])
 
 	// 普通用户
-	const serviceList1 = [
-		{
-			icon: '/static/Tioimages/1v专业指导.png',
-			name: '陪伴陪聊',
+	const serviceList1 = [{
+			icon: '/static/Tioimages/父母体检.png',
+			name: '老人生活',
 			key: 1,
 		},
 		{
 			icon: '/static/Tioimages/1 妇女儿童权益保护服务.png',
-			name: '孩子陪伴',
+			name: '孩子成长',
 			key: 2,
 		},
 		{
-			icon: '/static/Tioimages/临时帮手.png',
-			name: '临时帮手',
+			icon: '/static/Tioimages/家庭保洁.png',
+			name: '家庭保洁',
 			key: 3,
 		},
 		{
-			icon: '/static/Tioimages/专家服务.png',
-			name: '专家服务',
+			icon: '/static/Tioimages/临时帮手.png',
+			name: '临时帮手',
 			key: 4,
 		},
 		{
@@ -110,27 +106,27 @@
 			key: 5,
 		},
 		{
-			icon: '/static/Tioimages/家庭保洁.png',
-			name: '家庭保洁',
+			icon: '/static/Tioimages/专家服务.png',
+			name: '专家服务',
 			key: 6,
 		},
 		{
-			icon: '/static/Tioimages/旅游服务.png',
+			icon: '/static/Tioimages/15-旅游服务-01.png',
 			name: '旅游服务',
 			key: 7,
 		},
 		{
-			icon: '/static/Tioimages/健康管理.png',
-			name: '健康管理',
+			icon: '/static/Tioimages/交友.png',
+			name: '交友专区',
 			key: 8,
 		},
 		{
-			icon: '/static/Tioimages/交友.png',
-			name: '交友专区',
+			icon: '/static/Tioimages/休闲娱乐.png',
+			name: '娱乐专区',
 			key: 9,
 		},
 		{
-			icon: '/static/Tioimages/购物商城.png',
+			icon: '/static/Tioimages/福利商城_购物车.png',
 			name: '商城购物',
 			key: 10,
 		},
@@ -139,64 +135,73 @@
 			name: '本地生活',
 			key: 11,
 		},
+		{
+			icon: '/static/Tioimages/其他服务.png',
+			name: '其他服务',
+			key: 12,
+		},
 	]
 
 	//志愿者
-	const serviceList2 = [
-		{
-			icon: '/static/Tioimages/1v专业指导.png',
-			name: '陪伴陪聊',
+	const serviceList2 = [{
+			icon: '/static/Tioimages/父母体检.png',
+			name: '老人生活',
 			key: 1,
 		},
 		{
 			icon: '/static/Tioimages/1 妇女儿童权益保护服务.png',
-			name: '孩子陪护',
+			name: '孩子成长',
 			key: 2,
 		},
-		{
-			icon: '/static/Tioimages/健康管理.png',
-			name: '健康管理',
-			key: 3,
-		},
 		{
 			icon: '/static/Tioimages/家庭保洁.png',
 			name: '家庭保洁',
-			key: 4
+			key: 3,
 		},
 		{
 			icon: '/static/Tioimages/临时帮手.png',
 			name: '临时帮手',
-			key: 5
-		},
-		{
-			icon: '/static/Tioimages/专家服务.png',
-			name: '专家服务',
-			key: 6
+			key: 4,
 		},
 		{
 			icon: '/static/Tioimages/家电维修.png',
 			name: '家电维护',
-			key: 8
+			key: 5,
 		},
 		{
-			icon: '/static/Tioimages/旅游服务.png',
+			icon: '/static/Tioimages/专家服务.png',
+			name: '专家服务',
+			key: 6,
+		},
+		{
+			icon: '/static/Tioimages/15-旅游服务-01.png',
 			name: '旅游服务',
-			key: 9
+			key: 7,
 		},
 		{
 			icon: '/static/Tioimages/交友.png',
 			name: '交友专区',
-			key: 10
+			key: 8,
+		},
+		{
+			icon: '/static/Tioimages/休闲娱乐.png',
+			name: '娱乐专区',
+			key: 9,
 		},
 		{
-			icon: '/static/Tioimages/购物商城.png',
+			icon: '/static/Tioimages/福利商城_购物车.png',
 			name: '商城购物',
-			key: 11
+			key: 10,
 		},
 		{
 			icon: '/static/Tioimages/本地生活.png',
 			name: '本地生活',
-			key: 12
+			key: 11,
+		},
+		{
+			icon: '/static/Tioimages/其他服务.png',
+			name: '其他服务',
+			key: 12,
 		},
 		{
 			icon: '/static/serverImg/home/icon/icon8.png',
@@ -205,46 +210,33 @@
 		},
 	]
 
-	const serveiceList =computed(()=>{
-		console.log('userType ____>',userType);
-		
-		if(userType === 1){
+	const serveiceList = computed(() => {
+		console.log('userType ____>', userType);
+
+		if (userType === 1) {
 			return serviceList1
 		}
 		return serviceList2
 	})
 
-	const parentIdMap = {
-		'孩子陪护': 2,
-		'陪伴陪聊': 1,
-		'家庭助理': 3,
-		'健康管理': 4,
-		'家庭清洁': 5,
-		'家务帮手': 6,
-		'资讯与服务': 7,
-	};
 
-	// const getParentId = (service) => parentIdMap[service.name] || 1;
 
 
 	// 宫格点击事件
-	const handleGridClick = async (index) => {
-		const service = serveiceList.value[index]; // 获取点击的服务条目
+	const handleGridClick = async (service) => {
 		// 用户
 		if (userType == 1) {
 
 			// 动态获取 parentId
-			// const parentId = getParentId(service); // 通过服务条目动态获取 parentId
 			const params = {
-				parentId: service.key
+				parentId: service.key,
 			}
 			const res = await volunteerSeachgetTreeList(params)
-			console.log(res, '>>>>>dictSort = null')
 
 			// 只有第一条和第二条可以跳转
 			if (service.key === 1 || service.key === 2) {
 				uni.navigateTo({
-					url: `/pages_home/pages/client/details?dataList=${encodeURIComponent(JSON.stringify(res.data))}`
+					url: `/pages_home/pages/client/details?dataList=${encodeURIComponent(JSON.stringify(res.data))}&serviceCategory=${service.key}`
 				});
 			} else {
 				// 其他条目提示“敬请期待”
@@ -255,7 +247,7 @@
 			}
 		}
 		// 志愿者
-		if (userType == 2 ) {
+		if (userType == 2) {
 			if (service.key !== 7) {
 				const res = await getVolunteerInfo({
 					serviceCategory: service.key
@@ -267,7 +259,7 @@
 					})
 					return
 				}
-				service.key === 1 || service.key === 2 ? uni.navigateTo({
+				[1, 2].includes(service.key) ? uni.navigateTo({
 					url: `/pages_home/pages/register/index?data=${encodeURIComponent(JSON.stringify(service))}`
 				}) : uni.showToast({
 					title: '敬请期待',
@@ -423,9 +415,9 @@
 		height: 78rpx;
 	}
 
-.swiper {
-	height: 340rpx;
-}
+	.swiper {
+		height: 340rpx;
+	}
 
 	.grid-text {
 		font-size: 14px;

+ 6 - 7
components/Services/services.vue

@@ -4,8 +4,8 @@
 			<template #left>
 				<view class="demo-warter" v-for="(item, index) in props.leftList" :key="index"
 					@click="goToDetail(item)">
-					<up-lazy-load threshold="-450" border-radius="10" :image="item.volunteerPicture"
-						:index="index"></up-lazy-load>
+					<up-lazy-load threshold="50" border-radius="10" :image="item.volunteerPicture" :index="index"
+						mode="aspectFill"></up-lazy-load>
 					<view class="demo-title">
 						{{ item.businessTierName }}
 					</view>
@@ -24,8 +24,8 @@
 			<template #right>
 				<view class="demo-warter" v-for="(item, index) in props.rightList" :key="index"
 					@click="goToDetail(item)">
-					<up-lazy-load threshold="-450" border-radius="10" :image="item.volunteerPicture"
-						:index="index"></up-lazy-load>
+					<up-lazy-load threshold="50" border-radius="10" :image="item.volunteerPicture" :index="index"
+						mode="aspectFill"></up-lazy-load>
 					<view class="demo-title">
 						{{ item.businessTierName }}
 					</view>
@@ -62,7 +62,7 @@
 			serviceCategory: item.serviceCategory, // 获取 serviceCategory
 			businessManagementId: item.businessManagementId, //获取 businessManagementId
 		};
-		
+
 		uni.navigateTo({
 			url: `/pages_home/pages/Volunteerside/goodsDetails?params=${JSON.stringify(params)}`
 		});
@@ -105,10 +105,9 @@
 		font-size: 30rpx;
 		margin-top: 5px;
 		color: black;
-		/* margin-left: 15rpx; */
 		display: -webkit-box;
 		-webkit-box-orient: vertical;
-		-webkit-line-clamp: 3;
+		-webkit-line-clamp: 2;
 		overflow: hidden;
 		text-overflow: ellipsis;
 		word-break: break-all;

+ 84 - 48
components/its-calendar/its-calendar.vue

@@ -9,16 +9,16 @@
 				</view>
 			</view>
 			<view class="calendar_time">
-				<view class="time_x" :class="{
-		      'time_x_sty': host_index == item?.timeStamp, 
-		      'disabled-time': isTimeDisabled(item?.timeStamp) // 新增: 添加禁用类
-		    }" v-for="(item, index) in timeHostArr[day_index]" :key="index"
-					@click="(nowTimes < item?.timeStamp && item.hasReservation !== 1 && !isTimeDisabled(item?.timeStamp)) ? hosts(item) : ''"
-					:style="{
-		      'color': ((nowTimes > item?.timeStamp || item.hasReservation === 1 || isTimeDisabled(item?.timeStamp)) ? '#999999' : '')
-		    }">
-					<text>{{item?.hours}}</text>
-					<text v-if="item.hasReservation === 1" class="hasRe-text">已预约</text>
+				<view class="time_x" 
+				  :class="{
+				    'time_x_sty': host_index == item?.timeStamp, 
+				    'disabled-time': shouldDisable(item) 
+				  }" 
+				  v-for="(item, index) in timeHostArr[day_index]" 
+				  :key="index"
+				  @click="handleTimeClick(item)">
+				  <text>{{item?.hours}}</text>
+				  <text v-if="item.hasReservation === 1" class="hasRe-text">已预约</text>
 				</view>
 			</view>
 		</view>
@@ -27,7 +27,6 @@
 		</view> -->
 	</view>
 </template>
-
 <script>
 	export default {
 		props: {
@@ -40,18 +39,20 @@
 				type: Array,
 				default: () => []
 			},
-
+			businessDuration: {
+				type: Number,
+				default: 0
+			} // 从父组件接收的服务时长(分钟)
 		},
 		data() {
 			return {
 				dayArr: [],
-				hostArr: [],
 				day_index: 0,
 				host_index: '',
-				host_All: [],
-				nowTimes: '',
-				frequency: '',
-				disableAfterTime: null, //记录当前时间
+				nowTimes: new Date().getTime(), // 只保留一个定义
+				disableAfterTime: null,
+				selectedTime: null,
+				selectedDay: null // 新增:记录选择的日期
 			}
 		},
 		watch: {
@@ -73,65 +74,94 @@
 		},
 		mounted() {},
 		methods: {
+			handleTimeClick(item) {
+				if (!this.shouldDisable(item)) {
+					this.hosts(item);
+				}
+			},
 			// 点击日期
 			dayList(e, index) {
 				this.day_index = index
 				this.$emit('getByDate', this.timeArr[index])
 			},
-			// 点击时间
-			hosts(e) {
-				this.host_All = e
-				this.host_index = e.timeStamp
-				this.host_All.yearToDate = this.timeArr[this.day_index]
-				this.disableAfterTime = e.timeStamp //记录当前选择时间戳
-				this.$emit('getByTime', this.host_All)
+			// 转换时间戳为毫秒
+			ensureMillisecond(timestamp) {
+				return timestamp > 9999999999 ? timestamp : timestamp * 1000;
+			},
+
+			shouldDisable(item) {
+				if (!item) return true;
+
+				const itemTime = this.ensureMillisecond(item.timeStamp);
+
+				// 已预约
+				if (item.hasReservation === 1) return true;
+
+				// 过去时间
+				if (this.nowTimes > itemTime) return true;
+
+				// 选择后的时间段
+				if (this.selectedTime) {
+					return itemTime > this.selectedTime &&
+						itemTime <= this.disableAfterTime;
+				}
+
+				return false;
 			},
-			isTimeDisabled(timeStamp) {
-				return this.disableAfterTime && timeStamp > this.disableAfterTime;
+			hosts(item) {
+				const itemTime = this.ensureMillisecond(item.timeStamp);
+
+				this.host_index = item.timeStamp; // 显示用原始值
+				this.selectedTime = itemTime;
+				this.disableAfterTime = itemTime + (this.businessDuration * 60 * 1000);
+				this.$emit('getByTime', {
+					...item,
+					timeStamp: itemTime // 传递转换后的值
+				});
 			},
+
 			// 点击立即预约
 			sub() {
 				if (this.host_index == '') {
-					this.$tool.toast('请选择时间')
+					this.$tool.toast('请选择时间');
 				} else {
-					let day = this.dayArr[this.day_index]
-					let time = this.time(this.host_index)
+					let day = this.dayArr[this.day_index];
+					let time = this.times(this.host_index);
 					let comTime = {
 						days: day.days,
 						weeks: day.weeks,
 						hours: this.host_All.hours,
 						timeStamp: this.host_All.timeStamp,
 						time: time
-					}
+					};
 					this.$emit('getTime', comTime);
 				}
 			},
+
 			// 格式化时间
 			times(data) {
 				let date = new Date(data * 1000);
-				//时间戳为10位需*1000,时间戳为13位的话不需乘1000
 				let h = date.getHours();
-				h = h < 10 ? ('0' + h) : h; //小时补0
+				h = h < 10 ? ('0' + h) : h; // 小时补0
 				let m = date.getMinutes();
-				m = m < 10 ? ('0' + m) : m; //分钟补0
-				return h + ':' + m
+				m = m < 10 ? ('0' + m) : m; // 分钟补0
+				return h + ':' + m;
 			},
 			time(data, type) {
 				let date = new Date(data * 1000);
-				//时间戳为10位需*1000,时间戳为13位的话不需乘1000
 				let y = date.getFullYear();
 				let MM = date.getMonth() + 1;
-				MM = MM < 10 ? ('0' + MM) : MM; //月补0
+				MM = MM < 10 ? ('0' + MM) : MM; // 月补0
 				let d = date.getDate();
-				d = d < 10 ? ('0' + d) : d; //天补0
+				d = d < 10 ? ('0' + d) : d; // 天补0
 				let h = date.getHours();
-				h = h < 10 ? ('0' + h) : h; //小时补0
+				h = h < 10 ? ('0' + h) : h; // 小时补0
 				let m = date.getMinutes();
-				m = m < 10 ? ('0' + m) : m; //分钟补0
+				m = m < 10 ? ('0' + m) : m; // 分钟补0
 				let s = date.getSeconds();
-				s = s < 10 ? ('0' + s) : s; //秒补0
+				s = s < 10 ? ('0' + s) : s; // 秒补0
 				if (type == 'yymmdd') {
-					return y + '-' + MM + '-' + d
+					return y + '-' + MM + '-' + d;
 				} else if (type == 'hhmmss') {
 					return h + ':' + m + ':' + s;
 				} else {
@@ -222,12 +252,18 @@
 	}
 
 
-	.disabled-time {
-		background-color: #f2f2f2;
-		/* 灰色背景 */
-		color: #999999;
-		/* 灰色文字 */
-		pointer-events: none;
-		/* 禁用点击事件 */
+
+	.time_x {
+	  /* 正常状态样式 */
+	  &.disabled-time {
+	    background-color: #f2f2f2;
+	    color: #999999;
+	    pointer-events: none;
+	  }
+	  
+	  &.time_x_sty {
+	    background-color: #FFE97B;
+	    color: #000000;
+	  }
 	}
 </style>

+ 3 - 1
config.js

@@ -2,8 +2,10 @@
 const config = {
 	// baseUrl: 'https://vue.ruoyi.vip/prod-api',
 	//cloud后台网关地址
-	baseUrl: 'http://192.168.100.94:9527',
+	baseUrl: 'http://192.168.100.133:9527',
 	// baseUrl: 'https://zybooks.tech/prod-api',
+	mapKey:'KFEBZ-P2GKZ-A5PX4-7Q6Y7-KXOBF-XCB4C',
+	appName: '金邻助家',
 	// 应用信息
 	appInfo: {
 		// 应用名称

+ 7 - 1
manifest.json

@@ -60,7 +60,13 @@
         "optimization" : {
             "subPackages" : true
         },
-        "lazyCodeLoading" : "requiredComponents"
+        "lazyCodeLoading" : "requiredComponents",
+        "requiredPrivateInfos" : [ "getLocation", "chooseLocation" ],
+        "permission" : {
+            "scope.userLocation" : {
+                "desc" : "你的位置信息将用于警情上报"
+            }
+        }
     },
     "mp-alipay" : {
         "usingComponents" : true

+ 65 - 14
pages.json

@@ -47,9 +47,16 @@
 			"style": {
 				"navigationBarTitleText": "我的"
 			}
+		},
+		{
+			"path": "pages/mallMenu",
+			"style": {
+				"navigationBarTitleText": "分类"
+			}
 		}
 	],
-	"subPackages": [{
+	"subPackages": [
+		{
 			"root": "pages_home/",
 			"pages": [
 				{
@@ -68,7 +75,6 @@
 					"path": "pages/details/index",
 					"style": {
 						"navigationBarTitleText": "注册详情"
-						
 					}
 				},
 				{
@@ -77,11 +83,21 @@
 						"navigationBarTitleText": "详情"
 					}
 				},
-				{"path": "components/cc-selectDity/cc-selectDity"},
-				{"path": "components/cust-form/index"},
-				{"path": "components/font-title/index"},
-				{"path": "components/picker/index"},
-				{"path": "components/updata-imgs/index"},
+				{
+					"path": "components/cc-selectDity/cc-selectDity"
+				},
+				{
+					"path": "components/cust-form/index"
+				},
+				{
+					"path": "components/font-title/index"
+				},
+				{
+					"path": "components/picker/index"
+				},
+				{
+					"path": "components/updata-imgs/index"
+				},
 				{
 					"path": "pages/login/index",
 					"style": {
@@ -98,7 +114,8 @@
 		},
 		{
 			"root": "pages_orderuser/pages",
-			"pages": [{
+			"pages": [
+				{
 					"path": "order/orderdetails",
 					"style": {
 						"navigationBarTitleText": "消息"
@@ -234,12 +251,15 @@
 						"navigationBarTitleText": "添加用户地址"
 					}
 				},
-				{"path": "components/u-city-select/u-city-select"}
+				{
+					"path": "components/u-city-select/u-city-select"
+				}
 			]
 		},
 		{
 			"root": "pages_classify",
-			"pages": [{
+			"pages": [
+				{
 					"path": "pages/handle/index",
 					"style": {
 						"navigationBarTitleText": "订单处理"
@@ -257,9 +277,18 @@
 						"navigationBarTitleText": "详情"
 					}
 				},
-				{"path": "components/PositioningMap/index"},
-				{"path": "components/Slide/index"}
-
+				{
+					"path": "components/PositioningMap/index"
+				},
+				{
+					"path": "components/Slide/index"
+				},
+				{
+					"path": "pages/orderItem/userComment",
+					"style": {
+						"navigationBarTitleText": "评论"
+					}
+				}
 			]
 		}
 	],
@@ -268,12 +297,20 @@
 		"selectedColor": "#000000",
 		"borderStyle": "white",
 		"backgroundColor": "#ffffff",
-		"list": [{
+		"list": [
+			{
 				"pagePath": "pages/index",
 				"iconPath": "static/images/tabbar/home.png",
 				"selectedIconPath": "static/images/tabbar/home_.png",
 				"text": "首页"
 			},
+			{
+				"pagePath": "pages/mallMenu",
+				"iconPath": "static/images/tabbar/class.png",
+				"selectedIconPath": "static/images/tabbar/class_.png",
+				"text": "分类",
+				"visible": false
+			},
 			{
 				"pagePath": "pages/classify",
 				"iconPath": "static/images/tabbar/work.png",
@@ -292,5 +329,19 @@
 		"navigationBarTextStyle": "black",
 		"navigationBarTitleText": "RuoYi",
 		"navigationBarBackgroundColor": "#FFFFFF"
+	},
+	"plugins": {
+		"citySelector": {
+			"version": "1.0.2",
+			"provider": "wx63ffb7b7894e99ae"
+		}
+	},
+	"permission": {
+		"scope.userFuzzyLocation": {
+			"desc": "你的位置信息将用于小程序定位"
+		},
+		"scope.userLocation": {
+			"desc": "你的位置信息将用于小程序定位"
+		}
 	}
 }

+ 1 - 3
pages/UserSelection.vue

@@ -42,14 +42,12 @@ const list = [
 		bgcColor: ' rgba(233, 91, 93, 1)'
 	}
 ]
-
 function handleBtn(userType = 0) { // 默认值 0
 	const params = {
 		userType: userType // 使用传入的 userType
 	};
 	// 把 userType 存入本地存储
 	uni.setStorageSync('userType', userType);
-
 	userOrWorker(params)
 		.then(res => {
 			// 重新拉取用户信息,储存本地
@@ -62,6 +60,7 @@ function handleBtn(userType = 0) { // 默认值 0
 		.catch(err => {
 			console.error('设置失败:', err);
 		});
+
 }
 </script>
 
@@ -142,5 +141,4 @@ function handleBtn(userType = 0) { // 默认值 0
 	color: rgba(107, 114, 128, 1);
 	margin-top: 36rpx;
 }
-
 </style>

+ 193 - 177
pages/classify.vue

@@ -16,210 +16,226 @@
 			</view>
 		</view>
 		<!-- 用户 -->
-		<OrderList :dataList="dataList" @fetchData="getListData" v-else />
+		<OrderList :dataList="dataList" :dictSort="dictData" @fetchData="getListData" v-else />
 	</view>
 </template>
 
 <script setup>
-import {
-	ref
-} from 'vue';
-import List from '@/pages/common/orderList/index.vue';
-import {
-	provide
-} from 'vue';
-import {
-	getVolunteerOrderList
-} from '@/api/volunteer.js'
-import {
-	onMounted
-} from 'vue';
-import {
-	useDict
-} from '@/utils/dict.js';
-import {
-	onLoad,
-	onShow
-} from '@dcloudio/uni-app';
-import OrderList from '@/pages/common/classify/orderlist.vue'
-import {
-	userMainOrderList
-} from "@/api/userList.js"
-
-const {
-	order_status,
-	lrr_service_status
-} = useDict('order_status', 'lrr_service_status');
-
-provide('order_status', order_status); //订单/服务状态
-provide('lrr_service_status', lrr_service_status); //订单/服务状态
-
-
-const userType = uni.getStorageSync('userType') //读取本地存储
-
-// 用户/志愿者 识别标识
-const userOrWorker = uni.getStorageSync('storage_data').vuex_userOrWorker //读取本地存储
-
-const tab = ref('');
-const tabKey = ref(0);
-const dataList = ref([]) //用户
-const data = ref([]); //志愿者
-
-/**
- * 	0待支付 1已支付 2支付超时或取消 3进行中 4已完成 5申请退款中 6已退款 7部分退款 8 待确认
- */
-const column = [{
-	name: "全部",
-	value: "",
-},
-{
-	name: "待服务",
-	value: "0",
-},
-{
-	name: "进行中",
-	value: "1",
-},
-{
-	name: "已完成",
-	value: "2",
-},
-{
-	name: "已取消",
-	value: "3",
-}
-]
-
-const column2 = [{
-	name: "全部",
-	value: "",
-},
-{
-	name: "待支付",
-	value: "1",
-},
-{
-	name: "待服务",
-	value: "2",
-},
-{
-	name: "进行中",
-	value: "3",
-},
-{
-	name: "已完成",
-	value: "4",
-},
-{
-	name: "已取消",
-	value: "5",
+	import {
+		ref
+	} from 'vue';
+	import List from '@/pages/common/orderList/index.vue';
+	import {
+		provide
+	} from 'vue';
+	import {
+		getVolunteerOrderList
+	} from '@/api/volunteer.js'
+	import {
+		onMounted
+	} from 'vue';
+	import {
+		useDict
+	} from '@/utils/dict.js';
+	import {
+		onLoad,
+		onShow
+	} from '@dcloudio/uni-app';
+	import OrderList from '@/pages/common/classify/orderlist.vue'
+	import {
+		userMainOrderList,
+		systemDictdaTalist
+	} from "@/api/userList.js"
+
+	const {
+		order_status,
+		lrr_service_status
+	} = useDict('order_status', 'lrr_service_status');
+
+	provide('order_status', order_status); //订单/服务状态
+	provide('lrr_service_status', lrr_service_status); //订单/服务状态
+
+
+	const userType = uni.getStorageSync('userType') //读取本地存储
+
+	// 用户/志愿者 识别标识
+	const userOrWorker = uni.getStorageSync('storage_data').vuex_userOrWorker //读取本地存储
+
+	const tab = ref('');
+	const tabKey = ref(0);
+	const dataList = ref([]) //用户
+	const data = ref([]); //志愿者
+	// 定义存储字典数据的响应式变量
+	const dictData = ref([]);
+	/**
+	 * 	0待支付 1已支付 2支付超时或取消 3进行中 4已完成 5申请退款中 6已退款 7部分退款 8 待确认
+	 */
+	const column = [{
+			name: "全部",
+			value: "",
+		},
+		{
+			name: "待服务",
+			value: "0",
+		},
+		{
+			name: "进行中",
+			value: "1",
+		},
+		{
+			name: "已完成",
+			value: "2",
+		},
+		{
+			name: "已取消",
+			value: "3",
+		}
+	]
+
+	const column2 = [{
+			name: "全部",
+			value: "",
+		},
+		{
+			name: "待支付",
+			value: "1",
+		},
+		{
+			name: "待服务",
+			value: "2",
+		},
+		{
+			name: "进行中",
+			value: "3",
+		},
+		{
+			name: "已完成",
+			value: "4",
+		},
+		{
+			name: "已取消",
+			value: "5",
+		}
+	]
+
+	//获取用户订单列表状态
+	async function getData() {
+  console.log('进入');
+  try {
+    const res = await systemDictdaTalist().catch(err => {
+      console.error('接口请求失败:', err);
+      throw err; // 重新抛出以进入 catch 块
+    });
+    console.log(res, '用户状态获取成功');
+    dictData.value = res.rows;
+    console.log(dictData.value, 'dictData.value');
+  } catch (e) {
+    console.error('获取数据异常:', e); // 确保这里打印错误
+  }
 }
-]
 
+	async function getList() {
+		try {
+			uni.hideLoading();
+			uni.showLoading({
+				title: '数据加载中...'
+			});
 
-async function getList() {
-	console.log(userType, '>>>>>>userType');
-	try {
-		uni.hideLoading();
-		uni.showLoading({
-			title: '数据加载中...'
+			// 判断 userType 来决定调用哪个接口
+			let res;
+			if (userType === 1) {
+				// 如果 userType 是 1,调用 userMainOrderList 接口
+				res = await getListData();
+			} else if (userType === 2) {
+				// 如果 userType 是 2,调用 getVolunteerOrderList 接口
+				res = await getVolunteerOrderList({
+					orderStatus: tab.value
+				});
+				data.value = res.data;
+			}
+
+		} catch (error) {
+			console.log('error', error);
+			uni.showToast({
+				title: error.msg,
+				icon: 'error',
+			});
+		} finally {
+			uni.hideLoading();
+		}
+	}
+	const getListData = async (orderStatus = tab.value) => {
+		const res = await userMainOrderList({
+			orderStatus: orderStatus
 		});
+		dataList.value = res.data
+	}
+	/**
+	 * 1: 查看
+	 * 2:沟通
+	 * 3:上传照片
+	 */
+	function btnClick(row, type) {
+		if (type === 1 && row.orderStatus === '2') {
+			uni.navigateTo({
+				url: `/pages_classify/pages/order/index?orderId=${row.secondOrderId}`
+			});
+			return;
+		}
+		if (type === 1) {
 
-		// 判断 userType 来决定调用哪个接口
-		let res;
-		if (userType === 1) {
-			// 如果 userType 是 1,调用 userMainOrderList 接口
-			res = await getListData();
-		} else if (userType === 2) {
-			// 如果 userType 是 2,调用 getVolunteerOrderList 接口
-			res = await getVolunteerOrderList({
-				orderStatus: tab.value
+			uni.navigateTo({
+				url: `/pages_classify/pages/handle/index?orderId=${row.secondOrderId}`
 			});
+			return
+			console.log('res==>',res);
+			
 			data.value = res.data;
 		}
 
-	} catch (error) {
-		console.log('error', error);
-		uni.showToast({
-			title: error.msg,
-			icon: 'error',
-		});
-	} finally {
-		uni.hideLoading();
-	}
-}
-const getListData = async (orderStatus = tab.value) => {
-	const res = await userMainOrderList({
-		orderStatus: orderStatus
-	});
-	dataList.value = res.data
-}
-/**
- * 1: 查看
- * 2:沟通
- * 3:上传照片
- */
-function btnClick(row, type) {
-	console.log('btnClick', type, row, row.orderStatus);
-	if (type === 1 && row.orderStatus === '2') {
+		//前往沟通
 		uni.navigateTo({
-			url: `/pages_classify/pages/order/index?orderId=${row.secondOrderId}`
+			url: `/pages_orderuser/pages/talk/pages/index/index?orderId=${row.secondOrderId}`
 		});
-		return;
-	}
-	if (type === 1) {
 
-		uni.navigateTo({
-			url: `/pages_classify/pages/handle/index?orderId=${row.secondOrderId}`
-		});
-		return
 	}
-
-	//前往沟通
-	uni.navigateTo({
-		url: `/pages_orderuser/pages/talk/pages/index/index?orderId=${row.secondOrderId}`
-	});
-
-}
-provide('onClick', btnClick);
+	provide('onClick', btnClick);
 
 
-function onChange(tabItem) {
-	console.log('onChange called with tabItem:', tabItem); // 确认是否进入 onChange
-	tab.value = tabItem.value;
-	getList();
-	console.log('change', tabItem, tab.value);
-}
+	function onChange(tabItem) {
+		tab.value = tabItem.value;
+		getList();
+	}
 
 
 
-onMounted(() => {
-	getList()
-	getListData()
-})
+	onMounted(() => {
+		getList()
+		getListData()
+		getData()
+	})
 
 
-onShow(() => {
-	const params = getApp().globalData.switchTabParams || {};
-	tabKey.value = params.tabKey || 0;
-	console.log('cc', params, tabKey.value);
-	onChange(column[tabKey.value])
-	// 使用后建议清除参数,避免重复读取 
-	getApp().globalData.switchTabParams = null;
+	onShow(() => {
+		const params = getApp().globalData.switchTabParams || {};
+		tabKey.value = params.tabKey || 0;
+		onChange(column[tabKey.value])
+		// 使用后建议清除参数,避免重复读取 
+		getApp().globalData.switchTabParams = null;
 
-})
+	})
 </script>
 
 <style lang="scss" scoped>
-.classify-main {
-	height: 100vh;
-
-	.list {
-		position: fixed;
-		top: 50px;
-		bottom: 0px;
-		left: 0px;
-		right: 0px;
+	.classify-main {
+		height: 100vh;
+
+		.list {
+			position: fixed;
+			top: 50px;
+			bottom: 0px;
+			left: 0px;
+			right: 0px;
+		}
 	}
-}
 </style>

+ 68 - 53
pages/common/classify/orderlist.vue

@@ -21,7 +21,7 @@
 				<up-list-item v-for="(item, index) in dataList" :key="index">
 					<view class="list-item">
 						<!-- 左侧图片 -->
-						<image src="/static/img/dd.png" mode="aspectFill" class="item-image"></image>
+						<image :src="item.volunteerPicture" mode="aspectFill" class="item-image"></image>
 
 						<!-- 中间信息 -->
 						<view class="item-info">
@@ -34,15 +34,11 @@
 						<view class="item-right">
 							<view class="rating">评分:9.5</view>
 							<view class="status-tags">
-								<up-tag v-if="item.orderStatus == '0'" type="info">未开始</up-tag>
-								<up-tag v-else-if="item.orderStatus == '1'" type="warning">进行中</up-tag>
-								<up-tag v-else-if="item.orderStatus == '2'" type="success">已完成</up-tag>
+								{{dictSortMap[item.orderStatus]}}
 							</view>
 							<view class="Wrap-Btn">
-								<up-button type="primary" text="沟通" size="mini" shape="circle"
-									class="action-btn"></up-button>
-								<up-button type="error" text="查看" size="mini" shape="circle" class="action-btn"
-									@click="handlClick(item)"></up-button>
+							    <up-button type="primary" text="沟通" size="mini" shape="circle" class="action-btn"></up-button>
+							    <up-button type="error" text="查看" size="mini" shape="circle" class="action-btn" @click="handlClick(item)"></up-button>
 							</view>
 						</view>
 					</view>
@@ -53,42 +49,43 @@
 </template>
 
 <script setup>
-import {
-	ref,
-	onMounted
-} from "vue"
-
-// const tab = ref('')
-const userType = uni.getStorageSync('userType') //读取本地存储
-
-// 用户/志愿者 识别标识
-const userOrWorker = uni.getStorageSync('storage_data').vuex_userOrWorker //读取本地存储
-const orderStatus = ref(0)
-const column2 = [{
-	name: "全部",
-	value: "",
-},
-{
-	name: "待支付",
-	value: "1",
-},
-{
-	name: "待服务",
-	value: "2",
-},
-{
-	name: "进行中",
-	value: "3",
-},
-{
-	name: "已完成",
-	value: "4",
-},
-{
-	name: "已取消",
-	value: "5",
-}
-]
+	import {
+		ref,
+		onMounted,
+		computed
+	} from "vue"
+
+
+	const userType = uni.getStorageSync('userType') //读取本地存储
+
+	// 用户/志愿者 识别标识
+	const userOrWorker = uni.getStorageSync('storage_data').vuex_userOrWorker //读取本地存储
+	const orderStatus = ref(0)
+	const column2 = [{
+			name: "全部",
+			value: "",
+		},
+		{
+			name: "待支付",
+			value: "1",
+		},
+		{
+			name: "待服务",
+			value: "0",
+		},
+		{
+			name: "进行中",
+			value: "3",
+		},
+		{
+			name: "已完成",
+			value: "4",
+		},
+		{
+			name: "已取消",
+			value: "2",
+		}
+	]
 
 
 	const props = defineProps({
@@ -96,23 +93,41 @@ const column2 = [{
 			typeof: Array,
 			default: () => [],
 		},
+		dictSort: {
+			type: Array,
+			default: () => [], // 默认值
+		},
+		fetchData: Function, // 刷新数据的方法
 	})
 
+
 	const emits = defineEmits([
 		'fetchData'
 	])
+	
+	const dictSortMap = computed(() => {
+		let mapObj = {}
+		props.dictSort.forEach((item => {
+			mapObj[item.dictValue] = item.dictLabel
+		}))
+		return mapObj
+	})
 
-
-const handlClick = (item) => {
-	const mainOrderId = item.mainOrderId; // 获取详情id
-	uni.navigateTo({
-		url: `/pages_classify/pages/orderItem/orderdetails?mainOrderId=${mainOrderId}`
-	});
-}
+	const handlClick = (item) => {
+		const mainOrderId = item.mainOrderId; // 获取详情id
+		uni.navigateTo({
+			url: `/pages_classify/pages/orderItem/orderdetails?mainOrderId=${mainOrderId}`
+		});
+	}
+	
+	// 评论
+	const handleComment  = () =>{
+		uni.navigateTo({
+			url: `/pages_classify/pages/orderItem/userComment`
+		});
+	}
 
 	function onChange(tabItem) {
-		console.log(tabItem,'>>>>>>>>>>>>tabItem')
-		// tab.value = tabItem.value;
 		emits('fetchData', tabItem.value)
 	}
 </script>

+ 2 - 0
pages/common/orderList/listItem.vue

@@ -57,6 +57,8 @@ const props = defineProps({
         }
     },
 });
+console.log('datadata',props.data);
+
 
 const inject_click = inject('onClick');
 

+ 213 - 196
pages/index.vue

@@ -54,238 +54,255 @@
 </template>
 
 <script setup>
-import {
-	ref,
-	reactive,
-	onMounted
-} from 'vue';
-import {
-	onLoad,
-	onShow,
-	onReachBottom
-} from "@dcloudio/uni-app";
-import RankingList from '@/pages/common/rankingList/index.vue';
-import ServIces from "@/components/Services/services.vue"
-import {
-	Client
-} from "@/components/Client/new_file.vue"
-import {
-	volunteerinfolist,
-} from "@/api/volunteerDetailsApi/details.js"
-import {
-	slideshow
-} from '@/api/home.js'
-
-const total = ref(0)
-const listData = ref([])
-const rightList = ref([])
-const leftList = ref([])
-const userType = uni.getStorageSync('userType') //读取本地存储
-const globalData = ref({
-	statusBarHeight: 47,
-	navBarHeight: 91
-});
-const data = reactive({
-	address: '重庆市',
-	queryValue: ''
-})
-const list3 = ref([]);
-const ValueZone = ref([]);
-const hotList = ref([])
-
-// 分页
-const pages = ref({
-	current: 1,
-	pageSize: 10,
-	total: 0
-})
-
-
-
-const loadmoreInfo = ref({
-	status: 'loadmore',
-	loadingText: '努力加载中...',
-	loadmoreText: '点击加载更多~',
-	nomoreText: '已经到底啦~'
-})
-
-// 加载更多
-async function handleLoadmore(e) {
-	if (pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)) {
-		pages.value.current += 1;
-		loadmoreInfo.value.status = 'loading';
-		await getList();
-	} else {
-		loadmoreInfo.value.status = 'nomore';
+	import {
+		ref,
+		reactive,
+		onMounted
+	} from 'vue';
+	import {
+		provide
+	} from 'vue';
+	import {
+		onLoad,
+		onShow,
+		onReachBottom
+	} from "@dcloudio/uni-app";
+	import RankingList from '@/pages/common/rankingList/index.vue';
+	import ServIces from "@/components/Services/services.vue"
+	import {
+		Client
+	} from "@/components/Client/new_file.vue"
+	import {
+		volunteerinfolist,
+	} from "@/api/volunteerDetailsApi/details.js"
+	import {
+		slideshow
+	} from '@/api/home.js'
+	import {
+		useDict
+	} from '@/utils/dict.js';
+	
+
+	const total = ref(0)
+	const listData = ref([])
+	const rightList = ref([])
+	const leftList = ref([])
+	const list3 = ref([]);
+	const ValueZone = ref([]);
+	const hotList = ref([])
+	const userType = uni.getStorageSync('userType') //读取本地存储
+
+	const {
+		lrr_service_category
+	} = useDict('lrr_service_category');
+
+	const globalData = ref({
+		statusBarHeight: 47,
+		navBarHeight: 91
+	});
+	const data = reactive({
+		address: '重庆市',
+		queryValue: ''
+	})
+
+	// 分页
+	const pages = ref({
+		current: 1,
+		pageSize: 10,
+		total: 0,
+		serviceCategory: '',
+		// appStatus:"2",
+	})
+
+	const loadmoreInfo = ref({
+		status: 'loadmore',
+		loadingText: '努力加载中...',
+		loadmoreText: '点击加载更多~',
+		nomoreText: '已经到底啦~'
+	})
+
+	// 加载更多
+	async function handleLoadmore(e) {
+		if (pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)) {
+			pages.value.current += 1;
+			loadmoreInfo.value.status = 'loading';
+			await getList();
+		} else {
+			loadmoreInfo.value.status = 'nomore';
+		}
 	}
-}
-
 
-const getList = async () => {
-	try {
-		loadmoreInfo.value.status = 'loading';
 
-		// 请求时传递分页参数
-		const res = await volunteerinfolist({
-			pageNum: pages.value.current, // 当前页码
-			pageSize: pages.value.pageSize // 每页大小
-		});
+	const getList = async () => {
+		try {
+			loadmoreInfo.value.status = 'loading';
+
+			const params = {
+			    pageNum: pages.value.current,
+			    pageSize: pages.value.pageSize,
+			    serviceCategory: pages.value.serviceCategory || '',
+				// appStatus:pages.value.appStatus,
+			  };
+			  console.log('请求参数:', params); // 调试输出
+			
+			  const res = await volunteerinfolist(params);
+
+			if (!res || !res.rows) {
+				return;
+			}
+
+			// 判断是否已经到了最后一页
+			if (pages.value.current >= Math.ceil(res.total / pages.value.pageSize)) {
+				loadmoreInfo.value.status = 'nomore';
+			} else {
+				loadmoreInfo.value.status = 'loadmore';
+			}
+
+			// 将数据分成左右两列
+			res.rows.forEach((item, index) => {
+				index % 2 !== 0 ? leftList.value.push(item) : rightList.value.push(item);
+			});
+
+			pages.value.total = res.total;
+		} catch (error) {
+			leftList.value = [];
+			rightList.value = [];
+			loadmoreInfo.value.status = 'loadmore';
+			pages.value.total = 0;
+			console.error('Error fetching data:', error);
+		}
+	};
 
-		console.log(res, '>>>>>>>res');
 
-		if (!res || !res.rows) {
-			return;
+	onReachBottom(() => {
+		if (pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)) {
+			pages.value.current = pages.value.current + 1
+			loadmoreInfo.value.status = 'nomore'
+			getList()
 		}
+	})
 
-		// 判断是否已经到了最后一页
-		if (pages.value.current >= Math.ceil(res.total / pages.value.pageSize)) {
-			loadmoreInfo.value.status = 'nomore';
-		} else {
-			loadmoreInfo.value.status = 'loadmore';
-		}
 
-		// 将数据分成左右两列
-		res.rows.forEach((item, index) => {
-			index % 2 !== 0 ? leftList.value.push(item) : rightList.value.push(item);
-		});
 
-		pages.value.total = res.total;
-	} catch (error) {
-		leftList.value = [];
-		rightList.value = [];
-		loadmoreInfo.value.status = 'loadmore';
-		pages.value.total = 0;
-		console.error('Error fetching data:', error);
-	}
-};
+	const getBanners = async () => {
+		try {
+			const res = await slideshow(7);
+			if (res.code === 200 && res.data.picture) {
+				list3.value = res.data.picture.split(',');
+			}
 
+			const value_res = await slideshow(8);
+			if (value_res.code === 200 && value_res.data.picture) {
+				ValueZone.value = value_res.data.picture.split(',');
+			}
 
-onReachBottom(() => {
-	if (pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)) {
-		pages.value.current = pages.value.current + 1
-		loadmoreInfo.value.status = 'nomore'
-		getList()
-	}
-})
+			const hot_res = await slideshow(11);
+			if (hot_res.code === 200 && hot_res.data.picture) {
+				hotList.value = hot_res.data.picture.split(',');
+			}
+		} catch (error) {
+			console.log('error', error);
 
+		}
+	}
 
+	onShow(() => {
+		getList()
+		getBanners();
+		// getListData()
+		// 在 App.vue  中初始化 
+		uni.getSystemInfo({
+			success: (res) => {
+				const statusBarHeight = res.statusBarHeight;
+				const navBarHeight = res.platform === 'android' ? 48 : 44 + res.statusBarHeight;
+				globalData.value = {
+					statusBarHeight,
+					navBarHeight
+				};
+				console.log('statusBarHeight', statusBarHeight, navBarHeight);
+
+			}
+		});
+	})
+</script>
 
-const getBanners = async () => {
-	try {
-		const res = await slideshow(7);
-		if (res.code === 200 && res.data.picture) {
-			list3.value = res.data.picture.split(',');
+<style scoped lang="scss">
+	.main-content {
+		background: rgba(255, 255, 255, 1);
+
+		.home-banner {
+			display: flex;
+			align-items: flex-end;
+			justify-content: space-between;
+			// background: rgba(255, 255, 255, 1);
+			// background-color: #ED806A;
+			background-color: rgba(221, 60, 62, 1);
+			box-shadow: 0rpx 0rpx 0rpx rgba(0, 0, 0, 0), 0rpx 0rpx 0rpx rgba(0, 0, 0, 0), 0rpx 2.08rpx 4.17rpx rgba(0, 0, 0, 0.05);
+			padding: 20rpx 16rpx;
+			color: #fff;
+			position: fixed;
+			top: 0px;
+			left: 0px;
+			right: 0;
+			z-index: 99;
 		}
 
-		const value_res = await slideshow(8);
-		if (value_res.code === 200 && value_res.data.picture) {
-			ValueZone.value = value_res.data.picture.split(',');
+		.home-banner-left {
+			display: flex;
+			align-items: center;
+			width: 30%;
 		}
 
-		const hot_res = await slideshow(11);
-		if (hot_res.code === 200 && hot_res.data.picture) {
-			hotList.value = hot_res.data.picture.split(',');
+		.home-banner-center {
+			flex: 1;
+			font-size: 38rpx;
 		}
-	} catch (error) {
-		console.log('error', error);
 
-	}
-}
+		.home-banner-rigth {
+			width: 30%;
+		}
 
-onShow(() => {
-	getList()
-	getBanners();
+		.home-main {
+			padding: 12px 16px 0;
 
-	// 在 App.vue  中初始化 
-	uni.getSystemInfo({
-		success: (res) => {
-			const statusBarHeight = res.statusBarHeight;
-			const navBarHeight = res.platform === 'android' ? 48 : 44 + res.statusBarHeight;
-			globalData.value = { statusBarHeight, navBarHeight };
-			console.log('statusBarHeight', statusBarHeight, navBarHeight);
 
 		}
-	});
-})
-</script>
 
-<style scoped lang="scss">
-.main-content {
-	background: rgba(255, 255, 255, 1);
-
-	.home-banner {
-		display: flex;
-		align-items: flex-end;
-		justify-content: space-between;
-		// background: rgba(255, 255, 255, 1);
-		// background-color: #ED806A;
-		background-color: rgba(221, 60, 62, 1);
-		box-shadow: 0rpx 0rpx 0rpx rgba(0, 0, 0, 0), 0rpx 0rpx 0rpx rgba(0, 0, 0, 0), 0rpx 2.08rpx 4.17rpx rgba(0, 0, 0, 0.05);
-		padding: 20rpx 16rpx;
-		color: #fff;
-		position: fixed;
-		top: 0px;
-		left: 0px;
-		right: 0;
-		z-index: 99;
-	}
-
-	.home-banner-left {
-		display: flex;
-		align-items: center;
-		width: 30%;
+		.home-ranking {
+			padding: 24rpx 16px;
+		}
 	}
 
-	.home-banner-center {
-		flex: 1;
-		font-size: 38rpx;
+	.hot-box-title {
+		padding: 0 32rpx;
 	}
 
-	.home-banner-rigth {
-		width: 30%;
+	.hot-swiper {
+		padding: 24rpx 32rpx 0;
 	}
 
-	.home-main {
-		padding: 12px 16px 0;
+	.hot-box {
+		padding: 24rpx 32rpx;
+		display: grid;
+		grid-template-columns: repeat(2, 1fr);
+		gap: 8rpx;
 
 
+		.hot-item {
+			// padding: 32rpx 16rpx;
+			// border-radius: 10rpx;
+		}
 	}
 
-	.home-ranking {
-		padding: 24rpx 16px;
+	.home-grid2 {
+		margin-bottom: 32rpx;
+		background: #fff;
+		padding: 12px 0;
+		border-radius: 8px;
 	}
-}
-
-.hot-box-title {
-	padding: 0 32rpx;
-}
-
-.hot-swiper {
-	padding: 24rpx 32rpx 0;
-}
-
-.hot-box {
-	padding: 24rpx 32rpx;
-	display: grid;
-	grid-template-columns: repeat(2, 1fr);
-	gap: 8rpx;
-
 
-	.hot-item {
-		// padding: 32rpx 16rpx;
-		// border-radius: 10rpx;
+	.home-g-bgc {
+		background: #f7f7f7;
+		padding: 24rpx;
 	}
-}
-
-.home-grid2 {
-	margin-bottom: 32rpx;
-	background: #fff;
-	padding: 12px 0;
-	border-radius: 8px;
-}
-
-.home-g-bgc {
-	background: #f7f7f7;
-	padding: 24rpx;
-}
 </style>

+ 1 - 2
pages/login.vue

@@ -4,14 +4,13 @@
 			<image :src="imagePath" mode="aspectFit" style="width: 100rpx;height: 100rpx;"></image>
 			<text class="title">金邻助家</text>
 		</view>
-
 		<up-popup :show="show" mode="bottom" @close="close" @open="open">
 			<view class="popup-content">
 				<!-- 上方头像 -->
 				<up-avatar :src="src" class="avatar"></up-avatar>
 
 				<!-- 下方按钮 -->
-				<up-button type="success" shape="circle" class="button" @click="handleLogin">获取微信授权登录</up-button>
+				<up-button type="error" shape="circle" class="button" @click="handleLogin">获取微信授权登录</up-button>
 			</view>
 			<view class="xieyi text-center">
 				<text class="text-grey1">登录即代表同意</text>

+ 355 - 0
pages/mallMenu.vue

@@ -0,0 +1,355 @@
+<template>
+    <view class="u-wrap">
+        <view class="u-menu-wrap">
+            <scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop"
+                :scroll-into-view="itemId">
+                <view v-for="(item, index) in tabbar" :key="index" class="u-tab-item"
+                    :class="[current == index ? 'u-tab-item-active' : '']" @tap.stop="swichMenu(index)">
+                    <text class="u-line-1">{{ item.businessName }}</text>
+                </view>
+            </scroll-view>
+            <scroll-view :scroll-top="scrollRightTop" scroll-y scroll-with-animation class="right-box"
+                @scroll="rightScroll">
+                <view class="page-view">
+                    <view class="class-item" :id="'item' + index" v-for="(item, index) in tabbar" :key="index">
+                        <view v-for="(classItem, index) in item.children" :key="index + 'title'">
+                            <view class="item-title">
+                                <text>{{ classItem.businessName }}</text>
+                            </view>
+                            <view class="item-container">
+                                <view class="thumb-box"
+                                    v-for="(item1, index1) in (classItem.children ? classItem.children : [classItem])"
+                                    :key="index1" @click="clickMenu(item1, classItem.parentId)">
+                                    <!-- <image class="item-menu-image" src="https://cdn.uviewui.com/uview/common/classify/1/1.jpg" mode=""></image> -->
+                                    <view class="item-menu-name">{{ item1.businessName }}</view>
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+            </scroll-view>
+        </view>
+    </view>
+</template>
+<script>
+import { getTreeList } from '@/api/volunteer'
+import { volunteerSeachgetTreeList } from "@/api/volunteerDetailsApi/details.js"
+import { getVolunteerInfo } from '@/api/volunteer.js'
+export default {
+    data() {
+        return {
+            scrollTop: 0, //tab标题的滚动条位置
+            oldScrollTop: 0,
+            current: 0, // 预设当前项的值
+            menuHeight: 0, // 左边菜单的高度
+            menuItemHeight: 0, // 左边菜单item的高度
+            itemId: '', // 栏目右边scroll-view用于滚动的id
+            tabbar: [],
+
+            arr: [],
+            scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
+            timer: null, // 定时器
+            userType: uni.getStorageSync('userType')
+
+        }
+    },
+    onReady() {
+        this.getData();
+        this.getMenuItemTop()
+    },
+    methods: {
+        getData() {
+            getTreeList({ parentId: '0' }).then(res => {
+                this.tabbar = res.data;
+            })
+        },
+        // 点击左边的栏目切换
+        async swichMenu(index) {
+            if (this.arr.length == 0) {
+                await this.getMenuItemTop();
+            }
+            if (index == this.current) return;
+            this.scrollRightTop = this.oldScrollTop;
+            this.$nextTick(() => {
+                this.scrollRightTop = this.arr[index];
+                this.current = index;
+                this.leftMenuStatus(index);
+            })
+        },
+        // 获取一个目标元素的高度
+        getElRect(elClass, dataVal) {
+            new Promise((resolve, reject) => {
+                const query = uni.createSelectorQuery().in(this);
+                query.select('.' + elClass).fields({
+                    size: true
+                }, res => {
+                    // 如果节点尚未生成,res值为null,循环调用执行
+                    if (!res) {
+                        setTimeout(() => {
+                            this.getElRect(elClass);
+                        }, 10);
+                        return;
+                    }
+                    this[dataVal] = res.height;
+                    resolve();
+                }).exec();
+            })
+        },
+        // 观测元素相交状态
+        async observer() {
+            this.tabbar.map((val, index) => {
+                let observer = uni.createIntersectionObserver(this);
+                // 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
+                // 如果跟.right-box底部相交,就动态设置左边栏目的活动状态
+                observer.relativeTo('.right-box', {
+                    top: 0
+                }).observe('#item' + index, res => {
+                    if (res.intersectionRatio > 0) {
+                        let id = res.id.substring(4);
+                        this.leftMenuStatus(id);
+                    }
+                })
+            })
+        },
+        // 设置左边菜单的滚动状态
+        async leftMenuStatus(index) {
+            this.current = index;
+            // 如果为0,意味着尚未初始化
+            if (this.menuHeight == 0 || this.menuItemHeight == 0) {
+                await this.getElRect('menu-scroll-view', 'menuHeight');
+                await this.getElRect('u-tab-item', 'menuItemHeight');
+            }
+            // 将菜单活动item垂直居中
+            this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
+        },
+        // 获取右边菜单每个item到顶部的距离
+        getMenuItemTop() {
+            new Promise(resolve => {
+                let selectorQuery = uni.createSelectorQuery();
+                selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
+                    // 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
+                    if (!rects.length) {
+                        setTimeout(() => {
+                            this.getMenuItemTop();
+                        }, 10);
+                        return;
+                    }
+                    rects.forEach((rect) => {
+                        // 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
+                        this.arr.push(rect.top - rects[0].top);
+                        resolve();
+                    })
+                }).exec()
+            })
+        },
+        // 右边菜单滚动
+        async rightScroll(e) {
+            this.oldScrollTop = e.detail.scrollTop;
+            if (this.arr.length == 0) {
+                await this.getMenuItemTop();
+            }
+            if (this.timer) return;
+            if (!this.menuHeight) {
+                await this.getElRect('menu-scroll-view', 'menuHeight');
+            }
+            setTimeout(() => { // 节流
+                this.timer = null;
+                // scrollHeight为右边菜单垂直中点位置
+                let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
+                for (let i = 0; i < this.arr.length; i++) {
+                    let height1 = this.arr[i];
+                    let height2 = this.arr[i + 1];
+                    // 如果不存在height2,意味着数据循环已经到了最后一个,设置左边菜单为最后一项即可
+                    if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
+                        this.leftMenuStatus(i);
+                        return;
+                    }
+                }
+            }, 10)
+        },
+        async clickMenu(service, key) {
+            console.log(service, key);
+
+            if (this.userType == '2') {
+                const res = await getVolunteerInfo({
+                    serviceCategory: key
+                });
+                if (res.code === 200 && res.data) {
+                    //已有注册,跳转详情页面
+                    uni.navigateTo({
+                        url: `/pages_home/pages/details/index?data=${encodeURIComponent(JSON.stringify({ ...service, key }))}`
+                    })
+                    return
+                }
+                [1, 2] ? uni.navigateTo({
+                    url: `/pages_home/pages/register/index?data=${encodeURIComponent(JSON.stringify({ ...service, key }))}`
+                }) : uni.showToast({
+                    title: '敬请期待',
+                    icon: 'none'
+                })
+                return;
+
+            }
+
+            // 动态获取 parentId
+            const params = {
+                parentId: key
+            }
+            const res = await volunteerSeachgetTreeList(params)
+            // 只有第一条和第二条可以跳转
+            if (key === '1' || key === '2') {
+                uni.navigateTo({
+                    url: `/pages_home/pages/client/details?dataList=${encodeURIComponent(JSON.stringify(res.data))}`
+                });
+            } else {
+                // 其他条目提示“敬请期待”
+                uni.showToast({
+                    title: '敬请期待',
+                    icon: 'none'
+                });
+            }
+
+        }
+
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.u-wrap {
+    height: calc(100vh);
+    /* #ifdef H5 */
+    height: calc(100vh - var(--window-top));
+    /* #endif */
+    display: flex;
+    flex-direction: column;
+}
+
+.u-search-box {
+    padding: 18rpx 30rpx;
+}
+
+.u-menu-wrap {
+    flex: 1;
+    display: flex;
+    overflow: hidden;
+}
+
+.u-search-inner {
+    background-color: rgb(234, 234, 234);
+    border-radius: 100rpx;
+    display: flex;
+    align-items: center;
+    padding: 10rpx 16rpx;
+}
+
+.u-search-text {
+    font-size: 26rpx;
+    color: $u-tips-color;
+    margin-left: 10rpx;
+}
+
+.u-tab-view {
+    width: 200rpx;
+    height: 100%;
+}
+
+.u-tab-item {
+    height: 110rpx;
+    background: #f6f6f6;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 26rpx;
+    color: #444;
+    font-weight: 400;
+    line-height: 1;
+}
+
+.u-tab-item-active {
+    position: relative;
+    color: rgba(221, 94, 69, 1);
+    font-size: 30rpx;
+    font-weight: 600;
+    background: #fff;
+}
+
+.u-tab-item-active::before {
+    border-left: 4px solid rgba(221, 94, 69, 1) !important;
+}
+
+.u-tab-item-active::before {
+    content: "";
+    position: absolute;
+    border-left: 4px solid $u-primary;
+    height: 32rpx;
+    left: 0;
+    top: 39rpx;
+}
+
+.u-tab-view {
+    height: 100%;
+}
+
+.right-box {
+    background-color: rgb(250, 250, 250);
+}
+
+.page-view {
+    padding: 16rpx;
+}
+
+.class-item {
+    margin-bottom: 30rpx;
+    background-color: #fff;
+    padding: 16rpx;
+    border-radius: 8rpx;
+}
+
+.class-item:last-child {
+    min-height: 100vh;
+}
+
+.item-title {
+    font-size: 26rpx;
+    color: $u-main-color;
+    font-weight: bold;
+    text-align: center;
+}
+
+.item-menu-name {
+    font-weight: normal;
+    font-size: 28rpx;
+    color: $u-main-color;
+
+
+}
+
+.item-container {
+    // display: flex;
+    // flex-wrap: wrap;
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    gap: 12rpx;
+    margin: 24rpx 0;
+}
+
+.thumb-box {
+    // width: 33.333333%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    // margin-top: 20rpx;
+
+    background: #f5f5f5;
+    padding: 12rpx 0;
+}
+
+.item-menu-image {
+    width: 120rpx;
+    height: 120rpx;
+}
+</style>

+ 7 - 2
pages_classify/components/PositioningMap/index.vue

@@ -7,7 +7,10 @@
 
 <script setup>
 import { ref, onMounted, watch } from 'vue';
-const QQMapWX = require('./sdk/qqmap-wx-jssdk.min.js')
+import config from '@/config'
+const mapKey = config.mapKey;
+const QQMapWX = require('/static/sdk/qqmap-wx-jssdk.min.js')
+
 // 接收外部传入的地址
 const props = defineProps({
     address: {
@@ -30,10 +33,12 @@ const mapData = ref({
 let qqmapsdk = null;
 
 onMounted(() => {
+    console.log('mapKey-------------->',mapKey,QQMapWX);
+    
     mapCtx.value = wx.createMapContext('wxMapId');
 
     qqmapsdk = new QQMapWX({
-        key: 'KFEBZ-P2GKZ-A5PX4-7Q6Y7-KXOBF-XCB4C'
+        key: mapKey
     });
 
     console.log('props',props.address);

+ 177 - 37
pages_classify/pages/handle/index.vue

@@ -1,11 +1,12 @@
 <!-- 订单详情 -->
 <template>
-    <view class="order-detail">
-        <view class="service-info">
-            <PositioningMap :address="detaile.address" />
-        </view>
-        <view class="user-info order-card">
-            <view class="user-box">
+    <view>
+        <view class="order-detail">
+            <view class="service-info">
+                <PositioningMap :address="detaile.address" />
+            </view>
+            <view class="user-info order-card">
+                <!-- <view class="user-box">
                 <view class="info-list">
                     <view>被服务人员:{{ detaile.name }}</view>
                     <view style="display: flex;">服务类别: <dict-tag :options="lrr_service_category"
@@ -17,10 +18,38 @@
                     <view>备注信息:{{ detaile.remark }}</view>
 
                 </view>
+            </view> -->
+
+                <view class="handle-user">
+                    <view class="handle-user-left">
+                        <img src='/static/serverImg/mine/user.png' alt=""
+                            style="width: 96rpx;height: 96rpx;margin-right: 32rpx;">
+                        <view class="handle-user-info">
+                            <view class="user-name">{{ detaile.name }}</view>
+                            <view class="user-id" style="display: flex;">服务类别:<dict-tag :options="lrr_service_category"
+                                    :value="detaile.serviceCategory" /></view>
+                        </view>
+                    </view>
+                    <view class="user-phone" @click="onPhone(detaile.telephone)">
+                        <up-icon name="phone" color="#fff" size="25"></up-icon>
+                    </view>
+                </view>
+
+                <view class="handle-adress">
+                    <up-icon name="map" color="rgba(156, 163, 175, 1)" size="20"></up-icon>
+                    <view class="adress-text">{{ detaile.address }}</view>
+                    <up-icon name="pushpin" color="rgba(221, 94, 69, 1)" size="25"></up-icon>
+                </view>
+                <view class="handle-remark">
+                    <view class="remark-title">备注</view>
+                    <view class="remark-text">{{ detaile.remark || '暂无备注' }}</view>
+                </view>
             </view>
         </view>
-
-        <view class=" footer-g">
+        <view class="footer-g">
+            <view class="handle-start" v-if="orderStatus && serveTimes">
+                服务已开始:<text class="handle-time">{{ dateData }}</text>
+            </view>
             <Slide ref="verify" @change='change' :sliderText="slideData" />
         </view>
     </view>
@@ -28,7 +57,7 @@
 
 <script setup>
 import { ref } from 'vue';
-import { onLoad } from '@dcloudio/uni-app';
+import { onLoad, onUnload } from '@dcloudio/uni-app';
 import { getVolunteerOrderInfo, getTimesByDate, } from '@/api/volunteer.js'
 import { getAddress } from '@/api/address.js'
 import PositioningMap from '@/pages_classify/components/PositioningMap/index.vue'
@@ -37,21 +66,29 @@ import { useDict } from '@/utils/dict.js';
 import DictTag from '@/components/DictTag/index.vue'
 import { wxMakePhoneCall } from '@/utils/wxRequest.js'
 import { computed } from 'vue';
-
+import dayjs from 'dayjs'
 const fileList = ref([]);
 const orderId = ref('');
 const detaile = ref({});
 const verify = ref(null);
-
+const rateValue = ref(3)
 const {
     lrr_service_category
 } = useDict('lrr_service_category');
 
 const orderStatus = ref(false);//false:未开始服务 true:服务已开始,待上传图片
 const onPhone = (phone) => {
-    wxMakePhoneCall(phone)
+    if(phone){
+        wxMakePhoneCall(phone)
+    }
 }
 
+const dateData = ref('00:00:00');
+let timer = null;
+// const dateData = computed(()=>{
+//     return dayjs(new Date()).format("hh:mm:ss")
+// })
+
 const slideData = computed(() => {
     //服务已开始,待上传图片
     if (orderStatus.value) {
@@ -69,23 +106,30 @@ const getOrderDetail = async () => {
         // const ad_res = await getAddress(res.data.addressId);
 
         let data = res.data.secondOrder;
-        detaile.value = {...res.data.secondOrder,...res.data.address}
-        // if (ad_res.data) {
-        //     data = {
-        //         ...data,
-        //         address: ad_res.data.address,
-        //         name: ad_res.data.name,
-        //         telephone: ad_res.data.telephone,
-        //         isContagion: ad_res.data.isContagion,
-        //         haveContagion: ad_res.data.haveContagion,
-
-        //     }
-        // }
-        // detaile.value = data;
+        detaile.value = { ...res.data.secondOrder, ...res.data.address,serveTimes:res.data.secondOrder.updateTime }
         if (data.orderStatus === '1') {
 
             orderStatus.value = true;
         }
+        if (res.data.secondOrder.updateTime) {
+            timer = setInterval(() => {
+                console.log('time', res.data.secondOrder.updateTime);
+                const timeDiff = Math.abs(new Date() - new Date(res.data.secondOrder.updateTime));
+                const units = {
+                    day: Math.floor(timeDiff / (1000 * 60 * 60 * 24)),
+                    hour: Math.floor(timeDiff / (1000 * 60 * 60)),
+                    minute: Math.floor(timeDiff / (1000 * 60)),
+                    second: Math.floor(timeDiff / 1000)
+                };
+                // 默认返回完整格式 
+                const hours = units.hour % 24;
+                const minutes = units.minute % 60;
+                const seconds = units.second % 60;
+                dateData.value = `${hours}小时${minutes}分钟${seconds}秒`;
+            }, 1000);
+        }
+
+
 
         console.log('xxxx', detaile.value);
 
@@ -127,20 +171,25 @@ const change = (e) => {
             title: '操作成功',
             icon: 'success',
             success: () => {
-               setTimeout(()=>{
-                uni.redirectTo({ url: `/pages_classify/pages/order/index?orderId=${orderId.value}` });
-               },800)
+                setTimeout(() => {
+                    uni.redirectTo({ url: `/pages_classify/pages/order/index?orderId=${orderId.value}` });
+                }, 800)
             }
         })
 
     }
 }
 
+
 onLoad((options) => {
     console.log('options', options);
     orderId.value = options.orderId;
     getOrderDetail();
 
+})
+onUnload(() => {
+    timer = null;
+
 })
 </script>
 <style lang="scss" scoped>
@@ -149,7 +198,8 @@ onLoad((options) => {
     top: 0;
     left: 0;
     right: 0;
-    bottom: 0;
+    bottom: 280rpx;
+    overflow-y: auto;
     // padding: 12px 12px 24px;
     // background: rgba(245, 245, 245, 1);
 
@@ -209,15 +259,7 @@ onLoad((options) => {
         }
     }
 
-    .footer-g {
-        padding: 12px;
-        position: absolute;
-        bottom: 18px;
-        left: 0px;
-        right: 0px;
-        background: rgba(255, 255, 255, 1);
 
-    }
 
     .upload-img {
         height: 68px;
@@ -246,4 +288,102 @@ onLoad((options) => {
         color: #3c9cff;
     }
 }
+
+.handle-user {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+
+    .handle-user-left {
+        display: flex;
+        align-items: center;
+
+        .handle-user-info {
+            .user-name {
+                font-size: 32rpx;
+                font-weight: 400;
+                color: rgba(17, 24, 39, 1);
+            }
+
+            .user-id {
+                font-size: 28rpx;
+                font-weight: 400;
+                color: rgba(107, 114, 128, 1);
+            }
+
+        }
+
+    }
+
+    .user-phone {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+
+        width: 80rpx;
+        height: 80rpx;
+        border-radius: 50%;
+        background: rgba(221, 94, 69, 1);
+    }
+
+}
+
+.handle-adress {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 38rpx;
+
+    .adress-text {
+        flex: 1;
+        text-align: left;
+        padding-left: 24rpx;
+    }
+
+}
+
+.handle-remark {
+    margin-top: 30rpx;
+
+    .remark-title {
+        font-size: 28rpx;
+        font-weight: 400;
+        color: rgba(17, 24, 39, 1);
+        margin-bottom: 20rpx;
+    }
+
+    .remark-text {
+        border-radius: 16rpx;
+        background: rgba(249, 250, 251, 1);
+        padding: 32rpx;
+        font-size: 32rpx;
+        font-weight: 400;
+        line-height: 48rpx;
+        color: rgba(75, 85, 99, 1);
+    }
+}
+
+.handle-start {
+    margin-bottom: 30rpx;
+    font-size: 32rpx;
+    font-weight: 400;
+    color: rgba(75, 85, 99, 1);
+    text-align: center;
+
+    .handle-time {
+        font-size: 32rpx;
+        font-weight: 400;
+        color: rgba(17, 24, 39, 1);
+    }
+}
+
+.footer-g {
+    padding: 12px;
+    position: absolute;
+    bottom: 18px;
+    left: 0px;
+    right: 0px;
+    background: rgba(255, 255, 255, 1);
+
+}
 </style>

+ 35 - 5
pages_classify/pages/order/index.vue

@@ -34,9 +34,9 @@
 						<view class="info-item">{{ detaile.volunteerReview }}</view>
 					</view>
 				</view>
-				<view class="upload-box">
+				<view class="upload-box-see">
 					<view class="upload-img-item" v-for="(item) in volunteerPicture" :key="item.url">
-						<img class="upload-img" :src="item.url" :alt="item.fileName" srcset="">
+						<img class="upload-img-see" :src="item.url" :alt="item.fileName" srcset="">
 					</view>
 				</view>
 			</view>
@@ -48,9 +48,9 @@
 						<view  class="info-item">{{ detaile.userReview || '用户未完成评价'}}</view>
 					</view>
 				</view>
-				<view class="upload-box">
+				<view class="upload-box-see">
 					<view class="upload-img-item" v-for="(item) in userPicture" :key="item.url">
-						<img class="upload-img" :src="item.url" :alt="item.fileName" srcset="">
+						<img class="upload-img-see" :src="item.url" :alt="item.fileName" srcset="">
 					</view>
 				</view>
 			</view>
@@ -74,7 +74,8 @@
 
 
 		<view class=" footer-g" v-if="detaile.orderStatus === '1'">
-			<up-button type="primary" text="确定结束" @click="onSubmit"></up-button>
+			<!-- <up-button type="primary" text="确定结束" @click="onSubmit"></up-button> -->
+			<view class="status-btn" @click="onSubmit">确定结束</view>
 		</view>
 	</view>
 </template>
@@ -286,6 +287,10 @@ onLoad((options) => {
 	.upload-box {
 		display: flex;
 		flex-wrap: wrap;
+		// display: flex;
+		// flex-direction: column;
+		// align-items: center;
+		// justify-content: center;
 
 		.upload-img-item {
 			position: relative;
@@ -298,6 +303,15 @@ onLoad((options) => {
 			}
 		}
 	}
+	.upload-box-see {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		.upload-img-see{
+			margin-bottom: 12px;
+		}
+	}
 
 	.phone {
 		color: #3c9cff;
@@ -307,4 +321,20 @@ onLoad((options) => {
 		margin-bottom: 12px;
 	}
 }
+
+.status-btn {
+        // width: 716rpx;
+        height: 96rpx;
+        border-radius: 16rpx;
+        background: rgba(221, 94, 69, 1);
+
+        display: flex;
+        align-items: center;
+        justify-content: center;
+
+        font-size: 32rpx;
+        font-weight: 400;
+        color: rgba(255, 255, 255, 1);
+        margin-bottom: 88rpx;
+    }
 </style>

+ 89 - 50
pages_classify/pages/orderItem/orderdetails.vue

@@ -1,25 +1,27 @@
 <template>
 	<view>
-			<view class="address-container">
-			  <view class="address-header">
-			    <!-- 左侧默认标签-->
-			    <up-tag text="默认" type="error" style="width: 40rpx; height: 30rpx; margin-right: 10rpx;"></up-tag>
-			    
-			    <!-- 中间收货人信息 -->
-			    <view class="contact-info">
-			      {{listData.address.name}}
-			      {{listData.address.telephone}}
-			    </view>
-			    
-			    <!-- 右侧图标 -->
-			    <up-icon name="arrow-right" class="arrow-icon"></up-icon>
-			  </view>
-			  
-			  <!-- 下方地址信息 -->
-			  <view class="address-detail">
-			    {{listData.address.address}}
-			  </view>
+		<view class="address-container">
+			<view class="address-header">
+				<!-- 左侧默认标签-->
+				<up-tag text="默认" type="error" style="width: 40rpx; height: 30rpx; margin-right: 10rpx;"></up-tag>
+
+				<!-- 中间收货人信息 -->
+				<view class="contact-info">
+					{{listData.address.name}}
+					{{listData.address.telephone}}
+				</view>
+
+				<!-- 右侧图标 -->
+				<up-icon name="arrow-right" class="arrow-icon"></up-icon>
+			</view>
+
+			<!-- 下方地址信息 -->
+			<view class="address-detail">
+				{{listData.address.provinceName}}
+				{{listData.address.cityName}}
+				{{listData.address.districtName}}
 			</view>
+		</view>
 
 		<view>
 			<up-card title="志愿者介绍" :head-style="{ height: '80rpx', padding: '20rpx',}">
@@ -48,7 +50,8 @@
 			<up-card title="证书" :head-style="{ height: '80rpx', padding: '20rpx',}">
 				<template #body>
 					<view class="certificate">
-						<image  v-for="item in certificationPictures" :key="item" :src="item" mode="" style="width: 100%;" class="certificate-img"></image>
+						<image v-for="item in certificationPictures" :key="item" :src="item" mode=""
+							style="width: 100%;" class="certificate-img"></image>
 					</view>
 				</template>
 			</up-card>
@@ -62,22 +65,22 @@
 
 					</view>
 					<view class="list-item">
-						<image src="/static/img/dd.png" mode="aspectFill" class="item-image"></image>
-						<!-- 状态:orderStatus: 0未开始 ,1进行中,2已完成-->
-						<!-- score如果=null,显示待评价, -->
-
+						<image :src="listData.volunteerInfo.volunteerPicture" mode="aspectFill" class="item-image">
+						</image>
 						<view class="item-info">
-							<view class="info-line">类别:{{ listData.volunteerInfo.projectName }}-{{ listData.volunteerInfo.serviceSubjectName }}</view>
+							<view class="info-line">
+								类别:{{ listData.volunteerInfo.projectName }}-{{ listData.volunteerInfo.serviceSubjectName }}
+							</view>
 							<text>开始日期:{{item.workDate}}</text>
 							<text>开始时间: {{item.workStartTime}}</text>
 						</view>
-						<view class="item-right">
-							<view class="rating" v-if="score === null">待评价</view>
-							<up-tag v-if="item.orderStatus === '0'">未开始</up-tag>
-							<up-tag v-else-if="item.orderStatus === '1'">进行中</up-tag>
-							<up-tag v-else-if="item.orderStatus === '2'">已完成</up-tag>
+						<view class="status-tags">
+							{{dataList.dictLabel}}
 						</view>
 					</view>
+					<view>
+						<up-button type="primary" text="评论" @click="handlButClick"></up-button>
+					</view>
 				</up-list-item>
 			</up-list>
 		</view>
@@ -91,60 +94,94 @@
 	} from '@dcloudio/uni-app'
 	import {
 		ref,
-		computed
+		computed,
+		onMounted
 	} from "vue";
 	import {
 		orderInfomainOrderId
 	} from "@/api/userList.js";
+	import {
+		systemDictdaTalist
+	} from "@/api/userList.js"
+
 
 	const listData = ref(); //志愿者详情数据
+	const dataList = ref([])
 	const orderStatus = ref(0)
 	const score = ref(null)
 	const mainOrderId = ref(''); //志愿者ID
 
-	const certificationPictures =computed(()=>{
-		if(listData.value.volunteerInfo.certificationPicture){
+	const certificationPictures = computed(() => {
+		if (listData.value.volunteerInfo.certificationPicture) {
 			return listData.value.volunteerInfo.certificationPicture.split(',')
 		}
 		return []
 	})
 
+	//获取用户订单列表状态
+	async function getData() {
+		console.log('进入');
+		try {
+			const res = await systemDictdaTalist().catch(err => {
+				console.error('接口请求失败:', err);
+				throw err; // 重新抛出以进入 catch 块
+			});
+			dataList.value = res.rows;
+			console.log(dataList.value, 'dataList.value');
+		} catch (e) {
+			console.error('获取数据异常:', e); // 确保这里打印错误
+		}
+	}
+
+	const handlButClick = (item) => {
+		uni.navigateTo({
+			url: `/pages_classify/pages/orderItem/userComment?mainOrderId=${mainOrderId.value}&data=${encodeURIComponent(JSON.stringify(listData.value))}`
+		});
+	}
+
 	// 获取传递的参数
 	onLoad(async (options) => {
 		mainOrderId.value = options.mainOrderId;
 		const res = await orderInfomainOrderId(mainOrderId.value)
+		console.log(res, '>>>>>>>res>>>>>>>>132')
 		listData.value = res.data;
 	});
+
+	onMounted(() => {
+		getData()
+	})
 </script>
 
 <style scoped>
 	.address-container {
-	  padding: 20rpx;
-	  border: 1rpx solid #eee;
-	  border-radius: 10rpx;
+		padding: 20rpx;
+		border: 1rpx solid #eee;
+		border-radius: 10rpx;
 	}
-	
+
 	.address-header {
-	  display: flex;
-	  align-items: center;
-	  margin-bottom: 10rpx;
+		display: flex;
+		align-items: center;
+		margin-bottom: 10rpx;
 	}
-	
+
 	.contact-info {
-	  flex: 1;  /* 占据剩余空间 */
-	  font-size: 28rpx;
-	  margin-left: 25rpx;
+		flex: 1;
+		/* 占据剩余空间 */
+		font-size: 28rpx;
+		margin-left: 25rpx;
 	}
-	
+
 	.arrow-icon {
-	  margin-left: auto;  /* 将图标推到最右侧 */
+		margin-left: auto;
+		/* 将图标推到最右侧 */
 	}
-	
+
 	.address-detail {
-	  font-size: 26rpx;
-	  color: #666;
+		font-size: 26rpx;
+		color: #666;
 	}
-	
+
 	.card-container {
 		display: flex;
 		position: relative;
@@ -264,11 +301,13 @@
 		margin-top: 18rpx;
 		width: 100%;
 	}
+
 	.certificate {
 		display: flex;
 		flex-direction: column;
 
 	}
+
 	.certificate-img {
 		margin-bottom: 24rpx;
 	}

+ 152 - 0
pages_classify/pages/orderItem/userComment.vue

@@ -0,0 +1,152 @@
+<template>
+	<view>
+		<view>
+			服务评价:
+			<up-image :show-loading="true" :src="src" width="80px" height="80px" @click="click"></up-image>
+		</view>
+		<view>
+			<view>
+				<text>服务礼仪:</text>
+				<template>
+					<up-rate :count="count" v-model="IfonForm.protocolScore" count="5"></up-rate>
+				</template>
+			</view>
+			<view>
+				<text>着装整洁:</text>
+				<template>
+					<up-rate :count="count" v-model="IfonForm.clothingScore" count="5"></up-rate>
+				</template>
+			</view>
+			<view>
+				<text>专业能力:</text>
+				<template>
+					<up-rate :count="count" v-model="IfonForm.abilityScore" count="5"></up-rate>
+				</template>
+			</view>
+			<view>
+				<text>服务质量:</text>
+				<template>
+					<up-rate :count="count" v-model="IfonForm.qualityScore" count="5"></up-rate>
+				</template>
+			</view>
+		</view>
+
+		<view class="service-info order-card">
+			<!-- 回顯 -->
+			<view class="upload-box">
+				<view class="upload-img-item" v-for="(item, index) in fileList" :key="item.url">
+					<view class="delete-icon" @click="deletePic(index)"><up-icon name="close-circle-fill"
+							color="#f64a1f" size="18"></up-icon></view>
+					<img class="upload-img" :src="item.url" :alt="item.fileName" srcset="">
+				</view>
+				<img src="/static/img/upload.png" alt="" class="upload-img" @click="uploadClick('img')"
+					v-if="fileList.length < 10">
+			</view>
+		</view>
+
+		<up-textarea v-model="IfonForm.userReview" placeholder="请输入评论内容"></up-textarea>
+		<up-button type="error" text="发布" @click="handlButClick"></up-button>
+	</view>
+</template>
+
+<script setup>
+	import {
+		onMounted,
+		ref
+	} from 'vue';
+	import {
+		usersUserFinishOrder
+	} from "@/api/userList.js";
+	import {
+		onLoad,
+	} from '@dcloudio/uni-app';
+	import {
+		wxUploadFile
+	} from '@/utils/wxRequest.js'
+
+
+	const count = ref(4);
+	const fileList = ref([]);
+	const src = ref('https://cdn.uviewui.com/uview/album/1.jpg');
+
+
+
+	const IfonForm = ref({
+		protocolScore: 0, //服务礼仪
+		clothingScore: 0, //服装整洁
+		abilityScore: 0, //专业能力
+		qualityScore: 0, //服务质量
+		userReview:'',
+	})
+
+
+
+	// 删除图片
+	const deletePic = (event) => {
+		fileList.value.splice(event.index, 1);
+	};
+
+
+
+	const uploadClick = async (type) => {
+		const res = await wxUploadFile(type);
+		fileList.value = [...fileList.value, ...res];
+		console.log('xxxxres', res, fileList.value);
+	}
+
+	const handlButClick = async () => {
+		// 提取所有图片的 URL
+		const imageUrls = fileList.value.map(item => item.url);
+		const volunteerInfoId = IfonForm.value.volunteerInfoId;
+		const secondOrderId = IfonForm.value.secondOrderId; 
+		try {
+			const params = {
+				...IfonForm.value,
+				images: imageUrls,
+				volunteerInfoId: volunteerInfoId,
+				secondOrderId: secondOrderId, 
+			}
+			console.log(params, 'params>>>')
+			const res = await usersUserFinishOrder(params)
+			if (res.code == 200) {
+				uni.navigateTo({
+					url: '/pages/classify'
+				})
+				uni.showToast({
+					title: '评价提交成功',
+					icon: 'success'
+				});
+			} else {
+				console.log('提交失败')
+			}
+		} catch (e) {
+			uni.showToast({
+				title: '提交失败,请重试',
+				icon: 'error'
+			});
+		}
+
+	}
+
+onLoad(async (options) => {
+	const data = JSON.parse(decodeURIComponent(options.data));
+	console.log(data, '》》》》》》 获取传递的 listData'); // 获取传递的 listData
+
+	const secondOrderList = data.secondOrderList || [];
+	
+	// 获取第一个 secondOrderId
+	const secondOrderId = secondOrderList.length > 0 ? secondOrderList[0].secondOrderId : null;
+
+	// 如果 secondOrderId 存在,则设置到 IfonForm 中
+	if (secondOrderId) {
+		IfonForm.value.secondOrderId = secondOrderId;
+	}
+
+	// 获取 volunteerInfoId
+	const volunteerInfoId = data.volunteerInfo?.volunteerInfoId || data.volunteerInfoId;
+	IfonForm.value.volunteerInfoId = volunteerInfoId;
+});
+</script>
+
+<style>
+</style>

Разница между файлами не показана из-за своего большого размера
+ 0 - 11332
pages_home/components/cc-selectDity/areaBak240404.js


+ 0 - 332
pages_home/components/cc-selectDity/cc-selectDityBak.vue

@@ -1,332 +0,0 @@
-<template>
-	<view>
-		<!--自定义地址选择器-->
-		<view class="cc_area_mask" v-show="show == true"></view>
-		<view :class="'cc_area_view ' + (show ? 'show':'hide')">
-			<view class="cc_area_view_btns">
-				<text class="cc_area_view_btn_cancle" @tap="handleNYZAreaCancle">取消</text>
-				<text class="cc_area_view_btn_title" style="color: #393939;font-size: 32upx;">地区选择</text>
-				<text class="cc_area_view_btn_sure" @tap="handleNYZAreaSelect" :data-province="province"
-					:data-city="city" :data-area="area" style="color: #4284e5;">确定</text>
-			</view>
-			<picker-view class="cc_area_pick_view" indicator-style="height: 35px;" @change="handleNYZAreaChange"
-				:value="value">
-				<picker-view-column>
-					<view v-for="(item, index) in provinces" :key="index" class="cc_area_colum_view">{{item}}</view>
-				</picker-view-column>
-				<picker-view-column>
-					<view v-for="(item, index) in citys" :key="index" class="cc_area_colum_view">{{item}}</view>
-				</picker-view-column>
-				<picker-view-column>
-					<view v-for="(item, index) in areas" :key="index" class="cc_area_colum_view">{{item}}</view>
-				</picker-view-column>
-			</picker-view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import {
-		getProvinces,
-		getMyCity,
-		getAreas,
-		getAreasCode
-	} from "./area.js"
-
-	let index = [0, 0, 0];
-	let provinces = getProvinces();
-	let citys = getMyCity(index[0]);
-	let areas = getMyCity(index[0], index[1]);
-
-	export default {
-		mixins: [{
-			methods: {
-				setData: function(obj, callback) {
-					let that = this;
-					const handleData = (tepData, tepKey, afterKey) => {
-						tepKey = tepKey.split('.');
-						tepKey.forEach(item => {
-							if (tepData[item] === null || tepData[item] === undefined) {
-								let reg = /^[0-9]+$/;
-								tepData[item] = reg.test(afterKey) ? [] : {};
-								tepData = tepData[item];
-							} else {
-								tepData = tepData[item];
-							}
-						});
-						return tepData;
-					};
-					const isFn = function(value) {
-						return typeof value == 'function' || false;
-					};
-					Object.keys(obj).forEach(function(key) {
-						let val = obj[key];
-						key = key.replace(/\]/g, '').replace(/\[/g, '.');
-						let front, after;
-						let index_after = key.lastIndexOf('.');
-						if (index_after != -1) {
-							after = key.slice(index_after + 1);
-							front = handleData(that, key.slice(0, index_after), after);
-						} else {
-							after = key;
-							front = that;
-						}
-						if (front.$data && front.$data[after] === undefined) {
-							Object.defineProperty(front, after, {
-								get() {
-									return front.$data[after];
-								},
-								set(newValue) {
-									front.$data[after] = newValue;
-									that.$forceUpdate();
-								},
-								enumerable: true,
-								configurable: true
-							});
-
-							// #ifndef VUE3
-							that.$set(front, after, val);
-							// #endif
-
-							// #ifdef VUE3
-							Reflect.set(front, after, val);
-							// #endif
-
-						} else {
-
-							// #ifndef VUE3
-							that.$set(front, after, val);
-							// #endif
-
-							// #ifdef VUE3
-							Reflect.set(front, after, val);
-							// #endif
-						}
-					});
-					isFn(callback) && this.$nextTick(callback);
-				}
-			}
-		}],
-		data() {
-			return {
-				provinces: getProvinces(),
-				citys: getMyCity(index[0]),
-				areas: getAreas(index[0], index[1]),
-				value: [0, 0, 0]
-			};
-		},
-
-		components: {},
-		props: {
-			// 省
-			province: {
-				//控制area_select显示隐藏
-				type: String,
-				default: ''
-			},
-			// 市
-			city: {
-				//控制area_select显示隐藏
-				type: String,
-				default: ''
-			},
-			// 区
-			area: {
-				//控制area_select显示隐藏
-				type: String,
-				default: ''
-			},
-
-			show: {
-				//控制area_select显示隐藏
-				type: Boolean,
-				default: false
-			},
-			maskShow: {
-				//是否显示蒙层
-				type: Boolean,
-				default: true
-			}
-		},
-		watch: {
-			province() {
-				this.init();
-			},
-			city() {
-				this.init();
-			},
-			area() {
-				this.init();
-			}
-		},
-		mounted() {
-			let provinceIndex = this.provinces.indexOf(this.province);
-			this.citys = getMyCity(provinceIndex);
-			let cityIndex = this.citys.indexOf(this.city);
-			this.areas = getAreas(provinceIndex, cityIndex);
-			let areaIndex = this.areas.indexOf(this.area);
-
-			// 设置选择序列
-			this.value = [provinceIndex, cityIndex, areaIndex];
-			let areaCode = getAreasCode(provinceIndex, cityIndex, areaIndex);
-			//console.log(areaCode)
-			//console.log("this.value = " + JSON.stringify(this.value));
-		},
-		methods: {
-			init() {
-				//console.log(this.area)
-				let provinceIndex = this.provinces.indexOf(this.province);
-				this.citys = getMyCity(provinceIndex);
-				let cityIndex = this.citys.indexOf(this.city);
-				this.areas = getAreas(provinceIndex, cityIndex);
-				let areaIndex = this.areas.indexOf(this.area);
-
-				//获取地区编码
-				let areaCode = getAreasCode(provinceIndex, cityIndex, areaIndex);
-				// 设置选择序列
-				this.value = [provinceIndex, cityIndex, areaIndex];
-
-			},
-			handleNYZAreaChange: function(e) {
-				var that = this;
-				var value = e.detail.value;
-
-				// 更新 index
-				index = value;
-
-				// 获取对应的城市和区域数据
-				let selectCitys = getMyCity(index[0]);
-				let selectAreas = getAreas(index[0], index[1]);
-
-				// 触发 setData 更新数据
-				that.setData({
-					citys: selectCitys,
-					areas: selectAreas,
-					value: index
-				});
-
-				let areaCode = getAreasCode(index[0], index[1], index[2]);
-
-				// 触发事件
-				that.$emit("changeClick", provinces[index[0]], selectCitys[index[1]], selectAreas[index[2]], areaCode);
-
-
-			},
-
-			/**
-			 * 确定按钮的点击事件
-			 */
-			handleNYZAreaSelect: function(e) {
-				var myEventDetail = e;
-				var myEventOption = {};
-				this.$emit('sureSelectArea', {
-					detail: myEventDetail
-				}, myEventOption);
-
-				// 复原初始状态
-				index = [0, 0, 0];
-			},
-
-			handleNYZAreaCancle: function(e) {
-				var that = this;
-
-				this.$emit('hideShow', {
-					detail: false
-				});
-
-				// 复原初始状态
-				index = [0, 0, 0];
-			}
-
-
-		},
-
-
-
-
-
-
-		/**
-		 * 取消按钮的点击事件
-		 */
-		handleNYZAreaCancle: function(e) {
-			var that = this;
-			//console.log("e:" + JSON.stringify(e));
-			this.$emit('hideShow', {
-				detail: false
-			});
-			// 复原初始状态
-			index = [0, 0, 0];
-		}
-	}
-</script>
-<style scoped lang="scss">
-	.cc_area_view {
-		width: 100%;
-		position: fixed;
-		bottom: -1000px;
-		left: 0px;
-		background-color: #fff;
-		z-index: 21;
-		transition: all 0.3s;
-	}
-
-	.cc_area_pick_view {
-		height: 400px;
-		width: 100%;
-
-	}
-
-	.cc_area_colum_view {
-		line-height: 35px;
-		text-align: center;
-		font-size: 28upx;
-	}
-
-	.hide {
-		bottom: -1000upx;
-		transition: all 0.3s;
-	}
-
-	.show {
-		bottom: 0upx;
-		transition: all 0.3s;
-	}
-
-	.cc_area_view_btns {
-		background-color: #fff;
-		border-bottom: 1px solid #eeeeee;
-		font-size: 30upx;
-		padding: 18upx 0upx;
-		display: flex;
-		justify-content: space-between;
-	}
-
-	.cc_area_view_btns>text {
-		display: inline-block;
-		word-spacing: 4upx;
-		letter-spacing: 4upx;
-	}
-
-	.cc_area_view_btn_cancle {
-		color: #939393;
-		padding-right: 20upx;
-		padding-left: 25upx;
-	}
-
-	.cc_area_view_btn_sure {
-		float: right;
-		padding-left: 20upx;
-		padding-right: 25upx;
-	}
-
-	.cc_area_mask {
-		width: 100%;
-		height: 100vh;
-		background-color: rgba(28, 28, 28, 0.6);
-		position: absolute;
-		top: 0upx;
-		left: 0upx;
-		z-index: 20;
-	}
-</style>

+ 50 - 14
pages_home/components/cust-form/index.vue

@@ -28,7 +28,8 @@
                             trigger: ['blur']
                         }
                     ]" :required="true">
-                        <up-input v-model="formData.phonenumber" border="none" placeholder="请输入手机号" :disabled="!isCode"></up-input>
+                        <up-input v-model="formData.phonenumber" border="none" placeholder="请输入手机号"
+                            :disabled="!isCode"></up-input>
                     </up-form-item>
 
                     <up-form-item label="验证码" prop="code" labelWidth="94" borderBottom :rules="[
@@ -39,7 +40,7 @@
                             message: '请填写4位验证码',
                             trigger: ['blur']
                         }
-                    ]" :required="true" >
+                    ]" :required="true">
                         <up-input v-model="formData.code" border="none" placeholder="请填写验证码"></up-input>
                         <template #right>
                             <up-button @tap="getCode" :text="code_data.tips" type="success" size="mini"
@@ -61,11 +62,11 @@
                 <up-form-item v-if="item.type === 'city'" :label="item.label" :prop="item.key" borderBottom
                     labelWidth="94" :required="item.required">
                     <view @click.self="() => openCity(item)">
-                        <up-input v-model="formData[item.key]" disabled disabledColor="#ffffff"
-                            :placeholder="'请选择' + item.label" border="none"></up-input>
+                        <up-input v-model="formData[item.key]" disabled disabledColor="#ffffff" placeholder="省、市、区等地区信息"
+                            border="none"></up-input>
                     </view>
                     <template #right>
-                        <up-icon name="arrow-right"></up-icon>
+                        <up-icon name="map" size="22" @click="onCityWx(item)"></up-icon>
                     </template>
                 </up-form-item>
 
@@ -102,6 +103,11 @@ import { onMounted, reactive, ref } from "vue";
 import CcSelectDity from '@/pages_home/components/cc-selectDity/cc-selectDity.vue';
 import Picker from '@/pages_home/components/picker/index.vue'
 import { sendCode } from '@/api/sm.js';
+import {
+    onShow,
+    onUnload
+} from "@dcloudio/uni-app";
+import { splitAddress } from '@/utils/adress'
 const props = defineProps({
     column: {
         type: Array,
@@ -112,7 +118,6 @@ const props = defineProps({
         default: true
     }
 });
-
 const formData = reactive({
     sex: null,
     city: null,
@@ -211,13 +216,13 @@ async function getCode() {
             })
             const res = await sendCode(formData.phonenumber);
             console.log(res);
-            
+
             if (res.code == 200) {
                 uni.hideLoading();
                 uCode.value.start();
                 uni.$u.toast('验证码已发送');
             }
-        }else{
+        } else {
             uni.$u.toast('请输入手机号');
         }
     } else {
@@ -238,26 +243,26 @@ function startFace() {
 function setData(data) {
     console.log('setData=>data', data);
     Object.assign(formData, {
-                ...data,
-                sex: data.sex === 0 ? '男' : '女',
+        ...data,
+        sex: data.sex === 0 ? '男' : '女',
     })
     for (let i = 0; i < props.column.length; i++) {
         const element = props.column[i];
 
-       
+
         if (element.type === 'cascader') {
             const key = data[element.key]
             // const key ='7'
 
             const lable = pickerRef.value.piceInit(key);
-            console.log('element.type', lable, key,element.key);
+            console.log('element.type', lable, key, element.key);
             Object.assign(formData, {
                 [element.key]: lable,
                 [element.key + 'key']: key
             })
             console.log('eformData', formData);
-        }else {
-            
+        } else {
+
         }
 
     }
@@ -288,8 +293,38 @@ function clickPick(row) {
     pickerRef.value.show();
 
 }
+function onCityWx(row) {
+    console.log('地区选点',row);
+    wx.chooseLocation({
+        success: function (res) {
+            const result = splitAddress(res.address);
+            console.log(res,result);
+            Object.assign(cityData, {     
+                province: result.province,
+                city: result.city,
+                area:result.district,
+            })
+            Object.assign(formData, {
+                [row.key]: `${result.province}${result.city}${result.district}`,
+                address:result.detail
+            })
+        },
+        fail: function (err) {
+            console.log(err);
+            uni.showToast({
+			title:'获取地址失败',
+			icon: 'error',
+		});
+        },
+    })
+}
 
+onShow(() => {
+ 
+})
+onUnload(() => {
 
+})
 onMounted(async () => {
     const rules = {};
     for (let i = 0; i < props.column.length; i++) {
@@ -306,6 +341,7 @@ onMounted(async () => {
     console.log('uni=====>', uni);
 
 })
+
 defineExpose({
     setData,//修改表单数据值
     onSubmit,//提交表单,先校验再提交

+ 0 - 4
pages_home/components/volunteerSide/adresss.vue

@@ -70,12 +70,8 @@
 		])
 
 		function handleChane(addressId, item) {
-			console.log('当前选中的 addressId:', addressId);
 			const selectedItem = dataList.value.find(item => item.addressId === addressId);
-			 console.log('准备发送的数据:', JSON.stringify(selectedItem));
 			emits('update:modelValue', false)
-
-
 			emits('update:addressInfo',selectedItem)
 		}
 

+ 78 - 57
pages_home/pages/Volunteerside/goodsDetails.vue

@@ -75,7 +75,7 @@
 							type="daterange"></uniDatetimePickerMy>
 					</view>
 					<view>
-						<its-calendar :timeArr="doorToDoorTimeArr" :timeHostArr="timeHostArr" @getByDate="getByDate"
+						<its-calendar :businessDuration="listData.businessDuration" :timeArr="doorToDoorTimeArr" :timeHostArr="timeHostArr" @getByDate="getByDate"
 							@getByTime="getByTime"></its-calendar>
 					</view>
 				</view>
@@ -220,6 +220,7 @@
 
 	const src = ref('http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg')
 	const businessPrice = ref() //价格
+	const addressId = ref('')//用户下单地址
 	const volunteerId = ref(''); // 存储志愿者ID
 	const serviceCategory = ref('') //存储大类别
 	const businessManagementId = ref('') //具体分类id
@@ -240,16 +241,16 @@
 	const showSum = ref(false);
 	const remark = ref('') //备注
 	const radiovalue1 = ref('苹果');
+	const selectedAddress = ref(null);
+	const addressFlag = ref(false)
+
+	const addressInfo = ref(null)
 	// Radio 单选框数据
 	const radiolist1 = reactive([{
 		name: '',
 		disabled: false,
 	}, ]);
 
-	const selectedAddress = ref(null);
-	const addressFlag = ref(false)
-
-	const addressInfo = ref(null)
 
 	// 详情底部立即购买弹框
 	const buttonClick = (e) => {
@@ -292,9 +293,9 @@
 
 	// 新增:处理子组件传回的地址数据
 	const handleAddressUpdate = (newAddress) => {
+		console.log(newAddress,'接受到的数据')
 		selectedAddress.value = newAddress;
 		addressFlag.value = false; // 关闭选择器
-		console.log('selectedAddress更新后:', JSON.stringify(selectedAddress.value)); // 添加这行
 	};
 	// 详情底部底部数据
 	const options = ref([{
@@ -476,59 +477,79 @@
 		}
 		return []
 	})
+	
+	
+	
 	// 确认购买
-	const handlConfiRmpurchase = async () => {
-		// 定义要发送的数据
-		const orderData = {
-			orders: {
-				serviceOnePrice: businessPrice.value,
-				serviceTotalPrice: computeMoney.value, //需要传获取到的总价
-				serviceCategory: serviceCategory.value, //大类别参数
-				totalTimes: totalTimes.value, //点击的次数
-				serviceStartDate: "2025-04-18",
-				startTime: "8:00",
-				serviceDuration: 4,
-				paymentMethod: 1,
-				addressId: 7,
-				volunteerId: volunteerId.value,
-				remark: remark.value,
-				businessManagementId: businessManagementId.value,
-				volunteerInfoId: listData.value.volunteerInfoId,
-			},
-			workDateList: []
-		};
-		// 转换所有选择的时间
-		selectedTimes.value.forEach(item => {
-			orderData.workDateList.push({
-				workDate: item.date,
-				workStartTime: item.time
-			});
-		});
-
-		try {
-			const res = await ordersCreateOrder(orderData);
-			if (res.code == 200) {
-				uni.showToast({
-					title: '支付成功',
-					icon: 'success', // 或者 'none'
-					duration: 1500, // 显示时间,单位毫秒,默认1500
-					mask: true, // 是否显示透明蒙层,防止触摸穿透,默认false
-				});
-				setTimeout(() => {
-					uni.reLaunch({
-						url: '/pages/index'
-					});
-				}, 1500)
-			}
-		} catch (error) {
-			uni.showToast({
-				title: '支付失败',
-				icon: 'success', // 或者 'none'
-				duration: 1500, // 显示时间,单位毫秒,默认1500
-				mask: true, // 是否显示透明蒙层,防止触摸穿透,默认false
-			});
-		}
+	const handlConfiRmpurchase = () => {
+		if (!selectedAddress.value) {
+		    uni.showToast({
+		      title: '请先选择收货地址',
+		      icon: 'none',
+		      duration: 2000,
+		    });
+		    return; // 阻止购买
+		  }
+		
+		  // 如果有地址,执行购买逻辑
+		  proceedToPayment();
+		
+
+	
 	};
+	
+	const proceedToPayment = async () => {
+	  // 定义要发送的数据
+	  const orderData = {
+	  	orders: {
+	  		serviceOnePrice: businessPrice.value,
+	  		serviceTotalPrice: computeMoney.value, //需要传获取到的总价
+	  		serviceCategory: serviceCategory.value, //大类别参数
+	  		totalTimes: totalTimes.value, //点击的次数
+	  		serviceStartDate: "2025-04-18",
+	  		startTime: "8:00",
+	  		serviceDuration: 4,
+	  		paymentMethod: 1,
+	  		volunteerId: volunteerId.value,
+	  		remark: remark.value,
+	  		businessManagementId: businessManagementId.value,
+	  		volunteerInfoId: listData.value.volunteerInfoId,
+	  		addressId:selectedAddress.value.addressId,
+	  	},
+	  	workDateList: []
+	  };
+	  // 转换所有选择的时间
+	  selectedTimes.value.forEach(item => {
+	  	orderData.workDateList.push({
+	  		workDate: item.date,
+	  		workStartTime: item.time
+	  	});
+	  });
+	  try {
+	  	const res = await ordersCreateOrder(orderData);
+	  	if (res.code == 200) {
+	  		uni.showToast({
+	  			title: '支付成功',
+	  			icon: 'success', // 或者 'none'
+	  			duration: 1500, // 显示时间,单位毫秒,默认1500
+	  			mask: true, // 是否显示透明蒙层,防止触摸穿透,默认false
+	  		});
+	  		setTimeout(() => {
+	  			uni.reLaunch({
+	  				url: '/pages/index'
+	  			});
+	  		}, 1500)
+	  	}
+	  } catch (error) {
+	  	uni.showToast({
+	  		title: '支付失败',
+	  		icon: 'error', // 或者 'none'
+	  		duration: 1500, // 显示时间,单位毫秒,默认1500
+	  		mask: true, // 是否显示透明蒙层,防止触摸穿透,默认false
+	  	});
+	  }
+	};
+
 
 	onMounted(async () => {
 		await getListTime()

+ 89 - 36
pages_home/pages/client/details.vue

@@ -31,8 +31,8 @@
 			<!-- 瀑布流 -->
 			<view v-if="userType == '1'">
 				<up-waterfall v-model="flowList">
-					<template #left :listData="listData">
-						<view class="demo-warter" v-for="(item, index) in listData" :key="index"
+					<template #left>
+						<view class="demo-warter" v-for="(item, index) in leftList" :key="index"
 							@click="goToDetail(item)">
 							<up-lazy-load threshold="-450" border-radius="10" :image="item.volunteerPicture"
 								:index="index"></up-lazy-load>
@@ -51,7 +51,7 @@
 							</view>
 						</view>
 					</template>
-					<template #right :rightList="rightList">
+					<template #right>
 						<view class="demo-warter" v-for="(item, index) in rightList" :key="index"
 							@click="goToDetail(item)">
 							<up-lazy-load threshold="-450" border-radius="10" :image="item.volunteerPicture"
@@ -73,6 +73,9 @@
 					</template>
 				</up-waterfall>
 			</view>
+			<up-loadmore style="margin-top: 40rpx;" :status="loadmoreInfo.status"
+				:loadmoreText="loadmoreInfo.loadingText" :loadingText="loadmoreInfo.loadmoreText"
+				:nomoreText="loadmoreInfo.nomoreText" @loadmore="handleLoadmore" v-if="userType == 1" />
 
 		</view>
 	</view>
@@ -87,8 +90,11 @@
 		nextTick
 	} from 'vue';
 	import {
-		onLoad
-	} from '@dcloudio/uni-app';
+		onLoad,
+		onShow,
+		onReachBottom
+	} from "@dcloudio/uni-app";
+
 	import {
 		typeOptionSelect,
 		volunteerInfoList,
@@ -98,9 +104,6 @@
 		volunteerSeachgetTreeList,
 		volunteerinfolist
 	} from "@/api/volunteerDetailsApi/details.js"
-	import {
-		useRoute
-	} from 'vue-router';
 
 
 	const value1 = ref(1)
@@ -110,11 +113,17 @@
 	const flowList = ref([]); //list数据
 	const listData = ref([])
 	const rightList = ref([])
+	const currentTabs2 = ref(0)
+	const total = ref(0)
+	const serviceCategory = ref('')
+	const leftList = ref([])
+	const showDropdown = ref(false)
+
+
+
 	const defaultTab = ref({
 		dictValue: 1
 	});
-	const currentTabs2 = ref(0)
-	const total = ref(0)
 
 
 	const userType = uni.getStorageSync('userType') //读取本地存储
@@ -122,31 +131,18 @@
 	// 用户/志愿者 识别标识
 	const userOrWorker = uni.getStorageSync('storage_data').vuex_userOrWorker //读取本地存储
 
-	// 获取当前路由对象
-	const route = useRoute();
-
-	// 存储服务名称
-	const serviceName = ref('');
 
-	const showDropdown = ref(false)
 
 	function handlTabs(item, index) {
-		console.log(index, typeof index, '>>>>index');
-		console.log(item, '>>>>item');
 		currentTabs2.value = 0
 		list2.value = item.children
-
 	}
 
 	function clickList2(item, index) {
-		console.log(index, typeof index, '>>>>index99999');
-		console.log(item, '>>>>item9999');
-		// list2.value = item.children
 		currentTabs2.value = index
 	}
 
 	function toggleDropdown() {
-		console.log("点击了")
 		showDropdown.value = !showDropdown.value
 	}
 
@@ -171,38 +167,95 @@
 
 	onLoad((options) => {
 		const dataList = JSON.parse(decodeURIComponent(options.dataList));
-		// businessName
-		console.log(dataList, '>>>>>option');
-		// data.value = option;
-
+		
+		serviceCategory.value = options.serviceCategory
 		list1.value = dataList
 		list2.value = dataList[0].children
+	})
+
+	// 分页
+	const pages = ref({
+		current: 1,
+		pageSize: 10,
+		total: 0
+	})
 
+
+
+	const loadmoreInfo = ref({
+		status: 'loadmore',
+		loadingText: '努力加载中...',
+		loadmoreText: '点击加载更多~',
+		nomoreText: '已经到底啦~'
 	})
 
+
+	// 加载更多
+	async function handleLoadmore(e) {
+		if (pages.value.current < Math.ceil(pages.value.total / pages.value.pageSize)) {
+			pages.value.current += 1;
+			loadmoreInfo.value.status = 'loading';
+			await getList();
+		} else {
+			loadmoreInfo.value.status = 'nomore';
+		}
+	}
+
+
+	// const getListAdderss = async () => {
+	// 	const res = await volunteerDataList()
+	// 	console.log(res, 'volunteerDataList>>>>>>>>>>')
+	// }
+	
+
 	const getList = async () => {
 		try {
-			const res = await volunteerinfolist();
+			loadmoreInfo.value.status = 'loading';
+
+			// 请求时传递分页参数
+			const res = await volunteerinfolist({
+				pageNum: pages.value.current, // 当前页码
+				pageSize: pages.value.pageSize, // 每页大小
+				serviceCategory: serviceCategory.value
+			});
+
+			console.log(res, '>>>>>>>res');
+
 			if (!res || !res.rows) {
-				console.error('No data returned from API');
 				return;
 			}
 
-			let leftArr = [];
-			let rightArr = [];
+			// 判断是否已经到了最后一页
+			if (pages.value.current >= Math.ceil(res.total / pages.value.pageSize)) {
+				loadmoreInfo.value.status = 'nomore';
+			} else {
+				loadmoreInfo.value.status = 'loadmore';
+			}
 
-			(res.rows || []).forEach((item, index) => {
-				index % 2 !== 0 ? leftArr.push(item) : rightArr.push(item);
+			// 将数据分成左右两列
+			res.rows.forEach((item, index) => {
+				index % 2 !== 0 ? leftList.value.push(item) : rightList.value.push(item);
 			});
 
-			listData.value = leftArr;
-			rightList.value = rightArr;
-			total.value = res.rows;
+			pages.value.total = res.total;
 		} catch (error) {
+			leftList.value = [];
+			rightList.value = [];
+			loadmoreInfo.value.status = 'loadmore';
+			pages.value.total = 0;
 			console.error('Error fetching data:', error);
 		}
 	};
 
+	onReachBottom(() => {
+		if (loadmoreInfo.value.status !== 'nomore') { // 更宽松的条件
+			loadmoreInfo.value.status = 'loading';
+			pages.value.current += 1;
+			getList();
+		}
+	})
+
+
 
 	onMounted(() => {
 		getList()

+ 11 - 6
pages_home/pages/details/index.vue

@@ -118,7 +118,7 @@ const list = [
 const serveslist =[
 {
         label: "服务项目",
-        key: "businessManagementId",
+        key: "businessTierName",
     },
     {
         label: "服务时长",
@@ -329,6 +329,8 @@ onLoad((options) => {
             letter-spacing: 0rpx;
             line-height: 40rpx;
             color: rgba(17, 24, 39, 1);
+
+
         }
 
 
@@ -352,14 +354,17 @@ onLoad((options) => {
 
     .card-imgs {
         display: flex;
-        flex-wrap: wrap;
-        margin-right: 32rpx;
+        // flex-wrap: wrap;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+
     }
 
     .upload-img {
-        height: 136rpx;
-        width: 136rpx;
-        margin-right: 24rpx;
+        // height: 136rpx;
+        // width: 136rpx;
+        margin-bottom: 24rpx;
     }
 }
 </style>

+ 21 - 1
pages_home/pages/register/data.js

@@ -242,5 +242,25 @@ const education = [
     },
 ]
 
+// 健康管理
+const health  = [
+    {
+        label: "地区",
+        key: "city",
+        type: "city",
+        option: city_option,
+        rules: rules.city,
+        required:true
+    },
+    {
+        label: "详细地址",
+        key: "address",
+        type: "input",
+        rules: rules.address,
+        required:true
+    },
+]
+
+
 
-export { chatting,    education }
+export { chatting, education,health}

+ 3 - 1
pages_home/pages/register/index.vue

@@ -75,7 +75,7 @@ import { onLoad } from '@dcloudio/uni-app';
 import FontTitle from "@/pages_home/components/font-title/index.vue";
 import CustForm from "@/pages_home/components/cust-form/index";
 import UpdataImgs from "@/pages_home/components/updata-imgs/index.vue";
-import { chatting, education } from "./data";
+import { chatting, education, health } from "./data";
 import { add, getVolunteerInfo } from "@/api/volunteer";
 import { computed } from 'vue';
 import { getTreeList } from '@/api/volunteer'
@@ -157,6 +157,8 @@ const sex_status = {
 const register_column = {
 	1: chatting,
 	2: education,
+	3: health
+
 }
 
 //根据类型获取表单item 值

+ 30 - 32
pages_mine/components/setupUser/Add.vue

@@ -25,16 +25,6 @@
 				:style="{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }" labelWidth="70">
 				<up-input v-model="modelForm.telephone" border="none" placeholder="请输入手机号"></up-input>
 			</up-form-item>
-			<up-form-item label="是否有传染疾病" prop="isContagion" borderBottom labelWidth="150">
-				<up-radio-group v-model="modelForm.isContagion" placement="row" @change="handleContagionChange">
-					<up-radio :customStyle="{marginRight: '16px'}" v-for="(item, index) in isContagionOption"
-						:key="index" :label="item.name" :name="item.key"></up-radio>
-				</up-radio-group>
-			</up-form-item>
-			<up-form-item v-show="showContagionContent" label="传染病内容" prop="haveContagion" borderBottom
-				labelWidth="100">
-				<up-input v-model="modelForm.haveContagion" border="none" placeholder="请输入传染病内容"></up-input>
-			</up-form-item>
 			<up-form-item label="地区" prop="area" borderBottom @click="()=> addressShow = true" labelWidth="70">
 				<pickerAddress @change="addressChange"
 					:selectValue="[ modelForm.provinceInd, modelForm.cityInd, modelForm.districtInd ]">
@@ -46,7 +36,7 @@
 					</view>
 				</pickerAddress>
 				<template #right>
-					<up-icon name="arrow-right"></up-icon>
+					<up-icon name="map" size="22" @click="onCityWx"></up-icon>
 				</template>
 			</up-form-item>
 			<up-form-item label="地址" prop="address" borderBottom labelWidth="70">
@@ -67,6 +57,7 @@
 		computed
 	} from 'vue';
 	import pickerAddress from '@/pages_mine/components/pickerAddress/pickerAddress.vue' // 地区选择器组件
+	import { splitAddress } from '@/utils/adress'
 	const formRef = ref(null)
 	const modelForm = ref({
 		name: '',
@@ -74,8 +65,6 @@
 		label: '',
 		age: '',
 		telephone: '',
-		isContagion: '',
-		haveContagion: '',
 
 		provinceName: '', // 省
 		provinceCode: '',
@@ -91,7 +80,8 @@
 
 		address: ''
 	})
-	// 回显把provinceName,cityName,districtName字段拼接
+	
+	
 	const rulesForm = ref({
 		name: {
 			type: 'string',
@@ -140,17 +130,7 @@
 		value: 1,
 	}, ]);
 
-	const isContagionOption = ref([{
-			name: '是',
-			key: 1,
-			disabled: false,
-		},
-		{
-			name: '否',
-			key: 0,
-			disabled: false,
-		}
-	])
+
 	const relaTionsHip = ref([{
 			name: '父母'
 		}, {
@@ -219,13 +199,31 @@
 		modelForm.value.districtInd = index[2]
 
 	}
-
-	function handleContagionChange(value) {
-		showContagionContent.value = value === 1; // 显示传染病内容输入框
-		if (value === 0) {
-			modelForm.value.haveContagion = ''; // 清空输入框
-		}
-	}
+	function onCityWx(row) {
+    console.log('地区选点',row);
+    wx.chooseLocation({
+        success: function (res) {
+            const result = splitAddress(res.address);
+            console.log(res,result);
+            modelForm.value.provinceName = result.province
+			modelForm.value.cityName = result.city
+			modelForm.value.districtName = result.district
+			modelForm.value.address = result.detail
+			modelForm.value.longitude =res.longitude
+			modelForm.value.latitude = res.latitude
+
+
+        },
+        fail: function (err) {
+            console.log(err);
+            uni.showToast({
+			title:'获取地址失败',
+			icon: 'error',
+		});
+        },
+    })
+}
+	
 	// 预留校验函数
 	function handleVerify() {
 		// formRef.value

+ 45 - 58
pages_mine/pages/selectAddress/edit.vue

@@ -25,16 +25,6 @@
 				:style="{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }" labelWidth="70">
 				<up-input v-model="modelForm.telephone" border="none" placeholder="请输入手机号"></up-input>
 			</up-form-item>
-			<up-form-item label="是否有传染疾病" prop="isContagion" borderBottom labelWidth="150">
-				<up-radio-group v-model="modelForm.isContagion" placement="row" @change="handleContagionChange">
-					<up-radio :customStyle="{marginRight: '16px'}" v-for="(item, index) in isContagionOption"
-						:key="index" :label="item.name" :name="item.key"></up-radio>
-				</up-radio-group>
-			</up-form-item>
-			<up-form-item v-show="showContagionContent" label="传染病内容" prop="haveContagion" borderBottom
-				labelWidth="100">
-				<up-input v-model="modelForm.haveContagion" border="none" placeholder="请输入传染病内容"></up-input>
-			</up-form-item>
 			<up-form-item label="地区" prop="area" borderBottom @click="()=> addressShow = true" labelWidth="70">
 				<pickerAddress @change="addressChange"
 					:selectValue="[ modelForm.provinceInd, modelForm.cityInd, modelForm.districtInd ]">
@@ -58,7 +48,8 @@
 		<up-action-sheet :show="labelFlag" :actions="relaTionsHip" @select="sexSelectsHip"
 			@close="labelFlag = false"></up-action-sheet>
 		<view class="Wrapper-Btn">
-			<up-button @click="handleQux" type="error" :plain="true" :hairline="true" text="取消" :customStyle="hadlClickEdit"></up-button>
+			<up-button @click="handleQux" type="error" :plain="true" :hairline="true" text="取消"
+				:customStyle="hadlClickEdit"></up-button>
 			<up-button type="error" @click="handleSubmit" text="编辑" :customStyle="hadlClickEdit" />
 		</view>
 	</view>
@@ -70,6 +61,7 @@
 		reactive,
 		computed,
 	} from 'vue';
+
 	import {
 		onLoad
 	} from '@dcloudio/uni-app';
@@ -80,7 +72,7 @@
 
 	const formRef = ref(null)
 
-	// 获取页面传递的参数
+
 	// 获取页面传递的参数
 	onLoad((options) => {
 		if (options) {
@@ -90,18 +82,15 @@
 			options.provinceName = decodeURIComponent(decodeURIComponent(options.provinceName || ''));
 			options.name = decodeURIComponent(decodeURIComponent(options.name || ''));
 			options.address = decodeURIComponent(decodeURIComponent(options.address || ''));
-			options.haveContagion = decodeURIComponent(decodeURIComponent(options.haveContagion || ''));
 			modelForm.value = {
 				...modelForm.value,
 				...options,
 				sex: options.sex ? Number(options.sex) : '',
 				age: options.age ? Number(options.age) : '',
-				isContagion: options.isContagion ? Number(options.isContagion) : '',
 				provinceName: options.provinceName || '',
 				cityName: options.cityName || '',
 				districtName: options.districtName || '',
 			};
-			showContagionContent.value = options.isContagion === 1;
 		}
 	});
 
@@ -111,8 +100,6 @@
 		label: '',
 		age: '',
 		telephone: '',
-		isContagion: '',
-		haveContagion: '',
 
 		provinceName: '', // 省
 		provinceCode: '',
@@ -166,8 +153,7 @@
 	let labelFlag = ref(false)
 	let addressShow = ref(false)
 	let index = ref(0)
-	// 新增一个响应式变量,控制传染病内容的显示
-	const showContagionContent = ref(false);
+
 
 	const sexOptions = ref([{
 		name: '男',
@@ -177,17 +163,6 @@
 		value: 1,
 	}, ]);
 
-	const isContagionOption = ref([{
-			name: '是',
-			key: 1,
-			disabled: false,
-		},
-		{
-			name: '否',
-			key: 0,
-			disabled: false,
-		}
-	])
 	const relaTionsHip = ref([{
 			name: '父母'
 		}, {
@@ -236,29 +211,42 @@
 		labelFlag.value = false;
 	}
 
-	function addressChange(info) {
-
-		console.log(info, '>>>>data');
-
-		const {
-			data,
-			code,
-			index
-		} = info
-
-		modelForm.value.provinceName = data[0]
-		modelForm.value.provinceCode = code[0]
-		modelForm.value.provinceInd = index[0]
-
-		modelForm.value.cityName = data[1]
-		modelForm.value.cityCode = code[1]
-		modelForm.value.cityInd = index[1]
-
-		modelForm.value.districtName = data[2]
-		modelForm.value.districtCode = code[2]
-		modelForm.value.districtInd = index[2]
-	}
-
+function addressChange(info) {
+    console.log(info, '>>>>data');
+    
+    if (!info || !info.data) {
+        console.error('Invalid address change info:', info);
+        return;
+    }
+    
+    if (!Array.isArray(info.data) || info.data.length < 3) {
+        console.error('Invalid address data:', info.data);
+        return;
+    }
+    
+    const code = Array.isArray(info.code) ? info.code : ['', '', ''];
+    
+    let indexArray;
+    if (Array.isArray(info.index)) {
+        indexArray = info.index;
+    } else if (info.index && typeof info.index[Symbol.iterator] === 'function') {
+        indexArray = Array.from(info.index);
+    } else {
+        indexArray = [0, 0, 0];
+    }
+    
+    modelForm.value.provinceName = info.data[0] || '';
+    modelForm.value.provinceCode = code[0] || '';
+    modelForm.value.provinceInd = indexArray[0] || 0;
+    
+    modelForm.value.cityName = info.data[1] || '';
+    modelForm.value.cityCode = code[1] || '';
+    modelForm.value.cityInd = indexArray[1] || 0;
+    
+    modelForm.value.districtName = info.data[2] || '';
+    modelForm.value.districtCode = code[2] || '';
+    modelForm.value.districtInd = indexArray[2] || 0;
+}
 	// 提交编辑
 	async function handleSubmit() {
 		try {
@@ -269,7 +257,6 @@
 			const submitData = {
 				...modelForm.value,
 				sex: modelForm.value.sex,
-				isContagion: modelForm.value.isContagion
 			};
 
 			// 3. 显示加载中提示(可选)
@@ -301,7 +288,7 @@
 
 				// 7. 跳转页面
 				uni.navigateTo({
-					url:'/pages_mine/pages/selectAddress/index'
+					url: '/pages_mine/pages/selectAddress/index'
 				});
 			} else {
 				uni.showToast({
@@ -318,9 +305,9 @@
 			});
 		}
 	}
-	const handleQux = () =>{
+	const handleQux = () => {
 		uni.navigateBack({
-			delta:1
+			delta: 1
 		})
 	}
 	const hadlClickEdit = {
@@ -330,7 +317,7 @@
 </script>
 
 <style scoped>
-	.Wrapper-Btn{
+	.Wrapper-Btn {
 		display: flex;
 		justify-content: center;
 		align-items: center;

+ 1 - 0
pages_mine/pages/selectAddress/index.vue

@@ -141,6 +141,7 @@
 	  padding: 24rpx 0;
 	  border-bottom: 1rpx solid #f0f0f0;
 	  position: relative; /* 可选:用于绝对定位 */
+	  width: 100%;
 	}
 	.radio-group {
 		flex-shrink: 0;

+ 49 - 19
pages_mine/pages/wallet/index.vue

@@ -8,7 +8,7 @@
             <view class="wallet-box-top">
                 <view class="flex-center-column">
                     <text class="wallet-box-title">钱包总额(元)</text>
-                    <view class="wallet-box-price">2000</view>
+                    <view class="wallet-box-price">{{ data.balance }}</view>
                 </view>
                 <view>
                     <view class="wallet-box-btn1 flex-center" @click="onWithdrawal">提现</view>
@@ -19,15 +19,15 @@
             <view class="wallet-box-bottom">
                 <view class="flex-center-column">
                     <text class="wallet-box-title">可提现(元)</text>
-                    <view class="wallet-box-price2">2000</view>
+                    <view class="wallet-box-price2">{{ data.balance }}</view>
                 </view>
                 <view class="flex-center-column">
                     <text class="wallet-box-title">待入账(元)</text>
-                    <view class="wallet-box-price2">2000</view>
+                    <view class="wallet-box-price2">{{  data.orderFrozenBalance }}</view>
                 </view>
                 <view class="flex-center-column">
                     <text class="wallet-box-title">银行卡(张)</text>
-                    <view class="wallet-box-price2">2</view>
+                    <view class="wallet-box-price2">0</view>
                 </view>
             </view>
         </view>
@@ -44,23 +44,28 @@
 <script setup>
 import { ref } from 'vue';
 import BankItem from '@/pages_mine/components/bank-item/bank-item.vue';
+import { getVolunteerAccountInfo } from "@/api/mine";
+import {
+	onShow
+} from '@dcloudio/uni-app';
 const bankList = ref([
-    {
-        bankCode: 'ABC',
-        bankName: '中国农业银行',
-        cardType: '储蓄卡',
-        cardCode: '5106365986893',
-        color: 'linear-gradient(135deg, rgba(43, 102, 248, 1) 0%, rgba(27, 69, 178, 1) 100%), rgba(0, 0, 0, 0)'
-    },
-    {
-        bankCode: 'ABC',
-        bankName: '中国农业银行',
-        cardType: '储蓄卡',
-        cardCode: '5106365986893',
-        color: 'linear-gradient(135deg, rgba(43, 102, 248, 1) 0%, rgba(27, 69, 178, 1) 100%), rgba(0, 0, 0, 0)'
-    },
+    // {
+    //     bankCode: 'ABC',
+    //     bankName: '中国农业银行',
+    //     cardType: '储蓄卡',
+    //     cardCode: '5106365986893',
+    //     color: 'linear-gradient(135deg, rgba(43, 102, 248, 1) 0%, rgba(27, 69, 178, 1) 100%), rgba(0, 0, 0, 0)'
+    // },
+    // {
+    //     bankCode: 'ABC',
+    //     bankName: '中国农业银行',
+    //     cardType: '储蓄卡',
+    //     cardCode: '5106365986893',
+    //     color: 'linear-gradient(135deg, rgba(43, 102, 248, 1) 0%, rgba(27, 69, 178, 1) 100%), rgba(0, 0, 0, 0)'
+    // },
 ])
-
+const userType = uni.getStorageSync('userType') //读取本地存储
+const data = ref({});
 const onWithdrawal = () => {
     uni.navigateTo({
         url: '/pages_mine/pages/withdrawal/index'
@@ -85,6 +90,31 @@ const onBankCardDetails = (record) => {
     })
 }
 
+const init = async() => {
+	try {
+		uni.showLoading({
+			title: '数据加载中...'
+		});
+
+		if(userType === 2){
+			const res = await getVolunteerAccountInfo();
+			data.value =res.data;			
+		}
+	} catch (error) {
+		console.log('error', error);
+		uni.showToast({
+			title: error.msg,
+			icon: 'error',
+		});
+	} finally {
+		uni.hideLoading();
+	}
+}
+
+onShow(()=>{
+    init();
+})
+
 </script>
 
 <style lang="scss" scoped>

BIN
static/Tioimages/15-旅游服务-01.png


BIN
static/Tioimages/休闲娱乐.png


BIN
static/Tioimages/其他服务.png


BIN
static/Tioimages/旅游服务.png


BIN
static/Tioimages/父母体检.png


BIN
static/Tioimages/福利商城_购物车.png


BIN
static/Tioimages/购物商城.png


BIN
static/images/tabbar/class.png


BIN
static/images/tabbar/class_.png


BIN
static/images/tabbar/home.png


BIN
static/images/tabbar/home_.png


BIN
static/images/tabbar/mine.png


BIN
static/images/tabbar/mine_.png


BIN
static/images/tabbar/work.png


BIN
static/images/tabbar/work_.png


pages_classify/components/PositioningMap/sdk/qqmap-wx-jssdk.js → static/sdk/qqmap-wx-jssdk.js


pages_classify/components/PositioningMap/sdk/qqmap-wx-jssdk.min.js → static/sdk/qqmap-wx-jssdk.min.js


+ 61 - 0
utils/adress.js

@@ -0,0 +1,61 @@
+import config from '@/config'
+const mapKey = config.mapKey;
+const appName = config.appName;
+
+/**
+ * 腾讯位置服务地图选点
+ */
+const chooseLocationInit = () => {
+    const key = mapKey; //使用在腾讯位置服务申请的key
+    const referer = appName; //调用插件的app的名称
+    wx.navigateTo({
+        url: `plugin://chooseLocation/index?key=${key}&referer=${referer}`,
+    });
+
+}
+
+/**
+ * 腾讯位置服务城市选择器
+ * @param {*} city 城市名称
+ */
+const citySelectorNavigateTo = (city) => {
+    const key = mapKey; // 使用在腾讯位置服务申请的key
+    const referer = appName; // 调用插件的app的名称
+    const hotCitys = '重庆'; // 用户自定义的的热门城市
+
+    wx.navigateTo({
+        url: `plugin://citySelector/index?key=${key}&referer=${referer}&hotCitys=${hotCitys}`,
+    })
+}
+
+function splitAddress(address) {
+    // 处理直辖市(如北京市朝阳区)
+    const directCityRegex = /^(北京|天津|上海|重庆)(市)?(.+?区)/;
+    const directMatch = address.match(directCityRegex); 
+    if (directMatch) {
+      return {
+        province: directMatch[1],
+        city: directMatch[1]+'市',
+        district: directMatch[3],
+        detail: address.replace(directCityRegex,  '')
+      }
+    }
+  
+    // 常规拆分逻辑 
+    const provinceRegex = /(.+?(省|自治区|行政区|特别行政区))/;
+    const cityRegex = /(.+?(市|自治州|州|盟))/;
+    
+    const province = address.match(provinceRegex)?.[1]  || '';
+    const city = address.replace(province,  '').match(cityRegex)?.[1] || '';
+    const remaining = address.replace(province  + city, '');
+    const district = remaining.match(/(.+?( 区|县|市|旗))/)?.[1] || '';
+    const detail = remaining.replace(district,  '').trim();
+   
+    return {province, city, district, detail};
+  }
+
+export  { 
+    chooseLocationInit,
+    citySelectorNavigateTo,
+    splitAddress
+}