瀏覽代碼

fix: 回退quota_id=out_biz_no错误方案;调整额度时quota_id为空则从支付宝查询回填

alphah 1 周之前
父節點
當前提交
7b73cd407d

+ 2 - 6
backend/app/plugin/module_payment/expense/institution/scope_sync.py

@@ -98,12 +98,10 @@ async def _sync_employee_quota(
                 existing = await auth.db.execute(check)
                 if not existing.scalar_one_or_none():
                     total, available, status = _compute_quota_status(inst)
-                    out_biz_no = f"scope_{inst_id}_{employee_id}"
                     stmt = insert(QuotaModel).values(
                         employee_id=employee_id,
                         institution_id=inst_id,
-                        out_biz_no=out_biz_no,
-                        quota_id=out_biz_no,
+                        out_biz_no=f"scope_{inst_id}_{employee_id}",
                         total_amount=total,
                         available_amount=available,
                         status=status,
@@ -216,11 +214,9 @@ async def sync_employee_to_all_institution(
             if existing.scalar_one_or_none():
                 continue
             total, available, status = _compute_quota_status(inst)
-            out_biz_no = f"all_{inst_id}_{employee_id}"
             stmt = insert(QuotaModel).values(
                 employee_id=employee_id, institution_id=inst_id,
-                out_biz_no=out_biz_no,
-                quota_id=out_biz_no,
+                out_biz_no=f"all_{inst_id}_{employee_id}",
                 total_amount=total, available_amount=available,
                 status=status,
                 enterprise_id=enterprise_id, tenant_id=tenant_id,

+ 57 - 5
backend/app/plugin/module_payment/expense/quota/service.py

@@ -480,15 +480,13 @@ class QuotaService:
                         quota_amount = Decimal("0")
 
                     # 每次都新增独立记录,不覆盖已有记录
-                    out_biz_no = f"batch_{data.batch_no}_{emp_id}"
                     stmt = insert(QuotaModel).values(
                         employee_id=emp_id,
                         institution_id=data.institution_id,
                         quota_type=data.quota_type,
                         target_type="INSTITUTION",
                         target_id=data.institution_id,
-                        out_biz_no=out_biz_no,
-                        quota_id=out_biz_no,  # 先用 out_biz_no 作初始值,后续支付宝回调更新
+                        out_biz_no=f"batch_{data.batch_no}_{emp_id}",
                         total_amount=quota_amount,
                         available_amount=quota_amount,
                         status=QuotaStatusEnum.QUOTA_ACTIVE.value,
@@ -784,13 +782,67 @@ class QuotaService:
         from .model import QuotaModel
         from sqlalchemy import select, update as sa_update
 
-        # 查询当前额度记录
+        # 查询当前额度记录(支持按 quota_id 或 id 查找)
         stmt = select(QuotaModel).where(QuotaModel.quota_id == data.quota_id)
         result = await auth.db.execute(stmt)
         quota = result.scalar_one_or_none()
+        if not quota:
+            # quota_id 为空时尝试按数据库 id 查找
+            try:
+                local_id = int(data.quota_id)
+                stmt = select(QuotaModel).where(QuotaModel.id == local_id)
+                result = await auth.db.execute(stmt)
+                quota = result.scalar_one_or_none()
+            except (ValueError, TypeError):
+                pass
         if not quota:
             raise CustomException(msg="额度记录不存在")
 
+        # 如果本地 quota_id 为空,尝试从 Alipay 获取真实 quota_id
+        alipay_quota_id = quota.quota_id
+        if not alipay_quota_id and quota.out_biz_no:
+            try:
+                from alipay.aop.api.request.AlipayEbppInvoiceExpensecontrolQuotaQueryRequest import (
+                    AlipayEbppInvoiceExpensecontrolQuotaQueryRequest,
+                )
+                from alipay.aop.api.domain.AlipayEbppInvoiceExpensecontrolQuotaQueryModel import (
+                    AlipayEbppInvoiceExpensecontrolQuotaQueryModel,
+                )
+                from alipay.aop.api.response.AlipayEbppInvoiceExpensecontrolQuotaQueryResponse import (
+                    AlipayEbppInvoiceExpensecontrolQuotaQueryResponse,
+                )
+                query_model = AlipayEbppInvoiceExpensecontrolQuotaQueryModel()
+                query_model.enterprise_id = quota.enterprise_id or data.enterprise_id
+                query_model.owner_id = quota.employee_id
+                query_model.owner_type = "ENTERPRISE_PAY_UID"
+                query_model.page_num = 1
+                query_model.page_size = 10
+
+                query_request = AlipayEbppInvoiceExpensecontrolQuotaQueryRequest()
+                query_request.biz_model = query_model
+
+                client = AlipayClient.get_client()
+                query_response = client.execute(query_request)
+                if query_response:
+                    query_result = AlipayEbppInvoiceExpensecontrolQuotaQueryResponse()
+                    query_result.parse_response_content(query_response)
+                    if query_result.is_success() and hasattr(query_result, 'quota_detail_info_list') and query_result.quota_detail_info_list:
+                        for q in query_result.quota_detail_info_list:
+                            qid = getattr(q, 'quota_id', None)
+                            if qid:
+                                alipay_quota_id = qid
+                                # 回写本地
+                                upd = sa_update(QuotaModel).where(QuotaModel.id == quota.id).values(quota_id=qid)
+                                await auth.db.execute(upd)
+                                await auth.db.flush()
+                                log.info(f"从支付宝回填 quota_id: id={quota.id}, quota_id={qid}")
+                                break
+            except Exception as e:
+                log.warning(f"从支付宝获取真实 quota_id 失败: {e}")
+
+        if not alipay_quota_id:
+            raise CustomException(msg="该额度暂未关联支付宝额度ID,无法调整(请等待支付宝同步后重试)")
+
         current_available = float(quota.available_amount) if quota.available_amount else 0
         diff = round(data.amount - current_available, 2)
         outer_source_id = str(get_snowflake_id())
@@ -810,7 +862,7 @@ class QuotaService:
             raise CustomException(msg="支付宝SDK未正确安装")
 
         model = AlipayEbppInvoiceExpensecontrolQuotaModifyModel()
-        model.quota_id = data.quota_id
+        model.quota_id = alipay_quota_id
         model.action = "ADD" if diff >= 0 else "DEDUCT"
         model.outer_source_id = outer_source_id
         model.enterprise_id = data.enterprise_id

二進制
frontend/dist.zip


+ 1 - 1
frontend/src/views/module_payment/institution/components/QuotaList.vue

@@ -240,7 +240,7 @@ function handleDetail(row: any) {
 
 function handleAdjust(row: any) {
   currentAdjustQuota.value = {
-    quota_id: row.quota_id,
+    quota_id: row.quota_id || String(row.id || ""),
     available_amount: row.available_amount,
     total_amount: row.total_amount,
   };