@aochuang/client-sdk 1.0.367 → 1.0.369
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.
- package/package.json +1 -1
- package/services/client-chat/client-chat-wechat/client-chat-account.js +57 -14
- package/services/client-chat/client-chat-wechat/client-chat-session.js +23 -4
- package/services/client-chat/client-chat-wechat/client-chat-socket.js +5 -1
- package/services/client-chat/client-chat-wechat/client-chat.js +108 -56
- package/services/client-chat/client-chat-wechat/docs//350/264/246/345/217/267/346/234/252/350/257/273/346/225/260/351/207/217/344/270/216/344/274/232/350/257/235/346/234/252/350/257/273/346/225/260/351/207/217/344/270/215/344/270/200/350/207/264/351/227/256/351/242/230/344/277/256/345/244/215.md +296 -0
- package/services/socket/socket.js +9 -5
- package/utils/log.js +579 -220
package/package.json
CHANGED
|
@@ -30,7 +30,8 @@ export default class ClientChatAccount {
|
|
|
30
30
|
onAccountRemoved: null,
|
|
31
31
|
onUnreadMessageNumChange: null,
|
|
32
32
|
onDeleteAccountSession: null,
|
|
33
|
-
onAccountLoaded: null
|
|
33
|
+
onAccountLoaded: null,
|
|
34
|
+
onUnreadMessageNumLog: null
|
|
34
35
|
}, options)
|
|
35
36
|
if (!options.loadAccountDataMethod) {
|
|
36
37
|
throw new Error('缺少loadAccountDataMethod配置')
|
|
@@ -51,6 +52,19 @@ export default class ClientChatAccount {
|
|
|
51
52
|
this.onUnreadMessageNumChange = options.onUnreadMessageNumChange
|
|
52
53
|
this.onDeleteAccountSession = options.onDeleteAccountSession
|
|
53
54
|
this.onAccountLoaded = options.onAccountLoaded
|
|
55
|
+
this.onUnreadMessageNumLog = options.onUnreadMessageNumLog
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
_addUnreadMessageNumLog (title, data) {
|
|
59
|
+
if (this.onUnreadMessageNumLog) {
|
|
60
|
+
this.onUnreadMessageNumLog({
|
|
61
|
+
group: 'client-chat-account:unreadMessageNum',
|
|
62
|
+
content: {
|
|
63
|
+
title,
|
|
64
|
+
data
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
54
68
|
}
|
|
55
69
|
|
|
56
70
|
get accountData () {
|
|
@@ -198,6 +212,10 @@ export default class ClientChatAccount {
|
|
|
198
212
|
})
|
|
199
213
|
}
|
|
200
214
|
this.data.accountUnreadMessageNumData = nextData
|
|
215
|
+
this._addUnreadMessageNumLog('服务端全量刷新账号未读数量', {
|
|
216
|
+
source: 'refreshAll',
|
|
217
|
+
accounts: nextData
|
|
218
|
+
})
|
|
201
219
|
})
|
|
202
220
|
}
|
|
203
221
|
|
|
@@ -216,23 +234,33 @@ export default class ClientChatAccount {
|
|
|
216
234
|
return true
|
|
217
235
|
}
|
|
218
236
|
})
|
|
237
|
+
const before = index >= 0 ? this.data.accountUnreadMessageNumData[index] : null
|
|
238
|
+
const after = {
|
|
239
|
+
id: wechatAccountId,
|
|
240
|
+
num: rs.data[0].unread || 0,
|
|
241
|
+
muteNum: rs.data[0].muteUnread || 0
|
|
242
|
+
}
|
|
219
243
|
if (index >= 0) {
|
|
220
|
-
this.data.accountUnreadMessageNumData.splice(index, 1,
|
|
221
|
-
id: wechatAccountId,
|
|
222
|
-
num: rs.data[0].unread || 0,
|
|
223
|
-
muteNum: rs.data[0].muteUnread || 0
|
|
224
|
-
})
|
|
244
|
+
this.data.accountUnreadMessageNumData.splice(index, 1, after)
|
|
225
245
|
} else {
|
|
226
|
-
this.data.accountUnreadMessageNumData.push(
|
|
227
|
-
id: wechatAccountId,
|
|
228
|
-
num: rs.data[0].unread || 0,
|
|
229
|
-
muteNum: rs.data[0].muteUnread || 0
|
|
230
|
-
})
|
|
246
|
+
this.data.accountUnreadMessageNumData.push(after)
|
|
231
247
|
}
|
|
248
|
+
this._addUnreadMessageNumLog('服务端刷新账号未读数量', {
|
|
249
|
+
source: 'refresh',
|
|
250
|
+
wechatAccountId,
|
|
251
|
+
before: before ? { num: before.num, muteNum: before.muteNum } : null,
|
|
252
|
+
after: { num: after.num, muteNum: after.muteNum }
|
|
253
|
+
})
|
|
232
254
|
})
|
|
233
255
|
}
|
|
234
256
|
|
|
235
|
-
|
|
257
|
+
/**
|
|
258
|
+
* 本地增量更新账号未读数量
|
|
259
|
+
* @param { String } accountId
|
|
260
|
+
* @param { Function } callback 返回 { num, muteNum }
|
|
261
|
+
* @param { String } source 调用来源标记,仅用于日志排查
|
|
262
|
+
*/
|
|
263
|
+
updateAccountUnreadMessageNum (accountId, callback, source) {
|
|
236
264
|
return this.getAccount(accountId).then(rs => {
|
|
237
265
|
if (!rs || !rs.data) {
|
|
238
266
|
console.warn('未找到' + accountId + '工作微信号')
|
|
@@ -248,11 +276,26 @@ export default class ClientChatAccount {
|
|
|
248
276
|
return true
|
|
249
277
|
}
|
|
250
278
|
})
|
|
279
|
+
const beforeNum = unreadMessageNumIndex >= 0 ? this.data.accountUnreadMessageNumData[unreadMessageNumIndex].num : 0
|
|
280
|
+
const beforeMuteNum = unreadMessageNumIndex >= 0 ? this.data.accountUnreadMessageNumData[unreadMessageNumIndex].muteNum : 0
|
|
251
281
|
const nextReadMessageNum = callback({
|
|
252
282
|
account: rs.data,
|
|
253
|
-
unreadMesasgeNum:
|
|
254
|
-
unreadMessageMuteNum:
|
|
283
|
+
unreadMesasgeNum: beforeNum,
|
|
284
|
+
unreadMessageMuteNum: beforeMuteNum
|
|
255
285
|
})
|
|
286
|
+
if (this.onUnreadMessageNumLog && nextReadMessageNum !== undefined && nextReadMessageNum !== null) {
|
|
287
|
+
const afterNum = typeof nextReadMessageNum === 'object' ? nextReadMessageNum.num : nextReadMessageNum
|
|
288
|
+
const afterMuteNum = typeof nextReadMessageNum === 'object' ? nextReadMessageNum.muteNum : beforeMuteNum
|
|
289
|
+
if (afterNum !== beforeNum || afterMuteNum !== beforeMuteNum) {
|
|
290
|
+
this._addUnreadMessageNumLog('本地增量更新账号未读数量', {
|
|
291
|
+
source: source || 'unknown',
|
|
292
|
+
wechatAccountId: accountId,
|
|
293
|
+
before: { num: beforeNum, muteNum: beforeMuteNum },
|
|
294
|
+
after: { num: afterNum, muteNum: afterMuteNum },
|
|
295
|
+
delta: { num: (afterNum || 0) - (beforeNum || 0), muteNum: (afterMuteNum || 0) - (beforeMuteNum || 0) }
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
}
|
|
256
299
|
if (nextReadMessageNum && typeof nextReadMessageNum === 'object') {
|
|
257
300
|
/**
|
|
258
301
|
* {
|
|
@@ -311,11 +311,22 @@ export default class ClientChatSession {
|
|
|
311
311
|
if (!rs.data) {
|
|
312
312
|
return Promise.reject('未找到会话' + sessionId)
|
|
313
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* 轮询合并上下文,会依次传给每个 serializeMethod(见 client-chat.js onCmdNewMessage 里 getSession 的回调)
|
|
316
|
+
* baseLastMsgTime 服务端返回的会话 lastMsgTime,用来判断某条消息服务端是否已经算进 unreadMsgCount
|
|
317
|
+
* processedMessageIds 本次轮询期间处理过的所有消息 id
|
|
318
|
+
* skippedMessageIds 服务端返回的会话已经包含(wechatTime <= baseLastMsgTime)、本地不再给会话未读 +1 的消息 id
|
|
319
|
+
* unreadMessageIds 本地给会话未读 +1 的消息 id
|
|
320
|
+
* accountUnreadDelta 本次轮询期间需要累加到工作微信号(账号)未读数量上的条数。
|
|
321
|
+
* 注意它和 unreadMessageIds.length 不同:账号未读初始值是登录时取的,不包含本次收到的任何消息,
|
|
322
|
+
* 所以被 skip 的消息也要算进来;只有"正在看当前会话被直接标记已读"的消息不算
|
|
323
|
+
*/
|
|
314
324
|
const context = {
|
|
315
325
|
baseLastMsgTime: rs.data.lastMsgTime || 0,
|
|
316
326
|
processedMessageIds: [],
|
|
317
327
|
skippedMessageIds: [],
|
|
318
|
-
unreadMessageIds: []
|
|
328
|
+
unreadMessageIds: [],
|
|
329
|
+
accountUnreadDelta: 0
|
|
319
330
|
}
|
|
320
331
|
const serializeTasks = pollRequest.serializeTasks.slice().sort((a, b) => {
|
|
321
332
|
return a.wechatTime - b.wechatTime || a.index - b.index
|
|
@@ -326,7 +337,11 @@ export default class ClientChatSession {
|
|
|
326
337
|
context.processedMessageIds.push(task.messageId)
|
|
327
338
|
}
|
|
328
339
|
})
|
|
329
|
-
|
|
340
|
+
// wechatAccountId 传 null 表示非分页来源,onAddSession 会把未读同步到账号;
|
|
341
|
+
// 同时带上 unreadDelta,让账号只累加本次新增的条数,而不是服务端返回的整个 unreadMsgCount(那里面的存量部分账号初始值已经包含了)
|
|
342
|
+
this.addSession(rs.data, null, {
|
|
343
|
+
unreadDelta: context.accountUnreadDelta
|
|
344
|
+
})
|
|
330
345
|
const wechatAccountId = rs.data.wechatAccountId
|
|
331
346
|
this._addGetSessionLog('会话轮询合并完成', {
|
|
332
347
|
sessionId,
|
|
@@ -341,6 +356,7 @@ export default class ClientChatSession {
|
|
|
341
356
|
processedMessageCount: context.processedMessageIds.length,
|
|
342
357
|
skippedMessageCount: context.skippedMessageIds.length,
|
|
343
358
|
unreadMessageCount: context.unreadMessageIds.length,
|
|
359
|
+
accountUnreadDelta: context.accountUnreadDelta,
|
|
344
360
|
hasSessionMap: !!this.sessionMap[sessionId],
|
|
345
361
|
hasAllSessionGroup: !!this._getSessionBySessionGroup(sessionId, ALL_WECHAT_ACCOUNT_ID),
|
|
346
362
|
hasAccountSessionGroup: !!this._getSessionBySessionGroup(sessionId, wechatAccountId)
|
|
@@ -486,8 +502,10 @@ export default class ClientChatSession {
|
|
|
486
502
|
* "unreadMsgCount": 3,
|
|
487
503
|
* "wechatAccountId": "2a39a725814acf07502299ab2285fff8d44377f5"
|
|
488
504
|
* }
|
|
505
|
+
* @params { Object } - options
|
|
506
|
+
* @params { Number } - options.unreadDelta 本次新增的未读条数,新消息触发getSession拉回会话时传入,用于账号未读数量只累加新增部分而不是整个unreadMsgCount
|
|
489
507
|
*/
|
|
490
|
-
addSession (data, wechatAccountId) {
|
|
508
|
+
addSession (data, wechatAccountId, options = {}) {
|
|
491
509
|
if (!data || !data.conversationId) {
|
|
492
510
|
throw new Error('缺少必须参数conversationId')
|
|
493
511
|
}
|
|
@@ -591,7 +609,8 @@ export default class ClientChatSession {
|
|
|
591
609
|
}
|
|
592
610
|
this.onAddSession && this.onAddSession({
|
|
593
611
|
wechatAccountId,
|
|
594
|
-
session: nextData
|
|
612
|
+
session: nextData,
|
|
613
|
+
unreadDelta: options.unreadDelta
|
|
595
614
|
})
|
|
596
615
|
}
|
|
597
616
|
|
|
@@ -228,8 +228,12 @@ export default class Websocket {
|
|
|
228
228
|
exportLogData () {
|
|
229
229
|
return this.socket.exportLogData()
|
|
230
230
|
}
|
|
231
|
+
|
|
232
|
+
checkAndSync () {
|
|
233
|
+
return this.socket.checkAndSync()
|
|
234
|
+
}
|
|
231
235
|
|
|
232
236
|
clearLogData () {
|
|
233
237
|
return this.socket.clearLogData()
|
|
234
238
|
}
|
|
235
|
-
}
|
|
239
|
+
}
|
|
@@ -115,23 +115,42 @@ class ClientChat {
|
|
|
115
115
|
const mergeSessionCommonOptions = (options, instance) => {
|
|
116
116
|
let updateSessioning = false
|
|
117
117
|
let removeSessioning = false
|
|
118
|
-
|
|
118
|
+
/**
|
|
119
|
+
* 会话新增回调,负责把新增会话的未读数量同步到工作微信号(账号)的未读数量上
|
|
120
|
+
* @param { Object } session - 新增的会话
|
|
121
|
+
* @param { String } wechatAccountId - 有值代表是分页加载(loadData/reload)来的会话,账号未读初始值已经包含,不累加
|
|
122
|
+
* @param { Number } unreadDelta - 本次真正新增的未读条数,只有新消息触发 getSession 拉回会话时才会传(见 client-chat-session.js getSession)
|
|
123
|
+
*
|
|
124
|
+
* 账号未读数量的初始值来自登录时的 getAccountUnreadMessageNumMethod,是服务端按该账号"所有会话"算的,
|
|
125
|
+
* 不管本地有没有分页加载到这些会话。所以非分页来源的会话要区分两种情况:
|
|
126
|
+
* 1. 分配过来的会话(loadAssignTaskSessionData):之前不属于这个账号,账号初始值里没有它,
|
|
127
|
+
* 需要把整个 session.unreadMsgCount 累加上去。此时 unreadDelta 为 undefined。
|
|
128
|
+
* 2. 新消息触发 getSession 拉回来的会话:一直属于这个账号,只是本地没翻页加载到,它的存量未读已经在账号初始值里了,
|
|
129
|
+
* 如果再把整个 unreadMsgCount 加上去就会重复计算存量部分(这就是"会话都已读了但账号还有未读数、刷新后归零"的主因)。
|
|
130
|
+
* 这种情况只能累加本次轮询期间新增的条数,即 unreadDelta。
|
|
131
|
+
*/
|
|
132
|
+
options.onAddSession = ({ session, wechatAccountId, unreadDelta }) => {
|
|
119
133
|
// 不是来源于分页的时候,没有wechatAccountId就是代表不是走的分页增加的会话,一般为获取新消息或则分配的会话
|
|
120
134
|
if (!wechatAccountId && instance === this.session) {
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
// unreadDelta 是数字 → getSession 来源,只加新增;否则 → 分配等来源,整个 unreadMsgCount 加上
|
|
136
|
+
const delta = typeof unreadDelta === 'number' ? unreadDelta : (session.unreadMsgCount || 0)
|
|
137
|
+
// delta 为 0 时不更新,避免产生无意义的账号未读更新和日志
|
|
138
|
+
if (delta > 0) {
|
|
139
|
+
// 更新账号未读消息数量
|
|
140
|
+
this.account.updateAccountUnreadMessageNum(session.wechatAccountId, ({ unreadMesasgeNum, unreadMessageMuteNum }) => {
|
|
141
|
+
if (session.mute) {
|
|
142
|
+
return {
|
|
143
|
+
num: (unreadMesasgeNum || 0) + delta,
|
|
144
|
+
muteNum: (unreadMessageMuteNum || 0) + delta
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
return {
|
|
148
|
+
num: (unreadMesasgeNum || 0) + delta,
|
|
149
|
+
muteNum: unreadMessageMuteNum
|
|
150
|
+
}
|
|
132
151
|
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
152
|
+
}, typeof unreadDelta === 'number' ? 'onAddSession:getSession' : 'onAddSession')
|
|
153
|
+
}
|
|
135
154
|
}
|
|
136
155
|
// 同步未读会话
|
|
137
156
|
if (instance !== this.sessionUnread && session.unreadMsgCount > 0) {
|
|
@@ -231,7 +250,7 @@ class ClientChat {
|
|
|
231
250
|
muteNum: unreadMessageMuteNum
|
|
232
251
|
}
|
|
233
252
|
}
|
|
234
|
-
})
|
|
253
|
+
}, 'onRemoveSession')
|
|
235
254
|
// 删除会话会同步删除所有的实例,所以需要做这个检查
|
|
236
255
|
if (this.sessionManage.currentSession && this.sessionManage.currentSession.conversationId === session.conversationId) {
|
|
237
256
|
this.sessionManage.setCurrentSession(null)
|
|
@@ -287,7 +306,7 @@ class ClientChat {
|
|
|
287
306
|
muteNum: unreadMessageMuteNum
|
|
288
307
|
}
|
|
289
308
|
}
|
|
290
|
-
})
|
|
309
|
+
}, 'onSessionReadChange')
|
|
291
310
|
}
|
|
292
311
|
}
|
|
293
312
|
this.session = new ClientChatSession({
|
|
@@ -445,8 +464,12 @@ class ClientChat {
|
|
|
445
464
|
rs.data.lastMsgId = data.id
|
|
446
465
|
rs.data.lastUpdateTime = data.updateDate
|
|
447
466
|
}
|
|
467
|
+
// 正在看这个会话并且允许自动标记已读
|
|
468
|
+
const isCurrentSessionRead = this.sessionManage.currentSession && this.sessionManage.currentSession.conversationId === sessionId && this.shouldMarkCurrentSessionRead(sessionId, data)
|
|
469
|
+
// 会话未读数量:isAfterServerMessage 为 true 表示这条消息比服务端返回的会话 lastMsgTime 新,
|
|
470
|
+
// 服务端返回的 unreadMsgCount 还没算它,需要本地 +1;否则服务端已经算进去了,skip 掉避免重复
|
|
448
471
|
if (!data.isSend && isAfterServerMessage) {
|
|
449
|
-
if (
|
|
472
|
+
if (isCurrentSessionRead) {
|
|
450
473
|
rs.data.unreadMsgCount = 0
|
|
451
474
|
} else {
|
|
452
475
|
rs.data.unreadMsgCount = (rs.data.unreadMsgCount || 0) + 1
|
|
@@ -455,6 +478,13 @@ class ClientChat {
|
|
|
455
478
|
} else {
|
|
456
479
|
context.skippedMessageIds.push(data.id)
|
|
457
480
|
}
|
|
481
|
+
// 账号未读数量:和会话未读数量的判断口径不一样。
|
|
482
|
+
// 账号未读初始值是登录时从服务端取的,不包含这条新消息,所以不管这条消息有没有被服务端算进会话的 unreadMsgCount(即不管是否被 skip),
|
|
483
|
+
// 账号都要 +1。唯一不加的情况是"正在看当前会话并被直接标记已读"(此时会话未读被置 0,不会再通过 onSessionReadChange 扣减账号)。
|
|
484
|
+
// 这个累计值会通过 addSession(rs.data, null, { unreadDelta }) 传给 onAddSession,账号只累加这个增量而不是整个 unreadMsgCount
|
|
485
|
+
if (!data.isSend && !(isAfterServerMessage && isCurrentSessionRead)) {
|
|
486
|
+
context.accountUnreadDelta += 1
|
|
487
|
+
}
|
|
458
488
|
}
|
|
459
489
|
return rs
|
|
460
490
|
}, {
|
|
@@ -496,7 +526,7 @@ class ClientChat {
|
|
|
496
526
|
muteNum: unreadMessageMuteNum
|
|
497
527
|
}
|
|
498
528
|
}
|
|
499
|
-
})
|
|
529
|
+
}, 'onNewFriendMessage')
|
|
500
530
|
}
|
|
501
531
|
}
|
|
502
532
|
return nextSession
|
|
@@ -581,8 +611,12 @@ class ClientChat {
|
|
|
581
611
|
rs.data.lastMsgId = data.id
|
|
582
612
|
rs.data.lastUpdateTime = data.updateDate
|
|
583
613
|
}
|
|
614
|
+
// 正在看这个会话并且允许自动标记已读
|
|
615
|
+
const isCurrentSessionRead = this.sessionManage.currentSession && this.sessionManage.currentSession.conversationId === sessionId && this.shouldMarkCurrentSessionRead(sessionId, data)
|
|
616
|
+
// 会话未读数量:isAfterServerMessage 为 true 表示这条消息比服务端返回的会话 lastMsgTime 新,
|
|
617
|
+
// 服务端返回的 unreadMsgCount 还没算它,需要本地 +1;否则服务端已经算进去了,skip 掉避免重复
|
|
584
618
|
if (!data.isSend && isAfterServerMessage) {
|
|
585
|
-
if (
|
|
619
|
+
if (isCurrentSessionRead) {
|
|
586
620
|
rs.data.unreadMsgCount = 0
|
|
587
621
|
} else {
|
|
588
622
|
rs.data.unreadMsgCount = (rs.data.unreadMsgCount || 0) + 1
|
|
@@ -594,6 +628,13 @@ class ClientChat {
|
|
|
594
628
|
} else {
|
|
595
629
|
context.skippedMessageIds.push(data.id)
|
|
596
630
|
}
|
|
631
|
+
// 账号未读数量:和会话未读数量的判断口径不一样。
|
|
632
|
+
// 账号未读初始值是登录时从服务端取的,不包含这条新消息,所以不管这条消息有没有被服务端算进会话的 unreadMsgCount(即不管是否被 skip),
|
|
633
|
+
// 账号都要 +1。唯一不加的情况是"正在看当前会话并被直接标记已读"(此时会话未读被置 0,不会再通过 onSessionReadChange 扣减账号)。
|
|
634
|
+
// 这个累计值会通过 addSession(rs.data, null, { unreadDelta }) 传给 onAddSession,账号只累加这个增量而不是整个 unreadMsgCount
|
|
635
|
+
if (!data.isSend && !(isAfterServerMessage && isCurrentSessionRead)) {
|
|
636
|
+
context.accountUnreadDelta += 1
|
|
637
|
+
}
|
|
597
638
|
}
|
|
598
639
|
return rs
|
|
599
640
|
}, {
|
|
@@ -638,7 +679,7 @@ class ClientChat {
|
|
|
638
679
|
muteNum: unreadMessageMuteNum
|
|
639
680
|
}
|
|
640
681
|
}
|
|
641
|
-
})
|
|
682
|
+
}, 'onNewRoomMessage')
|
|
642
683
|
}
|
|
643
684
|
}
|
|
644
685
|
return nextSession
|
|
@@ -748,6 +789,26 @@ class ClientChat {
|
|
|
748
789
|
getAccountGreetingUnreadMsgCountMethod: options.getAccountGreetingUnreadMsgCountMethod,
|
|
749
790
|
batchGetAccountGreetingUnreadMsgCountMethod: options.batchGetAccountGreetingUnreadMsgCountMethod,
|
|
750
791
|
clearAccountGreetingUnreadMsgCountMethod: options.clearAccountGreetingUnreadMsgCountMethod,
|
|
792
|
+
// 账号未读数量变化日志,附带该账号本地会话未读之和,用于排查账号未读数和会话未读数不一致的问题
|
|
793
|
+
onUnreadMessageNumLog: (log) => {
|
|
794
|
+
if (!this.socket) {
|
|
795
|
+
return
|
|
796
|
+
}
|
|
797
|
+
const wechatAccountId = log.content && log.content.data && log.content.data.wechatAccountId
|
|
798
|
+
if (wechatAccountId && this.session) {
|
|
799
|
+
log.content.data.localSessionUnread = Object.keys(this.session.sessionMap).reduce((rs, id) => {
|
|
800
|
+
const session = this.session.sessionMap[id]
|
|
801
|
+
if (session && session.wechatAccountId === wechatAccountId) {
|
|
802
|
+
rs.num += session.unreadMsgCount || 0
|
|
803
|
+
if (session.mute) {
|
|
804
|
+
rs.muteNum += session.unreadMsgCount || 0
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return rs
|
|
808
|
+
}, { num: 0, muteNum: 0 })
|
|
809
|
+
}
|
|
810
|
+
this.socket.addLog(log)
|
|
811
|
+
},
|
|
751
812
|
onAccountAdded: ({ account }) => {
|
|
752
813
|
return this.account.refreshAccountUnreadMessageNum({
|
|
753
814
|
wechatAccountId: account.id
|
|
@@ -919,25 +980,10 @@ class ClientChat {
|
|
|
919
980
|
return this.contacts.getFriend(sessionFriendId, true)
|
|
920
981
|
})
|
|
921
982
|
}
|
|
922
|
-
//
|
|
923
|
-
|
|
924
|
-
rs.forEach(session => {
|
|
925
|
-
this.account.updateAccountUnreadMessageNum(session.wechatAccountId, ({ unreadMesasgeNum, unreadMessageMuteNum }) => {
|
|
926
|
-
if (session.mute) {
|
|
927
|
-
return {
|
|
928
|
-
num: (unreadMesasgeNum || 0) + (session.unreadMsgCount || 0),
|
|
929
|
-
muteNum: (unreadMessageMuteNum || 0) + (session.unreadMsgCount || 0)
|
|
930
|
-
}
|
|
931
|
-
} else {
|
|
932
|
-
return {
|
|
933
|
-
num: (unreadMesasgeNum || 0) + (session.unreadMsgCount || 0),
|
|
934
|
-
muteNum: unreadMessageMuteNum
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
})
|
|
938
|
-
})
|
|
939
|
-
}
|
|
983
|
+
// 分配会话的未读数量已经在onAddSession里累加到工作微信号上了,这里不再重复累加
|
|
984
|
+
// 转移/删除的好友如果本地没有加载到对应会话,本地是无法扣减的,所以统一以服务端为准刷新一次
|
|
940
985
|
return ps.finally(() => {
|
|
986
|
+
this.refreshAccountsUnreadMessageNum([].concat(wechatAccountIds, data.wechatAccountIds || []))
|
|
941
987
|
// 这里应该标记那些工作微信号的通讯录修改了,后面要在界面打个提示,告诉用户通讯录变化了,让手动刷新一下
|
|
942
988
|
// 同时也将缓存都清理一下,例如工作微信号分组统计数量等
|
|
943
989
|
this.contacts.markModify() // 标记通讯录修改
|
|
@@ -963,6 +1009,8 @@ class ClientChat {
|
|
|
963
1009
|
this.session.removeSession(session.conversationId)
|
|
964
1010
|
}
|
|
965
1011
|
}
|
|
1012
|
+
// 本地没有加载到该会话时无法扣减未读数量,以服务端为准刷新一次
|
|
1013
|
+
this.refreshAccountsUnreadMessageNum(data.wechatAccountIds)
|
|
966
1014
|
// todo 刷新一下微信号,如果微信号一个好友都没了,应该要删除掉的
|
|
967
1015
|
this.contacts.markModify() // 标记通讯录修改
|
|
968
1016
|
}
|
|
@@ -1001,25 +1049,10 @@ class ClientChat {
|
|
|
1001
1049
|
ps = this.account.reloadData()
|
|
1002
1050
|
}
|
|
1003
1051
|
}
|
|
1004
|
-
//
|
|
1005
|
-
|
|
1006
|
-
rs.forEach(session => {
|
|
1007
|
-
this.account.updateAccountUnreadMessageNum(session.wechatAccountId, ({ unreadMesasgeNum, unreadMessageMuteNum }) => {
|
|
1008
|
-
if (session.mute) {
|
|
1009
|
-
return {
|
|
1010
|
-
num: (unreadMesasgeNum || 0) + (session.unreadMsgCount || 0),
|
|
1011
|
-
muteNum: (unreadMessageMuteNum || 0) + (session.unreadMsgCount || 0)
|
|
1012
|
-
}
|
|
1013
|
-
} else {
|
|
1014
|
-
return {
|
|
1015
|
-
num: (unreadMesasgeNum || 0) + (session.unreadMsgCount || 0),
|
|
1016
|
-
muteNum: unreadMessageMuteNum
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
})
|
|
1020
|
-
})
|
|
1021
|
-
}
|
|
1052
|
+
// 分配会话的未读数量已经在onAddSession里累加到工作微信号上了,这里不再重复累加
|
|
1053
|
+
// 转移/删除的群聊如果本地没有加载到对应会话,本地是无法扣减的,所以统一以服务端为准刷新一次
|
|
1022
1054
|
return ps.finally(() => {
|
|
1055
|
+
this.refreshAccountsUnreadMessageNum([].concat(wechatAccountIds, data.wechatAccountIds || []))
|
|
1023
1056
|
// 这里应该标记那些工作微信号的通讯录修改了,后面要在界面打个提示,告诉用户通讯录变化了,让手动刷新一下
|
|
1024
1057
|
// 同时也将缓存都清理一下,例如工作微信号分组统计数量等
|
|
1025
1058
|
this.contacts.markModify() // 标记通讯录修改
|
|
@@ -1043,6 +1076,8 @@ class ClientChat {
|
|
|
1043
1076
|
}
|
|
1044
1077
|
// 删除群聊
|
|
1045
1078
|
this.contacts.removeRoom(data.wechatChatroomId)
|
|
1079
|
+
// 本地没有加载到该会话时无法扣减未读数量,以服务端为准刷新一次
|
|
1080
|
+
this.refreshAccountsUnreadMessageNum(data.wechatAccountIds)
|
|
1046
1081
|
}
|
|
1047
1082
|
// 更新群聊
|
|
1048
1083
|
else {
|
|
@@ -1080,6 +1115,8 @@ class ClientChat {
|
|
|
1080
1115
|
wechatAccountId: data.wechatAccountId,
|
|
1081
1116
|
unreadGreetingMsgCount: data.unreadGreetingMsgCount
|
|
1082
1117
|
})
|
|
1118
|
+
// 刷新所有微信号请求数量
|
|
1119
|
+
this.account.getAccountGreetingUnreadMsgCount()
|
|
1083
1120
|
},
|
|
1084
1121
|
onCmdNewFriendRequest: ({ data }) => {
|
|
1085
1122
|
// 刷新指定微信号请求数量
|
|
@@ -1151,6 +1188,10 @@ class ClientChat {
|
|
|
1151
1188
|
Promise.all(ps).finally(() => {
|
|
1152
1189
|
this.friendMessage.setLastReceiveMessageTime(Date.now())
|
|
1153
1190
|
this.roomMessage.setLastReceiveMessageTime(Date.now())
|
|
1191
|
+
// 断线期间本地增量可能和服务端产生偏差(其他端已读、消息延迟等),重连后以服务端为准全量校准一次
|
|
1192
|
+
if (ps.length) {
|
|
1193
|
+
this.account.refreshAllAccountUnreadMesageNum()
|
|
1194
|
+
}
|
|
1154
1195
|
})
|
|
1155
1196
|
},
|
|
1156
1197
|
onSocketClose: (evt) => {
|
|
@@ -1205,6 +1246,17 @@ class ClientChat {
|
|
|
1205
1246
|
this.shouldMarkCurrentSessionReadMethod = method
|
|
1206
1247
|
}
|
|
1207
1248
|
|
|
1249
|
+
/**
|
|
1250
|
+
* 以服务端为准刷新指定工作微信号的未读消息数量,用于本地增量无法处理的场景(例如本地未加载到的会话被删除/转移)
|
|
1251
|
+
* @param { Array<String> } wechatAccountIds
|
|
1252
|
+
*/
|
|
1253
|
+
refreshAccountsUnreadMessageNum (wechatAccountIds) {
|
|
1254
|
+
const ids = Array.from(new Set((wechatAccountIds || []).filter(id => id && this.account.accountMap[id])))
|
|
1255
|
+
ids.forEach(wechatAccountId => {
|
|
1256
|
+
this.account.refreshAccountUnreadMessageNum({ wechatAccountId })
|
|
1257
|
+
})
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1208
1260
|
shouldMarkCurrentSessionRead (sessionId, data) {
|
|
1209
1261
|
if (typeof this.shouldMarkCurrentSessionReadMethod === 'function') {
|
|
1210
1262
|
return this.shouldMarkCurrentSessionReadMethod({
|