Browse Source

feat: 系统月度使用情况表格形式展示完成

zhangying 10 months ago
parent
commit
ccb0fbd971

+ 4 - 0
doc/待更新脚本.txt

@@ -0,0 +1,4 @@
+-- 2024-6-13 系统月度使用情况统计菜单与权限数据
+INSERT INTO sys_function_code VALUES ('T010503', '系统月度使用情况统计', 'T0105', 3);
+INSERT INTO `sys_menu` VALUES ('T010503', 3, '系统月度使用情况统计', NULL, 'views/statistics/MonthSystemApplyCount', '/siteDataMap', 'T0105', NULL, 0, 1, 1, 'T010503', 1, NULL,NULL);
+insert into sys_role_sys_function_code (`RoleID`, `FunctionCode`) values('20afde90-a81a-11ed-a6c5-7085c2a9999e','T010503');

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

@@ -5,6 +5,7 @@ import com.hz.employmentsite.filter.exception.RespGenerstor;
 import com.hz.employmentsite.services.service.statistics.StatisticsService;
 import com.hz.employmentsite.util.DateUtils;
 import com.hz.employmentsite.util.ExcelHelper;
+import com.hz.employmentsite.vo.statistics.RegionSystemDataCount;
 import com.hz.employmentsite.vo.statistics.SystemDataCount;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -42,6 +43,12 @@ public class StatisticsController {
         return RespGenerstor.success(systemDataCount);
     }
 
