智慧教务系统
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

<?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());
}
}
}