mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
bug修改
This commit is contained in:
parent
623efdc041
commit
da85b453e1
306
.claude/api-data-null-analysis.md
Normal file
306
.claude/api-data-null-analysis.md
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
# API返回data为null问题深度分析报告
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
用户报告通过Postman请求所有API接口都返回 `"data": null`,即使代码中明确传递了数据给 `$this->success()` 方法。
|
||||||
|
|
||||||
|
## 分析过程
|
||||||
|
|
||||||
|
### 1. 架构分析
|
||||||
|
|
||||||
|
#### 控制器继承链
|
||||||
|
```
|
||||||
|
Ccblife extends Common extends Api
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Ccblife.php**: `/Users/billy/Code/fengketrade.com/addons/shopro/controller/Ccblife.php`
|
||||||
|
- **Common.php**: `/Users/billy/Code/fengketrade.com/addons/shopro/controller/Common.php`
|
||||||
|
- **Api.php**: `/Users/billy/Code/fengketrade.com/application/common/controller/Api.php`
|
||||||
|
|
||||||
|
#### success/error/result方法定义
|
||||||
|
|
||||||
|
**Api.php (第170-219行)**:
|
||||||
|
```php
|
||||||
|
protected function success($msg = '', $data = null, $code = 1, $type = null, array $header = [])
|
||||||
|
{
|
||||||
|
$this->result($msg, $data, $code, $type, $header);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function error($msg = '', $data = null, $code = 0, $type = null, array $header = [])
|
||||||
|
{
|
||||||
|
$this->result($msg, $data, $code, $type, $header);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function result($msg, $data = null, $code = 0, $type = null, array $header = [])
|
||||||
|
{
|
||||||
|
$result = [
|
||||||
|
'code' => $code,
|
||||||
|
'msg' => $msg,
|
||||||
|
'time' => Request::instance()->server('REQUEST_TIME'),
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
$type = $type ? : $this->responseType;
|
||||||
|
if (isset($header['statuscode'])) {
|
||||||
|
$code = $header['statuscode'];
|
||||||
|
unset($header['statuscode']);
|
||||||
|
} else {
|
||||||
|
$code = $code >= 1000 || $code < 200 ? 200 : $code;
|
||||||
|
}
|
||||||
|
$response = Response::create($result, $type, $code)->header($header);
|
||||||
|
throw new HttpResponseException($response);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Common.php (第30-85行)**:
|
||||||
|
- success/error/result方法**已被注释**,从git历史看从未启用过
|
||||||
|
- 因此Ccblife控制器使用的是Api基类的方法
|
||||||
|
|
||||||
|
### 2. 可能原因排查
|
||||||
|
|
||||||
|
#### ✅ 已排除的原因
|
||||||
|
|
||||||
|
1. **Request Filter机制**
|
||||||
|
- Api.php第102行: `$this->request->filter('trim,strip_tags,htmlspecialchars');`
|
||||||
|
- 检查ThinkPHP源码第1095行: `elseif (is_scalar($value))`
|
||||||
|
- **结论**: filter只处理标量值,不会处理数组/对象,不是问题根源
|
||||||
|
|
||||||
|
2. **全局响应钩子**
|
||||||
|
- 检查 `application/tags.php`: 无response相关钩子
|
||||||
|
- 检查 `application/common/behavior/Common.php`: 无response处理
|
||||||
|
- **结论**: 无全局钩子修改响应数据
|
||||||
|
|
||||||
|
3. **Response处理流程**
|
||||||
|
- 检查 `thinkphp/library/think/Response.php`
|
||||||
|
- 检查 `thinkphp/library/think/response/Json.php`
|
||||||
|
- **结论**: Response类正常进行json_encode,无数据篡改
|
||||||
|
|
||||||
|
4. **Common.php重写**
|
||||||
|
- Common.php中success/error/result方法已注释
|
||||||
|
- **结论**: 使用的是Api基类的标准实现
|
||||||
|
|
||||||
|
### 3. 实际测试结果
|
||||||
|
|
||||||
|
#### 测试1: init接口(成功返回数据)
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://fengketrade.test/addons/shopro/index/init" -H "platform: H5"
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 1,
|
||||||
|
"msg": "初始化",
|
||||||
|
"time": "1760930544",
|
||||||
|
"data": {
|
||||||
|
"app": { ... }, // 完整的数据对象
|
||||||
|
"platform": { ... },
|
||||||
|
"template": { ... },
|
||||||
|
"chat": { ... }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**结论**: `/addons/shopro/index/init` 接口**data字段正常返回数据**!
|
||||||
|
|
||||||
|
#### 测试2: decryptParam接口(返回data:null)
|
||||||
|
```bash
|
||||||
|
curl -X POST http://fengketrade.test/addons/shopro/ccblife/decryptParam \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"ccbParamSJ":"test"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"msg": "解密失败: ",
|
||||||
|
"time": "1760930527",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**分析**:
|
||||||
|
- code=0 表示这是error响应
|
||||||
|
- 触发代码: `Ccblife.php` 第354行 `$this->error('解密失败: ' . $e->getMessage());`
|
||||||
|
- **error()方法签名**: `error($msg = '', $data = null, $code = 0, ...)`
|
||||||
|
- **调用方式**: 只传了第一个参数$msg,第二个参数$data默认值就是null
|
||||||
|
- **结论**: 这是**预期行为**,错误响应时确实data为null
|
||||||
|
|
||||||
|
#### 测试3: page接口(返回data:null)
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://fengketrade.test/addons/shopro/index/page?id=1"
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"msg": "记录未找到",
|
||||||
|
"time": "1760930559",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**分析**:
|
||||||
|
- code=0 表示error响应
|
||||||
|
- 触发代码: `Index.php` 第116行 `$this->error(__('No Results were found'));`
|
||||||
|
- **结论**: 错误响应,data为null是**预期行为**
|
||||||
|
|
||||||
|
### 4. Ccblife.php中的success调用检查
|
||||||
|
|
||||||
|
```php
|
||||||
|
// 第107行 - login方法
|
||||||
|
$this->success(__('Logged in successful'), [
|
||||||
|
'token' => $token,
|
||||||
|
'user_info' => $userInfo,
|
||||||
|
'redirect_url' => $redirectUrl
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 第149行 - autoLogin方法
|
||||||
|
$this->success('登录成功', [
|
||||||
|
'token' => $token,
|
||||||
|
'user_id' => $userInfo['user_id'],
|
||||||
|
'is_new_user' => $userInfo['is_new'],
|
||||||
|
'userInfo' => $userInfo
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 第347行 - decryptParam方法
|
||||||
|
$this->success('解密成功', $decryptedParams);
|
||||||
|
```
|
||||||
|
|
||||||
|
**结论**: 所有success调用**都正确传递了data参数**。
|
||||||
|
|
||||||
|
### 5. 问题根源推断
|
||||||
|
|
||||||
|
基于测试结果,我认为问题可能是:
|
||||||
|
|
||||||
|
#### 可能性1: 用户测试的是错误场景
|
||||||
|
- 用户可能测试的接口都触发了异常或错误条件
|
||||||
|
- error()方法调用时很多地方只传了$msg参数,没有传$data
|
||||||
|
- **导致data为null是正常的错误响应行为**
|
||||||
|
|
||||||
|
#### 可能性2: 参数传递问题
|
||||||
|
- 用户Postman请求时可能缺少必要参数或token
|
||||||
|
- 导致接口执行异常分支,返回error响应
|
||||||
|
- **需要检查请求头和请求体是否完整**
|
||||||
|
|
||||||
|
#### 可能性3: 特定接口存在问题
|
||||||
|
- 并非"所有接口"都返回data:null
|
||||||
|
- init接口已验证可正常返回data
|
||||||
|
- **需要用户明确具体哪些接口有问题**
|
||||||
|
|
||||||
|
## 关键发现
|
||||||
|
|
||||||
|
### ✅ 正常工作的部分
|
||||||
|
1. Api基类的success/error/result方法实现正确
|
||||||
|
2. Response JSON序列化正常
|
||||||
|
3. init接口验证可以正常返回完整data数据
|
||||||
|
4. Ccblife.php中success方法调用语法正确
|
||||||
|
|
||||||
|
### ❓ 需要用户确认的信息
|
||||||
|
1. 具体测试了哪几个API接口?
|
||||||
|
2. 这些接口的完整请求URL、Headers、Body是什么?
|
||||||
|
3. 是否有token认证?
|
||||||
|
4. 返回的完整JSON响应(包括msg和code字段)?
|
||||||
|
5. 是否所有接口返回的code都是0(错误)?
|
||||||
|
|
||||||
|
### ⚠️ 潜在问题点
|
||||||
|
1. **error调用缺少data参数**
|
||||||
|
- 在很多地方调用error()时只传了msg
|
||||||
|
- 如: `$this->error('错误信息');`
|
||||||
|
- 应该改为: `$this->error('错误信息', ['detail' => ...]);`
|
||||||
|
|
||||||
|
2. **异常处理可能吞掉data**
|
||||||
|
```php
|
||||||
|
// Ccblife.php 第113-115行
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error($e->getMessage()); // 只传msg,data为null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 修复建议
|
||||||
|
|
||||||
|
### 短期修复
|
||||||
|
如果确实需要在error响应中也返回数据,修改所有error调用:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// 修改前
|
||||||
|
$this->error('参数解密失败');
|
||||||
|
|
||||||
|
// 修改后
|
||||||
|
$this->error('参数解密失败', [
|
||||||
|
'error_code' => 'DECRYPT_FAILED',
|
||||||
|
'timestamp' => time()
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 长期优化
|
||||||
|
1. **统一异常处理**
|
||||||
|
```php
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('错误: ' . $e->getMessage());
|
||||||
|
$this->error('操作失败', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **规范化响应格式**
|
||||||
|
- success时data必须有值(至少是空数组[])
|
||||||
|
- error时data可以包含错误详情
|
||||||
|
- 避免所有error都返回data:null
|
||||||
|
|
||||||
|
3. **增加调试日志**
|
||||||
|
```php
|
||||||
|
protected function result($msg, $data = null, $code = 0, $type = null, array $header = [])
|
||||||
|
{
|
||||||
|
// 添加调试日志
|
||||||
|
if (config('app_debug')) {
|
||||||
|
Log::debug('API Response', [
|
||||||
|
'msg' => $msg,
|
||||||
|
'data' => $data,
|
||||||
|
'code' => $code
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'code' => $code,
|
||||||
|
'msg' => $msg,
|
||||||
|
'time' => Request::instance()->server('REQUEST_TIME'),
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
// ... 后续代码
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 下一步行动
|
||||||
|
|
||||||
|
1. **用户需要提供**:
|
||||||
|
- 具体的API接口URL列表
|
||||||
|
- 完整的Postman请求示例(包括Headers和Body)
|
||||||
|
- 完整的响应JSON(包括code和msg字段)
|
||||||
|
|
||||||
|
2. **开发者需要检查**:
|
||||||
|
- 是否所有"data:null"的响应code都是0(错误响应)?
|
||||||
|
- 是否success响应(code=1)也出现data:null?
|
||||||
|
- 是否有日志记录显示data确实被构建了但最后变成null?
|
||||||
|
|
||||||
|
3. **验证测试**:
|
||||||
|
- 测试已验证正常的init接口
|
||||||
|
- 对比init和问题接口的差异
|
||||||
|
- 使用相同的Postman配置测试两个接口
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
目前**没有发现系统性的问题导致所有API的data都为null**。测试验证了:
|
||||||
|
- init接口可以正常返回完整data
|
||||||
|
- decryptParam和page接口返回data:null是因为触发了error分支
|
||||||
|
|
||||||
|
**强烈建议用户提供具体的问题接口和完整请求信息,以便进一步定位问题。**
|
||||||
|
|
||||||
|
当前的data:null很可能是:
|
||||||
|
1. 错误响应的正常行为(code=0)
|
||||||
|
2. 调用error时未传data参数
|
||||||
|
3. 请求参数不完整触发异常分支
|
||||||
|
|
||||||
|
而非框架层面的全局性问题。
|
||||||
@ -194,10 +194,18 @@
|
|||||||
<span class="label">登录状态:</span>
|
<span class="label">登录状态:</span>
|
||||||
<span class="value" id="login-status">未登录</span>
|
<span class="value" id="login-status">未登录</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">自动登录:</span>
|
||||||
|
<span class="value" id="auto-login-status">待检测</span>
|
||||||
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="label">建行用户ID:</span>
|
<span class="label">建行用户ID:</span>
|
||||||
<span class="value" id="ccb-user-id">-</span>
|
<span class="value" id="ccb-user-id">-</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">登录时间:</span>
|
||||||
|
<span class="value" id="login-time">-</span>
|
||||||
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="label">建行参数:</span>
|
<span class="label">建行参数:</span>
|
||||||
<span class="value" id="ccb-param">无</span>
|
<span class="value" id="ccb-param">无</span>
|
||||||
@ -211,9 +219,10 @@
|
|||||||
|
|
||||||
<button class="btn" onclick="refreshEnv()">🔄 刷新环境检测</button>
|
<button class="btn" onclick="refreshEnv()">🔄 刷新环境检测</button>
|
||||||
<button class="btn" onclick="decryptCcbParam()">🔓 解密建行参数</button>
|
<button class="btn" onclick="decryptCcbParam()">🔓 解密建行参数</button>
|
||||||
<button class="btn btn-success" onclick="testLogin()">🔐 测试登录入库</button>
|
<button class="btn btn-success" onclick="testLogin()">🔐 测试登录入库(手动)</button>
|
||||||
|
<button class="btn btn-success" onclick="forceAutoLogin()">⚡ 强制自动登录(重新)</button>
|
||||||
<button class="btn" onclick="getUserInfo()">获取建行用户信息</button>
|
<button class="btn" onclick="getUserInfo()">获取建行用户信息</button>
|
||||||
<button class="btn btn-secondary" onclick="doAutoLogin()">执行自动登录</button>
|
<button class="btn btn-secondary" onclick="doAutoLogin()">执行自动登录(JSBridge)</button>
|
||||||
<button class="btn btn-success" onclick="testPayment()">测试支付功能</button>
|
<button class="btn btn-success" onclick="testPayment()">测试支付功能</button>
|
||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
@ -263,8 +272,157 @@
|
|||||||
document.getElementById('bridge-status').innerHTML =
|
document.getElementById('bridge-status').innerHTML =
|
||||||
'<span class="status status-success">已就绪</span>';
|
'<span class="status status-success">已就绪</span>';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 自动登录逻辑
|
||||||
|
autoLoginOnLoad();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 页面加载时自动登录
|
||||||
|
function autoLoginOnLoad() {
|
||||||
|
console.log('[自动登录] 开始检测...');
|
||||||
|
|
||||||
|
// 更新状态显示
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-warning">检测中...</span>';
|
||||||
|
|
||||||
|
// 获取 URL 参数
|
||||||
|
var params = CcbLifeBridge.getUrlParams();
|
||||||
|
|
||||||
|
// 检查是否有建行参数
|
||||||
|
if (params.ccbParamSJ) {
|
||||||
|
console.log('[自动登录] 检测到 ccbParamSJ 参数');
|
||||||
|
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-warning">正在执行...</span>';
|
||||||
|
|
||||||
|
// 检查是否已经登录过(避免重复登录)
|
||||||
|
var token = localStorage.getItem('ccb_token');
|
||||||
|
var loginTimestamp = localStorage.getItem('ccb_login_timestamp');
|
||||||
|
var now = Date.now();
|
||||||
|
|
||||||
|
// 如果已登录且登录时间在30分钟内,跳过自动登录
|
||||||
|
if (token && loginTimestamp && (now - parseInt(loginTimestamp)) < 30 * 60 * 1000) {
|
||||||
|
console.log('[自动登录] 已存在有效登录,跳过');
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-success">已跳过(使用缓存)</span>';
|
||||||
|
showResult('✅ 检测到已登录状态\n\n使用缓存的 Token\n\n如需重新登录,请点击"测试登录入库"按钮');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示自动登录提示
|
||||||
|
showResult('🔄 检测到建行参数,正在自动登录...\n\n1. 解密建行参数\n2. 验证用户信息\n3. 创建/更新用户\n4. 生成登录 Token');
|
||||||
|
showLoading(true);
|
||||||
|
|
||||||
|
// 延迟500ms执行,确保页面渲染完成
|
||||||
|
setTimeout(function() {
|
||||||
|
executeAutoLogin(params.ccbParamSJ);
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
console.log('[自动登录] 未检测到 ccbParamSJ 参数');
|
||||||
|
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-error">未触发(无参数)</span>';
|
||||||
|
|
||||||
|
// 检查本地缓存
|
||||||
|
var cachedToken = localStorage.getItem('ccb_token');
|
||||||
|
var cachedUserInfo = localStorage.getItem('ccb_user_info');
|
||||||
|
|
||||||
|
if (cachedToken && cachedUserInfo) {
|
||||||
|
try {
|
||||||
|
var user = JSON.parse(cachedUserInfo);
|
||||||
|
console.log('[自动登录] 使用缓存的登录信息');
|
||||||
|
updateLoginStatus({ userInfo: user });
|
||||||
|
showResult('✅ 使用缓存的登录状态\n\n用户信息:\n' + JSON.stringify(user, null, 2));
|
||||||
|
} catch(e) {
|
||||||
|
console.error('[自动登录] 解析缓存失败', e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('[自动登录] 无缓存,显示未登录状态');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行自动登录
|
||||||
|
function executeAutoLogin(ccbParamSJ) {
|
||||||
|
console.log('[自动登录] 开始调用登录接口');
|
||||||
|
|
||||||
|
// 调用后端登录接口
|
||||||
|
fetch('/addons/shopro/ccblife/login?ccbParamSJ=' + encodeURIComponent(ccbParamSJ), {
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
showLoading(false);
|
||||||
|
|
||||||
|
console.log('[自动登录] 接口返回:', data);
|
||||||
|
|
||||||
|
if (data.code === 1) {
|
||||||
|
var loginData = data.data;
|
||||||
|
|
||||||
|
// 保存 token 和用户信息
|
||||||
|
localStorage.setItem('ccb_token', loginData.token);
|
||||||
|
localStorage.setItem('ccb_user_info', JSON.stringify(loginData.user_info));
|
||||||
|
localStorage.setItem('ccb_login_timestamp', Date.now().toString());
|
||||||
|
|
||||||
|
// 更新自动登录状态
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-success">成功</span>';
|
||||||
|
|
||||||
|
// 更新登录时间
|
||||||
|
document.getElementById('login-time').textContent =
|
||||||
|
new Date().toLocaleString('zh-CN', { hour12: false });
|
||||||
|
|
||||||
|
// 更新页面显示
|
||||||
|
updateLoginStatus({ userInfo: loginData.user_info });
|
||||||
|
|
||||||
|
// 触发自定义事件
|
||||||
|
window.dispatchEvent(new CustomEvent('ccb:login:success', {
|
||||||
|
detail: loginData
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log('[自动登录] 登录成功!');
|
||||||
|
|
||||||
|
showResult('✅ 自动登录成功!\n\n' +
|
||||||
|
'用户昵称: ' + loginData.user_info.nickname + '\n' +
|
||||||
|
'手机号: ' + loginData.user_info.mobile + '\n' +
|
||||||
|
'建行用户ID: ' + loginData.user_info.ccb_user_id + '\n\n' +
|
||||||
|
'Token: ' + loginData.token.substr(0, 20) + '...\n\n' +
|
||||||
|
'是否新用户: ' + (loginData.user_info.is_new ? '是' : '否') + '\n' +
|
||||||
|
'登录时间: ' + new Date().toLocaleString('zh-CN', { hour12: false }) + '\n\n' +
|
||||||
|
'跳转URL: ' + loginData.redirect_url
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果有重定向URL且不是默认首页,可以自动跳转(可选)
|
||||||
|
// if (loginData.redirect_url && loginData.redirect_url !== '/pages/index/index') {
|
||||||
|
// setTimeout(function() {
|
||||||
|
// window.location.href = loginData.redirect_url;
|
||||||
|
// }, 2000);
|
||||||
|
// }
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('[自动登录] 登录失败:', data.msg);
|
||||||
|
|
||||||
|
// 更新自动登录状态
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-error">失败</span>';
|
||||||
|
|
||||||
|
showResult('❌ 自动登录失败\n\n错误信息: ' + data.msg + '\n\n' +
|
||||||
|
(data.data ? '详细信息:\n' + JSON.stringify(data.data, null, 2) + '\n\n' : '') +
|
||||||
|
'请尝试手动点击"测试登录入库"按钮');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
showLoading(false);
|
||||||
|
console.error('[自动登录] 请求异常:', error);
|
||||||
|
|
||||||
|
// 更新自动登录状态
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-error">异常</span>';
|
||||||
|
|
||||||
|
showResult('❌ 自动登录请求失败\n\n' + error.message + '\n\n请检查网络连接或手动点击"测试登录入库"按钮');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 更新环境状态
|
// 更新环境状态
|
||||||
function updateEnvStatus() {
|
function updateEnvStatus() {
|
||||||
var isInApp = CcbLifeBridge.isInCcbApp();
|
var isInApp = CcbLifeBridge.isInCcbApp();
|
||||||
@ -518,6 +676,31 @@
|
|||||||
}, 5000); // 每5秒查询一次
|
}, 5000); // 每5秒查询一次
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 强制自动登录(忽略缓存)
|
||||||
|
function forceAutoLogin() {
|
||||||
|
var params = CcbLifeBridge.getUrlParams();
|
||||||
|
|
||||||
|
if (!params.ccbParamSJ) {
|
||||||
|
showResult('错误: URL 中没有 ccbParamSJ 参数\n\n请从建行生活 App 跳转到此页面,或在 URL 中添加 ccbParamSJ 参数');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除登录时间戳,强制重新登录
|
||||||
|
localStorage.removeItem('ccb_login_timestamp');
|
||||||
|
|
||||||
|
showResult('🔄 强制重新登录...\n\n忽略缓存,重新执行登录流程');
|
||||||
|
showLoading(true);
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
document.getElementById('auto-login-status').innerHTML =
|
||||||
|
'<span class="status status-warning">强制执行...</span>';
|
||||||
|
|
||||||
|
// 延迟执行
|
||||||
|
setTimeout(function() {
|
||||||
|
executeAutoLogin(params.ccbParamSJ);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
// 测试登录入库
|
// 测试登录入库
|
||||||
function testLogin() {
|
function testLogin() {
|
||||||
var params = CcbLifeBridge.getUrlParams();
|
var params = CcbLifeBridge.getUrlParams();
|
||||||
@ -544,10 +727,15 @@
|
|||||||
// 保存 token 和用户信息
|
// 保存 token 和用户信息
|
||||||
localStorage.setItem('ccb_token', loginData.token);
|
localStorage.setItem('ccb_token', loginData.token);
|
||||||
localStorage.setItem('ccb_user_info', JSON.stringify(loginData.user_info));
|
localStorage.setItem('ccb_user_info', JSON.stringify(loginData.user_info));
|
||||||
|
localStorage.setItem('ccb_login_timestamp', Date.now().toString());
|
||||||
|
|
||||||
// 更新页面显示
|
// 更新页面显示
|
||||||
updateLoginStatus({ userInfo: loginData.user_info });
|
updateLoginStatus({ userInfo: loginData.user_info });
|
||||||
|
|
||||||
|
// 更新登录时间
|
||||||
|
document.getElementById('login-time').textContent =
|
||||||
|
new Date().toLocaleString('zh-CN', { hour12: false });
|
||||||
|
|
||||||
showResult('✅ 登录成功!\n\n' +
|
showResult('✅ 登录成功!\n\n' +
|
||||||
'用户信息:\n' + JSON.stringify(loginData.user_info, null, 2) + '\n\n' +
|
'用户信息:\n' + JSON.stringify(loginData.user_info, null, 2) + '\n\n' +
|
||||||
'Token:' + loginData.token.substr(0, 20) + '...\n\n' +
|
'Token:' + loginData.token.substr(0, 20) + '...\n\n' +
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user