diff --git a/controllers/ShareController.php b/controllers/ShareController.php index 8576e9e..d1be71e 100644 --- a/controllers/ShareController.php +++ b/controllers/ShareController.php @@ -6,6 +6,7 @@ use app\models\Share; use app\models\ShareSearch; use Yii; use yii\web\Controller; +use yii\web\ForbiddenHttpException; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use yii\web\Response; @@ -67,12 +68,26 @@ class ShareController extends Controller * If creation is successful, the browser will be redirected to the 'view' page. * @return string|Response */ - public function actionCreate() + public function actionCreate(): Response|string { $model = new Share(); if ($this->request->isPost) { if ($model->load($this->request->post())) { + //对access_code进行检测 + if (empty($model->access_code) || !preg_match('/^[a-zA-Z0-9]{4}$/', $model->access_code)) { + Yii::$app->session->setFlash('error', '访问密码必须是4位字母和数字的组合'); + return $this->render('create', ['model' => $model]); + } + + //对file_relative_path进行检测 + $absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $model->file_relative_path; + if (!file_exists($absolutePath)) { + Yii::$app->session->setFlash('error', '文件或文件夹不存在'); + return $this->render('create', ['model' => $model]); + } + + $model->access_code = strtolower($model->access_code); $model->sharer_id = Yii::$app->user->id; // 自动设置 sharer_id 为当前用户的 ID if ($model->save()) { return $this->redirect(['view', 'share_id' => $model->share_id]); @@ -143,4 +158,70 @@ class ShareController extends Controller throw new NotFoundHttpException('The requested page does not exist.'); } + + public function actionAccess($share_id, $access_code = null) + { + if ($this->request->isPost) { + $model = $this->findModel($share_id); + $access_code = $this->request->post('Share')['access_code']; + if ($access_code === $model->access_code) { + // 访问密码正确,显示文件信息和下载按钮 + $access_granted = Yii::$app->session->get('access_granted', []); + $access_granted[$share_id] = true; + Yii::$app->session->set('access_granted', $access_granted); // 将访问权限信息存储到 session 中 + $absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . $model->sharer_id . '/' . $model->file_relative_path; + $isDirectory = is_dir($absolutePath); + $sharerUsername = $model->getSharerUsername(); + return $this->render('_file_info', [ + 'model' => $model, + 'isDirectory' => $isDirectory, + 'sharerUsername' => $sharerUsername, + ]); + } else { + Yii::$app->session->setFlash('error', '访问密码错误'); + } + } + $model = new Share(); + $model->access_code = $access_code; + + return $this->render('access', [ + 'model' => $model, + ]); + } + + /** + * @throws ForbiddenHttpException + * @throws NotFoundHttpException + */ + public function actionDownload($share_id) + { + $access_granted = Yii::$app->session->get('access_granted', []); + if (!isset($access_granted[$share_id]) || !$access_granted[$share_id]) { + throw new \yii\web\ForbiddenHttpException('你没有权限下载这个文件'); + } + + $model = $this->findModel($share_id); + + $absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . $model->sharer_id . '/' . $model->file_relative_path; + if (is_file($absolutePath)) { + return Yii::$app->response->sendFile($absolutePath); + } else if (is_dir($absolutePath)) { + // 如果是文件夹,压缩后发送 + $zipPath = $absolutePath . '.zip'; + $zip = new \ZipArchive(); + $zip->open($zipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); + $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($absolutePath)); + foreach ($files as $file) { + if (!$file->isDir()) { + $filePath = $file->getRealPath(); + $relativePath = substr($filePath, strlen($absolutePath) + 1); + $zip->addFile($filePath, $relativePath); + } + } + $zip->close(); + return Yii::$app->response->sendFile($zipPath); + }else{ + throw new NotFoundHttpException('异常,文件不存在'); + } + } } diff --git a/models/Share.php b/models/Share.php index a2f5dce..e16f82a 100644 --- a/models/Share.php +++ b/models/Share.php @@ -65,4 +65,8 @@ class Share extends \yii\db\ActiveRecord { return $this->hasOne(User::class, ['id' => 'sharer_id']); } + public function getSharerUsername() + { + return $this->sharer->username; + } } diff --git a/views/home/index.php b/views/home/index.php index 6a686aa..388add8 100644 --- a/views/home/index.php +++ b/views/home/index.php @@ -8,6 +8,7 @@ use app\models\NewFolderForm; use app\models\RenameForm; +use app\models\Share; use app\models\ZipForm; use yii\bootstrap5\ActiveForm; use yii\bootstrap5\Html; @@ -236,6 +237,22 @@ Modal::begin([ echo Html::tag('p', '', ['id' => 'crc32b']); echo Html::tag('p', '', ['id' => 'sha256']); Modal::end(); + +Modal::begin([ + 'title' => '

创建分享

', + 'id' => 'shareModal', +// 'size' => 'modal-sm', +]); +$form = ActiveForm::begin(['id' => 'share-form', 'action' => ['share/create'], 'method' => 'post']); +$model3 = new Share(); +echo $form->field($model3, 'file_relative_path')->textInput(['readonly' => true])->label('文件位置'); +echo $form->field($model3, 'access_code')->textInput(['maxlength' => 4])->label('访问密码(4位英文数字组合,不区分大小写)'); +echo Html::button('生成密码', ['id' => 'generate_access_code', 'class' => 'btn btn-primary']); +echo str_repeat(' ', 5); // 添加5个空格 +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]); ?> diff --git a/views/share/_file_info.php b/views/share/_file_info.php new file mode 100644 index 0000000..724fa56 --- /dev/null +++ b/views/share/_file_info.php @@ -0,0 +1,30 @@ +title = '文件信息'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ +

分享者:

+

分享创建日期: creation_date) ?>

+ +

+ $model->share_id]), ['class' => 'btn btn-primary']); + } else { + // 如果是文件,显示 "下载文件" 按钮 + echo Html::a('下载文件', Url::to(['share/download', 'share_id' => $model->share_id]), ['class' => 'btn btn-primary']); + } + ?>

+ +
\ No newline at end of file diff --git a/views/share/access.php b/views/share/access.php new file mode 100644 index 0000000..6b9d88a --- /dev/null +++ b/views/share/access.php @@ -0,0 +1,26 @@ +title = '访问分享'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ + + + field($model, 'access_code')->passwordInput(['maxlength' => true]) ?> + +
+ 'btn btn-primary']) ?> +
+ + + +
\ No newline at end of file diff --git a/views/share/index.php b/views/share/index.php index 59ad186..06c4ff9 100644 --- a/views/share/index.php +++ b/views/share/index.php @@ -27,15 +27,29 @@ $this->params['breadcrumbs'][] = $this->title; 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [ - ['class' => 'yii\grid\SerialColumn'], - - 'share_id', + ['class' => 'yii\grid\SerialColumn', + 'headerOptions' => ['style' => 'width:4%;'], + ], + [ + 'attribute' => 'share_id', + 'headerOptions' => ['style' => 'width:6%;'], + ], // 'sharer_id', - 'file_relative_path', - 'access_code', - 'creation_date', + [ + 'attribute' => 'file_relative_path', + 'headerOptions' => ['style' => 'width:60%;'], + ], + [ + 'attribute' => 'access_code', + 'headerOptions' => ['style' => 'width:7%;'], + ], + [ + 'attribute' => 'creation_date', + 'headerOptions' => ['style' => 'width:15%;'], + ], [ 'class' => ActionColumn::className(), + 'headerOptions' => ['style' => 'width:8%;'], 'urlCreator' => function ($action, Share $model, $key, $index, $column) { return Url::toRoute([$action, 'share_id' => $model->share_id]); } diff --git a/views/share/view.php b/views/share/view.php index a622de8..85d5432 100644 --- a/views/share/view.php +++ b/views/share/view.php @@ -1,23 +1,29 @@ title = $model->share_id; +$this->title = '分享ID '.$model->share_id; $this->params['breadcrumbs'][] = ['label' => 'Shares', 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; -\yii\web\YiiAsset::register($this); +YiiAsset::register($this); +JqueryAsset::register($this); ?>

title) ?>

