feat(NoteForm): 增加文件上传状态反馈

This commit is contained in:
JefferyHcool
2025-06-19 14:54:51 +08:00
parent 2b0fb8f4ad
commit d92cc4a977
24 changed files with 777 additions and 374 deletions

36
backend/app/db/engine.py Normal file
View File

@@ -0,0 +1,36 @@
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from dotenv import load_dotenv
load_dotenv()
# 默认 SQLite如果想换 PostgreSQL 或 MySQL可以直接改 .env
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///bili_note.db")
# SQLite 需要特定连接参数,其他数据库不需要
engine_args = {}
if DATABASE_URL.startswith("sqlite"):
engine_args["connect_args"] = {"check_same_thread": False}
engine = create_engine(
DATABASE_URL,
echo=os.getenv("SQLALCHEMY_ECHO", "false").lower() == "true",
**engine_args
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_engine():
return engine
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

View File

@@ -0,0 +1,9 @@
from app.db.models.models import Model
from app.db.models.providers import Provider
from app.db.models.video_tasks import VideoTask
from app.db.engine import get_engine, Base
def init_db():
engine = get_engine()
Base.metadata.create_all(bind=engine)

View File

@@ -1,67 +1,67 @@
from app.db.sqlite_client import get_connection
def init_model_table():
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS models (
id INTEGER PRIMARY KEY AUTOINCREMENT,
provider_id INTEGER NOT NULL,
model_name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
conn.commit()
conn.close()
from app.db.engine import get_db
from app.db.models.models import Model
def get_model_by_provider_and_name(provider_id: int, model_name: str):
conn = get_connection()
cursor = conn.execute(
"SELECT * FROM models WHERE provider_id = ? AND model_name = ?",
(provider_id, model_name)
)
row = cursor.fetchone()
return row
# 插入模型
db = next(get_db())
try:
model = db.query(Model).filter_by(provider_id=provider_id, model_name=model_name).first()
if model:
return {
"id": model.id,
"provider_id": model.provider_id,
"model_name": model.model_name,
"created_at": model.created_at,
}
return None
finally:
db.close()
def insert_model(provider_id: int, model_name: str):
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
INSERT INTO models (provider_id, model_name)
VALUES (?, ?)
""", (provider_id, model_name))
conn.commit()
conn.close()
db = next(get_db())
try:
model = Model(provider_id=provider_id, model_name=model_name)
db.add(model)
db.commit()
db.refresh(model)
return {
"id": model.id,
"provider_id": model.provider_id,
"model_name": model.model_name,
"created_at": model.created_at,
}
finally:
db.close()
# 根据provider查模型
def get_models_by_provider(provider_id: int):
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
SELECT id, model_name FROM models
WHERE provider_id = ?
""", (provider_id,))
rows = cursor.fetchall()
conn.close()
return [{"id": row[0], "model_name": row[1]} for row in rows]
db = next(get_db())
try:
models = db.query(Model).filter_by(provider_id=provider_id).all()
return [{"id": m.id, "model_name": m.model_name} for m in models]
finally:
db.close()
# 删除某个模型
def delete_model(model_id: int):
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
DELETE FROM models WHERE id = ?
""", (model_id,))
conn.commit()
conn.close()
db = next(get_db())
try:
model = db.query(Model).filter_by(id=model_id).first()
if model:
db.delete(model)
db.commit()
finally:
db.close()
def get_all_models():
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
SELECT id, provider_id, model_name FROM models
""")
rows = cursor.fetchall()
conn.close()
return [{"id": row[0], "provider_id": row[1], "model_name": row[2]} for row in rows]
db = next(get_db())
try:
models = db.query(Model).all()
return [
{"id": m.id, "provider_id": m.provider_id, "model_name": m.model_name}
for m in models
]
finally:
db.close()

View File

View File

@@ -0,0 +1,12 @@
from sqlalchemy import Column, Integer, String, DateTime, func, ForeignKey
from app.db.engine import Base
class Model(Base):
__tablename__ = "models"
id = Column(Integer, primary_key=True, autoincrement=True)
provider_id = Column(Integer, nullable=False)
model_name = Column(String, nullable=False)
created_at = Column(DateTime, server_default=func.now())

View File

@@ -0,0 +1,17 @@
from sqlalchemy import Column, String, Integer, DateTime, func
from sqlalchemy.orm import declarative_base
from app.db.engine import Base
class Provider(Base):
__tablename__ = "providers"
id = Column(String, primary_key=True)
name = Column(String, nullable=False)
logo = Column(String, nullable=False)
type = Column(String, nullable=False)
api_key = Column(String, nullable=False)
base_url = Column(String, nullable=False)
enabled = Column(Integer, default=1)
created_at = Column(DateTime, server_default=func.now())

View File

