Преглед изворни кода

feat: pay_transfer表新增payee_type冗余列+索引,自动回填存量数据

alphah пре 1 недеља
родитељ
комит
9100219eb0

+ 52 - 0
backend/app/alembic/versions/a1b2c3d4e5f6_add_payee_type_to_pay_transfer.py

@@ -0,0 +1,52 @@
+"""add payee_type to pay_transfer
+
+Revision ID: a1b2c3d4e5f6
+Revises: 6c2d2ac3ce5a
+Create Date: 2026-05-22 11:35:00.000000
+
+"""
+from typing import Sequence, Union
+
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.sql import text
+
+
+# revision identifiers, used by Alembic.
+revision: str = 'a1b2c3d4e5f6'
+down_revision: Union[str, None] = '6c2d2ac3ce5a'
+branch_labels: Union[str, Sequence[str], None] = None
+depends_on: Union[str, Sequence[str], None] = None
+
+
+def _get_json_extract_sql() -> str:
+    """根据数据库类型返回 JSON 提取 SQL"""
+    dialect = op.get_bind().dialect.name
+    if dialect == 'postgresql':
+        return "UPDATE pay_transfer SET payee_type = payee_info->>'identity_type' WHERE payee_info IS NOT NULL AND payee_info->>'identity_type' IS NOT NULL"
+    elif dialect == 'mysql':
+        return "UPDATE pay_transfer SET payee_type = JSON_UNQUOTE(JSON_EXTRACT(payee_info, '$.identity_type')) WHERE payee_info IS NOT NULL AND JSON_EXTRACT(payee_info, '$.identity_type') IS NOT NULL"
+    else:
+        # SQLite 等,跳过回填
+        return None
+
+
+def upgrade() -> None:
+    # 1. 添加 payee_type 列(允许 NULL)
+    op.add_column('pay_transfer', sa.Column(
+        'payee_type', sa.String(32), nullable=True,
+        comment='收款方类型: ALIPAY_ACCOUNT/BANK_CARD/BOOK'
+    ))
+
+    # 2. 回填存量数据:从 payee_info JSON 中提取 identity_type
+    backfill_sql = _get_json_extract_sql()
+    if backfill_sql:
+        op.execute(text(backfill_sql))
+
+    # 3. 创建索引
+    op.create_index('ix_pay_transfer_payee_type', 'pay_transfer', ['payee_type'])
+
+
+def downgrade() -> None:
+    op.drop_index('ix_pay_transfer_payee_type', table_name='pay_transfer')
+    op.drop_column('pay_transfer', 'payee_type')

+ 3 - 0
backend/app/plugin/module_payment/account/model.py

@@ -77,6 +77,9 @@ class TransferModel(PaymentModelMixin, TenantMixin, EnterpriseMixin):
     payee_info: Mapped[dict | None] = mapped_column(
         JSON, comment="收款方信息"
     )
+    payee_type: Mapped[str | None] = mapped_column(
+        String(32), index=True, comment="收款方类型: ALIPAY_ACCOUNT/BANK_CARD/BOOK"
+    )
     status: Mapped[str] = mapped_column(
         String(32),
         default=TransferStatusEnum.DEALING.value,

+ 2 - 0
backend/app/plugin/module_payment/account/service.py

@@ -345,6 +345,7 @@ class AccountService:
             "amount": model.amount,
             "order_title": model.order_title,
             "payee_info": data.payee_info.model_dump() if data.payee_info else None,
+            "payee_type": data.payee_info.identity_type if data.payee_info else None,
             "status": result.status,
             "order_no": result.order_no,
             "fund_order_id": result.fund_order_id,
@@ -477,6 +478,7 @@ class AccountService:
             "amount": model.amount,
             "order_title": model.order_title,
             "payee_info": data.payee_info.model_dump() if data.payee_info else None,
+            "payee_type": data.payee_info.identity_type if data.payee_info else None,
             "status": result.status,
             "order_no": result.order_no,
             "fund_order_id": result.fund_order_id,