jinji.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <template>
  2. <view>
  3. <view class="text-white text-center" style="margin-top: 200rpx;">
  4. <view class="datt">严重危害生命财产安全 </view>
  5. <view class="datt margin-top-sm">求助专属通道</view>
  6. <!-- <view class="margin-top">平台将为您,保留录音证据,实时位置,通知平台联系人</view> -->
  7. </view>
  8. <!-- <view class="text-center" style="margin-top: 120rpx;" @touchstart.stop.prevent="voiceBegin"
  9. @touchmove.stop.prevent="voiceIng" @touchend.stop.prevent="voiceEnd"
  10. @touchcancel.stop.prevent="voiceCancel">
  11. <image src="../static/yuyin.png" style="width: 300rpx;height: 300rpx;pointer-events: none;"></image>
  12. </view> -->
  13. <!-- 录音UI效果 -->
  14. <!-- <view class="record" :class="recording?'':'hidden'">
  15. <view class="ing" :class="willStop?'hidden':''">
  16. <view class="icon luyin2"></view>
  17. </view>
  18. <view class="cancel" :class="willStop?'':'hidden'">
  19. <view class="icon chehui"></view>
  20. </view>
  21. <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
  22. </view> -->
  23. <!-- <view class="text-center" style="margin-top:200rpx;" @touchstart.stop.prevent="voiceBegin"
  24. @touchmove.stop.prevent="voiceIng" @touchend.stop.prevent="voiceEnd"
  25. @touchcancel.stop.prevent="voiceCancel">
  26. <image src="../static/sos.png" style="width: 200rpx;height: 200rpx;pointer-events: none;"></image>
  27. </view> -->
  28. <view class="text-center" @click="getPhoneNumber()" style="margin-top:200rpx;">
  29. <image src="../static/sos.png" style="width: 200rpx;height: 200rpx;pointer-events: none;"></image>
  30. </view>
  31. </view>
  32. </template>
  33. <script>
  34. import configdata from '@/common/config.js';
  35. var innerAudioContext; //播放
  36. // #ifdef H5
  37. var recorder; // 定义一个MediaRecorder对象
  38. var stream; //定义一个音频流的对象
  39. var chunks = []; // 定义一个用于存储音频数据片段的数组
  40. // #endif
  41. export default {
  42. data() {
  43. return {
  44. latitude: '',
  45. longitude: '',
  46. content: '',
  47. //录音相关参数
  48. //H5不能录音
  49. RECORDER: uni.getRecorderManager(),
  50. isVoice: false,
  51. voiceTis: '按住 说话',
  52. recordTis: "手指上滑 取消发送",
  53. recording: false,
  54. willStop: false,
  55. initPoint: {
  56. identifier: 0,
  57. Y: 0
  58. },
  59. recordTimer: null,
  60. recordLength: 0,
  61. //播放语音相关参数
  62. AUDIO: uni.createInnerAudioContext(),
  63. playMsgid: null,
  64. VoiceTimer: null,
  65. blobData: '',
  66. voicePaths: '',
  67. voicePath: '',
  68. phoneNumber: '',
  69. }
  70. },
  71. onLoad: function(option) {
  72. // this.$Request.getT('/app/common/type/425').then(res => {
  73. // if (res.code == 0) {
  74. // if (res.data && res.data.value && res.data.value == '是') {
  75. // this.isYuyin = res.data.value
  76. // // #ifndef H5
  77. // //录音开始事件
  78. // this.RECORDER.onStart((e) => {
  79. // this.recordBegin(e);
  80. // })
  81. // //录音结束事件
  82. // this.RECORDER.onStop((e) => {
  83. // this.recordEnd(e);
  84. // })
  85. // // #endif
  86. // }
  87. // }
  88. // });
  89. let that = this;
  90. // uni.getLocation({
  91. // type: 'wgs84',
  92. // success: function(res) {
  93. // console.log('当前位置的经度:' + res.longitude);
  94. // console.log('当前位置的纬度:' + res.latitude);
  95. // that.latitude = res.latitude
  96. // that.longitude = res.longitude
  97. // }
  98. // });
  99. },
  100. onBackPress() {
  101. this.AUDIO.stop();
  102. },
  103. onHide() {
  104. this.AUDIO.stop();
  105. },
  106. mounted() {
  107. innerAudioContext = uni.createInnerAudioContext(); //播放
  108. let _this = this;
  109. // #ifndef H5
  110. //录音停止事件
  111. // recorderManager.onStop(function(res) {
  112. // console.log('recorder stop' + res.tempFilePath);
  113. // // _this.recordEnd(res);
  114. // _this.voicePath = res.tempFilePath;
  115. // });
  116. // #endif
  117. },
  118. beforeDestroy() {
  119. // innerAudioContext.destroy();
  120. // var recorder; // 定义一个MediaRecorder对象
  121. // chunks = [];
  122. },
  123. methods: {
  124. //获取配置的求助电话
  125. getPhoneNumber() {
  126. this.$Request.getT('/app/common/type/444').then(res => {
  127. if (res.code == 0) {
  128. if (res.data && res.data.value) {
  129. uni.makePhoneCall({
  130. phoneNumber: res.data.value
  131. })
  132. }
  133. }
  134. });
  135. },
  136. // 切换语音/文字输入
  137. switchVoice() {
  138. this.isVoice = this.isVoice ? false : true;
  139. },
  140. setChatSave() {
  141. let userId = this.$queue.getData('userId');
  142. let userName = this.$queue.getData('nickName');
  143. let data = {
  144. image: this.content,
  145. state: 9,
  146. type: this.longitude,
  147. platform: this.latitude,
  148. userId: userId,
  149. userName: userName
  150. }
  151. this.$Request.postJson('/app/message/insertMessage', data).then(
  152. res => {
  153. if (res.code == 0) {
  154. this.$queue.showToast('上传成功!');
  155. } else {
  156. this.$queue.showToast(res.msg);
  157. }
  158. });
  159. },
  160. // 录音开始
  161. voiceBegin(e) {
  162. // #ifdef H5
  163. if (stream) {
  164. stream.getTracks().forEach((track) => track.stop())
  165. stream = null
  166. }
  167. if (recorder) {
  168. recorder = null
  169. }
  170. this.recordLength = 0
  171. this.voicePaths = '';
  172. this.voicePath = '';
  173. this.startRecord()
  174. // #endif
  175. if (e.touches.length > 1) {
  176. return;
  177. }
  178. this.initPoint.Y = e.touches[0].clientY;
  179. this.initPoint.identifier = e.touches[0].identifier;
  180. // #ifndef H5
  181. this.RECORDER.start({
  182. format: "mp3"
  183. }); //录音开始,
  184. // #endif
  185. },
  186. //开始录音
  187. startRecord: async function() {
  188. let _this = this
  189. // 获取麦克风音频数据流
  190. stream = await navigator.mediaDevices.getUserMedia({
  191. audio: true
  192. })
  193. // 初始化MediaRecorder对象
  194. recorder = new MediaRecorder(stream);
  195. console.log('asdsad___' + recorder)
  196. // alert('asdsad___' + recorder)
  197. // 将 stream 转成 blob 来存放
  198. recorder.ondataavailable = (blobEvent) => {
  199. chunks.push(blobEvent.data);
  200. }
  201. // 停止时生成预览的 blob url
  202. recorder.onstop = () => {
  203. const blob = new Blob(chunks, {
  204. type: 'audio/mp3'
  205. })
  206. // const mediaUrl = URL.createObjectURL(blob);
  207. _this.voicePaths = blob;
  208. _this.blobData = blob;
  209. // that.voicePath = mediaUrl;
  210. // const newbold = new File([recordPath]),{type:'audio/mp3'}
  211. // alert(that.voicePaths,URL.createObjectURL(blob))
  212. }
  213. recorder.start();
  214. _this.recordBegin()
  215. },
  216. //录音开始UI效果
  217. recordBegin(e) {
  218. this.recording = true;
  219. this.voiceTis = '松开 结束';
  220. this.recordLength = 0;
  221. this.recordTimer = setInterval(() => {
  222. this.recordLength++;
  223. }, 1000)
  224. },
  225. // 录音被打断
  226. voiceCancel() {
  227. this.recording = false;
  228. this.voiceTis = '按住 说话';
  229. this.recordTis = '手指上滑 取消发送'
  230. this.willStop = true; //不发送录音
  231. this.RECORDER.stop(); //录音结束
  232. },
  233. // 录音中(判断是否触发上滑取消发送)
  234. voiceIng(e) {
  235. // // #ifdef H5
  236. // this.startRecord()
  237. // // #endif
  238. if (!this.recording) {
  239. return;
  240. }
  241. let touche = e.touches[0];
  242. //上滑一个导航栏的高度触发上滑取消发送
  243. if (this.initPoint.Y - touche.clientY >= uni.upx2px(100)) {
  244. this.willStop = true;
  245. this.recordTis = '松开手指 取消发送'
  246. } else {
  247. this.willStop = false;
  248. this.recordTis = '手指上滑 取消发送'
  249. }
  250. },
  251. // 结束录音
  252. voiceEnd(e) {
  253. if (!this.recording) {
  254. return;
  255. }
  256. this.recording = false;
  257. this.voiceTis = '按住 说话';
  258. this.recordTis = '手指上滑 取消发送'
  259. //原生录音停止
  260. // #ifdef H5
  261. //停止录音
  262. if (recorder.state != "inactive") {
  263. recorder.stop();
  264. }
  265. //把音频流也停止掉
  266. stream.getTracks().forEach((track) => track.stop())
  267. this.uplodMp3(this.voicePaths);
  268. // #endif
  269. // #ifndef H5
  270. this.RECORDER.stop(); //录音结束
  271. // #endif
  272. },
  273. //录音结束(回调文件)
  274. recordEnd(e) {
  275. clearInterval(this.recordTimer);
  276. if (!this.willStop) {
  277. this.$queue.showLoading('发送中...')
  278. console.log("e: " + JSON.stringify(e));
  279. let msg = {
  280. length: 0,
  281. url: e.tempFilePath
  282. }
  283. let min = parseInt(this.recordLength / 60);
  284. let sec = this.recordLength % 60;
  285. min = min < 10 ? '0' + min : min;
  286. sec = sec < 10 ? '0' + sec : sec;
  287. if (this.recordLength % 60 > 1) {
  288. msg.length = min + ':' + sec;
  289. console.log('msg.length___:' + msg.length)
  290. uni.uploadFile({ // 上传接口
  291. url: this.config("APIHOST1") + '/alioss/upload', //真实的接口地址
  292. filePath: e.tempFilePath,
  293. name: 'file',
  294. success: (uploadFileRes) => {
  295. uni.hideLoading();
  296. this.content = JSON.parse(uploadFileRes.data).data;
  297. console.log("语音:" + this.content)
  298. this.setChatSave();
  299. uni.hideLoading();
  300. }
  301. });
  302. } else {
  303. this.$queue.showToast('语音要大于一秒才可以发送!')
  304. }
  305. } else {
  306. console.log('取消发送录音');
  307. }
  308. this.willStop = false;
  309. },
  310. //上传mp3格式的音频
  311. uplodMp3(recordPath) {
  312. let _this = this;
  313. // var newbold = new File([recordPath],{type:'audio/mp3'})
  314. clearInterval(_this.recordTimer);
  315. if (!_this.willStop) {
  316. // that.$queue.showLoading('发送中...')
  317. uni.showLoading({
  318. title: '录音上传中...'
  319. })
  320. let msg = {
  321. length: 0,
  322. url: recordPath
  323. }
  324. let min = parseInt(_this.recordLength / 60);
  325. let sec = _this.recordLength % 60;
  326. min = min < 10 ? '0' + min : min;
  327. sec = sec < 10 ? '0' + sec : sec;
  328. if (_this.recordLength % 60 > 1) {
  329. msg.length = min + ':' + sec;
  330. // console.log('msg.length___:' + msg.length)
  331. setTimeout(function() {
  332. uni.uploadFile({ // 上传接口
  333. url: _this.config("APIHOST1") + '/alioss/upload', //真实的接口地址
  334. file: _this.blobData,
  335. // file: recordPath,
  336. name: 'file',
  337. success: (uploadFileRes) => {
  338. console.error('uploadFileRes------' + uploadFileRes)
  339. uni.hideLoading();
  340. _this.content = JSON.parse(uploadFileRes.data).data;
  341. // console.log("语音:" + that.content)
  342. _this.setChatSave();
  343. uni.hideLoading();
  344. }
  345. });
  346. }, 1000)
  347. } else {
  348. _this.$queue.showToast('语音要大于一秒才可以发送!')
  349. }
  350. } else {
  351. console.log('取消发送录音');
  352. }
  353. _this.willStop = false;
  354. },
  355. config: function(name) {
  356. var info = null;
  357. if (name) {
  358. var name2 = name.split("."); //字符分割
  359. if (name2.length > 1) {
  360. info = configdata[name2[0]][name2[1]] || null;
  361. } else {
  362. info = configdata[name] || null;
  363. }
  364. if (info == null) {
  365. let web_config = cache.get("web_config");
  366. if (web_config) {
  367. if (name2.length > 1) {
  368. info = web_config[name2[0]][name2[1]] || null;
  369. } else {
  370. info = web_config[name] || null;
  371. }
  372. }
  373. }
  374. }
  375. return info;
  376. },
  377. }
  378. }
  379. </script>
  380. <style lang="scss">
  381. @import "../setting/css/style.scss";
  382. page {
  383. background: #346EF6;
  384. }
  385. .datt {
  386. font-size: 42rpx;
  387. font-family: PingFang SC;
  388. font-weight: 800;
  389. }
  390. </style>