ソースを参照

fix: 登录异步bug

lxf 3 週間 前
コミット
3c79577035
6 ファイル変更375 行追加421 行削除
  1. 29 39
      App.vue
  2. 5 1
      main.js
  3. 1 0
      package.json
  4. 246 377
      pages/tabBar/home/home.vue
  5. 4 4
      pages/tabBar/home/subPages/allGardenMap.vue
  6. 90 0
      store/user.js

+ 29 - 39
App.vue

@@ -1,42 +1,32 @@
-<script>
-	import USER from '@/api/user.js'
-	export default {
-		onLaunch: async function() {
-			await this.handleWxLogin()
-		},
-		onShow: function() {
-			console.log('App Show')
-		},
-		onHide: function() {
-			console.log('App Hide')
-		},
-		methods: {
-			async handleWxLogin() {
-				// #ifdef MP-WEIXIN
-				// 1. 获取code
-				return new Promise((resolve, reject) => {
-				  uni.login({
-					success: async({code} ) => {
-					  const { data } = await USER.fetchLogin({code})
-					  uni.setStorageSync('userInfo', data);
-					  resolve(data)
-					},
-					fail: err => {
-					  console.error(err)
-					  reject(err)
-					}
-				  })
-				})
-				// #endif
-				
-				// #ifdef H5
-				const {data} = await USER.userInfo()
-				uni.setStorageSync('userInfo', data);
-				// #endif
-			}
-		}
-	}
-</script>
+<script setup>
+import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
+import { useUserStore } from '@/store/user'
+
+// 在 setup 中获取 store
+const userStore = useUserStore()
+
+onLaunch(() => {
+  console.log('App Launch')
+  
+  // 应用启动时尝试静默登录
+  setTimeout(() => {
+    userStore.getTokenSafe().then(token => {
+      console.log('静默登录成功', token)
+    }).catch(err => {
+      console.log('静默登录失败,等待手动登录', err)
+    })
+  }, 0)
+})
+
+onShow(() => {
+  console.log('App Show')
+})
+
+onHide(() => {
+  console.log('App Hide')
+})
+</script>
+
 
 <style lang="scss">
 	/*每个页面公共css */

+ 5 - 1
main.js

@@ -1,4 +1,5 @@
 import App from './App'
+import { createPinia } from 'pinia'
 
 // #ifndef VUE3
 import Vue from 'vue'
@@ -17,9 +18,12 @@ import uviewPlus from '@/uni_modules/uview-plus'
 import { createSSRApp } from 'vue'
 export function createApp() {
   const app = createSSRApp(App)
+  const pinia = createPinia()
   app.use(uviewPlus)
+  app.use(pinia)
   return {
-    app
+    app,
+	pinia
   }
 }
 // #endif

+ 1 - 0
package.json

@@ -4,6 +4,7 @@
     "crypto-js": "^4.2.0",
     "dayjs": "^1.11.13",
     "js-base64": "^3.7.8",
+    "pinia": "^3.0.3",
     "qqmap-wx-jssdk": "^1.0.0"
   }
 }

+ 246 - 377
pages/tabBar/home/home.vue

@@ -3,42 +3,22 @@
 		<view class="home-top">
 			<view class="home-search">
 				<view class="search-wrap">
-					<up-search placeholder="搜索品种" v-model="typeSearch"></up-search>
+					<up-search placeholder="搜索农场名称" v-model="typeSearch"></up-search>
 				</view>
 			</view>
