优化聊天消息附件支持预览
This commit is contained in:
parent
705d7f3da0
commit
9e560c79ae
@ -357,22 +357,26 @@ class DialogController extends AbstractController
|
|||||||
//
|
//
|
||||||
if ($data['type'] == 'file') {
|
if ($data['type'] == 'file') {
|
||||||
$codeExt = ['txt'];
|
$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'));
|
$msg = Base::json2array($dialogMsg->getRawOriginal('msg'));
|
||||||
$filePath = public_path($msg['path']);
|
$filePath = public_path($msg['path']);
|
||||||
if (in_array($msg['ext'], $codeExt) && $msg['size'] < 2 * 1024 * 1024) {
|
if (in_array($msg['ext'], $codeExt) && $msg['size'] < 2 * 1024 * 1024) {
|
||||||
// 文本代码,限制2M内的文件
|
// 文本预览,限制2M内的文件
|
||||||
$data['content'] = file_get_contents($filePath);
|
$data['content'] = file_get_contents($filePath);
|
||||||
$data['file_mode'] = 1;
|
$data['file_mode'] = 1;
|
||||||
|
} elseif (in_array($msg['ext'], $officeExt)) {
|
||||||
|
// office预览
|
||||||
|
$data['file_mode'] = 2;
|
||||||
} else {
|
} else {
|
||||||
// 支持预览
|
// 其他预览
|
||||||
if (in_array($msg['ext'], $fillExt)) {
|
if (in_array($msg['ext'], $localExt)) {
|
||||||
$url = Base::fillUrl($msg['path']);
|
$url = Base::fillUrl($msg['path']);
|
||||||
} else {
|
} else {
|
||||||
$url = 'http://' . env('APP_IPPR') . '.3/' . $msg['path'];
|
$url = 'http://' . env('APP_IPPR') . '.3/' . $msg['path'];
|
||||||
}
|
}
|
||||||
$data['url'] = base64_encode($url);
|
$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\FileLink;
|
||||||
use App\Models\FileUser;
|
use App\Models\FileUser;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Models\WebSocketDialogMsg;
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Module\Ihttp;
|
use App\Module\Ihttp;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Request;
|
use Request;
|
||||||
|
use Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine file
|
* @apiDefine file
|
||||||
@ -379,11 +381,11 @@ class FileController extends AbstractController
|
|||||||
* @apiName content
|
* @apiName content
|
||||||
*
|
*
|
||||||
* @apiParam {Number|String} id
|
* @apiParam {Number|String} id
|
||||||
* - Number 文件ID(需要登录)
|
* - Number: 文件ID(需要登录)
|
||||||
* - String 链接码(不需要登录,用于预览)
|
* - String: 链接码(不需要登录,用于预览)
|
||||||
* @apiParam {String} down 直接下载
|
* @apiParam {String} down 直接下载
|
||||||
* - no: 浏览(默认)
|
* - no: 浏览(默认)
|
||||||
* - yes: 下载
|
* - yes: 下载(office文件直接下载)
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
@ -1083,6 +1083,60 @@ class ProjectController extends AbstractController
|
|||||||
return Base::retSuccess('success', $file);
|
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. 下载任务文件
|
* @api {get} api/project/task/filedown 22. 下载任务文件
|
||||||
*
|
*
|
||||||
|
@ -96,7 +96,7 @@ services:
|
|||||||
|
|
||||||
fileview:
|
fileview:
|
||||||
container_name: "dootask-fileview-${APP_ID}"
|
container_name: "dootask-fileview-${APP_ID}"
|
||||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC2"
|
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC3"
|
||||||
environment:
|
environment:
|
||||||
TZ: "Asia/Shanghai"
|
TZ: "Asia/Shanghai"
|
||||||
KK_CONTEXT_PATH: "/fileview"
|
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) {
|
window.require(["ace/theme/dracula-dark"], function(m) {
|
||||||
if (typeof module == "object" && typeof exports == "object" && module) {
|
if (typeof module == "object" && typeof exports == "object" && module) {
|
||||||
module.exports = m;
|
module.exports = m;
|
||||||
|
@ -123,7 +123,7 @@ export default {
|
|||||||
case 'ppt':
|
case 'ppt':
|
||||||
return 'pptx'
|
return 'pptx'
|
||||||
}
|
}
|
||||||
return '';
|
return type;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadFile() {
|
loadFile() {
|
||||||
@ -144,11 +144,12 @@ export default {
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
let fileKey = this.code || this.value.id;
|
let fileKey = this.code || this.value.id;
|
||||||
|
let fileName = $A.strExists(this.fileName, '.') ? this.fileName : (this.fileName + '.' + this.fileType);
|
||||||
const config = {
|
const config = {
|
||||||
"document": {
|
"document": {
|
||||||
"fileType": this.fileType,
|
"fileType": this.fileType,
|
||||||
"key": this.fileType + '-' + fileKey,
|
"key": this.fileType + '-' + fileKey,
|
||||||
"title": this.fileName + '.' + this.fileType,
|
"title": fileName,
|
||||||
"url": 'http://nginx/api/file/content/?id=' + fileKey + '&token=' + this.userToken,
|
"url": 'http://nginx/api/file/content/?id=' + fileKey + '&token=' + this.userToken,
|
||||||
},
|
},
|
||||||
"editorConfig": {
|
"editorConfig": {
|
||||||
@ -164,6 +165,11 @@ export default {
|
|||||||
"callbackUrl": 'http://nginx/api/file/content/office?id=' + fileKey + '&token=' + this.userToken,
|
"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) {
|
if (this.readOnly) {
|
||||||
config.editorConfig.mode = "view";
|
config.editorConfig.mode = "view";
|
||||||
config.editorConfig.callbackUrl = null;
|
config.editorConfig.callbackUrl = null;
|
||||||
|
@ -181,8 +181,8 @@ export default {
|
|||||||
this.$Electron.ipcRenderer.send('windowRouter', {
|
this.$Electron.ipcRenderer.send('windowRouter', {
|
||||||
title: `${this.msgData.msg.name} (${$A.bytesToSize(this.msgData.msg.size)})`,
|
title: `${this.msgData.msg.name} (${$A.bytesToSize(this.msgData.msg.size)})`,
|
||||||
titleFixed: true,
|
titleFixed: true,
|
||||||
name: 'msgview-' + this.msgData.id,
|
name: 'file-msg-' + this.msgData.id,
|
||||||
path: "/single/msgview/" + this.msgData.id,
|
path: "/single/file/msg/" + this.msgData.id,
|
||||||
force: false,
|
force: false,
|
||||||
config: {
|
config: {
|
||||||
parent: null,
|
parent: null,
|
||||||
@ -191,7 +191,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} 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>
|
</ETooltip>
|
||||||
</li>
|
</li>
|
||||||
<li :class="['project-icon', searchText!='' ? 'active' : '']">
|
<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" />
|
<Icon class="menu-icon" type="ios-search" @click="searchFocus" />
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
<Input v-model="searchText" ref="searchInput" :placeholder="$L('名称、描述...')" class="search-input" clearable/>
|
<Input v-model="searchText" ref="searchInput" :placeholder="$L('名称、描述...')" class="search-input" clearable/>
|
||||||
@ -537,17 +537,6 @@ export default {
|
|||||||
|
|
||||||
...mapGetters(['projectData', 'projectParameter', 'transforTasks']),
|
...mapGetters(['projectData', 'projectParameter', 'transforTasks']),
|
||||||
|
|
||||||
searchAlways() {
|
|
||||||
return !(!this.searchText
|
|
||||||
|| this.settingShow
|
|
||||||
|| this.userShow
|
|
||||||
|| this.inviteShow
|
|
||||||
|| this.transferShow
|
|
||||||
|| this.workflowShow
|
|
||||||
|| this.logShow
|
|
||||||
|| this.archivedTaskShow);
|
|
||||||
},
|
|
||||||
|
|
||||||
userWaitRemove() {
|
userWaitRemove() {
|
||||||
const {userids, useridbak} = this.userData;
|
const {userids, useridbak} = this.userData;
|
||||||
if (!userids) {
|
if (!userids) {
|
||||||
|
@ -279,18 +279,22 @@
|
|||||||
<li v-for="file in fileList">
|
<li v-for="file in fileList">
|
||||||
<img v-if="file.id" class="file-ext" :src="file.thumb"/>
|
<img v-if="file.id" class="file-ext" :src="file.thumb"/>
|
||||||
<Loading v-else class="file-load"/>
|
<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>
|
<div class="file-size">{{$A.bytesToSize(file.size)}}</div>
|
||||||
<EPopover v-model="file._deling" class="file-delete">
|
<div class="file-menu" :class="{show:file._show_menu}">
|
||||||
<div class="task-detail-delete-file-popover">
|
<Icon @click="viewFile(file)" type="md-eye" />
|
||||||
<p>{{$L('你确定要删除这个文件吗?')}}</p>
|
<Icon @click="downFile(file)" type="md-arrow-round-down" />
|
||||||
<div class="buttons">
|
<EPopover v-model="file._show_menu" class="file-delete">
|
||||||
<Button size="small" type="text" @click="file._deling=false">{{$L('取消')}}</Button>
|
<div class="task-detail-delete-file-popover">
|
||||||
<Button size="small" type="primary" @click="deleteFile(file)">{{$L('确定')}}</Button>
|
<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>
|
||||||
</div>
|
<i slot="reference" class="taskfont del"></i>
|
||||||
<i slot="reference" :class="['taskfont', file._deling ? 'deling' : '']"></i>
|
</EPopover>
|
||||||
</EPopover>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="item-content">
|
<ul class="item-content">
|
||||||
@ -1102,7 +1106,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
deleteFile(file) {
|
deleteFile(file) {
|
||||||
this.$set(file, '_deling', false);
|
this.$set(file, '_show_menu', false);
|
||||||
this.$store.dispatch("forgetTaskFile", file.id)
|
this.$store.dispatch("forgetTaskFile", file.id)
|
||||||
//
|
//
|
||||||
this.$store.dispatch("call", {
|
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) {
|
downFile(file) {
|
||||||
$A.modalConfirm({
|
$A.modalConfirm({
|
||||||
title: '下载文件',
|
title: '下载文件',
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="single-msgview">
|
<div class="single-file-msg">
|
||||||
<PageTitle :title="title"/>
|
<PageTitle :title="title"/>
|
||||||
<Loading v-if="loadIng > 0"/>
|
<Loading v-if="loadIng > 0"/>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<AceEditor v-if="isCode" v-model="codeContent" :ext="codeExt" class="view-editor" readOnly/>
|
<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>
|
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.single-msgview {
|
.single-file-msg {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.preview-iframe,
|
.preview-iframe,
|
||||||
@ -44,9 +45,10 @@
|
|||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
import AceEditor from "../../components/AceEditor";
|
import AceEditor from "../../components/AceEditor";
|
||||||
|
import OnlyOffice from "../../components/OnlyOffice";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {AceEditor},
|
components: {OnlyOffice, AceEditor},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loadIng: 0,
|
loadIng: 0,
|
||||||
@ -73,6 +75,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return "Loading..."
|
return "Loading..."
|
||||||
},
|
},
|
||||||
|
|
||||||
isCode() {
|
isCode() {
|
||||||
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 1;
|
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 1;
|
||||||
},
|
},
|
||||||
@ -88,9 +91,27 @@ export default {
|
|||||||
}
|
}
|
||||||
return 'txt'
|
return 'txt'
|
||||||
},
|
},
|
||||||
isPreview() {
|
|
||||||
|
isOffice() {
|
||||||
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 2;
|
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() {
|
previewUrl() {
|
||||||
if (this.isPreview) {
|
if (this.isPreview) {
|
||||||
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.msgDetail.url))
|
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',
|
name: 'single-file',
|
||||||
path: '/single/file/:id',
|
path: '/single/file/:id',
|
||||||
@ -85,11 +95,6 @@ export default [
|
|||||||
path: '/single/task/:id',
|
path: '/single/task/:id',
|
||||||
component: () => import('./pages/single/task.vue'),
|
component: () => import('./pages/single/task.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'single-msgview',
|
|
||||||
path: '/single/msgview/:id',
|
|
||||||
component: () => import('./pages/single/msgview.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'login',
|
name: 'login',
|
||||||
path: '/login',
|
path: '/login',
|
||||||
|
@ -251,10 +251,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
color: $primary-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.file-size {
|
.file-size {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@ -263,27 +259,38 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #bbbbbb;
|
color: #bbbbbb;
|
||||||
}
|
}
|
||||||
.file-delete {
|
.file-menu {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
.taskfont {
|
&.show {
|
||||||
display: none;
|
opacity: 1;
|
||||||
|
}
|
||||||
|
i {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #aaaaaa;
|
color: #aaaaaa;
|
||||||
transition: color 0.3s;
|
transition: color 0.3s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 0 4px;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #ff0000;
|
color: #777777;
|
||||||
}
|
}
|
||||||
&.deling {
|
&.del {
|
||||||
display: inline-block;
|
font-size: 13px;
|
||||||
|
&:hover {
|
||||||
|
color: #ff0000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
.file-delete {
|
.file-name {
|
||||||
.taskfont {
|
color: $primary-title-color;
|
||||||
display: inline-block;
|
}
|
||||||
}
|
.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) {
|
window.require(["ace/theme/dracula-dark"], function(m) {
|
||||||
if (typeof module == "object" && typeof exports == "object" && module) {
|
if (typeof module == "object" && typeof exports == "object" && module) {
|
||||||
module.exports = m;
|
module.exports = m;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user