From 5d3031d9f0ff7ccedc3e0c1f4f1fad3ccf25b26f Mon Sep 17 00:00:00 2001 From: minimaxagent1 Date: Sat, 2 Aug 2025 10:35:11 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E7=BA=A7=E5=88=ABLoading?= =?UTF-8?q?=E7=AE=A1=E7=90=86=20=E7=BB=9F=E4=B8=80=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=B0=E7=9A=84request=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/auth/auth.js | 47 ++ api/donor/donor.js | 8 +- api/index/index.js | 9 +- .../institutionalStructure.js | 30 +- .../institutionalStructureDetail.js | 26 +- api/monk/monk.js | 8 +- common/http.config.js | 53 +++ main.js | 8 +- .../institutionalStructure.vue | 46 +- .../mixins/data-manager.js | 11 +- pages/login/login.vue | 72 ++- pages/nearbystores/index.vue | 16 +- pages/test/api-test.vue | 95 ++++ pages/test/test.vue | 99 +++++ utils/request.js | 415 ++++++++++++++++-- utils/router.js | 28 ++ 16 files changed, 843 insertions(+), 128 deletions(-) create mode 100644 api/auth/auth.js create mode 100644 common/http.config.js create mode 100644 pages/test/api-test.vue create mode 100644 pages/test/test.vue diff --git a/api/auth/auth.js b/api/auth/auth.js new file mode 100644 index 0000000..e80d310 --- /dev/null +++ b/api/auth/auth.js @@ -0,0 +1,47 @@ +// 认证相关API +import { post } from '@/utils/request' + +/** + * 微信登录 + * @param {Object} data - 登录数据 + * @param {string} data.loginCode - 微信登录code + * @param {number} data.appId - 应用ID + * @returns {Promise} 返回登录结果 + */ +export function wxLogin(data) { + return post('/wxLogin', data, { + noToken: true, + showLoading: true, + loadingText: '登录中...' + }) +} + +/** + * 用户登录 + * @param {Object} data - 登录数据 + * @returns {Promise} 返回登录结果 + */ +export function userLogin(data) { + return post('/user/login', data, { + noToken: true, + showLoading: true, + loadingText: '登录中...' + }) +} + +/** + * 用户登出 + * @returns {Promise} 返回登出结果 + */ +export function userLogout() { + return post('/user/logout') +} + +/** + * 刷新token + * @param {string} refreshToken - 刷新token + * @returns {Promise} 返回刷新结果 + */ +export function refreshToken(refreshToken) { + return post('/user/refresh', { refreshToken }, { noToken: true }) +} \ No newline at end of file diff --git a/api/donor/donor.js b/api/donor/donor.js index 3ca4e3f..ae17dc6 100644 --- a/api/donor/donor.js +++ b/api/donor/donor.js @@ -1,4 +1,4 @@ -import { request } from '@/utils/request' +import { get, post } from '@/utils/request' /** * 获取捐款记录列表 @@ -16,9 +16,5 @@ import { request } from '@/utils/request' * @returns {Promise} 返回捐款记录列表 */ export function getDonorList(params) { - return request({ - url: '/app/donor/listDonor', - method: 'get', - params - }) + return get('/app/donor/listDonor', params) } \ No newline at end of file diff --git a/api/index/index.js b/api/index/index.js index 6f2ef11..b4d3129 100644 --- a/api/index/index.js +++ b/api/index/index.js @@ -1,15 +1,14 @@ // 首页配置相关API -import { request } from '@/utils/request' +import { get } from '@/utils/request' /** * 获取首页配置 * @returns {Promise} 返回首页配置数据 */ export function getHomeConfig() { - return request({ - url: '/app/homeCfg', - method: 'GET', - timeout: 10000 // 10秒超时 + return get('/app/homeCfg', {}, { + timeout: 10000, // 10秒超时 + showLoading: false // 不显示加载状态,因为页面有自己的loading }) } diff --git a/api/institutionalStructure/institutionalStructure.js b/api/institutionalStructure/institutionalStructure.js index 0d0e666..a55804c 100644 --- a/api/institutionalStructure/institutionalStructure.js +++ b/api/institutionalStructure/institutionalStructure.js @@ -1,5 +1,5 @@ // 建制相关API -import { request } from '@/utils/request' +import { get, post, put, del } from '@/utils/request' /** * 获取建制数据列表 @@ -18,10 +18,8 @@ export function getInstitutionalList(params = {}) { isAsc: 'descending' } - return request({ - url: '/app/formed/listFormed', - method: 'GET', - params: { ...defaultParams, ...params } + return get('/app/formed/listFormed', { ...defaultParams, ...params }, { + showLoading: false // 使用页面级别的loading管理 }) } @@ -31,10 +29,7 @@ export function getInstitutionalList(params = {}) { * @returns {Promise} 返回建制详情 */ export function getInstitutionalDetail(id) { - return request({ - url: `/app/formed/getFormed/${id}`, - method: 'GET' - }) + return get(`/app/formed/getFormed/${id}`) } /** @@ -43,11 +38,7 @@ export function getInstitutionalDetail(id) { * @returns {Promise} 返回创建结果 */ export function createInstitutional(data) { - return request({ - url: '/app/formed/createFormed', - method: 'POST', - data - }) + return post('/app/formed/createFormed', data) } /** @@ -56,11 +47,7 @@ export function createInstitutional(data) { * @returns {Promise} 返回更新结果 */ export function updateInstitutional(data) { - return request({ - url: '/app/formed/updateFormed', - method: 'PUT', - data - }) + return put('/app/formed/updateFormed', data) } /** @@ -69,8 +56,5 @@ export function updateInstitutional(data) { * @returns {Promise} 返回删除结果 */ export function deleteInstitutional(id) { - return request({ - url: `/app/formed/deleteFormed/${id}`, - method: 'DELETE' - }) + return del(`/app/formed/deleteFormed/${id}`) } \ No newline at end of file diff --git a/api/institutionalStructure/institutionalStructureDetail.js b/api/institutionalStructure/institutionalStructureDetail.js index 5eb85b4..c9e6c2c 100644 --- a/api/institutionalStructure/institutionalStructureDetail.js +++ b/api/institutionalStructure/institutionalStructureDetail.js @@ -1,5 +1,5 @@ // 建制详情相关API -import { request } from '@/utils/request' +import { get, put, del } from '@/utils/request' /** * 获取建制详情 @@ -7,13 +7,7 @@ import { request } from '@/utils/request' * @returns {Promise} 返回建制详情 */ export function getInstitutionalDetail(formedId) { - return request({ - url: '/app/formed/formedDetail', - method: 'GET', - params: { - formedId: formedId - } - }) + return get('/app/formed/formedDetail', { formedId }) } /** @@ -22,10 +16,7 @@ export function getInstitutionalDetail(formedId) { * @returns {Promise} 返回建制详情 */ export function getInstitutionalDetailById(id) { - return request({ - url: `/app/formed/getFormed/${id}`, - method: 'GET' - }) + return get(`/app/formed/getFormed/${id}`) } /** @@ -34,11 +25,7 @@ export function getInstitutionalDetailById(id) { * @returns {Promise} 返回更新结果 */ export function updateInstitutionalDetail(data) { - return request({ - url: '/app/formed/updateFormed', - method: 'PUT', - data - }) + return put('/app/formed/updateFormed', data) } /** @@ -47,8 +34,5 @@ export function updateInstitutionalDetail(data) { * @returns {Promise} 返回删除结果 */ export function deleteInstitutionalDetail(id) { - return request({ - url: `/app/formed/deleteFormed/${id}`, - method: 'DELETE' - }) + return del(`/app/formed/deleteFormed/${id}`) } diff --git a/api/monk/monk.js b/api/monk/monk.js index a1222a5..ef5f6a4 100644 --- a/api/monk/monk.js +++ b/api/monk/monk.js @@ -1,4 +1,4 @@ -import { request } from '@/utils/request.js' +import { get } from '@/utils/request.js' /** * 获取高僧列表 @@ -6,9 +6,7 @@ import { request } from '@/utils/request.js' * @returns {Promise} */ export function getMonkList(params = {}) { - return request({ - url: '/app/monk/listMonk', - method: 'GET', - params + return get('/app/monk/listMonk', params, { + showLoading: false // 使用页面级别的loading管理 }) } diff --git a/common/http.config.js b/common/http.config.js new file mode 100644 index 0000000..6541b42 --- /dev/null +++ b/common/http.config.js @@ -0,0 +1,53 @@ +// HTTP配置文件 - 替代 http.interceptor.js +import { setRequestConfig, getRequestConfig } from '@/utils/request.js' + +/** + * 初始化HTTP配置 + * @param {Object} Vue - Vue实例 + * @param {Object} vm - 组件实例 + */ +const install = (Vue, vm) => { + // 设置默认配置 + const defaultConfig = { + loadingText: '努力加载中~', + loadingTime: 800, + showLoading: true, + loadingMask: true + } + + setRequestConfig(defaultConfig) + + // 将request方法挂载到Vue原型上,方便使用 + Vue.prototype.$request = { + get: (url, params, options) => { + return import('@/utils/request.js').then(({ get }) => { + return get(url, params, options) + }) + }, + post: (url, data, options) => { + return import('@/utils/request.js').then(({ post }) => { + return post(url, data, options) + }) + }, + put: (url, data, options) => { + return import('@/utils/request.js').then(({ put }) => { + return put(url, data, options) + }) + }, + delete: (url, options) => { + return import('@/utils/request.js').then(({ del }) => { + return del(url, options) + }) + }, + // 获取当前配置 + getConfig: () => getRequestConfig(), + // 设置配置 + setConfig: (config) => setRequestConfig(config) + } + + console.log('HTTP配置初始化完成') +} + +export default { + install +} \ No newline at end of file diff --git a/main.js b/main.js index c3a417d..54b40a6 100644 --- a/main.js +++ b/main.js @@ -38,8 +38,12 @@ const app = new Vue({ store, render: h => h(App), }).$mount('#app'); -import httpInterceptor from '@/common/http.interceptor.js' -Vue.use(httpInterceptor, app) +import httpConfig from '@/common/http.config.js' +Vue.use(httpConfig, app) + +// 初始化全局loading管理器 +import { initGlobalLoadingManager } from '@/utils/request.js' +initGlobalLoadingManager() // Vue.use(httpApi, app) // #ifdef MP-WEIXIN Vue.prototype.wxLogin = async function(){ diff --git a/pages/institutionalStructure/institutionalStructure.vue b/pages/institutionalStructure/institutionalStructure.vue index c35faea..68fcad2 100644 --- a/pages/institutionalStructure/institutionalStructure.vue +++ b/pages/institutionalStructure/institutionalStructure.vue @@ -37,6 +37,7 @@ import StatusDisplay from "../../components/status-display/status-display.vue"; import { InstitutionalDataFormatter } from "./utils/data-formatter.js"; import { dataManagerMixin } from "./mixins/data-manager.js"; import CommonEnum from "../../enum/common"; +import { PageLoadingManager } from "../../utils/request.js"; export default { mixins: [dataManagerMixin], @@ -57,19 +58,50 @@ export default { } }, onLoad() { + // 初始化页面loading管理器 + this.pageLoading = new PageLoadingManager() // 页面加载时获取数据 this.getInstitutionalData() }, + onUnload() { + // 页面卸载时清除loading + if (this.pageLoading) { + this.pageLoading.destroy() + } + }, methods: { // 获取建制数据 async getInstitutionalData(isLoadMore = false) { - await this.fetchData( - isLoadMore, - getInstitutionalList, - InstitutionalDataFormatter.transformData - ) - // 将数据赋值给 institutionalData - this.institutionalData = this.dataList + console.log('开始获取建制数据, isLoadMore:', isLoadMore) + + // 显示页面loading + if (this.pageLoading && !isLoadMore) { + this.pageLoading.show('努力加载中~') + } + + try { + const result = await this.fetchData( + isLoadMore, + getInstitutionalList, + InstitutionalDataFormatter.transformData + ) + console.log('建制数据获取成功:', result) + // 将数据赋值给 institutionalData + this.institutionalData = this.dataList + console.log('建制数据已更新, 数量:', this.institutionalData.length) + } catch (error) { + console.error('获取建制数据失败:', error) + uni.showToast({ + title: '获取数据失败', + icon: 'none' + }) + } finally { + // 隐藏页面loading + if (this.pageLoading && !isLoadMore) { + this.pageLoading.hide() + console.log('页面loading已隐藏') + } + } }, // 刷新数据 diff --git a/pages/institutionalStructure/mixins/data-manager.js b/pages/institutionalStructure/mixins/data-manager.js index 3d66096..b0d8e0b 100644 --- a/pages/institutionalStructure/mixins/data-manager.js +++ b/pages/institutionalStructure/mixins/data-manager.js @@ -24,7 +24,11 @@ export const dataManagerMixin = { * @param {Function} dataTransformer 数据转换函数 */ async fetchData(isLoadMore = false, apiCall, dataTransformer) { - this.loading = true + // 只在加载更多时设置loading状态,初始加载使用页面级别loading + if (isLoadMore) { + this.loading = true + } + try { if (isLoadMore) { this.pageNum++ @@ -63,7 +67,10 @@ export const dataManagerMixin = { icon: 'none' }) } finally { - this.loading = false + // 只在加载更多时清除loading状态 + if (isLoadMore) { + this.loading = false + } } }, diff --git a/pages/login/login.vue b/pages/login/login.vue index 50788ed..d15f964 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -18,6 +18,8 @@ + + \ No newline at end of file diff --git a/pages/test/test.vue b/pages/test/test.vue new file mode 100644 index 0000000..360e30b --- /dev/null +++ b/pages/test/test.vue @@ -0,0 +1,99 @@ + + + + + \ No newline at end of file diff --git a/utils/request.js b/utils/request.js index ec84ed4..ceeca7f 100644 --- a/utils/request.js +++ b/utils/request.js @@ -1,8 +1,170 @@ // 统一请求工具 import { getTempToken, shouldUseTempToken } from '@/config/dev.js' -// const BASE_URL = 'http://192.168.2.7:4501' -const BASE_URL = 'https://testlu.chuangtewl.com/prod-api' +// 环境配置 +const ENV_CONFIG = { + development: { + baseUrl: 'http://192.168.2.7:4501', + loadingText: '努力加载中~', + loadingTime: 800 + }, + production: { + baseUrl: 'https://testlu.chuangtewl.com/prod-api', + loadingText: '努力加载中~', + loadingTime: 800 + } +} + +// 获取当前环境配置 +const getCurrentConfig = () => { + // 可以通过环境变量或其他方式判断环境 + const isDev = process.env.NODE_ENV === 'development' || + uni.getSystemInfoSync().platform === 'devtools' + console.log('当前环境判断:', { + NODE_ENV: process.env.NODE_ENV, + platform: uni.getSystemInfoSync().platform, + isDev: isDev + }) + return isDev ? ENV_CONFIG.development : ENV_CONFIG.production +} + +const config = getCurrentConfig() +const BASE_URL = config.baseUrl + +// 全局loading状态管理 +let isLoading = false +let loadingTimer = null + +// 设置loading超时自动清除 +const setLoadingTimeout = () => { + if (loadingTimer) { + clearTimeout(loadingTimer) + } + loadingTimer = setTimeout(() => { + console.warn('Loading超时,强制清除') + forceHideLoading() + }, 30000) // 30秒超时 +} + +// 调试信息 +console.log('HTTP配置:', { + baseUrl: BASE_URL, + config: config +}) + +/** + * 获取请求头 + * @param {Object} customHeader - 自定义请求头 + * @returns {Object} 请求头对象 + */ +function getRequestHeaders(customHeader = {}) { + const token = uni.getStorageSync('token') + let authorization = token + + // 平台差异化处理 + // #ifdef H5 + authorization = token ? `Bearer ${token}` : '' + // #endif + + return { + 'Content-Type': 'application/json;charset=UTF-8', + 'Authorization': authorization, + ...customHeader + } +} + +/** + * 处理响应错误 + * @param {Object} res - 响应对象 + * @param {Function} reject - Promise reject函数 + */ +function handleResponseError(res, reject, options = {}) { + // 先清除loading状态 + if (options.showLoading !== false) { + hideLoading() + } + + const errorMap = { + 401: { + title: '登录已过期,请重新登录', + action: () => { + setTimeout(() => { + uni.reLaunch({ + url: '/pages/login/login' + }) + }, 1500) + } + }, + 403: { + title: '权限不足', + action: () => {} + }, + 404: { + title: '请求的资源不存在', + action: () => {} + }, + 500: { + title: '服务器错误', + action: () => {} + } + } + + const error = errorMap[res.statusCode] || { + title: res.data?.msg || '请求失败', + action: () => {} + } + + // 显示错误提示 + uni.showToast({ + title: error.title, + icon: 'none', + duration: 2000 + }) + + // 执行错误处理动作 + error.action() + + reject(new Error(error.title)) +} + +/** + * 显示加载状态 + * @param {string} text - 加载提示文字 + */ +function showLoading(text = config.loadingText) { + try { + if (!isLoading) { + isLoading = true + uni.showLoading({ + title: text, + mask: true + }) + // 设置超时清除 + setLoadingTimeout() + } + } catch (error) { + console.warn('显示loading失败:', error) + } +} + +/** + * 隐藏加载状态 + */ +function hideLoading() { + try { + if (isLoading) { + isLoading = false + // 清除超时定时器 + if (loadingTimer) { + clearTimeout(loadingTimer) + loadingTimer = null + } + uni.hideLoading() + } + } catch (error) { + console.warn('隐藏loading失败:', error) + } +} /** * 统一请求方法 @@ -12,6 +174,10 @@ const BASE_URL = 'https://testlu.chuangtewl.com/prod-api' * @param {Object} options.params - 查询参数 * @param {Object} options.data - 请求体数据 * @param {Object} options.header - 请求头 + * @param {number} options.timeout - 超时时间 + * @param {boolean} options.showLoading - 是否显示加载状态 + * @param {string} options.loadingText - 加载提示文字 + * @param {boolean} options.noToken - 是否需要token * @returns {Promise} 返回请求结果 */ export function request(options = {}) { @@ -21,59 +187,75 @@ export function request(options = {}) { let token = localToken // 如果本地没有token且启用了临时token,则使用临时token - if (!token && shouldUseTempToken()) { + if (!token && shouldUseTempToken() && !options.noToken) { token = getTempToken() console.log('使用临时token进行开发测试') } + // 验证URL格式 + if (!options.url || typeof options.url !== 'string') { + reject(new Error('无效的URL')) + return + } + + // 确保URL以/开头 + const url = options.url.startsWith('/') ? options.url : '/' + options.url + // 构建请求配置 const requestOptions = { - url: BASE_URL + options.url, + url: BASE_URL + url, method: options.method || 'GET', - header: { - 'Content-Type': 'application/json', - ...options.header - }, + header: getRequestHeaders(options.header), timeout: options.timeout || 60000, // 默认60秒超时 success: (res) => { + // 隐藏加载状态 + if (options.showLoading !== false) { + hideLoading() + } + // 请求成功处理 if (res.statusCode === 200) { resolve(res.data) - } else if (res.statusCode === 401) { - // 认证失败 - uni.showToast({ - title: '登录已过期,请重新登录', - icon: 'none' - }) - setTimeout(() => { - uni.navigateTo({ - url: '/pages/login/login' - }) - }, 1500) - reject(new Error('认证失败')) } else { - // 其他错误 - uni.showToast({ - title: res.data?.msg || '请求失败', - icon: 'none' - }) - reject(new Error(res.data?.msg || '请求失败')) + // 处理错误响应 + handleResponseError(res, reject, options) } }, fail: (err) => { + // 隐藏加载状态 + if (options.showLoading !== false) { + hideLoading() + } + // 请求失败处理 - console.error('请求失败:', err) + console.error('请求失败:', { + error: err, + url: requestOptions.url, + method: requestOptions.method, + baseUrl: BASE_URL, + originalUrl: options.url + }) + + // 根据错误类型显示不同的提示 + let errorMessage = '网络错误' + if (err.errMsg && err.errMsg.includes('invalid url')) { + errorMessage = '请求地址无效' + } else if (err.errMsg && err.errMsg.includes('timeout')) { + errorMessage = '请求超时' + } + uni.showToast({ - title: '网络错误', - icon: 'none' + title: errorMessage, + icon: 'none', + duration: 2000 }) reject(err) } } - // 添加token到请求头 - if (token) { - requestOptions.header.Authorization = token + // 特殊接口处理 + if (url === '/login/login' || url === '/wxLogin' || url === '/user/login') { + requestOptions.header.noToken = true } // 添加参数 @@ -85,7 +267,22 @@ export function request(options = {}) { requestOptions.data = options.data } + // 显示加载状态 + if (options.showLoading !== false) { + setTimeout(() => { + showLoading(options.loadingText || config.loadingText) + }, config.loadingTime) + } + // 发起请求 + console.log('发起请求:', { + url: requestOptions.url, + method: requestOptions.method, + header: requestOptions.header, + data: requestOptions.data, + timeout: requestOptions.timeout, + baseUrl: BASE_URL + }) uni.request(requestOptions) }) } @@ -94,15 +291,15 @@ export function request(options = {}) { * GET请求 * @param {string} url - 请求地址 * @param {Object} params - 查询参数 - * @param {Object} header - 请求头 + * @param {Object} options - 请求选项 * @returns {Promise} 返回请求结果 */ -export function get(url, params = {}, header = {}) { +export function get(url, params = {}, options = {}) { return request({ url, method: 'GET', params, - header + ...options }) } @@ -110,15 +307,15 @@ export function get(url, params = {}, header = {}) { * POST请求 * @param {string} url - 请求地址 * @param {Object} data - 请求体数据 - * @param {Object} header - 请求头 + * @param {Object} options - 请求选项 * @returns {Promise} 返回请求结果 */ -export function post(url, data = {}, header = {}) { +export function post(url, data = {}, options = {}) { return request({ url, method: 'POST', data, - header + ...options }) } @@ -126,28 +323,158 @@ export function post(url, data = {}, header = {}) { * PUT请求 * @param {string} url - 请求地址 * @param {Object} data - 请求体数据 - * @param {Object} header - 请求头 + * @param {Object} options - 请求选项 * @returns {Promise} 返回请求结果 */ -export function put(url, data = {}, header = {}) { +export function put(url, data = {}, options = {}) { return request({ url, method: 'PUT', data, - header + ...options }) } /** * DELETE请求 * @param {string} url - 请求地址 - * @param {Object} header - 请求头 + * @param {Object} options - 请求选项 * @returns {Promise} 返回请求结果 */ -export function del(url, header = {}) { +export function del(url, options = {}) { return request({ url, method: 'DELETE', - header + ...options }) +} + +/** + * 设置请求配置 + * @param {Object} newConfig - 新的配置对象 + */ +export function setRequestConfig(newConfig) { + Object.assign(config, newConfig) +} + +/** + * 获取当前配置 + * @returns {Object} 当前配置对象 + */ +export function getRequestConfig() { + return { ...config } +} + +/** + * 清除token + */ +export function clearToken() { + uni.removeStorageSync('token') + uni.removeStorageSync('refreshToken') +} + +/** + * 设置token + * @param {string} token - token值 + */ +export function setToken(token) { + uni.setStorageSync('token', token) +} + +/** + * 获取token + * @returns {string} token值 + */ +export function getToken() { + return uni.getStorageSync('token') +} + +/** + * 强制清除loading状态 + */ +export function forceHideLoading() { + isLoading = false + // 清除超时定时器 + if (loadingTimer) { + clearTimeout(loadingTimer) + loadingTimer = null + } + try { + uni.hideLoading() + } catch (error) { + console.warn('强制清除loading失败:', error) + } +} + +/** + * 初始化全局loading管理 + */ +export function initGlobalLoadingManager() { + // 监听页面显示事件 + uni.$on('page-show', () => { + forceHideLoading() + }) + + // 监听页面隐藏事件 + uni.$on('page-hide', () => { + forceHideLoading() + }) + + // 监听应用进入前台 + uni.$on('app-show', () => { + forceHideLoading() + }) + + // 监听应用进入后台 + uni.$on('app-hide', () => { + forceHideLoading() + }) + + console.log('全局loading管理器已初始化') +} + +/** + * 页面级别的loading管理 + */ +export class PageLoadingManager { + constructor() { + this.isLoading = false + this.timer = null + } + + show(text = '加载中...') { + this.hide() // 先清除之前的loading + this.isLoading = true + try { + uni.showLoading({ + title: text, + mask: true + }) + // 设置超时 + this.timer = setTimeout(() => { + console.warn('页面Loading超时,强制清除') + this.hide() + }, 30000) + } catch (error) { + console.warn('显示页面loading失败:', error) + } + } + + hide() { + this.isLoading = false + if (this.timer) { + clearTimeout(this.timer) + this.timer = null + } + try { + uni.hideLoading() + } catch (error) { + console.warn('隐藏页面loading失败:', error) + } + } + + // 页面卸载时清理 + destroy() { + this.hide() + } } \ No newline at end of file diff --git a/utils/router.js b/utils/router.js index c379331..9d56445 100644 --- a/utils/router.js +++ b/utils/router.js @@ -46,6 +46,13 @@ export const PAGE_TYPE_MAP = { * @param {Object} options - 跳转选项 */ export function navigateToPage(pageType, options = {}) { + // 清除loading状态 + try { + uni.hideLoading() + } catch (error) { + console.warn('清除loading失败:', error) + } + const targetPage = PAGE_TYPE_MAP[pageType]; if (!targetPage) { @@ -79,6 +86,13 @@ export function navigateToPage(pageType, options = {}) { * @param {string} pageType - 页面类型 */ export function switchToTab(pageType) { + // 清除loading状态 + try { + uni.hideLoading() + } catch (error) { + console.warn('清除loading失败:', error) + } + const tabRoutes = { 'index': PAGE_ROUTES.INDEX, 'my': PAGE_ROUTES.MY @@ -124,6 +138,13 @@ export function navigateBack(delta = 1) { * @param {string} pageType - 页面类型 */ export function redirectToPage(pageType) { + // 清除loading状态 + try { + uni.hideLoading() + } catch (error) { + console.warn('清除loading失败:', error) + } + const targetPage = PAGE_TYPE_MAP[pageType]; if (!targetPage) { @@ -144,6 +165,13 @@ export function redirectToPage(pageType) { * @param {string} pageType - 页面类型 */ export function reLaunchToPage(pageType) { + // 清除loading状态 + try { + uni.hideLoading() + } catch (error) { + console.warn('清除loading失败:', error) + } + const targetPage = PAGE_TYPE_MAP[pageType]; if (!targetPage) {