Files
DianZhanDemo/server/api/universal-query.post.ts

137 lines
3.6 KiB
TypeScript
Raw Normal View History

2025-12-11 02:09:07 +08:00
/**
* 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 : '未知错误'}`,
})
}
})