From eaf9c983b41f2c1fe682526eab131999f84fb8fe Mon Sep 17 00:00:00 2001
From: wupengfei <834520024@qq.com>
Date: 星期一, 20 十月 2025 15:47:35 +0800
Subject: [PATCH] feat: 页面

---
 src/constants/fourStreams.ts                                                 |   23 +
 src/views/MaterialReview/MaterialReview.vue                                  |    9 
 src/views/StatisticalReport/components/FinancialAllocationDetailDialog.vue   |  104 ++++
 src/views/StatisticalReport/RewardStatistics.vue                             |  506 ++++++++++++++++++++++++
 src/views/StatisticalReport/components/EnterpriseWithdrawalDetailDialog.vue  |  104 ++++
 src/views/EnterpriseInfo/components/RewardGrantRecordView.vue                |    2 
 src/views/StatisticalReport/hooks/rewardStatistics.ts                        |   56 ++
 src/hooks/index.ts                                                           |    1 
 src/views/StatisticalReport/components/PlatformDisbursementDetailDialog.vue  |  104 ++++
 src/hooks/industrialPark.ts                                                  |    8 
 src/views/StatisticalReport/components/EnterpriseRechargeDetailDialog.vue    |  104 ++++
 src/views/Reward/RewardGrant.vue                                             |    7 
 src/views/Reward/WithdrawalApproval.vue                                      |    5 
 src/views/StatisticalReport/components/EnterpriseConsumptionDetailDialog.vue |  104 ++++
 src/views/StatisticalReport/components/BalanceDetailDialog.vue               |   60 ++
 src/router/index.ts                                                          |   29 +
 src/views/StatisticalReport/hooks/index.ts                                   |    1 
 src/views/Reward/RewardGrantRegister.vue                                     |    2 
 18 files changed, 1,221 insertions(+), 8 deletions(-)

diff --git a/src/constants/fourStreams.ts b/src/constants/fourStreams.ts
index d881f87..795e448 100644
--- a/src/constants/fourStreams.ts
+++ b/src/constants/fourStreams.ts
@@ -161,3 +161,26 @@
   /// 璐㈡斂鎷ㄤ粯
   Finance = 30,
 }
+
+export enum EnumParkRewardStatisticsDetailScene {
+  /**
+   * 璐㈡斂鎷ㄤ粯
+   */
+  Finance = 1,
+  /**
+   * 骞冲彴鎷ㄤ粯
+   */
+  Transfer = 2,
+  /**
+   * 浼佷笟鍏呭��
+   */
+  Recharge = 3,
+  /**
+   * 浼佷笟鎻愮幇
+   */
+  DrawWith = 4,
+  /**
+   * 浼佷笟娑堣垂
+   */
+  Trade = 5,
+}
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index 40bb2cf..475a6f8 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -10,3 +10,4 @@
 export * from './dic';
 export * from './table';
 export * from './fourStreams';
+export * from './industrialPark';
diff --git a/src/hooks/industrialPark.ts b/src/hooks/industrialPark.ts
index 6c0fde9..f03b60c 100644
--- a/src/hooks/industrialPark.ts
+++ b/src/hooks/industrialPark.ts
@@ -15,6 +15,13 @@
     return industrialPark;
   }
 
+  function getIndustrialParkByName(industrialParkName: string) {
+    const industrialPark = industrialParkList.value.find(
+      (item) => item.parkName === industrialParkName
+    );
+    return industrialPark;
+  }
+
   function getIndustrialParkTypeNameById(industrialParkId: string) {
     const industrialPark = getIndustrialParkById(industrialParkId);
     return industrialPark?.parkTypeName ?? '';
@@ -30,5 +37,6 @@
     getIndustrialParkNameById,
     getIndustrialParkById,
     getIndustrialParkTypeNameById,
+    getIndustrialParkByName,
   };
 }
diff --git a/src/router/index.ts b/src/router/index.ts
index 23d6f7b..4fe318f 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -184,6 +184,7 @@
       },
     ],
   },
+
   {
     path: '/Reward',
     redirect: 'noRedirect',
@@ -273,6 +274,34 @@
       },
     ],
   },
+  {
+    path: '/StatisticalReport',
+    redirect: 'noRedirect',
+    component: Layout,
+    hidden: false,
+    alwaysShow: true,
+    meta: {
+      rank: 10040,
+      title: '缁熻鎶ヨ〃',
+      rootMenu: true,
+      icon: 'home',
+    },
+    children: [
+      {
+        path: '/RewardStatistics',
+        name: 'RewardStatistics',
+        hidden: false,
+        alwaysShow: true,
+        component: () => import('@/views/StatisticalReport/RewardStatistics.vue'),
+        meta: {
+          rank: 10041,
+          title: '濂栧姳閲戠粺璁�',
+          // rootMenu: true,
+          icon: 'home',
+        },
+      },
+    ],
+  },
   // {
   //   path: '/Syatem',
   //   redirect: 'noRedirect',
diff --git a/src/views/EnterpriseInfo/components/RewardGrantRecordView.vue b/src/views/EnterpriseInfo/components/RewardGrantRecordView.vue
index a5167f1..f9c0dd7 100644
--- a/src/views/EnterpriseInfo/components/RewardGrantRecordView.vue
+++ b/src/views/EnterpriseInfo/components/RewardGrantRecordView.vue
@@ -7,8 +7,6 @@
         v-bind="dialogMaterialFileProps"
         :show-upload-btn="false"
         :show-delete-btn="false"
