This commit is contained in:
949036910@qq.com
2026-05-30 12:46:17 +08:00
parent d9c4e04d66
commit d6fefd6138
7 changed files with 138 additions and 2 deletions

View File

@@ -8,7 +8,7 @@ from sqlalchemy.ext.asyncio import async_engine_from_config
from app.config import get_settings from app.config import get_settings
from app.database import Base from app.database import Base
from app.models import CardKey, DesktopConfig, Oem, User # noqa: F401 — 注册元数据 from app.models import CardKey, Config, DesktopConfig, Oem, User # noqa: F401 — 注册元数据
config = context.config config = context.config
settings = get_settings() settings = get_settings()

View File

@@ -0,0 +1,41 @@
"""create configs table"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = "016"
down_revision: Union[str, None] = "015"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"configs",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("name", sa.String(length=64), nullable=False),
sa.Column("value", sa.Text(), nullable=False),
sa.Column("mark", sa.String(length=255), nullable=True),
sa.Column(
"created_at",
sa.DateTime(timezone=True),
server_default=sa.text("CURRENT_TIMESTAMP"),
nullable=False,
),
sa.Column(
"updated_at",
sa.DateTime(timezone=True),
server_default=sa.text("CURRENT_TIMESTAMP"),
nullable=False,
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("name", name="uq_configs_name"),
)
op.create_index(op.f("ix_configs_name"), "configs", ["name"], unique=False)
def downgrade() -> None:
op.drop_index(op.f("ix_configs_name"), table_name="configs")
op.drop_table("configs")

View File

@@ -7,9 +7,13 @@ from fastapi.staticfiles import StaticFiles
from app.api.v1.router import api_router from app.api.v1.router import api_router
from app.config import get_settings from app.config import get_settings
from app.core.branding_images import IMAGES_DIR, ensure_images_dir from app.core.branding_images import IMAGES_DIR, ensure_images_dir
from app.dependencies import DbSession
from app.middleware.api_crypto import ApiCryptoMiddleware from app.middleware.api_crypto import ApiCryptoMiddleware
from app.redis_client import close_redis, init_redis from app.redis_client import close_redis, init_redis
from app.schemas.common import ApiResponse from app.schemas.common import ApiResponse
from app.schemas.release_version import ReleaseVersionOut, SetReleaseVersionIn
from app.services import config_store
from app.services.config_store import RELEASE_VERSION_KEY
settings = get_settings() settings = get_settings()
@@ -41,6 +45,35 @@ def create_app() -> FastAPI:
async def health() -> ApiResponse[dict]: async def health() -> ApiResponse[dict]:
return ApiResponse(ok=True, message="服务正常", data={"status": "up"}) return ApiResponse(ok=True, message="服务正常", data={"status": "up"})
@app.get("/api/checkupdate", response_model=ApiResponse[ReleaseVersionOut])
async def check_update(db: DbSession) -> ApiResponse[ReleaseVersionOut]:
version = await config_store.get_config_value(db, RELEASE_VERSION_KEY)
if not version:
return ApiResponse(ok=False, message="未配置 releaseversion")
return ApiResponse(
ok=True,
message="",
data=ReleaseVersionOut(version=version),
)
@app.post("/api/setreleaseversion", response_model=ApiResponse[ReleaseVersionOut])
async def set_release_version(
body: SetReleaseVersionIn,
db: DbSession,
) -> ApiResponse[ReleaseVersionOut]:
version = body.version.strip()
saved = await config_store.set_config_value(
db,
RELEASE_VERSION_KEY,
version,
mark="桌面端发布版本",
)
return ApiResponse(
ok=True,
message="已更新 releaseversion",
data=ReleaseVersionOut(version=saved),
)
ensure_images_dir() ensure_images_dir()
app.mount( app.mount(
"/images", "/images",

View File

@@ -1,6 +1,7 @@
from app.models.card_key import CardKey from app.models.card_key import CardKey
from app.models.config import Config
from app.models.desktopConfig import DesktopConfig from app.models.desktopConfig import DesktopConfig
from app.models.oem import Oem from app.models.oem import Oem
from app.models.user import User from app.models.user import User
__all__ = ["User", "DesktopConfig", "CardKey", "Oem"] __all__ = ["User", "DesktopConfig", "CardKey", "Oem", "Config"]

18
app/models/config.py Normal file
View File

@@ -0,0 +1,18 @@
from datetime import datetime
from sqlalchemy import DateTime, String, Text, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class Config(Base):

View File

@@ -0,0 +1,9 @@
from pydantic import BaseModel, Field
class ReleaseVersionOut(BaseModel):
version: str
class SetReleaseVersionIn(BaseModel):
version: str = Field(min_length=1, max_length=64)

View File

@@ -0,0 +1,34 @@
"""configs 表:全局键值配置(如 releaseversion"""
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.config import Config
RELEASE_VERSION_KEY = "releaseversion"
async def get_config_value(db: AsyncSession, name: str) -> str | None:
result = await db.execute(select(Config).where(Config.name == name))
row = result.scalar_one_or_none()
return row.value if row else None
async def set_config_value(
db: AsyncSession,
name: str,
value: str,
*,
mark: str | None = None,
) -> str:
result = await db.execute(select(Config).where(Config.name == name))
row = result.scalar_one_or_none()
if row is None:
row = Config(name=name, value=value, mark=mark)
db.add(row)
else:
row.value = value
if mark is not None:
row.mark = mark
await db.flush()
return row.value