Files
ledgerly/frontend/src/locales/messages.ts
T
rosercode c1f5d02564 feat: 支持数据库运行时配置与多数据库,重构设置页并完善打包
- 数据库支持 SQLite / MySQL 运行时配置与切换,未配置时仍可启动,配置后自动建表
- 新增默认分类与标签初始化,注册用户自动创建
- 新增注册开关(默认关闭,可在系统设置开启;无用户时允许创建首个账号)
- 合并数据库、注册与 AI 配置为「系统设置」页,拆分「模型使用情况」独立页面
- AI 一键设置支持新建分类与标签
- 前端构建产物打包进可执行 jar,后端增加 SPA 路由回退
- jar 更名为 finance-app,补全 Gradle Wrapper,移除 archive 任务
- 更新 DeepSeek 模型说明文案
2026-09-18 12:33:41 +08:00

520 lines
45 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 多语言消息定义:每个 key 同时维护中文(zh)、英文(en)与日文(ja),一一对应,便于对照维护
export default {
// 语言名称(用于切换器展示,始终以自身语言呈现)
locale: {
zhCN: { zh: '简体中文', en: '简体中文', ja: '简体中文' },
enUS: { zh: 'English', en: 'English', ja: 'English' },
jaJP: { zh: '日本語', en: '日本語', ja: '日本語' },
},
// 通用文案与枚举
common: {
confirm: { zh: '确定', en: 'Confirm', ja: '確認' },
cancel: { zh: '取消', en: 'Cancel', ja: 'キャンセル' },
delete: { zh: '删除', en: 'Delete', ja: '削除' },
edit: { zh: '编辑', en: 'Edit', ja: '編集' },
operation: { zh: '操作', en: 'Actions', ja: '操作' },
name: { zh: '名称', en: 'Name', ja: '名前' },
type: { zh: '类型', en: 'Type', ja: '種類' },
sort: { zh: '排序', en: 'Order', ja: '並び順' },
all: { zh: '全部', en: 'All', ja: 'すべて' },
min: { zh: '最小', en: 'Min', ja: '最小' },
max: { zh: '最大', en: 'Max', ja: '最大' },
reset: { zh: '重置', en: 'Reset', ja: 'リセット' },
loadFailed: { zh: '加载失败', en: 'Failed to load', ja: '読み込みに失敗しました' },
operationFailed: { zh: '操作失败', en: 'Operation failed', ja: '操作に失敗しました' },
createSuccess: { zh: '创建成功', en: 'Created successfully', ja: '作成しました' },
updateSuccess: { zh: '修改成功', en: 'Updated successfully', ja: '更新しました' },
deleteSuccess: { zh: '删除成功', en: 'Deleted successfully', ja: '削除しました' },
deleteFailed: { zh: '删除失败', en: 'Failed to delete', ja: '削除に失敗しました' },
confirmDelete: { zh: '确认删除', en: 'Confirm Deletion', ja: '削除の確認' },
types: {
expense: { zh: '支出', en: 'Expense', ja: '支出' },
income: { zh: '收入', en: 'Income', ja: '収入' },
},
payment: {
wechat: { zh: '微信', en: 'WeChat', ja: 'WeChat' },
alipay: { zh: '支付宝', en: 'Alipay', ja: 'Alipay' },
cash: { zh: '现金', en: 'Cash', ja: '現金' },
bank: { zh: '银行卡', en: 'Bank Card', ja: '銀行カード' },
},
},
// 登录页
login: {
title: { zh: '收支管理系统 - 登录', en: 'Finance Manager - Sign In', ja: '収支管理システム - ログイン' },
username: { zh: '用户名', en: 'Username', ja: 'ユーザー名' },
password: { zh: '密码', en: 'Password', ja: 'パスワード' },
usernamePlaceholder: { zh: '请输入用户名', en: 'Enter your username', ja: 'ユーザー名を入力してください' },
passwordPlaceholder: { zh: '请输入密码', en: 'Enter your password', ja: 'パスワードを入力してください' },
submit: { zh: '登录', en: 'Sign In', ja: 'ログイン' },
toRegister: { zh: '没有账号?去注册', en: "Don't have an account? Sign up", ja: 'アカウントをお持ちでない方は新規登録' },
fillRequired: { zh: '请填写用户名和密码', en: 'Please enter username and password', ja: 'ユーザー名とパスワードを入力してください' },
success: { zh: '登录成功', en: 'Signed in successfully', ja: 'ログインしました' },
failed: { zh: '登录失败', en: 'Sign in failed', ja: 'ログインに失敗しました' },
},
// 注册页
register: {
title: { zh: '收支管理系统 - 注册', en: 'Finance Manager - Sign Up', ja: '収支管理システム - 新規登録' },
username: { zh: '用户名', en: 'Username', ja: 'ユーザー名' },
nickname: { zh: '昵称', en: 'Nickname', ja: 'ニックネーム' },
password: { zh: '密码', en: 'Password', ja: 'パスワード' },
confirmPassword: { zh: '确认密码', en: 'Confirm Password', ja: 'パスワードの確認' },
usernamePlaceholder: { zh: '3-50个字符', en: '3-50 characters', ja: '3~50文字' },
nicknamePlaceholder: { zh: '可选', en: 'Optional', ja: '任意' },
passwordPlaceholder: { zh: '至少6个字符', en: 'At least 6 characters', ja: '6文字以上' },
confirmPasswordPlaceholder: { zh: '再次输入密码', en: 'Enter the password again', ja: 'パスワードをもう一度入力してください' },
submit: { zh: '注册', en: 'Sign Up', ja: '新規登録' },
toLogin: { zh: '已有账号?去登录', en: 'Already have an account? Sign in', ja: 'アカウントをお持ちの方はログイン' },
fillRequired: { zh: '请填写用户名和密码', en: 'Please enter username and password', ja: 'ユーザー名とパスワードを入力してください' },
usernameMin: { zh: '用户名至少3个字符', en: 'Username must be at least 3 characters', ja: 'ユーザー名は3文字以上で入力してください' },
passwordMin: { zh: '密码至少6个字符', en: 'Password must be at least 6 characters', ja: 'パスワードは6文字以上で入力してください' },
passwordMismatch: { zh: '两次密码不一致', en: 'The two passwords do not match', ja: 'パスワードが一致しません' },
success: { zh: '注册成功,请登录', en: 'Registered successfully, please sign in', ja: '登録しました。ログインしてください' },
failed: { zh: '注册失败', en: 'Registration failed', ja: '登録に失敗しました' },
},
// 主布局
layout: {
appTitle: { zh: '收支管理', en: 'Finance Manager', ja: '収支管理' },
dashboard: { zh: '统计面板', en: 'Dashboard', ja: 'ダッシュボード' },
transactions: { zh: '收支记录', en: 'Transactions', ja: '収支記録' },
categories: { zh: '分类管理', en: 'Categories', ja: 'カテゴリ管理' },
tags: { zh: '标签管理', en: 'Tags', ja: 'タグ管理' },
settings: { zh: '系统设置', en: 'Settings', ja: 'システム設定' },
user: { zh: '用户', en: 'User', ja: 'ユーザー' },
logout: { zh: '退出', en: 'Sign Out', ja: 'ログアウト' },
},
// 数据库设置
database: {
title: { zh: '数据库设置', en: 'Database Settings', ja: 'データベース設定' },
setupTitle: { zh: '初始化数据库', en: 'Initialize Database', ja: 'データベースの初期化' },
intro: { zh: '可选择本地 SQLite 文件数据库或 MySQL 数据库。保存后立即生效并自动建表,原有数据库的数据保持不变。', en: 'Choose a local SQLite file database or a MySQL database. Changes take effect immediately with automatic table creation; data in the previous database is preserved.', ja: 'ローカルの SQLite ファイルデータベースまたは MySQL を選択できます。保存すると即時に反映され、テーブルが自動作成されます。以前のデータベースのデータは保持されます。' },
setupIntro: { zh: '首次使用请先完成数据库配置。推荐零配置的 SQLite(本地文件),也可以连接已有的 MySQL。', en: 'Please configure a database before first use. SQLite (local file) requires no setup; you may also connect to an existing MySQL.', ja: '初回利用の前にデータベースを設定してください。設定不要の SQLite(ローカルファイル)を推奨します。既存の MySQL に接続することもできます。' },
setupHint: { zh: '配置完成后即可登录使用;如需修改,可稍后在「数据库设置」中调整。', en: 'After configuration you can sign in. You can adjust it later in Database Settings.', ja: '設定後はログインして利用できます。後で「データベース設定」から変更できます。' },
configured: { zh: '已配置', en: 'Configured', ja: '設定済み' },
notConfigured: { zh: '未配置', en: 'Not configured', ja: '未設定' },
currentType: { zh: '当前类型', en: 'Current type', ja: '現在の種類' },
currentSummary: { zh: '连接地址', en: 'Connection', ja: '接続先' },
configFile: { zh: '配置文件', en: 'Config file', ja: '設定ファイル' },
type: { zh: '数据库类型', en: 'Database type', ja: 'データベースの種類' },
sqlitePath: { zh: '数据库文件', en: 'Database file', ja: 'データベースファイル' },
sqlitePathPlaceholder: { zh: '例如 data/finance.db', en: 'e.g. data/finance.db', ja: '例:data/finance.db' },
sqliteHint: { zh: 'SQLite 为本地单文件数据库,路径相对于服务运行目录;建议使用 data 目录并做好持久化挂载。', en: 'SQLite is a single local file; the path is relative to the server working directory. Use a data directory with persistent storage.', ja: 'SQLite はローカルの単一ファイルです。パスはサーバーの作業ディレクトリからの相対パスです。data ディレクトリと永続化ストレージの利用を推奨します。' },
sqlitePathRequired: { zh: '请填写 SQLite 数据库文件路径', en: 'Please enter the SQLite database file path', ja: 'SQLite データベースファイルのパスを入力してください' },
mysqlRequired: { zh: '请填写主机地址、数据库名与用户名', en: 'Please fill in host, database and username', ja: 'ホスト、データベース名、ユーザー名を入力してください' },
host: { zh: '主机地址', en: 'Host', ja: 'ホスト' },
port: { zh: '端口', en: 'Port', ja: 'ポート' },
database: { zh: '数据库名', en: 'Database', ja: 'データベース名' },
username: { zh: '用户名', en: 'Username', ja: 'ユーザー名' },
password: { zh: '密码', en: 'Password', ja: 'パスワード' },
passwordPlaceholder: { zh: '请输入密码', en: 'Enter password', ja: 'パスワードを入力してください' },
passwordKeep: { zh: '已配置,留空表示不修改', en: 'Configured; leave blank to keep unchanged', ja: '設定済み。空欄のままにすると変更されません' },
test: { zh: '测试连接', en: 'Test connection', ja: '接続テスト' },
save: { zh: '保存并应用', en: 'Save & Apply', ja: '保存して適用' },
testSuccess: { zh: '连接成功', en: 'Connection succeeded', ja: '接続に成功しました' },
testFailed: { zh: '连接失败', en: 'Connection failed', ja: '接続に失敗しました' },
saveSuccess: { zh: '数据库配置已保存并生效', en: 'Database configuration saved and applied', ja: 'データベース設定を保存して適用しました' },
saveFailed: { zh: '数据库配置失败', en: 'Failed to configure database', ja: 'データベース設定に失敗しました' },
loadFailed: { zh: '加载数据库状态失败', en: 'Failed to load database status', ja: 'データベース状態の読み込みに失敗しました' },
},
// 系统设置
settings: {
title: { zh: '系统设置', en: 'Settings', ja: 'システム設定' },
databaseSection: { zh: '数据库配置', en: 'Database', ja: 'データベース' },
aiSection: { zh: 'AI 模型配置', en: 'AI Model', ja: 'AI モデル' },
viewUsage: { zh: '使用情况', en: 'Usage', ja: '利用状況' },
registrationSection: { zh: '注册设置', en: 'Registration', ja: '登録設定' },
},
// 注册设置
registration: {
statusOn: { zh: '已开启', en: 'Enabled', ja: '有効' },
statusOff: { zh: '已关闭', en: 'Disabled', ja: '無効' },
enabledHint: { zh: '关闭后新用户无法注册;系统无任何用户时仍可创建首个账号', en: 'When off, new users cannot sign up; the first account can still be created when there are no users.', ja: 'オフにすると新規登録できません。ユーザーが一人もいない場合は最初のアカウントを作成できます。' },
firstUserHint: { zh: '当前系统暂无用户,可直接注册首个账号', en: 'No users yet — you can register the first account directly.', ja: '現在ユーザーがいないため、最初のアカウントを直接登録できます。' },
save: { zh: '保存', en: 'Save', ja: '保存' },
saveSuccess: { zh: '注册设置已保存', en: 'Registration settings saved', ja: '登録設定を保存しました' },
saveFailed: { zh: '保存注册设置失败', en: 'Failed to save registration settings', ja: '登録設定の保存に失敗しました' },
loadFailed: { zh: '加载注册状态失败', en: 'Failed to load registration status', ja: '登録状態の読み込みに失敗しました' },
},
// 模型使用情况
aiUsage: {
title: { zh: '模型使用情况', en: 'Model Usage', ja: 'モデル利用状況' },
back: { zh: '返回设置', en: 'Back to Settings', ja: '設定に戻る' },
},
// 统计面板
dashboard: {
title: { zh: '统计面板', en: 'Dashboard', ja: 'ダッシュボード' },
range: {
month: { zh: '本月', en: 'This Month', ja: '今月' },
'3month': { zh: '近3月', en: 'Last 3 Months', ja: '過去3か月' },
'12month': { zh: '近12月', en: 'Last 12 Months', ja: '過去12か月' },
custom: { zh: '自定义', en: 'Custom', ja: 'カスタム' },
},
granularity: {
day: { zh: '按日', en: 'Daily', ja: '日別' },
week: { zh: '按周', en: 'Weekly', ja: '週別' },
month: { zh: '按月', en: 'Monthly', ja: '月別' },
quarter: { zh: '按季', en: 'Quarterly', ja: '四半期別' },
year: { zh: '按年', en: 'Yearly', ja: '年別' },
},
filterType: { zh: '类型', en: 'Type', ja: '種類' },
filterCategory: { zh: '分类', en: 'Category', ja: 'カテゴリ' },
filterPaymentMethod: { zh: '支付方式', en: 'Payment Method', ja: '支払方法' },
minAmount: { zh: '最小金额', en: 'Min Amount', ja: '最小金額' },
maxAmount: { zh: '最大金额', en: 'Max Amount', ja: '最大金額' },
remark: { zh: '备注搜索', en: 'Search Remark', ja: '備考検索' },
resetFilters: { zh: '重置筛选', en: 'Reset Filters', ja: 'フィルターをリセット' },
totalIncome: { zh: '总收入', en: 'Total Income', ja: '総収入' },
totalExpense: { zh: '总支出', en: 'Total Expense', ja: '総支出' },
balance: { zh: '结余', en: 'Balance', ja: '収支' },
transactionCount: { zh: '交易笔数', en: 'Transactions', ja: '取引件数' },
avgDailyIncome: { zh: '日均收入', en: 'Avg. Daily Income', ja: '1日平均収入' },
avgDailyExpense: { zh: '日均支出', en: 'Avg. Daily Expense', ja: '1日平均支出' },
maxExpense: { zh: '最大单笔支出', en: 'Largest Expense', ja: '最大の支出' },
avgExpense: { zh: '平均每笔支出', en: 'Avg. Expense', ja: '平均支出' },
trend: { zh: '收支趋势', en: 'Income & Expense Trend', ja: '収支の推移' },
expenseCategoryPie: { zh: '支出分类占比', en: 'Expense by Category', ja: '支出カテゴリの割合' },
paymentPie: { zh: '支付方式分布', en: 'Payment Method Distribution', ja: '支払方法の内訳' },
uncategorized: { zh: '未分类', en: 'Uncategorized', ja: '未分類' },
},
// 收支记录
transaction: {
title: { zh: '收支记录', en: 'Transactions', ja: '収支記録' },
sortLabel: { zh: '排序:', en: 'Sort:', ja: '並び順:' },
sort: {
timeDesc: { zh: '交易时间(新→旧)', en: 'Time (Newest First)', ja: '取引日時(新しい順)' },
timeAsc: { zh: '交易时间(旧→新)', en: 'Time (Oldest First)', ja: '取引日時(古い順)' },
amountDesc: { zh: '金额(高→低)', en: 'Amount (High to Low)', ja: '金額(高い順)' },
amountAsc: { zh: '金额(低→高)', en: 'Amount (Low to High)', ja: '金額(低い順)' },
},
batchSet: { zh: '一键设置', en: 'Batch Set', ja: '一括設定' },
importBill: { zh: '导入账单', en: 'Import Bill', ja: '明細をインポート' },
exportExcel: { zh: '导出 Excel', en: 'Export Excel', ja: 'Excel をエクスポート' },
addRecord: { zh: '新增记录', en: 'Add Record', ja: '記録を追加' },
moreFilter: { zh: '更多筛选', en: 'More Filters', ja: '詳細フィルター' },
clear: { zh: '清空', en: 'Clear', ja: 'クリア' },
amountRange: { zh: '金额区间', en: 'Amount Range', ja: '金額範囲' },
search: { zh: '查询', en: 'Search', ja: '検索' },
reset: { zh: '重置', en: 'Reset', ja: 'リセット' },
activeFilters: { zh: '已激活:', en: 'Active:', ja: '適用中:' },
clearAll: { zh: '清空全部', en: 'Clear all', ja: 'すべてクリア' },
exampleLabel: { zh: '示例', en: 'Examples', ja: '例' },
summary: { zh: '总计 {total} 条 · 第 {page} / {pages} 页 · 每页 {size} 条', en: 'Total {total} · Page {page} / {pages} · {size} per page', ja: '合計 {total} 件 · {page} / {pages} ページ · 1ページ {size} 件' },
pageExpense: { zh: '本页支出', en: 'Page Expense', ja: 'このページの支出' },
pageIncome: { zh: '本页收入', en: 'Page Income', ja: 'このページの収入' },
pageBalance: { zh: '本页结余', en: 'Page Balance', ja: 'このページの収支' },
column: {
index: { zh: '序号', en: 'No.', ja: 'No.' },
transactionTime: { zh: '交易时间', en: 'Time', ja: '取引日時' },
type: { zh: '类型', en: 'Type', ja: '種類' },
category: { zh: '分类', en: 'Category', ja: 'カテゴリ' },
amount: { zh: '金额', en: 'Amount', ja: '金額' },
paymentMethod: { zh: '支付方式', en: 'Payment', ja: '支払方法' },
remark: { zh: '备注', en: 'Remark', ja: '備考' },
tags: { zh: '标签', en: 'Tags', ja: 'タグ' },
includeInStats: { zh: '计入统计', en: 'In Stats', ja: '集計対象' },
actions: { zh: '操作', en: 'Actions', ja: '操作' },
},
notIncluded: { zh: '不计入', en: 'Excluded', ja: '対象外' },
uncategorized: { zh: '未分类', en: 'Uncategorized', ja: '未分類' },
untagged: { zh: '无标签', en: 'Untagged', ja: 'タグなし' },
remarkHidden: { zh: '备注已隐藏', en: 'Remark hidden', ja: '備考を非表示にしました' },
remarkView: { zh: '查看', en: 'View', ja: '表示' },
remarkHide: { zh: '隐藏', en: 'Hide', ja: '非表示' },
remarkCollapse: { zh: '收起', en: 'Collapse', ja: '折りたたむ' },
remarkUnhide: { zh: '取消隐藏', en: 'Unhide', ja: '非表示を解除' },
rawData: { zh: '原始数据', en: 'Raw Data', ja: '元データ' },
rawDataTitle: { zh: '原始账单数据', en: 'Raw Bill Data', ja: '元の明細データ' },
createdTime: { zh: '创建时间:{time}', en: 'Created: {time}', ja: '作成日時:{time}' },
editRecord: { zh: '编辑记录', en: 'Edit Record', ja: '記録を編集' },
addRecordTitle: { zh: '新增记录', en: 'Add Record', ja: '記録を追加' },
batchTitle: { zh: '一键设置分类与统计', en: 'Batch Set Category & Stats', ja: 'カテゴリと集計を一括設定' },
batchScope: { zh: '作用范围', en: 'Scope', ja: '対象範囲' },
batchScopeHint: { zh: '将对当前表格展示的 {count} 条记录设置分类与计入统计', en: 'Apply category and stats settings to the {count} records shown in the table', ja: '現在表示中の {count} 件の記録にカテゴリと集計設定を適用します' },
expenseCategory: { zh: '支出分类', en: 'Expense Category', ja: '支出カテゴリ' },
incomeCategory: { zh: '收入分类', en: 'Income Category', ja: '収入カテゴリ' },
notSetExpense: { zh: '不设置支出分类', en: 'No expense category', ja: '支出カテゴリを設定しない' },
notSetIncome: { zh: '不设置收入分类', en: 'No income category', ja: '収入カテゴリを設定しない' },
addTag: { zh: '添加标签', en: 'Add Tags', ja: 'タグを追加' },
removeTag: { zh: '移除标签', en: 'Remove Tags', ja: 'タグを削除' },
notAddTag: { zh: '不添加标签', en: 'No tags to add', ja: 'タグを追加しない' },
notRemoveTag: { zh: '不移除标签', en: 'No tags to remove', ja: 'タグを削除しない' },
batchStats: {
keep: { zh: '不修改', en: 'No Change', ja: '変更しない' },
include: { zh: '计入统计', en: 'Include in Stats', ja: '集計に含める' },
exclude: { zh: '不计入统计', en: 'Exclude from Stats', ja: '集計から除外' },
},
includeInStats: { zh: '计入统计', en: 'In Stats', ja: '集計対象' },
includeInStatsHint: { zh: '关闭后不纳入月度统计(如借款、转账等)', en: 'When off, excluded from monthly stats (e.g. loans, transfers)', ja: 'オフにすると月次集計に含まれません(借入・振替など)' },
deleteConfirm: { zh: '确定要删除这条记录吗?', en: 'Are you sure you want to delete this record?', ja: 'この記録を削除してもよろしいですか?' },
selectCategory: { zh: '请选择分类', en: 'Please select a category', ja: 'カテゴリを選択してください' },
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: '支払方法を選択' },
remarkPlaceholder: { zh: '可选备注说明', en: 'Optional remark', ja: '備考(任意)' },
remarkHistoryClear: { zh: '清空历史', en: 'Clear history', ja: '履歴をクリア' },
tagPlaceholder: { zh: '选择标签', en: 'Select tags', ja: 'タグを選択' },
noRawData: { zh: '该记录没有原始账单数据', en: 'This record has no raw bill data', ja: 'この記録には元の明細データがありません' },
remarkHiddenSuccess: { zh: '已隐藏备注', en: 'Remark hidden', ja: '備考を非表示にしました' },
remarkShownSuccess: { zh: '已取消隐藏', en: 'Remark unhidden', ja: '備考の非表示を解除しました' },
statsIncluded: { zh: '已计入统计', en: 'Included in stats', ja: '集計に含めました' },
statsExcluded: { zh: '已排除统计', en: 'Excluded from stats', ja: '集計から除外しました' },
noRecordsToSet: { zh: '当前表格没有可设置的记录', en: 'No records available in the current table', ja: '現在のテーブルに設定できる記録がありません' },
batchNothingSelected: { zh: '请至少选择分类、计入统计或标签', en: 'Please select a category, stats option or tag', ja: 'カテゴリ、集計設定、タグのいずれかを選択してください' },
batchUpdated: { zh: '已更新 {count} 条记录 | 已更新 {count} 条记录', en: 'Updated {count} record | Updated {count} records', ja: '{count} 件を更新しました' },
exportSuccess: { zh: '导出成功', en: 'Exported successfully', ja: 'エクスポートしました' },
exportFailed: { zh: '导出失败', en: 'Export failed', ja: 'エクスポートに失敗しました' },
exportFileName: { zh: '交易记录', en: 'transactions', ja: '取引記録' },
includeFilter: {
yes: { zh: '计入', en: 'Included', ja: '含める' },
no: { zh: '不计入', en: 'Excluded', ja: '含めない' },
},
},
// 分类管理
category: {
title: { zh: '分类管理', en: 'Categories', ja: 'カテゴリ管理' },
add: { zh: '新增分类', en: 'Add Category', ja: 'カテゴリを追加' },
expenseSection: { zh: '支出分类', en: 'Expense Categories', ja: '支出カテゴリ' },
incomeSection: { zh: '收入分类', en: 'Income Categories', ja: '収入カテゴリ' },
editTitle: { zh: '编辑分类', en: 'Edit Category', ja: 'カテゴリを編集' },
addTitle: { zh: '新增分类', en: 'Add Category', ja: 'カテゴリを追加' },
name: { zh: '分类名称', en: 'Category Name', ja: 'カテゴリ名' },
namePlaceholder: { zh: '请输入分类名称', en: 'Enter category name', ja: 'カテゴリ名を入力してください' },
type: { zh: '类型', en: 'Type', ja: '種類' },
icon: { zh: '图标', en: 'Icon', ja: 'アイコン' },
iconPlaceholder: { zh: '点击选择 Emoji', en: 'Click to pick an emoji', ja: 'クリックして絵文字を選択' },
emojiInputPlaceholder: { zh: '自定义输入 Emoji 或文字', en: 'Custom emoji or text', ja: '絵文字または文字を自由に入力' },
clearIcon: { zh: '清除图标', en: 'Clear icon', ja: 'アイコンをクリア' },
sort: { zh: '排序', en: 'Order', ja: '並び順' },
nameRequired: { zh: '请输入分类名称', en: 'Please enter a category name', ja: 'カテゴリ名を入力してください' },
deleteConfirm: { zh: '确定要删除这个分类吗?', en: 'Are you sure you want to delete this category?', ja: 'このカテゴリを削除してもよろしいですか?' },
},
// 标签管理
tag: {
title: { zh: '标签管理', en: 'Tags', ja: 'タグ管理' },
add: { zh: '新增标签', en: 'Add Tag', ja: 'タグを追加' },
editTitle: { zh: '编辑标签', en: 'Edit Tag', ja: 'タグを編集' },
addTitle: { zh: '新增标签', en: 'Add Tag', ja: 'タグを追加' },
name: { zh: '标签名称', en: 'Tag Name', ja: 'タグ名' },
namePlaceholder: { zh: '请输入标签名称', en: 'Enter tag name', ja: 'タグ名を入力してください' },
label: { zh: '标签', en: 'Tag', ja: 'タグ' },
color: { zh: '颜色', en: 'Color', ja: '色' },
sort: { zh: '排序', en: 'Order', ja: '並び順' },
nameRequired: { zh: '请输入标签名称', en: 'Please enter a tag name', ja: 'タグ名を入力してください' },
deleteConfirm: { zh: '删除后将从所有交易记录中移除该标签,确定删除吗?', en: 'This tag will be removed from all transactions. Delete it?', ja: '削除するとすべての取引記録からこのタグが外れます。削除してもよろしいですか?' },
},
// 账单导入
import: {
title: { zh: '导入账单', en: 'Import Bill', ja: '明細をインポート' },
billType: { zh: '账单类型:', en: 'Bill type:', ja: '明細の種類:' },
billTypeALIPAY: { zh: '支付宝', en: 'Alipay', ja: 'Alipay' },
billTypeWECHAT: { zh: '微信', en: 'WeChat', ja: 'WeChat' },
billFile: { zh: '账单文件:', en: 'Bill file:', ja: '明細ファイル:' },
dropText: { zh: '点击或拖拽文件到此处', en: 'Click or drag a file here', ja: 'クリックまたはドラッグでファイルを選択' },
fileHint: { zh: '仅支持{label}导出的账单文件({exts})', en: 'Only {label} bill files are supported ({exts})', ja: '{label}からエクスポートした明細ファイルのみ対応({exts})' },
extSeparator: { zh: '、', en: ', ', ja: '、' },
exportHintALIPAY: { zh: '导出路径:支付宝 App → 我的 → 账单 → 开具交易流水证明 / 账单导出,选择 CSV 格式。', en: 'Export path: Alipay App → Me → Bills → Issue Transaction Record / Export Bill, choose CSV format.', ja: 'エクスポート手順:Alipay アプリ → マイ → 請求 → 取引履歴証明の発行 / 明細のエクスポート で CSV 形式を選択。' },
exportHintWECHAT: { zh: '导出路径:微信 App → 我 → 服务 → 钱包 → 账单 → 常见问题 → 下载账单 → 用于个人对账,选择 xlsx 格式。', en: 'Export path: WeChat App → Me → Services → Wallet → Bills → FAQ → Download Bills → For personal reconciliation, choose xlsx format.', ja: 'エクスポート手順:WeChat アプリ → 自分 → サービス → ウォレット → 請求 → よくある質問 → 請求書のダウンロード → 個人の照合用 で xlsx 形式を選択。' },
parse: { zh: '解析', en: 'Parse', ja: '解析' },
expenseDefaultCategory: { zh: '支出默认分类(可不选):', en: 'Default expense category (optional):', ja: '支出の既定カテゴリ(任意):' },
incomeDefaultCategory: { zh: '收入默认分类(可不选):', en: 'Default income category (optional):', ja: '収入の既定カテゴリ(任意):' },
defaultTags: { zh: '默认标签(可不选):', en: 'Default tags (optional):', ja: '既定タグ(任意):' },
notSetCategory: { zh: '未选则不计分类', en: 'No category if unselected', ja: '未選択の場合は分類なし' },
notSetTag: { zh: '未选则不打标签', en: 'No tags if unselected', ja: '未選択の場合はタグなし' },
selectAll: { zh: '全选', en: 'Select All', ja: 'すべて選択' },
previewSummary: { zh: '共 {total} 条,筛选后 {filtered} 条,已勾选 {checked} 条', en: 'Total {total}, {filtered} after filtering, {checked} selected', ja: '全 {total} 件、絞り込み後 {filtered} 件、選択済み {checked} 件' },
searchPlaceholder: { zh: '搜索交易对方/商品/单号', en: 'Search counterparty / product / order no.', ja: '取引相手/商品/注文番号を検索' },
typePlaceholder: { zh: '类型', en: 'Type', ja: '種類' },
statusPlaceholder: { zh: '状态', en: 'Status', ja: 'ステータス' },
typeFilter: {
income: { zh: '收入', en: 'Income', ja: '収入' },
expense: { zh: '支出', en: 'Expense', ja: '支出' },
neutral: { zh: '不计入', en: 'Excluded', ja: '対象外' },
},
statusFilter: {
importable: { zh: '可导入', en: 'Importable', ja: 'インポート可' },
duplicate: { zh: '已存在', en: 'Duplicate', ja: '登録済み' },
error: { zh: '不可导入', en: 'Not Importable', ja: 'インポート不可' },
},
notIncluded: { zh: '不计入', en: 'Excluded', ja: '対象外' },
notImportable: { zh: '不可导入', en: 'Not Importable', ja: 'インポート不可' },
prevStep: { zh: '上一步', en: 'Previous', ja: '前へ' },
confirmImport: { zh: '确认导入({count})', en: 'Confirm Import ({count})', ja: 'インポートを確定({count})' },
resultSummary: { zh: '导入完成:成功 {imported} 条,跳过 {skipped} 条,失败 {failed} 条', en: 'Import complete: {imported} succeeded, {skipped} skipped, {failed} failed', ja: 'インポート完了:成功 {imported} 件、スキップ {skipped} 件、失敗 {failed} 件' },
done: { zh: '完成', en: 'Done', ja: '完了' },
column: {
transactionTime: { zh: '交易时间', en: 'Time', ja: '取引日時' },
type: { zh: '类型', en: 'Type', ja: '種類' },
amount: { zh: '金额', en: 'Amount', ja: '金額' },
counterparty: { zh: '交易对方', en: 'Counterparty', ja: '取引相手' },
product: { zh: '商品名称', en: 'Product', ja: '商品名' },
status: { zh: '状态', en: 'Status', ja: 'ステータス' },
},
errorFileType: { zh: '账单类型「{label}」仅支持 {exts} 格式的文件', en: 'Bill type "{label}" only supports files in {exts} format', ja: '明細の種類「{label}」は {exts} 形式のファイルのみ対応しています' },
selectFileFirst: { zh: '请先选择账单文件', en: 'Please select a bill file first', ja: '先に明細ファイルを選択してください' },
parseFailed: { zh: '解析失败', en: 'Parse failed', ja: '解析に失敗しました' },
selectAtLeastOne: { zh: '请至少勾选一条记录', en: 'Please select at least one record', ja: '少なくとも1件の記録を選択してください' },
importFailed: { zh: '导入失败', en: 'Import failed', ja: 'インポートに失敗しました' },
loadCategoriesFailed: { zh: '加载分类失败', en: 'Failed to load categories', ja: 'カテゴリの読み込みに失敗しました' },
loadTagsFailed: { zh: '加载标签失败', en: 'Failed to load tags', ja: 'タグの読み込みに失敗しました' },
},
// AI 智能建议
ai: {
intro: { zh: '启用后,可在收支记录页使用 AI 智能建议(一键设置中推荐分类与标签)、智能记账与 AI 查询;调用量与 Token 消耗可在「模型使用情况」查看。', en: 'Once enabled, you can use AI suggestions (categories & tags in Batch Set), Smart Entry, and AI Query on the Transactions page; call counts and token usage are available under "Model Usage".', ja: '有効にすると、収支記録ページで AI 提案(一括設定でカテゴリとタグを推薦)、スマート入力、AI 検索を利用できます。呼び出し回数とトークン消費は「モデル利用状況」で確認できます。' },
enabledOn: { zh: '已启用', en: 'Enabled', ja: '有効' },
enabledOff: { zh: '未启用', en: 'Disabled', ja: '無効' },
enabled: { zh: '启用 AI 建议', en: 'Enable AI suggestions', ja: 'AI 提案を有効にする' },
enabledHint: { zh: '关闭后不会发起任何 AI 请求', en: 'No AI requests are sent when disabled', ja: 'オフにすると AI リクエストは送信されません' },
apiKey: { zh: 'API Key', en: 'API Key', ja: 'API Key' },
apiKeyPlaceholder: { zh: '请输入 DeepSeek API Key', en: 'Enter your DeepSeek API Key', ja: 'DeepSeek API Key を入力してください' },
apiKeyKeep: { zh: '已配置,留空表示不修改', en: 'Configured; leave blank to keep unchanged', ja: '設定済み。空欄のままにすると変更されません' },
baseUrl: { zh: '接口地址', en: 'Base URL', ja: 'エンドポイント' },
model: { zh: '模型', en: 'Model', ja: 'モデル' },
save: { zh: '保存', en: 'Save', ja: '保存' },
test: { zh: '测试连接', en: 'Test connection', ja: '接続テスト' },
saveSuccess: { zh: '保存成功', en: 'Saved successfully', ja: '保存しました' },
loadFailed: { zh: '加载 AI 配置失败', en: 'Failed to load AI config', ja: 'AI 設定の読み込みに失敗しました' },
testSuccess: { zh: '连接成功', en: 'Connection succeeded', ja: '接続に成功しました' },
testFailed: { zh: '连接失败', en: 'Connection failed', ja: '接続に失敗しました' },
suggestButton: { zh: 'AI 智能建议', en: 'AI suggestions', ja: 'AI 提案' },
pickButton: { zh: 'AI 推荐', en: 'AI Pick', ja: 'AI におまかせ' },
scope: {
label: { zh: '建议内容', en: 'Scope', ja: '提案内容' },
both: { zh: '分类与标签', en: 'Category & Tags', ja: 'カテゴリとタグ' },
category: { zh: '仅分类', en: 'Category only', ja: 'カテゴリのみ' },
tag: { zh: '仅标签', en: 'Tags only', ja: 'タグのみ' },
},
suggestTitle: { zh: 'AI 分类与标签建议', en: 'AI category & tag suggestions', ja: 'AI によるカテゴリとタグの提案' },
suggesting: { zh: '正在分析,请稍候…', en: 'Analyzing, please wait…', ja: '分析中です。しばらくお待ちください…' },
suggestFailed: { zh: 'AI 建议生成失败', en: 'Failed to generate AI suggestions', ja: 'AI 提案の生成に失敗しました' },
noSuggestion: { zh: 'AI 未返回有效建议', en: 'AI returned no valid suggestions', ja: 'AI から有効な提案が返されませんでした' },
applyAll: { zh: '应用勾选({count})', en: 'Apply selected ({count})', ja: '選択項目を適用({count})' },
applyNone: { zh: '请至少勾选一条建议', en: 'Please select at least one suggestion', ja: '少なくとも1件の提案を選択してください' },
aggregated: { zh: '已聚合为 {groups} 类、共 {count} 条记录', en: 'Aggregated into {groups} groups, {count} records in total', ja: '{groups} グループ、合計 {count} 件の記録に集約しました' },
applySuccess: { zh: '已应用 {count} 条建议', en: 'Applied {count} suggestions', ja: '{count} 件の提案を適用しました' },
oneApplied: { zh: '已应用 AI 推荐分类', en: 'AI category applied', ja: 'AI が提案したカテゴリを適用しました' },
tagApplied: { zh: '已应用 AI 推荐标签', en: 'AI tags applied', ja: 'AI が提案したタグを適用しました' },
applyFailed: { zh: '应用建议失败', en: 'Failed to apply suggestions', ja: '提案の適用に失敗しました' },
applyHint: { zh: '将覆盖分类并追加标签;标记「新建」的分类/标签会在确认后创建', en: 'Categories will be overwritten and tags appended; items marked "New" will be created after confirmation.', ja: 'カテゴリは上書き、タグは追加されます。「新規」の項目は確定後に作成されます。' },
newBadge: { zh: '新建', en: 'New', ja: '新規' },
applyNewTitle: { zh: '确认新建', en: 'Confirm creation', ja: '新規作成の確認' },
applyNewConfirm: { zh: '将新建 {categories} 个分类、{tags} 个标签,确认应用?', en: 'Will create {categories} category(ies) and {tags} tag(s). Continue?', ja: '{categories} 件のカテゴリと {tags} 件のタグを作成します。適用しますか?' },
needConfig: { zh: 'AI 未启用,请先在「AI 设置」中配置', en: 'AI is not enabled. Please configure it in AI Settings first.', ja: 'AI が有効になっていません。「AI 設定」で設定してください。' },
decorate: {
emojiButton: { zh: 'AI 推荐', en: 'AI Pick', ja: 'AI におまかせ' },
colorButton: { zh: 'AI 推荐', en: 'AI Pick', ja: 'AI におまかせ' },
nameRequired: { zh: '请先输入名称', en: 'Please enter a name first', ja: '先に名前を入力してください' },
failed: { zh: 'AI 推荐失败', en: 'AI recommendation failed', ja: 'AI の提案に失敗しました' },
},
category: {
label: { zh: 'AI 生成分类', en: 'AI Category', ja: 'AI 生成カテゴリ' },
placeholder: { zh: '描述用途,如:日常通勤打车地铁', en: 'Describe it, e.g. daily commute by taxi and metro', ja: '用途を説明してください(例:日常の通勤でタクシーと地下鉄)' },
button: { zh: 'AI 生成', en: 'Generate', ja: 'AI で生成' },
textRequired: { zh: '请输入分类描述', en: 'Please enter a description', ja: 'カテゴリの説明を入力してください' },
applied: { zh: '已生成分类,请确认后保存', en: 'Category generated, please confirm and save', ja: 'カテゴリを生成しました。確認して保存してください' },
failed: { zh: 'AI 生成分类失败', en: 'Failed to generate category', ja: 'AI によるカテゴリ生成に失敗しました' },
},
newCategory: {
button: { zh: 'AI 新建', en: 'AI New', ja: 'AI で新規作成' },
hint: { zh: 'AI 建议新分类:', en: 'AI suggests:', ja: 'AI の提案する新カテゴリ:' },
save: { zh: '保存并选用', en: 'Save & Select', ja: '保存して選択' },
saved: { zh: '已创建并选用新分类', en: 'Category created and selected', ja: '新しいカテゴリを作成して選択しました' },
exists: { zh: '已存在同名分类,已为你选中', en: 'A same-name category exists and has been selected', ja: '同名のカテゴリが存在するため選択しました' },
needInfo: { zh: '请先填写备注或金额,便于生成分类', en: 'Please fill in a remark or amount first', ja: 'カテゴリ生成のため、先に備考または金額を入力してください' },
},
newTag: {
button: { zh: 'AI 新建', en: 'AI New', ja: 'AI で新規作成' },
hint: { zh: 'AI 建议新标签:', en: 'AI suggests tag:', ja: 'AI の提案する新タグ:' },
save: { zh: '保存并选用', en: 'Save & Select', ja: '保存して選択' },
saved: { zh: '已创建并选用新标签', en: 'Tag created and selected', ja: '新しいタグを作成して選択しました' },
exists: { zh: '已存在同名标签,已为你选中', en: 'A same-name tag exists and has been selected', ja: '同名のタグが存在するため選択しました' },
needInfo: { zh: '请先填写备注或金额,便于生成标签', en: 'Please fill in a remark or amount first', ja: 'タグ生成のため、先に備考または金額を入力してください' },
failed: { zh: 'AI 生成标签失败', en: 'Failed to generate tag', ja: 'AI によるタグ生成に失敗しました' },
},
query: {
placeholder: { zh: '用自然语言查询,如:上个月餐饮花了多少', en: 'Ask in natural language, e.g. dining expenses last month', ja: '自然言語で検索(例:先月の食費はいくら)' },
examples: { zh: '上个月餐饮|超过500的支出|待报销的支出|微信支付', en: 'Dining last month|Expenses over 500|Pending reimbursement|Paid by WeChat', ja: '先月の食費|500を超える支出|精算待ちの支出|WeChat 払い' },
button: { zh: 'AI 查询', en: 'AI Query', ja: 'AI 検索' },
emptyInput: { zh: '请输入查询内容', en: 'Please enter a query', ja: '検索内容を入力してください' },
clearHistory: { zh: '清空历史', en: 'Clear history', ja: '履歴をクリア' },
failed: { zh: 'AI 查询解析失败', en: 'Failed to parse the query', ja: 'AI 検索の解析に失敗しました' },
resultTitle: { zh: 'AI 解析结果', en: 'AI Query Result', ja: 'AI 解析結果' },
apply: { zh: '应用筛选', en: 'Apply filters', ja: 'フィルターを適用' },
applied: { zh: '已应用 AI 查询筛选条件', en: 'AI query filters applied', ja: 'AI 検索のフィルターを適用しました' },
noCondition: { zh: '未识别到可用的筛选条件,请换一种说法', en: 'No usable filter conditions recognized, please rephrase', ja: '利用できる条件を認識できませんでした。別の言い方をしてください' },
type: { zh: '类型', en: 'Type', ja: '種類' },
category: { zh: '分类', en: 'Category', ja: 'カテゴリ' },
tag: { zh: '标签', en: 'Tag', ja: 'タグ' },
payment: { zh: '支付方式', en: 'Payment', ja: '支払方法' },
dateRange: { zh: '时间范围', en: 'Date range', ja: '期間' },
amountRange: { zh: '金额范围', en: 'Amount range', ja: '金額範囲' },
remark: { zh: '备注', en: 'Remark', ja: '備考' },
includeInStats: { zh: '计入统计', en: 'In stats', ja: '集計対象' },
includeYes: { zh: '计入', en: 'Included', ja: '含める' },
includeNo: { zh: '不计入', en: 'Excluded', ja: '含めない' },
unmatched: { zh: '未识别', en: 'Unmatched', ja: '未認識' },
},
record: {
button: { zh: '智能记账', en: 'Smart Entry', ja: 'スマート入力' },
title: { zh: 'AI 智能记账', en: 'AI Smart Entry', ja: 'AI スマート入力' },
hint: { zh: '用一句话描述这笔收支,AI 会帮你填好表单,确认后再保存。', en: 'Describe the transaction in one sentence; AI fills the form for you to confirm.', ja: 'この収支を一文で説明すると、AI がフォームを入力します。確認してから保存してください。' },
placeholder: { zh: '例如:昨天中午吃饭 35 支付宝', en: 'e.g. Lunch yesterday 35 Alipay', ja: '例:昨日の昼食 35 Alipay' },
parse: { zh: '解析', en: 'Parse', ja: '解析' },
emptyInput: { zh: '请输入记账内容', en: 'Please enter the transaction description', ja: '記帳内容を入力してください' },
failed: { zh: 'AI 记账解析失败', en: 'Failed to parse the transaction', ja: 'AI 記帳の解析に失敗しました' },
},
column: {
record: { zh: '记录', en: 'Record', ja: '記録' },
count: { zh: '命中条数', en: 'Matched', ja: '該当件数' },
category: { zh: '建议分类', en: 'Suggested category', ja: '提案カテゴリ' },
tags: { zh: '建议标签', en: 'Suggested tags', ja: '提案タグ' },
reason: { zh: '理由', en: 'Reason', ja: '理由' },
},
usage: {
title: { zh: '使用情况', en: 'Usage', ja: '利用状況' },
recentTitle: { zh: '最近调用记录', en: 'Recent calls', ja: '最近の呼び出し履歴' },
refresh: { zh: '刷新', en: 'Refresh', ja: '更新' },
totalCalls: { zh: '调用次数', en: 'Calls', ja: '呼び出し回数' },
successCalls: { zh: '成功', en: 'Succeeded', ja: '成功' },
failedCalls: { zh: '失败', en: 'Failed', ja: '失敗' },
promptTokens: { zh: '输入 Token', en: 'Prompt tokens', ja: '入力トークン' },
completionTokens: { zh: '输出 Token', en: 'Completion tokens', ja: '出力トークン' },
totalTokens: { zh: '总 Token', en: 'Total tokens', ja: '合計トークン' },
cachedTokens: { zh: '缓存命中', en: 'Cached tokens', ja: 'キャッシュヒット' },
success: { zh: '成功', en: 'Success', ja: '成功' },
failed: { zh: '失败', en: 'Failed', ja: '失敗' },
loadFailed: { zh: '加载使用情况失败', en: 'Failed to load usage', ja: '利用状況の読み込みに失敗しました' },
empty: { zh: '暂无调用记录', en: 'No usage records yet', ja: '呼び出し履歴はまだありません' },
type: {
suggest: { zh: '生成建议', en: 'Suggest', ja: '提案生成' },
decorate: { zh: '图标配色', en: 'Icon & Color', ja: 'アイコンと配色' },
category: { zh: '生成分类', en: 'Category', ja: 'カテゴリ生成' },
test: { zh: '测试连接', en: 'Test', ja: '接続テスト' },
},
column: {
time: { zh: '时间', en: 'Time', ja: '日時' },
type: { zh: '类型', en: 'Type', ja: '種類' },
count: { zh: '分析条数', en: 'Records', ja: '分析件数' },
promptTokens: { zh: '输入', en: 'Prompt', ja: '入力' },
completionTokens: { zh: '输出', en: 'Completion', ja: '出力' },
totalTokens: { zh: '总计', en: 'Total', ja: '合計' },
duration: { zh: '耗时', en: 'Duration', ja: '所要時間' },
status: { zh: '状态', en: 'Status', ja: 'ステータス' },
},
},
},
}