mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
- 新增钱包余额管理、充值、扣费、退款完整流程 - 新增支付网关抽象层(支持手动/支付宝/微信) - 用量计费从配额系统迁移到钱包余额扣费 - 新增管理员钱包管理与支付订单管理页面 - 新增用户钱包中心页面 - 移除独立 Key 锁定机制,统一由钱包余额控制 - 新增相关 API 路由、序列化器与数据库迁移 - 新增钱包、支付、退款相关测试
66 lines
1.8 KiB
Python
66 lines
1.8 KiB
Python
"""remove standalone api key locking
|
|
|
|
Revision ID: 7c91d2e4f8a1
|
|
Revises: 6f7a8b9c0d1e
|
|
Create Date: 2026-03-05 17:00:00.000000+00:00
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
from sqlalchemy import inspect
|
|
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "7c91d2e4f8a1"
|
|
down_revision: str | None = "6f7a8b9c0d1e"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
_CONSTRAINT_NAME = "ck_api_keys_standalone_not_locked"
|
|
|
|
|
|
def _column_exists(table_name: str, column_name: str) -> bool:
|
|
bind = op.get_bind()
|
|
insp = inspect(bind)
|
|
insp.clear_cache()
|
|
return column_name in [c["name"] for c in insp.get_columns(table_name)]
|
|
|
|
|
|
def _check_constraint_exists(table_name: str, constraint_name: str) -> bool:
|
|
bind = op.get_bind()
|
|
insp = inspect(bind)
|
|
insp.clear_cache()
|
|
return any(c.get("name") == constraint_name for c in insp.get_check_constraints(table_name))
|
|
|
|
|
|
def upgrade() -> None:
|
|
if not (
|
|
_column_exists("api_keys", "is_standalone")
|
|
and _column_exists("api_keys", "is_locked")
|
|
and _column_exists("api_keys", "is_active")
|
|
):
|
|
return
|
|
|
|
op.execute(sa.text("""
|
|
UPDATE api_keys
|
|
SET is_active = FALSE,
|
|
is_locked = FALSE
|
|
WHERE is_standalone IS TRUE AND is_locked IS TRUE
|
|
"""))
|
|
|
|
if not _check_constraint_exists("api_keys", _CONSTRAINT_NAME):
|
|
op.create_check_constraint(
|
|
_CONSTRAINT_NAME,
|
|
"api_keys",
|
|
"(NOT is_standalone) OR (NOT is_locked)",
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
if _check_constraint_exists("api_keys", _CONSTRAINT_NAME):
|
|
op.drop_constraint(_CONSTRAINT_NAME, "api_keys", type_="check")
|