Browse Source

fix:冲突修改

贾宇博 3 weeks ago
parent
commit
10ee610437

+ 9 - 0
api/userList.js

@@ -39,4 +39,13 @@ export function usersUserFinishOrder(data) {
 		method: 'post',
 		data:data
 	})
+}
+
+// 用户详情小订单
+export function userdictDataList(params) {
+	return request({
+		url: `/system/dict/data/list`,
+		method: 'get',
+		params: params
+	})
 }

+ 4 - 4
components/Client/new_file.vue

@@ -5,8 +5,8 @@
 				<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">
-					<up-grid-item v-for="(item, index) in serveiceList.slice(0,10)" :key="index"
+				<up-grid :border="false" col="4">
+					<up-grid-item v-for="(item, index) in serveiceList.slice(0,12)" :key="index"
 						:custom-style="custmoStyle" @click="handleGridClick(item)">
 						<view class="grid-box">
 							<view class="grid-icon">
@@ -18,8 +18,8 @@
 				</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"
+				<up-grid :border="false" col="4">
+					<up-grid-item v-for="(item, index) in serveiceList.slice(12,serveiceList.length)" :key="index"
 						:custom-style="custmoStyle" @click="handleGridClick(item)">
 						<view class="grid-box">
 							<view class="grid-icon">

+ 3 - 2
components/Services/services.vue

@@ -62,9 +62,10 @@
 			serviceCategory: item.serviceCategory, // 获取 serviceCategory
 			businessManagementId: item.businessManagementId, //获取 businessManagementId
 		};
-
+		const data = encodeURIComponent(JSON.stringify(params))
+		console.log(data, '>>>>>data');
 		uni.navigateTo({
-			url: `/pages_home/pages/Volunteerside/goodsDetails?params=${JSON.stringify(params)}`
+			url: `/pages_home/pages/Volunteerside/goodsDetails?params=${data}`
 		});
 	}
 </script>

+ 269 - 0
components/its-calendar/its-calendar - 副本.vue

