吉安感知网项目-前端
shuishen
2026-02-27 a3ca31bcf7fc88a66e7c9780d5d6efd76e12f289
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
import { useUserStore } from "@/store/index.js";
import useAppStore from "../store/modules/app/index.js";
import websocketService from "@/utils/websocket.js";
// #ifdef APP-PLUS
import { openDialog, allowFloat, getBatteryCapacity, showIncomingCallNotification, cancelIncomingCallNotification } from '@/uni_modules/lgh-dialog'
// #endif
export function useGlobalWS() {
    const userStore = useUserStore();
  const appStore = useAppStore();
  const callStatus = ref(null)
  // token 存储
  const accessToken = ref('')
  // 断线恢复定时器
  let recoverTimer = null
  // 存储铃声实例
  let ringtoneInstance = null
 
  // 监听WebView消息事件
  if (typeof uni !== 'undefined' && uni.$on) {
    uni.$on('webViewMessage', (data) => {
      console.log('📨 useGlobalWS 收到 WebView 消息:', data)
      // 处理挂断消息
      if (data?.type === 'hangupVoice') {
        console.log('📞 收到挂断消息')
        initWS()
      }
    });
  }
 
  // 设置默认用户ID为3
  const defaultUserId = '2021474815063486465';
  // WebSocket基础URL
  // const WS_BASE = 'wss://wrj.shuixiongit.com/ws/chat?userId=';
  const WS_BASE = 'ws://218.202.104.82:38201/ws/chat';
 
    // 消息处理
  function messageHandler(payload) {
    // 先尝试直接处理消息(适用于mobile-web-view的voiceCallDetail页面的消息格式)
    const t = (payload.type || '').toString()
    callStatus.value = t
    // 处理语音通话请求
    if (t === 'call') {
      console.log('📞 全局收到来电 call,来自', payload.from)
      // 触发震动
      triggerVibration();
      // 构建来电参数
      const callParams = {
        peerUid: payload.from,
        from: payload.from,
        type: 'incoming'
      };
      // #ifdef APP-PLUS
      // 发送来电通知(锁屏/后台都会弹出 + 亮屏)
      showIncomingCallNotification(payload.from || '未知来电')
      // 拉起应用到前台
            openDialog()
      // #endif
      // 转义参数以便在URL中传递
      const encodedParams = encodeURIComponent(JSON.stringify(callParams));
 
      try {
        // 优先使用uni-app的导航API(适用于同应用内跳转)
        if (typeof uni !== 'undefined' && uni.navigateTo) {
          uni.navigateTo({
            url: `/subPackages/voiceCallDetail/index?voiceparams=${encodedParams}`,
          });
        } else {
          console.error('无法跳转到语音通话页面:当前环境不支持导航');
        }
      } catch (error) {
        console.error('跳转到语音通话页面失败:', error);
      }
      return
    }
    // 通话接听或结束时,取消来电通知
    if (t === 'accept' || t === 'reject' || t === 'hangup' || t === 'cancel') {
      // #ifdef APP-PLUS
      cancelIncomingCallNotification()
      // #endif
    }
  }
 
  // 播放来电铃声 - 定义在 messageHandler 外部
  // function playRingtone() {
  //   try {
  //     if (typeof uni !== 'undefined' && uni.createInnerAudioContext) {
  //       const ringtone = uni.createInnerAudioContext();
  //       // 使用默认铃声,注意路径写法
  //       ringtone.src = '/static/audio/ringtone.mp3';
  //       ringtone.loop = true;
  //       ringtone.volume = 0.8;
  //       ringtone.play();
  //       // 存储铃声实例
  //       ringtoneInstance = ringtone; // 使用局部变量而不是window
  //     }
  //   } catch (error) {
  //   }
  // }
 
  // 触发震动
  function triggerVibration() {
    try {
      if (typeof uni !== 'undefined') {
        // 方法1:使用uni.vibrate(现代API)
        if (uni.vibrate) {
          // 震动400ms
          uni.vibrate({
            duration: 400,
            success: () => {
              console.log('📳 震动已触发');
            },
            fail: (error) => {
              // 方法2:使用uni.vibrateLong(兼容旧设备)
              if (uni.vibrateLong) {
                uni.vibrateLong({
                  success: () => {
                    console.log('📳 兼容模式震动已触发');
                  },
                  fail: (err) => {
                    console.error('兼容模式震动失败:', err);
                  }
                });
              }
            }
          });
        }
        // 方法3:使用plus API(H5+)
        if (typeof plus !== 'undefined' && plus.device && plus.device.vibrate) {
          plus.device.vibrate(400);
          console.log('📳 H5+ 震动已触发');
        }
      }
    } catch (error) {
      console.error('触发震动失败:', error);
    }
  }
 
  // 停止铃声
  // function stopRingtone() {
  //   try {
  //     if (ringtoneInstance) {
  //       ringtoneInstance.stop();
  //       ringtoneInstance.destroy();
  //       ringtoneInstance = null;
  //     }
  //   } catch (error) {
  //     // 即使出错也重置实例
  //     ringtoneInstance = null;
  //   }
  // }
  //
  // // 监听停止铃声事件
  // if (typeof uni !== 'undefined' && uni.$on) {
  //   uni.$on('stopRingtone', stopRingtone);
  //   // 监听WebView消息事件
  //   uni.$on('webViewMessage', (data) => {
  //     // 检查是否是停止铃声消息
  //     if (data?.type === 'stopVoice') {
  //       stopRingtone();
  //       console.log('📳 收到WebView停止铃声消息,已停止铃声');
  //
  //     }
  //   });
  // }
 
  // 初始化WebSocket连接
  function isVoiceCallDetailActive() {
    try {
      const pages = getCurrentPages()
      const currentPage = pages[pages.length - 1]
      const route = currentPage?.route || currentPage?.$page?.fullPath || ''
      return String(route).includes('subPackages/voiceCallDetail/index')
    } catch (error) {
      return false
    }
  }
 
  function shouldRecoverWS() {
    return !isVoiceCallDetailActive() && !!useUserStore()?.userInfo?.access_token
  }
 
  function ensureRecoverTimer() {
    if (recoverTimer) {
      return
    }
    recoverTimer = setInterval(() => {
      // console.log('shouldRecoverWS()',shouldRecoverWS(),'----------',websocketService.getConnected())
      if (shouldRecoverWS() && !websocketService.getConnected()) {
        initWS()
      }
    }, 3000)
  }
 
  function initWS() {
    websocketService.close()
    const userStore = useUserStore()
    accessToken.value =userStore?.userInfo.access_token
    if (!accessToken.value || isVoiceCallDetailActive()) {
      return
    }
    try {
      websocketService.setOnMessageCallback(messageHandler);
      websocketService.setOnOpenCallback(() => {})
      websocketService.setOnCloseCallback(() => {
        if (shouldRecoverWS()) {
          ensureRecoverTimer()
        }
      })
      websocketService.setOnErrorCallback(() => {
        if (shouldRecoverWS()) {
          ensureRecoverTimer()
        }
      })
 
      // 获取当前用户ID,优先使用store中的用户信息
      const userId = userStore.userInfo?.new_userInfo.userId || defaultUserId;
            console.log('🌐 全局WebSocket初始化开始,用户ID:', userId)
 
      // 检查是否已经有活跃的WebSocket连接
      if (!websocketService.getConnected() || websocketService.userId !== userId) {
        // 使用用户ID初始化WebSocket连接
        websocketService.init(userId, WS_BASE, accessToken.value);
        // console.log('🌐 全局WebSocket初始化成功,用户ID:', userId);
      }
    } catch (error) {
    }
  }
  watch(
    () => callStatus.value,
    (newValue) => {
      if (newValue === 'accept') {
        console.log('📞 通话中,跳过WebSocket初始化');
        return;
      }
      initWS();
    },
    { immediate: true, deep: true }
  )
 
  ensureRecoverTimer()
}