You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.4 KiB
139 lines
5.4 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\adminapi\controller\upload;
|
|
|
|
use core\base\BaseAdminController;
|
|
use core\exception\AdminException;
|
|
|
|
/**
|
|
* 腾讯云COS代理上传(临时开发环境解决方案)
|
|
* 注意:生产环境应该直接配置COS的CORS规则而不是使用代理
|
|
*/
|
|
class CosProxy extends BaseAdminController
|
|
{
|
|
/**
|
|
* 代理上传到腾讯云COS
|
|
* @return \think\Response
|
|
*/
|
|
public function proxyUpload()
|
|
{
|
|
try {
|
|
// 从表单或JSON中获取数据
|
|
$upload_url = $this->request->post('upload_url');
|
|
|
|
// 尝试多种方式获取表单数据
|
|
$form_data = [];
|
|
|
|
// 方式1: 从form_data字段获取JSON字符串
|
|
$form_data_json = $this->request->post('form_data', '');
|
|
if (!empty($form_data_json)) {
|
|
$form_data = json_decode($form_data_json, true);
|
|
if (json_last_error() === JSON_ERROR_NONE) {
|
|
// JSON解析成功
|
|
} else {
|
|
$form_data = [];
|
|
}
|
|
}
|
|
|
|
// 如果JSON解析失败,检查是否有独立的字段
|
|
if (empty($form_data)) {
|
|
$possible_fields = ['key', 'policy', 'q-sign-algorithm', 'q-ak', 'q-key-time', 'q-signature', 'domain'];
|
|
foreach ($possible_fields as $field) {
|
|
$value = $this->request->post($field);
|
|
if (!empty($value)) {
|
|
$form_data[$field] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (empty($upload_url)) {
|
|
throw new AdminException('缺少上传地址');
|
|
}
|
|
|
|
// 处理文件上传
|
|
$file = $this->request->file('file');
|
|
if (empty($file)) {
|
|
throw new AdminException('缺少上传文件');
|
|
}
|
|
|
|
// 添加调试模式 - 如果upload_url包含debug,则返回解析的数据不执行实际上传
|
|
if (strpos($upload_url, 'debug') !== false) {
|
|
return success([
|
|
'debug' => true,
|
|
'upload_url' => $upload_url,
|
|
'form_data' => $form_data,
|
|
'form_data_count' => count($form_data),
|
|
'file_info' => [
|
|
'name' => $file->getOriginalName(),
|
|
'size' => $file->getSize(),
|
|
'mime' => $file->getMime()
|
|
]
|
|
]);
|
|
}
|
|
|
|
// 腾讯云COS要求特定的字段顺序
|
|
$post_data = [];
|
|
|
|
// 添加所有表单字段,确保file在最后
|
|
foreach ($form_data as $key => $value) {
|
|
$post_data[$key] = $value;
|
|
}
|
|
|
|
// 最后添加文件(腾讯云COS要求file字段在最后)
|
|
$curl_file = new \CURLFile($file->getPathname(), $file->getMime(), $file->getOriginalName());
|
|
$post_data['file'] = $curl_file;
|
|
|
|
// 发送请求到腾讯云COS
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $upload_url);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
|
|
curl_setopt($ch, CURLOPT_HEADER, true);
|
|
|
|
$full_response = curl_exec($ch);
|
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
|
$error = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
if ($error) {
|
|
throw new AdminException('上传失败: ' . $error);
|
|
}
|
|
|
|
// 解析响应头和内容
|
|
$header = substr($full_response, 0, $header_size);
|
|
$body = substr($full_response, $header_size);
|
|
|
|
if ($http_code === 204 || $http_code === 200) {
|
|
// 上传成功
|
|
$domain = rtrim($form_data['domain'] ?? '', '/');
|
|
$key = $form_data['key'] ?? '';
|
|
$file_url = $domain . '/' . $key;
|
|
|
|
return success([
|
|
'url' => $file_url,
|
|
'http_code' => $http_code,
|
|
'response_body' => substr($body, 0, 100) // 调试信息
|
|
]);
|
|
} else {
|
|
throw new AdminException("上传失败,HTTP状态码: {$http_code}, 响应: " . substr($body, 0, 200));
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
return fail($e->getMessage());
|
|
}
|
|
}
|
|
}
|