/** * 建行生活平台集成模块 * * @author Billy * @date 2025-01-17 */ import sheep from '@/sheep'; import ccbApi from './api'; // 建行生活配置 const config = { // 是否开启调试 debug: true, // API基础路径 apiBaseUrl: '/addons/shopro', // 超时时间 timeout: 10000, }; // 建行生活平台对象 const CcbLifePlatform = { // 平台标识 platform: 'ccblife', // 平台名称 name: '建行生活', // 是否在建行生活环境中 isInCcbApp: false, // JSBridge 对象 bridge: null, // 就绪状态 isReady: false, // 就绪回调队列 readyCallbacks: [], /** * 初始化 */ init() { // 检测环境 this.detectEnvironment(); // 如果在建行App内,初始化JSBridge if (this.isInCcbApp) { this.setupBridge(); // 自动登录 this.autoLogin(); } console.log('[CcbLife] 初始化完成, 是否在建行App内:', this.isInCcbApp); }, /** * 检测运行环境 */ detectEnvironment() { // #ifdef H5 const ua = navigator.userAgent.toLowerCase(); // 检查User-Agent if (ua.indexOf('ccblife') > -1 || ua.indexOf('ccb') > -1) { this.isInCcbApp = true; return; } // 检查URL参数 const urlParams = this.getUrlParams(); if (urlParams.ccbParamSJ || urlParams.from === 'ccblife') { this.isInCcbApp = true; return; } // 检查JSBridge if (window.WebViewJavascriptBridge || window.mbspay) { this.isInCcbApp = true; return; } // #endif // #ifdef APP-PLUS // 在APP中也可能通过插件方式集成建行SDK // TODO: 检测建行SDK插件 // #endif // #ifdef MP-WEIXIN // 小程序环境不支持建行生活 this.isInCcbApp = false; // #endif }, /** * 设置JSBridge */ setupBridge() { // #ifdef H5 const self = this; // iOS WebViewJavascriptBridge if (window.WebViewJavascriptBridge) { self.bridge = window.WebViewJavascriptBridge; self.onBridgeReady(); } else { document.addEventListener('WebViewJavascriptBridgeReady', function() { self.bridge = window.WebViewJavascriptBridge; self.onBridgeReady(); }, false); } // Android 直接通过window对象 if (window.mbspay && !self.bridge) { self.bridge = window.mbspay; self.onBridgeReady(); } // 设置超时检查 setTimeout(() => { if (!self.isReady) { console.warn('[CcbLife] JSBridge 未就绪'); } }, 3000); // #endif }, /** * Bridge就绪回调 */ onBridgeReady() { this.isReady = true; console.log('[CcbLife] JSBridge 已就绪'); // 执行所有等待的回调 this.readyCallbacks.forEach(callback => callback()); this.readyCallbacks = []; }, /** * 等待Bridge就绪 */ ready(callback) { if (this.isReady) { callback(); } else { this.readyCallbacks.push(callback); } }, /** * 获取URL参数 */ getUrlParams() { const params = {}; // #ifdef H5 const search = window.location.search.substring(1); if (search) { const pairs = search.split('&'); pairs.forEach(pair => { const parts = pair.split('='); if (parts.length === 2) { params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); } }); } // #endif return params; }, /** * 获取建行用户信息 */ async getUserInfo() { return new Promise((resolve, reject) => { if (!this.isInCcbApp) { reject({ code: -1, msg: '不在建行生活App内' }); return; } this.ready(() => { this.callNative('getUserInfo', {}, (result) => { if (result && result.userid) { resolve({ code: 0, data: { ccb_user_id: result.userid, mobile: result.mobile || '', nickname: result.nickname || '', avatar: result.avatar || '' } }); } else { reject({ code: -1, msg: '获取用户信息失败' }); } }); }); }); }, /** * 自动登录 */ async autoLogin() { try { // 检查是否已登录 const token = uni.getStorageSync('token'); if (token) { console.log('[CcbLife] 用户已登录'); return; } // 获取用户信息 const userResult = await this.getUserInfo(); if (userResult.code !== 0) { throw new Error(userResult.msg); } // 调用后端登录接口 const loginResult = await ccbApi.autoLogin(userResult.data); if (loginResult.code === 1) { // 保存Token和用户信息 uni.setStorageSync('token', loginResult.data.token); uni.setStorageSync('userInfo', loginResult.data.userInfo); // 更新Shopro用户状态 sheep.$store('user').getInfo(); console.log('[CcbLife] 自动登录成功'); // 触发登录成功事件 uni.$emit('ccb:login:success', loginResult.data); } else { throw new Error(loginResult.msg); } } catch (error) { console.error('[CcbLife] 自动登录失败:', error); } }, /** * 调起建行支付 */ async payment(options) { return new Promise((resolve, reject) => { if (!this.isInCcbApp) { reject({ code: -1, msg: '不在建行生活App内' }); return; } // 必需参数检查 if (!options.payment_string) { reject({ code: -1, msg: '缺少支付串参数' }); return; } this.ready(() => { // #ifdef H5 // 区分iOS和Android if (this.isIOS()) { // iOS使用URL Scheme this.paymentForIOS(options, resolve, reject); } else { // Android使用JSBridge this.paymentForAndroid(options, resolve, reject); } // #endif // #ifdef APP-PLUS // APP中调用原生插件 this.paymentForApp(options, resolve, reject); // #endif }); }); }, /** * iOS支付 */ paymentForIOS(options, resolve, reject) { // #ifdef H5 const paymentUrl = 'comccbpay://pay?' + options.payment_string; // 尝试打开支付页面 window.location.href = paymentUrl; // 设置回调检查 setTimeout(() => { resolve({ code: 0, msg: '已调起支付,请在建行App内完成支付' }); }, 1000); // #endif }, /** * Android支付 */ paymentForAndroid(options, resolve, reject) { this.callNative('payment', { payment_string: options.payment_string }, (result) => { if (result && result.success) { resolve({ code: 0, data: result }); } else { reject({ code: -1, msg: result ? result.error : '支付失败' }); } }); }, /** * APP支付 */ paymentForApp(options, resolve, reject) { // #ifdef APP-PLUS // TODO: 调用建行SDK插件 uni.showToast({ title: 'APP支付暂未实现', icon: 'none' }); reject({ code: -1, msg: 'APP支付暂未实现' }); // #endif }, /** * 调用原生方法 */ callNative(method, params, callback) { // #ifdef H5 try { if (this.isIOS() && this.bridge && this.bridge.callHandler) { // iOS WebViewJavascriptBridge this.bridge.callHandler(method, params, callback); } else if (window.mbspay && window.mbspay[method]) { // Android直接调用 const result = window.mbspay[method](JSON.stringify(params)); if (callback) { callback(typeof result === 'string' ? JSON.parse(result) : result); } } else { console.warn('[CcbLife] 原生方法不存在:', method); if (callback) { callback({ success: false, error: '原生方法不存在' }); } } } catch (e) { console.error('[CcbLife] 调用原生方法失败:', e); if (callback) { callback({ success: false, error: e.message }); } } // #endif }, /** * 判断是否iOS */ isIOS() { // #ifdef H5 return /iPhone|iPad|iPod/i.test(navigator.userAgent); // #endif // #ifndef H5 return uni.getSystemInfoSync().platform === 'ios'; // #endif }, /** * 处理URL跳转登录 */ async handleUrlLogin() { const params = this.getUrlParams(); // 如果有ccbParamSJ参数,说明是从建行跳转过来的 if (params.ccbParamSJ) { try { // 调用后端解密并登录 const result = await ccbApi.login(params); if (result.code === 1) { // 保存Token和用户信息 uni.setStorageSync('token', result.data.token); uni.setStorageSync('userInfo', result.data.user_info); // 更新用户状态 sheep.$store('user').getInfo(); // 跳转到指定页面 const redirectUrl = result.data.redirect_url || '/pages/index/index'; uni.reLaunch({ url: redirectUrl }); } else { uni.showToast({ title: result.msg || '登录失败', icon: 'none' }); } } catch (error) { console.error('[CcbLife] URL登录失败:', error); uni.showToast({ title: '登录失败', icon: 'none' }); } } } }; // 导出平台对象 export default CcbLifePlatform;