Common problems with applets WebSocket :(solved in this article) 1. Automatically disconnects and reconnects, but only two Websockets exist. –1 Compatibility: 1.1 Normal Chat After a period of time, the WebSocket is automatically disconnected and reconnected, and the previous chat records are saved
–1 Compatibility: 1.2 If the user has a black screen but does not exit the small program after a period of time, WebSocket automatically disconnects and re-links, and saves the previous chat records
–1 Compatibility: 1.3 In the chat room page, click the back button in the upper right corner, the page will automatically execute the uninstallation, this time the WebSocket is not destroyed, the second entry will exist two WebSockets, the third entry will be an error (can exist two websockets at the same time).
Solution: Because there are many compatibility situations, the solution can be seen in the code. The idea is to add a switch that automatically reconnects. (You can create a WebSocket only after the WebSocket is destroyed.) Determine whether to reconnect the WebSocket.
2. The recording succeeds, but the backend cannot receive the voice file. Wx.arraybuffertobase64 (res.frameBuffer), convert the resulting arrayBuffer to Base64 and pass it to the back end, setting signType: ‘BASE64.
3. The BASE64 decoding fails when recording is transmitted to the back-end. Solution: Confirm with the back end whether the sampling rate, encoding rate, audio format, and frame size of the recording file are consistent.
Recommended Settings:
var recorder = wx.getRecorderManager();
const options = {
duration: 10000.// Specifies the recording duration, in ms
sampleRate: 16000./ / sampling rate
numberOfChannels: 1.// Number of recording channels
encodeBitRate: 24000.// Code rate
format: 'mp3'.// Audio format, valid value aAC /mp3
frameSize: 12.// Specify the frame size, in KB
}
recorder.start(options) // Start recording
Copy the code
4. How to automatically focus the page on the latest chat messages
Solution: Perform a public page focus method after the list assignment of the chat message is successful:
// Public focus method, the method is clumsy, but the transition effect is smooth and smooth
bottom: function() {
var that = this;
this.setData({
scrollTop: 100000})},// Call an example:
this.setData({
allContentList: that.data.allContentList,
})
this.bottom();
Copy the code
5. When the user enters a space and sends it, the chat bubble will definitely distort because it is not as tall as the space line.
Solution: The CSS sets the minimum height of the bubble box —- min-height: 80rpx; (The value can be customized according to requirements)
6. How to implement the small triangle of chat bubble box? The triangle also wants to give it a border, how to do that?
Effect:
Implementation steps: set the style of text bubble box – in the text bubble box set a new box relative positioning, put an EM and a SPAN label inside, set absolute positioning, use the border to set transparent color, example code:
<view class='new_txt_ai'>
<view class='arrow'>
<em></em>
<span></span>
</view>
<view class='ai_content'>121 is a natural number between 120 and 122. It is also odd number, composite number, square number</view>
</view>
Copy the code
.new_txt_ai {
width: 460rpx;
border-radius: 7rpx;
left: 20rpx;
background-color: #fff;
position: relative;
border: 1px solid #d0d0d0;
float: left;
}
.new_txt_ai .arrow {
position: relative;
width: 40rpx;
left: -30rpx;
}
.new_txt_ai .arrow em {
position: absolute;
border-style: solid;
border-width: 15rpx;
top: 20rpx;
border-color: transparent #d0d0d0 transparent transparent;
}
.new_txt_ai .arrow span {
position: absolute;
top: 20rpx;
border-style: solid;
border-width: 15rpx;
border-color: transparent #fff transparent transparent;
left: 2rpx;
}
.ai_content {
word-break: break-all;
padding: 17rpx 30rpx 17rpx 30rpx;
}
Copy the code
All the relevant code, the code logic is more clear but strong plasticity. Provide reference.
WXML source code:
<! <button bindtap='close'> </button> <button bindtap='open'>
<! -- <swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"> <block wx:for="{{listCustmerServiceBanner}}" wx:key=''> <swiper-item> <image src="{{item.picUrl}}" bindtap='swiper_item_click' id='{{index}}' class="slide-image" /> </swiper-item> </block> </swiper> -->
<view class='page_bg' wx:if='{{block}}' bindtap='hide_bg' />
<view class='btn_bg' wx:if='{{block}}'>
<view wx:for="{{link_list}}" wx:key='index'>
<button class="sp_tit" id='{{index}}' bindtap='list_item'>{{item}}</button>
</view>
</view>
<scroll-view class="history" scroll-y="true" scroll-with-animation scroll-top="{{scrollTop}}">
<block wx:key="{{index}}" wx:for="{{allContentList}}">
<block wx:if="{{item.is_my}}">
<view class='my_right new_txt'>
<view class='time' wx:if='{{item.messageTime&&item.messageTime! = 0}} '>
{{item.messageTime}}
</view>
<view class='p_r page_r' style='margin-right: 25rpx; ' wx:if='{{item.text}}'>
<view class='new_txt'>
<view class='new_txt_my'>
<view class='arrow'>
<em></em>
<span></span>
</view>
<text decode="true">{{item.text}}</text>
</view>
</view>
<open-data class='new_img' type="userAvatarUrl"></open-data>
</view>
<view class='p_r page_r' style='margin-right: 25rpx; ' wx:if='{{item.audio}}' bindtap='my_audio_click' data-id='{{index}}'>
<view class='new_txt_my_2' style=' width:{{item.length}}px'>
<image class='my_audio' src='/images/yuyin_icon.png'></image>
</view>
<span class='_span'></span>
<open-data class='new_img' type="userAvatarUrl"></open-data>
</view>
</view>
</block>
<! -- <view class='you_left' id='id_{{allContentList.length}}'> -->
<block wx:if="{{item.is_ai&&item.is_ai! = ' '}}">
<view class='you_left' style='width:100%; ' id='id_{{allContentList.length}}' wx:key="{{index}}">
<view class='time' wx:if='{{item.messageTime}}'>
{{item.messageTime}}
</view>
<view class='p_r' style='margin-left: 20rpx; '>
<image class='new_img' src='/images/top_img.png'></image>
<view class='new_txt'>
<view class='new_txt_ai'>
<view class='arrow'>
<em></em>
<span></span>
</view>
<! -- {{item.text}} -->
<view class='ai_content'>
<block wx:for='{{item.is_ai}}' wx:for-item='itt' wx:for-index='indexi' wx:key=' '>
<text wx:if='{{itt.type=="1"&&item.show_answer}}' decode="true" >{{itt.answer}}</text>
<block wx:if='{{itt.type=="1"&&! item.show_answer}}'>
<text decode="true" wx:if='{{indexi==0}}'>{{itt.answer}}</text>
<view decode="true" style='color:#0000EE' bindtap='add_question' data-messagetime='{{itt.messageTime}}' data-question='{{itt.question}}' data-answer='{{itt.answer}}'>, {{itt. Question}}?</view>
</block>
<text wx:if='{{item.type=="2"}}' decode="true" style='color:#0000EE' bindtap='link' id='{{item.link}}'>{{item.text}}</text>
<image wx:if='{{item.type=="3"}}' style='width:{{item.w}}rpx; height:{{item.h}}rpx; ' src='{{item.src}}'></image>
<text wx:if='{{item.type=="10"}}' decode="true" data-path='{{item.path}}' data-appid='{{item.appId}}' bindtap='minip'>{{item.text}}</text>
</block>
</view>
<! -- <view class='is_ai_btn' wx:if='{{item.solve_show&&item.is_ai[0].answer! = "I don't understand"}} "> < view bindtap = 'is_problem' data - id = '1' data - the item = '{{index}}' style = '{{item. Yse_problem?" color: red;" :""}}'> <image src='{{item.yse_problem?" / images/in_zan. PNG "is:"/images/zan. PNG "}} "/ > solution < / view > < view bindtap = 'is_problem' data - id = '0' data - the item = '{{index}}' class='two' style=' {{item.no_problem?" color: #00B1FF;" :""}}'> <image src='{{item.no_problem?" / images/in_zan_no. PNG ":". / images/zan_no PNG}} "/ >" unresolved < / view > < view > -- >
<view class='yes_problem_log' wx:if="{{item.yse_problem&&item.solve_show}}" style=' '>Thank you for your feedback, we will continue to make efforts!</view>
<view class='yes_problem_log' style='color:#32CF3C' wx:if="{{item.no_problem&&item.solve_show}}" bindtap='phone_click'>Call human customer service</view>
</view>
</view>
</view>
</view>
</block>
</block>
</scroll-view>
<! - mask - >
<view class='zezhao' wx:if='{{cross}}' bindtap='add_icon_click' id='2'></view>
<! -- Input box -->
<view class='{{cross?" in_voice_icon":""}}'>
<view class="sendmessage" wx:if='{{! cross}}' style='bottom:{{input_bottom}}px'>
<input type="text" style='{{focus?" border-bottom: 1px solid #88DD4B;" : ""}} ' adjust-position='{{false}}' cursor-spacing='5' bindinput="bindKeyInput" value='{{inputValue}}' focus='{{focus}}' bindblur='no_focus' bindfocus="focus" confirm-type="done" placeholder="Please enter the question you wish to consult."/>
<button wx:if='{{if_send&&inputValue! = ""}} ' bindtap="submitTo" class='user_input_text'>send</button>
<image class='add_icon' bindtap='add_icon_click' id='1' wx:if='{{add&&! if_send&&inputValue==""}}' src='/images/jia_img.png'></image>
<image class='add_icon' bindtap='add_icon_click' id='2' wx:if='{{cross}}' src='/images/audio/cross37.png'></image>
</view>
<view wx:if='{{cross}}' class='item' bindtap='phone_click'>
<image class='img' src='/images/yuyin_icon.png'></image>
<view class='text'>Artificial customer service</view>
</view>
</view>
<! -- <view class='zezhao' wx:if='{{add_icon_click}}' bindtap='add_icon_click'></view> -->
<! -- <view class='in_voice_icon'> <view class="sendmessage_2"> <input type="text" bindinput="bindKeyInput" adjust-position='{{false}}' value='{{inputValue}}' focus='{{focus}}' bindfocus="focus" confirm-type="done" placeholder="" /> <image class='add_icon' bindtap='add_icon_click' src='/images/audio/cross37.png'></image> </view> <view class='item' bindtap='phone_click'> <image class='img' src='/images/yuyin_icon.png'></image> <view </view> </view>
Copy the code
WXSS source code:
page {
background-color: #f2f2f2;
height: 100%;
padding: 0 auto;
margin: 0 auto;
}
swiper {
height: 180rpx;
}
swiper swiper-item .slide-image {
width: 100%;
height: 180rpx;
}
.jia_img {
height: 80rpx;
width: 90rpx;
}
.time {
text-align: center;
padding: 5rpx 20rpx 5rpx 20rpx;
border-radius: 10rpx;
display: block;
height: 38rpx;
line-height: 38rpx;
position: relative;
margin: 0 auto;
margin-bottom: 20rpx;
width: 90rpx;
color: white;
font-size: 26rpx;
background-color: #dedede;
}
.tab {
bottom: 120rpx;
}
.tab_1 {
position: fixed;
bottom: 50rpx;
width: 200rpx;
font-size: 26rpx;
left: 50%;
margin-left: -45rpx;
height: 100rpx;
}
.tab_2 {
right: 30rpx;
position: fixed;
}
Chat / * * /
.my_right {
float: right;
margin-top: 30rpx;
position: relative;
}
.my_audio {
height: 60rpx;
width: 60rpx;
z-index: 2;
position: relative;
top: 10rpx;
left: 20rpx;
}
.you_left {
margin-top: 30rpx;
float: left;
position: relative;
padding-left: 5rpx;
}
.new_img {
width: 85rpx;
height: 85rpx;
overflow: hidden;
}
.page_r {
float: right;
}
.new_txt {
min-width: 380rpx;
width: 460rpx;
word-break: break-all;
}
.new_txt_my {
border-radius: 7rpx;
background: #9fe75a;
position: relative;
right: 30rpx;
min-height: 50rpx;
padding: 17rpx 30rpx 17rpx 30rpx;
float: right;
border: 1px solid #d0d0d0;
}
.new_txt_my .arrow {
position: absolute;
z-index: 2;
width: 40rpx;
right: -38rpx;
}
.new_txt_my .arrow em {
position: absolute;
border-style: solid;
border-width: 15rpx;
border-color: transparent transparent transparent #d0d0d0;
top: 1rpx;
}
.new_txt_my .arrow span {
position: absolute;
top: 5rpx;
border-style: solid;
border-width: 15rpx;
border-color: transparent transparent transparent #9fe75a;
}
.new_txt_my_2 {
word-break: break-all;
border-radius: 7rpx;
background: #9fe75a;
min-width: 330rpx;
max-width: 530rpx;
padding: 17rpx 30rpx 17rpx 30rpx;
float: right;
}
.new_txt_ai {
width: 460rpx;
border-radius: 7rpx;
left: 20rpx;
background-color: #fff;
position: relative;
border: 1px solid #d0d0d0;
float: left;
}
.new_txt_ai .arrow {
position: relative;
width: 40rpx;
left: -30rpx;
}
.new_txt_ai .arrow em {
position: absolute;
border-style: solid;
border-width: 15rpx;
top: 20rpx;
border-color: transparent #d0d0d0 transparent transparent;
}
.new_txt_ai .arrow span {
position: absolute;
top: 20rpx;
border-style: solid;
border-width: 15rpx;
border-color: transparent #fff transparent transparent;
left: 2rpx;
}
.ai_content {
word-break: break-all;
padding: 17rpx 30rpx 17rpx 30rpx;
}
.sanjiao {
top: 25rpx;
position: relative;
width: 0px;
height: 0px;
border-width: 15rpx;
border-style: solid;
}
.my {
border-color: transparent transparent transparent #9fe75a;
}
.you {
border-color: transparent #fff transparent transparent;
}
._span {
border-color: #fff transparent transparent;
top: -17px;
}
.is_ai_btn {
border-radius: 0 0 7px 7px;
border-top: 1px solid #d0d0d0;
background: white;
position: relative;
bottom: 0;
left: 0;
width: 100%;
height: 80rpx;
line-height: 80rpx;
display: flex;
flex-direction: row;
text-align: center;
}
.is_ai_btn view {
width: 50%;
}
.is_ai_btn image {
width: 32rpx;
position: relative;
top: 4rpx;
height: 32rpx;
}
.is_ai_btn .two {
border-left: 1px solid #d0d0d0;
}
.yes_problem_log {
border-top: 1px solid #d0d0d0;
height: 80rpx;
text-align: center;
line-height: 80rpx;
}
.voice_icon {
width: 60rpx;
height: 60rpx;
margin: 0 auto;
padding: 10rpx 10rpx 10rpx 10rpx;
}
.add_icon {
width: 70rpx;
height: 70rpx;
margin: 0 auto;
padding: 20rpx 10rpx 10rpx 15rpx;
}
.voice_ing {
width: 90%;
height: 75rpx;
line-height: 85rpx;
text-align: center;
border-radius: 15rpx;
border: 1px solid #d0d0d0;
}
.zezhao {
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
background: rgba(0.0.0.0.5);
}
.in_voice_icon {
z-index: 3;
left: 0;
bottom: 0;
width: 100%;
position: absolute;
height: 500rpx;
background: #f8f8f8;
}
.in_voice_icon .item {
position: relative;
left: 50%;
margin-left: -60rpx;
margin-top: 180rpx;
text-align: center;
width: 120rpx;
}
.in_voice_icon .img {
width: 120rpx;
height: 120rpx;
border-radius: 15rpx;
}
.in_voice_icon .text {
font-size: 32rpx;
margin-top: 20rpx;
background: white;
width: 200rpx;
margin-left: -40rpx;
border-radius: 15rpx;
height: 80rpx;
line-height: 80rpx;
}
.sendmessage {
width: 100%;
z-index: 2;
display: flex;
position: fixed;
bottom: 0px;
background-color: #f8f8f8;
flex-direction: row;
height: 100rpx;
}
.sendmessage input {
width: 78%;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
margin-top: 10rpx;
margin-left: 20rpx;
border-bottom: 1px solid #d0d0d0;
padding-left: 20rpx;
}
.sendmessage button {
border: 1px solid white;
width: 18%;
height: 80rpx;
background: #0c0;
color: white;
line-height: 80rpx;
margin-top: 10rpx;
font-size: 28rpx;
}
.hei {
height: 20rpx;
}
.history {
/* height: 73%; * /
height: 88%;
display: flex;
font-size: 14px;
line-height: 50rpx;
position: relative;
top: 20rpx;
}
.icno_kf {
position: fixed;
bottom: 160rpx;
margin: 0 auto;
text-align: center;
left: 50%;
margin-left: -40rpx;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
Copy the code
Js source code:
// pages/index/to_news/to_news.js
var app = getApp();
var util = require(".. /.. /utils/util.js");
var socketOpen = false;
var uuid = ' ',
time_ = "1";
var recorder = wx.getRecorderManager();
const innerAudioContext = wx.createInnerAudioContext() // Get the player object
var frameBuffer_Data, session, SocketTask, string_base64, open_num = 0, submitTo_string,
onUnload_num = 0,
autoRestart, onHide_s = false;
Page({
data: {
listCustmerServiceBanner: [].indicatorDots: false.autoplay: false.interval: 5000.duration: 1000.user_input_text: ' '.// The user enters the text
inputValue: ' '.time: ' '.returnValue: ' '.if_send: false.add: true.cross: false.// is_my: true, text: '12432'
allContentList: [{}, {
is_ai: []}],num: 0
},
// The page loads
onLoad: function(e) {
autoRestart = true; // Whether to restart
console.log('onLoad')
if (e && e.ofOperatorType) {
this.setData({
ofOperatorType: e.ofOperatorType
})
} else {
this.setData({
ofOperatorType: 2})}// if (onUnload_num < 1) {
this.webSocket_open()
// }
},
onShow: function(e) {
onHide_s = false
},
onHide: function() {
autoRestart = false;
onHide_s = true
console.log('onHide')},onUnload: function() {
onUnload_num++;
autoRestart = false;
console.log('onUnload')
this.close();
},
// The page is loaded
onReady: function() {
var that = this;
this.on_recorder();
this.bottom()
},
/ / create the websocket
webSocket_open: function () {
var that = this;
console.log('Start creating')
/ / create a Socket
SocketTask = wx.connectSocket({
url: app.webS_url,
header: {
'content-type': 'application/json'
},
method: 'post'.success: function(res) {
console.log('WebSocket connection creation ', res)
},
fail: function(err) {
wx.showToast({
title: 'Network exception! ',})console.log(err)
},
})
that.initSocket();
},
// Submit text
submitTo: function(e) {
submitTo_string =false
console.log('Submit text')
console.log("SocketTask", SocketTask)
let that = this;
if (that.data.inputValue == "") {
return;
}
var data = {
cmd: 1.type: 1.signType: 'BASE64'.session: session,
body: that.data.inputValue,
}
console.log('Submit literal data:', socketOpen, data)
if (socketOpen) {
// If the socket is opened, data is sent to the server
sendSocketMessage(data)
if(session ! =undefined&& session ! =null) {
this.data.allContentList.push({
is_my: true.text: this.data.inputValue
});
this.setData({
allContentList: this.data.allContentList,
if_send: false.inputValue: ' '
})
}
that.bottom()
} else {
submitTo_string=true;
this.webSocket_open()
}
},
// The socket listens for events
initSocket: function () {
var that = this;
console.log("aaa", SocketTask)
SocketTask.onOpen(res= > {
socketOpen = true;
open_num++
if (session == undefined || session == null) {
// repositoryType = 1 Unicom 2 Mobile 3 Telecom
// ofType int Enter the customer service applets type 1, applets jump 2, search
// ofOperatorType int No Operator type 1, Mobile 2, Unicom 3, Telecom
// WY_APPID String No Small program APPID
if (app.appid) {
var data = {
cmd: 2.ofType: 1.wy_appid: app.appid
}
} else {
var data = {
cmd: 2.ofType: 2.ofOperatorType: that.data.ofOperatorType
// ofOperatorType: 1
}
}
sendSocketMessage(data)
}
console.log('Listen for WebSocket connection opening events. ', res)
})
SocketTask.onClose(onClose= > {
console.log('Listen for WebSocket connection closure events. ', onClose)
session = null;
SocketTask = false;
socketOpen = false;
// if (! autoRestart && onHide_s) {
// this.webSocket_open()
// }
// if (autoRestart) {
// this.webSocket_open()
// }
})
SocketTask.onError(onError= > {
console.log('Listening for WebSocket error. Error message ', onError)
session = null;
})
SocketTask.onMessage(onMessage= > {
var onMessage_data = JSON.parse(onMessage.data);
console.log("onMessage:", onMessage_data)
// if (onMessage_data == 'session is empty ') {
// if (submitTo_string) {
// console.log('submitTo_string2222222222')
// that.submitTo()
/ /}
// return;
// }
if (onMessage_data.minipTitle) {
wx.setTopBarText({
text: onMessage_data.minipTitle,
})
}
let is_ai_arr = onMessage_data.body;
/ / login. By default, a message is sent to the user to display, not display resolved unresolved
if (onMessage_data.cmd == 3) {
that.session_pro = new Promise(function (resolve) {
session = onMessage_data.session;
if (submitTo_string) {
console.log('submitTo_string11111111')
that.submitTo()
}
resolve(session)
})
var messageTime = util.formatTime(onMessage_data.messageTime);
// if (open_num < 2){
if (is_ai_arr.length == 1) {
that.data.allContentList.push({
is_ai: is_ai_arr,
solve_show: false.show_answer: true.messageTime: messageTime
});
} else {
console.log('is_ai_arr:', is_ai_arr)
that.data.allContentList.push({
is_ai: is_ai_arr,
show_answer: false.solve_show: false.messageTime: messageTime
});
}
// }
this.setData({
listCustmerServiceBanner: onMessage_data.listCustmerServiceBanner,
staffServicePhone: onMessage_data.staffServicePhone,
allContentList: that.data.allContentList
})
} else {
// The message is received normally
uuid = onMessage_data.messageRecordUuid;
var messageTime;
time_ = onMessage_data.messageTime;
if (time_ + 1000 * 60 * 10 > onMessage_data.messageTime) {
messageTime = 0;
} else {
messageTime = util.formatTime(onMessage_data.messageTime);
}
let arr_list = that.data.allContentList
if (is_ai_arr.length == 1) {
arr_list.push({
show_answer: true.is_ai: is_ai_arr,
messageTime: messageTime,
solve_show: true.no_problem: false.yse_problem: false
});
} else {
arr_list.push({
show_answer: false.is_ai: is_ai_arr,
messageTime: messageTime,
solve_show: true.no_problem: false.yse_problem: false
});
}
that.setData({
allContentList: arr_list }) } that.bottom(); })},// Click the wheel map
swiper_item_click: function (e) {
var id = e.target.id
console.log(id);
var item_banners = this.data.listCustmerServiceBanner[id];
var page = item_banners.page;
// Type 1, own small program, 2, other small program 3, H5
switch (item_banners.type) {
case 1:
wx.navigateTo({
url: page,
})
break;
case 2:
wx.navigateToMiniProgram({
appId: item_banners.appid,
path: page,
extraData: {},
envVersion: 'release'.success(res) {
// Open successfully}})break;
case 3:
wx.navigateTo({
url: web + '? url=' + page,
})
break; }},/ / close
close: function (e) {
if (SocketTask) {
SocketTask.close(function (close) {
console.log('Close the WebSocket connection. ', close)
})
}
},
// Solve the problem
is_problem: function(e) {
console.log('e.target.id', e.currentTarget.dataset.id)
console.log('item', e.currentTarget.dataset.item)
var id = e.currentTarget.dataset.id;
var item = e.currentTarget.dataset.item;
// id=1 Resolved 0 unresolved
var yse_problem = this.data.allContentList[item].yse_problem;
var no_problem = this.data.allContentList[item].no_problem;
if (yse_problem || no_problem) {
console.log(12)
return
} else {
if (id == 1) {
this.setData({
['allContentList[' + item + '].yse_problem'] :true})}else if (id == 0) {
this.setData({
['allContentList[' + item + '].no_problem'] :true})}console.log(this.data.allContentList[item].yse_problem, this.data.allContentList[item].no_problem)
this.bottom();
}
var url = app.httpUrl + '/v1/userFeedbackResult.do'
var data = {
'session': app.http_session,
'type': id,
'uuid': uuid
}
console.log('userFeedbackResult Submitted data: ', data)
util.request(url, 'POST', data, ' '.function(res) {
console.log('userFeedbackResult returns data: ', res.data)
}, function(err) {
console.log(err)
})
},
// Jump routines
minip: function(e) {
console.log(e)
wx.navigateToMiniProgram({
appId: e.target.dataset.appid,
path: e.target.dataset.path,
extraData: {},
envVersion: 'develop'.success(res) {
// Open successfully}})},/ / jump WEB
link: function(e) {
console.log(e.target.id)
wx.navigateTo({
url: '.. /web/web? link=' + e.target.id,
})
},
// Click the plus sign
add_icon_click: function(e) {
console.log(e.target.id)
// e.target.id == 1 click + ==2 click X
if (e.target.id == 2) {
this.setData({
add: true.cross: false.input_bottom: 0})}else if (e.target.id == 1) {
this.setData({
add: false.cross: true.input_bottom: 240})}},// Automatically add the answer to the question
add_question: function(e) {
var that = this;
let answer = e.currentTarget.dataset.answer;
let messageTime = e.currentTarget.dataset.messagetime;
let question = e.currentTarget.dataset.question;
console.log('question:', question, 'answer:', answer, 'messageTime', messageTime);
this.data.allContentList.push({
is_my: true.text: question
});
this.setData({
allContentList: this.data.allContentList,
if_send: false.inputValue: ' '
})
that.bottom();
setTimeout(function() {
that.data.allContentList.push({
is_ai: [{
answer: answer,
type: 1}].solve_show: true.show_answer: true.messageTime: false.text: question
});
that.setData({
allContentList: that.data.allContentList,
})
that.bottom();
}, 1000)},// Make a phone call
phone_click: function() {
var that = this;
wx.showModal({
title: ' '.content: 'Whether to call' + that.data.staffServicePhone + 'Human Customer Service Number'.success: function(res) {
if (res.confirm) {
wx.makePhoneCall({
phoneNumber: that.data.staffServicePhone // This is an example, not a real phone number})}else if (res.cancel) {
console.log('User hit Cancel')}}})},/ / input box
bindKeyInput: function(e) {
console.log(e.detail.value)
if (e.detail.value == "") {
this.setData({
if_send: false.inputValue: e.detail.value
})
} else {
this.setData({
if_send: true.inputValue: e.detail.value
})
}
},
// Get focus
focus: function(e) {
var that = this;
console.log(e.detail.height)
this.setData({
focus: true.add: true.cross: false.input_bottom: e.detail.height
})
},
// Lose focus
no_focus: function(e) {
if (this.data.cross) {
this.setData({
focus: false.input_bottom: 240})},else {
this.setData({
focus: false.input_bottom: 0})}},// Get the ID node of the HEI and switch the screen focus to this node
bottom: function() {
var that = this;
this.setData({
scrollTop: 100000})},hide_bg: function() {
this.setData({
block: false})},// Click record event
my_audio_click: function(e) {
console.log('My_audio_click executed', e)
var index = e.currentTarget.dataset.id;
console.log('url'.this.data.allContentList[index].audio);
innerAudioContext.src = this.data.allContentList[index].audio
innerAudioContext.seek(0);
innerAudioContext.play();
},
// Click on the record
voice_ing_start: function() {
var that = this;
this.setData({
voice_ing_start_date: new Date().getTime(), // Record the start click time
})
const options = {
duration: 10000.// Specifies the recording duration, in ms
sampleRate: 16000./ / sampling rate
numberOfChannels: 1.// Number of recording channels
encodeBitRate: 24000.// Code rate
format: 'mp3'.// Audio format, valid value aAC /mp3
frameSize: 12.// Specify the frame size, in KB
}
recorder.start(options) // Start recording
this.animation = wx.createAnimation({
duration: 1200,})// Play button animation
that.animation.scale(0.8.0.8); / / reduction
that.setData({
spreakingAnimation: that.animation.export()
})
},
// Recording listening event
on_recorder: function() {
var that = this;
recorder.onStart((res) = > {
console.log('Start recording');
})
recorder.onStop((res) = > {
console.log('Stop recording, temporary path', res.tempFilePath);
// _tempFilePath = res.tempFilePath;
var x = new Date().getTime() - this.data.voice_ing_start_date
if (x > 1000) {
that.data.allContentList.push({
is_my: true.audio: res.tempFilePath,
length: x / 1000 * 30
});
that.setData({
allContentList: that.data.allContentList
})
}
})
recorder.onFrameRecorded((res) = > {
var x = new Date().getTime() - this.data.voice_ing_start_date
if (x > 1000) {
console.log('onFrameRecorded res.frameBuffer', res.frameBuffer);
string_base64 = wx.arrayBufferToBase64(res.frameBuffer)
// console.log('string_base64--', wx.arrayBufferToBase64(string_base64))
if (res.isLastFrame) {
that.session_pro.then(function(session) {
var data = {
audioType: 3.cmd: 1.type: 2.signType: 'BASE64'.session: session,
body: string_base64,
}
console.log('that.data.allContentList', that.data.allContentList)
sendSocketMessage(data)
})
// Go to the next step
} else {
that.session_pro.then(function(session) {
var data = {
cmd: 1.audioType: 2.type: 2.signType: 'BASE64'.session: session,
body: string_base64
}
console.log('Recording uploaded data:', data)
sendSocketMessage(data)
})
}
}
})
},
// Release the recording
voice_ing_end: function() {
var that = this;
that.setData({
voice_icon_click: false.animationData: {}})this.animation = "";
var x = new Date().getTime() - this.data.voice_ing_start_date
if (x < 1000) {
console.log('Stop recording, speak for less than 1 second! ')
wx.showModal({
title: 'tip'.content: 'Speak for longer than a second! ',
})
recorder.stop();
} else {
// Stop recording and uploadrecorder.stop(); }},// Click on the audio image
voice_icon_click: function() {
this.setData({
voice_icon_click:!this.data.voice_icon_click
})
},
})
// To send data over a WebSocket connection, wx.connectSocket must be first followed by a wx.onsocketOpen callback.
function sendSocketMessage(msg) {
var that = this;
if(app.http_session ! ="") {
msg.http_session = app.http_session
console.log('Send data over WebSocket connection'.JSON.stringify(msg))
SocketTask.send({
data: JSON.stringify(msg)
}, function(res) {
console.log('Sent', res)
})
} else {
app.promise.then(function(http_session) {
msg.http_session = http_session;
console.log('Send data over WebSocket connection'.JSON.stringify(msg));
SocketTask.send({
data: JSON.stringify(msg)
}, function(res) {
console.log('Sent', res); }}})})Copy the code
Util file source:
// Verify mobile phone number
function isUnicoms(mobileNo) {
// Move: 134(0-8), 135, 136, 137, 138, 139, 147, 150, 151, 152, 157, 158, 159, 178, 182, 183, 184, 187, 188, 198
// Unicom: 130, 131, 132, 145, 155, 156, 175, 176, 185, 186, 166
// Telecommunication: 133, 153, 173, 177, 180, 181, 189, 199
// 1, China Mobile 2, China Unicom 3, China Telecom
var move = / ^ ((134) | | (135) (136) | | (137) (138) | | (139) (147) | | (150) (151) | | (152) (157) | | (158) (159) | | (178) (182) | | (183) (184) | | (187) (188) | (19 8))\d{8}$/g;
var link = /^((130)|(131)|(132)|(155)|(156)|(145)|(185)|(186)|(176)|(175)|(170)|(171)|(166))\d{8}$/g;
var telecom = /^((133)|(153)|(173)|(177)|(180)|(181)|(189)|(199))\d{8}$/g;
if (move.test(mobileNo)) {
return '1';
} else if (link.test(mobileNo)) {
return '2';
} else if (telecom.test(mobileNo)) {
return '3';
} else {
return 'Non-triple segment'; }}// Network request
function request(url, method, data, message, _success, _fail) {
wx.showNavigationBarLoading()
if(message ! ="") {
wx.showLoading({
title: message
})
}
wx.request({
url: url,
data: data,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: method,
success: function (res) {
_success(res)
wx.hideNavigationBarLoading()
if(message ! ="") {
wx.hideLoading()
}
},
fail: function (err) {
if (err) {
_fail(err)
}
wx.hideNavigationBarLoading()
if(message ! ="") {
wx.hideLoading()
}
},
})
}
// Upload voice
function up_audio(url, audioSrc,name, data, _succ, _fail) {
const uploadTask = wx.uploadFile({
url: url, // This is an example, not a real interface address
filePath: audioSrc,
name: name,
formData: data,
header: {
"content-type": "multipart/form-data"
},
success: function (res) {
_succ(res)
},fail:function(err){
_fail(err)
}
})
uploadTask.onProgressUpdate((res) = > {
console.log('audio upload progress ', res.progress)
console.log('audio Length of data uploaded ', res.totalBytesSent)
console.log('Total length of data that audio expects to upload', res.totalBytesExpectedToSend)
})
}
function formatTime(unixtime) {
var dateTime = new Date(parseInt(unixtime))
var year = dateTime.getFullYear();
var month = dateTime.getMonth() + 1;
var day = dateTime.getDate();
var hour = dateTime.getHours();
var minute = dateTime.getMinutes();
var second = dateTime.getSeconds();
var now = new Date(a);var now_new = Date.parse(now.toDateString()); //typescript transforms
var milliseconds = now_new - dateTime;
var timeSpanStr = hour + ':' + minute;
// var timeSpanStr = year + '-' + month + '-' + day + ' ' + hour + ':' + minute;
return timeSpanStr;
}
module.exports = {
request: request,
isUnicoms: isUnicoms,
formatTime:formatTime,
up_audio: up_audio
}
Copy the code
App.js for reference:
//app.js
var util = require('utils/util.js');
App({
onLaunch: function () {
var that = this;
that.http_session = ' ';
return that.promise = new Promise(function (resolve) {
Ws: / / / that. WebS_url = '/ 192.168.199.147:7041'; // Fill in the address you requested
= 'http://192.168.199.147:7051'. / / that httpUrl / / fill in the test you request
wx.login({
success: function (res) {
var data = {
code: res.code
}
if (res.code) {
// Initiate a network request
var url = that.httpUrl + '/v1/user/login.do';
util.request(url, 'POST', data, ' '.function (res) {
console.log(res);
that.http_session = res.data.body;
resolve(that.http_session);
}, function (err) {
console.log(err); })}else {
console.log('Login failed! '+ res.errMsg) } } }); })},/ / formid
form_id_bg: function (formId) {
console.log('form_id_bg executed ')
let url = this.httpUrl + '/v1/formid/saveFormid.do';
this.promise.then(function (http_session) {
let data = {
session: http_session,
// minipid: '10000',
formId: formId
}
util.request(url, 'post', data, ' '.function (res) {})})},onShow: function (even) {
var e;
// if (even.referrerInfo.extraData && even.referrerInfo.extraData.foo) {
// e = even.referrerInfo.extraData.foo
// }
if (e && e.appid) {
this.appid = e.appid; }}})Copy the code