微信二维码接口

master
lion 4 months ago
parent 96d2a3d6f8
commit 06e734ec44

@ -439,49 +439,82 @@ class CourseController extends BaseController
$generate = !empty($all['generate']); $generate = !empty($all['generate']);
$path = config('filesystems.disks.public.root') . '/course_qrcode/' . $courseId . '.png'; $path = config('filesystems.disks.public.root') . '/course_qrcode/' . $courseId . '.png';
$url = config('filesystems.disks.public.url') . '/course_qrcode/' . $courseId . '.png'; $url = config('filesystems.disks.public.url') . '/course_qrcode/' . $courseId . '.png';
$debugFile = storage_path('logs/qrcode_debug.log');
$debug = function ($msg) use ($debugFile, $courseId) {
@file_put_contents(
$debugFile,
date('Y-m-d H:i:s') . " [{$courseId}] {$msg}\n",
FILE_APPEND
);
};
$debug('hit generate=' . ($generate ? '1' : '0') . ' sapi=' . PHP_SAPI);
// 已有文件直接返回,避免走微信/旧 OPcache 方法签名问题 // 已有文件直接返回
clearstatcache(true, $path); clearstatcache(true, $path);
if (is_file($path)) { if (is_file($path)) {
$debug('return existing file');
return $this->success($url); return $this->success($url);
} }
if (!$generate) { if (!$generate) {
$debug('no file and generate=0');
return $this->success(''); return $this->success('');
} }
try { try {
$courseModel = new Course(); // 生成逻辑内联在控制器,避免模型 OPcache/签名不一致
// 兼容 FPM OPcache 未刷新时旧方法只有 1 个参数(PHP8 多传参会直接 500) $appId = (string) config('app.applet_appid');
$ref = new \ReflectionMethod($courseModel, 'getCourseQrcode'); $secret = (string) config('app.applet_secret');
if ($ref->getNumberOfParameters() >= 2) { if ($appId === '' || $secret === '') {
$result = $courseModel->getCourseQrcode($courseId, true); $debug('missing appid/secret');
} else { return $this->fail([ResponseCode::ERROR_BUSINESS, '二维码生成失败:未配置小程序 APPID/SECRET']);
$result = $courseModel->getCourseQrcode($courseId);
} }
clearstatcache(true, $path);
if (empty($result) && is_file($path)) { $debug('request wechat app_code');
$result = $url; $app = Factory::miniProgram([
'app_id' => $appId,
'secret' => $secret,
]);
$tmp = $app->app_code->get('packages/course/detail?id=' . $courseId, [
'env_version' => 'release',
]);
$content = $tmp instanceof \EasyWeChat\Kernel\Http\StreamResponse
? $tmp->getBodyContents()
: (string) $tmp;
$debug('wechat bytes=' . strlen($content));
if ($content === '' || strpos(ltrim($content), '{') === 0) {
$debug('invalid wechat body=' . substr($content, 0, 200));
return $this->fail([ResponseCode::ERROR_BUSINESS, '二维码生成失败:微信接口返回异常']);
} }
if (empty($result)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '二维码生成失败,请检查微信配置或缓存后重试']); $dir = dirname($path);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
} }
return $this->success($result); if (file_put_contents($path, $content) === false) {
$debug('write file failed');
return $this->fail([ResponseCode::ERROR_BUSINESS, '二维码生成失败:写入文件失败']);
}
@chmod($path, 0644);
$debug('saved ok');
return $this->success($url);
} catch (\Throwable $e) { } catch (\Throwable $e) {
\Log::error('courses/qrcode failed', [ $safeMsg = preg_replace('/[^\x09\x0A\x0D\x20-\x7E\x{4e00}-\x{9fff}]/u', '?', $e->getMessage());
'id' => $courseId, $debug('exception: ' . $safeMsg);
'generate' => $generate, try {
'message' => $e->getMessage(), \Log::error('courses/qrcode failed', [
'file' => $e->getFile(), 'id' => $courseId,
'line' => $e->getLine(), 'message' => $safeMsg,
]); ]);
// 生成过程异常时,若磁盘已有文件仍返回成功 } catch (\Throwable $ignored) {
}
clearstatcache(true, $path); clearstatcache(true, $path);
if (is_file($path)) { if (is_file($path)) {
return $this->success($url); return $this->success($url);
} }
return $this->fail([ return $this->fail([
ResponseCode::ERROR_BUSINESS, ResponseCode::ERROR_BUSINESS,
'二维码生成失败: ' . $e->getMessage(), '二维码生成失败: ' . ($safeMsg ?: '未知错误'),
]); ]);
} }
} }

Loading…
Cancel
Save