mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-17 03:03:41 +00:00
perf: 优化预览文件
This commit is contained in:
parent
4024aca002
commit
b758133f63
@ -13,6 +13,7 @@ use App\Module\Base;
|
|||||||
use App\Module\Ihttp;
|
use App\Module\Ihttp;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Redirect;
|
||||||
use Request;
|
use Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -447,7 +448,8 @@ class FileController extends AbstractController
|
|||||||
* - yes
|
* - yes
|
||||||
* @apiParam {String} down 直接下载
|
* @apiParam {String} down 直接下载
|
||||||
* - no: 浏览(默认)
|
* - no: 浏览(默认)
|
||||||
* - yes: 下载(office文件直接下载)
|
* - yes: 下载(office文件直接下载,除非是preview)
|
||||||
|
* - preview: 转预览地址
|
||||||
* @apiParam {Number} [history_id] 读取历史记录ID
|
* @apiParam {Number} [history_id] 读取历史记录ID
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
@ -486,6 +488,9 @@ class FileController extends AbstractController
|
|||||||
$builder->whereId($history_id);
|
$builder->whereId($history_id);
|
||||||
}
|
}
|
||||||
$content = $builder->orderByDesc('id')->first();
|
$content = $builder->orderByDesc('id')->first();
|
||||||
|
if ($down === 'preview') {
|
||||||
|
return Redirect::to(FileContent::formatPreview($file, $content?->content));
|
||||||
|
}
|
||||||
return FileContent::formatContent($file, $content?->content, $down == 'yes');
|
return FileContent::formatContent($file, $content?->content, $down == 'yes');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -381,6 +381,7 @@ class File extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
public static function formatFileData(array $data)
|
public static function formatFileData(array $data)
|
||||||
{
|
{
|
||||||
|
$fileName = $data['name'];
|
||||||
$filePath = $data['path'];
|
$filePath = $data['path'];
|
||||||
$fileSize = $data['size'];
|
$fileSize = $data['size'];
|
||||||
$fileExt = $data['ext'];
|
$fileExt = $data['ext'];
|
||||||
@ -436,9 +437,9 @@ class File extends AbstractModel
|
|||||||
}
|
}
|
||||||
if ($fileExt != 'pdf') {
|
if ($fileExt != 'pdf') {
|
||||||
$fileDotExt = ".{$fileExt}";
|
$fileDotExt = ".{$fileExt}";
|
||||||
$fileName = Base::rightDelete($data['name'], $fileDotExt) . $fileDotExt;
|
$fullFileName = Base::rightDelete($fileName, $fileDotExt) . $fileDotExt;
|
||||||
$url = Base::urlAddparameter($url, [
|
$url = Base::urlAddparameter($url, [
|
||||||
'fullfilename' => $fileName
|
'fullfilename' => $fullFileName
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$data['content'] = [
|
$data['content'] = [
|
||||||
|
|||||||
@ -40,6 +40,40 @@ class FileContent extends AbstractModel
|
|||||||
{
|
{
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转预览地址
|
||||||
|
* @param File $file
|
||||||
|
* @param $content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function formatPreview($file, $content)
|
||||||
|
{
|
||||||
|
$content = Base::json2array($content ?: []);
|
||||||
|
$filePath = $content['url'];
|
||||||
|
if (in_array($file->type, ['word', 'excel', 'ppt'])) {
|
||||||
|
if (empty($content)) {
|
||||||
|
$filePath = 'assets/office/empty.' . str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $file->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$fileExt = $file->ext;
|
||||||
|
$fileName = $file->name;
|
||||||
|
$fileSize = $file->size;
|
||||||
|
if (in_array($fileExt, File::localExt)) {
|
||||||
|
$url = Base::fillUrl($filePath);
|
||||||
|
} else {
|
||||||
|
$url = 'http://' . env('APP_IPPR') . '.3/' . $filePath;
|
||||||
|
}
|
||||||
|
if ($fileExt != 'pdf') {
|
||||||
|
$fileDotExt = ".{$fileExt}";
|
||||||
|
$fullFileName = Base::rightDelete($fileName, $fileDotExt) . $fileDotExt;
|
||||||
|
$url = Base::urlAddparameter($url, [
|
||||||
|
'fullfilename' => $fullFileName
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$previewType = $fileSize < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
||||||
|
return Base::fillUrl("fileview/onlinePreview?url=" . urlencode(base64_encode($url)) . "&officePreviewType=" . $previewType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取格式内容(或下载)
|
* 获取格式内容(或下载)
|
||||||
* @param File $file
|
* @param File $file
|
||||||
@ -53,7 +87,7 @@ class FileContent extends AbstractModel
|
|||||||
$content = Base::json2array($content ?: []);
|
$content = Base::json2array($content ?: []);
|
||||||
if (in_array($file->type, ['word', 'excel', 'ppt'])) {
|
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'], $file->type)), $name);
|
return Response::download(public_path('assets/office/empty.' . str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $file->type)), $name);
|
||||||
}
|
}
|
||||||
return Response::download(public_path($content['url']), $name);
|
return Response::download(public_path($content['url']), $name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,10 +102,12 @@ services:
|
|||||||
|
|
||||||
fileview:
|
fileview:
|
||||||
container_name: "dootask-fileview-${APP_ID}"
|
container_name: "dootask-fileview-${APP_ID}"
|
||||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC4"
|
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC5"
|
||||||
environment:
|
environment:
|
||||||
TZ: "Asia/Shanghai"
|
TZ: "Asia/Shanghai"
|
||||||
KK_CONTEXT_PATH: "/fileview"
|
KK_CONTEXT_PATH: "/fileview"
|
||||||
|
KK_OFFICE_PREVIEW_SWITCH_DISABLED: true
|
||||||
|
KK_FILE_UPLOAD_ENABLED: true
|
||||||
networks:
|
networks:
|
||||||
extnetwork:
|
extnetwork:
|
||||||
ipv4_address: "${APP_IPPR}.7"
|
ipv4_address: "${APP_IPPR}.7"
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="component-only-office">
|
<div class="component-only-office">
|
||||||
<Alert v-if="loadError" class="load-error" type="error" show-icon>{{$L('组件加载失败!')}}</Alert>
|
<iframe v-if="isPreviewAndMobile" ref="myPreview" class="preview-iframe" :src="mobilePreviewUrl"></iframe>
|
||||||
<div :id="id" class="placeholder"></div>
|
<template v-else>
|
||||||
<div v-if="loadIng > 0" class="office-loading"><Loading/></div>
|
<Alert v-if="loadError" class="load-error" type="error" show-icon>{{$L('组件加载失败!')}}</Alert>
|
||||||
|
<div :id="id" class="placeholder"></div>
|
||||||
|
</template>
|
||||||
|
<div v-if="loading" class="office-loading"><Loading/></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -92,7 +95,7 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loadIng: 0,
|
loading: false,
|
||||||
loadError: false,
|
loadError: false,
|
||||||
|
|
||||||
docEditor: null,
|
docEditor: null,
|
||||||
@ -100,14 +103,19 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
//
|
if (this.isPreviewAndMobile) {
|
||||||
|
this.loading = true;
|
||||||
|
}
|
||||||
|
window.addEventListener('message', this.handleMessage)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.docEditor !== null) {
|
if (this.docEditor !== null) {
|
||||||
this.docEditor.destroyEditor();
|
this.docEditor.destroyEditor();
|
||||||
this.docEditor = null;
|
this.docEditor = null;
|
||||||
}
|
}
|
||||||
|
window.removeEventListener('message', this.handleMessage)
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@ -120,6 +128,23 @@ export default {
|
|||||||
fileName() {
|
fileName() {
|
||||||
return this.value.name;
|
return this.value.name;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fileUrl() {
|
||||||
|
const codeId = this.code || this.value.id;
|
||||||
|
let fileUrl = `file/content/?id=${codeId}&token=${this.userToken}`;
|
||||||
|
if (this.historyId > 0) {
|
||||||
|
fileUrl += `&history_id=${this.historyId}`
|
||||||
|
}
|
||||||
|
return fileUrl;
|
||||||
|
},
|
||||||
|
|
||||||
|
isPreviewAndMobile() {
|
||||||
|
return (this.readOnly || this.historyId > 0) && this.windowSmall
|
||||||
|
},
|
||||||
|
|
||||||
|
mobilePreviewUrl() {
|
||||||
|
return $A.apiUrl(this.fileUrl) + "&down=preview"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@ -128,10 +153,13 @@ export default {
|
|||||||
if (!id) {
|
if (!id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.loadIng++;
|
if (this.isPreviewAndMobile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loading = true;
|
||||||
this.loadError = false;
|
this.loadError = false;
|
||||||
$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"), (e) => {
|
$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"), (e) => {
|
||||||
this.loadIng--;
|
this.loading = false;
|
||||||
if (e !== null) {
|
if (e !== null) {
|
||||||
this.loadError = true;
|
this.loadError = true;
|
||||||
return;
|
return;
|
||||||
@ -153,6 +181,15 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
handleMessage(event) {
|
||||||
|
const data = event.data;
|
||||||
|
switch (data.act) {
|
||||||
|
case 'ready':
|
||||||
|
this.loading = false;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
getType(type) {
|
getType(type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'word':
|
case 'word':
|
||||||
@ -185,17 +222,15 @@ export default {
|
|||||||
let codeId = this.code || this.value.id;
|
let codeId = this.code || this.value.id;
|
||||||
let fileName = $A.strExists(this.fileName, '.') ? this.fileName : (this.fileName + '.' + this.fileType);
|
let fileName = $A.strExists(this.fileName, '.') ? this.fileName : (this.fileName + '.' + this.fileType);
|
||||||
let fileKey = `${this.fileType}-${keyAppend||codeId}`;
|
let fileKey = `${this.fileType}-${keyAppend||codeId}`;
|
||||||
let fileUrl = `http://nginx/api/file/content/?id=${codeId}&token=${this.userToken}`;
|
|
||||||
if (this.historyId > 0) {
|
if (this.historyId > 0) {
|
||||||
fileKey += `-${this.historyId}`
|
fileKey += `-${this.historyId}`
|
||||||
fileUrl += `&history_id=${this.historyId}`
|
|
||||||
}
|
}
|
||||||
const config = {
|
const config = {
|
||||||
"document": {
|
"document": {
|
||||||
"fileType": this.fileType,
|
"fileType": this.fileType,
|
||||||
"title": fileName,
|
"title": fileName,
|
||||||
"key": fileKey,
|
"key": fileKey,
|
||||||
"url": fileUrl,
|
"url": `http://nginx/api/${this.fileUrl}`,
|
||||||
},
|
},
|
||||||
"editorConfig": {
|
"editorConfig": {
|
||||||
"mode": "edit",
|
"mode": "edit",
|
||||||
@ -224,9 +259,6 @@ export default {
|
|||||||
config.document.url = `http://nginx/api/project/task/filedown/?file_id=${$A.leftDelete(codeId, "taskFile_")}&token=${this.userToken}`;
|
config.document.url = `http://nginx/api/project/task/filedown/?file_id=${$A.leftDelete(codeId, "taskFile_")}&token=${this.userToken}`;
|
||||||
}
|
}
|
||||||
if (this.readOnly || this.historyId > 0) {
|
if (this.readOnly || this.historyId > 0) {
|
||||||
if (this.windowSmall) {
|
|
||||||
config.type = "mobile";
|
|
||||||
}
|
|
||||||
config.editorConfig.mode = "view";
|
config.editorConfig.mode = "view";
|
||||||
config.editorConfig.callbackUrl = null;
|
config.editorConfig.callbackUrl = null;
|
||||||
if (!config.editorConfig.user.id) {
|
if (!config.editorConfig.user.id) {
|
||||||
|
|||||||
@ -277,7 +277,8 @@ export default {
|
|||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
if (this.isPreview) {
|
if (this.isPreview) {
|
||||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.contentDetail.url))
|
const previewType = this.file.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
||||||
|
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.contentDetail.url)}&officePreviewType=${previewType}`)
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,7 +111,8 @@ export default {
|
|||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
if (this.isPreview) {
|
if (this.isPreview) {
|
||||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.contentDetail.url))
|
const previewType = this.file.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
||||||
|
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.contentDetail.url)}&officePreviewType=${previewType}`)
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,7 +134,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.msgDetail.content.url))
|
const previewType = this.msgDetail.msg.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
||||||
|
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.msgDetail.content.url)}&officePreviewType=${previewType}`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@ -121,7 +121,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.fileDetail.content.url))
|
const previewType = this.fileDetail.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
||||||
|
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.fileDetail.content.url)}&officePreviewType=${previewType}`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
BIN
resources/assets/statics/public/assets/office/empty.docx
Normal file
BIN
resources/assets/statics/public/assets/office/empty.docx
Normal file
Binary file not shown.
BIN
resources/assets/statics/public/assets/office/empty.pptx
Normal file
BIN
resources/assets/statics/public/assets/office/empty.pptx
Normal file
Binary file not shown.
BIN
resources/assets/statics/public/assets/office/empty.xlsx
Normal file
BIN
resources/assets/statics/public/assets/office/empty.xlsx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user