Переглянути джерело

feat: 企业报表增加行业统计报表

zhangying 7 місяців тому
батько
коміт
ef99ff94ae

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

@@ -252,6 +252,14 @@ public class StatisticsController {
         return RespGenerstor.success(statisticsService.findRegionCompanyWorkSituationCount(startDate, endDate));
     }
 
+    /**
+     * 查询各个行业各个规模的企业的岗位招聘人数情况
+     */
+    @GetMapping("/workSituationCountInIndustry")
+    public BaseResponse getIndustryCompanyWorkSituationCount(@RequestParam(required = false) Date startDate, @RequestParam(required = false) Date endDate) {
+        return RespGenerstor.success(statisticsService.findIndustryCompanyWorkSituationCount(startDate, endDate));
+    }
+
     /**
      * 导出指定时间段的系统使用情况
      *

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

@@ -233,4 +233,14 @@ public interface StatisticsCQuery {
      * 查询各区县各个规模的企业的岗位招聘人数情况
      */
     List<ModelCompanyCount> findRegionCompanyRecruitCount(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+    /**
+     * 查询各个行业各个规模的企业的用工情况
+     */
+    List<ModelCompanyCount> findIndustryCompanyWorkSituationCount(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+    /**
+     * 查询各个行业各个规模的企业的岗位招聘人数情况
+     */
+    List<ModelCompanyCount> findIndustryCompanyRecruitCount(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
 }

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

@@ -665,4 +665,15 @@ public class StatisticsServiceImpl implements StatisticsService {
         companyCountList.addAll(statisticsCQuery.findRegionCompanyRecruitCount(startDate, endDate)); // 岗位招聘人数
         return companyCountList;
     }
+
+    /**
+     * 查询各个行业各个规模的企业的岗位招聘人数情况
+     */
+    @Override
+    public List<ModelCompanyCount> findIndustryCompanyWorkSituationCount(Date startDate, Date endDate) {
+        List<ModelCompanyCount> companyCountList = new ArrayList<>();
+        companyCountList.addAll(statisticsCQuery.findIndustryCompanyWorkSituationCount(startDate, endDate));
+        companyCountList.addAll(statisticsCQuery.findIndustryCompanyRecruitCount(startDate, endDate));
+        return companyCountList;
+    }
 }

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

@@ -132,4 +132,9 @@ public interface StatisticsService {
      * 查询各区县的各个规模的企业用工人数与岗位招聘人数
      */
     List<ModelCompanyCount> findRegionCompanyWorkSituationCount(Date startDate, Date endDate);
+
+    /**
+     * 查询各个行业各个规模的企业的岗位招聘人数情况
+     */
+    List<ModelCompanyCount> findIndustryCompanyWorkSituationCount(Date startDate, Date endDate);
 }

+ 4 - 0
src/main/java/com/hz/employmentsite/vo/statistics/company/ModelCompanyCount.java

@@ -8,6 +8,10 @@ public class ModelCompanyCount {
 
     private String regionName;
 
+    private String parentIndustryName;
+
+    private String industryName;
+
     private Integer companyModel;
 
     private String companyModelName;

+ 65 - 2
src/main/resources/mapping/cquery/StatisticsCQuery.xml

@@ -1099,7 +1099,7 @@
             area.`name` AS regionName,
             company.CompanyModel,
             dict.`Name` AS companyModelName,
-            COUNT( company.workSituation ) AS workSituationCount
+            SUM( company.workSituation ) AS workSituationCount
         FROM
             area_code area
                 LEFT JOIN pc_site site ON area.`code` = site.RegionCode
@@ -1132,7 +1132,7 @@
             area.`name` AS regionName,
             company.CompanyModel,
             dict.`Name` AS companyModelName,
-            COUNT( post.recruitCount ) AS recruitCount
+            SUM( post.recruitCount ) AS recruitCount
         FROM
             area_code area
                 LEFT JOIN pc_site site ON area.`code` = site.RegionCode
@@ -1159,4 +1159,67 @@
         ORDER BY
             area.`code`
     </select>
+
+    <select id="findIndustryCompanyWorkSituationCount" resultType="com.hz.employmentsite.vo.statistics.company.ModelCompanyCount">
+        SELECT
+            pIndustry.industryName AS parentIndustryName,
+            industry.industryName,
+            company.CompanyModel,
+            dict.`Name` AS companyModelName,
+            SUM( company.WorkSituation ) AS workSituationCount
+        FROM
+            pc_industry industry
+                LEFT JOIN pc_industry pIndustry ON industry.parentId = pIndustry.industryId
+                LEFT JOIN pc_company company ON company.IndustryID = industry.industryId
+                LEFT JOIN sys_dictionary_item dict ON company.CompanyModel = dict.`Value`
+                AND dict.DictionaryCode = 'CompanyModel'
+        WHERE
+            industry.parentId != ''
+	        AND industry.parentId IS NOT NULL
+            <if test="startDate != null">
+                and DATE(company.CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+            </if>
+            <if test="endDate != null ">
+                and DATE(company.CreateTime) <![CDATA[ <= ]]> DATE(#{endDate})
+            </if>
+        GROUP BY
+            pIndustry.industryName,
+            industry.industryName,
+            company.CompanyModel,
+            dict.`Name`
+        ORDER BY
+            industry.parentId
+    </select>
+
+    <select id="findIndustryCompanyRecruitCount" resultType="com.hz.employmentsite.vo.statistics.company.ModelCompanyCount">
+        SELECT
+            pIndustry.industryName AS parentIndustryName,
+            industry.industryName,
+            company.CompanyModel,
+            dict.`Name` AS companyModelName,
+            COUNT( post.RecruitCount ) AS recruitCount
+        FROM
+            pc_industry industry
+                LEFT JOIN pc_industry pIndustry ON industry.parentId = pIndustry.industryId
+                LEFT JOIN pc_company company ON company.IndustryID = industry.industryId
+                LEFT JOIN pc_post post on company.CompanyID = post.CompanyID
+                LEFT JOIN sys_dictionary_item dict ON company.CompanyModel = dict.`Value`
+                AND dict.DictionaryCode = 'CompanyModel'
+        WHERE
+            industry.parentId != ''
+	        AND industry.parentId IS NOT NULL
+            <if test="startDate != null">
+                and DATE(post.CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+            </if>
+            <if test="endDate != null ">
+                and DATE(post.CreateTime) <![CDATA[ <= ]]> DATE(#{endDate})
+            </if>
+        GROUP BY
+            pIndustry.industryName,
+            industry.industryName,
+            company.CompanyModel,
+            dict.`Name`
+        ORDER BY
+            industry.parentId
+    </select>
 </mapper>

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

@@ -356,3 +356,19 @@ export function getRegionCompanyWorkSituationCount(params: any) {
     },
   );
 }
+
+/**
+ * 查询各个行业各个规模的企业的岗位招聘人数情况
+ */
+export function getIndustryCompanyWorkSituationCount(params: any) {
+  return request<object>(
+    {
+      url: 'statistics/workSituationCountInIndustry',
+      method: 'get',
+      params: params,
+    },
+    {
+      isNew: true,
+    },
+  );
+}

+ 219 - 4
vue/src/views/statistics/CompanyStatistics.vue

@@ -32,8 +32,9 @@
       <a-col :span="24" class="flex-space-between">
         <div>
           <a-radio-group v-model:value="searchType" button-style="solid" @change="searchTypeChange">
-            <a-radio-button value="companyCount">企业入库与走访情况统计</a-radio-button>
-            <a-radio-button value="workSituationCount">企业用工人数与岗位招聘人数统计</a-radio-button>
+            <a-radio-button value="companyCount">各区县企业入库与走访情况统计</a-radio-button>
+            <a-radio-button value="workSituationCount">各区县企业用工人数与岗位招聘人数统计</a-radio-button>
+            <a-radio-button value="industryWorkSituationCount">各行业企业用工人数与岗位招聘人数统计</a-radio-button>
           </a-radio-group>
         </div>
         <div>
@@ -59,6 +60,15 @@
                bordered>
       </a-table>
     </div>
+    <!-- 企业用工人数与岗位招聘人数统计 -->
+    <div v-show="searchType == 'industryWorkSituationCount'">
+      <a-table :columns="industryWorkSituationCountDataTableColumns" :data-source="industryWorkSituationCountDataList"
+               :scroll="{ x:'100%' }"
+               :loading="searchLoading"
+               :pagination="false"
+               bordered>
+      </a-table>
+    </div>
   </div>
 </template>
 
@@ -67,7 +77,11 @@ import {onMounted, reactive, ref} from "vue";
 import type {RangeValue} from "ant-design-vue/es/vc-picker/interface";
 import dayjs from "dayjs";
 import {getSysDictionaryList} from "@/api/system/dictionary";
-import {getRegionCompanyModelCompanyCount, getRegionCompanyWorkSituationCount} from "@/api/statistics";
+import {
+  getIndustryCompanyWorkSituationCount,
+  getRegionCompanyModelCompanyCount,
+  getRegionCompanyWorkSituationCount
+} from "@/api/statistics";
 
 const searchParams = reactive({
   startDate: "",
@@ -94,6 +108,70 @@ const workSituationCountDataTableColumns = ref<Array<any>>([
 ]);
 const workSituationCountDataList = ref<Array<any>>([]);
 const workSituationCountKeyTemp = ref<Array<any>>([]);
+// 各行业企业用工人数与岗位招聘人数统计表结构
+const industryWorkSituationCountDataTableColumns = ref<Array<any>>([
+  {
+    title: '产业分类', dataIndex: 'estateCategoryName', key: 'estateCategoryName', align: "center", width: 150,
+    customCell: (record, index: any) => {
+      const obj = {
+        colSpan: 1,
+        rowSpan: 1,
+      };
+      if (record.estateCategoryName == '合计' || record.estateCategoryName == '小计') {
+        obj.colSpan = 3;
+      }
+      if (index === 0 || record.estateCategoryName !== industryWorkSituationCountDataList.value[index - 1].estateCategoryName) {
+        for (let i = index + 1; i < industryWorkSituationCountDataList.value.length; i++) {
+          if (industryWorkSituationCountDataList.value[i].estateCategoryName == record.estateCategoryName) {
+            obj.rowSpan++;
+          } else {
+            break;
+          }
+        }
+      } else {
+        obj.rowSpan = 0;
+      }
+      return obj;
+    },
+  }, {
+    title: '所属行业', dataIndex: 'parentIndustryName', key: 'parentIndustryName', align: "center", width: 150,
+    customCell: (record, index: any) => {
+      const obj = {
+        colSpan: 1,
+        rowSpan: 1,
+      };
+      if (record.estateCategoryName == '合计' || record.estateCategoryName == '小计') {
+        obj.colSpan = 0;
+      }
+      if (index === 0 || record.parentIndustryName !== industryWorkSituationCountDataList.value[index - 1].parentIndustryName) {
+        for (let i = index + 1; i < industryWorkSituationCountDataList.value.length; i++) {
+          if (industryWorkSituationCountDataList.value[i].parentIndustryName == record.parentIndustryName) {
+            obj.rowSpan++;
+          } else {
+            break;
+          }
+        }
+      } else {
+        obj.rowSpan = 0;
+      }
+      return obj;
+    },
+  }, {
+    title: '行业名称', dataIndex: 'industryName', key: 'industryName', align: "center", width: 200,
+    customCell: (record) => {
+      const obj = {
+        colSpan: 1,
+        rowSpan: 1,
+      };
+      if (record.estateCategoryName == '合计' || record.estateCategoryName == '小计') {
+        obj.colSpan = 0;
+      }
+      return obj;
+    },
+  },
+]);
+const industryWorkSituationCountDataList = ref<Array<any>>([]);
+const industryWorkSituationCountKeyTemp = ref<Array<any>>([]);
 
 // 时间段变更事件
 const onRangeChange = (dateString: [string, string]) => {
@@ -132,7 +210,7 @@ function getCompanyModel() {
           },
         ]
       })
-      // 企业用工人数与岗位招聘人数统计表结构
+      // 区县企业用工人数与岗位招聘人数统计表结构
       workSituationCountKeyTemp.value.push(...[key + 'WorkSituationCount', key + 'RecruitCount']);
       workSituationCountDataTableColumns.value.push({
         title: item.name, dataIndex: key, key, align: "center",
@@ -151,6 +229,25 @@ function getCompanyModel() {
           },
         ]
       })
+      // 行业企业用工人数与岗位招聘人数统计表结构
+      industryWorkSituationCountKeyTemp.value.push(...[key + 'WorkSituationCount', key + 'RecruitCount']);
+      industryWorkSituationCountDataTableColumns.value.push({
+        title: item.name, dataIndex: key, key, align: "center",
+        children: [
+          {
+            title: '用工人数',
+            dataIndex: key + 'WorkSituationCount',
+            key: key + 'WorkSituationCount',
+            align: "center"
+          },
+          {
+            title: '岗位人数',
+            dataIndex: key + 'RecruitCount',
+            key: key + 'RecruitCount',
+            align: "center"
+          },
+        ]
+      })
     })
   });
 }
