Skip to content

Commit

Permalink
perf: 聊天消息附件支持预览
Browse files Browse the repository at this point in the history
  • Loading branch information
kuaifan committed Jan 26, 2022
1 parent 08372fa commit 705d7f3
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 13 deletions.
50 changes: 50 additions & 0 deletions app/Http/Controllers/Api/DialogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,56 @@ public function msg__readlist()
return Base::retSuccess('success', $read ?: []);
}

/**
* @api {get} api/dialog/msg/detail 08. 消息详情
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__detail
*
* @apiParam {Number} msg_id 消息ID
*
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function msg__detail()
{
User::auth();
//
$msg_id = intval(Request::input('msg_id'));
//
$dialogMsg = WebSocketDialogMsg::whereId($msg_id)->first();
if (empty($dialogMsg)) {
return Base::retError("文件不存在");
}
$data = $dialogMsg->toArray();
//
if ($data['type'] == 'file') {
$codeExt = ['txt'];
$fillExt = ['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内的文件
$data['content'] = file_get_contents($filePath);
$data['file_mode'] = 1;
} else {
// 支持预览
if (in_array($msg['ext'], $fillExt)) {
$url = Base::fillUrl($msg['path']);
} else {
$url = 'http://' . env('APP_IPPR') . '.3/' . $msg['path'];
}
$data['url'] = base64_encode($url);
$data['file_mode'] = 2;
}
}
//
return Base::retSuccess("success", $data);
}

/**
* @api {get} api/dialog/msg/download 08. 文件下载
*
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"stylus-loader": "^6.2.0",
"tinymce": "^5.10.2",
"tui-calendar-hi": "^1.15.1-5",
"view-design-hi": "^4.7.0-8",
"view-design-hi": "^4.7.0-10",
"vue": "^2.6.14",
"vue-clipboard2": "^0.3.3",
"vue-emoji-picker": "^1.0.3",
Expand Down
2 changes: 1 addition & 1 deletion public/css/iview.css

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion resources/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import Language from './language/index'
import store from './store/index'

Vue.use(Vuex);
Vue.use(ViewUI);
Vue.use(ViewUI, {
modal: {
checkEscClose: true
}
});
Vue.use(VueRouter);
Vue.use(Language);

Expand Down
40 changes: 34 additions & 6 deletions resources/assets/js/pages/manage/components/DialogView.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<template>
<div class="dialog-view" :data-id="msgData.id">
<div :class="`dialog-view ${msgData.type}`" :data-id="msgData.id">

<!--文本-->
<div v-if="msgData.type === 'text'" class="dialog-content">
<pre class="no-dark-mode" v-html="textMsg(msgData.msg.text)"></pre>
<pre class="no-dark-mode">{{textMsg(msgData.msg.text)}}</pre>
</div>

<!--等待-->
<div v-else-if="msgData.type === 'loading'" class="dialog-content loading"><Loading/></div>

<!--文件-->
<div v-else-if="msgData.type === 'file'" :class="['dialog-content', msgData.msg.type]">
<div class="dialog-file" @click="downFile">
<img v-if="msgData.msg.type === 'img'" class="file-img" :style="imageStyle(msgData.msg)" :src="msgData.msg.thumb"/>
<div class="dialog-file">
<img v-if="msgData.msg.type === 'img'" class="file-img" :style="imageStyle(msgData.msg)" :src="msgData.msg.thumb" @click="viewFile"/>
<div v-else class="file-box">
<img class="file-thumb" :src="msgData.msg.thumb"/>
<div class="file-info">
Expand All @@ -19,7 +21,15 @@
</div>
</div>
</div>
<div class="dialog-file-menu">
<div class="file-menu-warp"></div>
<div class="file-menu-icon">
<Icon @click="viewFile" type="md-eye" />
<Icon @click="downFile" type="md-arrow-round-down" />
</div>
</div>
</div>

<!--未知-->
<div v-else class="dialog-content unknown">{{$L("未知的消息类型")}}</div>

Expand Down Expand Up @@ -138,8 +148,7 @@ export default {
if (!text) {
return ""
}
text = text.trim().replace(/(\n\x20*){3,}/g, "<br/><br/>");
text = text.trim().replace(/\n/g, "<br/>");
text = text.trim().replace(/(\n\x20*){3,}/g, "\n\n");
return text;
},
Expand Down Expand Up @@ -167,6 +176,25 @@ export default {
return {};
},
viewFile() {
if (this.$Electron) {
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,
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/msgview/${this.msgData.id}`))
}
},
downFile() {
$A.modalConfirm({
title: '下载文件',
Expand Down
130 changes: 130 additions & 0 deletions resources/assets/js/pages/single/msgview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<template>
<div class="single-msgview">
<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>
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
</template>
</div>
</template>

<style lang="scss" scoped>
.single-msgview {
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";
export default {
components: {AceEditor},
data() {
return {
loadIng: 0,
msgDetail: {},
}
},
mounted() {
//
},
watch: {
'$route': {
handler() {
this.getInfo();
},
immediate: true
},
},
computed: {
title() {
const {msg} = this.msgDetail;
if (msg && msg.name) {
return msg.name;
}
return "Loading..."
},
isCode() {
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 1;
},
codeContent() {
if (this.isCode) {
return this.msgDetail.content;
}
return '';
},
codeExt() {
if (this.isCode) {
return this.msgDetail.msg.ext;
}
return 'txt'
},
isPreview() {
return this.msgDetail.type == 'file' && this.msgDetail.file_mode == 2;
},
previewUrl() {
if (this.isPreview) {
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.msgDetail.url))
}
return ''
}
},
methods: {
getInfo() {
let msg_id = $A.runNum(this.$route.params.id);
if (msg_id <= 0) {
return;
}
this.loadIng++;
this.$store.dispatch("call", {
url: 'dialog/msg/detail',
data: {
msg_id,
},
}).then(({data}) => {
this.loadIng--;
this.msgDetail = data;
}).catch(({msg}) => {
this.loadIng--;
$A.modalError({
content: msg,
onOk: () => {
if (this.$Electron) {
window.close();
}
}
});
});
}
}
}
</script>
5 changes: 5 additions & 0 deletions resources/assets/js/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ 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',
Expand Down
44 changes: 41 additions & 3 deletions resources/assets/sass/pages/components/dialog-wrapper.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
line-height: 22px;
max-width: 100%;
.ivu-tag {
flex-shrink: 0;
margin: 0 6px 0 0;
padding: 0 5px;
&.ivu-tag-success {
Expand Down Expand Up @@ -110,19 +111,50 @@
height: 30px;
}
.dialog-view {
max-width: 70%;
display: flex;
flex-direction: column;
align-items: flex-start;
margin: 0 0 0 8px;
position: relative;
&.text {
max-width: 70%;
}
.dialog-content {
color: #333333;
background-color: #F4F5F7;
padding: 8px;
min-width: 32px;
border-radius: 6px 6px 6px 0;
.dialog-file {
cursor: pointer;
.dialog-file-menu {
opacity: 0;
transition: all 0.3s;
position: absolute;
left: 0;
bottom: -8px;
.file-menu-warp {
width: 100%;
height: 12px;
}
.file-menu-icon {
display: flex;
align-items: center;
border-radius: 4px;
border: 1px solid #ddd;
> i {
flex: 1;
display: inline-block;
padding: 4px 6px;
color: #999;
font-size: 13px;
cursor: pointer;
&:hover {
color: #777;
}
&+i {
border-left: 1px solid #ddd;
}
}
}
}
> pre {
display: block;
Expand All @@ -133,6 +165,11 @@
word-wrap: break-word;
word-break: break-word;
}
&:hover {
.dialog-file-menu {
opacity: 1;
}
}
&.loading {
display: flex;
.common-loading {
Expand Down Expand Up @@ -187,6 +224,7 @@
overflow: hidden;
.file-img {
display: flex;
cursor: pointer;
}
}
&.unknown {
Expand Down
2 changes: 1 addition & 1 deletion resources/assets/statics/public/css/iview.css

Large diffs are not rendered by default.

0 comments on commit 705d7f3

Please sign in to comment.