2025-10-17 16:32:16 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace addons\shopro\controller;
|
|
|
|
|
|
|
|
|
|
|
|
use addons\shopro\controller\Common;
|
2025-10-17 17:18:15 +08:00
|
|
|
|
use addons\shopro\library\ccblife\CcbUrlDecrypt;
|
|
|
|
|
|
use app\admin\model\shopro\user\User;
|
|
|
|
|
|
use think\Db;
|
2025-10-17 16:32:16 +08:00
|
|
|
|
use think\Log;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 建行生活用户登录控制器
|
2025-10-17 17:18:15 +08:00
|
|
|
|
* 处理建行用户登录、绑定、参数解密等功能
|
2025-10-17 16:32:16 +08:00
|
|
|
|
*/
|
|
|
|
|
|
class Ccblife extends Common
|
|
|
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 不需要登录的方法
|
|
|
|
|
|
* @var array
|
|
|
|
|
|
*/
|
2025-10-20 08:54:02 +08:00
|
|
|
|
protected $noNeedLogin = ['autoLogin', 'login', 'callback', 'decryptParam'];
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 不需要权限的方法
|
|
|
|
|
|
* @var array
|
|
|
|
|
|
*/
|
|
|
|
|
|
protected $noNeedRight = ['*'];
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-10-20 10:37:59 +08:00
|
|
|
|
* 建行生活用户登录(URL跳转方式或POST方式)
|
2025-10-17 17:18:15 +08:00
|
|
|
|
* 建行App会携带加密参数跳转到此地址
|
2025-10-17 16:32:16 +08:00
|
|
|
|
*
|
2025-10-20 10:37:59 +08:00
|
|
|
|
* GET/POST /addons/shopro/ccblife/login
|
2025-10-17 17:18:15 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public function login()
|
|
|
|
|
|
{
|
|
|
|
|
|
try {
|
2025-10-20 10:37:59 +08:00
|
|
|
|
// 获取参数(支持 GET 和 POST)
|
|
|
|
|
|
$ccbParamSJ = $this->request->param('ccbParamSJ', '');
|
|
|
|
|
|
$otherParams = $this->request->param();
|
2025-10-17 17:18:15 +08:00
|
|
|
|
|
2025-10-20 11:33:27 +08:00
|
|
|
|
// 记录接收到的参数(调试用)
|
|
|
|
|
|
Log::info('建行登录接收参数: ' . json_encode([
|
|
|
|
|
|
'method' => $this->request->method(),
|
|
|
|
|
|
'ccbParamSJ_exists' => !empty($ccbParamSJ),
|
|
|
|
|
|
'ccbParamSJ_length' => strlen($ccbParamSJ),
|
|
|
|
|
|
'all_params' => array_keys($otherParams),
|
|
|
|
|
|
'content_type' => $this->request->header('content-type')
|
|
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
// 验证必要参数
|
|
|
|
|
|
if (empty($ccbParamSJ)) {
|
2025-10-20 11:33:27 +08:00
|
|
|
|
$this->error('缺少必要参数 ccbParamSJ', [
|
|
|
|
|
|
'received_params' => array_keys($otherParams)
|
|
|
|
|
|
]);
|
2025-10-17 17:18:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 10:37:59 +08:00
|
|
|
|
// 从插件配置文件直接加载(避免config()缓存问题)
|
|
|
|
|
|
$configFile = __DIR__ . '/../config/ccblife.php';
|
|
|
|
|
|
if (!file_exists($configFile)) {
|
|
|
|
|
|
$this->error('建行配置文件不存在');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$config = include $configFile;
|
|
|
|
|
|
|
|
|
|
|
|
// 验证配置
|
|
|
|
|
|
if (empty($config['private_key'])) {
|
|
|
|
|
|
$this->error('配置错误:private_key 为空');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Log::info('建行登录解密参数: ' . json_encode([
|
|
|
|
|
|
'ccbParamSJ_length' => strlen($ccbParamSJ),
|
|
|
|
|
|
'service_id' => $config['service_id'],
|
|
|
|
|
|
'private_key_length' => strlen($config['private_key'])
|
|
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
2025-10-17 17:18:15 +08:00
|
|
|
|
|
2025-10-20 09:23:30 +08:00
|
|
|
|
// 解密参数(使用服务方私钥)
|
|
|
|
|
|
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['private_key']);
|
2025-10-17 17:18:15 +08:00
|
|
|
|
if (!$decryptedParams) {
|
2025-10-20 10:37:59 +08:00
|
|
|
|
// 检查日志文件获取详细错误
|
|
|
|
|
|
$logFile = RUNTIME_PATH . 'log/' . date('Ym') . '/' . date('d') . '.log';
|
|
|
|
|
|
$errorDetail = '';
|
|
|
|
|
|
if (file_exists($logFile)) {
|
|
|
|
|
|
$logContent = file_get_contents($logFile);
|
|
|
|
|
|
// 提取最后几行日志
|
|
|
|
|
|
$lines = explode("\n", $logContent);
|
|
|
|
|
|
$errorDetail = implode("\n", array_slice($lines, -10));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$this->error('参数解密失败,请查看日志: ' . $errorDetail);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证解密结果
|
|
|
|
|
|
if (!is_array($decryptedParams)) {
|
|
|
|
|
|
$this->error('解密参数格式错误');
|
2025-10-17 17:18:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 10:37:59 +08:00
|
|
|
|
Log::info('解密参数成功: ' . json_encode($decryptedParams, JSON_UNESCAPED_UNICODE));
|
2025-10-17 17:18:15 +08:00
|
|
|
|
|
2025-10-20 10:37:59 +08:00
|
|
|
|
// 获取建行用户信息(直接从解密参数中获取)
|
|
|
|
|
|
$ccbUserId = $decryptedParams['userid'] ?? '';
|
|
|
|
|
|
$mobile = $decryptedParams['mobile'] ?? '';
|
2025-10-17 17:18:15 +08:00
|
|
|
|
|
|
|
|
|
|
if (empty($ccbUserId)) {
|
|
|
|
|
|
$this->error('用户信息获取失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理用户登录/注册
|
2025-10-20 11:07:55 +08:00
|
|
|
|
$userInfo = $this->processUserLogin($ccbUserId, $mobile, $decryptedParams);
|
2025-10-17 17:18:15 +08:00
|
|
|
|
|
|
|
|
|
|
// 生成商城Token
|
|
|
|
|
|
$this->auth->direct($userInfo['user_id']);
|
|
|
|
|
|
$token = $this->auth->getToken();
|
|
|
|
|
|
|
|
|
|
|
|
// 构建跳转URL
|
2025-10-20 10:37:59 +08:00
|
|
|
|
$redirectUrl = $decryptedParams['redirect_url'] ?? '/pages/index/index';
|
2025-10-20 14:09:00 +08:00
|
|
|
|
set_token_in_header($this->auth->getToken());
|
2025-10-20 11:07:55 +08:00
|
|
|
|
$this->success(__('Logged in successful'), [
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'token' => $token,
|
|
|
|
|
|
'user_info' => $userInfo,
|
|
|
|
|
|
'redirect_url' => $redirectUrl
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
2025-10-20 11:33:27 +08:00
|
|
|
|
} catch (\think\exception\HttpResponseException $e) {
|
|
|
|
|
|
// HttpResponseException 是框架正常的响应机制,直接向上抛出
|
|
|
|
|
|
throw $e;
|
2025-10-17 17:18:15 +08:00
|
|
|
|
} catch (\Exception $e) {
|
2025-10-20 11:33:27 +08:00
|
|
|
|
// 记录详细错误日志
|
|
|
|
|
|
Log::error('建行生活登录失败: ' . $e->getMessage());
|
|
|
|
|
|
Log::error('错误文件: ' . $e->getFile());
|
|
|
|
|
|
Log::error('错误行号: ' . $e->getLine());
|
|
|
|
|
|
Log::error('错误堆栈: ' . $e->getTraceAsString());
|
|
|
|
|
|
|
|
|
|
|
|
// 返回友好的错误信息(如果异常消息为空,给默认提示)
|
|
|
|
|
|
$errorMsg = $e->getMessage() ?: '登录失败,请稍后重试';
|
|
|
|
|
|
$this->error($errorMsg, [
|
|
|
|
|
|
'error_type' => get_class($e),
|
|
|
|
|
|
'error_file' => basename($e->getFile()),
|
|
|
|
|
|
'error_line' => $e->getLine()
|
|
|
|
|
|
]);
|
2025-10-17 17:18:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 建行用户自动登录(JSBridge方式)
|
|
|
|
|
|
* H5在建行App内打开时,通过JSBridge获取用户信息后调用
|
2025-10-17 16:32:16 +08:00
|
|
|
|
*
|
2025-10-17 17:18:15 +08:00
|
|
|
|
* POST /addons/shopro/ccblife/autoLogin
|
2025-10-17 16:32:16 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public function autoLogin()
|
|
|
|
|
|
{
|
|
|
|
|
|
try {
|
2025-10-17 17:18:15 +08:00
|
|
|
|
// 获取请求参数
|
2025-10-17 16:32:16 +08:00
|
|
|
|
$ccbUserId = $this->request->post('ccb_user_id', '');
|
|
|
|
|
|
$mobile = $this->request->post('mobile', '');
|
|
|
|
|
|
$nickname = $this->request->post('nickname', '');
|
|
|
|
|
|
$avatar = $this->request->post('avatar', '');
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
// 验证必需参数
|
2025-10-17 16:32:16 +08:00
|
|
|
|
if (empty($ccbUserId)) {
|
|
|
|
|
|
$this->error('建行用户ID不能为空');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
// 处理用户登录/注册
|
2025-10-20 11:33:27 +08:00
|
|
|
|
$userInfo = $this->processUserLogin($ccbUserId, $mobile, [
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'nickname' => $nickname,
|
|
|
|
|
|
'avatar' => $avatar
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用Auth系统登录并生成Token
|
|
|
|
|
|
$this->auth->direct($userInfo['user_id']);
|
|
|
|
|
|
$token = $this->auth->getToken();
|
|
|
|
|
|
|
|
|
|
|
|
// 返回结果
|
|
|
|
|
|
$this->success('登录成功', [
|
|
|
|
|
|
'token' => $token,
|
|
|
|
|
|
'user_id' => $userInfo['user_id'],
|
|
|
|
|
|
'is_new_user' => $userInfo['is_new'],
|
|
|
|
|
|
'userInfo' => $userInfo
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
2025-10-20 11:33:27 +08:00
|
|
|
|
} catch (\think\exception\HttpResponseException $e) {
|
|
|
|
|
|
// HttpResponseException 是框架正常的响应机制,直接向上抛出
|
|
|
|
|
|
throw $e;
|
2025-10-17 17:18:15 +08:00
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
|
Log::error('建行自动登录失败: ' . $e->getMessage());
|
2025-10-20 11:33:27 +08:00
|
|
|
|
Log::error('错误堆栈: ' . $e->getTraceAsString());
|
2025-10-17 17:18:15 +08:00
|
|
|
|
$this->error('登录失败: ' . $e->getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理用户登录/注册
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $ccbUserId 建行用户ID
|
|
|
|
|
|
* @param string $mobile 手机号
|
2025-10-20 09:58:32 +08:00
|
|
|
|
* @param array $params 其他参数(包含 Usr_Name 等建行返回的数据)
|
2025-10-17 17:18:15 +08:00
|
|
|
|
* @return array 用户信息
|
|
|
|
|
|
*/
|
2025-10-20 11:07:55 +08:00
|
|
|
|
private function processUserLogin($ccbUserId, $mobile, $params)
|
2025-10-17 17:18:15 +08:00
|
|
|
|
{
|
|
|
|
|
|
Db::startTrans();
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 查询是否已存在建行用户
|
|
|
|
|
|
$user = Db::name('user')->where('ccb_user_id', $ccbUserId)->find();
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
|
|
|
|
|
if ($user) {
|
2025-10-17 17:18:15 +08:00
|
|
|
|
// 用户已存在,更新登录信息
|
|
|
|
|
|
$isNew = false;
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
Db::name('user')->where('id', $user['id'])->update([
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'prevtime' => $user['logintime'] ?? null, // 记录上次登录时间
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'logintime' => time(),
|
|
|
|
|
|
'loginip' => $this->request->ip(),
|
|
|
|
|
|
'updatetime' => time()
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
2025-10-20 09:58:32 +08:00
|
|
|
|
// 重新获取更新后的用户信息
|
|
|
|
|
|
$user = Db::name('user')->where('id', $user['id'])->find();
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// 用户不存在,先尝试通过手机号查找
|
2025-10-20 09:58:32 +08:00
|
|
|
|
if (!empty($mobile)) {
|
2025-10-17 17:18:15 +08:00
|
|
|
|
$user = Db::name('user')->where('mobile', $mobile)->find();
|
|
|
|
|
|
}
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
if ($user) {
|
2025-10-20 09:58:32 +08:00
|
|
|
|
// 手机号已存在,绑定建行用户ID
|
2025-10-17 17:18:15 +08:00
|
|
|
|
$isNew = false;
|
|
|
|
|
|
|
|
|
|
|
|
Db::name('user')->where('id', $user['id'])->update([
|
2025-10-17 16:32:16 +08:00
|
|
|
|
'ccb_user_id' => $ccbUserId,
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'prevtime' => $user['logintime'] ?? null,
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'logintime' => time(),
|
|
|
|
|
|
'loginip' => $this->request->ip(),
|
|
|
|
|
|
'updatetime' => time()
|
|
|
|
|
|
]);
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
2025-10-20 09:58:32 +08:00
|
|
|
|
// 重新获取更新后的用户信息
|
|
|
|
|
|
$user = Db::name('user')->where('id', $user['id'])->find();
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// 创建新用户
|
|
|
|
|
|
$isNew = true;
|
|
|
|
|
|
|
2025-10-20 09:58:32 +08:00
|
|
|
|
// 从建行参数中获取用户名(Usr_Name 或 nickname)
|
|
|
|
|
|
$userName = $params['Usr_Name'] ?? $params['nickname'] ?? '';
|
|
|
|
|
|
if (empty($userName)) {
|
|
|
|
|
|
$userName = '建行用户' . substr($ccbUserId, -4);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 生成盐值
|
|
|
|
|
|
$salt = \fast\Random::alnum();
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
$userData = [
|
2025-10-17 16:32:16 +08:00
|
|
|
|
'ccb_user_id' => $ccbUserId,
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'username' => 'ccb_' . substr(md5($ccbUserId), 0, 10), // 唯一用户名
|
|
|
|
|
|
'nickname' => $userName,
|
|
|
|
|
|
'mobile' => $mobile ?: '',
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'avatar' => $params['avatar'] ?? '/assets/img/avatar.png',
|
|
|
|
|
|
'status' => 'normal',
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'salt' => $salt,
|
|
|
|
|
|
'password' => md5(md5(\fast\Random::alnum(32)) . $salt), // 随机密码
|
|
|
|
|
|
'group_id' => 0, // 默认用户组
|
|
|
|
|
|
'level' => 0, // 默认等级
|
|
|
|
|
|
'gender' => 0, // 未知性别
|
|
|
|
|
|
'money' => 0.00,
|
|
|
|
|
|
'commission' => 0.00,
|
|
|
|
|
|
'score' => 0,
|
|
|
|
|
|
'successions' => 1,
|
|
|
|
|
|
'maxsuccessions' => 1,
|
|
|
|
|
|
'loginfailure' => 0,
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'joinip' => $this->request->ip(),
|
|
|
|
|
|
'jointime' => time(),
|
|
|
|
|
|
'logintime' => time(),
|
|
|
|
|
|
'loginip' => $this->request->ip(),
|
|
|
|
|
|
'createtime' => time(),
|
|
|
|
|
|
'updatetime' => time()
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2025-10-20 11:07:55 +08:00
|
|
|
|
Log::info('创建建行新用户: ' . json_encode([
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'ccb_user_id' => $ccbUserId,
|
|
|
|
|
|
'mobile' => $mobile,
|
|
|
|
|
|
'nickname' => $userName
|
2025-10-20 11:07:55 +08:00
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
2025-10-17 17:18:15 +08:00
|
|
|
|
|
|
|
|
|
|
$userId = Db::name('user')->insertGetId($userData);
|
2025-10-20 09:58:32 +08:00
|
|
|
|
if (!$userId) {
|
|
|
|
|
|
throw new \Exception('创建用户失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
$user = Db::name('user')->where('id', $userId)->find();
|
|
|
|
|
|
}
|
2025-10-17 16:32:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
Db::commit();
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
2025-10-20 11:07:55 +08:00
|
|
|
|
Log::info('建行用户登录处理成功: ' . json_encode([
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'user_id' => $user['id'],
|
|
|
|
|
|
'ccb_user_id' => $ccbUserId,
|
|
|
|
|
|
'is_new' => $isNew
|
2025-10-20 11:07:55 +08:00
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
2025-10-20 09:58:32 +08:00
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
return [
|
|
|
|
|
|
'user_id' => $user['id'],
|
|
|
|
|
|
'nickname' => $user['nickname'],
|
|
|
|
|
|
'avatar' => $user['avatar'],
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'mobile' => $user['mobile'],
|
2025-10-17 17:18:15 +08:00
|
|
|
|
'is_new' => $isNew,
|
|
|
|
|
|
'ccb_user_id' => $ccbUserId
|
|
|
|
|
|
];
|
2025-10-17 16:32:16 +08:00
|
|
|
|
|
2025-10-17 17:18:15 +08:00
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
|
Db::rollback();
|
2025-10-20 11:07:55 +08:00
|
|
|
|
Log::error('建行用户登录处理失败: ' . json_encode([
|
2025-10-20 09:58:32 +08:00
|
|
|
|
'error' => $e->getMessage(),
|
|
|
|
|
|
'ccb_user_id' => $ccbUserId,
|
|
|
|
|
|
'trace' => $e->getTraceAsString()
|
2025-10-20 11:07:55 +08:00
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
2025-10-17 17:18:15 +08:00
|
|
|
|
throw $e;
|
2025-10-17 16:32:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 08:54:02 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 解密建行参数(调试用)
|
|
|
|
|
|
* 用于前端测试页面解密建行传递的加密参数
|
|
|
|
|
|
*
|
|
|
|
|
|
* POST /addons/shopro/ccblife/decryptParam
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function decryptParam()
|
|
|
|
|
|
{
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 获取加密参数
|
|
|
|
|
|
$ccbParamSJ = $this->request->post('ccbParamSJ', '');
|
|
|
|
|
|
|
|
|
|
|
|
if (empty($ccbParamSJ)) {
|
|
|
|
|
|
$this->error('缺少 ccbParamSJ 参数');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 09:23:30 +08:00
|
|
|
|
// 从插件配置文件直接加载(避免config()缓存问题)
|
|
|
|
|
|
$configFile = __DIR__ . '/../config/ccblife.php';
|
|
|
|
|
|
if (!file_exists($configFile)) {
|
|
|
|
|
|
$this->error('建行配置文件不存在');
|
|
|
|
|
|
}
|
2025-10-20 08:54:02 +08:00
|
|
|
|
|
2025-10-20 09:23:30 +08:00
|
|
|
|
$config = include $configFile;
|
2025-10-20 08:54:02 +08:00
|
|
|
|
|
2025-10-20 09:23:30 +08:00
|
|
|
|
// 验证配置
|
|
|
|
|
|
if (empty($config['private_key'])) {
|
|
|
|
|
|
$this->error('配置错误:private_key 为空');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-20 11:07:55 +08:00
|
|
|
|
Log::info('解密建行参数: ' . json_encode([
|
2025-10-20 09:23:30 +08:00
|
|
|
|
'ccbParamSJ_length' => strlen($ccbParamSJ),
|
|
|
|
|
|
'service_id' => $config['service_id'],
|
|
|
|
|
|
'private_key_length' => strlen($config['private_key'])
|
2025-10-20 11:07:55 +08:00
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
2025-10-20 09:23:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 解密参数(使用服务方私钥)
|
|
|
|
|
|
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['private_key']);
|
|
|
|
|
|
|
|
|
|
|
|
if ($decryptedParams === false || empty($decryptedParams)) {
|
|
|
|
|
|
// 检查日志文件获取详细错误
|
|
|
|
|
|
$logFile = RUNTIME_PATH . 'log/' . date('Ymd') . '.log';
|
|
|
|
|
|
$errorDetail = '';
|
|
|
|
|
|
if (file_exists($logFile)) {
|
|
|
|
|
|
$logContent = file_get_contents($logFile);
|
|
|
|
|
|
// 提取最后几行日志
|
|
|
|
|
|
$lines = explode("\n", $logContent);
|
|
|
|
|
|
$errorDetail = implode("\n", array_slice($lines, -10));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$this->error('参数解密失败,请查看日志: ' . $errorDetail);
|
2025-10-20 08:54:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回解密后的数据
|
|
|
|
|
|
$this->success('解密成功', $decryptedParams);
|
|
|
|
|
|
|
2025-10-20 11:33:27 +08:00
|
|
|
|
} catch (\think\exception\HttpResponseException $e) {
|
|
|
|
|
|
// HttpResponseException 是框架正常的响应机制,直接向上抛出
|
|
|
|
|
|
throw $e;
|
2025-10-20 08:54:02 +08:00
|
|
|
|
} catch (\Exception $e) {
|
2025-10-20 11:07:55 +08:00
|
|
|
|
Log::error('建行参数解密失败: ' . json_encode([
|
2025-10-20 09:23:30 +08:00
|
|
|
|
'error' => $e->getMessage(),
|
|
|
|
|
|
'trace' => $e->getTraceAsString()
|
2025-10-20 11:07:55 +08:00
|
|
|
|
], JSON_UNESCAPED_UNICODE));
|
2025-10-20 08:54:02 +08:00
|
|
|
|
$this->error('解密失败: ' . $e->getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-17 16:32:16 +08:00
|
|
|
|
}
|