实现分享、访问分享功能

This commit is contained in:
Chenx221 2024-02-17 16:43:39 +08:00
parent 3bba14059b
commit 4c1bcf0da2
Signed by: chenx221
GPG Key ID: D7A9EC07024C3021
9 changed files with 236 additions and 13 deletions

View File

@ -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('异常,文件不存在');
}
}
}

View File

@ -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;
}
}

View File

@ -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' => '<h4>创建分享</h4>',
'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('&nbsp;', 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]);
?>

View File

@ -0,0 +1,30 @@
<?php
/** @var yii\web\View $this */
/** @var app\models\Share $model */
/** @var bool $isDirectory */
/** @var string $sharerUsername */
use yii\bootstrap5\Html;
use yii\helpers\Url;
$this->title = '文件信息';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="share-file-info">
<h1><?= Html::encode($this->title) ?></h1>
<p>分享者: <?= Html::encode($sharerUsername) ?></p> <!-- 显示分享者的用户名 -->
<p>分享创建日期: <?= Html::encode($model->creation_date) ?></p>
<p>
<?php
if ($isDirectory) {
// 如果是目录,显示 "下载文件夹" 按钮
echo Html::a('下载文件夹', Url::to(['share/download', 'share_id' => $model->share_id]), ['class' => 'btn btn-primary']);
} else {
// 如果是文件,显示 "下载文件" 按钮
echo Html::a('下载文件', Url::to(['share/download', 'share_id' => $model->share_id]), ['class' => 'btn btn-primary']);
}
?> </p>
</div>

26
views/share/access.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/** @var yii\web\View $this */
/** @var app\models\Share $model */
use yii\bootstrap5\ActiveForm;
use yii\bootstrap5\Html;
$this->title = '访问分享';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="share-access">
<h1><?= Html::encode($this->title) ?></h1>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'access_code')->passwordInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton('提交', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

View File

@ -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]);
}

View File

@ -1,23 +1,29 @@
<?php
use yii\helpers\Html;
use yii\web\JqueryAsset;
use yii\web\View;
use yii\web\YiiAsset;
use yii\widgets\DetailView;
/** @var yii\web\View $this */
/** @var app\models\Share $model */
$this->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);
?>
<div class="share-view">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Update', ['update', 'share_id' => $model->share_id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'share_id' => $model->share_id], [
<?= Html::a('复制分享链接', null, ['class' => 'btn btn-primary', 'id' => 'copy-link-button']) ?>
<?= Html::a('访问分享链接', ['share/access', 'share_id' => $model->share_id], ['class' => 'btn btn-primary', 'target' => '_blank']) ?>
<?= Html::a('修改分享', ['update', 'share_id' => $model->share_id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('取消分享', ['delete', 'share_id' => $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;
]) ?>
</div>
<?php
$this->registerJsFile('@web/js/share_view.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]);
?>

View File

@ -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 () {

11
web/js/share_view.js Normal file
View File

@ -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);
});
});
});