feat: 支持文件下载

This commit is contained in:
kuaifan 2022-01-24 14:28:48 +08:00
parent d516330a41
commit 870276fa48
4 changed files with 61 additions and 14 deletions

View File

@ -382,6 +382,9 @@ class FileController extends AbstractController
* @apiParam {Number|String} id
* - Number 文件ID需要登录
* - String 链接码(不需要登录,用于预览)
* @apiParam {String} down 直接下载
* - no: 浏览(默认)
* - yes: 下载
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -390,6 +393,7 @@ class FileController extends AbstractController
public function content()
{
$id = Request::input('id');
$down = Request::input('down', 'no');
//
if (Base::isNumber($id)) {
User::auth();
@ -405,7 +409,7 @@ class FileController extends AbstractController
}
//
$content = FileContent::whereFid($file->id)->orderByDesc('id')->first();
return FileContent::formatContent($file->type, $content ? $content->content : []);
return FileContent::formatContent($file, $content?->content, $down == 'yes');
}
/**

View File

@ -41,22 +41,24 @@ class FileContent extends AbstractModel
use SoftDeletes;
/**
* 获取格式内容
* @param $type
* 获取格式内容(或下载)
* @param File $file
* @param $content
* @param $download
* @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public static function formatContent($type, $content)
public static function formatContent($file, $content, $download = false)
{
$content = Base::json2array($content);
if (in_array($type, ['word', 'excel', 'ppt'])) {
$name = $file->ext ? "{$file->name}.{$file->ext}" : null;
$content = Base::json2array($content ?: []);
if (in_array($file->type, ['word', 'excel', 'ppt'])) {
if (empty($content)) {
return Response::download(resource_path('assets/statics/office/empty.' . str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $type)));
return Response::download(resource_path('assets/statics/office/empty.' . str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $file->type)), $name);
}
return Response::download(public_path($content['url']));
return Response::download(public_path($content['url']), $name);
}
if (empty($content)) {
$content = match ($type) {
$content = match ($file->type) {
'document' => [
"type" => "md",
"content" => "",
@ -69,15 +71,24 @@ class FileContent extends AbstractModel
],
default => json_decode('{}'),
};
if ($download) {
abort(403, "This file is empty.");
}
} else {
$content['preview'] = false;
if ($content['ext'] && !in_array($content['ext'], ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'])) {
$url = 'http://' . env('APP_IPPR') . '.3/' . $content['url'];
if (in_array($type, ['picture', 'image', 'tif', 'media'])) {
if ($file->ext && !in_array($file->ext, ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'])) {
if ($download) {
return Response::download(public_path($content['url']), $name);
}
if (in_array($file->type, ['picture', 'image', 'tif', 'media'])) {
$url = Base::fillUrl($content['url']);
} else {
$url = 'http://' . env('APP_IPPR') . '.3/' . $content['url'];
}
$content['url'] = base64_encode($url);
$content['preview'] = true;
} elseif ($download) {
abort(403, "This file not support download.");
}
}
return Base::retSuccess('success', [ 'content' => $content ]);

View File

@ -104,8 +104,14 @@
</template>
<div class="file-menu" :style="contextMenuStyles">
<Dropdown trigger="custom" :visible="contextMenuVisible" transfer @on-clickoutside="handleClickContextMenuOutside" @on-visible-change="handleVisibleChangeMenu">
<DropdownMenu slot="list" class="page-file-dropdown-menu">
<Dropdown
trigger="custom"
:visible="contextMenuVisible"
transfer-class-name="page-file-dropdown-menu"
@on-clickoutside="handleClickContextMenuOutside"
@on-visible-change="handleVisibleChangeMenu"
transfer>
<DropdownMenu slot="list">
<template v-if="contextMenuItem.id">
<DropdownItem @click.native="handleContextClick('open')">{{$L('打开')}}</DropdownItem>
<Dropdown placement="right-start" transfer>
@ -133,6 +139,7 @@
<template v-else-if="contextMenuItem.share">
<DropdownItem @click.native="handleContextClick('outshare')" divided>{{$L('退出共享')}}</DropdownItem>
</template>
<DropdownItem @click.native="handleContextClick('download')" :disabled="contextMenuItem.ext == ''">{{$L('下载')}}</DropdownItem>
<DropdownItem @click.native="handleContextClick('delete')" divided style="color:red">{{$L('删除')}}</DropdownItem>
</template>
<template v-else>
@ -902,6 +909,30 @@ export default {
this.linkGet()
break;
case 'download':
if (!item.ext) {
$A.modalError("此文件不支持下载");
return;
}
$A.modalConfirm({
title: '下载文件',
content: `${item.name}.${item.ext} (${$A.bytesToSize(item.size)})`,
okText: '立即下载',
onOk: () => {
let url = $A.apiUrl(`file/content?id=${item.id}&down=yes&token=${this.userToken}`);
if (this.$Electron) {
try {
this.$Electron.shell.openExternal(url);
} catch (e) {
$A.modalError("下载失败");
}
} else {
window.open(url)
}
}
});
break;
case 'delete':
let typeName = item.type == 'folder' ? '文件夹' : '文件';
$A.modalConfirm({

View File

@ -509,6 +509,7 @@
}
.page-file-dropdown-menu {
max-height: none !important;
.ivu-dropdown {
width: 100%;
.arrow-forward-item {