fix:授权用户定位
parent
15b9d11157
commit
ff60fdf732
162
api/index.js
162
api/index.js
|
|
@ -11,6 +11,91 @@ let isRefreshing = false
|
||||||
// 等待刷新完成的请求队列
|
// 等待刷新完成的请求队列
|
||||||
let refreshSubscribers = []
|
let refreshSubscribers = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查当前是否在登录页面
|
||||||
|
* @returns {Boolean} 是否在登录页面
|
||||||
|
*/
|
||||||
|
function isInLoginPage() {
|
||||||
|
try {
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
if (pages.length === 0) return false
|
||||||
|
const currentPage = pages[pages.length - 1]
|
||||||
|
const currentRoute = currentPage ? currentPage.route : ''
|
||||||
|
return currentRoute === 'pages/login/login'
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查登录页面状态失败:', error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否刚刚从登录页面返回(页面栈中有登录页面)
|
||||||
|
* @returns {Boolean} 是否刚刚从登录页面返回
|
||||||
|
*/
|
||||||
|
function isJustBackFromLogin() {
|
||||||
|
try {
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
if (pages.length <= 1) return false
|
||||||
|
// 检查页面栈中是否有登录页面(除了当前页面)
|
||||||
|
const hasLoginPage = pages.some((page, index) => {
|
||||||
|
// 排除当前页面(最后一个)
|
||||||
|
if (index === pages.length - 1) return false
|
||||||
|
const route = page ? page.route : ''
|
||||||
|
return route === 'pages/login/login'
|
||||||
|
})
|
||||||
|
return hasLoginPage
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查登录页面返回状态失败:', error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转到登录页面(如果不在登录页面才跳转)
|
||||||
|
* 如果已经在登录页面,则不进行跳转
|
||||||
|
* 如果多次被弹出,退出时直接回到根目录
|
||||||
|
*/
|
||||||
|
function navigateToLogin() {
|
||||||
|
// 如果已经在登录页面,不需要再次跳转
|
||||||
|
if (isInLoginPage()) {
|
||||||
|
console.log('已在登录页面,无需重复跳转')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前页面栈
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
|
||||||
|
// 如果页面栈中有多个页面,且包含登录页面,说明可能是多次弹出
|
||||||
|
// 使用 reLaunch 直接回到根目录(首页),然后跳转到登录页
|
||||||
|
if (pages.length > 1) {
|
||||||
|
// 检查页面栈中是否有登录页面
|
||||||
|
const hasLoginPage = pages.some(page => {
|
||||||
|
const route = page ? page.route : ''
|
||||||
|
return route === 'pages/login/login'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (hasLoginPage) {
|
||||||
|
// 多次被弹出,直接回到根目录
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正常情况,跳转到登录页面
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/login/login',
|
||||||
|
fail: (err) => {
|
||||||
|
// 如果 navigateTo 失败(可能因为页面栈已满),使用 reLaunch
|
||||||
|
console.warn('navigateTo 失败,使用 reLaunch:', err)
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新token
|
* 刷新token
|
||||||
* @param {String} refreshToken 刷新令牌
|
* @param {String} refreshToken 刷新令牌
|
||||||
|
|
@ -133,21 +218,36 @@ export function request(options = {}) {
|
||||||
// 构建完整URL(处理BASE_URL末尾斜杠问题)
|
// 构建完整URL(处理BASE_URL末尾斜杠问题)
|
||||||
const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url.startsWith('/') ? url : '/' + url}`
|
const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url.startsWith('/') ? url : '/' + url}`
|
||||||
|
|
||||||
// 构建请求头
|
// 构建请求头(先添加基础头,再添加传入的 header,最后添加 token,确保 token 不会被覆盖)
|
||||||
const requestHeader = {
|
const requestHeader = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'tenant-id': '1', // 统一添加租户ID
|
'tenant-id': '1', // 统一添加租户ID
|
||||||
...header
|
...header
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加token(如果需要认证)
|
// 添加token(如果需要认证,必须在最后添加,确保不会被 header 参数覆盖)
|
||||||
if (needAuth) {
|
if (needAuth) {
|
||||||
const token = uni.getStorageSync('token')
|
const token = uni.getStorageSync('token')
|
||||||
if (token) {
|
if (token) {
|
||||||
requestHeader['Authorization'] = `Bearer ${token}`
|
requestHeader['Authorization'] = `Bearer ${token}`
|
||||||
|
console.log('[API] 请求已添加 Authorization 头:', url)
|
||||||
|
console.log('[API] Token 长度:', token.length, 'Token 前10位:', token.substring(0, 10))
|
||||||
|
} else {
|
||||||
|
console.error('[API] 需要认证但未找到 token,请求可能失败:', url)
|
||||||
|
console.error('[API] 当前存储的所有 key:', uni.getStorageInfoSync().keys)
|
||||||
|
// 即使没有 token,也尝试发起请求(让后端返回 401)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 调试:打印请求信息
|
||||||
|
console.log('[API] 发起请求:', {
|
||||||
|
url: fullUrl,
|
||||||
|
method: method.toUpperCase(),
|
||||||
|
needAuth: needAuth,
|
||||||
|
hasAuthHeader: !!requestHeader['Authorization'],
|
||||||
|
headers: Object.keys(requestHeader)
|
||||||
|
})
|
||||||
|
|
||||||
// 发起请求
|
// 发起请求
|
||||||
uni.request({
|
uni.request({
|
||||||
url: fullUrl,
|
url: fullUrl,
|
||||||
|
|
@ -169,6 +269,12 @@ export function request(options = {}) {
|
||||||
if (res.data.code !== undefined) {
|
if (res.data.code !== undefined) {
|
||||||
// 处理业务错误码401(账号未登录)
|
// 处理业务错误码401(账号未登录)
|
||||||
if (res.data.code === 401) {
|
if (res.data.code === 401) {
|
||||||
|
// 如果已经在登录页面,不需要显示弹窗和跳转
|
||||||
|
if (isInLoginPage()) {
|
||||||
|
reject(new Error('未授权'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 显示登录弹窗
|
// 显示登录弹窗
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
|
@ -184,9 +290,7 @@ export function request(options = {}) {
|
||||||
uni.removeStorageSync('userId')
|
uni.removeStorageSync('userId')
|
||||||
uni.removeStorageSync('userInfo')
|
uni.removeStorageSync('userInfo')
|
||||||
// 跳转到登录页面
|
// 跳转到登录页面
|
||||||
uni.navigateTo({
|
navigateToLogin()
|
||||||
url: '/pages/login/login'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -213,18 +317,13 @@ export function request(options = {}) {
|
||||||
resolve(res.data)
|
resolve(res.data)
|
||||||
}
|
}
|
||||||
} else if (res.statusCode === 401) {
|
} else if (res.statusCode === 401) {
|
||||||
// token过期或未登录,尝试使用refreshToken刷新
|
// HTTP 401 状态码,直接显示登录弹窗
|
||||||
const refreshToken = uni.getStorageSync('refreshToken')
|
// 如果已经在登录页面,不需要显示弹窗和跳转
|
||||||
if (refreshToken) {
|
if (isInLoginPage()) {
|
||||||
// 尝试刷新token
|
reject(new Error('未授权'))
|
||||||
refreshAccessToken(refreshToken)
|
return
|
||||||
.then(() => {
|
}
|
||||||
// 刷新成功,重新发起原请求
|
|
||||||
return request(options)
|
|
||||||
})
|
|
||||||
.then(resolve)
|
|
||||||
.catch(() => {
|
|
||||||
// 刷新失败,显示登录弹窗
|
|
||||||
const errorMsg = res.data?.msg || res.data?.message || '账号未登录,请前往登录'
|
const errorMsg = res.data?.msg || res.data?.message || '账号未登录,请前往登录'
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
|
|
@ -239,38 +338,11 @@ export function request(options = {}) {
|
||||||
uni.removeStorageSync('tokenExpiresTime')
|
uni.removeStorageSync('tokenExpiresTime')
|
||||||
uni.removeStorageSync('userId')
|
uni.removeStorageSync('userId')
|
||||||
uni.removeStorageSync('userInfo')
|
uni.removeStorageSync('userInfo')
|
||||||
uni.navigateTo({
|
navigateToLogin()
|
||||||
url: '/pages/login/login'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
reject(new Error('未授权'))
|
reject(new Error('未授权'))
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 没有refreshToken,显示登录弹窗
|
|
||||||
const errorMsg = res.data?.msg || res.data?.message || '账号未登录,请前往登录'
|
|
||||||
uni.showModal({
|
|
||||||
title: '提示',
|
|
||||||
content: errorMsg,
|
|
||||||
showCancel: false,
|
|
||||||
confirmText: '去登录',
|
|
||||||
success: (modalRes) => {
|
|
||||||
if (modalRes.confirm) {
|
|
||||||
// 清除token,跳转到登录页
|
|
||||||
uni.removeStorageSync('token')
|
|
||||||
uni.removeStorageSync('refreshToken')
|
|
||||||
uni.removeStorageSync('tokenExpiresTime')
|
|
||||||
uni.removeStorageSync('userId')
|
|
||||||
uni.removeStorageSync('userInfo')
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/login/login'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
reject(new Error('未授权'))
|
|
||||||
}
|
|
||||||
} else if (res.statusCode >= 500) {
|
} else if (res.statusCode >= 500) {
|
||||||
// 服务器错误
|
// 服务器错误
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,12 @@
|
||||||
"usingComponents" : true,
|
"usingComponents" : true,
|
||||||
"requiredPrivateInfos" : [
|
"requiredPrivateInfos" : [
|
||||||
"getLocation"
|
"getLocation"
|
||||||
]
|
],
|
||||||
|
"permission" : {
|
||||||
|
"scope.userLocation" : {
|
||||||
|
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mp-alipay" : {
|
"mp-alipay" : {
|
||||||
"usingComponents" : true
|
"usingComponents" : true
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "服务",
|
"navigationBarTitleText": "服务",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"scope.userLocation": {
|
||||||
|
"desc": "你的位置信息将用于小程序位置接口的效果展示"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
<view class="store-image-wrapper">
|
<view class="store-image-wrapper">
|
||||||
<image
|
<image
|
||||||
class="store-image"
|
class="store-image"
|
||||||
:src="storeInfo.coverUrl || '/static/service/store-default.png'"
|
:src="storeInfo.coverUrl"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
></image>
|
></image>
|
||||||
</view>
|
</view>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<view class="store-brand">
|
<view class="store-brand">
|
||||||
<image
|
<image
|
||||||
class="brand-image"
|
class="brand-image"
|
||||||
:src="storeInfo.coverUrl || '/static/service/store-default.png'"
|
:src="storeInfo.coverUrl"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
></image>
|
></image>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -132,6 +132,8 @@ export default {
|
||||||
categoryLabel: "",
|
categoryLabel: "",
|
||||||
shopId: null,
|
shopId: null,
|
||||||
userInfo: {},
|
userInfo: {},
|
||||||
|
hasCheckedLogin: false, // 是否已经检查过登录状态
|
||||||
|
isLoadingAfterLogin: false, // 是否正在登录后重新加载
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -172,6 +174,43 @@ export default {
|
||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onShow() {
|
||||||
|
// 页面显示时,检查登录状态并更新用户信息
|
||||||
|
// 如果之前未登录,现在已登录,重新加载数据
|
||||||
|
const token = uni.getStorageSync('token');
|
||||||
|
const newUserInfo = uni.getStorageSync('userInfo') || {};
|
||||||
|
|
||||||
|
// 如果之前没有用户信息,现在有了(说明刚登录成功),重新加载数据
|
||||||
|
if (token && (!this.userInfo || !this.userInfo.id) && newUserInfo && newUserInfo.id) {
|
||||||
|
this.userInfo = newUserInfo;
|
||||||
|
this.isLoadingAfterLogin = true; // 标记正在登录后重新加载
|
||||||
|
|
||||||
|
// 设置一个全局标记,表示刚刚登录返回,用于防止 401 弹窗
|
||||||
|
uni.setStorageSync('justBackFromLogin', true);
|
||||||
|
// 5秒后清除标记
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.removeStorageSync('justBackFromLogin');
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
// 延迟一下,确保 token 已经保存并生效,避免与之前的请求冲突
|
||||||
|
setTimeout(() => {
|
||||||
|
// 如果有店铺ID,重新加载店铺数据(特别是菜单数据,可能需要登录才能查看)
|
||||||
|
if (this.shopId) {
|
||||||
|
this.loadStoreData();
|
||||||
|
}
|
||||||
|
// 加载完成后清除标记
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isLoadingAfterLogin = false;
|
||||||
|
}, 1000);
|
||||||
|
}, 500); // 增加延迟时间,确保之前的请求已经完成
|
||||||
|
} else if (token) {
|
||||||
|
// 如果已登录,更新用户信息(可能用户信息有更新)
|
||||||
|
this.userInfo = newUserInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记已经检查过登录状态
|
||||||
|
this.hasCheckedLogin = true;
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 加载店铺数据
|
// 加载店铺数据
|
||||||
async loadStoreData() {
|
async loadStoreData() {
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,12 @@ export default {
|
||||||
const pages = getCurrentPages()
|
const pages = getCurrentPages()
|
||||||
if (pages.length > 1) {
|
if (pages.length > 1) {
|
||||||
this.showBack = true
|
this.showBack = true
|
||||||
|
// 从其他页面跳转过来,说明可能有弹窗需要关闭
|
||||||
|
// 延迟一下,确保页面已经加载完成,弹窗会自动关闭
|
||||||
|
setTimeout(() => {
|
||||||
|
// 尝试隐藏可能存在的弹窗(虽然 uni 没有直接关闭 showModal 的 API)
|
||||||
|
// 但页面跳转后,弹窗应该会自动关闭
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
this.getSystemInfo()
|
this.getSystemInfo()
|
||||||
},
|
},
|
||||||
|
|
@ -186,9 +192,16 @@ export default {
|
||||||
})
|
})
|
||||||
|
|
||||||
// 登录成功,保存token(兼容不同的响应格式)
|
// 登录成功,保存token(兼容不同的响应格式)
|
||||||
|
console.log('[登录] 登录接口返回数据:', res)
|
||||||
const token = res?.accessToken || res?.token || res?.data?.accessToken || res?.data?.token
|
const token = res?.accessToken || res?.token || res?.data?.accessToken || res?.data?.token
|
||||||
if (token) {
|
if (token) {
|
||||||
uni.setStorageSync('token', token)
|
uni.setStorageSync('token', token)
|
||||||
|
console.log('[登录] Token 已保存,长度:', token.length)
|
||||||
|
// 验证保存是否成功
|
||||||
|
const savedToken = uni.getStorageSync('token')
|
||||||
|
console.log('[登录] 验证保存的 token:', savedToken ? '成功' : '失败')
|
||||||
|
} else {
|
||||||
|
console.error('[登录] 未找到 token,返回数据:', res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存refreshToken(用于刷新accessToken)
|
// 保存refreshToken(用于刷新accessToken)
|
||||||
|
|
@ -235,19 +248,17 @@ export default {
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 延迟跳转,让用户看到成功提示
|
// 延迟跳转,让用户看到成功提示,统一跳转到首页
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 检查是否有返回路径
|
|
||||||
const pages = getCurrentPages()
|
|
||||||
if (pages.length > 1) {
|
|
||||||
// 有上一页,返回上一页
|
|
||||||
uni.navigateBack()
|
|
||||||
} else {
|
|
||||||
// 没有上一页,跳转到首页
|
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index',
|
||||||
|
fail: () => {
|
||||||
|
// 如果 switchTab 失败(可能不在 tabBar 页面),使用 reLaunch
|
||||||
|
uni.reLaunch({
|
||||||
url: '/pages/index/index'
|
url: '/pages/index/index'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}, 1500)
|
}, 1500)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('登录失败:', error)
|
console.error('登录失败:', error)
|
||||||
|
|
@ -305,12 +316,16 @@ export default {
|
||||||
// 登录成功,保存token
|
// 登录成功,保存token
|
||||||
// 根据接口返回:{ code: 0, data: { accessToken, refreshToken, expiresTime, userId, ... } }
|
// 根据接口返回:{ code: 0, data: { accessToken, refreshToken, expiresTime, userId, ... } }
|
||||||
// request 函数在 code === 0 时返回 res.data.data || res.data,所以 res 就是 data 对象
|
// request 函数在 code === 0 时返回 res.data.data || res.data,所以 res 就是 data 对象
|
||||||
|
console.log('[登录] 登录接口返回数据:', res)
|
||||||
const token = res?.accessToken || res?.data?.accessToken || res?.token || res?.data?.token
|
const token = res?.accessToken || res?.data?.accessToken || res?.token || res?.data?.token
|
||||||
if (token) {
|
if (token) {
|
||||||
uni.setStorageSync('token', token)
|
uni.setStorageSync('token', token)
|
||||||
console.log('Token 已保存:', token)
|
console.log('[登录] Token 已保存,长度:', token.length)
|
||||||
|
// 验证保存是否成功
|
||||||
|
const savedToken = uni.getStorageSync('token')
|
||||||
|
console.log('[登录] 验证保存的 token:', savedToken ? '成功' : '失败')
|
||||||
} else {
|
} else {
|
||||||
console.error('未找到 token,返回数据:', res)
|
console.error('[登录] 未找到 token,返回数据:', res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存refreshToken(用于刷新accessToken)
|
// 保存refreshToken(用于刷新accessToken)
|
||||||
|
|
@ -358,16 +373,17 @@ export default {
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 延迟跳转
|
// 延迟跳转,让用户看到成功提示,统一跳转到首页
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const pages = getCurrentPages()
|
|
||||||
if (pages.length > 1) {
|
|
||||||
uni.navigateBack()
|
|
||||||
} else {
|
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index',
|
||||||
|
fail: () => {
|
||||||
|
// 如果 switchTab 失败(可能不在 tabBar 页面),使用 reLaunch
|
||||||
|
uni.reLaunch({
|
||||||
url: '/pages/index/index'
|
url: '/pages/index/index'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}, 1500)
|
}, 1500)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('一键登录失败:', error)
|
console.error('一键登录失败:', error)
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
src="/static/service/location-icon.png"
|
src="/static/service/location-icon.png"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
></image>
|
></image>
|
||||||
<text class="distance-text">{{ item.distance || 0 }}km</text>
|
<text class="distance-text">{{ formatDistance(item.distance) }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -222,7 +222,7 @@ export default {
|
||||||
onLoad() {
|
onLoad() {
|
||||||
this.getSystemInfo();
|
this.getSystemInfo();
|
||||||
this.getServiceCategoryFun(); // 获取服务分类
|
this.getServiceCategoryFun(); // 获取服务分类
|
||||||
// this.checkAndRequestLocation(); // 检查并请求位置权限
|
this.requestUserLocation(); // 请求用户位置授权并获取位置
|
||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
// 每次显示页面时刷新数据
|
// 每次显示页面时刷新数据
|
||||||
|
|
@ -242,6 +242,15 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 格式化距离显示:将米转换成千米
|
||||||
|
formatDistance(distanceInMeters) {
|
||||||
|
if (!distanceInMeters || distanceInMeters === 0) {
|
||||||
|
return '0km';
|
||||||
|
}
|
||||||
|
// 将米转换成千米,保留1位小数
|
||||||
|
const distanceInKm = (distanceInMeters / 1000).toFixed(1);
|
||||||
|
return `${distanceInKm}km`;
|
||||||
|
},
|
||||||
// 获取系统信息
|
// 获取系统信息
|
||||||
getSystemInfo() {
|
getSystemInfo() {
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
|
@ -318,8 +327,8 @@ export default {
|
||||||
this.loadServiceList();
|
this.loadServiceList();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 检查并请求位置权限
|
// 请求用户位置授权并获取位置(使用 wx.getLocation - 精确位置)
|
||||||
checkAndRequestLocation() {
|
requestUserLocation() {
|
||||||
// 先检查是否已有存储的位置信息
|
// 先检查是否已有存储的位置信息
|
||||||
const savedLocation = uni.getStorageSync("userLocation");
|
const savedLocation = uni.getStorageSync("userLocation");
|
||||||
if (savedLocation && savedLocation.latitude && savedLocation.longitude) {
|
if (savedLocation && savedLocation.latitude && savedLocation.longitude) {
|
||||||
|
|
@ -327,12 +336,65 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有位置信息,请求授权并获取位置
|
// 获取位置的统一方法
|
||||||
|
const getLocation = () => {
|
||||||
|
uni.getLocation({
|
||||||
|
type: "gcj02", // 使用 gcj02 坐标系(火星坐标系,国内常用)
|
||||||
|
success: (res) => {
|
||||||
|
console.log("获取位置成功1:", res);
|
||||||
|
const location = {
|
||||||
|
latitude: res.latitude,
|
||||||
|
longitude: res.longitude,
|
||||||
|
};
|
||||||
|
// 存储位置信息
|
||||||
|
uni.setStorageSync("userLocation", location);
|
||||||
|
|
||||||
|
// 如果当前是店铺类型分类且已经有选中的分类,刷新列表以使用新的位置信息
|
||||||
|
if (this.isStoreCategory() && this.currentCategory !== null) {
|
||||||
|
this.pageNo = 1;
|
||||||
|
this.serviceList = [];
|
||||||
|
this.hasMore = true;
|
||||||
|
this.loadServiceList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error("获取位置失败:", err);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 微信小程序环境需要先检查授权
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.getSetting({
|
||||||
|
success: (res) => {
|
||||||
|
if (res.authSetting["scope.userLocation"] === false) {
|
||||||
|
// 用户之前拒绝过授权,引导去设置页面
|
||||||
|
uni.showModal({
|
||||||
|
title: "位置权限",
|
||||||
|
content: "需要获取您的位置信息以提供附近店铺服务,是否前往设置开启?",
|
||||||
|
confirmText: "去设置",
|
||||||
|
cancelText: "取消",
|
||||||
|
success: (modalRes) => {
|
||||||
|
if (modalRes.confirm) {
|
||||||
|
uni.openSetting({
|
||||||
|
success: (settingRes) => {
|
||||||
|
if (settingRes.authSetting["scope.userLocation"]) {
|
||||||
|
getLocation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (res.authSetting["scope.userLocation"] === true) {
|
||||||
|
// 已经授权,直接获取位置
|
||||||
|
getLocation();
|
||||||
|
} else {
|
||||||
|
// 未询问过授权,请求授权
|
||||||
uni.authorize({
|
uni.authorize({
|
||||||
scope: "scope.userLocation",
|
scope: "scope.userLocation",
|
||||||
success: () => {
|
success: () => {
|
||||||
// 授权成功,获取位置
|
getLocation();
|
||||||
this.getUserLocation();
|
|
||||||
},
|
},
|
||||||
fail: () => {
|
fail: () => {
|
||||||
// 授权失败,提示用户
|
// 授权失败,提示用户
|
||||||
|
|
@ -341,13 +403,12 @@ export default {
|
||||||
content: "需要获取您的位置信息以提供附近店铺服务,是否前往设置开启?",
|
content: "需要获取您的位置信息以提供附近店铺服务,是否前往设置开启?",
|
||||||
confirmText: "去设置",
|
confirmText: "去设置",
|
||||||
cancelText: "取消",
|
cancelText: "取消",
|
||||||
success: (res) => {
|
success: (modalRes) => {
|
||||||
if (res.confirm) {
|
if (modalRes.confirm) {
|
||||||
uni.openSetting({
|
uni.openSetting({
|
||||||
success: (settingRes) => {
|
success: (settingRes) => {
|
||||||
if (settingRes.authSetting["scope.userLocation"]) {
|
if (settingRes.authSetting["scope.userLocation"]) {
|
||||||
// 用户开启了位置权限,获取位置
|
getLocation();
|
||||||
this.getUserLocation();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -356,24 +417,19 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
fail: () => {
|
||||||
|
// 获取设置失败,直接尝试获取位置
|
||||||
|
getLocation();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
// 获取用户当前位置
|
// #ifndef MP-WEIXIN
|
||||||
getUserLocation() {
|
// 非微信小程序环境,直接获取位置
|
||||||
uni.getLocation({
|
getLocation();
|
||||||
type: "gcj02",
|
// #endif
|
||||||
success: (res) => {
|
|
||||||
const location = {
|
|
||||||
latitude: res.latitude,
|
|
||||||
longitude: res.longitude,
|
|
||||||
};
|
|
||||||
// 存储位置信息
|
|
||||||
uni.setStorageSync("userLocation", location);
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error("获取位置失败:", err);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 选择位置/距离
|
// 选择位置/距离
|
||||||
|
|
@ -481,9 +537,16 @@ export default {
|
||||||
name: this.searchKeyword,
|
name: this.searchKeyword,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果选择了距离,添加 distance 参数
|
// 获取用户位置信息
|
||||||
|
const savedLocation = uni.getStorageSync("userLocation");
|
||||||
|
if (savedLocation && savedLocation.latitude && savedLocation.longitude) {
|
||||||
|
params.myLatitude = savedLocation.latitude;
|
||||||
|
params.myLongitude = savedLocation.longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果选择了距离,添加 distance 参数(将千米转换成米)
|
||||||
if (this.selectedDistance !== null) {
|
if (this.selectedDistance !== null) {
|
||||||
params.distance = this.selectedDistance;
|
params.distance = this.selectedDistance * 1000; // 将 km 转换成 m
|
||||||
}
|
}
|
||||||
|
|
||||||
res = await getGuildStorePage(params);
|
res = await getGuildStorePage(params);
|
||||||
|
|
@ -503,6 +566,9 @@ export default {
|
||||||
const newList = res.list || [];
|
const newList = res.list || [];
|
||||||
this.total = res.total || 0;
|
this.total = res.total || 0;
|
||||||
|
|
||||||
|
// 处理列表数据:将接口返回的 distance(米)转换成千米用于显示
|
||||||
|
// 注意:这里不修改原始数据,只在显示时转换
|
||||||
|
|
||||||
if (isLoadMore) {
|
if (isLoadMore) {
|
||||||
// 加载更多,追加数据
|
// 加载更多,追加数据
|
||||||
this.serviceList = [...this.serviceList, ...newList];
|
this.serviceList = [...this.serviceList, ...newList];
|
||||||
|
|
|
||||||
|
|
@ -78,3 +78,4 @@ export default {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue