wupengfei
5 天以前 eaf9c983b41f2c1fe682526eab131999f84fb8fe
feat: 页面
9个文件已添加
9个文件已修改
1229 ■■■■■ 已修改文件
src/constants/fourStreams.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/industrialPark.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EnterpriseInfo/components/RewardGrantRecordView.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/MaterialReview/MaterialReview.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Reward/RewardGrant.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Reward/RewardGrantRegister.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Reward/WithdrawalApproval.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/RewardStatistics.vue 506 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/components/BalanceDetailDialog.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/components/EnterpriseConsumptionDetailDialog.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/components/EnterpriseRechargeDetailDialog.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/components/EnterpriseWithdrawalDetailDialog.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/components/FinancialAllocationDetailDialog.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/components/PlatformDisbursementDetailDialog.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/hooks/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/StatisticalReport/hooks/rewardStatistics.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/fourStreams.ts
@@ -161,3 +161,26 @@
  /// 财政拨付
  Finance = 30,
}
export enum EnumParkRewardStatisticsDetailScene {
  /**
   * 财政拨付
   */
  Finance = 1,
  /**
   * 平台拨付
   */
  Transfer = 2,
  /**
   * 企业充值
   */
  Recharge = 3,
  /**
   * 企业提现
   */
  DrawWith = 4,
  /**
   * 企业消费
   */
  Trade = 5,
}
src/hooks/index.ts
@@ -10,3 +10,4 @@
export * from './dic';
export * from './table';
export * from './fourStreams';
export * from './industrialPark';
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,
  };
}
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',
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"
      />
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: '审核状态',
  },
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([
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"
            />
src/views/Reward/WithdrawalApproval.vue
@@ -111,6 +111,11 @@
    name: '审核状态',
  },
  {
    id: '8',
    enCode: 'a',
    name: '审核人',
  },
  {
    id: '9',
    enCode: 'checkTime',
    name: '审核时间',
src/views/StatisticalReport/RewardStatistics.vue
New file
@@ -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="企业名/信用代码/联系人/联系方式"
              @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: '信用代码',
    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年MM月' },
      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>
src/views/StatisticalReport/components/BalanceDetailDialog.vue
New file
@@ -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>
src/views/StatisticalReport/components/EnterpriseConsumptionDetailDialog.vue
New file
@@ -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>
src/views/StatisticalReport/components/EnterpriseRechargeDetailDialog.vue
New file
@@ -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>
src/views/StatisticalReport/components/EnterpriseWithdrawalDetailDialog.vue
New file
@@ -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>
src/views/StatisticalReport/components/FinancialAllocationDetailDialog.vue
New file
@@ -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>
src/views/StatisticalReport/components/PlatformDisbursementDetailDialog.vue
New file
@@ -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>
src/views/StatisticalReport/hooks/index.ts
New file
@@ -0,0 +1 @@
export * from './rewardStatistics';
src/views/StatisticalReport/hooks/rewardStatistics.ts
New file
@@ -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,
  };
}