@@ -0,0 +1,269 @@
+<template>
+	<view>
+		<view class="calendar">
+			<view class="calendar_day">
+				<view class="day_x" :style="{'color': (day_index == index ? '#FE3B3C' : '')}"
+					v-for="(item, index) in dayArr" :key="index" @click.stop="dayList(item,index)">
+					<view class="day_x_a">{{item.weeks}}</view>
+					<view class="day_x_b">{{item.days}}</view>
+				</view>
+			</view>
+			<view class="calendar_time">
+				<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>
+		<!-- <view class="sub" @click="sub()">
+			立即预约
+		</view> -->
+	</view>
+</template>
+<script>
+	export default {
+		props: {
+			timeArr: {
+				type: Array,
+				default: () => []
+			},
+
+			timeHostArr: {
+				type: Array,
+				default: () => []
+			},
+			businessDuration: {
+				type: Number,
+				default: 0
+			} // 从父组件接收的服务时长(分钟)
+		},
+		data() {
+			return {
+				dayArr: [],
+				day_index: 0,
+				host_index: '',
+				nowTimes: new Date().getTime(), // 只保留一个定义
+				disableAfterTime: null,
+				selectedTime: null,
+				selectedDay: null // 新增:记录选择的日期
+			}
+		},
+		watch: {
+			timeArr: {
+				handler(newVal) {
+
+					let dateArr = newVal.map(item => {
+						let day = new Date(item)
+						const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
+						return {
+							weeks: daysOfWeek[day.getDay()],
+							days: item.slice(5)
+						}
+					})
+					this.dayArr = dateArr
+				},
+				immediate: true
+			}
+		},
+		mounted() {},
+		methods: {
+			handleTimeClick(item) {
+				if (!this.shouldDisable(item)) {
+					this.hosts(item);
+				}
+			},
+			// 点击日期
+			dayList(e, index) {
+				this.day_index = index
+				this.$emit('getByDate', this.timeArr[index])
+			},
+			// 转换时间戳为毫秒
+			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;
+			},
+			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('请选择时间');
+				} else {
+					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);
+				let h = date.getHours();
+				h = h < 10 ? ('0' + h) : h; // 小时补0
+				let m = date.getMinutes();
+				m = m < 10 ? ('0' + m) : m; // 分钟补0
+				return h + ':' + m;
+			},
+			time(data, type) {
+				let date = new Date(data * 1000);
+				let y = date.getFullYear();
+				let MM = date.getMonth() + 1;
+				MM = MM < 10 ? ('0' + MM) : MM; // 月补0
+				let d = date.getDate();
+				d = d < 10 ? ('0' + d) : d; // 天补0
+				let h = date.getHours();
+				h = h < 10 ? ('0' + h) : h; // 小时补0
+				let m = date.getMinutes();
+				m = m < 10 ? ('0' + m) : m; // 分钟补0
+				let s = date.getSeconds();
+				s = s < 10 ? ('0' + s) : s; // 秒补0
+				if (type == 'yymmdd') {
+					return y + '-' + MM + '-' + d;
+				} else if (type == 'hhmmss') {
+					return h + ':' + m + ':' + s;
+				} else {
+					return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s;
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #F4F4F4;
+	}
+
+	.calendar {
+		width: 710rpx;
+		height: 460rpx;
+		background-color: #FFFFFF;
+		margin: 20rpx auto 10rpx;
+		border-radius: 8rpx;
+	}
+
+	.calendar_day {
+		display: flex;
+		width: 100%;
+		height: 120rpx;
+
+		.day_x {
+			display: flex;
+			flex-flow: column nowrap;
+			justify-content: center;
+			align-items: center;
+			width: 20%;
+			height: 100%;
+			font-size: 30rpx;
+			color: #333333;
+		}
+	}
+
+	.calendar_time {
+		display: flex;
+		width: 100%;
+		height: 448rpx;
+		flex-flow: row wrap;
+		align-content: flex-start;
+		margin: 20rpx 0;
+		overflow-y: auto;
+
+		.time_x {
+			display: flex;
+			flex-flow: row;
+			justify-content: center;
+			align-items: center;
+			width: 20%;
+			height: 54rpx;
+			border-radius: 26rpx;
+			margin: 10rpx 0;
+			font-size: 30rpx;
+			color: #333333;
+
+			display: flex;
+			flex-direction: column;
+
+			.hasRe-text {
+				font-size: 20rpx;
+				color: #999999;
+			}
+		}
+
+		.time_x_sty {
+			background-color: #FFE97B;
+			color: #000000 !important;
+		}
+	}
+
+	.sub {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		width: 710rpx;
+		height: 100rpx;
+		border-radius: 50rpx;
+		margin: 30rpx auto;
+		color: #FFFFFF;
+		font-size: 36rpx;
+		background-color: #FE3B3C;
+	}
+
+
+
+	.time_x {
+	  /* 正常状态样式 */
+	  &.disabled-time {
+	    background-color: #f2f2f2;
+	    color: #999999;
+	    pointer-events: none;
+	  }
+	  
+	  &.time_x_sty {
+	    background-color: #FFE97B;
+	    color: #000000;
+	  }
+	}
+</style>

+ 69 - 15
components/its-calendar/its-calendar.vue

@@ -11,8 +11,8 @@
 			<view class="calendar_time">
 				<view class="time_x" 
 				  :class="{
-				    'time_x_sty': host_index == item?.timeStamp, 
-				    'disabled-time': shouldDisable(item) 
+				    'time_x_sty': item?.checked, 
+				    'disabled-time': item?.disabled
 				  }" 
 				  v-for="(item, index) in timeHostArr[day_index]" 
 				  :key="index"
@@ -52,13 +52,12 @@
 				nowTimes: new Date().getTime(), // 只保留一个定义
 				disableAfterTime: null,
 				selectedTime: null,
