3 files modified
2 files added
| | |
| | | <script setup> |
| | | import { onHide, onLaunch, onShow } from "@dcloudio/uni-app"; |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | import { useAppStore, useUserStore, useLocationStore } from "@/store"; |
| | | import { useGlobalWS } from "@/hooks/useGlobalWS.js"; |
| | | |
| | | const appStore = useAppStore(); |
| | | const userStore = useUserStore(); |
| | | const locationStore = useLocationStore(); |
| | | |
| | | useGlobalWS(); |
| | | |
| | | onShow(() => { |
| | | onShow(async () => { |
| | | console.log("App Show"); |
| | | // 应用从后台返回前台时,重新初始化位置服务 |
| | | if (userStore.userInfo && locationStore) { |
| | | try { |
| | | await locationStore.initLocationService(); |
| | | } catch (error) { |
| | | console.error('重新初始化位置服务失败:', error); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | onHide(() => { |
| | | console.log("App Hide"); |
| | | // 应用进入后台时,停止位置监听以节省资源 |
| | | if (locationStore) { |
| | | locationStore.stopLocationWatch(); |
| | | } |
| | | }); |
| | | |
| | | onLaunch(() => { |
| | |
| | | import { getAssetsImage } from "@/utils/index.js"; |
| | | import md5 from "js-md5"; |
| | | import { loginByUsername } from "@/api/user/index.js"; |
| | | import { useUserStore } from "@/store/index.js"; |
| | | import { useUserStore, useLocationStore } from "@/store/index.js"; |
| | | import locationUtil from "@/utils/location.js"; |
| | | import websocketService from "@/utils/websocket.js"; |
| | | |
| | | import { HOME_PATH, LOGIN_PATH, removeQueryString } from "@/router"; |
| | |
| | | const agreed = ref(true); |
| | | |
| | | const userStore = useUserStore(); |
| | | const locationStore = useLocationStore(); |
| | | const loginForm = ref({ |
| | | username: "", |
| | | password: "", |
| | |
| | | ); |
| | | userStore.setUserInfo(res.data.data); |
| | | console.log('登录成功,WebSocket连接将由全局钩子统一管理'); |
| | | |
| | | // 请求位置权限并初始化位置服务 |
| | | try { |
| | | // 请求位置权限 |
| | | const hasPermission = await locationUtil.requestLocationPermission(); |
| | | if (hasPermission) { |
| | | console.log('获取位置权限成功'); |
| | | // 初始化位置服务 |
| | | await locationStore.initLocationService(); |
| | | } else { |
| | | console.log('获取位置权限失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('处理位置服务失败:', error); |
| | | } |
| | | |
| | | uni.reLaunch({ |
| | | url: "/pages/work/index", |
| | | }); |
| | |
| | | import useAppStore from "./modules/app" |
| | | import useUserStore from "./modules/user" |
| | | import useMapStore from "./modules/map" |
| | | import useLocationStore from "./modules/location" |
| | | |
| | | // 安装pinia状态管理插件 |
| | | function setupStore (app) { |
| | |
| | | } |
| | | |
| | | // 导出模块 |
| | | export { useAppStore, useUserStore, useMapStore } |
| | | export { useAppStore, useUserStore, useMapStore, useLocationStore } |
| | | export default setupStore |
| New file |
| | |
| | | import { defineStore } from 'pinia' |
| | | import locationUtil from '@/utils/location.js' |
| | | |
| | | const useLocationStore = defineStore('location', { |
| | | state: () => ({ |
| | | // 当前位置信息 |
| | | currentLocation: null, |
| | | // 位置权限状态 |
| | | hasPermission: false, |
| | | // 系统定位服务是否开启 |
| | | systemLocationEnabled: true, |
| | | // 位置更新间隔(毫秒) |
| | | updateInterval: 5000, |
| | | // 位置监听器ID |
| | | watcherId: null |
| | | }), |
| | | |
| | | getters: { |
| | | /** |
| | | * 获取当前位置 |
| | | * @returns {Object|null} 当前位置信息 |
| | | */ |
| | | getCurrentLocation: (state) => state.currentLocation, |
| | | |
| | | /** |
| | | * 获取位置权限状态 |
| | | * @returns {boolean} 是否有位置权限 |
| | | */ |
| | | getPermissionStatus: (state) => state.hasPermission, |
| | | |
| | | /** |
| | | * 获取系统定位服务状态 |
| | | * @returns {boolean} 系统定位服务是否开启 |
| | | */ |
| | | getSystemLocationStatus: (state) => state.systemLocationEnabled |
| | | }, |
| | | |
| | | actions: { |
| | | /** |
| | | * 初始化位置服务 |
| | | */ |
| | | async initLocationService() { |
| | | try { |
| | | // 检查系统定位服务是否开启 |
| | | this.systemLocationEnabled = await locationUtil.checkSystemLocationEnabled(); |
| | | if (!this.systemLocationEnabled) { |
| | | console.warn('系统定位服务未开启'); |
| | | } |
| | | |
| | | // 请求位置权限 |
| | | this.hasPermission = await locationUtil.requestLocationPermission(); |
| | | if (this.hasPermission) { |
| | | // 获取当前位置 |
| | | await this.updateCurrentLocation(); |
| | | // 开始位置监听 |
| | | this.startLocationWatch(); |
| | | } |
| | | } catch (error) { |
| | | console.error('初始化位置服务失败:', error); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 更新当前位置 |
| | | */ |
| | | async updateCurrentLocation() { |
| | | try { |
| | | const location = await locationUtil.getCurrentLocation(); |
| | | this.currentLocation = location; |
| | | console.log('位置更新:', location); |
| | | return location; |
| | | } catch (error) { |
| | | console.error('更新位置失败:', error); |
| | | return null; |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 开始位置监听 |
| | | */ |
| | | startLocationWatch() { |
| | | if (this.watcherId) { |
| | | this.stopLocationWatch(); |
| | | } |
| | | |
| | | this.watcherId = locationUtil.startLocationWatcher((location) => { |
| | | this.currentLocation = location; |
| | | // 可以在这里添加位置信息上报逻辑 |
| | | this.reportLocation(location); |
| | | }, { |
| | | interval: this.updateInterval |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | | * 停止位置监听 |
| | | */ |
| | | stopLocationWatch() { |
| | | if (this.watcherId) { |
| | | locationUtil.stopLocationWatcher(); |
| | | this.watcherId = null; |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 重新请求位置权限 |
| | | */ |
| | | async reRequestPermission() { |
| | | this.hasPermission = await locationUtil.requestLocationPermission(); |
| | | if (this.hasPermission) { |
| | | await this.updateCurrentLocation(); |
| | | this.startLocationWatch(); |
| | | } |
| | | return this.hasPermission; |
| | | }, |
| | | |
| | | /** |
| | | * 位置信息上报(可根据实际需求实现) |
| | | * @param {Object} location 位置信息 |
| | | */ |
| | | reportLocation(location) { |
| | | // 这里可以添加位置信息上报到服务器的逻辑 |
| | | // 例如:api.uploadLocation(location) |
| | | console.log('位置上报:', location); |
| | | }, |
| | | |
| | | /** |
| | | * 清理位置服务 |
| | | */ |
| | | cleanupLocationService() { |
| | | this.stopLocationWatch(); |
| | | this.currentLocation = null; |
| | | } |
| | | } |
| | | }) |
| | | |
| | | export default useLocationStore |
| New file |
| | |
| | | /** |
| | | * 位置管理工具类 |
| | | * 用于处理位置权限请求和实时位置获取 |
| | | */ |
| | | import permission from './voiceCallByTX/TrtcCloud/permission.js' |
| | | |
| | | // 平台判断 |
| | | const isIos = () => { |
| | | // #ifdef APP-PLUS |
| | | return plus.os.name === "iOS"; |
| | | // #endif |
| | | return false; |
| | | }; |
| | | |
| | | // 位置更新回调函数 |
| | | let locationUpdateCallback = null; |
| | | // 位置监听器ID |
| | | let locationWatcherId = null; |
| | | |
| | | /** |
| | | * 请求位置权限 |
| | | * @returns {Promise<boolean>} 是否获取到权限 |
| | | */ |
| | | export const requestLocationPermission = async () => { |
| | | return new Promise(async (resolve) => { |
| | | // #ifdef APP-PLUS |
| | | if (isIos()) { |
| | | // iOS平台 |
| | | const hasPermission = permission.judgeIosPermission('location'); |
| | | if (hasPermission) { |
| | | resolve(true); |
| | | } else { |
| | | // iOS需要提示用户手动开启权限 |
| | | uni.showModal({ |
| | | title: '提示', |
| | | content: '应用需要获取位置信息权限,请在设置中开启', |
| | | confirmText: '去设置', |
| | | cancelText: '取消', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | permission.gotoAppPermissionSetting(); |
| | | resolve(false); |
| | | } else { |
| | | resolve(false); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } else { |
| | | // Android平台 |
| | | const result = await permission.requestAndroidPermission('android.permission.ACCESS_FINE_LOCATION'); |
| | | if (result === 1) { |
| | | resolve(true); |
| | | } else if (result === 0) { |
| | | // 拒绝本次申请 |
| | | resolve(false); |
| | | } else if (result === -1) { |
| | | // 永久拒绝 |
| | | uni.showModal({ |
| | | title: '提示', |
| | | content: '应用需要获取位置信息权限,请在设置中开启', |
| | | confirmText: '去设置', |
| | | cancelText: '取消', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | permission.gotoAppPermissionSetting(); |
| | | resolve(false); |
| | | } else { |
| | | resolve(false); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | // #endif |
| | | // #ifdef H5 |
| | | // H5平台使用浏览器原生API请求权限 |
| | | if (navigator.geolocation) { |
| | | navigator.permissions.query({ name: 'geolocation' }).then((result) => { |
| | | if (result.state === 'granted') { |
| | | resolve(true); |
| | | } else if (result.state === 'prompt') { |
| | | // 还未请求过权限,会在getLocation时提示 |
| | | resolve(true); |
| | | } else { |
| | | resolve(false); |
| | | } |
| | | }).catch(() => { |
| | | resolve(false); |
| | | }); |
| | | } else { |
| | | resolve(false); |
| | | } |
| | | // #endif |
| | | // #ifdef MP |
| | | // 小程序平台 |
| | | uni.getSetting({ |
| | | success: (res) => { |
| | | if (res.authSetting['scope.userLocation']) { |
| | | resolve(true); |
| | | } else { |
| | | uni.authorize({ |
| | | scope: 'scope.userLocation', |
| | | success: () => { |
| | | resolve(true); |
| | | }, |
| | | fail: () => { |
| | | uni.showModal({ |
| | | title: '提示', |
| | | content: '应用需要获取位置信息权限,请在设置中开启', |
| | | confirmText: '去设置', |
| | | cancelText: '取消', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | uni.openSetting(); |
| | | resolve(false); |
| | | } else { |
| | | resolve(false); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | // #endif |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 获取当前位置信息 |
| | | * @returns {Promise<Object>} 位置信息对象 |
| | | */ |
| | | export const getCurrentLocation = () => { |
| | | return new Promise((resolve, reject) => { |
| | | uni.getLocation({ |
| | | type: 'gcj02', |
| | | altitude: true, |
| | | success: (res) => { |
| | | resolve({ |
| | | latitude: res.latitude, |
| | | longitude: res.longitude, |
| | | altitude: res.altitude, |
| | | accuracy: res.accuracy, |
| | | speed: res.speed, |
| | | verticalAccuracy: res.verticalAccuracy, |
| | | horizontalAccuracy: res.horizontalAccuracy |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('获取位置失败:', err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 开始实时位置监听 |
| | | * @param {Function} callback 位置更新回调函数 |
| | | * @param {Object} options 监听选项 |
| | | * @returns {number} 监听器ID |
| | | */ |
| | | export const startLocationWatcher = (callback, options = {}) => { |
| | | if (locationWatcherId) { |
| | | stopLocationWatcher(); |
| | | } |
| | | |
| | | locationUpdateCallback = callback; |
| | | |
| | | locationWatcherId = uni.startLocationUpdate({ |
| | | success: () => { |
| | | console.log('开始位置监听成功'); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('开始位置监听失败:', err); |
| | | // 如果是因为权限问题,重新请求权限 |
| | | if (err.errCode === 12002) { |
| | | requestLocationPermission(); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // 监听位置更新 |
| | | uni.onLocationChange((res) => { |
| | | const locationInfo = { |
| | | latitude: res.latitude, |
| | | longitude: res.longitude, |
| | | altitude: res.altitude, |
| | | accuracy: res.accuracy, |
| | | speed: res.speed, |
| | | verticalAccuracy: res.verticalAccuracy, |
| | | horizontalAccuracy: res.horizontalAccuracy, |
| | | timestamp: res.timestamp |
| | | }; |
| | | |
| | | if (locationUpdateCallback) { |
| | | locationUpdateCallback(locationInfo); |
| | | } |
| | | }); |
| | | |
| | | return locationWatcherId; |
| | | }; |
| | | |
| | | /** |
| | | * 停止位置监听 |
| | | */ |
| | | export const stopLocationWatcher = () => { |
| | | if (locationWatcherId) { |
| | | uni.stopLocationUpdate({ |
| | | success: () => { |
| | | console.log('停止位置监听成功'); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('停止位置监听失败:', err); |
| | | } |
| | | }); |
| | | locationWatcherId = null; |
| | | } |
| | | |
| | | // 移除位置更新监听 |
| | | uni.offLocationChange(); |
| | | locationUpdateCallback = null; |
| | | }; |
| | | |
| | | /** |
| | | * 检查系统定位服务是否开启 |
| | | * @returns {Promise<boolean>} 是否开启 |
| | | */ |
| | | export const checkSystemLocationEnabled = async () => { |
| | | return new Promise((resolve) => { |
| | | // #ifdef APP-PLUS |
| | | const enabled = permission.checkSystemEnableLocation(); |
| | | resolve(enabled); |
| | | // #endif |
| | | // #ifdef H5 |
| | | resolve(navigator.geolocation ? true : false); |
| | | // #endif |
| | | // #ifdef MP |
| | | uni.getSystemInfo({ |
| | | success: (res) => { |
| | | // 小程序无法直接检查系统定位服务是否开启 |
| | | resolve(true); |
| | | }, |
| | | fail: () => { |
| | | resolve(false); |
| | | } |
| | | }); |
| | | // #endif |
| | | }); |
| | | }; |
| | | |
| | | export default { |
| | | requestLocationPermission, |
| | | getCurrentLocation, |
| | | startLocationWatcher, |
| | | stopLocationWatcher, |
| | | checkSystemLocationEnabled |
| | | }; |