Browse Source

fix(account): sync-all 权限不足时降级为手动同步提示

alphah 2 weeks ago
parent
commit
334a95beea
1 changed files with 25 additions and 5 deletions
  1. 25 5
      backend/app/plugin/module_payment/account/service.py

+ 25 - 5
backend/app/plugin/module_payment/account/service.py

@@ -863,13 +863,12 @@ class AccountService:
     ) -> dict:
         """
         全量同步转账状态
-        查出本地所有 pay_transfer.out_biz_no,逐个调用 fund.trans.common.query 查询支付宝状态并更新
+        尝试调 fund.trans.common.query,如无权限则降级为列出 DEALING 记录供手动同步
         """
-        from sqlalchemy import select, update as sa_update
+        from sqlalchemy import select
         from app.plugin.module_payment.account.model import TransferModel
         from app.plugin.module_payment.account.enums import TransferStatusEnum
 
-        # 直接查所有有 out_biz_no 的转账记录(绕过权限过滤)
         stmt = select(TransferModel).where(
             TransferModel.out_biz_no.isnot(None),
         ).order_by(TransferModel.id.asc())
@@ -879,6 +878,7 @@ class AccountService:
         synced = 0
         errors = 0
         details = []
+        _has_permission = True
 
         for transfer in all_transfers:
             out_biz_no = transfer.out_biz_no
@@ -888,6 +888,10 @@ class AccountService:
 
             try:
                 result = await cls._sync_transfer_detail(auth, out_biz_no, eid)
+                if result is False:
+                    # fund.trans.common.query 无权限
+                    _has_permission = False
+                    break
                 if result:
                     synced += 1
                     details.append({"out_biz_no": out_biz_no, "old_status": transfer.status, "new_status": result})
@@ -898,6 +902,17 @@ class AccountService:
                 details.append({"out_biz_no": out_biz_no, "status": transfer.status, "error": str(e)})
                 log.warning(f"全量同步 - 查询失败: out_biz_no={out_biz_no}, err={e}")
 
+        if not _has_permission:
+            # 无权限时降级为列出 DEALING 记录
+            dealing = [t for t in all_transfers if t.status == TransferStatusEnum.DEALING.value]
+            return {
+                "total": len(all_transfers),
+                "synced": 0,
+                "dealing_count": len(dealing),
+                "details": [{"out_biz_no": t.out_biz_no, "status": "DEALING"} for t in dealing],
+                "note": "fund.trans.common.query 无权限,请在支付宝开放平台开通接口权限后重试,或逐个使用 sync-status 手动补录",
+            }
+
         if synced > 0:
             await auth.db.flush()
 
@@ -914,8 +929,8 @@ class AccountService:
         auth: AuthSchema,
         out_biz_no: str,
         enterprise_id: str,
-    ) -> str | None:
-        """调用 fund.trans.common.query 查询单笔转账详情并更新本地记录,返回新状态"""
+    ) -> str | bool | None:
+        """调用 fund.trans.common.query 查询单笔转账详情并更新本地记录,返回新状态/False(无权限)/None(其他失败)"""
         from sqlalchemy import update as sa_update
         from app.plugin.module_payment.account.model import TransferModel
 
@@ -951,6 +966,11 @@ class AccountService:
         result.parse_response_content(response)
 
         if not result.is_success():
+            sub_code = getattr(result, 'sub_code', '') or ''
+            sub_msg = getattr(result, 'sub_msg', '') or ''
+            if '权限' in sub_msg or 'NO_PERMISSION' in sub_code:
+                log.warning(f"fund.trans.common.query 无权限: out_biz_no={out_biz_no}")
+                return False
             return None
 
         alipay_status = getattr(result, 'status', None)