-        :show-check-btn="false"
-        downloadBtnText="鏌ョ湅"
         title="鏌ョ湅鍑瘉"
         :BusinessTypeEnumText="ApplyTransferFileBusinessTypeEnumText"
       />
diff --git a/src/views/MaterialReview/MaterialReview.vue b/src/views/MaterialReview/MaterialReview.vue
index c3f3735..1d6b544 100644
--- a/src/views/MaterialReview/MaterialReview.vue
+++ b/src/views/MaterialReview/MaterialReview.vue
@@ -74,7 +74,7 @@
 import { useGlobalEventContext } from '@/hooks';
 
 defineOptions({
-  name: 'MaterialReview',
+  name: 'MaterialReviewList',
 });
 
 const column: API.CustomModuleColumnDto[] = [
@@ -110,11 +110,16 @@
   },
   {
     id: '7',
+    enCode: 'a',
+    name: '瀹℃牳浜�',
+  },
+  {
+    id: '8',
     enCode: 'outCheckTime',
     name: '瀹℃牳鏃ユ湡',
   },
   {
-    id: '8',
+    id: '9',
     enCode: 'outCheckStatus',
     name: '瀹℃牳鐘舵��',
   },
diff --git a/src/views/Reward/RewardGrant.vue b/src/views/Reward/RewardGrant.vue
index 27e2812..7d9061b 100644
--- a/src/views/Reward/RewardGrant.vue
+++ b/src/views/Reward/RewardGrant.vue
@@ -72,8 +72,6 @@
         v-bind="dialogMaterialFileProps"
         :show-upload-btn="false"
         :show-delete-btn="false"
-        :show-check-btn="false"
-        downloadBtnText="鏌ョ湅"
         title="鏌ョ湅鍑瘉"
         :BusinessTypeEnumText="TransferFileEnumInRewardGrandText"
       />
@@ -189,6 +187,11 @@
     name: '骞冲彴鎷ㄤ粯鐧昏鏃ユ湡',
     width: 180,
   },
