| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <?php
- namespace business\common\services;
- use app\common\exceptions\AppException;
- use business\common\models\Material;
- use EasyWeChat\Factory;
- class MaterialService
- {
- static $current;
- protected $agent_app;
- protected $nickname;
- protected $business_id;
- protected $filterName = false;
- const MEDIA_UPLOAD = "cgi-bin/media/upload";
- private function __construct($business_id)
- {
- $business_id or $business_id = SettingService::getBusinessId();
- if (!$business_id) {
- throw new AppException('企业ID参数缺失!');
- }
- $this->business_id = $business_id;
- }
- /**
- * @param $business_id
- * @param $app
- * @return static
- * @throws AppException
- */
- public static function current($business_id = 0, $app = null)
- {
- if (static::$current) {
- return static::$current;
- }
- static::$current = new static($business_id);
- if ($app) {
- static::$current->setApp($app);
- } else {
- $config = SettingService::getQyWxSetting($business_id);
- static::$current->setApp(Factory::work([
- 'corp_id' => $config['corpid'],
- 'agent_id' => $config['agentid'],
- 'secret' => $config['contact_secret'],
- ]));
- }
- return static::$current;
- }
- public function setApp($app)
- {
- $this->agent_app = $app;
- }
- // 设置文本昵称
- public function setNickname($nickname)
- {
- $this->nickname = $nickname;
- }
- public function filterName()
- {
- $this->filterName = true;
- }
- /**
- * Upload Image.
- *
- * @return mixed
- */
- public function uploadImage(string $path)
- {
- return $this->upload('image', $path);
- }
- /**
- * Upload Voice.
- *
- * @return mixed
- */
- public function uploadVoice(string $path)
- {
- return $this->upload('voice', $path);
- }
- /**
- * Upload Video.
- *
- * @return mixed
- */
- public function uploadVideo(string $path)
- {
- return $this->upload('video', $path);
- }
- /**
- * Upload File.
- *
- * @return mixed
- */
- public function uploadFile(string $path)
- {
- return $this->upload('file', $path);
- }
- /**
- * 组装请求
- * @param string $type
- * @param string $url
- * @return mixed
- */
- private function upload(string $type, string $url)
- {
- $query = ['type' => $type];
- $multipart[0] = [
- 'name' => "media",
- 'filename' => self::baseName($url),
- 'contents' => fopen($url, 'r'),
- ];
- return $this->httpUpload($query, $multipart);
- }
- /**
- * 发送请求上传临时素材给企业微信
- * @param string $query
- * @param array $multipart
- * @return mixed
- */
- private function httpUpload(array $query, array $multipart)
- {
- $res = $this->agent_app->media->request(self::MEDIA_UPLOAD, 'POST', ['query' => $query, 'multipart' => $multipart, 'connect_timeout' => 30, 'timeout' => 30, 'read_timeout' => 30]);
- return $res;
- }
- /**
- * 返回文件名
- * @param $filename
- * @return string
- */
- public static function baseName($filename) : string
- {
- return preg_replace('/^.+[\\\\\\/]/', '', $filename);
- }
- public function handleContent($content_list)
- {
- foreach ($content_list as &$v) {
- switch ($v['type']) {
- case 'text':
- // PC后台编辑素材内容时换行有以下三种形式
- $str = str_replace('<div><br></div>', "\n", html_entity_decode($v['news']));
- $str = str_replace('<br>',"\n",$str);
- $v['news'] = strip_tags(str_replace('<div>',"\n",$str));
- if ($this->filterName){
- $v['news'] = str_replace('客户昵称', '', $v['news']);
- }
- // 传入客户昵称或群聊昵称则替换
- if ($this->nickname) {
- $v['news'] = str_replace('客户昵称', $this->nickname, $v['news']);
- }
- break;
- case 'image':
- $v['media_id'] = $this->getMediaId($v['type'], $v['link_img']);
- break;
- case 'link':
- break;
- case 'applet':
- $v['media_id'] = $this->getMediaId('image', $v['link_img']);
- if ($v['page']){
- if ($start = strpos($v['page'],'?') !== false){
- $v['page'] = substr_replace($v['page'],'.html?',$start,1);
- }else{
- $v['page'] .= '.html';
- }
- }
- break;
- case 'video':
- $v['media_id'] = $this->getMediaId($v['type'], $v['link_video']);
- break;
- case 'file':
- $v['media_id'] = $this->getMediaId($v['type'], $v['link_file']);
- break;
- }
- }
- return $content_list;
- }
- public function getMediaId($type, $url)
- {
- $file_name = self::baseName($url);
- $model = Material::builder($this->business_id)
- ->where([
- 'type' => $type,
- 'file_name' => $file_name
- ])
- ->first();
- if ($model and (time() - $model->updated_at < 60 * 60 * 24 * 3)) {
- return $model->media_id;
- }
- switch ($type) {
- case 'image':
- $res = $this->uploadImage($url);
- break;
- case 'video':
- $res = $this->uploadVideo($url);
- break;
- case 'file':
- $res = $this->uploadFile($url);
- break;
- }
- if (!is_array($res)) {
- $res = json_decode($res, true);
- }
- if ($res['errcode'] === 0) {
- if (!$model) {
- $model = new Material();
- }
- $data = [
- 'uniacid' => \YunShop::app()->uniacid,
- 'business_id' => $this->business_id,
- 'type' => $type,
- 'file_name' => $file_name,
- 'file_url' => $url,
- 'media_id' => $res['media_id'],
- 'updated_at' => time()
- ];
- $model->fill($data);
- if ($model->save()) {
- return $res['media_id'];
- } else {
- \Log::debug('media_id保存失败', ['uniacid' => $data['uniacid'], 'business_id' => $data['business_id'], 'type' => $type, 'file_name' => $file_name, 'media_id' => $res['media_id']]);
- throw new \Exception('media_id保存失败');
- }
- } else {
- \Log::debug('素材上传失败,' . $res['errmsg'], ['uniacid' => \YunShop::app()->uniacid, 'business_id' => $this->business_id, 'type' => $type, 'file_name' => $file_name]);
- throw new \Exception('media_id获取失败');
- }
- }
- }
|