ExchangeView.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <template>
  2. <view>
  3. <customNav :shownav="false" title="" tinColor="#006AFF" jiantou="0"></customNav>
  4. <view class="toptalbarCtv" :style="{top: statusBarHeight+'rpx'}">
  5. <view class="contentColumnC" style="background-color: #006AFF;height: 90rpx;align-items: center;">
  6. <view class="contentInRowS" style="width: 92%;">
  7. <uni-icons custom-prefix="custom-icon" color="white" type="back" size="23" @click="gotoBack"></uni-icons>
  8. <text style="font-size: 32rpx;color: white;">{{$t('exchange.xinxi')}}</text>
  9. <text style="font-size: 30rpx;color: white;">{{linkNote}}</text>
  10. <!-- <uni-icons custom-prefix="custom-icon" color="white" type="person-filled" size="23" @click="friendMSG"></uni-icons> -->
  11. </view>
  12. </view>
  13. </view>
  14. <view :style="{marginTop: contenttop+'rpx'}">
  15. <scroll-view scroll-y="true" :style="'height:'+scrollHeight+'rpx;'" :scroll-into-view="btview">
  16. <view class="contentColumn" style="width: 90%;margin-left: 5%;margin-top: 30rpx;">
  17. <view v-for="(item,index) in xiaoxiList">
  18. <view v-if="item.type!=2" class="contentColumn">
  19. <view class="contentInRowL">
  20. <text style="font-size: 32rpx;">{{item.rcuser}}</text>
  21. <text style="font-size: 28rpx;color: darkgray;">{{item.time}}</text>
  22. </view>
  23. <view v-if="item.msg.type==0" class="contentInRowL">
  24. <text class="msgctst">{{item.msg.msg}}</text>
  25. </view>
  26. <view v-if="item.msg.type==1" class="contentInRowL">
  27. <netImage class="spIcon" width="120" height="120" :mysrc="item.msg.msg" mymode="scaleToFill" @Emyimageclick="myimageclick"></netImage>
  28. </view>
  29. </view>
  30. <view v-if="item.type==2" class="contentColumn">
  31. <view class="contentInRowR" style="align-items: center;margin-top: 20rpx;">
  32. <text v-if="item.state==2" class="reddoint"></text>
  33. <text style="font-size: 28rpx;color: darkgray;">{{item.time}}</text>
  34. </view>
  35. <view v-if="item.msg.type==0" class="contentInRowR">
  36. <text class="msgctst">{{item.msg.msg}}</text>
  37. </view>
  38. <view v-if="item.msg.type==1" class="contentInRowR">
  39. <netImage class="spIcon" width="120" height="120" :mysrc="item.msg.msg" mymode="scaleToFill" @Emyimageclick="myimageclick"></netImage>
  40. </view>
  41. </view>
  42. </view>
  43. </view>
  44. <view id='bt123' style="height: 140rpx;"></view>
  45. <view v-if="showActV" style="height: 160rpx;"></view>
  46. </scroll-view>
  47. <view class="bottomfloatV">
  48. <view class="contentInRowC" style="height: 100rpx;align-items: flex-start;margin-top: 8rpx;">
  49. <input class="inputVst" type="text" :value="msg" :placeholder="$t('exchange.qingshurxx')" @input="msgInput" confirm-type="send" v-on:confirm="send">
  50. <uni-icons class="updatamsg" custom-prefix="custom-icon" color="#006AFF" type="plus" size="32" @click="onupdatamsg"></uni-icons>
  51. </view>
  52. <view v-if="showActV">
  53. <view class="item_list" style="width: 90%;">
  54. <view class="item_content contentColumnC" v-for="(item, index) in actLst" @click="actLstsel(index)">
  55. <uni-icons class="updatamsg" custom-prefix="custom-icon" color="#1A1A1A" :type="item.icon" size="32" ></uni-icons>
  56. <view class="title">
  57. <text class="text1row" style="font-size: 28rpx;">{{item.title}}</text>
  58. </view>
  59. </view>
  60. </view>
  61. </view>
  62. </view>
  63. </view>
  64. </view>
  65. </template>
  66. <script>
  67. import api from "@/pages/api/api.js"
  68. import {
  69. UploadImage
  70. } from '@/pages/api/basic.js';
  71. //import dataBase from "@/pages/api/dataBase.js"
  72. export default {
  73. data() {
  74. return {
  75. statusBarHeight:0,
  76. contenttop:0,
  77. scrollHeight:0,
  78. btview:'bt123',
  79. userInfo:'',
  80. linkNote:'',
  81. msg:'',
  82. sendIndex:0,
  83. xiaoxiList:[],
  84. showActV:false,
  85. actLst:[],
  86. roomId: Math.floor(Math.random() * 100000),
  87. imUser:'',
  88. iscaller:false,
  89. isAndroid:false,
  90. audioObj:null,
  91. soundPlay:false
  92. }
  93. },
  94. onLoad(option) {
  95. var systemInfo = uni.getSystemInfoSync();
  96. this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
  97. this.statusBarHeight=systemInfo.statusBarHeight*(750/systemInfo.windowWidth);
  98. this.contenttop=this.statusBarHeight+50;
  99. this.scrollHeight=systemInfo.windowHeight*(750/systemInfo.windowWidth)-this.contenttop-100;
  100. this.linkNote=this.$t('audioCall.weilianjie')
  101. getApp().globalData.EXViewOpen=true;
  102. this.userInfo = uni.getStorageSync('userInfo');
  103. if(option.caller==1){
  104. this.iscaller=true;
  105. this.imUser = uni.getStorageSync('imUser');
  106. }
  107. else{
  108. var payload=uni.getStorageSync('impayload');
  109. this.doPushMessage(payload);
  110. if(!this.isAndroid){
  111. this.audioObj=uni.createInnerAudioContext();
  112. this.audioObj.src='hybrid/html/xuanfu/img/y800.mp3';
  113. this.audioObj.play();
  114. this.soundPlay=true;
  115. }
  116. }
  117. this.initWebSocket();
  118. this.initACTbut();
  119. this.getxiaoxiList();
  120. },
  121. onShow() {
  122. },
  123. onUnload() {
  124. if(this.soundPlay){
  125. this.audioObj.pause();
  126. }
  127. this.closeWebSocket();
  128. getApp().globalData.EXViewOpen=false;
  129. },
  130. methods: {
  131. doPushMessage(str){
  132. if(str.indexOf("\\\"")!=-1){
  133. str=str.replace(/\\\"/g, '\"');
  134. str = str.replace(/\"{/g, '{');
  135. str = str.replace(/}\"/g, '}');
  136. }
  137. var obj = JSON.parse(str)
  138. this.imUser=obj;
  139. console.log(this.imUser);
  140. uni.setStorageSync('imUser',this.imUser)
  141. },
  142. getxiaoxiList(){
  143. var xxstr = 'xiaoxi'+this.imUser.ddId;
  144. console.log(xxstr);
  145. var List = uni.getStorageSync(xxstr);
  146. if(''==List||null==List||undefined==List){
  147. this.xiaoxiList=[];
  148. return;
  149. }
  150. else{
  151. if(List.length>20){
  152. this.xiaoxiList = List.slice(List.length-20);
  153. }
  154. else{
  155. this.xiaoxiList = List;
  156. }
  157. var xxstr = 'xiaoxi'+this.imUser.ddId;
  158. uni.setStorageSync(xxstr,this.xiaoxiList);
  159. }
  160. console.log(this.xiaoxiList);
  161. },
  162. gotoBack(){
  163. uni.navigateBack();
  164. },
  165. myimageclick(url){
  166. console.log('myimageclick',JSON.stringify(url));
  167. uni.navigateTo({
  168. url:'/pages/index/BigimageView?mysrc='+url
  169. })
  170. },
  171. initACTbut(){
  172. var img={
  173. icon:'image',
  174. title:this.$t('exchange.tupian'),
  175. index:1
  176. }
  177. this.actLst.push(img);
  178. // var file={
  179. // icon:'upload',
  180. // title:this.$t('exchange.wenjian'),
  181. // index:2
  182. // }
  183. // this.actLst.push(file);
  184. var audio={
  185. icon:'phone',
  186. title:'IM',
  187. index:3
  188. }
  189. this.actLst.push(audio);
  190. // var vidio={
  191. // icon:'videocam',
  192. // title:'视频',
  193. // index:4
  194. // }
  195. // this.actLst.push(vidio);
  196. },
  197. actLstsel(index){
  198. console.log(index)
  199. if(index==0){
  200. this.selectImage();
  201. return;
  202. }
  203. if(index==1){
  204. uni.navigateTo({
  205. url:'/pages/imcall/audioCall?caller=1'
  206. })
  207. return;
  208. }
  209. },
  210. //-----------------
  211. selectImage(){
  212. var that = this;
  213. uni.chooseImage({
  214. count: 1, // 图片数量
  215. sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
  216. sourceType: ['album'], //从相册选择或者拍照
  217. success: (res) => {
  218. const tempFilePaths = res.tempFilePaths;
  219. console.log('-----',tempFilePaths)
  220. uni.uploadFile({
  221. url:this.$baseurl+UploadImage, //上传图片api
  222. filePath: tempFilePaths[0],
  223. name: 'file',
  224. header:{
  225. //"Authorization": userinfo.token
  226. },
  227. success: (res) => {
  228. let group = JSON.parse(res.data);
  229. that.sendImg(group.data);
  230. }
  231. });
  232. }
  233. });
  234. },
  235. sendImg(str){
  236. var sentMsg={
  237. msg:str,
  238. type:1
  239. };
  240. var item={
  241. type:2,
  242. state:0,
  243. time:getApp().globalData.sj(),
  244. msg:sentMsg
  245. }
  246. this.xiaoxiList.push(item);
  247. var xxstr = 'xiaoxi'+this.imUser.ddId;
  248. uni.setStorageSync(xxstr,this.xiaoxiList);
  249. console.log(this.xiaoxiList);
  250. this.sendIndex=this.xiaoxiList.length-1;
  251. this.sendMessage(sentMsg,0);
  252. },
  253. msgInput(event){
  254. this.msg = event.target.value;
  255. },
  256. send(){
  257. console.log('11111111111111',this.msg)
  258. if(this.msg.length>0){
  259. var sentMsg={
  260. msg:this.msg,
  261. type:0
  262. };
  263. var item={
  264. type:2,
  265. state:0,
  266. time:getApp().globalData.sj(),
  267. msg:sentMsg
  268. }
  269. this.xiaoxiList.push(item);
  270. var xxstr = 'xiaoxi'+this.imUser.ddId;
  271. uni.setStorageSync(xxstr,this.xiaoxiList)
  272. this.sendIndex=this.xiaoxiList.length-1;
  273. this.sendMessage(sentMsg,0);
  274. this.msg='';
  275. }
  276. },
  277. onupdatamsg(){
  278. this.showActV = !this.showActV;
  279. },
  280. //WebSocket--------------------------------
  281. // 初始化WebSocket连接
  282. initWebSocket() {
  283. const wsUrl = 'ws://api.awayqtw.com:8080/ws/'+this.userInfo.userId; // 替换为你的WebSocket服务器URL
  284. // this.ws = uni.connectSocket({
  285. // url: wsUrl,
  286. // });
  287. var that = this;
  288. this.ws = uni.connectSocket({
  289. url: wsUrl, //仅为示例,并非真实接口地址。
  290. success() {
  291. that.start();
  292. }
  293. });
  294. console.log(this.ws);
  295. // var that = this;
  296. // setTimeout(() => {
  297. // that.start();
  298. // }, 1000)
  299. },
  300. start(){
  301. var that = this;
  302. uni.onSocketOpen(function (res) {
  303. console.log('WebSocket连接已打开!');
  304. if(that.iscaller){
  305. that.senSocket();
  306. }
  307. else{//发送远端连接通知
  308. that.sendIndex=-1;
  309. that.sendMessage('WebSocket远端连接',0);
  310. }
  311. });
  312. uni.onSocketMessage(function (res) {
  313. uni.hideLoading();
  314. console.log('收到服务器内容:',res);
  315. var data = res.data;
  316. if(data.indexOf("远端连接")!=-1){
  317. that.linkNote=that.$t('audioCall.yilianjie')
  318. return;
  319. }
  320. if(data.indexOf("连接成功")!=-1){
  321. return;
  322. }
  323. if(data.indexOf("发送成功")!=-1){//1
  324. if(that.sendIndex<0){
  325. that.linkNote=that.$t('audioCall.yilianjie');
  326. return;
  327. }
  328. console.log(that.xiaoxiList[that.sendIndex]);
  329. that.xiaoxiList[that.sendIndex].state=1;
  330. return;
  331. }
  332. if(data.indexOf("发送失败")!=-1){//2
  333. if(that.sendIndex<0){
  334. return;
  335. }
  336. that.xiaoxiList[that.sendIndex].state=2;
  337. return;
  338. }
  339. console.log(JSON.parse(res.data));
  340. var rcmag = JSON.parse(res.data);
  341. rcmag=JSON.parse(rcmag.msg);
  342. var item={
  343. type:1,
  344. state:3,
  345. time:getApp().globalData.sj(),
  346. msg:rcmag
  347. }
  348. console.log(item);
  349. that.xiaoxiList.push(item);
  350. var xxstr = 'xiaoxi'+that.imUser.ddId;
  351. uni.setStorageSync(xxstr,that.xiaoxiList);
  352. });
  353. uni.onSocketError(function (res) {
  354. console.log('WebSocket连接打开失败,请检查!');
  355. });
  356. uni.onSocketClose(function (res) {
  357. console.log('WebSocket 已关闭!');
  358. });
  359. },
  360. // 发送消息
  361. sendMessage(sentMsg,type) {
  362. console.log('sendMessage',sentMsg);
  363. var data={
  364. to:this.imUser.userId,
  365. type:type,//类型0个人,1群聊,2全体
  366. time:getApp().globalData.sj(),
  367. msg:sentMsg,
  368. };
  369. uni.showLoading({
  370. title:'Loading...',
  371. mask:true
  372. })
  373. uni.sendSocketMessage({
  374. data:JSON.stringify(data)
  375. });
  376. },
  377. // 关闭WebSocket连接
  378. closeWebSocket() {
  379. uni.closeSocket();
  380. },
  381. senSocket(){//推送消息通知
  382. if(this.imUser.cid==''||this.imUser.cid==null||this.imUser.cid==undefined){
  383. uni.showToast({
  384. title:this.$t('audioCall.wfjt'),
  385. icon: 'none',
  386. duration: 1000
  387. });
  388. return;
  389. }
  390. var payload={
  391. ddId:this.imUser.ddId,
  392. roomId:this.roomId,
  393. userId:this.userInfo.userId,
  394. nickName:this.userInfo.nickName,
  395. avatar:this.userInfo.avatar,
  396. cid:this.userInfo.cid,
  397. }
  398. api('pushMsgYH',{
  399. cid:this.imUser.cid,
  400. title:'IM Message',
  401. content:'IM Message',
  402. payload:payload
  403. },res=>{
  404. console.log(res)
  405. },failc=>{
  406. //console.log('getadvertis----',failc)
  407. })
  408. },
  409. }
  410. }
  411. </script>
  412. <style lang="scss">
  413. page{
  414. background-color: #F4F4F4;
  415. }
  416. .toptalbarCtv{
  417. position: fixed;
  418. background-color: white;
  419. left: 0;
  420. right: 0;
  421. top: 0;
  422. z-index: 999;
  423. }
  424. .msgctst{
  425. font-size: 32rpx;
  426. color: #1a1a1a;
  427. background-color: white;
  428. border-radius: 12rpx;
  429. padding: 16rpx;
  430. }
  431. .mymsgctst{
  432. font-size: 32rpx;
  433. color:white;
  434. background-color: #7a7a7a;
  435. border-radius: 12rpx;
  436. padding: 16rpx;
  437. }
  438. .spIcon{
  439. width: 150rpx;
  440. height: 150rpx;
  441. }
  442. .bottomfloatV{
  443. position: fixed;
  444. flex-direction: column;
  445. justify-content: center;
  446. align-items: center;
  447. left: 0;
  448. right: 0;
  449. bottom: 0;
  450. z-index: 999;
  451. background-color: white;
  452. }
  453. .inputVst{
  454. margin-top: 10rpx;
  455. width: 76%;
  456. background-color: #F4F4F4;
  457. height: 80rpx;
  458. border-radius: 20rpx;
  459. }
  460. .updatamsg{
  461. margin-left: 10rpx;
  462. margin-top: 10rpx;
  463. }
  464. .item_list{
  465. display: flex;
  466. flex-wrap: wrap;
  467. justify-content:flex-start;
  468. width: 90%;
  469. margin-left: 5%;
  470. .item_content{
  471. width: 24.6%;
  472. height: 160rpx;
  473. box-sizing: border-box;
  474. image{
  475. width: 100rpx;
  476. height: 100rpx;
  477. display: block;
  478. }
  479. .title{
  480. width: 100%;
  481. text-align: center;
  482. //height: 60rpx;
  483. line-height: 40rpx;
  484. padding-bottom: 10rpx;
  485. }
  486. }
  487. }
  488. .titleview{
  489. padding-left: 40rpx;
  490. padding-top: 22rpx;
  491. line-height: 46rpx;
  492. }
  493. .reddoint{
  494. background-color: crimson;
  495. width: 30rpx;
  496. height: 30rpx;
  497. border-radius: 15rpx;
  498. margin-right: 10rpx;
  499. }
  500. </style>