UserTaskClass.php 11 KB

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