feat: 扩展 AI 记账能力并优化收支记录交互

- AI 能力:新增分类 Emoji 推荐、标签颜色推荐、自然语言生成分类/标签、单条记录分类推荐

- AI 批量建议:按类型+支付方式+备注去重聚合后分批调用,支持分类/标签/两者范围并记忆偏好,结果可勾选应用

- 分类/标签管理:新增 EmojiPicker 与预设色板,支持 AI 一键推荐并在列表可视化

- 收支记录:新增序号列,标签筛选支持无标签,编辑记录时允许不设置分类

- 修复:账单导入未选择默认标签时生成空 IN 列表导致的 SQL 语法错误

- AI 未启用时隐藏所有 AI 入口与弹窗
This commit is contained in:
2026-09-18 09:57:53 +08:00
parent 49c70a732d
commit a8ef91ed3d
30 changed files with 2009 additions and 132 deletions
+47 -4
View File
@@ -10,9 +10,11 @@ export interface AiConfig {
model: string
}
/** 单条 AI 建议 */
/** 单条 AI 建议(按类型、备注、支付方式聚合后的一组记录) */
export interface AiSuggestion {
transactionId: number
transactionIds: number[]
count: number
categoryId: number | null
categoryName: string | null
tagIds: number[]
@@ -35,9 +37,50 @@ export function testAiConfig() {
return request.post('/ai/config/test', {}, { timeout: 60000 })
}
/** 生成分类与标签建议(调用大模型,超时放宽) */
export function suggestByAi(ids: number[]) {
return request.post('/ai/suggest', { ids }, { timeout: 120000 })
/** 生成分类与标签建议(scope:BOTH/CATEGORY/TAG;重复记录聚合后按批调用,超时按批数放宽) */
export function suggestByAi(ids: number[], scope = 'BOTH') {
const batches = Math.max(1, Math.ceil(ids.length / 100))
return request.post('/ai/suggest', { ids, scope }, { timeout: Math.min(Math.max(120000, batches * 90000), 600000) })
}
/** AI 生成的分类建议 */
export interface AiCategoryResult {
name: string
type: string
icon: string
reason: string
}
/** 根据自然语言描述生成分类(调用大模型,超时放宽) */
export function parseCategoryByAi(text: string) {
return request.post('/ai/category', { text }, { timeout: 60000 })
}
/** AI 生成的标签建议 */
export interface AiTagResult {
name: string
color: string
reason: string
}
/** 根据自然语言描述生成标签(调用大模型,超时放宽) */
export function parseTagByAi(text: string) {
return request.post('/ai/tag', { text }, { timeout: 60000 })
}
/** 根据表单当前内容生成单条分类与标签建议(调用大模型,超时放宽) */
export function suggestOneByAi(data: { type: string; amount?: number | null; paymentMethod?: string; remark?: string }) {
return request.post('/ai/suggest-one', data, { timeout: 60000 })
}
/** AI 推荐分类 Emoji 图标(调用大模型,超时放宽) */
export function suggestEmoji(name: string, type?: string) {
return request.post('/ai/emoji', { name, type }, { timeout: 60000 })
}
/** AI 推荐标签颜色(调用大模型,超时放宽) */
export function suggestColor(name: string) {
return request.post('/ai/color', { name }, { timeout: 60000 })
}
/** 一键应用建议:覆盖分类并追加标签 */
+2 -2
View File
@@ -38,9 +38,9 @@ export function createTransaction(data: {
return request.post('/transaction', data)
}
/** 更新指定交易记录 */
/** 更新指定交易记录(categoryId 为空表示不设置分类) */
export function updateTransaction(id: number, data: {
categoryId: number
categoryId: number | null
type: string
amount: number
paymentMethod?: string