perf: 长文本消息的处理

This commit is contained in:
kuaifan 2022-06-09 16:06:18 +08:00
parent a11eb11166
commit 0035789951
4 changed files with 84 additions and 48 deletions

49
resources/assets/js/functions/utils.js vendored Executable file
View File

@ -0,0 +1,49 @@
module.exports = {
/**
* 消息格式化处理
* @param text
* @param userid
* @returns {string|*}
*/
textMsgFormat(text, userid) {
if (!text) {
return ""
}
const atReg = new RegExp(`<span class="mention user" data-id="${userid}">`, "g")
text = text.trim().replace(/(\n\x20*){3,}/g, "\n\n");
text = text.replace(/&nbsp;/g, ' ')
text = text.replace(/<p><\/p>/g, '<p><br/></p>')
text = text.replace(/\{\{RemoteURL\}\}/g, $A.apiUrl('../'))
text = text.replace(atReg, `<span class="mention me" data-id="${userid}">`)
// 处理内容连接
if (/https*:\/\//.test(text)) {
text = text.split(/(<[^>]*>)/g).map(string => {
if (string && !/<[^>]*>/.test(string)) {
string = string.replace(/(https*:\/\/)((\w|=|\?|\.|\/|&|-|:|\+|%|;)+)/g, "<a href=\"$1$2\" target=\"_blank\">$1$2</a>")
}
return string;
}).join("")
}
// 处理图片显示尺寸
const array = text.match(/<img\s+[^>]*?>/g);
if (array) {
const widthReg = new RegExp("width=\"(\\d+)\""),
heightReg = new RegExp("height=\"(\\d+)\"")
array.some(res => {
const widthMatch = res.match(widthReg),
heightMatch = res.match(heightReg);
if (widthMatch && heightMatch) {
const width = parseInt(widthMatch[1]),
height = parseInt(heightMatch[1]),
maxSize = res.indexOf("emoticon") > -1 ? 150 : 220;
const scale = $A.scaleToScale(width, height, maxSize, maxSize);
const value = res
.replace(widthReg, `original-width="${width}" width="${scale.width}"`)
.replace(heightReg, `original-height="${height}" height="${scale.height}"`)
text = text.replace(res, value)
}
})
}
return text;
}
}

View File

@ -124,6 +124,7 @@ import WCircle from "../../../components/WCircle";
import {mapState} from "vuex";
import {Store} from "le5le-store";
import longpress from "../../../directives/longpress";
import {textMsgFormat} from "../../../functions/utils";
export default {
name: "DialogView",
@ -224,10 +225,6 @@ export default {
}
}
return classArray;
},
atUserReg() {
return new RegExp(`<span class="mention user" data-id="${this.userId}">`, "g")
}
},
@ -292,44 +289,7 @@ export default {
},
textMsg(text) {
if (!text) {
return ""
}
text = text.trim().replace(/(\n\x20*){3,}/g, "\n\n");
text = text.replace(/&nbsp;/g, ' ')
text = text.replace(/<p><\/p>/g, '<p><br/></p>')
text = text.replace(/\{\{RemoteURL\}\}/g, $A.apiUrl('../'))
text = text.replace(this.atUserReg, `<span class="mention me" data-id="${this.userId}">`)
//
if (/https*:\/\//.test(text)) {
text = text.split(/(<[^>]*>)/g).map(string => {
if (string && !/<[^>]*>/.test(string)) {
string = string.replace(/(https*:\/\/)((\w|=|\?|\.|\/|&|-|:|\+|%|;)+)/g, "<a href=\"$1$2\" target=\"_blank\">$1$2</a>")
}
return string;
}).join("")
}
//
const array = text.match(/<img\s+[^>]*?>/g);
if (array) {
const widthReg = new RegExp("width=\"(\\d+)\""),
heightReg = new RegExp("height=\"(\\d+)\"")
array.some(res => {
const widthMatch = res.match(widthReg),
heightMatch = res.match(heightReg);
if (widthMatch && heightMatch) {
const width = parseInt(widthMatch[1]),
height = parseInt(heightMatch[1]),
maxSize = res.indexOf("emoticon") > -1 ? 150 : 220;
const scale = $A.scaleToScale(width, height, maxSize, maxSize);
const value = res
.replace(widthReg, `original-width="${width}" width="${scale.width}"`)
.replace(heightReg, `original-height="${height}" height="${scale.height}"`)
text = text.replace(res, value)
}
})
}
return text;
return textMsgFormat(text, this.userId);
},
recordStyle(info) {

View File

@ -570,15 +570,20 @@ export default {
this.onActive();
//
let tempId = $A.randomString(16);
this.tempMsgs.push({
let tempMsg = {
id: tempId,
dialog_id: this.dialogData.id,
type: 'text',
userid: this.userId,
msg: {
text: msgText,
text: $A.stringLength(msgText) > 2000 ? '' : msgText,
},
});
};
if (msgText.length > 2000) {
tempMsg.type = 'loading';
tempMsg.msg = { };
}
this.tempMsgs.push(tempMsg);
//
this.$store.dispatch("call", {
url: 'dialog/msg/sendtext',

View File

@ -7,7 +7,10 @@
<TEditor v-else-if="isType('text')" :value="msgDetail.content.content" height="100%" readOnly/>
<Drawio v-else-if="isType('drawio')" v-model="msgDetail.content" :title="msgDetail.msg.name" readOnly/>
<Minder v-else-if="isType('mind')" :value="msgDetail.content" readOnly/>
<AceEditor v-else-if="isType('code')" v-model="msgDetail.content.content" :ext="msgDetail.msg.ext" class="view-editor" readOnly/>
<template v-else-if="isType('code')">
<div v-if="isLongText(msgDetail.msg.name)" class="view-code" v-html="longTextFormat(msgDetail.content.content)"></div>
<AceEditor v-else v-model="msgDetail.content.content" :ext="msgDetail.msg.ext" class="view-editor" readOnly/>
</template>
<OnlyOffice v-else-if="isType('office')" v-model="officeContent" :code="officeCode" :documentKey="documentKey" readOnly/>
<iframe v-else-if="isType('preview')" class="preview-iframe" :src="previewUrl"/>
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
@ -23,7 +26,8 @@
.ace_editor,
.markdown-preview-warp,
.teditor-wrapper,
.no-support {
.no-support,
.view-code {
position: absolute;
top: 0;
left: 0;
@ -39,6 +43,11 @@
float: none;
max-width: none;
}
.view-code {
white-space: pre-wrap;
word-wrap: break-word;
overflow: auto;
}
.view-editor,
.no-support {
display: flex;
@ -59,6 +68,8 @@
<script>
import Vue from 'vue'
import Minder from '../../components/Minder'
import {textMsgFormat} from "../../functions/utils";
import {mapState} from "vuex";
Vue.use(Minder)
const MDPreview = () => import('../../components/MDEditor/preview');
@ -88,6 +99,8 @@ export default {
},
},
computed: {
...mapState(['userId']),
msgId() {
const {msgId} = this.$route.params;
return parseInt(/^\d+$/.test(msgId) ? msgId : 0);
@ -150,6 +163,7 @@ export default {
this.loadIng--;
});
},
documentKey() {
return new Promise(resolve => {
this.$store.dispatch("call", {
@ -164,7 +178,15 @@ export default {
resolve(0)
});
});
}
},
isLongText(name) {
return /^LongText-/.test(name)
},
longTextFormat(text) {
return textMsgFormat(text, this.userId)
},
}
}
</script>