真人素材库V3 | 虚拟人像库 | app/admin build
This commit is contained in:
Vendored
+110
-110
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -28,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<script type="module" crossorigin src="/assets/index-BJj5fRkV.js"></script>
|
<script type="module" crossorigin src="/assets/index-Bo_aUzmj.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-D7ShJUt4.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-D7ShJUt4.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ VIDEO_COVER_WIDTH=600
|
|||||||
VIDEO_COVER_TIMEOUT_SECONDS=15
|
VIDEO_COVER_TIMEOUT_SECONDS=15
|
||||||
VIDEO_COVER_FORMAT=png
|
VIDEO_COVER_FORMAT=png
|
||||||
|
|
||||||
|
# VOLC
|
||||||
|
VOLC_ACCESS_KEY_ID=AKLTYWY5Yjc5YjM3N2IwNDc3M2I3NTU2YjlmNTczYzQzMmM
|
||||||
|
VOLC_SECRET_ACCESS_KEY=TXpjM01HUTFZMlV5TUdKbE5Ea3lNRGhqTUdSak16UTFOV0ptTW1SaE5XRQ==
|
||||||
|
|
||||||
# VOLC_SMS
|
# VOLC_SMS
|
||||||
VOLC_SMS_ACCESS_KEY_ID=AKLTYWY5Yjc5YjM3N2IwNDc3M2I3NTU2YjlmNTczYzQzMmM
|
VOLC_SMS_ACCESS_KEY_ID=AKLTYWY5Yjc5YjM3N2IwNDc3M2I3NTU2YjlmNTczYzQzMmM
|
||||||
VOLC_SMS_SECRET_ACCESS_KEY=TXpjM01HUTFZMlV5TUdKbE5Ea3lNRGhqTUdSak16UTFOV0ptTW1SaE5XRQ==
|
VOLC_SMS_SECRET_ACCESS_KEY=TXpjM01HUTFZMlV5TUdKbE5Ea3lNRGhqTUdSak16UTFOV0ptTW1SaE5XRQ==
|
||||||
|
|||||||
+202
@@ -0,0 +1,202 @@
|
|||||||
|
"""rename private portrait asset limit and add library type
|
||||||
|
|
||||||
|
Revision ID: cd7688999204
|
||||||
|
Revises: e7038d02c355
|
||||||
|
Create Date: 2026-07-07 13:21:49.612465
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "cd7688999204"
|
||||||
|
down_revision: Union[str, None] = "e7038d02c355"
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# 1. users 字段改名:必须 rename,保留原有用户额度数据
|
||||||
|
op.alter_column(
|
||||||
|
"users",
|
||||||
|
"private_portrait_image_limit",
|
||||||
|
new_column_name="private_portrait_asset_limit",
|
||||||
|
existing_type=sa.Integer(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text("5"),
|
||||||
|
comment="私域人像素材总量限制,真人/虚拟共用,图片/视频共用,0 表示关闭",
|
||||||
|
existing_comment="私域真人图片素材数量限制,0表示关闭",
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. private_portrait_asset_groups
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_asset_groups",
|
||||||
|
sa.Column(
|
||||||
|
"library_type",
|
||||||
|
sa.String(length=32),
|
||||||
|
server_default="real_person",
|
||||||
|
nullable=False,
|
||||||
|
comment="素材库类型:real_person 真人认证;aigc_virtual 虚拟人像",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_asset_groups_library_type",
|
||||||
|
"private_portrait_asset_groups",
|
||||||
|
["library_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_asset_groups_user_library",
|
||||||
|
"private_portrait_asset_groups",
|
||||||
|
["user_id", "library_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. private_portrait_assets
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_assets",
|
||||||
|
sa.Column(
|
||||||
|
"library_type",
|
||||||
|
sa.String(length=32),
|
||||||
|
server_default="real_person",
|
||||||
|
nullable=False,
|
||||||
|
comment="素材库类型:real_person 真人认证;aigc_virtual 虚拟人像",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_assets",
|
||||||
|
sa.Column("video_duration", sa.Float(), nullable=True, comment="视频素材时长,秒"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_assets",
|
||||||
|
sa.Column("video_cover_url", sa.Text(), nullable=True, comment="视频素材封面预览地址"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_assets",
|
||||||
|
sa.Column("file_size", sa.Integer(), nullable=True, comment="素材文件大小,字节"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_assets",
|
||||||
|
sa.Column("mime_type", sa.String(length=128), nullable=True, comment="素材 MIME 类型"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 如果 private_portrait_assets.asset_type 已经存在索引,这条要删除
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_assets_asset_type",
|
||||||
|
"private_portrait_assets",
|
||||||
|
["asset_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_assets_library_type",
|
||||||
|
"private_portrait_assets",
|
||||||
|
["library_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_assets_user_library_status_created",
|
||||||
|
"private_portrait_assets",
|
||||||
|
["user_id", "library_type", "status", "created_at"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4. private_portrait_projects
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_projects",
|
||||||
|
sa.Column(
|
||||||
|
"library_type",
|
||||||
|
sa.String(length=32),
|
||||||
|
server_default="real_person",
|
||||||
|
nullable=False,
|
||||||
|
comment="素材库类型:real_person 真人认证;aigc_virtual 虚拟人像",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_projects",
|
||||||
|
sa.Column("image_asset_count", sa.Integer(), server_default="0", nullable=False, comment="图片素材数量"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_projects",
|
||||||
|
sa.Column("video_asset_count", sa.Integer(), server_default="0", nullable=False, comment="视频素材数量"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_projects",
|
||||||
|
sa.Column("active_image_asset_count", sa.Integer(), server_default="0", nullable=False, comment="可用图片素材数量"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"private_portrait_projects",
|
||||||
|
sa.Column("active_video_asset_count", sa.Integer(), server_default="0", nullable=False, comment="可用视频素材数量"),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_projects_library_type",
|
||||||
|
"private_portrait_projects",
|
||||||
|
["library_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"idx_private_portrait_projects_user_library_status_created",
|
||||||
|
"private_portrait_projects",
|
||||||
|
["user_id", "library_type", "status", "created_at"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# 1. users 字段反向改名:保留数据
|
||||||
|
op.alter_column(
|
||||||
|
"users",
|
||||||
|
"private_portrait_asset_limit",
|
||||||
|
new_column_name="private_portrait_image_limit",
|
||||||
|
existing_type=sa.Integer(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text("5"),
|
||||||
|
comment="私域真人图片素材数量限制,0表示关闭",
|
||||||
|
existing_comment="私域人像素材总量限制,真人/虚拟共用,图片/视频共用,0 表示关闭",
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. private_portrait_projects
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_projects_user_library_status_created",
|
||||||
|
table_name="private_portrait_projects",
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_projects_library_type",
|
||||||
|
table_name="private_portrait_projects",
|
||||||
|
)
|
||||||
|
op.drop_column("private_portrait_projects", "active_video_asset_count")
|
||||||
|
op.drop_column("private_portrait_projects", "active_image_asset_count")
|
||||||
|
op.drop_column("private_portrait_projects", "video_asset_count")
|
||||||
|
op.drop_column("private_portrait_projects", "image_asset_count")
|
||||||
|
op.drop_column("private_portrait_projects", "library_type")
|
||||||
|
|
||||||
|
# 3. private_portrait_assets
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_assets_user_library_status_created",
|
||||||
|
table_name="private_portrait_assets",
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_assets_library_type",
|
||||||
|
table_name="private_portrait_assets",
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_assets_asset_type",
|
||||||
|
table_name="private_portrait_assets",
|
||||||
|
)
|
||||||
|
op.drop_column("private_portrait_assets", "mime_type")
|
||||||
|
op.drop_column("private_portrait_assets", "file_size")
|
||||||
|
op.drop_column("private_portrait_assets", "video_cover_url")
|
||||||
|
op.drop_column("private_portrait_assets", "video_duration")
|
||||||
|
op.drop_column("private_portrait_assets", "library_type")
|
||||||
|
|
||||||
|
# 4. private_portrait_asset_groups
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_asset_groups_user_library",
|
||||||
|
table_name="private_portrait_asset_groups",
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
"idx_private_portrait_asset_groups_library_type",
|
||||||
|
table_name="private_portrait_asset_groups",
|
||||||
|
)
|
||||||
|
op.drop_column("private_portrait_asset_groups", "library_type")
|
||||||
@@ -37,6 +37,10 @@ class Settings(BaseSettings):
|
|||||||
SMS_TEMPLATE_CODE: str = "SMS_001"
|
SMS_TEMPLATE_CODE: str = "SMS_001"
|
||||||
SMS_MOCK: bool = True
|
SMS_MOCK: bool = True
|
||||||
|
|
||||||
|
# 火山引擎配置。
|
||||||
|
VOLC_ACCESS_KEY_ID: str = ""
|
||||||
|
VOLC_SECRET_ACCESS_KEY: str = ""
|
||||||
|
|
||||||
# 火山引擎短信配置。
|
# 火山引擎短信配置。
|
||||||
# SmsAccount=消息组ID,TemplateID=模板ID,Sign=短信签名内容。
|
# SmsAccount=消息组ID,TemplateID=模板ID,Sign=短信签名内容。
|
||||||
VOLC_SMS_ACCESS_KEY_ID: str = ""
|
VOLC_SMS_ACCESS_KEY_ID: str = ""
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ def _remote_error_http_status(code: str) -> int:
|
|||||||
class ArkPrivateAssetClient:
|
class ArkPrivateAssetClient:
|
||||||
"""火山 Ark 私域可信素材 Asset API Client。只做 AK/SK 鉴权调用与响应标准化。"""
|
"""火山 Ark 私域可信素材 Asset API Client。只做 AK/SK 鉴权调用与响应标准化。"""
|
||||||
|
|
||||||
def __init__(self, *, ak: str | None = None, sk: str | None = None, for_celery: bool = False):
|
def __init__(self, *, for_celery: bool = False):
|
||||||
self.ak = ak or settings.VOLC_SMS_ACCESS_KEY_ID
|
self.ak = settings.VOLC_ACCESS_KEY_ID
|
||||||
self.sk = sk or settings.VOLC_SMS_SECRET_ACCESS_KEY
|
self.sk = settings.VOLC_SECRET_ACCESS_KEY
|
||||||
self.for_celery = for_celery
|
self.for_celery = for_celery
|
||||||
if not self.ak or not self.sk:
|
if not self.ak or not self.sk:
|
||||||
raise ArkPrivateAssetClientError("火山 AK/SK 未配置:VOLC_SMS_ACCESS_KEY_ID / VOLC_SMS_SECRET_ACCESS_KEY")
|
raise ArkPrivateAssetClientError("火山 AK/SK 未配置:VOLC_SMS_ACCESS_KEY_ID / VOLC_SMS_SECRET_ACCESS_KEY")
|
||||||
|
|||||||
Reference in New Issue
Block a user