@@ -0,0 +1,14 @@
from sqlalchemy import Column, Integer, String, DateTime, func
from sqlalchemy.orm import declarative_base
from app.db.engine import Base
class VideoTask(Base):
__tablename__ = "video_tasks"
id = Column(Integer, primary_key=True, autoincrement=True)
video_id = Column(String, nullable=False)
platform = Column(String, nullable=False)
task_id = Column(String, unique=True, nullable=False)
created_at = Column(DateTime, server_default=func.now())

View File

@@ -1,14 +1,13 @@
import json
import os
import sys
from app.db.sqlite_client import get_connection
from app.db.models.providers import Provider
from app.utils.logger import get_logger
from app.db.engine import get_engine, Base, get_db
logger = get_logger(__name__)
def get_builtin_providers_path():
if getattr(sys, 'frozen', False):
base_path = sys._MEIPASS
@@ -16,213 +15,115 @@ def get_builtin_providers_path():
base_path = os.path.dirname(__file__)
return os.path.join(base_path, 'builtin_providers.json')
def seed_default_providers():
conn = get_connection()
if conn is None:
logger.error("Failed to connect to database.")
return
cursor = conn.cursor()
# 检查已有数据
cursor.execute("SELECT COUNT(*) FROM providers")
count = cursor.fetchone()[0]
if count > 0:
logger.info("Providers already exist, skipping seed.")
conn.close()
return
json_path = get_builtin_providers_path()
db = next(get_db())
try:
with open(json_path, 'r', encoding='utf-8') as f:
providers = json.load(f)
except Exception as e:
logger.error(f"Failed to read builtin_providers.json: {e}")
conn.close()
return
if db.query(Provider).count() > 0:
logger.info("Providers already exist, skipping seed.")
return
json_path = get_builtin_providers_path()
try:
with open(json_path, 'r', encoding='utf-8') as f:
providers = json.load(f)
except Exception as e:
logger.error(f"Failed to read builtin_providers.json: {e}")
return
try:
for p in providers:
cursor.execute("""
INSERT INTO providers (id, name, api_key, base_url, logo, type, enabled)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
p['id'],
p['name'],
p['api_key'],
p['base_url'],
p['logo'],
p['type'],
p.get('enabled', 1)
db.add(Provider(
id=p['id'],
name=p['name'],
api_key=p['api_key'],
base_url=p['base_url'],
logo=p['logo'],
type=p['type'],
enabled=p.get('enabled', 1)
))
conn.commit()
db.commit()
logger.info("Default providers seeded successfully.")
except Exception as e:
logger.error(f"Failed to seed default providers: {e}")
finally:
conn.close()
def init_provider_table():
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS providers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
logo TEXT NOT NULL,
type TEXT NOT NULL,
api_key TEXT NOT NULL,
base_url TEXT NOT NULL,
enabled INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
db.close()
def insert_provider(id: str, name: str, api_key: str, base_url: str, logo: str, type_: str, enabled: int = 1):
db = next(get_db())
try:
conn.commit()
conn.close()
logger.info("provider table created successfully.")
seed_default_providers()
except Exception as e:
logger.error(f"Failed to create provider table: {e}")
def insert_provider(id: str, name: str, api_key: str, base_url: str, logo: str, type_: str,enabled:int=1):
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("""
INSERT INTO providers (id, name, api_key, base_url, logo, type, enabled)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (id, name, api_key, base_url, logo, type_, enabled))
try:
conn.commit()
conn.close()
provider = Provider(id=id, name=name, api_key=api_key, base_url=base_url, logo=logo, type=type_, enabled=enabled)
db.add(provider)
db.commit()
logger.info(f"Provider inserted successfully. id: {id}, name: {name}, type: {type_}")
return id
except Exception as e:
logger.error(f"Failed to insert provider: {e}")
return None
finally:
db.close()
def get_enabled_providers():
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("SELECT * FROM providers WHERE enabled = 1")
db = next(get_db())
try:
rows = cursor.fetchall()
conn.close()
if rows is None:
logger.info("No providers found")
return None
logger.info(f"Providers found: {rows}")
return rows
except Exception as e:
logger.error(f"Failed to get enabled providers: {e}")
return db.query(Provider).filter_by(enabled=1).all()
finally:
db.close()
def get_provider_by_name(name: str):
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("SELECT * FROM providers WHERE name = ?", (name,))
db = next(get_db())
try:
row = cursor.fetchone()
conn.close()
if row is None:
logger.info(f"Provider not found: {name}")
return None
logger.info(f"Provider found: {row[0]}")
return db.query(Provider).filter_by(name=name).first()
finally:
db.close()
return row
except Exception as e:
logger.error(f"Failed to get provider by name: {e}")
def get_provider_by_id(id: int):
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("SELECT * FROM providers WHERE id = ?", (id,))
def get_provider_by_id(id: str):
db = next(get_db())
try:
row = cursor.fetchone()
conn.close()
if row is None:
logger.info(f"Provider not found: {id}")
return None
logger.info(f"Provider found: {row[0]}")
return row
except Exception as e:
logger.error(f"Failed to get provider by id: {e}")
return db.query(Provider).filter_by(id=id).first()
finally:
db.close()
def get_all_providers():
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("SELECT * FROM providers")
db = next(get_db())
try:
rows = cursor.fetchall()
conn.close()
if rows is None:
logger.info("No providers found")
return None
logger.info(f"Providers found total {len(rows) }")
return rows
except Exception as e:
logger.error(f"Failed to get all providers: {e}")
return db.query(Provider).all()
finally:
db.close()
def update_provider(id: str, **kwargs):
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
fields = []
values = []
for key, value in kwargs.items():
fields.append(f"{key} = ?")
values.append(value)
if not fields:
logger.warning("No fields provided for update.")
return
sql = f"""
UPDATE providers
SET {', '.join(fields)}
WHERE id = ?
"""
values.append(id) # id 最后加
cursor = conn.cursor()
db = next(get_db())
try:
cursor.execute(sql, values)
conn.commit()
conn.close()
logger.info(f"Provider updated successfully. id: {id}, updated_fields: {fields}")
provider = db.query(Provider).filter_by(id=id).first()
if not provider:
logger.warning(f"Provider {id} not found for update.")
return
for key, value in kwargs.items():
if hasattr(provider, key):
setattr(provider, key, value)
db.commit()
logger.info(f"Provider updated successfully. id: {id}, updated_fields: {list(kwargs.keys())}")
except Exception as e:
logger.error(f"Failed to update provider: {e}")
finally:
db.close()
def delete_provider(id: int):
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("DELETE FROM providers WHERE id = ?", (id,))
def delete_provider(id: str):
db = next(get_db())
try:
conn.commit()
conn.close()
logger.info(f"Provider deleted successfully. id: {id}")
provider = db.query(Provider).filter_by(id=id).first()
if provider:
db.delete(provider)
db.commit()
logger.info(f"Provider deleted successfully. id: {id}")
except Exception as e:
logger.error(f"Failed to delete provider: {e}")
logger.error(f"Failed to delete provider: {e}")
finally:
db.close()

