ChangeQRCode.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace app\admin\command;
  3. use app\common\library\Redis;
  4. use app\common\library\WeChatObject;
  5. use Symfony\Component\Cache\Simple\RedisCache;
  6. use think\Config;
  7. use think\console\Command;
  8. use think\console\Input;
  9. use think\console\input\Option;
  10. use think\console\Output;
  11. use EasyWeChat\Factory;
  12. use think\Log;
  13. use think\Request;
  14. class ChangeQRCode extends Command{
  15. /**
  16. * @var array $imgSize 图片规格
  17. */
  18. private $imgSize = [
  19. 1 => [
  20. 'size' => 143, //二维码宽度
  21. 'x' => 376, //水印x
  22. 'y' => 35 //水印y
  23. ],
  24. 2 => [
  25. 'size' => 147, //二维码宽度
  26. 'x' => 374, //水印x
  27. 'y' => 33 //水印y
  28. ],
  29. 3 => [
  30. 'size' => 135, //二维码宽度
  31. 'x' => 372, //水印x
  32. 'y' => 46 //水印y
  33. ],
  34. 4 => [
  35. 'size' => 179, //二维码宽度
  36. 'x' => 356, //水印x
  37. 'y' => 15 //水印y
  38. ],
  39. 5 => [
  40. 'size' => 179, //二维码宽度
  41. 'x' => 356, //水印x
  42. 'y' => 15 //水印y
  43. ],
  44. 6 => [
  45. 'size' => 179, //二维码宽度
  46. 'x' => 356, //水印x
  47. 'y' => 15 //水印y
  48. ]
  49. ];
  50. protected function configure()
  51. {
  52. $this
  53. ->setName('changeQRCode')
  54. ->addOption('type', 't', Option::VALUE_OPTIONAL, '处理自定义二维码错误问题', 'modify')
  55. ->setDescription('处理自定义二维码错误问题');
  56. }
  57. protected function execute(Input $input, Output $output)
  58. {
  59. Request::instance()->module('admin'); //cli模式下无法获取到当前的项目模块,手动指定一下
  60. $type = $input->getOption('type');
  61. switch ($type) {
  62. case 'modify':
  63. $this->modify($input, $output);
  64. break;
  65. default:
  66. $output->writeln("Type: {$type} 无法识别的类型");
  67. }
  68. }
  69. /**
  70. * @param Input $input
  71. * @param Output $output
  72. */
  73. private function modify(Input $input, Output $output){
  74. $output->info("开始处理自定义二维码错误问题.");
  75. try{
  76. if(!$source = model('CustomQrcode')->where(['type'=>'2'])->select()){
  77. $output->info('没有要处理的自定义二维码错误数据');
  78. }
  79. foreach($source as $key => $val){
  80. //处理合成图片
  81. if(strpos($val['url'], 'mp.weixin.qq.com') === false){
  82. $tmp = explode('_',basename($val['url'],".png"));
  83. $template_id = $tmp[2];
  84. if(!$adminConfig = model('AdminConfig')->where(['admin_id'=>$val['admin_id']])->find()){
  85. $output->error(sprintf('未处理 Channel_id:%d CustomQRCode_id:%d 渠道配置信息获取失败',$val['admin_id'],$val['id']));
  86. continue;
  87. }
  88. if(empty($adminConfig['appid']) || empty($adminConfig['json']) ){
  89. $output->error(sprintf('未处理 Channel_id:%d CustomQRCode_id:%d 渠道微信没有授权',$val['admin_id'],$val['id']));
  90. continue;
  91. }
  92. //获取微信永久二维码
  93. $adminConfig = model('AdminConfig')->getAdminInfoAll($val['admin_id']);
  94. $wechat = new WeChatObject($adminConfig);
  95. $officialAccount = $wechat->getOfficialAccount();
  96. $result = $officialAccount->qrcode->forever($val['index']);
  97. if(empty($result) || isset($result['errcode'])){
  98. $output->error(sprintf('未处理 Channel_id:%d CustomQRCode_id:%d 获取微信二维码失败',$val['admin_id'],$val['id']));
  99. continue;
  100. }
  101. $wx_url = $officialAccount->qrcode->url($result['ticket']);
  102. $image_1 = imagecreatefrompng(ROOT_PATH . "public/assets/img/essay/qrcode_{$template_id}.png"); //底图
  103. $image_2 = $this->createThumbnail($wx_url,$this->imgSize[$template_id]['size'],$this->imgSize[$template_id]['size']);
  104. imagecopymerge($image_1, $image_2, $this->imgSize[$template_id]['x'], $this->imgSize[$template_id]['y'], 0, 0, imagesx($image_2),
  105. imagesy($image_2), 100);
  106. $imgPath = ROOT_PATH . 'public/uploads/qrcode/'; //图片保存路径
  107. if (!file_exists($imgPath)) { //创建文件夹
  108. mkdir($imgPath, 0700, true);
  109. clearstatcache();
  110. }
  111. $imgPath = $imgPath .$val['book_id'].'_'.$val['chapter_id'] .'_' . $template_id .'_'.$val['admin_id'].'_'.time().'.png';
  112. $data['url'] = cdnurl("/uploads/qrcode/" . $val['book_id'] .'_'.$val['chapter_id'] . '_' . $template_id .'_'.$val['admin_id'].'_'.time().'.png');
  113. if(!imagepng($image_1, $imgPath)){
  114. $output->error(sprintf('未处理 Channel_id:%d CustomQRCode_id:%d 拼接图片失败',$val['admin_id'],$val['id']));
  115. continue;
  116. }
  117. imagedestroy($image_1);
  118. imagedestroy($image_2);
  119. if(false !== model('CustomQrcode')->where(['id'=>$val['id']])->update($data)){
  120. $output->info(sprintf('已处理 Channel_id:%d CustomQRCode_id:%d ImagePath:%s',$val['admin_id'],$val['id'],$imgPath));
  121. }else{
  122. $output->info(sprintf('未处理 Channel_id:%d CustomQRCode_id:%d 更新数据失败 ImagePath:%s',$val['admin_id'],$val['id'],$imgPath));
  123. }
  124. }
  125. }
  126. }catch (\Exception $e){
  127. $output->error('处理自定义二维码出错,Error:'.$e->getMessage());
  128. }
  129. }
  130. /**
  131. * 生成保持原图纵横比的缩略图,支持.png .jpg .gif
  132. * 缩略图类型统一为.png格式
  133. * $srcFile 原图像文件名称
  134. * $toW 缩略图宽
  135. * $toH 缩略图高
  136. * @return bool
  137. */
  138. private function createThumbnail($srcFile, $toW, $toH)
  139. {
  140. $toW += 20;
  141. $toH += 20;
  142. $info = "";
  143. //返回含有4个单元的数组,0-宽,1-高,2-图像类型,3-宽高的文本描述。
  144. //失败返回false并产生警告。
  145. $data = getimagesize($srcFile, $info);
  146. if (!$data)
  147. return false;
  148. //将文件载入到资源变量im中
  149. switch ($data[2]) //1-GIF,2-JPG,3-PNG
  150. {
  151. case 1:
  152. if(!function_exists("imagecreatefromgif"))
  153. {
  154. echo "the GD can't support .gif, please use .jpeg or .png! <a href='javascript:history.back();'>back</a>";
  155. exit();
  156. }
  157. $im = imagecreatefromgif($srcFile);
  158. break;
  159. case 2:
  160. if(!function_exists("imagecreatefromjpeg"))
  161. {
  162. echo "the GD can't support .jpeg, please use other picture! <a href='javascript:history.back();'>back</a>";
  163. exit();
  164. }
  165. $im = imagecreatefromjpeg($srcFile);
  166. break;
  167. case 3:
  168. $im = imagecreatefrompng($srcFile);
  169. break;
  170. }
  171. //计算缩略图的宽高
  172. $srcW = imagesx($im);
  173. $srcH = imagesy($im);
  174. $toWH = $toW / $toH;
  175. $srcWH = $srcW / $srcH;
  176. if ($toWH <= $srcWH)
  177. {
  178. $ftoW = $toW;
  179. $ftoH = (int)($ftoW * ($srcH / $srcW));
  180. }
  181. else
  182. {
  183. $ftoH = $toH;
  184. $ftoW = (int)($ftoH * ($srcW / $srcH));
  185. }
  186. if (function_exists("imagecreatetruecolor"))
  187. {
  188. $ni = imagecreatetruecolor($ftoW, $ftoH); //新建一个真彩色图像
  189. if ($ni)
  190. {
  191. //重采样拷贝部分图像并调整大小 可保持较好的清晰度
  192. imagecopyresampled($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
  193. }
  194. else
  195. {
  196. //拷贝部分图像并调整大小
  197. $ni = imagecreate($ftoW, $ftoH);
  198. imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
  199. }
  200. }
  201. else
  202. {
  203. $ni = imagecreate($ftoW, $ftoH);
  204. imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
  205. }
  206. ImageDestroy($im);
  207. return $ni;
  208. }
  209. }