@aochuang/client-sdk 1.0.278

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/README.md +93 -0
  2. package/common/avatar/avatar.vue +86 -0
  3. package/common/avatar/index.js +3 -0
  4. package/common/badge/badge.vue +105 -0
  5. package/common/badge/index.js +3 -0
  6. package/common/context-menu/context-menu-box.vue +61 -0
  7. package/common/context-menu/context-menu-group.vue +162 -0
  8. package/common/context-menu/context-menu-item.vue +179 -0
  9. package/common/context-menu/context-menu.vue +201 -0
  10. package/common/context-menu/index.js +3 -0
  11. package/common/context-menu/utils.js +138 -0
  12. package/common/friend-avatar/default.svg +1 -0
  13. package/common/friend-avatar/friend-avatar.vue +29 -0
  14. package/common/friend-avatar/index.js +3 -0
  15. package/common/image/index.js +3 -0
  16. package/common/index.js +17 -0
  17. package/common/room-avatar/default.svg +6 -0
  18. package/common/room-avatar/index.js +3 -0
  19. package/common/room-avatar/room-avatar.vue +29 -0
  20. package/common/scroll-load-more/index.js +3 -0
  21. package/common/scroll-load-more/scroll-load-more.vue +195 -0
  22. package/common/user-avatar/default.svg +1 -0
  23. package/common/user-avatar/index.js +3 -0
  24. package/common/user-avatar/user-avatar.vue +29 -0
  25. package/components/account-select/account-select-skeleton.vue +56 -0
  26. package/components/account-select/account-select.vue +205 -0
  27. package/components/account-select/all.svg +1 -0
  28. package/components/account-select/index.js +3 -0
  29. package/components/chat-editor/MENTION_TOKEN_SUMMARY.md +74 -0
  30. package/components/chat-editor/chat-editor-button/chat-editor-button.vue +78 -0
  31. package/components/chat-editor/chat-editor-suggestions/chat-editor-suggestions.vue +329 -0
  32. package/components/chat-editor/chat-editor-toolbar/chat-editor-toolbar-item.vue +28 -0
  33. package/components/chat-editor/chat-editor-toolbar/chat-editor-toolbar.vue +17 -0
  34. package/components/chat-editor/chat-editor.vue +933 -0
  35. package/components/chat-editor/index.js +12 -0
  36. package/components/chat-editor/utils.js +189 -0
  37. package/components/chat-friend-profile/chat-friend-profile.vue +118 -0
  38. package/components/chat-friend-profile/index.js +3 -0
  39. package/components/chat-layout/chat-layout.vue +71 -0
  40. package/components/chat-layout/index.js +3 -0
  41. package/components/chat-panel/chat-panel-box.vue +350 -0
  42. package/components/chat-panel/chat-panel-chat.vue +121 -0
  43. package/components/chat-panel/chat-panel-chats.vue +674 -0
  44. package/components/chat-panel/chat-panel-empty.vue +32 -0
  45. package/components/chat-panel/chat-panel-increment.vue +80 -0
  46. package/components/chat-panel/chat-panel-inner-msg.vue +25 -0
  47. package/components/chat-panel/chat-panel-loading.vue +29 -0
  48. package/components/chat-panel/chat-panel-nearest.vue +136 -0
  49. package/components/chat-panel/chat-panel.vue +292 -0
  50. package/components/chat-panel/index.js +3 -0
  51. package/components/chat-panel/util.js +83 -0
  52. package/components/chat-room-profile/chat-room-profile.vue +103 -0
  53. package/components/chat-room-profile/index.js +3 -0
  54. package/components/contacts-friend-select/contacts-friend-select-skeleton.vue +41 -0
  55. package/components/contacts-friend-select/contacts-friend-select.vue +204 -0
  56. package/components/contacts-friend-select/index.js +3 -0
  57. package/components/contacts-group-select/contacts-group-select-item.vue +98 -0
  58. package/components/contacts-group-select/contacts-group-select-skeleton.vue +81 -0
  59. package/components/contacts-group-select/contacts-group-select.vue +396 -0
  60. package/components/contacts-group-select/index.js +3 -0
  61. package/components/contacts-room-select/contacts-room-select-skeleton.vue +41 -0
  62. package/components/contacts-room-select/contacts-room-select.vue +208 -0
  63. package/components/contacts-room-select/index.js +3 -0
  64. package/components/index.js +43 -0
  65. package/components/layout/index.js +3 -0
  66. package/components/layout/layout.vue +70 -0
  67. package/components/session-select/index.js +11 -0
  68. package/components/session-select/session-select-item-skeleton.vue +59 -0
  69. package/components/session-select/session-select-item.vue +190 -0
  70. package/components/session-select/session-select.vue +386 -0
  71. package/components/wechat-chat-control/calling/calling.vue +227 -0
  72. package/components/wechat-chat-control/calling/phone-fill.svg +1 -0
  73. package/components/wechat-chat-control/calling/vidicon-fill.svg +1 -0
  74. package/components/wechat-chat-control/channel-live/channel-live.vue +198 -0
  75. package/components/wechat-chat-control/channel-live/quote-icon.svg +1 -0
  76. package/components/wechat-chat-control/channel-video/channel-video.vue +180 -0
  77. package/components/wechat-chat-control/channel-video/quote-icon.svg +1 -0
  78. package/components/wechat-chat-control/channel-video-card/channel-video-card.vue +139 -0
  79. package/components/wechat-chat-control/channel-video-card/quote-icon.svg +1 -0
  80. package/components/wechat-chat-control/company-card/company-card.vue +136 -0
  81. package/components/wechat-chat-control/company-card/quote-icon.svg +1 -0
  82. package/components/wechat-chat-control/custom-expression/custom-expression.vue +45 -0
  83. package/components/wechat-chat-control/empty/empty.vue +27 -0
  84. package/components/wechat-chat-control/file-url/file-url.vue +307 -0
  85. package/components/wechat-chat-control/file-url/icons/file-excel-line.svg +1 -0
  86. package/components/wechat-chat-control/file-url/icons/file-info-line.svg +1 -0
  87. package/components/wechat-chat-control/file-url/icons/file-music-line.svg +1 -0
  88. package/components/wechat-chat-control/file-url/icons/file-pdf-line.svg +1 -0
  89. package/components/wechat-chat-control/file-url/icons/file-ppt-line.svg +1 -0
  90. package/components/wechat-chat-control/file-url/icons/file-settings-line.svg +1 -0
  91. package/components/wechat-chat-control/file-url/icons/file-text-line.svg +1 -0
  92. package/components/wechat-chat-control/file-url/icons/file-unknow-line.svg +1 -0
  93. package/components/wechat-chat-control/file-url/icons/file-word-line.svg +1 -0
  94. package/components/wechat-chat-control/file-url/icons/file-zip-line.svg +1 -0
  95. package/components/wechat-chat-control/file-url/icons/index.js +24 -0
  96. package/components/wechat-chat-control/image/image.vue +344 -0
  97. package/components/wechat-chat-control/image/index.js +1 -0
  98. package/components/wechat-chat-control/image/util.js +29 -0
  99. package/components/wechat-chat-control/index.js +104 -0
  100. package/components/wechat-chat-control/jx-sys-text/jx-sys-text.vue +28 -0
  101. package/components/wechat-chat-control/location/location.vue +179 -0
  102. package/components/wechat-chat-control/location/offline-bg.png +0 -0
  103. package/components/wechat-chat-control/member-change/member-change.vue +37 -0
  104. package/components/wechat-chat-control/music/icons/163.png +0 -0
  105. package/components/wechat-chat-control/music/icons/163.svg +12 -0
  106. package/components/wechat-chat-control/music/icons/default.png +0 -0
  107. package/components/wechat-chat-control/music/icons/default.svg +1 -0
  108. package/components/wechat-chat-control/music/icons/kuwo.png +0 -0
  109. package/components/wechat-chat-control/music/icons/qq.png +0 -0
  110. package/components/wechat-chat-control/music/icons/qq.svg +1 -0
  111. package/components/wechat-chat-control/music/music.vue +156 -0
  112. package/components/wechat-chat-control/music/utils.js +30 -0
  113. package/components/wechat-chat-control/quote-message/quote-message.vue +257 -0
  114. package/components/wechat-chat-control/real-time-position/icon.svg +1 -0
  115. package/components/wechat-chat-control/real-time-position/real-time-position.vue +57 -0
  116. package/components/wechat-chat-control/red-envelopes/quote-icon.svg +1 -0
  117. package/components/wechat-chat-control/red-envelopes/red-envelope.svg +1 -0
  118. package/components/wechat-chat-control/red-envelopes/red-envelopes.vue +168 -0
  119. package/components/wechat-chat-control/revoke-me-message/revoke-me-message.vue +41 -0
  120. package/components/wechat-chat-control/revoke-other-message/revoke-other-message.vue +41 -0
  121. package/components/wechat-chat-control/revoke-you-message/revoke-you-message.vue +41 -0
  122. package/components/wechat-chat-control/room-calling/phone-fill.svg +1 -0
  123. package/components/wechat-chat-control/room-calling/room-calling.vue +52 -0
  124. package/components/wechat-chat-control/room-calling/vidicon-fill.svg +1 -0
  125. package/components/wechat-chat-control/share-card/quote-icon.svg +1 -0
  126. package/components/wechat-chat-control/share-card/share-card.vue +140 -0
  127. package/components/wechat-chat-control/system/system.vue +122 -0
  128. package/components/wechat-chat-control/system-batch-message/system-batch-message.vue +28 -0
  129. package/components/wechat-chat-control/system-money/system-money.vue +39 -0
  130. package/components/wechat-chat-control/text/icons/icon.svg +6 -0
  131. package/components/wechat-chat-control/text/text.vue +164 -0
  132. package/components/wechat-chat-control/text-with-at/text-with-at.vue +88 -0
  133. package/components/wechat-chat-control/transfer/collection.svg +1 -0
  134. package/components/wechat-chat-control/transfer/quote-icon.svg +1 -0
  135. package/components/wechat-chat-control/transfer/red-transfer.svg +1 -0
  136. package/components/wechat-chat-control/transfer/refund.svg +1 -0
  137. package/components/wechat-chat-control/transfer/transfer.svg +1 -0
  138. package/components/wechat-chat-control/transfer/transfer.vue +263 -0
  139. package/components/wechat-chat-control/unknow/unknow.vue +21 -0
  140. package/components/wechat-chat-control/url/icons/link.svg +1 -0
  141. package/components/wechat-chat-control/url/icons/video.svg +6 -0
  142. package/components/wechat-chat-control/url/miniprogram.svg +1 -0
  143. package/components/wechat-chat-control/url/url-file.vue +47 -0
  144. package/components/wechat-chat-control/url/url-link.vue +169 -0
  145. package/components/wechat-chat-control/url/url-merge.vue +164 -0
  146. package/components/wechat-chat-control/url/url-miniprogram.vue +259 -0
  147. package/components/wechat-chat-control/url/url.vue +116 -0
  148. package/components/wechat-chat-control/util.js +234 -0
  149. package/components/wechat-chat-control/video/icons/video.svg +1 -0
  150. package/components/wechat-chat-control/video/video.vue +304 -0
  151. package/components/wechat-chat-control/voice/icons/voice.svg +1 -0
  152. package/components/wechat-chat-control/voice/voice.vue +464 -0
  153. package/components/wechat-chat-control/wechat-chat-control-config-item.vue +24 -0
  154. package/components/wechat-chat-control/wechat-chat-control-config-msg.vue +21 -0
  155. package/components/wechat-chat-control/wechat-chat-control-config.vue +57 -0
  156. package/components/wechat-chat-panel/chat-panel-chat-status/chat-panel-chat-status.vue +69 -0
  157. package/components/wechat-chat-panel/chat-panel-item.vue +695 -0
  158. package/components/wechat-chat-panel/chat-panel.vue +257 -0
  159. package/components/wechat-chat-panel/index.js +3 -0
  160. package/components/wework-chat-control/calling/calling.vue +223 -0
  161. package/components/wework-chat-control/calling/phone-fill.svg +1 -0
  162. package/components/wework-chat-control/calling/vidicon-fill.svg +1 -0
  163. package/components/wework-chat-control/channel-live/channel-live.vue +198 -0
  164. package/components/wework-chat-control/channel-live/quote-icon.svg +1 -0
  165. package/components/wework-chat-control/channel-video/channel-video.vue +180 -0
  166. package/components/wework-chat-control/channel-video/quote-icon.svg +1 -0
  167. package/components/wework-chat-control/company-card/company-card.vue +136 -0
  168. package/components/wework-chat-control/company-card/quote-icon.svg +1 -0
  169. package/components/wework-chat-control/custom-expression/custom-expression.vue +34 -0
  170. package/components/wework-chat-control/empty/empty.vue +27 -0
  171. package/components/wework-chat-control/expression/expression.vue +53 -0
  172. package/components/wework-chat-control/file-url/file-url.vue +247 -0
  173. package/components/wework-chat-control/file-url/icons/file-excel-line.svg +1 -0
  174. package/components/wework-chat-control/file-url/icons/file-info-line.svg +1 -0
  175. package/components/wework-chat-control/file-url/icons/file-music-line.svg +1 -0
  176. package/components/wework-chat-control/file-url/icons/file-pdf-line.svg +1 -0
  177. package/components/wework-chat-control/file-url/icons/file-ppt-line.svg +1 -0
  178. package/components/wework-chat-control/file-url/icons/file-settings-line.svg +1 -0
  179. package/components/wework-chat-control/file-url/icons/file-text-line.svg +1 -0
  180. package/components/wework-chat-control/file-url/icons/file-unknow-line.svg +1 -0
  181. package/components/wework-chat-control/file-url/icons/file-word-line.svg +1 -0
  182. package/components/wework-chat-control/file-url/icons/file-zip-line.svg +1 -0
  183. package/components/wework-chat-control/file-url/icons/index.js +24 -0
  184. package/components/wework-chat-control/image/image.vue +296 -0
  185. package/components/wework-chat-control/image/index.js +1 -0
  186. package/components/wework-chat-control/image/util.js +21 -0
  187. package/components/wework-chat-control/index.js +105 -0
  188. package/components/wework-chat-control/jx-sys-text/jx-sys-text.vue +28 -0
  189. package/components/wework-chat-control/link/link.vue +100 -0
  190. package/components/wework-chat-control/location/location.vue +181 -0
  191. package/components/wework-chat-control/location/offline-bg.png +0 -0
  192. package/components/wework-chat-control/red-envelopes/quote-icon.svg +1 -0
  193. package/components/wework-chat-control/red-envelopes/red-envelope.svg +1 -0
  194. package/components/wework-chat-control/red-envelopes/red-envelopes.vue +168 -0
  195. package/components/wework-chat-control/share-card/quote-icon.svg +1 -0
  196. package/components/wework-chat-control/share-card/share-card.vue +140 -0
  197. package/components/wework-chat-control/text/icons/icon.svg +6 -0
  198. package/components/wework-chat-control/text/text.vue +157 -0
  199. package/components/wework-chat-control/unknow/unknow.vue +21 -0
  200. package/components/wework-chat-control/url/icons/link.svg +1 -0
  201. package/components/wework-chat-control/url/icons/video.svg +6 -0
  202. package/components/wework-chat-control/url/miniprogram.svg +1 -0
  203. package/components/wework-chat-control/url/url-file.vue +37 -0
  204. package/components/wework-chat-control/url/url-link.vue +169 -0
  205. package/components/wework-chat-control/url/url-merge.vue +164 -0
  206. package/components/wework-chat-control/url/url-miniprogram.vue +248 -0
  207. package/components/wework-chat-control/url/url.vue +103 -0
  208. package/components/wework-chat-control/util.js +223 -0
  209. package/components/wework-chat-control/video/icons/video.svg +1 -0
  210. package/components/wework-chat-control/video/video.vue +304 -0
  211. package/components/wework-chat-control/voice/icons/voice.svg +1 -0
  212. package/components/wework-chat-control/voice/voice.vue +464 -0
  213. package/components/wework-chat-panel/chat-panel-controls/company-card/company-card.vue +35 -0
  214. package/components/wework-chat-panel/chat-panel-controls/expression/expression.vue +36 -0
  215. package/components/wework-chat-panel/chat-panel-controls/file-url/file-url.vue +35 -0
  216. package/components/wework-chat-panel/chat-panel-controls/image/image.vue +36 -0
  217. package/components/wework-chat-panel/chat-panel-controls/index.js +35 -0
  218. package/components/wework-chat-panel/chat-panel-controls/jx-sys-text/jx-sys-text.vue +28 -0
  219. package/components/wework-chat-panel/chat-panel-controls/link/link.vue +35 -0
  220. package/components/wework-chat-panel/chat-panel-controls/location/location.vue +35 -0
  221. package/components/wework-chat-panel/chat-panel-controls/text/text.vue +43 -0
  222. package/components/wework-chat-panel/chat-panel-controls/unkonw/unkonw.vue +39 -0
  223. package/components/wework-chat-panel/chat-panel-controls/video/video.vue +37 -0
  224. package/components/wework-chat-panel/chat-panel-controls/voice/voice.vue +35 -0
  225. package/components/wework-chat-panel/chat-panel-item.vue +650 -0
  226. package/components/wework-chat-panel/chat-panel.vue +163 -0
  227. package/components/wework-chat-panel/index.js +3 -0
  228. package/package.json +23 -0
  229. package/services/client-chat/client-chat-wechat/client-chat-account.js +426 -0
  230. package/services/client-chat/client-chat-wechat/client-chat-concats.js +1029 -0
  231. package/services/client-chat/client-chat-wechat/client-chat-draft.js +92 -0
  232. package/services/client-chat/client-chat-wechat/client-chat-message.js +588 -0
  233. package/services/client-chat/client-chat-wechat/client-chat-session-manage.js +67 -0
  234. package/services/client-chat/client-chat-wechat/client-chat-session.js +1048 -0
  235. package/services/client-chat/client-chat-wechat/client-chat-socket.js +215 -0
  236. package/services/client-chat/client-chat-wechat/client-chat.js +1065 -0
  237. package/services/client-chat/client-chat-wechat/index.js +3 -0
  238. package/services/client-chat/client-chat-wechat/utils.js +82 -0
  239. package/services/client-chat/client-chat-wework/client-chat-account.js +310 -0
  240. package/services/client-chat/client-chat-wework/client-chat-concats.js +772 -0
  241. package/services/client-chat/client-chat-wework/client-chat-message.js +278 -0
  242. package/services/client-chat/client-chat-wework/client-chat-session.js +929 -0
  243. package/services/client-chat/client-chat-wework/client-chat-socket.js +64 -0
  244. package/services/client-chat/client-chat-wework/client-chat.js +330 -0
  245. package/services/client-chat/client-chat-wework/index.js +3 -0
  246. package/services/client-chat/client-chat-wework/utils.js +82 -0
  247. package/services/index.js +10 -0
  248. package/services/socket/index.js +5 -0
  249. package/services/socket/socket.js +797 -0
  250. package/services/socket/utils.js +7 -0
  251. package/uni-common/account-portray/account-portray.vue +51 -0
  252. package/uni-common/account-select/account-select-item.vue +172 -0
  253. package/uni-common/account-select/account-select.vue +252 -0
  254. package/uni-common/all-friend-avatar/all-friend-avatar.vue +49 -0
  255. package/uni-common/friend-avatar/default.svg +1 -0
  256. package/uni-common/friend-avatar/friend-avatar.vue +27 -0
  257. package/uni-common/friend-avatar/index.js +3 -0
  258. package/uni-common/friend-loader/friend-loader.vue +53 -0
  259. package/uni-common/friend-portray/friend-portray.vue +56 -0
  260. package/uni-common/group-avatar/default.svg +1 -0
  261. package/uni-common/group-avatar/group-avatar.vue +18 -0
  262. package/uni-common/group-avatar/index.js +3 -0
  263. package/uni-common/room-avatar/default.svg +6 -0
  264. package/uni-common/room-avatar/index.js +3 -0
  265. package/uni-common/room-avatar/room-avatar.vue +27 -0
  266. package/uni-common/room-loader/room-loader.vue +53 -0
  267. package/uni-common/room-portray/room-portray.vue +56 -0
  268. package/uni-components/chat-control/calling/calling.vue +91 -0
  269. package/uni-components/chat-control/calling/phone-fill.svg +1 -0
  270. package/uni-components/chat-control/calling/vidicon-fill.svg +1 -0
  271. package/uni-components/chat-control/channel-video/channel-video.vue +89 -0
  272. package/uni-components/chat-control/channel-video-card/channel-video-card.vue +105 -0
  273. package/uni-components/chat-control/channel-video-live/channel-video-live.vue +92 -0
  274. package/uni-components/chat-control/chat-control-config-item/chat-control-config-item.vue +20 -0
  275. package/uni-components/chat-control/chat-control-config-item/index.js +3 -0
  276. package/uni-components/chat-control/chat-control-config-msg/chat-control-config-msg-app.vue +25 -0
  277. package/uni-components/chat-control/chat-control-config-msg/chat-control-config-msg-h5.vue +21 -0
  278. package/uni-components/chat-control/chat-control-config.vue +59 -0
  279. package/uni-components/chat-control/chat-control.vue +218 -0
  280. package/uni-components/chat-control/company-card/company-card.vue +123 -0
  281. package/uni-components/chat-control/const.js +28 -0
  282. package/uni-components/chat-control/expression/expression.vue +41 -0
  283. package/uni-components/chat-control/image/image.vue +68 -0
  284. package/uni-components/chat-control/index.js +89 -0
  285. package/uni-components/chat-control/location/location.vue +110 -0
  286. package/uni-components/chat-control/member-change/member-change.vue +32 -0
  287. package/uni-components/chat-control/quote-message/quote-message.vue +216 -0
  288. package/uni-components/chat-control/real-time-position/real-time-position.vue +62 -0
  289. package/uni-components/chat-control/redpacket/red-envelope.svg +1 -0
  290. package/uni-components/chat-control/redpacket/redpacket.vue +75 -0
  291. package/uni-components/chat-control/share-card/share-card.vue +101 -0
  292. package/uni-components/chat-control/system/system.vue +69 -0
  293. package/uni-components/chat-control/system-batch-message/system-batch-message.vue +30 -0
  294. package/uni-components/chat-control/system-text/system-text.vue +32 -0
  295. package/uni-components/chat-control/text/text.vue +67 -0
  296. package/uni-components/chat-control/text-with-at/text-with-at.vue +51 -0
  297. package/uni-components/chat-control/transfer/red-transfer.svg +1 -0
  298. package/uni-components/chat-control/transfer/transfer.vue +80 -0
  299. package/uni-components/chat-control/unkonw/unkonw.vue +37 -0
  300. package/uni-components/chat-control/url/icons/file-excel-line.svg +1 -0
  301. package/uni-components/chat-control/url/icons/file-info-line.svg +1 -0
  302. package/uni-components/chat-control/url/icons/file-music-line.svg +1 -0
  303. package/uni-components/chat-control/url/icons/file-pdf-line.svg +1 -0
  304. package/uni-components/chat-control/url/icons/file-ppt-line.svg +1 -0
  305. package/uni-components/chat-control/url/icons/file-settings-line.svg +1 -0
  306. package/uni-components/chat-control/url/icons/file-text-line.svg +1 -0
  307. package/uni-components/chat-control/url/icons/file-unknow-line.svg +1 -0
  308. package/uni-components/chat-control/url/icons/file-word-line.svg +1 -0
  309. package/uni-components/chat-control/url/icons/file-zip-line.svg +1 -0
  310. package/uni-components/chat-control/url/icons/index.js +24 -0
  311. package/uni-components/chat-control/url/miniprogram.svg +1 -0
  312. package/uni-components/chat-control/url/url-miniprogram.vue +116 -0
  313. package/uni-components/chat-control/url/url.vue +306 -0
  314. package/uni-components/chat-control/url-new/icons/file-excel-line.svg +1 -0
  315. package/uni-components/chat-control/url-new/icons/file-info-line.svg +1 -0
  316. package/uni-components/chat-control/url-new/icons/file-music-line.svg +1 -0
  317. package/uni-components/chat-control/url-new/icons/file-pdf-line.svg +1 -0
  318. package/uni-components/chat-control/url-new/icons/file-ppt-line.svg +1 -0
  319. package/uni-components/chat-control/url-new/icons/file-settings-line.svg +1 -0
  320. package/uni-components/chat-control/url-new/icons/file-text-line.svg +1 -0
  321. package/uni-components/chat-control/url-new/icons/file-unknow-line.svg +1 -0
  322. package/uni-components/chat-control/url-new/icons/file-word-line.svg +1 -0
  323. package/uni-components/chat-control/url-new/icons/file-zip-line.svg +1 -0
  324. package/uni-components/chat-control/url-new/icons/index.js +24 -0
  325. package/uni-components/chat-control/url-new/url-new.vue +110 -0
  326. package/uni-components/chat-control/utils.js +12 -0
  327. package/uni-components/chat-control/video/video.vue +156 -0
  328. package/uni-components/chat-control/voice/voice.vue +166 -0
  329. package/uni-components/chat-editor/chat-editor-chartlet/chat-editor-chartlet-collect.vue +84 -0
  330. package/uni-components/chat-editor/chat-editor-chartlet/chat-editor-chartlet-system.vue +28 -0
  331. package/uni-components/chat-editor/chat-editor-chartlet/chat-editor-chartlet.vue +85 -0
  332. package/uni-components/chat-editor/chat-editor-func/chat-editor-func.vue +157 -0
  333. package/uni-components/chat-editor/chat-editor-func-at/chat-editor-func-at-panel.vue +158 -0
  334. package/uni-components/chat-editor/chat-editor-func-at/chat-editor-func-at.vue +61 -0
  335. package/uni-components/chat-editor/chat-editor-func-button/chat-editor-func-button.vue +58 -0
  336. package/uni-components/chat-editor/chat-editor-func-file/chat-editor-func-file.vue +54 -0
  337. package/uni-components/chat-editor/chat-editor-func-image/chat-editor-func-image.vue +42 -0
  338. package/uni-components/chat-editor/chat-editor-func-video/chat-editor-func-video.vue +42 -0
  339. package/uni-components/chat-editor/chat-editor-func-voice/chat-editor-func-voice.vue +25 -0
  340. package/uni-components/chat-editor/chat-editor-message-send/chat-editor-message-send.vue +158 -0
  341. package/uni-components/chat-editor/chat-editor-quote/chat-editor-quote.vue +75 -0
  342. package/uni-components/chat-editor/chat-editor.vue +257 -0
  343. package/uni-components/chat-editor/index.js +10 -0
  344. package/uni-components/chat-editor/util.js +65 -0
  345. package/uni-components/chat-panel/chat-panel-chats-box.vue +238 -0
  346. package/uni-components/chat-panel/chat-panel-chats-forward/chat-panel-chats-forward.vue +273 -0
  347. package/uni-components/chat-panel/chat-panel-chats-item.vue +578 -0
  348. package/uni-components/chat-panel/chat-panel-chats-status/chat-panel-chats-status.vue +71 -0
  349. package/uni-components/chat-panel/chat-panel-chats.vue +368 -0
  350. package/uni-components/chat-panel/chat-panel.vue +227 -0
  351. package/uni-components/contacts-group-select/contacts-group-select-item.vue +85 -0
  352. package/uni-components/contacts-group-select/contacts-group-select-panel.vue +119 -0
  353. package/uni-components/contacts-group-select/contacts-group-select.vue +150 -0
  354. package/utils/color.js +178 -0
  355. package/utils/data.js +11 -0
  356. package/utils/date.js +107 -0
  357. package/utils/event.js +3 -0
  358. package/utils/file.js +26 -0
  359. package/utils/index.js +5 -0
  360. package/utils/json.js +40 -0
  361. package/utils/log.js +243 -0
  362. package/utils/queue.js +97 -0
  363. package/utils/regexp.js +9 -0
  364. package/utils/string.js +66 -0
  365. package/utils/url.js +48 -0
  366. package/utils/util.js +130 -0
