From 052a1c6f01420d695cb3c251619249725181ff02 Mon Sep 17 00:00:00 2001
From: wupengfei <834520024@qq.com>
Date: 星期二, 22 七月 2025 09:32:38 +0800
Subject: [PATCH] feat: 页面

---
 src/constants/fourStreams.ts                                |    3 
 src/views/Reward/components/RegisterGrantDialog.vue         |  121 ++++
 src/views/Reward/components/BatchRegisterDialog.vue         |  214 +++++++
 src/views/Reward/RewardApplyTradeCheck.vue                  |   31 +
 src/hooks/fourStreams.ts                                    |  175 ++++++
 src/views/Reward/components/UploadFileDialog.vue            |   86 +++
 src/constants/enum.ts                                       |    2 
 src/views/Reward/components/RewardApplyTradeCheckDialog.vue |   50 +
 src/views/Reward/constants/columns.ts                       |   26 
 src/hooks/index.ts                                          |    1 
 src/views/MaterialReview/MaterialReviewAudit.vue            |  108 ---
 src/views/Reward/RewardGrant.vue                            |   11 
 src/components/commonView/DeclareEnterpriseTableView.vue    |   16 
 src/constants/reward.ts                                     |    2 
 src/views/Reward/RewardDeclareDetail.vue                    |  135 ----
 src/components/Table/PortraitTableWithAttachment.vue        |    1 
 src/router/index.ts                                         |   28 
 src/views/MaterialReview/MaterialReviewDetail.vue           |  124 ----
 src/views/Reward/FinancialApproval.vue                      |  257 +++++++++
 src/views/Reward/RewardGrantRegister.vue                    |  282 ++++++++++
 20 files changed, 1,293 insertions(+), 380 deletions(-)

diff --git a/src/components/Table/PortraitTableWithAttachment.vue b/src/components/Table/PortraitTableWithAttachment.vue
index cefb234..ab47935 100644
--- a/src/components/Table/PortraitTableWithAttachment.vue
+++ b/src/components/Table/PortraitTableWithAttachment.vue
@@ -1,4 +1,5 @@
 <template>
+  <slot name="title"></slot>
   <PortraitTable v-bind="portraitTableProps" :label-width="labelWidth"> </PortraitTable>
   <div class="enclosure-list-title">闄勪欢鍒楄〃</div>
   <ProTableV2
diff --git a/src/components/commonView/DeclareEnterpriseTableView.vue b/src/components/commonView/DeclareEnterpriseTableView.vue
index 8fdd4d1..d3e38de 100644
--- a/src/components/commonView/DeclareEnterpriseTableView.vue
+++ b/src/components/commonView/DeclareEnterpriseTableView.vue
@@ -11,6 +11,9 @@
         </SearchInput>
       </QueryFilterItem>
     </template>
+    <template #btn>
+      <slot name="btn"></slot>
+    </template>
   </ProTableQueryFilterBar>
   <ProTableV2
     v-bind="proTableProps"
@@ -53,23 +56,12 @@
   };
   openDialog?: (row) => void;
   column?: API.ModuleColumnDto[];
+  operationBtns?: OperationBtnType[];
 };
 
 const props = withDefaults(defineProps<Props>(), {
   column: () => BaseDeclareEnterpriseTableViewColumns,
 });
-
-const operationBtns = defineOperationBtns([
-  {
-    data: {
-      enCode: 'detailBtn',
-      name: '璇︽儏',
-    },
-    emits: {
-      onClick: (role) => props.openDialog(role),
-    },
-  },
-]);
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/constants/enum.ts b/src/constants/enum.ts
index bf513f0..2c5984b 100644
--- a/src/constants/enum.ts
+++ b/src/constants/enum.ts
@@ -49,3 +49,5 @@
   Warning: 'var(--el-color-warning)',
   Danger: 'var(--el-color-danger)',
 };
+
+export const TempFolderPath = 'https://parkmanagement.oss-cn-hangzhou.aliyuncs.com/12333/temp';
diff --git a/src/constants/fourStreams.ts b/src/constants/fourStreams.ts
index 59a436b..4b6fcf8 100644
--- a/src/constants/fourStreams.ts
+++ b/src/constants/fourStreams.ts
@@ -1,4 +1,5 @@
 import { defineColumns } from '@bole-core/components';
+import { TempFolderPath } from './enum';
 
 export enum FourStreamsMaterialFileBusinessTypeEnum {
   /** 鍥尯鍏ラ┗鍗忚 */
@@ -136,3 +137,5 @@
 
   return { addRewardApplyStep3Columns };
 }
+
+export const BountyBatchApplyTransferTemp = `${TempFolderPath}/%E5%85%A5%E8%B4%A6%E6%A8%A1%E6%9D%BF.xlsx`;
diff --git a/src/constants/reward.ts b/src/constants/reward.ts
index ce66d20..49d6dd0 100644
--- a/src/constants/reward.ts
+++ b/src/constants/reward.ts
@@ -134,7 +134,7 @@
 export enum IncomeTypeEnum {
   /**璐㈡斂鎷ㄤ粯 */
   Fiscal = 10,
-  /**骞冲彴鍏呭�� */
+  /**骞冲彴鎷ㄤ粯 */
   Platform = 20,
 }
 
diff --git a/src/hooks/fourStreams.ts b/src/hooks/fourStreams.ts
new file mode 100644
index 0000000..b312d80
--- /dev/null
+++ b/src/hooks/fourStreams.ts
@@ -0,0 +1,175 @@
+import { defineColumns, defineOperationBtns, useFormDialog, useTable } from '@bole-core/components';
+import { OrderInputType } from '@bole-core/core';
+import { useQueryClient } from '@tanstack/vue-query';
+import { setOSSLink } from '@/utils';
+import {
+  CustomerApplyFileTypeListItem,
+  EnterpriseApplyFileUtils,
+} from '@/components/commonView/utils';
+import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
+import * as enterpriseApplyFileServices from '@/services/api/EnterpriseApplyFile';
+import { BaseDeclareEnterpriseTableViewColumns, EnterpriseTypeText } from '@/constants';
+
+export const rewardGrantRegisterColumns = computed(() =>
+  defineColumns([
+    ...BaseDeclareEnterpriseTableViewColumns,
+    {
+      id: '9',
+      enCode: 'a',
+      name: '璐㈡斂鎷ㄤ粯閲戦',
+    },
+    {
+      id: '10',
+      enCode: 'a',
+      name: '璐㈡斂鎷ㄤ粯宸茬櫥璁�',
+    },
+    {
+      id: '11',
+      enCode: 'a',
+      name: '鏈�杩戠櫥璁版棩鏈�',
+    },
+    {
+      id: '12',
+      enCode: 'a',
+      name: '璐㈡斂鎷ㄤ粯鐧昏鐘舵��',
+    },
+    {
+      id: '13',
+      enCode: 'a',
+      name: '骞冲彴鎷ㄤ粯閲戦',
+    },
+    {
+      id: '14',
+      enCode: 'a',
+      name: '骞冲彴鎷ㄤ粯宸茬櫥璁�',
+    },
+    {
+      id: '15',
+      enCode: 'a',
+      name: '鏈�杩戠櫥璁版棩鏈�',
+    },
+    {
+      id: '16',
+      enCode: 'a',
+      name: '骞冲彴鎷ㄤ粯鐧昏鐘舵��',
+    },
+  ])
+);
+
+type UseDeclareEnterpriseTableOptions = {
+  id?: Ref<string>;
+  applyMonth?: Ref<string>;
+};
+
+export function useDeclareEnterpriseTable(options: UseDeclareEnterpriseTableOptions = {}) {
+  const { id, applyMonth } = options;
+
+  const {
+    getDataSource: getList,
+    proTableProps,
+    paginationState,
+    extraParamState,
+    reset,
+  } = useTable(
+    async ({ pageIndex, pageSize }, extraParamState) => {
+      try {
+        let params: API.GetParkBountyApplyInfoInput = {
+          pageModel: {
+            rows: pageSize,
+            page: pageIndex,
+            orderInput: extraParamState.orderInput,
+          },
+          searchKeyWord: extraParamState.searchKeyWord,
+          parkBountyApplyId: id.value,
+        };
+        let res = await parkBountyApplyServices.getOutCheckParkBountyApplyDetailList(params);
+        return res;
+      } catch (error) {}
+    },
+    {
+      defaultExtraParams: {
+        orderInput: [{ property: 'parkBountyApplyId', order: OrderInputType.Desc }],
+        searchKeyWord: '',
+      },
+      columnsRenderProps: {
+        authType: { type: 'enum', valueEnum: EnterpriseTypeText },
+        licenseUrl: {
+          type: 'urlV2',
+          formatter: (row: API.UserCertificationAuditListDto) => setOSSLink(row.licenseUrl),
+        },
+        applyAmount: { type: 'money' },
+      },
+    }
+  );
+
+  const queryClient = useQueryClient();
+  const { dialogProps, handleAdd, editForm, dialogState } = useFormDialog({
+    defaultFormParams: {
+      list: [] as CustomerApplyFileTypeListItem[],
+      companyId: '',
+    },
+  });
+  async function openDialog(row: API.ParkBountyApplyDetailInfo) {
+    try {
+      const applyFilesRes = await queryClient.ensureQueryData({
+        queryKey: [
+          'enterpriseApplyFileServices/getCustomerUploadApplyFiles',
+          row.enterpriseId,
+          applyMonth.value,
+        ],
+        queryFn: async () => {
+          return await enterpriseApplyFileServices.getCustomerUploadApplyFiles({
+            enterpriseId: row.enterpriseId,
+            withMonth: applyMonth.value,
+          });
+        },
+      });
+      const lastUploadEnterPactFile = await queryClient.ensureQueryData({
+        queryKey: ['enterpriseApplyFileServices/getCustomerUploadApplyFiles', row.enterpriseId],
+        queryFn: async () => {
+          return await parkBountyApplyServices.getEnterpriseLastUploadEnterPactFileNew({
+            companyId: row.enterpriseId,
+          });
+        },
+      });
+
+      const applyUploadFiles = await parkBountyApplyServices.getEnterpriseParkApplyUploadFiles({
+        companyId: row.enterpriseId,
+        parkBountyApplyId: id.value,
+      });
+      handleAdd({
+        list: EnterpriseApplyFileUtils.initParkCollectFileListApplyFiles(
+          applyUploadFiles,
+          applyFilesRes.items,
+          lastUploadEnterPactFile
+        ),
+        companyId: row.enterpriseId,
+      });
+    } catch (error) {}
+  }
+
+  const operationBtns = defineOperationBtns([
+    {
+      data: {
+        enCode: 'detailBtn',
+        name: '璇︽儏',
+      },
+      emits: {
+        onClick: (row) => openDialog(row),
+      },
+    },
+  ]);
+
+  return {
+    getList,
+    proTableProps,
+    paginationState,
+    extraParamState,
+    reset,
+    openDialog,
+    dialogProps,
+    dialogState,
+    editForm,
+    operationBtns,
+  };
+}
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index e101419..40bb2cf 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -9,3 +9,4 @@
 export * from './help';
 export * from './dic';
 export * from './table';