View File

@@ -1,78 +1,61 @@
from .sqlite_client import get_connection
from app.db.models.video_tasks import VideoTask
from app.db.engine import get_db
from app.utils.logger import get_logger
logger = get_logger(__name__)
def init_video_task_table():
conn = get_connection()
if conn is None:
logger.error("Failed to connect to the database.")
return
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS video_tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_id TEXT NOT NULL,
platform TEXT NOT NULL,
task_id TEXT NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
try:
conn.commit()
conn.close()
logger.info("video_tasks table created successfully.")
except Exception as e:
logger.error(f"Failed to create video_tasks table: {e}")
# 插入任务
def insert_video_task(video_id: str, platform: str, task_id: str):
db = next(get_db())
try:
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
INSERT INTO video_tasks (video_id, platform, task_id)
VALUES (?, ?, ?)
""", (video_id, platform, task_id))
conn.commit()
conn.close()
logger.info(f"Video task inserted successfully."
f"video_id: {video_id}"
f"platform: {platform}"
f"task_id: {task_id}")
task = VideoTask(video_id=video_id, platform=platform, task_id=task_id)
db.add(task)
db.commit()
db.refresh(task)
logger.info(f"Video task inserted successfully. video_id: {video_id}, platform: {platform}, task_id: {task_id}")
except Exception as e:
logger.error(f"Failed to insert video task: {e}")
finally:
db.close()
# 查询任务(最新一条)
def get_task_by_video(video_id: str, platform: str):
db = next(get_db())
try:
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
SELECT task_id FROM video_tasks
WHERE video_id = ? AND platform = ?
ORDER BY created_at DESC
LIMIT 1
""", (video_id, platform))
result = cursor.fetchone()
conn.close()
if result is None:
task = (
db.query(VideoTask)
.filter_by(video_id=video_id, platform=platform)
.order_by(VideoTask.created_at.desc())
.first()
)
if task:
logger.info(f"Task found for video_id: {video_id} and platform: {platform}")
return task.task_id
else:
logger.info(f"No task found for video_id: {video_id} and platform: {platform}")
logger.info(f"Task found for video_id: {video_id} and platform: {platform}")
return result[0] if result else None
return None
except Exception as e:
logger.error(f"Failed to get task by video: {e}")
finally:
db.close()
# 删除任务
def delete_task_by_video(video_id: str, platform: str):
db = next(get_db())
try:
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
DELETE FROM video_tasks
WHERE video_id = ? AND platform = ?
""", (video_id, platform))
conn.commit()
conn.close()
logger.info(f"Task deleted for video_id: {video_id} and platform: {platform}")
tasks = (
db.query(VideoTask)
.filter_by(video_id=video_id, platform=platform)
.all()
)
for task in tasks:
db.delete(task)
db.commit()
logger.info(f"Task(s) deleted for video_id: {video_id} and platform: {platform}")
except Exception as e:
logger.error(f"Failed to delete task by video: {e}")
logger.error(f"Failed to delete task by video: {e}")
finally:
db.close()