UserTaskClass.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. *
  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. Log::error($err);
  58. return [false, $err];
  59. }
  60. $user = User::getUserInfo($uid);
  61. if (!$user) {
  62. $err = '用户不存在';
  63. Log::error($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 (isset($imageInfo['att_dir']) &&
  99. strstr($imageInfo['att_dir'], 'http') !== false &&
  100. curl_file_exist($imageInfo['att_dir']) === false) {
  101. $imageInfo = null;
  102. SystemAttachment::where(['name' => $name])->delete();
  103. }
  104. if (!$imageInfo) { // 数据库中无记录
  105. $res = RoutineCode::getShareCode($user['uid'], 'spread', '', '');
  106. if (!$res) {
  107. return [false, '二维码生成失败'];
  108. }
  109. $uploadType = (int)sys_config('upload_type', UPLOAD_FS);
  110. $upload = new Upload($uploadType, [
  111. 'accessKey' => sys_config('accessKey'),
  112. 'secretKey' => sys_config('secretKey'),
  113. 'uploadUrl' => sys_config('uploadUrl'),
  114. 'storageName' => sys_config('storage_name'),
  115. 'storageRegion' => sys_config('storage_region'),
  116. ]);
  117. // 上传分享二维码 [ qiniu 添加一个子路径]
  118. $remoteName = $uploadType == UPLOAD_QINIU ? self::QINIU_PATH . '/' . $name : $name;
  119. $uploadRes = $upload->to('routine/spread/code')->validate()->stream($res['res'], $remoteName);
  120. if ($uploadRes === false) {
  121. $err = $upload->getError();
  122. Log::error("upload error:" . $err);
  123. return [false, $err];
  124. }
  125. $upload->delete($name);
  126. $imageInfo = $upload->getUploadInfo();
  127. // 20210919 为了能小程序下载,这个函数上传的图片全部使用 https
  128. $httpsUrl = set_http_type($imageInfo['dir']);
  129. $imageInfo['image_type'] = $uploadType;
  130. SystemAttachment::attachmentAdd(basename($imageInfo['name']), $imageInfo['size'], $imageInfo['type'], $httpsUrl, $httpsUrl, 1, $imageInfo['image_type'], $imageInfo['time'], 2);
  131. RoutineQrcode::setRoutineQrcodeFind($res['id'], ['status' => 1, 'url_time' => time(), 'qrcode_url' => $imageInfo['dir']]);
  132. $urlCode = $imageInfo['dir'];
  133. } else {
  134. $urlCode = $imageInfo['att_dir'];
  135. }
  136. if ($imageInfo['image_type'] == UPLOAD_FS) {
  137. $urlCode = $siteUrl . $urlCode;
  138. }
  139. $siteUrlHttps = set_http_type($siteUrl, $siteSsl ? 0 : 1);
  140. $filelink = [
  141. 'Bold' => 'public/static' . DS . 'font' . DS . 'Alibaba-PuHuiTi-Regular.otf',
  142. 'Normal' => 'public/static' . DS . 'font' . DS . 'Alibaba-PuHuiTi-Regular.otf',
  143. ];
  144. if (!file_exists($filelink['Bold'])) {
  145. $err = '缺少字体文件Bold';
  146. Log::error($err);
  147. return [false, $err];
  148. }
  149. if (!file_exists($filelink['Normal'])) {
  150. $err = '缺少字体文件Normal';
  151. Log::error($err);
  152. return [false, $err];
  153. }
  154. foreach ($routineSpreadBanner as $key => &$item) {
  155. $posterInfo = '海报生成失败';
  156. $config = array(
  157. 'image' => array(
  158. array(
  159. 'url' => $urlCode, //二维码资源
  160. 'stream' => 0,
  161. 'left' => 114,
  162. 'top' => 790,
  163. 'right' => 0,
  164. 'bottom' => 0,
  165. 'width' => 120,
  166. 'height' => 120,
  167. 'opacity' => 100
  168. )
  169. ),
  170. 'text' => array(
  171. array(
  172. 'text' => $user['nickname'],
  173. 'left' => 250,
  174. 'top' => 840,
  175. 'fontPath' => $rootPath . $filelink['Bold'], //字体文件
  176. 'fontSize' => 16, //字号
  177. 'fontColor' => '40,40,40', //字体颜色
  178. 'angle' => 0,
  179. ),
  180. array(
  181. 'text' => '邀请您加入' . sys_config('site_name'),
  182. 'left' => 250,
  183. 'top' => 880,
  184. 'fontPath' => $rootPath . $filelink['Normal'], //字体文件
  185. 'fontSize' => 16, //字号
  186. 'fontColor' => '40,40,40', //字体颜色
  187. 'angle' => 0,
  188. )
  189. ),
  190. 'background' => $item['pic'],
  191. 'name' => self::QINIU_PATH . '/' . self::generate_user_poster_filename($user['uid'], $item['id'], $user['is_promoter']),
  192. );
  193. $resRoutine = $resRoutine && $posterInfo = UtilService::setSharePoster($config, 'routine/spread/poster');
  194. if (!is_array($posterInfo)) {
  195. Log::error($posterInfo);
  196. return [false, $posterInfo];
  197. }
  198. // 20210919 为了能小程序下载,这个函数上传的图片全部使用 https
  199. $httpsUrl = set_http_type($posterInfo['dir']);
  200. SystemAttachment::attachmentAdd(basename($posterInfo['name']), $posterInfo['size'], $posterInfo['type'], $httpsUrl, $httpsUrl, 1, $posterInfo['image_type'], $posterInfo['time'], 2);
  201. if ($resRoutine) {
  202. if ($posterInfo['image_type'] == UPLOAD_FS)
  203. $item['poster'] = $siteUrlHttps . $posterInfo['dir'];
  204. else
  205. $item['poster'] = set_http_type($posterInfo['dir'], $siteSsl ? 0 : 1);
  206. $item['poster'] = str_replace('\\', '/', $item['poster']);
  207. }
  208. }
  209. } else if ($type == 2) {
  210. Log::error(__FUNCTION__ . ' bad parameter type=2');
  211. }
  212. if ($resRoutine && $resWap) {
  213. return [true, $routineSpreadBanner];
  214. } else {
  215. return [false, '生成图片失败'];
  216. }
  217. } catch (\Exception $e) {
  218. Log::error('生成图片时,系统错误:' . $e->getMessage());
  219. return [false, '生成图片时,系统错误:' . $e->getMessage()];
  220. }
  221. }
  222. }