+export * from './fourStreams';
diff --git a/src/router/index.ts b/src/router/index.ts
index 6314848..23d6f7b 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -222,13 +222,24 @@
         },
       },
       {
+        path: '/RewardGrantRegister/:id',
+        name: 'RewardGrantRegister',
+        hidden: true,
+        component: () => import('@/views/Reward/RewardGrantRegister.vue'),
+        meta: {
+          rank: 10033,
+          title: '濂栧姳閲戠櫥璁�',
+          rootMenu: false,
+        },
+      },
+      {
         path: '/WithdrawalApproval',
         name: 'WithdrawalApproval',
         hidden: false,
         alwaysShow: true,
         component: () => import('@/views/Reward/WithdrawalApproval.vue'),
         meta: {
-          rank: 10033,
+          rank: 10040,
           title: '鎻愮幇瀹℃壒',
           // rootMenu: true,
           icon: 'home',
@@ -241,12 +252,25 @@
         alwaysShow: true,
         component: () => import('@/views/Reward/RewardApplyTradeCheck.vue'),
         meta: {
-          rank: 10034,
+          rank: 10050,
           title: '鍑鸿处瀹℃壒',
           // rootMenu: true,
           icon: 'home',
         },
       },
+      {
+        path: '/FinancialApproval',
+        name: 'FinancialApproval',
+        hidden: false,
+        alwaysShow: true,
+        component: () => import('@/views/Reward/FinancialApproval.vue'),
+        meta: {
+          rank: 10060,
+          title: '璐㈠姟瀹℃壒',
+          // rootMenu: true,
+          icon: 'home',
+        },
+      },
     ],
   },
   // {
diff --git a/src/views/MaterialReview/MaterialReviewAudit.vue b/src/views/MaterialReview/MaterialReviewAudit.vue
index fcb7d90..7773e91 100644
--- a/src/views/MaterialReview/MaterialReviewAudit.vue
+++ b/src/views/MaterialReview/MaterialReviewAudit.vue
@@ -9,7 +9,7 @@
               :extra-param-state="extraParamState"
               :pro-table-props="proTableProps"
               :reset="reset"
-              :open-dialog="openDialog"
+              :operationBtns="operationBtns"
             ></DeclareEnterpriseTableView>
             <MateriaDetailDialog
               v-bind="dialogProps"
@@ -91,7 +91,7 @@
 import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
 import * as enterpriseApplyFileServices from '@/services/api/EnterpriseApplyFile';
 import { convertApi2FormUrlObjectBySeparator, setOSSLink } from '@/utils';
-import { useGlobalEventContext, useRouteView } from '@/hooks';
+import { useDeclareEnterpriseTable, useGlobalEventContext, useRouteView } from '@/hooks';
 import { FormInstance } from 'element-plus';
 import { Message, OrderInputType } from '@bole-core/core';
 import { FourStreamsMaterialFileTableItem } from '@/components/commonView/types';
@@ -116,17 +116,18 @@
   parkTypeName: '',
   applyMonth: '',
   applySumAmount: 0,
-  // enterpriseTaxSubFileUrl: [] as UploadUserFile[],
-  // enterpriseOperateFileUrl: [] as UploadUserFile[],
-  // enterpriseRelateFileUrl: [] as UploadUserFile[],
-  // bountyAssignFileUlr: [] as UploadUserFile[],
-  // bountyCollectFileUrl: [] as UploadUserFile[],
   parkCollectFileList: [] as CustomerApplyFileTypeListItem[],
   calculationFileList: [] as CustomerApplyFileTypeListItem[],
 
   status: '' as any as BountyCheckStatusEnum,
   remark: '',
 });
+
+const { extraParamState, getList, reset, proTableProps, operationBtns, dialogProps } =
+  useDeclareEnterpriseTable({
+    id: ref(id),
+    applyMonth: toRef(form, 'applyMonth'),
+  });
 
 const { data: detail, isLoading } = useQuery({
   queryKey: ['parkBountyApplyServices/getOutCheckParkBountyApplyDetailBaseInfo', id],
@@ -145,17 +146,6 @@
     form.parkTypeName = data.parkTypeName;
     form.applyMonth = data.applyMonth;
     form.applySumAmount = data.applySumAmount;
-    // form.enterpriseTaxSubFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseTaxSubFileUrl
-    // );
-    // form.enterpriseOperateFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseOperateFileUrl
-    // );
-    // form.bountyAssignFileUlr = convertApi2FormUrlObjectBySeparator(data?.bountyAssignFileUlr);
-    // form.bountyCollectFileUrl = convertApi2FormUrlObjectBySeparator(data?.bountyCollectFileUrl);
-    // form.enterpriseRelateFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseRelateFileUrl
-    // );
     form.parkCollectFileList = EnterpriseApplyFileUtils.convertApiFileToParkCollectFileList(
       data.listFiles
     );
@@ -166,43 +156,6 @@
     getList();
   },
 });
