| 140 | * 不依赖 FTS 索引,适用于 CLI/MCP 场景 |
| 141 | */ |
| 142 | export function searchMessagesLike( |
| 143 | db: DatabaseAdapter, |
| 144 | keyword: string, |
| 145 | options?: { limit?: number; offset?: number } |
| 146 | ): PaginatedMessages { |
| 147 | const limit = options?.limit ?? 50 |
| 148 | const offset = options?.offset ?? 0 |
| 149 | |
| 150 | const countRow = db |
| 151 | .prepare( |
| 152 | `SELECT COUNT(*) as total |
| 153 | FROM message msg |
| 154 | JOIN member m ON msg.sender_id = m.id |
| 155 | WHERE msg.content LIKE ? AND COALESCE(m.account_name, '') != '系统消息'` |
| 156 | ) |
| 157 | .get(`%${keyword}%`) as { total: number } |
| 158 | |
| 159 | const rows = db |
| 160 | .prepare( |
| 161 | `SELECT |
| 162 | msg.id as id, |
| 163 | m.id as senderId, |
| 164 | COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName, |
| 165 | m.platform_id as senderPlatformId, |
| 166 | msg.content as content, |
| 167 | msg.ts as timestamp, |
| 168 | msg.type as type |
| 169 | FROM message msg |
| 170 | JOIN member m ON msg.sender_id = m.id |
| 171 | WHERE msg.content LIKE ? AND COALESCE(m.account_name, '') != '系统消息' |
| 172 | ORDER BY msg.ts DESC |
| 173 | LIMIT ? OFFSET ?` |
| 174 | ) |
| 175 | .all(`%${keyword}%`, limit + 1, offset) as Array<{ |
| 176 | id: number |
| 177 | senderId: number |
| 178 | senderName: string |
| 179 | senderPlatformId: string |
| 180 | content: string |
| 181 | timestamp: number |
| 182 | type: number |
| 183 | }> |
| 184 | |
| 185 | const hasMore = rows.length > limit |
| 186 | const messages = rows.slice(0, limit).map((row) => ({ |
| 187 | id: Number(row.id), |
| 188 | senderId: Number(row.senderId), |
| 189 | senderName: String(row.senderName || ''), |
| 190 | senderPlatformId: String(row.senderPlatformId || ''), |
| 191 | content: row.content != null ? String(row.content) : '', |
| 192 | timestamp: Number(row.timestamp), |
| 193 | type: Number(row.type), |
| 194 | })) |
| 195 | |
| 196 | return { messages, hasMore, total: countRow.total } |
| 197 | } |
| 198 | |
| 199 | /** |