Browse Source

feat: 数据大屏-求职人员

zhangying 8 months ago
parent
commit
9fe459cf41

+ 6 - 1
src/main/java/com/hz/employmentsite/config/WebConfiguration.java

@@ -122,8 +122,13 @@ public class WebConfiguration implements WebMvcConfigurer {
         excludePath.add("/api/statistics/systemApplyCountBySite"); // 各驿站的业务数据情况
         excludePath.add("/api/statistics/companyAndPostCountByRegion"); // 各区县的企业与岗位数量情况
         excludePath.add("/api/statistics/companyModelCount"); // 各区县的企业规模情况
+        excludePath.add("/api/statistics/jobUserCountByAgeRange"); // 求职人员年龄分布
+        excludePath.add("/api/statistics/empAndUnEmpJobUserCount"); // 已就业与未就业人员情况
+        excludePath.add("/api/statistics/difficultyPersonTypeCount"); // 12种就业困难人员分布情况
+        excludePath.add("/api/statistics/companyModelCount"); // 企业规模分布情况
+        excludePath.add("/api/statistics/jobUserAndJobHuntCount"); // 各县区的指定时间内求职人员与就业意向新增数量
         excludePath.add("/api/jobUserServiceRecords/getSystemServiceList"); // 系统整体的服务记录
-
+        excludePath.add("/api/jobusermgr/recommendmgt/getList"); // 推荐库列表查询
 
         excludePath.add("/api/wx/**");
         excludePath.add("/gdgovMapApi");

+ 32 - 2
src/main/java/com/hz/employmentsite/controller/statistics/StatisticsController.java

@@ -79,8 +79,10 @@ public class StatisticsController {
      * 查询各个年龄段的求职人员数量
      */
     @GetMapping("/jobUserCountByAgeRange")
-    public BaseResponse findJobUserCountByAgeRange(@RequestParam(required = false) String year, @RequestParam(required = false) String month) {
-        List<AgeRangeJobUserCount> result = statisticsService.findJobUserCountByAgeRange(year, month);
+    public BaseResponse findJobUserCountByAgeRange(@RequestParam(required = false) String year,
+                                                   @RequestParam(required = false) String month,
+                                                   @RequestParam(required = false) Boolean isNotCity) {
+        List<AgeRangeJobUserCount> result = statisticsService.findJobUserCountByAgeRange(year, month, isNotCity);
         return RespGenerstor.success(result);
     }
 
@@ -111,6 +113,15 @@ public class StatisticsController {
         return RespGenerstor.success(result);
     }
 
+    /**
+     * 查询各区县的失业与已就业人员情况
+     */
+    @GetMapping("/empAndUnEmpJobUserCount")
+    public BaseResponse findEmployedAndUnemployedCount() {
+        List<RegionJobUserCount> result = statisticsService.findEmployedAndUnemployedCount();
+        return RespGenerstor.success(result);
+    }
+
     /**
      * 查询各驿站的业务数据情况
      */
@@ -140,6 +151,25 @@ public class StatisticsController {
         return RespGenerstor.success(regionCompanyModel);
     }
 
+    /**
+     * 查询12种就业困难人员的分布情况
+     */
+    @GetMapping("/difficultyPersonTypeCount")
+    public BaseResponse getDifficultyPersonTypeCount() {
+        List<PersonTypeJobUserCount> result = statisticsService.findDifficultyPersonTypeCount();
+        return RespGenerstor.success(result);
+    }
+
+    /**
+     * 查询各县区的指定时间内求职人员与就业意向新增数量
+     */
+    @GetMapping("/jobUserAndJobHuntCount")
+    public BaseResponse getJobUserAndJobHuntCount(@RequestParam(required = false) Date startDate,
+                                                  @RequestParam(required = false) Date endDate){
+        List<RegionJobUserCount> result = statisticsService.findJobUserAndJobHuntCount(startDate, endDate);
+        return RespGenerstor.success(result);
+    }
+
     /**
      * 导出指定时间段的系统使用情况
      *

+ 20 - 4
src/main/java/com/hz/employmentsite/mapper/cquery/StatisticsCQuery.java

@@ -41,7 +41,7 @@ public interface StatisticsCQuery {
     /**
      * 查询各年龄段的求职人员数量
      */
-    List<AgeRangeJobUserCount> findJobUserCountByAgeRange(@Param("year") String year, @Param("month") String month);
+    List<AgeRangeJobUserCount> findJobUserCountByAgeRange(@Param("year") String year, @Param("month") String month, @Param("isNotCity") Boolean isNotCity);
 
     /**
      * 查询各重点人员类别在各学历的分布情况
@@ -49,9 +49,13 @@ public interface StatisticsCQuery {
     List<PersonTypeJobUserCount> findJobUserCountByPersonType(@Param("year") String year, @Param("month") String month);
 
     /**
-     * 查询各县区的未就业的求职人员清空
+     * 查询各县区的求职人员情况
      */
-    List<RegionJobUserCount> findJobUserByRegionAndStatus(@Param("year") String year, @Param("month") String month);
+    List<RegionJobUserCount> findJobUserByRegion(@Param("year") String year,
+                                                 @Param("month") String month,
+                                                 @Param("isNotCity") Boolean isNotCity,
+                                                 @Param("startDate") Date startDate,
+                                                 @Param("endDate") Date endDate);
 
     /**
      * 查询各县区的就业困难人员情况(特殊重点人员类别)
@@ -115,7 +119,7 @@ public interface StatisticsCQuery {
     /**
      * 查询已就业的求职人员人数
      */
-    List<RegionJobUserCount> findEmployedJobUserCount();
+    List<RegionJobUserCount> findJobUserCountByStatus(@Param("jobStatus") Integer status);
 
     /**
      * 查询各区县的企业数量
@@ -131,4 +135,16 @@ public interface StatisticsCQuery {
      * 查询企业规模在各区县的分布情况-数据大屏
      */
     List<ModelCompanyCount> findCompanyModelDataByRegion();
+
+    /**
+     * 查询12种就业困难人员类型的人数分布情况-数据大屏
+     */
+    List<PersonTypeJobUserCount> findDifficultyPersonTypeCount();
+
+    /**
+     * 查询各县区的求职人员情况
+     */
+    List<RegionJobUserCount> findJobHuntByRegion(@Param("startDate") Date startDate,
+                                                 @Param("endDate") Date endDate,
+                                                 @Param("isNotCity") Boolean isNotCity);
 }

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

@@ -289,8 +289,8 @@ public class StatisticsServiceImpl implements StatisticsService {
      * 查询各年龄段的求职人员数量
      */
     @Override
-    public List<AgeRangeJobUserCount> findJobUserCountByAgeRange(String year, String month) {
-        return statisticsCQuery.findJobUserCountByAgeRange(year, month);
+    public List<AgeRangeJobUserCount> findJobUserCountByAgeRange(String year, String month, Boolean isNotCity) {
+        return statisticsCQuery.findJobUserCountByAgeRange(year, month, isNotCity);
     }
 
     /**
@@ -344,7 +344,7 @@ public class StatisticsServiceImpl implements StatisticsService {
      */
     @Override
     public List<RegionJobUserCount> findJobUserByRegionAndDifficulty(String year, String month) {
-        List<RegionJobUserCount> regionCountList = statisticsCQuery.findJobUserByRegionAndStatus(year, month);
+        List<RegionJobUserCount> regionCountList = statisticsCQuery.findJobUserByRegion(year, month, null, null, null);
         List<RegionJobUserCount> difficultyCountList = statisticsCQuery.findJobUserByRegionAndPersonType(year, month);
 
         // 解析两个查询结果
@@ -368,9 +368,32 @@ public class StatisticsServiceImpl implements StatisticsService {
      */
     @Override
     public List<RegionJobUserCount> findEmployedJobUserCount() {
-        return statisticsCQuery.findEmployedJobUserCount();
+        return statisticsCQuery.findJobUserCountByStatus(1);
     }
 
+    /**
+     * 查询系统中未就业与已就业人员情况
+     */
+    @Override
+    public List<RegionJobUserCount> findEmployedAndUnemployedCount() {
+        List<RegionJobUserCount> unEmp = statisticsCQuery.findJobUserCountByStatus(2);
+        List<RegionJobUserCount> emp = statisticsCQuery.findJobUserCountByStatus(1);
+        Map<String, RegionJobUserCount> resultMap = new HashMap<>();
+
+        // 合并两个结果
+        unEmp.forEach(item -> {
+            // 查找最终结果中是否有相同的区县,没有则新建,有则将查询数据填充到对应的字段
+            resultMap.computeIfAbsent(item.getRegionName(), k -> new RegionJobUserCount(item.getRegionCode(), item.getRegionName()))
+                    .setUnemployedCount(item.getJobUserCount());
+        });
+        emp.forEach(item -> {
+            resultMap.computeIfAbsent(item.getRegionName(), k -> new RegionJobUserCount(item.getRegionCode(), item.getRegionName()))
+                    .setJobUserCount(item.getJobUserCount());
+        });
+        return new ArrayList<>(resultMap.values());
+    }
+
+
     /**
      * 查询各驿站的业务数据信息
      */
@@ -411,4 +434,34 @@ public class StatisticsServiceImpl implements StatisticsService {
     public List<ModelCompanyCount> findRegionCompanyModel() {
         return statisticsCQuery.findCompanyModelDataByRegion();
     }
+
+    /**
+     * 查询12种就业困难人员类型的人数分布情况-数据大屏
+     */
+    @Override
+    public List<PersonTypeJobUserCount> findDifficultyPersonTypeCount() {
+        return statisticsCQuery.findDifficultyPersonTypeCount();
+    }
+
+    /**
+     * 查询各区县指定时间内添加的求职人员与求职意向
+     */
+    @Override
+    public List<RegionJobUserCount> findJobUserAndJobHuntCount(Date startDate, Date endDate) {
+        List<RegionJobUserCount> jobUserList = statisticsCQuery.findJobUserByRegion(null, null, true, startDate, endDate);
+        List<RegionJobUserCount> jobHuntList = statisticsCQuery.findJobHuntByRegion(startDate, endDate, true);
+        Map<String, RegionJobUserCount> resultMap = new HashMap<>();
+
+        // 合并两个结果
+        jobUserList.forEach(item -> {
+            // 查找最终结果中是否有相同的区县,没有则新建,有则将查询数据填充到对应的字段
+            resultMap.computeIfAbsent(item.getRegionName(), k -> new RegionJobUserCount(item.getRegionCode(), item.getRegionName()))
+                    .setJobUserCount(item.getJobUserCount());
+        });
+        jobHuntList.forEach(item -> {
+            resultMap.computeIfAbsent(item.getRegionName(), k -> new RegionJobUserCount(item.getRegionCode(), item.getRegionName()))
+                    .setJobHuntCount(item.getJobHuntCount());
+        });
+        return new ArrayList<>(resultMap.values());
+    }
 }

+ 16 - 1
src/main/java/com/hz/employmentsite/services/service/statistics/StatisticsService.java

@@ -39,7 +39,7 @@ public interface StatisticsService {
     /**
      * 查询各年龄段的求职人员数量
      */
-    List<AgeRangeJobUserCount> findJobUserCountByAgeRange(String year, String month);
+    List<AgeRangeJobUserCount> findJobUserCountByAgeRange(String year, String month, Boolean isNotCity);
 
     /**
      * 查询各重点人员类别在各学历的分布情况
@@ -56,6 +56,11 @@ public interface StatisticsService {
      */
     List<RegionJobUserCount> findEmployedJobUserCount();
 
+    /**
+     * 查询系统中未就业与已就业人员情况
+     */
+    List<RegionJobUserCount> findEmployedAndUnemployedCount();
+
     /**
      * 查询各驿站的业务数据信息
      */
@@ -70,4 +75,14 @@ public interface StatisticsService {
      * 查询各区县的企业的企业规模情况-数据大屏
      */
     List<ModelCompanyCount> findRegionCompanyModel();
+
+    /**
+     * 查询12种就业困难人员类型的人数分布情况-数据大屏
+     */
+    List<PersonTypeJobUserCount> findDifficultyPersonTypeCount();
+
+    /**
+     * 查询各区县指定时间内添加的求职人员与求职意向
+     */
+    List<RegionJobUserCount> findJobUserAndJobHuntCount(Date startDate, Date endDate);
 }

+ 20 - 1
src/main/java/com/hz/employmentsite/vo/statistics/jobUser/RegionJobUserCount.java

@@ -1,15 +1,19 @@
 package com.hz.employmentsite.vo.statistics.jobUser;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class RegionJobUserCount {
     private String regionCode;
 
     private String regionName;
 
     /**
-     * 正常失业人数
+     * 正常失业人数 / 正常求职人数 / 已就业人数
      */
     private int jobUserCount;
 
@@ -17,4 +21,19 @@ public class RegionJobUserCount {
      * 就业困难人数
      */
     private int difficultyCount;
+
+    /**
+     * 失业人数
+     */
+    private int unemployedCount;
+
+    /**
+     * 求职意向数量
+     */
+    private int jobHuntCount;
+
+    public RegionJobUserCount(String regionCode, String regionName) {
+        this.regionCode = regionCode;
+        this.regionName = regionName;
+    }
 }

+ 1 - 1
src/main/resources/mapping/cquery/JobHuntCQuery.xml

@@ -69,7 +69,7 @@
             and jobuser.siteId = #{siteID}
         </if>
         <if test="regionCode != '' and regionCode != null">
-            and jobuser.RegionCode = #{regionCode}
+            and site.RegionCode = #{regionCode}
         </if>
         <if test="startDate != null and endDate == null">
             and jobHunt.CreateTime <![CDATA[ >= ]]> #{startDate}

+ 70 - 4
src/main/resources/mapping/cquery/StatisticsCQuery.xml

@@ -185,9 +185,13 @@
             Sex,
             COUNT(1) AS jobUserCount
         FROM
-            pc_jobuser
+            pc_jobuser jobUser
+            LEFT JOIN pc_site site ON jobUser.SiteID = site.SiteID
         WHERE
             1=1
+            <if test="isNotCity!=null">
+                and site.RegionCode != '441301000000000'
+            </if>
             <if test="year!='' and year!=null">
                 and YEAR(CreateTime) = #{year}
             </if>
@@ -232,7 +236,7 @@
             jobuser.CultureRank DESC
     </select>
 
-    <select id="findJobUserByRegionAndStatus" resultType="com.hz.employmentsite.vo.statistics.jobUser.RegionJobUserCount">
+    <select id="findJobUserByRegion" resultType="com.hz.employmentsite.vo.statistics.jobUser.RegionJobUserCount">
         SELECT
             area.`code` AS regionCode,
             area.`name` AS regionName,
@@ -243,12 +247,21 @@
                 LEFT JOIN pc_jobuser jobUser ON site.SiteID = jobUser.SiteID
         WHERE
             area.lv = 3
+            <if test="isNotCity!=null">
+                and site.RegionCode != '441301000000000'
+            </if>
             <if test="year!='' and year!=null">
                 and YEAR(jobUser.CreateTime) = #{year}
             </if>
             <if test="month!='' and month!=null">
                 and MONTH(jobUser.CreateTime) = #{month}
             </if>
+            <if test="startDate != null">
+                and DATE(jobUser.CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+            </if>
+            <if test="endDate != null ">
+                and DATE(jobUser.CreateTime) <![CDATA[ <= ]]> DATE(#{endDate})
+            </if>
         GROUP BY
             area.`code`,
             area.`name`
@@ -500,7 +513,7 @@
             `Week` ASC
     </select>
 
-    <select id="findEmployedJobUserCount" resultType="com.hz.employmentsite.vo.statistics.jobUser.RegionJobUserCount">
+    <select id="findJobUserCountByStatus" resultType="com.hz.employmentsite.vo.statistics.jobUser.RegionJobUserCount">
         SELECT
             area.`code` AS regionCode,
             area.`name` AS regionName,
@@ -511,7 +524,12 @@
                 LEFT JOIN pc_jobuser jobUser ON site.SiteID = jobUser.SiteID
         WHERE
             area.lv = 3
-          AND jobUser.JobStatusID = 1
+            <if test="jobStatus != null and jobStatus == 1">
+                AND jobUser.JobStatusID = 1
+            </if>
+            <if test="jobStatus != null and jobStatus > 1">
+                AND jobUser.JobStatusID > 1
+            </if>
         GROUP BY
             area.`code`,
             area.`name`
@@ -591,4 +609,52 @@
         ORDER BY
             area.`code`
     </select>
+
+    <select id="findDifficultyPersonTypeCount" resultType="com.hz.employmentsite.vo.statistics.jobUser.PersonTypeJobUserCount">
+        SELECT
+            item.`Name` AS keyTypeName,
+            item.`Value` AS keyPersonTypeID,
+            COUNT( jobUser.JobuserID ) AS jobUserCount
+        FROM
+            sys_dictionary_item item
+            LEFT JOIN pc_jobuser jobUser ON jobUser.KeyPersonTypeID = item.`Value`
+            LEFT JOIN pc_site site ON jobUser.SiteID = site.SiteID
+        WHERE
+            item.DictionaryCode = 'KeyPersonType'
+            AND item.`Value` IN ( 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 )
+            AND site.RegionCode != '441301000000000'
+        GROUP BY
+            item.`Name`,
+            item.`Value`
+        ORDER BY
+            item.`Value`
+    </select>
+
+    <select id="findJobHuntByRegion" resultType="com.hz.employmentsite.vo.statistics.jobUser.RegionJobUserCount">
+        SELECT
+            area.`code` AS regionCode,
+            area.`name` AS regionName,
+            COUNT( jobHunt.JobHuntID ) AS jobHuntCount
+        FROM
+            area_code area
+            LEFT JOIN pc_site site ON area.`code` = site.RegionCode
+            LEFT JOIN pc_jobuser jobUser ON site.SiteID = jobUser.SiteID
+            LEFT JOIN pc_jobhunt jobHunt ON jobUser.JobuserID = jobHunt.JobUserID
+        WHERE
+            area.lv = 3
+            <if test="isNotCity!=null">
+                and site.RegionCode != '441301000000000'
+            </if>
+            <if test="startDate != null">
+                and DATE(jobHunt.CreateTime) <![CDATA[ >= ]]> DATE(#{startDate})
+            </if>
+            <if test="endDate != null ">
+                and DATE(jobHunt.CreateTime) <![CDATA[ <= ]]> DATE(#{endDate})
+            </if>
+        GROUP BY
+            area.`code`,
+            area.`name`
+        ORDER BY
+            area.`code`
+    </select>
 </mapper>

+ 50 - 2
vue/src/api/statistics/index.ts

@@ -54,12 +54,12 @@ export function getYearSystemDataCount(params: any) {
 /**
  * 查询各个年龄段的求职人员数量
  */
-export function getJobUserCountByAgeRange(year: any, month: any) {
+export function getJobUserCountByAgeRange(year: any, month: any, isNotCity) {
   return request<object>(
     {
       url: 'statistics/jobUserCountByAgeRange',
       method: 'get',
-      params: {year, month},
+      params: {year, month, isNotCity},
     },
     {
       isNew: true,
@@ -115,6 +115,22 @@ export function getEmployedJobUserCount() {
   );
 }
 
+/**
+ * 查询各区县的已就业与未就业人员
+ */
+export function getEmployedAndUnemployedCount() {
+  return request<object>(
+    {
+      url: 'statistics/empAndUnEmpJobUserCount',
+      method: 'get',
+      params: {},
+    },
+    {
+      isNew: true,
+    },
+  );
+}
+
 /**
  * 查询各驿站的业务数据情况
  * @param params 查询参数
@@ -164,3 +180,35 @@ export function getCompanyModelCount() {
     },
   );
 }
+
+/**
+ * 查询12种就业困难人员的分布情况
+ */
+export function getDifficultyPersonTypeCount() {
+  return request<object>(
+    {
+      url: 'statistics/difficultyPersonTypeCount',
+      method: 'get',
+      params: {},
+    },
+    {
+      isNew: true,
+    },
+  );
+}
+
+/**
+ * 查询各县区的指定时间内求职人员与就业意向新增数量
+ */
+export function getJobUserAndJobHuntCount(startDate: any, endDate: any) {
+  return request<object>(
+    {
+      url: 'statistics/jobUserAndJobHuntCount',
+      method: 'get',
+      params: {startDate, endDate},
+    },
+    {
+      isNew: true,
+    },
+  );
+}

+ 1 - 1
vue/src/router/constant.ts

@@ -7,7 +7,7 @@ export const PARENT_LAYOUT_NAME = 'ParentLayout';
 export const PAGE_NOT_FOUND_NAME = 'PageNotFound';
 
 // 路由白名单
-export const whiteNameList = [LOGIN_NAME, 'icons', 'error', 'error-404', 'dataScreenIndex', 'dataScreenCompany'] as const; // no redirect whitelist
+export const whiteNameList = [LOGIN_NAME, 'icons', 'error', 'error-404', 'dataScreenIndex', 'dataScreenCompany', 'dataScreenJobUser'] as const; // no redirect whitelist
 
 export type WhiteNameList = typeof whiteNameList;
 

+ 10 - 1
vue/src/router/outsideLayout.ts

@@ -58,4 +58,13 @@ export const dataScreenCompanyRoute: RouteRecordRaw = {
   },
 };
 
-export default [LoginRoute, companyDataMapRoute, siteDataMapRoute, jobUserDataMapRoute, dataScreenIndexRoute, dataScreenCompanyRoute];
+export const dataScreenJobUserRoute: RouteRecordRaw = {
+  path: '/dataMap/dataScreenJobUser',
+  name: 'dataScreenJobUser',
+  component: () => import('@/views/dataScreen/html/jobUser.vue'),
+  meta: {
+    title: '惠州市就业驿站管理系统',
+  },
+};
+
+export default [LoginRoute, companyDataMapRoute, siteDataMapRoute, jobUserDataMapRoute, dataScreenIndexRoute, dataScreenCompanyRoute, dataScreenJobUserRoute];

+ 73 - 10
vue/src/views/dataScreen/echarts.ts

@@ -148,7 +148,7 @@ export function initDataSetBarImageTable(dataSetSource: any, seriesList: any, do
  * @param legendList 图表数据说明
  * @param domId 目标DOM元素ID
  */
-export function initStackBarImageTable(xTitleList: any, seriesList: any, legendList: any, domId: any) {
+export function initStackBarImageTable(xTitleList: any, seriesList: any, legendList: any, domId: any, showTextLength: any) {
   const chartDom = document.getElementById(domId);
   let myChart = echarts.init(chartDom);
   if (myChart != null) {
@@ -182,7 +182,26 @@ export function initStackBarImageTable(xTitleList: any, seriesList: any, legendL
     },
     xAxis: {
       type: 'category',
-      data: xTitleList
+      data: xTitleList,
+      axisLabel: {
+        color: '#69859b',
+        formatter: function (params: any) {
+          let newParamsName = '';
+          const paramsNameNumber = params.length; // 文字总长度
+          const rowNumber = Math.ceil(paramsNameNumber / showTextLength);
+          if (paramsNameNumber > showTextLength) {
+            for (let p = 0; p < rowNumber; p++) {
+              const start = p * showTextLength;
+              const end = start + showTextLength;
+              const tempStr = p === rowNumber - 1 ? params.substring(start, paramsNameNumber) : params.substring(start, end) + '\n';
+              newParamsName += tempStr;
+            }
+          } else {
+            newParamsName = params;
+          }
+          return newParamsName;
+        },
+      }
     },
     yAxis: {
       type: 'value',
@@ -274,7 +293,7 @@ export function initStripBarImageTable(yAxisList: any, seriesList: any, domId: a
  * @param domId 目标DOM元素ID
  * @param seriesName 注解信息的名称
  */
-export function initPieImageTable(seriesDataList: any, graphicChildren: any, domId: any, seriesName: any) {
+export function initRingPieImageTable(seriesDataList: any, graphicChildren: any, domId: any, seriesName: any) {
   const chartDom = document.getElementById(domId);
   let myChart = echarts.init(chartDom);
   if (myChart != null) {
@@ -313,6 +332,50 @@ export function initPieImageTable(seriesDataList: any, graphicChildren: any, dom
   option && myChart.setOption(option);
 }
 
+/**
+ * 饼图图表初始化
+ * @param seriesDataList 展示数据
+ * @param domId 目标DOM元素ID
+ * @param seriesName 注解信息的名称
+ */
+export function initPieImageTable(seriesDataList: any, domId: any, seriesName: any) {
+  const chartDom = document.getElementById(domId);
+  let myChart = echarts.init(chartDom);
+  if (myChart != null) {
+    // 销毁老的图表实例
+    myChart.dispose();
+    myChart = echarts.init(chartDom)
+  }
+  const option = {
+    tooltip: {
+      trigger: 'item'
+    },
+    grid: {
+      top: '3%',
+      left: '3%',
+      right: '3%',
+      bottom: '3%',
+      containLabel: true
+    },
+    series: [
+      {
+        name: seriesName,
+        type: 'pie',
+        radius: '70%',
+        label: {
+          color: 'inherit',
+          position: 'outer',
+          borderWidth: 0,
+          formatter: '{b}:{d}%'
+        },
+        data: seriesDataList
+      }
+    ],
+  };
+
+  option && myChart.setOption(option);
+}
+
 export const PieColorData = {
   "惠城区": "#716c85",
   "惠阳区": "#c8ceda",
@@ -324,11 +387,11 @@ export const PieColorData = {
 }
 
 export const CompanyModelColorData = {
-  "20人以下": "#661cff",
-  "20-99人": "#ffec1c",
-  "100-299人": "#e4495a",
-  "300-499人": "#ee84d6",
-  "500-999人": "#f1bc29",
-  "1000-9999人": "#81ffaf",
-  "10000人以上": "#81d3f8",
+  "20人以下": "#716c85",
+  "20-99人": "#c8ceda",
+  "100-299人": "#006efe",
+  "300-499人": "#9192ac",
+  "500-999人": "#76f7fe",
+  "1000-9999人": "#6cd300",
+  "10000人以上": "#f6b400",
 }

+ 12 - 7
vue/src/views/dataScreen/html/company.vue

@@ -34,7 +34,7 @@
             <div class="nav-items nav-active">
               <div class="nav-2"></div>
               <h2 style="color: #77F8FF;">企业情况</h2></div>
-            <div class="nav-items">
+            <div class="nav-items" @click="goJobUser">
               <div class="nav-3"></div>
               <h2 style="color: #77F8FF;">求职情况</h2></div>
             <div class="nav-items">
@@ -107,7 +107,7 @@ import {getCompanyAndPostByRegion, getCompanyModelCount} from "@/api/statistics"
 import {
   CompanyModelColorData,
   initDataSetBarImageTable,
-  initPieImageTable,
+  initRingPieImageTable,
   initStackBarImageTable, initStripBarImageTable,
   PieColorData
 } from "@/views/dataScreen/echarts";
@@ -201,8 +201,8 @@ function setPieTable(result: any) {
     }
   ]);
 
-  initPieImageTable(companyArr, createTextConfig('企业数', companyTotal), "companyPieBox", "企业数");
-  initPieImageTable(postArr, createTextConfig('岗位数', postTotal), "postPieBox", "岗位数");
+  initRingPieImageTable(companyArr, createTextConfig('企业数', companyTotal), "companyPieBox", "企业数");
+  initRingPieImageTable(postArr, createTextConfig('岗位数', postTotal), "postPieBox", "岗位数");
   initDataSetBarImageTable(barTableArr, [
     {type: 'bar', barMaxWidth: '10px', color: "#0062cc"},
     {type: 'bar', barMaxWidth: '10px', color: '#73ecf3'}
@@ -245,7 +245,7 @@ function setStrip(result: any, domId: string) {
 // 查询企业规模数据
 function loadCompanyModelCount() {
   getCompanyModelCount().then((result: any) => {
-    // 获取X轴刻度标题,去除重复项,去除“市本级”
+    // 设置X轴刻度标题
     const xTitleList = ["惠城区", "惠阳区", "博罗县", "惠东县", "龙门县", "大亚湾区", "仲恺区"];
     // 按数据设置Y轴的值内容
     const yValueList = result.filter((item: any) => item.companyModel != null && item.regionName != '市本级').reduce((acc: any, item: any) => {
@@ -266,13 +266,13 @@ function loadCompanyModelCount() {
         name: key,
         type: 'bar',
         barMaxWidth: '15px',
-        stack: 'ageRange',
+        stack: 'companyModel', // 堆叠内容分类(相同类型堆在同一柱体上)
         emphasis: {focus: 'series'},
         color: CompanyModelColorData[key],
         data: yValueList[key]
       })
     }
-    initStackBarImageTable(xTitleList, bars, legendList, 'companyModelCountBox')
+    initStackBarImageTable(xTitleList, bars, legendList, 'companyModelCountBox', 4)
   })
 }
 
@@ -281,6 +281,11 @@ function goIndex() {
   router.push({name: "dataScreenIndex"})
 }
 
+// 跳转求职人员面板
+function goJobUser() {
+  router.push({name: "dataScreenJobUser"})
+}
+
 // 查询推荐岗位数据
 function findMgtData() {
   getList({pageIndex: 1, pageSize: 10}).then((result: any) => {

+ 8 - 3
vue/src/views/dataScreen/html/index.vue

@@ -34,7 +34,7 @@
             <div class="nav-items" @click="goCompany">
               <div class="nav-2"></div>
               <h2 style="color: #77F8FF;">企业情况</h2></div>
-            <div class="nav-items">
+            <div class="nav-items" @click="goJobUser">
               <div class="nav-3"></div>
               <h2 style="color: #77F8FF;">求职情况</h2></div>
             <div class="nav-items">
@@ -186,7 +186,7 @@ import {computed, onBeforeUnmount, onMounted, reactive, ref} from "vue";
 import {
   initDataSetBarImageTable,
   initLineImageTable,
-  initPieImageTable,
+  initRingPieImageTable,
   PieColorData
 } from "@/views/dataScreen/echarts";
 import dayjs from "dayjs";
@@ -388,7 +388,7 @@ function loadEmployedUser() {
     ]
 
     // 生成图表
-    initPieImageTable(arr, graphicChildren, "employedCountBox", "已就业人数");
+    initRingPieImageTable(arr, graphicChildren, "employedCountBox", "已就业人数");
   })
 }
 
@@ -532,6 +532,11 @@ function goCompany() {
   router.push({name: "dataScreenCompany"})
 }
 
+// 跳转求职人员面板
+function goJobUser() {
+  router.push({name: "dataScreenJobUser"})
+}
+
 onMounted(() => {
   const now = dayjs();
   searchParams.monthStartDate = now.startOf('month').format('YYYY-MM-DD');

+ 367 - 0
vue/src/views/dataScreen/html/jobUser.vue

@@ -0,0 +1,367 @@
+<template>
+  <div style="height:100vh; min-height:1080px;">
+    <!-- 头部 -->
+    <div class="header">
+      <h1 style="color: #77F8FF;">惠州市就业驿站大数据</h1>
+      <div class="time">{{ formattedTime }}</div>
+    </div>
+
+    <!-- 内容区 -->
+    <div class="body-content">
+      <!-- 左 -->
+      <div class="side" style="padding-left: 20px;">
+        <div class="content-box">
+          <div class="box-title">全市求职情况一览</div>
+          <div class="chart-box" id="allUnEmpAndEmpJobUserCountBox"></div>
+        </div>
+        <div class="content-box">
+          <div class="box-title">年龄占比</div>
+          <div class="chart-box" id="ageRangeJobUserCountBox"></div>
+        </div>
+        <div class="content-box">
+          <div class="box-title">就业困难人员分布</div>
+          <div class="chart-box" id="difficultyPersonTypeCountBox"></div>
+        </div>
+      </div>
+
+      <!-- 中 -->
+      <div class="center">
+        <div class="center-1">
+          <div class="nav">
+            <div class="nav-items" @click="goIndex">
+              <div class="nav-1"></div>
+              <h2 style="color: #77F8FF;">总体概况</h2></div>
+            <div class="nav-items" @click="goCompany">
+              <div class="nav-2"></div>
+              <h2 style="color: #77F8FF;">企业情况</h2></div>
+            <div class="nav-items nav-active">
+              <div class="nav-3"></div>
+              <h2 style="color: #77F8FF;">求职情况</h2></div>
+            <div class="nav-items">
+              <div class="nav-4"></div>
+              <h2 style="color: #77F8FF;">服务情况</h2></div>
+          </div>
+          <div class="s-box">
+            <div class="statistics t-1">
+              <div style="margin: 8px 0 0 18px; position: revert;">
+                <div class="s-title">求职人数</div>
+                <div class="s-number">{{ allSystemDataCountList.count.jobUserCount }}</div>
+                <div class="waves" style="right: -187px; top: 42px"></div>
+              </div>
+            </div>
+            <div class="statistics t-2">
+              <div style="margin: 8px 0 0 78px; position: revert;">
+                <div class="s-title">未就业数</div>
+                <div class="s-number">{{ allSystemDataCountList.count.unEmpCount }}</div>
+                <div class="waves" style="left: -86px; top: 42px"></div>
+              </div>
+            </div>
+            <div class="statistics t-3">
+              <div style="margin: 78px 0 0 98px; position: revert;">
+                <div class="s-title">已就业数</div>
+                <div class="s-number">{{ allSystemDataCountList.count.empCount }}</div>
+                <div class="waves" style="left: -106px; top: -141px"></div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="center-2">
+          <div class="box-bigtitle">区县就业困难人员</div>
+          <div class="chart-box" id="ordinaryDifficultyCountBox"></div>
+        </div>
+      </div>
+
+      <!-- 右 -->
+      <div class="side" style="padding-right: 20px;">
+        <div class="content-box">
+          <div class="box-title">本周新增</div>
+          <div class="chart-box" id="weekNewAddCountBox">
+
+          </div>
+        </div>
+        <div class="content-box">
+          <div class="box-title">本月新增</div>
+          <div class="chart-box" id="monthNewAddCountBox">
+
+          </div>
+        </div>
+        <div class="content-box">
+          <div class="box-title">本季度新增</div>
+          <div class="chart-box" id="quarterNewAddCountBox">
+
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import {computed, onBeforeUnmount, onMounted, reactive, ref} from "vue";
+import dayjs from "dayjs";
+import weekOfYear from 'dayjs/plugin/weekOfYear';
+import weekday from 'dayjs/plugin/weekday';
+import {useRouter} from "vue-router";
+import {
+  getDifficultyPersonTypeCount,
+  getEmployedAndUnemployedCount, getJobUserAndJobHuntCount,
+  getJobUserByRegionAndDifficulty,
+  getJobUserCountByAgeRange
+} from "@/api/statistics";
+import {
+  CompanyModelColorData,
+  initDataSetBarImageTable,
+  initPieImageTable, initRingPieImageTable,
+  initStackBarImageTable, initStripBarImageTable
+} from "@/views/dataScreen/echarts";
+import isoWeek from "dayjs/plugin/isoWeek";
+import quarterOfYear from "dayjs/plugin/quarterOfYear";
+
+dayjs.extend(weekOfYear);
+dayjs.extend(weekday);
+dayjs.extend(isoWeek);
+dayjs.extend(quarterOfYear);
+
+const router = useRouter();
+
+// 全市数据情况
+const allSystemDataCountList = reactive({
+  count: {
+    jobUserCount: 0,
+    unEmpCount: 0,
+    empCount: 0
+  },
+  list: []
+});
+
+// 实时时间
+const currentTime = ref(new Date());
+const formattedTime = computed(() => {
+  const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
+  const year = currentTime.value.getFullYear();
+  const month = (currentTime.value.getMonth() + 1).toString().padStart(2, '0');
+  const date = currentTime.value.getDate().toString().padStart(2, '0');
+  const day = days[currentTime.value.getDay()];
+  const hours = currentTime.value.getHours().toString().padStart(2, '0');
+  const minutes = currentTime.value.getMinutes().toString().padStart(2, '0');
+  // const seconds = currentTime.value.getSeconds().toString().padStart(2, '0');
+
+  return `${year}-${month}-${date} ${day} ${hours}:${minutes}`;
+});
+
+// 获取全市就业情况
+function loadEmployedAndUnemployedCount() {
+  getEmployedAndUnemployedCount().then((result: any) => {
+    // 设置X轴刻度标题
+    const xTitleList = ["惠城区", "惠阳区", "博罗县", "惠东县", "龙门县", "大亚湾区", "仲恺区"];
+    const unEmp = new Array(xTitleList.length).fill(0);
+    const emp = new Array(xTitleList.length).fill(0);
+    result.filter((item: any) => item.regionName != "市本级").forEach((item: any) => {
+      // 查询到区县名称在xTitleList的下标是多少
+      const index = xTitleList.findIndex((regionItem: any) => regionItem == item.regionName);
+      // 替换掉对应下标的内容
+      unEmp[index] = item.unemployedCount;
+      emp[index] = item.jobUserCount;
+    })
+    const legendList = ["未就业", "已就业"];
+    const bars = [
+      {
+        name: '未就业',
+        type: 'bar',
+        barMaxWidth: '15px',
+        stack: 'emp', // 堆叠内容分类(相同类型堆在同一柱体上)
+        emphasis: {focus: 'series'},
+        color: "#0062cc",
+        data: unEmp
+      }, {
+        name: '已就业',
+        type: 'bar',
+        barMaxWidth: '15px',
+        stack: 'emp', // 堆叠内容分类(相同类型堆在同一柱体上)
+        emphasis: {focus: 'series'},
+        color: "#73ecf3",
+        data: emp
+      }
+    ];
+
+    // 统计出总求职人数与未就业,已就业的合计人数
+    allSystemDataCountList.count.unEmpCount = unEmp.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
+    allSystemDataCountList.count.empCount = emp.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
+    allSystemDataCountList.count.jobUserCount = allSystemDataCountList.count.unEmpCount + allSystemDataCountList.count.empCount;
+
+    // 初始化图表
+    initStackBarImageTable(xTitleList, bars, legendList, 'allUnEmpAndEmpJobUserCountBox', 3)
+  })
+}
+
+// 获取求职人员的年龄分布情况
+function loadAgeRange() {
+  getJobUserCountByAgeRange(null, null, true).then((result: any) => {
+    // 初始化数据
+    const data = [
+      {name: "16-25岁", value: 0, itemStyle: {color: "#716c85"}},
+      {name: "26-35岁", value: 0, itemStyle: {color: "#c8ceda"}},
+      {name: "36-45岁", value: 0, itemStyle: {color: "#006efe"}},
+      {name: "46-55岁", value: 0, itemStyle: {color: "#9192ac"}},
+      {name: "55岁以上", value: 0, itemStyle: {color: "#76f7fe"}},
+    ];
+    result.forEach((item: any) => {
+      // 将对应的年龄段的求职人员数量累加到初始数据里
+      const target = data.find(d => d.name === item.ageRange);
+      if (target) {
+        target.value += item.jobUserCount;
+      }
+    })
+
+    // 初始化图表
+    initPieImageTable(data, "ageRangeJobUserCountBox", "")
+  })
+}
+
+// 获取区县普通求职人员与就业困难人员
+function loadDifficultyUser() {
+  getJobUserByRegionAndDifficulty({}).then((result: any) => {
+    let arr: any[] = [];
+    arr.push(['类型', '失业人数', '就业困难人数'])
+    result.forEach((item: any) => {
+      if (item.regionName != "市本级") {
+        arr.push([item.regionName, item.jobUserCount, item.difficultyCount]);
+      }
+    })
+
+    initDataSetBarImageTable(arr, [{type: 'bar', barMaxWidth: '10px', color: "#0062cc"}, {
+      type: 'bar',
+      barMaxWidth: '10px',
+      color: '#73ecf3'
+    }], 'ordinaryDifficultyCountBox', 4)
+  })
+}
+
+// 查询12种就业困难人员的分布情况
+function loadDifficultyPersonTypeCount() {
+  getDifficultyPersonTypeCount().then((result: any) => {
+    let jobUserArr: any[] = [];
+    let jobUserTotal = 0;
+    result.forEach((item: any) => {
+      if (item.jobUserCount > 0) {
+        jobUserTotal += item.jobUserCount;
+        // 设置图表数据
+        jobUserArr.push({
+          value: item.jobUserCount,
+          name: item.keyTypeName,
+        });
+      }
+    })
+    // 圆环中间的文本
+    const graphicChildren = [
+      {
+        type: 'text',
+        left: 'center',
+        top: '43%',
+        style: {fill: 'rgba(119,248,255,0.7)', text: "困难人员数", font: 'bold 12px Arial', textAlign: 'center'}
+      },
+      {
+        type: 'text',
+        left: 'center',
+        top: '53%',
+        style: {fill: '#77F8FF', text: jobUserTotal, font: 'bold 16px Arial', textAlign: 'center'}
+      }
+    ];
+    initRingPieImageTable(jobUserArr, graphicChildren, "difficultyPersonTypeCountBox", "就业困难人数");
+  })
+}
+
+// 查询各区县的求职人员与就业意向新增数量
+function loadJobUserAndJobHuntCount(startDate: any, endDate: any, domId: any) {
+  getJobUserAndJobHuntCount(startDate, endDate).then((result: any) => {
+    console.log(result);
+    // 预先设置区县数据
+    const regionArr = ["惠城区", "惠阳区", "博罗县", "惠东县", "龙门县", "大亚湾区", "仲恺区"];
+    // 初始化企业与岗位数组
+    const jobUserData = new Array(regionArr.length).fill(0);
+    const jobHuntData = new Array(regionArr.length).fill(0);
+    // 按查询数据填充数组
+    result.forEach((item: any) => {
+      if (item.resionName != "市本级") {
+        const index = regionArr.findIndex((regionItem: any) => regionItem == item.regionName);
+        jobUserData[index] = item.jobUserCount;
+        jobHuntData[index] = item.jobHuntCount;
+      }
+    })
+    // 填充数组
+    const seriesList = [
+      {
+        name: '求职人员数',
+        type: 'bar',
+        color: "#0062cc",
+        data: jobUserData
+      },
+      {
+        name: '求职意向数',
+        type: 'bar',
+        color: "#73ecf3",
+        data: jobHuntData
+      },
+    ]
+    initStripBarImageTable(regionArr, seriesList, domId);
+  })
+}
+
+// 跳转首页
+function goIndex() {
+  router.push({name: "dataScreenIndex"})
+}
+
+// 跳转企业面板
+function goCompany() {
+  router.push({name: "dataScreenCompany"})
+}
+
+onMounted(() => {
+  // 获取当前时间
+  const now = dayjs();
+  // 手动计算当前时间的季度的开始与结束日期
+  const month = now.month();
+  let startOfQuarter;
+  let endOfQuarter;
+  if (month >= 0 && month <= 2) {
+    // 1-3 月
+    startOfQuarter = dayjs(now.year() + '-01-01').format('YYYY-MM-DD');
+    endOfQuarter = dayjs(now.year() + '-03-31').format('YYYY-MM-DD');
+  } else if (month >= 3 && month <= 5) {
+    // 4-6 月
+    startOfQuarter = dayjs(now.year() + '-04-01').format('YYYY-MM-DD');
+    endOfQuarter = dayjs(now.year() + '-06-30').format('YYYY-MM-DD');
+  } else if (month >= 6 && month <= 8) {
+    // 7-9 月
+    startOfQuarter = dayjs(now.year() + '-07-01').format('YYYY-MM-DD');
+    endOfQuarter = dayjs(now.year() + '-09-30').format('YYYY-MM-DD');
+  } else {
+    // 10-12 月
+    startOfQuarter = dayjs(now.year() + '-10-01').format('YYYY-MM-DD');
+    endOfQuarter = dayjs(now.year() + '-12-31').format('YYYY-MM-DD');
+  }
+
+  loadDifficultyUser();
+  loadEmployedAndUnemployedCount();
+  loadAgeRange();
+  loadDifficultyPersonTypeCount();
+  loadJobUserAndJobHuntCount(now.startOf('isoWeek').format('YYYY-MM-DD'), now.endOf('isoWeek').format('YYYY-MM-DD'), "weekNewAddCountBox");
+  loadJobUserAndJobHuntCount(now.startOf('month').format('YYYY-MM-DD'), now.endOf('month').format('YYYY-MM-DD'), "monthNewAddCountBox");
+  loadJobUserAndJobHuntCount(startOfQuarter, endOfQuarter, "quarterNewAddCountBox");
+
+  currentTime.value = new Date();
+  const timer = setInterval(() => {
+    currentTime.value = new Date();
+  }, 1000);
+  onBeforeUnmount(() => {
+    clearInterval(timer);
+  });
+})
+
+</script>
+
+<style scoped>
+@import url('@/views/dataScreen/html/css/reset.css');
+@import url('@/views/dataScreen/html/css/style.css');
+</style>

+ 1 - 1
vue/src/views/statistics/JobUserCount.vue

@@ -146,7 +146,7 @@ const pickerDate = ref<any>();
 // 查询各年龄段求职人员数量
 async function ageRangeOnSearch() {
   searchLoading.value = true;
-  await getJobUserCountByAgeRange(searchParams.year, searchParams.month).then((result: any) => {
+  await getJobUserCountByAgeRange(searchParams.year, searchParams.month, null).then((result: any) => {
     // 保存原始数据
     ageRangeJobUserData.originalList = result;