company.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <template>
  2. <div style="height:100vh; min-height:1080px;">
  3. <!-- 头部 -->
  4. <div class="header">
  5. <h1 style="color: #77F8FF;">惠州市就业驿站大数据</h1>
  6. <div class="time">{{ formattedTime }}</div>
  7. </div>
  8. <!-- 内容区 -->
  9. <div class="body-content">
  10. <!-- 左 -->
  11. <div class="side" style="padding-left: 20px;">
  12. <div class="content-box">
  13. <div class="box-title">企业占比</div>
  14. <div class="chart-box" id="companyPieBox"></div>
  15. </div>
  16. <div class="content-box">
  17. <div class="box-title">岗位占比</div>
  18. <div class="chart-box" id="postPieBox"></div>
  19. </div>
  20. <div class="content-box">
  21. <div class="box-title">全市企业情况</div>
  22. <div class="chart-box" id="companyAndPostCountBox"></div>
  23. </div>
  24. </div>
  25. <!-- 中 -->
  26. <div class="center">
  27. <div class="center-1">
  28. <div class="nav">
  29. <div class="nav-items" @click="goIndex">
  30. <div class="nav-1"></div>
  31. <h2 style="color: #77F8FF;">总体概况</h2></div>
  32. <div class="nav-items nav-active">
  33. <div class="nav-2"></div>
  34. <h2 style="color: #77F8FF;">企业情况</h2></div>
  35. <div class="nav-items">
  36. <div class="nav-3"></div>
  37. <h2 style="color: #77F8FF;">求职情况</h2></div>
  38. <div class="nav-items">
  39. <div class="nav-4"></div>
  40. <h2 style="color: #77F8FF;">服务情况</h2></div>
  41. </div>
  42. <div class="s-box">
  43. <div class="statistics t-1">
  44. <div style="margin: 8px 0 0 18px; position: revert;">
  45. <div class="s-title">岗位数</div>
  46. <div class="s-number">{{ allSystemDataCountList.count.postCount }}</div>
  47. <div class="waves" style="right: -187px; top: 42px"></div>
  48. </div>
  49. </div>
  50. <div class="statistics t-2">
  51. <div style="margin: 8px 0 0 78px; position: revert;">
  52. <div class="s-title">企业数</div>
  53. <div class="s-number">{{ allSystemDataCountList.count.companyCount }}</div>
  54. <div class="waves" style="left: -86px; top: 42px"></div>
  55. </div>
  56. </div>
  57. <div class="statistics t-3">
  58. <div style="margin: 78px 0 0 98px; position: revert;">
  59. <div class="s-title">推荐岗位数</div>
  60. <div class="s-number">{{ allSystemDataCountList.count.jobUserCount }}</div>
  61. <div class="waves" style="left: -106px; top: -141px"></div>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. <div class="center-2">
  67. <div class="box-bigtitle">企业规模情况</div>
  68. <div class="chart-box" id="companyModelCountBox"></div>
  69. </div>
  70. </div>
  71. <!-- 右 -->
  72. <div class="side" style="padding-right: 20px;">
  73. <div class="content-box">
  74. <div class="box-title">本周新增企业</div>
  75. <div class="chart-box">
  76. </div>
  77. </div>
  78. <div class="content-box">
  79. <div class="box-title">本月新增企业</div>
  80. <div class="chart-box">
  81. </div>
  82. </div>
  83. <div class="content-box">
  84. <div class="box-title">本季度新增企业</div>
  85. <div class="chart-box">
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </template>
  92. <script setup lang="ts">
  93. import {computed, onBeforeUnmount, onMounted, ref} from "vue";
  94. import dayjs from "dayjs";
  95. import weekOfYear from 'dayjs/plugin/weekOfYear';
  96. import weekday from 'dayjs/plugin/weekday';
  97. import {getCompanyAndPostByRegion, getCompanyModelCount} from "@/api/statistics";
  98. import {
  99. initDataSetBarImageTable,
  100. initPieImageTable,
  101. initStackBarImageTable,
  102. PieColorData
  103. } from "@/views/dataScreen/echarts";
  104. import {useRouter} from "vue-router";
  105. dayjs.extend(weekOfYear);
  106. dayjs.extend(weekday);
  107. const router = useRouter();
  108. // 全市数据情况
  109. const allSystemDataCountList = ref({
  110. count: {
  111. companyCount: 0,
  112. postCount: 0,
  113. jobUserCount: 0
  114. },
  115. list: []
  116. });
  117. // 实时时间
  118. const currentTime = ref(new Date());
  119. const formattedTime = computed(() => {
  120. const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
  121. const year = currentTime.value.getFullYear();
  122. const month = (currentTime.value.getMonth() + 1).toString().padStart(2, '0');
  123. const date = currentTime.value.getDate().toString().padStart(2, '0');
  124. const day = days[currentTime.value.getDay()];
  125. const hours = currentTime.value.getHours().toString().padStart(2, '0');
  126. const minutes = currentTime.value.getMinutes().toString().padStart(2, '0');
  127. // const seconds = currentTime.value.getSeconds().toString().padStart(2, '0');
  128. return `${year}-${month}-${date} ${day} ${hours}:${minutes}`;
  129. });
  130. // 查询企业与岗位数据
  131. function loadCompanyAndPostCount() {
  132. getCompanyAndPostByRegion({}).then((result: any) => {
  133. // 生成图表需要的数据
  134. let companyArr: any[] = [], postArr: any[] = [], barTableArr = [['区县', '企业数', '岗位数']];
  135. let companyTotal = 0, postTotal = 0;
  136. result.forEach((item: any) => {
  137. if (item.regionName !== "市本级") {
  138. companyTotal += item.companyCount;
  139. postTotal += item.postCount;
  140. const commonData = {
  141. value: item.companyCount,
  142. name: item.regionName,
  143. itemStyle: {color: PieColorData[item.regionName]}
  144. };
  145. if (item.companyCount > 0) {
  146. companyArr.push(commonData);
  147. }
  148. if (item.postCount > 0) {
  149. postArr.push({...commonData, value: item.postCount});
  150. }
  151. barTableArr.push([item.regionName, item.companyCount, item.postCount]);
  152. }
  153. });
  154. // 环形图的中间文本内容
  155. const createTextConfig = (text: string, total: number) => ([
  156. {
  157. type: 'text',
  158. left: 'center',
  159. top: '43%',
  160. style: {fill: 'rgba(119,248,255,0.7)', text, font: 'bold 12px Arial', textAlign: 'center'}
  161. },
  162. {
  163. type: 'text',
  164. left: 'center',
  165. top: '53%',
  166. style: {fill: '#77F8FF', text: total, font: 'bold 16px Arial', textAlign: 'center'}
  167. }
  168. ]);
  169. initPieImageTable(companyArr, createTextConfig('企业数', companyTotal), "companyPieBox", "企业数");
  170. initPieImageTable(postArr, createTextConfig('岗位数', postTotal), "postPieBox", "岗位数");
  171. initDataSetBarImageTable(barTableArr, [
  172. {type: 'bar', barMaxWidth: '10px', color: "#0062cc"},
  173. {type: 'bar', barMaxWidth: '10px', color: '#73ecf3'}
  174. ], 'companyAndPostCountBox', 3);
  175. });
  176. }
  177. // 查询企业规模数据
  178. function loadCompanyModelCount() {
  179. getCompanyModelCount().then((result: any) => {
  180. console.log(result);
  181. // 获取X轴刻度标题,去除重复项,去除“市本级”
  182. const xTitleList = Array.from(new Set(result.map((item: any) => item.regionName))).filter((regionName: string) => regionName !== "市本级");
  183. console.log(xTitleList);
  184. // Y轴的值内容
  185. const yValueList = result.filter((item: any) => item.companyModel != null && item.regionName != '市本级').reduce((acc: any, item: any) => {
  186. if (!acc[item.companyModelName]) {
  187. acc[item.companyModelName] = [];
  188. }
  189. // 将人数填充
  190. acc[item.companyModelName].push(item.companyCount);
  191. return acc;
  192. }, {});
  193. let bars: any[] = [];
  194. let legendList: any[] = [];
  195. for (let key in yValueList) {
  196. legendList.push(key);
  197. bars.push({
  198. name: key,
  199. type: 'bar',
  200. barMaxWidth: '15px',
  201. stack: 'ageRange',
  202. emphasis: {focus: 'series'},
  203. data: yValueList[key]
  204. })
  205. }
  206. initStackBarImageTable(xTitleList, bars, legendList, 'companyModelCountBox')
  207. })
  208. }
  209. // 跳转首页
  210. function goIndex() {
  211. router.push({name: "dataScreenIndex"})
  212. }
  213. onMounted(() => {
  214. loadCompanyAndPostCount();
  215. loadCompanyModelCount();
  216. currentTime.value = new Date();
  217. const timer = setInterval(() => {
  218. currentTime.value = new Date();
  219. }, 1000);
  220. onBeforeUnmount(() => {
  221. clearInterval(timer);
  222. });
  223. })
  224. </script>
  225. <style scoped>
  226. @import url('@/views/dataScreen/html/css/reset.css');
  227. @import url('@/views/dataScreen/html/css/style.css');
  228. </style>