-			<!-- <map
-			    id="mapId"
-			    :latitude="latitude"
-			    :longitude="longitude"
-				:scale="scale"
-			    @markertap="onMarkerTap"
-			    @callouttap="onCalloutTap"
-			    @labeltap="onLabelTap"
-			    :markers="markers"
-			    :include-points="includePoints"
-				:enable-poi="false"
-				:enable-traffic="false"
-				:enable-satellite="true"
-				:enable-building="false"
-			    show-location
-			    style="width: 100%; height: 280rpx;clip-path: inset(0rpx round 16rpx);"
-			  ></map> -->
-			  <video src="https://birdseye-img.sysuimars.com/youwei-uniapp/home/map-video.mp4" object-fit="cover" :show-fullscreen-btn="false"
-			  	:autoplay="true" class="map-video" loop muted :show-progress="false" :show-play-btn="false">
-			  </video>
-			<view class="map-tips" @click="toPage('allGardenMap')">
-				飞鸟入驻管理果场详情,点击查看
-			</view>
+			<div class="home-box" @click="toPage('allGardenMap')">
+				<video src="https://birdseye-img.sysuimars.com/youwei-uniapp/home/map-video.mp4" object-fit="cover"
+					:show-fullscreen-btn="false" :autoplay="true" class="map-video" loop muted :show-progress="false"
+					:show-play-btn="false">
+				</video>
+				<view class="map-tips">
+					飞鸟入驻管理果场详情,点击查看
+				</view>
+			</div>
 		</view>
 		<view class="type-wrap">
-			 <up-scroll-list 
-				:indicator="typeList.length>5" 
-				indicatorColor="#F3C11D33" 
-				indicatorActiveColor="#F3C11D" 
-				:indicatorWidth="30" 
-				:indicatorBarWidth="13"
-				ref="scrollListRef"
-			>
+			<up-scroll-list :indicator="typeList && typeList.length>5" indicatorColor="#F3C11D33" indicatorActiveColor="#F3C11D"
+				:indicatorWidth="30" :indicatorBarWidth="13" ref="scrollListRef">
 				<view class="item-type">
 					<image class="type-img" :src="`${config.BASIC_IMG}home/type-icon.png`" alt="" />
 					<view class="type-text">
@@ -51,14 +31,14 @@
 						{{item.name}}
 					</view>
 				</view>
-				
+
 			</up-scroll-list>
 		</view>
 		<!-- 好味热卖 -->
 		<view class="home-hot" v-if="gardenList && gardenList.length">
 			<hot-component-vue :farmId="gardenList[0].farmId"></hot-component-vue>
 		</view>
-		
+
 		<!-- 有味果园 -->
 		<view class="garden-wrap">
 			<view class="garden-content">
@@ -71,17 +51,14 @@
 					</view>
 				</view>
 				<view class="garden-list">
-					<view
-						class="garden-item"
-						v-for="farm in gardenList"
-						:key="farm.farmId || farm.id"
-						@click="goGardenItem(farm)"
-					>
+					<view class="garden-item" v-for="farm in gardenList" :key="farm.farmId || farm.id"
+						@click="goGardenItem(farm)">
 						<view class="garden-l" v-if="farm.coverVideo">
-							<video :id="`home-video-${farm.farmId || farm.id}`" :src="farm.coverVideo" :show-progress="false" :show-play-btn="true"
-								:picture-in-picture-mode="[]" :show-background-playback-button="false" :show-center-play-btn="false" object-fit="cover" :show-fullscreen-btn="false"
-								  disable-picture-in-picture :autoplay="false"  x5-video-player-type="h5" class="video-dom"
-								loop muted>
+							<video :id="`home-video-${farm.farmId || farm.id}`" :src="farm.coverVideo"
+								:show-progress="false" :show-play-btn="true" :picture-in-picture-mode="[]"
+								:show-background-playback-button="false" :show-center-play-btn="false"
+								object-fit="cover" :show-fullscreen-btn="false" disable-picture-in-picture
+								:autoplay="false" x5-video-player-type="h5" class="video-dom" loop muted>
 							</video>
 						</view>
 						<view class="garden-l" v-else>
