文件上传、图片上传对接阿里云OSS
This commit is contained in:
@@ -14,3 +14,9 @@ Route::group('v1/auth', function () {
|
|||||||
Route::get('info', 'app\\common\\controller\\Auth@info')->middleware(['jwt']); // 获取用户信息
|
Route::get('info', 'app\\common\\controller\\Auth@info')->middleware(['jwt']); // 获取用户信息
|
||||||
Route::post('refresh', 'app\\common\\controller\\Auth@refresh')->middleware(['jwt']); // 刷新令牌
|
Route::post('refresh', 'app\\common\\controller\\Auth@refresh')->middleware(['jwt']); // 刷新令牌
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 附件上传相关路由
|
||||||
|
Route::group('v1/', function () {
|
||||||
|
Route::post('attachment/upload', 'app\\common\\controller\\Attachment@upload'); // 上传附件
|
||||||
|
Route::get('attachment/:id', 'app\\common\\controller\\Attachment@info'); // 获取附件信息
|
||||||
|
})->middleware(['jwt']);
|
||||||
140
Server/application/common/controller/Attachment.php
Normal file
140
Server/application/common/controller/Attachment.php
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\controller;
|
||||||
|
|
||||||
|
use think\Controller;
|
||||||
|
use think\facade\Request;
|
||||||
|
use app\common\model\Attachment as AttachmentModel;
|
||||||
|
use app\common\util\AliyunOSS;
|
||||||
|
|
||||||
|
class Attachment extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @return \think\response\Json
|
||||||
|
*/
|
||||||
|
public function upload()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 获取上传文件
|
||||||
|
$file = Request::file('file');
|
||||||
|
if (!$file) {
|
||||||
|
return json([
|
||||||
|
'code' => 400,
|
||||||
|
'msg' => '请选择要上传的文件'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证文件
|
||||||
|
$validate = \think\facade\Validate::rule([
|
||||||
|
'file' => [
|
||||||
|
'fileSize' => 10485760, // 10MB
|
||||||
|
'fileExt' => 'jpg,jpeg,png,gif,doc,docx,pdf,zip,rar',
|
||||||
|
'fileMime' => 'image/jpeg,image/png,image/gif,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,application/zip,application/x-rar-compressed'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$validate->check(['file' => $file])) {
|
||||||
|
return json([
|
||||||
|
'code' => 400,
|
||||||
|
'msg' => $validate->getError()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成文件hash
|
||||||
|
$hashKey = md5_file($file->getRealPath());
|
||||||
|
|
||||||
|
// 检查文件是否已存在
|
||||||
|
$existFile = AttachmentModel::getByHashKey($hashKey);
|
||||||
|
if ($existFile) {
|
||||||
|
return json([
|
||||||
|
'code' => 200,
|
||||||
|
'msg' => '文件已存在',
|
||||||
|
'data' => [
|
||||||
|
'id' => $existFile['id'],
|
||||||
|
'name' => $existFile['name'],
|
||||||
|
'url' => $existFile['source']
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成OSS对象名称
|
||||||
|
$objectName = AliyunOSS::generateObjectName($file->getOriginalName());
|
||||||
|
|
||||||
|
// 上传到OSS
|
||||||
|
$result = AliyunOSS::uploadFile($file->getRealPath(), $objectName);
|
||||||
|
|
||||||
|
if (!$result['success']) {
|
||||||
|
return json([
|
||||||
|
'code' => 500,
|
||||||
|
'msg' => '文件上传失败:' . $result['error']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
$attachmentData = [
|
||||||
|
'name' => Request::param('name') ?: $file->getOriginalName(),
|
||||||
|
'hash_key' => $hashKey,
|
||||||
|
'server' => 'aliyun_oss',
|
||||||
|
'source' => $result['url'],
|
||||||
|
'size' => $result['size'],
|
||||||
|
'suffix' => pathinfo($file->getOriginalName(), PATHINFO_EXTENSION)
|
||||||
|
];
|
||||||
|
|
||||||
|
$attachmentId = AttachmentModel::addAttachment($attachmentData);
|
||||||
|
|
||||||
|
if (!$attachmentId) {
|
||||||
|
return json([
|
||||||
|
'code' => 500,
|
||||||
|
'msg' => '保存附件信息失败'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json([
|
||||||
|
'code' => 200,
|
||||||
|
'msg' => '上传成功',
|
||||||
|
'data' => [
|
||||||
|
'id' => $attachmentId,
|
||||||
|
'name' => $attachmentData['name'],
|
||||||
|
'url' => $attachmentData['source']
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json([
|
||||||
|
'code' => 500,
|
||||||
|
'msg' => '上传失败:' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取附件信息
|
||||||
|
* @param int $id 附件ID
|
||||||
|
* @return \think\response\Json
|
||||||
|
*/
|
||||||
|
public function info($id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$attachment = AttachmentModel::find($id);
|
||||||
|
|
||||||
|
if (!$attachment) {
|
||||||
|
return json([
|
||||||
|
'code' => 404,
|
||||||
|
'msg' => '附件不存在'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json([
|
||||||
|
'code' => 200,
|
||||||
|
'msg' => '获取成功',
|
||||||
|
'data' => $attachment
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json([
|
||||||
|
'code' => 500,
|
||||||
|
'msg' => '获取失败:' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
Server/application/common/model/Attachment.php
Normal file
55
Server/application/common/model/Attachment.php
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\model;
|
||||||
|
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
class Attachment extends Model
|
||||||
|
{
|
||||||
|
// 设置表名
|
||||||
|
protected $name = 'attachments';
|
||||||
|
|
||||||
|
// 设置主键
|
||||||
|
protected $pk = 'id';
|
||||||
|
|
||||||
|
// 自动写入时间戳
|
||||||
|
protected $autoWriteTimestamp = 'datetime';
|
||||||
|
|
||||||
|
// 定义时间戳字段名
|
||||||
|
protected $createTime = 'create_at';
|
||||||
|
protected $updateTime = 'update_at';
|
||||||
|
protected $deleteTime = 'delete_at';
|
||||||
|
|
||||||
|
// 定义字段类型
|
||||||
|
protected $type = [
|
||||||
|
'id' => 'integer',
|
||||||
|
'dl_count' => 'integer',
|
||||||
|
'size' => 'integer',
|
||||||
|
'scene' => 'integer',
|
||||||
|
'create_at' => 'datetime',
|
||||||
|
'update_at' => 'datetime',
|
||||||
|
'delete_at' => 'datetime'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加附件记录
|
||||||
|
* @param array $data 附件数据
|
||||||
|
* @return int|bool
|
||||||
|
*/
|
||||||
|
public static function addAttachment($data)
|
||||||
|
{
|
||||||
|
$attachment = new self();
|
||||||
|
return $attachment->allowField(true)->save($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据hash_key获取附件
|
||||||
|
* @param string $hashKey
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public static function getByHashKey($hashKey)
|
||||||
|
{
|
||||||
|
return self::where('hash_key', $hashKey)
|
||||||
|
->where('delete_at', null)
|
||||||
|
->find();
|
||||||
|
}
|
||||||
|
}
|
||||||
77
Server/application/common/util/AliyunOSS.php
Normal file
77
Server/application/common/util/AliyunOSS.php
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\util;
|
||||||
|
|
||||||
|
use OSS\OssClient;
|
||||||
|
use OSS\Core\OssException;
|
||||||
|
|
||||||
|
class AliyunOSS
|
||||||
|
{
|
||||||
|
// OSS配置信息
|
||||||
|
const ACCESS_KEY_ID = 'your_access_key_id';
|
||||||
|
const ACCESS_KEY_SECRET = 'your_access_key_secret';
|
||||||
|
const ENDPOINT = 'oss-cn-hangzhou.aliyuncs.com';
|
||||||
|
const BUCKET = 'your_bucket_name';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取OSS客户端实例
|
||||||
|
* @return OssClient
|
||||||
|
* @throws OssException
|
||||||
|
*/
|
||||||
|
public static function getClient()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return new OssClient(
|
||||||
|
self::ACCESS_KEY_ID,
|
||||||
|
self::ACCESS_KEY_SECRET,
|
||||||
|
self::ENDPOINT
|
||||||
|
);
|
||||||
|
} catch (OssException $e) {
|
||||||
|
throw new OssException('创建OSS客户端失败:' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件到OSS
|
||||||
|
* @param string $filePath 本地文件路径
|
||||||
|
* @param string $objectName OSS对象名称
|
||||||
|
* @return array
|
||||||
|
* @throws OssException
|
||||||
|
*/
|
||||||
|
public static function uploadFile($filePath, $objectName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$client = self::getClient();
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
$result = $client->uploadFile(self::BUCKET, $objectName, $filePath);
|
||||||
|
|
||||||
|
// 获取文件访问URL
|
||||||
|
$url = $client->signUrl(self::BUCKET, $objectName, 3600);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'url' => $url,
|
||||||
|
'object_name' => $objectName,
|
||||||
|
'size' => filesize($filePath),
|
||||||
|
'mime_type' => mime_content_type($filePath)
|
||||||
|
];
|
||||||
|
} catch (OssException $e) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成OSS对象名称
|
||||||
|
* @param string $originalName 原始文件名
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function generateObjectName($originalName)
|
||||||
|
{
|
||||||
|
$ext = pathinfo($originalName, PATHINFO_EXTENSION);
|
||||||
|
$name = md5(uniqid(mt_rand(), true));
|
||||||
|
return date('Y/m/d/') . $name . '.' . $ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace app\common;
|
namespace app\common\util;
|
||||||
|
|
||||||
use Darabonba\OpenApi\Models\Config;
|
use Darabonba\OpenApi\Models\Config;
|
||||||
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
|
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
|
||||||
Reference in New Issue
Block a user