|
|
|
@ -1,913 +0,0 @@
|
|
|
|
|
<template>
|
|
|
|
|
<!-- -->
|
|
|
|
|
<view class="chat-bottom" :style="{'bottom':isInput==true?getKeyHeight()+'px':'0px'}" @touchend='endAudio'>
|
|
|
|
|
<view class="bottom-operation">
|
|
|
|
|
<view class="goVoice" @click="setAudioShow">
|
|
|
|
|
<image src="../../../static/im/voice.png" mode=""></image>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- <u-input type="textarea" maxlength="300" :clearable="false" height="80rpx" v-model="chatInfo" placeholder-style="color:#999;" placeholder="输入文字..." /> -->
|
|
|
|
|
<textarea v-if="!isIos()&&!audioShow" class="textarea" :class="{'textarea2':chatInfo}" maxlength="300"
|
|
|
|
|
v-model="chatInfo" @focus='onInput' placeholder-style="color:#999;" placeholder="输入文字..."
|
|
|
|
|
:auto-height='true' :adjust-position="false" />
|
|
|
|
|
<textarea v-if="isIos()&&!audioShow" class="textarea" :class="{'textarea2':chatInfo}" maxlength="300"
|
|
|
|
|
v-model="chatInfo" @focus='onInput' placeholder-style="color:#999;" placeholder="输入文字..."
|
|
|
|
|
:auto-height='true' />
|
|
|
|
|
<!-- <view class="textarea" v-if="audioShow">按住说话</view> -->
|
|
|
|
|
<view class="goexpression" @click="setEmojiShow">
|
|
|
|
|
<image src="../../../static/im/expression.png" mode=""></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-show="chatInfo" class="send-btn" @touchend.prevent="sendMsg">
|
|
|
|
|
发送
|
|
|
|
|
</view>
|
|
|
|
|
<view class="more" v-show="!chatInfo" @click="setMoreShow">
|
|
|
|
|
<image src="../../../static/im/more.png" mode=""></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="bottom-box">
|
|
|
|
|
<view v-show="emojiShow" class="emoji-box">
|
|
|
|
|
<view class="tools-box">
|
|
|
|
|
<text class="emoji" @click="setEmoji(item)"
|
|
|
|
|
v-for="(item,index) in getEmoji()">{{entitiestoUtf16(item)}}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-show="moreShow" class="operation-box">
|
|
|
|
|
<view class="operation-item" @click="goQuick">
|
|
|
|
|
<view class="item-btn">
|
|
|
|
|
<image src="../../../static/im/reply.png" mode=""></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="item-hint">回复</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="operation-item" @click="chooseImage">
|
|
|
|
|
<view class="item-btn">
|
|
|
|
|
<image src="../../../static/im/picture.png" mode=""></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="item-hint">相册</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="operation-item" @click="chooseFile">
|
|
|
|
|
<view class="item-btn">
|
|
|
|
|
<image src="../../../static/im/file.png" mode=""></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="item-hint">文件</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="operation-item" @click="chatCollect">
|
|
|
|
|
<view class="item-btn">
|
|
|
|
|
<image src="../../../static/im/collect.png"></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="item-hint">收藏</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<u-popup v-model="showAitFlag" mode="bottom" border-radius="16" >
|
|
|
|
|
<!-- -->
|
|
|
|
|
<view class="ait-box" :style="{'height':isInput==true? (425 - keyHeight/2) +'px':'425px'}">
|
|
|
|
|
<view class="ab-title" >
|
|
|
|
|
<u-icon class='abt-close' name="arrow-down" color="#333333" size="24"></u-icon>
|
|
|
|
|
<text class="abt-txt">选择提醒的人</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="ipt-wrp">
|
|
|
|
|
<image class="ipt-icon" src="@/static/sousuo.png"></image>
|
|
|
|
|
<input type="text" confirm-type="search" v-model="aitKeyword" class="ipt" placeholder="昵称搜索" >
|
|
|
|
|
</view>
|
|
|
|
|
<view class="ab-item" @click="setAit()">
|
|
|
|
|
<view class="abi-all">@</view>
|
|
|
|
|
<view class="abi-name">@所有人({{groupPeoList.length}})</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="ab-item" @click="setAit(item)" v-for="(item,index) in groupPeoList" v-if="item.nickName.includes(aitKeyword)">
|
|
|
|
|
<image class="abi-img" :src="item.avatar"></image>
|
|
|
|
|
<view class="abi-name clamp">{{item.nickName}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</u-popup>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {
|
|
|
|
|
utf16toEntities,
|
|
|
|
|
entitiestoUtf16
|
|
|
|
|
} from '@/common/js/utils.js'
|
|
|
|
|
import emojiData from '@/common/js/emoji.js'
|
|
|
|
|
import {
|
|
|
|
|
sendMsg,
|
|
|
|
|
sendGroupMsg,
|
|
|
|
|
sendSpecialMessage,
|
|
|
|
|
sendTextMsg,
|
|
|
|
|
getUserByGroupId
|
|
|
|
|
} from '@/common/api-request/im.js'
|
|
|
|
|
import cCircle from "@/components/Your_Exios-Circle/Your_Exios-Circle.vue"
|
|
|
|
|
import api from '@/common/js/api.js'
|
|
|
|
|
const baseUrl = api.host['local'];
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
cCircle
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
toUserNo: {
|
|
|
|
|
type: [String, Number],
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
sendType: {
|
|
|
|
|
type: [String, Number],
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
isInput: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
},
|
|
|
|
|
keyHeight: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 0
|
|
|
|
|
},
|
|
|
|
|
isScreen: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
chatInfo: '',
|
|
|
|
|
userNo: '',
|
|
|
|
|
moreShow: false,
|
|
|
|
|
emojiShow: false,
|
|
|
|
|
audioShow: false,
|
|
|
|
|
showAitFlag: false,
|
|
|
|
|
groupPeoList: [],
|
|
|
|
|
recorderManager: {}, //全局唯一录音对象
|
|
|
|
|
innerAudioContext: {}, //音频播放对象
|
|
|
|
|
voicePath: [], //录音文件地址
|
|
|
|
|
timer: null, //转圈计时器
|
|
|
|
|
audioText: '长按录音',
|
|
|
|
|
audioStart: false,
|
|
|
|
|
sendFlag: true, //防止多次点击发送
|
|
|
|
|
voiceCel: false,
|
|
|
|
|
stamp: 0, //时间戳
|
|
|
|
|
txtIndex: 0, //当前输入框光标位置
|
|
|
|
|
aitKeyword: '',
|
|
|
|
|
isserchinput:false
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
let app = this;
|
|
|
|
|
app.userNo = uni.getStorageSync('loginToken').userNo
|
|
|
|
|
//设置录音相关对象
|
|
|
|
|
app.recorderManager = uni.getRecorderManager();
|
|
|
|
|
console.log('录音对象', app.recorderManager)
|
|
|
|
|
app.innerAudioContext = uni.createInnerAudioContext();
|
|
|
|
|
app.innerAudioContext.autoplay = true;
|
|
|
|
|
app.recorderManager.onStop(function(res) {
|
|
|
|
|
console.log('-------停止录音', res)
|
|
|
|
|
let now = new Date().getTime()
|
|
|
|
|
let obj = {
|
|
|
|
|
path: res.tempFilePath,
|
|
|
|
|
duration: parseInt((now - app.stamp) / 100) * 100
|
|
|
|
|
}
|
|
|
|
|
if (obj.duration < 1000) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: '录音太短了!'
|
|
|
|
|
})
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
app.cancelAudio()
|
|
|
|
|
}, 200)
|
|
|
|
|
} else {
|
|
|
|
|
//判断是否是上划取消
|
|
|
|
|
if (!app.voiceCel) {
|
|
|
|
|
app.voicePath.push(obj);
|
|
|
|
|
app.sendAudio()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (app.sendType === 2) {
|
|
|
|
|
getUserByGroupId(app.toUserNo).then(res => {
|
|
|
|
|
console.log('--------------获取群成员', res.data)
|
|
|
|
|
app.groupPeoList = res.data
|
|
|
|
|
app.groupPeoList.forEach((el, idx) => {
|
|
|
|
|
if (el.userNo == app.userNo) {
|
|
|
|
|
app.groupPeoList.splice(idx, 1)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
let app = this;
|
|
|
|
|
if (app.innerAudioContext.stop) {
|
|
|
|
|
app.innerAudioContext.stop()
|
|
|
|
|
}
|
|
|
|
|
if (app.timer) {
|
|
|
|
|
clearInterval(app.timer)
|
|
|
|
|
app.timer = null;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onShow() {
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
getserchInput(){
|
|
|
|
|
//监听键盘高度变化
|
|
|
|
|
uni.onKeyboardHeightChange(res => {
|
|
|
|
|
if (res.height > 0) {
|
|
|
|
|
console.log(res.height,'禁停')
|
|
|
|
|
// app.keyHeight = res.height
|
|
|
|
|
// app.isInput = true;
|
|
|
|
|
} else {
|
|
|
|
|
// app.isInput = false;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
setAit(item) {
|
|
|
|
|
let app = this;
|
|
|
|
|
app.showAitFlag = false;
|
|
|
|
|
//截取光标前后字符串,方便后续拼接
|
|
|
|
|
let curEnd = app.chatInfo.slice(app.txtIndex)
|
|
|
|
|
let curStr = app.chatInfo.slice(0, app.txtIndex)
|
|
|
|
|
|
|
|
|
|
if (item) {
|
|
|
|
|
app.chatInfo = curStr + item.nickName + '\t' + curEnd
|
|
|
|
|
} else {
|
|
|
|
|
app.chatInfo = curStr + '所有人' + '\t' + curEnd
|
|
|
|
|
}
|
|
|
|
|
console.log(item)
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
//获取键盘高度
|
|
|
|
|
getKeyHeight() {
|
|
|
|
|
// if (this.isIos()) {
|
|
|
|
|
// if (this.isScreen) {
|
|
|
|
|
// return (this.keyHeight - 35)
|
|
|
|
|
// } else {
|
|
|
|
|
// return (this.keyHeight - 5)
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// // return this.keyHeight
|
|
|
|
|
// return 0
|
|
|
|
|
// }
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
async sendMsg() {
|
|
|
|
|
let app = this;
|
|
|
|
|
let ids = []
|
|
|
|
|
let isAt = false;
|
|
|
|
|
if (app.sendType === 2) {
|
|
|
|
|
//正则匹配@开头\t结尾的被艾特人员
|
|
|
|
|
let reg = /@.*?\\t/gi;
|
|
|
|
|
let result = JSON.stringify(app.chatInfo).match(reg)
|
|
|
|
|
if (result) {
|
|
|
|
|
for (let i = 0; i < result.length; i++) {
|
|
|
|
|
let el = result[i];
|
|
|
|
|
let cur = el.slice(1, el.length - 2)
|
|
|
|
|
if (cur == '所有人') {
|
|
|
|
|
app.groupPeoList.forEach(val => {
|
|
|
|
|
ids.push(val.userNo)
|
|
|
|
|
})
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
app.groupPeoList.forEach(val => {
|
|
|
|
|
if (val.nickName == cur) {
|
|
|
|
|
ids.push(val.userNo)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
console.log(cur)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
isAt = ids.length > 0 ? true : false;
|
|
|
|
|
}
|
|
|
|
|
if (!app.sendFlag) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
app.sendFlag = false;
|
|
|
|
|
let res;
|
|
|
|
|
if (!app.chatInfo) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: "请输入聊天内容!"
|
|
|
|
|
})
|
|
|
|
|
app.sendFlag = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (app.sendType === 1) {
|
|
|
|
|
// 单聊
|
|
|
|
|
res = await sendTextMsg({
|
|
|
|
|
content: app.chatInfo,
|
|
|
|
|
fromUserNo: app.userNo,
|
|
|
|
|
toUserNo: app.toUserNo
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
//群聊
|
|
|
|
|
res = await sendTextMsg({
|
|
|
|
|
content: app.chatInfo,
|
|
|
|
|
fromUserNo: app.userNo,
|
|
|
|
|
groupId: app.toUserNo,
|
|
|
|
|
atUsers: ids,
|
|
|
|
|
isAt: isAt
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
app.chatInfo = '';
|
|
|
|
|
uni.$emit('scoket', JSON.stringify(res.data))
|
|
|
|
|
// app.audioShow = false;
|
|
|
|
|
// app.moreShow = false;
|
|
|
|
|
// app.emojiShow = false;
|
|
|
|
|
} else {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: res.msg
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
app.sendFlag = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
chooseImage() {
|
|
|
|
|
let app = this;
|
|
|
|
|
uni.chooseImage({
|
|
|
|
|
count: 1, //默认9
|
|
|
|
|
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
|
|
|
|
sourceType: ['album', 'camera'], //从相册选择
|
|
|
|
|
success: function(res) {
|
|
|
|
|
console.log(res.tempFilePaths[0]);
|
|
|
|
|
let filePath = res.tempFilePaths[0]
|
|
|
|
|
app.uploadFile(filePath, 1)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
chooseFile() {
|
|
|
|
|
let app = this;
|
|
|
|
|
if (this.isIos()) {
|
|
|
|
|
const iOSFileSelect = uni.requireNativePlugin('YangChuan-YCiOSFileSelect');
|
|
|
|
|
let params = {
|
|
|
|
|
"document-types": ["public.text", "public.zip", "public.movie", "public.data", "com.adobe.pdf",
|
|
|
|
|
"com.microsoft.word.doc", "com.adobe.postscript", "com.microsoft.excel.xls",
|
|
|
|
|
"com.adobe.encapsulated- postscript", "com.microsoft.powerpoint.ppt",
|
|
|
|
|
"com.adobe.photoshop- image", "com.microsoft.word.rtf",
|
|
|
|
|
"com.microsoft.advanced- systems-format", "com.microsoft.advanced- stream-redirector"
|
|
|
|
|
],
|
|
|
|
|
"isBase64": 0
|
|
|
|
|
}
|
|
|
|
|
iOSFileSelect.show(params, result => {
|
|
|
|
|
let filePath = result.url
|
|
|
|
|
console.log(result,'result')
|
|
|
|
|
let fileName = result.lastName
|
|
|
|
|
let fileSize = result.version
|
|
|
|
|
app.uploadFile(filePath, 4,fileName,fileSize)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
const plugin = uni.requireNativePlugin('GuoWei-SelectFileModule')
|
|
|
|
|
plugin.chooseFile({
|
|
|
|
|
count: 1
|
|
|
|
|
},
|
|
|
|
|
result => {
|
|
|
|
|
let filePath = result.files[0].url
|
|
|
|
|
let fileName = result.files[0].name
|
|
|
|
|
let fileSize = result.files[0].size
|
|
|
|
|
console.log('-----im文件选择', result)
|
|
|
|
|
app.uploadFile(filePath, 4, fileName, fileSize)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
startAudio() {
|
|
|
|
|
console.log('开始录音', this.recorderManager);
|
|
|
|
|
let app = this
|
|
|
|
|
clearInterval(app.timer)
|
|
|
|
|
app.timer = null;
|
|
|
|
|
app.stamp = new Date().getTime()
|
|
|
|
|
uni.vibrateShort({
|
|
|
|
|
success: function() {
|
|
|
|
|
console.log('开始录音2', this.recorderManager);
|
|
|
|
|
app.timer = setInterval(() => {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: '录音时间过长!'
|
|
|
|
|
})
|
|
|
|
|
app.endAudio()
|
|
|
|
|
app.$emit('longStop')
|
|
|
|
|
}, 60000)
|
|
|
|
|
console.log('开始录音3', this.recorderManager);
|
|
|
|
|
app.recorderManager.start();
|
|
|
|
|
app.audioText = '松开停止'
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
endAudio(val = false) {
|
|
|
|
|
let app = this;
|
|
|
|
|
app.voiceCel = val;
|
|
|
|
|
if (app.timer) {
|
|
|
|
|
console.log('录音结束');
|
|
|
|
|
clearInterval(app.timer)
|
|
|
|
|
app.timer = null;
|
|
|
|
|
app.recorderManager.stop();
|
|
|
|
|
app.audioText = '点击播放'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
playVoice() {
|
|
|
|
|
console.log('播放录音');
|
|
|
|
|
// console.log('this.voicePath', this.voicePath, this.audioStart);
|
|
|
|
|
if (!this.audioStart) {
|
|
|
|
|
this.audioStart = true
|
|
|
|
|
this.innerAudioContext.src = this.voicePath[0];
|
|
|
|
|
this.innerAudioContext.play();
|
|
|
|
|
this.audioText = '暂停播放'
|
|
|
|
|
} else if (this.audioStart) {
|
|
|
|
|
this.audioStart = false
|
|
|
|
|
this.innerAudioContext.stop()
|
|
|
|
|
this.audioText = '点击播放'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
cancelAudio() {
|
|
|
|
|
let app = this;
|
|
|
|
|
// app.audioShow = false;
|
|
|
|
|
app.moreShow = false;
|
|
|
|
|
app.emojiShow = false;
|
|
|
|
|
app.timer = null;
|
|
|
|
|
app.innerAudioContext.stop()
|
|
|
|
|
app.voicePath.length > 0 ? app.voicePath.shift() : app.voicePath = []
|
|
|
|
|
app.audioStart = false;
|
|
|
|
|
app.audioText = '长按录音'
|
|
|
|
|
},
|
|
|
|
|
sendAudio() {
|
|
|
|
|
let app = this;
|
|
|
|
|
if (app.voicePath.length == 1) {
|
|
|
|
|
app.uploadFile(app.voicePath[0].path, 2)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
uploadFile(filePath, type, fileName = '', fileSize = 0) {
|
|
|
|
|
let header = {}
|
|
|
|
|
let app = this;
|
|
|
|
|
if (uni.getStorageSync('loginToken')) {
|
|
|
|
|
let token = uni.getStorageSync('loginToken');
|
|
|
|
|
header['Authorization'] = token.tokenHead + token.token;
|
|
|
|
|
header['R-Authorization'] = token.tokenHead + token.refreshToken;
|
|
|
|
|
// header['Content-Type'] = 'multipart/form-data'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let scoketParams = {
|
|
|
|
|
isLoading: 'load',
|
|
|
|
|
fromUserNo: app.userNo,
|
|
|
|
|
toUserNo: app.sendType == 1 ? app.toUserNo : '',
|
|
|
|
|
groupId: app.sendType == 2 ? app.toUserNo : '',
|
|
|
|
|
type: type,
|
|
|
|
|
fileName: fileName,
|
|
|
|
|
fileSize: fileSize,
|
|
|
|
|
filePath: filePath,
|
|
|
|
|
audioSeconds: app.voicePath && app.voicePath.length > 0 ? app.voicePath[0].duration : ''
|
|
|
|
|
}
|
|
|
|
|
console.log('ios',scoketParams)
|
|
|
|
|
uni.$emit('scoket', JSON.stringify(scoketParams))
|
|
|
|
|
|
|
|
|
|
uni.uploadFile({
|
|
|
|
|
url: baseUrl + '/edu-im/file/upload',
|
|
|
|
|
filePath: filePath,
|
|
|
|
|
header: header,
|
|
|
|
|
name: "file",
|
|
|
|
|
success: function(res) {
|
|
|
|
|
let resData = JSON.parse(res.data).data
|
|
|
|
|
let params = {
|
|
|
|
|
content: resData.content,
|
|
|
|
|
fileName: resData.filename,
|
|
|
|
|
size: resData.size,
|
|
|
|
|
fromUserNo: app.userNo,
|
|
|
|
|
toUserNo: app.sendType == 1 ? app.toUserNo : '',
|
|
|
|
|
groupId: app.sendType == 2 ? app.toUserNo : '',
|
|
|
|
|
type: type,
|
|
|
|
|
audioSeconds: app.voicePath && app.voicePath.length > 0 ? app.voicePath[0]
|
|
|
|
|
.duration : ''
|
|
|
|
|
}
|
|
|
|
|
sendSpecialMessage(params).then(ret => {
|
|
|
|
|
console.log('ret', ret)
|
|
|
|
|
if (ret.code === 200) {
|
|
|
|
|
console.log('-----------------im发送图片', ret)
|
|
|
|
|
app.chatInfo = '';
|
|
|
|
|
uni.$emit('scoket', JSON.stringify(ret.data))
|
|
|
|
|
app.innerAudioContext.stop()
|
|
|
|
|
// app.audioShow = false;
|
|
|
|
|
app.moreShow = false;
|
|
|
|
|
app.emojiShow = false;
|
|
|
|
|
app.audioStart = false;
|
|
|
|
|
app.audioText = '长按录音'
|
|
|
|
|
if (app.voicePath.length > 1) {
|
|
|
|
|
app.voicePath.shift()
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
app.sendAudio()
|
|
|
|
|
}, 1000)
|
|
|
|
|
} else {
|
|
|
|
|
app.voicePath = []
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: ret.msg
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
fail: function(error) {
|
|
|
|
|
// uni.showToast({
|
|
|
|
|
// title: "网络异常", //提示文字
|
|
|
|
|
// duration: 3000, //显示时长
|
|
|
|
|
// icon: "none", //图标,支持"success"、"loading"
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
scoketParams.isLoading = 'fail'
|
|
|
|
|
uni.$emit('scoket', JSON.stringify(scoketParams))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
chatCollect() {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/im/chat/chatCollect'
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
goQuick() {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/im/quick/index?sendType=' + this.sendType + '&toUserNo=' + this.toUserNo
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
getEmoji() {
|
|
|
|
|
return [...emojiData[0].list, ...emojiData[1].list, ...emojiData[4].list]
|
|
|
|
|
},
|
|
|
|
|
setEmoji(data) {
|
|
|
|
|
let str = ' ' + this.entitiestoUtf16(data) + ' '
|
|
|
|
|
this.chatInfo += str;
|
|
|
|
|
},
|
|
|
|
|
onInput() {
|
|
|
|
|
this.emojiShow = false;
|
|
|
|
|
this.audioShow = false;
|
|
|
|
|
this.moreShow = false;
|
|
|
|
|
this.$emit('setInput', false)
|
|
|
|
|
},
|
|
|
|
|
setMoreShow() {
|
|
|
|
|
this.moreShow = !this.moreShow;
|
|
|
|
|
this.emojiShow = false;
|
|
|
|
|
this.audioShow = false;
|
|
|
|
|
this.$emit('setInput', this.moreShow)
|
|
|
|
|
},
|
|
|
|
|
setAudioShow() {
|
|
|
|
|
this.audioShow = !this.audioShow;
|
|
|
|
|
this.emojiShow = false;
|
|
|
|
|
this.moreShow = false;
|
|
|
|
|
this.$emit('setInput', false)
|
|
|
|
|
// this.$emit('setInput', this.audioShow)
|
|
|
|
|
},
|
|
|
|
|
setEmojiShow() {
|
|
|
|
|
// this.chatInfo = '@阿萨德\t@asdadad1\t2 '
|
|
|
|
|
// console.log(JSON.stringify(this.chatInfo))
|
|
|
|
|
// return false;
|
|
|
|
|
this.emojiShow = !this.emojiShow;
|
|
|
|
|
this.moreShow = false;
|
|
|
|
|
this.audioShow = false;
|
|
|
|
|
this.$emit('setInput', this.emojiShow)
|
|
|
|
|
},
|
|
|
|
|
utf16toEntities(val) {
|
|
|
|
|
return utf16toEntities(val)
|
|
|
|
|
},
|
|
|
|
|
entitiestoUtf16(val) {
|
|
|
|
|
return entitiestoUtf16(val)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
audioShow: function(n, o) {
|
|
|
|
|
this.$emit('onAudioShow', n)
|
|
|
|
|
},
|
|
|
|
|
chatInfo: function(n, o) {
|
|
|
|
|
let app = this;
|
|
|
|
|
if (app.sendType != 2) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//获取当前光标位置
|
|
|
|
|
uni.getSelectedTextRange({
|
|
|
|
|
success: res => {
|
|
|
|
|
app.txtIndex = res.end;
|
|
|
|
|
//截取光标前后字符串,方便后续拼接
|
|
|
|
|
let curEnd = n.slice(res.end)
|
|
|
|
|
let curStr = n.slice(0, res.end)
|
|
|
|
|
/*
|
|
|
|
|
新增艾特相关
|
|
|
|
|
*/
|
|
|
|
|
let oldStr1 = o.slice(0, res.end)
|
|
|
|
|
if (curStr == oldStr1 + '@') {
|
|
|
|
|
app.aitKeyword = '';
|
|
|
|
|
app.showAitFlag = true;
|
|
|
|
|
uni.hideKeyboard()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
删除艾特相关
|
|
|
|
|
*/
|
|
|
|
|
//截取删除前的字符串
|
|
|
|
|
let oldStr = o.slice(0, res.end + 1)
|
|
|
|
|
//判断是否是删除\t,是则算删除艾特
|
|
|
|
|
if (curStr.length < oldStr.length && curStr + '\t' == oldStr) {
|
|
|
|
|
//将对应艾特人员数据删除
|
|
|
|
|
let num = curStr.lastIndexOf('@')
|
|
|
|
|
let nowStr = curStr.slice(0, num)
|
|
|
|
|
app.chatInfo = nowStr + curEnd;
|
|
|
|
|
console.log('删除艾特')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
// .isInput {
|
|
|
|
|
// bottom: 570rpx !important;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
.chat-bottom {
|
|
|
|
|
position: fixed;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
min-height: 148rpx;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: column;
|
|
|
|
|
|
|
|
|
|
.bottom-operation {
|
|
|
|
|
width: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
padding: 17px 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.goVoice {
|
|
|
|
|
width: 52rpx;
|
|
|
|
|
height: 52rpx;
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
margin-bottom: 15rpx;
|
|
|
|
|
image {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.textarea {
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
max-height: 200rpx !important;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
width: 490rpx;
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
background: #F8F8F8;
|
|
|
|
|
border-radius: 40rpx;
|
|
|
|
|
padding: 0 40rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.textarea2 {
|
|
|
|
|
width: 420rpx;
|
|
|
|
|
line-height: 48rpx;
|
|
|
|
|
min-height: 80rpx;
|
|
|
|
|
|
|
|
|
|
/deep/.uni-textarea-textarea{
|
|
|
|
|
padding-top: 16rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.audio {
|
|
|
|
|
flex: 1;
|
|
|
|
|
background: #F8F8F8;
|
|
|
|
|
border-radius: 39rpx;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
font-family: PingFang SC;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #333;
|
|
|
|
|
height: 78rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 78rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/deep/.u-input {
|
|
|
|
|
flex: 1;
|
|
|
|
|
background: #F8F8F8;
|
|
|
|
|
border-radius: 39rpx;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
font-family: PingFang SC;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #333;
|
|
|
|
|
max-height: 200rpx !important;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
|
|
.u-input__textarea {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 20rpx 40rpx;
|
|
|
|
|
max-height: 200rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.goexpression {
|
|
|
|
|
width: 52rpx;
|
|
|
|
|
height: 53rpx;
|
|
|
|
|
margin-left: 15rpx;
|
|
|
|
|
margin-right: 19rpx;
|
|
|
|
|
margin-bottom: 15rpx;
|
|
|
|
|
|
|
|
|
|
image {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.more {
|
|
|
|
|
width: 53rpx;
|
|
|
|
|
height: 53rpx;
|
|
|
|
|
margin-bottom: 15rpx;
|
|
|
|
|
|
|
|
|
|
image {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.send-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
background-color: #fb3a4e;
|
|
|
|
|
color: #fff;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
border-radius: 10rpx;
|
|
|
|
|
margin-bottom: 15rpx;
|
|
|
|
|
transition: all .3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.operation-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
background-color: #f8f8f8;
|
|
|
|
|
padding: 0 30rpx;
|
|
|
|
|
|
|
|
|
|
.operation-item {
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
padding: 30rpx 0;
|
|
|
|
|
|
|
|
|
|
.item-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
|
|
|
|
image {
|
|
|
|
|
width: 50rpx;
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item-hint {
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
font-family: PingFang SC;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #999999;
|
|
|
|
|
margin-top: 13rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottom-box {
|
|
|
|
|
max-height: 300rpx;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.emoji-box {
|
|
|
|
|
padding: 0 30rpx 30rpx;
|
|
|
|
|
|
|
|
|
|
.emoji {
|
|
|
|
|
margin: 10rpx;
|
|
|
|
|
font-size: 48rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.audio-box {
|
|
|
|
|
height: 300rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
.circle {
|
|
|
|
|
margin: 0 100rpx;
|
|
|
|
|
width: 150rpx;
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
|
|
.audio-icon {
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ait-box {
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
height: 850rpx;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
z-index: 999;
|
|
|
|
|
.ab-title {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-top: 40rpx;
|
|
|
|
|
|
|
|
|
|
.abt-close {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 10rpx;
|
|
|
|
|
left: 40rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.abt-txt {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
font-family: PingFang SC-Medium, PingFang SC;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ab-item {
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
padding: 0 40rpx;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
background-color: #EEEEEE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.abi-all {
|
|
|
|
|
width: 80rpx;
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
margin-right: 30rpx;
|
|
|
|
|
background-color: #FFEBED;
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
font-family: SF Pro Display-Medium, SF Pro Display;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #FB3A4E;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.abi-img {
|
|
|
|
|
width: 80rpx;
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
margin-right: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.abi-name {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
font-family: PingFang SC-Regular, PingFang SC;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
color: #333333;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ipt-wrp {
|
|
|
|
|
margin: 18rpx auto;
|
|
|
|
|
position: relative;
|
|
|
|
|
width: 690rpx;
|
|
|
|
|
|
|
|
|
|
.ipt-icon {
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 28rpx;
|
|
|
|
|
height: 24rpx;
|
|
|
|
|
width: 24rpx;
|
|
|
|
|
top: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ipt {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
background: #f6f6f6;
|
|
|
|
|
border-radius: 32rpx;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #999;
|
|
|
|
|
padding-left: 76rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|