feat: 支持数据库运行时配置与多数据库,重构设置页并完善打包
- 数据库支持 SQLite / MySQL 运行时配置与切换,未配置时仍可启动,配置后自动建表 - 新增默认分类与标签初始化,注册用户自动创建 - 新增注册开关(默认关闭,可在系统设置开启;无用户时允许创建首个账号) - 合并数据库、注册与 AI 配置为「系统设置」页,拆分「模型使用情况」独立页面 - AI 一键设置支持新建分类与标签 - 前端构建产物打包进可执行 jar,后端增加 SPA 路由回退 - jar 更名为 finance-app,补全 Gradle Wrapper,移除 archive 任务 - 更新 DeepSeek 模型说明文案
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
-- SQLite 建表脚本
|
||||
-- 说明:与 MySQL 版(init.sql)保持相同的表结构与语义,差异如下:
|
||||
-- 1. 自增主键使用 INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
-- 2. 不支持列 COMMENT,故移除全部注释
|
||||
-- 3. TINYINT(1) 使用 INTEGER,JSON 使用 TEXT,DECIMAL 使用 NUMERIC
|
||||
-- 4. 索引使用独立的 CREATE INDEX 语句
|
||||
-- 5. 时间默认值与触发器使用本地时间(SQLite 的 CURRENT_TIMESTAMP 为 UTC)
|
||||
-- 语句分隔符为 ;;,以兼容 CREATE TRIGGER 内部的分号
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_user (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
nickname VARCHAR(50),
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime')),
|
||||
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_category (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
type VARCHAR(10) NOT NULL,
|
||||
icon VARCHAR(50),
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
CREATE INDEX IF NOT EXISTS idx_category_user_id ON t_category (user_id);;
|
||||
CREATE INDEX IF NOT EXISTS idx_category_user_type ON t_category (user_id, type);;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_transaction (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
category_id INTEGER,
|
||||
type VARCHAR(10) NOT NULL,
|
||||
amount NUMERIC(12, 2) NOT NULL,
|
||||
payment_method VARCHAR(30),
|
||||
remark VARCHAR(255),
|
||||
remark_hidden INTEGER NOT NULL DEFAULT 0,
|
||||
external_no VARCHAR(64),
|
||||
transaction_time DATETIME NOT NULL,
|
||||
include_in_stats INTEGER NOT NULL DEFAULT 1,
|
||||
raw_data TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime')),
|
||||
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
CREATE INDEX IF NOT EXISTS idx_transaction_user_id ON t_transaction (user_id);;
|
||||
CREATE INDEX IF NOT EXISTS idx_transaction_category_id ON t_transaction (category_id);;
|
||||
CREATE INDEX IF NOT EXISTS idx_transaction_time ON t_transaction (transaction_time);;
|
||||
CREATE INDEX IF NOT EXISTS idx_transaction_user_time ON t_transaction (user_id, transaction_time);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_user_external ON t_transaction (user_id, external_no);;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_tag (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
color VARCHAR(20),
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
CREATE INDEX IF NOT EXISTS idx_tag_user_id ON t_tag (user_id);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_tag_user_name ON t_tag (user_id, name);;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_transaction_tag (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
transaction_id INTEGER NOT NULL,
|
||||
tag_id INTEGER NOT NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_transaction_tag ON t_transaction_tag (transaction_id, tag_id);;
|
||||
CREATE INDEX IF NOT EXISTS idx_transaction_tag_tag_id ON t_transaction_tag (tag_id);;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_ai_config (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
enabled INTEGER NOT NULL DEFAULT 0,
|
||||
api_key VARCHAR(255),
|
||||
base_url VARCHAR(255) NOT NULL DEFAULT 'https://api.deepseek.com',
|
||||
model VARCHAR(50) NOT NULL DEFAULT 'deepseek-chat',
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime')),
|
||||
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_ai_config_user_id ON t_ai_config (user_id);;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_ai_usage (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
type VARCHAR(20) NOT NULL,
|
||||
model VARCHAR(50),
|
||||
transaction_count INTEGER NOT NULL DEFAULT 0,
|
||||
prompt_tokens INTEGER NOT NULL DEFAULT 0,
|
||||
completion_tokens INTEGER NOT NULL DEFAULT 0,
|
||||
total_tokens INTEGER NOT NULL DEFAULT 0,
|
||||
cached_tokens INTEGER NOT NULL DEFAULT 0,
|
||||
success INTEGER NOT NULL DEFAULT 1,
|
||||
error_message VARCHAR(500),
|
||||
duration_ms INTEGER,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'))
|
||||
);;
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_usage_user_created ON t_ai_usage (user_id, created_at);;
|
||||
|
||||
-- 兜底触发器:当应用层未显式更新 updated_at 时,自动刷新为本地时间
|
||||
CREATE TRIGGER IF NOT EXISTS trg_user_updated_at
|
||||
AFTER UPDATE ON t_user
|
||||
FOR EACH ROW
|
||||
WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE t_user SET updated_at = strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime') WHERE id = OLD.id;
|
||||
END;;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS trg_transaction_updated_at
|
||||
AFTER UPDATE ON t_transaction
|
||||
FOR EACH ROW
|
||||
WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE t_transaction SET updated_at = strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime') WHERE id = OLD.id;
|
||||
END;;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS trg_ai_config_updated_at
|
||||
AFTER UPDATE ON t_ai_config
|
||||
FOR EACH ROW
|
||||
WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE t_ai_config SET updated_at = strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime') WHERE id = OLD.id;
|
||||
END;;
|
||||
Reference in New Issue
Block a user