+    @GetMapping("/monthSystemApplyCount")
+    public BaseResponse findMonthSystemDataCount(@RequestParam String dateStr){
+        Map<String, List<RegionSystemDataCount>> result = statisticsService.findMonthSystemDataCount(dateStr);
+        return RespGenerstor.success(result);
+    }
+
     /**
      * 导出指定时间段的系统使用情况
      *

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

@@ -1,10 +1,13 @@
 package com.hz.employmentsite.mapper.cquery;
 
+import com.hz.employmentsite.vo.statistics.RegionSystemDataCount;
 import com.hz.employmentsite.vo.statistics.SystemDataCount;
 import org.apache.ibatis.annotations.Param;
 
+import java.time.LocalDate;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 public interface StatisticsCQuery {
     /**
@@ -15,4 +18,17 @@ public interface StatisticsCQuery {
      * @return 数据统计VO类集合
      */
     List<SystemDataCount> findSystemDataCount(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+    /**
+     * 查询指定一周的系统使用情况
+     * @param startDate 开始时间
+     * @param endDate 结束时间
+     * @return 系统使用情况统计数量
+     */
+    List<RegionSystemDataCount> findWeekSystemDataCount(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
+
+    /**
+     * 查询各区县的驿站工作人员合计数量
+     */
+    List<Map<String, Object>> findRegionSiteUserCount();
 }

+ 89 - 4
src/main/java/com/hz/employmentsite/services/impl/statistics/StatisticsServiceImpl.java

@@ -2,14 +2,14 @@ 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.util.DateUtils;
+import com.hz.employmentsite.vo.statistics.RegionSystemDataCount;
 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.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.time.LocalDate;
+import java.util.*;
 
 @Service("StatisticsService")
 public class StatisticsServiceImpl implements StatisticsService {
@@ -17,6 +17,9 @@ public class StatisticsServiceImpl implements StatisticsService {
     @Autowired
     private StatisticsCQuery statisticsCQuery;
 
+    @Autowired
+    private DateUtils dateUtils;
+
     /**
      * 查询指定时间段系统使用情况
      *
@@ -71,4 +74,86 @@ public class StatisticsServiceImpl implements StatisticsService {
 
         return list;
     }
+
+    /**
+     * 查询指定月份的系统使用情况统计
+     *
+     * @param dateStr 月份日期
+     * @return
+     */
+    @Override
+    public Map<String, List<RegionSystemDataCount>> findMonthSystemDataCount(String dateStr) {
+        // 各区县的驿站工作人员统计数量
+        List<Map<String, Object>> regionSiteUserCount = statisticsCQuery.findRegionSiteUserCount();
+
+        // 解析日期,获取每周的开始结束时间
+        List<Map<String, LocalDate>> weekDate = dateUtils.getWeekDateByMonth(dateStr);
+
+        Map<String, List<RegionSystemDataCount>> result = new LinkedHashMap<>();
+        // 汇总数据
+        List<RegionSystemDataCount> sumData = new ArrayList<>();
+        // 创建一个 map 来存储 regionCode 和 siteUserCount 的对应关系
+        Map<String, Integer> siteUserCountMap = new HashMap<>();
+        for (Map<String, Object> objectMap : regionSiteUserCount) {
+            String regionCode = (String) objectMap.get("code");
+            String regionName = (String) objectMap.get("name");
+            int siteUserCount = ((Long) objectMap.get("siteUserCount")).intValue();
+            siteUserCountMap.put(regionCode, siteUserCount);
+            // 计算合计数量
+            RegionSystemDataCount summaryData = new RegionSystemDataCount(regionCode, regionName, siteUserCount, 0, 0, 0);
+            sumData.add(summaryData);
+        }
+        // 按每周的日期进行系统使用数据查询
+        for (int i = 0; i < weekDate.size(); i++) {
+            // 获取当前周的开始日期和结束日期
+            LocalDate startDate = weekDate.get(i).get("startDate");
+            LocalDate endDate = weekDate.get(i).get("endDate");
+
+            // 查询当前周的系统使用数据
+            List<RegionSystemDataCount> contData = statisticsCQuery.findWeekSystemDataCount(startDate, endDate);
+
+            // 创建合计数据
+            RegionSystemDataCount summaryData = new RegionSystemDataCount("100", "合计", 0, 0, 0, 0);
+
+            // 填充驿站工作人员统计数量
+            for (RegionSystemDataCount dataCount : contData) {
+                String regionCode = dataCount.getRegionCode();
+                if (siteUserCountMap.containsKey(regionCode)) {
+                    dataCount.setSiteUserCount(siteUserCountMap.get(regionCode));
+                }
+                // 合计数据累加
+                summaryData.setSiteUserCount(summaryData.getSiteUserCount() + dataCount.getSiteUserCount());
+                summaryData.setCompanyCount(summaryData.getCompanyCount() + dataCount.getCompanyCount());
+                summaryData.setPostCount(summaryData.getPostCount() + dataCount.getPostCount());
+                summaryData.setJobUserCount(summaryData.getJobUserCount() + dataCount.getJobUserCount());
+
+                // 将各个区县的数据累加到汇总
+                for (RegionSystemDataCount sumDatum : sumData) {
+                    if (sumDatum.getRegionCode().equals(dataCount.getRegionCode())) {
+                        sumDatum.setSiteUserCount(dataCount.getSiteUserCount());
+                        sumDatum.setCompanyCount(sumDatum.getCompanyCount() + dataCount.getCompanyCount());
+                        sumDatum.setPostCount(sumDatum.getPostCount() + dataCount.getPostCount());
+                        sumDatum.setJobUserCount(sumDatum.getJobUserCount() + dataCount.getJobUserCount());
+                    }
+                }
+            }
+            // 将汇总对象添加到结果中
+            contData.add(summaryData);
+
+            // 保存结果
+            result.put("第" + (i + 1) + "周", contData);
+        }
+        // 计算汇总的合计
+        RegionSystemDataCount summaryData = new RegionSystemDataCount("100", "合计", 0, 0, 0, 0);
+        for (RegionSystemDataCount sumDatum : sumData) {
+            summaryData.setSiteUserCount(summaryData.getSiteUserCount() + sumDatum.getSiteUserCount());
+            summaryData.setCompanyCount(summaryData.getCompanyCount() + sumDatum.getCompanyCount());
+            summaryData.setPostCount(summaryData.getPostCount() + sumDatum.getPostCount());
+            summaryData.setJobUserCount(summaryData.getJobUserCount() + sumDatum.getJobUserCount());
+        }
+        sumData.add(summaryData);
+        result.put("汇总", sumData);
+
+        return result;
+    }
 }

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

@@ -1,9 +1,11 @@
 package com.hz.employmentsite.services.service.statistics;
 
+import com.hz.employmentsite.vo.statistics.RegionSystemDataCount;
 import com.hz.employmentsite.vo.statistics.SystemDataCount;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 public interface StatisticsService {
     /**
@@ -14,4 +16,11 @@ public interface StatisticsService {
      * @return 数据统计VO类集合
      */
     List<SystemDataCount> findSystemDataCount(Date startDate, Date endDate);
+
+    /**
+     * 查询指定月份的系统使用情况统计
+     * @param dateStr 月份日期
+     * @return
+     */
+    Map<String, List<RegionSystemDataCount>> findMonthSystemDataCount(String dateStr);
 }

+ 53 - 3
src/main/java/com/hz/employmentsite/util/DateUtils.java

@@ -5,9 +5,7 @@ import org.springframework.stereotype.Component;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.*;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
+import java.util.*;
 
 @Component
 public class DateUtils {
@@ -463,4 +461,56 @@ public class DateUtils {
         }
         return 0;
     }
+
+    /**
+     * 根据给定日期字符串获取该月的每周起始日期和结束日期的列表
+     * @param dateStr 指定的月份日期
+     * @return 当月的每周的起始日期与结束日期
+     */
+    public List<Map<String, LocalDate>> getWeekDateByMonth(String dateStr){
+        // 解析年份和月份
+        String[] parts = dateStr.split("-");
+        int year = Integer.parseInt(parts[0]);
+        int month = Integer.parseInt(parts[1]);
+
+        // 构建年月对象和该月的第一天和最后一天
+        YearMonth yearMonth = YearMonth.of(year, month);
+        LocalDate firstDayOfMonth = yearMonth.atDay(1);
+        LocalDate lastDayOfMonth = yearMonth.atEndOfMonth();
+
+        // 初始化周列表
+        List<Map<String, LocalDate>> weeks = new ArrayList<>();
+
+        // 计算第一个完整周的起始和结束日期
+        LocalDate startOfWeek = firstDayOfMonth.with(DayOfWeek.MONDAY);
+        if (startOfWeek.isAfter(firstDayOfMonth)) {
+            startOfWeek = startOfWeek.minusWeeks(1);
+        }
+        LocalDate endOfWeek = startOfWeek.with(DayOfWeek.SUNDAY);
+        if (endOfWeek.isBefore(firstDayOfMonth)) {
+            endOfWeek = firstDayOfMonth;
+        }
+
+        // 遍历每个完整的周,直到最后一个完整周
+        while (endOfWeek.isBefore(lastDayOfMonth)) {
+            // 构建当前周的起始日期和结束日期的Map
+            Map<String, LocalDate> week = new HashMap<>();
+            week.put("startDate", startOfWeek.isBefore(firstDayOfMonth) ? firstDayOfMonth : startOfWeek);
+            week.put("endDate", endOfWeek);
+            weeks.add(week);
+
+            // 移动到下一周
+            startOfWeek = startOfWeek.plusWeeks(1);
+            endOfWeek = endOfWeek.plusWeeks(1);
+        }
+
+        // 处理最后一个周,可能不是完整的一周
+        Map<String, LocalDate> lastWeek = new HashMap<>();
+        lastWeek.put("startDate", startOfWeek);
+        lastWeek.put("endDate", lastDayOfMonth);
+        weeks.add(lastWeek);
+
+        return weeks;
+    }
+
 }

+ 22 - 0
src/main/java/com/hz/employmentsite/vo/statistics/RegionSystemDataCount.java

@@ -0,0 +1,22 @@
+package com.hz.employmentsite.vo.statistics;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class RegionSystemDataCount {
+    private String regionCode;
+
+    private String regionName;
+
+    private int siteUserCount;
+
+    private int companyCount;
+
+    private int postCount;
+
+    private int jobUserCount;
+}

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

@@ -68,4 +68,84 @@
         LEFT JOIN area_code area ON site.RegionCode = area.`code`
         ORDER BY site.RegionCode
     </select>
+
+    <select id="findWeekSystemDataCount" resultType="com.hz.employmentsite.vo.statistics.RegionSystemDataCount">
+        SELECT
+            subquery.RegionCode,
+            area.`name` AS regionName,
+            SUM(subquery.companyCount) AS companyCount,
+            SUM(subquery.postCount) AS postCount,
+            SUM(subquery.jobUserCount) AS jobUserCount
+        FROM
+            (
+                SELECT
+                    site.SiteID,
+                    site.RegionCode,
+                    -- 指定时间段的登记企业数量
+                    (
+                        SELECT COUNT(1)
+                        FROM pc_company
+                        WHERE
+                            SiteID = site.SiteID
+                        <if test="startDate != null">
+                            and DATE(CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+                        </if>
+                        <if test="endDate != null ">
+                            and DATE(CreateTime) <![CDATA[ <= ]]> DATE(#{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 DATE(CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+                        </if>
+                        <if test="endDate != null ">
+                            and DATE(CreateTime) <![CDATA[ <= ]]> DATE(#{endDate})
+                        </if>
+                    ) AS postCount,
+                    -- 指定时间段的登记求职人员数量
+                    (
+                        SELECT COUNT(1)
+                        FROM pc_jobuser
+                        WHERE
+                            SiteID = site.SiteID
+                        <if test="startDate != null">
+                            and DATE(CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+                        </if>
+                        <if test="endDate != null ">
+                            and DATE(CreateTime) <![CDATA[ <= ]]> DATE(#{endDate})
+                        </if>
+                    ) AS jobUserCount
+                FROM
+                    pc_site site
+            ) AS subquery
+                LEFT JOIN area_code area ON subquery.RegionCode = area.`code`
+        GROUP BY
+            subquery.RegionCode, area.`name`
+        ORDER BY
+            subquery.RegionCode;
+    </select>
+
+    <select id="findRegionSiteUserCount" resultType="Map">
+        SELECT
+            area.`code`,
+            area.`name`,
+            COUNT( sysUser.UserID ) AS siteUserCount
+        FROM
+            area_code area
+                LEFT JOIN pc_site site ON site.RegionCode = area.`code`
+                LEFT JOIN pc_site_user siteUser ON site.SiteID = siteUser.SiteID
+                LEFT JOIN sys_user sysUser ON siteUser.UserID = sysUser.UserID AND sysUser.RecordStatus = 1
+        WHERE
+            area.lv = 3
+        GROUP BY
+            area.`code`,
+            area.`name`
+        ORDER BY
+            area.`code`
+    </select>
 </mapper>

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

@@ -16,3 +16,20 @@ export function getSystemApplyCount(params: any) {
     },
   );
 }
+
+/**
+ * 查询月度系统使用情况
+ * @param params 查询参数
+ */
+export function getMonthSystemDataCount(params: any) {
+  return request<object>(
+    {
+      url: 'statistics/monthSystemApplyCount',
+      method: 'get',
+      params: params,
+    },
+    {
+      isNew: true,
+    },
+  );
+}

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

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

+ 205 - 0
vue/src/views/statistics/MonthSystemApplyCount.vue

@@ -0,0 +1,205 @@
+<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-date-picker format="YYYY-MM" picker="month" v-model:value="pickerDate" :allow-clear="false"
+                           @change="pickerDateChange"/>
+          </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>
+    <!-- 操作按钮 -->
+    <a-row class="edit-operation" style="margin-bottom: 20px">
+      <a-col :span="24" class="flex-space-between">
+        <div>
+          <a-radio-group v-model:value="dataType" button-style="solid">
+            <a-radio-button value="table">表格</a-radio-button>
+            <a-radio-button value="imageTable">图表</a-radio-button>
+          </a-radio-group>
+        </div>
+        <div>
+          <BExportExcel :filename="'系统使用情况统计'"
+                        :params="{...exportSearchParams}"
+                        :title="'导出'"
+                        :url="'statistics/export/systemApplyCount'"></BExportExcel>
+        </div>
+      </a-col>
+    </a-row>
+    <!-- 数据展示 -->
+    <div v-show="dataType == 'table'">
+      <a-table :columns="originalColumns" :data-source="systemApplyCount" :scroll="{ x:'1300' }"
+               :loading="tableLoading"
+               :pagination="false"
+               bordered>
+      </a-table>
+    </div>
+    <div v-show="dataType == 'imageTable'">
+
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import {computed, onMounted, reactive, ref} from "vue";
+import {getMonthSystemDataCount} from "@/api/statistics";
+import dayjs from "dayjs";
+import BExportExcel from "@/components/basic/excel/exportExcel/exportExcel.vue";
+
+// 查询条件
+const searchParams = reactive({
+  dateStr: "",
+})
+// 导出Excel查询参数
+const exportSearchParams = computed(() => {
+  return JSON.parse(JSON.stringify(searchParams));
+})
+const pickerDate = ref<any>(dayjs());
+// 表格加载
+const tableLoading = ref(false);
+// 展示类型切换
+const dataType = ref("table");
+// 统计数据
+const systemApplyCount = ref<Array<any>>([]);
+// 表格定义
+const originalColumns = ref<Array<any>>([
+  {
+    title: '项目', dataIndex: 'regionName', key: 'regionName', align: "center", width: 200, fixed: 'left'
+  },
+  {
+    title: '第一周',
+    children: [
+      {title: '驿站人员数量', dataIndex: 'siteUserCount', key: 'siteUserCount', width: 120, align: "center"},
+      {title: '录入企业数量', dataIndex: 'companyCount', key: 'companyCount', width: 120, align: "center"},
+      {title: '收集岗位数量', dataIndex: 'postCount', key: 'postCount', width: 120, align: "center"},
+      {title: '登记求职人数', dataIndex: 'jobUserCount', key: 'jobUserCount', width: 120, align: "center"},
+    ]
+  }
+])
+
+// 数据加载
+function loadData() {
+  tableLoading.value = true;
+  getMonthSystemDataCount(searchParams).then((result: any) => {
+    console.log(result);
+    // 初始化数据,获取到区县名称
+    let arr = new Array<any>();
+    if (result && Object.keys(result).length > 0) {
+      // 获取到查询结果Map中的第一个键值对,解析获取到县区信息,填充进初始数组中
+      result[Object.keys(result)[0]].forEach((item: any) => {
+        arr.push({
+          regionCode: item.regionCode,
+          regionName: item.regionName
+        });
+      });
+    }
+    // 初始化表结构
+    originalColumns.value = [{
+      title: '项目', dataIndex: 'regionName', key: 'regionName', align: "center", width: 200, fixed: 'left'
+    }]
+    // 解析第一周到第五周的统计数据
+    for (let i = 1; i <= 5; i++) {
+      // 填充数据
+      initTableData(result, '第' + i + '周', arr, i + 'z');
+    }
+    // 解析汇总数据
+    initTableData(result, '汇总', arr, 'hz');
+    systemApplyCount.value = arr;
+  }).finally(() => {
+    tableLoading.value = false;
+  })
+}
+
+// 查询表单
+function onReset() {
+  searchParams.dateStr = dayjs(new Date().getDate()).format("YYYY-MM");
+  loadData()
+}
+
+// 日期变更事件
+function pickerDateChange(date: any, dateStr: string) {
+  console.log(date);
+  searchParams.dateStr = dateStr;
+  loadData();
+}
+
+// 表格数据与结构定义初始化
+function initTableData(result: any, resultKey: any, arr: any, arrNewKey: any) {
+  if (!result[resultKey]) {
+    return;
+  }
+  // 填充数据
+  result[resultKey].forEach((item: any) => {
+    let arrItem = arr.find((arrElement: any) => arrElement.regionCode === item.regionCode);
+    if (arrItem) {
+      // 将item的其他字段重命名,然后将其赋值给arr中对应的元素
+      Object.keys(item).forEach(key => {
+        if (key !== 'regionCode' && key !== 'regionName') {
+          arrItem[key + arrNewKey] = item[key];
+        }
+      });
+    }
+  })
+  // 填充表结构
+  originalColumns.value.push({
+    title: resultKey,
+    children: [
+      {
+        title: '驿站人员数量',
+        dataIndex: 'siteUserCount' + arrNewKey,
+        key: 'siteUserCount' + arrNewKey,
+        width: 120,
+        align: "center"
+      },
+      {
+        title: '录入企业数量',
+        dataIndex: 'companyCount' + arrNewKey,
+        key: 'companyCount' + arrNewKey,
+        width: 120,
+        align: "center"
+      },
+      {
+        title: '收集岗位数量',
+        dataIndex: 'postCount' + arrNewKey,
+        key: 'postCount' + arrNewKey,
+        width: 120,
+        align: "center"
+      },
+      {
+        title: '登记求职人数',
+        dataIndex: 'jobUserCount' + arrNewKey,
+        key: 'jobUserCount' + arrNewKey,
+        width: 120,
+        align: "center"
+      },
+    ]
+  })
+}
+
+onMounted(() => {
+  searchParams.dateStr = dayjs().format("YYYY-MM");
+  loadData();
+})
+</script>
+
+<script lang="ts">
+// 设置页面名称进行组件缓存
+export default {
+  name: "MonthSystemApplyDataCount",
+}
+</script>
+
+<style scoped>
+
+</style>