diff --git a/app/index/controller/WechatController.php b/app/index/controller/WechatController.php
index 7b6c419..d525078 100644
--- a/app/index/controller/WechatController.php
+++ b/app/index/controller/WechatController.php
@@ -5,22 +5,101 @@ use think\facade\Request;
use think\facade\Log;
use think\facade\Cache;
use GuzzleHttp\Client;
-
+use app\index\model\User;
use app\index\model\AdminConfig;
class WechatController extends BaseController
{
+ /**
+ * 测试接口是否正常工作
+ */
+ public function test()
+ {
+ try {
+ // 设置响应头
+ header('Content-Type: application/json; charset=utf-8');
+
+ $data = [
+ 'time' => date('Y-m-d H:i:s'),
+ 'status' => 'ok',
+ 'server' => [
+ 'REQUEST_METHOD' => $_SERVER['REQUEST_METHOD'] ?? '',
+ 'REQUEST_URI' => $_SERVER['REQUEST_URI'] ?? '',
+ 'HTTP_HOST' => $_SERVER['HTTP_HOST'] ?? '',
+ 'REMOTE_ADDR' => $_SERVER['REMOTE_ADDR'] ?? '',
+ ]
+ ];
+
+ // 记录详细日志
+ Log::info('接口测试 - 请求信息:' . json_encode($data, JSON_UNESCAPED_UNICODE));
+
+ return json($data, JSON_UNESCAPED_UNICODE);
+ } catch (\Exception $e) {
+ $error = [
+ 'error' => $e->getMessage(),
+ 'time' => date('Y-m-d H:i:s')
+ ];
+ Log::error('接口测试错误:' . json_encode($error, JSON_UNESCAPED_UNICODE));
+ return json($error, JSON_UNESCAPED_UNICODE);
+ }
+ }
+
public function index()
{
- // 检查请求方法
- if (Request::method() == 'GET') {
- // 首次验证服务器地址的有效性
- $this->checkSignature();
- } elseif (Request::method() == 'POST') {
- // 接收消息并回复
- $response = $this->receiveMessage();
- // 直接输出回复的XML字符串
- echo $response;
+ try {
+ // 设置响应头
+ header('Content-Type: text/html; charset=utf-8');
+
+ // 记录原始请求信息
+ $requestInfo = [
+ 'time' => date('Y-m-d H:i:s'),
+ 'method' => Request::method(),
+ 'url' => Request::url(true),
+ 'ip' => Request::ip(),
+ 'params' => Request::param(),
+ 'headers' => getallheaders(),
+ 'server' => [
+ 'REQUEST_METHOD' => $_SERVER['REQUEST_METHOD'] ?? '',
+ 'REQUEST_URI' => $_SERVER['REQUEST_URI'] ?? '',
+ 'HTTP_HOST' => $_SERVER['HTTP_HOST'] ?? '',
+ 'REMOTE_ADDR' => $_SERVER['REMOTE_ADDR'] ?? '',
+ 'QUERY_STRING' => $_SERVER['QUERY_STRING'] ?? '',
+ 'HTTP_USER_AGENT' => $_SERVER['HTTP_USER_AGENT'] ?? '',
+ 'HTTP_REFERER' => $_SERVER['HTTP_REFERER'] ?? '',
+ ]
+ ];
+
+ Log::info('微信接口访问请求信息:' . json_encode($requestInfo, JSON_UNESCAPED_UNICODE));
+
+ // 获取原始数据
+ $rawData = file_get_contents("php://input");
+ if (!empty($rawData)) {
+ $rawData = mb_convert_encoding($rawData, 'UTF-8', 'UTF-8,GBK,GB2312');
+ Log::info('微信接口原始数据:' . $rawData);
+ }
+
+ // 检查请求方法
+ if (Request::method() == 'GET') {
+ Log::info('微信接口:GET请求,进行签名验证');
+ // 首次验证服务器地址的有效性
+ $this->checkSignature();
+ } elseif (Request::method() == 'POST') {
+ Log::info('微信接口:POST请求,处理消息');
+ // 接收消息并回复
+ $response = $this->receiveMessage();
+ // 直接输出回复的XML字符串
+ echo $response;
+ exit;
+ } else {
+ Log::error('微信接口:不支持的请求方法 - ' . Request::method());
+ echo '';
+ exit;
+ }
+ } catch (\Exception $e) {
+ Log::error('微信接口错误:' . $e->getMessage());
+ Log::error('错误堆栈:' . $e->getTraceAsString());
+ // 返回空字符串,避免微信服务器重试
+ echo '';
exit;
}
}
@@ -28,18 +107,62 @@ class WechatController extends BaseController
// 验证签名
protected function checkSignature()
{
- $signature = Request::get('signature');
- $timestamp = Request::get('timestamp');
- $nonce = Request::get('nonce');
- $echostr = Request::get('echostr');
- $token = AdminConfig::where('config_name', 'wechat_token')->value('config_value');
- $tmpArr = array($token, $timestamp, $nonce);
- sort($tmpArr, SORT_STRING);
- $tmpStr = implode($tmpArr);
- $tmpStr = sha1($tmpStr);
+ try {
+ $signature = Request::get('signature');
+ $timestamp = Request::get('timestamp');
+ $nonce = Request::get('nonce');
+ $echostr = Request::get('echostr');
+
+ $debugInfo = [
+ 'signature' => $signature,
+ 'timestamp' => $timestamp,
+ 'nonce' => $nonce,
+ 'echostr' => $echostr,
+ 'url' => Request::url(true),
+ 'time' => date('Y-m-d H:i:s')
+ ];
+
+ Log::info('微信验证参数:', $debugInfo);
+
+ if (empty($signature) || empty($timestamp) || empty($nonce)) {
+ Log::error('微信验证参数缺失', $debugInfo);
+ exit;
+ }
- if ($tmpStr == $signature) {
- echo $echostr;
+ $token = AdminConfig::where('config_name', 'wechat_token')->value('config_value');
+ if (empty($token)) {
+ Log::error('微信token未配置');
+ exit;
+ }
+
+ Log::info('微信token:' . $token);
+
+ $tmpArr = array($token, $timestamp, $nonce);
+ sort($tmpArr, SORT_STRING);
+ $tmpStr = implode($tmpArr);
+ $tmpStr = sha1($tmpStr);
+
+ $verifyInfo = [
+ 'tmpStr' => $tmpStr,
+ 'signature' => $signature,
+ 'token' => $token,
+ 'timestamp' => $timestamp,
+ 'nonce' => $nonce
+ ];
+
+ Log::info('签名验证:', $verifyInfo);
+
+ if ($tmpStr == $signature) {
+ Log::info('微信签名验证成功');
+ echo $echostr;
+ exit;
+ } else {
+ Log::error('微信签名验证失败', $verifyInfo);
+ exit;
+ }
+ } catch (\Exception $e) {
+ Log::error('微信验证签名错误:' . $e->getMessage());
+ Log::error('错误堆栈:' . $e->getTraceAsString());
exit;
}
}
@@ -47,45 +170,128 @@ class WechatController extends BaseController
// 接收消息
protected function receiveMessage()
{
- $postStr = file_get_contents("php://input");
- if (empty($postStr)) {
- return '';
+ try {
+ $postStr = file_get_contents("php://input");
+ if (empty($postStr)) {
+ Log::error('微信消息:接收数据为空');
+ return '';
+ }
+
+ // 转换编码
+ $postStr = mb_convert_encoding($postStr, 'UTF-8', 'UTF-8,GBK,GB2312');
+ Log::info('微信消息:' . $postStr);
+
+ libxml_disable_entity_loader(true);
+ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
+ if ($postObj === false) {
+ Log::error('微信消息:XML解析失败');
+ return '';
+ }
+
+ // 检查消息类型
+ $msgType = strtolower((string) $postObj->MsgType);
+ Log::info('微信消息类型:' . $msgType);
+
+ // 处理事件消息
+ if ($msgType == 'event') {
+ $event = strtolower((string) $postObj->Event);
+ Log::info('微信事件类型:' . $event);
+
+ // 处理扫码事件和关注事件
+ 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);
+
+ 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
+ ];
+ file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE));
+ Log::info('更新票据文件中的用户信息');
+ }
+ } catch (\Exception $e) {
+ Log::error('获取用户信息失败:' . $e->getMessage());
+ Log::error('错误堆栈:' . $e->getTraceAsString());
+ }
+
+ return 'success';
+ }
+ }
+
+ return 'success';
+ } catch (\Exception $e) {
+ Log::error('处理微信消息错误:' . $e->getMessage());
+ Log::error('错误堆栈:' . $e->getTraceAsString());
+ return 'success';
}
-
- libxml_disable_entity_loader(true);
- $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
- Log::write($postObj);
- // 检查消息类型
- $msgType = strtolower((string) $postObj->MsgType);
- if ($msgType == 'text') {
- // 提取消息内容
- $fromUsername = (string) $postObj->FromUserName; // 微信用户openid
- $toUsername = (string) $postObj->ToUserName; // 公众号id
- $keyword = trim((string) $postObj->Content);
-
- // 构造自动回复的文本消息
- $time = time();
- $textTpl = "
点击使用微信登录
+点击二维码可刷新
+