diff --git a/app/Http/Controllers/Api/FileController.php b/app/Http/Controllers/Api/FileController.php index 858499daa..c058f4900 100755 --- a/app/Http/Controllers/Api/FileController.php +++ b/app/Http/Controllers/Api/FileController.php @@ -13,6 +13,7 @@ use App\Module\Base; use App\Module\Ihttp; use Carbon\Carbon; use Illuminate\Support\Facades\DB; +use Redirect; use Request; /** @@ -447,7 +448,8 @@ class FileController extends AbstractController * - yes * @apiParam {String} down 直接下载 * - no: 浏览(默认) - * - yes: 下载(office文件直接下载) + * - yes: 下载(office文件直接下载,除非是preview) + * - preview: 转预览地址 * @apiParam {Number} [history_id] 读取历史记录ID * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) @@ -486,6 +488,9 @@ class FileController extends AbstractController $builder->whereId($history_id); } $content = $builder->orderByDesc('id')->first(); + if ($down === 'preview') { + return Redirect::to(FileContent::formatPreview($file, $content?->content)); + } return FileContent::formatContent($file, $content?->content, $down == 'yes'); } diff --git a/app/Models/File.php b/app/Models/File.php index af294bcf9..006e37c5f 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -381,6 +381,7 @@ class File extends AbstractModel */ public static function formatFileData(array $data) { + $fileName = $data['name']; $filePath = $data['path']; $fileSize = $data['size']; $fileExt = $data['ext']; @@ -436,9 +437,9 @@ class File extends AbstractModel } if ($fileExt != 'pdf') { $fileDotExt = ".{$fileExt}"; - $fileName = Base::rightDelete($data['name'], $fileDotExt) . $fileDotExt; + $fullFileName = Base::rightDelete($fileName, $fileDotExt) . $fileDotExt; $url = Base::urlAddparameter($url, [ - 'fullfilename' => $fileName + 'fullfilename' => $fullFileName ]); } $data['content'] = [ diff --git a/app/Models/FileContent.php b/app/Models/FileContent.php index df86e574a..662a4becd 100644 --- a/app/Models/FileContent.php +++ b/app/Models/FileContent.php @@ -40,6 +40,40 @@ class FileContent extends AbstractModel { 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 @@ -53,7 +87,7 @@ class FileContent extends AbstractModel $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'], $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); } diff --git a/docker-compose.yml b/docker-compose.yml index f0faf907b..ef27056ca 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -102,10 +102,12 @@ services: fileview: container_name: "dootask-fileview-${APP_ID}" - image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC4" + image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC5" environment: TZ: "Asia/Shanghai" KK_CONTEXT_PATH: "/fileview" + KK_OFFICE_PREVIEW_SWITCH_DISABLED: true + KK_FILE_UPLOAD_ENABLED: true networks: extnetwork: ipv4_address: "${APP_IPPR}.7" diff --git a/resources/assets/statics/office/empty.docx b/public/assets/office/empty.docx similarity index 100% rename from resources/assets/statics/office/empty.docx rename to public/assets/office/empty.docx diff --git a/resources/assets/statics/office/empty.pptx b/public/assets/office/empty.pptx similarity index 100% rename from resources/assets/statics/office/empty.pptx rename to public/assets/office/empty.pptx diff --git a/resources/assets/statics/office/empty.xlsx b/public/assets/office/empty.xlsx similarity index 100% rename from resources/assets/statics/office/empty.xlsx rename to public/assets/office/empty.xlsx diff --git a/resources/assets/js/components/OnlyOffice.vue b/resources/assets/js/components/OnlyOffice.vue index e1861e911..ae2d8e410 100644 --- a/resources/assets/js/components/OnlyOffice.vue +++ b/resources/assets/js/components/OnlyOffice.vue @@ -1,8 +1,11 @@ @@ -92,7 +95,7 @@ export default { data() { return { - loadIng: 0, + loading: false, loadError: false, docEditor: null, @@ -100,14 +103,19 @@ export default { }, mounted() { - // + if (this.isPreviewAndMobile) { + this.loading = true; + } + window.addEventListener('message', this.handleMessage) }, + beforeDestroy() { if (this.docEditor !== null) { this.docEditor.destroyEditor(); this.docEditor = null; } + window.removeEventListener('message', this.handleMessage) }, computed: { @@ -120,6 +128,23 @@ export default { fileName() { 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: { @@ -128,10 +153,13 @@ export default { if (!id) { return; } - this.loadIng++; + if (this.isPreviewAndMobile) { + return; + } + this.loading = true; this.loadError = false; $A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"), (e) => { - this.loadIng--; + this.loading = false; if (e !== null) { this.loadError = true; return; @@ -153,6 +181,15 @@ export default { }, methods: { + handleMessage(event) { + const data = event.data; + switch (data.act) { + case 'ready': + this.loading = false; + break + } + }, + getType(type) { switch (type) { case 'word': @@ -185,17 +222,15 @@ export default { let codeId = this.code || this.value.id; let fileName = $A.strExists(this.fileName, '.') ? this.fileName : (this.fileName + '.' + this.fileType); let fileKey = `${this.fileType}-${keyAppend||codeId}`; - let fileUrl = `http://nginx/api/file/content/?id=${codeId}&token=${this.userToken}`; if (this.historyId > 0) { fileKey += `-${this.historyId}` - fileUrl += `&history_id=${this.historyId}` } const config = { "document": { "fileType": this.fileType, "title": fileName, "key": fileKey, - "url": fileUrl, + "url": `http://nginx/api/${this.fileUrl}`, }, "editorConfig": { "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}`; } if (this.readOnly || this.historyId > 0) { - if (this.windowSmall) { - config.type = "mobile"; - } config.editorConfig.mode = "view"; config.editorConfig.callbackUrl = null; if (!config.editorConfig.user.id) { diff --git a/resources/assets/js/pages/manage/components/FileContent.vue b/resources/assets/js/pages/manage/components/FileContent.vue index 310b070bd..db33a605e 100644 --- a/resources/assets/js/pages/manage/components/FileContent.vue +++ b/resources/assets/js/pages/manage/components/FileContent.vue @@ -277,7 +277,8 @@ export default { previewUrl() { 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 { return ''; } diff --git a/resources/assets/js/pages/manage/components/FilePreview.vue b/resources/assets/js/pages/manage/components/FilePreview.vue index 37cf5c82b..c4b9a3af8 100644 --- a/resources/assets/js/pages/manage/components/FilePreview.vue +++ b/resources/assets/js/pages/manage/components/FilePreview.vue @@ -111,7 +111,8 @@ export default { previewUrl() { 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 { return ''; } diff --git a/resources/assets/js/pages/single/fileMsg.vue b/resources/assets/js/pages/single/fileMsg.vue index 6774aa162..db92a035d 100644 --- a/resources/assets/js/pages/single/fileMsg.vue +++ b/resources/assets/js/pages/single/fileMsg.vue @@ -134,7 +134,8 @@ export default { }, 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: { diff --git a/resources/assets/js/pages/single/fileTask.vue b/resources/assets/js/pages/single/fileTask.vue index d3eb83fee..0ab6f608f 100644 --- a/resources/assets/js/pages/single/fileTask.vue +++ b/resources/assets/js/pages/single/fileTask.vue @@ -121,7 +121,8 @@ export default { }, 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: { diff --git a/resources/assets/statics/public/assets/office/empty.docx b/resources/assets/statics/public/assets/office/empty.docx new file mode 100644 index 000000000..d491eadc0 Binary files /dev/null and b/resources/assets/statics/public/assets/office/empty.docx differ diff --git a/resources/assets/statics/public/assets/office/empty.pptx b/resources/assets/statics/public/assets/office/empty.pptx new file mode 100644 index 000000000..d2a2e2f92 Binary files /dev/null and b/resources/assets/statics/public/assets/office/empty.pptx differ diff --git a/resources/assets/statics/public/assets/office/empty.xlsx b/resources/assets/statics/public/assets/office/empty.xlsx new file mode 100644 index 000000000..026036fb6 Binary files /dev/null and b/resources/assets/statics/public/assets/office/empty.xlsx differ