feat: 完善 API Keys 批量删除功能并修复搜索跨选择问题

## 主要改进

### 🔧 核心修复
- 修复搜索时勾选状态无法保存的问题
- 优化全选/取消全选逻辑,支持跨搜索结果保持选择状态
- 改进批量删除的用户体验
- 添加 Unicode 字符处理中间件,提升请求体解析稳定性

### 🎯 具体变更
- **路由修复**: 解决批量删除路由匹配问题,调整路由顺序
- **API客户端**: 修复 DELETE 方法支持请求体数据传输
- **前端逻辑**: 分离筛选和搜索的监听器,搜索时保持已选中状态
- **全选优化**: 取消全选时只移除当前页选中项,保留其他页面选择
- **Unicode处理**: 添加无效 UTF-16 代理对清理和错误处理机制
- **配置管理**: 将 .mcp.json 添加到 .gitignore,避免本地配置被提交

### 🚀 用户体验提升
- 支持跨搜索结果批量选择和删除
- 批量删除按钮显示选中数量
- 智能的全选状态管理
- 更好的 Unicode 字符处理容错性

### 🧪 测试验证
- 验证搜索切换时选择状态保持
- 确认批量删除功能正常工作
- 检查 Redis 数据清理完整性
- 测试 Unicode 字符处理稳定性

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
iRubbish
2025-08-19 09:46:33 +08:00
parent f642fa7095
commit 1ee71ffbc9
7 changed files with 304 additions and 38 deletions

View File

@@ -141,10 +141,62 @@ class Application {
if (buf && buf.length && !buf.toString(encoding || 'utf8').trim()) {
throw new Error('Invalid JSON: empty body')
}
// Unicode 字符清理 - 清理无效的 UTF-16 代理对
if (buf && buf.length) {
try {
const str = buf.toString(encoding || 'utf8')
// 移除无效的 UTF-16 代理对字符
const cleanedStr = str.replace(
/[\uDC00-\uDFFF](?![\uD800-\uDBFF])|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/g,
'\uFFFD'
)
// 如果字符串被清理过重新写入buffer
if (cleanedStr !== str) {
logger.warn('🧹 Cleaned invalid Unicode characters from request body')
const cleanedBuf = Buffer.from(cleanedStr, encoding || 'utf8')
// 将清理后的内容复制回原buffer
cleanedBuf.copy(buf, 0)
// 调整buffer长度
buf._charsWritten = cleanedBuf.length
}
} catch (error) {
logger.warn(
'⚠️ Unicode cleaning failed, proceeding with original buffer:',
error.message
)
}
}
}
})
)
this.app.use(express.urlencoded({ extended: true, limit: '10mb' }))
// 🧹 Unicode 错误处理中间件
this.app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
// 检查是否是Unicode相关的JSON解析错误
if (
err.message.includes('surrogate') ||
err.message.includes('UTF-16') ||
err.message.includes('invalid character')
) {
logger.warn('🧹 Detected Unicode JSON parsing error, attempting recovery:', err.message)
return res.status(400).json({
type: 'error',
error: {
type: 'invalid_request_error',
message:
'The request body contains invalid Unicode characters. Please ensure your text uses valid UTF-8 encoding and does not contain malformed surrogate pairs.'
}
})
}
}
next(err)
})
this.app.use(securityMiddleware)
// 🎯 信任代理