wechaty-web-panel 1.6.112 → 1.6.113

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 (109) hide show
  1. package/dist/bot/chatgpt/index.js +235 -0
  2. package/dist/bot/coze/sdk/index.js +110 -0
  3. package/dist/bot/dify/sdk/index.js +461 -0
  4. package/dist/bot/dify/sdk/office.js +319 -0
  5. package/dist/bot/fastgpt/index.js +98 -0
  6. package/dist/bot/qanything/index.js +136 -0
  7. package/dist/botInstance/coze.js +167 -0
  8. package/dist/botInstance/cozev3.js +157 -0
  9. package/dist/botInstance/dify.js +160 -0
  10. package/dist/botInstance/fastgpt.js +130 -0
  11. package/dist/botInstance/gpt4v.js +95 -0
  12. package/dist/botInstance/officialOpenAi.js +186 -0
  13. package/dist/botInstance/qany.js +144 -0
  14. package/dist/botInstance/sdk/chatGPT4V.js +89 -0
  15. package/dist/botInstance/sdk/coze.js +200 -0
  16. package/dist/botInstance/sdk/difyClient.js +354 -0
  17. package/dist/botInstance/sdk/pTimeout.js +97 -0
  18. package/dist/botInstance/sdk/qanything.js +137 -0
  19. package/dist/botInstance/sdk/quick-lru.js +237 -0
  20. package/dist/common/hook.js +66 -0
  21. package/dist/common/index.js +513 -0
  22. package/dist/common/multiReply.js +158 -0
  23. package/dist/common/reply.js +23 -0
  24. package/dist/const/puppet-type.js +71 -0
  25. package/dist/db/aiDb.js +27 -0
  26. package/dist/db/aichatDb.js +84 -0
  27. package/dist/db/chatHistory.js +137 -0
  28. package/dist/db/configDb.js +97 -0
  29. package/dist/db/global.js +62 -0
  30. package/dist/db/gptConfig.js +85 -0
  31. package/dist/db/nedb.js +88 -0
  32. package/dist/db/puppetDb.js +58 -0
  33. package/dist/db/roomDb.js +83 -0
  34. package/dist/db/rssConfig.js +82 -0
  35. package/dist/db/rssHistory.js +88 -0
  36. package/dist/db/userDb.js +27 -0
  37. package/dist/handlers/on-callback-message.js +183 -0
  38. package/dist/handlers/on-error.js +5 -0
  39. package/dist/handlers/on-friend.js +62 -0
  40. package/dist/handlers/on-heartbeat.js +20 -0
  41. package/dist/handlers/on-login.js +58 -0
  42. package/dist/handlers/on-logout.js +17 -0
  43. package/dist/handlers/on-message.js +644 -0
  44. package/dist/handlers/on-ready.js +36 -0
  45. package/dist/handlers/on-record-message.js +56 -0
  46. package/dist/handlers/on-roomjoin.js +42 -0
  47. package/dist/handlers/on-roomleave.js +12 -0
  48. package/dist/handlers/on-roomtopic.js +16 -0
  49. package/dist/handlers/on-scan.js +64 -0
  50. package/dist/handlers/on-verifycode.js +42 -0
  51. package/dist/index.js +81 -69306
  52. package/dist/lib/contentCensor.js +23 -0
  53. package/dist/lib/index.js +562 -0
  54. package/dist/lib/oss.js +43 -0
  55. package/dist/lib/s3oss.js +33 -0
  56. package/dist/mcp/mcp-server.js +26 -0
  57. package/dist/mcp/src/config/database.js +51 -0
  58. package/dist/mcp/src/index.js +238 -0
  59. package/dist/mcp/src/mcp/schemas.js +178 -0
  60. package/dist/mcp/src/mcp/server.js +421 -0
  61. package/dist/mcp/src/mcp/streamable-server.js +690 -0
  62. package/dist/mcp/src/models/ChatMessage.js +151 -0
  63. package/dist/mcp/src/models/Friend.js +64 -0
  64. package/dist/mcp/src/models/Group.js +55 -0
  65. package/dist/mcp/src/models/GroupMember.js +67 -0
  66. package/dist/mcp/src/models/index.js +27 -0
  67. package/dist/mcp/src/scripts/migrate.js +21 -0
  68. package/dist/mcp/src/services/ChatDataService.js +284 -0
  69. package/dist/mcp/src/services/McpService.js +521 -0
  70. package/dist/mcp/src/services/McpTools.js +504 -0
  71. package/dist/mcp/streamable-examples.js +283 -0
  72. package/dist/mcp/streamable-server.js +79 -0
  73. package/dist/mcp/test-mcp.js +64 -0
  74. package/dist/mcp/test-streamable-server.js +86 -0
  75. package/dist/package-json.js +89 -0
  76. package/dist/proxy/aibotk.js +829 -0
  77. package/dist/proxy/api.js +431 -0
  78. package/dist/proxy/apib.js +587 -0
  79. package/dist/proxy/bot/chatgpt.js +38 -0
  80. package/dist/proxy/bot/coze.js +38 -0
  81. package/dist/proxy/bot/cozev3.js +38 -0
  82. package/dist/proxy/bot/dify.js +38 -0
  83. package/dist/proxy/bot/dispatch.js +81 -0
  84. package/dist/proxy/bot/fastgpt.js +27 -0
  85. package/dist/proxy/bot/qany.js +27 -0
  86. package/dist/proxy/config.js +14 -0
  87. package/dist/proxy/cozeAi.js +60 -0
  88. package/dist/proxy/cozeV3Ai.js +60 -0
  89. package/dist/proxy/difyAi.js +58 -0
  90. package/dist/proxy/fastgpt.js +55 -0
  91. package/dist/proxy/mqtt.js +275 -0
  92. package/dist/proxy/multimodal.js +122 -0
  93. package/dist/proxy/openAi.js +63 -0
  94. package/dist/proxy/outapi.js +62 -0
  95. package/dist/proxy/qAnyAi.js +57 -0
  96. package/dist/proxy/superagent.js +200 -0
  97. package/dist/proxy/tencent-open.js +255 -0
  98. package/dist/service/event-dispatch-service.js +309 -0
  99. package/dist/service/gpt4vService.js +45 -0
  100. package/dist/service/msg-filter-service.js +121 -0
  101. package/dist/service/msg-filters.js +645 -0
  102. package/dist/service/room-async-service.js +455 -0
  103. package/dist/task/index.js +535 -0
  104. package/dist/task/rss.js +174 -0
  105. package/package.json +2 -2
  106. package/src/package-json.js +2 -2
  107. package/tsconfig.json +3 -12
  108. package/dist/index.d.ts +0 -9
  109. package/tsconfig.cjs.json +0 -12
