manghe/app/common/service/PosterService.php
2025-06-16 22:02:14 +08:00

145 lines
5.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\service;
use app\common\model\UserPosterCache;
use app\common\server\TencentCosUploader;
use app\common\server\Wx;
use app\common\server\autoload;
use think\facade\Log;
class PosterService
{
/**
* 获取或生成用户推广海报
*
* @param int $userId 用户ID
* @param string $platform 平台类型,默认为小程序
* @return array 海报信息 ['status' => bool, 'message' => string, 'data' => ['image_url' => string]]
*/
public function getUserPoster($userId, $platform = null)
{
try {
// 获取平台类型,如果未指定则从请求头获取
if ($platform === null) {
$platform = request()->header('client', '');
if ($platform == "") {
$platform = request()->header('platform', 'MP-WEIXIN');
}
}
// 1. 验证用户ID
if ($userId <= 0) {
return ['status' => false, 'message' => '无效的用户ID'];
}
// 2. 获取系统配置
$config = getConfig('base');
$posterPath = $config['poster_template'] ?? '/img_poster.jpg';
$cacheExpire = $config['poster_cache_expire'] ?? (86400 * 100); // 默认缓存1天
// 3. 获取模板文件信息
$templateFile = getcwd() . $posterPath;
if (!file_exists($templateFile)) {
return ['status' => false, 'message' => '海报模板文件不存在'];
}
$templateHash = md5_file($templateFile);
// 4. 获取小程序配置
// 使用新的MiniprogramHelper获取当前域名对应的小程序配置
$miniprogram = \app\common\helper\MiniprogramHelper::getMiniprogramConfig();
$appId = $miniprogram['appid'] ?? '';
if (empty($appId)) {
$wechat_setting = getConfig("wechat_setting");
$appId = $wechat_setting['appid'] ?? '';
}
// 5. 查询缓存记录
$cacheRecord = UserPosterCache::findValidCache($userId, $templateHash, $appId, $platform);
// 6. 如果存在有效缓存,直接返回
if ($cacheRecord) {
return [
'status' => 1,
'message' => '海报获取成功',
'data' => ['image_url' => $cacheRecord['cos_url']]
];
}
// 7. 生成推广链接或URL根据平台类型
$qrContent = '';
if ($platform === 'MP-WEIXIN') {
// 小程序推广链接
$wxServer = new Wx(app());
$qrContent = $wxServer->generateUrlLinks($userId);
if (empty($qrContent)) {
return ['status' => false, 'message' => '生成推广链接失败'];
}
} else {
// H5推广URL
// $baseUrl = getConfig('base.site_url') ?? 'https://'.request()->host();
$qrContent = 'https://zfunbox.cn?pid=' . $userId;
}
// 8. 生成海报图片
$autoload = new autoload();
$imageData = $autoload->generatePosterWithQR($templateFile, $qrContent);
if (!$imageData) {
return ['status' => false, 'message' => '海报生成失败'];
}
// 9. 上传到腾讯云COS
$cosConfig = getConfig('uploads');
$tencentUploader = new TencentCosUploader($cosConfig);
// 创建文件存储路径
$filePath = 'poster/' . date('Ymd') . '/' . $userId . '_' . $platform . '_' . substr($templateHash, 0, 8) . '_' . uniqid() . '.png';
try {
$uploadResult = $tencentUploader->uploadFile($imageData, $filePath);
$cosUrl = $uploadResult['full_url'];
$fileSize = strlen($imageData);
// 10. 存储缓存记录
$expiresAt = date('Y-m-d H:i:s', time() + $cacheExpire);
$cacheData = [
'user_id' => $userId,
'app_id' => $appId,
'template_hash' => $templateHash,
'cos_url' => $cosUrl,
'file_size' => $fileSize,
'mime_type' => 'image/png',
'status' => 1,
'expires_at' => $expiresAt,
'platform' => $platform
];
// 11. 失效该用户的其他海报缓存
UserPosterCache::invalidateOldCaches($userId, $templateHash, $platform);
// 12. 保存新缓存记录
$posterCache = new UserPosterCache();
$posterCache->save($cacheData);
// 13. 随机清理过期缓存
if (mt_rand(1, 100) <= 5) {
UserPosterCache::cleanExpiredCaches();
}
return [
'status' => true,
'message' => '海报生成成功',
'data' => ['image_url' => $cosUrl]
];
} catch (\Exception $e) {
Log::error('用户海报上传COS失败' . $e->getMessage());
return ['status' => false, 'message' => '海报上传失败'];
}
} catch (\Exception $e) {
Log::error('获取用户海报异常:' . $e->getMessage());
return ['status' => false, 'message' => '系统异常,请稍后重试'];
}
}
}