Procházet zdrojové kódy

feat: 统计报表-指定时间段内系统使用情况统计

zhangying před 10 měsíci
rodič
revize
0dad829c0d

+ 6 - 0
doc/待更新脚本

@@ -0,0 +1,6 @@
+-- 2024-5-23 添加系统使用情况统计菜单与权限编码
+INSERT INTO sys_function_code VALUES ('T010502', '系统使用情况统计', 'T0105', 2);
+INSERT INTO `sys_menu` VALUES ('T010502', 2, '系统使用情况统计', NULL, 'views/statistics/SystemApplyCount', '/systemApplyCount', 'T0105', NULL, 0, 1, 1, 'T010502', 1, NULL);
+-- 2024-5-23 为系统管理员添加统使用情况统计权限
+insert into sys_role_sys_function_code (`RoleID`, `FunctionCode`) values('20afde90-a81a-11ed-a6c5-7085c2a9999e','T0105');
+insert into sys_role_sys_function_code (`RoleID`, `FunctionCode`) values('20afde90-a81a-11ed-a6c5-7085c2a9999e','T010502');

+ 35 - 0
src/main/java/com/hz/employmentsite/controller/statistics/StatisticsController.java

@@ -0,0 +1,35 @@
+package com.hz.employmentsite.controller.statistics;
+
+import com.hz.employmentsite.filter.exception.BaseResponse;
+import com.hz.employmentsite.filter.exception.RespGenerstor;
+import com.hz.employmentsite.services.service.statistics.StatisticsService;
+import com.hz.employmentsite.vo.statistics.SystemDataCount;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/api/statistics")
+public class StatisticsController {
+    @Autowired
+    private StatisticsService statisticsService;
+
+    /**
+     * 查询指定时间段系统使用情况
+     *
+     * @param startDate 开始时间
+     * @param endDate   结束时间
+     * @return 数据统计VO类集合
+     */
+    @GetMapping("/systemApplyCount")
+    public BaseResponse getSystemApplyCount(@RequestParam(value = "startDate", required = false) Date startDate,
+                                            @RequestParam(value = "endDate", required = false) Date endDate) {
+        List<SystemDataCount> systemDataCount = statisticsService.findSystemDataCount(startDate, endDate);
+        return RespGenerstor.success(systemDataCount);
+    }
+}

+ 18 - 0
src/main/java/com/hz/employmentsite/mapper/cquery/StatisticsCQuery.java

