init6
This commit is contained in:
136
server/api/universal-query.post.ts
Normal file
136
server/api/universal-query.post.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* 通用高级查询API接口
|
||||
* Universal Advanced Query API Endpoint
|
||||
*/
|
||||
import type { AdvancedQueryOptions } from '@nuxt4crud/shared'
|
||||
import { prisma } from '../lib/prisma'
|
||||
import { createSqlQueryBuilder } from '../lib/sql-query-builder'
|
||||
|
||||
/**
|
||||
* 通用查询请求体接口
|
||||
* Universal query request body interface
|
||||
*/
|
||||
interface UniversalQueryRequest {
|
||||
table: string
|
||||
options: AdvancedQueryOptions
|
||||
searchFields?: string[]
|
||||
mode?: 'query' | 'aggregate'
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持的表名映射(安全检查)
|
||||
* Supported table names mapping (security check)
|
||||
*/
|
||||
const ALLOWED_TABLES = {
|
||||
Post: 'posts', // 支持 Post 表
|
||||
User: 'users', // 支持 User 表
|
||||
// 可以在这里添加更多允许查询的表
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 默认搜索字段配置
|
||||
* Default search fields configuration
|
||||
*/
|
||||
const DEFAULT_SEARCH_FIELDS: Record<string, string[]> = {
|
||||
posts: ['title', 'content'], // Post 表搜索字段
|
||||
users: ['name', 'email'], // User 表搜索字段
|
||||
// 可以为其他表配置默认搜索字段
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用高级查询API处理器
|
||||
* Universal advanced query API handler
|
||||
*/
|
||||
export default defineEventHandler(async event => {
|
||||
try {
|
||||
// 只允许POST方法
|
||||
assertMethod(event, 'POST')
|
||||
|
||||
// 获取请求体
|
||||
const body = (await readBody(event)) as UniversalQueryRequest
|
||||
|
||||
// 验证请求参数
|
||||
if (!body.table || !body.options) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: '缺少必要参数: table 和 options',
|
||||
})
|
||||
}
|
||||
|
||||
// 安全检查:验证表名是否允许
|
||||
const tableName = ALLOWED_TABLES[body.table as keyof typeof ALLOWED_TABLES]
|
||||
if (!tableName) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `不允许查询表: ${body.table}`,
|
||||
})
|
||||
}
|
||||
|
||||
// 创建SQL查询构造器
|
||||
const queryBuilder = createSqlQueryBuilder(prisma)
|
||||
|
||||
// 获取表字段信息
|
||||
const availableFields = await queryBuilder.getTableFields(tableName)
|
||||
|
||||
// 验证查询选项
|
||||
const validationErrors = queryBuilder.validateQueryOptions(body.options, availableFields)
|
||||
if (validationErrors.length > 0) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `查询参数验证失败: ${validationErrors.join(', ')}`,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取搜索字段
|
||||
const searchFields = body.searchFields || DEFAULT_SEARCH_FIELDS[tableName] || []
|
||||
|
||||
// 执行查询
|
||||
let result: any
|
||||
|
||||
if (body.mode === 'aggregate') {
|
||||
// 执行聚合查询
|
||||
result = await queryBuilder.executeAggregateQuery(tableName, body.options)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
table: tableName,
|
||||
mode: 'aggregate',
|
||||
result,
|
||||
options: body.options,
|
||||
availableFields,
|
||||
searchFields,
|
||||
},
|
||||
message: '聚合查询执行成功',
|
||||
}
|
||||
} else {
|
||||
// 执行普通查询
|
||||
result = await queryBuilder.executeQuery(tableName, body.options, searchFields)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
table: tableName,
|
||||
mode: 'query',
|
||||
...result,
|
||||
availableFields,
|
||||
searchFields,
|
||||
},
|
||||
message: '查询执行成功',
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Universal query API error:', error)
|
||||
|
||||
// 如果是已知错误,直接抛出
|
||||
if (error && typeof error === 'object' && 'statusCode' in error) {
|
||||
throw error
|
||||
}
|
||||
|
||||
// 处理未知错误
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: `查询执行失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user