9433cfb9创建于 2025年12月31日历史提交
/**
 * 微信绑定拦截器使用示例:
 * import {wechatBindNavigateToInterceptor, wechatBindSwitchTabInterceptor} from '@/utils/interceptor/checkWechat.uts'
 * 
	onPageShow(()=>{ // 推荐用onPageShow,避免页面缓存导致拦截失效
		uni.addInterceptor('switchTab',  wechatBindSwitchTabInterceptor)
		uni.addInterceptor('navigateTo', wechatBindNavigateToInterceptor)
	})
	
	onUnload(() => {
	  uni.removeInterceptor('navigateTo');
	  uni.removeInterceptor('switchTab');
	});
	
 */

import { userState } from '@/store/user-store.uts' // 导入setOpenid,用于绑定成功后更新状态
// 导入全局导航锁和公共方法(与登录/手机拦截器共用)
import { lock, getCurrentPagePath, getPureUrl } from '@/utils/common/lock-common.uts'
import {
	VITE_APP_USER_LOGIN_PAGE,
	VITE_APP_USER_REGISTER_PAGE,
	VITE_APP_USER_RESET_PASSWROD_PAGE,
	VITE_APP_USER_HELP_PAGE,
	VITE_APP_TABBAR_HOME_PAGE,
	VITE_APP_USER_BIND_PHONE_PAGE,
	VITE_APP_USER_WECHAT_AUTH_PAGE,
	VITE_APP_AGREEMENT_PAGE,
	VITE_APP_PRIVACY_PAGE
} from '@/config/page-setting.uts'
import {
	WARNGING_PATH,
}from '@/config/image-setting.uts'
// #ifdef WEB
import {
	ERROR_PATH
}from '@/config/image-setting.uts'
import { isWechat } from '@/utils/wechat.uts'
import {toGetCodeUrlWithLogin} from '@/api/youhujun/user/after-login/wechat-auth.uts'
import type { GetCodeUrlParam,GetCodeUrlApiResponse} from '@/api/youhujun/user/after-login/wechat-auth-type.uts'
import { VITE_APP_WECHAT_WEB_AUTH_URL } from '@/config/setting.uts'
// #endif