- $model->share_id], ['class' => 'btn btn-primary']) ?> - $model->share_id], [ + 'btn btn-primary', 'id' => 'copy-link-button']) ?> + $model->share_id], ['class' => 'btn btn-primary', 'target' => '_blank']) ?> + $model->share_id], ['class' => 'btn btn-primary']) ?> + $model->share_id], [ 'class' => 'btn btn-danger', 'data' => [ 'confirm' => 'Are you sure you want to delete this item?', @@ -38,3 +44,6 @@ $this->params['breadcrumbs'][] = $this->title; ]) ?>

+registerJsFile('@web/js/share_view.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]); +?> diff --git a/web/js/home_script.js b/web/js/home_script.js index 0ae8cfb..4556286 100644 --- a/web/js/home_script.js +++ b/web/js/home_script.js @@ -188,8 +188,39 @@ $(document).on('click', '.calc-sum-btn', function () { }); $(document).on('click', '.single-share-btn', function () { - console.log('分享按钮被点击'); - // 在这里添加你的代码 + var relativePath = $('.select-item:checked').first().data('relativePath'); + $('#shareModal #share-file_relative_path').val(relativePath); + $('#shareModal').modal('show'); +}); +$(document).on('click', '#generate_access_code', function () { + var accessCode = Math.random().toString(36).substring(2, 6); + $('#shareModal #share-access_code').val(accessCode); +}); + +// $(document).on('submit', '#share-form', function (event) { +// event.preventDefault(); +// +// var relativePath = $('#shareModal #share-file_relative_path').val(); +// var accessCode = $('#shareModal #share-access_code').val(); +// +// $.ajax({ +// type: "POST", +// url: "index.php?r=share%2Fcreate", +// data: { file_relative_path: relativePath, access_code: accessCode }, +// success: function() { +// // 处理响应 +// location.reload(); +// }, +// error: function() { +// // 处理错误 +// console.error('AJAX request failed.'); +// } +// }); +// }); +$(document).on('click', '.shares-btn', function () { + var relativePath = $(this).closest('tr').find('.select-item').data('relativePath'); + $('#shareModal #share-file_relative_path').val(relativePath); + $('#shareModal').modal('show'); }); $(document).on('click', '.batch-delete-btn', function () { diff --git a/web/js/share_view.js b/web/js/share_view.js new file mode 100644 index 0000000..42fc274 --- /dev/null +++ b/web/js/share_view.js @@ -0,0 +1,11 @@ +$(document).ready(function() { + $('#copy-link-button').click(function() { + var shareId = $('table.detail-view tbody tr:first-child td').text(); + var shareLink = window.location.origin + '/index.php?r=share%2Faccess&share_id=' + shareId; + navigator.clipboard.writeText(shareLink).then(function() { + alert('分享链接已复制到剪贴板'); + }).catch(function(error) { + console.error('复制失败: ', error); + }); + }); +}); \ No newline at end of file