123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152 |
- <?php
- namespace App\Service;
- use App\Libs\getid3\Duration;
- use App\Log;
- use App\Models\AuthorizeCorp;
- use App\Models\MassMsg;
- use App\Models\MassMsgLinkRecord;
- use App\Models\Material;
- use App\Models\PlatformPlayletGroup;
- use App\Models\PlatformPlayletGroupDetail;
- use App\Models\RadarCustomerDetail;
- use App\Support\EmailQueue;
- use Illuminate\Support\Facades\Storage;
- class MaterialService
- {
- /**
- * 上传素材
- * */
- public static function uploadMaterial($corpid, $type, $file, $needMediaId, $uploadToOss, &$data)
- {
- try{
- $mediaId = '';
- $expireTime = '';
- if (empty($file) || !$file->isValid()) {
- return 2311;
- }
- $originalExtension = strtolower($file->getClientOriginalExtension()); //文件扩展名
- if(!$originalExtension) $originalExtension = $file->guessExtension();
- $realPath = $file->getRealPath(); //临时文件的绝对路径
- $mimeType = $file->getClientMimeType(); // image/jpeg
- $fileSize = $file->getClientSize();
- switch ($type) {
- case 1: // 图片
- if (!in_array($originalExtension, ['jpg', 'png'])) {
- Log::logError('上传的图片类型为:', ['type' => $originalExtension, 'info' => $file->guessExtension() ], 'uploadMaterial');
- return 2301;
- }
- if($fileSize > 10 * 1024 * 1024) {
- return 2306;
- }
- if($fileSize > 2 * 1024 * 1024) {
- $uploadToOss = 1;
- }
- list($width, $height, $imageType, $attr) = getimagesize($realPath);
- if($width * $height > 1555200) {
- return 2312;
- }
- break;
- case 2: // 语音
- if (!in_array($originalExtension, ['amr'])) {
- return 2302;
- }
- if($fileSize > 2 * 1024 * 1024) {
- return 2307;
- }
- break;
- case 3: // 视频
- if (!in_array($originalExtension, ['mp4'])) {
- return 2303;
- }
- # 视频文件大小限制
- if($fileSize > 20 * 1024 * 1024) {
- return 2308;
- }
- break;
- case 4:
- # 文件大小限制20M
- if($fileSize > 20 * 1024 * 1024) {
- return 2318;
- }
- break;
- }
- // 上传文件
- $filename = date('YmdHis') . '-' . uniqid() . '.' . $originalExtension;
- // 使用我们新建的uploads本地存储空间(目录)
- $result = Storage::disk('uploads')->put($filename, file_get_contents($realPath));
- if(!$result)
- return 2304;
- $localFilePath = '../storage/uploads/'.$filename;
- if(!$uploadToOss && $type==1) { // 上传到腾讯
- $fileUrl = MaterialService::uploadImg($corpid, $realPath);
- } else {
- $oss = new OssService('playlet');
- $ossFile = $oss->upload($originalExtension, $localFilePath, $mimeType.'/'.date("Y-m-d",time()));
- $fileUrl = $ossFile['oss-request-url'];
- }
- // if($needMediaId) { // 需要获取素材mediaId
- // $mediaData = MaterialService::uploadMedia($corpid, $localFilePath, $type);
- // if(isset($mediaData['errcode']) && $mediaData['errcode']) {
- // EmailQueue::rPush('获取素材mediaId失败', json_encode($mediaData, JSON_UNESCAPED_UNICODE), ['xiaohua.hou@kuxuan-inc.com'], '获取素材mediaId失败');
- // Log::logError('素材上传失败', $mediaData, 'UploadMaterial');
- // return 2309;
- // }
- //
- // $mediaId = isset($mediaData['media_id']) ? $mediaData['media_id'] : '';
- // $expireTime = time();
- // if(!empty($mediaId))
- // $expireTime = date('Y-m-d H:i:s', $mediaData['created_at'] + 86400 * 3 - 200);
- // }
- // @unlink($localFilePath);
- // 保存数据到素材表
- $materialId = Material::insertGetId([
- 'corpid' => $corpid,
- 'type' => $type,
- 'local_path' => $localFilePath,
- 'oss_url' => $fileUrl,
- 'media_id' => $mediaId,
- 'expire_at' => $expireTime
- ]);
- if(!$materialId) return 2310;
- $data = array_filter([
- 'material_id' => $materialId,
- 'url' => $fileUrl,
- 'media_id' => $mediaId
- ]);
- } catch (\Exception $e) {
- EmailQueue::rPush('素材上传过程发生异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '素材上传过程发生异常');
- Log::logError('素材上传过程发生异常', [
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage()
- ], 'UploadMaterial-Exception');
- return 2305;
- }
- return 0;
- }
- /**
- * 上传朋友圈素材
- * */
- public static function uploadAttachment($corpid, $localFilePath, $type, $attachmentType, $retry=0)
- {
- # 获取AccessToken
- $accessToken = AuthorizeCorp::getAccessToken($corpid, '上传临时素材');
- if(empty($accessToken)) {
- return false;
- }
- $requestUri = config('qyWechat.upload_attachment');
- switch ($type) {
- case 1: // 图片
- $requestUri .= $accessToken . '&media_type=image&attachment_type='.$attachmentType;
- break;
- case 2: // 普通文件
- $requestUri .= $accessToken . '&media_type=file&attachment_type='.$attachmentType;
- break;
- case 3: // 视频
- $requestUri .= $accessToken . '&media_type=video&attachment_type='.$attachmentType;
- break;
- }
- $response = HttpService::httpUpload($requestUri, $localFilePath);
- Log::logError('请求的URL:'.$requestUri, [
- 'path' => $localFilePath,
- 'response' => $response,
- 'retry' => $retry
- ], 'HttpUploadAttachment');
- $responseData = json_decode($response, true);
- $errCode = $responseData['errcode'] ?? -1;
- if(($response===false || $errCode != 0) && $retry<5) { // 发起重试
- $retry++;
- Log::logInfo('上传朋友圈素材发起重试', [
- 'corpid' => $corpid,
- 'path' => $localFilePath,
- 'retry' => $retry
- ], 'HttpUploadAttachment');
- return MaterialService::uploadAttachment($corpid, $localFilePath, $type, $attachmentType, $retry);
- }
- if($response===false) { // 发起重试
- return false;
- }
- return $responseData;
- }
- /**
- * 上传临时素材
- * */
- public static function uploadMedia($corpid, $localFilePath, $type, $retry=0)
- {
- # 获取AccessToken
- $accessToken = AuthorizeCorp::getAccessToken($corpid, '上传临时素材');
- if(empty($accessToken)) {
- return false;
- }
- $requestUri = config('qyWechat.upload_media');
- switch ($type) {
- case 1: // 图片
- $requestUri .= $accessToken . '&type=image';
- break;
- case 2: // 语音
- $requestUri .= $accessToken . '&type=voice';
- break;
- case 3: // 视频
- $requestUri .= $accessToken . '&type=video';
- break;
- case 4: // 文件
- $requestUri .= $accessToken . '&type=file';
- break;
- }
- $response = HttpService::httpUpload($requestUri, $localFilePath);
- Log::logError('请求的URL:'.$requestUri, [
- 'corpid' => $corpid,
- 'path' => $localFilePath,
- 'response' => $response,
- 'retry' => $retry
- ], 'HttpUploadMedia');
- $responseData = json_decode($response, true);
- $errCode = $responseData['errcode'] ?? -1;
- if(($response===false || $errCode != 0) && $retry<5) { // 发起重试
- $retry++;
- Log::logInfo('上传临时素材发起重试', [
- 'corpid' => $corpid,
- 'path' => $localFilePath,
- 'retry' => $retry
- ], 'HttpUploadMedia');
- return MaterialService::uploadMedia($corpid, $localFilePath, $type, $retry);
- }
- return $responseData;
- }
- /**
- * 处理附件中的素材ID
- * */
- public static function mediaIdReplace($attachments, $corpid, $prefix = 'WelcomeCodeSendTrace')
- {
- if(empty($attachments)) return [];
- foreach ($attachments as $key=>&$attachment) {
- # 处理附件信息中的素材id
- if(isset($attachment['image']['media_id'])) { // 非小程序类的附件
- $materialId = $attachment['image']['media_id'];
- $mediaId = MaterialService::getMediaId($materialId, $corpid);
- if($mediaId===false) {
- Log::logInfo('【图片类】捕获到临时素材ID异常', [
- 'attachment' => $attachments,
- 'corpid' => $corpid,
- 'media_id' => $materialId
- ], $prefix);
- unset($attachments[$key]);
- continue;
- }
- $attachment['image']['media_id'] = $mediaId;
- } elseif(isset($attachment['miniprogram']['pic_media_id'])) {
- $materialId = $attachment['miniprogram']['pic_media_id'];
- $mediaId = MaterialService::getMediaId($materialId, $corpid);
- if($mediaId===false) {
- Log::logInfo('【小程序】捕获到临时素材ID异常', [
- 'attachment' => $attachments,
- 'corpid' => $corpid,
- 'media_id' => $materialId
- ], $prefix);
- unset($attachments[$key]);
- continue;
- }
- $attachment['miniprogram']['pic_media_id'] = $mediaId;
- }
- }
- Log::logInfo('处理附件中的素材ID:', [
- 'corpid' => $corpid,
- 'attachments' => $attachments
- ], $prefix);
- return $attachments;
- }
- /**
- * 处理附件中的素材ID
- * */
- public static function chatGroupWelcomeTemplateMediaIdReplace($attachments, $corpid, $prefix = 'WelcomeCodeSendTrace')
- {
- if(empty($attachments)) return [];
- foreach ($attachments as $key=>&$attachment) {
- # 处理附件信息中的素材id
- if(isset($attachments['image']['media_id'])) { // 非小程序类的附件
- $materialId = $attachments['image']['media_id'];
- $mediaId = MaterialService::getMediaId($materialId, $corpid);
- if($mediaId===false) {
- Log::logInfo('【图片类】捕获到临时素材ID异常', [
- 'attachment' => $attachments,
- 'corpid' => $corpid,
- 'media_id' => $materialId
- ], $prefix);
- unset($attachments[$key]);
- continue;
- }
- $attachments['image']['media_id'] = $mediaId;
- } elseif(isset($attachments['miniprogram']['pic_media_id'])) {
- $materialId = $attachments['miniprogram']['pic_media_id'];
- $mediaId = MaterialService::getMediaId($materialId, $corpid);
- if($mediaId===false) {
- Log::logInfo('【小程序】捕获到临时素材ID异常', [
- 'attachment' => $attachments,
- 'corpid' => $corpid,
- 'media_id' => $materialId
- ], $prefix);
- unset($attachments[$key]);
- continue;
- }
- $attachments['miniprogram']['pic_media_id'] = $mediaId;
- } elseif(isset($attachments['file']['media_id'])){
- $materialId = $attachments['file']['media_id'];
- $mediaId = MaterialService::getMediaId($materialId, $corpid, false, 4);
- if($mediaId===false) {
- Log::logInfo('【文件类】捕获到临时素材ID异常', [
- 'attachment' => $attachments,
- 'corpid' => $corpid,
- 'media_id' => $materialId
- ], $prefix);
- unset($attachments[$key]);
- continue;
- }
- $attachments['file']['media_id'] = $mediaId;
- } elseif (isset($attachments['video']['media_id'])) { // 非小程序类的附件
- $materialId = $attachments['video']['media_id'];
- $mediaId = MaterialService::getMediaId($materialId, $corpid, false, 3);
- if($mediaId===false) {
- Log::logInfo('【视频类】捕获到临时素材ID异常', [
- 'attachment' => $attachments,
- 'corpid' => $corpid,
- 'media_id' => $materialId
- ], $prefix);
- unset($attachments[$key]);
- continue;
- }
- $attachments['video']['media_id'] = $mediaId;
- }
- }
- Log::logInfo('处理附件中的素材ID:', [
- 'corpid' => $corpid,
- 'attachments' => $attachments
- ], $prefix);
- return $attachments;
- }
- /**
- * 处理附件中的雷达和推广链接信息
- * @param array $attachments 附件信息
- * @param string $corpid 企业id
- * @param string $userId 客服id
- * @param int $channel 渠道标识 1:朋友圈 2:群发消息 3:欢迎语 4:渠道活码
- * @param int $ruleId 对应渠道的规则id。用于个人时可设置为0
- * @param int $msgSendType 消息类型 0未知 1群发消息 2欢迎语
- * @param string $state 授权链接中可携带的参数
- * @return mixed
- * */
- public static function radarAttachment($attachments, $corpid, $userId, $channel, $ruleId, $msgSendType=0, $isAttachment=false, $state='STATE')
- {
- try {
- if(empty($attachments)) return [];
- foreach ($attachments as $key=>&$attachment) {
- # 检验是否存在雷达类附件
- $msgType = $attachment['msgtype'] ?? '';
- if(empty($msgType)) {
- unset($attachments[$key]);
- continue;
- }
- if($msgType == 'radar') {
- Log::logInfo('检测到待处理的雷达附件', [
- 'corpid' => $corpid,
- 'rule_id' => $ruleId,
- 'channel' => $channel,
- 'attachment' => $attachment
- ], 'radarAttachmentDealTrace');
- $attachment['msgtype'] = 'link';
- $radarId = $attachment['radar']['radar_id'] ?? 0;
- # 拼装雷达消息内容
- $linkData = RadarService::getLinkMsgOfRadar($radarId, $corpid, $userId, $channel, $ruleId, $state);
- Log::logInfo('雷达消息转链接消息的结果为:', [
- 'corpid' => $corpid,
- 'rule_id' => $ruleId,
- 'channel' => $channel,
- 'link_data' => $linkData
- ], 'radarAttachmentDealTrace');
- if(empty($linkData)) {
- Log::logInfo('未获取到雷达信息', [
- 'attachment' => $attachments,
- 'corpid' => $corpid
- ], 'RadarAttachmentDealTrace');
- unset($attachments[$key]);
- continue;
- }
- if($isAttachment) {
- $linkData['media_id'] = $attachment['radar']['media_id'];
- }
- $attachment['link'] = $linkData;
- unset($attachment['radar']);
- Log::logInfo('最终替换完成的雷达转链接消息体为:', [
- 'corpid' => $corpid,
- 'rule_id' => $ruleId,
- 'channel' => $channel,
- 'attachment' => $attachment
- ], 'radarAttachmentDealTrace');
- } elseif ($msgType == 'promote') {
- Log::logInfo('检测到待处理的推广链接', [
- 'corpid' => $corpid,
- 'rule_id' => $ruleId,
- 'channel' => $channel,
- 'attachment' => $attachment
- ], 'PromoteAttachmentDealTrace');
- $attachment['msgtype'] = 'link';
- # 获取推广链接
- $jumpUrl = $attachment['promote']['jump_url'] ?? '';
- if(empty($jumpUrl)) {
- Log::logInfo('未查询到推广链接信息', [
- 'attachment' => $attachments,
- 'corpid' => $corpid
- ], 'PromoteAttachmentDealTrace');
- unset($attachments[$key]);
- continue;
- }
- # 判断是否是剧集组推广链接。通过剧集组id、发送类型send_type确认
- $playletGroupId = getUrlParams($jumpUrl, 'group_id');
- $sendType = getUrlParams($jumpUrl, 'send_type');
- Log::logInfo('剧集组id相关信息', [
- 'group_id' => $playletGroupId,
- 'send_type' => $sendType,
- 'msg_send_type' => $msgSendType
- ], 'PromoteAttachmentDealTrace');
- # 如果有就获取对应的剧集推广链接进行存储
- if($playletGroupId && $sendType && $sendType==6 && $msgSendType) { // 剧集组对应剧生成推广链接
- $jumpUrl .='&sender='.$userId.'&rule_id='.$ruleId.'&msg_type='.$msgSendType;
- Log::logInfo('跳转链接更新为:', [
- 'jump_url' => $jumpUrl,
- ], 'PromoteAttachmentDealTrace');
- $hasRecord = false;
- if($msgSendType == 2) { // 欢迎语消息类型,优先判断是否已有短剧记录信息
- $hasRecord = MassMsgLinkRecord::where('corpid', $corpid)->where('sender', $userId)
- ->where('rule_id', $ruleId)->where('msg_type', $msgSendType)
- ->where('enable', 1)->exists();
- }
- if(!$hasRecord) {
- # 查询剧集组对应创建者信息
- $groupInfo = PlatformPlayletGroup::where('id', $playletGroupId)->where('enable', 1)->first();
- # 查询剧集组对应的剧信息
- $playletList = PlatformPlayletGroupDetail::where('group_id', $playletGroupId)->where('enable', 1)->get();
- $pidList = [];
- foreach ($playletList as $playlet) {
- $errno = 0;
- $playletData = PlatformService::createLink(
- $playlet, $playlet['platform_id'], $playlet['account_id'], $groupInfo->sys_group_id,
- $groupInfo->admin_id, $errno
- );
- if(empty($playletData) || $errno) {
- Log::logInfo('生成链接失败:', [
- 'jump_url' => $jumpUrl,
- 'errno' => $errno,
- 'playlet_data' => $playletData,
- 'group_id' => $playletGroupId
- ], 'PromoteAttachmentDealTrace');
- EmailQueue::rPush('群发消息生成推广链接失败', $playletGroupId.'-'.$errno.'-'.$ruleId, ['xiaohua.hou@kuxuan-inc.com'], '群发消息生成推广链接失败');
- continue;
- }
- array_push($pidList, $playletData['pid']);
- # 记录对应推广信息
- $recordResult = MassMsgLinkRecord::saveRecord(
- $corpid, $userId, $ruleId, $msgSendType, $playletGroupId, $playlet['playlet_id'],
- $playlet['platform_id'], $playlet['link_type'], $playlet['sort_order'], $playletData['path'],
- $playletData['desc'], $playletData['cover'], $playletData['pid']
- );
- if(!$recordResult) {
- Log::logError('剧集组推广信息记录失败:', [
- 'corpid' => $corpid,
- 'rule_id' => $ruleId,
- 'user_id' => $userId,
- 'playlet' => $playlet,
- 'link_data' => $playletData
- ], 'PlayletLinkRecordSave');
- }
- }
- if($msgSendType == 1) { // 更新群发消息的pid字段
- MassMsg::where('id', $ruleId)->update(['is_draw' => 1, 'pids' => json_encode(array_filter($pidList))]);
- }
- }
- }
- # 处理推广链接
- $link = MassMsgService::getPromoteLink($corpid, $jumpUrl);
- $linkData = $attachment['promote'];
- $linkData['url'] = $link;
- $attachment['link'] = $linkData;
- unset($attachment['promote']);
- Log::logInfo('最终替换完成的推广链接消息体为:', [
- 'corpid' => $corpid,
- 'rule_id' => $ruleId,
- 'channel' => $channel,
- 'attachment' => $attachment
- ], 'PromoteAttachmentDealTrace');
- }
- }
- } catch (\Exception $e) {
- Log::logError('处理附件中的雷达信息', [
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage(),
- 'attachments' => $attachments,
- 'is_attachment' => $isAttachment
- ], 'RadarAttachmentDeal-Exception');
- return [];
- }
- return $attachments;
- }
- public static function promoteAttachments($corpid, $attachments, $prefix = 'addWelcomeTemplate') {
- if (empty($attachments)) return [];
- try{
- if(isset($attachments['promote'])) {
- $attachment = $attachments['promote'];
- Log::logInfo('检测到待处理的推广链接', [
- 'attachment' => $attachment
- ], $prefix.'Trace');
- # 获取推广链接
- $jumpUrl = $attachment['url'] ?? '';
- if (empty($jumpUrl)) {
- Log::logInfo('未查询到推广链接信息', [
- 'attachment' => $attachments,
- ], $prefix.'Trace');
- unset($attachments['promote']);
- }
- # 处理推广链接
- $link = MassMsgService::getPromoteLink($corpid, $jumpUrl);
- $attachment['url'] = $link;
- $attachments['link'] = $attachment;
- unset($attachments['promote']);
- Log::logInfo('最终替换完成的推广链接消息体为:', [
- 'corpid' => $corpid,
- 'attachment' => $attachments
- ], $prefix.'Trace');
- }
- } catch (\Exception $exception) {
- Log::logError('处理附件中的雷达信息', [
- 'line' => $exception->getLine(),
- 'msg' => $exception->getMessage(),
- 'attachments' => $attachments,
- ], $prefix.'-Exception');
- return [];
- }
- return $attachments;
- }
- /**
- * 处理附件中的素材ID(新)
- * */
- public static function mediaIdDeal($attachments, $corpid)
- {
- if(empty($attachments)) return [];
- foreach ($attachments as $key=>&$attachment) {
- $msgType = $attachment['msgtype'] ?? '';
- switch($msgType) {
- case 'image':
- $type = 1;
- $attachmentType = 1;
- $materialId = $attachment['image']['media_id'];
- break;
- case 'video':
- $type = 3;
- $attachmentType = 1;
- $materialId = $attachment['video']['media_id'];
- break;
- case 'link':
- $type = 1;
- $attachmentType = 1;
- $materialId = $attachment['link']['media_id'];
- break;
- case 'radar':
- $type = 1;
- $attachmentType = 1;
- $radarId = $attachment['radar']['radar_id'];
- $materialId = RadarCustomerDetail::where('id', $radarId)->where('enable', 1)->value('cover_id');
- break;
- default:
- $materialId = '';
- break;
- }
- if(empty($materialId)) {
- Log::logError('捕获到非预期的附件类型', [
- 'corpid' => $corpid,
- 'attachment' => $attachment
- ], 'mediaIdDeal');
- unset($attachments[$key]);
- continue;
- }
- Log::logInfo('附件id获取', [
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType
- ], 'MediaIdDeal');
- $mediaId = MaterialService::getMediaId($materialId, $corpid, true, $type, $attachmentType);
- if($mediaId===false) {
- EmailQueue::rPush('获取附件mediaId失败', json_encode($attachment, JSON_UNESCAPED_UNICODE), ['xiaohua.hou@kuxuan-inc.com'], '获取附件mediaId失败');
- Log::logInfo('获取附件素材ID发生异常', [
- 'attachment' => $attachment,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType
- ], 'MediaIdDeal');
- unset($attachments[$key]);
- continue;
- }
- $attachment[$msgType]['media_id'] = $mediaId;
- }
- return $attachments;
- }
- /**
- * 下载素材并获取临时素材ID
- * */
- public static function getMediaId($materialId, $corpid, $forceRefresh=false, $type=1, $attachmentType=false)
- {
- try {
- $materialInfo = Material::select(['oss_url', 'media_id', 'expire_at', 'local_path', 'corpid'])
- ->where('id', $materialId)->where('type', $type)->first();
- Log::logInfo('数据库中获取的附件信息', [
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType,
- 'info' => $materialInfo->toArray()
- ], 'MediaIdDeal');
- if(empty($materialInfo)) {
- return false;
- }
- if($materialInfo->corpid != $corpid) {
- $materialModel = new Material;
- $materialModel->corpid = $corpid;
- $materialModel->local_path = $materialInfo->local_path;
- $materialModel->type = $type;
- $materialModel->oss_url = $materialInfo->oss_url;
- $materialModel->media_id = null;
- $materialModel->expire_at = date('Y-m-d H:i:s');
- $materialModel->save();
- $materialId = $materialModel->id;
- $materialInfo = $materialModel;
- $forceRefresh = true;
- }
- Log::logInfo('检查下附件过期没', [
- 'expire_at' => $materialInfo->expire_at,
- 'now' => date('Y-m-d H:i:s')
- ], 'MediaIdDeal');
- if($materialInfo->expire_at <= date('Y-m-d H:i:s') || $forceRefresh === true) { // 临时素材已过期或要求强制刷新
- Log::logInfo('数据库中附件信息过期了', [
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType,
- ], 'MediaIdDeal');
- $localFilePath = $materialInfo->local_path;
- if(!$localFilePath || !file_exists(public_path($localFilePath))) {
- $localFilePath = MaterialService::mediaDownload($materialInfo->oss_url, $type, $corpid);
- if($localFilePath === false) {
- Log::logInfo('数据库中附件本地path异常', [
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType,
- ], 'MediaIdDeal');
- return false;
- }
- }
- Log::logInfo('数据库中附件本地path', [
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType,
- ], 'MediaIdDeal');
- if($attachmentType === false) {
- $mediaData = MaterialService::uploadMedia($corpid, $localFilePath, $type);
- } else {
- $mediaData = MaterialService::uploadAttachment($corpid, $localFilePath, $type, $attachmentType);
- }
- Log::logInfo('新获取到的mediaData', [
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- 'type' => $type,
- 'attachment_type' => $attachmentType,
- 'mediaData' => $mediaData
- ], 'MediaIdDeal');
- // @unlink($localFilePath);
- if((isset($mediaData['errcode']) && $mediaData['errcode']) || $mediaData === false) {
- EmailQueue::rPush('获取素材mediaId失败', json_encode($mediaData, JSON_UNESCAPED_UNICODE), ['xiaohua.hou@kuxuan-inc.com'], '获取素材mediaId失败');
- Log::logError('素材ID获取失败', [
- 'response' => $mediaData,
- 'material_id' => $materialId,
- 'corpid' => $corpid,
- ], 'MediaIdReplace');
- return false;
- }
- $mediaId = $mediaData['media_id'];
- $expireTime = date('Y-m-d H:i:s', $mediaData['created_at'] + 86400 * 3 - 200);
- $result = Material::where('id', $materialId)->update([
- 'local_path' => $localFilePath,
- 'media_id'=>$mediaId,
- 'expire_at'=>$expireTime
- ]);
- if(!$result) {
- Log::logError('素材ID更新失败',$materialInfo->toArray(), 'MediaIdReplace');
- }
- } else {
- $mediaId = $materialInfo->media_id;
- }
- } catch (\Exception $e) {
- # 增加报警
- EmailQueue::rPush('素材ID获取失败', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '素材ID获取失败');
- Log::logError('素材ID获取失败', [
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage()
- ], 'MediaIdReplace');
- return false;
- }
- return $mediaId;
- }
- /**
- * 下载多媒体资源到本地
- * */
- public static function mediaDownload($url, $type, $corpid)
- {
- $url = trim($url, "'");
- $url = trim($url, '"');
- if(empty($url)) return '';
- switch($type) {
- case 1:
- $fileType = self::getImgType($url);
- break;
- case 3:
- $fileType = 'mp4';
- break;
- default:
- $fileType = 'jpg';
- }
- if($fileType === false) {
- Log::logError('图片后缀获取异常', [
- 'url' => $url,
- 'type' => $type,
- 'corpid' => $corpid
- ], 'MediaDownload');
- return false;
- }
- $save_dir = public_path('../storage/uploads/');
- // $save_dir = '/mnt/playlet/storage/uploads/';
- $fileName = md5($corpid.time().rand(100000,999999)).'.'.$fileType;
- try {
- //创建保存目录
- if(!file_exists($save_dir)) {
- if(!mkdir($save_dir, 0777, true)) {
- EmailQueue::rPush('下载图片时目录创建失败', $save_dir, ['xiaohua.hou@kuxuan-inc.com'], '下载图片时目录创建失败');
- Log::logError('创建目录失败,目录路径:'.$save_dir, [], 'CreateDir');
- }
- }
- //获取远程文件所采用的方法
- $ch = curl_init();
- $timeout = 20;
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
- $content = curl_exec($ch);
- curl_close($ch);
- $fp2 = @fopen($save_dir . $fileName, 'a');
- fwrite($fp2, $content);
- fclose($fp2);
- unset($content, $url);
- } catch (\Exception $e) {
- EmailQueue::rPush('素材文件下载抛出异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '素材文件下载抛出异常');
- Log::logError('素材文件下载抛出异常', [
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage(),
- 'path' => $save_dir
- ], 'CreateDir-Exception');
- }
- return realpath($save_dir . $fileName);
- }
- /**
- * 获取图片类型
- * */
- public static function getImgType($url, $retry=0)
- {
- $suffix = '';
- try {
- if(empty($suffix) && strstr($url, 'wx_fmt=') !== false) { // 公众号图片
- $suffix = self::getUrlParam($url, 'wx_fmt');
- }
- // Log::logInfo($url);
- if(empty($suffix) || $suffix=='other') {
- $info = getimagesize($url);
- $suffix = false;
- if($mime = $info['mime']){
- $suffix = explode('/',$mime)[1];
- }
- }
- if(empty($suffix)) {
- $suffix = pathinfo($url, PATHINFO_EXTENSION);
- }
- } catch(\Exception $e) {
- Log::logInfo('Error', [
- 'url' => $url,
- 'msg' => $e->getMessage()
- ], 'Error');
- $suffix = false;
- }
- if($suffix === false && $retry <3) { // 发起重试
- $retry++;
- return self::getImgType($url, $retry);
- }
- return $suffix ? : false;
- }
- /**
- * 获取url指定参数
- * */
- public static function getUrlParam($url, $param){
- $res = '';
- $a = strpos($url,'?');
- if($a!==false){
- $str = substr($url,$a+1);
- $arr = explode('&',$str);
- foreach($arr as $k=>$v){
- $tmp = explode('=',$v);
- if(!empty($tmp[0]) && !empty($tmp[1])){
- $barr[$tmp[0]] = $tmp[1];
- }
- }
- }
- if(!empty($barr[$param])){
- $res = $barr[$param];
- }
- return $res;
- }
- /**
- * 上传文件到oss
- * */
- public static function uploadFileToOss($corpid, $type, $file,$isMaterial, &$data)
- {
- try{
- if (empty($file) || !$file->isValid()) {
- return 2315;
- }
- $originalExtension = strtolower($file->getClientOriginalExtension()); //文件扩展名
- if(!$originalExtension) $originalExtension = $file->guessExtension();
- $realPath = $file->getRealPath(); //临时文件的绝对路径
- $mimeType = $file->getClientMimeType(); // image/jpeg
- $fileSize = $file->getClientSize();
- switch ($type) {
- case 1: // 图片
- if ($isMaterial && !in_array($originalExtension, ['jpg', 'png'])) {
- Log::logError('上传的图片类型为:', ['type' => $originalExtension], 'uploadFileToOss');
- return 2301;
- }
- if($fileSize > 10 * 1024 * 1024) {
- return 2306;
- }
- list($width, $height, $imageType, $attr) = getimagesize($realPath);
- if($isMaterial && $width * $height > 1555200) {// 上传素材时验证图片像素,单纯上传图片取消该限制
- return 2312;
- }
- break;
- case 2: // 语音
- if (!in_array($originalExtension, ['amr'])) {
- return 2302;
- }
- if($fileSize > 2 * 1024 * 1024) {
- return 2307;
- }
- break;
- case 3: // 视频
- if (!in_array($originalExtension, ['mp4'])) {
- return 2303;
- }
- # 视频文件大小限制
- if($fileSize > 20 * 1024 * 1024) {
- return 2308;
- }
- break;
- case 4:
- if (!in_array($originalExtension, ['pdf'])) {
- return 2313;
- }
- # 文件大小限制
- if($fileSize > 20 * 1024 * 1024) {
- return 2316;
- }
- break;
- }
- // 上传文件
- $filename = date('YmdHis') . '-' . uniqid() . '.' . $originalExtension;
- // 使用我们新建的uploads本地存储空间(目录)
- $result = Storage::disk('uploads')->put($filename, file_get_contents($realPath));
- if(!$result)
- return 2314;
- $oss = new OssService('playlet');
- $localFilePath = '../storage/uploads/'.$filename;
- $ossFile = $oss->upload($originalExtension, $localFilePath, $mimeType.'/'.date("Y-m-d",time()));
- $fileUrl = $ossFile['oss-request-url'];
- $data = array_filter([
- 'url' => $fileUrl,
- 'local_path' => $localFilePath
- ]);
- } catch (\Exception $e) {
- EmailQueue::rPush('文件上传过程发生异常', $e->getTraceAsString(), [
- 'xiaohua.hou@kuxuan-inc.com'], '文件上传过程发生异常');
- Log::logError('文件上传过程发生异常', [
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage()
- ], 'UploadMaterial-Exception');
- return 2317;
- }
- return 0;
- }
- public static function itemUrlReplace($attachments, $itemUrl)
- {
- if(empty($attachments)) return [];
- if(empty($itemUrl)) return $attachments;
- foreach ($attachments as $key=>&$attachment) {
- if(isset($attachment['link']['url'])) {
- $attachment['link']['url'] = $itemUrl;
- }
- if(isset($attachment['link']['jump_url'])) {
- $attachment['link']['jump_url'] = $itemUrl;
- }
- if(isset($attachment['promote']['jump_url'])) {
- $attachment['promote']['jump_url'] = $itemUrl;
- }
- if(isset($attachment['promote']['url'])) {
- $attachment['promote']['url'] = $itemUrl;
- }
- }
- return $attachments;
- }
- public static function turnToH5($attachments)
- {
- if(empty($attachments)) return [];
- foreach ($attachments as $key=>&$attachment) {
- # 图片类型media_id转换为mediaid
- if(isset($attachment['image']['media_id'])) {
- $attachment['image']['mediaid'] = $attachment['image']['media_id'];
- }
- # 图片类型 pic_url转换为 imgUrl
- if(isset($attachment['image']['pic_url'])) {
- $attachment['image']['imgUrl'] = $attachment['image']['pic_url'];
- }
- # 链接类型 picurl 转换为 imgUrl
- if(isset($attachment['link']['picurl'])) {
- $attachment['link']['imgUrl'] = $attachment['link']['picurl'];
- }
- # video类型media_id转换为mediaid
- if(isset($attachment['video']['media_id'])) {
- $attachment['video']['mediaid'] = $attachment['video']['media_id'];
- }
- # file类型media_id转换为mediaid
- if(isset($attachment['file']['media_id'])) {
- $attachment['file']['mediaid'] = $attachment['file']['media_id'];
- }
- # 小程序封面图替换
- if(isset($attachment['miniprogram']['pic_url'])){
- $attachment['miniprogram']['imgUrl']= $attachment['miniprogram']['pic_url'];
- }
- }
- return $attachments;
- }
- /**
- * 上传图片到企微
- * */
- public static function uploadImg($corpid, $filePath, $retry=0)
- {
- $accessToken = AuthorizeCorp::getAccessToken($corpid, '上传图片到企微');
- if(empty($accessToken)) {
- return false;
- }
- $requestUri = config('qyWechat.upload_img');
- $requestUri .= $accessToken;
- $response = HttpService::httpUpload($requestUri, $filePath);
- $responseData = json_decode($response, true);
- # 发起重试
- if($response===false || $responseData['errcode'] == -1) { // 企微系统繁忙,发起重试
- if($retry < 5) {
- Log::logInfo('企微系统繁忙,发起重试', [
- 'retry' => $retry,
- 'response' => $responseData
- ], 'UploadImg');
- $retry++;
- return MaterialService::uploadImg($filePath, $retry);
- }
- }
- Log::logInfo('上传图片到企微返回结果', [
- 'retry' => $retry,
- 'corpid' => $corpid,
- 'response' => $responseData
- ], 'UploadImg');
- return $responseData['url'] ?? '';
- }
- /**
- * 通过图片链接上传资源到oss
- * */
- public static function uploadFileByUrl($corpid, $imgUrl, &$ossUrl)
- {
- try{
- # 下载图片
- $realPath = MaterialService::mediaDownload($imgUrl, 1, $corpid);
- if($realPath === false) return 2319;
- # 上传图片
- $originalExtension = MaterialService::getImgType($imgUrl); //文件扩展名
- if($originalExtension === false) return 2319;
- $oss = new OssService('playlet');
- $ossFile = $oss->upload($originalExtension, $realPath, 'image/'.date("Y-m-d",time()));
- # 上传成功删除本地图片
- @unlink($realPath);
- # 返回oss链接
- $ossUrl = $ossFile['oss-request-url'];
- } catch (\Exception $e) {
- EmailQueue::rPush('通过图片链接上传资源到oss流程出现异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '创建朋友圈消息流程出现异常');
- Log::logError('通过图片链接上传资源到oss流程出现异常', [
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage(),
- 'corpid' => $corpid,
- 'imgUrl' => $imgUrl
- ], 'uploadFileByUrl');
- return 2319;
- }
- return 0;
- }
- }
|