feat: 支持文件下载
This commit is contained in:
parent
d516330a41
commit
870276fa48
@ -382,6 +382,9 @@ class FileController extends AbstractController
|
|||||||
* @apiParam {Number|String} id
|
* @apiParam {Number|String} id
|
||||||
* - Number 文件ID(需要登录)
|
* - Number 文件ID(需要登录)
|
||||||
* - String 链接码(不需要登录,用于预览)
|
* - String 链接码(不需要登录,用于预览)
|
||||||
|
* @apiParam {String} down 直接下载
|
||||||
|
* - no: 浏览(默认)
|
||||||
|
* - yes: 下载
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -390,6 +393,7 @@ class FileController extends AbstractController
|
|||||||
public function content()
|
public function content()
|
||||||
{
|
{
|
||||||
$id = Request::input('id');
|
$id = Request::input('id');
|
||||||
|
$down = Request::input('down', 'no');
|
||||||
//
|
//
|
||||||
if (Base::isNumber($id)) {
|
if (Base::isNumber($id)) {
|
||||||
User::auth();
|
User::auth();
|
||||||
@ -405,7 +409,7 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
$content = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
$content = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
||||||
return FileContent::formatContent($file->type, $content ? $content->content : []);
|
return FileContent::formatContent($file, $content?->content, $down == 'yes');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,22 +41,24 @@ class FileContent extends AbstractModel
|
|||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取格式内容
|
* 获取格式内容(或下载)
|
||||||
* @param $type
|
* @param File $file
|
||||||
* @param $content
|
* @param $content
|
||||||
|
* @param $download
|
||||||
* @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
* @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||||
*/
|
*/
|
||||||
public static function formatContent($type, $content)
|
public static function formatContent($file, $content, $download = false)
|
||||||
{
|
{
|
||||||
$content = Base::json2array($content);
|
$name = $file->ext ? "{$file->name}.{$file->ext}" : null;
|
||||||
if (in_array($type, ['word', 'excel', 'ppt'])) {
|
$content = Base::json2array($content ?: []);
|
||||||
|
if (in_array($file->type, ['word', 'excel', 'ppt'])) {
|
||||||
if (empty($content)) {
|
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)) {
|
if (empty($content)) {
|
||||||
$content = match ($type) {
|
$content = match ($file->type) {
|
||||||
'document' => [
|
'document' => [
|
||||||
"type" => "md",
|
"type" => "md",
|
||||||
"content" => "",
|
"content" => "",
|
||||||
@ -69,15 +71,24 @@ class FileContent extends AbstractModel
|
|||||||
],
|
],
|
||||||
default => json_decode('{}'),
|
default => json_decode('{}'),
|
||||||
};
|
};
|
||||||
|
if ($download) {
|
||||||
|
abort(403, "This file is empty.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$content['preview'] = false;
|
$content['preview'] = false;
|
||||||
if ($content['ext'] && !in_array($content['ext'], ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'])) {
|
if ($file->ext && !in_array($file->ext, ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'])) {
|
||||||
$url = 'http://' . env('APP_IPPR') . '.3/' . $content['url'];
|
if ($download) {
|
||||||
if (in_array($type, ['picture', 'image', 'tif', 'media'])) {
|
return Response::download(public_path($content['url']), $name);
|
||||||
|
}
|
||||||
|
if (in_array($file->type, ['picture', 'image', 'tif', 'media'])) {
|
||||||
$url = Base::fillUrl($content['url']);
|
$url = Base::fillUrl($content['url']);
|
||||||
|
} else {
|
||||||
|
$url = 'http://' . env('APP_IPPR') . '.3/' . $content['url'];
|
||||||
}
|
}
|
||||||
$content['url'] = base64_encode($url);
|
$content['url'] = base64_encode($url);
|
||||||
$content['preview'] = true;
|
$content['preview'] = true;
|
||||||
|
} elseif ($download) {
|
||||||
|
abort(403, "This file not support download.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Base::retSuccess('success', [ 'content' => $content ]);
|
return Base::retSuccess('success', [ 'content' => $content ]);
|
||||||
|
@ -104,8 +104,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="file-menu" :style="contextMenuStyles">
|
<div class="file-menu" :style="contextMenuStyles">
|
||||||
<Dropdown trigger="custom" :visible="contextMenuVisible" transfer @on-clickoutside="handleClickContextMenuOutside" @on-visible-change="handleVisibleChangeMenu">
|
<Dropdown
|
||||||
<DropdownMenu slot="list" class="page-file-dropdown-menu">
|
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">
|
<template v-if="contextMenuItem.id">
|
||||||
<DropdownItem @click.native="handleContextClick('open')">{{$L('打开')}}</DropdownItem>
|
<DropdownItem @click.native="handleContextClick('open')">{{$L('打开')}}</DropdownItem>
|
||||||
<Dropdown placement="right-start" transfer>
|
<Dropdown placement="right-start" transfer>
|
||||||
@ -133,6 +139,7 @@
|
|||||||
<template v-else-if="contextMenuItem.share">
|
<template v-else-if="contextMenuItem.share">
|
||||||
<DropdownItem @click.native="handleContextClick('outshare')" divided>{{$L('退出共享')}}</DropdownItem>
|
<DropdownItem @click.native="handleContextClick('outshare')" divided>{{$L('退出共享')}}</DropdownItem>
|
||||||
</template>
|
</template>
|
||||||
|
<DropdownItem @click.native="handleContextClick('download')" :disabled="contextMenuItem.ext == ''">{{$L('下载')}}</DropdownItem>
|
||||||
<DropdownItem @click.native="handleContextClick('delete')" divided style="color:red">{{$L('删除')}}</DropdownItem>
|
<DropdownItem @click.native="handleContextClick('delete')" divided style="color:red">{{$L('删除')}}</DropdownItem>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@ -902,6 +909,30 @@ export default {
|
|||||||
this.linkGet()
|
this.linkGet()
|
||||||
break;
|
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':
|
case 'delete':
|
||||||
let typeName = item.type == 'folder' ? '文件夹' : '文件';
|
let typeName = item.type == 'folder' ? '文件夹' : '文件';
|
||||||
$A.modalConfirm({
|
$A.modalConfirm({
|
||||||
|
1
resources/assets/sass/pages/page-file.scss
vendored
1
resources/assets/sass/pages/page-file.scss
vendored
@ -509,6 +509,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page-file-dropdown-menu {
|
.page-file-dropdown-menu {
|
||||||
|
max-height: none !important;
|
||||||
.ivu-dropdown {
|
.ivu-dropdown {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.arrow-forward-item {
|
.arrow-forward-item {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user