@@ -0,0 +1,18 @@
+package com.hz.employmentsite.mapper.cquery;
+
+import com.hz.employmentsite.vo.statistics.SystemDataCount;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+public interface StatisticsCQuery {
+    /**
+     * 查询指定时间段系统使用情况
+     *
+     * @param startDate 开始时间
+     * @param endDate   结束时间
+     * @return 数据统计VO类集合
+     */
+    List<SystemDataCount> findSystemDataCount(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
+}

+ 29 - 0
src/main/java/com/hz/employmentsite/services/impl/statistics/StatisticsServiceImpl.java

@@ -0,0 +1,29 @@
+package com.hz.employmentsite.services.impl.statistics;
+
+import com.hz.employmentsite.mapper.cquery.StatisticsCQuery;
+import com.hz.employmentsite.services.service.statistics.StatisticsService;
+import com.hz.employmentsite.vo.statistics.SystemDataCount;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+
+@Service("StatisticsService")
+public class StatisticsServiceImpl implements StatisticsService {
+
+    @Autowired
+    private StatisticsCQuery statisticsCQuery;
+
+    /**
+     * 查询指定时间段系统使用情况
+     *
+     * @param startDate 开始时间
+     * @param endDate   结束时间
+     * @return 数据统计VO类集合
+     */
+    @Override
+    public List<SystemDataCount> findSystemDataCount(Date startDate, Date endDate) {
+        return statisticsCQuery.findSystemDataCount(startDate, endDate);
+    }
+}

+ 17 - 0
src/main/java/com/hz/employmentsite/services/service/statistics/StatisticsService.java

@@ -0,0 +1,17 @@
+package com.hz.employmentsite.services.service.statistics;
+
+import com.hz.employmentsite.vo.statistics.SystemDataCount;
+
+import java.util.Date;
+import java.util.List;
+
+public interface StatisticsService {
+    /**
+     * 查询指定时间段系统使用情况
+     *
+     * @param startDate 开始时间
+     * @param endDate   结束时间
+     * @return 数据统计VO类集合
+     */
+    List<SystemDataCount> findSystemDataCount(Date startDate, Date endDate);
+}

+ 25 - 0
src/main/java/com/hz/employmentsite/vo/statistics/SystemDataCount.java

@@ -0,0 +1,25 @@
+package com.hz.employmentsite.vo.statistics;
+
+import lombok.Data;
+
+/**
+ * 系统使用情况统计VO
+ */
+@Data
+public class SystemDataCount {
+    private String siteID;
+
+    private String siteName;
+
+    private String regionCode;
+
+    private String regionName;
+
+    private Integer siteUserCount;
+
+    private Integer companyCount;
+
+    private Integer postCount;
+
+    private Integer jobUserCount;
+}

+ 63 - 0
src/main/resources/mapping/cquery/StatisticsCQuery.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.hz.employmentsite.mapper.cquery.StatisticsCQuery">
+    <select id="findSystemDataCount" resultType="com.hz.employmentsite.vo.statistics.SystemDataCount">
+        SELECT
+        site.SiteID,
+        site.RegionCode,
+        site.SiteName,
+        area.`name` AS regionName,
+        -- 驿站人员数量
+        ( SELECT COUNT( 1 ) FROM pc_site_user WHERE SiteID = site.SiteID ) AS siteUserCount,
+        -- 指定时间段的登记企业数量
+        (
+        SELECT
+        COUNT( 1 )
+        FROM
+        pc_company
+        WHERE
+        SiteID = site.SiteID
+        <if test="startDate != null">
+            and CreateTime <![CDATA[ >= ]]> #{startDate}
+        </if>
+        <if test="endDate != null ">
+            and CreateTime <![CDATA[ <= ]]> #{endDate}
+        </if>
+        ) AS companyCount,
+        -- 指定时间段的登记岗位数量
+        (
+        SELECT
+        COUNT( 1 )
+        FROM
+        pc_post post
+        WHERE
+        CompanyID IN ( SELECT company.CompanyID FROM pc_company company WHERE company.SiteID = site.SiteID )
+        <if test="startDate != null">
+            and CreateTime <![CDATA[ >= ]]> #{startDate}
+        </if>
+        <if test="endDate != null ">
+            and CreateTime <![CDATA[ <= ]]> #{endDate}
+        </if>
+        ) AS postCount,
+        -- 指定时间段的登记求职人员数量
+        (
+        SELECT
+        COUNT( 1 )
+        FROM
+        pc_jobuser
+        WHERE
+        SiteID = site.SiteID
+        <if test="startDate != null">
+            and CreateTime <![CDATA[ >= ]]> #{startDate}
+        </if>
+        <if test="endDate != null ">
+            and CreateTime <![CDATA[ <= ]]> #{endDate}
+        </if>
+        ) AS jobUserCount
+        FROM
+        pc_site site
+        LEFT JOIN area_code area ON site.RegionCode = area.`code`
+        ORDER BY
+        site.RegionCode
+    </select>
+</mapper>

+ 18 - 0
vue/src/api/statistics/index.ts

@@ -0,0 +1,18 @@
+import {request} from "@/utils/request";
+
+/**
+ * 查询指定时间段系统使用情况
+ * @param params 查询参数
+ */
+export function getSystemApplyCount(params: any) {
+  return request<object>(
+    {
+      url: 'statistics/systemApplyCount',
+      method: 'get',
+      params: params,
+    },
+    {
+      isNew: true,
+    },
+  );
+}

+ 3 - 0
vue/src/router/asyncModules/statistics.ts

@@ -0,0 +1,3 @@
+export default {
+  'views/statistics/SystemApplyCount': () => import('@/views/statistics/SystemApplyCount.vue'),
+};

+ 210 - 0
vue/src/views/statistics/SystemApplyCount.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="card-search">
+    <a-form
+      ref="formRef"
+      name="advanced_search"
+      class="ant-advanced-search-form"
+      :model="searchParams"
+    >
+      <a-row :gutter="24">
+        <a-col :span="6">
+          <a-form-item label="统计日期" :label-col="{span:6}" name="reportDate">
+            <a-range-picker format="YYYY-MM-DD" :placeholder="['开始日期', '结束日期']"
+                            @change="onRangeChange"/>
+          </a-form-item>
+        </a-col>
+        <a-col :span="6" style="text-align: left">
+          <a-button type="primary" html-type="submit" @click="loadData">查询</a-button>
+          <a-button style="margin: 0 8px" @click="onReset">重置</a-button>
+        </a-col>
+      </a-row>
+    </a-form>
+    <div class="search-result-list">
+      <a-table :columns="originalColumns" :data-source="systemApplyCount" :scroll="{ x:'100%' }"
+               :loading="tableLoading"
+               :pagination="false"
+               bordered>
+        <template #bodyCell="{ column, text, record }">
+          <template v-if="column.key == 'regionName'">
+            <div>
+              {{ record.regionName }}
+            </div>
+          </template>
+          <template v-if="column.key == 'siteName'">
+            <div>
+              {{ record.siteName }}
+            </div>
+          </template>
+          <template v-if="column.key == 'siteUserCount'">
+            <div>
+              {{ record.siteUserCount }}
+            </div>
+          </template>
+          <template v-if="column.key == 'companyCount'">
+            <div>
+              {{ record.companyCount }}
+            </div>
+          </template>
+          <template v-if="column.key == 'postCount'">
+            <div>
+              {{ record.postCount }}
+            </div>
+          </template>
+          <template v-if="column.key == 'jobUserCount'">
+            <div>
+              {{ record.jobUserCount }}
+            </div>
+          </template>
+        </template>
+      </a-table>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import {onMounted, reactive, ref} from "vue";
+import {getSystemApplyCount} from "@/api/statistics";
+import type {FormInstance, TableColumnType} from "ant-design-vue";
+import dayjs from "dayjs";
+
+const formRef = ref<FormInstance>();
+
+const originalColumns: TableColumnType[] = [
+  {
+    title: '行政区划', dataIndex: 'regionName', key: 'regionName', align: "center", width: 250,
+    customCell: (record, index: any) => {
+      const obj = {
+        colSpan: 1,
+        rowSpan: 1,
+      };
+      if (record.regionName == '合计') {
+        obj.colSpan = 2;
+      }
+      if (index === 0 || record.regionName !== systemApplyCount.value[index - 1].regionName) {
+        for (let i = index + 1; i < systemApplyCount.value.length; i++) {
+          if (systemApplyCount.value[i].regionName == record.regionName) {
+            obj.rowSpan++;
+          } else {
+            break;
+          }
+        }
+      } else {
+        obj.rowSpan = 0;
+      }
+      return obj;
+    },
+  },
+  {
+    title: '驿站名', dataIndex: 'siteName', key: 'siteName', align: "center", width: 250,
+    customCell: (record) => {
+      const obj = {
+        colSpan: 1,
+      };
+      if (record.siteName == '合计') {
+        obj.colSpan = 0;
+      }
+      return obj;
+    },
+  },
+  {title: '驿站人员数量', dataIndex: 'siteUserCount', key: 'siteUserCount', align: "center"},
+  {title: '录入企业数量', dataIndex: 'companyCount', key: 'companyCount', align: "center"},
+  {title: '收集岗位数量', dataIndex: 'postCount', key: 'postCount', align: "center"},
+  {title: '登记求职人数', dataIndex: 'jobUserCount', key: 'jobUserCount', align: "center"},
+]
+
+// 统计数据
+const systemApplyCount = ref<Array<any>>([]);
+// 查询条件
+const searchParams = reactive({
+  startDate: "",
+  endDate: ""
+})
+// 表格加载
+const tableLoading = ref(false);
+// const reportDate = ref();
+
+// 数据加载
+function loadData() {
+  tableLoading.value = true;
+  getSystemApplyCount(searchParams).then((result: any) => {
+    systemApplyCount.value = result;
+    // 计算合计数据
+    let total = result.reduce((acc, item) => {
+      acc.siteUserCount += item.siteUserCount || 0;
+      acc.companyCount += item.companyCount || 0;
+      acc.postCount += item.postCount || 0;
+      acc.jobUserCount += item.jobUserCount || 0;
+      return acc;
+    }, {siteUserCount: 0, companyCount: 0, postCount: 0, jobUserCount: 0});
+    total.siteName = "合计"
+    total.regionName = "合计"
+    systemApplyCount.value.unshift(total);
+
+    // 为每个县区计算小计
+    let regionMap = new Map();
+    result.forEach((item: any) => {
+      if (item.regionName !== '合计') {
+        if (!regionMap.has(item.regionCode)) {
+          regionMap.set(item.regionCode, {
+            regionCode: item.regionCode,
+            regionName: item.regionName,
+            siteName: "小计",
+            siteUserCount: 0,
+            companyCount: 0,
+            postCount: 0,
+            jobUserCount: 0
+          });
+        }
+        let regionTotal = regionMap.get(item.regionCode);
+        regionTotal.siteUserCount += item.siteUserCount || 0;
+        regionTotal.companyCount += item.companyCount || 0;
+        regionTotal.postCount += item.postCount || 0;
+        regionTotal.jobUserCount += item.jobUserCount || 0;
+      }
+    });
+
+    // 将统计结果插入到相同regionCode的第一个位置
+    let arr = new Array<any>();
+    systemApplyCount.value.forEach(item => {
+      if (regionMap.has(item.regionCode)) {
+        arr.push(regionMap.get(item.regionCode));
+        regionMap.delete(item.regionCode);
+      }
+      arr.push(item);
+    });
+    systemApplyCount.value = arr;
+  }).finally(() => {
+    tableLoading.value = false;
+  })
+}
+
+// 时间段变更事件
+const onRangeChange = (dateString: [string, string]) => {
+  searchParams.startDate = dateString != null ? dayjs(dateString[0]).format("YYYY-MM-DD") : "";
+  searchParams.endDate = dateString != null ? dayjs(dateString[1]).format("YYYY-MM-DD") : "";
+};
+
+// 查询表单
+function onReset() {
+  formRef.value?.resetFields();
+  loadData()
+}
+
+// 页面初始化
+onMounted(() => {
+  loadData()
+})
+</script>
+
+<script lang="ts">
+// 设置页面名称进行组件缓存
+export default {
+  name: "SystemApplyDataCount",
+}
+</script>
+
+<style lang="less">
+.totalCol {
+  background-color: #40a9ff !important;
+}
+</style>