@@ -0,0 +1,797 @@
1
+ import Vue from 'vue'
2
+ import { createPromise } from '../../utils/util.js'
3
+ import { firstLetterUpperCase, unique } from '../../utils/string.js'
4
+ import { isUni } from './utils.js'
5
+ import Event from '../../utils/event.js'
6
+ import Log from '../../utils/log'
7
+
8
+ export const CONNECT_STATUS = {
9
+ Ready: -1,
10
+ Close: 0,
11
+ Connecting: 1,
12
+ Success: 2,
13
+ Error: 3
14
+ }
15
+
16
+ export default class Socket {
17
+
18
+ socketAdapter = null
19
+
20
+ reconnectCount = 0
21
+
22
+ maxReconnectCount = 1000 // 最大重连次数
23
+
24
+ reconnectInterval = 1000
25
+
26
+ maxReconnectInterval = 60000
27
+
28
+ data = Vue.observable({
29
+ connectIpChange: false, // 连接设备是否变化,如果变化需要提示用户退出重新登录
30
+ connectMessage: null,
31
+ connectUrl: null,
32
+ connectStatus: CONNECT_STATUS.Ready
33
+ })
34
+
35
+ get connectStatus () {
36
+ return this.data.connectStatus
37
+ }
38
+
39
+ get connectIpChange () {
40
+ return this.data.connectIpChange
41
+ }
42
+
43
+ messageCallbackMap = {}
44
+
45
+ constructor (options) {
46
+ options = Object.assign({
47
+ url: null,
48
+ client: null,
49
+ logEnable: false,
50
+ logName: 'socket',
51
+ logMaxSize: 5 * 1024 * 1024, // 最多记5M日志
52
+ socketAdapter: null, // 支持从外面传一个socket构造函数,但是要实现socket标准的使用方式
53
+ onExceedMaxReconnectLimit: null, // 超过最大重连次数回调
54
+ onBeforeSendMessage: null,
55
+ getLoginUserIdMethod: null,
56
+ getLoginUserTokenMethod: null
57
+ }, options)
58
+ if (!options.client) {
59
+ throw new Error('client不能为空')
60
+ }
61
+ if (!options.getLoginUserTokenMethod) {
62
+ throw new Error('getLoginUserTokenMethod不能为空')
63
+ }
64
+ if (!options.getLoginUserIdMethod) {
65
+ throw new Error('getLoginUserIdMethod不能为空')
66
+ }
67
+ this.socketAdapter = options.socketAdapter
68
+ this.client = options.client
69
+ this.getLoginUserTokenMethod = options.getLoginUserTokenMethod
70
+ this.getLoginUserIdMethod = options.getLoginUserIdMethod
71
+ this.onExceedMaxReconnectLimit = options.onExceedMaxReconnectLimit
72
+ this.onBeforeSendMessage = options.onBeforeSendMessage
73
+ this.logEnable = !!options.logEnable
74
+ this.url = options.url
75
+ this.event = new Event()
76
+ this.log = new Log({
77
+ maxSize: options.logMaxSize, // 最多存5M的日志数据
78
+ name: options.logName || 'socket'
79
+ })
80
+ // 会话失效
81
+ this.event.on('onCmdKickOut', () => {
82
+ this.event.emit('onKickOut')
83
+ this.data.connectIpChange = true
84
+ })
85
+ this.connectPromise = Promise.reject({
86
+ errMsg: 'socket未连接'
87
+ })
88
+ this.readyPromise = Promise.reject({
89
+ errMsg: 'socket未登录'
90
+ })
91
+ // 手动捕获一下,防止控制台总是提示
92
+ this.connectPromise.catch((e) => {})
93
+ this.readyPromise.catch((e) => {})
94
+ }
95
+
96
+ get token () {
97
+ return this.getLoginUserTokenMethod()
98
+ }
99
+
100
+ get accountId () {
101
+ return this.getLoginUserIdMethod()
102
+ }
103
+
104
+ _isCurrentSocket (socket) {
105
+ return !!socket && socket === this._ws
106
+ }
107
+
108
+ _handleReconnectLimitExceeded () {
109
+ const err = new Error('socket重连次数已超过上限')
110
+ clearTimeout(this._reconnectTimer)
111
+ this._isReconnecting = false
112
+ this._reconnectPromise = null
113
+ this._reconnectReject = null
114
+ // this.onExceedMaxReconnectLimit && this.onExceedMaxReconnectLimit(err)
115
+ return err
116
+ }
117
+
118
+ connect () {
119
+ if (!this.url) {
120
+ return Promise.reject('缺少连接地址url配置')
121
+ }
122
+ if (this.connectStatus === CONNECT_STATUS.Connecting || this.connectStatus === CONNECT_STATUS.Success) {
123
+ return Promise.all([
124
+ this.connectPromise,
125
+ this.readyPromise
126
+ ])
127
+ }
128
+ let ps = Promise.resolve()
129
+ // 将上一次连接的socket实例销毁
130
+ if (this.lastConnectPromise) {
131
+ ps = this.lastConnectPromise.then(socket => {
132
+ // 主要是清理一下自定义的socket构造类里面的事件,比如shareworker里面创建的
133
+ socket && socket.destroy && socket.destroy()
134
+ }, () => {})
135
+ this.lastConnectPromise = null
136
+ }
137
+ ps = ps.then(() => {
138
+ this.data.connectIpChange = false
139
+ this.connectPromise = createPromise()
140
+ this.lastConnectPromise = this.connectPromise
141
+ this.readyPromise = createPromise()
142
+ this.data.connectUrl = this.url + `?client=${this.client}&accountId=${this.accountId}&accessToken=${this.token}`
143
+ let socket = null
144
+ this.data.connectStatus = CONNECT_STATUS.Connecting
145
+ this.logEnable && this.log.addLog({
146
+ group: 'socket:connect',
147
+ content: {
148
+ title: '开始连接',
149
+ socketUrl: this.data.connectUrl
150
+ }
151
+ })
152
+ this._ws = null
153
+ if (this.socketAdapter) {
154
+ socket = new this.socketAdapter(this.data.connectUrl)
155
+ this._ws = socket
156
+ socket.onopen = () => {
157
+ if (!this._isCurrentSocket(socket)) {
158
+ return
159
+ }
160
+ // onclose会比onopen先触发,导致connectStatus不正确,会被设置为错误的success状态,下次reconnect的时候判断连接状态出问题了
161
+ // 因为前面状态在connecting,所以可以这么判断一下
162
+ if (this.data.connectStatus === CONNECT_STATUS.Close || this.data.connectStatus === CONNECT_STATUS.Error) {
163
+ this.readyPromise.reject(new Error('socket连接已经关闭或者发生了错误'))
164
+ } else {
165
+ this.data.connectStatus = CONNECT_STATUS.Success
166
+ this.connectPromise.resolve(socket)
167
+ this.handleSocketOpen(() => {
168
+ this.readyPromise.resolve(socket)
169
+ }, (err) => {
170
+ this.readyPromise.reject(err)
171
+ }, socket)
172
+ }
173
+ }
174
+ socket.onmessage = (evt) => {
175
+ this.handleSocketMesssage(evt, socket)
176
+ }
177
+ socket.onclose = (evt) => {
178
+ this.handleSocketClose(evt, socket)
179
+ }
180
+ socket.onerror = (evt) => {
181
+ if (!this._isCurrentSocket(socket)) {
182
+ return
183
+ }
184
+ this.connectPromise.reject(evt)
185
+ this.handleSocketError(evt, socket)
186
+ }
187
+ } else if (isUni()) {
188
+ socket = uni.connectSocket({
189
+ url: this.data.connectUrl,
190
+ method: 'GET',
191
+ complete: () => {},
192
+ fail: (err) => {
193
+ this.data.connectMessage = err
194
+ this.connectPromise.reject(err)
195
+ }
196
+ })
197
+ this._ws = socket
198
+ socket.onOpen((evt) => {
199
+ if (!this._isCurrentSocket(socket)) {
200
+ return
201
+ }
202
+ this.data.connectStatus = CONNECT_STATUS.Success
203
+ this.connectPromise.resolve(socket)
204
+ this.handleSocketOpen(() => {
205
+ this.readyPromise.resolve(socket)
206
+ }, err => {
207
+ this.readyPromise.reject(err)
208
+ }, socket)
209
+ })
210
+ socket.onClose((evt) => {
211
+ this.handleSocketClose(evt, socket)
212
+ })
213
+ socket.onError((err) => {
214
+ if (!this._isCurrentSocket(socket)) {
215
+ return
216
+ }
217
+ this.connectPromise.reject(err)
218
+ this.handleSocketError(err, socket)
219
+ })
220
+ socket.onMessage((evt) => {
221
+ this.handleSocketMesssage(evt, socket)
222
+ })
223
+ } else {
224
+ socket = new WebSocket(this.data.connectUrl)
225
+ this._ws = socket
226
+ socket.onopen = () => {
227
+ if (!this._isCurrentSocket(socket)) {
228
+ return
229
+ }
230
+ this.data.connectStatus = CONNECT_STATUS.Success
231
+ this.connectPromise.resolve(socket)
232
+ this.handleSocketOpen(() => {
233
+ this.readyPromise.resolve(socket)
234
+ }, (err) => {
235
+ this.readyPromise.reject(err)
236
+ }, socket)
237
+ }
238
+ socket.onmessage = (evt) => {
239
+ this.handleSocketMesssage(evt, socket)
240
+ }
241
+ socket.onclose = (evt) => {
242
+ this.handleSocketClose(evt, socket)
243
+ }
244
+ socket.onerror = (evt) => {
245
+ if (!this._isCurrentSocket(socket)) {
246
+ return
247
+ }
248
+ this.connectPromise.reject(evt)
249
+ this.handleSocketError(evt, socket)
250
+ }
251
+ }
252
+ return Promise.all([
253
+ this.connectPromise,
254
+ this.readyPromise
255
+ ])
256
+ })
257
+ return ps
258
+ }
259
+
260
+ handleSocketOpen (successFn, errorFn, socket) {
261
+ if (socket && !this._isCurrentSocket(socket)) {
262
+ return
263
+ }
264
+ let params = {
265
+ cmdType: "CmdSignIn",
266
+ throttle: true, // 开启节流,先请求的先生效,主要是sharedWorker里面放置CmdSignIn在多个页签时多次触发
267
+ throttleTime: 1000 * 5,
268
+ accountId: this.accountId,
269
+ accessToken: this.token,
270
+ client: this.client
271
+ }
272
+ this.logEnable && this.log.addLog({
273
+ group: 'socket:onopen',
274
+ content: {
275
+ title: 'socket连接中'
276
+ }
277
+ })
278
+ this.sendMessage(params).then(() => {
279
+ if (socket && !this._isCurrentSocket(socket)) {
280
+ return
281
+ }
282
+ this.logEnable && this.log.addLog({
283
+ group: 'socket:onopen',
284
+ content: {
285
+ title: 'socket已连接'
286
+ }
287
+ })
288
+ this._startHeartbeat() // 注释掉,因为现在心跳的命令改了,用账号在线状态控制,减少命令发送频率
289
+ successFn && successFn()
290
+ this.event.emit('onOpen')
291
+ }, (err) => {
292
+ if (socket && !this._isCurrentSocket(socket)) {
293
+ return
294
+ }
295
+ errorFn && errorFn(err)
296
+ })
297
+ }
298
+
299
+ handleSocketClose (evt, socket) {
300
+ // closePromise 必须在 _isCurrentSocket 检查之前处理,
301
+ // 避免 handleSocketError 先置空 _ws 导致 closePromise 永远不被 resolve
302
+ if (this.closePromise) {
303
+ this.closePromise.resolve()
304
+ this.closePromise = null
305
+ }
306
+ if (socket && !this._isCurrentSocket(socket)) {
307
+ return
308
+ }
309
+ const prevConnectStatus = this.connectStatus
310
+ this._ws = null
311
+ this.data.connectStatus = CONNECT_STATUS.Close
312
+ this.connectPromise = createPromise()
313
+ this.connectPromise.reject('socket连接已关闭')
314
+ this.connectPromise.catch(e => {})
315
+ // 同时拒绝 readyPromise,确保 connect() 的 Promise.all 能快速失败,触发 scheduleRetry
316
+ if (this.readyPromise && typeof this.readyPromise.reject === 'function') {
317
+ this.readyPromise.reject(new Error('socket连接关闭'))
318
+ }
319
+ this.logEnable && this.log.addLog({
320
+ group: 'socket:onclose',
321
+ content: {
322
+ title: 'socket连接关闭',
323
+ code: evt.code,
324
+ reason: evt.reason,
325
+ }
326
+ })
327
+ if (!evt.reason || evt.reason.indexOf('(手动关闭)') < 0) {
328
+ if (prevConnectStatus === CONNECT_STATUS.Connecting) {
329
+ return
330
+ }
331
+ this.reconnect()
332
+ }
333
+ this.event.emit('onClose', {
334
+ code: evt.code,
335
+ reason: evt.reason
336
+ })
337
+ }
338
+
339
+ handleSocketError (evt, socket) {
340
+ if (socket && !this._isCurrentSocket(socket)) {
341
+ return
342
+ }
343
+ console.log(evt, 'WSERR');
344
+ this.logEnable && this.log.addLog({
345
+ group: 'socket:onclose',
346
+ content: {
347
+ title: 'socket连接失败'
348
+ }
349
+ })
350
+ this.data.connectStatus = CONNECT_STATUS.Error
351
+ this.connectPromise = createPromise()
352
+ this.connectPromise.reject('socket连接错误')
353
+ this.connectPromise.catch(e => {})
354
+ // 同时拒绝 readyPromise,确保 connect() 的 Promise.all 能快速失败
355
+ if (this.readyPromise && typeof this.readyPromise.reject === 'function') {
356
+ this.readyPromise.reject(new Error('socket连接错误'))
357
+ }
358
+ this.reconnect()
359
+ }
360
+
361
+ mockSocketMessage (evt) {
362
+ this.handleSocketMesssage(evt)
363
+ }
364
+
365
+ handleSocketMesssage (evt, socket) {
366
+ if (socket && !this._isCurrentSocket(socket)) {
367
+ return
368
+ }
369
+ const messageData = typeof evt.data === 'string' ? JSON.parse(evt.data) : evt.data
370
+ if (!messageData) {
371
+ return
372
+ }
373
+ if (this.messageCallbackMap[messageData.seq]) {
374
+ if (messageData.code === -1) {
375
+ this.messageCallbackMap[messageData.seq].reject({
376
+ errMsg: messageData.extra
377
+ })
378
+ } else {
379
+ this.messageCallbackMap[messageData.seq].resolve({
380
+ data: messageData.extra
381
+ })
382
+ }
383
+ }
384
+ this.logEnable && this.log.addLog({
385
+ group: 'socket:receiveMessage',
386
+ content: {
387
+ title: '收到消息',
388
+ message: messageData
389
+ }
390
+ })
391
+ this.event.emit('onReceiveMessage', {
392
+ data: messageData
393
+ })
394
+ // if (messageData && messageData.extra === 'pong') {
395
+ // this._heartbeatCheck && this._heartbeatCheck.resolve()
396
+ // return
397
+ // }
398
+ if (messageData.cmdType) {
399
+ const callbackName = 'on' + firstLetterUpperCase(messageData.cmdType)
400
+ this.event.emit(callbackName, {
401
+ data: messageData
402
+ })
403
+ this.callMessage({
404
+ cmdType: 'CommandResponse',
405
+ seq: messageData.seq,
406
+ result: 0,
407
+ extra: ''
408
+ })
409
+ }
410
+ }
411
+
412
+ reconnect () {
413
+ // 防止并发重连调用(handleSocketError 和 handleSocketClose 都可能触发 reconnect)
414
+ if (this._isReconnecting) {
415
+ return this._reconnectPromise || Promise.resolve()
416
+ }
417
+ this._isReconnecting = true
418
+
419
+ this._reconnectPromise = this.close({
420
+ code: 1000,
421
+ reason: '重连关闭连接'
422
+ }).finally(() => {
423
+ return new Promise((resolve, reject) => {
424
+ this._reconnectReject = reject
425
+ this.reconnectCount++
426
+ if (this.maxReconnectCount > 0 && this.reconnectCount > this.maxReconnectCount) {
427
+ reject(this._handleReconnectLimitExceeded())
428
+ return
429
+ }
430
+ const onConnectSuccess = () => {
431
+ this.reconnectInterval = 1000
432
+ this.reconnectCount = 0
433
+ this._isReconnecting = false
434
+ this._reconnectReject = null
435
+ this._reconnectPromise = null
436
+ resolve()
437
+ }
438
+ const scheduleRetry = () => {
439
+ if (this.maxReconnectCount > 0 && this.reconnectCount >= this.maxReconnectCount) {
440
+ reject(this._handleReconnectLimitExceeded())
441
+ return
442
+ }
443
+ // 指数退避 + 随机抖动
444
+ const jitter = Math.random() * 500 * 2 - 500
445
+ const actualInterval = Math.min(this.reconnectInterval + jitter, this.maxReconnectInterval)
446
+ // 先翻倍再等待,避免定时器被取消导致倍数丢失
447
+ this.reconnectInterval = Math.min(this.reconnectInterval * 2, this.maxReconnectInterval)
448
+ clearTimeout(this._reconnectTimer)
449
+ this._reconnectTimer = setTimeout(() => {
450
+ this.reconnectCount++
451
+ this.connect().then(onConnectSuccess, scheduleRetry)
452
+ }, actualInterval)
453
+ }
454
+ // 第一次的时候不延时,主要是外面发消息的时候手动重连,需要能加连接中的状态串起来,否则发送的消息直接失败
455
+ if (this.reconnectCount === 1) {
456
+ this.connect().then(onConnectSuccess, scheduleRetry)
457
+ } else {
458
+ scheduleRetry()
459
+ }
460
+ })
461
+ })
462
+
463
+ return this._reconnectPromise
464
+ }
465
+
466
+ /**
467
+ * 告诉服务器接收到了消息,没有callback回调逻辑
468
+ */
469
+ callMessage (message) {
470
+ const nextMessage = Object.assign({}, message)
471
+ if (!nextMessage.cmdType) {
472
+ throw new Error('发送消息缺少cmdType参数')
473
+ }
474
+ const messagePromise = createPromise()
475
+ if (isUni()) {
476
+ this.connectPromise.then(socket => {
477
+ socket.send({
478
+ data: JSON.stringify(nextMessage),
479
+ success: () => {
480
+ messagePromise.resolve()
481
+ },
482
+ fail: (err) => {
483
+ messagePromise.reject(err)
484
+ }
485
+ })
486
+ })
487
+ } else {
488
+ this.connectPromise.then(socket => {
489
+ try {
490
+ socket.send(JSON.stringify(nextMessage))
491
+ messagePromise.resolve()
492
+ } catch (err) {
493
+ messagePromise.reject(err)
494
+ }
495
+ })
496
+ }
497
+ return messagePromise
498
+ }
499
+
500
+ /**
501
+ * 向服务器会传消息,服务器不会返回回调消息,客户端发送消息-》服务端-》告诉客户端状态
502
+ */
503
+ sendMessage (message, beforeCallback) {
504
+ this.logEnable && this.log.addLog({
505
+ group: 'socket:sendMessage',
506
+ content: {
507
+ title: '发送消息',
508
+ message
509
+ }
510
+ })
511
+ const nextMessage = Object.assign({
512
+ seq: unique()
513
+ }, message)
514
+ if (!nextMessage.seq) {
515
+ throw new Error('发送消息缺少seq参数')
516
+ }
517
+ const messageId = nextMessage.seq
518
+ if (!nextMessage.cmdType) {
519
+ throw new Error('发送消息缺少cmdType参数')
520
+ }
521
+ const messagePromise = createPromise()
522
+ let ps = Promise.resolve()
523
+ if (this.onBeforeSendMessage) {
524
+ const rs = this.onBeforeSendMessage({
525
+ message
526
+ })
527
+ if (rs && rs.then) {
528
+ ps = rs
529
+ }
530
+ }
531
+ ps = ps.then(() => {
532
+ if (beforeCallback) {
533
+ // 主要是给client-chat-wechat新增临时消息时处理
534
+ return beforeCallback({
535
+ message
536
+ })
537
+ }
538
+ })
539
+ ps.then(() => {
540
+ let callback = null
541
+ const onCallback = (fn) => {
542
+ if (callback) {
543
+ throw new Error('[Socket]不允许重复设置callback')
544
+ }
545
+ callback = fn
546
+ }
547
+ this.event.emit('onSendMessage', {
548
+ data: nextMessage,
549
+ onCallback
550
+ })
551
+ const messageObject = {
552
+ messageId,
553
+ message: nextMessage,
554
+ resolve: (data) => {
555
+ messagePromise.resolve(data)
556
+ messageObject.destroy()
557
+ callback && callback({
558
+ data
559
+ })
560
+ },
561
+ reject: (err) => {
562
+ messagePromise.reject(err)
563
+ messageObject.destroy()
564
+ callback && callback({
565
+ error: err
566
+ })
567
+ },
568
+ destroy: () => {
569
+ clearTimeout(messageObject._timeoutId)
570
+ delete this.messageCallbackMap[messageId]
571
+ },
572
+ _timeoutId: setTimeout(() => {
573
+ messageObject.reject('timeout')
574
+ }, 1000 * 30) // 30s认为超时
575
+ }
576
+ this.messageCallbackMap[messageId] = messageObject
577
+ if (isUni()) {
578
+ this.connectPromise.then(socket => {
579
+ socket.send({
580
+ data: JSON.stringify(nextMessage),
581
+ fail: (err) => {
582
+ messagePromise.reject(err)
583
+ }
584
+ })
585
+ }, err => {
586
+ messagePromise.reject(err)
587
+ })
588
+ } else {
589
+ this.connectPromise.then(socket => {
590
+ try {
591
+ socket.send(JSON.stringify(nextMessage))
592
+ } catch (err) {
593
+ messagePromise.reject(err)
594
+ }
595
+ }, err => {
596
+ messagePromise.reject(err)
597
+ })
598
+ }
599
+ }, messagePromise.reject)
600
+ return messagePromise
601
+ }
602
+
603
+ close (options) {
604
+ options = Object.assign({
605
+ code: null,
606
+ reason: null
607
+ }, options)
608
+ if (this._heartbeatCheck) {
609
+ this._heartbeatCheck.destroy()
610
+ }
611
+ if (this.connectStatus === CONNECT_STATUS.Close || this.connectStatus === CONNECT_STATUS.Ready) {
612
+ return Promise.resolve()
613
+ }
614
+ if (!options.reason) {
615
+ options.reason = ''
616
+ }
617
+ options.reason = options.reason + '(手动关闭)' // 加一个手动关闭,后面close事件中判断一下,如果是手动关闭的不需要重连,如果是服务器关闭的,就需要重连,因为后端不知道为什么会主动关闭
618
+ // 直接使用 _ws 引用关闭 socket,避免 connectPromise 被替换后无法关闭旧连接
619
+ const socket = this._ws
620
+ if (!socket) {
621
+ this.data.connectStatus = CONNECT_STATUS.Close
622
+ return Promise.resolve()
623
+ }
624
+ return new Promise((resolve, reject) => {
625
+ if (isUni()) {
626
+ socket.close({
627
+ reason: options.reason,
628
+ code: options.code,
629
+ success: () => {
630
+ this.connectPromise = Promise.reject({
631
+ errMsg: 'socket已关闭'
632
+ })
633
+ this.data.connectStatus = CONNECT_STATUS.Close
634
+ resolve()
635
+ },
636
+ fail: (err) => {
637
+ reject(err)
638
+ }
639
+ })
640
+ } else {
641
+ this.closePromise = createPromise()
642
+ socket.close(options.code, options.reason)
643
+ this.closePromise.then(resolve, reject)
644
+ }
645
+ })
646
+ }
647
+
648
+ disconnect () {
649
+ this.data.connectIpChange = false
650
+ for (let i in this.messageCallbackMap) {
651
+ this.messageCallbackMap[i].destroy()
652
+ }
653
+ this.reconnectInterval = 1000
654
+ this.reconnectCount = 0
655
+ this._isReconnecting = false
656
+ clearTimeout(this._reconnectTimer)
657
+ if (this._reconnectReject) {
658
+ this._reconnectPromise && this._reconnectPromise.catch(() => {})
659
+ this._reconnectReject(new Error('disconnect取消重连'))
660
+ this._reconnectReject = null
661
+ this._reconnectPromise = null
662
+ }
663
+ return this.close({
664
+ code: 1000,
665
+ reason: '断开连接'
666
+ })
667
+ }
668
+
669
+ setUrl (url) {
670
+ this.url = url || ''
671
+ }
672
+
673
+ /**
674
+ * 手动触发一次心跳逻辑,主要是要快速检查微信号在线状态
675
+ */
676
+ doHeartbeat () {
677
+ this.readyPromise.then(() => {
678
+ this._startHeartbeat()
679
+ })
680
+ }
681
+
682
+ _startHeartbeat () {
683
+ this._heartbeatCheck && this._heartbeatCheck.destroy()
684
+ this._createHeartbeatCheck({
685
+ onDisconnect: () => {
686
+ // 心跳超时,就重连
687
+ console.log('心跳超时,开始重连')
688
+ this.reconnect()
689
+ }
690
+ })
691
+ }
692
+ _createHeartbeatCheck (options) {
693
+ // 合并配置,默认25s心跳(后端好像是30s,增加一些容差,防止因为网路或者其他原因导致断开连接了),5次熔断
694
+ options = Object.assign({
695
+ spanTime: 1000 * 25,
696
+ fusingNum: 5,
697
+ onDisconnect: null
698
+ }, options)
699
+
700
+ let rejectNum = 0
701
+ let intervalTimer = null // 改用setInterval,统一管理定时器
702
+ let isStop = false
703
+ let lastHeartbeatTime = Date.now() // 记录上次心跳发送时间,精准计时
704
+
705
+ // 检查熔断逻辑(抽离,便于复用)
706
+ const checkFusing = () => {
707
+ if (rejectNum > options.fusingNum) {
708
+ isStop = true
709
+ clearInterval(intervalTimer) // 停止定时器
710
+ options.onDisconnect && options.onDisconnect()
711
+ console.error(`连续${rejectNum}次心跳无响应,触发断开连接`)
712
+ }
713
+ }
714
+ // 核心:发送心跳的方法(抽离成独立函数,便于复用)
715
+ const sendCmdPing = (isFirst) => {
716
+ if (isStop) {
717
+ return
718
+ }
719
+ // 连接未成功,直接返回
720
+ if (this.connectStatus !== CONNECT_STATUS.Success) {
721
+ console.warn('WebSocket未连接成功,跳过本次心跳')
722
+ return
723
+ }
724
+ const params = {}
725
+ // 触发参数合并事件
726
+ this.event.emit('onHeartbeatCheck', {
727
+ mergeParams (nextParams) {
728
+ Object.assign(params, nextParams)
729
+ }
730
+ })
731
+ // 发送心跳消息(完善catch异常捕获)
732
+ this.sendMessage(Object.assign({
733
+ wechatAccountIds: []
734
+ }, params, {
735
+ throttle: isFirst ? false : true, // 判断isFrist是因为shareworker里面会进行节流处理导致获取在线的微信号太慢了,所以第一次的时候不做节流,后面在开启节流,先请求的先生效,主要是sharedWorker里面放置CmdRequestWechatAccountsAliveStatus在多个页签时多次触发
736
+ throttleTime: options.spanTime,
737
+ cmdType: 'CmdRequestWechatAccountsAliveStatus'
738
+ })).then((evt) => {
739
+ // 心跳成功:重置计数 + 更新上次心跳时间
740
+ this.event.emit('onHeartbeatSuccess', evt)
741
+ rejectNum = 0
742
+ lastHeartbeatTime = Date.now() // 关键:更新成功时间
743
+ console.log(`心跳成功,重置熔断计数`)
744
+ }).catch((err) => {
745
+ // 心跳发送失败:累加计数,避免静默中断
746
+ console.error(`心跳发送失败:`, err)
747
+ ++rejectNum
748
+ checkFusing() // 立即检查是否熔断
749
+ })
750
+ }
751
+
752
+ // 心跳定时触发逻辑(核心:固定间隔检查,精准计时)
753
+ const heartbeatLoop = () => {
754
+ if (isStop) {
755
+ return
756
+ }
757
+ const now = Date.now()
758
+ // 计算实际间隔:当前时间 - 上次心跳时间
759
+ const actualSpan = now - lastHeartbeatTime
760
+ // 仅当实际间隔≥设定间隔时,才发送心跳(避免浏览器降频导致重复发送)
761
+ if (actualSpan >= options.spanTime - 1000) { // 预留1s误差
762
+ sendCmdPing(false) // 非首次,开启节流
763
+ // 发送后立即更新上次心跳时间(避免重复触发)
764
+ lastHeartbeatTime = Date.now()
765
+ }
766
+ // 检查熔断(无论是否发送心跳,都要检查)
767
+ checkFusing()
768
+ }
769
+ // 初始化:首次发送心跳(无节流)
770
+ sendCmdPing(true)
771
+ // 启动固定间隔定时器(1s检查一次,避免降频影响)
772
+ intervalTimer = setInterval(heartbeatLoop, 1000)
773
+
774
+ // 暴露销毁和重置方法(完善定时器清理)
775
+ this._heartbeatCheck = {
776
+ resolve: () => {
777
+ rejectNum = 0
778
+ lastHeartbeatTime = Date.now() // 重置计时
779
+ },
780
+ destroy: () => {
781
+ isStop = true
782
+ clearInterval(intervalTimer) // 清理interval
783
+ intervalTimer = null
784
+ this._heartbeatCheck = null
785
+ console.log('心跳检测已销毁')
786
+ }
787
+ }
788
+ }
789
+
790
+ exportLogData () {
791
+ return this.log.exportLogData()
792
+ }
793
+
794
+ clearLogData () {
795
+ return this.log.clearLogData()
796
+ }
797
+ }