当前版本CRMEB-BZ v5.4.0(20240708)
本方案优势
- 可随时开启关闭云存储
- 无需替换数据库内图片路径
- 通过中间件动态替换图片路径
数据库变更
php think migrate:create UpdateSystemAttachment
public function change()
{
$table->addColumn('cloud_name', 'string', ['limit' => MysqlAdapter::TEXT_TINY, 'default' => '', 'comment' => '附件名称'])
->addColumn('cloud_att_dir', 'string', ['limit' => MysqlAdapter::TEXT_TINY, 'default' => '', 'comment' => '附件路径'])
->addColumn('cloud_satt_dir', 'string', ['limit' => MysqlAdapter::TEXT_TINY, 'default' => '', 'comment' => '压缩图片路径'])
->update();
}
代码变更
1. 控制器变更
\app\adminapi\controller\v1\setting\SystemStorage::uploadType
方法,修改为
/**
* 切换存储类型
* @param SystemConfigServices $services
* @param $type
* @return mixed
*/
public function uploadType(SystemConfigServices $services, $type)
{
$upload_type = sys_config('upload_type', SystemAttachment::UPLOAD_TYPE_LOCAL);
if (SystemAttachment::UPLOAD_TYPE_LOCAL !== (int)$upload_type) {
// david 2024年11月21日 09:31:58
return response_json()->fail('禁止修改存储类型');
}
$status = $this->services->count(['type' => $type, 'status' => 1]);
if (!$status && $type != 1) {
return app('json')->success(400227);
}
$services->update('upload_type', ['value' => json_encode($type)], 'menu_name');
\crmeb\services\CacheService::clear();
if ($type != 1) {
$msg = 400228;
} else {
$msg = 400229;
}
return app('json')->success($msg);
}
2. 服务层变更
初始化上传对象
\app\services\other\UploadService::init
方法,修改为
/**
* @param null $type
* @return Upload|mixed
*/
public static function init($type = null)
{
if (is_null($type)) {
$type = (int)sys_config('upload_type', 1);
}
if (isset(self::$upload['upload_' . $type])) {
return self::$upload['upload_' . $type];
}
$type = (int)$type;
$config = [];
switch ($type) {
case SystemAttachment::UPLOAD_TYPE_QINIU://七牛
$config = [
'accessKey' => sys_config('qiniu_accessKey'),
'secretKey' => sys_config('qiniu_secretKey'),
];
break;
case SystemAttachment::UPLOAD_TYPE_ALI_OSS:// oss 阿里云
$config = [
'accessKey' => sys_config('accessKey'),
'secretKey' => sys_config('secretKey'),
];
break;
case SystemAttachment::UPLOAD_TYPE_TENCENT_COS:// cos 腾讯云
$config = [
'accessKey' => sys_config('tengxun_accessKey'),
'secretKey' => sys_config('tengxun_secretKey'),
'appid' => sys_config('tengxun_appid'),
];
break;
case SystemAttachment::UPLOAD_TYPE_JD://京东云
$config = [
'accessKey' => sys_config('jd_accessKey'),
'secretKey' => sys_config('jd_secretKey'),
'storageRegion' => sys_config('jd_storageRegion'),
];
break;
case SystemAttachment::UPLOAD_TYPE_HUAWEI://华为云
$config = [
'accessKey' => sys_config('hw_accessKey'),
'secretKey' => sys_config('hw_secretKey'),
];
break;
case SystemAttachment::UPLOAD_TYPE_TIANYI://天翼云
$config = [
'accessKey' => sys_config('ty_accessKey'),
'secretKey' => sys_config('ty_secretKey'),
];
break;
case SystemAttachment::UPLOAD_TYPE_LOCAL:
break;
default:
throw new UploadException(400733);
}
//除了本地存储其他都去获取配置信息
if (SystemAttachment::UPLOAD_TYPE_LOCAL !== $type) {
/** @var SystemStorageServices $make */
$make = app()->make(SystemStorageServices::class);
$res = $make->getConfig($type);
$config['uploadUrl'] = $res['domain'];
$config['storageName'] = $res['name'];
if (5 !== $type) $config['storageRegion'] = $res['region'];
$config['cdn'] = $res['cdn'];
}
$thumb = SystemConfigService::more(['thumb_big_height', 'thumb_big_width', 'thumb_mid_height', 'thumb_mid_width', 'thumb_small_height', 'thumb_small_width',]);
$water = SystemConfigService::more([
'image_watermark_status',
'watermark_type',
'watermark_image',
'watermark_opacity',
'watermark_position',
'watermark_rotate',
'watermark_text',
'watermark_text_angle',
'watermark_text_color',
'watermark_text_size',
'watermark_x',
'watermark_y']);
$config = array_merge($config, ['thumb' => $thumb], ['water' => $water]);
return self::$upload['upload_' . $type] = new Upload($type, $config);
}
图片上传
\app\services\system\attachment\SystemAttachmentServices::upload
方法,修改为
/**
* 图片上传
* @param int $pid
* @param string $file
* @param int $upload_type
* @param int $type
* @param $menuName
* @param string $uploadToken
* @return mixed
*/
public function upload(int $pid, string $file, int $upload_type, int $type, $menuName, $uploadToken = '')
{
$realName = false;
if ($upload_type == 0) {
$upload_type = sys_config('upload_type', 1);
}
if ($menuName == 'weixin_ckeck_file' || $menuName == 'ico_path') {
$upload_type = 1;
$realName = true;
}
try {
$path = make_path('attach', 2, true);
if ($path === '') {
throw new AdminException(400555);
}
// 本地始终保留一份 david 2024年10月31日 10:44:15
$upload = UploadService::init(1);
$local = $upload->to($path)->validate()->move($file, $realName);
if ($local === false) {
throw new UploadException($upload->getError());
} else {
$fileInfo = $upload->getUploadInfo();
$fileType = pathinfo($fileInfo['name'], PATHINFO_EXTENSION);
if ($fileInfo && $type == 0 && !in_array($fileType, ['xlsx', 'xls', 'mp4'])) {
$data['name'] = $fileInfo['name'];
$data['real_name'] = $fileInfo['real_name'];
$data['att_dir'] = $fileInfo['dir'];
$data['satt_dir'] = $fileInfo['thumb_path'];
$data['att_size'] = $fileInfo['size'];
$data['att_type'] = $fileInfo['type'];
$data['image_type'] = 1;
$data['module_type'] = 1;
$data['time'] = $fileInfo['time'] ?? time();
$data['pid'] = $pid;
$data['scan_token'] = $uploadToken;
/** @var SystemAttachment $systemAttachment */
$systemAttachment = $this->dao->save($data);
}
if ($upload_type == 1) {
return $local->filePath;
}
}
// 云存储
$upload = UploadService::init($upload_type);
$res = $upload->to(DS . 'uploads' . $path)->validate()->move($file, $realName);
if ($res === false) {
throw new UploadException($upload->getError());
} else {
$fileInfo = $upload->getUploadInfo();
$fileType = pathinfo($fileInfo['name'], PATHINFO_EXTENSION);
if ($fileInfo && $type == 0 && !in_array($fileType, ['xlsx', 'xls', 'mp4'])) {
$cloud = [];
// 保存云存储文件信息 david 2024年11月21日 13:07:52
$cloud['cloud_name'] = $fileInfo['name'];
$cloud['cloud_att_dir'] = $fileInfo['dir'];
$cloud['cloud_satt_dir'] = $fileInfo['thumb_path'];
$cloud['image_type'] = $upload_type;
if (isset($systemAttachment) && $systemAttachment instanceof SystemAttachment) {
$systemAttachment->save($cloud);
}
}
return $local->filePath;
}
} catch (Throwable $e) {
throw new UploadException($e->getMessage());
}
}
3. 模型层变更
\app\model\system\attachment\SystemAttachment
增加属性和常量
/**
* 禁止写入时间戳
* @var bool
*/
protected $autoWriteTimestamp = false;
/**
* 本地存储
*/
public const UPLOAD_TYPE_LOCAL = 1;
/**
* 七牛云存储
*/
public const UPLOAD_TYPE_QINIU = 2;
/**
* 阿里云OSS
*/
public const UPLOAD_TYPE_ALI_OSS = 3;
/**
* 腾讯云COS
*/
public const UPLOAD_TYPE_TENCENT_COS = 4;
/**
* 京东云
*/
public const UPLOAD_TYPE_JD = 5;
/**
* 华为云
*/
public const UPLOAD_TYPE_HUAWEI = 6;
/**
* 天翼云
*/
public const UPLOAD_TYPE_TIANYI = 7;
4. 新增中间件
app/middleware/UploadsUrlReplace.php
内容为
<?php
declare (strict_types=1);
namespace app\middleware;
use app\model\system\attachment\SystemAttachment;
use app\Request;
use Closure;
use think\facade\Config;
use think\Response;
/**
* 文件路径替换中间件
*/
class UploadsUrlReplace
{
/**
* 处理的路由前缀
*/
private const HOOK_ROUTE_PREFIX = [
'/api/'
];
/**
* 处理请求
* @param Request $request
* @param Closure $next
* @return Response
*/
public function handle(Request $request, Closure $next): Response
{
$baseUrl = $request->baseUrl();
$isSkip = true;
foreach (self::HOOK_ROUTE_PREFIX as $prefix) {
if (0 === strpos($baseUrl, $prefix)) {
$isSkip = false;
break;
}
}
$upload_type = sys_config('upload_type', 1);
/** @var Response $response */
$response = $next($request);
if ($isSkip || SystemAttachment::UPLOAD_TYPE_LOCAL === (int)$upload_type) {
return $response;
}
$site_url = sys_config('site_url');
$host = parse_url($site_url, PHP_URL_HOST);
$cdnBaseUrl = parse_url(Config::get('upload.cdn_base_url'), PHP_URL_HOST);
$pattern = '/' . $host . '.+\.(jpg|jpeg|png|gif|svg)"/i';
$content = $response->getContent();
if (false !== preg_match($pattern, $content, $matches)) {
$content = preg_replace_callback($pattern, fn($match) => str_replace($host, $cdnBaseUrl, $match[0]), $content);
$response->content($content);
}
return $response;
}
}
5. 配置变更
config/upload.php
新增配置项
// CDN或对象存储的完整域名
'cdn_base_url' => 'CDN或对象存储的完整域名',
app/middleware.php
全局中间件变更
启用中间件
// 文件路径替换中间件
\app\middleware\UploadsUrlReplace::class,
版权属于:大卫科技Blog
本文链接:https://www.iyuu.cn/archives/519/
转载时须注明出处