import logger from '../../../../utils/logger'; import constant from '../../../../utils/constant'; import { finishConsult } from "../../../../../../api/consultOrder" // eslint-disable-next-line no-undef // 导入 TUICallKitServer 模块,使您的应用具有全局呼叫的能力 import { TUICallKitServer } from "../../../../../../TUICallKit/TUICallService/index"; Component({ /** * 组件的属性列表 */ properties: { conversation: { type: Object, value: {}, observer(newVal) { this.setData({ conversation: newVal, },()=>{ //this.getMessageone(this.data.conversation) }); }, }, order_inquiry_id: { type: String, value: '', observer(newVal) { this.setData({ order_inquiry_id:newVal, }); }, }, doctor_user_id:{ type: String, value: '', observer(newVal) { this.setData({ doctor_user_id:newVal, }); }, }, inquiry_type: { type: String, value: '', observer(newVal) { this.setData({ inquiry_type:newVal }); }, }, inquiry_mode: { type: String, value: '', observer(newVal) { this.setData({ inquiry_mode:newVal }); }, }, patient_family_data:{ type: Object, value:{}, observer(newVal) { this.setData({ patient_family_data:newVal }); }, }, msgData:{ type: Object, value:{}, observer(newVal) { this.setData({ msgData:newVal },()=>{ //console.log(newVal); // this.setMsgRound(); }); }, }, message_rounds:{ type: Number, value: 0, observer(newVal) { this.setData({ message_rounds:newVal }); }, }, times_number:{ type: Number, value: 0, observer(newVal) { this.setData({ times_number:newVal },()=>{ }); }, }, duration:{ type: Number, value: 0, observer(newVal) { this.setData({ duration:newVal }); }, }, rest_time:{ type: Number, value: 0, rest_time(newVal) { this.setData({ rest_time:newVal },()=>{ //console.log('剩余时间:'+newVal) }); }, }, hasCallKit: { type: Boolean, value: false, observer(hasCallKit) { this.setData({ hasCallKit, }); }, }, }, /** * 组件的初始数据 */ data: { conversation: {}, showCustomer:false, order_inquiry_id:'', doctor_user_id:'', inquiry_type:'', inquiry_mode:'', patient_family_data:{}, message: '', message_rounds:0, times_number:0,//总共回合数 msgData:{}, rest_time:0, duration:0, hideText:false, showTip:true, extensionArea: false, sendMessageBtn: false, displayFlag: '', isAudio: false, bottomVal: 0, startPoint: 0, popupToggle: false, isRecording: false, canSend: true, text: '按住说话', title: ' ', notShow: false, isShow: true, timer:null, recordtime:0, commonFunction: [ { name: '常用语', key: '0' }, { name: '发送订单', key: '1' }, { name: '服务评价', key: '2' }, ], displayServiceEvaluation: false, showErrorImageFlag: 0, messageList: [], isFirstSendTyping: true, time: 0, focus: false, isEmoji: false, fileList: [], hasCallKit: false, }, lifetimes: { attached() { // 加载声音录制管理器 this.recorderManager = wx.getRecorderManager(); this.recorderManager.onStop((res) => { wx.hideLoading(); if (this.data.canSend) { if (res.duration < 1000) { wx.showToast({ title: '录音时间太短', icon: 'none', }); } else { // res.tempFilePath 存储录音文件的临时路径 if(res.duration >= 60000){ wx.showToast({ title: '录音时间不能超过60s', duration:2000, icon: 'none', }); } this.sendCallback(); const message = wx.$TUIKit.createAudioMessage({ to: this.getToAccount(), conversationType: this.data.conversation.type, payload: { file: res, }, cloudCustomData: JSON.stringify({ order_inquiry_id:this.data.order_inquiry_id, inquiry_type:this.data.inquiry_type, inquiry_mode:this.data.inquiry_mode, message_rounds:this.data.msgData.msg_round, patient_family_data:this.data.patient_family_data, is_system:0 }) }); this.$sendTIMMessage(message); } } this.setData({ startPoint: 0, popupToggle: false, isRecording: false, canSend: true, title: ' ', text: '按住说话', }); }); }, ready(){ // wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.SDK_READY,this.$onMessageReady,this); }, detached() { // 一定要解除相关的事件绑定 //wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.SDK_READY, this.$onMessageReady,this); } }, pageLifetimes:{ hide: function () { let THIS=this; if(THIS.data.isRecording){ THIS.handleTouchEnd() } }, }, /** * 组件的方法列表 */ methods: { async call() { await TUICallKitServer.setSelfInfo( "典韦222", "http://xxx" ) await TUICallKitServer.call({ userID: this.data.doctor_user_id, type: 2, timeout:60, offlinePushInfo:{ title:'22222' }, userData:JSON.stringify({ order_inquiry_id:this.data.order_inquiry_id, inquiry_type:this.data.inquiry_type, inquiry_mode:this.data.inquiry_mode, message_rounds:this.data.msgData.msg_round, patient_family_data:this.data.patient_family_data, is_system:0 }), }); }, showTooltip(){ this.setData({ showTip:!this.data.showTip, }); }, handlefinishConsult(){ let {order_inquiry_id}=this.data; finishConsult(order_inquiry_id).then(data=>{ this.triggerEvent("freshChatStatus",order_inquiry_id) }) }, getMessageone(conversation){ wx.$TUIKit.getMessageListHopping({ conversationID: conversation.conversationID, direction: 0, count: 1, }).then((res) => { console.log("one"); console.log(res); const { messageList } = res.data; this.getLatestMessageList(messageList); }); }, // 获取消息列表来判断是否发送正在输入状态 getMessageList(conversation) { wx.$TUIKit.getMessageList({ conversationID: conversation.conversationID, nextReqMessageID: this.data.nextReqMessageID, count: 15, }).then((res) => { const { messageList } = res.data; this.setData({ messageList, }); }); }, // 打开录音开关 switchAudio() { wx.hideKeyboard(); if(!this.data.isAudio){ wx.getSetting({ success(res) { if (!res.authSetting['scope.record']) { wx.authorize({ scope: 'scope.record', success () { } }) } } }) } this.setData({ isAudio: !this.data.isAudio, isEmoji: false, text: '按住说话', focus: false, message:'', displayFlag:'', sendMessageBtn:false }); }, openRecord(e,callback){ let THIS=this; return new Promise((resolve, reject) => { wx.getSetting({ success(res) { if(!(res.authSetting['scope.record'])) { // 关闭订阅消息主按钮 return wx.showModal({ title: '提示', content: '您已关闭麦克风权限,请点击“确认”按钮在设置中打开麦克风权限。', success: function (res) { if (res.confirm) { wx.openSetting({ success(res) { } }); } }, complete(){ } }); } else { // 开放订阅消息主按钮 callback(e,THIS); resolve() } }, complete(){ wx.hideLoading(); } }) }) }, // 长按录音 handleLongPress(e) { this.setData({ recordtime:0 }) this.openRecord(e,this.recording); }, recording(e,THIS){ if(THIS.setMsgRound()){ wx.aegis.reportEvent({ name: 'messageType', ext1: 'messageType-audio', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); THIS.recorderManager.start({ duration: 61000, // 录音的时长,单位 ms,最大值 600000(10 分钟) sampleRate: 44100, // 采样率 numberOfChannels: 1, // 录音通道数 encodeBitRate: 192000, // 编码码率 format: 'aac', // 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台(Android、iOS、微信小程序和Web)互通 }); THIS.timer=setInterval(()=>{ if(THIS.data.recordtime>=60){ THIS.handleTouchEnd(); clearInterval(THIS.timer) }; THIS.setData({ recordtime:THIS.data.recordtime+1 }); },1000) THIS.setData({ startPoint: e.touches[0], title: '正在录音', // isRecording : true, // canSend: true, notShow: true, isShow: false, isRecording: true, popupToggle: true, }); } }, // 录音时的手势上划移动距离对应文案变化 handleTouchMove(e) { if (this.data.isRecording) { if (this.data.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 100) { this.setData({ text: '抬起停止', title: '松开手指,取消发送', canSend: false, }); } else if (this.data.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 20) { this.setData({ text: '抬起停止', title: '上划可取消', canSend: true, }); } else { this.setData({ text: '抬起停止', title: '正在录音', canSend: true, }); } } }, // 手指离开页面滑动 handleTouchEnd() { this.setData({ isRecording: false, popupToggle: false, recordtime:0 }); wx.hideLoading(); this.recorderManager.stop(); clearInterval(this.timer) }, // 选中表情消息 handleEmoji() { let targetFlag = 'emoji'; if (this.data.displayFlag === 'emoji') { targetFlag = ''; } this.setData({ isAudio: false, isEmoji: true, displayFlag: targetFlag, focus: false, }); }, // 选自定义消息 handleExtensions() { wx.aegis.reportEvent({ name: 'chooseExtensions', ext1: 'chooseExtensions', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); let targetFlag = 'extension'; if (this.data.displayFlag === 'extension') { targetFlag = ''; } this.setData({ displayFlag: targetFlag, }); }, error(e) { console.log(e.detail); }, handleSendPicture() { this.sendMediaMessage('camera', 'image'); }, handleSendImage() { wx.aegis.reportEvent({ name: 'messageType', ext1: 'messageType-image', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); this.sendMediaMessage('album', 'image'); }, sendMediaMessage(type, mediaType) { if(this.setMsgRound()){ const { fileList } = this.data; wx.chooseMedia({ count: 9, sourceType: [type], mediaType: [mediaType], success: (res) => { this.sendCallback(); const mediaInfoList = res.tempFiles; mediaInfoList.forEach((mediaInfo) => { fileList.push({ type: res.type, tempFiles: [{ tempFilePath: mediaInfo.tempFilePath }] }); }); fileList.forEach((file) => { if (file.type === 'image') { this.handleSendImageMessage(file); } if (file.type === 'video') { this.handleSendVideoMessage(file); } }); this.data.fileList = []; }, }); } }, // 发送图片消息 handleSendImageMessage(file) { const message = wx.$TUIKit.createImageMessage({ to: this.getToAccount(), conversationType: this.data.conversation.type, payload: { file, }, cloudCustomData: JSON.stringify({ order_inquiry_id:this.data.order_inquiry_id, inquiry_type:this.data.inquiry_type, inquiry_mode:this.data.inquiry_mode, message_rounds:this.data.msgData.msg_round, patient_family_data:this.data.patient_family_data, is_system:0 }), onProgress: (percent) => { message.percent = percent; }, }); this.$sendTIMMessage(message); }, // 发送视频消息 handleSendVideoMessage(file) { const message = wx.$TUIKit.createVideoMessage({ to: this.getToAccount(), conversationType: this.data.conversation.type, payload: { file, }, onProgress: (percent) => { message.percent = percent; }, }); this.$sendTIMMessage(message); }, handleShootVideo() { this.sendMediaMessage('camera', 'video'); }, handleSendVideo() { wx.aegis.reportEvent({ name: 'messageType', ext1: 'messageType-video', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); this.sendMediaMessage('album', 'video'); }, handleCommonFunctions(e) { switch (e.target.dataset.function.key) { case '0': this.setData({ displayCommonWords: true, }); break; case '1': this.setData({ displayOrderList: true, }); break; case '2': this.setData({ displayServiceEvaluation: true, }); break; default: break; } }, handleSendOrder() { this.setData({ displayOrderList: true, }); }, appendMessage(e) { this.setData({ message: this.data.message + e.detail.message, sendMessageBtn: true, hideText:true }); }, getToAccount() { if (!this.data.conversation || !this.data.conversation.conversationID) { return ''; } switch (this.data.conversation.type) { case wx.$TUIKitTIM.TYPES.CONV_C2C: return this.data.conversation.conversationID.replace(wx.$TUIKitTIM.TYPES.CONV_C2C, ''); case wx.$TUIKitTIM.TYPES.CONV_GROUP: return this.data.conversation.conversationID.replace(wx.$TUIKitTIM.TYPES.CONV_GROUP, ''); default: return this.data.conversation.conversationID; } }, async handleCheckAuthorize(e) { const type = e.currentTarget.dataset.value; wx.getSetting({ success: async (res) => { const isRecord = res.authSetting['scope.record']; const isCamera = res.authSetting['scope.camera']; if (!isRecord && type === 1) { const title = '麦克风权限授权'; const content = '使用语音通话,需要在设置中对麦克风进行授权允许'; try { await wx.authorize({ scope: 'scope.record' }); this.handleCalling(e); } catch (e) { this.handleShowModal(title, content); } return; } if ((!isRecord || !isCamera) && type === 2) { const title = '麦克风、摄像头权限授权'; const content = '使用视频通话,需要在设置中对麦克风、摄像头进行授权允许'; try { await wx.authorize({ scope: 'scope.record' }); await wx.authorize({ scope: 'scope.camera' }); this.handleCalling(e); } catch (e) { this.handleShowModal(title, content); } return; } this.handleCalling(e); }, }); }, handleShowModal(title, content) { wx.showModal({ title, content, confirmText: '去设置', success: (res) => { if (res.confirm) { wx.openSetting(); } }, }); }, handleCalling(e) { if (!this.data.hasCallKit) { wx.showToast({ title: '请先集成 TUICallKit 组件', icon: 'none', }); return; } const type = e.currentTarget.dataset.value; const conversationType = this.data.conversation.type; if (conversationType === wx.$TUIKitTIM.TYPES.CONV_GROUP) { if (type === 1) { wx.aegis.reportEvent({ name: 'audioCall', ext1: 'audioCall-group', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); } else if (type === 2) { wx.aegis.reportEvent({ name: 'videoCall', ext1: 'videoCall-group', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); } this.triggerEvent('handleCall', { type, conversationType, }); } if (conversationType === wx.$TUIKitTIM.TYPES.CONV_C2C) { const { userID } = this.data.conversation.userProfile; if (type === 1) { wx.aegis.reportEvent({ name: 'audioCall', ext1: 'audioCall-1v1', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); } else if (type === 2) { wx.aegis.reportEvent({ name: 'videoCall', ext1: 'videoCall-1v1', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); } this.triggerEvent('handleCall', { conversationType, type, userID, }); } this.setData({ displayFlag: '', }); }, orderMsg(){ let that=this; wx.requestSubscribeMessage({ tmplIds: ['82rKSdbKkbFK_tHmIMnHyfyRJq9ujvmAsTjRHdxmCdE'], success (res) { that.setData({ showCustomer:true }) } }) }, //发送成功之后回合数+1; sendCallback(){ let {times_number,msgData}=this.data; let rounds=msgData.msg_round; if(msgData.msg_type==1){ rounds=rounds+1; this.setData({ 'msgData.msg_round':rounds }) }; this.triggerEvent("getMessageRounds",{ msg_round:rounds, msg_type:2 }); setTimeout(() => { if(times_number>=0){ if(rounds==times_number){ wx.showToast({ title: '沟通已达到限制的'+times_number+'个回合', icon:"none" }) this.triggerEvent("changeTimeStatus",true); this.handlefinishConsult(); } }; }, 300); }, setMsgRound(){ let {duration,rest_time}=this.data; if(duration!=0 && rest_time==0){ wx.showToast({ title: '沟通时长已超过限制时间', icon:"none" }) this.triggerEvent("changeTimeStatus",true); this.handlefinishConsult(); return false; }; return true }, //发送前获取最新的一条消息 getLatestMessageList(messageList) { let list=messageList; if(list.length>0){ const messageList =list[list.length-1]; console.log(messageList); let customdata=JSON.parse(messageList.cloudCustomData); let msg_rounds=customdata.message_rounds; let from=messageList.flow; let type=messageList.type; this.setData({ message_rounds:msg_rounds || 0 }); if(this.data.times_number>=0){ let rest_rounds=this.data.times_number-this.data.message_rounds; this.triggerEvent("getMessageRounds",rest_rounds); } if(this.data.duration!=0 && this.data.rest_time==0){ wx.showToast({ title: '沟通时长已超过限制时间', icon:"none" }) this.handlefinishConsult(); return false; } if(this.data.times_number>=0){ if(msg_rounds==this.data.times_number){ wx.showToast({ title: '沟通已达到限制的'+this.data.times_number+'个回合', icon:"none" }) this.handlefinishConsult(); return false; } } if(this.data.times_number>=0){ if(from=="in" && type!="TIMCustomElem"){ msg_rounds=msg_rounds+1; this.setData({ message_rounds:msg_rounds }) } console.log("total:"+this.data.times_number,"message_rounds:"+this.data.message_rounds) let rest_rounds=this.data.times_number-this.data.message_rounds; this.triggerEvent("getMessageRounds",rest_rounds); } } return true }, sendTextMessage(msg, flag) { if(this.data.isAudio){ this.setData({ isAudio:false }); return false } if(!this.data.message){ wx.showToast({ title: '输入内容不能为空', icon:'none' }) return false }; if(this.setMsgRound()){ wx.aegis.reportEvent({ name: 'messageType', ext1: 'messageType-text', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); const to =this.getToAccount(); const text = flag ? msg : this.data.message; const { FEAT_NATIVE_CODE } = constant; this.sendCallback(); const message = wx.$TUIKit.createTextMessage({ to, conversationType: this.data.conversation.type, payload: { text, }, cloudCustomData: JSON.stringify({ order_inquiry_id:this.data.order_inquiry_id, inquiry_type:this.data.inquiry_type, inquiry_mode:this.data.inquiry_mode, message_rounds:this.data.msgData.msg_round, patient_family_data:this.data.patient_family_data, is_system:0 }), }); this.setData({ message: '', sendMessageBtn: false, hideText:false }); this.$sendTIMMessage(message); } }, // 监听输入框value值变化 onInputValueChange(event) { if (event.detail.message || event.detail.value) { this.setData({ message: event.detail.message || event.detail.value, sendMessageBtn: true, hideText:true }); } else { this.setData({ sendMessageBtn: false, hideText:false }); } //event.detail.value && this.sendTypingStatusMessage(); }, // 发送正在输入状态消息 sendTypingStatusMessage() { const { BUSINESS_ID_TEXT, FEAT_NATIVE_CODE } = constant; // 创建正在输入状态消息, "typingStatus":1,正在输入中1, 输入结束0, "version": 1 兼容老版本,userAction:0, // 14表示正在输入,actionParam:"EIMAMSG_InputStatus_Ing" //"EIMAMSG_InputStatus_Ing" 表示正在输入, "EIMAMSG_InputStatus_End" 表示输入结束 const typingMessage = wx.$TUIKit.createCustomMessage({ to: this.getToAccount(), conversationType: this.data.conversation.type, payload: { data: JSON.stringify({ businessID: BUSINESS_ID_TEXT.USER_TYPING, typingStatus: FEAT_NATIVE_CODE.ISTYPING_STATUS, version: FEAT_NATIVE_CODE.NATIVE_VERSION, userAction: FEAT_NATIVE_CODE.ISTYPING_ACTION, actionParam: constant.TYPE_INPUT_STATUS_ING, }), description: '', extension: '', }, cloudCustomData: JSON.stringify({ order_inquiry_id:this.data.order_inquiry_id, inquiry_type:this.data.inquiry_type, inquiry_mode:this.data.inquiry_mode, message_rounds:this.data.msgData.msg_round, patient_family_data:this.data.patient_family_data, is_system:0 }), }); // 在消息列表中过滤出对方的消息,并且获取最新消息的时间。 const inList = this.data.messageList.filter(item => item.flow === 'in'); if (inList.length === 0) return; const sortList = inList.sort((firstItem, secondItem) => secondItem.time - firstItem.time); const newMessageTime = sortList[0].time * 1000; // 发送正在输入状态消息的触发条件。 const isSendTypingMessage = this.data.messageList.every((item) => { try { const sendTypingMessage = JSON.parse(item.cloudCustomData); return sendTypingMessage.messageFeature.needTyping; } catch (error) { return false; } }); // 获取当前编辑时间,与收到对方最新的一条消息时间相比,时间小于30s则发送正在输入状态消息/ const now = new Date().getTime(); const timeDifference = (now - newMessageTime); if (isSendTypingMessage && timeDifference > (1000 * 30)) return; if (this.data.isFirstSendTyping) { this.$sendTypingMessage(typingMessage); this.setData({ isFirstSendTyping: false, }); } else { this.data.time = setTimeout(() => { this.$sendTypingMessage(typingMessage); }, (1000 * 4)); } }, // 监听是否获取焦点,有焦点则向父级传值,动态改变input组件的高度。 inputBindFocus(event) { this.setData({ focus: true, }); this.getMessageList(this.data.conversation); this.triggerEvent('pullKeysBoards', { event, }); // 有焦点则关闭除键盘之外的操作界面,例如表情组件。 this.handleClose(); }, // 监听是否失去焦点 inputBindBlur(event) { const { BUSINESS_ID_TEXT, FEAT_NATIVE_CODE } = constant; const typingMessage = wx.$TUIKit.createCustomMessage({ to: this.getToAccount(), conversationType: this.data.conversation.type, payload: { data: JSON.stringify({ businessID: BUSINESS_ID_TEXT.USER_TYPING, typingStatus: FEAT_NATIVE_CODE.NOTTYPING_STATUS, version: FEAT_NATIVE_CODE.NATIVE_VERSION, userAction: FEAT_NATIVE_CODE.NOTTYPING_ACTION, actionParam: constant.TYPE_INPUT_STATUS_END, }), cloudCustomData: JSON.stringify({ messageFeature: { needTyping: FEAT_NATIVE_CODE.FEAT_TYPING, version: FEAT_NATIVE_CODE.NATIVE_VERSION, }, }), description: '', extension: '', }, }); //this.$sendTypingMessage(typingMessage); this.setData({ isFirstSendTyping: true, }); clearTimeout(this.data.time); this.triggerEvent('downKeysBoards', { event, }); }, $handleSendTextMessage(event) { this.sendTextMessage(event.detail.message, true); this.setData({ displayCommonWords: false, }); }, $handleSendCustomMessage(e) { wx.aegis.reportEvent({ name: 'messageType', ext1: 'messageType-custom', ext2: wx.$chat_reportType, ext3: wx.$chat_SDKAppID, }); const message = wx.$TUIKit.createCustomMessage({ to: this.getToAccount(), conversationType: this.data.conversation.type, payload: e.detail.payload, }); this.$sendTIMMessage(message); this.setData({ displayOrderList: false, displayCommonWords: false, }); }, $handleCloseCards(e) { switch (e.detail.key) { case '0': this.setData({ displayCommonWords: false, }); break; case '1': this.setData({ displayOrderList: false, }); break; case '2': this.setData({ displayServiceEvaluation: false, }); break; default: break; } }, // 发送正在输入消息 $sendTypingMessage(message) { wx.$TUIKit.sendMessage(message, { onlineUserOnly: true, }); }, $sendTIMMessage(message) { this.triggerEvent('sendMessage', { message, }); wx.$TUIKit.sendMessage(message, { offlinePushInfo: { disablePush: true, }, }).then(() => { const firstSendMessage = wx.getStorageSync('isFirstSendMessage'); if (firstSendMessage) { wx.aegis.reportEvent({ name: 'sendMessage', ext1: 'sendMessage-success', ext2: 'imTuikitExternal', ext3: wx.$chat_SDKAppID, }); } //this.sendCallback(); }) .catch((error) => { logger.log(`| TUI-chat | message-input | sendMessageError: ${error.code} `); wx.aegis.reportEvent({ name: 'sendMessage', ext1: `sendMessage-failed#error: ${error}`, ext2: 'imTuikitExternal', ext3: wx.$chat_SDKAppID, }); this.triggerEvent('showMessageErrorImage', { showErrorImageFlag: error.code, message, }); }); this.setData({ displayFlag: '', }); }, handleClose() { this.setData({ displayFlag: '', }); }, handleServiceEvaluation() { this.setData({ displayServiceEvaluation: true, }); }, }, });