UserTaskClass.php 11 KB

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