@@ -261,8 +358,126 @@ function searchTypeChange() {
       searchLoading.value = false;
     })
   }
+  if (searchType.value == "industryWorkSituationCount") {
+    searchLoading.value = true;
+    industryWorkSituationCountDataList.value = [];
+    getIndustryCompanyWorkSituationCount({...searchParams}).then((result: any) => {
+      // 初始化合计数据
+      let count = {
+        estateCategoryId: -1,
+        estateCategoryName: "合计",
+        parentIndustryName: "合计",
+        industryName: "合计"
+      }
+      // 初始化字段值为O
+      industryWorkSituationCountKeyTemp.value.forEach((key: any) => {
+        count[key] = 0;
+      });
+      result.forEach((resItem: any) => {
+        const key = 'companyModel' + resItem.companyModel;
+        // 查询获取行业数据的下标,保证每个区县只存在一条数据
+        const findIndex = industryWorkSituationCountDataList.value.findIndex((find: any) => find.industryName == resItem.industryName);
+        if (findIndex > -1) {
+          // 行业已存在,修改这条数据
+          if (resItem.workSituationCount > 0) {
+            industryWorkSituationCountDataList.value[findIndex][key + 'WorkSituationCount'] = resItem.workSituationCount;
+            count[key + 'WorkSituationCount'] += resItem.workSituationCount;
+          }
+          if (resItem.recruitCount > 0) {
+            industryWorkSituationCountDataList.value[findIndex][key + 'RecruitCount'] = resItem.recruitCount;
+            count[key + 'RecruitCount'] += resItem.recruitCount;
+          }
+        } else {
+          // 不存在,新增一条数据
+          const newData = {
+            parentIndustryName: resItem.parentIndustryName,
+            industryName: resItem.industryName,
+          }
+          setEstateCategoryName(newData);
+          industryWorkSituationCountKeyTemp.value.forEach((key: any) => {
+            newData[key] = 0;
+          })
+          if (resItem.workSituationCount > 0) {
+            newData[key + 'WorkSituationCount'] = resItem.workSituationCount;
+            count[key + 'WorkSituationCount'] += resItem.workSituationCount;
+          }
+          if (resItem.recruitCount > 0) {
+            newData[key + 'RecruitCount'] = resItem.recruitCount;
+            count[key + 'RecruitCount'] += resItem.recruitCount;
+          }
+          industryWorkSituationCountDataList.value.push(newData);
+        }
+      });
+      // 按产业分类进行排序
+      industryWorkSituationCountDataList.value.sort((a, b) => a.estateCategoryId - b.estateCategoryId);
+      // 统计小计数据
+      calculateCategorySubtotal();
+      // 在末尾添加合计数据
+      industryWorkSituationCountDataList.value.push(count);
+    }).finally(() => {
+      searchLoading.value = false;
+    })
+  }
+}
+
+// 按一级行业名称判断所属产业
+function setEstateCategoryName(newData: any) {
+  // 所属产业判断
+  const categoryMap = {
+    '农、林、牧、渔业': {name: '第一产业', id: 1},
+    '采矿业': {name: '第二产业', id: 2},
+    '制造业': {name: '第二产业', id: 2},
+    '电力、热力、燃气及水生产和供应业': {name: '第二产业', id: 2},
+    '建筑业': {name: '第二产业', id: 2}
+  };
+  if (newData.parentIndustryName && categoryMap[newData.parentIndustryName]) {
+    const category = categoryMap[newData.parentIndustryName];
+    newData.estateCategoryName = category.name;
+    newData.estateCategoryId = category.id;
+  } else {
+    newData.estateCategoryName = '第三产业';
+    newData.estateCategoryId = 3;
+  }
+}
+
+// 统计小计数据
+function calculateCategorySubtotal() {
+  // 初始化每个类别的计数对象
+  const categorySubtotal = {
+    1: {}, // 第一产业
+    2: {}, // 第二产业
+    3: {} // 第三产业
+  };
+  // 初始化字段值为0
+  industryWorkSituationCountKeyTemp.value.forEach((key: any) => {
+    [1, 2, 3].forEach(categoryId => {
+      categorySubtotal[categoryId][key] = 0;
+    });
+  });
+  // 循环统计数据,进行小计数量的累加
+  industryWorkSituationCountDataList.value.forEach((count: any) => {
+    if (categorySubtotal[count.estateCategoryId]) {
+      Object.keys(categorySubtotal[count.estateCategoryId]).forEach(key => {
+        categorySubtotal[count.estateCategoryId][key] += count[key];
+      });
+    }
+  });
+  // 设置文本字段名称
+  ['estateCategoryName', 'parentIndustryName', 'industryName'].forEach((key: any) => {
+    [1, 2, 3].forEach(categoryId => {
+      categorySubtotal[categoryId][key] = '小计';
+    });
+  });
+  // 向表格插入小计数据
+  [1, 2, 3].forEach(categoryId => {
+    const lastIndex = industryWorkSituationCountDataList.value.map(item => item.estateCategoryId).lastIndexOf(categoryId);
+    if (lastIndex !== -1) {
+      industryWorkSituationCountDataList.value.splice(lastIndex + 1, 0, categorySubtotal[categoryId]);
+    }
+  });
 }
 
+
 onMounted(() => {
   getCompanyModel();
   onFinish();