@@ -116,339 +93,201 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onUnmounted, nextTick } from 'vue'
-import config from "@/api/config.js"
-import HOME from '@/api/home'
-import hotComponentVue from './hotComponent.vue'
-import { onLoad, onPageScroll } from "@dcloudio/uni-app"
-
-const typeSearch = ref(null)
- 
-function toPage(path) {
-  uni.navigateTo({
-    url: `/pages/tabBar/home/subPages/${path}`
-  });
-}
-
-function goGardenItem(farm) {
-	const id = farm?.farmId
-	uni.navigateTo({
-		url: `/pages/tabBar/home/subPages/gardenItem?farmId=${id}`
-	});
-}
-
-function goSourceReport(farm) {
-	const id = farm?.farmId
-	uni.navigateTo({
-		url: `/pages/tabBar/home/subPages/sourceReport?farmId=${id}`
-	});
-}
-
-onMounted(() => {
+	import {
+		ref,
+		onMounted,
+		onUnmounted,
+		nextTick
+	} from 'vue'
+	import config from "@/api/config.js"
+	import HOME from '@/api/home'
+	import { useUserStore } from '@/store/user' // 引入 Pinia store
+	import hotComponentVue from './hotComponent.vue'
+	import {
+		onLoad,
+		onPageScroll
+	} from "@dcloudio/uni-app"
+
+	// 获取 user store
+	const userStore = useUserStore()
 	
-			// 初始计算
-			nextTick(() => {
-				setTimeout(updateCenterVideo, 50)
-			})
-})
+	const typeSearch = ref(null)
+	const gardenList = ref([])
+	const typeList = ref([])
+	const playingId = ref(null)
+
+	function toPage(path) {
+		uni.navigateTo({
+			url: `/pages/tabBar/home/subPages/${path}`
+		});
+	}
+
+	function goGardenItem(farm) {
+		const id = farm?.farmId
+		uni.navigateTo({
+			url: `/pages/tabBar/home/subPages/gardenItem?farmId=${id}`
+		});
+	}
+
+	function goSourceReport(farm) {
+		const id = farm?.farmId
+		uni.navigateTo({
+			url: `/pages/tabBar/home/subPages/sourceReport?farmId=${id}`
+		});
+	}
+
+	onMounted(() => {
+		nextTick(() => {
+			setTimeout(updateCenterVideo, 50)
+		})
+	})
 
 	onPageScroll(() => handlePageScroll())
 
 	onUnmounted(() => {
-		// 离开页面时全部暂停
 		pauseAll()
 	})