-				selectedDay: null // 新增:记录选择的日期
+				selectedDay: null ,// 新增:记录选择的日期
 			}
 		},
 		watch: {
 			timeArr: {
 				handler(newVal) {
-
 					let dateArr = newVal.map(item => {
 						let day = new Date(item)
 						const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
@@ -72,12 +71,48 @@
 				immediate: true
 			}
 		},
-		mounted() {},
+		mounted() {
+		},
 		methods: {
 			handleTimeClick(item) {
-				if (!this.shouldDisable(item)) {
-					this.hosts(item);
+				console.log(this.businessDuration, '>>>>>>businessDuration');
+				// 禁用点击,取消点击触发
+				if (item.disabled) return false
+				
+				// if (!this.shouldDisable(item)) {
+				// 	item.checked = !item.checked
+				// 	this.hosts(item);
+				// }
+				
+				// 计算服务时间秒
+				const seconds = this.businessDuration * 60
+				// 计算最终服务时间
+				const endTimestamp = (item.timeStamp + seconds)
+				
+				// 禁用区域/释放区域数据
+				const filteredSlots = this.timeHostArr[this.day_index].filter(i => {
+				   return (i.timeStamp > item.timeStamp && 
+				          i.timeStamp <= endTimestamp)
+				 })
+				 
+				 console.log(filteredSlots, '>>>>>filteredSlots');
+				if (!item.checked) {
+					// 计算禁用时间区域
+					 filteredSlots.forEach(v => {
+						v.disabled = true
+					 })
+					 item.checked = true
+				} else {
+					// 释放禁用区域
+					filteredSlots.forEach(v => {
+						if (v.hasReservation !== 1) v.disabled = false
+					})
+					item.checked = false
 				}
+				
+				
+				
+				this.hosts(item);
 			},
 			// 点击日期
 			dayList(e, index) {
@@ -91,20 +126,39 @@
 
 			shouldDisable(item) {
 				if (!item) return true;
+				
+				// 已预约
+				if (item.hasReservation === 1) 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;
-				}
+				// // // 选择后的时间段
+				// if (this.selectedTime) {
+				// 	return itemTime > this.selectedTime &&
+				// 		itemTime <= this.disableAfterTime;
+				// }
+				
+				// let flat = false
+				
+				// this.timeHostArr[this.day_index].forEach(i => {
+				// 	if (i.checked) {
+				// 		const itemTime2 = this.ensureMillisecond(item.timeStamp);
+				// 		flat = itemTime2 > this.selectedTime &&
+				// 		itemTime2 <= this.disableAfterTime;
+				// 	}
+				// })
+				
+				
+				// if (!item.checked) {
+				// 	return itemTime > this.selectedTime &&
+				// 		itemTime <= this.disableAfterTime;
+				// }
+				
 
 				return false;
 			},

+ 4 - 6
pages/index.vue

@@ -114,7 +114,6 @@
 	})
 	
 const cityClick = () => {
-	console.log('cityClick', data.address);
 	citySelectorNavigateTo(data.address)
 }
 
@@ -148,8 +147,6 @@ const cityClick = () => {
 			    serviceCategory: pages.value.serviceCategory || '',
 				// appStatus:pages.value.appStatus,
 			  };
-			  console.log('请求参数:', params); // 调试输出
-			
 			  const res = await volunteerinfolist(params);
 
 			if (!res || !res.rows) {
@@ -212,7 +209,6 @@ const cityClick = () => {
 	}
 
 	onShow(() => {
-	getList()
 	getBanners();
 
 	// 在 App.vue  中初始化 
@@ -221,19 +217,21 @@ const cityClick = () => {
 			const statusBarHeight = res.statusBarHeight;
 			const navBarHeight = res.platform === 'android' ? 48 : 44 + res.statusBarHeight;
 			globalData.value = { statusBarHeight, navBarHeight };
-			console.log('statusBarHeight', statusBarHeight, navBarHeight);
 
 		}
 	});
 
 	if (citySelector) {
 		const selectedCity = citySelector.getCity(); // 如果点击确认选点按钮,则返回选点结果对象,否则返回null
-		console.log('citySelector', selectedCity,selectedCity.name)
 		data.address = selectedCity.name;
 	}
 
 })
 
+onMounted(() => {
+	getList()
+})
+
 onUnload(() => {
 	if (citySelector) {
 		// 页面卸载时设置插件选点数据为null,防止再次进入页面,geLocation返回的是上次选点结果

+ 1 - 1
pages/mallMenu.vue

@@ -19,7 +19,7 @@
                                 <view class="thumb-box"
                                     v-for="(item1, index1) in  (item.children?item.children:[item])"
                                     :key="index1" @click="clickMenu(item,item1)">
-                                    <image class="item-menu-image" :src="item1.business_icon" mode=""></image>
+                                    <image class="item-menu-image" :src="item1.businessIcon"></image>
                                     <view class="item-menu-name">{{ item1.businessName }}</view>
                                 </view>
                             </view>

+ 11 - 0
pages_classify/pages/orderItem/orderdetails.vue

@@ -73,6 +73,9 @@
 							</view>
 							<text>开始日期:{{item.workDate}}</text>
 							<text>开始时间: {{item.workStartTime}}</text>
+							
+							
+							{{dictSortMap[item.orderStatus]}}
 						</view>
 						<view class="status-tags">
 							{{dataList.dictLabel}}
@@ -117,6 +120,14 @@
 		}
 		return []
 	})
+	
+	const dictSortMap = computed(() => {
+		let mapObj = {}
+		dataList.value.forEach((item => {
+			mapObj[item.dictValue] = item.dictLabel
+		}))
+		return mapObj
+	})
 
 	//获取用户订单列表状态
 	async function getData() {

+ 64 - 53
pages_home/pages/Volunteerside/goodsDetails.vue

@@ -75,7 +75,7 @@
 							type="daterange"></uniDatetimePickerMy>
 					</view>
 					<view>
-						<its-calendar :businessDuration="listData.businessDuration" :timeArr="doorToDoorTimeArr" :timeHostArr="timeHostArr" @getByDate="getByDate"
+						<its-calendar v-if="show" :businessDuration="listData.businessDuration" :timeArr="doorToDoorTimeArr" :timeHostArr="timeHostArr" @getByDate="getByDate"
 							@getByTime="getByTime"></its-calendar>
 					</view>
 				</view>
@@ -114,17 +114,17 @@
 						</view>
 						<text v-else style="margin-left: 8px; font-size: 14px;">请选择服务地址</text>
 					</view>
-					<view class="card-container" v-for="(item, index) in computeClickTime" :key="index">
+					<view class="card-container" v-for="(item, index) in selectedTimes" :key="index">
 						<image class="card-image" :src="listData.volunteerPicture" mode="aspectFill"></image>
 						<view class="card-content"> <!-- Content container -->
 							<view class="info-item">服务项目:{{listData.projectName}}</view>
 							<view class="Telephone">服务时长:{{listData.businessDuration}}</view>
 							<view class="date">日期:{{item.date}}</view>
 							<view class="time">
-								时间:
-								<span v-for="(i,ind) in item.timeArr" :key="ind">
-									{{i}} &nbsp;&nbsp;&nbsp;
-								</span>
+								时间:{{ item.time }}
+								<!-- <span v-for="(i,ind) in item.timeArr" :key="ind">
+									{{i}} 
+								</span> -->
 							</view>
 						</view>
 					</view>
@@ -293,7 +293,6 @@
 
 	// 新增:处理子组件传回的地址数据
 	const handleAddressUpdate = (newAddress) => {
-		console.log(newAddress,'接受到的数据')
 		selectedAddress.value = newAddress;
 		addressFlag.value = false; // 关闭选择器
 	};
@@ -335,12 +334,12 @@
 
 	// 获取传递的参数
 	onLoad(async (options) => {
-		const params = JSON.parse(options.params);
+		const option = JSON.parse(decodeURIComponent(options.params));		
 		const {
 			volunteerId: id,
 			serviceCategory: categoy,
 			businessManagementId: manage
-		} = params
+		} = option
 		volunteerId.value = id;
 		serviceCategory.value = categoy;
 		businessManagementId.value = manage;
@@ -374,6 +373,7 @@
 			console.error('接口返回的日期范围为空');
 			doorToDoorTimeArr.value = [];
 			timeHostArr.value = []; // 清空时间段
+			
 		}
 	};
 
@@ -381,7 +381,7 @@
 	const getByDate = async (date = doorToDoorTimeArr.value[0]) => {
 		// 检查日期是否为空
 		if (!date) {
-			console.error('日期为空,跳过获取排班时间');
+			coannsole.error('日期为空,跳过获取排班时间');
 			return;
 		}
 
@@ -397,11 +397,25 @@
 
 		try {
 			const res = await volunteergetTimesByDate(params);
-			const TArr = res.data.map((item) => ({
-				...item,
-				hours: item.reservationTime,
-				timeStamp: new Date(`${date} ${item.reservationTime}`).getTime() / 1000,
-			}));
+			const TArr = res.data.map((item) => {
+				
+				// 初始化disabled变量
+				let disabled = false
+				if (item.hasReservation === 1) (disabled = true)
+				
+				let itemTime = item.timeStamp > 9999999999 ? item.timeStamp : item.timeStamp * 1000;
+				
+				if (new Date().getTime() > itemTime) (disabled = true)
+				
+				return {
+					...item,
+					hours: item.reservationTime,
+					timeStamp: new Date(`${date} ${item.reservationTime}`).getTime() / 1000,
+					date:date,
+					checked: false,
+					disabled
+				}
+			});
 
 			// 如果 doorToDoorTimeArr.value 为空,直接返回
 			if (!doorToDoorTimeArr.value.length) {
@@ -410,7 +424,7 @@
 			}
 
 			// 填充时间段数组
-			timeHostArr.value = Array(doorToDoorTimeArr.value.length).fill(TArr);
+			timeHostArr.value = Array(doorToDoorTimeArr.value.length).fill(TArr);			
 		} catch (error) {
 			console.error('获取排班时间失败:', error);
 		}
@@ -418,24 +432,23 @@
 
 	const getByTime = (timeObj) => {
 		if (timeObj.clicked) {
-			console.log('>>>>>> 已经点击过此时间');
 			return;
 		}
-
-		// 标记为已点击
-		timeObj.clicked = true;
-
-		// 添加到已选时间数组
-		selectedTimes.value.push({
-			date: timeObj.yearToDate,
-			time: timeObj.hours,
-			timestamp: timeObj.timeStamp
-		});
+		
+		if (timeObj.checked) { // 选中 添加到已选时间数组
+			selectedTimes.value.push({
+				date: timeObj.date,
+				time: timeObj.hours,
+				timestamp: timeObj.timeStamp
+			});
+		} else { // 取消选中
+			const index = selectedTimes.value.findIndex(
+				item => item.timestamp === timeObj.timeStamp
+			)
+			selectedTimes.value.splice(index, 1)
+		}
 
 		totalTimes.value = selectedTimes.value.length; // 更新点击次数
-
-
-		console.log(selectedTimes.value, '>>>>>selectedTimes.value');
 	}
 
 	// 立即购买显示时执行
@@ -444,32 +457,33 @@
 		totalTimes.value = 0;
 		currentTime.value = '';
 		currentDate.value = [];
+		// 初始化disabled/checked 数据状态
+		getByDate()
 	}
 
 
 	const computeMoney = computed(() => {
 		return totalTimes.value * businessPrice.value
 	})
-	const computeClickTime = computed(() => {
-		let timeArr = []
-		let nyr = selectedTimes.value.map(item => {
-			return item.date
-		})
-
-		let nyrSet = Array.from(new Set(nyr)).map(item => {
-			return {
-				date: item,
-				timeArr: []
-			}
-		})
-		selectedTimes.value.forEach(item => {
-			nyrSet.forEach(i => {
-				if (item.date == i.date) i.timeArr.push(item.time)
-			})
-		})
-		console.log(nyrSet, '>>>>>nyrSet');
-		return nyrSet
-	})
+	// const computeClickTime = computed(() => {
+	// 	let timeArr = []
+	// 	let nyr = selectedTimes.value.map(item => {
+	// 		return item.date
+	// 	})
+
+	// 	let nyrSet = Array.from(new Set(nyr)).map(item => {
+	// 		return {
+	// 			date: item,
+	// 			timeArr: []
+	// 		}
+	// 	})
+	// 	selectedTimes.value.forEach(item => {
+	// 		nyrSet.forEach(i => {
+	// 			if (item.date == i.date) i.timeArr.push(item.time)
+	// 		})
+	// 	})
+	// 	return nyrSet
+	// })
 
 	const certificationPictures = computed(() => {
 		if (listData.value.certificationPicture) {
@@ -493,9 +507,6 @@
 		
 		  // 如果有地址,执行购买逻辑
 		  proceedToPayment();
-		
-
-	
 	};
 	
 	const proceedToPayment = async () => {