footer-input.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <template>
  2. <view>
  3. <!-- 底部输入栏 -->
  4. <view :style="{ bottom: inputOffsetBottom > 0 ? '8rpx' : '0rpx' }" class="input-box" :class="popupLayerClass" @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 :confirm-type="'send'" :confirm-hold="true" @confirm="sendMsg(0, textMsg)"
  23. auto-height="true" :disabled="disabledSay===1"
  24. v-model="textMsg" @focus="textareaFocus" />
  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">
  33. <view class="iconfont icontianjia"></view>
  34. </view>
  35. <!-- #endif -->
  36. <!-- #ifdef H5 -->
  37. <view class="send" @tap="sendMsg(0, textMsg)" :class="isVoice?'hidden':''">
  38. <view class="iconfont icontuiguang-weixuan"></view>
  39. </view>
  40. <!-- #endif -->
  41. </view>
  42. <!-- 录音UI效果 -->
  43. <view class="record" :class="recording?'':'hidden'">
  44. <view class="ing" :class="willStop?'hidden':''">
  45. <view class="voice_an">
  46. <view class="voice_an_icon">
  47. <view id="one" class="wave"></view>
  48. <view id="two" class="wave"></view>
  49. <view id="three" class="wave"></view>
  50. <view id="four" class="wave"></view>
  51. <view id="five" class="wave"></view>
  52. <view id="six" class="wave"></view>
  53. <view id="seven" class="wave"></view>
  54. </view>
  55. </view>
  56. </view>
  57. <view class="cancel" :class="willStop?'':'hidden'"><view class="icon chehui" ></view></view>
  58. <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
  59. </view>
  60. </view>
  61. </template>
  62. <script>
  63. export default {
  64. name:'footer-input',
  65. props: {
  66. inputOffsetBottom: {
  67. type: Number,
  68. default: 0
  69. },
  70. isVoice: {
  71. type: Boolean,
  72. default: false
  73. },
  74. disabledSay: {
  75. type: Number,
  76. default: 0
  77. },
  78. popupLayerClass: {
  79. type: String,
  80. default: ''
  81. },
  82. textMsg2:{
  83. type:String,
  84. default:''
  85. }
  86. },
  87. data() {
  88. return {
  89. placeholder: '',
  90. initPoint:{identifier:0,Y:0},
  91. //录音相关参数
  92. // #ifndef H5
  93. //H5不能录音
  94. RECORDER:uni.getRecorderManager(),
  95. // #endif
  96. recordTis:"手指上滑 取消发送",
  97. voiceTis:'按住 说话',
  98. recording:false,
  99. willStop:false,
  100. recordTimer:null,
  101. recordLength:0,
  102. textMsg:'',
  103. };
  104. },
  105. watch:{
  106. textMsg:function(v){
  107. this.$emit('textMsgFunc',v)
  108. if(this.textMsg.indexOf('@')!=-1){
  109. if (this.chatObj.chatType==1){
  110. this.$u.route({
  111. url:'pages/chat/remind',
  112. params:{ msg :this.textMsg }
  113. });
  114. }
  115. }
  116. },
  117. textMsg2:function(v){
  118. this.textMsg = v
  119. }
  120. },
  121. mounted() {
  122. // #ifndef H5
  123. this.RECORDER.onStart((e)=>{
  124. this.recordBegin(e);
  125. })
  126. //录音结束事件
  127. this.RECORDER.onStop((e)=>{
  128. this.recordEnd(e);
  129. })
  130. // #endif
  131. },
  132. methods:{
  133. discard(){
  134. return;
  135. },
  136. sendMsg(index, msg){
  137. this.$emit('sendMsg', index,msg);
  138. this.textMsg = ''
  139. },
  140. textareaFocus(){
  141. this.$emit('textareaFocus', true);
  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. console.log('--------到此一游------1-')
  206. clearInterval(this.recordTimer);
  207. if(!this.willStop){
  208. let tempFilePaths =e.tempFilePath;
  209. let that=this;
  210. uni.uploadFile({
  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. console.log('--------到此一游------2-')
  232. this.$emit('sendMsg', 3,JSON.stringify(msg));
  233. }
  234. });
  235. }else{
  236. // console.log('取消发送录音');
  237. }
  238. this.willStop = false;
  239. console.log('--------到此一游------3-')
  240. },
  241. //更多功能(点击+弹出)
  242. showMore(){
  243. this.$emit('showMore', true);
  244. },
  245. // 打开抽屉
  246. openDrawer(){
  247. this.$emit('openDrawer', true);
  248. },
  249. // 隐藏抽屉
  250. hideDrawer(){
  251. this.$emit('hideDrawer', true);
  252. },
  253. }
  254. }
  255. </script>
  256. <style lang="scss">
  257. @import "@/pages/chat/style.scss";
  258. </style>