GiftCardQrCodeService.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. namespace app\common\service;
  3. use app\common\service\storage\Driver;
  4. use app\common\service\ConfigService;
  5. use app\common\service\WeChatConfigService;
  6. use EasyWeChat\Factory;
  7. use think\facade\Log;
  8. /**
  9. * 礼品卡二维码生成服务
  10. */
  11. class GiftCardQrCodeService
  12. {
  13. /**
  14. * @notes 生成礼品卡小程序二维码并上传到七牛云
  15. * @param string $cardNo 礼品卡卡号
  16. * @param string $cardPass 礼品卡密码
  17. * @return string|false 返回二维码文件路径或false
  18. */
  19. public static function generateAndUploadQrCode($cardNo, $cardPass)
  20. {
  21. try {
  22. // 小程序页面路径,根据实际情况修改
  23. $page = 'pages/gift-card/exchange';
  24. $scene = "cardPass={$cardPass}";
  25. // 生成小程序码
  26. $config = WeChatConfigService::getMnpConfig();
  27. $app = Factory::miniProgram($config);
  28. $accessToken = $app->access_token->getToken()['access_token'];
  29. $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken}";
  30. $data = [
  31. 'scene' => $scene,
  32. 'page' => $page,
  33. 'width' => 280,
  34. ];
  35. $ch = curl_init();
  36. curl_setopt($ch, CURLOPT_URL, $url);
  37. curl_setopt($ch, CURLOPT_POST, true);
  38. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  39. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  40. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  41. 'Content-Type: application/json; charset=utf-8'
  42. ]);
  43. // 重要:设置二进制传输模式
  44. curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
  45. $response = curl_exec($ch);
  46. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  47. curl_close($ch);
  48. if ($httpCode === 200) {
  49. // 检查是否为JSON错误响应
  50. $jsonData = json_decode($response, true);
  51. return $jsonData;
  52. if ($jsonData && isset($jsonData['errcode'])) {
  53. Log::error('微信API错误', $jsonData);
  54. return false;
  55. }
  56. // 保存二进制图片数据
  57. $saveDir = 'resource/image/gift_card/qr_code/';
  58. if (!file_exists($saveDir)) {
  59. mkdir($saveDir, 0777, true);
  60. }
  61. $fileName = 'gift_card_' . $cardNo . '_' . time() . '.png';
  62. $localPath = $saveDir . $fileName;
  63. // 直接写入二进制数据
  64. file_put_contents($localPath, $response);
  65. } else {
  66. Log::error('HTTP请求失败', ['code' => $httpCode]);
  67. return false;
  68. }
  69. $IMG = getQrCode($accessToken, $page.$scene, 'uploads/qrcode/', $cardPass);
  70. // $result = $app->app_code->getUnlimited($page = 'pages/index/index', $width = 430);
  71. // try {
  72. // $accessToken = $app->access_token->getToken()['access_token'];
  73. // $url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token={$accessToken}";
  74. //
  75. // $data = [
  76. // 'path' => $page . '?' . $scene,
  77. // 'width' => 280
  78. // ];
  79. //
  80. // // 使用Guzzle HTTP客户端
  81. // $client = new \GuzzleHttp\Client();
  82. // $response = $client->post($url, [
  83. // 'json' => $data,
  84. // 'headers' => [
  85. // 'Content-Type' => 'application/json'
  86. // ]
  87. // ]);
  88. // return $response;
  89. // // 检查响应
  90. // if ($response->getStatusCode() === 200) {
  91. // $body = $response->getBody();
  92. // // 这里$body就是二维码的二进制数据
  93. // } else {
  94. // Log::error('微信API调用失败', ['status' => $response->getStatusCode()]);
  95. // return false;
  96. // }
  97. //
  98. // } catch (\Exception $e2) {
  99. // Log::error('HTTP客户端调用失败', ['error' => $e2->getMessage()]);
  100. // return false;
  101. // }
  102. //
  103. // if (!($response instanceof \EasyWeChat\Kernel\Http\StreamResponse)) {
  104. // Log::error('生成小程序码失败', [
  105. // 'response' => $response,
  106. // 'response_type' => gettype($response),
  107. // 'page' => $page,
  108. // 'scene' => $scene
  109. // ]);
  110. // return false;
  111. // }
  112. // if (!($response instanceof \EasyWeChat\Kernel\Http\StreamResponse)) {
  113. // Log::error('生成小程序码失败', ['response' => $response]);
  114. // return false;
  115. // }
  116. return $IMG;
  117. // 保存到本地临时目录
  118. $saveDir = 'resource/image/gift_card/qr_code/';
  119. if (!file_exists($saveDir)) {
  120. mkdir($saveDir, 0777, true);
  121. }
  122. $fileName = 'gift_card_' . $cardNo . '_' . time() . '.png';
  123. $localPath = $saveDir . $fileName;
  124. // 保存小程序码到本地
  125. $response->saveAs($saveDir, $fileName);
  126. // 上传到七牛云
  127. $uploadPath = self::uploadToQiniu($localPath, 'gift_card/qr_code/' . $fileName);
  128. if ($uploadPath) {
  129. // 删除本地临时文件
  130. if (file_exists($localPath)) {
  131. unlink($localPath);
  132. }
  133. return 'gift_card/qr_code/' . $fileName;
  134. }
  135. return false;
  136. } catch (\Exception $e) {
  137. Log::error('生成礼品卡二维码失败', ['error' => $e->getMessage()]);
  138. return false;
  139. }
  140. }
  141. /**
  142. * @notes 上传文件到七牛云
  143. * @param string $localPath 本地文件路径
  144. * @param string $remotePath 远程文件路径
  145. * @return bool
  146. */
  147. private static function uploadToQiniu($localPath, $remotePath)
  148. {
  149. try {
  150. $config = [
  151. 'default' => ConfigService::get('storage', 'default', 'local'),
  152. 'engine' => ConfigService::get('storage_engine')
  153. ];
  154. if ($config['default'] === 'qiniu') {
  155. $storageDriver = new Driver($config);
  156. return $storageDriver->fetch($localPath, $remotePath);
  157. }
  158. // 如果不是七牛云存储,返回本地路径
  159. return true;
  160. } catch (\Exception $e) {
  161. Log::error('上传到七牛云失败', ['error' => $e->getMessage()]);
  162. return false;
  163. }
  164. }
  165. /**
  166. * @notes 批量生成二维码
  167. * @param array $giftCards 礼品卡数组
  168. * @return array
  169. */
  170. public static function batchGenerateQrCode($giftCards)
  171. {
  172. $result = [
  173. 'success' => 0,
  174. 'failed' => 0,
  175. 'total' => count($giftCards)
  176. ];
  177. foreach ($giftCards as $card) {
  178. $qrCodePath = self::generateAndUploadQrCode($card['card_no'], $card['card_pass']);
  179. if ($qrCodePath) {
  180. // 更新数据库中的二维码路径
  181. \app\common\model\GiftCardInfo::where('id', $card['id'])
  182. ->update(['qr_code_path' => $qrCodePath]);
  183. $result['success']++;
  184. } else {
  185. $result['failed']++;
  186. }
  187. }
  188. return $result;
  189. }
  190. }