feat(admin, miniapp): 优化数据库迁移逻辑与小程序图片资源处理
- 为后端Admin新增migration_compat工具,支持离线迁移时的基线资源检查,重构全部alembic迁移脚本适配离线模式,避免重复创建已存在的数据库表和字段 - 完善初始数据库迁移脚本,添加默认部门种子数据,新增ConciergeAdvisor详情字段从JSON到JSONB的类型转换迁移 - 小程序端新增图片资源解析工具resolveNetworkImage,实现本地静态资源到CDN的自动映射,添加图片加载容错降级机制 - 完善HeroSlide类型定义,新增actionLabel字段,优化首页轮播组件的文本渲染与错误处理逻辑 - 新增对应测试用例验证迁移路径正确性与前端数据处理逻辑 - 新增临时 brainstorm UI对比草稿与开发临时状态文件
This commit is contained in:
1 parent
96bcc7c032
commit
4e04feda5b
27 files changed
+2695
-377
No files matched your search
@@ -5,11 +5,14 @@ Revises: 0015_wanfa
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from alembic import context, op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
from app.migration_compat import baseline_table_names
|
||||
|
||||
|
||||
revision = "0016_concierge_advisors"
|
||||
down_revision = "0015_wanfa"
|
||||
@@ -60,14 +63,23 @@ SEED_ADVISORS = (
|
||||
)
|
||||
|
||||
|
||||
def is_offline_mode() -> bool:
|
||||
try:
|
||||
return context.is_offline_mode()
|
||||
except (NameError, AttributeError):
|
||||
return False
|
||||
|
||||
|
||||
def _seed_advisors() -> None:
|
||||
offline = is_offline_mode()
|
||||
details_type = sa.Text() if offline else sa.JSON()
|
||||
table = sa.table(
|
||||
"ConciergeAdvisor",
|
||||
sa.column("id", sa.String()),
|
||||
sa.column("avatar", sa.String()),
|
||||
sa.column("name", sa.String()),
|
||||
sa.column("role", sa.String()),
|
||||
sa.column("details", sa.JSON()),
|
||||
sa.column("details", details_type),
|
||||
sa.column("qrImage", sa.String()),
|
||||
sa.column("isActive", sa.Boolean()),
|
||||
sa.column("sortOrder", sa.Integer()),
|
||||
@@ -75,15 +87,18 @@ def _seed_advisors() -> None:
|
||||
sa.column("updatedAt", sa.DateTime()),
|
||||
)
|
||||
timestamp = datetime(2026, 1, 1)
|
||||
op.bulk_insert(
|
||||
table,
|
||||
[{**advisor, "createdAt": timestamp, "updatedAt": timestamp} for advisor in SEED_ADVISORS],
|
||||
)
|
||||
rows = [{**advisor, "createdAt": timestamp, "updatedAt": timestamp} for advisor in SEED_ADVISORS]
|
||||
if offline:
|
||||
rows = [{**advisor, "details": json.dumps(advisor["details"], ensure_ascii=False)} for advisor in rows]
|
||||
op.bulk_insert(table, rows)
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
bind = op.get_bind()
|
||||
existing_tables = set(inspect(bind).get_table_names())
|
||||
if is_offline_mode():
|
||||
existing_tables = baseline_table_names()
|
||||
else:
|
||||
bind = op.get_bind()
|
||||
existing_tables = set(inspect(bind).get_table_names())
|
||||
if "ConciergeAdvisor" not in existing_tables:
|
||||
op.create_table(
|
||||
"ConciergeAdvisor",
|
||||
@@ -102,7 +117,7 @@ def upgrade() -> None:
|
||||
op.create_index("ix_ConciergeAdvisor_isActive", "ConciergeAdvisor", ["isActive"])
|
||||
op.create_index("ix_ConciergeAdvisor_sortOrder", "ConciergeAdvisor", ["sortOrder"])
|
||||
|
||||
if context.is_offline_mode():
|
||||
if is_offline_mode():
|
||||
_seed_advisors()
|
||||
return
|
||||
|
||||
|
||||
Reference in new issue
Block a user