提交代码
This commit is contained in:
parent
7b4e41efc4
commit
25b765517a
@ -56,6 +56,8 @@ class WechatController extends BaseController
|
||||
'method' => Request::method(),
|
||||
'url' => Request::url(true),
|
||||
'ip' => Request::ip(),
|
||||
'real_ip' => Request::server('HTTP_X_REAL_IP'),
|
||||
'forwarded_ip' => Request::server('HTTP_X_FORWARDED_FOR'),
|
||||
'params' => Request::param(),
|
||||
'headers' => getallheaders(),
|
||||
'server' => [
|
||||
@ -66,6 +68,17 @@ class WechatController extends BaseController
|
||||
'QUERY_STRING' => $_SERVER['QUERY_STRING'] ?? '',
|
||||
'HTTP_USER_AGENT' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
||||
'HTTP_REFERER' => $_SERVER['HTTP_REFERER'] ?? '',
|
||||
'CONTENT_TYPE' => $_SERVER['CONTENT_TYPE'] ?? '',
|
||||
'CONTENT_LENGTH' => $_SERVER['CONTENT_LENGTH'] ?? '',
|
||||
'SERVER_NAME' => $_SERVER['SERVER_NAME'] ?? '',
|
||||
'SERVER_ADDR' => $_SERVER['SERVER_ADDR'] ?? '',
|
||||
'SERVER_PORT' => $_SERVER['SERVER_PORT'] ?? '',
|
||||
'REQUEST_SCHEME' => $_SERVER['REQUEST_SCHEME'] ?? '',
|
||||
],
|
||||
'env' => [
|
||||
'app_debug' => config('app.debug'),
|
||||
'app_env' => config('app.env'),
|
||||
'domain' => config('app.domain'),
|
||||
]
|
||||
];
|
||||
|
||||
@ -119,10 +132,12 @@ class WechatController extends BaseController
|
||||
'nonce' => $nonce,
|
||||
'echostr' => $echostr,
|
||||
'url' => Request::url(true),
|
||||
'time' => date('Y-m-d H:i:s')
|
||||
'time' => date('Y-m-d H:i:s'),
|
||||
'ip' => Request::ip(),
|
||||
'headers' => getallheaders()
|
||||
];
|
||||
|
||||
Log::info('微信验证参数:', $debugInfo);
|
||||
Log::info('微信验证参数:' . json_encode($debugInfo, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
if (empty($signature) || empty($timestamp) || empty($nonce)) {
|
||||
Log::error('微信验证参数缺失', $debugInfo);
|
||||
@ -150,7 +165,7 @@ class WechatController extends BaseController
|
||||
'nonce' => $nonce
|
||||
];
|
||||
|
||||
Log::info('签名验证:', $verifyInfo);
|
||||
Log::info('签名验证:' . json_encode($verifyInfo, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
if ($tmpStr == $signature) {
|
||||
Log::info('微信签名验证成功');
|
||||
@ -179,7 +194,7 @@ class WechatController extends BaseController
|
||||
|
||||
// 转换编码
|
||||
$postStr = mb_convert_encoding($postStr, 'UTF-8', 'UTF-8,GBK,GB2312');
|
||||
Log::info('微信消息:' . $postStr);
|
||||
Log::info('微信消息原始数据:' . $postStr);
|
||||
|
||||
libxml_disable_entity_loader(true);
|
||||
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
@ -199,90 +214,122 @@ class WechatController extends BaseController
|
||||
|
||||
// 处理扫码事件和关注事件
|
||||
if ($event == 'scan' || $event == 'subscribe') {
|
||||
$scene_str = trim((string) $postObj->EventKey);
|
||||
// 如果是关注事件,需要去掉前缀 'qrscene_'
|
||||
if ($event == 'subscribe' && strpos($scene_str, 'qrscene_') === 0) {
|
||||
$scene_str = substr($scene_str, 8);
|
||||
}
|
||||
|
||||
$fromUsername = trim((string) $postObj->FromUserName);
|
||||
$toUsername = trim((string) $postObj->ToUserName);
|
||||
$ticket = (string) $postObj->Ticket;
|
||||
|
||||
Log::info('微信扫码/关注事件', [
|
||||
'event' => $event,
|
||||
'scene_str' => $scene_str,
|
||||
'fromUsername' => $fromUsername,
|
||||
'toUsername' => $toUsername,
|
||||
'ticket' => $ticket,
|
||||
'time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
// 创建票据保存目录
|
||||
$upload_dir = 'public/storage/uploads/ticket/';
|
||||
if (!is_dir($upload_dir)) {
|
||||
mkdir($upload_dir, 0755, true);
|
||||
Log::info('创建票据保存目录:' . $upload_dir);
|
||||
}
|
||||
|
||||
// 保存扫码数据
|
||||
$data = [
|
||||
'openid' => $fromUsername,
|
||||
'scene_str' => $scene_str,
|
||||
'ticket' => $ticket,
|
||||
'scan_time' => time(),
|
||||
'event' => $event
|
||||
];
|
||||
|
||||
$content = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
$file = $upload_dir . $scene_str . "_" . $ticket . ".json";
|
||||
file_put_contents($file, $content);
|
||||
Log::info('保存扫码数据到文件:' . $file);
|
||||
|
||||
// 获取用户信息
|
||||
try {
|
||||
$accessToken = $this->getGZHAccessToken();
|
||||
$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$accessToken}&openid={$fromUsername}&lang=zh_CN";
|
||||
$client = new Client(['verify' => false]);
|
||||
$response = $client->get($url);
|
||||
$userInfo = json_decode($response->getBody(), true);
|
||||
$scene_str = trim((string) $postObj->EventKey);
|
||||
// 如果是关注事件,需要去掉前缀 'qrscene_'
|
||||
if ($event == 'subscribe' && strpos($scene_str, 'qrscene_') === 0) {
|
||||
$scene_str = substr($scene_str, 8);
|
||||
}
|
||||
|
||||
Log::info('获取用户信息结果:' . json_encode($userInfo, JSON_UNESCAPED_UNICODE));
|
||||
$fromUsername = trim((string) $postObj->FromUserName);
|
||||
$toUsername = trim((string) $postObj->ToUserName);
|
||||
$ticket = (string) $postObj->Ticket;
|
||||
|
||||
if (isset($userInfo['openid'])) {
|
||||
// 保存用户信息到数据库
|
||||
$user = User::where('openid', $fromUsername)->find();
|
||||
if (!$user) {
|
||||
$user = new User;
|
||||
$user->openid = $fromUsername;
|
||||
$user->name = $userInfo['nickname'] ?? '';
|
||||
$user->avatar = $userInfo['headimgurl'] ?? '';
|
||||
$user->save();
|
||||
Log::info('创建新用户', ['user' => $user->toArray()]);
|
||||
} else {
|
||||
// 更新用户信息
|
||||
$user->name = $userInfo['nickname'] ?? $user->name;
|
||||
$user->avatar = $userInfo['headimgurl'] ?? $user->avatar;
|
||||
$user->save();
|
||||
Log::info('更新用户信息', ['user' => $user->toArray()]);
|
||||
Log::info('微信扫码/关注事件详情', [
|
||||
'event' => $event,
|
||||
'scene_str' => $scene_str,
|
||||
'fromUsername' => $fromUsername,
|
||||
'toUsername' => $toUsername,
|
||||
'ticket' => $ticket,
|
||||
'time' => date('Y-m-d H:i:s'),
|
||||
'raw_data' => $postStr
|
||||
]);
|
||||
|
||||
// 创建票据保存目录
|
||||
$upload_dir = 'public/storage/uploads/ticket/';
|
||||
if (!is_dir($upload_dir)) {
|
||||
if (!mkdir($upload_dir, 0755, true)) {
|
||||
Log::error('创建票据保存目录失败:' . $upload_dir);
|
||||
return 'success';
|
||||
}
|
||||
Log::info('创建票据保存目录成功:' . $upload_dir);
|
||||
}
|
||||
|
||||
// 更新票据文件中的用户信息
|
||||
$data['user_info'] = [
|
||||
'uid' => $user->uid,
|
||||
'name' => $user->name,
|
||||
'avatar' => $user->avatar,
|
||||
'openid' => $user->openid
|
||||
];
|
||||
file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
Log::info('更新票据文件中的用户信息');
|
||||
// 保存扫码数据
|
||||
$data = [
|
||||
'openid' => $fromUsername,
|
||||
'scene_str' => $scene_str,
|
||||
'ticket' => $ticket,
|
||||
'scan_time' => time(),
|
||||
'event' => $event,
|
||||
'raw_data' => $postStr
|
||||
];
|
||||
|
||||
$content = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
$file = $upload_dir . $scene_str . "_" . $ticket . ".json";
|
||||
|
||||
if (file_put_contents($file, $content) === false) {
|
||||
Log::error('保存扫码数据失败:' . $file);
|
||||
return 'success';
|
||||
}
|
||||
Log::info('保存扫码数据成功:' . $file);
|
||||
|
||||
// 获取用户信息
|
||||
try {
|
||||
$accessToken = $this->getGZHAccessToken();
|
||||
Log::info('获取access_token成功:' . $accessToken);
|
||||
|
||||
$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$accessToken}&openid={$fromUsername}&lang=zh_CN";
|
||||
$client = new Client(['verify' => false]);
|
||||
$response = $client->get($url);
|
||||
$userInfo = json_decode($response->getBody(), true);
|
||||
|
||||
Log::info('获取用户信息结果:' . json_encode($userInfo, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
if (isset($userInfo['openid'])) {
|
||||
// 保存用户信息到数据库
|
||||
$user = User::where('openid', $fromUsername)->find();
|
||||
if (!$user) {
|
||||
$user = new User;
|
||||
$user->openid = $fromUsername;
|
||||
$user->name = $userInfo['nickname'] ?? '';
|
||||
$user->avatar = $userInfo['headimgurl'] ?? '';
|
||||
$user->save();
|
||||
Log::info('创建新用户成功', ['user' => $user->toArray()]);
|
||||
} else {
|
||||
// 更新用户信息
|
||||
$user->name = $userInfo['nickname'] ?? $user->name;
|
||||
$user->avatar = $userInfo['headimgurl'] ?? $user->avatar;
|
||||
$user->save();
|
||||
Log::info('更新用户信息成功', ['user' => $user->toArray()]);
|
||||
}
|
||||
|
||||
// 更新票据文件
|
||||
$data['user_info'] = [
|
||||
'uid' => $user->uid,
|
||||
'name' => $user->name,
|
||||
'avatar' => $user->avatar,
|
||||
'openid' => $user->openid
|
||||
];
|
||||
$data['login_status'] = 'success';
|
||||
|
||||
if (file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE)) === false) {
|
||||
Log::error('更新票据文件失败:' . $file);
|
||||
} else {
|
||||
Log::info('更新票据文件成功');
|
||||
}
|
||||
|
||||
// 设置登录session
|
||||
session('user_id', $user->uid);
|
||||
session('user_info', $data['user_info']);
|
||||
session('openid', $user->openid);
|
||||
|
||||
Log::info('用户登录成功', [
|
||||
'uid' => $user->uid,
|
||||
'name' => $user->name,
|
||||
'openid' => $user->openid
|
||||
]);
|
||||
} else {
|
||||
Log::error('获取用户信息失败:' . json_encode($userInfo, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取用户信息失败:' . $e->getMessage());
|
||||
Log::error('错误堆栈:' . $e->getTraceAsString());
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取用户信息失败:' . $e->getMessage());
|
||||
Log::error('处理扫码事件失败:' . $e->getMessage());
|
||||
Log::error('错误堆栈:' . $e->getTraceAsString());
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,56 +582,56 @@ class WechatController extends BaseController
|
||||
$scene_str = Request::post('scene_str');
|
||||
$ticket = Request::post('ticket');
|
||||
|
||||
Log::info('检查登录状态', [
|
||||
'scene_str' => $scene_str,
|
||||
'ticket' => $ticket,
|
||||
'time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
if (empty($scene_str) || empty($ticket)) {
|
||||
Log::warning('检查登录状态参数错误', [
|
||||
'scene_str' => $scene_str,
|
||||
'ticket' => $ticket
|
||||
]);
|
||||
return json(['code' => 0, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 检查票据文件
|
||||
$file = 'public/storage/uploads/ticket/' . $scene_str . "_" . $ticket . ".json";
|
||||
Log::info('检查票据文件:' . $file);
|
||||
|
||||
if (file_exists($file)) {
|
||||
$loginData = json_decode(file_get_contents($file), true);
|
||||
Log::info('票据文件内容:' . json_encode($loginData, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
if ($loginData) {
|
||||
// 检查是否包含用户信息
|
||||
if (isset($loginData['user_info'])) {
|
||||
Log::info('用户已扫码登录', [
|
||||
'user_info' => $loginData['user_info']
|
||||
]);
|
||||
|
||||
// 设置登录session
|
||||
session('user_id', $loginData['user_info']['uid']);
|
||||
session('user_info', $loginData['user_info']);
|
||||
session('openid', $loginData['user_info']['openid']);
|
||||
|
||||
// 删除临时文件
|
||||
unlink($file);
|
||||
|
||||
return json(['code' => 1, 'msg' => '登录成功']);
|
||||
} else {
|
||||
Log::info('等待获取用户信息');
|
||||
return json(['code' => 0, 'msg' => '正在获取用户信息,请稍候...']);
|
||||
}
|
||||
}
|
||||
if (!file_exists($file)) {
|
||||
return json(['code' => 0, 'msg' => '等待扫码']);
|
||||
}
|
||||
|
||||
Log::info('等待扫码');
|
||||
return json(['code' => 0, 'msg' => '等待扫码']);
|
||||
$loginData = json_decode(file_get_contents($file), true);
|
||||
if (!$loginData) {
|
||||
return json(['code' => 0, 'msg' => '等待扫码']);
|
||||
}
|
||||
|
||||
// 检查是否已经扫码
|
||||
if (!isset($loginData['openid'])) {
|
||||
return json(['code' => 0, 'msg' => '等待扫码']);
|
||||
}
|
||||
|
||||
// 检查是否已经获取用户信息
|
||||
if (!isset($loginData['user_info'])) {
|
||||
return json(['code' => 0, 'msg' => '正在获取用户信息,请稍候...']);
|
||||
}
|
||||
|
||||
// 检查登录状态
|
||||
if (!isset($loginData['login_status']) || $loginData['login_status'] !== 'success') {
|
||||
return json(['code' => 0, 'msg' => '正在处理登录,请稍候...']);
|
||||
}
|
||||
|
||||
// 登录成功,设置session
|
||||
session('user_id', $loginData['user_info']['uid']);
|
||||
session('user_info', $loginData['user_info']);
|
||||
session('openid', $loginData['user_info']['openid']);
|
||||
|
||||
// 删除临时文件
|
||||
@unlink($file);
|
||||
|
||||
// 返回用户信息
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '登录成功',
|
||||
'data' => [
|
||||
'user_info' => $loginData['user_info']
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('检查登录状态失败:' . $e->getMessage());
|
||||
Log::error('错误堆栈:' . $e->getTraceAsString());
|
||||
return json(['code' => 0, 'msg' => '系统错误']);
|
||||
}
|
||||
}
|
||||
@ -622,6 +669,8 @@ class WechatController extends BaseController
|
||||
'method' => Request::method(),
|
||||
'url' => Request::url(true),
|
||||
'ip' => Request::ip(),
|
||||
'real_ip' => Request::server('HTTP_X_REAL_IP'),
|
||||
'forwarded_ip' => Request::server('HTTP_X_FORWARDED_FOR'),
|
||||
'params' => Request::param(),
|
||||
'headers' => getallheaders(),
|
||||
'server' => [
|
||||
@ -632,6 +681,12 @@ class WechatController extends BaseController
|
||||
'QUERY_STRING' => $_SERVER['QUERY_STRING'] ?? '',
|
||||
'HTTP_USER_AGENT' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
||||
'HTTP_REFERER' => $_SERVER['HTTP_REFERER'] ?? '',
|
||||
'CONTENT_TYPE' => $_SERVER['CONTENT_TYPE'] ?? '',
|
||||
'CONTENT_LENGTH' => $_SERVER['CONTENT_LENGTH'] ?? '',
|
||||
'SERVER_NAME' => $_SERVER['SERVER_NAME'] ?? '',
|
||||
'SERVER_ADDR' => $_SERVER['SERVER_ADDR'] ?? '',
|
||||
'SERVER_PORT' => $_SERVER['SERVER_PORT'] ?? '',
|
||||
'REQUEST_SCHEME' => $_SERVER['REQUEST_SCHEME'] ?? '',
|
||||
]
|
||||
];
|
||||
|
||||
@ -651,12 +706,17 @@ class WechatController extends BaseController
|
||||
$nonce = Request::get('nonce');
|
||||
$echostr = Request::get('echostr');
|
||||
|
||||
Log::info('微信测试接口验证参数:', [
|
||||
$verifyInfo = [
|
||||
'signature' => $signature,
|
||||
'timestamp' => $timestamp,
|
||||
'nonce' => $nonce,
|
||||
'echostr' => $echostr
|
||||
]);
|
||||
'echostr' => $echostr,
|
||||
'time' => date('Y-m-d H:i:s'),
|
||||
'ip' => Request::ip(),
|
||||
'headers' => getallheaders()
|
||||
];
|
||||
|
||||
Log::info('微信测试接口验证参数:' . json_encode($verifyInfo, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
if (!empty($signature) && !empty($timestamp) && !empty($nonce)) {
|
||||
$token = AdminConfig::where('config_name', 'wechat_token')->value('config_value');
|
||||
|
||||
@ -57,12 +57,16 @@ class VisitStatsService
|
||||
// 执行所有命令
|
||||
$result = $pipe->exec();
|
||||
|
||||
// 更新数据库统计
|
||||
$this->updateDailyStats($date, [
|
||||
'total_visits' => $result[0],
|
||||
'daily_visits' => $result[1],
|
||||
'unique_visitors' => $this->getUniqueVisitors($date)
|
||||
]);
|
||||
// 使用Redis锁控制更新频率,每5分钟更新一次数据库
|
||||
$lockKey = $this->prefix.'update_lock:'.$date;
|
||||
if (!$this->redis->exists($lockKey)) {
|
||||
$this->redis->setex($lockKey, 300, 1); // 5分钟锁
|
||||
$this->updateDailyStats($date, [
|
||||
'total_visits' => $result[0],
|
||||
'daily_visits' => $result[1],
|
||||
'unique_visitors' => $this->getUniqueVisitors($date)
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => $result[0],
|
||||
@ -91,7 +95,7 @@ class VisitStatsService
|
||||
try {
|
||||
// 获取其他统计数据
|
||||
$otherStats = [
|
||||
'total_users' => Db::name('users')->count(), // 移除 delete_time 条件
|
||||
'total_users' => Db::name('users')->count(),
|
||||
'new_users' => Db::name('users')->whereDay('create_time', $date)->count(),
|
||||
'total_articles' => Db::name('articles')->where('delete_time', null)->count(),
|
||||
'daily_articles' => Db::name('articles')->whereDay('create_time', $date)->count(),
|
||||
@ -101,8 +105,10 @@ class VisitStatsService
|
||||
'resource_downloads' => Db::name('resources')->whereDay('update_time', $date)->sum('downloads')
|
||||
];
|
||||
|
||||
// 记录日志,方便调试
|
||||
Log::info('统计数据:' . json_encode($otherStats, JSON_UNESCAPED_UNICODE));
|
||||
// 只在调试模式下记录日志
|
||||
if (config('app.debug')) {
|
||||
Log::info('统计数据:' . json_encode($otherStats, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
// 合并统计数据
|
||||
$stats = array_merge($stats, $otherStats);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user