footer-input.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <view>
  3. <!-- 底部输入栏 -->
  4. <view class="input-box" :class="popupLayerClass" :style="{ bottom: inputOffsetBottom > 0 ? '30rpx' : '0' }" @touchmove.stop.prevent="discard">
  5. <!-- H5下不能录音,输入栏布局改动一下 -->
  6. <!-- #ifndef H5 -->
  7. <view class="voice">
  8. <view class="iconfont iconshuru" :class="isVoice?'iconshuru':'iconyuyin1'" @tap="switchVoice"></view>
  9. </view>
  10. <!-- #endif -->
  11. <!-- #ifdef H5 -->
  12. <view class="more" @tap="showMore">
  13. <view class="iconfont icontianjia"></view>
  14. </view>
  15. <!-- #endif -->
  16. <!-- 录音 -->
  17. <view class="textbox">
  18. <view class="voice-mode" :class="[isVoice?'':'hidden',recording?'recording':'']" @touchstart="voiceBegin"
  19. @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd" @touchcancel="voiceCancel">{{voiceTis}}</view>
  20. <view class="text-mode" :class="isVoice?'hidden':''">
  21. <view class="box">
  22. <textarea ref="tt" :confirm-type="'send'" :confirm-hold="true" @confirm="sendMsg(0, textMsg)"
  23. auto-height="true" :disabled="disabledSay===1"
  24. v-model="textMsg" @focus="enterInput" />
  25. </view>
  26. <view class="em" @tap="chooseEmoji">
  27. <view class="iconfont iconbiaoqing"></view>
  28. </view>
  29. </view>
  30. </view>
  31. <!-- #ifndef H5 -->
  32. <view class="more" @tap="showMore" :class="isBtn?'hidden':''">
  33. <view class="iconfont icontianjia"></view>
  34. </view>
  35. <!-- #endif -->
  36. <view class="send" :class="isBtn?'':'hidden'">
  37. <u-button @tap="sendMsg(0, textMsg)" type="success" size="mini">发送</u-button>
  38. </view>
  39. </view>
  40. <!-- 录音UI效果 -->
  41. <view class="record" :class="recording?'':'hidden'">
  42. <view class="ing" :class="willStop?'hidden':''">
  43. <view class="voice_an">
  44. <view class="voice_an_icon">
  45. <view id="one" class="wave"></view>
  46. <view id="two" class="wave"></view>
  47. <view id="three" class="wave"></view>
  48. <view id="four" class="wave"></view>
  49. <view id="five" class="wave"></view>
  50. <view id="six" class="wave"></view>
  51. <view id="seven" class="wave"></view>
  52. </view>
  53. </view>
  54. </view>
  55. <view class="cancel" :class="willStop?'':'hidden'"><view class="icon chehui" ></view></view>
  56. <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
  57. </view>
  58. </view>
  59. </template>
  60. <script>
  61. export default {
  62. name:'footer-input',
  63. props: {
  64. inputOffsetBottom: {
  65. type: Number,
  66. default: 0
  67. },
  68. isVoice: {
  69. type: Boolean,
  70. default: false
  71. },
  72. disabledSay: {
  73. type: Number,
  74. default: 0
  75. },
  76. popupLayerClass: {
  77. type: String,
  78. default: ''
  79. },
  80. textMsg2:{
  81. type:String,
  82. default:''
  83. }
  84. },
  85. data() {
  86. return {
  87. placeholder: '',
  88. initPoint:{identifier:0,Y:0},
  89. // #ifndef H5
  90. RECORDER:uni.getRecorderManager(),
  91. // #endif
  92. recordTis:"手指上滑 取消发送",
  93. voiceTis:'按住 说话',
  94. recording:false,
  95. willStop:false,
  96. recordTimer:null,
  97. recordLength:0,
  98. textMsg:'',
  99. };
  100. },
  101. computed:{
  102. isBtn:function(){
  103. return this.textMsg!="";
  104. }
  105. },
  106. watch:{
  107. textMsg:function(v){
  108. this.$emit('textMsgTap',v);
  109. if(v.indexOf('@')!=-1){
  110. if (this.chatObj.chatType==1){
  111. this.$u.route({
  112. url:'pages/chat/remind',
  113. params:{ msg :v }
  114. });
  115. }
  116. }
  117. },
  118. textMsg2:function(v){
  119. this.textMsg = v
  120. }
  121. },
  122. mounted() {
  123. // #ifndef H5
  124. this.RECORDER.onStart((e)=>{
  125. this.recordBegin(e);
  126. })
  127. this.RECORDER.onStop((e)=>{
  128. this.recordEnd(e);
  129. })
  130. // #endif
  131. },
  132. methods:{
  133. enterInput(){
  134. this.$emit('enterInput');
  135. },
  136. discard(){
  137. return;
  138. },
  139. sendMsg(index, msg){
  140. this.$emit('sendMsg', index,msg);
  141. this.textMsg = '';
  142. },
  143. // 选择表情
  144. chooseEmoji(){
  145. this.$emit('chooseEmoji', true);
  146. },
  147. // 切换语音/文字输入
  148. switchVoice(){
  149. this.$emit('switchVoice', true);
  150. },
  151. // 录音开始
  152. voiceBegin(e){
  153. if(e.touches.length>1){
  154. return ;
  155. }
  156. this.recording = true;
  157. this.initPoint.Y = e.touches[0].clientY;
  158. this.initPoint.identifier = e.touches[0].identifier;
  159. this.RECORDER.start({format:"mp3"});//录音开始,
  160. },
  161. //录音开始UI效果
  162. recordBegin(e){
  163. this.recording = true;
  164. this.voiceTis='松开 结束';
  165. this.recordLength = 0;
  166. this.recordTimer = setInterval(()=>{
  167. this.recordLength++;
  168. },1000)
  169. },
  170. // 录音被打断
  171. voiceCancel(){
  172. this.recording = false;
  173. this.voiceTis='按住 说话';
  174. this.recordTis = '手指上滑 取消发送'
  175. this.willStop = true;//不发送录音
  176. this.RECORDER.stop();//录音结束
  177. },
  178. // 录音中(判断是否触发上滑取消发送)
  179. voiceIng(e){
  180. if(!this.recording){
  181. return;
  182. }
  183. let touche = e.touches[0];
  184. //上滑一个导航栏的高度触发上滑取消发送
  185. if(this.initPoint.Y - touche.clientY>=uni.upx2px(100)){
  186. this.willStop = true;
  187. this.recordTis = '松开手指 取消发送'
  188. }else{
  189. this.willStop = false;
  190. this.recordTis = '手指上滑 取消发送'
  191. }
  192. },
  193. // 结束录音
  194. voiceEnd(e){
  195. if(!this.recording){
  196. return;
  197. }
  198. this.recording = false;
  199. this.voiceTis='按住 说话';
  200. this.recordTis = '手指上滑 取消发送'
  201. this.RECORDER.stop();//录音结束
  202. },
  203. //录音结束(回调文件)
  204. recordEnd(e){
  205. clearInterval(this.recordTimer);
  206. if(!this.willStop){
  207. let tempFilePaths =e.tempFilePath;
  208. let that=this;
  209. uni.uploadFile({
  210. //仅为示例,非真实的接口地址
  211. url: this.$uploadUrl,
  212. filePath: tempFilePaths,
  213. header: {
  214. 'merchcode':'md5'
  215. },
  216. name: 'file',
  217. formData: {
  218. 'user': 'test'
  219. },
  220. success: (res) => {
  221. let data =JSON.parse(res.data)
  222. let msg = {
  223. length:0,
  224. url:data.data
  225. }
  226. let min = parseInt(this.recordLength/60);
  227. let sec = this.recordLength%60;
  228. min = min<10?'0'+min:min;
  229. sec = sec<10?'0'+sec:sec;
  230. msg.length = min+':'+sec;
  231. this.$emit('sendMsg', 3,JSON.stringify(msg));
  232. }
  233. });
  234. }else{
  235. // console.log('取消发送录音');
  236. }
  237. this.willStop = false;
  238. },
  239. //更多功能(点击+弹出)
  240. showMore(){
  241. this.$emit('showMore', true);
  242. },
  243. // 打开抽屉
  244. openDrawer(){
  245. this.$emit('openDrawer', true);
  246. },
  247. // 隐藏抽屉
  248. hideDrawer(){
  249. this.$emit('hideDrawer', true);
  250. },
  251. }
  252. }
  253. </script>
  254. <style lang="scss">
  255. @import "@/pageC/chat/style.scss";
  256. </style>