-
-const {
-  getDataSource: getList,
-  proTableProps,
-  paginationState,
-  extraParamState,
-  reset,
-} = useTable(
-  async ({ pageIndex, pageSize }, extraParamState) => {
-    try {
-      let params: API.GetParkBountyApplyInfoInput = {
-        pageModel: {
-          rows: pageSize,
-          page: pageIndex,
-          orderInput: extraParamState.orderInput,
-        },
-        searchKeyWord: extraParamState.searchKeyWord,
-        parkBountyApplyId: id,
-      };
-      let res = await parkBountyApplyServices.getOutCheckParkBountyApplyDetailList(params);
-      return res;
-    } catch (error) {}
-  },
-  {
-    defaultExtraParams: {
-      orderInput: [{ property: 'enterpriseId', order: OrderInputType.Desc }],
-      searchKeyWord: '',
-    },
-    columnsRenderProps: {
-      authType: { type: 'enum', valueEnum: EnterpriseTypeText },
-      licenseUrl: {
-        type: 'urlV2',
-        formatter: (row: API.UserCertificationAuditListDto) => setOSSLink(row.licenseUrl),
-      },
-    },
-  }
-);
 
 function handleBack() {
   closeViewPush(route, {
@@ -242,52 +195,7 @@
   } catch (error) {}
 }
 
-const { dialogProps, handleAdd, editForm } = useFormDialog({
-  defaultFormParams: {
-    list: [] as CustomerApplyFileTypeListItem[],
-    companyId: '',
-  },
-});
 const { getIndustrialParkTypeNameById } = useIndustrialParkDropDownList();
-
-async function openDialog(row: API.ParkBountyApplyDetailInfo) {
-  try {
-    const applyFilesRes = await queryClient.ensureQueryData({
-      queryKey: [
-        'enterpriseApplyFileServices/getCustomerUploadApplyFiles',
-        row.enterpriseId,
-        form.applyMonth,
-      ],
-      queryFn: async () => {
-        return await enterpriseApplyFileServices.getCustomerUploadApplyFiles({
-          enterpriseId: row.enterpriseId,
-          withMonth: form.applyMonth,
-        });
-      },
-    });
-    const lastUploadEnterPactFile = await queryClient.ensureQueryData({
-      queryKey: ['enterpriseApplyFileServices/getCustomerUploadApplyFiles', row.enterpriseId],
-      queryFn: async () => {
-        return await parkBountyApplyServices.getEnterpriseLastUploadEnterPactFileNew({
-          companyId: row.enterpriseId,
-        });
-      },
-    });
-
-    const applyUploadFiles = await parkBountyApplyServices.getEnterpriseParkApplyUploadFiles({
-      companyId: row.enterpriseId,
-      parkBountyApplyId: id,
-    });
-    handleAdd({
-      list: EnterpriseApplyFileUtils.initParkCollectFileListApplyFiles(
-        applyUploadFiles,
-        applyFilesRes.items,
-        lastUploadEnterPactFile
-      ),
-      companyId: row.enterpriseId,
-    });
-  } catch (error) {}
-}
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/views/MaterialReview/MaterialReviewDetail.vue b/src/views/MaterialReview/MaterialReviewDetail.vue
index 3a27e09..8a0f348 100644
--- a/src/views/MaterialReview/MaterialReviewDetail.vue
+++ b/src/views/MaterialReview/MaterialReviewDetail.vue
@@ -24,8 +24,8 @@
               :extra-param-state="extraParamState"
               :pro-table-props="proTableProps"
               :reset="reset"
-              :open-dialog="openDialog"
               :column="addRewardApplyStep3Columns"
+              :operationBtns="operationBtns"
             ></DeclareEnterpriseTableView>
             <MateriaDetailDialog
               v-bind="dialogProps"
@@ -47,34 +47,25 @@
 import {
   AppContainer,
   LoadingLayout,
-  UploadUserFile,
   PageFormLayout,
-  useTable,
-  useFormDialog,
   TextOverTooltip,
 } from '@bole-core/components';
 import ChunkCellV2 from '@/components/Layout/ChunkCellV2.vue';
 import DetailView from '@/components/commonView/DetailView.vue';
 import MateriaDetailDialog from '@/components/commonView/MateriaDetailDialog.vue';
 import DeclareEnterpriseTableView from '@/components/commonView/DeclareEnterpriseTableView.vue';
-import { useQuery, useQueryClient } from '@tanstack/vue-query';
+import { useQuery } from '@tanstack/vue-query';
 import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
-import * as enterpriseApplyFileServices from '@/services/api/EnterpriseApplyFile';
-import { convertApi2FormUrlObjectBySeparator, setOSSLink } from '@/utils';
-import { useRouteView } from '@/hooks';
-import { OrderInputType } from '@bole-core/core';
+import { useDeclareEnterpriseTable, useRouteView } from '@/hooks';
 import {
-  EnterpriseTypeText,
   BountyCheckStatusEnum,
   BountyCheckStatusEnumText,
   BountyCheckStatusEnumColor,
   useAddRewardApplyStep3Columns,
 } from '@/constants';
-import { FourStreamsMaterialFileTableItem } from '@/components/commonView/types';
 import {
   CustomerApplyFileTypeListItem,
   EnterpriseApplyFileUtils,
-  FourStreamsMaterialUtils,
 } from '@/components/commonView/utils';
 import { useIndustrialParkDropDownList } from '@/hooks/industrialPark';
 
@@ -91,11 +82,6 @@
   parkTypeName: '',
   applyMonth: '',
   applySumAmount: 0,
-  // enterpriseTaxSubFileUrl: [] as UploadUserFile[],
-  // enterpriseOperateFileUrl: [] as UploadUserFile[],
-  // enterpriseRelateFileUrl: [] as UploadUserFile[],
-  // bountyAssignFileUlr: [] as UploadUserFile[],
-  // bountyCollectFileUrl: [] as UploadUserFile[],
   parkCollectFileList: [] as CustomerApplyFileTypeListItem[],
   calculationFileList: [] as CustomerApplyFileTypeListItem[],
 
@@ -108,6 +94,12 @@
 const { addRewardApplyStep3Columns } = useAddRewardApplyStep3Columns({
   suportEnterpriseUpload: toRef(form, 'suportEnterpriseUpload'),
 });
+
+const { extraParamState, getList, reset, proTableProps, operationBtns, dialogProps } =
+  useDeclareEnterpriseTable({
+    id: ref(id),
+    applyMonth: toRef(form, 'applyMonth'),
+  });
 
 const tableRef = ref<InstanceType<typeof DeclareEnterpriseTableView>>();
 
@@ -130,17 +122,6 @@
     form.applySumAmount = data.applySumAmount;
     form.outCheckStatus = data.outCheckStatus;
     form.outCheckRemark = data.outCheckRemark;
-    // form.enterpriseTaxSubFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseTaxSubFileUrl
-    // );
-    // form.enterpriseOperateFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseOperateFileUrl
-    // );
-    // form.bountyAssignFileUlr = convertApi2FormUrlObjectBySeparator(data?.bountyAssignFileUlr);
-    // form.bountyCollectFileUrl = convertApi2FormUrlObjectBySeparator(data?.bountyCollectFileUrl);
-    // form.enterpriseRelateFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseRelateFileUrl
-    // );
     form.parkCollectFileList = EnterpriseApplyFileUtils.convertApiFileToParkCollectFileList(
       data.listFiles
     );
@@ -154,94 +135,7 @@
   },
 });
 
-const {
-  getDataSource: getList,
-  proTableProps,
-  paginationState,
-  extraParamState,
-  reset,
-} = useTable(
-  async ({ pageIndex, pageSize }, extraParamState) => {
-    try {
-      let params: API.GetParkBountyApplyInfoInput = {
-        pageModel: {
-          rows: pageSize,
-          page: pageIndex,
-          orderInput: extraParamState.orderInput,
-        },
-        searchKeyWord: extraParamState.searchKeyWord,
-        parkBountyApplyId: id,
-      };
-      let res = await parkBountyApplyServices.getOutCheckParkBountyApplyDetailList(params);
-      return res;
-    } catch (error) {}
-  },
-  {
-    defaultExtraParams: {
-      orderInput: [{ property: 'parkBountyApplyId', order: OrderInputType.Desc }],
-      searchKeyWord: '',
-    },
-    columnsRenderProps: {
-      authType: { type: 'enum', valueEnum: EnterpriseTypeText },
-      applyAmount: { type: 'money' },
-    },
-  }
-);
-
-const { dialogProps, handleAdd, editForm } = useFormDialog({
-  defaultFormParams: {
-    list: [] as CustomerApplyFileTypeListItem[],
-    companyId: '',
-  },
-});
-
 const { getIndustrialParkTypeNameById } = useIndustrialParkDropDownList();
