gui-im-input.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template name="gui-im-input">
  2. <view>
  3. <view class="gui-im-footer"
  4. :style="{paddingBottom:paddingB}">
  5. <view class="gui-im-menus graceIMFonts icon-voice"
  6. hover-class="gui-tap" v-if="voiceBtnShow"
  7. @tap="showRec"></view>
  8. <view class="gui-im-menus graceIMFonts icon-photograph"
  9. hover-class="gui-tap"
  10. @tap="chooseImg"></view>
  11. <view class="gui-im-input">
  12. <textarea type="text"
  13. v-model="inputMsg"
  14. :fixed="true"
  15. @confirm="sendTextMsg"
  16. :cursor-spacing="35"></textarea>
  17. </view>
  18. <view class="gui-items"
  19. style="padding:0 12rpx; margin-right:10rpx;"
  20. hover-class="gui-tap" @tap="sendTextMsg">发送</view>
  21. </view>
  22. <!-- 语音输入 -->
  23. <view class="gui-im-record" v-if="recShow">
  24. <view class="gui-im-record-txt">
  25. {{recTxt}}<text v-if="recing">已录音 : {{recLength}} s</text>
  26. </view>
  27. <view class="gui-im-record-btn"
  28. @tap="rec" :class="[recing ? 'gui-im-recording' : '']"></view>
  29. <view class="gui-im-send-voice"
  30. v-if="tmpVoice != ''">
  31. <text @tap="sendVoiceMsg">发送语音</text>
  32. </view>
  33. <view class="gui-im-record-close graceIMFonts icon-close"
  34. @tap="closeRec" v-if="!recing"></view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. var bgAudioMannager = uni.getBackgroundAudioManager();
  40. export default {
  41. name : "gui-im-input",
  42. props : { },
  43. data() {
  44. return {
  45. paddingB : '0',
  46. uploading : false,
  47. recShow : false,
  48. recTxt : "请点击绿色按钮开始录音",
  49. inputMsg : "",
  50. recorderManager : null,
  51. recing : false,
  52. recLength : 1,
  53. recTimer : null,
  54. tmpVoice : '',
  55. voiceLen : 0,
  56. voiceBtnShow : false,
  57. // 播放相关
  58. player : null,
  59. playTxt : "试听语音"
  60. }
  61. },
  62. created : function(){
  63. // #ifndef H5
  64. this.voiceBtnShow = true;
  65. this.recorderManager = uni.getRecorderManager();
  66. this.recorderManager.onStop((res) => {
  67. this.tmpVoice = res.tempFilePath;
  68. this.recing = false;
  69. this.recTxt = "... 已录音 "+this.recLength+
  70. "s, 点击绿色按钮重新录音 ...";
  71. clearInterval(this.recTimer);
  72. });
  73. this.recorderManager.onError(() => {
  74. uni.showToast({ title: '录音失败', icon: 'none' });
  75. this.recing = false;
  76. this.recTxt = "请点击绿色按钮开始录音",
  77. clearInterval(this.recTimer);
  78. });
  79. // #endif
  80. // #ifdef MP
  81. try {
  82. var res = uni.getSystemInfoSync();
  83. res.model = res.model.replace(' ', '');
  84. res.model = res.model.toLowerCase();
  85. var res1 = res.model.indexOf('iphonex');
  86. if(res1 > 5){res1 = -1;}
  87. var res2 = res.model.indexOf('iphone1');
  88. if(res2 > 5){res2 = -1;}
  89. if(res1 != -1 || res2 != -1){
  90. this.paddingB = uni.upx2px(50)+'px';
  91. }
  92. } catch (e){return null;}
  93. // #endif
  94. },
  95. methods:{
  96. // 录音
  97. rec : function(){
  98. if (this.recing){
  99. this.recorderManager.stop();
  100. this.recing = false;
  101. this.recTxt = "... 已录音 "+this.recLength
  102. +"s, 点击绿色按钮重新录音 ...";
  103. clearInterval(this.recTimer);
  104. } else {
  105. this.recorderManager.start({duration:60000, format:'mp3' });
  106. this.recing = true;
  107. this.recTxt = "... 正在录音 ...";
  108. this.recLength = 1;
  109. this.recTimer = setInterval(()=>{this.recLength++;}, 1000);
  110. }
  111. },
  112. // 发送录音
  113. sendVoiceMsg : function(){
  114. if (this.tmpVoice == '') {
  115. uni.showToast({ title: "请先录制一段语音", icon: "none" });
  116. return;
  117. }
  118. // 关闭界面
  119. this.recShow = false;
  120. this.$emit('sendVoice', this.tmpVoice, this.recLength);
  121. this.tmpVoice = '';
  122. this.recLength = 0;
  123. this.recTxt = "请点击绿色按钮开始录音";
  124. },
  125. // 展示录音界面
  126. showRec : function(){this.recShow = true;},
  127. // 关闭录音界面
  128. closeRec: function (){this.recShow = false;},
  129. // 发送文本消息
  130. sendTextMsg: function () {
  131. if (this.inputMsg < 1) {return false;}
  132. this.$emit('sendText', this.inputMsg);
  133. this.inputMsg = '';
  134. },
  135. // 选择图片
  136. chooseImg : function(){
  137. uni.chooseImage({
  138. count : 1,
  139. sizeType : ['compressed'],
  140. sourceType : ['album', 'camera'],
  141. success : (res)=>{
  142. const tempFilePaths = res.tempFilePaths;
  143. this.$emit('chooseImage', tempFilePaths[0]);
  144. }
  145. });
  146. }
  147. }
  148. }
  149. </script>
  150. <style scoped>
  151. .gui-im-footer{background:#FFFFFF; width:100%; position:fixed; left:0; bottom:0; height:100rpx; display:flex; flex-wrap:nowrap; overflow:hidden; box-shadow:1px 1px 6px #999999; align-items:center;}
  152. .gui-im-footer .gui-items{width:auto; line-height:88rpx; flex-shrink:0; font-size:28rpx; color:#2B2E3D;}
  153. .gui-im-menus{width:80rpx; height:80rpx; flex-shrink:0; line-height:80rpx; text-align:center;}
  154. .gui-im-input{width:600rpx; margin:10rpx; padding:10rpx 16rpx; background:#F4F5F6; border-radius:6rpx; height:60rpx;}
  155. .gui-im-input textarea{width:100%; background:#F4F5F6; color:#2B2E3D; height:40rpx; line-height:40rpx; font-size:28rpx; margin-top:10rpx;}
  156. .gui-im-record{width:100%; position:fixed; left:0; bottom:0; background:#FFFFFF; padding:30px 0; padding-bottom:100rpx; z-index:11; box-shadow:1px 1px 6px #999999;}
  157. .gui-im-record-close{width:100rpx; height:100rpx; position:absolute; top:0px; right:0px; z-index:100; text-align:center; line-height:100rpx; color:#888888; font-size:38rpx !important;}
  158. .gui-im-record-txt{text-align:center; font-size:26rpx; line-height:30px; padding-bottom:10px; color:#CCCCCC;}
  159. .gui-im-record-btn{width:60px; height:60px; margin:0 auto; border:5px solid #F1F2F3; border-radius:100%; background:#00B26A;}
  160. .gui-im-recording{background:#FF0000; animation:fade linear 2s infinite;}
  161. @keyframes fade{from{opacity:0.1;} 50%{opacity:1;} to{opacity:0.1;}}
  162. .gui-im-record-txt text{color:#00B26A; padding:0 12px;}
  163. .gui-im-send-voice{margin-top:12px; font-size:28rpx; color:#00BA62; text-align:center;}
  164. .gui-im-send-voice text{margin:0 15px; color:#00BA62;}
  165. @font-face{font-family:"graceIMFonts"; src:url('data:font/truetype;charset=utf-8;base64,d09GMgABAAAAAASoAAsAAAAACpAAAARbAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDMgqILIZ4ATYCJAMUCwwABCAFhG0HSxsHCcgOJQUABgUAAMBk8EB6fW8yk/3Z7Cd4BLPXQW6vA9B99wc4f67lvzL5jC8R2YVkAS+XAsN4QPB1pPqF+wfHUj8K/8Hyvu1BXjGyLDq25lGBDagb1ySRuNkEfcvRGr5iXEVcDQGYRBOJS2OXykbwRoFqQYpmTZc48HZYUBEkgaF3BBypENvQMbT12hNgq/b24g35wgANXYLX6jelSITc52EvKqRlDzJKWljFuYDbcSCBTAAFYkGgZxZuhipT05hBv+dOLYCJgYb2POx50vPyFxW2DZaiQzqT/8MDDYlCgHCAGk+KrY0reB4m8aDB8yQeJDwv50HBiwrZtGh0ur0JhAGiEhCdYIisoERHonui2lcmOM2zJHp7m6a+suXpoNZng9tfDG17vkyohugi+3dbns4wdwWyFuTaGyL2DH1o+v/RweMTg2Y6LqngIEk2qXNSr6zPX9naOrilZVBb25D29qFN+/Nh99riT7Z3vdsad6xlyKkr1tWNZ09eGz6kkbRWS7iliav7hBVp1hm64Q4O3rMhcFCzzBa4ywoa3MgWtHtjyNAmVUhYR3kdd6O7DasHDfpeN2jwb7vbQFjoV6Fa7o6VK9v0qChdVrZdRURhRbwW3rqlUHWLS5mMreMeM3nRSDO2TbYUy16uGosg002pTpZwphre5b7iZKa3S1VPqnNboCS+PE4Hmd9c9SJ2Lk+1zG3JjnAsPmH0XBpvDWJl+WX186e6zIWKSG6z0np0qthYRZSdTEQULL34fb9uJZ66RKiru0eP4K4lSXcWecR/xPf20/WbFi0Bz/8qJrcUz0VLHq9jd7SqyEjVyoWKSFZYZV4TL99QQihCuiGEghgP3sLyqYFyCAlv/7hDnEsCyWXFCOnjZkAVINnlhrLtTEJFJEusvRjRsGVZpxpGRH+psDBFlC1MRCRsj0k9bjZvPtcjYrOpiXamCVUROssu7hLWO2VNhdl5+yxFRU/Z8/pcBwNGkpu2yNAKAPaY/CNXAvak/CmXAfaM/CYXH8o/w6M7d+aODar8ZrgUAB2fJ5zRauxBhbTgeNSSWHrgShOOqa8crbp6d0qSt09n10Gh0T6LTOBwDfjzrxh7EEUmBAZBFmh4EAUSg0SkwmaCjotCcGBQAyYZlBzvIgCKG0I5gXTGAAS+nIKGN9dB4ssnUmH/QCeY/+DAV0gwGSICzugiWUw3GxZgjmER8V1IESyTCDvz1YvrsdSmc9Qu18jNmDqVIIrLznUnS7CJaRH7ONuleMYIItQyUDFcD+u6hWxqqVhg0TJjdnpMzpSgJ4oWLAN8aYCC4WBgRBA8XSAUBCxMiLIww9fz+vVgJNrQ4aARXT/8zWAoTpTVI+KIJjYBskRjJuralEon7UjEw2iEgCC3QgsDRDF1YXQes0DYwZupYAQY0cgZIjbpxNDJSFJNdPU6Yx5LT5ueeAZdaEIKJXThwGPGdM60RcRz0WJbUY1TF8sb8IrH8sVdigkAAA==') format('truetype');}
  166. .graceIMFonts{font-family:"graceIMFonts" !important; font-style:normal; color:#2B2E3D; font-size:56rpx;}
  167. .icon-voice:before{content:"\e63a";}
  168. .icon-photograph:before{content:"\e619";}
  169. .icon-close:before{content:"\e625";}
  170. .icon-kbd{content:"\e73b";}
  171. </style>