batch-zip-btn功能实现
今天写的有点多了 有点烦躁起来了
This commit is contained in:
parent
e7eed036f1
commit
a8902fd449
@ -22,7 +22,11 @@
|
|||||||
"bestyii/yii2-gii-rest": "*",
|
"bestyii/yii2-gii-rest": "*",
|
||||||
"bestyii/yii2-openapi-reader": "dev-master",
|
"bestyii/yii2-openapi-reader": "dev-master",
|
||||||
"fortawesome/font-awesome": "^6.5",
|
"fortawesome/font-awesome": "^6.5",
|
||||||
"ext-zip": "*"
|
"ext-zip": "*",
|
||||||
|
"ext-rar": "*",
|
||||||
|
"wapmorgan/unified-archive": "^1.2",
|
||||||
|
"symfony/console": "^6.1",
|
||||||
|
"gemorroj/archive7z": "^5.7"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"yiisoft/yii2-debug": "~2.1.0",
|
"yiisoft/yii2-debug": "~2.1.0",
|
||||||
|
@ -5,7 +5,11 @@ namespace app\controllers;
|
|||||||
use app\models\NewFolderForm;
|
use app\models\NewFolderForm;
|
||||||
use app\models\RenameForm;
|
use app\models\RenameForm;
|
||||||
use app\models\UploadForm;
|
use app\models\UploadForm;
|
||||||
|
use app\models\ZipForm;
|
||||||
use app\utils\FileTypeDetector;
|
use app\utils\FileTypeDetector;
|
||||||
|
use wapmorgan\UnifiedArchive\Exceptions\FileAlreadyExistsException;
|
||||||
|
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
|
||||||
|
use wapmorgan\UnifiedArchive\UnifiedArchive;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\bootstrap5\ActiveForm;
|
use yii\bootstrap5\ActiveForm;
|
||||||
use yii\filters\VerbFilter;
|
use yii\filters\VerbFilter;
|
||||||
@ -36,6 +40,7 @@ class HomeController extends Controller
|
|||||||
'new-folder' => ['POST'],
|
'new-folder' => ['POST'],
|
||||||
'download-folder' => ['GET'],
|
'download-folder' => ['GET'],
|
||||||
'multi-ff-zip-dl' => ['POST'],
|
'multi-ff-zip-dl' => ['POST'],
|
||||||
|
'zip' => ['POST'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
@ -61,7 +66,7 @@ class HomeController extends Controller
|
|||||||
if ($directory === '.' || $directory == null) {
|
if ($directory === '.' || $directory == null) {
|
||||||
$directory = null;
|
$directory = null;
|
||||||
$parentDirectory = null;
|
$parentDirectory = null;
|
||||||
} elseif ($directory === '..' || str_contains($directory, '../')) {
|
} elseif (str_contains($directory, '..')) {
|
||||||
throw new NotFoundHttpException('Invalid directory.');
|
throw new NotFoundHttpException('Invalid directory.');
|
||||||
} else {
|
} else {
|
||||||
$parentDirectory = dirname($directory);
|
$parentDirectory = dirname($directory);
|
||||||
@ -127,7 +132,7 @@ class HomeController extends Controller
|
|||||||
$relativePath = rawurldecode($relativePath);
|
$relativePath = rawurldecode($relativePath);
|
||||||
|
|
||||||
// 检查相对路径是否只包含允许的字符
|
// 检查相对路径是否只包含允许的字符
|
||||||
if (!preg_match($this->pattern, $relativePath) || $relativePath === '.' || $relativePath === '..' || str_contains($relativePath, '../')) {
|
if (!preg_match($this->pattern, $relativePath) || str_contains($relativePath, '..')) {
|
||||||
throw new NotFoundHttpException('Invalid file path.');
|
throw new NotFoundHttpException('Invalid file path.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +168,7 @@ class HomeController extends Controller
|
|||||||
$relativePath = rawurldecode($relativePath);
|
$relativePath = rawurldecode($relativePath);
|
||||||
|
|
||||||
// 检查相对路径是否只包含允许的字符
|
// 检查相对路径是否只包含允许的字符
|
||||||
if (!preg_match($this->pattern, $relativePath) || $relativePath === '.' || $relativePath === '..' || str_contains($relativePath, '../')) {
|
if (!preg_match($this->pattern, $relativePath) || str_contains($relativePath, '..')) {
|
||||||
throw new NotFoundHttpException('Invalid file path.');
|
throw new NotFoundHttpException('Invalid file path.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +212,7 @@ class HomeController extends Controller
|
|||||||
{
|
{
|
||||||
$relativePath = Yii::$app->request->post('relativePath');
|
$relativePath = Yii::$app->request->post('relativePath');
|
||||||
$relativePath = rawurldecode($relativePath);
|
$relativePath = rawurldecode($relativePath);
|
||||||
if (!preg_match($this->pattern, $relativePath) || $relativePath === '.' || $relativePath === '..' || str_contains($relativePath, '../')) {
|
if (!preg_match($this->pattern, $relativePath) || str_contains($relativePath, '..')) {
|
||||||
throw new NotFoundHttpException('Invalid file path.');
|
throw new NotFoundHttpException('Invalid file path.');
|
||||||
}
|
}
|
||||||
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
||||||
@ -282,7 +287,7 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
foreach ($uploadedFiles as $uploadedFile) {
|
foreach ($uploadedFiles as $uploadedFile) {
|
||||||
$model->uploadFile = $uploadedFile;
|
$model->uploadFile = $uploadedFile;
|
||||||
if (!preg_match($this->pattern, $model->uploadFile->fullPath) || $model->uploadFile->fullPath === '.' || $model->uploadFile->fullPath === '..' || str_contains($model->uploadFile->fullPath, '../')) {
|
if (!preg_match($this->pattern, $model->uploadFile->fullPath) || str_contains($model->uploadFile->fullPath, '..')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($model->upload()) {
|
if ($model->upload()) {
|
||||||
@ -360,7 +365,7 @@ class HomeController extends Controller
|
|||||||
public function actionDownloadFolder($relativePath)
|
public function actionDownloadFolder($relativePath)
|
||||||
{
|
{
|
||||||
$relativePath = rawurldecode($relativePath);
|
$relativePath = rawurldecode($relativePath);
|
||||||
if (!preg_match($this->pattern, $relativePath) || $relativePath === '.' || $relativePath === '..' || str_contains($relativePath, '../')) {
|
if (!preg_match($this->pattern, $relativePath) || str_contains($relativePath, '..')) {
|
||||||
throw new NotFoundHttpException('Invalid path.');
|
throw new NotFoundHttpException('Invalid path.');
|
||||||
}
|
}
|
||||||
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
||||||
@ -416,7 +421,7 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
foreach ($relativePaths as $relativePath) {
|
foreach ($relativePaths as $relativePath) {
|
||||||
// 检查相对路径是否只包含允许的字符
|
// 检查相对路径是否只包含允许的字符
|
||||||
if (!preg_match($this->pattern, $relativePath) || $relativePath === '.' || $relativePath === '..' || str_contains($relativePath, '../')) {
|
if (!preg_match($this->pattern, $relativePath) || str_contains($relativePath, '..')) {
|
||||||
throw new NotFoundHttpException('Invalid file path.');
|
throw new NotFoundHttpException('Invalid file path.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,15 +456,12 @@ class HomeController extends Controller
|
|||||||
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
||||||
|
|
||||||
if (is_file($absolutePath)) {
|
if (is_file($absolutePath)) {
|
||||||
// 如果是文件,直接添加到 zip 文件
|
|
||||||
$zip->addFile($absolutePath, $relativePath);
|
$zip->addFile($absolutePath, $relativePath);
|
||||||
} else if (is_dir($absolutePath)) {
|
} else if (is_dir($absolutePath)) {
|
||||||
// 如果是目录,获取目录中的所有文件并添加到 zip 文件
|
|
||||||
$files = new \RecursiveIteratorIterator(
|
$files = new \RecursiveIteratorIterator(
|
||||||
new \RecursiveDirectoryIterator($absolutePath),
|
new \RecursiveDirectoryIterator($absolutePath),
|
||||||
\RecursiveIteratorIterator::LEAVES_ONLY
|
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($files as $name => $file) {
|
foreach ($files as $name => $file) {
|
||||||
if (!$file->isDir()) {
|
if (!$file->isDir()) {
|
||||||
$filePath = $file->getRealPath();
|
$filePath = $file->getRealPath();
|
||||||
@ -470,11 +472,43 @@ class HomeController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$zip->close();
|
$zip->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送下载
|
|
||||||
return Yii::$app->response->sendFile($zipPath);
|
return Yii::$app->response->sendFile($zipPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function actionZip()
|
||||||
|
{
|
||||||
|
$model = new ZipForm();
|
||||||
|
$relativePaths = json_decode(Yii::$app->request->post('relativePath'), true);
|
||||||
|
$targetDirectory = Yii::$app->request->post('targetDirectory')??'.';
|
||||||
|
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
|
||||||
|
if (str_contains($targetDirectory, '..')) {
|
||||||
|
throw new NotFoundHttpException('Invalid target directory.');
|
||||||
|
} elseif (!is_dir(Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $targetDirectory)) {
|
||||||
|
throw new NotFoundHttpException('Directory not found.');
|
||||||
|
}
|
||||||
|
$absolutePaths = [];
|
||||||
|
foreach ($relativePaths as $relativePath) {
|
||||||
|
if (!preg_match($this->pattern, $relativePath) || str_contains($relativePath, '..')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
|
||||||
|
if (!file_exists($absolutePath)) {
|
||||||
|
throw new NotFoundHttpException('The requested file does not exist.');
|
||||||
|
}
|
||||||
|
$absolutePaths[] = $absolutePath;
|
||||||
|
}
|
||||||
|
$zipPath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $targetDirectory . '/' . $model->zipFilename . '.' . $model->zipFormat;
|
||||||
|
try {
|
||||||
|
UnifiedArchive::create($absolutePaths, $zipPath);
|
||||||
|
Yii::$app->session->setFlash('success', '打包成功');
|
||||||
|
} catch (FileAlreadyExistsException $e) {
|
||||||
|
Yii::$app->session->setFlash('error', '目标文件夹已存在同名压缩档案');
|
||||||
|
} catch (UnsupportedOperationException $e) {
|
||||||
|
Yii::$app->session->setFlash('error', '不支持的操作');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->redirect(['index', 'directory' => $targetDirectory]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class NewFolderForm extends Model
|
|||||||
|
|
||||||
public function validateRelativePath($attribute, $params, $validator)
|
public function validateRelativePath($attribute, $params, $validator)
|
||||||
{
|
{
|
||||||
if (str_contains($this->$attribute, '../') || str_contains($this->$attribute, '..')) {
|
if (str_contains($this->$attribute, '..')) {
|
||||||
$this->addError($attribute, 'Invalid file path.');
|
$this->addError($attribute, 'Invalid file path.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
models/ZipForm.php
Normal file
30
models/ZipForm.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use yii\base\Model;
|
||||||
|
|
||||||
|
class ZipForm extends Model
|
||||||
|
{
|
||||||
|
public $zipFilename;
|
||||||
|
public $zipFormat;
|
||||||
|
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['zipFilename', 'zipFormat'], 'required'],
|
||||||
|
['zipFilename', 'string', 'max' => 255],
|
||||||
|
['zipFormat', 'in', 'range' => ['zip', '7z']],
|
||||||
|
['zipFilename', 'match', 'pattern' => '/^[^\p{C}\/:*?"<>|\\\\]+$/u', 'message' => 'Invalid file name.'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'zipFilename' => '压缩文件名',
|
||||||
|
'zipFormat' => '压缩格式',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
use app\models\NewFolderForm;
|
use app\models\NewFolderForm;
|
||||||
use app\models\RenameForm;
|
use app\models\RenameForm;
|
||||||
|
use app\models\ZipForm;
|
||||||
use yii\bootstrap5\ActiveForm;
|
use yii\bootstrap5\ActiveForm;
|
||||||
use yii\bootstrap5\Html;
|
use yii\bootstrap5\Html;
|
||||||
use app\assets\FontAwesomeAsset;
|
use app\assets\FontAwesomeAsset;
|
||||||
@ -211,6 +212,22 @@ echo Html::submitButton('提交', ['class' => 'btn btn-primary']);
|
|||||||
ActiveForm::end();
|
ActiveForm::end();
|
||||||
Modal::end();
|
Modal::end();
|
||||||
|
|
||||||
|
Modal::begin([
|
||||||
|
'title' => '<h4>创建压缩文件</h4>',
|
||||||
|
'id' => 'zipModal',
|
||||||
|
'size' => 'modal-lg',
|
||||||
|
]);
|
||||||
|
$model2 = new ZipForm();
|
||||||
|
$form = ActiveForm::begin(['id' => 'zip-form', 'action' => ['home/zip'], 'method' => 'post']);
|
||||||
|
|
||||||
|
echo $form->field($model2, 'zipFilename')->textInput(['maxlength' => true])->label('压缩文件名');
|
||||||
|
echo $form->field($model2, 'zipFormat')->dropDownList(['zip' => 'ZIP', '7z' => '7Z'])->label('压缩格式');
|
||||||
|
echo Html::hiddenInput('relativePath', '', ['id' => 'zipRelativePath']);
|
||||||
|
echo Html::hiddenInput('targetDirectory', $directory, ['id' => 'zipTargetDirectory']); // 添加这一行
|
||||||
|
echo Html::submitButton('创建', ['class' => 'btn btn-primary']);
|
||||||
|
|
||||||
|
ActiveForm::end();
|
||||||
|
Modal::end();
|
||||||
$this->registerJsFile('@web/js/home_script.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]);
|
$this->registerJsFile('@web/js/home_script.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ $(document).on('click', '.batch-zip-download-btn', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 将相对路径添加到表单中
|
// 将相对路径添加到表单中
|
||||||
$.each(relativePaths, function(index, value) {
|
$.each(relativePaths, function (index, value) {
|
||||||
form.append($('<input>', {
|
form.append($('<input>', {
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
name: 'relativePaths[]',
|
name: 'relativePaths[]',
|
||||||
@ -88,10 +88,17 @@ $(document).on('click', '.batch-zip-download-btn', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('click', '.batch-zip-btn', function () {
|
$(document).on('click', '.batch-zip-btn', function () {
|
||||||
console.log('打包按钮被点击');
|
var relativePaths = $('.select-item:checked').map(function () {
|
||||||
// 在这里添加你的代码
|
return $(this).data('relativePath');
|
||||||
|
}).get();
|
||||||
|
$('#zipRelativePath').val(JSON.stringify(relativePaths));
|
||||||
|
$('#zipModal').modal('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(document).on('click', '.unzip-btn', function () {
|
$(document).on('click', '.unzip-btn', function () {
|
||||||
console.log('解压按钮被点击');
|
console.log('解压按钮被点击');
|
||||||
// 在这里添加你的代码
|
// 在这里添加你的代码
|
||||||
|
Loading…
Reference in New Issue
Block a user