发送图文消息

需求:点击选择图片或拖拽选择图片(均可多选)。可输入文字,最终经后台发给app端,因此需保留顺序和布局信息,将参数格式化。

模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<FormItem label="消息内容:" class="ivu-form-item-required">
<div style="word-wrap: break-word;white-space : normal;">
<div class="config-point-ipt set-item-content contentLengthNotice" style="height:200px; overflow-y:auto;" id="content" contenteditable="true" name="content" @keyup="removeBackgroundImage" @dragenter="ignoreDrag" @dragover="ignoreDrag" @drop="drop">
</div>
<p v-if="!hasContent" style="color:#c7c1c1;position:absolute;bottom:205px;left:20px;pointer-events: none;">
请输入消息内容,最多不超过1000字
</p>
<form id="myForm">
<input @change="chooseImage" multiple type="file" accept="image/jpeg,image/x-png,image/gif" id="" value="" style="width:64px"/>
</form>
<span style="color: #7070dc;font-size:5px;font-style:italic;">
Tips:您可通过点击左侧添加图片,亦可从本地文件夹向消息内容框拖放图片
</span>
</div>
</FormItem>

<FormItem>
<Button type="primary" @click="sendHandler">确定发送</Button>
</FormItem>
1
2
3
4
5
6
// 拖拽进入事件,拖拽移动事件
ignoreDrag(e) {
// 确保其他元素不会取得该事件
e.stopPropagation();
e.preventDefault();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// 拖拽放下事件
drop(e) {
this.hasContent = true;
e.stopPropagation();
e.preventDefault();
let contentEl = document.querySelector('#content');
contentEl.focus();
//去掉背景图片
if (contentEl.classList.contains('contentLengthNotice')) {
contentEl.classList.remove('contentLengthNotice');
}
let _this = this;
let files = e.dataTransfer.files;

for (let i = 0; i < files.length; i++) {
// 获取File引用:
let file = files[i];
if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
this.Message.error('存在非图片文件,请重新拖选!');
return;
}

_this.imgLength++;
//读取文件:
let reader = new FileReader();

reader.onloadend = function() {
// 图片的 base64 格式, 可以直接当成 img 的 src 属性值
let dataURL = reader.result;
let imgEle = document.createElement('img');
imgEle.setAttribute('src', dataURL);
imgEle.setAttribute('alt', file.name);
imgEle.setAttribute(
'id',
file.name.substring(0, file.name.lastIndexOf('.')) +
'_' +
_this.imgLength +
file.name.substring(file.name.lastIndexOf('.'))
);
// 获取真实宽高
let img = new Image();
img.src = dataURL;
img.onload = function() {
let width = img.width;
let height = img.height;
let win = contentEl.ownerDocument.defaultView;
let contentWidth = win.getComputedStyle(contentEl, null).width;
let contentPaddingLeft = win.getComputedStyle(contentEl, null).paddingLeft;
let contentBorderLeftWidth = win.getComputedStyle(contentEl, null).borderLeftWidth;
let preEleWidth =
parseInt(contentWidth) - 2 * parseInt(contentBorderLeftWidth) - 2 * parseInt(contentPaddingLeft);
if (width > preEleWidth) {
imgEle.style.width = preEleWidth;
imgEle.style.heigth = (preEleWidth * height) / width + 'px';
} else {
imgEle.style.width = width;
imgEle.style.heigth = height + 'px';
}
window.document.execCommand('InsertHtml', '', imgEle.outerHTML);
};
};
//以DataURL的形式读取文件:
reader.readAsDataURL(file);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 输入时事件
removeBackgroundImage() {
let contentEl = document.querySelector('#content');
this.contentText = contentEl.innerText;
if (this.contentText.length >= 1000) {
this.$Message.error('内容不能超过1000字');
}

if (contentEl.innerHTML) {
this.hasContent = true;
} else {
this.hasContent = false;
}
if (contentEl.classList.contains('contentLengthNotice')) {
contentEl.classList.remove('contentLengthNotice');
}
if (!contentEl.innerHTML && !contentEl.classList.contains('contentLengthNotice')) {
contentEl.classList.add('contentLengthNotice');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 选择文件
chooseImage(e) {
this.hasContent = true;
let _this = this;
let contentEl = document.querySelector('#content');
contentEl.focus();
// 读取文件
let files = e.target.files;
for (let i = 0; i < files.length; i++) {
let file = files[i];
_this.imgLength++;
let reader = new FileReader();
reader.readAsDataURL(file); // 读出 base64
reader.onloadend = function() {
// 图片的 base64 格式, 可以直接当成 img 的 src 属性值
let dataURL = reader.result;
let contentEl = document.querySelector('#content');
let imgEle = document.createElement('img');
imgEle.setAttribute('src', dataURL);
imgEle.setAttribute('alt', file.name);
imgEle.setAttribute(
'id',
file.name.substring(0, file.name.lastIndexOf('.')) +
'_' +
_this.imgLength +
file.name.substring(file.name.lastIndexOf('.'))
);
// 获取真实宽高
let img = new Image();
img.src = dataURL;
img.onload = function() {
let width = img.width;
let height = img.height;
let win = contentEl.ownerDocument.defaultView;
let contentWidth = win.getComputedStyle(contentEl, null).width;
let contentPaddingLeft = win.getComputedStyle(contentEl, null).paddingLeft;
let contentBorderLeftWidth = win.getComputedStyle(contentEl, null).borderLeftWidth;
let preEleWidth =
parseInt(contentWidth) - 2 * parseInt(contentBorderLeftWidth) - 2 * parseInt(contentPaddingLeft);
if (width > preEleWidth) {
imgEle.style.width = preEleWidth;
imgEle.style.heigth = (preEleWidth * height) / width + 'px';
} else {
imgEle.style.width = width;
imgEle.style.heigth = height + 'px';
}
window.document.execCommand('InsertHtml', '', imgEle.outerHTML);
};
};
}
document.getElementById('myForm').reset();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 发送
sendHandler() {
let contentEl = document.querySelector('#content');

let imgEles = document.getElementsByTagName('img');
let imgContentArr = [];
for (let i = 0; i < imgEles.length; i++) {
let obj = {};
obj.imgName = imgEles[i].getAttribute('id');
obj.imgBase64 = imgEles[i].getAttribute('src').substring(imgEles[i].getAttribute('src').indexOf('base64,') + 7);
imgEles[i].setAttribute('src', '');
imgContentArr.push(obj);
}
let txtContent = contentEl.innerHTML.replace(/ src=""/g, '');
if (txtContent === '' && imgContentArr.length === 0) {
this.$Message.error('信息内容不能为空!');
return;
}
if (contentEl.innerText.length >= 1000) {
this.lengthFlag = true;
return;
}
let messageContent = {
txtContent: escapeHTML(txtContent),
imgContentArr: imgContentArr
};
this.$api['sendMessage/send']({
content: messageContent
}).then(data => {
this.$Message.success({
content: '发送成功',
duration: 3,
closable: true
});
this.hasContent = false;
contentEl.innerHTML = '';
});
}

接口调用方法见axios封装及api调用方法