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