ソースを参照

fix: 修复创建制度时standard_condition_info_list为空问题+合并支付宝端自动发放额度+手工发放按钮入口

- institution/controller.py: 兜底添加QUOTA_TOTAL:0条件规则
- quota/service.py: 列表查询合并支付宝端自动发放额度
- QuotaList.vue: 新增额度管理/手工发放跳转按钮
- quota/index.vue: 支持?tab=batch参数自动切换标签页
alphah 2 週間 前
コミット
8f8b956142

+ 52 - 1
backend/app/plugin/module_payment/expense/quota/service.py

@@ -590,10 +590,61 @@ class QuotaService:
     ) -> dict:
         crud = QuotaCRUD(auth)
         offset = (page_no - 1) * page_size
-        return await crud.page(
+        result = await crud.page(
             offset=offset,
             limit=page_size,
             order_by=[{"id": "desc"}],
             search=search or {},
             out_schema=QuotaListOutSchema,
         )
+        # 如果指定了 institution_id,同时查询支付宝端自动发放的额度
+        if search and search.get("institution_id"):
+            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,
+                )
+
+                alipay_model = AlipayEbppInvoiceExpensecontrolQuotaQueryModel()
+                alipay_model.target_type = "INSTITUTION"
+                alipay_model.target_id = search["institution_id"]
+                alipay_model.page_size = 100
+                alipay_model.page_num = 1
+
+                request = AlipayEbppInvoiceExpensecontrolQuotaQueryRequest()
+                request.biz_model = alipay_model
+
+                client = AlipayClient.get_client()
+                response = client.execute(request)
+
+                if response:
+                    alipay_result = AlipayEbppInvoiceExpensecontrolQuotaQueryResponse()
+                    alipay_result.parse_response_content(response)
+                    if alipay_result.is_success() and hasattr(alipay_result, 'quota_detail_info_list') and alipay_result.quota_detail_info_list:
+                        # 将支付宝端额度合并到结果中(去重)
+                        existing_ids = {item.get("quota_id") for item in result.get("items", []) if item.get("quota_id")}
+                        for q in alipay_result.quota_detail_info_list:
+                            qid = getattr(q, 'quota_id', None)
+                            if qid and qid not in existing_ids:
+                                result["items"].append({
+                                    "quota_id": qid,
+                                    "target_type": getattr(q, 'target_type', None),
+                                    "target_id": getattr(q, 'target_id', None),
+                                    "quota_type": getattr(q, 'quota_type', None),
+                                    "employee_id": getattr(q, 'owner_id', None),
+                                    "total_amount": getattr(q, 'total_amount', None),
+                                    "available_amount": getattr(q, 'available_amount', None),
+                                    "status": getattr(q, 'status', "QUOTA_ACTIVE"),
+                                    "created_time": getattr(q, 'effective_start_date', None),
+                                })
+                                existing_ids.add(qid)
+                        result["total"] = len(result["items"])
+            except Exception as e:
+                log.warning(f"查询支付宝端额度失败(不影响本地数据): {e}")
+
+        return result

BIN
frontend/dist.zip


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

@@ -1,13 +1,19 @@
 <template>
   <div class="quota-list">
-    <div v-if="!readonly" class="quota-list__toolbar">
+    <div v-if="!readonly" class="quota-list__toolbar" style="display: flex; gap: 8px; flex-wrap: wrap;">
       <el-button
-        v-hasPerm="['module_payment:quota:create']"
         type="primary"
         size="small"
-        @click="handleCreate"
+        @click="goToQuotaPage('quota')"
       >
-        发放额度
+        额度管理
+      </el-button>
+      <el-button
+        type="success"
+        size="small"
+        @click="goToQuotaPage('batch')"
+      >
+        手工发放
       </el-button>
     </div>
 
@@ -92,6 +98,7 @@ import QuotaAPI, {
 import QuotaDetailDialog from "./QuotaDetailDialog.vue";
 import { ElMessage } from "element-plus";
 import { onMounted, ref } from "vue";
+import { useRouter } from "vue-router";
 
 interface Props {
   institutionId: string;
@@ -108,6 +115,17 @@ const loading = ref(false);
 
 const detailVisible = ref(false);
 const currentQuotaId = ref("");
+const router = useRouter();
+
+function goToQuotaPage(tab: string) {
+  router.push({
+    path: "/module_payment/quota",
+    query: {
+      institution_id: props.institutionId,
+      tab: tab,
+    },
+  });
+}
 
 async function fetchList() {
   if (!props.institutionId) return;

+ 5 - 1
frontend/src/views/module_payment/quota/index.vue

@@ -325,7 +325,11 @@ const categoryTabs = [
   { key: "quota", label: "额度管理" },
   { key: "batch", label: "手工发放" },
 ];
-const activeCategory = ref("quota");
+const activeCategory = ref((route.query.tab as string) || "quota");
+
+onMounted(() => {
+  if (activeCategory.value === "batch") loadBatchList();
+});
 
 function handleCategoryChange(key: string) {
   activeCategory.value = key;