<?php
namespace app\common\lib\wechat;
use think\Exception;
use think\facade\Cache;
use think\facade\Request;
use think\Image;
use think\facade\Db;
class QrCode extends Basic
{
// 小程序页面路径
private string $path = "pages/myCenter/invite";
// 小程序码保存路径
private string $savePath = "./storage/qrcode/";
// 二维码参数
private string $param = "";
public function __construct(string $path = "", string $field = "", string $param = "", int $width = 430)
{
if (!empty($path) && empty($field)) {
$this->path = $path;
}
if (!empty($path) && !empty($field) && !empty($param)) {
$this->path = "{$path}?{$field}={$param}";
}
$this->param = $param;
}
/**
* 生成小程序码并可选择合并背景图
*
* @param string $backgroundPath 背景图路径
* @param int $qrWidth 二维码在背景图上的宽度位置
* @param int $qrHeight 二维码在背景图上的高度位置
* @return string 生成后的二维码URL
*/
public function setQrcode(string $backgroundPath = '', int $qrWidth = 160, int $qrHeight = 530): string
{
try {
// 获取访问令牌
$accessToken = Cache::get('accesstoken');
if (empty($accessToken)) {
$accessToken = (new AccessToken())->getAccesToken();
Cache::set('accesstoken', $accessToken, 7200); // 假设token有效期为2小时
}
// 请求小程序码
$url = "https://api.weixin.qq.com/wxa/getwxacode?access_token={$accessToken}";
$data = [
'path' => $this->path,
'scene' => 'type=qrcode',
'width' => 430,
];
$result = $this->curlPost($url, $data, 'POST');
if ($result === false || isset($result['errcode'])) {
throw new Exception("Failed to get QR code: " . json_encode($result));
}
// 保存二维码到文件
$fileName = md5($this->param);
$directory = $this->savePath . date('Ymd') . '/';
if (!$this->createDirectory($directory)) {
throw new Exception("目录创建失败: {$directory}");
}
$filePath = "{$directory}{$fileName}.png";
if (!file_put_contents($filePath, $result)) {
throw new Exception("文件写入失败: {$filePath}");
}
// 生成完整URL
$fullDomain = (new \app\common\lib\data\Str())->getFullDomain();
$qrcodeUrl = $fullDomain . ltrim($filePath, '.');
// 合并背景图(如果提供)
if (!empty($backgroundPath)) {
return $this->mergeWithBackground($backgroundPath, $filePath, $qrcodeUrl, $qrWidth, $qrHeight);
}
return $qrcodeUrl;
} catch (Exception $e) {
// 记录错误日志
error_log($e->getMessage());
return '';
}
}
/**
* 将二维码与背景图合并
*/
private function mergeWithBackground(string $backgroundPath, string $qrcodePath, string $defaultUrl, int $qrWidth, int $qrHeight): string
{
try {
$fileName = md5(uniqid() . time());
$newImagePath = $this->savePath . date('Ymd') . "/{$fileName}.png";
$background = Image::open($backgroundPath);
$background->water($qrcodePath, [$qrWidth, $qrHeight])->save($newImagePath);
$imageInfo = [
'url' => Request::domain() . substr($newImagePath, 1),
'size' => filesize($newImagePath),
'name' => $fileName,
'mime' => mime_content_type($newImagePath),
'ext' => 'png',
];
$fileData = [
'f_uuid' => setUUID(),
'f_file' => $imageInfo['url'],
'f_location' => 0,
'f_type' => 'image',
'f_info' => serialize($imageInfo),
'f_user_uuid' => $this->request->index_user_uuid ?? '',
'f_create_time' => time(),
];
Db::name('File')->insert($fileData);
return $imageInfo['url'];
} catch (Exception $e) {
// 记录错误日志
error_log($e->getMessage());
return $defaultUrl;
}
}
/**
* 递归创建目录
*/
private function createDirectory(string $path, int $mode = 0777, bool $recursive = true): bool
{
if (is_dir($path)) {
return true;
}
if (mkdir($path, $mode, $recursive)) {
chmod($path, $mode);
return true;
}
if (!is_dir(dirname($path))) {
if ($this->createDirectory(dirname($path), $mode, $recursive)) {
return $this->createDirectory($path, $mode, $recursive);
}
}
return false;
}
/**
* 发送HTTP POST请求
*/
// public function curlPost($url, $data, $method = "POST")
// {
// $ch = curl_init(); //1.初始化
// curl_setopt($ch, CURLOPT_URL, $url); //2.请求地址
// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);//3.请求方式
// //4.参数如下
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//https
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');//模拟浏览器
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
// curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Encoding: gzip, deflate'));//gzip解压内容
// curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
//
// if ($method == "POST") {//5.post方式的时候添加数据
// $data = json_encode($data);
// curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// }
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// $tmpInfo = curl_exec($ch);//6.执行
//
// if (curl_errno($ch)) {//7.如果出错
// return curl_error($ch);
// }
// curl_close($ch);//8.关闭
// return $tmpInfo;
// }
}
版权属于:
小破孩
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
评论 (0)