-const queryClient = useQueryClient();
-async function openDialog(row: API.ParkBountyApplyDetailInfo) {
-  try {
-    const applyFilesRes = await queryClient.ensureQueryData({
-      queryKey: [
-        'enterpriseApplyFileServices/getCustomerUploadApplyFiles',
-        row.enterpriseId,
-        form.applyMonth,
-      ],
-      queryFn: async () => {
-        return await enterpriseApplyFileServices.getCustomerUploadApplyFiles({
-          enterpriseId: row.enterpriseId,
-          withMonth: form.applyMonth,
-        });
-      },
-    });
-    const lastUploadEnterPactFile = await queryClient.ensureQueryData({
-      queryKey: ['enterpriseApplyFileServices/getCustomerUploadApplyFiles', row.enterpriseId],
-      queryFn: async () => {
-        return await parkBountyApplyServices.getEnterpriseLastUploadEnterPactFileNew({
-          companyId: row.enterpriseId,
-        });
-      },
-    });
-
-    const applyUploadFiles = await parkBountyApplyServices.getEnterpriseParkApplyUploadFiles({
-      companyId: row.enterpriseId,
-      parkBountyApplyId: id,
-    });
-    handleAdd({
-      list: EnterpriseApplyFileUtils.initParkCollectFileListApplyFiles(
-        applyUploadFiles,
-        applyFilesRes.items,
-        lastUploadEnterPactFile
-      ),
-      companyId: row.enterpriseId,
-    });
-  } catch (error) {}
-  // handleAdd({
-  //   list: FourStreamsMaterialUtils.initFourStreamsMaterialFileList(
-  //     row,
-  //     getIndustrialParkTypeNameById(detail.value?.parkId)
-  //   ),
-  //   companyId: row.enterpriseId,
-  // });
-}
 
 function handleBack() {
   closeViewPush(route, {
diff --git a/src/views/Reward/FinancialApproval.vue b/src/views/Reward/FinancialApproval.vue
new file mode 100644
index 0000000..59c2461
--- /dev/null
+++ b/src/views/Reward/FinancialApproval.vue
@@ -0,0 +1,257 @@
+<template>
+  <LoadingLayout :loading="state.loading">
+    <AppContainer>
+      <ProTableQueryFilterBar @on-reset="reset">
+        <template #query>
+          <QueryFilterItem>
+            <FieldSelect
+              v-model="extraParamState.enterpriseId"
+              placeholder="璇烽�夋嫨鍥尯"
+              :value-enum="fourStreamsIndustrialParkList"
+              enumLabelKey="parkName"
+              enum-value-key="id"
+              clearable
+              @change="getList()"
+            />
+          </QueryFilterItem>
+          <QueryFilterItem tip-content="瀹℃牳鐘舵��">
+            <FieldRadio
+              v-model="extraParamState.auditStatus"
+              :value-enum="EnumParkBountyTradeDetailAuditStatusText"
+              buttonStyle
+              showAllBtn
+              @change="getList()"
+            ></FieldRadio>
+          </QueryFilterItem>
+          <QueryFilterItem tip-content="鐢宠鍑鸿处鏃ユ湡">
+            <FieldDatePicker
+              v-model="extraParamState.creationTime"
+              type="daterange"
+              range-separator="~"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              clearable
+              @change="getList()"
+            ></FieldDatePicker>
+          </QueryFilterItem>
+          <QueryFilterItem>
+            <SearchInput
+              v-model="extraParamState.searchKeyWord"
+              style="width: 200px"
+              placeholder="浼佷笟鍚嶇О/淇$敤浠g爜"
+              @on-click-search="getList"
+            >
+            </SearchInput>
+          </QueryFilterItem>
+        </template>
+      </ProTableQueryFilterBar>
+      <ProTableV2
+        v-bind="proTableProps"
+        :columns="RewardApplyTradeCheckColumns"
+        :operationBtns="operationBtns"
+      >
+      </ProTableV2>
+      <RewardApplyTradeCheckDialog v-bind="dialogProps"></RewardApplyTradeCheckDialog>
+    </AppContainer>
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import {
+  ProTableQueryFilterBar,
+  FieldSelect,
+  ProTableV2,
+  SearchInput,
+  LoadingLayout,
+  AppContainer,
+  QueryFilterItem,
+  useTable,
+  FieldDatePicker,
+  useFormDialog,
+  UploadUserFile,
+  defineOperationBtns,
+  FieldRadio,
+} from '@bole-core/components';
+import { Message, OrderInputType } from '@bole-core/core';
+import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
+import {
+  EnterpriseType,
+  EnterpriseTypeText,
+  EnumParkBountyTradeDetailAuditStatus,
+  EnumParkBountyTradeDetailAuditStatusTag,
+  EnumParkBountyTradeDetailAuditStatusText,
+} from '@/constants';
+import { ModelValueType } from 'element-plus';
+import RewardApplyTradeCheckDialog from './components/RewardApplyTradeCheckDialog.vue';
+import { convertApi2FormUrlOnlyOne, format } from '@/utils';
+import { RewardApplyTradeCheckColumns } from './constants';
+import { useIndustrialParkDropDownList } from '@/hooks/industrialPark';
+
+defineOptions({
+  name: 'FinancialApproval',
+});
+
+const operationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'detailBtn',
+      name: '璇︽儏',
+    },
+    emits: {
+      onClick: (role) => openDialog(role, true),
+    },
+    extraProps: {
+      hide: (row: API.GetParkBountyTradeDetailOutput) =>
+        row.auditStatus === EnumParkBountyTradeDetailAuditStatus.Wait,
+    },
+  },
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '瀹℃壒',
+    },
+    emits: {
+      onClick: (row) => openDialog(row),
+    },
+    extraProps: {
+      hide: (row: API.GetParkBountyTradeDetailOutput) =>
+        row.auditStatus !== EnumParkBountyTradeDetailAuditStatus.Wait,
+    },
+  },
+]);
+
+const BaseState = {
+  loading: true,
+};
+
+const state = reactive({ ...BaseState });
+const { industrialParkList } = useIndustrialParkDropDownList();
+
+const fourStreamsIndustrialParkList = computed(() => {
+  return industrialParkList.value.filter((x) => !!x.rewardEnable);
+});
+
+onMounted(async () => {
+  await getList();
+  state.loading = false;
+});
+
+const {
+  getDataSource: getList,
+  proTableProps,
+  paginationState,
+  extraParamState,
+  reset,
+} = useTable(
+  async ({ pageIndex, pageSize }, extraParamState) => {
+    try {
+      let params: API.GetParkBountyTradeDetailByIdInput = {
+        pageModel: {
+          rows: pageSize,
+          page: pageIndex,
+          orderInput: extraParamState.orderInput,
+        },
+        searchKeyWord: extraParamState.searchKeyWord,
+        // transferTimeBegin: format(extraParamState.transferTime?.[0] ?? '', 'YYYY-MM-DD 00:00:00'),
+        // transferTimeEnd: format(extraParamState.transferTime?.[1] ?? '', 'YYYY-MM-DD 23:59:59'),
+        creationTimeBegin: format(extraParamState.creationTime?.[0] ?? '', 'YYYY-MM-DD 00:00:00'),
+        creationTimeEnd: format(extraParamState.creationTime?.[1] ?? '', 'YYYY-MM-DD 23:59:59'),
+        // "enterpriseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
+        // "auditStatus": 10
+      };
+      let res = await parkBountyApplyServices.getParkBountyTradeDetailList(params, {
+        showLoading: !state.loading,
+      });
+      return res;
+    } catch (error) {}
+  },
+  {
+    defaultExtraParams: {
+      searchKeyWord: '',
+      enterpriseId: '',
+      auditStatus: '' as any as EnumParkBountyTradeDetailAuditStatus,
+      creationTime: [] as unknown as ModelValueType,
+      orderInput: [{ property: 'tradeTime', order: OrderInputType.Desc }],
+    },
+    columnsRenderProps: {
+      authType: { type: 'enum', valueEnum: EnterpriseTypeText },
+      tradeTime: { type: 'date', format: 'YYYY-MM-DD HH:mm:ss' },
+      tradeAmount: { type: 'money' },
+      remianAmount: { type: 'money' },
+      auditStatus: {
+        type: 'tag',
+        valueEnum: EnumParkBountyTradeDetailAuditStatusText,
+        tagTypeEnum: EnumParkBountyTradeDetailAuditStatusTag,
+      },
+    },
+  }
+);
+
+function openDialog(row: API.GetParkBountyTradeDetailOutput, isCheck = false) {
+  handleAdd({
+    id: row.id,
+    isCheck,
+    auditStatus:
+      row.auditStatus === EnumParkBountyTradeDetailAuditStatus.Reject
+        ? EnumParkBountyTradeDetailAuditStatus.Reject
+        : EnumParkBountyTradeDetailAuditStatus.Pass,
+    auditRemark: row.auditRemark,
+    payAuditFileUrl: convertApi2FormUrlOnlyOne(row.payAuditFileUrl),
+    userName: row.userName,
+    enterpriseName: row.enterpriseName,
+    societyCreditCode: row.societyCreditCode,
+    contactPhone: row.contactPhone,
+    authType: row.authType,
+    parkName: row.parkName,
+    parkTypeName: row.parkTypeName,
+    tradeAmount: row.tradeAmount,
+    remianAmount: row.remianAmount,
+    tradeTime: row.tradeTime,
+    auditTime: row.auditTime,
+    payRemark: row.payRemark,
+    payFileUrl: convertApi2FormUrlOnlyOne(row.payFileUrl),
+  });
+}
+
+const { dialogProps, handleAdd, handleEdit, editForm } = useFormDialog({
+  onConfirm: handleAddOrEdit,
+  defaultFormParams: {
+    id: '',
+    auditStatus: '' as any as EnumParkBountyTradeDetailAuditStatus,
+    auditRemark: '',
+    payAuditFileUrl: [] as UploadUserFile[],
+    isCheck: false,
+    userName: '',
+    enterpriseName: '',
+    societyCreditCode: '',
+    contactPhone: '',
+    authType: EnterpriseType.HREnterprise,
+    parkName: '',
+    parkTypeName: '',
+    tradeAmount: '' as any as number,
+    remianAmount: '' as any as number,
+    tradeTime: '',
+    auditTime: '',
+    payRemark: '',
+    payFileUrl: [] as UploadUserFile[],
+  },
+});
+
+async function handleAddOrEdit() {
+  try {
+    let params: API.AuditParkBountyTradeInput = {
+      id: editForm.id,
+      auditStatus: editForm.auditStatus,
+      /** 瀹℃牳澶囨敞 */
+      auditRemark: editForm.auditRemark,
+      /** 瀹℃牳鍑瘉 */
+      payAuditFileUrl: editForm.payAuditFileUrl?.[0]?.path ?? '',
+    };
+    let res = await parkBountyApplyServices.auditParkBountyApplyTrade(params);
+    if (res) {
+      Message.successMessage('鎿嶄綔鎴愬姛');
+      getList(paginationState.pageIndex);
+    }
+  } catch (error) {}
+}
+</script>
diff --git a/src/views/Reward/RewardApplyTradeCheck.vue b/src/views/Reward/RewardApplyTradeCheck.vue
index 32b478b..9c7a057 100644
--- a/src/views/Reward/RewardApplyTradeCheck.vue
+++ b/src/views/Reward/RewardApplyTradeCheck.vue
@@ -3,6 +3,26 @@
     <AppContainer>
       <ProTableQueryFilterBar @on-reset="reset">
         <template #query>
+          <QueryFilterItem>
+            <FieldSelect
+              v-model="extraParamState.enterpriseId"
+              placeholder="璇烽�夋嫨鍥尯"
+              :value-enum="fourStreamsIndustrialParkList"
+              enumLabelKey="parkName"
+              enum-value-key="id"
+              clearable
+              @change="getList()"
+            />
+          </QueryFilterItem>
+          <QueryFilterItem tip-content="瀹℃牳鐘舵��">
+            <FieldRadio
+              v-model="extraParamState.auditStatus"
+              :value-enum="EnumParkBountyTradeDetailAuditStatusText"
+              buttonStyle
+              showAllBtn
+              @change="getList()"
+            ></FieldRadio>
+          </QueryFilterItem>
           <QueryFilterItem tip-content="鐢宠鍑鸿处鏃ユ湡">
             <FieldDatePicker
               v-model="extraParamState.creationTime"
@@ -39,7 +59,7 @@
 <script setup lang="ts">
 import {
   ProTableQueryFilterBar,
-  OperationBtnType,
+  FieldSelect,
   ProTableV2,
   SearchInput,
   LoadingLayout,
@@ -50,6 +70,7 @@
   useFormDialog,
   UploadUserFile,
   defineOperationBtns,
+  FieldRadio,
 } from '@bole-core/components';
 import { Message, OrderInputType } from '@bole-core/core';
 import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
@@ -64,6 +85,7 @@
 import RewardApplyTradeCheckDialog from './components/RewardApplyTradeCheckDialog.vue';
 import { convertApi2FormUrlOnlyOne, format } from '@/utils';
 import { RewardApplyTradeCheckColumns } from './constants';
