|
@@ -0,0 +1,316 @@
|
|
|
+<template>
|
|
|
+ <div class="card-search">
|
|
|
+ <!-- 操作按钮 -->
|
|
|
+ <a-row class="edit-operation" style="margin-bottom: 20px">
|
|
|
+ <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="ageRange">各年龄段人员分布</a-radio-button>
|
|
|
+ <a-radio-button value="personTypeAndCulture">重点人员类别与学历分布</a-radio-button>
|
|
|
+ <a-radio-button value="regionAndDifficulty">各区县就业困难人员数量</a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ </div>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ <!-- 数据展示 -->
|
|
|
+ <!-- 年龄段统计 -->
|
|
|
+ <div v-show="searchType == 'ageRange'">
|
|
|
+ <a-divider orientation="left">表格</a-divider>
|
|
|
+ <a-table :columns="ageRangeTableColumns" :data-source="ageRangeJobUserData.tableList" :scroll="{ x:'100%' }"
|
|
|
+ :loading="searchLoading"
|
|
|
+ :pagination="false"
|
|
|
+ bordered>
|
|
|
+ </a-table>
|
|
|
+ <a-divider orientation="left">图表</a-divider>
|
|
|
+ <div id="ageRangeImageTable" style="width: 100%; height: 500px"></div>
|
|
|
+ </div>
|
|
|
+ <!-- 重点人员类别-学历分布统计 -->
|
|
|
+ <div v-show="searchType == 'personTypeAndCulture'">
|
|
|
+ <a-divider orientation="left">表格</a-divider>
|
|
|
+ <a-table :columns="personTypeTableColumns" :data-source="personTypeJobUserData.tableList" :scroll="{ x:'100%' }"
|
|
|
+ :loading="searchLoading"
|
|
|
+ :pagination="false"
|
|
|
+ bordered>
|
|
|
+ </a-table>
|
|
|
+ <a-divider orientation="left">图表</a-divider>
|
|
|
+ <div id="personTypeAndCultureImageTable" style="width: 100%; height: 500px"></div>
|
|
|
+ </div>
|
|
|
+ <!-- 正常失业人员与就业困难人员统计 -->
|
|
|
+ <div v-show="searchType == 'regionAndDifficulty'">
|
|
|
+ <a-divider orientation="left">表格</a-divider>
|
|
|
+ <a-table :columns="regionTableColumns" :data-source="regionJobUserData.tableList" :scroll="{ x:'100%' }"
|
|
|
+ :loading="searchLoading"
|
|
|
+ :pagination="false"
|
|
|
+ bordered>
|
|
|
+ </a-table>
|
|
|
+ <a-divider orientation="left">图表</a-divider>
|
|
|
+ <div id="regionAndDifficultyImageTable" style="width: 100%; height: 500px"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import {onMounted, reactive, ref} from "vue";
|
|
|
+import {
|
|
|
+ getJobUserByRegionAndDifficulty,
|
|
|
+ getJobUserCountByAgeRange,
|
|
|
+ getJobUserCountByPersonType
|
|
|
+} from "@/api/statistics";
|
|
|
+import {initDataSetBarImageTable, initStackBarImageTable} from "@/utils/echartsUtil";
|
|
|
+
|
|
|
+// 查询方法类型
|
|
|
+const searchType = ref("ageRange");
|
|
|
+// 查询加载
|
|
|
+const searchLoading = ref(false);
|
|
|
+
|
|
|
+// 各年龄段人员统计数据
|
|
|
+const ageRangeJobUserData = reactive({
|
|
|
+ originalList: new Array<any>(),
|
|
|
+ tableList: new Array<any>(),
|
|
|
+ imageTable: new Array<any>(),
|
|
|
+})
|
|
|
+// 各年龄段人员统计数据表格定义
|
|
|
+const ageRangeTableColumns = [
|
|
|
+ {
|
|
|
+ title: '年龄段', dataIndex: 'ageRange', key: 'ageRange', align: "center"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '男', dataIndex: 'maleCount', key: 'maleCount', align: "center"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '女', dataIndex: 'femaleCount', key: 'femaleCount', align: "center"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '合计', dataIndex: 'total', key: 'total', align: "center"
|
|
|
+ },
|
|
|
+]
|
|
|
+// 各重点人员在各学历分布统计数据
|
|
|
+const personTypeJobUserData = reactive({
|
|
|
+ originalList: new Array<any>(),
|
|
|
+ tableList: new Array<any>(),
|
|
|
+ imageTable: new Array<any>(),
|
|
|
+});
|
|
|
+// 各重点人员在各学历分布统计数据表格定义
|
|
|
+const personTypeTableColumns = ref([
|
|
|
+ {
|
|
|
+ title: '人员类别', dataIndex: 'keyTypeName', key: 'keyTypeName', align: "center"
|
|
|
+ },
|
|
|
+])
|
|
|
+// 各区县的失业人数与就业困难人数统计数据
|
|
|
+const regionJobUserData = reactive({
|
|
|
+ originalList: new Array<any>(),
|
|
|
+ tableList: new Array<any>(),
|
|
|
+ imageTable: new Array<any>(),
|
|
|
+});
|
|
|
+// 各区县的失业人数与就业困难人数统计数据表格定义
|
|
|
+const regionTableColumns = [
|
|
|
+ {
|
|
|
+ title: '县区', dataIndex: 'regionName', key: 'regionName', align: "center"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '失业人员数量', dataIndex: 'jobUserCount', key: 'jobUserCount', align: "center"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '就业困难人数', dataIndex: 'difficultyCount', key: 'keyTypeName', align: "center"
|
|
|
+ },
|
|
|
+]
|
|
|
+
|
|
|
+// 查询各年龄段求职人员数量
|
|
|
+async function ageRangeOnSearch() {
|
|
|
+ searchLoading.value = true;
|
|
|
+ await getJobUserCountByAgeRange().then((result: any) => {
|
|
|
+ // 保存原始数据
|
|
|
+ ageRangeJobUserData.originalList = result;
|
|
|
+
|
|
|
+ // 生成表格数据
|
|
|
+ let tableList: any[] = [];
|
|
|
+ let ageRangeMap: { [key: string]: any } = {};
|
|
|
+ let imageTableMaleCount: number[] = [];
|
|
|
+ let imageTableFemaleCount: number[] = [];
|
|
|
+
|
|
|
+ result.forEach((resultItem: any) => {
|
|
|
+ let {ageRange, sex, jobUserCount} = resultItem;
|
|
|
+
|
|
|
+ // 如果 ageRangeMap 中不存在该年龄段,初始化
|
|
|
+ if (!ageRangeMap[ageRange]) {
|
|
|
+ ageRangeMap[ageRange] = {ageRange, maleCount: 0, femaleCount: 0};
|
|
|
+ tableList.push(ageRangeMap[ageRange]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据性别累加对应的计数,并记录到图表数据数组中
|
|
|
+ if (sex === 1) {
|
|
|
+ ageRangeMap[ageRange].maleCount += jobUserCount;
|
|
|
+ imageTableMaleCount.push(jobUserCount);
|
|
|
+ } else if (sex === 2) {
|
|
|
+ ageRangeMap[ageRange].femaleCount += jobUserCount;
|
|
|
+ imageTableFemaleCount.push(jobUserCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算总计数
|
|
|
+ ageRangeMap[ageRange].total = ageRangeMap[ageRange].maleCount + ageRangeMap[ageRange].femaleCount;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 计算合计
|
|
|
+ let maleCount = 0, femaleCount = 0;
|
|
|
+ tableList.forEach(item => {
|
|
|
+ maleCount += item.maleCount;
|
|
|
+ femaleCount += item.femaleCount;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 将合计数据添加到
|
|
|
+ tableList.push({ageRange: '合计', maleCount, femaleCount, total: maleCount + femaleCount});
|
|
|
+ ageRangeJobUserData.tableList = tableList;
|
|
|
+
|
|
|
+ // 创建图表数据
|
|
|
+ let bars = ['男', '女'].map((name, index) => ({
|
|
|
+ name,
|
|
|
+ type: 'bar',
|
|
|
+ stack: 'ageRange',
|
|
|
+ emphasis: {focus: 'series'},
|
|
|
+ data: index == 0 ? imageTableMaleCount : imageTableFemaleCount
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 生成图表
|
|
|
+ setTimeout(() => {
|
|
|
+ initStackBarImageTable(['16-25岁', '26-35岁', '36-45岁', '46-55岁', '55岁以上'], bars, ['男', '女'], 'ageRangeImageTable', '各年龄段求职人员数量')
|
|
|
+ }, 100)
|
|
|
+
|
|
|
+ }).finally(() => {
|
|
|
+ searchLoading.value = false;
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 查询各重点人员类别在各学历的分布情况
|
|
|
+async function personTypeOnSearch() {
|
|
|
+ searchLoading.value = true;
|
|
|
+ await getJobUserCountByPersonType().then((result: any) => {
|
|
|
+ // 保存原始数据
|
|
|
+ personTypeJobUserData.originalList = result;
|
|
|
+
|
|
|
+ // 表格数据
|
|
|
+ let tableList: any[] = [];
|
|
|
+ // 初始化表格定义
|
|
|
+ personTypeTableColumns.value = [
|
|
|
+ {
|
|
|
+ title: '人员类别', dataIndex: 'keyTypeName', key: 'keyTypeName', align: "center"
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ // 表格title与key的键值对
|
|
|
+ let tableKeyAndName = new Map();
|
|
|
+
|
|
|
+ // 解析准备生成表格数据
|
|
|
+ result.forEach((resultItem: any) => {
|
|
|
+ tableKeyAndName.set(resultItem.cultureRank, resultItem.cultureName);
|
|
|
+ // 创建对象字段名称
|
|
|
+ const key = 'cultureRank' + resultItem.cultureRank;
|
|
|
+
|
|
|
+ // 查询相同的KeyPersonTypeID的对应数组下标
|
|
|
+ const findIndex = tableList.findIndex(item => item.keyPersonTypeID == resultItem.keyPersonTypeID);
|
|
|
+ if (findIndex != -1) {
|
|
|
+ // 在已添加的元素里进行数据插入
|
|
|
+ tableList[findIndex][key] = resultItem.jobUserCount;
|
|
|
+ } else {
|
|
|
+ // 创建一个新的元素
|
|
|
+ let data = {
|
|
|
+ keyPersonTypeID: resultItem.keyPersonTypeID,
|
|
|
+ keyTypeName: resultItem.keyTypeName
|
|
|
+ }
|
|
|
+ data[key] = resultItem.jobUserCount;
|
|
|
+ tableList.push(data)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 填充表结构
|
|
|
+ tableKeyAndName.forEach((value: any, key: any) => {
|
|
|
+ personTypeTableColumns.value.push({
|
|
|
+ title: value, dataIndex: 'cultureRank' + key, key: 'cultureRank' + key, align: "center"
|
|
|
+ })
|
|
|
+ })
|
|
|
+ personTypeJobUserData.tableList = tableList;
|
|
|
+
|
|
|
+ // 创建图表数据
|
|
|
+ // X轴标题内容
|
|
|
+ const xTitleList = tableList.map(item => item.keyTypeName);
|
|
|
+ // Y轴的值内容
|
|
|
+ const yValueList = result.reduce((acc: any, item: any) => {
|
|
|
+ if (!acc[item.cultureName]) {
|
|
|
+ acc[item.cultureName] = [];
|
|
|
+ }
|
|
|
+ // 将人数填充
|
|
|
+ acc[item.cultureName].push(item.jobUserCount);
|
|
|
+ return acc;
|
|
|
+ }, {});
|
|
|
+ let bars: any[] = [];
|
|
|
+ let legendList: any[] = [];
|
|
|
+ for (let key in yValueList) {
|
|
|
+ legendList.push(key);
|
|
|
+ bars.push({
|
|
|
+ name: key,
|
|
|
+ type: 'bar',
|
|
|
+ stack: 'ageRange',
|
|
|
+ emphasis: {focus: 'series'},
|
|
|
+ data: yValueList[key]
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成图表
|
|
|
+ setTimeout(() => {
|
|
|
+ initStackBarImageTable(xTitleList, bars, legendList, 'personTypeAndCultureImageTable', '重点人员类别学历分布统计')
|
|
|
+ }, 100)
|
|
|
+ }).finally(() => {
|
|
|
+ searchLoading.value = false;
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 查询各区县正常失业人员与就业困难人员情况
|
|
|
+async function regionDifficultyOnSearch() {
|
|
|
+ searchLoading.value = true;
|
|
|
+ await getJobUserByRegionAndDifficulty().then((result: any) => {
|
|
|
+ // 保存原始数据
|
|
|
+ regionJobUserData.originalList = result;
|
|
|
+ regionJobUserData.tableList = result;
|
|
|
+
|
|
|
+ let arr: any[] = [];
|
|
|
+ arr.push(['类型', '失业人数', '就业困难人数'])
|
|
|
+ result.forEach((item: any) => {
|
|
|
+ arr.push([item.regionName, item.jobUserCount, item.difficultyCount])
|
|
|
+ })
|
|
|
+
|
|
|
+ // 生成表格
|
|
|
+ setTimeout(() => {
|
|
|
+ initDataSetBarImageTable(arr, [{type: 'bar'}, {type: 'bar'}], 'regionAndDifficultyImageTable', '各区县失业人员与就业困难人员情况统计')
|
|
|
+ }, 100)
|
|
|
+ }).finally(() => {
|
|
|
+ searchLoading.value = false;
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 查询方法变更事件
|
|
|
+function searchTypeChange() {
|
|
|
+ if (searchType.value == 'ageRange') {
|
|
|
+ ageRangeOnSearch();
|
|
|
+ }
|
|
|
+ if (searchType.value == 'personTypeAndCulture') {
|
|
|
+ personTypeOnSearch();
|
|
|
+ }
|
|
|
+ if (searchType.value == 'regionAndDifficulty') {
|
|
|
+ regionDifficultyOnSearch();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ searchTypeChange();
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+// 设置页面名称进行组件缓存
|
|
|
+export default {
|
|
|
+ name: "JobUserCount",
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+
|
|
|
+</style>
|