wupengfei
8 天以前 8e99c3b1e12340c27ef71a3a3b0e7c93ae7f8464
feat: databoard
5个文件已修改
41个文件已添加
2007 ■■■■■ 已修改文件
src/assets/dataBoard/data-board-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-center-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-center-chart-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-center-icon1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-center-icon2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-center-icon3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-center-map.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg4.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg5.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg6.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg7.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-data-info-bg8.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-footer.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-map-choose.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-map-init.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-table-icon1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-table-icon2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-table-icon3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-title-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/fonts/DrukWide-Bold.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/fonts/DrukWide-Bold.woff 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/fonts/DrukWide-Bold.woff2 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/fonts/Fontquan-XinYiGuanHeiTi Regular.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/fonts/YouSheBiaoTiHei Regular.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/industrialPark.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/DataBoard.ts 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/IndustrialPark.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/WaterDropCloud.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/typings.d.ts 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/style/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/DataBoardHome.vue 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardCenterChart.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardCenterDataContent.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardCenterDataItem.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardCenterMap.vue 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardCenterMapMark.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardContentItem.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardDataInfoItem.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataBoardTableView.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/components/DataOverviewContent.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/hooks/index.ts 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/DataBoard/utils/index.ts 280 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/dataBoard/data-board-bg.png
src/assets/dataBoard/data-board-center-bg.png
src/assets/dataBoard/data-board-center-chart-bg.png
src/assets/dataBoard/data-board-center-icon1.png
src/assets/dataBoard/data-board-center-icon2.png
src/assets/dataBoard/data-board-center-icon3.png
src/assets/dataBoard/data-board-center-map.png
src/assets/dataBoard/data-board-data-info-bg1.png
src/assets/dataBoard/data-board-data-info-bg2.png
src/assets/dataBoard/data-board-data-info-bg3.png
src/assets/dataBoard/data-board-data-info-bg4.png
src/assets/dataBoard/data-board-data-info-bg5.png
src/assets/dataBoard/data-board-data-info-bg6.png
src/assets/dataBoard/data-board-data-info-bg7.png
src/assets/dataBoard/data-board-data-info-bg8.png
src/assets/dataBoard/data-board-footer.png
src/assets/dataBoard/data-board-map-choose.png
src/assets/dataBoard/data-board-map-init.png
src/assets/dataBoard/data-board-table-icon1.png
src/assets/dataBoard/data-board-table-icon2.png
src/assets/dataBoard/data-board-table-icon3.png
src/assets/dataBoard/data-board-title-bg.png
src/assets/fonts/DrukWide-Bold.ttf
Binary files differ
src/assets/fonts/DrukWide-Bold.woff
Binary files differ
src/assets/fonts/DrukWide-Bold.woff2
Binary files differ
src/assets/fonts/Fontquan-XinYiGuanHeiTi Regular.ttf
Binary files differ
src/assets/fonts/YouSheBiaoTiHei Regular.ttf
Binary files differ
src/hooks/industrialPark.ts
@@ -37,6 +37,15 @@
    return industrialPark?.parkName ?? '';
  }
  /**数据看板 */
  const dataBoardIndustrialParkList = computed(() => {
    return industrialParkList.value.map((x, index) => ({
      ...x,
      choose: index === 0,
      class: `init${index + 1}`,
    }));
  });
  return {
    industrialParkList,
    getIndustrialParkNameById,
@@ -44,5 +53,6 @@
    getIndustrialParkTypeNameById,
    getIndustrialParkByName,
    fourStreamsIndustrialParkList,
    dataBoardIndustrialParkList,
  };
}
src/services/api/DataBoard.ts
New file
@@ -0,0 +1,174 @@
/* eslint-disable */
// @ts-ignore
import { request } from '@/utils/request';
/** 查询数据看板奖励金使用排行 GET /api/DataBoard/GetDataBoardBountyUseAmountRank */
export async function getDataBoardBountyUseAmountRank(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardBountyUseAmountRankParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardBountyUseAmountRankOutput>(
    '/api/DataBoard/GetDataBoardBountyUseAmountRank',
    {
      method: 'GET',
      params: {
        ...params,
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板投保人数排行 GET /api/DataBoard/GetDataBoardInsurePeopleCountRank */
export async function getDataBoardInsurePeopleCountRank(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardInsurePeopleCountRankParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardInsurePeopleCountRankOutput>(
    '/api/DataBoard/GetDataBoardInsurePeopleCountRank',
    {
      method: 'GET',
      params: {
        ...params,
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板新增申报批次 GET /api/DataBoard/GetDataBoardNewBountyApplyCount */
export async function getDataBoardNewBountyApplyCount(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardNewBountyApplyCountParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardNewBountyApplyCountOutput>(
    '/api/DataBoard/GetDataBoardNewBountyApplyCount',
    {
      method: 'GET',
      params: {
        ...params,
        input: undefined,
        ...params['input'],
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板新增发放额 GET /api/DataBoard/GetDataBoardNewBountyReleaseAmountCount */
export async function getDataBoardNewBountyReleaseAmountCount(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardNewBountyReleaseAmountCountParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardNewBountyReleaseAmountCountOutput>(
    '/api/DataBoard/GetDataBoardNewBountyReleaseAmountCount',
    {
      method: 'GET',
      params: {
        ...params,
        input: undefined,
        ...params['input'],
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板新增发放额 GET /api/DataBoard/GetDataBoardNewBountyUseAmountCount */
export async function getDataBoardNewBountyUseAmountCount(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardNewBountyUseAmountCountParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardNewBountyUseAmountCountOutput>(
    '/api/DataBoard/GetDataBoardNewBountyUseAmountCount',
    {
      method: 'GET',
      params: {
        ...params,
        input: undefined,
        ...params['input'],
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板新增入驻企业 GET /api/DataBoard/GetDataBoardNewCustomerCount */
export async function getDataBoardNewCustomerCount(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardNewCustomerCountParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardNewCustomerCountOutput>(
    '/api/DataBoard/GetDataBoardNewCustomerCount',
    {
      method: 'GET',
      params: {
        ...params,
        input: undefined,
        ...params['input'],
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板投保人数对比 GET /api/DataBoard/GetDataBoardNewInsurePeopleCount */
export async function getDataBoardNewInsurePeopleCount(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardNewInsurePeopleCountParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardNewInsurePeopleCountOutput>(
    '/api/DataBoard/GetDataBoardNewInsurePeopleCount',
    {
      method: 'GET',
      params: {
        ...params,
        input: undefined,
        ...params['input'],
      },
      ...(options || {}),
    }
  );
}
/** 查询数据看板概况 GET /api/DataBoard/GetDataBoardOverview */
export async function getDataBoardOverview(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardOverviewParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardOverviewOutput>('/api/DataBoard/GetDataBoardOverview', {
    method: 'GET',
    params: {
      ...params,
      input: undefined,
      ...params['input'],
    },
    ...(options || {}),
  });
}
/** 查询数据看板园区概况 GET /api/DataBoard/GetDataBoardOverviewByPark */
export async function getDataBoardOverviewByPark(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetDataBoardOverviewByParkParams,
  options?: API.RequestConfig
) {
  return request<API.GetDataBoardOverviewByParkOutput>(
    '/api/DataBoard/GetDataBoardOverviewByPark',
    {
      method: 'GET',
      params: {
        ...params,
      },
      ...(options || {}),
    }
  );
}
src/services/api/IndustrialPark.ts
@@ -99,6 +99,24 @@
  );
}
/** 查询园区奖励金模板名称 POST /api/IndustrialPark/GetIndustrialPartBountyTemplates */
export async function getIndustrialPartBountyTemplates(
  body: API.GetIndustrialPartBountyTemplatesInput,
  options?: API.RequestConfig
) {
  return request<API.GetIndustrialPartBountyTemplatesOutput>(
    '/api/IndustrialPark/GetIndustrialPartBountyTemplates',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      data: body,
      ...(options || {}),
    }
  );
}
/** 设置奖励金申报状态 POST /api/IndustrialPark/SetIndustrialParkRewardEnable */
export async function setIndustrialParkRewardEnable(
  body: API.SetIndustrialParkRewardEnableInput,
src/services/api/WaterDropCloud.ts
New file
@@ -0,0 +1,11 @@
/* eslint-disable */
// @ts-ignore
import { request } from '@/utils/request';
/** 同步客户材料 POST /api/WaterDropCloud/SyncCompanyMaterial */
export async function syncCompanyMaterial(options?: API.RequestConfig) {
  return request<any>('/api/WaterDropCloud/SyncCompanyMaterial', {
    method: 'POST',
    ...(options || {}),
  });
}
src/services/api/index.ts
@@ -23,6 +23,7 @@
import * as Consult from './Consult';
import * as CooperationApply from './CooperationApply';
import * as Customer from './Customer';
import * as DataBoard from './DataBoard';
import * as ElectronSign from './ElectronSign';
import * as EnterpriseApplyFile from './EnterpriseApplyFile';
import * as EnterpriseMaterial from './EnterpriseMaterial';
@@ -90,6 +91,7 @@
import * as Version from './Version';
import * as Wallet from './Wallet';
import * as WalletChannel from './WalletChannel';
import * as WaterDropCloud from './WaterDropCloud';
import * as Withdraw from './Withdraw';
import * as WxNotify from './WxNotify';
import * as WxPayNotify from './WxPayNotify';
@@ -115,6 +117,7 @@
  Consult,
  CooperationApply,
  Customer,
  DataBoard,
  ElectronSign,
  EnterpriseApplyFile,
  EnterpriseMaterial,
@@ -182,6 +185,7 @@
  Version,
  Wallet,
  WalletChannel,
  WaterDropCloud,
  Withdraw,
  WxNotify,
  WxPayNotify,
src/services/api/typings.d.ts
@@ -249,7 +249,7 @@
    /** 是否支持财政拨付 */
    suportFinance?: boolean;
    /** 文件 */
    industrialParkApplyFileFile?: IndustrialParkApplyFileFile[];
    bountTemplates?: AddIndustrialParkInputBountTemplate[];
    /** 无需政务端审核 */
    notNeedGovernmentAudit?: boolean;
    /** 无需运营端审核 */
@@ -258,6 +258,15 @@
    dualReviewOfGovernmentAffairs?: boolean;
    /** 公司信息 */
    industrialParkCompanyFile?: IndustrialParkCompanyFile[];
  }
  interface AddIndustrialParkInputBountTemplate {
    /** 模板Id */
    templateId?: string;
    /** 模板名称 */
    templateName?: string;
    /** 文件 */
    items?: IndustrialParkApplyFileFile[];
  }
  interface AddIndustryBodyAuditInput {
@@ -467,6 +476,8 @@
  interface AddParkBountyApplyStepOneInput {
    batchNo?: string;
    parkId?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    applyMonth?: string;
    removeCompanyIds?: string[];
  }
@@ -1398,6 +1409,7 @@
  interface APIgetCustomerFileTypeHeadParams {
    enterpriseId?: string;
    templateId?: string;
  }
  interface APIgetCustomerTemplateDetailParams {
@@ -1410,6 +1422,44 @@
  interface APIgetCustomerTemplateParamListByTemplateIdParams {
    templateId?: string;
  }
  interface APIgetDataBoardBountyUseAmountRankParams {
    /** 查询数量 */
    take?: number;
  }
  interface APIgetDataBoardInsurePeopleCountRankParams {
    /** 查询数量 */
    take?: number;
  }
  interface APIgetDataBoardNewBountyApplyCountParams {
    input?: GetDataBoardNewBountyApplyCountInput;
  }
  interface APIgetDataBoardNewBountyReleaseAmountCountParams {
    input?: GetDataBoardNewBountyReleaseAmountCountInput;
  }
  interface APIgetDataBoardNewBountyUseAmountCountParams {
    input?: GetDataBoardNewBountyUseAmountCountInput;
  }
  interface APIgetDataBoardNewCustomerCountParams {
    input?: GetDataBoardNewCustomerCountInput;
  }
  interface APIgetDataBoardNewInsurePeopleCountParams {
    input?: GetDataBoardNewInsurePeopleCountInput;
  }
  interface APIgetDataBoardOverviewByParkParams {
    industrialParkId?: string;
  }
  interface APIgetDataBoardOverviewParams {
    input?: GetDataBoardOverviewInput;
  }
  interface APIgetDefaultConnectionStringParams {
@@ -5851,6 +5901,8 @@
    applyAmount?: number;
    fileTypes?: CustomerUploadMonthApplyFileType[];
    enterpriseId?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    /** 是否是运营端代上传 */
    isAdminFileUpload?: boolean;
  }
@@ -5880,6 +5932,8 @@
    applyAmount?: number;
    fileTypes?: CustomerUploadMonthApplyFileType[];
    enterpriseId?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    /** 是否是运营端代上传 */
    isAdminFileUpload?: boolean;
    /** 汇总材料 */
@@ -7722,6 +7776,8 @@
  interface GetCustomerUploadApplyFilesInput {
    id?: string;
    enterpriseId?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    userId?: string;
    withMonth?: string;
    parkBountyApplyId?: string;
@@ -7746,6 +7802,8 @@
  interface GetCustomerUploadApplyFilesResponse {
    /** 所属月份 */
    withMonth?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    /** 企业名称 */
    enterpriseName?: string;
    /** 申报金额 */
@@ -7759,6 +7817,8 @@
  interface GetCustomerUploadApplyFilesV2Response {
    /** 所属月份 */
    withMonth?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    /** 企业名称 */
    enterpriseName?: string;
    /** 申报金额 */
@@ -7775,11 +7835,119 @@
  interface GetCustomerUploadFileRecordInput {
    withMonth?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    userId?: string;
    isApply?: boolean;
  }
  interface GetCustomerUploadFileRecordOutput {
    id?: string;
  }
  interface GetDataBoardBountyUseAmountRankOutput {
    items?: GetDataBoardBountyUseAmountRankOutputItem[];
  }
  interface GetDataBoardBountyUseAmountRankOutputItem {
    /** 企业名称 */
    enterpriseName?: string;
    /** 金额 */
    amount?: number;
  }
  interface GetDataBoardInsurePeopleCountRankOutput {
    items?: GetDataBoardInsurePeopleCountRankOutputItem[];
  }
  interface GetDataBoardInsurePeopleCountRankOutputItem {
    /** 企业名称 */
    enterpriseName?: string;
    /** 人数 */
    count?: number;
  }
  type GetDataBoardNewBountyApplyCountInput = Record<string, any>;
  interface GetDataBoardNewBountyApplyCountOutput {
    /** X轴 */
    x?: string[];
    /** 当月数据 */
    currentMonthData?: number[];
    /** 上月数据 */
    lastMonthData?: number[];
  }
  type GetDataBoardNewBountyReleaseAmountCountInput = Record<string, any>;
  interface GetDataBoardNewBountyReleaseAmountCountOutput {
    /** X轴 */
    x?: string[];
    /** 当月数据 */
    currentMonthData?: number[];
    /** 上月数据 */
    lastMonthData?: number[];
  }
  type GetDataBoardNewBountyUseAmountCountInput = Record<string, any>;
  interface GetDataBoardNewBountyUseAmountCountOutput {
    /** X轴 */
    x?: string[];
    /** 当月数据 */
    currentMonthData?: number[];
    /** 上月数据 */
    lastMonthData?: number[];
  }
  type GetDataBoardNewCustomerCountInput = Record<string, any>;
  interface GetDataBoardNewCustomerCountOutput {
    /** X轴 */
    x?: string[];
    /** 当月数据 */
    currentMonthData?: number[];
    /** 上月数据 */
    lastMonthData?: number[];
  }
  type GetDataBoardNewInsurePeopleCountInput = Record<string, any>;
  interface GetDataBoardNewInsurePeopleCountOutput {
    /** X轴 */
    x?: string[];
    /** 数据 */
    data?: number[];
  }
  interface GetDataBoardOverviewByParkOutput {
    /** 总入驻企业 */
    totalCustomerCount?: number;
    /** 奖励金发放总额 */
    sumBountyReleaseAmount?: number;
    /** 奖励金使用总额 */
    sumBountyUseAmount?: number;
    /** 投保人数 */
    insurePeopleCount?: number;
  }
  type GetDataBoardOverviewInput = Record<string, any>;
  interface GetDataBoardOverviewOutput {
    /** 总入驻企业 */
    totalCustomerCount?: number;
    /** 总申报数量 */
    totalBountyApplyCount?: number;
    /** 奖励金发放总额 */
    sumBountyReleaseAmount?: number;
    /** 奖励金使用总额 */
    sumBountyUseAmount?: number;
    /** 当月发放额 */
    currentMonthSumBountyReleaseAmount?: number;
    /** 当月使用额 */
    currentMonthSumBountyUseAmount?: number;
    /** 当月投保人数 */
    currentMonthInsurePeopleCount?: number;
  }
  interface GetEnterpriseBuntyTradeDto {
@@ -8215,6 +8383,21 @@
    categoryId?: string;
    /** 查询条件:产品名称/服务商名称 */
    queryCondition?: string;
  }
  interface GetIndustrialPartBountyTemplatesInput {
    /** 园区Id */
    id?: string;
  }
  interface GetIndustrialPartBountyTemplatesOutput {
    /** 奖励金模板名称 */
    bountyTemplates?: GetIndustrialPartBountyTemplatesOutputItem[];
  }
  interface GetIndustrialPartBountyTemplatesOutputItem {
    id?: string;
    templateName?: string;
  }
  interface GetInformationAdvertiseByCategoryInput {
@@ -9605,6 +9788,8 @@
  interface GetParkCollectFileTypeListInput {
    parkId?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
    searchType?: number;
  }
@@ -11725,8 +11910,18 @@
    registerAddress?: string;
    /** 备注 */
    remark?: string;
    industrialParkFileTypeList?: IndustrialParkFileTypeOutput[];
    /** 奖励金模板 */
    bountyTemplates?: IndustrialParkDetailOutputFileTypeTemplate[];
    industrialParkCompanyList?: IndustrialParkCompanyOutput[];
  }
  interface IndustrialParkDetailOutputFileTypeTemplate {
    /** 模板Id */
    templateId?: string;
    /** 模板名称 */
    templateName?: string;
    /** 材料 */
    items?: IndustrialParkFileTypeOutput[];
  }
  interface IndustrialParkDropDownOutput {
@@ -16659,6 +16854,10 @@
  interface OutCheckParkBountyApplyBaseInfo {
    /** 申请批次号 */
    batchNo?: string;
    /** 奖励金模板 */
    bountyTemplateId?: string;
    /** 奖励金模板名称 */
    bountyTemplateName?: string;
    /** 申请园区Id */
    parkId?: string;
    /** 申请园区 */
@@ -16808,6 +17007,10 @@
  interface ParkBountyApplyBaseInfo {
    /** 申请批次号 */
    batchNo?: string;
    /** 模板Id */
    bountyTemplateId?: string;
    /** 模板名称 */
    bountyTemplateName?: string;
    /** 申请园区Id */
    parkId?: string;
    /** 申请园区 */
@@ -22899,7 +23102,7 @@
    /** 是否支持财政拨付 */
    suportFinance?: boolean;
    /** 文件 */
    industrialParkApplyFileFile?: IndustrialParkApplyFileFile[];
    bountTemplates?: AddIndustrialParkInputBountTemplate[];
    /** 无需政务端审核 */
    notNeedGovernmentAudit?: boolean;
    /** 无需运营端审核 */
@@ -23587,6 +23790,8 @@
    fileSearchTypeId?: string;
    listFiles?: CustomerUploadMonthApplyFileTypeDto[];
    enterpriseId?: string;
    /** 奖励金模板Id */
    bountyTemplateId?: string;
  }
  interface UploadParkApplyCustomerFilesInput {
src/style/index.scss
@@ -195,3 +195,24 @@
    }
  }
}
@font-face {
  font-family: DrukWide-Bold;
  src: url('@/assets/fonts/DrukWide-Bold.woff2') format('woff2');
  font-style: normal;
  font-weight: normal;
}
@font-face {
  font-family: 'YouSheBiaoTiHei Regular';
  src: url('@/assets/fonts/YouSheBiaoTiHei Regular.ttf') format('truetype');
  font-style: normal;
  font-weight: normal;
}
@font-face {
  font-family: 'Fontquan-XinYiGuanHeiTi Regular';
  src: url('@/assets/fonts/Fontquan-XinYiGuanHeiTi Regular.ttf') format('truetype');
  font-style: normal;
  font-weight: normal;
}
src/views/DataBoard/DataBoardHome.vue
New file
@@ -0,0 +1,306 @@
<template>
  <div class="data-board-home-wrapper">
    <div class="data-board-home">
      <div class="data-board-home-title">
        <div class="data-board-home-title-logo"></div>
        <div class="data-board-home-title-text">{{ '江西818综合数据展示' }}</div>
        <div class="data-board-home-title-time">
          {{ dataBoardTime }}
        </div>
      </div>
      <div class="data-board-home-content">
        <div class="data-board-home-content-left">
          <DataBoardContentItem title="数据概况" class="data-overview">
            <DataOverviewContent></DataOverviewContent>
          </DataBoardContentItem>
          <DataBoardContentItem title="新增入驻企业" class="new-enter">
            <div class="new-enter-content">
              <v-chart :option="newEnterOption" />
            </div>
          </DataBoardContentItem>
          <DataBoardContentItem title="新增申报批次" :hasBottom="false" class="new-declare">
            <div class="new-declare-content">
              <v-chart :option="newDeclareOption" />
            </div>
          </DataBoardContentItem>
        </div>
        <div class="data-board-home-content-center">
          <DataBoardCenterDataContent></DataBoardCenterDataContent>
          <div class="data-board-home-content-center-map">
            <img
              class="data-board-home-content-center-map-bg left"
              :src="DataBoardCenterBg"
              alt=""
            />
            <img
              class="data-board-home-content-center-map-bg right"
              :src="DataBoardCenterBg"
              alt=""
            />
            <DataBoardCenterMap></DataBoardCenterMap>
          </div>
          <DataBoardCenterChart></DataBoardCenterChart>
        </div>
        <div class="data-board-home-content-right">
          <DataBoardContentItem title="奖励金使用排行" class="data-table-content">
            <DataBoardTableView
              :tableData="bountyUseAmountRankList"
              unit="元"
              :isMoney="true"
              customerName="使用金额"
            ></DataBoardTableView>
          </DataBoardContentItem>
          <DataBoardContentItem title="投保人数排行" class="data-table-content">
            <DataBoardTableView
              :tableData="insurePeopleCountRankList"
              unit="人"
              customerName="投保人数"
            ></DataBoardTableView>
          </DataBoardContentItem>
          <DataBoardContentItem title="投保人数对比" :hasBottom="false" class="insure-person">
            <div class="insure-person-content">
              <v-chart :option="insurePersonOption" />
            </div>
          </DataBoardContentItem>
        </div>
      </div>
      <div class="data-board-home-footer"></div>
    </div>
  </div>
</template>
<script setup lang="ts">
import DataBoardContentItem from './components/DataBoardContentItem.vue';
import DataBoardTableView from './components/DataBoardTableView.vue';
import DataBoardCenterMap from './components/DataBoardCenterMap.vue';
import DataBoardCenterChart from './components/DataBoardCenterChart.vue';
import DataOverviewContent from './components/DataOverviewContent.vue';
import DataBoardCenterDataContent from './components/DataBoardCenterDataContent.vue';
import DataBoardCenterBg from '@/assets/dataBoard/data-board-center-bg.png';
import 'echarts';
import vChart from 'vue-echarts';
import * as dataBoardServices from '@/services/api/DataBoard';
import { format } from '@/utils';
import {
  createNewEnterChartOptions,
  createNewDeclareChartOptions,
  createInsurePersonOptionChartOptions,
} from './utils';
import { useQuery } from '@tanstack/vue-query';
import {
  useGetDataBoardBountyUseAmountRank,
  useGetDataBoardInsurePeopleCountRank,
  useGetDataBoardNewBountyApplyCount,
  useGetDataBoardNewCustomerCount,
  useGetDataBoardNewInsurePeopleCount,
} from './hooks';
import { take } from 'lodash';
defineOptions({
  name: 'DataBoardHome',
});
const dataBoardTime = ref(null);
let timer = null;
const tableData = [
  {
    name: '公司名',
    num: 3842,
  },
  {
    name: '公司名',
    num: 32,
  },
  {
    name: '公司名',
    num: 342,
  },
  {
    name: '公司名',
    num: 342,
  },
  {
    name: '公司名',
    num: 342,
  },
  {
    name: '公司名',
    num: 342,
  },
];
const updateTime = () => {
  dataBoardTime.value = format(new Date(), 'YYYY.MM.DD HH:mm:ss');
};
const { detail: newCustomerCount } = useGetDataBoardNewCustomerCount();
const { detail: newBountyApplyCount } = useGetDataBoardNewBountyApplyCount();
const { detail: newInsurePeopleCount } = useGetDataBoardNewInsurePeopleCount();
const { bountyUseAmountRankList } = useGetDataBoardBountyUseAmountRank({
  take: 6,
});
const { insurePeopleCountRankList } = useGetDataBoardInsurePeopleCountRank({
  take: 6,
});
const newEnterOption = computed(() =>
  createNewEnterChartOptions({
    data: [newCustomerCount.value.lastMonthData, newCustomerCount.value.currentMonthData],
    xAxisData: newCustomerCount.value.x,
    name: ['上月', '本月'],
    color: ['#19DAB0', '#00A6FF'],
  })
);
const newDeclareOption = computed(() =>
  createNewDeclareChartOptions({
    data: [newBountyApplyCount.value.lastMonthData, newBountyApplyCount.value.currentMonthData],
    xAxisData: newBountyApplyCount.value.x,
    name: ['上月', '本月'],
    color: ['#00A6FF', '#FECD07'],
  })
);
const insurePersonOption = computed(() =>
  createInsurePersonOptionChartOptions({
    data: newInsurePeopleCount.value.data,
    xAxisData: newInsurePeopleCount.value.x,
    name: format(new Date(), 'YYYY-MM'),
  })
);
onMounted(() => {
  updateTime();
  timer = setInterval(updateTime, 1000);
});
// 卸载时清除定时器(避免内存泄漏)
onUnmounted(() => {
  clearInterval(timer);
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-home-wrapper {
  overflow: auto;
  min-width: 0;
  flex: 1;
  height: 100%;
}
.data-board-home {
  width: 1920px;
  height: 1080px;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-color: #182234;
  background-image: url('@/assets/dataBoard/data-board-bg.png');
  .data-board-home-title {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    padding: 0 34px;
    .data-board-home-title-text {
      display: inline-flex;
      font-size: 36px;
      line-height: 47px;
      font-family: YouSheBiaoTiHei Regular;
      background: linear-gradient(to bottom, #ffffff, #bef6ff);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    .data-board-home-title-time {
      position: absolute;
      right: 34px;
      display: inline-flex;
      font-size: 16px;
      font-family: Fontquan-XinYiGuanHeiTi Regular;
      background: linear-gradient(to bottom, #ffffff, #6fcdff);
      -webkit-background-clip: text;
      line-height: 19px;
      -webkit-text-fill-color: transparent;
    }
  }
  .data-board-home-content {
    display: flex;
    justify-content: space-between;
    padding: 30px 30px 0;
    .data-board-home-content-left {
      width: 446px;
      .new-enter {
        .new-enter-content {
          width: 100%;
          height: 280px;
        }
      }
      .new-declare {
        .new-declare-content {
          width: 100%;
          height: 250px;
        }
      }
    }
    .data-board-home-content-center {
      margin: 0 20px;
      min-width: 0;
      flex: 1;
      .data-board-home-content-center-map {
        position: relative;
        margin-bottom: 10px;
        width: 100%;
        height: 560px;
        .data-board-home-content-center-map-bg {
          position: absolute;
          top: 0;
          width: 70px;
          height: 560px;
          &.left {
            left: 0;
          }
          &.right {
            right: 0;
            transform: rotateY(180deg);
          }
        }
      }
    }
    .data-board-home-content-right {
      width: 446px;
      .insure-person {
        .insure-person-content {
          width: 100%;
          height: 250px;
        }
      }
    }
  }
  .data-board-home-footer {
    width: 100%;
    height: 46px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url('@/assets/dataBoard/data-board-footer.png');
  }
}
</style>
src/views/DataBoard/components/DataBoardCenterChart.vue
New file
@@ -0,0 +1,92 @@
<template>
  <div class="data-board-center-chart">
    <div class="data-board-center-chart-item">
      <div class="data-board-center-chart-item-title">新增发放额</div>
      <div class="data-board-center-chart-item-chart">
        <v-chart :option="newBountyReleaseAmountOption" />
      </div>
    </div>
    <div class="data-board-center-chart-item right">
      <div class="data-board-center-chart-item-title">新增使用额</div>
      <div class="data-board-center-chart-item-chart">
        <v-chart :option="newBountyUseAmountCountOption" />
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import 'echarts';
import vChart from 'vue-echarts';
import { createNewBountyReleaseAmountChartOptions } from '../utils';
import {
  useGetDataBoardNewBountyReleaseAmountCount,
  useGetDataBoardNewBountyUseAmountCount,
} from '../hooks';
defineOptions({
  name: 'DataBoardCenterChart',
});
const { detail: newBountyReleaseAmountCount } = useGetDataBoardNewBountyReleaseAmountCount();
const { detail: newBountyUseAmountCount } = useGetDataBoardNewBountyUseAmountCount();
const newBountyReleaseAmountOption = computed(() =>
  createNewBountyReleaseAmountChartOptions({
    data: [
      newBountyReleaseAmountCount.value.lastMonthData,
      newBountyReleaseAmountCount.value.currentMonthData,
    ],
    xAxisData: newBountyReleaseAmountCount.value.x,
    name: ['上月', '本月'],
    color: ['#00A6FF', '#FECD07'],
  })
);
const newBountyUseAmountCountOption = computed(() =>
  createNewBountyReleaseAmountChartOptions({
    data: [
      newBountyUseAmountCount.value.lastMonthData,
      newBountyUseAmountCount.value.currentMonthData,
    ],
    xAxisData: newBountyUseAmountCount.value.x,
    name: ['上月', '本月'],
    color: ['#00A6FF', '#FECD07'],
  })
);
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-center-chart {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  padding: 35px 20px;
  height: 292px;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url('@/assets/dataBoard/data-board-center-chart-bg.png');
  .data-board-center-chart-item {
    &.right {
      margin-left: 20px;
    }
    .data-board-center-chart-item-title {
      margin-bottom: 20px;
      font-size: 22px;
      font-family: YouSheBiaoTiHei Regular;
      text-align: center;
      background: linear-gradient(to bottom, #ffffff, #98ecff);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    .data-board-center-chart-item-chart {
      width: 100%;
      height: 200px;
    }
  }
}
</style>
src/views/DataBoard/components/DataBoardCenterDataContent.vue
New file
@@ -0,0 +1,46 @@
<template>
  <div class="data-board-home-content-center-top">
    <DataBoardCenterDataItem
      :value="detail?.currentMonthSumBountyReleaseAmount"
      label="当月发放额"
      :image="DataBoardCenterIcon1"
    ></DataBoardCenterDataItem>
    <DataBoardCenterDataItem
      :value="detail?.currentMonthSumBountyUseAmount"
      label="当月使用额"
      :image="DataBoardCenterIcon2"
    ></DataBoardCenterDataItem>
    <DataBoardCenterDataItem
      :value="detail?.currentMonthInsurePeopleCount"
      label="当月投保人数"
      :precision="0"
      :image="DataBoardCenterIcon3"
    ></DataBoardCenterDataItem>
  </div>
</template>
<script setup lang="ts">
import DataBoardCenterIcon1 from '@/assets/dataBoard/data-board-center-icon1.png';
import DataBoardCenterIcon2 from '@/assets/dataBoard/data-board-center-icon2.png';
import DataBoardCenterIcon3 from '@/assets/dataBoard/data-board-center-icon3.png';
import DataBoardCenterDataItem from './DataBoardCenterDataItem.vue';
import { useGetDataBoardOverview } from '../hooks';
defineOptions({
  name: 'DataBoardCenterDataContent',
});
const { detail } = useGetDataBoardOverview();
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-home-content-center-top {
  display: grid;
  margin-bottom: 6px;
  padding: 0 20px;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 16px;
}
</style>
src/views/DataBoard/components/DataBoardCenterDataItem.vue
New file
@@ -0,0 +1,80 @@
<template>
  <div class="data-board-center-data-item">
    <div class="data-board-data-info-item-icon">
      <img :src="image" alt="" />
    </div>
    <div class="data-board-data-info-item-content">
      <div class="data-board-data-info-item-value">
        <el-statistic :value="value" :precision="precision" />
      </div>
      <div class="data-board-data-info-item-label">{{ label }}</div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { useTransition } from '@vueuse/core';
defineOptions({
  name: 'DataBoardCenterDataItem',
});
type Props = {
  image: string;
  label: string;
  value: number;
  precision?: number;
};
const props = withDefaults(defineProps<Props>(), {
  value: 0,
  precision: 2,
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-center-data-item {
  display: flex;
  padding: 8px 12px;
  background: rgba(0, 5, 18, 0.27);
  .data-board-data-info-item-icon {
    width: 64px;
    height: 64px;
    img {
      width: 100%;
      height: 100%;
    }
  }
  .data-board-data-info-item-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    margin-left: 10px;
    .data-board-data-info-item-value {
      margin-bottom: 5px;
      font-size: 22px;
      font-family: DrukWide-Bold;
      line-height: 30px;
      :deep() {
        .el-statistic__content {
          color: #ffffff;
        }
      }
    }
    .data-board-data-info-item-label {
      font-size: 16px;
      line-height: 22px;
      color: #ffffff;
    }
  }
}
</style>
src/views/DataBoard/components/DataBoardCenterMap.vue
New file
@@ -0,0 +1,179 @@
<template>
  <div class="data-board-home-content-center-map">
    <div class="data-board-home-content-center-map-data">
      <DataBoardDataInfoItem
        :backgroundImage="DataBoardDataInfoBg5"
        label="企业数量"
        :value="form.totalCustomerCount"
      ></DataBoardDataInfoItem>
      <DataBoardDataInfoItem
        :backgroundImage="DataBoardDataInfoBg6"
        label="发放额"
        :value="form.sumBountyReleaseAmount"
      ></DataBoardDataInfoItem>
      <DataBoardDataInfoItem
        :backgroundImage="DataBoardDataInfoBg7"
        label="使用额"
        :value="form.sumBountyUseAmount"
      ></DataBoardDataInfoItem>
      <DataBoardDataInfoItem
        :backgroundImage="DataBoardDataInfoBg8"
        label="投保人数"
        :value="form.insurePeopleCount"
      ></DataBoardDataInfoItem>
    </div>
    <div class="data-board-home-content-center-map-img">
      <img class="data-board-home-content-center-map-img-bg" :src="DataBoardCenterMap" alt="" />
      <DataBoardCenterMapMark
        v-for="(item, index) in form.mapList"
        :key="index"
        v-model:choose="item.choose"
        :parkName="item.parkName"
        :class="item.class"
        @click="handleClick(item.id)"
      ></DataBoardCenterMapMark>
    </div>
  </div>
</template>
<script setup lang="ts">
import DataBoardCenterMap from '@/assets/dataBoard/data-board-center-map.png';
import DataBoardDataInfoBg5 from '@/assets/dataBoard/data-board-data-info-bg5.png';
import DataBoardDataInfoBg6 from '@/assets/dataBoard/data-board-data-info-bg6.png';
import DataBoardDataInfoBg7 from '@/assets/dataBoard/data-board-data-info-bg7.png';
import DataBoardDataInfoBg8 from '@/assets/dataBoard/data-board-data-info-bg8.png';
import DataBoardDataInfoItem from './DataBoardDataInfoItem.vue';
import DataBoardCenterMapMark from './DataBoardCenterMapMark.vue';
import { useIntervalFn } from '@vueuse/core';
import * as dataBoardServices from '@/services/api/DataBoard';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import { useIndustrialParkDropDownList } from '@/hooks';
import _ from 'lodash';
import { on } from 'events';
defineOptions({
  name: 'DataBoardCenterMap',
});
const queryClient = useQueryClient();
const { dataBoardIndustrialParkList } = useIndustrialParkDropDownList();
const form = reactive({
  industrialParkId: '',
  mapList: [],
  totalCustomerCount: 0,
  sumBountyReleaseAmount: 0,
  sumBountyUseAmount: 0,
  insurePeopleCount: 0,
});
// const { value } = useIntervalValue(12222);
function handleClick(id: string) {
  form.mapList.forEach((item, index) => {
    item.choose = item.id === id;
  });
  form.industrialParkId = id;
  refetch();
}
const { data: detail, refetch } = useQuery({
  queryKey: ['dataBoardServices/getDataBoardOverviewByPark', form.industrialParkId],
  queryFn: async () => {
    return await dataBoardServices.getDataBoardOverviewByPark(
      { industrialParkId: form.industrialParkId },
      {
        showLoading: false,
      }
    );
  },
  placeholderData: () => ({} as API.GetDataBoardOverviewByParkOutput),
  enabled: () => !!form.industrialParkId,
  onSuccess(data) {
    form.totalCustomerCount = data.totalCustomerCount;
    form.sumBountyReleaseAmount = data.sumBountyReleaseAmount;
    form.sumBountyUseAmount = data.sumBountyUseAmount;
    form.insurePeopleCount = data.insurePeopleCount;
  },
});
onMounted(async () => {
  await queryClient.invalidateQueries(['industrialParkServices/getIndustrialParkDropDownList']);
  if (dataBoardIndustrialParkList.value.length > 0) {
    form.industrialParkId = dataBoardIndustrialParkList.value[0].id;
    form.mapList = dataBoardIndustrialParkList.value;
    refetch();
  }
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-home-content-center-map {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  .data-board-home-content-center-map-data {
    position: absolute;
    top: 30px;
    left: 25px;
    width: 223px;
    .data-board-data-info-item {
      margin-bottom: 16px;
      padding: 9px 0;
      :deep() {
        .data-board-data-info-item-label {
          margin-left: 65px;
        }
        .data-board-data-info-item-value {
          margin-left: 65px;
        }
      }
    }
  }
  .data-board-home-content-center-map-img {
    position: relative;
    height: 100%;
    text-align: center;
    .data-board-home-content-center-map-img-bg {
      height: 100%;
    }
    .data-board-center-map-mark {
      position: absolute;
      cursor: pointer;
      &.init1 {
        top: 115px;
        left: 230px;
      }
      &.init2 {
        top: 260px;
        left: 75px;
      }
      &.init3 {
        top: 340px;
        right: 90px;
      }
      &.init4 {
        top: 305px;
        right: 10px;
      }
    }
  }
}
</style>
src/views/DataBoard/components/DataBoardCenterMapMark.vue
New file
@@ -0,0 +1,84 @@
<template>
  <div class="data-board-center-map-mark">
    <div class="data-board-center-map-mark-item init" v-if="!innerChoose">
      <img :src="DataBoardMapInit" alt="" />
    </div>
    <div class="data-board-center-map-mark-item choose" v-else>
      <div class="data-board-center-map-mark-item-park">{{ parkName }}</div>
      <img :src="DataBoardMapChoose" alt="" />
    </div>
  </div>
</template>
<script setup lang="ts">
import DataBoardMapInit from '@/assets/dataBoard/data-board-map-init.png';
import DataBoardMapChoose from '@/assets/dataBoard/data-board-map-choose.png';
defineOptions({
  name: 'DataBoardCenterMapMark',
});
type Props = {
  choose: boolean;
  parkName: string;
};
const props = withDefaults(defineProps<Props>(), {
  choose: false,
});
const emit = defineEmits<{
  (e: 'update:choose', value: Props['choose']): void;
}>();
const innerChoose = computed({
  get() {
    return props.choose;
  },
  set(val) {
    emit('update:choose', val);
  },
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-center-map-mark {
  .data-board-center-map-mark-item {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 154px;
    height: 104px;
    &.init {
      img {
        width: 88px;
        height: 72px;
      }
    }
    &.choose {
      position: relative;
      img {
        width: 100%;
        height: 100%;
      }
      .data-board-center-map-mark-item-park {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        font-size: 24px;
        line-height: 50px;
        font-family: YouSheBiaoTiHei Regular;
        text-align: center;
        color: #ffffff;
      }
    }
  }
}
</style>
src/views/DataBoard/components/DataBoardContentItem.vue
New file
@@ -0,0 +1,56 @@
<template>
  <div
    class="data-board-content-item"
    :style="{
      marginBottom: hasBottom ? '18px' : '0',
    }"
  >
    <div class="data-board-content-item-title">
      <div class="data-board-content-item-title-text">{{ title }}</div>
    </div>
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
defineOptions({
  name: 'DataBoardContentItem',
});
type Props = {
  title: string;
  hasBottom?: boolean;
};
const props = withDefaults(defineProps<Props>(), {
  hasBottom: true,
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-content-item {
  display: flex;
  flex-direction: column;
  background: rgba(0, 5, 18, 0.27);
  .data-board-content-item-title {
    display: flex;
    height: 42px;
    font-family: YouSheBiaoTiHei Regular;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url('@/assets/dataBoard/data-board-title-bg.png');
    .data-board-content-item-title-text {
      padding-left: 36px;
      font-size: 24px;
      line-height: 32px;
      background: linear-gradient(to bottom, #ffffff, #b5efff);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }
  }
}
</style>
src/views/DataBoard/components/DataBoardDataInfoItem.vue
New file
@@ -0,0 +1,64 @@
<template>
  <div
    class="data-board-data-info-item"
    :style="{
      backgroundImage: `url(${backgroundImage})`,
    }"
  >
    <div class="data-board-data-info-item-label">{{ label }}</div>
    <div class="data-board-data-info-item-value">
      <el-statistic :value="value" />
    </div>
  </div>
</template>
<script setup lang="ts">
import { useTransition } from '@vueuse/core';
defineOptions({
  name: 'DataBoardDataInfoItem',
});
type Props = {
  backgroundImage: string;
  label: string;
};
const props = withDefaults(defineProps<Props>(), {});
const value = defineModel<number>('value');
// const _value = useTransition(value, {
//   duration: 500,
// });
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-data-info-item {
  display: flex;
  justify-content: center;
  text-align: left;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  flex-direction: column;
  .data-board-data-info-item-label {
    margin-bottom: 4px;
    margin-left: 86px;
    font-size: 13px;
    color: #ffffff;
  }
  .data-board-data-info-item-value {
    margin-left: 86px;
    font-size: 16px;
    font-family: YouSheBiaoTiHei Regular;
    background: linear-gradient(to bottom, #ffffff, #6fcdff);
    -webkit-background-clip: text;
    line-height: 19px;
    -webkit-text-fill-color: transparent;
  }
}
</style>
src/views/DataBoard/components/DataBoardTableView.vue
New file
@@ -0,0 +1,117 @@
<template>
  <div class="data-board-table">
    <div class="data-board-table-item title">
      <div class="data-board-table-item-icon">排名</div>
      <div class="data-board-table-item-content">企业名</div>
      <div class="data-board-table-item-num">{{ customerName }}</div>
    </div>
    <div
      v-for="(item, index) in props.tableData"
      :key="index"
      class="data-board-table-item"
      :class="{ isOdd: index % 2 === 0 }"
    >
      <div class="data-board-table-item-icon">
        <img
          class="data-board-table-item-icon-img"
          v-if="index < 3"
          :src="iconList[index]"
          alt=""
        />
        <span class="data-board-table-item-icon-index" v-else>{{ index + 1 }}</span>
      </div>
      <div class="data-board-table-item-content ellipsis">{{ item.name }}</div>
      <div class="data-board-table-item-num">
        {{ `${isMoney ? toThousand(item.value) : item.value}${unit}` }}
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import DataBoardTableIcon1 from '@/assets/dataBoard/data-board-table-icon1.png';
import DataBoardTableIcon2 from '@/assets/dataBoard/data-board-table-icon2.png';
import DataBoardTableIcon3 from '@/assets/dataBoard/data-board-table-icon3.png';
import { toThousand } from '@/utils';
defineOptions({
  name: 'DataBoardTableView',
});
type Props = {
  tableData: any[];
  unit: string;
  isMoney?: boolean;
  customerName: string;
};
const props = withDefaults(defineProps<Props>(), {
  isMoney: false,
});
const iconList = [DataBoardTableIcon1, DataBoardTableIcon2, DataBoardTableIcon3];
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-board-table {
  display: flex;
  padding: 0 14px 11px;
  flex-direction: column;
  .data-board-table-item {
    display: grid;
    align-items: center;
    height: 37px;
    font-size: 14px;
    color: #ffffff;
    background-position: bottom center;
    background-repeat: no-repeat;
    background-size: 100% 2px;
    grid-template-columns: 60px 3fr 2fr;
    background-image: linear-gradient(
      to right,
      rgba(150, 150, 150, 0),
      rgb(121, 121, 121),
      rgba(150, 150, 150, 0)
    );
    &.title {
      font-size: 14px;
      color: #9d9d9d;
    }
    &.isOdd {
      background-color: #141c2f;
    }
    .data-board-table-item-icon {
      display: flex;
      justify-content: center;
      .data-board-table-item-icon-img {
        width: 24px;
        height: 28px;
      }
      .data-board-table-item-icon-index {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 34px;
        height: 16px;
        font-size: 14px;
        font-family: YouSheBiaoTiHei Regular;
        color: #ffffff;
        background-color: #3e4b68;
        transform: skewX(-30deg);
      }
    }
    .data-board-table-item-num {
      text-align: right;
    }
  }
}
</style>
src/views/DataBoard/components/DataOverviewContent.vue
New file
@@ -0,0 +1,57 @@
<template>
  <div class="data-overview-content">
    <DataBoardDataInfoItem
      :backgroundImage="DataBoardDataInfoBg1"
      label="总入驻企业"
      :value="detail?.totalCustomerCount"
    ></DataBoardDataInfoItem>
    <DataBoardDataInfoItem
      :backgroundImage="DataBoardDataInfoBg2"
      label="总申报数量"
      :value="detail?.totalBountyApplyCount"
    ></DataBoardDataInfoItem>
    <DataBoardDataInfoItem
      :backgroundImage="DataBoardDataInfoBg3"
      label="奖励金发放总额"
      :value="detail?.sumBountyReleaseAmount"
    ></DataBoardDataInfoItem>
    <DataBoardDataInfoItem
      :backgroundImage="DataBoardDataInfoBg4"
      label="奖励金使用总额"
      :value="detail?.sumBountyUseAmount"
    ></DataBoardDataInfoItem>
  </div>
</template>
<script setup lang="ts">
import DataBoardDataInfoBg1 from '@/assets/dataBoard/data-board-data-info-bg1.png';
import DataBoardDataInfoBg2 from '@/assets/dataBoard/data-board-data-info-bg2.png';
import DataBoardDataInfoBg3 from '@/assets/dataBoard/data-board-data-info-bg3.png';
import DataBoardDataInfoBg4 from '@/assets/dataBoard/data-board-data-info-bg4.png';
import DataBoardDataInfoItem from './DataBoardDataInfoItem.vue';
import { useGetDataBoardOverview } from '../hooks';
defineOptions({
  name: 'DataOverviewContent',
});
const { detail } = useGetDataBoardOverview();
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
.data-overview-content {
  display: grid;
  justify-content: center;
  align-items: center;
  padding: 50px 18px;
  grid-template-columns: repeat(2, 1fr);
  grid-column-gap: 18px;
  grid-row-gap: 30px;
  .data-board-data-info-item {
    padding: 14px 0;
  }
}
</style>
src/views/DataBoard/hooks/index.ts
New file
@@ -0,0 +1,197 @@
import { useQuery } from '@tanstack/vue-query';
import { useIntervalFn } from '@vueuse/core';
import * as dataBoardServices from '@/services/api/DataBoard';
export function useIntervalValue<T>(initValue: T) {
  const value = ref(initValue);
  const preValue = ref(initValue);
  useIntervalFn(() => {
    value.value = 0;
    setTimeout(() => {
      value.value = preValue.value;
    }, 500);
  }, 5000);
  function changeValue(_value: T) {
    value.value = _value;
    preValue.value = _value;
  }
  return { value, changeValue };
}
export function useGetDataBoardOverview() {
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardOverview'],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardOverview(
        {},
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardOverviewOutput),
  });
  return {
    detail,
  };
}
export function useGetDataBoardNewCustomerCount() {
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardNewCustomerCount'],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardNewCustomerCount(
        {},
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardNewCustomerCountOutput),
  });
  return {
    detail,
  };
}
export function useGetDataBoardNewBountyApplyCount() {
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardNewBountyApplyCount'],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardNewBountyApplyCount(
        {},
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardNewBountyApplyCountOutput),
  });
  return {
    detail,
  };
}
export function useGetDataBoardNewBountyReleaseAmountCount() {
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardNewBountyReleaseAmountCount'],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardNewBountyReleaseAmountCount(
        {},
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardNewBountyReleaseAmountCountOutput),
  });
  return {
    detail,
  };
}
export function useGetDataBoardNewBountyUseAmountCount() {
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardNewBountyUseAmountCount'],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardNewBountyUseAmountCount(
        {},
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardNewBountyUseAmountCountOutput),
  });
  return {
    detail,
  };
}
export function useGetDataBoardNewInsurePeopleCount() {
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardNewInsurePeopleCount'],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardNewInsurePeopleCount(
        {},
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardNewInsurePeopleCountOutput),
  });
  return {
    detail,
  };
}
type UseGetDataBoardBountyUseAmountRankOptions = {
  take: number;
};
export function useGetDataBoardBountyUseAmountRank(
  options: UseGetDataBoardBountyUseAmountRankOptions
) {
  const { take } = options;
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardBountyUseAmountRank', take],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardBountyUseAmountRank(
        { take: take },
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardBountyUseAmountRankOutput),
  });
  const bountyUseAmountRankList = computed(() =>
    detail.value.items?.map((x) => ({
      name: x.enterpriseName,
      value: x.amount,
    }))
  );
  return {
    bountyUseAmountRankList,
  };
}
export function useGetDataBoardInsurePeopleCountRank(
  options: UseGetDataBoardBountyUseAmountRankOptions
) {
  const { take } = options;
  const { data: detail, isLoading } = useQuery({
    queryKey: ['dataBoardServices/getDataBoardInsurePeopleCountRank', take],
    queryFn: async () => {
      return await dataBoardServices.getDataBoardInsurePeopleCountRank(
        { take: take },
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as API.GetDataBoardInsurePeopleCountRankOutput),
  });
  const insurePeopleCountRankList = computed(() =>
    detail.value.items?.map((x) => ({
      name: x.enterpriseName,
      value: x.count,
    }))
  );
  return {
    insurePeopleCountRankList,
  };
}
src/views/DataBoard/utils/index.ts
New file
@@ -0,0 +1,280 @@
import _ from 'lodash';
import { CustomSeriesOption, EChartsOption } from 'echarts';
import * as echarts from 'echarts';
export function getScreenImageUrlsByGlob() {
  const modules = import.meta.glob('@/assets/parkScreen/*.png', { eager: true });
  const imgUrls: string[] = [];
  for (const path in modules) {
    const mod = modules[path] as { default: any };
    imgUrls.push(mod.default);
  }
  return imgUrls;
}
type CreateNewEnterChartOptionsOptions = {
  data: number[][];
  xAxisData: (number | string)[];
  name: string[];
  yAxisName?: string;
  color: string[];
};
const CommonBarChartOptions: EChartsOption = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow',
    },
  },
  legend: {
    right: '5%',
    textStyle: {
      fontSize: 14,
      color: '#D4F1FF',
    },
    itemHeight: 5,
    itemWidth: 12,
  },
  xAxis: {
    type: 'category',
    nameTextStyle: {
      color: '#D4F1FF',
      fontSize: 12,
    },
    axisTick: {
      show: false,
    },
    axisLabel: {
      fontSize: 12,
      color: '#D4F1FF',
    },
  },
  yAxis: {
    nameTextStyle: {
      color: '#D4F1FF',
      fontSize: 12,
    },
    axisLabel: {
      fontSize: 12,
      color: '#D4F1FF',
    },
    splitLine: {
      show: true,
      lineStyle: {
        color: '#384658',
      },
    },
  },
  series: [],
};
export function createNewEnterChartOptions({
  data,
  xAxisData,
  name,
  yAxisName = '单位/个',
  color,
}: CreateNewEnterChartOptionsOptions) {
  return _.merge({}, CommonBarChartOptions, {
    xAxis: {
      data: xAxisData,
    },
    yAxis: {
      name: yAxisName,
    },
    series: data.map((x, index) => ({
      name: name[index],
      type: 'bar',
      data: x?.map((y) => ({
        value: y,
      })),
      itemStyle: {
        color: color[index],
      },
      barWidth: '15%',
    })),
  } as EChartsOption);
}
export function createNewDeclareChartOptions({
  data,
  xAxisData,
  name,
  yAxisName = '单位/个',
  color,
}: CreateNewEnterChartOptionsOptions) {
  return _.merge({}, CommonBarChartOptions, {
    xAxis: {
      data: xAxisData,
    },
    yAxis: {
      name: yAxisName,
    },
    series: data.map((x, index) => ({
      name: name[index],
      type: 'bar',
      data: x?.map((y) => ({
        value: y,
      })),
      label: {
        show: true,
        position: 'top',
        distance: 0,
        formatter: '...',
        fontSize: 16,
        color: color[index],
      },
      itemStyle: {
        color: color[index],
        opacity: 0.6,
      },
      barWidth: 14,
    })),
  } as EChartsOption);
}
type CreatInsurePersonChartOptionsOptions = {
  data: number[];
  xAxisData: (number | string)[];
  name: string;
  yAxisName?: string;
};
export function createInsurePersonOptionChartOptions({
  data,
  xAxisData,
  name,
  yAxisName = '单位/个',
}: CreatInsurePersonChartOptionsOptions) {
  return {
    legend: {
      right: '5%',
      textStyle: {
        fontSize: 14,
        color: '#D4F1FF',
      },
      itemHeight: 0,
      itemWidth: 0,
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985',
        },
      },
    },
    xAxis: {
      nameTextStyle: {
        color: '#D4F1FF',
        fontSize: 12,
      },
      axisTick: {
        show: false,
      },
      axisLabel: {
        fontSize: 12,
        color: '#D4F1FF',
      },
      data: xAxisData,
    },
    yAxis: {
      axisLabel: {
        fontSize: 12,
        color: '#D4F1FF',
      },
      nameTextStyle: {
        color: '#D4F1FF',
        fontSize: 12,
      },
      name: yAxisName,
      splitLine: {
        show: true,
        lineStyle: {
          color: '#384658',
        },
      },
    },
    series: {
      name: name,
      type: 'line',
      data: data,
      areaStyle: {
        color: new echarts.graphic.LinearGradient(
          0,
          0,
          0,
          1, // 渐变方向:0,0(右上)→ 0,1(右下)(垂直向下)
          [
            { offset: 0, color: `rgba(0, 166, 255, 0.2)` }, // 折线处颜色(不透明)
            { offset: 1, color: 'rgba(64, 158, 255, 0)' }, // X轴处颜色(完全透明)
          ]
        ),
      },
    },
  };
}
export function createNewBountyReleaseAmountChartOptions({
  data,
  xAxisData,
  name,
  yAxisName = '单位/个',
  color,
}: CreateNewEnterChartOptionsOptions) {
  return _.merge({}, CommonBarChartOptions, {
    xAxis: {
      data: xAxisData,
      boundaryGap: false,
    },
    yAxis: {
      name: yAxisName,
    },
    legend: {
      itemWidth: 12,
      itemHeight: 5,
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985',
        },
      },
    },
    series: data.map((x, index) => ({
      name: name[index],
      type: 'line',
      data: x?.map((y) => ({
        value: y,
      })),
      smooth: true,
      lineStyle: {
        width: 1,
        color: color[index], // 折线颜色
      },
      itemStyle: {
        opacity: 0,
      },
      showSymbol: false,
      areaStyle: {
        color: new echarts.graphic.LinearGradient(
          0,
          0,
          0,
          1, // 渐变方向:0,0(右上)→ 0,1(右下)(垂直向下)
          [
            { offset: 0, color: `${color[index]}` }, // 折线处颜色(不透明)
            { offset: 0.5, color: 'rgba(64, 158, 255, 0)' }, // X轴处颜色(完全透明)
          ]
        ),
      },
    })),
  } as EChartsOption);
}