+import { useIndustrialParkDropDownList } from '@/hooks/industrialPark';
 
 defineOptions({
   name: 'RewardApplyTradeCheck',
@@ -103,6 +125,11 @@
 };
 
 const state = reactive({ ...BaseState });
+const { industrialParkList } = useIndustrialParkDropDownList();
+
+const fourStreamsIndustrialParkList = computed(() => {
+  return industrialParkList.value.filter((x) => !!x.rewardEnable);
+});
 
 onMounted(async () => {
   await getList();
@@ -141,6 +168,8 @@
   {
     defaultExtraParams: {
       searchKeyWord: '',
+      enterpriseId: '',
+      auditStatus: '' as any as EnumParkBountyTradeDetailAuditStatus,
       creationTime: [] as unknown as ModelValueType,
       orderInput: [{ property: 'tradeTime', order: OrderInputType.Desc }],
     },
diff --git a/src/views/Reward/RewardDeclareDetail.vue b/src/views/Reward/RewardDeclareDetail.vue
index 1bf9d08..6c481f1 100644
--- a/src/views/Reward/RewardDeclareDetail.vue
+++ b/src/views/Reward/RewardDeclareDetail.vue
@@ -9,8 +9,8 @@
               :extra-param-state="extraParamState"
               :pro-table-props="proTableProps"
               :reset="reset"
-              :open-dialog="openDialog"
               :column="addRewardApplyStep3Columns"
+              :operationBtns="operationBtns"
             ></DeclareEnterpriseTableView>
             <MateriaDetailDialog
               v-bind="dialogProps"
@@ -29,31 +29,19 @@
 </template>
 
 <script setup lang="ts">
-import {
-  AppContainer,
-  LoadingLayout,
-  UploadUserFile,
-  PageFormLayout,
-  useTable,
-  useFormDialog,
-} from '@bole-core/components';
+import { AppContainer, LoadingLayout, PageFormLayout } from '@bole-core/components';
 import DetailView from '@/components/commonView/DetailView.vue';
 import ChunkCellV2 from '@/components/Layout/ChunkCellV2.vue';
 import MateriaDetailDialog from '@/components/commonView/MateriaDetailDialog.vue';
 import DeclareEnterpriseTableView from '@/components/commonView/DeclareEnterpriseTableView.vue';
-import { useQuery, useQueryClient } from '@tanstack/vue-query';
+import { useQuery } from '@tanstack/vue-query';
 import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
-import * as enterpriseApplyFileServices from '@/services/api/EnterpriseApplyFile';
-import { convertApi2FormUrlObjectBySeparator, setOSSLink } from '@/utils';
-import { useRouteView } from '@/hooks';
-import { OrderInputType } from '@bole-core/core';
-import { EnterpriseTypeText, useAddRewardApplyStep3Columns } from '@/constants';
-import { FourStreamsMaterialFileTableItem } from '@/components/commonView/types';
+import { useDeclareEnterpriseTable, useRouteView } from '@/hooks';
+import { useAddRewardApplyStep3Columns } from '@/constants';
 import { useIndustrialParkDropDownList } from '@/hooks/industrialPark';
 import {
   CustomerApplyFileTypeListItem,
   EnterpriseApplyFileUtils,
-  FourStreamsMaterialUtils,
 } from '@/components/commonView/utils';
 
 defineOptions({
@@ -69,19 +57,20 @@
   parkTypeName: '',
   applyMonth: '',
   applySumAmount: 0,
-  // enterpriseTaxSubFileUrl: [] as UploadUserFile[],
-  // enterpriseOperateFileUrl: [] as UploadUserFile[],
-  // enterpriseRelateFileUrl: [] as UploadUserFile[],
   parkCollectFileList: [] as CustomerApplyFileTypeListItem[],
   calculationFileList: [] as CustomerApplyFileTypeListItem[],
-  // bountyAssignFileUlr: [] as UploadUserFile[],
-  // bountyCollectFileUrl: [] as UploadUserFile[],
   suportEnterpriseUpload: false,
 });
 
 const { addRewardApplyStep3Columns } = useAddRewardApplyStep3Columns({
   suportEnterpriseUpload: toRef(form, 'suportEnterpriseUpload'),
 });
+
+const { extraParamState, getList, reset, proTableProps, operationBtns, dialogProps } =
+  useDeclareEnterpriseTable({
+    id: ref(id),
+    applyMonth: toRef(form, 'applyMonth'),
+  });
 
 const { data: detail, isLoading } = useQuery({
   queryKey: ['parkBountyApplyServices/getParkBountyApplyDetailBaseInfo', id],
@@ -100,121 +89,19 @@
     form.parkTypeName = data.parkTypeName;
     form.applyMonth = data.applyMonth;
     form.applySumAmount = data.applySumAmount;
-    // form.enterpriseTaxSubFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseTaxSubFileUrl
-    // );
-    // form.enterpriseOperateFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseOperateFileUrl
-    // );
     form.parkCollectFileList = EnterpriseApplyFileUtils.convertApiFileToParkCollectFileList(
       data.listFiles
     );
     form.calculationFileList = EnterpriseApplyFileUtils.convertApiFileToParkCollectFileList(
       data.collectCountListFiles
     );
-    // form.bountyAssignFileUlr = convertApi2FormUrlObjectBySeparator(data?.bountyAssignFileUlr);
-    // form.bountyCollectFileUrl = convertApi2FormUrlObjectBySeparator(data?.bountyCollectFileUrl);
-    // form.enterpriseRelateFileUrl = convertApi2FormUrlObjectBySeparator(
-    //   data?.enterpriseRelateFileUrl
-    // );
     form.suportEnterpriseUpload = data.suportEnterpriseUpload;
 
     getList();
   },
 });
 
-const {
-  getDataSource: getList,
-  proTableProps,
-  paginationState,
-  extraParamState,
-  reset,
-} = useTable(
-  async ({ pageIndex, pageSize }, extraParamState) => {
-    try {
-      let params: API.GetParkBountyApplyInfoInput = {
-        pageModel: {
-          rows: pageSize,
-          page: pageIndex,
-          orderInput: extraParamState.orderInput,
-        },
-        searchKeyWord: extraParamState.searchKeyWord,
-        parkBountyApplyId: id,
-      };
-      let res = await parkBountyApplyServices.getOutCheckParkBountyApplyDetailList(params);
-      return res;
-    } catch (error) {}
-  },
-  {
-    defaultExtraParams: {
-      orderInput: [{ property: 'parkBountyApplyId', order: OrderInputType.Desc }],
-      searchKeyWord: '',
-    },
-    columnsRenderProps: {
-      authType: { type: 'enum', valueEnum: EnterpriseTypeText },
-      licenseUrl: {
-        type: 'urlV2',
-        formatter: (row: API.UserCertificationAuditListDto) => setOSSLink(row.licenseUrl),
-      },
-      applyAmount: { type: 'money' },
-    },
-  }
-);
-
-const { dialogProps, handleAdd, editForm } = useFormDialog({
-  defaultFormParams: {
-    list: [] as CustomerApplyFileTypeListItem[],
-    companyId: '',
-  },
-});
-
 const { getIndustrialParkTypeNameById } = useIndustrialParkDropDownList();
-const queryClient = useQueryClient();
-async function openDialog(row: API.ParkBountyApplyDetailInfo) {
-  try {
-    const applyFilesRes = await queryClient.ensureQueryData({
-      queryKey: [
-        'enterpriseApplyFileServices/getCustomerUploadApplyFiles',
-        row.enterpriseId,
-        form.applyMonth,
-      ],
-      queryFn: async () => {
-        return await enterpriseApplyFileServices.getCustomerUploadApplyFiles({
-          enterpriseId: row.enterpriseId,
-          withMonth: form.applyMonth,
-        });
-      },
-    });
-    const lastUploadEnterPactFile = await queryClient.ensureQueryData({
-      queryKey: ['enterpriseApplyFileServices/getCustomerUploadApplyFiles', row.enterpriseId],
-      queryFn: async () => {
-        return await parkBountyApplyServices.getEnterpriseLastUploadEnterPactFileNew({
-          companyId: row.enterpriseId,
-        });
-      },
-    });
-
-    const applyUploadFiles = await parkBountyApplyServices.getEnterpriseParkApplyUploadFiles({
-      companyId: row.enterpriseId,
-      parkBountyApplyId: id,
-    });
-    handleAdd({
-      list: EnterpriseApplyFileUtils.initParkCollectFileListApplyFiles(
-        applyUploadFiles,
-        applyFilesRes.items,
-        lastUploadEnterPactFile
-      ),
-      companyId: row.enterpriseId,
-    });
-  } catch (error) {}
-  // handleEdit({
-  //   list: FourStreamsMaterialUtils.initFourStreamsMaterialFileList(
-  //     row,
-  //     getIndustrialParkTypeNameById(detail.value?.parkId)
-  //   ),
-  //   companyId: row.enterpriseId,
-  // });
-}
 
 function handleBack() {
   closeViewPush(route, {
diff --git a/src/views/Reward/RewardGrant.vue b/src/views/Reward/RewardGrant.vue
index e6b15e0..27e2812 100644
--- a/src/views/Reward/RewardGrant.vue
+++ b/src/views/Reward/RewardGrant.vue
@@ -233,7 +233,7 @@
       name: '鐧昏',
     },
     emits: {
-      onClick: (role) => openRegisterDialog(role),
+      onClick: (role) => goRewardGrantRegister(role),
     },
     extraProps: {
       hide: (row: API.GetParkBountyApplyListOutput) =>
@@ -544,6 +544,15 @@
     }
   } catch (error) {}
 }
+
+function goRewardGrantRegister(row: API.GetParkBountyApplyListOutput) {
+  router.push({
+    name: 'RewardGrantRegister',
+    params: {
+      id: row.id,
+    },
+  });
+}
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/views/Reward/RewardGrantRegister.vue b/src/views/Reward/RewardGrantRegister.vue
new file mode 100644
index 0000000..c096eb3
--- /dev/null
+++ b/src/views/Reward/RewardGrantRegister.vue
@@ -0,0 +1,282 @@
+<template>
+  <LoadingLayout>
+    <AppContainer>
+      <PageFormLayout title="濂栧姳閲戠櫥璁�">
+        <DetailView :form="form">
+          <ChunkCellV2 title="鐢虫姤浼佷笟鍚嶅崟">
+            <DeclareEnterpriseTableView
+              :getList="getList"
+              :extra-param-state="extraParamState"
+              :pro-table-props="proTableProps"
+              :reset="reset"
+              :operationBtns="registerOperationBtns"
+              :column="rewardGrantRegisterColumns"
+            >
+              <template #btn>
+                <el-button type="primary" link @click="downloadTemp()">涓嬭浇妯℃澘</el-button>
+                <el-button icon="Upload" type="primary" @click="openUploadFileDialog()"
+                  >瀵煎叆</el-button
+                >
+                <el-button icon="Plus" type="primary" @click="openBatchRegisterDialog()"
+                  >鎵归噺鐧昏</el-button
+                >
+              </template>
+            </DeclareEnterpriseTableView>
+            <FourStreamsMaterialFileDialogV2
+              v-bind="dialogMaterialFileProps"
+              :show-upload-btn="false"
+              :show-delete-btn="false"
+              :show-check-btn="false"
+              downloadBtnText="鏌ョ湅"
+              title="鏌ョ湅鍑瘉"
+              :BusinessTypeEnumText="TransferFileEnumInRewardGrandText"
+            />
+          </ChunkCellV2>
+        </DetailView>
+        <template #footer>
+          <el-button @click="handleBack">鍙栨秷</el-button>
+          <el-button @click="handleBack" type="primary">纭</el-button>
+        </template>
+      </PageFormLayout>
+    </AppContainer>
+    <RegisterGrantDialog v-bind="dialogRegisterGrantProps" />
+    <UploadFileDialog v-bind="dialogUploadFileProps" />
+    <BatchRegisterDialog v-bind="dialogBatchRegisterProps" />
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import {
+  AppContainer,
+  defineOperationBtns,
+  LoadingLayout,
+  PageFormLayout,
+  UploadUserFile,
+  useFormDialog,
+  XLSXUtils,
+} from '@bole-core/components';
+import DetailView from '@/components/commonView/DetailView.vue';
+import ChunkCellV2 from '@/components/Layout/ChunkCellV2.vue';
+import DeclareEnterpriseTableView from '@/components/commonView/DeclareEnterpriseTableView.vue';
+import { useQuery } from '@tanstack/vue-query';
+import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
+import { useRouteView } from '@/hooks';
+import { useIndustrialParkDropDownList } from '@/hooks/industrialPark';
+import {
+  CustomerApplyFileTypeListItem,
+  EnterpriseApplyFileUtils,
+  FourStreamsMaterialUtils,
+} from '@/components/commonView/utils';
+import {
+  BountyBatchApplyTransferTemp,
+  FinanceStatusEnum,
+  IncomeTypeEnum,
+  SettleStatusEnum,
+  TransferFileEnumInRewardGrandText,
+} from '@/constants';
+import { useDeclareEnterpriseTable, rewardGrantRegisterColumns } from '@/hooks';
+import { TransferFileEnumInRewardGrandTableItem } from '@/components/commonView/types';
+import RegisterGrantDialog from './components/RegisterGrantDialog.vue';
+import BatchRegisterDialog from './components/BatchRegisterDialog.vue';
+import UploadFileDialog from './components/UploadFileDialog.vue';
+import { downloadFileByUrl } from '@/utils';
+import { Message } from '@bole-core/core';
+import { ImportParkBountyDataHeaderMap } from './constants';
+
+defineOptions({
+  name: 'RewardGrantRegister',
+});
+
+const route = useRoute();
+const { closeViewPush } = useRouteView();
+const id = route.params?.id as string;
+const form = reactive({
+  batchNo: '',
+  parkName: '',
+  parkTypeName: '',
+  applyMonth: '',
+  applySumAmount: 0,
+  parkCollectFileList: [] as CustomerApplyFileTypeListItem[],
+  calculationFileList: [] as CustomerApplyFileTypeListItem[],
+  suportEnterpriseUpload: false,
+});
+
+const { extraParamState, paginationState, getList, reset, proTableProps } =
+  useDeclareEnterpriseTable({
+    id: ref(id),
+    applyMonth: toRef(form, 'applyMonth'),
+  });
+
+const registerOperationBtns = defineOperationBtns([
+  {
+    data: {
+      enCode: 'registerGrantBtn',
+      name: '鐧昏',
+    },
+    emits: {
+      onClick: (row) => openRegisterGrantDialog(row),
+    },
+  },
+  {
+    data: {
+      enCode: 'checkBtn',
+      name: '鏌ョ湅鍑瘉',
+    },
+    emits: {
+      onClick: (row) => openMaterialFileDialog(row),
+    },
+  },
+]);
+
+const { data: detail, isLoading } = useQuery({
+  queryKey: ['parkBountyApplyServices/getParkBountyApplyDetailBaseInfo', id],
+  queryFn: async () => {
+    return await parkBountyApplyServices.getParkBountyApplyDetailBaseInfo(
+      { parkBountyApplyId: id },
+      {
+        showLoading: false,
+      }
+    );
+  },
+  placeholderData: () => ({} as API.ParkBountyApplyBaseInfo),
+  onSuccess(data) {
+    form.batchNo = data.batchNo;
+    form.parkName = data.parkName;
+    form.parkTypeName = data.parkTypeName;
+    form.applyMonth = data.applyMonth;
+    form.applySumAmount = data.applySumAmount;
+    form.parkCollectFileList = EnterpriseApplyFileUtils.convertApiFileToParkCollectFileList(
+      data.listFiles
+    );
+    form.calculationFileList = EnterpriseApplyFileUtils.convertApiFileToParkCollectFileList(
+      data.collectCountListFiles
+    );
+    form.suportEnterpriseUpload = data.suportEnterpriseUpload;
+
+    getList();
+  },
+});
+
+const { getIndustrialParkTypeNameById } = useIndustrialParkDropDownList();
+
+const { dialogProps: dialogMaterialFileProps, handleAdd: handleMaterialFileAdd } = useFormDialog({
+  defaultFormParams: {
+    list: [] as TransferFileEnumInRewardGrandTableItem[],
+  },
+});
+function openMaterialFileDialog(row: API.GetParkBountyApplyListOutput) {
+  handleMaterialFileAdd({
+    list: FourStreamsMaterialUtils.initApplyRewardGrandFileList(row),
+  });
+}
+
+const {
+  dialogProps: dialogRegisterGrantProps,
+  handleEdit: handleRegisterGrantEdit,
+  editForm: editRegisterForm,
+} = useFormDialog({
+  onConfirm: handleRegisterGrant,
+  defaultFormParams: {
+    incomeType: '' as any as IncomeTypeEnum,
+    parkBountyApplyId: '',
+    fileUrl: [] as UploadUserFile[],
+    financeSumAmount: 0,
+    showSuportPlatRecharge: false,
+    showSuportFiscalRecharge: false,
+  },
+});
+
+function openRegisterGrantDialog(row?: API.GetParkBountyApplyListOutput) {
+  handleRegisterGrantEdit({
+    incomeType: '' as any as IncomeTypeEnum,
+    fileUrl: [] as UploadUserFile[],
+    showSuportPlatRecharge: row.settleStatus === SettleStatusEnum.WaitForSettle,
+    showSuportFiscalRecharge: row.financeStatus === FinanceStatusEnum.WaitForIncome,
+    parkBountyApplyId: row.id,
+    financeSumAmount: 0,
+  });
+}
+
+async function handleRegisterGrant() {}
+
+const { dialogProps: dialogUploadFileProps, handleAdd: handleUploadFileAdd } = useFormDialog({
+  onConfirm: handleImportParkBountyData,
+  defaultFormParams: {
+    parkBountyApplyId: '',
+    url: [] as UploadUserFile[],
+    certificateUrl: [] as UploadUserFile[],
+  },
+});
+
+async function handleImportParkBountyData(response: UploadUserFile) {
+  try {
+    let params: API.ImportBountyApplyDataInput = {
+      parkBountyApplyId: id,
+      url: response.url,
+    };
+    let res = await parkBountyApplyServices.importParkBountyData(params, {
+      timeout: 100000000,
+    });
+    if (res.error.length > 0) {
+      await Message.tipMessage('瀛樺湪閿欒鏁版嵁,鏄惁瀵煎嚭');
+      XLSXUtils.exportToXLSX({
+        workbookDataList: res.error,
+        fileName: '鎵归噺瀵煎叆鍏ヨ处-閿欒鏁版嵁',
+        workbookHeaderMap: ImportParkBountyDataHeaderMap,
+      });
+    }
+    getList(paginationState.pageIndex);
+  } catch (error) {}
+}
+
+function openUploadFileDialog() {
+  handleUploadFileAdd({
+    parkBountyApplyId: id,
+    url: [] as UploadUserFile[],
+    certificateUrl: [] as UploadUserFile[],
+  });
+}
+
+async function openBatchRegisterDialog() {
+  try {
+    handleBatchRegisterAdd({
+      parkBountyApplyId: id,
+      showSuportPlatRecharge: false,
+    });
+  } catch (error) {}
+}
+
+const {
+  dialogProps: dialogBatchRegisterProps,
+  handleAdd: handleBatchRegisterAdd,
+  editForm: batchRegisterEditForm,
+} = useFormDialog({
+  onConfirm: handleBatchRegister,
+  defaultFormParams: {
+    parkBountyApplyDetailIds: [] as string[],
+    amount: 0,
+    companyList: [] as API.GetNotTransferCompanyNameListOutput[],
+    incomeType: IncomeTypeEnum.Fiscal,
+    parkBountyApplyId: '',
+    showSuportPlatRecharge: false,
+
+    certificateUrl: [] as UploadUserFile[],
+  },
+});
+
+async function handleBatchRegister() {}
+
+function downloadTemp() {
+  downloadFileByUrl(BountyBatchApplyTransferTemp, '鐧昏妯℃澘');
+}
+
+function handleBack() {
+  closeViewPush(route, {
+    name: 'RewardGrant',
+  });
+}
+</script>
+
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+</style>
diff --git a/src/views/Reward/components/BatchRegisterDialog.vue b/src/views/Reward/components/BatchRegisterDialog.vue
new file mode 100644
index 0000000..a3f1014
--- /dev/null
+++ b/src/views/Reward/components/BatchRegisterDialog.vue
@@ -0,0 +1,214 @@
+<template>
+  <ProDialog
+    title="鎵归噺鐧昏"
+    v-model="visible"
+    @close="onDialogClose"
+    destroy-on-close
+    draggable
+    width="700px"
+  >
+    <ProForm :model="form" ref="dialogForm" label-width="120px">
+      <ProFormItemV2 prop="ids" class="pro-form-item-label-hidden">
+        <div class="batchEntryRewardBody">
+          <el-transfer
+            v-model="deleteList"
+            filterable
+            :filter-method="filterMethod"
+            filter-placeholder="璇疯緭鍏ユ悳绱㈠唴瀹�"
+            :data="form.companyList"
+            :titles="['鐧昏', '涓嶇櫥璁�']"
+            :props="prop"
+            @change="handleChange"
+          />
+        </div>
+      </ProFormItemV2>
+      <ProFormItemV2 label="鐧昏绫诲瀷:" prop="incomeType" required>
+        <ProFormRadio
+          v-model="form.incomeType"
+          :value-enum="incomeTypeEnum"
+          :button-style="false"
+          @change="handleIncomeTypeChange"
+        />
+      </ProFormItemV2>
+      <ProFormItemV2
+        label="鐧昏閲戦:"
+        prop="amount"
+        :check-rules="[{ message: '璇疯緭鍏ョ櫥璁伴噾棰�', type: 'number' }]"
+      >
+        <ProFormInputNumber
+          v-model="form.amount"
+          :controls="false"
+          :min="0"
+          unit="鍏�"
+          :precision="2"
+        ></ProFormInputNumber>
+      </ProFormItemV2>
+      <ProFormItemV2
+        label="涓婁紶鐧昏鍑瘉:"
+        prop="certificateUrl"
+        :check-rules="[{ message: '璇蜂笂浼犵櫥璁板嚟璇�', type: 'upload' }]"
+      >
+        <ProFormUpload
+          v-model:file-url="form.certificateUrl"
+          :limitFileSize="50"
+          accept="doc,docx,pdf,xls,xlsx,jpg/jpeg,png"
+        ></ProFormUpload>
+      </ProFormItemV2>
+    </ProForm>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')">鍙� 娑�</el-button>
+        <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { FormInstance, TransferPropsAlias } from 'element-plus';
+import {
+  ProDialog,
+  ProForm,
+  ProFormItemV2,
+  ProFormInputNumber,
+  ProFormRadio,
+  ProFormUpload,
+  UploadUserFile,
+} from '@bole-core/components';
+import { Message } from '@bole-core/core';
+import { IncomeTypeEnumText, IncomeTypeEnum } from '@/constants';
+import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
+
+defineOptions({
+  name: 'BatchRegisterDialog',
+});
+
+type Props = {
+  /**
+   * @deprecated
+   */
+  financeSumAmount?: number;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+
+const visible = defineModel({ type: Boolean });
+
+type Form = {
+  title?: string;
+  parkBountyApplyDetailIds: string[];
+  amount: number;
+  companyList: API.GetNotTransferCompanyNameListOutput[];
+  incomeType: IncomeTypeEnum;
+  parkBountyApplyId: string;
+  showSuportPlatRecharge: boolean;
+
+  certificateUrl: UploadUserFile[];
+};
+
+const form = defineModel<Form>('form');
+
+const incomeTypeEnum = computed(() => {
+  return [
+    {
+      label: IncomeTypeEnumText[IncomeTypeEnum.Fiscal],
+      value: IncomeTypeEnum.Fiscal,
+    },
+    form.value.showSuportPlatRecharge && {
+      label: IncomeTypeEnumText[IncomeTypeEnum.Platform],
+      value: IncomeTypeEnum.Platform,
+    },
+  ].filter(Boolean);
+});
+
+const deleteList = ref<string[]>([]);
+
+watch(visible, (value, oldValue) => {
+  if (value && !oldValue) {
+    getParkBountyApplyBatchFinanceEnterprise();
+  }
+});
+
+async function getParkBountyApplyBatchTransferEnterprise() {
+  try {
+    let res = await parkBountyApplyServices.getParkBountyApplyBatchTransferEnterprise({
+      parkBountyApplyId: form.value.parkBountyApplyId,
+    });
+    if (res) {
+      form.value.companyList = res;
+      form.value.parkBountyApplyDetailIds = res.map((x) => x.parkBountyApplyDetailId);
+      deleteList.value = [];
+    }
+  } catch (error) {}
+}
+
+async function getParkBountyApplyBatchFinanceEnterprise() {
+  try {
+    let res = await parkBountyApplyServices.getParkBountyApplyBatchFinanceEnterprise({
+      parkBountyApplyId: form.value.parkBountyApplyId,
+    });
+    if (res) {
+      form.value.companyList = res;
+      form.value.parkBountyApplyDetailIds = res.map((x) => x.parkBountyApplyDetailId);
+      deleteList.value = [];
+    }
+  } catch (error) {}
+}
+function handleIncomeTypeChange() {
+  if (form.value.incomeType === IncomeTypeEnum.Fiscal) {
+    getParkBountyApplyBatchFinanceEnterprise();
+  } else {
+    getParkBountyApplyBatchTransferEnterprise();
+  }
+}
+
+function handleChange(ids: string[]) {
+  form.value.parkBountyApplyDetailIds = form.value.companyList
+    .filter((item) => !ids.includes(item.companyId))
+    .map((item) => item.parkBountyApplyDetailId);
+}
+
+const emit = defineEmits<{
+  (e: 'onConfirm'): void;
+  (e: 'onCancel'): void;
+}>();
+
+const dialogForm = ref<FormInstance>();
+
+function onDialogClose() {
+  if (!dialogForm.value) return;
+  dialogForm.value.resetFields();
+}
+
+function handleConfirm() {
+  if (!form.value.parkBountyApplyDetailIds.length) {
+    Message.warnMessage('璇烽�夋嫨鍏ヨ处浼佷笟');
+    return;
+  }
+  if (!dialogForm.value) return;
+  dialogForm.value.validate((valid) => {
+    if (valid) {
+      emit('onConfirm');
+    } else {
+      return;
+    }
+  });
+}
+
+const prop = {
+  label: 'name',
+  key: 'companyId',
+} as TransferPropsAlias;
+
+const filterMethod = (query: string, item: API.GetCompanyNameListOutput) => {
+  return item.name.toLowerCase().includes(query.toLowerCase());
+};
+</script>
+
+<style lang="scss" scoped>
+.batchEntryRewardBody {
+  display: flex;
+  justify-content: center;
+  width: 100%;
+}
+</style>
diff --git a/src/views/Reward/components/RegisterGrantDialog.vue b/src/views/Reward/components/RegisterGrantDialog.vue
new file mode 100644
index 0000000..4a135dc
--- /dev/null
+++ b/src/views/Reward/components/RegisterGrantDialog.vue
@@ -0,0 +1,121 @@
+<template>
+  <ProDialog
+    title="鐧昏"
+    v-model="visible"
+    @close="onDialogClose"
+    destroy-on-close
+    draggable
+    width="700px"
+  >
+    <ProForm :model="form" ref="dialogForm" label-width="120px">
+      <ProFormItemV2
+        label="鐧昏绫诲瀷:"
+        prop="incomeType"
+        :check-rules="[{ message: '璇烽�夋嫨鐧昏绫诲瀷' }]"
+      >
+        <ProFormRadio
+          v-model="form.incomeType"
+          :value-enum="incomeTypeEnum"
+          :button-style="false"
+        />
+      </ProFormItemV2>
+      <ProFormItemV2
+        label="杈撳叆閲戦:"
+        prop="financeSumAmount"
+        :check-rules="[{ message: '璇疯緭鍏ラ噾棰�', type: 'number' }]"
+      >
+        <ProFormInputNumber
+          v-model="form.financeSumAmount"
+          :controls="false"
+          :min="0"
+          unit="鍏�"
+          :precision="2"
+        ></ProFormInputNumber>
+      </ProFormItemV2>
+      <ProFormItemV2
+        label="涓婁紶鍑瘉:"
+        prop="fileUrl"
+        :check-rules="[{ message: '璇蜂笂浼犲嚟璇�', type: 'upload' }]"
+      >
+        <ProFormUpload
+          v-model:file-url="form.fileUrl"
+          :limitFileSize="50"
+          accept="doc,docx,pdf,xls,xlsx,jpg/jpeg,png"
+        ></ProFormUpload>
+      </ProFormItemV2>
+    </ProForm>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')">鍙� 娑�</el-button>
+        <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { FormInstance } from 'element-plus';
+import {
+  ProDialog,
+  ProForm,
+  ProFormItemV2,
+  ProFormInputNumber,
+  ProFormRadio,
+  ProFormUpload,
+  UploadUserFile,
+} from '@bole-core/components';
+import { IncomeTypeEnumText, IncomeTypeEnum, FinanceStatusEnum } from '@/constants';
+
+defineOptions({
+  name: 'RegisterGrantDialog',
+});
+
+const visible = defineModel({ type: Boolean });
+
+type Form = {
+  title?: string;
+  financeSumAmount: number;
+  fileUrl: UploadUserFile[];
+  incomeType: IncomeTypeEnum;
+  showSuportPlatRecharge: boolean;
+  showSuportFiscalRecharge: boolean;
+};
+
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'onConfirm'): void;
+  (e: 'onCancel'): void;
+}>();
+
+const incomeTypeEnum = computed(() => {
+  return [
+    form.value.showSuportFiscalRecharge && {
+      label: IncomeTypeEnumText[IncomeTypeEnum.Fiscal],
+      value: IncomeTypeEnum.Fiscal,
+    },
+    form.value.showSuportPlatRecharge && {
+      label: IncomeTypeEnumText[IncomeTypeEnum.Platform],
+      value: IncomeTypeEnum.Platform,
+    },
+  ].filter(Boolean);
+});
+
+const dialogForm = ref<FormInstance>();
+
+function onDialogClose() {
+  if (!dialogForm.value) return;
+  dialogForm.value.resetFields();
+}
+
+function handleConfirm() {
+  if (!dialogForm.value) return;
+  dialogForm.value.validate((valid) => {
+    if (valid) {
+      emit('onConfirm');
+    } else {
+      return;
+    }
+  });
+}
+</script>
diff --git a/src/views/Reward/components/RewardApplyTradeCheckDialog.vue b/src/views/Reward/components/RewardApplyTradeCheckDialog.vue
index 42d82a7..92e94dc 100644
--- a/src/views/Reward/components/RewardApplyTradeCheckDialog.vue
+++ b/src/views/Reward/components/RewardApplyTradeCheckDialog.vue
@@ -1,6 +1,13 @@
 <template>
   <ProDialog title="鍑鸿处瀹℃壒" v-model="visible" @close="onDialogClose" destroy-on-close draggable>
-    <PortraitTableWithAttachment v-bind="portraitTableWithAttachmentProps" />
+    <PortraitTableWithAttachment v-bind="portraitTableWithAttachmentProps">
+      <template #title>
+        <el-row class="portrait-table-with-attachment-title">
+          <el-text style="color: #333333">鎵撴淇℃伅</el-text>
+          <el-button type="primary" link @click="handleApply">澶嶅埗</el-button>
+        </el-row>
+      </template>
+    </PortraitTableWithAttachment>
     <ProForm
       :model="form"
       ref="dialogForm"
@@ -103,7 +110,7 @@
   UploadUserFile,
 } from '@bole-core/components';
 import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
-import { usePortraitTableWithAttachment } from '@/hooks';
+import { copyTextToClipboard, usePortraitTableWithAttachment } from '@/hooks';
 import { convertApi2FormUrl, convertApi2FormUrlOnlyOne } from '@/utils';
 import { useQuery } from '@tanstack/vue-query';
 import {
@@ -157,11 +164,6 @@
   annexList: computed(() => form.value?.payFileUrl),
   columns: [
     {
-      label: '寮�鎴疯处鍙�',
-      key: 'userName',
-      formatter: () => '1511 2001 2920 0156 069',
-    },
-    {
       label: '杩涜处鍗曚綅',
       key: 'enterpriseName',
       formatter: () => '澶钩璐骇淇濋櫓鏈夐檺鍏徃鎶氬窞涓績鏀叕鍙�',
@@ -175,6 +177,11 @@
       label: '寮�鎴烽摱琛�',
       key: 'contactPhone',
       formatter: () => '涓浗宸ュ晢閾惰鑲′唤鏈夐檺鍏徃鎶氬窞璧d笢鏀',
+    },
+    {
+      label: '寮�鎴疯处鍙�',
+      key: 'userName',
+      formatter: () => '1511 2001 2920 0156 069',
     },
     // {
     //   label: '浼佷笟绫诲瀷',
@@ -190,19 +197,19 @@
     //   label: '鍥尯绫诲瀷',
     //   key: 'parkTypeName',
     // },
-    // {
-    //   label: '娑堣垂绫诲瀷',
-    //   key: 'payRemark',
-    // },
     {
-      label: '鐢宠鍑鸿处閲戦',
-      key: 'tradeAmount',
-      type: 'money',
+      label: '娑堣垂绫诲瀷',
+      key: 'payRemark',
     },
     {
-      label: '鐢宠鍑鸿处鏃堕棿',
+      label: '鍑鸿处瀹℃牳鏃ユ湡',
       key: 'tradeTime',
       type: 'date',
+    },
+    {
+      label: '鍑鸿处閲戦',
+      key: 'tradeAmount',
+      type: 'money',
     },
     {
       label: '璧勯噾浣欓',
@@ -233,4 +240,17 @@
     }
   });
 }
