feat: 交易渠道重命名、账单来源统计默认值、AI 规则生成与统计搜索,AI 改用 openai-java SDK
- 交易记录「支付方式」全链路重命名为「交易渠道」(channel):DB 列、实体/DTO/VO、接口 /api/transaction/channels、统计维度 CHANNEL、AI 提示词与 JSON 字段、前端与中英日文案;新增 SchemaMigrator 在启动/切换数据源时幂等迁移列名(MySQL 用 information_schema、SQLite 用 PRAGMA) - 按账单来源设置「计入统计」默认值:AppConfig 持久化 + GET/PUT /api/app/bill-source-include-in-stats,导入解析按「解析器判定 && 来源默认」应用并覆盖上传与邮箱两条路径,设置页新增面板 - AI 生成规则:基于所选已打标签记录归纳分类/标签规则(POST /api/ai/rule/suggest、/api/ai/rule/apply),规则页两步弹窗(选择记录→预览创建),支持候选记录分页/搜索/筛选;按「类型+关键词+分类+标签」签名与已有规则去重,重复项标记「已存在」并禁止导入 - 规则列表新增分页与搜索:GET /api/rule/page(名称/关键词、启用状态、收支类型) - 统计面板 AI 搜索:POST /api/ai/statistics 将自然语言解析为时间/类型/分类/标签/渠道/金额/统计口径/趋势粒度并回填;交互对齐账单列表 AI 查询(弹窗 + 历史 + 示例 + 空条件守卫);统计后端补充标签筛选,仪表盘新增标签筛选与 AI 搜索 - AI 客户端改用 OpenAI 官方 Java SDK(com.openai:openai-java),自定义 baseUrl 指向 DeepSeek,保留 chat 签名与 DeepSeekResponse - AI 数据外发收敛:分类/标签建议与规则生成不再发送 rawData 与金额,仅发送类型/备注/渠道/分类/标签;新增 AiCallType.RULE / STATISTICS - 收支记录页新增「刷新」按钮
This commit is contained in:
@@ -28,11 +28,12 @@ export default {
|
||||
deleteSuccess: { zh: '删除成功', en: 'Deleted successfully', ja: '削除しました' },
|
||||
deleteFailed: { zh: '删除失败', en: 'Failed to delete', ja: '削除に失敗しました' },
|
||||
confirmDelete: { zh: '确认删除', en: 'Confirm Deletion', ja: '削除の確認' },
|
||||
refresh: { zh: '刷新', en: 'Refresh', ja: '更新' },
|
||||
types: {
|
||||
expense: { zh: '支出', en: 'Expense', ja: '支出' },
|
||||
income: { zh: '收入', en: 'Income', ja: '収入' },
|
||||
},
|
||||
payment: {
|
||||
channel: {
|
||||
wechat: { zh: '微信', en: 'WeChat', ja: 'WeChat' },
|
||||
alipay: { zh: '支付宝', en: 'Alipay', ja: 'Alipay' },
|
||||
cash: { zh: '现金', en: 'Cash', ja: '現金' },
|
||||
@@ -135,9 +136,21 @@ export default {
|
||||
aiSection: { zh: 'AI 模型配置', en: 'AI Model', ja: 'AI モデル' },
|
||||
viewUsage: { zh: '使用情况', en: 'Usage', ja: '利用状況' },
|
||||
registrationSection: { zh: '注册设置', en: 'Registration', ja: '登録設定' },
|
||||
billSourceStatsSection: { zh: '账单来源统计默认值', en: 'Bill Source Stats Defaults', ja: '請求元の集計既定値' },
|
||||
notificationSection: { zh: '定时通知', en: 'Scheduled Notifications', ja: '定期通知' },
|
||||
},
|
||||
|
||||
// 账单来源统计默认值
|
||||
billSourceStats: {
|
||||
hint: { zh: '设置各账单来源导入时是否默认计入统计;不计入的记录仍会导入,但不参与统计', en: 'Set whether bills from each source count toward statistics by default. Excluded records are still imported but not counted.', ja: '各請求元の取り込み時に集計へ含めるかを設定します。除外した記録も取り込みますが集計対象外になります。' },
|
||||
included: { zh: '计入统计', en: 'Included', ja: '集計対象' },
|
||||
excluded: { zh: '不计入统计', en: 'Excluded', ja: '集計対象外' },
|
||||
save: { zh: '保存', en: 'Save', ja: '保存' },
|
||||
loadFailed: { zh: '加载账单来源统计默认值失败', en: 'Failed to load bill source stats defaults', ja: '請求元の集計既定値の読み込みに失敗しました' },
|
||||
saveSuccess: { zh: '账单来源统计默认值已保存', en: 'Bill source stats defaults saved', ja: '請求元の集計既定値を保存しました' },
|
||||
saveFailed: { zh: '保存账单来源统计默认值失败', en: 'Failed to save bill source stats defaults', ja: '請求元の集計既定値の保存に失敗しました' },
|
||||
},
|
||||
|
||||
// 注册设置
|
||||
registration: {
|
||||
statusOn: { zh: '已开启', en: 'Enabled', ja: '有効' },
|
||||
@@ -295,7 +308,16 @@ export default {
|
||||
},
|
||||
filterType: { zh: '类型', en: 'Type', ja: '種類' },
|
||||
filterCategory: { zh: '分类', en: 'Category', ja: 'カテゴリ' },
|
||||
filterPaymentMethod: { zh: '支付方式', en: 'Payment Method', ja: '支払方法' },
|
||||
filterChannel: { zh: '交易渠道', en: 'Channel', ja: '取引チャネル' },
|
||||
filterTag: { zh: '标签', en: 'Tag', ja: 'タグ' },
|
||||
aiSearchPlaceholder: { zh: '用一句话描述统计需求,如「上个月餐饮花了多少」', en: 'Describe what to analyze, e.g. "How much did I spend on dining last month?"', ja: '集計したい内容を文章で入力(例:先月の飲食費は?)' },
|
||||
aiSearchButton: { zh: 'AI 搜索', en: 'AI Search', ja: 'AI 検索' },
|
||||
aiSearchEmpty: { zh: '请输入统计需求', en: 'Please enter a query', ja: '検索内容を入力してください' },
|
||||
aiSearchApplied: { zh: '已按 AI 解析结果更新统计', en: 'Statistics updated from AI parsing', ja: 'AI の解析結果で統計を更新しました' },
|
||||
aiSearchFailed: { zh: 'AI 统计搜索失败', en: 'AI statistics search failed', ja: 'AI 統計検索に失敗しました' },
|
||||
aiExample1: { zh: '上个月餐饮花了多少', en: 'How much on dining last month?', ja: '先月の飲食費は?' },
|
||||
aiExample2: { zh: '近半年交通支出趋势,按周看', en: 'Transport spending trend over the last 6 months, weekly', ja: '直近半年の交通費の推移を週別で' },
|
||||
aiExample3: { zh: '今年各类支出占比', en: 'Expense breakdown by category this year', ja: '今年のカテゴリ別支出割合' },
|
||||
minAmount: { zh: '最小金额', en: 'Min Amount', ja: '最小金額' },
|
||||
maxAmount: { zh: '最大金额', en: 'Max Amount', ja: '最大金額' },
|
||||
remark: { zh: '备注搜索', en: 'Search Remark', ja: '備考検索' },
|
||||
@@ -311,8 +333,8 @@ export default {
|
||||
trend: { zh: '收支趋势', en: 'Income & Expense Trend', ja: '収支の推移' },
|
||||
expenseCategoryPie: { zh: '支出分类占比', en: 'Expense by Category', ja: '支出カテゴリの割合' },
|
||||
incomeCategoryPie: { zh: '收入分类占比', en: 'Income by Category', ja: '収入カテゴリの割合' },
|
||||
expensePaymentPie: { zh: '支出支付方式占比', en: 'Expense by Payment Method', ja: '支出の支払方法の割合' },
|
||||
incomePaymentPie: { zh: '收入支付方式占比', en: 'Income by Payment Method', ja: '収入の支払方法の割合' },
|
||||
expenseChannelPie: { zh: '支出交易渠道占比', en: 'Expense by Channel', ja: '支出の取引チャネル割合' },
|
||||
incomeChannelPie: { zh: '收入交易渠道占比', en: 'Income by Channel', ja: '収入の取引チャネル割合' },
|
||||
uncategorized: { zh: '未分类', en: 'Uncategorized', ja: '未分類' },
|
||||
},
|
||||
|
||||
@@ -349,7 +371,7 @@ export default {
|
||||
type: { zh: '类型', en: 'Type', ja: '種類' },
|
||||
category: { zh: '分类', en: 'Category', ja: 'カテゴリ' },
|
||||
amount: { zh: '金额', en: 'Amount', ja: '金額' },
|
||||
paymentMethod: { zh: '支付方式', en: 'Payment', ja: '支払方法' },
|
||||
channel: { zh: '交易渠道', en: 'Channel', ja: '取引チャネル' },
|
||||
remark: { zh: '备注', en: 'Remark', ja: '備考' },
|
||||
tags: { zh: '标签', en: 'Tags', ja: 'タグ' },
|
||||
includeInStats: { zh: '计入统计', en: 'In Stats', ja: '集計対象' },
|
||||
@@ -391,7 +413,7 @@ export default {
|
||||
validAmount: { zh: '请输入有效金额', en: 'Please enter a valid amount', ja: '有効な金額を入力してください' },
|
||||
selectCategoryPlaceholder: { zh: '请选择分类', en: 'Select a category', ja: 'カテゴリを選択' },
|
||||
amountPlaceholder: { zh: '请输入金额', en: 'Enter amount', ja: '金額を入力してください' },
|
||||
paymentPlaceholder: { zh: '选择支付方式', en: 'Select payment method', ja: '支払方法を選択' },
|
||||
channelPlaceholder: { zh: '选择交易渠道', en: 'Select channel', ja: '取引チャネルを選択' },
|
||||
remarkPlaceholder: { zh: '可选备注说明', en: 'Optional remark', ja: '備考(任意)' },
|
||||
remarkHistoryClear: { zh: '清空历史', en: 'Clear history', ja: '履歴をクリア' },
|
||||
tagPlaceholder: { zh: '选择标签', en: 'Select tags', ja: 'タグを選択' },
|
||||
@@ -480,6 +502,10 @@ export default {
|
||||
deleteConfirm: { zh: '确定要删除这个规则吗?', en: 'Are you sure you want to delete this rule?', ja: 'このルールを削除してもよろしいですか?' },
|
||||
loadCategoriesFailed: { zh: '加载分类失败', en: 'Failed to load categories', ja: 'カテゴリの読み込みに失敗しました' },
|
||||
loadTagsFailed: { zh: '加载标签失败', en: 'Failed to load tags', ja: 'タグの読み込みに失敗しました' },
|
||||
searchPlaceholder: { zh: '搜索规则名称或关键词', en: 'Search name or keyword', ja: 'ルール名またはキーワードを検索' },
|
||||
status: { zh: '启用状态', en: 'Status', ja: '有効状態' },
|
||||
statusOn: { zh: '已启用', en: 'Enabled', ja: '有効' },
|
||||
statusOff: { zh: '已停用', en: 'Disabled', ja: '無効' },
|
||||
},
|
||||
|
||||
// 账单导入
|
||||
@@ -601,6 +627,28 @@ export default {
|
||||
nameRequired: { zh: '请先输入名称', en: 'Please enter a name first', ja: '先に名前を入力してください' },
|
||||
failed: { zh: 'AI 推荐失败', en: 'AI recommendation failed', ja: 'AI の提案に失敗しました' },
|
||||
},
|
||||
rule: {
|
||||
entry: { zh: 'AI 生成规则', en: 'AI Generate Rules', ja: 'AI でルール生成' },
|
||||
title: { zh: 'AI 生成规则建议', en: 'AI Rule Suggestions', ja: 'AI ルール提案' },
|
||||
hint: { zh: 'AI 将依据所选记录的已有标签与分类,生成分类与标签规则建议,可编辑后勾选创建', en: 'AI derives rules from the tags and categories of the selected records; edit and select to create.', ja: 'AI が選択した記録の既存タグとカテゴリからルールを提案します。編集して選択後に作成できます。' },
|
||||
selectHint: { zh: '选择要用于生成规则的已打标签记录(默认全选当前页,已选 {count} 条)', en: 'Select tagged records to derive rules (current page selected by default, {count} selected)', ja: 'ルール生成に使うタグ付き記録を選択(既定で現在ページを全選択、選択中 {count} 件)' },
|
||||
searchPlaceholder: { zh: '搜索备注', en: 'Search remark', ja: '備考を検索' },
|
||||
selectPageAll: { zh: '全选本页', en: 'Select page', ja: 'このページを全選択' },
|
||||
clearSelection: { zh: '清空选择', en: 'Clear selection', ja: '選択をクリア' },
|
||||
generate: { zh: '生成规则', en: 'Generate rules', ja: 'ルールを生成' },
|
||||
back: { zh: '返回上一步', en: 'Back', ja: '戻る' },
|
||||
noTagged: { zh: '暂无可用的已打标签记录', en: 'No tagged records available', ja: 'タグ付きの記録がありません' },
|
||||
loadRecordsFailed: { zh: '加载已打标签记录失败', en: 'Failed to load tagged records', ja: 'タグ付き記録の読み込みに失敗しました' },
|
||||
reason: { zh: '理由', en: 'Reason', ja: '理由' },
|
||||
newPrefix: { zh: '新建:', en: 'New: ', ja: '新規:' },
|
||||
apply: { zh: '创建勾选规则', en: 'Create selected', ja: '選択したルールを作成' },
|
||||
selectRequired: { zh: '请至少勾选一条记录或规则', en: 'Please select at least one record or rule', ja: '少なくとも1件の記録またはルールを選択してください' },
|
||||
applied: { zh: '已创建 {count} 条规则', en: 'Created {count} rule(s)', ja: '{count} 件のルールを作成しました' },
|
||||
failed: { zh: 'AI 规则生成失败', en: 'Failed to generate AI rules', ja: 'AI ルールの生成に失敗しました' },
|
||||
applyFailed: { zh: '创建规则失败', en: 'Failed to create rules', ja: 'ルールの作成に失敗しました' },
|
||||
duplicate: { zh: '已存在', en: 'Exists', ja: '既存' },
|
||||
allDuplicate: { zh: '生成的规则均已存在,无需创建', en: 'All generated rules already exist', ja: '生成されたルールはすべて既存です' },
|
||||
},
|
||||
category: {
|
||||
label: { zh: 'AI 生成分类', en: 'AI Category', ja: 'AI 生成カテゴリ' },
|
||||
placeholder: { zh: '描述用途,如:日常通勤打车地铁', en: 'Describe it, e.g. daily commute by taxi and metro', ja: '用途を説明してください(例:日常の通勤でタクシーと地下鉄)' },
|
||||
@@ -643,7 +691,7 @@ export default {
|
||||
type: { zh: '类型', en: 'Type', ja: '種類' },
|
||||
category: { zh: '分类', en: 'Category', ja: 'カテゴリ' },
|
||||
tag: { zh: '标签', en: 'Tag', ja: 'タグ' },
|
||||
payment: { zh: '支付方式', en: 'Payment', ja: '支払方法' },
|
||||
channel: { zh: '交易渠道', en: 'Channel', ja: '取引チャネル' },
|
||||
dateRange: { zh: '时间范围', en: 'Date range', ja: '期間' },
|
||||
amountRange: { zh: '金额范围', en: 'Amount range', ja: '金額範囲' },
|
||||
remark: { zh: '备注', en: 'Remark', ja: '備考' },
|
||||
|
||||
Reference in New Issue
Block a user