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,151 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import sequelize from '../config/database.js';
3
+ const ChatMessage = sequelize.define('ChatMessage', {
4
+ id: {
5
+ type: DataTypes.INTEGER,
6
+ primaryKey: true,
7
+ autoIncrement: true
8
+ },
9
+ robotId: {
10
+ type: DataTypes.STRING,
11
+ allowNull: false,
12
+ comment: '当前登录机器人的id'
13
+ },
14
+ robotName: {
15
+ type: DataTypes.STRING,
16
+ allowNull: true,
17
+ comment: '当前登录机器人的昵称'
18
+ },
19
+ conversationId: {
20
+ type: DataTypes.STRING,
21
+ allowNull: false,
22
+ comment: '会话id, 如果是私聊就是好友wxid,如果是群聊就是群wxid'
23
+ },
24
+ conversationName: {
25
+ type: DataTypes.STRING,
26
+ allowNull: true,
27
+ comment: '会话名,如果是私聊就是好友昵称,如果是群聊就是群名'
28
+ },
29
+ conversationAvatar: {
30
+ type: DataTypes.TEXT,
31
+ allowNull: true,
32
+ comment: '会话头像,如果是私聊就是好友头像,如果是群聊就是群头像'
33
+ },
34
+ isRobotAnswer: {
35
+ type: DataTypes.BOOLEAN,
36
+ defaultValue: false,
37
+ comment: '是否机器人回复,用于检查是否机器人自己回复'
38
+ },
39
+ realUser: {
40
+ type: DataTypes.INTEGER,
41
+ defaultValue: 0,
42
+ comment: '是否真人回复'
43
+ },
44
+ msgId: {
45
+ type: DataTypes.STRING,
46
+ allowNull: true,
47
+ comment: '消息ID'
48
+ },
49
+ contentType: {
50
+ type: DataTypes.STRING,
51
+ defaultValue: '文字',
52
+ comment: '对话内容类型:文字,图片,文件,h5连接,小程序,名片等'
53
+ },
54
+ recordType: {
55
+ type: DataTypes.STRING,
56
+ allowNull: false,
57
+ comment: 'contact 私聊 room 群聊'
58
+ },
59
+ chatUserName: {
60
+ type: DataTypes.STRING,
61
+ allowNull: true,
62
+ comment: '聊天用户昵称'
63
+ },
64
+ chatUserAlias: {
65
+ type: DataTypes.STRING,
66
+ allowNull: true,
67
+ comment: '聊天用户备注'
68
+ },
69
+ chatUserId: {
70
+ type: DataTypes.STRING,
71
+ allowNull: true,
72
+ comment: '聊天用户id'
73
+ },
74
+ chatUserAvatar: {
75
+ type: DataTypes.TEXT,
76
+ allowNull: true,
77
+ comment: '聊天用户头像'
78
+ },
79
+ roomName: {
80
+ type: DataTypes.STRING,
81
+ allowNull: true,
82
+ comment: '群聊名称'
83
+ },
84
+ roomId: {
85
+ type: DataTypes.STRING,
86
+ allowNull: true,
87
+ comment: '群聊id'
88
+ },
89
+ content: {
90
+ type: DataTypes.TEXT,
91
+ allowNull: true,
92
+ comment: '聊天内容'
93
+ },
94
+ url: {
95
+ type: DataTypes.TEXT,
96
+ allowNull: true,
97
+ comment: 'h5链接'
98
+ },
99
+ fileName: {
100
+ type: DataTypes.STRING,
101
+ allowNull: true,
102
+ comment: '文件名称'
103
+ },
104
+ isImage: {
105
+ type: DataTypes.BOOLEAN,
106
+ defaultValue: false,
107
+ comment: '是否图片'
108
+ },
109
+ description: {
110
+ type: DataTypes.TEXT,
111
+ allowNull: true,
112
+ comment: 'h5描述'
113
+ },
114
+ imageUrl: {
115
+ type: DataTypes.TEXT,
116
+ allowNull: true,
117
+ comment: 'h5图片链接'
118
+ },
119
+ title: {
120
+ type: DataTypes.STRING,
121
+ allowNull: true,
122
+ comment: 'h5标题'
123
+ },
124
+ timestamp: {
125
+ type: DataTypes.BIGINT,
126
+ allowNull: false,
127
+ comment: '聊天时间戳'
128
+ }
129
+ }, {
130
+ tableName: 'chat_messages',
131
+ timestamps: true,
132
+ indexes: [
133
+ {
134
+ fields: ['robotId', 'conversationId']
135
+ },
136
+ {
137
+ fields: ['robotId']
138
+ },
139
+ {
140
+ fields: ['timestamp']
141
+ },
142
+ {
143
+ fields: ['recordType']
144
+ },
145
+ {
146
+ fields: ['msgId']
147
+ }
148
+ ]
149
+ });
150
+ export default ChatMessage;
151
+ //# sourceMappingURL=ChatMessage.js.map
@@ -0,0 +1,64 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import sequelize from '../config/database.js';
3
+ const Friend = sequelize.define('Friend', {
4
+ id: {
5
+ type: DataTypes.INTEGER,
6
+ primaryKey: true,
7
+ autoIncrement: true
8
+ },
9
+ robotId: {
10
+ type: DataTypes.STRING,
11
+ allowNull: false,
12
+ comment: '机器人账号id'
13
+ },
14
+ wxid: {
15
+ type: DataTypes.STRING,
16
+ allowNull: false,
17
+ comment: '好友wxid'
18
+ },
19
+ wxNumber: {
20
+ type: DataTypes.STRING,
21
+ allowNull: true,
22
+ comment: '好友微信号'
23
+ },
24
+ name: {
25
+ type: DataTypes.STRING,
26
+ defaultValue: null,
27
+ comment: '昵称'
28
+ },
29
+ avatar: {
30
+ type: DataTypes.TEXT,
31
+ allowNull: true,
32
+ defaultValue: null,
33
+ comment: '头像'
34
+ },
35
+ alias: {
36
+ type: DataTypes.STRING,
37
+ allowNull: true,
38
+ comment: '别名'
39
+ },
40
+ remark: {
41
+ type: DataTypes.STRING,
42
+ allowNull: true,
43
+ comment: '备注'
44
+ },
45
+ tags: {
46
+ type: DataTypes.STRING,
47
+ allowNull: true,
48
+ comment: '标签'
49
+ }
50
+ }, {
51
+ tableName: 'friends',
52
+ timestamps: true,
53
+ indexes: [
54
+ {
55
+ fields: ['robotId', 'wxid'],
56
+ unique: true
57
+ },
58
+ {
59
+ fields: ['robotId']
60
+ }
61
+ ]
62
+ });
63
+ export default Friend;
64
+ //# sourceMappingURL=Friend.js.map
@@ -0,0 +1,55 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import sequelize from '../config/database.js';
3
+ const Group = sequelize.define('Group', {
4
+ id: {
5
+ type: DataTypes.INTEGER,
6
+ primaryKey: true,
7
+ autoIncrement: true
8
+ },
9
+ robotId: {
10
+ type: DataTypes.STRING,
11
+ allowNull: false,
12
+ comment: '机器人账号id'
13
+ },
14
+ wxid: {
15
+ type: DataTypes.STRING,
16
+ allowNull: false,
17
+ unique: true, // 添加唯一约束,支持外键引用
18
+ comment: '群wxid'
19
+ },
20
+ adminId: {
21
+ type: DataTypes.STRING,
22
+ allowNull: true,
23
+ comment: '群管理员wxid'
24
+ },
25
+ name: {
26
+ type: DataTypes.STRING,
27
+ defaultValue: null,
28
+ comment: '群名'
29
+ },
30
+ avatar: {
31
+ type: DataTypes.TEXT,
32
+ allowNull: true,
33
+ defaultValue: null,
34
+ comment: '群头像'
35
+ },
36
+ memberCount: {
37
+ type: DataTypes.INTEGER,
38
+ allowNull: true,
39
+ comment: '群成员数'
40
+ }
41
+ }, {
42
+ tableName: 'groups',
43
+ timestamps: true,
44
+ indexes: [
45
+ {
46
+ fields: ['robotId', 'wxid'],
47
+ unique: true
48
+ },
49
+ {
50
+ fields: ['robotId']
51
+ }
52
+ ]
53
+ });
54
+ export default Group;
55
+ //# sourceMappingURL=Group.js.map
@@ -0,0 +1,67 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import sequelize from '../config/database.js';
3
+ const GroupMember = sequelize.define('GroupMember', {
4
+ id: {
5
+ type: DataTypes.INTEGER,
6
+ primaryKey: true,
7
+ autoIncrement: true
8
+ },
9
+ robotId: {
10
+ type: DataTypes.STRING,
11
+ allowNull: false,
12
+ comment: '机器人账号id'
13
+ },
14
+ roomWxid: {
15
+ type: DataTypes.STRING,
16
+ allowNull: false,
17
+ comment: '群wxid, 和群数据的wxid进行关联'
18
+ },
19
+ wxid: {
20
+ type: DataTypes.STRING,
21
+ allowNull: false,
22
+ comment: '群成员wxid'
23
+ },
24
+ wxNumber: {
25
+ type: DataTypes.STRING,
26
+ allowNull: true,
27
+ comment: '群成员微信号'
28
+ },
29
+ name: {
30
+ type: DataTypes.STRING,
31
+ defaultValue: null,
32
+ comment: '群成员昵称'
33
+ },
34
+ avatar: {
35
+ type: DataTypes.TEXT,
36
+ allowNull: true,
37
+ defaultValue: null,
38
+ comment: '群成员头像'
39
+ },
40
+ alias: {
41
+ type: DataTypes.STRING,
42
+ allowNull: true,
43
+ comment: '群成员别名'
44
+ },
45
+ remark: {
46
+ type: DataTypes.STRING,
47
+ allowNull: true,
48
+ comment: '群成员备注'
49
+ }
50
+ }, {
51
+ tableName: 'group_members',
52
+ timestamps: true,
53
+ indexes: [
54
+ {
55
+ fields: ['robotId', 'roomWxid', 'wxid'],
56
+ unique: true
57
+ },
58
+ {
59
+ fields: ['robotId', 'roomWxid']
60
+ },
61
+ {
62
+ fields: ['robotId']
63
+ }
64
+ ]
65
+ });
66
+ export default GroupMember;
67
+ //# sourceMappingURL=GroupMember.js.map
@@ -0,0 +1,27 @@
1
+ import Friend from './Friend.js';
2
+ import Group from './Group.js';
3
+ import GroupMember from './GroupMember.js';
4
+ import ChatMessage from './ChatMessage.js';
5
+ // 建立模型关联关系
6
+ // 使用应用层关联,不在数据库级别创建外键约束
7
+ Group.hasMany(GroupMember, {
8
+ foreignKey: 'roomWxid',
9
+ sourceKey: 'wxid',
10
+ as: 'members',
11
+ constraints: false // 禁用数据库级别的外键约束
12
+ });
13
+ GroupMember.belongsTo(Group, {
14
+ foreignKey: 'roomWxid',
15
+ targetKey: 'wxid',
16
+ as: 'group',
17
+ constraints: false // 禁用数据库级别的外键约束
18
+ });
19
+ // 导出所有模型
20
+ export { Friend, Group, GroupMember, ChatMessage };
21
+ export default {
22
+ Friend,
23
+ Group,
24
+ GroupMember,
25
+ ChatMessage
26
+ };
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,21 @@
1
+ import { testConnection, initDatabase } from '../config/database.js';
2
+ /**
3
+ * 数据库迁移脚本
4
+ */
5
+ async function migrate() {
6
+ try {
7
+ console.log('🔄 开始数据库迁移...');
8
+ // 测试连接
9
+ await testConnection();
10
+ // 同步数据库结构
11
+ await initDatabase();
12
+ console.log('✅ 数据库迁移完成!');
13
+ process.exit(0);
14
+ }
15
+ catch (error) {
16
+ console.error('❌ 数据库迁移失败:', error);
17
+ process.exit(1);
18
+ }
19
+ }
20
+ migrate();
21
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1,284 @@
1
+ import { Friend, Group, GroupMember, ChatMessage } from '../models/index.js';
2
+ import { sequelize } from '../config/database.js';
3
+ /**
4
+ * 微信聊天数据存储服务
5
+ */
6
+ class ChatDataService {
7
+ /**
8
+ * 批量写入好友信息
9
+ * @param {Array} friendsData - 好友信息数组
10
+ * @param {Object} options - 配置选项
11
+ * @returns {Promise<Array>} 创建的好友记录
12
+ */
13
+ async batchCreateFriends(friendsData, options = {}) {
14
+ const { updateOnDuplicate = true } = options;
15
+ if (!Array.isArray(friendsData) || friendsData.length === 0) {
16
+ throw new Error('好友数据不能为空');
17
+ }
18
+ try {
19
+ if (updateOnDuplicate) {
20
+ // 使用 bulkCreate 的 updateOnDuplicate 选项
21
+ const result = await Friend.bulkCreate(friendsData, {
22
+ updateOnDuplicate: ['name', 'avatar', 'alias', 'remark', 'tags', 'wxNumber'],
23
+ validate: true
24
+ });
25
+ console.log(`✅ 成功批量写入/更新 ${result.length} 条好友记录`);
26
+ return result;
27
+ }
28
+ else {
29
+ // 仅创建新记录,忽略重复的
30
+ const result = await Friend.bulkCreate(friendsData, {
31
+ ignoreDuplicates: true,
32
+ validate: true
33
+ });
34
+ console.log(`✅ 成功批量写入 ${result.length} 条好友记录`);
35
+ return result;
36
+ }
37
+ }
38
+ catch (error) {
39
+ console.error('❌ 批量写入好友信息失败:', error);
40
+ throw error;
41
+ }
42
+ }
43
+ /**
44
+ * 批量写入群信息
45
+ * @param {Array} groupsData - 群信息数组
46
+ * @param {Object} options - 配置选项
47
+ * @returns {Promise<Array>} 创建的群记录
48
+ */
49
+ async batchCreateGroups(groupsData, options = {}) {
50
+ const { updateOnDuplicate = true } = options;
51
+ if (!Array.isArray(groupsData) || groupsData.length === 0) {
52
+ throw new Error('群组数据不能为空');
53
+ }
54
+ try {
55
+ if (updateOnDuplicate) {
56
+ const result = await Group.bulkCreate(groupsData, {
57
+ updateOnDuplicate: ['name', 'avatar', 'adminId', 'memberCount'],
58
+ validate: true
59
+ });
60
+ console.log(`✅ 成功批量写入/更新 ${result.length} 条群组记录`);
61
+ return result;
62
+ }
63
+ else {
64
+ const result = await Group.bulkCreate(groupsData, {
65
+ ignoreDuplicates: true,
66
+ validate: true
67
+ });
68
+ console.log(`✅ 成功批量写入 ${result.length} 条群组记录`);
69
+ return result;
70
+ }
71
+ }
72
+ catch (error) {
73
+ console.error('❌ 批量写入群组信息失败:', error);
74
+ throw error;
75
+ }
76
+ }
77
+ /**
78
+ * 批量写入群成员信息
79
+ * @param {Array} membersData - 群成员信息数组
80
+ * @param {Object} options - 配置选项
81
+ * @returns {Promise<Array>} 创建的群成员记录
82
+ */
83
+ async batchCreateGroupMembers(membersData, options = {}) {
84
+ const { updateOnDuplicate = true } = options;
85
+ if (!Array.isArray(membersData) || membersData.length === 0) {
86
+ throw new Error('群成员数据不能为空');
87
+ }
88
+ try {
89
+ if (updateOnDuplicate) {
90
+ const result = await GroupMember.bulkCreate(membersData, {
91
+ updateOnDuplicate: ['name', 'avatar', 'alias', 'remark', 'wxNumber'],
92
+ validate: true
93
+ });
94
+ console.log(`✅ 成功批量写入/更新 ${result.length} 条群成员记录`);
95
+ return result;
96
+ }
97
+ else {
98
+ const result = await GroupMember.bulkCreate(membersData, {
99
+ ignoreDuplicates: true,
100
+ validate: true
101
+ });
102
+ console.log(`✅ 成功批量写入 ${result.length} 条群成员记录`);
103
+ return result;
104
+ }
105
+ }
106
+ catch (error) {
107
+ console.error('❌ 批量写入群成员信息失败:', error);
108
+ throw error;
109
+ }
110
+ }
111
+ /**
112
+ * 写入对话记录
113
+ * @param {Object|Array} messageData - 消息数据,可以是单条或数组
114
+ * @returns {Promise<Object|Array>} 创建的消息记录
115
+ */
116
+ async createChatMessage(messageData) {
117
+ if (Array.isArray(messageData)) {
118
+ return this.batchCreateChatMessages(messageData);
119
+ }
120
+ if (!messageData || typeof messageData !== 'object') {
121
+ throw new Error('消息数据不能为空');
122
+ }
123
+ try {
124
+ const result = await ChatMessage.create(messageData);
125
+ console.log(`✅ 成功写入聊天记录: ${result.id}`);
126
+ return result;
127
+ }
128
+ catch (error) {
129
+ console.error('❌ 写入聊天记录失败:', error);
130
+ throw error;
131
+ }
132
+ }
133
+ /**
134
+ * 批量写入对话记录
135
+ * @param {Array} messagesData - 消息数据数组
136
+ * @returns {Promise<Array>} 创建的消息记录
137
+ */
138
+ async batchCreateChatMessages(messagesData) {
139
+ if (!Array.isArray(messagesData) || messagesData.length === 0) {
140
+ throw new Error('消息数据不能为空');
141
+ }
142
+ try {
143
+ const result = await ChatMessage.bulkCreate(messagesData, {
144
+ validate: true
145
+ });
146
+ console.log(`✅ 成功批量写入 ${result.length} 条聊天记录`);
147
+ return result;
148
+ }
149
+ catch (error) {
150
+ console.error('❌ 批量写入聊天记录失败:', error);
151
+ throw error;
152
+ }
153
+ }
154
+ /**
155
+ * 使用事务批量写入所有数据
156
+ * @param {Object} data - 包含所有类型数据的对象
157
+ * @param {Array} data.friends - 好友数据
158
+ * @param {Array} data.groups - 群组数据
159
+ * @param {Array} data.groupMembers - 群成员数据
160
+ * @param {Array} data.messages - 消息数据
161
+ * @returns {Promise<Object>} 写入结果
162
+ */
163
+ async batchCreateAllData(data) {
164
+ const { friends = [], groups = [], groupMembers = [], messages = [] } = data;
165
+ const transaction = await sequelize.transaction();
166
+ try {
167
+ const results = {};
168
+ // 批量写入好友信息
169
+ if (friends.length > 0) {
170
+ results.friends = await Friend.bulkCreate(friends, {
171
+ updateOnDuplicate: ['name', 'avatar', 'alias', 'remark', 'tags', 'wxNumber'],
172
+ validate: true,
173
+ transaction
174
+ });
175
+ }
176
+ // 批量写入群组信息
177
+ if (groups.length > 0) {
178
+ results.groups = await Group.bulkCreate(groups, {
179
+ updateOnDuplicate: ['name', 'avatar', 'adminId', 'memberCount'],
180
+ validate: true,
181
+ transaction
182
+ });
183
+ }
184
+ // 批量写入群成员信息
185
+ if (groupMembers.length > 0) {
186
+ results.groupMembers = await GroupMember.bulkCreate(groupMembers, {
187
+ updateOnDuplicate: ['name', 'avatar', 'alias', 'remark', 'wxNumber'],
188
+ validate: true,
189
+ transaction
190
+ });
191
+ }
192
+ // 批量写入消息记录
193
+ if (messages.length > 0) {
194
+ results.messages = await ChatMessage.bulkCreate(messages, {
195
+ validate: true,
196
+ transaction
197
+ });
198
+ }
199
+ await transaction.commit();
200
+ console.log(`✅ 事务成功提交,写入数据统计:`, {
201
+ friends: results.friends?.length || 0,
202
+ groups: results.groups?.length || 0,
203
+ groupMembers: results.groupMembers?.length || 0,
204
+ messages: results.messages?.length || 0
205
+ });
206
+ return results;
207
+ }
208
+ catch (error) {
209
+ await transaction.rollback();
210
+ console.error('❌ 事务回滚,批量写入失败:', error);
211
+ throw error;
212
+ }
213
+ }
214
+ /**
215
+ * 根据robotId查询好友列表
216
+ * @param {string} robotId - 机器人ID
217
+ * @returns {Promise<Array>} 好友列表
218
+ */
219
+ async getFriendsByRobotId(robotId) {
220
+ try {
221
+ const friends = await Friend.findAll({
222
+ where: { robotId },
223
+ order: [['createdAt', 'DESC']]
224
+ });
225
+ return friends;
226
+ }
227
+ catch (error) {
228
+ console.error('❌ 查询好友列表失败:', error);
229
+ throw error;
230
+ }
231
+ }
232
+ /**
233
+ * 根据robotId查询群组列表
234
+ * @param {string} robotId - 机器人ID
235
+ * @returns {Promise<Array>} 群组列表
236
+ */
237
+ async getGroupsByRobotId(robotId) {
238
+ try {
239
+ const groups = await Group.findAll({
240
+ where: { robotId },
241
+ include: [{
242
+ model: GroupMember,
243
+ as: 'members'
244
+ }],
245
+ order: [['createdAt', 'DESC']]
246
+ });
247
+ return groups;
248
+ }
249
+ catch (error) {
250
+ console.error('❌ 查询群组列表失败:', error);
251
+ throw error;
252
+ }
253
+ }
254
+ /**
255
+ * 根据条件查询聊天记录
256
+ * @param {Object} query - 查询条件
257
+ * @returns {Promise<Array>} 聊天记录列表
258
+ */
259
+ async getChatMessages(query = {}) {
260
+ const { robotId, conversationId, recordType, limit = 100, offset = 0 } = query;
261
+ try {
262
+ const whereClause = {};
263
+ if (robotId)
264
+ whereClause.robotId = robotId;
265
+ if (conversationId)
266
+ whereClause.conversationId = conversationId;
267
+ if (recordType)
268
+ whereClause.recordType = recordType;
269
+ const messages = await ChatMessage.findAll({
270
+ where: whereClause,
271
+ limit,
272
+ offset,
273
+ order: [['timestamp', 'DESC']]
274
+ });
275
+ return messages;
276
+ }
277
+ catch (error) {
278
+ console.error('❌ 查询聊天记录失败:', error);
279
+ throw error;
280
+ }
281
+ }
282
+ }
283
+ export default ChatDataService;
284
+ //# sourceMappingURL=ChatDataService.js.map