feat: 新增智能查数(自然语言转 SQL 只读查询)
新增「智能查数」功能:用户用自然语言提问,由大模型生成一条只读 SQL,经安全校验后在当前用户数据上执行,前端按结果形状自适应渲染为统计卡片、表格或图表。入口位于侧边栏,仅在 AI 启用时显示。 变更内容: - 后端新增 AiSqlQueryService 与 POST /api/ai/sql,新增 AiCallType.SQL 用量记录与提示词模板 ai-sql-system.tpl - 新增安全网关 TextToSqlGuard:仅允许单条 SELECT,拒绝写操作、多语句、危险函数与 SELECT INTO/FOR UPDATE;校验表白名单与 schema 前缀;递归注入 user_id 隔离(主表加 WHERE、JOIN 加 ON,覆盖括号连接与 CTE);结果上限 1000 - 表结构改由 TextToSqlSchemaProvider 从数据库元数据动态读取(60 秒缓存),白名单与表列中文说明集中在 TextToSqlTables,字段增删改无需调整提示词 - 新增 AiSqlQueryResultVO、AiSqlColumnVO,返回生成的 SQL、列元数据与行数据 - 前端新增智能查数页 SqlQuery.vue(路由 /smart-query),按结果形状渲染单行统计卡片、多行动态表格并支持柱状图与饼图切换 - 渠道列用 getChannelLabel 本地化展示,生成的 SQL 用 sql-formatter 缩进、highlight.js 高亮并支持复制 - 新增共享 useAiEnabled 状态,侧边栏「智能查数」菜单仅 AI 启用时显示,设置页保存 AI 配置后即时刷新 - 设置页与收支记录页文案补充智能查数相关三语文案 依赖与清理: - 新增前端依赖 sql-formatter、highlight.js - 移除仓库内测试文件 LedgerlyApplicationTests、PromptTemplateServiceTest、AiPromptPayloadPrivacyTest,此后测试源码不再纳入提交 说明: - 表结构动态读取保证字段变更零维护,仅可查表白名单需显式登记 - 安全网关对 JOIN 条件注入 ON 子句以保证 LEFT JOIN 语义,并对括号连接与 CTE 递归处理
This commit is contained in:
@@ -234,6 +234,36 @@ export function queryByAi(query: string) {
|
||||
return request.post('/ai/query', { query }, { timeout: 120000 })
|
||||
}
|
||||
|
||||
/** 智能查数结果的列元数据 */
|
||||
export interface AiSqlColumn {
|
||||
key: string
|
||||
title: string
|
||||
type: 'NUMBER' | 'STRING' | 'DATE' | 'DATETIME' | 'BOOLEAN'
|
||||
}
|
||||
|
||||
/** 智能查数结果 */
|
||||
export interface AiSqlQueryResult {
|
||||
/** 生成的 SQL(经安全校验后的最终语句) */
|
||||
sql: string
|
||||
/** 查询意图说明 */
|
||||
explanation: string
|
||||
/** 建议的展示类型 */
|
||||
chartType: 'SCALAR' | 'TABLE' | 'BAR' | 'PIE'
|
||||
/** 结果列元数据 */
|
||||
columns: AiSqlColumn[]
|
||||
/** 结果行数据 */
|
||||
rows: Record<string, unknown>[]
|
||||
/** 返回行数 */
|
||||
rowCount: number
|
||||
/** 是否因行数上限被截断 */
|
||||
truncated: boolean
|
||||
}
|
||||
|
||||
/** 将自然语言转换为只读 SQL 并执行查询(调用大模型,超时放宽) */
|
||||
export function queryBySql(query: string) {
|
||||
return request.post('/ai/sql', { query }, { timeout: 120000 })
|
||||
}
|
||||
|
||||
/** 自然语言记账解析结果 */
|
||||
export interface AiRecordResult {
|
||||
summary: string
|
||||
|
||||
Reference in New Issue
Block a user