fengketrade/public/ccblife-demo.html

553 lines
18 KiB
HTML
Raw Normal View History

2025-10-17 17:18:15 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>建行生活 H5 集成示例</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: #f5f5f5;
padding: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
font-size: 24px;
margin-bottom: 20px;
color: #333;
text-align: center;
}
.info-section {
background: #f8f9fa;
border-radius: 4px;
padding: 15px;
margin-bottom: 20px;
}
.info-item {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
font-size: 14px;
}
.info-item:last-child {
margin-bottom: 0;
}
.label {
color: #666;
}
.value {
color: #333;
font-weight: 500;
}
.btn {
display: block;
width: 100%;
padding: 12px 20px;
background: #0066cc;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
margin-bottom: 15px;
transition: background 0.3s;
}
.btn:hover {
background: #0052a3;
}
.btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.btn-secondary {
background: #6c757d;
}
.btn-secondary:hover {
background: #545b62;
}
.btn-success {
background: #28a745;
}
.btn-success:hover {
background: #218838;
}
.result {
background: #f0f8ff;
border: 1px solid #b6d4fe;
border-radius: 4px;
padding: 15px;
margin-top: 20px;
white-space: pre-wrap;
font-family: monospace;
font-size: 12px;
max-height: 300px;
overflow-y: auto;
}
.status {
display: inline-block;
padding: 4px 8px;
border-radius: 3px;
font-size: 12px;
margin-left: 10px;
}
.status-success {
background: #d4edda;
color: #155724;
}
.status-error {
background: #f8d7da;
color: #721c24;
}
.status-warning {
background: #fff3cd;
color: #856404;
}
.loading {
display: none;
text-align: center;
padding: 20px;
}
.loading.active {
display: block;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #0066cc;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.divider {
height: 1px;
background: #e9ecef;
margin: 20px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>建行生活 H5 集成示例</h1>
<!-- 环境信息 -->
<div class="info-section">
<h3>环境信息</h3>
<div class="info-item">
<span class="label">当前环境:</span>
<span class="value" id="env-status">检测中...</span>
</div>
2025-10-20 08:54:02 +08:00
<div class="info-item">
<span class="label">设备类型:</span>
<span class="value" id="device-type">-</span>
</div>
2025-10-17 17:18:15 +08:00
<div class="info-item">
<span class="label">JSBridge 状态:</span>
<span class="value" id="bridge-status">未就绪</span>
</div>
2025-10-20 08:54:02 +08:00
<div class="info-item">
<span class="label">Bridge 对象:</span>
<span class="value" id="bridge-object">检测中...</span>
</div>
2025-10-17 17:18:15 +08:00
<div class="info-item">
<span class="label">登录状态:</span>
<span class="value" id="login-status">未登录</span>
</div>
<div class="info-item">
<span class="label">建行用户ID</span>
<span class="value" id="ccb-user-id">-</span>
</div>
2025-10-20 08:54:02 +08:00
<div class="info-item">
<span class="label">建行参数:</span>
<span class="value" id="ccb-param"></span>
</div>
2025-10-17 17:18:15 +08:00
</div>
<div class="divider"></div>
<!-- 功能测试 -->
<h3 style="margin-bottom: 15px;">功能测试</h3>
2025-10-20 08:54:02 +08:00
<button class="btn" onclick="refreshEnv()">🔄 刷新环境检测</button>
<button class="btn" onclick="decryptCcbParam()">🔓 解密建行参数</button>
2025-10-17 17:18:15 +08:00
<button class="btn" onclick="getUserInfo()">获取建行用户信息</button>
<button class="btn btn-secondary" onclick="doAutoLogin()">执行自动登录</button>
<button class="btn btn-success" onclick="testPayment()">测试支付功能</button>
<div class="divider"></div>
<!-- 调试功能 -->
<h3 style="margin-bottom: 15px;">调试功能</h3>
<button class="btn btn-secondary" onclick="checkUrlParams()">检查 URL 参数</button>
2025-10-20 08:54:02 +08:00
<button class="btn btn-secondary" onclick="showUserAgent()">显示 User-Agent</button>
<button class="btn btn-secondary" onclick="checkBridgeObjects()">检查 Bridge 对象</button>
2025-10-17 17:18:15 +08:00
<button class="btn btn-secondary" onclick="clearCache()">清除缓存</button>
<button class="btn btn-secondary" onclick="toggleDebug()">切换调试模式</button>
<!-- 加载状态 -->
<div class="loading" id="loading">
<div class="spinner"></div>
<p style="margin-top: 10px;">处理中...</p>
</div>
<!-- 结果显示 -->
<div class="result" id="result" style="display: none;"></div>
</div>
<!-- 引入 JSBridge -->
<script src="/assets/js/ccblife-bridge.js"></script>
<script>
// 初始化配置
window.onload = function() {
// 初始化 CcbLifeBridge
CcbLifeBridge.init({
debug: true,
apiBaseUrl: '/addons/shopro'
});
// 更新环境状态
updateEnvStatus();
// 监听登录成功事件
window.addEventListener('ccb:login:success', function(e) {
console.log('登录成功事件:', e.detail);
updateLoginStatus(e.detail);
});
// 监听 Bridge 就绪
CcbLifeBridge.ready(function() {
document.getElementById('bridge-status').innerHTML =
'<span class="status status-success">已就绪</span>';
});
};
// 更新环境状态
function updateEnvStatus() {
var isInApp = CcbLifeBridge.isInCcbApp();
var envEl = document.getElementById('env-status');
if (isInApp) {
envEl.innerHTML = '<span class="status status-success">建行生活 App 内</span>';
} else {
envEl.innerHTML = '<span class="status status-warning">普通浏览器</span>';
}
2025-10-20 08:54:02 +08:00
// 设备类型
var deviceType = CcbLifeBridge.isIOS() ? 'iOS' : 'Android';
document.getElementById('device-type').textContent = deviceType;
// 检查 Bridge 对象
checkBridgeObjectsStatus();
// 检查建行参数
var params = CcbLifeBridge.getUrlParams();
if (params.ccbParamSJ) {
document.getElementById('ccb-param').innerHTML =
'<span class="status status-warning">已加密(点击解密按钮)</span>';
} else {
document.getElementById('ccb-param').textContent = '无';
}
2025-10-17 17:18:15 +08:00
// 检查登录状态
var token = localStorage.getItem('ccb_token');
var userInfo = localStorage.getItem('ccb_user_info');
if (token && userInfo) {
try {
var user = JSON.parse(userInfo);
updateLoginStatus({ userInfo: user });
} catch(e) {
console.error('解析用户信息失败', e);
}
}
}
2025-10-20 08:54:02 +08:00
// 检查 Bridge 对象状态
function checkBridgeObjectsStatus() {
var bridgeObjects = [];
if (window.WebViewJavascriptBridge) {
bridgeObjects.push('WebViewJavascriptBridge');
}
if (window.mbspay) {
bridgeObjects.push('mbspay');
}
var bridgeEl = document.getElementById('bridge-object');
if (bridgeObjects.length > 0) {
bridgeEl.innerHTML = '<span class="status status-success">' +
bridgeObjects.join(', ') + '</span>';
} else {
bridgeEl.innerHTML = '<span class="status status-error">未检测到</span>';
}
}
// 刷新环境检测
function refreshEnv() {
updateEnvStatus();
// 重新检查 Bridge 就绪状态
if (CcbLifeBridge.isReady) {
document.getElementById('bridge-status').innerHTML =
'<span class="status status-success">已就绪</span>';
} else {
document.getElementById('bridge-status').innerHTML =
'<span class="status status-error">未就绪</span>';
// 等待 3 秒后重新检查
setTimeout(function() {
if (CcbLifeBridge.isReady) {
document.getElementById('bridge-status').innerHTML =
'<span class="status status-success">已就绪</span>';
}
}, 3000);
}
showResult('环境信息已刷新');
}
2025-10-17 17:18:15 +08:00
// 更新登录状态
function updateLoginStatus(data) {
document.getElementById('login-status').innerHTML =
'<span class="status status-success">已登录</span>';
if (data.userInfo && data.userInfo.ccb_user_id) {
document.getElementById('ccb-user-id').textContent = data.userInfo.ccb_user_id;
}
}
// 获取用户信息
function getUserInfo() {
showLoading(true);
CcbLifeBridge.getUserInfo(function(result) {
showLoading(false);
if (result.success) {
showResult('获取用户信息成功:\n' + JSON.stringify(result.data, null, 2));
} else {
showResult('获取用户信息失败:' + result.error);
}
});
}
// 执行自动登录
function doAutoLogin() {
if (!CcbLifeBridge.isInCcbApp()) {
showResult('错误:不在建行生活 App 内,无法执行自动登录');
return;
}
showLoading(true);
CcbLifeBridge.getUserInfo(function(result) {
if (result.success) {
CcbLifeBridge.doLogin(result.data);
showLoading(false);
showResult('正在登录...\n用户信息' + JSON.stringify(result.data, null, 2));
} else {
showLoading(false);
showResult('获取用户信息失败:' + result.error);
}
});
}
// 测试支付功能
function testPayment() {
// 这里需要先调用后端接口生成支付串
var orderId = prompt('请输入订单ID测试用', '1');
if (!orderId) {
return;
}
showLoading(true);
// 模拟调用后端生成支付串
fetch('/addons/shopro/ccbpayment/createPayment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'token': localStorage.getItem('ccb_token') || ''
},
body: JSON.stringify({
order_id: orderId
})
})
.then(response => response.json())
.then(data => {
showLoading(false);
if (data.code === 1) {
// 调起支付
CcbLifeBridge.payment({
payment_string: data.data.payment_string
}, function(result) {
if (result.success) {
showResult('支付调起成功,请在建行 App 内完成支付');
} else {
showResult('支付调起失败:' + result.error);
}
});
} else {
showResult('生成支付串失败:' + data.msg);
}
})
.catch(error => {
showLoading(false);
showResult('请求失败:' + error.message);
});
}
2025-10-20 08:54:02 +08:00
// 解密建行参数
function decryptCcbParam() {
var params = CcbLifeBridge.getUrlParams();
if (!params.ccbParamSJ) {
showResult('错误URL 中没有 ccbParamSJ 参数');
return;
}
showLoading(true);
// 调用后端接口解密
fetch('/addons/shopro/ccblife/decryptParam', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
ccbParamSJ: params.ccbParamSJ
})
})
.then(response => response.json())
.then(data => {
showLoading(false);
if (data.code === 1) {
var decrypted = data.data;
showResult('解密成功:\n' + JSON.stringify(decrypted, null, 2));
// 更新显示
document.getElementById('ccb-param').innerHTML =
'<span class="status status-success">已解密</span>';
// 如果有用户ID显示出来
if (decrypted.userid) {
document.getElementById('ccb-user-id').textContent = decrypted.userid;
}
} else {
showResult('解密失败:' + data.msg);
}
})
.catch(error => {
showLoading(false);
showResult('请求失败:' + error.message);
});
}
2025-10-17 17:18:15 +08:00
// 检查 URL 参数
function checkUrlParams() {
var params = CcbLifeBridge.getUrlParams();
showResult('URL 参数:\n' + JSON.stringify(params, null, 2));
}
2025-10-20 08:54:02 +08:00
// 显示 User-Agent
function showUserAgent() {
var ua = navigator.userAgent;
showResult('User-Agent\n' + ua);
}
// 检查 Bridge 对象
function checkBridgeObjects() {
var info = {
WebViewJavascriptBridge: typeof window.WebViewJavascriptBridge !== 'undefined',
mbspay: typeof window.mbspay !== 'undefined',
bridgeReady: CcbLifeBridge.isReady,
isIOS: CcbLifeBridge.isIOS(),
isInCcbApp: CcbLifeBridge.isInCcbApp()
};
showResult('Bridge 对象检测:\n' + JSON.stringify(info, null, 2));
}
2025-10-17 17:18:15 +08:00
// 清除缓存
function clearCache() {
localStorage.removeItem('ccb_token');
localStorage.removeItem('ccb_user_info');
document.getElementById('login-status').innerHTML =
'<span class="status status-warning">未登录</span>';
document.getElementById('ccb-user-id').textContent = '-';
showResult('缓存已清除');
}
// 切换调试模式
function toggleDebug() {
CcbLifeBridge.config.debug = !CcbLifeBridge.config.debug;
showResult('调试模式:' + (CcbLifeBridge.config.debug ? '开启' : '关闭'));
}
// 显示加载状态
function showLoading(show) {
var loading = document.getElementById('loading');
if (show) {
loading.classList.add('active');
} else {
loading.classList.remove('active');
}
}
// 显示结果
function showResult(message) {
var resultEl = document.getElementById('result');
resultEl.style.display = 'block';
resultEl.textContent = message;
}
</script>
</body>
</html>