mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 12:57:32 +08:00
代码优化
This commit is contained in:
parent
da85b453e1
commit
db2c6c4af4
@ -114,7 +114,7 @@ class Ccblife extends Common
|
||||
|
||||
// 构建跳转URL
|
||||
$redirectUrl = $decryptedParams['redirect_url'] ?? '/pages/index/index';
|
||||
|
||||
set_token_in_header($this->auth->getToken());
|
||||
$this->success(__('Logged in successful'), [
|
||||
'token' => $token,
|
||||
'user_info' => $userInfo,
|
||||
|
||||
@ -1095,6 +1095,12 @@ class OrderCreate
|
||||
$orderData['type'] = $this->order_type;
|
||||
$orderData['order_sn'] = get_sn($this->user->id);
|
||||
$orderData['user_id'] = $this->user->id;
|
||||
|
||||
// 添加建行用户ID(如果用户是通过建行登录的)
|
||||
if (isset($this->user->ccb_user_id) && $this->user->ccb_user_id) {
|
||||
$orderData['ccb_user_id'] = $this->user->ccb_user_id;
|
||||
}
|
||||
|
||||
$orderData['activity_id'] = $result['activity_id'];
|
||||
$orderData['activity_type'] = $result['activity_type'];
|
||||
$orderData['promo_types'] = join(',', $result['promo_types']);
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { onShow, onPageScroll, onPullDownRefresh } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
|
||||
@ -27,6 +27,87 @@
|
||||
const template = computed(() => sheep.$store('app').template.user);
|
||||
const isLogin = computed(() => sheep.$store('user').isLogin);
|
||||
|
||||
// 建行生活自动登录(测试用)
|
||||
const testCcbLogin = async () => {
|
||||
// 检查是否已登录
|
||||
if (isLogin.value) {
|
||||
console.log('[User] 用户已登录,跳过建行测试登录');
|
||||
return;
|
||||
}
|
||||
|
||||
// 测试用的固定加密参数
|
||||
const testCcbParam = {
|
||||
ccbParamSJ: "ZWVlRURYQndmYlpJOGpMRWRPRWEwRjVCZk82NjQxam1sL0l0d0NWMm9lUDdURld3MDRXamlNSGcva29COXBoZkVHKytHbHpSeUM3VkNESkUvTXYrOHFGYkhZWXo4d1NmanZuN0kvODF6TEo1OU9UbTZhS29MSUw3NjQzTGRKQWtrUHhyQi92TEVscWZzVWhlbVBpMVhHbHV2Z2RheXczK0VDL0J5N0g5aWNNR1ZPbFpWN0w4RHlNMGcrY09ZdWF2RUwzN2xheUNqUXdNV1dkR0F6RmlKL1V4b0NyMUhQM2R0Ui9ld0Vicll4eFdFeTFvUEthQ3Z5Vy9MajZxNFhQZTlrSjdTQVh1UjFyOWZGYjdMa003LzZpNnVSd2hWSnBCZ1h0WnRwU1VQb3UxSmh1UG00ejdleW9SUVMrOUJ2bW5VcVJBZnM0dy9RWEIwRlhwOGtLZW5rQ3RPK2xjdHlmTzE2cnU5UXJleHhmT2Y1ZXZwNjh3Qy9aTWVCTnoxZng4OXI2YWd5NUFWbmE2bzUwOVJES2tCZElhaG5JZll2eURPa2lyeTBqS0pBdGptSkRIRWFhcjUvaTlTVXkrbVdIbklmdDNsZE4rbWRnMWE0R0tzZmpqNUpDcll2VkFvQ0tBWklIc3FRL21admtrSDBqWEhYZ0ZrMjk2MWJ3eExSNGI=",
|
||||
cityid: "360100",
|
||||
CITYID: "360100"
|
||||
};
|
||||
|
||||
console.log('[User] 开始建行测试登录...');
|
||||
|
||||
// 显示加载提示
|
||||
uni.showLoading({
|
||||
title: '建行登录中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
try {
|
||||
// 调用建行登录API
|
||||
const result = await sheep.$api.third.ccbLogin(testCcbParam);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
if (result.code === 1) {
|
||||
console.log('[User] 登录接口返回成功,开始更新状态...');
|
||||
|
||||
// 🔑 关键:使用setToken方法更新登录状态
|
||||
// 这会同时:
|
||||
// 1. 设置isLogin = true
|
||||
// 2. 保存token到storage
|
||||
// 3. 自动调用loginAfter()更新用户信息
|
||||
sheep.$store('user').setToken(result.data.token);
|
||||
|
||||
// 也保存userInfo到storage(可选,setToken会自动获取)
|
||||
uni.setStorageSync('userInfo', result.data.user_info);
|
||||
|
||||
console.log('[User] ✅ 建行测试登录成功');
|
||||
console.log('[User] 登录状态已更新:', sheep.$store('user').isLogin);
|
||||
|
||||
// 显示欢迎提示
|
||||
uni.showToast({
|
||||
title: `欢迎 ${result.data.user_info?.nickname || ''}`,
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
// 等待状态更新完成后刷新页面
|
||||
setTimeout(() => {
|
||||
console.log('[User] 刷新页面数据...');
|
||||
sheep.$store('user').updateUserData();
|
||||
}, 100);
|
||||
} else {
|
||||
throw new Error(result.msg || '登录失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[User] ❌ 建行测试登录失败:', error);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
uni.showModal({
|
||||
title: '登录失败',
|
||||
content: error.message || error.msg || '请检查网络连接',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 页面挂载时自动登录(仅用于测试)
|
||||
onMounted(() => {
|
||||
// 延迟500ms执行,确保页面渲染完成
|
||||
setTimeout(() => {
|
||||
testCcbLogin();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
sheep.$store('user').updateUserData();
|
||||
});
|
||||
|
||||
@ -126,4 +126,59 @@ export default {
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
// 建行生活相关
|
||||
ccblife: {
|
||||
// URL跳转登录(解密ccbParamSJ)
|
||||
login: (params) =>
|
||||
request({
|
||||
url: 'ccblife/login',
|
||||
method: 'GET',
|
||||
params,
|
||||
custom: {
|
||||
showSuccess: false,
|
||||
showLoading: false,
|
||||
showError: false,
|
||||
},
|
||||
}),
|
||||
|
||||
// JSBridge自动登录
|
||||
autoLogin: (data) =>
|
||||
request({
|
||||
url: 'ccblife/autoLogin',
|
||||
method: 'POST',
|
||||
data,
|
||||
custom: {
|
||||
showSuccess: false,
|
||||
showLoading: false,
|
||||
showError: false,
|
||||
},
|
||||
}),
|
||||
|
||||
// 解密建行参数(测试用)
|
||||
decryptParam: (data) =>
|
||||
request({
|
||||
url: 'ccblife/decryptParam',
|
||||
method: 'POST',
|
||||
data,
|
||||
custom: {
|
||||
showSuccess: false,
|
||||
showLoading: false,
|
||||
showError: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
// 快捷方法:建行登录(兼容旧代码)
|
||||
ccbLogin: (params) =>
|
||||
request({
|
||||
url: 'ccblife/login',
|
||||
method: 'GET',
|
||||
params,
|
||||
custom: {
|
||||
showSuccess: false,
|
||||
showLoading: false,
|
||||
showError: false,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@ -99,30 +99,74 @@ const CcbLifePlatform = {
|
||||
setupBridge() {
|
||||
// #ifdef H5
|
||||
const self = this;
|
||||
let bridgeCheckCount = 0;
|
||||
const MAX_BRIDGE_CHECK = 20; // 最多检查20次
|
||||
const BRIDGE_CHECK_INTERVAL = 500; // 每500ms检查一次,总共10秒
|
||||
|
||||
// iOS WebViewJavascriptBridge
|
||||
if (window.WebViewJavascriptBridge) {
|
||||
self.bridge = window.WebViewJavascriptBridge;
|
||||
self.onBridgeReady();
|
||||
} else {
|
||||
document.addEventListener('WebViewJavascriptBridgeReady', function() {
|
||||
self.bridge = window.WebViewJavascriptBridge;
|
||||
self.onBridgeReady();
|
||||
}, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 监听iOS Bridge就绪事件
|
||||
document.addEventListener('WebViewJavascriptBridgeReady', function() {
|
||||
self.bridge = window.WebViewJavascriptBridge;
|
||||
self.onBridgeReady();
|
||||
}, false);
|
||||
|
||||
// Android 直接通过window对象
|
||||
if (window.mbspay && !self.bridge) {
|
||||
if (window.mbspay) {
|
||||
self.bridge = window.mbspay;
|
||||
self.onBridgeReady();
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置超时检查
|
||||
setTimeout(() => {
|
||||
if (!self.isReady) {
|
||||
console.warn('[CcbLife] JSBridge 未就绪');
|
||||
// 轮询检查Bridge是否已加载(建行App可能需要时间初始化)
|
||||
const bridgeCheckInterval = setInterval(() => {
|
||||
bridgeCheckCount++;
|
||||
|
||||
// 检查iOS Bridge
|
||||
if (window.WebViewJavascriptBridge && !self.isReady) {
|
||||
clearInterval(bridgeCheckInterval);
|
||||
self.bridge = window.WebViewJavascriptBridge;
|
||||
self.onBridgeReady();
|
||||
console.log(`[CcbLife] iOS Bridge 已就绪(检查${bridgeCheckCount}次)`);
|
||||
return;
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
// 检查Android Bridge
|
||||
if (window.mbspay && !self.isReady) {
|
||||
clearInterval(bridgeCheckInterval);
|
||||
self.bridge = window.mbspay;
|
||||
self.onBridgeReady();
|
||||
console.log(`[CcbLife] Android Bridge 已就绪(检查${bridgeCheckCount}次)`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 达到最大检查次数
|
||||
if (bridgeCheckCount >= MAX_BRIDGE_CHECK) {
|
||||
clearInterval(bridgeCheckInterval);
|
||||
console.error('[CcbLife] ⚠️ JSBridge 初始化超时,建行功能可能不可用');
|
||||
|
||||
// 显示提示
|
||||
if (self.isInCcbApp) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '建行环境初始化失败,部分功能可能无法使用。建议重新打开页面。',
|
||||
showCancel: true,
|
||||
cancelText: '关闭',
|
||||
confirmText: '重新加载',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, BRIDGE_CHECK_INTERVAL);
|
||||
// #endif
|
||||
},
|
||||
|
||||
@ -207,42 +251,91 @@ const CcbLifePlatform = {
|
||||
|
||||
/**
|
||||
* 自动登录
|
||||
* @param {Number} retryCount - 重试次数
|
||||
*/
|
||||
async autoLogin() {
|
||||
async autoLogin(retryCount = 0) {
|
||||
const MAX_RETRY = 2; // 最多重试2次
|
||||
const RETRY_DELAY = 2000; // 重试延迟2秒
|
||||
|
||||
try {
|
||||
// 检查是否已登录
|
||||
const token = uni.getStorageSync('token');
|
||||
if (token) {
|
||||
console.log('[CcbLife] 用户已登录');
|
||||
return;
|
||||
console.log('[CcbLife] 用户已登录,跳过自动登录');
|
||||
// 验证token有效性
|
||||
try {
|
||||
await sheep.$store('user').getInfo();
|
||||
console.log('[CcbLife] Token有效');
|
||||
return { success: true, cached: true };
|
||||
} catch (e) {
|
||||
console.warn('[CcbLife] Token已失效,清除并重新登录');
|
||||
uni.removeStorageSync('token');
|
||||
uni.removeStorageSync('userInfo');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[CcbLife] 开始自动登录...');
|
||||
|
||||
// 获取用户信息
|
||||
const userResult = await this.getUserInfo();
|
||||
if (userResult.code !== 0) {
|
||||
throw new Error(userResult.msg);
|
||||
throw new Error(userResult.msg || '获取建行用户信息失败');
|
||||
}
|
||||
|
||||
console.log('[CcbLife] 建行用户信息获取成功:', userResult.data);
|
||||
|
||||
// 调用后端登录接口
|
||||
const loginResult = await ccbApi.autoLogin(userResult.data);
|
||||
|
||||
if (loginResult.code === 1) {
|
||||
// 保存Token和用户信息
|
||||
uni.setStorageSync('token', loginResult.data.token);
|
||||
uni.setStorageSync('userInfo', loginResult.data.userInfo);
|
||||
// 🔑 使用setToken方法更新登录状态(关键!)
|
||||
// 这会自动:设置isLogin=true + 保存token + 调用loginAfter()
|
||||
sheep.$store('user').setToken(loginResult.data.token);
|
||||
|
||||
// 更新Shopro用户状态
|
||||
sheep.$store('user').getInfo();
|
||||
// 也保存userInfo到storage(setToken会自动获取最新的)
|
||||
uni.setStorageSync('userInfo', loginResult.data.user_info || loginResult.data.userInfo);
|
||||
|
||||
console.log('[CcbLife] 自动登录成功');
|
||||
console.log('[CcbLife] ✅ 自动登录成功');
|
||||
|
||||
// 触发登录成功事件
|
||||
uni.$emit('ccb:login:success', loginResult.data);
|
||||
|
||||
// 显示欢迎提示
|
||||
uni.showToast({
|
||||
title: '欢迎回来',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
|
||||
return { success: true, data: loginResult.data };
|
||||
} else {
|
||||
throw new Error(loginResult.msg);
|
||||
throw new Error(loginResult.msg || '登录接口返回失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[CcbLife] 自动登录失败:', error);
|
||||
console.error(`[CcbLife] ❌ 自动登录失败(第${retryCount + 1}次):`, error.message || error);
|
||||
|
||||
// 重试逻辑
|
||||
if (retryCount < MAX_RETRY) {
|
||||
console.log(`[CcbLife] ${RETRY_DELAY / 1000}秒后进行第${retryCount + 2}次尝试...`);
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(this.autoLogin(retryCount + 1));
|
||||
}, RETRY_DELAY);
|
||||
});
|
||||
}
|
||||
|
||||
// 重试失败后的处理
|
||||
console.error('[CcbLife] 自动登录失败,已达最大重试次数');
|
||||
|
||||
// 显示友好提示
|
||||
uni.showModal({
|
||||
title: '登录提示',
|
||||
content: '自动登录失败,请点击登录按钮手动登录',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
|
||||
return { success: false, error: error.message || '未知错误' };
|
||||
}
|
||||
},
|
||||
|
||||
@ -396,40 +489,97 @@ const CcbLifePlatform = {
|
||||
|
||||
/**
|
||||
* 处理URL跳转登录
|
||||
* 建行App通过URL携带加密参数跳转到H5时调用
|
||||
*/
|
||||
async handleUrlLogin() {
|
||||
const params = this.getUrlParams();
|
||||
|
||||
// 如果有ccbParamSJ参数,说明是从建行跳转过来的
|
||||
// 如果有ccbParamSJ参数,说明是从建行跳转过来的
|
||||
if (params.ccbParamSJ) {
|
||||
console.log('[CcbLife] 检测到URL登录参数,开始处理...');
|
||||
|
||||
// 显示加载提示
|
||||
uni.showLoading({
|
||||
title: '登录中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
try {
|
||||
// 检查是否已经登录过(避免重复登录)
|
||||
const existingToken = uni.getStorageSync('token');
|
||||
const loginTimestamp = uni.getStorageSync('ccb_url_login_timestamp');
|
||||
const now = Date.now();
|
||||
|
||||
// 如果5分钟内已经用同样的参数登录过,跳过
|
||||
if (existingToken && loginTimestamp && (now - loginTimestamp) < 5 * 60 * 1000) {
|
||||
console.log('[CcbLife] 检测到最近已登录,跳过URL登录');
|
||||
uni.hideLoading();
|
||||
|
||||
// 直接跳转
|
||||
const redirectUrl = params.redirect_url || '/pages/index/index';
|
||||
uni.reLaunch({ url: redirectUrl });
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用后端解密并登录
|
||||
const result = await ccbApi.login(params);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
if (result.code === 1) {
|
||||
// 保存Token和用户信息
|
||||
uni.setStorageSync('token', result.data.token);
|
||||
// 🔑 使用setToken方法更新登录状态(关键!)
|
||||
sheep.$store('user').setToken(result.data.token);
|
||||
|
||||
// 保存用户信息和登录时间戳
|
||||
uni.setStorageSync('userInfo', result.data.user_info);
|
||||
uni.setStorageSync('ccb_url_login_timestamp', Date.now());
|
||||
|
||||
// 更新用户状态
|
||||
sheep.$store('user').getInfo();
|
||||
console.log('[CcbLife] ✅ URL登录成功');
|
||||
|
||||
// 跳转到指定页面
|
||||
const redirectUrl = result.data.redirect_url || '/pages/index/index';
|
||||
uni.reLaunch({
|
||||
url: redirectUrl
|
||||
});
|
||||
} else {
|
||||
// 触发登录成功事件
|
||||
uni.$emit('ccb:login:success', result.data);
|
||||
|
||||
// 显示欢迎提示
|
||||
uni.showToast({
|
||||
title: result.msg || '登录失败',
|
||||
icon: 'none'
|
||||
title: `欢迎${result.data.user_info?.nickname || ''}`,
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
|
||||
// 延迟跳转,让用户看到提示
|
||||
setTimeout(() => {
|
||||
const redirectUrl = result.data.redirect_url || '/pages/index/index';
|
||||
uni.reLaunch({
|
||||
url: redirectUrl
|
||||
});
|
||||
}, 1500);
|
||||
|
||||
} else {
|
||||
throw new Error(result.msg || '登录失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[CcbLife] URL登录失败:', error);
|
||||
uni.showToast({
|
||||
title: '登录失败',
|
||||
icon: 'none'
|
||||
console.error('[CcbLife] ❌ URL登录失败:', error);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
// 显示详细错误
|
||||
uni.showModal({
|
||||
title: 'URL登录失败',
|
||||
content: error.message || error.msg || '参数解密失败,请重新进入',
|
||||
showCancel: true,
|
||||
cancelText: '返回',
|
||||
confirmText: '重试',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 重试
|
||||
this.handleUrlLogin();
|
||||
} else {
|
||||
// 返回建行或首页
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user