初步完成上传功能
为了个进度条整了一堆活 目前功能还没有完善(包括文件重复的检测)
This commit is contained in:
parent
efd40e3982
commit
468b37b85a
@ -3,6 +3,7 @@
|
|||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use app\models\RenameForm;
|
use app\models\RenameForm;
|
||||||
|
use app\models\UploadForm;
|
||||||
use app\utils\FileTypeDetector;
|
use app\utils\FileTypeDetector;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\filters\VerbFilter;
|
use yii\filters\VerbFilter;
|
||||||
@ -10,10 +11,12 @@ use yii\helpers\ArrayHelper;
|
|||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\NotFoundHttpException;
|
use yii\web\NotFoundHttpException;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
|
use yii\web\UploadedFile;
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
protected string $pattern = '/^[^\p{C}\/:*?"<>|\\\\]+$/u';
|
protected string $pattern = '/^[^\p{C}\/:*?"<>|\\\\]+$/u';
|
||||||
|
|
||||||
public function behaviors()
|
public function behaviors()
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
@ -26,6 +29,7 @@ class HomeController extends Controller
|
|||||||
'download' => ['GET'],
|
'download' => ['GET'],
|
||||||
'rename' => ['POST'],
|
'rename' => ['POST'],
|
||||||
'delete' => ['POST'],
|
'delete' => ['POST'],
|
||||||
|
'upload' => ['POST'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
@ -254,4 +258,39 @@ class HomeController extends Controller
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
* https://devs.chenx221.cyou:8081/index.php?r=home%2Fupload
|
||||||
|
*
|
||||||
|
* @return string|Response
|
||||||
|
*/
|
||||||
|
public function actionUpload()
|
||||||
|
{
|
||||||
|
$model = new UploadForm();
|
||||||
|
$model->targetDir = Yii::$app->request->post('targetDir', '.');
|
||||||
|
$uploadedFiles = UploadedFile::getInstancesByName('files');
|
||||||
|
$successCount = 0;
|
||||||
|
$totalCount = count($uploadedFiles);
|
||||||
|
|
||||||
|
foreach ($uploadedFiles as $uploadedFile) {
|
||||||
|
$model->uploadFile = $uploadedFile;
|
||||||
|
if (!preg_match($this->pattern, $model->uploadFile->baseName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($model->upload()) {
|
||||||
|
$successCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($successCount === $totalCount) {
|
||||||
|
Yii::$app->session->setFlash('success', 'All files uploaded successfully.');
|
||||||
|
} elseif ($successCount > 0) {
|
||||||
|
Yii::$app->session->setFlash('warning', 'Some files uploaded successfully.');
|
||||||
|
} else {
|
||||||
|
Yii::$app->session->setFlash('error', 'Failed to upload files.');
|
||||||
|
}
|
||||||
|
//返回状态码200
|
||||||
|
return Yii::$app->response->statusCode = 200; // 如果出错请删掉return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
48
models/UploadForm.php
Normal file
48
models/UploadForm.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* 这里的代码借鉴了 https://www.yiiframework.com/doc/guide/2.0/en/input-file-upload
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use yii\base\Model;
|
||||||
|
use yii\web\UploadedFile;
|
||||||
|
|
||||||
|
class UploadForm extends Model
|
||||||
|
{
|
||||||
|
public UploadedFile|null $uploadFile;
|
||||||
|
public $targetDir; //相对路径
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['uploadFile'], 'file', 'skipOnEmpty' => false, 'checkExtensionByMimeType' => false], //这规则奇怪的放走近科学都可以拍好几集了
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function upload()
|
||||||
|
{
|
||||||
|
if ($this->validate()) {
|
||||||
|
if ($this->targetDir === null) {
|
||||||
|
$this->targetDir = '.';
|
||||||
|
}
|
||||||
|
if (str_contains($this->targetDir, '..')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$userHomeDir = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id;
|
||||||
|
$absolutePath = $userHomeDir . '/' . $this->targetDir;
|
||||||
|
if (!is_dir($absolutePath)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$fileName = $this->uploadFile->baseName;
|
||||||
|
if ($this->uploadFile->extension !== '') {
|
||||||
|
$fileName .= '.' . $this->uploadFile->extension;
|
||||||
|
}
|
||||||
|
$this->uploadFile->saveAs($absolutePath . '/' . $fileName);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,12 @@
|
|||||||
/* @var $directory string 当前路径 */
|
/* @var $directory string 当前路径 */
|
||||||
|
|
||||||
use app\models\RenameForm;
|
use app\models\RenameForm;
|
||||||
|
use app\models\UploadForm;
|
||||||
use yii\bootstrap5\ActiveForm;
|
use yii\bootstrap5\ActiveForm;
|
||||||
use yii\bootstrap5\Html;
|
use yii\bootstrap5\Html;
|
||||||
use app\assets\FontAwesomeAsset;
|
use app\assets\FontAwesomeAsset;
|
||||||
use yii\bootstrap5\Modal;
|
use yii\bootstrap5\Modal;
|
||||||
|
use yii\bootstrap5\Progress;
|
||||||
use yii\helpers\Url;
|
use yii\helpers\Url;
|
||||||
use yii\web\JqueryAsset;
|
use yii\web\JqueryAsset;
|
||||||
use yii\web\View;
|
use yii\web\View;
|
||||||
@ -23,7 +25,7 @@ JqueryAsset::register($this);
|
|||||||
$this->registerCssFile('@web/css/home_style.css');
|
$this->registerCssFile('@web/css/home_style.css');
|
||||||
?>
|
?>
|
||||||
<div class="home-directory">
|
<div class="home-directory">
|
||||||
<div class="d-flex justify-content-between align-items-center" style="margin-bottom: 1rem;">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<h1><?= Html::encode($this->title) ?></h1>
|
<h1><?= Html::encode($this->title) ?></h1>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton"
|
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton"
|
||||||
@ -31,6 +33,10 @@ $this->registerCssFile('@web/css/home_style.css');
|
|||||||
<i class="fa-solid fa-arrow-up-from-bracket"></i> 上传文件
|
<i class="fa-solid fa-arrow-up-from-bracket"></i> 上传文件
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||||
|
<li hidden>
|
||||||
|
<input type="file" id="file-input" name="uploadFile" multiple>
|
||||||
|
<input type="hidden" name="targetDir" value="<?= $directory ?>" id="target-dir">
|
||||||
|
</li>
|
||||||
<li><?= Html::button('上传文件', ['class' => 'dropdown-item file-upload-btn']) ?></li>
|
<li><?= Html::button('上传文件', ['class' => 'dropdown-item file-upload-btn']) ?></li>
|
||||||
<li><?= Html::button('上传文件夹', ['class' => 'dropdown-item folder-upload-btn']) ?></li>
|
<li><?= Html::button('上传文件夹', ['class' => 'dropdown-item folder-upload-btn']) ?></li>
|
||||||
<li>
|
<li>
|
||||||
@ -41,6 +47,16 @@ $this->registerCssFile('@web/css/home_style.css');
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--上传进度条-->
|
||||||
|
<?php
|
||||||
|
echo Progress::widget([
|
||||||
|
'percent' => 0,
|
||||||
|
'barOptions' => ['class' => ['bg-success', 'progress-bar-animated', 'progress-bar-striped']],
|
||||||
|
'label' => '123', //NMD 不是说可选吗
|
||||||
|
'options' => ['style' => 'display: none;margin-top: 10px;', 'id' => 'progress-bar']
|
||||||
|
]);
|
||||||
|
?>
|
||||||
|
|
||||||
<nav style="--bs-breadcrumb-divider: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M2.5 0L1 1.5 3.5 4 1 6.5 2.5 8l4-4-4-4z' fill='%236c757d'/%3E%3C/svg%3E");"
|
<nav style="--bs-breadcrumb-divider: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M2.5 0L1 1.5 3.5 4 1 6.5 2.5 8l4-4-4-4z' fill='%236c757d'/%3E%3C/svg%3E");"
|
||||||
aria-label="breadcrumb">
|
aria-label="breadcrumb">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
|
@ -38,7 +38,8 @@ table a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
border-radius: 0.375rem;
|
/*border-radius: 0.375rem;*/
|
||||||
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb .breadcrumb-item {
|
.breadcrumb .breadcrumb-item {
|
||||||
|
@ -18,8 +18,36 @@ $(document).on('click', '.delete-btn', function () {
|
|||||||
$('#deleteModal').modal('show');
|
$('#deleteModal').modal('show');
|
||||||
});
|
});
|
||||||
$(document).on('click', '.file-upload-btn', function () {
|
$(document).on('click', '.file-upload-btn', function () {
|
||||||
console.log('你点击了上传文件,但功能尚未实现');
|
// 触发文件输入元素的点击事件
|
||||||
|
$('#file-input').click();
|
||||||
});
|
});
|
||||||
|
$('#file-input').on('change', function () {
|
||||||
|
$('#progress-bar').show();
|
||||||
|
var files = this.files;
|
||||||
|
var formData = new FormData();
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
formData.append('files[]', files[i]);
|
||||||
|
}
|
||||||
|
formData.append('targetDir', $('#target-dir').val());
|
||||||
|
formData.append('_csrf', $('meta[name="csrf-token"]').attr('content'));
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.upload.onprogress = function (event) {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
var percentComplete = event.loaded / event.total * 100;
|
||||||
|
$('#progress-bar .progress-bar').css('width', percentComplete + '%').text(Math.round(percentComplete) + '%');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (xhr.status !== 200) {
|
||||||
|
alert('An error occurred during the upload.');
|
||||||
|
}
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
xhr.open('POST', 'index.php?r=home%2Fupload');
|
||||||
|
xhr.send(formData);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
$(document).on('click', '.folder-upload-btn', function () {
|
$(document).on('click', '.folder-upload-btn', function () {
|
||||||
console.log('你点击了上传文件夹,但功能尚未实现');
|
console.log('你点击了上传文件夹,但功能尚未实现');
|
||||||
});
|
});
|
||||||
@ -65,7 +93,5 @@ dropArea.addEventListener('dragleave', function (event) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function uploadFile(file) {
|
|
||||||
console.log('准备上传,但功能尚未实现');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user