优化聊天消息附件支持预览
This commit is contained in:
parent
705d7f3da0
commit
9e560c79ae
@ -357,22 +357,26 @@ class DialogController extends AbstractController
|
||||
//
|
||||
if ($data['type'] == 'file') {
|
||||
$codeExt = ['txt'];
|
||||
$fillExt = ['jpg', 'jpeg', 'png', 'gif'];
|
||||
$officeExt = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
|
||||
$localExt = ['jpg', 'jpeg', 'png', 'gif'];
|
||||
$msg = Base::json2array($dialogMsg->getRawOriginal('msg'));
|
||||
$filePath = public_path($msg['path']);
|
||||
if (in_array($msg['ext'], $codeExt) && $msg['size'] < 2 * 1024 * 1024) {
|
||||
// 文本代码,限制2M内的文件
|
||||
// 文本预览,限制2M内的文件
|
||||
$data['content'] = file_get_contents($filePath);
|
||||
$data['file_mode'] = 1;
|
||||
} elseif (in_array($msg['ext'], $officeExt)) {
|
||||
// office预览
|
||||
$data['file_mode'] = 2;
|
||||
} else {
|
||||
// 支持预览
|
||||
if (in_array($msg['ext'], $fillExt)) {
|
||||
// 其他预览
|
||||
if (in_array($msg['ext'], $localExt)) {
|
||||
$url = Base::fillUrl($msg['path']);
|
||||
} else {
|
||||
$url = 'http://' . env('APP_IPPR') . '.3/' . $msg['path'];
|
||||
}
|
||||
$data['url'] = base64_encode($url);
|
||||
$data['file_mode'] = 2;
|
||||
$data['file_mode'] = 3;
|
||||
}
|
||||
}
|
||||
//
|
||||
|
@ -9,10 +9,12 @@ use App\Models\FileContent;
|
||||
use App\Models\FileLink;
|
||||
use App\Models\FileUser;
|
||||
use App\Models\User;
|
||||
use App\Models\WebSocketDialogMsg;
|
||||
use App\Module\Base;
|
||||
use App\Module\Ihttp;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Request;
|
||||
use Response;
|
||||
|
||||
/**
|
||||
* @apiDefine file
|
||||
@ -379,11 +381,11 @@ class FileController extends AbstractController
|
||||
* @apiName content
|
||||
*
|
||||
* @apiParam {Number|String} id
|
||||
* - Number 文件ID(需要登录)
|
||||
* - String 链接码(不需要登录,用于预览)
|
||||
* - Number: 文件ID(需要登录)
|
||||
* - String: 链接码(不需要登录,用于预览)
|
||||
* @apiParam {String} down 直接下载
|
||||
* - no: 浏览(默认)
|
||||
* - yes: 下载
|
||||
* - yes: 下载(office文件直接下载)
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
|
@ -1083,6 +1083,60 @@ class ProjectController extends AbstractController
|
||||
return Base::retSuccess('success', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/project/task/filedetail 22. 获取任务文件详情
|
||||
*
|
||||
* @apiDescription 需要token身份(限:项目、任务负责人)
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup project
|
||||
* @apiName task__filedetail
|
||||
*
|
||||
* @apiParam {Number} file_id 文件ID
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function task__filedetail()
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$file_id = intval(Request::input('file_id'));
|
||||
//
|
||||
$file = ProjectTaskFile::find($file_id);
|
||||
if (empty($file)) {
|
||||
return Base::retError("文件不存在");
|
||||
}
|
||||
$data = $file->toArray();
|
||||
$data['path'] = $file->getRawOriginal('path');
|
||||
//
|
||||
ProjectTask::userTask($file->task_id, true, true);
|
||||
//
|
||||
$codeExt = ['txt'];
|
||||
$officeExt = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
|
||||
$localExt = ['jpg', 'jpeg', 'png', 'gif'];
|
||||
$filePath = public_path($data['path']);
|
||||
if (in_array($data['ext'], $codeExt) && $data['size'] < 2 * 1024 * 1024) {
|
||||
// 文本预览,限制2M内的文件
|
||||
$data['content'] = file_get_contents($filePath);
|
||||
$data['file_mode'] = 1;
|
||||
} elseif (in_array($data['ext'], $officeExt)) {
|
||||
// office预览
|
||||
$data['file_mode'] = 2;
|
||||
} else {
|
||||
// 其他预览
|
||||
if (in_array($data['ext'], $localExt)) {
|
||||
$url = Base::fillUrl($data['path']);
|
||||
} else {
|
||||
$url = 'http://' . env('APP_IPPR') . '.3/' . $data['path'];
|
||||
}
|
||||
$data['url'] = base64_encode($url);
|
||||
$data['file_mode'] = 3;
|
||||
}
|
||||
//
|
||||
return Base::retSuccess('success', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/project/task/filedown 22. 下载任务文件
|
||||
*
|
||||
|
@ -96,7 +96,7 @@ services:
|
||||
|
||||
fileview:
|
||||
container_name: "dootask-fileview-${APP_ID}"
|
||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC2"
|
||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC3"
|
||||
environment:
|
||||
TZ: "Asia/Shanghai"
|
||||
KK_CONTEXT_PATH: "/fileview"
|
||||
|
2
public/js/ace/theme-dracula-dark.js
vendored
2
public/js/ace/theme-dracula-dark.js
vendored
@ -1,4 +1,4 @@
|
||||
define("ace/theme/dracula-dark",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-dracula-dark",t.cssText=".ace-dracula-dark .ace_gutter {background: #232323;color: rgb(144,145,148)}.ace-dracula-dark .ace_print-margin {width: 1px;background: #44475a}.ace-dracula-dark {background-color: #232323;color: #f8f8f2}.ace-dracula-dark .ace_cursor {color: #f8f8f0}.ace-dracula-dark .ace_marker-layer .ace_selection {background: #44475a}.ace-dracula-dark.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #232323;border-radius: 2px}.ace-dracula-dark .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-dracula-dark .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #a29709}.ace-dracula-dark .ace_marker-layer .ace_active-line {background: #44475a}.ace-dracula-dark .ace_gutter-active-line {background-color: #44475a}.ace-dracula-dark .ace_marker-layer .ace_selected-word {box-shadow: 0px 0px 0px 1px #a29709;border-radius: 3px;}.ace-dracula-dark .ace_fold {background-color: #50fa7b;border-color: #f8f8f2}.ace-dracula-dark .ace_keyword {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_language {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_numeric {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character.ace_escape {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_other {color: #bd93f9}.ace-dracula-dark .ace_support.ace_function {color: #8be9fd}.ace-dracula-dark .ace_support.ace_constant {color: #6be5fd}.ace-dracula-dark .ace_support.ace_class {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_support.ace_type {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_storage {color: #ff79c6}.ace-dracula-dark .ace_storage.ace_type {font-style: italic;color: #8be9fd}.ace-dracula-dark .ace_invalid {color: #F8F8F0;background-color: #ff79c6}.ace-dracula-dark .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #bd93f9}.ace-dracula-dark .ace_string {color: #f1fa8c}.ace-dracula-dark .ace_comment {color: #6272a4}.ace-dracula-dark .ace_variable {color: #50fa7b}.ace-dracula-dark .ace_variable.ace_parameter {font-style: italic;color: #ffb86c}.ace-dracula-dark .ace_entity.ace_other.ace_attribute-name {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_function {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_tag {color: #ff79c6}.ace-dracula-dark .ace_invisible {color: #626680;}.ace-dracula-dark .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}",t.$selectionColorConflict=!0;var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass,!1)}); (function() {
|
||||
define("ace/theme/dracula-dark",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-dracula-dark",t.cssText=".ace-dracula-dark .ace_gutter {background: #000000;color: rgb(144,145,148)}.ace-dracula-dark .ace_print-margin {width: 1px;background: #44475a}.ace-dracula-dark {background-color: #000000;color: #f8f8f2}.ace-dracula-dark .ace_cursor {color: #f8f8f0}.ace-dracula-dark .ace_marker-layer .ace_selection {background: #44475a}.ace-dracula-dark.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #000000;border-radius: 2px}.ace-dracula-dark .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-dracula-dark .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #a29709}.ace-dracula-dark .ace_marker-layer .ace_active-line {background: #44475a}.ace-dracula-dark .ace_gutter-active-line {background-color: #44475a}.ace-dracula-dark .ace_marker-layer .ace_selected-word {box-shadow: 0px 0px 0px 1px #a29709;border-radius: 3px;}.ace-dracula-dark .ace_fold {background-color: #50fa7b;border-color: #f8f8f2}.ace-dracula-dark .ace_keyword {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_language {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_numeric {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character.ace_escape {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_other {color: #bd93f9}.ace-dracula-dark .ace_support.ace_function {color: #8be9fd}.ace-dracula-dark .ace_support.ace_constant {color: #6be5fd}.ace-dracula-dark .ace_support.ace_class {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_support.ace_type {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_storage {color: #ff79c6}.ace-dracula-dark .ace_storage.ace_type {font-style: italic;color: #8be9fd}.ace-dracula-dark .ace_invalid {color: #F8F8F0;background-color: #ff79c6}.ace-dracula-dark .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #bd93f9}.ace-dracula-dark .ace_string {color: #f1fa8c}.ace-dracula-dark .ace_comment {color: #6272a4}.ace-dracula-dark .ace_variable {color: #50fa7b}.ace-dracula-dark .ace_variable.ace_parameter {font-style: italic;color: #ffb86c}.ace-dracula-dark .ace_entity.ace_other.ace_attribute-name {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_function {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_tag {color: #ff79c6}.ace-dracula-dark .ace_invisible {color: #626680;}.ace-dracula-dark .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}",t.$selectionColorConflict=!0;var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass,!1)}); (function() {
|
||||
window.require(["ace/theme/dracula-dark"], function(m) {
|
||||
if (typeof module == "object" && typeof exports == "object" && module) {
|
||||
module.exports = m;
|
||||
|
@ -123,7 +123,7 @@ export default {
|
||||
case 'ppt':
|
||||
return 'pptx'
|
||||
}
|
||||
return '';
|
||||
return type;
|
||||
},
|
||||
|
||||
loadFile() {
|
||||
@ -144,11 +144,12 @@ export default {
|
||||
}
|
||||
//
|
||||
let fileKey = this.code || this.value.id;
|
||||
let fileName = $A.strExists(this.fileName, '.') ? this.fileName : (this.fileName + '.' + this.fileType);
|
||||
const config = {
|
||||
"document": {
|
||||
"fileType": this.fileType,
|
||||
"key": this.fileType + '-' + fileKey,
|
||||
"title": this.fileName + '.' + this.fileType,
|
||||
"title": fileName,
|
||||
"url": 'http://nginx/api/file/content/?id=' + fileKey + '&token=' + this.userToken,
|
||||
},
|
||||
"editorConfig": {
|
||||
@ -164,6 +165,11 @@ export default {
|
||||
"callbackUrl": 'http://nginx/api/file/content/office?id=' + fileKey + '&token=' + this.userToken,
|
||||
}
|
||||
};
|
||||
if ($A.leftExists(fileKey, "msgFile_")) {
|
||||
config.document.url = 'http://nginx/api/dialog/msg/download/?msg_id=' + $A.leftDelete(fileKey, "msgFile_") + '&token=' + this.userToken;
|
||||
} else if ($A.leftExists(fileKey, "taskFile_")) {
|
||||
config.document.url = 'http://nginx/api/project/task/filedown/?file_id=' + $A.leftDelete(fileKey, "taskFile_") + '&token=' + this.userToken;
|
||||
}
|
||||
if (this.readOnly) {
|
||||
config.editorConfig.mode = "view";
|
||||
config.editorConfig.callbackUrl = null;
|
||||
|
@ -181,8 +181,8 @@ export default {
|
||||
this.$Electron.ipcRenderer.send('windowRouter', {
|
||||
title: `${this.msgData.msg.name} (${$A.bytesToSize(this.msgData.msg.size)})`,
|
||||
titleFixed: true,
|
||||
name: 'msgview-' + this.msgData.id,
|
||||
path: "/single/msgview/" + this.msgData.id,
|
||||
name: 'file-msg-' + this.msgData.id,
|
||||
path: "/single/file/msg/" + this.msgData.id,
|
||||
force: false,
|
||||
config: {
|
||||
parent: null,
|
||||
@ -191,7 +191,7 @@ export default {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
window.open($A.apiUrl(`../single/msgview/${this.msgData.id}`))
|
||||
window.open($A.apiUrl(`../single/file/msg/${this.msgData.id}`))
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
</ETooltip>
|
||||
</li>
|
||||
<li :class="['project-icon', searchText!='' ? 'active' : '']">
|
||||
<Tooltip :always="searchAlways" @on-popper-show="searchFocus" theme="light">
|
||||
<Tooltip :always="searchText!=''" @on-popper-show="searchFocus" theme="light" :rawIndex="10">
|
||||
<Icon class="menu-icon" type="ios-search" @click="searchFocus" />
|
||||
<div slot="content">
|
||||
<Input v-model="searchText" ref="searchInput" :placeholder="$L('名称、描述...')" class="search-input" clearable/>
|
||||
@ -537,17 +537,6 @@ export default {
|
||||
|
||||
...mapGetters(['projectData', 'projectParameter', 'transforTasks']),
|
||||
|
||||
searchAlways() {
|
||||
return !(!this.searchText
|
||||
|| this.settingShow
|
||||
|| this.userShow
|
||||
|| this.inviteShow
|
||||
|| this.transferShow
|
||||
|| this.workflowShow
|
||||
|| this.logShow
|
||||
|| this.archivedTaskShow);
|
||||
},
|
||||
|
||||
userWaitRemove() {
|
||||
const {userids, useridbak} = this.userData;
|
||||
if (!userids) {
|
||||
|
@ -279,18 +279,22 @@
|
||||
<li v-for="file in fileList">
|
||||
<img v-if="file.id" class="file-ext" :src="file.thumb"/>
|
||||
<Loading v-else class="file-load"/>
|
||||
<div class="file-name" @click="downFile(file)">{{file.name}}</div>
|
||||
<div class="file-name">{{file.name}}</div>
|
||||
<div class="file-size">{{$A.bytesToSize(file.size)}}</div>
|
||||
<EPopover v-model="file._deling" class="file-delete">
|
||||
<div class="task-detail-delete-file-popover">
|
||||
<p>{{$L('你确定要删除这个文件吗?')}}</p>
|
||||
<div class="buttons">
|
||||
<Button size="small" type="text" @click="file._deling=false">{{$L('取消')}}</Button>
|
||||
<Button size="small" type="primary" @click="deleteFile(file)">{{$L('确定')}}</Button>
|
||||
<div class="file-menu" :class="{show:file._show_menu}">
|
||||
<Icon @click="viewFile(file)" type="md-eye" />
|
||||
<Icon @click="downFile(file)" type="md-arrow-round-down" />
|
||||
<EPopover v-model="file._show_menu" class="file-delete">
|
||||
<div class="task-detail-delete-file-popover">
|
||||
<p>{{$L('你确定要删除这个文件吗?')}}</p>
|
||||
<div class="buttons">
|
||||
<Button size="small" type="text" @click="file._show_menu=false">{{$L('取消')}}</Button>
|
||||
<Button size="small" type="primary" @click="deleteFile(file)">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" :class="['taskfont', file._deling ? 'deling' : '']"></i>
|
||||
</EPopover>
|
||||
<i slot="reference" class="taskfont del"></i>
|
||||
</EPopover>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="item-content">
|
||||
@ -1102,7 +1106,7 @@ export default {
|
||||
},
|
||||
|
||||
deleteFile(file) {
|
||||
this.$set(file, '_deling', false);
|
||||
this.$set(file, '_show_menu', false);
|
||||
this.$store.dispatch("forgetTaskFile", file.id)
|
||||
//
|
||||
this.$store.dispatch("call", {
|
||||
@ -1166,6 +1170,25 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
viewFile(file) {
|
||||
if (this.$Electron) {
|
||||
this.$Electron.ipcRenderer.send('windowRouter', {
|
||||
title: `${file.name} (${$A.bytesToSize(file.size)})`,
|
||||
titleFixed: true,
|
||||
name: 'file-task-' + file.id,
|
||||
path: "/single/file/task/" + file.id,
|
||||
force: false,
|
||||
config: {
|
||||
parent: null,
|
||||
width: Math.min(window.screen.availWidth, 1440),
|
||||
height: Math.min(window.screen.availHeight, 900),
|
||||
}
|
||||
});
|
||||
} else {
|
||||
window.open($A.apiUrl(`../single/file/task/${file.id}`))
|
||||
}
|
||||
},
|
||||
|
||||
downFile(file) {
|
||||
$A.modalConfirm({
|
||||
title: '下载文件',
|
||||
|
@ -1,17 +1,18 @@
|
||||
<template>
|
||||
<div class="single-msgview">
|
||||
<div class="single-file-msg">
|
||||
<PageTitle :title="title"/>
|
||||
<Loading v-if="loadIng > 0"/>
|
||||
<template v-else>
|
||||
<AceEditor v-if="isCode" v-model="codeContent" :ext="codeExt" class="view-editor" readOnly/>
|
||||
<iframe v-else-if="isPreview" class="preview-iframe" :src="previewUrl"></iframe>
|
||||
<OnlyOffice v-else-if="isOffice" v-model="officeContent" :code="officeCode" readOnly/>
|
||||
<iframe v-else-if="isPreview" class="preview-iframe" :src="previewUrl"/>
|
||||
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.single-msgview {
|
||||
.single-file-msg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.preview-iframe,
|
||||
@ -44,9 +45,10 @@
|
||||
</style>
|
||||
<script>
|
||||
import AceEditor from "../../components/AceEditor";
|
||||
import OnlyOffice from "../../components/OnlyOffice";
|
||||
|
||||
export default {
|
||||
components: {AceEditor},
|
||||
components: {OnlyOffice, AceEditor},
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
@ -73,6 +75,7 @@ export default {
|
||||
}
|
||||
return "Loading..."
|
||||
},
|
||||
|
||||
isCode() {
|
||||
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 1;
|
||||
},
|
||||
@ -88,9 +91,27 @@ export default {
|
||||
}
|
||||
return 'txt'
|
||||
},
|
||||
isPreview() {
|
||||
|
||||
isOffice() {
|
||||
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 2;
|
||||
},
|
||||
officeContent() {
|
||||
return {
|
||||
id: this.isOffice ? this.msgDetail.id : 0,
|
||||
type: this.msgDetail.msg.ext,
|
||||
name: this.title
|
||||
}
|
||||
},
|
||||
officeCode() {
|
||||
if (this.isOffice) {
|
||||
return "msgFile_" + this.msgDetail.id;
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
isPreview() {
|
||||
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 3;
|
||||
},
|
||||
previewUrl() {
|
||||
if (this.isPreview) {
|
||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.msgDetail.url))
|
151
resources/assets/js/pages/single/fileTask.vue
Normal file
151
resources/assets/js/pages/single/fileTask.vue
Normal file
@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div class="single-file-task">
|
||||
<PageTitle :title="title"/>
|
||||
<Loading v-if="loadIng > 0"/>
|
||||
<template v-else>
|
||||
<AceEditor v-if="isCode" v-model="codeContent" :ext="codeExt" class="view-editor" readOnly/>
|
||||
<OnlyOffice v-else-if="isOffice" v-model="officeContent" :code="officeCode" readOnly/>
|
||||
<iframe v-else-if="isPreview" class="preview-iframe" :src="previewUrl"/>
|
||||
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.single-file-task {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.preview-iframe,
|
||||
.ace_editor,
|
||||
.no-support {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.preview-iframe {
|
||||
background: 0 0;
|
||||
float: none;
|
||||
max-width: none;
|
||||
}
|
||||
.view-editor,
|
||||
.no-support {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
</style>
|
||||
<script>
|
||||
import AceEditor from "../../components/AceEditor";
|
||||
import OnlyOffice from "../../components/OnlyOffice";
|
||||
|
||||
export default {
|
||||
components: {OnlyOffice, AceEditor},
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
|
||||
fileDetail: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//
|
||||
},
|
||||
watch: {
|
||||
'$route': {
|
||||
handler() {
|
||||
this.getInfo();
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
const {name} = this.fileDetail;
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
return "Loading..."
|
||||
},
|
||||
|
||||
isCode() {
|
||||
return this.fileDetail.file_mode == 1;
|
||||
},
|
||||
codeContent() {
|
||||
if (this.isCode) {
|
||||
return this.fileDetail.content;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
codeExt() {
|
||||
if (this.isCode) {
|
||||
return this.fileDetail.ext;
|
||||
}
|
||||
return 'txt'
|
||||
},
|
||||
|
||||
isOffice() {
|
||||
return this.fileDetail.file_mode == 2;
|
||||
},
|
||||
officeContent() {
|
||||
return {
|
||||
id: this.isOffice ? this.fileDetail.id : 0,
|
||||
type: this.fileDetail.ext,
|
||||
name: this.title
|
||||
}
|
||||
},
|
||||
officeCode() {
|
||||
if (this.isOffice) {
|
||||
return "taskFile_" + this.fileDetail.id;
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
isPreview() {
|
||||
return this.fileDetail.file_mode == 3;
|
||||
},
|
||||
previewUrl() {
|
||||
if (this.isPreview) {
|
||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.fileDetail.url))
|
||||
}
|
||||
return ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getInfo() {
|
||||
let file_id = $A.runNum(this.$route.params.id);
|
||||
if (file_id <= 0) {
|
||||
return;
|
||||
}
|
||||
this.loadIng++;
|
||||
this.$store.dispatch("call", {
|
||||
url: 'project/task/filedetail',
|
||||
data: {
|
||||
file_id,
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.loadIng--;
|
||||
this.fileDetail = data;
|
||||
}).catch(({msg}) => {
|
||||
this.loadIng--;
|
||||
$A.modalError({
|
||||
content: msg,
|
||||
onOk: () => {
|
||||
if (this.$Electron) {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
15
resources/assets/js/routes.js
vendored
15
resources/assets/js/routes.js
vendored
@ -75,6 +75,16 @@ export default [
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'single-file-msg',
|
||||
path: '/single/file/msg/:id',
|
||||
component: () => import('./pages/single/fileMsg.vue'),
|
||||
},
|
||||
{
|
||||
name: 'single-file-task',
|
||||
path: '/single/file/task/:id',
|
||||
component: () => import('./pages/single/fileTask.vue'),
|
||||
},
|
||||
{
|
||||
name: 'single-file',
|
||||
path: '/single/file/:id',
|
||||
@ -85,11 +95,6 @@ export default [
|
||||
path: '/single/task/:id',
|
||||
component: () => import('./pages/single/task.vue'),
|
||||
},
|
||||
{
|
||||
name: 'single-msgview',
|
||||
path: '/single/msgview/:id',
|
||||
component: () => import('./pages/single/msgview.vue'),
|
||||
},
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
|
@ -251,10 +251,6 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
.file-size {
|
||||
flex-shrink: 0;
|
||||
@ -263,27 +259,38 @@
|
||||
font-size: 12px;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
.file-delete {
|
||||
.file-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: 0;
|
||||
transition: all 0.3s;
|
||||
padding-left: 12px;
|
||||
.taskfont {
|
||||
display: none;
|
||||
&.show {
|
||||
opacity: 1;
|
||||
}
|
||||
i {
|
||||
font-size: 14px;
|
||||
color: #aaaaaa;
|
||||
transition: color 0.3s;
|
||||
cursor: pointer;
|
||||
padding: 0 4px;
|
||||
&:hover {
|
||||
color: #ff0000;
|
||||
color: #777777;
|
||||
}
|
||||
&.deling {
|
||||
display: inline-block;
|
||||
&.del {
|
||||
font-size: 13px;
|
||||
&:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.file-delete {
|
||||
.taskfont {
|
||||
display: inline-block;
|
||||
}
|
||||
.file-name {
|
||||
color: $primary-title-color;
|
||||
}
|
||||
.file-menu {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
define("ace/theme/dracula-dark",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-dracula-dark",t.cssText=".ace-dracula-dark .ace_gutter {background: #232323;color: rgb(144,145,148)}.ace-dracula-dark .ace_print-margin {width: 1px;background: #44475a}.ace-dracula-dark {background-color: #232323;color: #f8f8f2}.ace-dracula-dark .ace_cursor {color: #f8f8f0}.ace-dracula-dark .ace_marker-layer .ace_selection {background: #44475a}.ace-dracula-dark.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #232323;border-radius: 2px}.ace-dracula-dark .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-dracula-dark .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #a29709}.ace-dracula-dark .ace_marker-layer .ace_active-line {background: #44475a}.ace-dracula-dark .ace_gutter-active-line {background-color: #44475a}.ace-dracula-dark .ace_marker-layer .ace_selected-word {box-shadow: 0px 0px 0px 1px #a29709;border-radius: 3px;}.ace-dracula-dark .ace_fold {background-color: #50fa7b;border-color: #f8f8f2}.ace-dracula-dark .ace_keyword {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_language {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_numeric {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character.ace_escape {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_other {color: #bd93f9}.ace-dracula-dark .ace_support.ace_function {color: #8be9fd}.ace-dracula-dark .ace_support.ace_constant {color: #6be5fd}.ace-dracula-dark .ace_support.ace_class {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_support.ace_type {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_storage {color: #ff79c6}.ace-dracula-dark .ace_storage.ace_type {font-style: italic;color: #8be9fd}.ace-dracula-dark .ace_invalid {color: #F8F8F0;background-color: #ff79c6}.ace-dracula-dark .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #bd93f9}.ace-dracula-dark .ace_string {color: #f1fa8c}.ace-dracula-dark .ace_comment {color: #6272a4}.ace-dracula-dark .ace_variable {color: #50fa7b}.ace-dracula-dark .ace_variable.ace_parameter {font-style: italic;color: #ffb86c}.ace-dracula-dark .ace_entity.ace_other.ace_attribute-name {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_function {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_tag {color: #ff79c6}.ace-dracula-dark .ace_invisible {color: #626680;}.ace-dracula-dark .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}",t.$selectionColorConflict=!0;var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass,!1)}); (function() {
|
||||
define("ace/theme/dracula-dark",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-dracula-dark",t.cssText=".ace-dracula-dark .ace_gutter {background: #000000;color: rgb(144,145,148)}.ace-dracula-dark .ace_print-margin {width: 1px;background: #44475a}.ace-dracula-dark {background-color: #000000;color: #f8f8f2}.ace-dracula-dark .ace_cursor {color: #f8f8f0}.ace-dracula-dark .ace_marker-layer .ace_selection {background: #44475a}.ace-dracula-dark.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #000000;border-radius: 2px}.ace-dracula-dark .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-dracula-dark .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #a29709}.ace-dracula-dark .ace_marker-layer .ace_active-line {background: #44475a}.ace-dracula-dark .ace_gutter-active-line {background-color: #44475a}.ace-dracula-dark .ace_marker-layer .ace_selected-word {box-shadow: 0px 0px 0px 1px #a29709;border-radius: 3px;}.ace-dracula-dark .ace_fold {background-color: #50fa7b;border-color: #f8f8f2}.ace-dracula-dark .ace_keyword {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_language {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_numeric {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character {color: #bd93f9}.ace-dracula-dark .ace_constant.ace_character.ace_escape {color: #ff79c6}.ace-dracula-dark .ace_constant.ace_other {color: #bd93f9}.ace-dracula-dark .ace_support.ace_function {color: #8be9fd}.ace-dracula-dark .ace_support.ace_constant {color: #6be5fd}.ace-dracula-dark .ace_support.ace_class {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_support.ace_type {font-style: italic;color: #66d9ef}.ace-dracula-dark .ace_storage {color: #ff79c6}.ace-dracula-dark .ace_storage.ace_type {font-style: italic;color: #8be9fd}.ace-dracula-dark .ace_invalid {color: #F8F8F0;background-color: #ff79c6}.ace-dracula-dark .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #bd93f9}.ace-dracula-dark .ace_string {color: #f1fa8c}.ace-dracula-dark .ace_comment {color: #6272a4}.ace-dracula-dark .ace_variable {color: #50fa7b}.ace-dracula-dark .ace_variable.ace_parameter {font-style: italic;color: #ffb86c}.ace-dracula-dark .ace_entity.ace_other.ace_attribute-name {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_function {color: #50fa7b}.ace-dracula-dark .ace_entity.ace_name.ace_tag {color: #ff79c6}.ace-dracula-dark .ace_invisible {color: #626680;}.ace-dracula-dark .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}",t.$selectionColorConflict=!0;var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass,!1)}); (function() {
|
||||
window.require(["ace/theme/dracula-dark"], function(m) {
|
||||
if (typeof module == "object" && typeof exports == "object" && module) {
|
||||
module.exports = m;
|
||||
|
Loading…
x
Reference in New Issue
Block a user