@@ -0,0 +1,521 @@
1
+ import { Friend, Group, GroupMember, ChatMessage } from '../models/index.js';
2
+ import { sequelize } from '../config/database.js';
3
+ import { Op, fn, col, literal } from 'sequelize';
4
+ /**
5
+ * MCP (Model Context Protocol) 服务
6
+ * 提供各种高级查询和分析功能
7
+ */
8
+ class McpService {
9
+ /**
10
+ * 根据关键词搜索好友
11
+ * @param {Object} params - 搜索参数
12
+ * @returns {Promise<Array>} 搜索结果
13
+ */
14
+ async searchFriends(params = {}) {
15
+ const { robotId, keyword, tags, limit = 50, offset = 0, orderBy = 'createdAt', orderDirection = 'DESC' } = params;
16
+ const whereClause = {};
17
+ if (robotId)
18
+ whereClause.robotId = robotId;
19
+ // 关键词搜索:匹配姓名、备注、别名、微信号
20
+ if (keyword) {
21
+ whereClause[Op.or] = [
22
+ { name: { [Op.iLike]: `%${keyword}%` } },
23
+ { remark: { [Op.iLike]: `%${keyword}%` } },
24
+ { alias: { [Op.iLike]: `%${keyword}%` } },
25
+ { wxNumber: { [Op.iLike]: `%${keyword}%` } }
26
+ ];
27
+ }
28
+ // 标签搜索
29
+ if (tags) {
30
+ whereClause.tags = { [Op.iLike]: `%${tags}%` };
31
+ }
32
+ try {
33
+ const friends = await Friend.findAll({
34
+ where: whereClause,
35
+ limit,
36
+ offset,
37
+ order: [[orderBy, orderDirection]]
38
+ });
39
+ return {
40
+ data: friends,
41
+ total: await Friend.count({ where: whereClause }),
42
+ limit,
43
+ offset
44
+ };
45
+ }
46
+ catch (error) {
47
+ console.error('❌ 搜索好友失败:', error);
48
+ throw error;
49
+ }
50
+ }
51
+ /**
52
+ * 根据关键词搜索群组
53
+ * @param {Object} params - 搜索参数
54
+ * @returns {Promise<Array>} 搜索结果
55
+ */
56
+ async searchGroups(params = {}) {
57
+ const { robotId, keyword, includeMembers = false, minMemberCount = 0, maxMemberCount = null, limit = 50, offset = 0 } = params;
58
+ const whereClause = {};
59
+ if (robotId)
60
+ whereClause.robotId = robotId;
61
+ if (keyword) {
62
+ whereClause.name = { [Op.iLike]: `%${keyword}%` };
63
+ }
64
+ if (minMemberCount > 0) {
65
+ whereClause.memberCount = { [Op.gte]: minMemberCount };
66
+ }
67
+ if (maxMemberCount) {
68
+ whereClause.memberCount = {
69
+ ...whereClause.memberCount,
70
+ [Op.lte]: maxMemberCount
71
+ };
72
+ }
73
+ try {
74
+ const include = includeMembers ? [{
75
+ model: GroupMember,
76
+ as: 'members'
77
+ }] : [];
78
+ const groups = await Group.findAll({
79
+ where: whereClause,
80
+ include,
81
+ limit,
82
+ offset,
83
+ order: [['memberCount', 'DESC']]
84
+ });
85
+ return {
86
+ data: groups,
87
+ total: await Group.count({ where: whereClause }),
88
+ limit,
89
+ offset
90
+ };
91
+ }
92
+ catch (error) {
93
+ console.error('❌ 搜索群组失败:', error);
94
+ throw error;
95
+ }
96
+ }
97
+ /**
98
+ * 高级聊天记录搜索
99
+ * @param {Object} params - 搜索参数
100
+ * @returns {Promise<Array>} 搜索结果
101
+ */
102
+ async searchChatMessages(params = {}) {
103
+ const { robotId, conversationId, keyword, contentType, recordType, chatUserId, isRobotAnswer, startTime, endTime, limit = 100, offset = 0 } = params;
104
+ const whereClause = {};
105
+ if (robotId)
106
+ whereClause.robotId = robotId;
107
+ if (conversationId)
108
+ whereClause.conversationId = conversationId;
109
+ if (contentType)
110
+ whereClause.contentType = contentType;
111
+ if (recordType)
112
+ whereClause.recordType = recordType;
113
+ if (chatUserId)
114
+ whereClause.chatUserId = chatUserId;
115
+ if (typeof isRobotAnswer === 'boolean')
116
+ whereClause.isRobotAnswer = isRobotAnswer;
117
+ // 关键词搜索消息内容
118
+ if (keyword) {
119
+ whereClause.content = { [Op.iLike]: `%${keyword}%` };
120
+ }
121
+ // 时间范围搜索
122
+ if (startTime || endTime) {
123
+ whereClause.timestamp = {};
124
+ if (startTime)
125
+ whereClause.timestamp[Op.gte] = startTime;
126
+ if (endTime)
127
+ whereClause.timestamp[Op.lte] = endTime;
128
+ }
129
+ try {
130
+ const messages = await ChatMessage.findAll({
131
+ where: whereClause,
132
+ limit,
133
+ offset,
134
+ order: [['timestamp', 'DESC']]
135
+ });
136
+ return {
137
+ data: messages,
138
+ total: await ChatMessage.count({ where: whereClause }),
139
+ limit,
140
+ offset
141
+ };
142
+ }
143
+ catch (error) {
144
+ console.error('❌ 搜索聊天记录失败:', error);
145
+ throw error;
146
+ }
147
+ }
148
+ /**
149
+ * 获取机器人统计信息
150
+ * @param {string} robotId - 机器人ID
151
+ * @returns {Promise<Object>} 统计信息
152
+ */
153
+ async getRobotStatistics(robotId) {
154
+ try {
155
+ const [friendCount, groupCount, groupMemberCount, messageCount, todayMessageCount] = await Promise.all([
156
+ Friend.count({ where: { robotId } }),
157
+ Group.count({ where: { robotId } }),
158
+ GroupMember.count({ where: { robotId } }),
159
+ ChatMessage.count({ where: { robotId } }),
160
+ ChatMessage.count({
161
+ where: {
162
+ robotId,
163
+ timestamp: {
164
+ [Op.gte]: new Date().setHours(0, 0, 0, 0)
165
+ }
166
+ }
167
+ })
168
+ ]);
169
+ // 获取最近活跃的会话
170
+ const recentConversations = await ChatMessage.findAll({
171
+ where: { robotId },
172
+ attributes: [
173
+ 'conversationId',
174
+ 'conversationName',
175
+ 'recordType',
176
+ [fn('MAX', col('timestamp')), 'lastMessageTime'],
177
+ [fn('COUNT', col('id')), 'messageCount']
178
+ ],
179
+ group: ['conversationId', 'conversationName', 'recordType'],
180
+ order: [[literal('"lastMessageTime"'), 'DESC']],
181
+ limit: 10
182
+ });
183
+ // 获取消息类型统计
184
+ const messageTypeStats = await ChatMessage.findAll({
185
+ where: { robotId },
186
+ attributes: [
187
+ 'contentType',
188
+ [fn('COUNT', col('id')), 'count']
189
+ ],
190
+ group: ['contentType'],
191
+ order: [[literal('count'), 'DESC']]
192
+ });
193
+ return {
194
+ robotId,
195
+ statistics: {
196
+ friendCount,
197
+ groupCount,
198
+ groupMemberCount,
199
+ messageCount,
200
+ todayMessageCount
201
+ },
202
+ recentConversations: recentConversations.map(conv => ({
203
+ conversationId: conv.conversationId,
204
+ conversationName: conv.conversationName,
205
+ recordType: conv.recordType,
206
+ lastMessageTime: conv.getDataValue('lastMessageTime'),
207
+ messageCount: conv.getDataValue('messageCount')
208
+ })),
209
+ messageTypeStats: messageTypeStats.map(stat => ({
210
+ contentType: stat.contentType,
211
+ count: stat.getDataValue('count')
212
+ }))
213
+ };
214
+ }
215
+ catch (error) {
216
+ console.error('❌ 获取机器人统计信息失败:', error);
217
+ throw error;
218
+ }
219
+ }
220
+ /**
221
+ * 获取会话详细信息
222
+ * @param {Object} params - 查询参数
223
+ * @returns {Promise<Object>} 会话信息
224
+ */
225
+ async getConversationDetails(params = {}) {
226
+ const { robotId, conversationId } = params;
227
+ if (!robotId || !conversationId) {
228
+ throw new Error('robotId 和 conversationId 是必需参数');
229
+ }
230
+ try {
231
+ // 获取会话基本信息
232
+ const firstMessage = await ChatMessage.findOne({
233
+ where: { robotId, conversationId },
234
+ order: [['timestamp', 'ASC']]
235
+ });
236
+ if (!firstMessage) {
237
+ throw new Error('未找到该会话');
238
+ }
239
+ // 获取会话统计
240
+ const messageStats = await ChatMessage.findAll({
241
+ where: { robotId, conversationId },
242
+ attributes: [
243
+ [fn('COUNT', col('id')), 'totalMessages'],
244
+ [fn('MIN', col('timestamp')), 'firstMessageTime'],
245
+ [fn('MAX', col('timestamp')), 'lastMessageTime'],
246
+ [fn('COUNT', literal('CASE WHEN "isRobotAnswer" = true THEN 1 END')), 'robotMessages'],
247
+ [fn('COUNT', literal('CASE WHEN "isRobotAnswer" = false THEN 1 END')), 'userMessages']
248
+ ]
249
+ });
250
+ // 获取参与者信息
251
+ const participants = await ChatMessage.findAll({
252
+ where: { robotId, conversationId },
253
+ attributes: [
254
+ 'chatUserId',
255
+ 'chatUserName',
256
+ [fn('COUNT', col('id')), 'messageCount'],
257
+ [fn('MAX', col('timestamp')), 'lastActiveTime']
258
+ ],
259
+ group: ['chatUserId', 'chatUserName'],
260
+ order: [[literal('"messageCount"'), 'DESC']]
261
+ });
262
+ // 如果是群聊,获取群组详情
263
+ let groupDetails = null;
264
+ if (firstMessage.recordType === 'room') {
265
+ groupDetails = await Group.findOne({
266
+ where: { robotId, wxid: conversationId },
267
+ include: [{
268
+ model: GroupMember,
269
+ as: 'members'
270
+ }]
271
+ });
272
+ }
273
+ return {
274
+ conversationId,
275
+ conversationName: firstMessage.conversationName,
276
+ recordType: firstMessage.recordType,
277
+ statistics: {
278
+ totalMessages: messageStats[0]?.getDataValue('totalMessages') || 0,
279
+ robotMessages: messageStats[0]?.getDataValue('robotMessages') || 0,
280
+ userMessages: messageStats[0]?.getDataValue('userMessages') || 0,
281
+ firstMessageTime: messageStats[0]?.getDataValue('firstMessageTime'),
282
+ lastMessageTime: messageStats[0]?.getDataValue('lastMessageTime')
283
+ },
284
+ participants: participants.map(p => ({
285
+ userId: p.chatUserId,
286
+ userName: p.chatUserName,
287
+ messageCount: p.getDataValue('messageCount'),
288
+ lastActiveTime: p.getDataValue('lastActiveTime')
289
+ })),
290
+ groupDetails
291
+ };
292
+ }
293
+ catch (error) {
294
+ console.error('❌ 获取会话详情失败:', error);
295
+ throw error;
296
+ }
297
+ }
298
+ /**
299
+ * 获取群组成员详细信息
300
+ * @param {Object} params - 查询参数
301
+ * @returns {Promise<Object>} 群组成员信息
302
+ */
303
+ async getGroupMembersDetail(params = {}) {
304
+ const { robotId, roomWxid, includeMessageStats = true } = params;
305
+ if (!robotId || !roomWxid) {
306
+ throw new Error('robotId 和 roomWxid 是必需参数');
307
+ }
308
+ try {
309
+ // 获取群组信息
310
+ const group = await Group.findOne({
311
+ where: { robotId, wxid: roomWxid }
312
+ });
313
+ if (!group) {
314
+ throw new Error('未找到该群组');
315
+ }
316
+ // 获取群成员列表
317
+ const members = await GroupMember.findAll({
318
+ where: { robotId, roomWxid },
319
+ order: [['createdAt', 'ASC']]
320
+ });
321
+ // 如果需要消息统计
322
+ let membersWithStats = members;
323
+ if (includeMessageStats) {
324
+ const memberStats = await ChatMessage.findAll({
325
+ where: {
326
+ robotId,
327
+ conversationId: roomWxid,
328
+ recordType: 'room'
329
+ },
330
+ attributes: [
331
+ 'chatUserId',
332
+ [fn('COUNT', col('id')), 'messageCount'],
333
+ [fn('MAX', col('timestamp')), 'lastMessageTime']
334
+ ],
335
+ group: ['chatUserId']
336
+ });
337
+ const statsMap = new Map(memberStats.map(stat => [
338
+ stat.chatUserId,
339
+ {
340
+ messageCount: stat.getDataValue('messageCount'),
341
+ lastMessageTime: stat.getDataValue('lastMessageTime')
342
+ }
343
+ ]));
344
+ membersWithStats = members.map(member => ({
345
+ ...member.toJSON(),
346
+ messageStats: statsMap.get(member.wxid) || {
347
+ messageCount: 0,
348
+ lastMessageTime: null
349
+ }
350
+ }));
351
+ }
352
+ return {
353
+ group: group.toJSON(),
354
+ members: membersWithStats,
355
+ summary: {
356
+ totalMembers: members.length,
357
+ activeMembers: membersWithStats.filter(m => m.messageStats?.messageCount > 0).length
358
+ }
359
+ };
360
+ }
361
+ catch (error) {
362
+ console.error('❌ 获取群组成员详情失败:', error);
363
+ throw error;
364
+ }
365
+ }
366
+ /**
367
+ * 获取消息热力图数据(按时间分布)
368
+ * @param {Object} params - 查询参数
369
+ * @returns {Promise<Array>} 热力图数据
370
+ */
371
+ async getMessageHeatmap(params = {}) {
372
+ const { robotId, conversationId, startDate, endDate, granularity = 'hour' // hour, day, week, month
373
+ } = params;
374
+ const whereClause = {};
375
+ if (robotId)
376
+ whereClause.robotId = robotId;
377
+ if (conversationId)
378
+ whereClause.conversationId = conversationId;
379
+ // 设置时间范围
380
+ if (startDate || endDate) {
381
+ whereClause.timestamp = {};
382
+ if (startDate)
383
+ whereClause.timestamp[Op.gte] = new Date(startDate).getTime();
384
+ if (endDate)
385
+ whereClause.timestamp[Op.lte] = new Date(endDate).getTime();
386
+ }
387
+ let dateFormat;
388
+ switch (granularity) {
389
+ case 'hour':
390
+ dateFormat = "to_char(to_timestamp(timestamp/1000), 'YYYY-MM-DD HH24:00:00')";
391
+ break;
392
+ case 'day':
393
+ dateFormat = "to_char(to_timestamp(timestamp/1000), 'YYYY-MM-DD')";
394
+ break;
395
+ case 'week':
396
+ dateFormat = "to_char(date_trunc('week', to_timestamp(timestamp/1000)), 'YYYY-MM-DD')";
397
+ break;
398
+ case 'month':
399
+ dateFormat = "to_char(to_timestamp(timestamp/1000), 'YYYY-MM')";
400
+ break;
401
+ default:
402
+ dateFormat = "to_char(to_timestamp(timestamp/1000), 'YYYY-MM-DD HH24:00:00')";
403
+ }
404
+ try {
405
+ const heatmapData = await ChatMessage.findAll({
406
+ where: whereClause,
407
+ attributes: [
408
+ [literal(dateFormat), 'timeSlot'],
409
+ [fn('COUNT', col('id')), 'messageCount']
410
+ ],
411
+ group: [literal(dateFormat)],
412
+ order: [[literal('"timeSlot"'), 'ASC']]
413
+ });
414
+ return heatmapData.map(item => ({
415
+ timeSlot: item.getDataValue('timeSlot'),
416
+ messageCount: item.getDataValue('messageCount')
417
+ }));
418
+ }
419
+ catch (error) {
420
+ console.error('❌ 获取消息热力图数据失败:', error);
421
+ throw error;
422
+ }
423
+ }
424
+ /**
425
+ * 全文搜索
426
+ * @param {Object} params - 搜索参数
427
+ * @returns {Promise<Object>} 搜索结果
428
+ */
429
+ async fullTextSearch(params = {}) {
430
+ const { robotId, keyword, searchTypes = ['friends', 'groups', 'messages'], limit = 20 } = params;
431
+ if (!keyword) {
432
+ throw new Error('搜索关键词不能为空');
433
+ }
434
+ const results = {};
435
+ try {
436
+ // 搜索好友
437
+ if (searchTypes.includes('friends')) {
438
+ results.friends = await this.searchFriends({
439
+ robotId,
440
+ keyword,
441
+ limit
442
+ });
443
+ }
444
+ // 搜索群组
445
+ if (searchTypes.includes('groups')) {
446
+ results.groups = await this.searchGroups({
447
+ robotId,
448
+ keyword,
449
+ limit
450
+ });
451
+ }
452
+ // 搜索消息
453
+ if (searchTypes.includes('messages')) {
454
+ results.messages = await this.searchChatMessages({
455
+ robotId,
456
+ keyword,
457
+ limit
458
+ });
459
+ }
460
+ return {
461
+ keyword,
462
+ searchTypes,
463
+ results,
464
+ summary: {
465
+ friendCount: results.friends?.total || 0,
466
+ groupCount: results.groups?.total || 0,
467
+ messageCount: results.messages?.total || 0
468
+ }
469
+ };
470
+ }
471
+ catch (error) {
472
+ console.error('❌ 全文搜索失败:', error);
473
+ throw error;
474
+ }
475
+ }
476
+ /**
477
+ * 获取数据库连接状态和系统信息
478
+ * @returns {Promise<Object>} 系统信息
479
+ */
480
+ async getSystemInfo() {
481
+ try {
482
+ await sequelize.authenticate();
483
+ const [totalFriends, totalGroups, totalGroupMembers, totalMessages] = await Promise.all([
484
+ Friend.count(),
485
+ Group.count(),
486
+ GroupMember.count(),
487
+ ChatMessage.count()
488
+ ]);
489
+ return {
490
+ database: {
491
+ status: 'connected',
492
+ dialect: sequelize.getDialect(),
493
+ version: await sequelize.databaseVersion()
494
+ },
495
+ statistics: {
496
+ totalFriends,
497
+ totalGroups,
498
+ totalGroupMembers,
499
+ totalMessages
500
+ },
501
+ system: {
502
+ nodeVersion: process.version,
503
+ platform: process.platform,
504
+ uptime: process.uptime(),
505
+ memoryUsage: process.memoryUsage()
506
+ }
507
+ };
508
+ }
509
+ catch (error) {
510
+ console.error('❌ 获取系统信息失败:', error);
511
+ return {
512
+ database: {
513
+ status: 'disconnected',
514
+ error: error.message
515
+ }
516
+ };
517
+ }
518
+ }
519
+ }
520
+ export default McpService;
521
+ //# sourceMappingURL=McpService.js.map