Fly 4 months ago
parent
commit
ac3fe62496

+ 192 - 0
components/Touchbox/Touchbox - 副本.vue

@@ -0,0 +1,192 @@
+<template>
+	<view class="site-box" ref="fixbox" :style="{ 'z-index':zIndex , 'height':popupHeight + 'px'}">
+		<view class="tap-touch-line" @touchmove="getstart" @touchend="getend" />
+		<slot />
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'Touchbox',
+		data() {
+			return {
+				windowHeight: 0,
+				touchHeight: uni.upx2px(100),
+				popupHeight: 0,
+				initialHeight:0,
+				oldHeight: 0,
+				scrollHeight: 0,
+				minTop: 0,
+				maxTop: 0,
+			};
+		},
+
+		props: {
+			zIndex: {
+				type: Number,
+				default: 99,
+			},
+			smallHeight: {
+				type: Number,
+				default: 0.35,
+			},
+			maxHeight: {
+				type: Number,
+				default: 0.65,
+			},
+		},
+		created() {
+			const { windowHeight } = uni.getSystemInfoSync();
+			this.windowHeight = windowHeight;
+			// this.windowWidth = uni.getSystemInfoSync().windowWidth;
+			this.popupHeight = this.initialHeight =  this.oldHeight = windowHeight * this.smallHeight;
+
+			this.maxTop = windowHeight * (1 - this.smallHeight);
+			this.minTop = windowHeight * (1 - this.maxHeight);
+
+			// minTop:0,
+			// maxTop:0,
+		},
+		mounted() {
+			this.$nextTick(function() {
+				// this.windowWidth = uni.getSystemInfoSync().windowWidth;
+				// this.windowHeight = uni.getSystemInfoSync().windowHeight;
+				// var defaultHeight = this.windowHeight * (1 - this.minHeight);
+				// this.firsttop = defaultHeight;
+				// this.phonetop =
+				// 	(this.windowHeight * this.maxHeight - this.windowHeight * this.minHeight) / 2;
+				// this.phoneMinTop =
+				// 	(this.windowHeight * this.minHeight - this.windowHeight * this.smallHeight) / 2;
+				// this.fixboxtop = defaultHeight;
+				// this.$emit('currentHeight', this.windowHeight - this.fixboxtop);
+				// this.$emit('maxtHeight', this.windowHeight * this.maxHeight);
+			});
+		},
+		onReady() {},
+		computed: {},
+		watch: {
+			popupHeight(newH, oldH) {
+				this.scrollHeight = newH - this.touchHeight; 
+			},
+			scrollHeight: {
+				handler(newH) {
+					this.$emit('currentHeight', newH);
+				},
+				immediate: true
+			}
+		},
+		methods: {
+			// 隐藏
+			concealList() {
+				// this.popupHeight = this.touchHeight
+				this.popupHeight = this.initialHeight
+			},
+			getstart(e) {
+				e.preventDefault();
+				const { clientY, screenY } = e.touches[0];
+				const Y = clientY || screenY;
+				// console.log(Y, this.maxTop)
+				// // 这里特殊处理 解决:在滑动框内如果存在滚动元素,则会出现滑动时滑动框和内部滚动同时滑的问题
+				if (Y < this.minTop || Y > (this.windowHeight - this.touchHeight)) {
+					return
+				}
+				this.popupHeight = this.windowHeight - Y;
+			},
+			getend() {
+				if (this.popupHeight >= this.oldHeight && (this.popupHeight - this.oldHeight) > 50) {
+					// 上拉
+					this.popupHeight = this.windowHeight * this.maxHeight
+				} else if ((this.oldHeight - this.popupHeight) > 50) {
+					// console.log("this.oldHeight = ", this.oldHeight, "this.popupHeight = ", this.popupHeight)
+					const s_h = this.windowHeight * this.smallHeight;
+					// 下拉
+					if (this.popupHeight >= s_h) {
+						// 在中等偏上区域,还原成中等高度
+						this.popupHeight = s_h
+					} else {
+						// 在中等偏下区域,还原成最小高度
+						this.popupHeight = this.initialHeight
+						// this.popupHeight = this.touchHeight
+						
+					}
+
+				} else {
+					// 拉取幅度不够,还原,防止误触发
+					this.popupHeight = this.oldHeight
+				};
+				
+				// 记录当前高度
+				this.oldHeight = this.popupHeight;
+			},
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+	.site-box {
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background-color: #ffffff;
+		// padding: 0 12px;
+		transition-property: top;
+		transition-duration: 0.7s;
+		border-radius: 40rpx 40rpx 0 0;
+
+		.tap-touch-line {
+			width: 100%;
+			height: 100rpx;
+			position: relative;
+
+			&:before {
+				content: '';
+				position: absolute;
+				left: 50%;
+				top: 50%;
+				transform: translate(-50%, -50%);
+				width: 30%;
+				height: 8rpx;
+				border-radius: 4rpx;
+				background-color: rgb(214, 215, 217);
+			}
+		}
+	}
+
+	// .tapBoxTouchLine {
+	// 	display: flex;
+	// 	align-items: center;
+	// 	justify-content: center;
+	// 	padding: 20rpx 0 30rpx;
+	// }
+
+	// .line {
+	// 	margin: 0px;
+	// 	vertical-align: middle;
+	// 	// border-bottom: 8rpx solid rgb(214, 215, 217);
+	// 	height: 8rpx;
+	// 	background-color: rgb(214, 215, 217);
+	// 	border-radius: 4rpx;
+
+	// 	// border: 4rpx;
+	// 	// border-top-color: rgb(214, 215, 217);
+	// 	// border-right-color: rgb(214, 215, 217);
+	// 	// border-left-color: rgb(214, 215, 217);
+	// }
+
+	// .fixedbox {
+	// 	position: fixed;
+	// 	left: 0;
+	// 	background-color: #ffffff;
+	// 	padding: 0 12px;
+	// }
+
+	// .fixedbox2 {
+	// 	position: fixed;
+	// 	left: 0;
+	// 	background-color: #ffffff;
+	// 	padding: 0 12px;
+	// 	transition-property: top;
+	// 	transition-duration: 0.4s;
+	// }
+</style>

+ 47 - 22
components/Touchbox/Touchbox.vue

@@ -1,7 +1,10 @@
 <template>
 	<view class="site-box" ref="fixbox" :style="{ 'z-index':zIndex , 'height':popupHeight + 'px'}">
-		<view class="tap-touch-line" @touchmove="getstart" @touchend="getend" />
-		<slot />
+		<view class="tap-touch-box" :style="{height:touchHeight + 'px'}"  @touchmove="getstart" @touchend="getend" >
+			<view class="tap-touch-line"/>
+			<slot name='touchSlot' />
+		</view>
+		<slot name='contentSlot' />
 	</view>
 </template>
 
@@ -11,9 +14,9 @@
 		data() {
 			return {
 				windowHeight: 0,
-				touchHeight: uni.upx2px(100),
+				touchHeight: uni.upx2px(125),
 				popupHeight: 0,
-				initialHeight:0,
+				initialHeight: 0,
 				oldHeight: 0,
 				scrollHeight: 0,
 				minTop: 0,
@@ -39,10 +42,11 @@
 			const { windowHeight } = uni.getSystemInfoSync();
 			this.windowHeight = windowHeight;
 			// this.windowWidth = uni.getSystemInfoSync().windowWidth;
-			this.popupHeight = this.initialHeight =  this.oldHeight = windowHeight * this.smallHeight;
+			this.popupHeight = this.initialHeight = this.oldHeight = windowHeight * this.smallHeight;
 
 			this.maxTop = windowHeight * (1 - this.smallHeight);
 			this.minTop = windowHeight * (1 - this.maxHeight);
+ 
 
 			// minTop:0,
 			// maxTop:0,
@@ -66,7 +70,7 @@
 		computed: {},
 		watch: {
 			popupHeight(newH, oldH) {
-				this.scrollHeight = newH - this.touchHeight; 
+				this.scrollHeight = newH - this.touchHeight;
 			},
 			scrollHeight: {
 				handler(newH) {
@@ -107,14 +111,14 @@
 						// 在中等偏下区域,还原成最小高度
 						this.popupHeight = this.initialHeight
 						// this.popupHeight = this.touchHeight
-						
+
 					}
 
 				} else {
 					// 拉取幅度不够,还原,防止误触发
 					this.popupHeight = this.oldHeight
 				};
-				
+
 				// 记录当前高度
 				this.oldHeight = this.popupHeight;
 			},
@@ -134,23 +138,44 @@
 		transition-duration: 0.7s;
 		border-radius: 40rpx 40rpx 0 0;
 
-		.tap-touch-line {
-			width: 100%;
-			height: 100rpx;
-			position: relative;
-
-			&:before {
-				content: '';
-				position: absolute;
-				left: 50%;
-				top: 50%;
-				transform: translate(-50%, -50%);
-				width: 30%;
+		.tap-touch-box {
+			padding: 20rpx 0;
+			.tap-touch-line {
+				width: 100%;
 				height: 8rpx;
-				border-radius: 4rpx;
-				background-color: rgb(214, 215, 217);
+				overflow: hidden;
+				position: relative;
+					&:before {
+						content: '';
+						position: absolute;
+						left: 50%;
+						top: 0;
+						transform: translateX(-50%);
+						width: 50rpx;
+						height: 16rpx;
+						border-radius: 8rpx;
+						background-color: rgb(214, 215, 217);
+					}
 			}
 		}
+
+		// .tap-touch-line {
+		// 	width: 100%;
+		// 	height: 100rpx;
+		// 	position: relative;
+
+		// 	&:before {
+		// 		content: '';
+		// 		position: absolute;
+		// 		left: 50%;
+		// 		top: 50%;
+		// 		transform: translate(-50%, -50%);
+		// 		width: 30%;
+		// 		height: 8rpx;
+		// 		border-radius: 4rpx;
+		// 		background-color: rgb(214, 215, 217);
+		// 	}
+		// }
 	}
 
 	// .tapBoxTouchLine {

File diff suppressed because it is too large
+ 20 - 11
components/tiandituMap/tiandituMap.vue


+ 0 - 6
pages.json

@@ -21,12 +21,6 @@
 			"style": {
 				"navigationBarTitleText": "政务地图"
 			}
-		},
-		{
-			"path": "pages/map/cs",
-			"style": {
-				"navigationBarTitleText": "政务地图"
-			}
 		}
 
 

+ 0 - 459
pages/map/cs.vue

@@ -1,459 +0,0 @@
-<template>
-	<view class="map-box">
-	 
-
-		<tiandituMap ref="tiandituMapRefs" @handleSearch="handleSearch" @clickMap="handleClickMap"
-			@moveMap="moveMapSearch" @onLoadTianDiTu="initMaps" @onSelect="selectPoint" :apiKey="apiKey"
-			@handleMapSite="handleMapSite">
-		</tiandituMap>
-
-		 
-	</view>
-</template>
-<script>
-	import tools from '@/components/tiandituMap/tools.js'
-	import search from "./model/search.vue"
-	import siteListModel from "./model/siteList.vue";
-	import { getMapCenterPoint_Api, getMapList_Api } from "@/api/map.js"
-	import siteDetails from "./model/siteDetails.vue"
-	import $config from "@/config/index.js"
-	import { EventBus } from "@/utils/vueBus.js"
-	import { getLocation, throttle } from "@/utils/tool.js"
-	let mapThat = this;
-	export default {
-		name: 'tdtmap',
-		components: {
-			search,
-			siteListModel,
-			siteDetails
-		},
-		data() {
-			return {
-				mapThat: this,
-				showMap: false,
-				longitude: undefined,
-				latitude: undefined,
-				apiKey: $config.tianKey,
-				winWidth: 0,
-				winHeight: 0,
-				winTop: 0,
-				datalist: [],
-				startY: 0,
-				selectItem: {},
-				iStatusBarHeight: 0,
-
-
-				siteListArr: [],
-				TouchHeight: 0,
-			}
-		},
-		created() {
-			mapThat = this;
-			getLocation();
-
-			this.getMapCenterPoint()
-		},
-		mounted() {
-			this.disableScroll()
-		},
-		beforeDestroy() {
-			try {
-				document.removeEventListener('touchmove');
-				document.body.removeEventListener('mousewheel');
-				document.body.removeEventListener('DOMMouseScroll');
-				document.removeEventListener('onmousewheel', function() {
-					window.event.returnValue = false;
-				});
-			} catch (error) {
-				//TODO handle the exception
-			}
-		},
-		watch: {
-			siteListArr: {
-				handler(newArr) {
-					try {
-						this.$refs.tiandituMapRefs.clearIcon().then(res => {
-							this.$nextTick(() => {
-								(newArr || []).forEach((el, index) => {
-									const { longitude, latitude, mapTypeIcon } = el
-									this.$refs.tiandituMapRefs.setIcon(longitude, latitude, false,
-										mapTypeIcon,
-										el);
-								})
-							})
-						});
-					} catch (error) {}
-
-				},
-				deep: true
-			}
-		},
-		methods: {
-			disableScroll() {
-				if (typeof window.addEventListener === 'function') {
-					document.addEventListener('touchmove', function(e) {
-						e.preventDefault();
-					}, { passive: false });
-					document.body.addEventListener('mousewheel', function(e) {
-						e.preventDefault();
-					});
-					document.body.addEventListener('DOMMouseScroll', function(e) {
-						e.preventDefault();
-					});
-				} else {
-					document.attachEvent('onmousewheel', function() {
-						window.event.returnValue = false;
-					});
-				}
-			},
-			// 点击地图
-			handleClickMap() {
-				if (this.$refs.TouchboxRef) {
-					this.$refs.TouchboxRef.concealList()
-				}
-			},
-			// 点击地图标注点位
-			handleMapSite(parmas = {}) {
-				const { Lng, Lat } = parmas;
-				const item = (this.siteListArr || []).find(el => el.longitude == Lng && el.latitude == Lat);
-				this.checkSiteDetails(item)
-			},
-			// 查看点位详情
-			checkSiteDetails(info) {
-				if (info) {
-					this.$refs.tiandituMapRefs.Trenderjs.SelectedDot(info)
-					// EventBus.$emit('TianDiTuSite', info)
-					this.handleClickMap();
-					this.$refs.siteDetailsRef.openDetails(info)
-				}
-			},
-			// 获取地图中心点
-			getMapCenterPoint() {
-				uni.showLoading()
-				this.showMap = false;
-				getMapCenterPoint_Api().then(res => {
-					const { longitude, latitude, mapTypeIcon } = res || {};
-					this.longitude = longitude;
-					this.latitude = latitude;
-					this.open(longitude, latitude, mapTypeIcon);
-				}).catch(err => { this.open(null, null) }).finally(() => {
-					uni.hideLoading()
-				})
-			},
-			moveMapSearch(parms) {
-				const { Lng, Lat } = parms;
-				this.longitude = Lng;
-				this.latitude = Lat;
-				this.$refs.searchRef.handleSearch()
-				// console.log("moveMapSearch", Lng, Lat)
-			},
-			handleSearch(val = {}) {
-				const parms = {
-					...val,
-					longitude: this.longitude,
-					latitude: this.latitude,
-					radius: 5000
-				};
-				getMapList_Api(parms).then(res => {
-					if (!res || res.length === 0) {
-						uni.showToast({
-							title: "当前区域无办理点位",
-							icon: 'none'
-						})
-					}
-					this.siteListArr = res || [];
-				}).catch(err => {
-					this.siteListArr = [];
-				}).finally(() => {
-					clearTimeout(this.SearchTimeout)
-					this.SearchTimeout = null;
-				})
-			},
-			// //普通搜索
-			// handleSearch(val = {}) {
-			// 	const parms = {
-			// 		...val,
-			// 		longitude: this.longitude,
-			// 		latitude: this.latitude,
-			// 		radius: 5000
-			// 	};
-			// 	getMapList_Api(parms).then(res => {
-			// 		if (!res || res.length === 0) {
-			// 			uni.showToast({
-			// 				title: "当前区域无办理点位",
-			// 				icon: 'none'
-			// 			})
-			// 		}
-			// 		this.siteListArr = res || [];
-			// 	}).catch(err => {
-			// 		this.siteListArr = [];
-			// 	})
-			// },
-			open(lon, lat, mapTypeIcon) {
-				if (lon && lat) {
-					this.$nextTick(() => {
-						this.$refs.tiandituMapRefs.initCharts(lon, lat, mapTypeIcon)
-						this.showMap = true;
-					})
-				} else {
-					uni.showModal({
-						title: '提示',
-						content: '地图中心点获取错误,请联系管理员!',
-						success: res => {
-							// console.log("showModal == ", res)
-							if (res.confirm) {}
-						}
-					})
-				}
-
-			},
-			close() {
-				this.visible = false
-			},
-			onConfirm() {
-				if (Object.keys(this.selectItem).length) {
-					this.visible = false
-					this.$emit('onSelect', this.selectItem)
-				} else {
-					tools.createMessage('请选择位置')
-				}
-			},
-			upDateLonLat(lon, lat) {
-				if (lon && lat) {
-					this.$refs.tiandituMapRefs.upDataCharts(lon, lat)
-				} else {
-					console.error('请传入lon, lat')
-				}
-			},
-			tianidtuSearch(value) {
-				if (value.city) {
-					this.cityInfoSearch(value)
-				} else {
-					this.infoSearch(value)
-				}
-			},
-			async infoSearch(value) { // 地理编码查询
-				let params = {
-					ds: {
-						"keyWord": value.keyword,
-					},
-					tk: this.apiKey,
-				}
-				let resData = await tools.createRequest('https://api.tianditu.gov.cn/geocoder', params, true)
-				if (resData.status === '0') {
-					const location = resData.location
-					const formateOne = tools.formatterAdressLocation(resData, 3)
-					this.datalist = [formateOne]
-					this.selectItem = datalist
-					this.$refs.tiandituMapRefs.upDataCharts(location.lon, location.lat)
-				}
-			},
-			async cityInfoSearch(value) { // 地名搜索2.0
-				let params = {
-					postStr: {
-						"keyWord": value.keyword,
-						"queryType": 12,
-						"start": 0,
-						"count": 10,
-						"specify": value.city.value
-					},
-					type: 'query',
-					tk: this.apiKey,
-				}
-				let resData = await tools.createRequest('https://api.tianditu.gov.cn/v2/search', params, true)
-				if (resData.status.infocode === 1000) {
-					const {
-						pois: aPoints,
-						count
-					} = resData
-					if (count === '0' || !aPoints || !aPoints.length) {
-						return tools.createMessage('没有找到该地址')
-					}
-					const {
-						pois,
-						keyWord,
-						lonlat
-					} = aPoints[0]
-					const formateData = aPoints.map((item) => tools.formatterAdressLocation(item, 2))
-					this.datalist = formateData
-					this.selectItem = formateData[0]
-					const [lon, lat] = lonlat.split(',')
-					this.$refs.tiandituMapRefs.upDataCharts(lon, lat)
-				} else {
-					tools.createMessage('数据异常', 1000, false, 'error')
-				}
-			},
-			selectListItem(item) {
-				this.$refs.tiandituMapRefs.upDataCharts(item.location.lon, item.location.lat)
-			},
-			selectPoint(e) {
-				this.domMinHeight = '0vh'
-				this.datalist = [e]
-				this.selectItem = e
-			},
-			initMaps() {
-				console.warn('--------天地图加载完成--------');
-				this.$emit('onLoad')
-			},
-			// start(e) {
-			// 	const clientY = e.changedTouches[0].clientY
-			// 	this.startY = clientY
-			// },
-			// end(e) {
-			// 	const transformY = e.changedTouches[0].clientY - this.startY;
-			// 	switch (true) {
-			// 		case transformY > 50:
-			// 			console.log('下划')
-			// 			this.domMaxHeight = '20vh'
-			// 			this.domMinHeight = '0vh'
-			// 			break;
-			// 		case transformY < -50:
-			// 			console.log('上划')
-			// 			this.domMaxHeight = '50vh'
-			// 			this.domMinHeight = '50vh'
-			// 			break;
-			// 		default:
-			// 			break;
-			// 	}
-
-			// },
-			selectCard(item) {
-				this.domMaxHeight = '20vh'
-				this.domMinHeight = '0vh'
-				this.selectItem = item
-				this.selectListItem(item)
-			},
-
-
-
-			setTouchHeight(val) {
-				// console.log('setScrollHeight = ', val)
-				// 实时返回的滑动组件高度
-				this.TouchHeight = val;
-			},
-			setScrollMaxHeight(val) {
-				//最大高度
-				this.scrollMaxHeight = val;
-			},
-
-
-		}
-	}
-</script>
-
-
-
-<style scope>
-	.map-box {
-		width: 100vw;
-		height: 100vh;
-		/* 		position: fixed;
-		left: 0;
-		top:0;
-		right: 0;
-		bottom: 0; */
-	}
-
-
-
-	.mask {
-		/* overflow: hidden; */
-		position: fixed;
-		left: 0;
-		background-color: #FFFFFF;
-		z-index: 399;
-	}
-
-	/* footer */
-	.list-boxd {
-		position: absolute;
-		bottom: 0;
-		left: 0;
-		z-index: 401;
-		right: 0;
-		border-radius: 14px 14px 0 0;
-		background: #FFFFFF;
-		transition: all 1s;
-	}
-
-	.list-header {
-		height: 20px;
-		position: relative;
-		border-bottom: 1px solid #f3f4f6;
-		cursor: pointer;
-	}
-
-	.list-header::after {
-		position: absolute;
-		left: 50%;
-		top: 50%;
-		transform: translate(-50%, -50%);
-		content: '';
-		height: 6px;
-		width: 60px;
-		border-top: 1px solid #e8e8e8;
-		border-bottom: 1px solid #e8e8e8;
-	}
-
-	.list-content {
-		max-height: 50vh;
-		overflow-y: scroll;
-	}
-
-	.card {
-		min-height: 44px;
-		padding: 12px;
-		position: relative;
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-
-	}
-
-	.card-left {
-		display: flex;
-		flex-direction: column;
-		justify-content: center;
-	}
-
-	.card-right {
-		padding-right: 10px;
-	}
-
-	.arrow {
-		border-top: 2px solid #666666;
-		border-right: 2px solid #666666;
-		width: 10px;
-		height: 10px;
-		transform: rotate(45deg);
-	}
-
-
-	.card:active {
-		background-color: #f3f4f6;
-	}
-
-
-	.card::after {
-		position: absolute;
-		content: '';
-		bottom: 0;
-		height: 1px;
-		background-color: #e8e8e8;
-		width: 90%;
-	}
-
-	.card:last-child::after {
-		height: 0;
-		background-color: #FFFFFF;
-	}
-
-	.card-title {
-		font-size: 18px;
-	}
-
-	.card-text {
-		color: #e8e8e8;
-		font-size: 13px;
-	}
-</style>

File diff suppressed because it is too large
+ 37 - 78
pages/map/index.vue


File diff suppressed because it is too large
+ 253 - 0
pages/map/model - 副本/search.vue


File diff suppressed because it is too large
+ 310 - 0
pages/map/model - 副本/siteDetails.vue


File diff suppressed because it is too large
+ 199 - 0
pages/map/model - 副本/siteList.vue


pages/map/model/siteServe.vue → pages/map/model - 副本/siteServe.vue


+ 353 - 0
pages/map/model - 副本/siteServeH6.vue

@@ -0,0 +1,353 @@
+<template>
+	<view class="serve-content" :style="{'height':height  +'px' }">
+		<view class="serve-title">可以办事项</view>
+		<view class="serve-search">
+			<input confirm-type="search" ref="searchInputRef" class="search-input" :auto-blur="true" type="text"
+				placeholder="搜索服务事项" v-model="matterName" @confirm="getMatterList" />
+			<view class="search-btn" @click.stop="getMatterList"> 搜 索 </view>
+		</view>
+		<view class="matter-loading" v-if="MatterListLoading">
+			<u-loading-icon />
+		</view>
+		<view class="serve" :style="{'height':scrollH  +'px' }" v-else-if="MatterList">
+			<scroll-view class="scroll-lable" :style="{'height':scrollH  +'px' }" scroll-y="true"
+				:show-scrollbar="false">
+				<template v-for="(value, key , index) in MatterList">
+					<view :class="['lable one-row' , index === activeIndex ? 'active-lable' : '' ]"
+						@click.stop="openTyle(index)">{{ key }}</view>
+				</template>
+			</scroll-view>
+			<scroll-view class="scroll-val" :scroll-into-view="scrollIntoView" @scroll="scrollService"
+				:style="{'height':scrollH  +'px' }" scroll-y="true" :show-scrollbar="false">
+				<template v-for="(value, key , index) in MatterList">
+					<view class="val-content" :id="`service_${index}`">
+						<view class="val-name">{{key}}</view>
+						<template v-for="(t_v, t_k , t_i) in (value || [])">
+							<!-- @click.stop="LookMatterDetails(item)" -->
+							<view class="val">
+								<view class="val-label val-item" @click.stop="setShowKey(index  , t_i)">
+									<text class="val-text one-row">{{ t_k }}</text>
+									<template v-if="t_v && t_v.length">
+										<svg t="1734508422065"
+											:class="['val-icon' , showKey === getShowKey(index  , t_i ) ? 'avtive-icon' : '']"
+											viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+											p-id="4279" xmlns:xlink="http://www.w3.org/1999/xlink">
+											<path
+												d="M492.675886 904.817574L885.696074 511.797385 492.675886 118.777197c-12.258185-12.258185-12.432147-32.892131 0.187265-45.51052 12.707416-12.707416 32.995485-12.703323 45.511543-0.187265l411.660734 411.660734c7.120165 7.120165 10.163477 17.065677 8.990768 26.624381 1.500167 9.755178-1.5104 20.010753-8.990768 27.491121L538.374694 950.515359c-12.258185 12.258185-32.892131 12.432147-45.511543-0.187265-12.707416-12.707416-12.703323-32.995485-0.187265-45.51052z"
+												p-id="4280"></path>
+										</svg>
+									</template>
+								</view>
+								<!-- showKey -->
+								<template v-if="showKey === getShowKey(index  , t_i )">
+									<view class="val-item" v-for="item in (t_v || [])">
+										{{item.name}}
+									</view>
+								</template>
+							</view>
+						</template>
+					</view>
+				</template>
+			</scroll-view>
+		</view>
+		<view v-else class="matter-loading">
+			<u-empty mode="data" :iconSize="emptySize" text="暂无可办事项" />
+		</view>
+	</view>
+</template>
+
+<script>
+	import { getMapMatterListH6_Api } from "@/api/map.js"
+	export default {
+		props: {
+			height: {
+				type: Number,
+				default: 0
+			},
+			mapLocationId: {
+				type: Number | String,
+				default: null
+			}
+		},
+		data() {
+			return {
+				showKey: '',
+				scrollH: 0,
+				matterName: '',
+				MatterList: null,
+				MatterListLoading: false,
+				activeIndex: undefined,
+				scrollIntoView: undefined,
+				scrollStatus: true,
+				oldScrollNum: 0,
+				RightTopArr: [],
+
+				emptySize: uni.upx2px(130)
+			}
+		},
+		watch: {
+			height: {
+				handler(newH) {
+					// 区域高度 - 标题高度 - 搜索区域高度
+					this.scrollH = newH - uni.upx2px(60) - uni.upx2px(100);
+				},
+				immediate: true
+			},
+			mapLocationId: {
+				handler(newId) {
+					this.getMatterList(newId)
+				},
+				immediate: true
+			},
+		},
+		created() {
+
+		},
+		methods: {
+			getShowKey(k_1, k_2) {
+				return `${k_1}${k_2}`
+			},
+			setShowKey(index, t_i) {
+				const k = this.getShowKey(index, t_i);
+				if (!this.showKey || this.showKey !== k) {
+					this.showKey = k;
+				} else {
+					this.showKey = ''
+				};
+			},
+			getLabel(item) {
+				console.log("getLabel = ", item)
+				const label = Object.keys(item)[0];
+				return label;
+			},
+			getMatterList() {
+				this.MatterListLoading = true;
+				const parmas = {
+					mapLocationId: this.mapLocationId,
+					matterName: this.matterName
+				};
+				getMapMatterListH6_Api(parmas).then(res => {
+					const keys = Object.keys(res || {});
+					if (keys && keys.length > 0) {
+						this.MatterList = res;
+						this.activeIndex = 0;
+						this.getNodesInfo()
+					} else {
+						this.MatterList = null;
+						this.activeIndex = undefined;
+					}
+				}).catch(err => {
+					this.MatterList = null;
+					this.activeIndex = undefined;
+				}).finally(() => {
+					setTimeout(() => {
+						this.MatterListLoading = false;
+					}, 300)
+				})
+			},
+
+			openTyle(index) {
+				this.scrollStatus = false;
+				this.activeIndex = index
+				this.scrollIntoView = `service_${index}`
+				setTimeout(() => {
+					this.scrollStatus = true;
+				}, 200)
+			},
+			scrollService(event) {
+				// console.log('stopPropagation  ' , event)
+				// event.stopPropagation();
+				if (!this.scrollStatus) return
+				const { scrollTop } = event.detail;
+				let scrollNums = scrollTop;
+				if (this.oldScrollNum > scrollTop) {
+					scrollNums = scrollTop + 80;
+				};
+				try {
+					this.RightTopArr.forEach((el, index) => {
+						let data = this.RightTopArr[index];
+						if (scrollNums >= data.height && index == this.RightTopArr.length - 1 ? true :
+							scrollNums < this.RightTopArr[parseInt(index) + 1].height) {
+							this.activeIndex = index;
+							throw new Error()
+						}
+					})
+				} catch (e) {
+					//TODO handle the exception
+				}
+
+				this.oldScrollNum = scrollTop;
+
+
+			},
+			// 查看事项详情
+			LookMatterDetails(item) {
+				// pages/map/matterDetails
+				// 在起始页面跳转到test.vue页面,并监听test.vue发送过来的事件数据
+				uni.navigateTo({
+					url: '/pages/map/matterDetails',
+					success: function(res) {
+						// 通过eventChannel向被打开页面传送数据
+						res.eventChannel.emit('acceptDataFromOpenerPage', item)
+					}
+				})
+			},
+
+			getNodesInfo() {
+				new Promise(resolve => {
+					let selectorQuery = uni.createSelectorQuery();
+					// 获取节点的位置信息
+					selectorQuery.selectAll('.val-content').boundingClientRect((rects) => {
+						// 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
+						if (!rects.length) {
+							setTimeout(() => {
+								this.$nextTick(() => {
+									this.getNodesInfo();
+								})
+							}, 10);
+							return;
+						}
+						this.RightTopArr = [];
+						// 生成之后开始添加进去数组
+						rects.forEach((rect) => {
+							// 这里减去rects[0].top,是因为第一项顶部不是贴到导航栏=>每一个商品距离顶部的高度,如果此页面顶部没有其他的view那就不用减去rects[0].top,自己视情况而定。
+							let tops = rect.top - rects[0].top;
+							this.RightTopArr.push({
+								height: tops,
+								id: rect.id
+							});
+						})
+						resolve();
+					}).exec()
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.serve-content {
+		border-top: 1rpx solid #F0F0F0;
+
+		.serve-title {
+			color: #7D7D7D;
+			font-size: 32rpx;
+			height: 60rpx;
+			line-height: 60rpx;
+		}
+
+		.serve-search {
+			width: 100%;
+			padding: 20rpx 0;
+			display: flex;
+			justify-content: space-between;
+			align-items: stretch;
+
+			.search-input {
+				flex: 1;
+				height: 60rpx;
+				border: 1rpx solid #F0F0F0;
+				border-radius: 10rpx;
+				padding: 0 15rpx;
+				font-size: 28rpx;
+			}
+
+			.search-btn {
+				width: 120rpx;
+				background-color: #3291F8;
+				margin-left: 20rpx;
+				line-height: 60rpx;
+				text-align: center;
+				color: #fff;
+				font-size: 28rpx;
+				border-radius: 10rpx;
+			}
+		}
+
+		.serve {
+			width: 100%;
+			overflow: hidden;
+			display: flex;
+			align-items: stretch;
+
+			.scroll-lable {
+				width: 160rpx;
+
+				.lable {
+					width: 100%;
+					height: 80rpx;
+					font-size: 30rpx;
+					line-height: 80rpx;
+					text-align: center;
+					border-left: 6rpx solid transparent;
+					padding: 0 10rpx;
+				}
+
+				.active-lable {
+					color: #3291F8;
+					font-weight: 600;
+					border-left-color: #3291F8;
+				}
+			}
+
+			.scroll-val {
+				width: calc(100% - 160rpx);
+				padding: 0 0 0 20rpx;
+
+				.val-content {
+					// height: 300px;
+				}
+
+				.val-name {
+					font-size: 30rpx;
+					padding: 15rpx 0;
+					font-weight: 600;
+				}
+				.val {
+					width: 100%; 
+					border: 1rpx solid #F0F0F0;
+					margin-bottom: 20rpx;
+					transition: height 1s;
+				
+					.val-item {
+						width: 100%;
+						min-height: 100rpx;
+						padding: 10rpx 20rpx;
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+						border-top: 1rpx solid #F0F0F0;
+						&:first-child{
+							border-top:none;
+						}
+					}
+
+					.val-label {
+					font-weight: 600;
+						.val-text {
+							flex: 1;
+							width: 1px;
+							font-size: 30rpx;
+						}
+
+						.val-icon {
+							width: 34rpx;
+							height: 34rpx;
+							transition: transform 0.3s;
+						}
+						.avtive-icon{
+							transform: rotate(90deg);
+						}
+					}
+				}
+				 
+			}
+		}
+
+		.matter-loading {
+			padding-top: 50rpx;
+			text-align: center;
+		}
+
+	}
+</style>

+ 25 - 12
pages/map/model/search.vue

@@ -1,5 +1,5 @@
 <template>
-	<view :class="[ 'search-content' , type === 'H6' ? 'h6-search-content' : '' ]">
+	<view :class="[ 'search-content']">
 		<view class="search-box">
 			<view class="search-input-box">
 				<svg t="1733904658291" class="search-icon" viewBox="0 0 1024 1024" version="1.1"
@@ -10,16 +10,16 @@
 					</path>
 				</svg>
 				<input confirm-type="search" ref="searchInputRef" class="search-input" :auto-blur="true" type="text"
-					placeholder="请输入关键字" v-model="locationName" @blur="onSearchFocus(true)" />
+					placeholder="请输入关键字" v-model="locationName" @blur="onSearchFocus(true)" placeholder-class="placeholder" />
 			</view>
 			<view class="search-select">
 				<view class="select-item" @click.stop="$refs.cityRef.open()">
 					<text class="item-text one-row">{{params.codeLabel || '办理区域'}}</text>
-					<u-icon name="arrow-down-fill" :color="downFillColor" size="16"></u-icon>
+					<u-icon name="arrow-down-fill" :color="downFillColor" size="14"></u-icon>
 				</view>
 				<view class="select-item" @click.stop="$refs.mapTypeRef.open()">
 					<text class="item-text one-row">{{ params.typeName || '位置类型'}}</text>
-					<u-icon name="arrow-down-fill" :color="downFillColor" size="16"></u-icon>
+					<u-icon name="arrow-down-fill" :color="downFillColor" size="14"></u-icon>
 				</view>
 			</view>
 		</view>
@@ -56,13 +56,14 @@
 				LocationTimeout: null,
 				SearchTimeout: null,
 				type: $confog.type,
-				downFillColor: '#101010'
+				downFillColor: '#808080'
 			}
 		},
 		created() {
 			this.type = $confog.type;
-			this.downFillColor = $confog.type === 'H6' ? '#929292' : '#101010'
+			this.downFillColor = $confog.type === 'H6' ? '#808080' : '#101010'
 			this.init()
+			
 		},
 		mounted() {
 			EventBus.$on('TianDiTuSearch', (callBack) => {
@@ -197,46 +198,58 @@
 		.search-input-box {
 			width: 100%;
 			height: $heig_;
+			border-radius: $radius_ ;
+			box-shadow: 0rpx -10rpx 30rpx #ccc;
 			display: flex;
 			align-items: center;
 			padding: 0 10px;
 			color: #020202;
+			font-size: 28rpx;
 
 			.search-icon {
 				width: 45rpx;
 				height: 45rpx;
 
 				path {
-					fill: #020202;
+					fill: #666666;
 				}
 			}
 
 			.search-input {
 				padding-left: 10px;
 			}
+			.placeholder{
+				color: #B3B3B3;
+			}
 		}
 
 		.search-select {
-			border-top: 1rpx solid #E8E8E8;
+			// border-top: 1rpx solid #E8E8E8;
 			width: 100%;
 			height: $heig_;
 			display: flex;
-			justify-content: space-between;
+			// justify-content: space-between;
 			align-items: center;
+			padding: 0 28rpx;
 
 			.select-item {
-				width: 50%;
+				// width: 50%;
 				display: flex;
 				justify-content: center;
 				align-items: center;
-				font-size: 30rpx;
+				font-size: 28rpx;
 				padding: 0 10rpx;
+				color: #1A1A1A;
+				min-width: 28rpx;
 
 				.item-text {
 					display: inline-block;
-					padding-right: 6rpx;
+					padding-right: 14rpx;
 					overflow: hidden;
 				}
+				&:first-child{
+					margin-right: 65rpx;
+				}
 			}
 		}
 	}

+ 19 - 0
pages/map/model/service-center.vue

@@ -0,0 +1,19 @@
+<template>
+	<view class="">
+
+	</view>
+</template>
+
+<script>
+	export default {
+
+		data() {
+			return {}
+		}
+
+
+	}
+</script>
+
+<style lang="scss" scoped>
+</style>

File diff suppressed because it is too large
+ 44 - 79
pages/map/model/siteDetails.vue


File diff suppressed because it is too large
+ 303 - 102
pages/map/model/siteList.vue


File diff suppressed because it is too large
+ 173 - 55
pages/map/model/siteServeH6.vue


BIN
static/images/btn_01.png


BIN
static/images/btn_02.png


BIN
static/images/direction.png


BIN
static/images/dot.png


BIN
static/images/dotq.png


BIN
static/images/location-text.png


BIN
static/images/location.png


BIN
static/images/position.png


BIN
static/images/time.png