|
@@ -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>
|