+  {
+    id: '11',
+    enCode: 'a',
+    name: '鎿嶄綔浜�',
+  },
 ];
 
 const operationBtns = defineOperationBtns([
diff --git a/src/views/Reward/RewardGrantRegister.vue b/src/views/Reward/RewardGrantRegister.vue
index c4fa6d6..98939eb 100644
--- a/src/views/Reward/RewardGrantRegister.vue
+++ b/src/views/Reward/RewardGrantRegister.vue
@@ -27,8 +27,6 @@
               v-bind="dialogMaterialFileProps"
               :show-upload-btn="false"
               :show-delete-btn="false"
-              :show-check-btn="false"
-              downloadBtnText="鏌ョ湅"
               title="鏌ョ湅鍑瘉"
               :BusinessTypeEnumText="TransferFileEnumInRewardGrandText"
             />
diff --git a/src/views/Reward/WithdrawalApproval.vue b/src/views/Reward/WithdrawalApproval.vue
index a575e10..6d17d8d 100644
--- a/src/views/Reward/WithdrawalApproval.vue
+++ b/src/views/Reward/WithdrawalApproval.vue
@@ -111,6 +111,11 @@
     name: '瀹℃牳鐘舵��',
   },
   {
+    id: '8',
+    enCode: 'a',
+    name: '瀹℃牳浜�',
+  },
+  {
     id: '9',
     enCode: 'checkTime',
     name: '瀹℃牳鏃堕棿',
diff --git a/src/views/StatisticalReport/RewardStatistics.vue b/src/views/StatisticalReport/RewardStatistics.vue
new file mode 100644
index 0000000..8d22efb
--- /dev/null
+++ b/src/views/StatisticalReport/RewardStatistics.vue
@@ -0,0 +1,506 @@
+<template>
+  <LoadingLayout :loading="state.loading">
+    <AppContainer>
+      <div class="statistics-wrapper">
+        <el-text class="mx-1">{{
+          `璐㈡斂鎷ㄤ粯鍚堣锛氾骏${toThousand(objectData?.sumFinanceAmount ?? 0)}`
+        }}</el-text>
+        <el-text class="mx-1">{{
+          `骞冲彴鎷ㄤ粯鍚堣锛氾骏${toThousand(objectData?.sumTransferAmount ?? 0)}`
+        }}</el-text>
+        <el-text class="mx-1">{{
+          `浼佷笟鍏呭�煎悎璁★細锟�${toThousand(objectData?.sumRechargeAmount ?? 0)}`
+        }}</el-text>
+        <el-text class="mx-1">{{
+          `浼佷笟娑堣垂鍚堣锛氾骏${toThousand(objectData?.sumTradeAmount ?? 0)}`
+        }}</el-text>
+        <el-text class="mx-1">{{
+          `浼佷笟浣欓鍚堣锛氾骏${toThousand(objectData?.sumAmount ?? 0)}`
+        }}</el-text>
+      </div>
+      <ProTableQueryFilterBar @on-reset="reset">
+        <template #query>
+          <QueryFilterItem tip-content="鐢虫姤鏈堜唤">
+            <FieldDatePicker
+              v-model="extraParamState.month"
+              type="month"
+              clearable
+              placeholder="璇烽�夋嫨鐢虫姤鏈堜唤"
+              format="YYYY-MM"
+              value-format="YYYY-MM"
+              @change="getList()"
+            ></FieldDatePicker>
+          </QueryFilterItem>
+          <QueryFilterItem>
+            <FieldSelect
+              v-model="extraParamState.industrialParkId"
+              placeholder="璇烽�夋嫨鍥尯"
+              :value-enum="fourStreamsIndustrialParkList"
+              enumLabelKey="parkName"
+              enum-value-key="id"
+              clearable
+              @change="getList()"
+            />
+          </QueryFilterItem>
+          <QueryFilterItem>
+            <SearchInput
+              v-model="extraParamState.keywords"
+              style="width: 300px"
+              placeholder="浼佷笟鍚�/淇$敤浠g爜/鑱旂郴浜�/鑱旂郴鏂瑰紡"
+              @on-click-search="getList"
+            >
+            </SearchInput>
+          </QueryFilterItem>
+        </template>
+        <template #btn>
+          <el-button @click="handleExport()" icon="Download" type="primary">瀵煎嚭</el-button>
+        </template>
+      </ProTableQueryFilterBar>
+      <ProTableV2 v-bind="proTableProps" :columns="column" :show-operation-column="false">
+        <template #sumFinanceAmountBtn="{ row }">
+          <el-button type="primary" link @click="handleFinancialAllocationDetail(row)"
+            >鏌ョ湅鏄庣粏</el-button
+          >
+        </template>
+        <template #sumTransferAmountBtn="{ row }">
+          <el-button type="primary" link @click="handlePlatformDisbursementDetail(row)"
+            >鏌ョ湅鏄庣粏</el-button
+          >
+        </template>
+        <template #sumRechargeAmountBtn="{ row }">
+          <el-button type="primary" link @click="handleEnterpriseRechargeDetail(row)"
+            >鏌ョ湅鏄庣粏</el-button
+          >
+        </template>
+        <template #sumTradeAmountBtn="{ row }">
+          <el-button type="primary" link @click="handleEnterpriseConsumptionDetail(row)"
+            >鏌ョ湅鏄庣粏</el-button
+          >
+        </template>
+        <template #sumDrawWithAmountBtn="{ row }">
+          <el-button type="primary" link @click="handleEnterpriseWithdrawalDetail(row)"
+            >鏌ョ湅鏄庣粏</el-button
+          >
+        </template>
+        <template #amountBtn="{ row }">
+          <el-button type="primary" link @click="handleBalanceDetail(row)">鏌ョ湅鏄庣粏</el-button>
+        </template>
+      </ProTableV2>
+    </AppContainer>
+    <FinancialAllocationDetailDialog
+      v-bind="dialogFinancialAllocationDetailProps"
+    ></FinancialAllocationDetailDialog>
+    <PlatformDisbursementDetailDialog
+      v-bind="dialogPlatformDisbursementDetailProps"
+    ></PlatformDisbursementDetailDialog>
+    <EnterpriseRechargeDetailDialog
+      v-bind="dialogEnterpriseRechargeDetailProps"
+    ></EnterpriseRechargeDetailDialog>
+    <EnterpriseConsumptionDetailDialog
+      v-bind="dialogEnterpriseConsumptionDetailProps"
+    ></EnterpriseConsumptionDetailDialog>
+    <EnterpriseWithdrawalDetailDialog
+      v-bind="dialogEnterpriseWithdrawalDetailProps"
+    ></EnterpriseWithdrawalDetailDialog>
+    <BalanceDetailDialog v-bind="dialogBalanceDetailProps"></BalanceDetailDialog>
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import {
+  ProTableQueryFilterBar,
+  OperationBtnType,
+  ProTableV2,
+  SearchInput,
+  LoadingLayout,
+  AppContainer,
+  QueryFilterItem,
+  useTable,
+  FieldDatePicker,
+  FieldSelect,
+  useFormDialog,
+  defineColumns,
+} from '@bole-core/components';
+import { useAccess, useIndustrialParkDropDownList } from '@/hooks';
+import { downloadFile, Message, OrderInputType } from '@bole-core/core';
+import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
+import { toThousand } from '@/utils';
+import _ from 'lodash';
+import FinancialAllocationDetailDialog from './components/FinancialAllocationDetailDialog.vue';
+import PlatformDisbursementDetailDialog from './components/PlatformDisbursementDetailDialog.vue';
+import EnterpriseRechargeDetailDialog from './components/EnterpriseRechargeDetailDialog.vue';
+import EnterpriseConsumptionDetailDialog from './components/EnterpriseConsumptionDetailDialog.vue';
+import EnterpriseWithdrawalDetailDialog from './components/EnterpriseWithdrawalDetailDialog.vue';
+import BalanceDetailDialog from './components/BalanceDetailDialog.vue';
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+
+defineOptions({
+  name: 'RewardStatistics',
+});
+
+const column = defineColumns([
+  {
+    id: '1',
+    enCode: 'enterpriseName',
+    name: '浼佷笟鍚嶇О',
+    width: 250,
+  },
+  {
+    id: '2',
+    enCode: 'societyCreditCode',
+    name: '淇$敤浠g爜',
+    width: 200,
+  },
+  {
+    id: '3',
+    enCode: 'industrialParkName',
+    name: '鎵�灞炲洯鍖�',
+    width: 200,
+  },
+  {
+    id: '4',
+    enCode: 'contact',
+    name: '鑱旂郴浜�',
+    width: 150,
+  },
+  {
+    id: '5',
+    enCode: 'contactPhone',
+    name: '鑱旂郴鏂瑰紡',
+    width: 120,
+  },
+  {
+    id: '6',
+    enCode: 'month',
+    name: '鐢虫姤鏈堜唤',
+    width: 120,
+  },
+  {
+    id: '7',
+    enCode: 'batchNo',
+    name: '鐢虫姤鎵规鍙�',
+    width: 150,
+  },
+  {
+    id: '8',
+    enCode: 'sumFinanceAmount',
+    name: '璐㈡斂鎷ㄤ粯閲戦',
+    width: 120,
+  },
+  {
+    id: '9',
+    enCode: 'sumFinanceAmountBtn',
+    name: '璐㈡斂鎷ㄤ粯鏄庣粏',
+    width: 120,
+  },
+  {
+    id: '10',
+    enCode: 'sumTransferAmount',
+    name: '骞冲彴鎷ㄤ粯閲戦',
+    width: 120,
+  },
+  {
+    id: '11',
+    enCode: 'sumTransferAmountBtn',
+    name: '骞冲彴鎷ㄤ粯鏄庣粏',
+    width: 120,
+  },
+  {
+    id: '12',
+    enCode: 'sumRechargeAmount',
+    name: '浼佷笟鍏呭�兼�婚',
+    width: 120,
+  },
+  {
+    id: '13',
+    enCode: 'sumRechargeAmountBtn',
+    name: '浼佷笟鍏呭�兼槑缁�',
+    width: 120,
+  },
+  {
+    id: '14',
+    enCode: 'sumTradeAmount',
+    name: '浼佷笟娑堣垂鎬婚',
+    width: 120,
+  },
+  {
+    id: '15',
+    enCode: 'sumTradeAmountBtn',
+    name: '浼佷笟娑堣垂鏄庣粏',
+    width: 120,
+  },
+  {
+    id: '16',
+    enCode: 'sumDrawWithAmount',
+    name: '浼佷笟鎻愮幇鎬婚',
+    width: 120,
+  },
+  {
+    id: '17',
+    enCode: 'sumDrawWithAmountBtn',
+    name: '浼佷笟鎻愮幇鏄庣粏',
+    width: 120,
+  },
+  {
+    id: '18',
+    enCode: 'amount',
+    name: '璐︽埛浣欓',
+    width: 120,
+  },
+  {
+    id: '19',
+    enCode: 'amountBtn',
+    name: '浣欓鏄庣粏',
+    width: 120,
+  },
+]);
+
+const BaseState = {
+  loading: true,
+  czbf: false,
+
+  detailObject: {} as API.GetRewardStatisticsDetailInput,
+};
+
+const state = reactive({ ...BaseState });
+
+onMounted(async () => {
+  // await getList();
+  state.loading = false;
+});
+
+const { industrialParkList } = useIndustrialParkDropDownList();
+
+const fourStreamsIndustrialParkList = computed(() => {
+  return industrialParkList.value.filter((x) => !!x.rewardEnable);
+});
+
+const {
+  getDataSource: getList,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  objectData,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      if (!extraParamState.month) {
+        Message.errorMessage('璇烽�夋嫨鏈堜唤');
+        return;
+      }
+      if (!extraParamState.industrialParkId) {
+        Message.errorMessage('璇烽�夋嫨鍥尯');
+        return;
+      }
+      let params: API.GetRewardStatisticsInput = {
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          orderInput: extraParamState.orderInput,
+        },
+        keywords: extraParamState.keywords,
+        industrialParkId: extraParamState.industrialParkId,
+        month: extraParamState.month,
+      };
+      let res = await parkBountyApplyServices.getRewardStatistics(params, {
+        showLoading: !state.loading,
+      });
+      return res;
+    } catch (error) {}
+  },
+  {
+    defaultExtraParams: {
+      keywords: '',
+      industrialParkId: '',
+      month: '',
+      orderInput: [{ property: 'enterpriseId', order: OrderInputType.Desc }],
+    },
+    columnsRenderProps: {
+      month: { type: 'date', format: 'YYYY骞碝M鏈�' },
+      sumFinanceAmount: {
+        type: 'money',
+        formatter: (row: API.GetRewardStatisticsDto) =>
+          row.sumFinanceAmount === null ? '涓嶆敮鎸�' : toThousand(row.sumFinanceAmount),
+      },
+      sumTransferAmount: {
+        type: 'money',
+        formatter: (row: API.GetRewardStatisticsDto) =>
+          row.sumTransferAmount === null ? '涓嶆敮鎸�' : toThousand(row.sumTransferAmount),
+      },
+      sumRechargeAmount: {
+        type: 'money',
+        formatter: (row: API.GetRewardStatisticsDto) =>
+          row.sumRechargeAmount === null ? '涓嶆敮鎸�' : toThousand(row.sumRechargeAmount),
+      },
+      sumDrawWithAmount: {
+        type: 'money',
+        formatter: (row: API.GetRewardStatisticsDto) =>
+          row.sumDrawWithAmount === null ? '涓嶆敮鎸�' : toThousand(row.sumDrawWithAmount),
+      },
+      sumTradeAmount: {
+        type: 'money',
+        formatter: (row: API.GetRewardStatisticsDto) =>
+          row.sumTradeAmount === null ? '涓嶆敮鎸�' : toThousand(row.sumTradeAmount),
+      },
+      amount: {
+        type: 'money',
+        formatter: (row: API.GetRewardStatisticsDto) =>
+          row.amount === null ? '涓嶆敮鎸�' : toThousand(row.amount),
+      },
+    },
+  }
+);
+
+const handleExport = _.debounce(
+  async () => {
+    if (!extraParamState.month) {
+      Message.errorMessage('璇烽�夋嫨鏈堜唤');
+      return;
+    }
+    if (!extraParamState.industrialParkId) {
+      Message.errorMessage('璇烽�夋嫨鍥尯');
+      return;
+    }
+    if (paginationState.total === 0) {
+      Message.warnMessage('娌℃湁鏁版嵁鍙互瀵煎嚭鍝');
+      return;
+    }
+    try {
+      let params: API.ExportRewardStatisticsInput = {
+        month: extraParamState.month,
+        industrialParkId: extraParamState.industrialParkId,
+        keywords: extraParamState.keywords,
+      };
+      let res = await parkBountyApplyServices.exportRewardStatistics(params, {
+        responseType: 'blob',
+        getResponse: true,
+      });
+      if (res) {
+        downloadFile(res.data, `濂栧姳閲戠粺璁, 'xlsx');
+        Message.successMessage('瀵煎嚭鎴愬姛');
+        getList(paginationState.pageIndex);
+      }
+    } catch (error) {}
+  },
+  1000,
+  { leading: true, trailing: false }
+);
+
+function createDetailObj(
+  row: API.GetRewardStatisticsDto,
+  scene: EnumParkRewardStatisticsDetailScene
+) {
+  return (state.detailObject = {
+    enterpriseId: row.enterpriseId,
+    month: row.month,
+    scene: scene,
+  });
+}
+
+const {
+  dialogProps: dialogFinancialAllocationDetailProps,
+  dialogState: dialogFinancialAllocationDetailState,
+  handleAdd: handleFinancialAllocationDetailAdd,
+} = useFormDialog({
+  defaultFormParams: state.detailObject,
+});
+
+function handleFinancialAllocationDetail(row: API.GetRewardStatisticsDto) {
+  handleFinancialAllocationDetailAdd(
+    createDetailObj(row, EnumParkRewardStatisticsDetailScene.Finance)
+  );
+}
+
+const {
+  dialogProps: dialogPlatformDisbursementDetailProps,
+  dialogState: dialogPlatformDisbursementDetailState,
+  handleAdd: handlePlatformDisbursementDetailAdd,
+} = useFormDialog({
+  defaultFormParams: state.detailObject,
+});
+
+function handlePlatformDisbursementDetail(row: API.GetRewardStatisticsDto) {
+  handlePlatformDisbursementDetailAdd(
+    createDetailObj(row, EnumParkRewardStatisticsDetailScene.Transfer)
+  );
+}
+
+const {
+  dialogProps: dialogEnterpriseRechargeDetailProps,
+  dialogState: dialogEnterpriseRechargeDetailState,
+  handleAdd: handleEnterpriseRechargeDetailAdd,
+} = useFormDialog({
+  defaultFormParams: state.detailObject,
+});
+
+function handleEnterpriseRechargeDetail(row: API.GetRewardStatisticsDto) {
+  handleEnterpriseRechargeDetailAdd(
+    createDetailObj(row, EnumParkRewardStatisticsDetailScene.Recharge)
+  );
+}
+
+const {
+  dialogProps: dialogEnterpriseConsumptionDetailProps,
+  dialogState: dialogEnterpriseConsumptionDetailState,
+  handleAdd: handleEnterpriseConsumptionDetailAdd,
+} = useFormDialog({
+  defaultFormParams: state.detailObject,
+});
+
+function handleEnterpriseConsumptionDetail(row: API.GetRewardStatisticsDto) {
+  handleEnterpriseConsumptionDetailAdd(
+    createDetailObj(row, EnumParkRewardStatisticsDetailScene.Trade)
+  );
+}
+
+const {
+  dialogProps: dialogEnterpriseWithdrawalDetailProps,
+  dialogState: dialogEnterpriseWithdrawalDetailState,
+  handleAdd: handleEnterpriseWithdrawalDetailAdd,
+} = useFormDialog({
+  defaultFormParams: state.detailObject,
+});
+
+function handleEnterpriseWithdrawalDetail(row: API.GetRewardStatisticsDto) {
+  handleEnterpriseWithdrawalDetailAdd(
+    createDetailObj(row, EnumParkRewardStatisticsDetailScene.DrawWith)
+  );
+}
+
+const {
+  dialogProps: dialogBalanceDetailProps,
+  dialogState: dialogBalanceDetailState,
+  handleAdd: handleBalanceDetailAdd,
+} = useFormDialog({
+  defaultFormParams: {
+    financeAmount: 0,
+    bountyAmount: 0,
+    rechargeAmount: 0,
+    sumDrawWithAmount: null,
+  },
+});
+
+function handleBalanceDetail(row: API.GetRewardStatisticsDto) {
+  handleBalanceDetailAdd({
+    financeAmount: row.financeAmount,
+    bountyAmount: row.bountyAmount,
+    rechargeAmount: row.rechargeAmount,
+    sumDrawWithAmount: row.sumDrawWithAmount,
+  });
+}
+</script>
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+
+.statistics-wrapper {
+  display: flex;
+  margin-bottom: 16px;
+  padding: 20px boleGetCssVar('proTable', 'filter-bar-horizontal-padding');
+  background-color: #ffffff;
+
+  .mx-1 + .mx-1 {
+    margin-left: 20px;
+  }
+}
+</style>
diff --git a/src/views/StatisticalReport/components/BalanceDetailDialog.vue b/src/views/StatisticalReport/components/BalanceDetailDialog.vue
new file mode 100644
index 0000000..cbf9499
--- /dev/null
+++ b/src/views/StatisticalReport/components/BalanceDetailDialog.vue
@@ -0,0 +1,60 @@
+<template>
+  <ProDialog title="浣欓鏄庣粏" v-model="visible" destroy-on-close draggable>
+    <PortraitTable v-bind="portraitTableProps" label-width="140px" :col-number="1"></PortraitTable>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')" type="primary">纭</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { ProDialog, toThousand } from '@bole-core/components';
+import { usePortraitTable } from '@/hooks';
+
+defineOptions({
+  name: 'PlatformDisbursementDetailDialog',
+});
+
+type Form = {
+  financeAmount?: number;
+  bountyAmount?: number;
+  rechargeAmount?: number;
+};
+
+const visible = defineModel({ type: Boolean });
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const { portraitTableProps } = usePortraitTable({
+  data: form,
+  columns: [
+    {
+      label: '璐㈡斂鎷ㄤ粯浣欓',
+      key: 'financeAmount',
+      type: 'money',
+      formatter: (row) =>
+        row.sumDrawWithAmount === null ? '涓嶆敮鎸�' : toThousand(row.financeAmount),
+    },
+    {
+      label: '骞冲彴鎷ㄤ粯浣欓',
+      key: 'bountyAmount',
+      type: 'money',
+    },
+    {
+      label: '棰勫厖鍊间綑棰�',
+      key: 'rechargeAmount',
+      type: 'money',
+    },
+  ],
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/StatisticalReport/components/EnterpriseConsumptionDetailDialog.vue b/src/views/StatisticalReport/components/EnterpriseConsumptionDetailDialog.vue
new file mode 100644
index 0000000..96ecb85
--- /dev/null
+++ b/src/views/StatisticalReport/components/EnterpriseConsumptionDetailDialog.vue
@@ -0,0 +1,104 @@
+<template>
+  <ProDialog title="浼佷笟娑堣垂鏄庣粏" v-model="visible" destroy-on-close draggable>
+    <ProDialogTableWrapper :height="400">
+      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
+        <template #operationBtn-checkBtn="{ data, row }">
+          <PreviewBtnV2
+            class="pro-table-operation-btn"
+            :url="convertApi2FormUrlBySeparator(row.url ?? '')"
+            preview-btn-text="鏌ョ湅鍑瘉"
+          />
+        </template>
+      </ProTableV2>
+    </ProDialogTableWrapper>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')" type="primary">纭</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  ProTableV2,
+  ProDialogTableWrapper,
+  defineColumns,
+  defineOperationBtns,
+  PreviewBtnV2,
+} from '@bole-core/components';
+import { convertApi2FormUrlBySeparator } from '@/utils';
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+import { useRewardStatisticsDetail } from '../hooks';
+
+defineOptions({
+  name: 'EnterpriseConsumptionDetailDialog',
+});
+
+type Form = {
+  enterpriseId?: string;
+  month?: string;
+  scene?: EnumParkRewardStatisticsDetailScene;
+};
+
+const visible = defineModel({ type: Boolean });
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const columns = defineColumns([
+  {
+    id: '1',
+    enCode: 'creationTime',
+    name: '濂栧姳閲戞秷璐规棩鏈�',
+  },
+  {
+    id: '2',
+    enCode: 'type',
+    name: '娑堣垂绫诲瀷',
+  },
+  {
+    id: '3',
+    enCode: 'amount',
+    name: '娑堣垂閲戦',
+  },
+]);
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '鏌ョ湅鍑瘉',
+    },
+    extraProps: {
+      hide: (row: API.GetRewardStatisticsDetailDto) => !row.url,
+    },
+  },
+]);
+
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      getRewardStatisticsDetail();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
+const { getRewardStatisticsDetail, proTableProps } = useRewardStatisticsDetail({
+  enterpriseId: toRef(form.value, 'enterpriseId'),
+  month: toRef(form.value, 'month'),
+  scene: toRef(form.value, 'scene'),
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/StatisticalReport/components/EnterpriseRechargeDetailDialog.vue b/src/views/StatisticalReport/components/EnterpriseRechargeDetailDialog.vue
new file mode 100644
index 0000000..800c32e
--- /dev/null
+++ b/src/views/StatisticalReport/components/EnterpriseRechargeDetailDialog.vue
@@ -0,0 +1,104 @@
+<template>
+  <ProDialog title="浼佷笟鍏呭�兼槑缁�" v-model="visible" destroy-on-close draggable>
+    <ProDialogTableWrapper :height="400">
+      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
+        <template #operationBtn-checkBtn="{ data, row }">
+          <PreviewBtnV2
+            class="pro-table-operation-btn"
+            :url="convertApi2FormUrlBySeparator(row.url ?? '')"
+            preview-btn-text="鏌ョ湅鍑瘉"
+          />
+        </template>
+      </ProTableV2>
+    </ProDialogTableWrapper>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')" type="primary">纭</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  ProTableV2,
+  ProDialogTableWrapper,
+  defineColumns,
+  defineOperationBtns,
+  PreviewBtnV2,
+} from '@bole-core/components';
+import { convertApi2FormUrlBySeparator } from '@/utils';
+import { useRewardStatisticsDetail } from '../hooks';
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+
+defineOptions({
+  name: 'EnterpriseRechargeDetailDialog',
+});
+
+type Form = {
+  enterpriseId?: string;
+  month?: string;
+  scene?: EnumParkRewardStatisticsDetailScene;
+};
+
+const visible = defineModel({ type: Boolean });
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const columns = defineColumns([
+  {
+    id: '1',
+    enCode: 'creationTime',
+    name: '浼佷笟鍏呭�兼棩鏈�',
+  },
+  {
+    id: '2',
+    enCode: 'auditTime',
+    name: '瀹℃牳閫氳繃鏃ユ湡',
+  },
+  {
+    id: '3',
+    enCode: 'amount',
+    name: '鍏呭�奸噾棰�',
+  },
+]);
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '鏌ョ湅鍑瘉',
+    },
+    extraProps: {
+      hide: (row: API.GetRewardStatisticsDetailDto) => !row.url,
+    },
+  },
+]);
+
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      getRewardStatisticsDetail();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
+const { getRewardStatisticsDetail, proTableProps } = useRewardStatisticsDetail({
+  enterpriseId: toRef(form.value, 'enterpriseId'),
+  month: toRef(form.value, 'month'),
+  scene: toRef(form.value, 'scene'),
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/StatisticalReport/components/EnterpriseWithdrawalDetailDialog.vue b/src/views/StatisticalReport/components/EnterpriseWithdrawalDetailDialog.vue
new file mode 100644
index 0000000..8e4d67c
--- /dev/null
+++ b/src/views/StatisticalReport/components/EnterpriseWithdrawalDetailDialog.vue
@@ -0,0 +1,104 @@
+<template>
+  <ProDialog title="浼佷笟鎻愮幇鏄庣粏" v-model="visible" destroy-on-close draggable>
+    <ProDialogTableWrapper :height="400">
+      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
+        <template #operationBtn-checkBtn="{ data, row }">
+          <PreviewBtnV2
+            class="pro-table-operation-btn"
+            :url="convertApi2FormUrlBySeparator(row.url ?? '')"
+            preview-btn-text="鏌ョ湅鍑瘉"
+          />
+        </template>
+      </ProTableV2>
+    </ProDialogTableWrapper>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')" type="primary">纭</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  ProTableV2,
+  ProDialogTableWrapper,
+  defineColumns,
+  defineOperationBtns,
+  PreviewBtnV2,
+} from '@bole-core/components';
+import { convertApi2FormUrlBySeparator } from '@/utils';
+import { useRewardStatisticsDetail } from '../hooks';
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+
+defineOptions({
+  name: 'EnterpriseWithdrawalDetailDialog',
+});
+
+type Form = {
+  enterpriseId?: string;
+  month?: string;
+  scene?: EnumParkRewardStatisticsDetailScene;
+};
+
+const visible = defineModel({ type: Boolean });
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const columns = defineColumns([
+  {
+    id: '1',
+    enCode: 'creationTime',
+    name: '鐢宠鎻愮幇鏃ユ湡',
+  },
+  {
+    id: '2',
+    enCode: 'auditTime',
+    name: '瀹℃牳閫氳繃鏃ユ湡',
+  },
+  {
+    id: '3',
+    enCode: 'amount',
+    name: '鎻愮幇閲戦',
+  },
+]);
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '鏌ョ湅鍑瘉',
+    },
+    extraProps: {
+      hide: (row: API.GetRewardStatisticsDetailDto) => !row.url,
+    },
+  },
+]);
+
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      getRewardStatisticsDetail();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
+const { getRewardStatisticsDetail, proTableProps } = useRewardStatisticsDetail({
+  enterpriseId: toRef(form.value, 'enterpriseId'),
+  month: toRef(form.value, 'month'),
+  scene: toRef(form.value, 'scene'),
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/StatisticalReport/components/FinancialAllocationDetailDialog.vue b/src/views/StatisticalReport/components/FinancialAllocationDetailDialog.vue
new file mode 100644
index 0000000..38cf061
--- /dev/null
+++ b/src/views/StatisticalReport/components/FinancialAllocationDetailDialog.vue
@@ -0,0 +1,104 @@
+<template>
+  <ProDialog title="璐㈡斂鎷ㄤ粯鏄庣粏" v-model="visible" destroy-on-close draggable>
+    <ProDialogTableWrapper :height="400">
+      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
+        <template #operationBtn-checkBtn="{ data, row }">
+          <PreviewBtnV2
+            class="pro-table-operation-btn"
+            :url="convertApi2FormUrlBySeparator(row.url ?? '')"
+            preview-btn-text="鏌ョ湅鍑瘉"
+          />
+        </template>
+      </ProTableV2>
+    </ProDialogTableWrapper>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')" type="primary">纭</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  ProTableV2,
+  ProDialogTableWrapper,
+  defineColumns,
+  defineOperationBtns,
+  PreviewBtnV2,
+} from '@bole-core/components';
+import { convertApi2FormUrlBySeparator } from '@/utils';
+import { useRewardStatisticsDetail } from '../hooks';
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+
+defineOptions({
+  name: 'FinancialAllocationDetailDialog',
+});
+
+type Form = {
+  enterpriseId?: string;
+  month?: string;
+  scene?: EnumParkRewardStatisticsDetailScene;
+};
+
+const visible = defineModel({ type: Boolean });
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const columns = defineColumns([
+  {
+    id: '1',
+    enCode: 'creationTime',
+    name: '璐㈡斂鎷ㄤ粯鏃ユ湡',
+  },
+  {
+    id: '2',
+    enCode: 'auditTime',
+    name: '鍏ヨ处鏃ユ湡',
+  },
+  {
+    id: '3',
+    enCode: 'amount',
+    name: '鎷ㄤ粯閲戦',
+  },
+]);
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '鏌ョ湅鍑瘉',
+    },
+    extraProps: {
+      hide: (row: API.GetRewardStatisticsDetailDto) => !row.url,
+    },
+  },
+]);
+
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      getRewardStatisticsDetail();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
+const { getRewardStatisticsDetail, proTableProps } = useRewardStatisticsDetail({
+  enterpriseId: toRef(form.value, 'enterpriseId'),
+  month: toRef(form.value, 'month'),
+  scene: toRef(form.value, 'scene'),
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/StatisticalReport/components/PlatformDisbursementDetailDialog.vue b/src/views/StatisticalReport/components/PlatformDisbursementDetailDialog.vue
new file mode 100644
index 0000000..de71759
--- /dev/null
+++ b/src/views/StatisticalReport/components/PlatformDisbursementDetailDialog.vue
@@ -0,0 +1,104 @@
+<template>
+  <ProDialog title="骞冲彴鎷ㄤ粯鏄庣粏" v-model="visible" destroy-on-close draggable>
+    <ProDialogTableWrapper :height="400">
+      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
+        <template #operationBtn-checkBtn="{ data, row }">
+          <PreviewBtnV2
+            class="pro-table-operation-btn"
+            :url="convertApi2FormUrlBySeparator(row.url ?? '')"
+            preview-btn-text="鏌ョ湅鍑瘉"
+          />
+        </template>
+      </ProTableV2>
+    </ProDialogTableWrapper>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')" type="primary">纭</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  ProDialog,
+  ProTableV2,
+  ProDialogTableWrapper,
+  defineColumns,
+  defineOperationBtns,
+  PreviewBtnV2,
+} from '@bole-core/components';
+import { convertApi2FormUrlBySeparator } from '@/utils';
+import { useRewardStatisticsDetail } from '../hooks';
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+
+defineOptions({
+  name: 'PlatformDisbursementDetailDialog',
+});
+
+type Form = {
+  enterpriseId?: string;
+  month?: string;
+  scene?: EnumParkRewardStatisticsDetailScene;
+};
+
+const visible = defineModel({ type: Boolean });
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void;
+  (e: 'onCancel'): void;
+}>();
+
+const columns = defineColumns([
+  {
+    id: '1',
+    enCode: 'creationTime',
+    name: '骞冲彴鎷ㄤ粯鏃ユ湡',
+  },
+  {
+    id: '2',
+    enCode: 'auditTime',
+    name: '鍏ヨ处鏃ユ湡',
+  },
+  {
+    id: '3',
+    enCode: 'amount',
+    name: '骞冲彴鎷ㄤ粯閲戦',
+  },
+]);
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '鏌ョ湅鍑瘉',
+    },
+    extraProps: {
+      hide: (row: API.GetRewardStatisticsDetailDto) => !row.url,
+    },
+  },
+]);
+
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      getRewardStatisticsDetail();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
+const { getRewardStatisticsDetail, proTableProps } = useRewardStatisticsDetail({
+  enterpriseId: toRef(form.value, 'enterpriseId'),
+  month: toRef(form.value, 'month'),
+  scene: toRef(form.value, 'scene'),
+});
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/StatisticalReport/hooks/index.ts b/src/views/StatisticalReport/hooks/index.ts
new file mode 100644
index 0000000..15e3ae4
--- /dev/null
+++ b/src/views/StatisticalReport/hooks/index.ts
@@ -0,0 +1 @@
+export * from './rewardStatistics';
diff --git a/src/views/StatisticalReport/hooks/rewardStatistics.ts b/src/views/StatisticalReport/hooks/rewardStatistics.ts
new file mode 100644
index 0000000..b1d4324
--- /dev/null
+++ b/src/views/StatisticalReport/hooks/rewardStatistics.ts
@@ -0,0 +1,56 @@
+import { EnumParkRewardStatisticsDetailScene } from '@/constants';
+import { useTable } from '@bole-core/components';
+import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
+import { OrderInputType } from '@bole-core/core';
+
+type UseRewardStatisticsDetailOptions = {
+  scene?: Ref<EnumParkRewardStatisticsDetailScene>;
+  enterpriseId?: Ref<string>;
+  month?: Ref<string>;
+};
+export function useRewardStatisticsDetail(options: UseRewardStatisticsDetailOptions = {}) {
+  const { scene = '' as any as EnumParkRewardStatisticsDetailScene, enterpriseId, month } = options;
+
+  const {
+    getDataSource: getRewardStatisticsDetail,
+    proTableProps,
+    paginationState,
+    extraParamState,
+    reset,
+  } = useTable(
+    async ({ pageIndex, pageSize }, extraParamState) => {
+      try {
+        let params: API.GetRewardStatisticsDetailInput = {
+          pageModel: {
+            rows: pageSize,
+            page: pageIndex,
+            orderInput: extraParamState.orderInput,
+          },
+          enterpriseId: unref(enterpriseId),
+          scene: unref(scene),
+          month: unref(month),
+        };
+        let res = await parkBountyApplyServices.getRewardStatisticsDetail(params);
+        return res;
+      } catch (error) {}
+    },
+    {
+      defaultExtraParams: {
+        orderInput: [{ property: 'creationTime', order: OrderInputType.Desc }],
+      },
+      columnsRenderProps: {
+        creationTime: { type: 'date', format: 'YYYY-MM-DD HH:mm:ss' },
+        auditTime: { type: 'date', format: 'YYYY-MM-DD HH:mm:ss' },
+        amount: { type: 'money' },
+      },
+    }
+  );
+
+  return {
+    getRewardStatisticsDetail,
+    proTableProps,
+    paginationState,
+    extraParamState,
+    reset,
+  };
+}

--
Gitblit v1.9.1