Преглед на файлове

feat(profile): 添加自动获取用户地理位置功能

- 在 manifest.json 中添加定位相关权限配置
- 新增自动获取位置按钮及交互逻辑
- 实现通过经纬度获取省市区地址信息
- 添加获取位置时的加载状态和错误提示
- 更新样式以支持定位按钮布局
mcbaiyun преди 2 месеца
родител
ревизия
6747de8107
променени са 2 файла, в които са добавени 72 реда и са изтрити 5 реда
  1. 11 2
      src/manifest.json
  2. 61 3
      src/pages/profile/complete-info.vue

+ 11 - 2
src/manifest.json

@@ -37,7 +37,9 @@
                     "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                     "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                     "<uses-feature android:name=\"android.hardware.camera\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>"
                 ]
             },
             /* ios打包配置 */
@@ -56,7 +58,14 @@
             "minified" : true,
             "postcss" : true
         },
-        "usingComponents" : true
+        "usingComponents" : true,
+        "permission" : {
+            "scope.userLocation" : {
+                "desc" : "获取用户位置"
+            }
+
+        },
+        "requiredPrivateInfos" : ["getLocation"]
     },
     "mp-alipay" : {
         "usingComponents" : true

+ 61 - 3
src/pages/profile/complete-info.vue

@@ -51,9 +51,14 @@
 
       <view class="form-item">
         <text class="label">省/市</text>
-        <picker mode="region" :value="region" @change="onRegionChange">
-          <view class="picker">{{ region.join(' ') || '请选择省/市' }}</view>
-        </picker>
+        <view class="location-section">
+          <picker mode="region" :value="region" @change="onRegionChange">
+            <view class="picker">{{ region.join(' ') || '请选择省/市' }}</view>
+          </picker>
+          <button class="get-location-btn" @click="getCurrentLocation" :disabled="gettingLocation">
+            {{ gettingLocation ? '获取中...' : '自动获取' }}
+          </button>
+        </view>
       </view>
 
 
@@ -82,6 +87,7 @@ const form = ref({
 const region = ref<string[]>([])
 const submitting = ref(false)
 const isChoosing = ref(false)
+const gettingLocation = ref(false)
 
 
 const onChooseAvatar = (e: any) => {
@@ -140,6 +146,37 @@ const onRegionChange = (e: any) => {
   form.value.address = region.value.join(' ')
 }
 
+const getCurrentLocation = async () => {
+  if (gettingLocation.value) return
+  gettingLocation.value = true
+  try {
+    // 获取经纬度
+    const locationRes = await uni.getLocation({ type: 'wgs84' })
+    const { latitude, longitude } = locationRes
+    console.log('getLocation success:', locationRes)
+
+    // 调用用户自己的地理编码接口
+    const geocodeRes = await uni.request({
+      url: `http://45.207.222.6/geo/nearest.php?latitude=${latitude}&longitude=${longitude}`,
+      method: 'GET'
+    })
+
+    const data = geocodeRes.data as any
+    if (data && data.province && data.city) {
+      region.value = [data.province, data.city,data.district]
+      form.value.address = region.value.join(' ')
+      uni.showToast({ title: '位置获取成功', icon: 'success' })
+    } else {
+      throw new Error('Geocode failed')
+    }
+  } catch (err) {
+    console.error('Get location error:', err)
+    uni.showToast({ title: '获取位置失败,请检查定位权限和网络', icon: 'none' })
+  } finally {
+    gettingLocation.value = false
+  }
+}
+
 const onSubmit = async () => {
   if (submitting.value) return
   if (!form.value.nickname || !form.value.avatar) {
@@ -310,6 +347,27 @@ const onSubmit = async () => {
   color: #333;
 }
 
+.location-section {
+  display: flex;
+  align-items: center;
+  gap: 20rpx;
+}
+
+.get-location-btn {
+  flex-shrink: 0;
+  height: 80rpx;
+  background: linear-gradient(135deg, #07C160 0%, #00A854 100%);
+  color: #fff;
+  border-radius: 8rpx;
+  font-size: 28rpx;
+  padding: 0 30rpx;
+  border: none;
+}
+
+.get-location-btn:disabled {
+  opacity: 0.5;
+}
+
 .submit-section {
   margin-top: 60rpx;
 }