UserTaskClass.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. namespace tw\async\tasks;
  3. use app\admin\model\system\SystemAttachment;
  4. use app\models\routine\RoutineCode;
  5. use crmeb\services\upload\Upload;
  6. use app\models\routine\RoutineQrcode;
  7. use crmeb\services\UtilService;
  8. use app\models\user\User;
  9. /**
  10. * 和用户相关的异步任务,采用 AsyncClass 的执行方法
  11. */
  12. class UserTaskClass {
  13. const QINIU_PATH = 'user_share_qrcode'; // 海报保存在七牛目录的子路径
  14. /**
  15. * 生成用户分享海报
  16. *
  17. * @param $uid
  18. * @param $postId : 数据库配置的海报背景 ID
  19. * @param $is_promoter
  20. * @return string
  21. */
  22. public static function generate_user_poster_filename($uid, $posterId, $is_promoter=true) : string
  23. {
  24. return $uid . '_' . $is_promoter . '_' . $posterId . '_user_routine_poster.jpg';
  25. }
  26. /**
  27. * 生成用户分享二维码文件名
  28. *
  29. * @param $uid
  30. * @param $is_promoter
  31. * @return string
  32. */
  33. public static function generate_user_share_qrcode_filename($uid, $is_promoter=true) : string
  34. {
  35. return $uid . '_' . $is_promoter . '_user_routine.jpg';
  36. }
  37. /**
  38. * 生成用户海报
  39. *
  40. * @param $user
  41. * @param $siteSsl
  42. * @param $type
  43. * @return array: [bool, str] : 表示是否成功,错误描述
  44. */
  45. public static function generate_user_poster(int $uid, bool $siteSsl=true, int $type=1) : array
  46. {
  47. $rootPath = app()->getRootPath();
  48. try {
  49. $resRoutine = true;//小程序
  50. $resWap = true;//公众号
  51. $siteUrl = sys_config('site_url');
  52. // 配置的海报背景模板
  53. $routineSpreadBanner = sys_data('routine_spread_banner');
  54. if (!count($routineSpreadBanner)) {
  55. $err = '暂无海报';
  56. errlog($err);
  57. return [false, $err];
  58. }
  59. $user = User::getUserInfo($uid);
  60. if (!$user) {
  61. $err = '用户不存在';
  62. errlog($err);
  63. return [false, $err];
  64. }
  65. $is_promoter = $user['is_promoter'] ?? 0;
  66. if (!$is_promoter) {
  67. return [false, '没有推广权限'];
  68. }
  69. if ($type == 1) {
  70. // 直接获取用户海报
  71. foreach ($routineSpreadBanner as &$item) {
  72. $item['namep'] = self::generate_user_poster_filename($user['uid'], $item['id'], $user['is_promoter']);
  73. }
  74. $posters = SystemAttachment::whereIn('name', array_column($routineSpreadBanner, 'namep'))->field('name, att_dir')->select()->toArray();
  75. if (count($posters)) {
  76. foreach ($routineSpreadBanner as $key => &$item) {
  77. foreach ($posters as $poster) {
  78. if ($item['namep'] == $poster['name']) {
  79. $item['poster'] = $poster['att_dir'];
  80. }
  81. }
  82. unset($item['namep']);
  83. if (!isset($item['poster'])) {
  84. unset($routineSpreadBanner[$key]);
  85. }
  86. }
  87. $routineSpreadBanner = array_values($routineSpreadBanner);
  88. if (count($routineSpreadBanner) > 0) {
  89. return [true, $routineSpreadBanner];
  90. }
  91. }
  92. //小程序个人分享二维码文件名
  93. $name = self::generate_user_share_qrcode_filename($user['uid'], $user['is_promoter']);
  94. $imageInfo = SystemAttachment::getInfo($name, 'name');
  95. //检测远程文件是否存在
  96. // 20210722 注释掉,太卡
  97. if (isset($imageInfo['att_dir']) &&
  98. strstr($imageInfo['att_dir'], 'http') !== false &&
  99. curl_file_exist($imageInfo['att_dir']) === false) {
  100. $imageInfo = null;
  101. SystemAttachment::where(['name' => $name])->delete();
  102. }
  103. if (!$imageInfo) { // 数据库中无记录
  104. $res = RoutineCode::getShareCode($user['uid'], 'spread', '', '');
  105. if (!$res) {
  106. return [false, '二维码生成失败'];
  107. }
  108. $uploadType = (int)sys_config('upload_type', UPLOAD_FS);
  109. $upload = new Upload($uploadType, [
  110. 'accessKey' => sys_config('accessKey'),
  111. 'secretKey' => sys_config('secretKey'),
  112. 'uploadUrl' => sys_config('uploadUrl'),
  113. 'storageName' => sys_config('storage_name'),
  114. 'storageRegion' => sys_config('storage_region'),
  115. ]);
  116. // 上传分享二维码 [ qiniu 添加一个子路径]
  117. $remoteName = $uploadType == UPLOAD_QINIU ? self::QINIU_PATH . '/' . $name : $name;
  118. $uploadRes = $upload->to('routine/spread/code')->validate()->stream($res['res'], $remoteName);
  119. if ($uploadRes === false) {
  120. $err = $upload->getError();
  121. errlog("upload error:" . $err);
  122. return [false, $err];
  123. }
  124. $upload->delete($name);
  125. $imageInfo = $upload->getUploadInfo();
  126. // 20210919 为了能小程序下载,这个函数上传的图片全部使用 https
  127. $httpsUrl = set_http_type($imageInfo['dir']);
  128. $imageInfo['image_type'] = $uploadType;
  129. SystemAttachment::attachmentAdd(basename($imageInfo['name']), $imageInfo['size'], $imageInfo['type'], $httpsUrl, $httpsUrl, 1, $imageInfo['image_type'], $imageInfo['time'], 2);
  130. RoutineQrcode::setRoutineQrcodeFind($res['id'], ['status' => 1, 'url_time' => time(), 'qrcode_url' => $imageInfo['dir']]);
  131. $urlCode = $imageInfo['dir'];
  132. } else {
  133. $urlCode = $imageInfo['att_dir'];
  134. }
  135. if ($imageInfo['image_type'] == UPLOAD_FS) {
  136. $urlCode = $siteUrl . $urlCode;
  137. }
  138. $siteUrlHttps = set_http_type($siteUrl, $siteSsl ? 0 : 1);
  139. $filelink = [
  140. 'Bold' => 'public/static' . DS . 'font' . DS . 'Alibaba-PuHuiTi-Regular.otf',
  141. 'Normal' => 'public/static' . DS . 'font' . DS . 'Alibaba-PuHuiTi-Regular.otf',
  142. ];
  143. if (!file_exists($filelink['Bold'])) {
  144. $err = '缺少字体文件Bold';
  145. errlog($err);
  146. return [false, $err];
  147. }
  148. if (!file_exists($filelink['Normal'])) {
  149. $err = '缺少字体文件Normal';
  150. errlog($err);
  151. return [false, $err];
  152. }
  153. foreach ($routineSpreadBanner as $key => &$item) {
  154. $posterInfo = '海报生成失败';
  155. $config = array(
  156. 'image' => array(
  157. array(
  158. 'url' => $urlCode, //二维码资源
  159. 'stream' => 0,
  160. 'left' => 114,
  161. 'top' => 790,
  162. 'right' => 0,
  163. 'bottom' => 0,
  164. 'width' => 120,
  165. 'height' => 120,
  166. 'opacity' => 100
  167. )
  168. ),
  169. 'text' => array(
  170. array(
  171. 'text' => $user['nickname'],
  172. 'left' => 250,
  173. 'top' => 840,
  174. 'fontPath' => $rootPath . $filelink['Bold'], //字体文件
  175. 'fontSize' => 16, //字号
  176. 'fontColor' => '40,40,40', //字体颜色
  177. 'angle' => 0,
  178. ),
  179. array(
  180. 'text' => '邀请您加入' . sys_config('site_name'),
  181. 'left' => 250,
  182. 'top' => 880,
  183. 'fontPath' => $rootPath . $filelink['Normal'], //字体文件
  184. 'fontSize' => 16, //字号
  185. 'fontColor' => '40,40,40', //字体颜色
  186. 'angle' => 0,
  187. )
  188. ),
  189. 'background' => $item['pic'],
  190. 'name' => self::QINIU_PATH . '/' . self::generate_user_poster_filename($user['uid'], $item['id'], $user['is_promoter']),
  191. );
  192. $resRoutine = $resRoutine && $posterInfo = UtilService::setSharePoster($config, 'routine/spread/poster');
  193. if (!is_array($posterInfo)) {
  194. errlog($posterInfo);
  195. return [false, $posterInfo];
  196. }
  197. // 20210919 为了能小程序下载,这个函数上传的图片全部使用 https
  198. $httpsUrl = set_http_type($posterInfo['dir']);
  199. SystemAttachment::attachmentAdd(basename($posterInfo['name']), $posterInfo['size'], $posterInfo['type'], $httpsUrl, $httpsUrl, 1, $posterInfo['image_type'], $posterInfo['time'], 2);
  200. if ($resRoutine) {
  201. if ($posterInfo['image_type'] == UPLOAD_FS)
  202. $item['poster'] = $siteUrlHttps . $posterInfo['dir'];
  203. else
  204. $item['poster'] = set_http_type($posterInfo['dir'], $siteSsl ? 0 : 1);
  205. $item['poster'] = str_replace('\\', '/', $item['poster']);
  206. }
  207. }
  208. } else if ($type == 2) {
  209. errlog(__FUNCTION__ . ' bad parameter type=2');
  210. }
  211. if ($resRoutine && $resWap) {
  212. return [true, $routineSpreadBanner];
  213. } else {
  214. return [false, '生成图片失败'];
  215. }
  216. } catch (\Exception $e) {
  217. errlog('生成图片时,系统错误:' . $e->getMessage());
  218. return [false, '生成图片时,系统错误:' . $e->getMessage()];
  219. }
  220. }
  221. }