fix(upload): 支持附件上传自动同步至腾讯云COS及CDN预览

这个提交包含在:
wikiboss
2026-10-17 15:56:29 +08:00
父节点 aaf7b6356b
当前提交 2a95de4225
共有 3 个文件被更改,包括 65 次插入 和 2 次删除

查看文件

@@ -45,10 +45,14 @@ class File extends Backend
'order' => $order
], $rows, $page);
$cosConfig = function_exists('get_addon_config') ? get_addon_config('cos') : [];
$cdnUrl = (!empty($cosConfig['cdnurl'])) ? rtrim($cosConfig['cdnurl'], '/') : '';
if (!empty($result['list'])) {
foreach ($result['list'] as &$v) {
$v['checked'] = false;
$v['showTools'] = false;
$v['fullurl'] = (!empty($cdnUrl) && stripos($v['url'], 'http') !== 0) ? ($cdnUrl . $v['url']) : cdnurl($v['url'], true);
}
}

查看文件

@@ -300,7 +300,7 @@
</div>
<div @click="handleSelectFile(index)" v-for="(item, index) of fileList" :key="item.id" class="file-list" @mouseenter="enterFileItem($event, index)" @mouseleave="leaveFileItem($event, index)">
<div class="file-img-item">
<img class="file-image" :src="item.mimetype.indexOf('image') >= 0 ? item.url : `/s.php/ajax/icon?suffix=${item.imagetype}`" alt="">
<img class="file-image" :src="item.mimetype.indexOf('image') >= 0 ? (item.fullurl || item.url) : `/s.php/ajax/icon?suffix=${item.imagetype}`" alt="">
</div>
<div v-if="item.checked || item.showTools" class="tools">
<div class="top">
@@ -315,7 +315,7 @@
<img src="/assets/img/check-check.png" alt="">
</div>
{/if}
<div @click.stop="handleOpenFile(item.url)" style="margin: 0 12px;" class="v-icon">
<div @click.stop="handleOpenFile(item.fullurl || item.url)" style="margin: 0 12px;" class="v-icon">
<img src="/assets/img/see-see.png?id=1" alt="">
</div>
<div @click.stop="dell(item.id)" class="v-icon">

查看文件

@@ -446,10 +446,69 @@ class Upload
$attachment->data(array_filter($params));
$attachment->save();
$this->syncToCos($attachment);
\think\Hook::listen("upload_after", $attachment);
return $attachment;
}
/**
* 同步文件到腾讯云COS
* @param Attachment $attachment
*/
protected function syncToCos($attachment)
{
try {
$addonInfo = get_addon_info('cos');
if (!$addonInfo || empty($addonInfo['state'])) {
return;
}
$cosConfig = get_addon_config('cos');
if (empty($cosConfig) || empty($cosConfig['secretId']) || empty($cosConfig['secretKey']) || empty($cosConfig['bucket'])) {
return;
}
if (!class_exists('\Qcloud\Cos\Client')) {
$cosAddonPath = (defined('ADDON_PATH') ? ADDON_PATH : (ROOT_PATH . 'addons' . DS)) . 'cos' . DIRECTORY_SEPARATOR;
\think\Loader::addNamespace('Qcloud\Cos', $cosAddonPath . 'library' . DIRECTORY_SEPARATOR . 'Qcloud' . DIRECTORY_SEPARATOR . 'Cos' . DIRECTORY_SEPARATOR);
\think\Loader::addNamespace('GuzzleHttp\Command', $cosAddonPath . 'library' . DIRECTORY_SEPARATOR . 'Guzzle' . DIRECTORY_SEPARATOR . 'command' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
\think\Loader::addNamespace('GuzzleHttp\Command\Guzzle', $cosAddonPath . 'library' . DIRECTORY_SEPARATOR . 'Guzzle' . DIRECTORY_SEPARATOR . 'guzzle-services' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
\think\Loader::addNamespace('GuzzleHttp\UriTemplate', $cosAddonPath . 'library' . DIRECTORY_SEPARATOR . 'Guzzle' . DIRECTORY_SEPARATOR . 'uri-template' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
}
$realPath = ROOT_PATH . 'public' . str_replace('/', DS, $attachment->url);
if (!file_exists($realPath)) {
return;
}
$client = new \Qcloud\Cos\Client([
'region' => $cosConfig['region'],
'schema' => 'https',
'credentials' => [
'secretId' => $cosConfig['secretId'],
'secretKey' => $cosConfig['secretKey'],
]
]);
$key = ltrim($attachment->url, '/');
$fileHandle = fopen($realPath, 'rb');
$client->upload($cosConfig['bucket'], $key, $fileHandle);
if (is_resource($fileHandle)) {
fclose($fileHandle);
}
$attachment->storage = 'cos';
$attachment->save();
// 如果设置了不保留本地备份,则删除本地文件
if (isset($cosConfig['serverbackup']) && $cosConfig['serverbackup'] == 0) {
@unlink($realPath);
}
} catch (\Exception $e) {
\think\Log::write('COS Upload Error: ' . $e->getMessage(), 'error');
}
}
/**
* 设置错误信息
* @param $msg