// 微信授权页面
const BIND_WECHAT_PAGE_URL = VITE_APP_USER_WECHAT_AUTH_PAGE;
const BIND_WECHAT_PAGE_ROUTE = BIND_WECHAT_PAGE_URL.replace(/^\//, ''); // 去掉开头/,匹配页面route格式

const HOME_PAGE_FULL_URL = VITE_APP_TABBAR_HOME_PAGE; // 首页完整路径
const HOME_PAGE_SHORT_URL = '/'; // 首页简写路径

// 无需绑定微信的路由白名单(按需添加)
const NO_WECHAT_BIND_WHITE_LIST = [
	//首页
	'/',
	VITE_APP_TABBAR_HOME_PAGE,
	//登录
	VITE_APP_USER_LOGIN_PAGE,
	//注册
	VITE_APP_USER_REGISTER_PAGE,
	//重置密码
	VITE_APP_USER_RESET_PASSWROD_PAGE,
	//帮助
	VITE_APP_USER_HELP_PAGE,
	//绑定手机
	VITE_APP_USER_BIND_PHONE_PAGE,
	//微信授权
	VITE_APP_USER_WECHAT_AUTH_PAGE,
	VITE_APP_AGREEMENT_PAGE,
	VITE_APP_PRIVACY_PAGE
];


/**
 * navigateTo 微信绑定拦截器
 */
const wechatBindNavigateToInterceptor = {
  invoke: function (options: NavigateToOptions) {
	if (!options.url) return; // 避免空url导致的异常
	const targetUrl = getPureUrl(options.url); // 获取目标纯路径
	// 目标是首页则直接放行(不管其他条件)
	if (targetUrl === HOME_PAGE_FULL_URL || targetUrl === HOME_PAGE_SHORT_URL) {
	  return;
	}
	// 白名单判断(兼容带参数URL)
	if (NO_WECHAT_BIND_WHITE_LIST.includes(getPureUrl(options.url))) return;
    //console.log('拦截 navigateTo 接口(微信绑定校验):', options);
    
    // 放行条件:已绑定微信 / 正在导航中
    if (userState.openid || getCurrentPagePath() === BIND_WECHAT_PAGE_ROUTE || lock.isWechatNavigating || lock.isLoginSuccessTempPass) {
      return;
    }

    lock.isWechatNavigating = true; // 上锁
    
    // 弹框提示绑定微信
    uni.showModal({
      title: '提示',
      content: '为了正常服务,请先微信授权',
      confirmText: '去授权',
      cancelText: '取消',
      success: async (res) => {
        if (res.confirm) {
          // 执行微信绑定逻辑
			  // #ifdef WEB
			  if(isWechat()){
				if(!VITE_APP_WECHAT_WEB_AUTH_URL){
					uni.showToast({ image: ERROR_PATH, title: `授权链接丢失`, mask: true, duration: 2000 })
				}
				const param: GetCodeUrlParam = {
					scope_type:20,
					state:10,
					auth_redirect_url:VITE_APP_WECHAT_WEB_AUTH_URL
				}
				const result:GetCodeUrlApiResponse | null  = await toGetCodeUrlWithLogin(param)
				console.log(result)
				if (result && result.data) {
					const { code,data } = result;
					//console.log('解构后的msg:', msg); // 正常输出"微信公众号发起授权成功"
					if(code === 0 && data){
						window.location.href = data.url
					}
				}
			  }else{
				uni.showToast({ image: WARNGING_PATH, title: `当前环境不支持微信登录`, mask: true, duration: 2000 })
			  }
			  // #endif
			  // #ifndef WEB
			  uni.showToast({ image: WARNGING_PATH, title: `当前环境不支持微信登录`, mask: true, duration: 2000 })
			  // #endif
        } else {
          // 用户取消绑定,释放导航锁
          lock.isWechatNavigating = false;
        }
      },
      fail: () => {
        // 弹框异常,兜底释放锁
        lock.isWechatNavigating = false;
      }
    });

	// 超时兜底释放锁,防止弹框/绑定中断导致锁残留
	setTimeout(()=>{
		if(lock.isWechatNavigating){
			lock.isWechatNavigating = false
		}
	},1000)

    // 返回false阻止原navigateTo执行
    return false;
  },
} as AddInterceptorOptions;

/**
 * switchTab 微信绑定拦截器
 */
const wechatBindSwitchTabInterceptor = {
  invoke: function (options: SwitchTabOptions) {
	if (!options.url) return; // 避免空url导致的异常
	const targetUrl = getPureUrl(options.url); // 获取目标纯路径
	// 目标是首页则直接放行(不管其他条件)
	if (targetUrl === HOME_PAGE_FULL_URL || targetUrl === HOME_PAGE_SHORT_URL) {
	  return;
	}
	// 白名单判断(兼容带参数URL)
	if (NO_WECHAT_BIND_WHITE_LIST.includes(getPureUrl(options.url))) return;
    //console.log('拦截 switchTab 接口(微信绑定校验):', options);
    
    // 放行条件:已绑定微信 / 正在导航中
    if (userState.openid || getCurrentPagePath() === BIND_WECHAT_PAGE_ROUTE || lock.isWechatSwitching || lock.isLoginSuccessTempPass) {
      return;
    }

    lock.isWechatSwitching = true; // 上锁
    
    // 弹框提示绑定微信
    uni.showModal({
      title: '提示',
      content: '为了正常服务,请先微信授权',
      confirmText: '去授权',
      cancelText: '取消',
      success: async (res) => {
        if (res.confirm) {
          // 执行微信绑定逻辑
          // #ifdef WEB
          if(isWechat()){
          				if(!VITE_APP_WECHAT_WEB_AUTH_URL){
          					uni.showToast({ image: ERROR_PATH, title: `授权链接丢失`, mask: true, duration: 2000 })
          				}
          				const param: GetCodeUrlParam = {
          					scope_type:20,
          					state:10,
          					auth_redirect_url:VITE_APP_WECHAT_WEB_AUTH_URL
          				}
          				const result:GetCodeUrlApiResponse | null  = await toGetCodeUrlWithLogin(param)
          				console.log(result)
          				if (result && result.data) {
          					const { code,data } = result;
          					//console.log('解构后的msg:', msg); // 正常输出"微信公众号发起授权成功"
          					if(code === 0 && data){
          						window.location.href = data.url
          					}
          				}
          }else{
          				uni.showToast({ image: WARNGING_PATH, title: `当前环境不支持微信登录`, mask: true, duration: 2000 })
          }
          // #endif
          // #ifndef WEB
          uni.showToast({ image: WARNGING_PATH, title: `当前环境不支持微信登录`, mask: true, duration: 2000 })
          // #endif
        } else {
          // 用户取消绑定,释放导航锁
          lock.isWechatSwitching = false;
        }
      },
      fail: () => {
        // 弹框异常,兜底释放锁
        lock.isWechatSwitching = false;
      }
    });

	// 超时兜底释放锁,防止弹框/绑定中断导致锁残留
	setTimeout(()=>{
		if(lock.isWechatSwitching){
			lock.isWechatSwitching = false
		}
	},1000)

    // 返回false阻止原switchTab执行
    return false;
  },
} as AddInterceptorOptions;

export {
  wechatBindNavigateToInterceptor,
  wechatBindSwitchTabInterceptor
};