-	
-	const playingId = ref(null)
-	
-		function throttle(fn, wait = 150) {
-			let lastTime = 0
-			let timer = null
-			return function(...args) {
-				const now = Date.now()
-				if (now - lastTime >= wait) {
-					lastTime = now
+
+	function throttle(fn, wait = 150) {
+		let lastTime = 0
+		let timer = null
+		return function(...args) {
+			const now = Date.now()
+			if (now - lastTime >= wait) {
+				lastTime = now
+				fn.apply(this, args)
+			} else {
+				clearTimeout(timer)
+				timer = setTimeout(() => {
+					lastTime = Date.now()
 					fn.apply(this, args)
-				} else {
-					clearTimeout(timer)
-					timer = setTimeout(() => {
-						lastTime = Date.now()
-						fn.apply(this, args)
-					}, wait - (now - lastTime))
-				}
+				}, wait - (now - lastTime))
 			}
 		}
-	
-		const handlePageScroll = throttle(() => {
-			updateCenterVideo()
-		}, 200)
-	
-		function updateCenterVideo() {
-			// 计算视口中心点附近的 video,播放该 video,其余暂停
-			const query = uni.createSelectorQuery()
-			query.selectAll('.video-dom').fields({ id: true, rect: true, size: true }, rects => {
-				if (!rects || !rects.length) return
-				const viewportHeight = uni.getSystemInfoSync().windowHeight
-				const viewportCenter = viewportHeight / 2
-				let minDistance = Number.POSITIVE_INFINITY
-				let closestId = null
-				rects.forEach(rect => {
-					if (!rect) return
-					const height = (typeof rect.height === 'number' ? rect.height : (rect.bottom - rect.top))
-					const elementCenter = rect.top + height / 2
-					// 仅考虑在可视区域内的元素
-					if (rect.bottom < 0 || rect.top > viewportHeight) return
-					const distance = Math.abs(elementCenter - viewportCenter)
-					if (distance < minDistance) {
-						minDistance = distance
-						closestId = rect.id
-					}
-				})
-				if (closestId && playingId.value !== closestId) {
-					playOnly(closestId)
+	}
+
+	const handlePageScroll = throttle(() => {
+		updateCenterVideo()
+	}, 200)
+
+	function updateCenterVideo() {
+		const query = uni.createSelectorQuery()
+		query.selectAll('.video-dom').fields({
+			id: true,
+			rect: true,
+			size: true
+		}, rects => {
+			if (!rects || !rects.length) return
+			const viewportHeight = uni.getSystemInfoSync().windowHeight
+			const viewportCenter = viewportHeight / 2
+			let minDistance = Number.POSITIVE_INFINITY
+			let closestId = null
+			rects.forEach(rect => {
+				if (!rect) return
+				const height = (typeof rect.height === 'number' ? rect.height : (rect.bottom - rect.top))
+				const elementCenter = rect.top + height / 2
+				if (rect.bottom < 0 || rect.top > viewportHeight) return
+				const distance = Math.abs(elementCenter - viewportCenter)
+				if (distance < minDistance) {
+					minDistance = distance
+					closestId = rect.id
 				}
-			}).exec()
-		}
-	
-		function playOnly(targetId) {
-			// 暂停所有,再播放目标
-			const ctxs = []
-			gardenList.value.forEach(item => {
-				if (!item.coverVideo) return
-				const id = `home-video-${item.farmId || item.id}`
-				const ctx = uni.createVideoContext(id)
-				ctxs.push({ id, ctx })
 			})
-			ctxs.forEach(({ id, ctx }) => {
-				if (id === targetId) {
-					try { ctx.play() } catch (e) {}
-					playingId.value = id
-				} else {
-					try { ctx.pause() } catch (e) {}
-				}
+			if (closestId && playingId.value !== closestId) {
+				playOnly(closestId)
+			}
+		}).exec()
+	}
+
+	function playOnly(targetId) {
+		const ctxs = []
+		gardenList.value.forEach(item => {
+			if (!item.coverVideo) return
+			const id = `home-video-${item.farmId || item.id}`
+			const ctx = uni.createVideoContext(id)
+			ctxs.push({
+				id,
+				ctx
 			})
-		}
-	
-		function pauseAll() {
-			gardenList.value.forEach(item => {
-				if (!item.coverVideo) return
-				const id = `home-video-${item.farmId || item.id}`
-				try { uni.createVideoContext(id).pause() } catch (e) {}
+		})
+		ctxs.forEach(({
+			id,
+			ctx
+		}) => {
+			if (id === targetId) {
+				try {
+					ctx.play()
+				} catch (e) {}
+				playingId.value = id
+			} else {
+				try {
+					ctx.pause()
+				} catch (e) {}
+			}
+		})
+	}
+
+	function pauseAll() {
+		gardenList.value.forEach(item => {
+			if (!item.coverVideo) return
+			const id = `home-video-${item.farmId || item.id}`
+			try {
+				uni.createVideoContext(id).pause()
+			} catch (e) {}
+		})
+	}
+
+	onLoad(async () => {
+		console.log('onLoad')
+		
+		try {
+			// 显示全局加载状态
+			uni.showLoading({
+				title: '加载中...',
+				mask: true
+			})
+			
+			// 【核心修改】等待token准备就绪
+			await userStore.getTokenSafe()
+			console.log('登录成功,token已就绪')
+			
+			// 现在可以安全地执行需要登录状态的请求
+			await getTypeList()
+			await getFarmData()
+			
+			// 隐藏加载状态
+			uni.hideLoading()
+		} catch (error) {
+			console.error('初始化失败:', error)
+			// 隐藏加载状态
+			uni.hideLoading()
+			// 登录失败处理,可以跳转到登录页或显示提示
+			uni.showToast({
+				title: '请先登录',
+				icon: 'none'
 			})
 		}
- 
-const latitude = ref(23.099994)
-const longitude = ref(113.324520)
-const markers = ref([])
-const includePoints = ref([])
-const mapCtx = ref(null)
-const mapPoint = '../../../static/map/point.png'
-const farmList = ref([]) // 新增果园列表数据
-const scale = ref(10)
-const gardenList = ref([])
-
-onLoad(async () => {
-  // #ifdef MP-WEIXIN
-  // mapCtx.value = uni.createMapContext('mapId')
-  
-  // mapCtx.value.on('markerClusterClick', res => {
-  //   console.log('markerClusterClick', res)
-  // })
-  
-  // bindEvent()
-  // #endif
-  
-  getTypeList()
-  
-  getFarmData()
-})
-
-const typeList = ref([])
-function getTypeList() {
-	HOME.fetchTypeList().then(({data}) => {
-		typeList.value = data
 	})
-}
- 
-function getFarmData() {
-  HOME.getAllFarm().then(({data}) => {
-	gardenList.value = data.filter(item => item.recommend !== null)
-	nextTick(() => setTimeout(updateCenterVideo, 50))
- //     farmList.value = (data || []).sort((a, b) => {
-	//   // 优先排序:lighten为true的排前面,然后按recommend排序
-	//   if (a.lighten !== b.lighten) return b.lighten ? 1 : -1
-	//   return (b.recommend || 0) - (a.recommend || 0)
-	// })
- //    if(farmList.value.length > 0) {
- //      // 设置地图中心点为第一个果园的位置
- //      const firstPoint = parsePoint(farmList.value[0].point)
- //      latitude.value = firstPoint.latitude
- //      longitude.value = firstPoint.longitude
-      
- //      // 生成标记点
- //      generateMarkers(farmList.value)
- //    }
-  })
-}
-
-// 解析POINT字符串为经纬度对象
-function parsePoint(pointStr) {
-  if(!pointStr) return {longitude: 113.324520, latitude: 23.099994}
-  
-  const regex = /POINT\(([^ ]+) ([^ ]+)\)/
-  const match = pointStr.match(regex)
-  if(match) {
-    return {
-      longitude: parseFloat(match[1]),
-      latitude: parseFloat(match[2])
-    }
-  }
-  return {longitude: 113.324520, latitude: 23.099994} // 默认值
-}
-
-// 生成标记点数据
-function generateMarkers(farms) {
-  const newMarkers = farms.map((farm, index) => {
-    const point = parsePoint(farm.point)
-    return {
-      id: farm.farmId || index + 1, // 使用farmId作为唯一标识
-      latitude: point.latitude,
-      longitude: point.longitude,
-      iconPath: mapPoint, // 使用果园图标
-      width: 20,
-      height: 20,
-      joinCluster: true,
-      // callout: { // 添加气泡标签
-      //   content: farm.name,
-      //   color: '#000',
-      //   fontSize: 14,
-      //   borderRadius: 4,
-      //   bgColor: '#FFCB3C',
-      //   padding: 8,
-      //   display: 'ALWAYS'
-      // },
-      label: {
-        content: farm.name, // 显示果园名称
-        color: '#000',
-        fontSize: 12,
-        bgColor: '#FFCB3C',
-        borderRadius: 8,
-        padding: 5,
-        anchorX: 0,
-        anchorY: -50,
-        borderWidth: 1,
-        borderColor: '#FFCB3C',
-        textAlign: 'center'
-      },
-      customData: farm // 存储原始数据用于点击事件
-    }
-  })
-  
-  // 更新包含的点位范围
-  includePoints.value = newMarkers.map(marker => ({
-    latitude: marker.latitude,
-    longitude: marker.longitude
-  }))
-  
-  // #ifdef MP-WEIXIN
-  mapCtx.value.addMarkers({
-    markers: newMarkers,
-    clear: true,
-    complete(res) {
-      console.log('添加标记点完成', res)
-    }
-  })
-  // #else
-  markers.value = newMarkers
-  // #endif
-}
- 
-const bindEvent = () => {
-  // #ifdef MP-WEIXIN
-  mapCtx.value.initMarkerCluster({
-    enableDefaultStyle: false,
-    zoomOnClick: true,
-    gridSize: 40,
-    complete(res) {
-      console.log('initMarkerCluster', res)
-    }
-  })
-  
-  mapCtx.value.on('markerClusterCreate', res => {
-    console.log('clusterCreate', res)
-    const clusters = res.clusters
-    const clusterMarkers = clusters.map(cluster => {
-      // 获取聚合中的第一个果园
-      const firstMarker = farmList.value.find(m => m.farmId === cluster.markerIds[0])
-      return {
-        ...cluster.center,
-        width: 20,
-        height: 20,
-        clusterId: cluster.clusterId,
-		iconPath: mapPoint, // 使用果园图标
-		label: {
-		  content: firstMarker?.name, // 显示果园名称
-		  color: '#000',
-		  fontSize: 12,
-		  bgColor: '#FFCB3C',
-		  borderRadius: 8,
-		  padding: 5,
-		  anchorX: 0,
-		  anchorY: -50,
-		  borderWidth: 1,
-		  borderColor: '#FFCB3C',
-		  textAlign: 'center'
-		},
-        customData: {
-          isCluster: true,
-          markerIds: cluster.markerIds,
-          firstMarkerData: firstMarker?.customData
-        }
-      }
-    })
-    
-    mapCtx.value.addMarkers({
-      markers: clusterMarkers,
-      clear: false,
-      complete(res) {
-      }
-    })
-  })
-  // #endif
-}
- 
-const onMarkerTap = (e) => {
-  const markerId = e.detail.markerId
-  const marker = markers.value.find(m => m.id === markerId)
-  if(marker && marker.customData) {
-    console.log('点击了果园:', marker.customData.name)
-    // 可以在这里跳转到果园详情页
-    uni.navigateTo({
-      url: `/pages/tabBar/home/subPages/gardenItem?farmId=${marker.customData.farmId}`
-    })
-  }
-}
-
-const onCalloutTap = (e) => {
-  console.log('点击了气泡:', e)
-  onMarkerTap(e) // 调用相同的处理逻辑
-}
-
-const onLabelTap = (e) => {
-  console.log('点击了标签:', e)
-  onMarkerTap(e) // 调用相同的处理逻辑
-}
-
-const removeMarkers = () => {
-  // #ifdef MP-WEIXIN
-  mapCtx.value.addMarkers({
-    clear: true,
-    markers: []
-  })
-  // #else
-  markers.value = []
-  // #endif
-}
+
+	async function getTypeList() {
+		try {
+			const { data } = await HOME.fetchTypeList()
+			typeList.value = data
+		} catch (error) {
+			console.error('获取类型列表失败:', error)
+		}
+	}
+
+	async function getFarmData() {
+		try {
+			const { data } = await HOME.getAllFarm()
+			if (!data || !data.length)  return
+			gardenList.value = data.filter(item => item.recommend !== null)
+			nextTick(() => setTimeout(updateCenterVideo, 50))
+		} catch (error) {
+			console.error('获取果园数据失败:', error)
+		}
+	}
 </script>
 
 <style lang="scss" scoped>
@@ -460,24 +299,28 @@ const removeMarkers = () => {
 			}
 		}
 	}
-	
+
 	/* 或者全局隐藏 */
 	::v-deep .uni-video-pip {
-	  display: none !important;
+		display: none !important;
 	}
+
 	.home-wrap {
 		background-color: #F2F3F5;
 		padding: 0 0 16rpx 0;
+
 		.home-top {
 			padding: 20rpx 24rpx 0 24rpx;
 			background: linear-gradient(#FFFFFF, rgba(242, 243, 245, 0));
 			position: relative;
 		}
+
 		.map-video {
 			width: 100%;
 			height: 280rpx;
 			border-radius: 16rpx;
 		}
+
 		.map-tips {
 			position: absolute;
 			bottom: 6rpx;
@@ -493,6 +336,7 @@ const removeMarkers = () => {
 			box-sizing: border-box;
 			border-radius: 0 0 16rpx 16rpx;
 		}
+
 		.home-search {
 			display: flex;
 			align-items: center;
@@ -500,18 +344,22 @@ const removeMarkers = () => {
 			border: 2rpx solid #FFD95E;
 			border-radius: 40rpx;
 			margin-bottom: 40rpx;
+
 			.search-wrap {
 				flex: 1;
+
 				// padding-left: 22rpx;
 				::v-deep {
 					.u-search {
 						.u-search__content {
 							background-color: transparent !important;
+
 							.u-search__content__input {
 								background-color: transparent !important;
-								
+
 							}
 						}
+
 						.u-search__action {
 							text-align: center;
 							line-height: 52rpx;
@@ -525,6 +373,7 @@ const removeMarkers = () => {
 					}
 				}
 			}
+
 			.search-btn {
 				text-align: center;
 				line-height: 52rpx;
@@ -536,6 +385,7 @@ const removeMarkers = () => {
 				height: 52rpx;
 			}
 		}
+
 		.type-wrap {
 			margin: 20rpx;
 			padding: 20rpx;
@@ -543,7 +393,7 @@ const removeMarkers = () => {
 			border-radius: 16rpx;
 			height: 200rpx;
 			box-sizing: border-box;
-			
+
 			// 覆盖 up-scroll-list 的默认样式,实现两端对齐
 			:deep(.u-scroll-list__scroll-view__content) {
 				display: flex;
@@ -552,51 +402,60 @@ const removeMarkers = () => {
 				width: 100%;
 				min-width: 100%;
 			}
-			
+
 			.item-type {
 				text-align: center;
 				font-size: 24rpx;
 				flex-shrink: 0;
+
 				.type-img {
 					width: 92rpx;
 					height: 92rpx;
 				}
 			}
-			.item-type + .item-type {
+
+			.item-type+.item-type {
 				padding-left: 22rpx;
 			}
 		}
+
 		.home-hot {
 			padding: 0 20rpx 20rpx;
 		}
-		
+
 		.garden-wrap {
 			margin: 0 20rpx 20rpx;
 			background: linear-gradient(#FFFFFF, rgba(255, 255, 255, 0));
 			padding: 2rpx;
 			border-radius: 16rpx;
-			.garden-content{
-				background: linear-gradient(#fff6d8 30rpx,  #FFFFFF 120rpx);
+
+			.garden-content {
+				background: linear-gradient(#fff6d8 30rpx, #FFFFFF 120rpx);
 				border-radius: 16rpx;
 				padding: 20rpx;
 				box-sizing: border-box;
+
 				.garden-list {
 					.garden-item {
 						display: flex;
+
 						.garden-l {
 							position: relative;
+
 							.video-dom {
 								width: 234rpx;
 								height: 200rpx;
 								object-fit: cover;
 								border-radius: 10rpx;
 							}
+
 							.garden-img {
 								width: 254rpx;
 								height: 200rpx;
 								object-fit: cover;
 								border-radius: 10rpx;
 							}
+
 							.img-text {
 								position: absolute;
 								left: 0%;
@@ -609,8 +468,10 @@ const removeMarkers = () => {
 								padding: 6rpx 14rpx;
 							}
 						}
+
 						.garden-r {
 							padding-left: 20rpx;
+
 							.garden-title {
 								font-size: 28rpx;
 								line-height: 42rpx;
@@ -618,15 +479,18 @@ const removeMarkers = () => {
 								font-weight: 600;
 								padding-bottom: 10rpx;
 							}
+
 							.garden-info {
 								color: rgba(0, 0, 0, 0.5);
 								font-size: 24rpx;
 								line-height: 36rpx;
 							}
+
 							.garden-btn-group {
 								padding-top: 20rpx;
 								display: flex;
 								align-items: center;
+
 								.btn-second {
 									padding: 0 20rpx;
 									border-radius: 40rpx;
@@ -636,6 +500,7 @@ const removeMarkers = () => {
 									height: 56rpx;
 									line-height: 56rpx;
 								}
+
 								.btn-primary {
 									padding: 0 20rpx;
 									border-radius: 40rpx;
@@ -650,27 +515,31 @@ const removeMarkers = () => {
 							}
 						}
 					}
-					.garden-item + .garden-item {
+
+					.garden-item+.garden-item {
 						margin-top: 20rpx;
 					}
 				}
 			}
-			
+
 		}
-		
-		
+
+
 		.hot-title {
 			display: flex;
 			align-items: center;
 			justify-content: space-between;
 			padding-bottom: 20rpx;
+
 			.title-l {
 				font-family: 'PangMenZhengDao';
 				font-size: 32rpx;
+
 				.title-color {
-					color: #F3C11D ;
+					color: #F3C11D;
 				}
 			}
+
 			.title-btn {
 				color: rgba(0, 0, 0, 0.6);
 				font-size: 24rpx;
@@ -678,8 +547,8 @@ const removeMarkers = () => {
 				align-items: center;
 			}
 		}
-	
-		
+
+
 		::v-deep {
 			.u-scroll-list__indicator {
 				margin-top: 20rpx;

+ 4 - 4
pages/tabBar/home/subPages/allGardenMap.vue

@@ -14,10 +14,10 @@
 	const webViewUrl = ref('')
 
 	onMounted(() => {
-		// webViewUrl.value =
-		// 	`https://feiniao-mini-h5-dev.sysuimars.cn/youwei/#/allGardenMap?userId=${userInfo.id}&token=${userInfo.token}`
-		// webViewUrl.value = "http://localhost:8081/#/allGardenMap?userId=91754&token=034d7cf5-25fc-42d3-993e-460120419e5a"
 		webViewUrl.value =
-			`http://localhost:8081/#/gardenMap?userId=${userInfo.id}&token=${userInfo.token}&isFromScan=true`
+			`https://feiniao-mini-h5-dev.sysuimars.cn/youwei/#/allGardenMap?userId=${userInfo.id}&token=${userInfo.token}`
+		// webViewUrl.value = "http://localhost:8081/#/allGardenMap?userId=91754&token=034d7cf5-25fc-42d3-993e-460120419e5a"
+		// webViewUrl.value =
+		// 	`http://localhost:8081/#/gardenMap?userId=${userInfo.id}&token=${userInfo.token}&isFromScan=true`
 	})
 </script>

+ 90 - 0
store/user.js

@@ -0,0 +1,90 @@
+// stores/user.js
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+import USER from '@/api/user.js'
+
+export const useUserStore = defineStore('user', () => {
+  const token = ref(uni.getStorageSync('token') || null)
+  const userInfo = ref(uni.getStorageSync('userInfo') || null)
+  const isLogging = ref(false)
+
+  const login = async () => {
+    // if (isLogging.value) {
+    //   throw new Error('登录正在进行中')
+    // }
+
+    isLogging.value = true
+    
+    try {
+      let loginData = null
+
+      // #ifdef MP-WEIXIN
+      loginData = await new Promise((resolve, reject) => {
+        uni.login({
+          success: async ({ code }) => {
+            try {
+              const { data } = await USER.fetchLogin({ code })
+              resolve(data)
+            } catch (error) {
+              reject(error)
+            }
+          },
+          fail: reject
+        })
+      })
+      // #endif
+
+      // #ifdef H5
+      const { data } = await USER.userInfo()
+      loginData = data
+      // #endif
+		uni.setStorageSync('userInfo', loginData);
+      if (loginData) {
+        const { token: newToken, ...userData } = loginData
+        
+        if (newToken) {
+          token.value = newToken
+          uni.setStorageSync('token', newToken)
+        }
+        
+        userInfo.value = userData
+        // uni.setStorageSync('userInfo', userData)
+        
+        return loginData
+      } else {
+        throw new Error('登录失败:未获取到数据')
+      }
+
+    } catch (error) {
+      token.value = null
+      userInfo.value = null
+      uni.removeStorageSync('token')
+      uni.removeStorageSync('userInfo')
+      throw error
+    } finally {
+      isLogging.value = false
+    }
+  }
+
+  const getTokenSafe = async () => {
+    if (token.value) {
+      return token.value
+    }
+    
+    try {
+      const result = await login()
+      return result.token || token.value
+    } catch (error) {
+      console.error('自动登录失败', error)
+      throw error
+    }
+  }
+
+  return {
+    token,
+    userInfo,
+    isLogging,
+    login,
+    getTokenSafe
+  }
+})