+
+function handleApply() {
+  copyTextToClipboard(
+    `寮�鎴峰悕绉帮細${form.value?.societyCreditCode}\n寮�鎴烽摱琛岋細${form.value?.contactPhone}\n寮�鎴疯处鍙凤細${form.value?.userName}`
+  );
+}
 </script>
+<style lang="scss" scoped>
+@use '@/style/common.scss' as *;
+
+.portrait-table-with-attachment-title {
+  justify-content: space-between;
+}
+</style>
diff --git a/src/views/Reward/components/UploadFileDialog.vue b/src/views/Reward/components/UploadFileDialog.vue
new file mode 100644
index 0000000..23785ab
--- /dev/null
+++ b/src/views/Reward/components/UploadFileDialog.vue
@@ -0,0 +1,86 @@
+<template>
+  <ProDialog
+    title="瀵煎叆"
+    v-model="visible"
+    @close="onDialogClose"
+    destroy-on-close
+    draggable
+    width="700px"
+  >
+    <ProForm :model="form" ref="dialogForm" label-width="120px">
+      <ProFormItemV2
+        label="涓婁紶鏂囦欢:"
+        prop="url"
+        :check-rules="[{ message: '璇蜂笂浼犳枃浠�', type: 'upload' }]"
+      >
+        <ProFormUpload v-model:file-url="form.url" accept="xlsx,xls"></ProFormUpload>
+      </ProFormItemV2>
+      <ProFormItemV2
+        label="涓婁紶鍑瘉:"
+        prop="certificateUrl"
+        :check-rules="[{ message: '璇蜂笂浼犲嚟璇�', type: 'upload' }]"
+      >
+        <ProFormUpload
+          v-model:file-url="form.certificateUrl"
+          :limitFileSize="50"
+          accept="doc,docx,pdf,xls,xlsx,jpg/jpeg,png"
+        ></ProFormUpload>
+      </ProFormItemV2>
+    </ProForm>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="emit('onCancel')">鍙� 娑�</el-button>
+        <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+      </span>
+    </template>
+  </ProDialog>
+</template>
+
+<script setup lang="ts">
+import { FormInstance } from 'element-plus';
+import {
+  ProDialog,
+  ProForm,
+  ProFormItemV2,
+  UploadUserFile,
+  ProFormUpload,
+} from '@bole-core/components';
+
+defineOptions({
+  name: 'UploadCertRewardDialog',
+});
+
+const visible = defineModel({ type: Boolean });
+
+type Form = {
+  title?: string;
+  certificateUrl: UploadUserFile[];
+  url: UploadUserFile[];
+  parkBountyApplyId: string;
+};
+
+const form = defineModel<Form>('form');
+
+const emit = defineEmits<{
+  (e: 'onConfirm'): void;
+  (e: 'onCancel'): void;
+}>();
+
+const dialogForm = ref<FormInstance>();
+
+function onDialogClose() {
+  if (!dialogForm.value) return;
+  dialogForm.value.resetFields();
+}
+
+function handleConfirm() {
+  if (!dialogForm.value) return;
+  dialogForm.value.validate((valid) => {
+    if (valid) {
+      emit('onConfirm');
+    } else {
+      return;
+    }
+  });
+}
+</script>
diff --git a/src/views/Reward/constants/columns.ts b/src/views/Reward/constants/columns.ts
index 58aab3c..0aac26b 100644
--- a/src/views/Reward/constants/columns.ts
+++ b/src/views/Reward/constants/columns.ts
@@ -43,13 +43,13 @@
     name: '鍥尯绫诲瀷',
   },
   {
-    id: '22',
+    id: '8',
     enCode: 'auditStatus',
     name: '瀹℃牳鐘舵��',
     width: 160,
   },
   {
-    id: '21',
+    id: '9',
     enCode: 'payRemark',
     name: '娑堣垂绫诲瀷',
     width: 160,
@@ -66,16 +66,24 @@
     name: '鐢宠鍑鸿处鏃堕棿',
     width: 160,
   },
-  // {
-  //   id: '12',
-  //   enCode: 'payFileUrl',
-  //   name: '鍑鸿处鍑瘉',
-  //   width: 160,
-  // },
   {
-    id: '9',
+    id: '12',
     enCode: 'remianAmount',
     name: '璧勯噾浣欓',
     width: 160,
   },
+  {
+    id: '13',
+    enCode: 'a',
+    name: '瀹℃牳鏃堕棿',
+    width: 160,
+  },
 ]);
+
+export const ImportParkBountyDataHeaderMap = {
+  enterpriseName: '浼佷笟鍚嶇О',
+  societyCreditCode: '淇$敤浠g爜',
+  financeToAmount: '璐㈡斂鎷ㄤ粯閲戦',
+  transferToAmount: '骞冲彴鎷ㄤ粯閲戦',
+  remark: '澶囨敞',
+};

--
Gitblit v1.9.1