admin/business/common/services/MaterialService.php

255 lines
7.1 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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获取失败');
}
}
}