mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
255 lines
8.5 KiB
Vue
255 lines
8.5 KiB
Vue
<script setup>
|
||
import { onLaunch, onShow, onError } from '@dcloudio/uni-app';
|
||
import { ShoproInit } from './sheep';
|
||
import sheep from '@/sheep';
|
||
|
||
// 防止重复登录的标志
|
||
let isLoggingIn = false;
|
||
|
||
onLaunch(() => {
|
||
// 隐藏原生导航栏 使用自定义底部导航
|
||
uni.hideTabBar({
|
||
fail: () => {},
|
||
});
|
||
|
||
// 初始化移动端调试控制台(仅H5环境)
|
||
// #ifdef H5
|
||
initVConsole();
|
||
// #endif
|
||
|
||
// 加载Shopro底层依赖
|
||
ShoproInit();
|
||
|
||
// 检测建行生活登录参数
|
||
checkCCBLogin();
|
||
|
||
// 启动 JSBridge 监控(每10秒打印一次)
|
||
// #ifdef H5
|
||
startJSBridgeMonitor();
|
||
// #endif
|
||
});
|
||
|
||
/**
|
||
* 初始化 vConsole 移动端调试控制台
|
||
* 在H5环境下提供类似Chrome DevTools的功能
|
||
*/
|
||
const initVConsole = () => {
|
||
// 动态导入vConsole,避免打包到非H5平台
|
||
import('vconsole')
|
||
.then((module) => {
|
||
const VConsole = module.default;
|
||
const vConsole = new VConsole({
|
||
defaultPlugins: ['system', 'network', 'element', 'storage'],
|
||
maxLogNumber: 1000,
|
||
disableLogScrolling: false,
|
||
});
|
||
|
||
// 保存实例供后续使用
|
||
window.vConsole = vConsole;
|
||
})
|
||
.catch((err) => {
|
||
console.error('[App] vConsole加载失败:', err);
|
||
});
|
||
};
|
||
|
||
onError((err) => {
|
||
console.log('AppOnError:', err);
|
||
});
|
||
|
||
onShow(() => {
|
||
// #ifdef APP-PLUS
|
||
// 获取urlSchemes参数
|
||
const args = plus.runtime.arguments;
|
||
if (args) {
|
||
}
|
||
|
||
// 获取剪贴板
|
||
uni.getClipboardData({
|
||
success: (res) => {},
|
||
});
|
||
// #endif
|
||
});
|
||
|
||
/**
|
||
* JSBridge 注入情况监控
|
||
* 每10秒打印一次所有建行相关 JSBridge 对象的状态,打印15次后自动停止
|
||
*/
|
||
const startJSBridgeMonitor = () => {
|
||
let count = 0;
|
||
const maxCount = 15;
|
||
|
||
// 立即执行一次
|
||
printJSBridgeStatus(++count, maxCount);
|
||
|
||
// 每10秒执行一次
|
||
const timer = setInterval(() => {
|
||
printJSBridgeStatus(++count, maxCount);
|
||
|
||
// 达到15次后清除定时器
|
||
if (count >= maxCount) {
|
||
clearInterval(timer);
|
||
console.log('[JSBridge] 监控已停止(已打印15次)');
|
||
}
|
||
}, 10000);
|
||
};
|
||
|
||
/**
|
||
* 打印 JSBridge 注入状态(精简版)
|
||
*/
|
||
const printJSBridgeStatus = (count, maxCount) => {
|
||
const timestamp = new Date().toLocaleTimeString('zh-CN', { hour12: false });
|
||
const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
||
const isAndroid = /Android/i.test(navigator.userAgent);
|
||
|
||
// 检测各个 Bridge 对象
|
||
const hasMbspay =
|
||
typeof window.mbspay !== 'undefined' && typeof window.mbspay.directpay === 'function';
|
||
const hasCCBBridge = typeof window.CCBBridge !== 'undefined';
|
||
const hasWebViewBridge = typeof window.WebViewJavascriptBridge !== 'undefined';
|
||
const hasAnyBridge = hasMbspay || hasCCBBridge || hasWebViewBridge;
|
||
|
||
// 支付能力
|
||
const canPay = isIOS || (isAndroid && hasMbspay);
|
||
|
||
// 一行输出所有状态(包含计数)
|
||
console.log(
|
||
`[JSBridge ${timestamp}] (${count}/${maxCount}) ` +
|
||
`设备:${isIOS ? 'iOS' : isAndroid ? 'Android' : 'PC'} | ` +
|
||
`mbspay:${hasMbspay ? '✅' : '❌'} | ` +
|
||
`CCBBridge:${hasCCBBridge ? '✅' : '❌'} | ` +
|
||
`WebViewBridge:${hasWebViewBridge ? '✅' : '❌'} | ` +
|
||
`支付能力:${canPay ? '✅' : '❌'} | ` +
|
||
`Bridge状态:${hasAnyBridge ? '✅就绪' : '❌未就绪'}`,
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 检测URL中的建行登录参数并自动登录
|
||
* 建行跳转URL格式:url?platform=ccblife&channel=mbs&ccbParamSJ=xxx&CITYID=330100&USERCITYID=440100
|
||
*
|
||
* 逻辑:
|
||
* 1. 解析URL参数获取ccbParamSJ
|
||
* 2. 检查上次登录时间
|
||
* 3. 如果在3小时内则跳过登录
|
||
* 4. 超过3小时则重新登录并更新时间戳
|
||
*/
|
||
const checkCCBLogin = () => {
|
||
// #ifdef H5
|
||
try {
|
||
let ccbParamSJ = null;
|
||
let platform = null;
|
||
let cityid = null;
|
||
|
||
// 优先从search中提取参数(建行标准格式:url?ccbParamSJ=xxx&CITYID=xxx)
|
||
if (window.location.search) {
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
ccbParamSJ = urlParams.get('ccbParamSJ');
|
||
platform = urlParams.get('platform') || 'ccblife';
|
||
cityid = urlParams.get('CITYID') || urlParams.get('cityid');
|
||
}
|
||
|
||
// 备用:从hash中提取参数(UniApp内部跳转可能使用)
|
||
if (!ccbParamSJ && window.location.hash.includes('?')) {
|
||
const hashParts = window.location.hash.split('?');
|
||
if (hashParts.length > 1) {
|
||
const hashParams = new URLSearchParams(hashParts[1]);
|
||
ccbParamSJ = hashParams.get('ccbParamSJ');
|
||
platform = hashParams.get('platform') || 'ccblife';
|
||
cityid = hashParams.get('CITYID') || hashParams.get('cityid');
|
||
}
|
||
}
|
||
|
||
// 如果有建行参数(固定建行生活环境,只要有ccbParamSJ就执行登录)
|
||
if (ccbParamSJ) {
|
||
// 获取上次登录时间
|
||
const lastLoginTime = uni.getStorageSync('lastCcbLoginTime') || 0;
|
||
const currentTime = Date.now();
|
||
const threeHoursInMs = 3 * 60 * 60 * 1000; // 3小时的毫秒数
|
||
|
||
// 检查是否在3小时内
|
||
if (lastLoginTime && currentTime - lastLoginTime < threeHoursInMs) {
|
||
const remainingMinutes = Math.ceil((threeHoursInMs - (currentTime - lastLoginTime)) / 1000 / 60);
|
||
console.log(`[CCB] 距离上次登录未满3小时(剩余${remainingMinutes}分钟),跳过登录`);
|
||
const cleanUrl = window.location.origin + '/pages/index/index';
|
||
window.history.replaceState({}, '', cleanUrl);
|
||
return;
|
||
}
|
||
|
||
console.log(`[CCB] ${lastLoginTime ? '超过3小时,重新登录' : '首次登录'}`);
|
||
|
||
// 防止重复调用
|
||
if (isLoggingIn) {
|
||
console.log('[CCB] 登录进行中,跳过');
|
||
return;
|
||
}
|
||
|
||
isLoggingIn = true;
|
||
|
||
// 延迟执行登录,确保依赖已初始化
|
||
setTimeout(async () => {
|
||
try {
|
||
// 直接覆盖登录,无需退出(建行生活场景)
|
||
const userStore = sheep.$store('user');
|
||
|
||
// 调用建行登录API(静默登录,不显示loading)
|
||
const result = await sheep.$api.third.ccbLogin({
|
||
ccbParamSJ: ccbParamSJ,
|
||
cityid: cityid || '360100',
|
||
CITYID: cityid || '360100',
|
||
});
|
||
|
||
if (result.code === 1) {
|
||
console.log('[CCB] 登录成功');
|
||
|
||
// 获取用户store
|
||
const userStore = sheep.$store('user');
|
||
|
||
// ⭐ 立即同步设置用户信息到store,避免页面显示延迟
|
||
if (result.data.user_info) {
|
||
userStore.userInfo = result.data.user_info;
|
||
console.log('[CCB] 用户信息已同步到store:', result.data.user_info.nickname);
|
||
}
|
||
|
||
// ⭐ 如果后端返回了订单数据,也立即同步(避免页面显示'--')
|
||
if (result.data.num_data) {
|
||
userStore.numData = result.data.num_data;
|
||
console.log('[CCB] 订单数据已同步到store:', result.data.num_data);
|
||
}
|
||
|
||
// 保存到本地存储
|
||
uni.setStorageSync('userInfo', result.data.user_info);
|
||
// 保存登录时间戳
|
||
uni.setStorageSync('lastCcbLoginTime', Date.now());
|
||
|
||
// 设置token(这会触发loginAfter异步加载完整数据)
|
||
// 注意:不使用await,让它在后台加载,不阻塞UI
|
||
userStore.setToken(result.data.token);
|
||
|
||
// 清除URL中的敏感参数
|
||
const cleanUrl = window.location.origin + '/pages/index/index';
|
||
window.history.replaceState({}, '', cleanUrl);
|
||
} else {
|
||
throw new Error(result.msg || '登录失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('[CCB] 登录失败:', error.message || error.msg);
|
||
|
||
// 静默失败,清除URL参数
|
||
const cleanUrl = window.location.origin + '/pages/index/index';
|
||
window.history.replaceState({}, '', cleanUrl);
|
||
} finally {
|
||
isLoggingIn = false;
|
||
}
|
||
}, 1200);
|
||
}
|
||
} catch (error) {
|
||
console.error('[CCB] 参数解析错误:', error);
|
||
}
|
||
// #endif
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
@import '@/sheep/scss/index.scss';
|
||
</style>
|