diff --git a/app/api/controller/Index.php b/app/api/controller/Index.php index f4791fe..26897c6 100755 --- a/app/api/controller/Index.php +++ b/app/api/controller/Index.php @@ -214,7 +214,7 @@ class Index extends Base /** - * 生成带用户推广二维码的海报图片 + * 生成带用户推广二维码的海报图片(兼容旧版API) * @return \think\response\Json|void */ public function generate_urllinks() @@ -231,123 +231,27 @@ class Index extends Base return $this->renderError('用户不存在'); } - // 获取配置信息 - $config = getConfig('base'); - $posterPath = $config['poster_template'] ?? '/img_poster.jpg'; - $cacheExpire = $config['poster_cache_expire'] ?? 86400; // 默认缓存1天 - - // 创建缓存目录结构(用户ID分组,避免单目录文件过多) - $userGroup = floor($userId / 1000); // 每1000个用户一个目录 - $cacheDir = runtime_path() . 'poster/' . $userGroup . '/'; - if (!is_dir($cacheDir)) { - mkdir($cacheDir, 0755, true); - } - - // 缓存文件名(基于用户ID和模板文件的哈希) - $templateFile = getcwd() . $posterPath; - $templateHash = md5_file($templateFile); // 使用文件内容哈希而不是修改时间 - $cacheFile = $cacheDir . 'user_' . $userId . '_' . $templateHash . '.png'; - - // 清理该用户的旧缓存文件(保留当前有效的) - $this->cleanUserPosterCache($cacheDir, $userId, $templateHash); - - // 定期清理过期缓存(每100次请求执行一次,避免频繁IO) - if (mt_rand(1, 100) === 1) { - $this->cleanExpiredPosterCache($cacheExpire); - } - - // 如果缓存存在且未过期,直接使用缓存 - if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheExpire)) { - $imageData = file_get_contents($cacheFile); - } else { - // 生成URL链接 - $wxServer = new \app\common\server\Wx($this->app); - $user_base = $wxServer->generateUrlLinks($userId); - - // 生成海报 - $autoload = new \app\common\server\autoload(); - $imageData = $autoload->generatePosterWithQR($templateFile, $user_base); - - // 保存到缓存 - if ($imageData) { - file_put_contents($cacheFile, $imageData); - // 更新最后访问时间文件(用于清理判断) - touch($cacheFile); - } - } + // 使用新的PosterService生成海报 + $posterService = new \app\common\service\PosterService(); + $result = $posterService->getUserPoster($userId); // 检查是否需要直接输出图片 - $outputImage = request()->param('output/d', 1); + $outputImage = request()->param('output/d', 0); - if ($imageData && $outputImage) { - header('Content-Type: image/png'); - header('Content-Length: ' . strlen($imageData)); - echo $imageData; - exit(); - } elseif ($imageData) { - // 生成可访问的URL(使用相对路径,更安全且灵活) - $relativePath = 'runtime/poster/' . $userGroup . '/user_' . $userId . '_' . $templateHash . '.png'; - return $this->renderSuccess('海报生成成功', [ - 'image_url' => request()->domain() . '/' . $relativePath - ]); + if ($result['status']) { + if ($outputImage) { + // 重定向到COS上的图片 + header("Location: " . $result['data']['image_url']); + exit(); + } else { + // 返回图片URL + return $this->renderSuccess('海报生成成功', [ + 'image_url' => $result['data']['image_url'] + ]); + } } else { // 生成失败,返回错误信息 - return $this->renderError('海报生成失败'); - } - } - - /** - * 清理指定用户的旧海报缓存 - * @param string $cacheDir 缓存目录 - * @param int $userId 用户ID - * @param string $currentHash 当前模板哈希 - */ - private function cleanUserPosterCache($cacheDir, $userId, $currentHash) - { - // 查找该用户的所有缓存文件 - $pattern = $cacheDir . 'user_' . $userId . '_*.png'; - $files = glob($pattern); - - foreach ($files as $file) { - // 如果不是当前使用的缓存文件,则删除 - if (strpos($file, 'user_' . $userId . '_' . $currentHash . '.png') === false) { - @unlink($file); - } - } - } - - /** - * 清理所有过期的海报缓存 - * @param int $expireTime 过期时间(秒) - */ - private function cleanExpiredPosterCache($expireTime) - { - // 获取缓存根目录 - $rootCacheDir = runtime_path() . 'poster/'; - if (!is_dir($rootCacheDir)) { - return; - } - - // 当前时间 - $now = time(); - - // 遍历所有用户组目录 - $groupDirs = glob($rootCacheDir . '*/'); - foreach ($groupDirs as $groupDir) { - // 获取组目录中的所有PNG文件 - $files = glob($groupDir . '*.png'); - foreach ($files as $file) { - // 如果文件过期(最后修改时间超过过期时间) - if ($now - filemtime($file) > $expireTime) { - @unlink($file); - } - } - - // 如果目录为空,删除目录 - $remainingFiles = glob($groupDir . '*'); - if (empty($remainingFiles)) { - @rmdir($groupDir); - } + return $this->renderError($result['message']); } } diff --git a/app/api/controller/Upload.php b/app/api/controller/Upload.php deleted file mode 100755 index 35155d3..0000000 --- a/app/api/controller/Upload.php +++ /dev/null @@ -1,261 +0,0 @@ -file('file', ''); - if (empty($files)) { - return $this->renderError("请上传图片"); - } - $ext = ['jpg', 'png', 'jpeg', 'JPG', 'PNG', 'JPEG', 'gif', 'apk', 'mp3']; - $type = substr($_FILES['file']['name'], strrpos($_FILES['file']['name'], '.') + 1); - if (!in_array($type, $ext)) { - return $this->renderError("文件格式错误"); - } - if ($_FILES['file']['size'] > 20971520) { - return $this->renderError("上传文件不能超过20M"); - } - #判断是否上传过 - $hash = $files->hash('sha1'); - $info = Db::name('picture')->where('token', $hash)->find(); - if ($info) { - $data['path'] = imageUrl($info['imgurl']); - $data['imgurl'] = $info['imgurl']; - return $this->renderSuccess('上传成功', $data); - } else { - $object_file = 'storage/topic'; - $accessKeyId = ''; - $accessKeySecret = ''; - $endpoint = ''; - $bucket = ''; - // 设置文件名称。 - $object = $object_file . '/' . date('Ymd') . '/' . sha1(date('YmdHis', time()) . uniqid()) . '.' . $type; - // 由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。 - $filePath = $_FILES['file']['tmp_name']; - try { - $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint); - $ossClient->uploadFile($bucket, $object, $filePath); - } catch (OssException $e) { - return $this->renderError("上传失败"); - } - #新增数据 - $object = '/' . $object; - $save_data['token'] = $hash; - $save_data['imgurl'] = $object; - $save_data['addtime'] = time(); - $save_data['status'] = 1; - $res = Db::name('picture')->insertGetId($save_data); - if ($res) { - $data['path'] = imageUrl($object); - $data['imgurl'] = $object; - return $this->renderSuccess('上传成功', $data); - } else { - return $this->renderError('上传失败'); - } - } - } - - public function picture1() - { - #获取表单上传文件 - $files = request()->file('file', ''); - if (empty($files)) { - return $this->renderError("请上传图片"); - } - $ext = ['jpg', 'png', 'jpeg', 'JPG', 'PNG', 'JPEG', 'gif']; - $type = substr($_FILES['file']['name'], strrpos($_FILES['file']['name'], '.') + 1); - if (!in_array($type, $ext)) { - return $this->renderError("文件格式错误"); - } - if ($_FILES['file']['size'] > 5242880) { - return $this->renderError("上传文件不能超过5M"); - } - #判断是否上传过 - $hash = $files->hash('sha1'); - $info = Db::name('picture')->where('token', $hash)->find(); - // if ($info) { - // $data['id'] = $info['id']; - // $data['path'] = imageUrl($info['imgurl']); - // $data['imgurl'] = $info['imgurl']; - // return $this->renderSuccess('上传成功', $data); - // } else { - - // 保存图片 - $date = date('Ymd'); - $uniqueFileName = md5(uniqid(rand(), true)) . '.' . $type; - $saveDir = './storage/topic/' . $date; - if (!is_dir($saveDir)) { - mkdir($saveDir, 0777, true); - } - $savename = $saveDir . '/' . $uniqueFileName; - - // 移动文件到目标目录 - if (move_uploaded_file($_FILES['file']['tmp_name'], $savename)) { - $savename = str_replace('\\', '/', $savename); - $savename = substr($savename, 1); // 去掉开头的 “.” - - // 新增数据 - $save_data['token'] = $hash; - $save_data['imgurl'] = $savename; - $save_data['addtime'] = time(); - $res = Db::name('picture')->insertGetId($save_data); - if ($res) { - $data['id'] = $res; - $data['path'] = imageUrl($savename); - $data['imgurl'] = $savename; - return $this->renderSuccess('上传成功', $data); - } else { - return $this->renderError('上传失败'); - } - } else { - return $this->renderError('文件保存失败'); - } - - // #保存图片 - // $savename = \think\facade\Filesystem::disk('public')->putFile('topic', $files); - // $hash = $files->hash('sha1'); - // $savename = '/storage/' . $savename; - // $savename = str_replace('\\', '/', $savename); - // #新增数据 - // $save_data['token'] = $hash; - // $save_data['imgurl'] = $savename; - // $save_data['addtime'] = time(); - // $res = Db::name('picture')->insertGetId($save_data); - // if ($res) { - // $data['id'] = $res; - // $data['path'] = imageUrl($savename); - // $data['imgurl'] = $savename; - // return $this->renderSuccess('上传成功', $data); - // } else { - // return $this->renderError('上传失败'); - // } - // } - } - /** - * 上传图片 - */ - public function picture_old() - { - // 获取表单上传文件 - $files = request()->file(); - if (empty($files['file'])) { - return $this->renderError("请上传图片"); - } - try { - $ext = ['jpg', 'png', 'jpeg', 'JPG', 'PNG', 'JPEG']; - $type = substr($_FILES['file']['name'], strrpos($_FILES['file']['name'], '.') + 1); - if (!in_array($type, $ext)) { - return $this->renderError("文件格式错误"); - } - $omgpath = $_FILES['file']['tmp_name']; - if ($this->checkMuma($omgpath) == 1) { - return $this->renderError('您上传的文件为可疑木马,请自重!'); - } - validate(['image' => 'filesize:10240|fileExt:jpg|image:200,200,jpg']) - ->check($files); - $file = $files['file']; - $savename = \think\facade\Filesystem::disk('public')->putFile('topic', $file); - $hash = $file->hash('sha1'); - } catch (\think\exception\ValidateException $e) { - return $this->renderError($e->getMessage()); - } - $savename = '/storage/' . $savename; - - $savename = str_replace('\\', '/', $savename); - - $pic = Db::name('picture')->where('token', $hash)->find(); - if ($pic) { - $return['id'] = $pic['id']; - $return['path'] = imageUrl($pic['imgurl']); - $return['imgurl'] = $pic['imgurl']; - unlink('.' . $savename); - return $this->renderSuccess('上传成功', $return); - } - //判断是否开始阿里云存储 - $oss_path = $hash . '.jpg'; - $path = $this->aliyunupload($oss_path, '.' . $savename); - unlink('.' . $savename); - $savename = $path; - - //新增数据 - $save_data['imgurl'] = $savename; - $save_data['token'] = $hash; - $save_data['addtime'] = time(); - $save_data['status'] = 1; - $resultId = Db::name('picture')->insertGetId($save_data); - if ($resultId) { - $return['id'] = $resultId; - $return['path'] = imageUrl($savename); - $return['imgurl'] = $savename; - return $this->renderSuccess('上传成功', $return); - } else { - return $this->renderError('上传失败'); - } - - } - - /** - * 检测文件是否包含木马 - * - * @param $filepath 文件路径 - * @return $status 0为正常 1为可疑木马文件 -1为文件没有上传 - */ - public function checkMuma($filepath) - { - $status = 0; - $tips = array( - "0" => "文件没问题", - "1" => "文件为可疑木马文件", - "-1" => "文件没有上传" - ); - if (file_exists($filepath)) { - $resource = fopen($filepath, 'rb'); - $fileSize = filesize($filepath); - fseek($resource, 0); - if ($fileSize > 512) { // 取头和尾 - $hexCode = bin2hex(fread($resource, 512)); - fseek($resource, $fileSize - 512); - $hexCode .= bin2hex(fread($resource, 512)); - } else { // 取全部 - if ($fileSize > 0) { - $hexCode = bin2hex(fread($resource, $fileSize)); - } else { - return $status = -1; - } - } - fclose($resource); - /* 通过匹配十六进制代码检测是否存在木马脚本*/ - /* 匹配16进制中的 <% ( ) %> */ - /* 匹配16进制中的 */ - /* 匹配16进制中的