feat: AI 图片记账、自定义交易渠道与淘宝/京东账单导入
- AI 图片记账:多图上传由视觉模型识别,SSE 实时推送进度,提取 rawData,按「类型+金额+时间」检测重复,支持缩略图与来源图片查看 - 自定义交易渠道:新增 t_channel 与渠道管理页,支持新建/改名/删除,并接入统计、导出与 AI 查询/记账/建议提示词 - AI 建议:单条建议新增交易渠道推荐(推荐已有渠道 / AI 新建渠道) - 账单导入:新增淘宝(xlsx)、京东(CSV)解析器 - 交易:新增批量创建接口,导入时按去重键兜底跳过重复 - 运行目录统一经 AppHome 解析,图片与数据文件落盘规范化 - 前端:AI 记账方式偏好记忆、AI 按钮与输入框对齐、来源图片弹窗支持加载原图
This commit is contained in:
@@ -76,6 +76,7 @@ CREATE TABLE IF NOT EXISTS t_ai_config (
|
||||
api_key VARCHAR(255) COMMENT 'DeepSeek API Key(明文存储)',
|
||||
base_url VARCHAR(255) NOT NULL DEFAULT 'https://api.deepseek.com' COMMENT 'API 基础地址',
|
||||
model VARCHAR(50) NOT NULL DEFAULT 'deepseek-chat' COMMENT '使用的模型名称',
|
||||
vision_model VARCHAR(50) NOT NULL DEFAULT 'deepseek-flash' COMMENT '图片记账使用的视觉模型名称',
|
||||
UNIQUE INDEX uk_user_id (user_id) COMMENT '用户ID唯一索引,每个用户一条配置'
|
||||
);
|
||||
|
||||
@@ -97,6 +98,32 @@ CREATE TABLE IF NOT EXISTS t_ai_usage (
|
||||
INDEX idx_user_created (user_id, created_at) COMMENT '用户ID+创建时间联合索引'
|
||||
);
|
||||
|
||||
-- AI 记账图片表:保存用户上传的账单/支付截图及其解析结果摘要
|
||||
CREATE TABLE IF NOT EXISTS t_ai_image (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '图片ID,主键自增',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
user_id BIGINT NOT NULL COMMENT '所属用户ID',
|
||||
file_path VARCHAR(500) NOT NULL COMMENT '图片本地存储相对路径',
|
||||
mime_type VARCHAR(50) COMMENT '图片 MIME 类型,如 image/jpeg',
|
||||
file_size BIGINT NOT NULL DEFAULT 0 COMMENT '图片文件大小(字节)',
|
||||
width INT COMMENT '图片宽度(像素)',
|
||||
height INT COMMENT '图片高度(像素)',
|
||||
model VARCHAR(50) COMMENT '解析使用的视觉模型名称',
|
||||
summary VARCHAR(500) COMMENT '解析结果摘要',
|
||||
record_count INT NOT NULL DEFAULT 0 COMMENT '解析出的交易记录条数',
|
||||
INDEX idx_ai_image_user_created (user_id, created_at) COMMENT '用户ID+创建时间联合索引'
|
||||
);
|
||||
|
||||
-- AI 记账图片与交易记录关联表:记录每张图片解析生成的交易记录
|
||||
CREATE TABLE IF NOT EXISTS t_ai_image_transaction (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '关联ID,主键自增',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
image_id BIGINT NOT NULL COMMENT 'AI 记账图片ID',
|
||||
transaction_id BIGINT NOT NULL COMMENT '交易记录ID',
|
||||
UNIQUE INDEX uk_ai_image_transaction (image_id, transaction_id) COMMENT '图片+交易唯一索引',
|
||||
INDEX idx_ai_image_transaction_transaction_id (transaction_id) COMMENT '交易记录ID索引'
|
||||
);
|
||||
|
||||
-- 通知配置表:存储每个用户的账单导入提醒设置
|
||||
CREATE TABLE IF NOT EXISTS t_notification_config (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '配置ID,主键自增',
|
||||
@@ -271,3 +298,17 @@ CREATE TABLE IF NOT EXISTS t_user_preference (
|
||||
pref_value TEXT COMMENT '偏好值,标量字符串或 JSON',
|
||||
UNIQUE INDEX uk_user_pref (user_id, pref_key) COMMENT '用户+偏好键唯一索引'
|
||||
);
|
||||
|
||||
-- 用户自定义交易渠道表:仅存放用户自建渠道,内置渠道由枚举维护
|
||||
CREATE TABLE IF NOT EXISTS t_channel (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '渠道ID,主键自增',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
user_id BIGINT NOT NULL COMMENT '所属用户ID',
|
||||
code VARCHAR(30) NOT NULL COMMENT '渠道编码,后端生成且稳定不变,交易记录按此关联',
|
||||
name VARCHAR(50) NOT NULL COMMENT '渠道名称,用户可修改',
|
||||
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序序号,数值越小越靠前',
|
||||
UNIQUE INDEX uk_channel_user_code (user_id, code) COMMENT '用户+渠道编码唯一索引',
|
||||
UNIQUE INDEX uk_channel_user_name (user_id, name) COMMENT '用户+渠道名称唯一索引',
|
||||
INDEX idx_channel_user_id (user_id) COMMENT '用户ID索引'
|
||||
);
|
||||
|
||||
@@ -78,7 +78,8 @@ CREATE TABLE IF NOT EXISTS t_ai_config (
|
||||
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'
|
||||
model VARCHAR(50) NOT NULL DEFAULT 'deepseek-chat',
|
||||
vision_model VARCHAR(50) NOT NULL DEFAULT 'deepseek-flash'
|
||||
);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_ai_config_user_id ON t_ai_config (user_id);;
|
||||
|
||||
@@ -99,6 +100,32 @@ CREATE TABLE IF NOT EXISTS t_ai_usage (
|
||||
);;
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_usage_user_created ON t_ai_usage (user_id, created_at);;
|
||||
|
||||
-- AI 记账图片表:保存用户上传的账单/支付截图及其解析结果摘要
|
||||
CREATE TABLE IF NOT EXISTS t_ai_image (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime')),
|
||||
user_id INTEGER NOT NULL,
|
||||
file_path VARCHAR(500) NOT NULL,
|
||||
mime_type VARCHAR(50),
|
||||
file_size INTEGER NOT NULL DEFAULT 0,
|
||||
width INTEGER,
|
||||
height INTEGER,
|
||||
model VARCHAR(50),
|
||||
summary VARCHAR(500),
|
||||
record_count INTEGER NOT NULL DEFAULT 0
|
||||
);;
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_image_user_created ON t_ai_image (user_id, created_at);;
|
||||
|
||||
-- AI 记账图片与交易记录关联表:记录每张图片解析生成的交易记录
|
||||
CREATE TABLE IF NOT EXISTS t_ai_image_transaction (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime')),
|
||||
image_id INTEGER NOT NULL,
|
||||
transaction_id INTEGER NOT NULL
|
||||
);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_ai_image_transaction ON t_ai_image_transaction (image_id, transaction_id);;
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_image_transaction_transaction_id ON t_ai_image_transaction (transaction_id);;
|
||||
|
||||
-- 兜底触发器:当应用层未显式更新 updated_at 时,自动刷新为本地时间
|
||||
CREATE TRIGGER IF NOT EXISTS trg_user_updated_at
|
||||
AFTER UPDATE ON t_user
|
||||
@@ -343,3 +370,25 @@ WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE t_user_preference SET updated_at = strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime') WHERE id = OLD.id;
|
||||
END;;
|
||||
|
||||
-- 用户自定义交易渠道表:仅存放用户自建渠道,内置渠道由枚举维护
|
||||
CREATE TABLE IF NOT EXISTS t_channel (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
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')),
|
||||
user_id INTEGER NOT NULL,
|
||||
code VARCHAR(30) NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0
|
||||
);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_channel_user_code ON t_channel (user_id, code);;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_channel_user_name ON t_channel (user_id, name);;
|
||||
CREATE INDEX IF NOT EXISTS idx_channel_user_id ON t_channel (user_id);;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS trg_channel_updated_at
|
||||
AFTER UPDATE ON t_channel
|
||||
FOR EACH ROW
|
||||
WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE t_channel SET updated_at = strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime') WHERE id = OLD.id;
|
||||
END;;
|
||||
|
||||
Reference in New Issue
Block a user