点击图片按钮,选择本地图片进行发送
From.vue
<template>
<a-spin :spinning="confirmLoading">
<a-row>
<a-col :span="18" :style="'height:750px;'">
<a-card type="inner" title="工单服务" :style="'background: RGB(247,247,247);height:100%;'">
<chat ref="chat"></chat>
<div class="hover-pr" style="text-align: right; margin-bottom: 5px; float: right;" @click="complaint">
<a-icon type="dislike" /> 我要投诉
</div>
<div @click="uploadImg">
<img style="width: 20px;height: 20px;" src="@/assets/picture.png"/>
</div>
<a-textarea rows="4" placeholder="输入内容" v-model="reply.replyContent" contenteditable @keyup.enter.exact="submit" @keydown.enter.exact="handleKeydown"/>
<a-button type="primary" :style="'float: right;margin-top:5px;'" @click="sendReplyContent" :disabled="model.issueState === '1'">发送</a-button>
</a-card>
</a-col>
</a-row>
</a-spin>
</template>
<script>
import chat from '@/components/chat/chat'
export default {
components: {
chat
},
data () {
return {
url: {
sendContent: "/aa/bb/add",
addPicture: "/aa/bb/addPicture",
isComplaint: "/aa/bb/isComplaint"
}
}
},
mounted() {
this.$refs.chat.getReplyList(this.model.id)
},
methods: {
//输入框按下回车发送
handleKeydown(event) {
if (event.shiftKey && event.keyCode === 13) {
document.execCommand('insertLineBreak'); // 换行
} else if (event.keyCode === 13) { // 回车键
console.log("回车发送");
this.sendReplyContent();
return false;
}
},
//上传图片
uploadImg:function (){
let that=this;
let input = document.createElement("input");
input.type = "file";
input.accept = "image/gif,image/jpeg,image/jpg,image/png";
input.style.display = "none";
input.addEventListener("change", function(e) {
let formData = new FormData();
let file = e.target.files[0];
formData.append("imgfile", file); //传给后台的file的key值是可以自己定义的
formData.append("issueId", that.reply.issueId); //传给后台的file的key值是可以自己定义的
httpAction(that.url.addPicture,formData,"post").then((res)=>{
console.log(res)
if(res.success){
that.$message.success("发送成功");
that.$refs.chat.getReplyList(that.model.id)
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
});
document.body.appendChild(input);
input.click();
},
// 发送消息
sendReplyContent(){
let that = this;
if (this.reply.replyContent.trim() === ''){
that.$message.warning("发送内容不能为空");
return ;
}
that.confirmLoading = true;
httpAction(this.url.sendContent,this.reply,"post").then((res)=>{
if(res.success){
that.reply.replyContent = '';
this.$refs.chat.getReplyList(this.model.id)
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
},
}
}
</script>
chat.vue
<template>
<div class="chat-content" style="height: 530px;overflow: scroll;">
<!-- recordContent 聊天记录数组-->
<div v-for="(itemc,indexc) in issueReplyList" :key="indexc">
<!-- 对方 -->
<div class="word" v-if="itemc.customerUserreply === null">
<img :src="'https://gts-workorder.oss-cn-beijing.aliyuncs.com/20210112/da98103c-d86b-4ff0-b508-cafc0258f6b1/阿里云小智.png'">
<div class="info">
<p class="time">{{itemc.createName}} {{itemc.createDate}}</p>
<div>
<div class="info-content" v-if="itemc.isPicture == '1'">
<img class="picture" :src="'data:image/png;base64,' + itemc.replyContent" @click="showImagePreview('data:image/png;base64,' + itemc.replyContent)">
</div>
<div class="info-content" v-else>{{itemc.replyContent}}</div>
</div>
</div>
</div>
<!-- 我的 -->
<div class="word-my" v-else>
<div class="info">
<p class="time">{{itemc.createName}} {{itemc.createDate}}</p>
<div>
<div class="info-content" v-if="itemc.isPicture == '1'">
<img class="picture" :src="'data:image/png;base64,' + itemc.replyContent" @click="showImagePreview('data:image/png;base64,' + itemc.replyContent)">
</div>
<div class="info-content" v-else>{{itemc.replyContent}}</div>
</div>
</div>
<img :src="'https://g.alicdn.com/aliyun/usercenter/1.3.12/images/workorder/avatar.png'">
</div>
</div>
</div>
</template>
<script>
import { getAction, httpAction } from '@api/manage'
export default {
name: 'chat',
created () {
//this.getReplyList();
},
watch: {
'processData': 'scrollToBottom'
},
data () {
return {
issueReplyList:[],
confirmLoading: false,
url: {
list: "/issue/customerserviceIssuereply/getlistByIssueId",
}
}
},
methods: {
//点击图片放大
showImagePreview(e) {
const image = new Image();
image.src = e;
console.log(e)
image.onload = () => {
// 创建弹出层
const previewContainer = document.createElement('div');
previewContainer.style.position = 'fixed';
previewContainer.style.top = 0;
previewContainer.style.bottom = 0;
previewContainer.style.left = 0;
previewContainer.style.right = 0;
previewContainer.style.backgroundColor = 'rgba(0,0,0,0.8)';
previewContainer.style.display = 'flex';
previewContainer.style.justifyContent = 'center';
previewContainer.style.alignItems = 'center';
document.body.appendChild(previewContainer);
// 在弹出层中添加图片
const previewImage = document.createElement('img');
previewImage.src = e;
previewImage.style.maxWidth = '85%';
previewImage.style.maxHeight = '85%';
previewContainer.appendChild(previewImage);
// 点击弹出层,关闭预览
previewContainer.addEventListener('click', () => {
document.body.removeChild(previewContainer);
});
};
},
scrollToBottom: function () {
this.$nextTick(() => {
let div = document.getElementsByClassName('chat-content')
div[0].scrollTop = div[0].scrollHeight
console.log(div)
})
},
getReplyList(issueId){
getAction(this.url.list + '?issueId=' + issueId).then((res)=>{
this.issueReplyList = [];
console.log(res)
if(res.success){
for (let i = 0;i < res.result.length;i++) {
this.issueReplyList.push(res.result[i])
}
this.scrollToBottom();
}else{
this.$message.warning(res.message);
}
}).finally(() => {
this.confirmLoading = false;
})
}
}
}
</script>
<style lang="less" scoped>
.chat-content{
width: 100%;
padding: 20px;
.word{
display: flex;
margin-bottom: 20px;
img{
width: 40px;
height: 40px;
border-radius: 50%;
}
.info{
margin-left: 10px;
.time{
font-size: 12px;
color: rgba(51,51,51,0.8);
margin: 0;
height: 20px;
line-height: 20px;
margin-top: -5px;
}
.info-content{
padding: 10px;
font-size: 14px;
background: #fff;
position: relative;
margin-top: 8px;
.picture{
width: 80px;
height: 80px;
border-radius: 1%;
}
}
//小三角形
.info-content::before{
position: absolute;
left: -8px;
top: 8px;
content: '';
border-right: 10px solid #FFF;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
}
}
}
.word-my{
display: flex;
justify-content:flex-end;
margin-bottom: 20px;
img{
width: 40px;
height: 40px;
border-radius: 50%;
}
.info{
width: 90%;
margin-left: 10px;
text-align: right;
.time{
font-size: 12px;
color: rgba(51,51,51,0.8);
margin: 0;
height: 20px;
line-height: 20px;
margin-top: -5px;
margin-right: 10px;
}
.info-content{
max-width: 70%;
padding: 10px;
font-size: 14px;
float: right;
margin-right: 10px;
position: relative;
margin-top: 8px;
background: #A3C3F6;
text-align: left;
.picture{
width: 100px;
height: 100px;
border-radius: 1%;
}
}
//小三角形
.info-content::after{
position: absolute;
right: -8px;
top: 8px;
content: '';
border-left: 10px solid #A3C3F6;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
}
}
}
}
</style>
Controller
图片用MultipartFile接收,再转成File,转成base64格式存入数据库
@AutoLog(value = "发送工单消息--图片")
@ApiOperation(value = "发送工单消息--图片", notes = "发送工单消息--图片")
@PostMapping(value = "/addPicture")
public Result<?> addPicture(@RequestParam("imgfile") MultipartFile file,@RequestParam("issueId") String issueId,CustomerserviceIssuereply customerserviceIssuereply) {
try {
customerserviceIssuereplyService.addPicture(customerserviceIssuereply,file,issueId);
}catch (Exception e){}
return Result.OK("发送成功!");
}
public void addPicture(CustomerserviceIssuereply customerserviceIssuereply,MultipartFile file,String issueId) throws IOException {
String fileName = file.getOriginalFilename();
File file2 = new File(fileName);
FileUtils.copyInputStreamToFile(file.getInputStream(), file2);
InputStream inputStream = new FileInputStream(file2);
byte[] bytes = IOUtils.toByteArray(inputStream);
String base64Str = Base64.encodeBase64String(bytes);
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
customerserviceIssuereply.setCustomerUserreply(sysUser.getId());
customerserviceIssuereply.setCreateBy(sysUser.getUsername());
customerserviceIssuereply.setCustomerUserreply(sysUser.getUsername());
customerserviceIssuereply.setCreateName(sysUser.getRealname());
customerserviceIssuereply.setCreateDate(new Date());
customerserviceIssuereply.setReplyCreatedate(new Date());
customerserviceIssuereply.setBpmStatus("0");
customerserviceIssuereply.setReplyContent(base64Str);
customerserviceIssuereply.setIsPicture("1");
super.baseMapper.insert(customerserviceIssuereply);
}