After Width: | Height: | Size: 424 B |
After Width: | Height: | Size: 423 B |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 5.5 KiB |
|
@ -277,8 +277,7 @@ const props = defineProps({
|
|||
},
|
||||
listType: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
default: "1",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["throw-data"]);
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
<div class="logo">管理平台</div>
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li @click="router.push({ path: '/BI' })">
|
||||
<!-- <div v-for="item1 in 4" :key="item1" :class="'horn' + item1" />-->
|
||||
<li @click="router.push({ path: '/large_screen_data_display' })">
|
||||
<div class="title">BI</div>
|
||||
</li>
|
||||
<template v-for="(item, index) in MENU" :key="index">
|
||||
|
@ -13,7 +12,6 @@
|
|||
@click="switchMenu(item.model)"
|
||||
:class="{ active: item.model === menuStore.getModel }"
|
||||
>
|
||||
<!-- <div v-for="item1 in 4" :key="item1" :class="'horn' + item1" />-->
|
||||
<div class="title">{{ item.title }}</div>
|
||||
</li>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import { post } from "@/request/axios.js";
|
||||
|
||||
export const getRiskManagement = (params) =>
|
||||
post("/riskpoint/statistic", params); // 风险管控统计分析
|
||||
export const getTroubleshootingTypeNumber = (params) =>
|
||||
post("/listmanager/countNumBi", params); // 排查类型
|
||||
export const getTroubleshootingTypeEcharts = (params) =>
|
||||
post("/checkrecord/listTypeBi", params); // 排查类型
|
||||
export const getUserUsage = (params) => post("/checkrecord/countNumBi", params); // 企业排查情况
|
||||
export const getTaskProcessingHidden = (params) =>
|
||||
post("/hidden/getBICount", params); // 任务处理情况隐患处理
|
||||
export const getTaskProcessingCheck = (params) =>
|
||||
post("/checkrecord/goBiListCount", params); // 任务处理情况日常检查
|
||||
export const getHiddenCount = (params) => post("/hidden/hiddenSta", params); // 隐患数量
|
||||
export const getAssignmentType = (params) =>
|
||||
post("/eightWork/eightWorkBI", params); // 作业类型
|
||||
export const getVideo = (params) => post("/video/getObjectForBiLogin", params); // 视频中心
|
||||
export const getFullStaffTraining = (params) =>
|
||||
post("/studytask/BIstatistics", params); // 全员培训统计
|
||||
export const getExamStatisticsUser = (params) =>
|
||||
post("/performanceexamine_user/list", params); // 考核情况统计用户
|
||||
export const getExamStatisticsDepartment = (params) =>
|
||||
post("/performanceexamine_dept/list", params); // 考核情况统计部门
|
|
@ -35,6 +35,16 @@ const routes = [
|
|||
meta: { title: "BI", isBreadcrumb: false, isMenu: false },
|
||||
component: () => import("@/views/BI/index"),
|
||||
},
|
||||
{
|
||||
path: "/large_screen_data_display",
|
||||
name: "/large_screen_data_display",
|
||||
meta: {
|
||||
title: "large_screen_data_display",
|
||||
isBreadcrumb: false,
|
||||
isMenu: false,
|
||||
},
|
||||
component: () => import("@/views/large_screen_data_display/index"),
|
||||
},
|
||||
{
|
||||
path: "/mobile",
|
||||
meta: { isBreadcrumb: false, isMenu: false, isLogin: false },
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<layout-card>
|
||||
<div id="printContent">
|
||||
<el-divider content-position="left">检查信息</el-divider>
|
||||
<el-descriptions border>
|
||||
<el-descriptions border :column="2">
|
||||
<el-descriptions-item label="隐患照片 ">
|
||||
<img
|
||||
v-viewer
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<layout-card>
|
||||
<div id="printContent">
|
||||
<el-divider content-position="left">检查信息</el-divider>
|
||||
<el-descriptions border>
|
||||
<el-descriptions border :column="2">
|
||||
<el-descriptions-item label="隐患照片 ">
|
||||
<img
|
||||
v-viewer
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<layout-card>
|
||||
<div id="printContent">
|
||||
<el-divider content-position="left">检查信息</el-divider>
|
||||
<el-descriptions border>
|
||||
<el-descriptions border :column="2">
|
||||
<el-descriptions-item label="处罚原因 ">
|
||||
{{ data.info.REASON }}
|
||||
</el-descriptions-item>
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<template>
|
||||
<div class="assignment_type">
|
||||
<div class="title">作业类型</div>
|
||||
<div id="main4" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getAssignmentType } from "@/request/large_screen_data_display.js";
|
||||
import { onMounted } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const fnGetData = async () => {
|
||||
const resData = await getAssignmentType();
|
||||
fnInitEcharts(resData.count);
|
||||
};
|
||||
onMounted(() => {
|
||||
fnGetData();
|
||||
});
|
||||
const fnInitEcharts = (data) => {
|
||||
const myChart = echarts.init(document.querySelector("#main4"));
|
||||
const option = {
|
||||
color: [
|
||||
"#459AF0",
|
||||
"#38C3B0",
|
||||
"#86CA5A",
|
||||
"#BFD44F",
|
||||
"#FCC248",
|
||||
"#FCE448",
|
||||
"#F58B41",
|
||||
"#F7765B",
|
||||
],
|
||||
legend: {
|
||||
orient: "vertical",
|
||||
right: "20",
|
||||
top: "center",
|
||||
data: [
|
||||
"盲板抽堵作业",
|
||||
"动土作业",
|
||||
"受限空间作业",
|
||||
"临时用电作业",
|
||||
"断路作业",
|
||||
"高处作业",
|
||||
"吊装作业",
|
||||
"动火作业",
|
||||
],
|
||||
textStyle: {
|
||||
color: "#2aaef2",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
formatter: "{b} {c} <br />{d}%",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "",
|
||||
type: "pie",
|
||||
radius: ["0%", "80%"],
|
||||
center: ["30%", "50%"],
|
||||
label: {
|
||||
show: true,
|
||||
position: "inside",
|
||||
formatter: (params) => {
|
||||
return `${params.percent}%`;
|
||||
},
|
||||
},
|
||||
labelLine: {
|
||||
show: false,
|
||||
},
|
||||
data: [
|
||||
{ value: data.blindboard_num, name: "盲板抽堵作业" },
|
||||
{ value: data.breakground_num, name: "动土作业" },
|
||||
{ value: data.confinedspace_num, name: "受限空间作业" },
|
||||
{ value: data.electricity_num, name: "临时用电作业" },
|
||||
{ value: data.cutroad_num, name: "断路作业" },
|
||||
{ value: data.highwork_num, name: "高处作业" },
|
||||
{ value: data.hoisting_num, name: "吊装作业" },
|
||||
{ value: data.hotwork_num, name: "动火作业" },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
myChart.setOption(option);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.assignment_type {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/C-2.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 212px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#main4 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<div class="exam_statistics">
|
||||
<div class="title">考核情况统计(月)</div>
|
||||
<div class="content">
|
||||
<div class="tabs">
|
||||
<div
|
||||
v-for="(item, index) in tabsList"
|
||||
:key="index"
|
||||
:class="['tab', { active: index === tabsIndex }]"
|
||||
@click="tabsIndex = index"
|
||||
>
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名次</th>
|
||||
<th v-if="tabsIndex === 0">姓名</th>
|
||||
<th v-if="tabsIndex === 1">部门</th>
|
||||
<th>等级</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(item, index) in tabsIndex === 0 ? userList : departmentList"
|
||||
:key="index"
|
||||
>
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td v-if="tabsIndex === 0">
|
||||
{{ item.DEPT_NAME_ALL }} - {{ item.USER_NAME }}
|
||||
</td>
|
||||
<td v-if="tabsIndex === 1">{{ item.DEPT_NAME_ALL }}</td>
|
||||
<td>
|
||||
{{
|
||||
fnComputeLevel(
|
||||
item.SCORE1 +
|
||||
item.SCORE2 +
|
||||
item.SCORE3 +
|
||||
item.SCORE4 +
|
||||
item.SCORE5
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getExamStatisticsDepartment,
|
||||
getExamStatisticsUser,
|
||||
} from "@/request/large_screen_data_display.js";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const tabsList = ["人员考核成绩", "部门考核成绩"];
|
||||
const tabsIndex = ref(0);
|
||||
const { list: userList } = useListData(getExamStatisticsUser, {
|
||||
otherParams: {
|
||||
MONTH: dayjs().subtract(1, "months").format("YYYY-MM"),
|
||||
},
|
||||
});
|
||||
const { list: departmentList } = useListData(getExamStatisticsDepartment, {
|
||||
otherParams: {
|
||||
MONTH: dayjs().subtract(1, "months").format("YYYY-MM"),
|
||||
},
|
||||
});
|
||||
const fnComputeLevel = (total) => {
|
||||
if (total >= 75) return "一级";
|
||||
else if (total >= 50) return "二级";
|
||||
else if (total >= 25) return "三级";
|
||||
else return "四级";
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.exam_statistics {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/R-3.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 357px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 15px;
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
padding-top: 15px;
|
||||
|
||||
.tab {
|
||||
width: 116px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
background-image: url("/src/assets/images/bi/tab-1.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-image: url("/src/assets/images/bi/tab-2.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
text-align: center;
|
||||
|
||||
thead {
|
||||
th {
|
||||
color: #14a3dd;
|
||||
padding: 4px 0;
|
||||
background-color: rgba(241, 241, 241, 0.059);
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr:nth-child(even) {
|
||||
background-color: rgba(241, 241, 241, 0.059);
|
||||
}
|
||||
|
||||
td {
|
||||
color: #d4eaf6;
|
||||
padding: 4px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<div class="full_staff_training">
|
||||
<div class="title">全员培训统计</div>
|
||||
<div id="main6" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getFullStaffTraining } from "@/request/large_screen_data_display.js";
|
||||
import { onMounted } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const fnGetData = async () => {
|
||||
const resData = await getFullStaffTraining();
|
||||
fnInitEcharts(resData.varList);
|
||||
};
|
||||
onMounted(() => {
|
||||
fnGetData();
|
||||
});
|
||||
const fnInitEcharts = (data) => {
|
||||
const myChart = echarts.init(document.querySelector("#main6"));
|
||||
const xData = [];
|
||||
const yData = [];
|
||||
data.forEach((item) => {
|
||||
xData.push(item.NAME);
|
||||
yData.push(item.count);
|
||||
});
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ["各培训类型学习人数"],
|
||||
top: "15",
|
||||
textStyle: {
|
||||
color: "#2aaef2",
|
||||
},
|
||||
orient: "horizontal",
|
||||
},
|
||||
grid: {
|
||||
top: "25%",
|
||||
right: "3%",
|
||||
left: "10%",
|
||||
bottom: "10%",
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xData,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "rgba(255,255,255,0.12)",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
margin: 10,
|
||||
color: "#e2e9ff",
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
name: "",
|
||||
nameTextStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: "{value}",
|
||||
color: "#e2e9ff",
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "rgba(255,255,255,0.12)",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "各培训类型学习数",
|
||||
type: "bar",
|
||||
data: yData,
|
||||
barWidth: "10px",
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
[
|
||||
{
|
||||
offset: 0,
|
||||
color: "#4abd91", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "#28b2d5", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
false
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
myChart.setOption(option);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.full_staff_training {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/R-2.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 190px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#main6 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div class="header">
|
||||
<div class="date">
|
||||
<span> {{ dayjs(now).format("YYYY-MM-DD") }}</span>
|
||||
<span class="pl-10">{{ dayjs(now).format("HH:mm:ss") }}</span>
|
||||
<span class="pl-10"> {{ weekList[dayjs(now).day()] }}</span>
|
||||
</div>
|
||||
<div class="title" />
|
||||
<div class="options">
|
||||
<div @click="router.push({ path: 'BI' })">
|
||||
<icon-world theme="outline" size="18" fill="#2aa7d3" />
|
||||
<span class="ml-5">地图</span>
|
||||
</div>
|
||||
<div class="ml-20" @click="router.back()">
|
||||
<icon-logout theme="outline" size="18" fill="#2aa7d3" />
|
||||
<span class="ml-5" style="vertical-align: center">退出</span>
|
||||
</div>
|
||||
<div class="ml-20">
|
||||
<div v-if="!isFullscreen" @click="enter">
|
||||
<icon-full-screen-one theme="outline" size="18" fill="#2aa7d3" />
|
||||
<span class="ml-5">全屏</span>
|
||||
</div>
|
||||
<div v-else @click="exit">
|
||||
<icon-off-screen theme="outline" size="18" fill="#2aa7d3" />
|
||||
<span class="ml-5">退出全屏</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import { useFullscreen, useNow } from "@vueuse/core";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
const { now } = useNow({ controls: true });
|
||||
const { isFullscreen, exit, enter } = useFullscreen();
|
||||
const weekList = {
|
||||
0: "星期日",
|
||||
1: "星期一",
|
||||
2: "星期二",
|
||||
3: "星期三",
|
||||
4: "星期四",
|
||||
5: "星期五",
|
||||
6: "星期六",
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header {
|
||||
position: relative;
|
||||
color: #2aa7d3;
|
||||
|
||||
.title {
|
||||
background-image: url("/src/assets/images/bi/title.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 1436px;
|
||||
height: 164px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.date {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.options {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
|
||||
div {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,179 @@
|
|||
<template>
|
||||
<div class="hidden_danger_situation">
|
||||
<div class="title">隐患情况统计</div>
|
||||
<div id="main5" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getHiddenCount } from "@/request/large_screen_data_display.js";
|
||||
import { onMounted } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const fnGetData = async () => {
|
||||
const resData = await getHiddenCount();
|
||||
fnInitEcharts(resData);
|
||||
};
|
||||
onMounted(() => {
|
||||
fnGetData();
|
||||
});
|
||||
const fnInitEcharts = (data) => {
|
||||
const myChart = echarts.init(document.querySelector("#main5"));
|
||||
const colorList = ["#f6f644", "#ea5514", "#00b6ce", "#33ff00"];
|
||||
const option = {
|
||||
title: {
|
||||
text: "",
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 400,
|
||||
color: "#2aaef2",
|
||||
},
|
||||
left: "0",
|
||||
top: "5%",
|
||||
},
|
||||
legend: {
|
||||
icon: "rect",
|
||||
top: "5%",
|
||||
right: "5%",
|
||||
itemWidth: 12,
|
||||
itemHeight: 12,
|
||||
itemGap: 20,
|
||||
textStyle: {
|
||||
color: "#2aaef2",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
grid: {
|
||||
top: "25%",
|
||||
bottom: "20%",
|
||||
left: "7%",
|
||||
right: "5%",
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: "category",
|
||||
data: data.names,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#DCE2E8",
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
fontSize: 12,
|
||||
margin: 15,
|
||||
},
|
||||
boundaryGap: false,
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#DCE2E8",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: "隐患总数",
|
||||
type: "line",
|
||||
data: data.all,
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: colorList[0],
|
||||
borderColor: colorList[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "未整改隐患数",
|
||||
type: "line",
|
||||
data: data.wzg,
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: colorList[1],
|
||||
borderColor: colorList[1],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "已整改隐患数",
|
||||
type: "line",
|
||||
data: data.yzg,
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: colorList[2],
|
||||
borderColor: colorList[2],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "已验收隐患数",
|
||||
type: "line",
|
||||
data: data.yys,
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: colorList[3],
|
||||
borderColor: colorList[3],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
myChart.setOption(option);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.hidden_danger_situation {
|
||||
background-image: url("/src/assets/images/bi/R-1.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 190px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#main5 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<div class="risk_management">
|
||||
<div class="title">风险管控统计分析</div>
|
||||
<div class="round-box">
|
||||
<div class="content">
|
||||
<h1>{{ info.unitcount }}</h1>
|
||||
<span>风险点(单元)</span>
|
||||
</div>
|
||||
<div class="round-jt" />
|
||||
<div class="content">
|
||||
<h1>{{ info.idcount }}</h1>
|
||||
<span>辨识部位</span>
|
||||
</div>
|
||||
<div class="round-jt" />
|
||||
<div class="content">
|
||||
<h1>
|
||||
{{ info.acount + info.bcount + info.ccount + info.dcount }}
|
||||
</h1>
|
||||
<span>存在风险</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { getRiskManagement } from "@/request/large_screen_data_display.js";
|
||||
|
||||
const info = ref({
|
||||
unitcount: 0,
|
||||
idcount: 0,
|
||||
acount: 0,
|
||||
bcount: 0,
|
||||
ccount: 0,
|
||||
dcount: 0,
|
||||
});
|
||||
|
||||
const fnGetData = async () => {
|
||||
const resData = await getRiskManagement();
|
||||
if (resData.idAll && resData.idAll.length > 0)
|
||||
info.value.idcount = resData.idAll.length;
|
||||
if (resData.unitAll && resData.unitAll.length > 0)
|
||||
info.value.unitcount = resData.unitAll.length;
|
||||
const key = {
|
||||
levelA: "acount",
|
||||
levelB: "bcount",
|
||||
levelC: "ccount",
|
||||
levelD: "dcount",
|
||||
};
|
||||
resData.riskAll.forEach((item) => {
|
||||
info.value[key[item.LEVELID]] = item.COUNT;
|
||||
});
|
||||
};
|
||||
fnGetData();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.risk_management {
|
||||
background-image: url("/src/assets/images/bi/L-1.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 185px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.round-box {
|
||||
padding: 15px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.content {
|
||||
background-image: url("/src/assets/images/bi/yuanl.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 97px;
|
||||
height: 97px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
|
||||
h1 {
|
||||
padding-top: 25px;
|
||||
color: #70c5ff;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
color: #aaddff;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
bottom: -19px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.round-jt {
|
||||
background-image: url("/src/assets/images/bi/jt-right.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 20px;
|
||||
height: 29px;
|
||||
margin: 0 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,126 @@
|
|||
<template>
|
||||
<div class="situation">
|
||||
<div class="title">双重预防建设情况</div>
|
||||
<div class="map"></div>
|
||||
<div class="statistics">
|
||||
<div class="item">
|
||||
<div>
|
||||
<img src="/src/assets/images/bi/faxianico.png" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ info.all }}</span>
|
||||
<span>发现隐患数</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div>
|
||||
<img src="/src/assets/images/bi/noonico.png" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ info.wzg }}</span>
|
||||
<span>未完成整改隐患</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div>
|
||||
<img src="/src/assets/images/bi/yinhuan.png" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
{{
|
||||
info.all !== 0 ? ((info.wzg / info.all) * 100).toFixed(2) : 0.0
|
||||
}}%
|
||||
</span>
|
||||
<span>未整改率</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { getHiddenCount } from "@/request/large_screen_data_display.js";
|
||||
|
||||
const info = ref({
|
||||
all: 0,
|
||||
wzg: 0,
|
||||
yzg: 0,
|
||||
yys: 0,
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
const resData = await getHiddenCount();
|
||||
for (let i = 0; i < resData.all.length; i++) {
|
||||
info.value.all += Number(resData.all[i]);
|
||||
}
|
||||
for (let i = 0; i < resData.wzg.length; i++) {
|
||||
info.value.wzg += Number(resData.wzg[i]);
|
||||
}
|
||||
for (let i = 0; i < resData.yzg.length; i++) {
|
||||
info.value.yzg += Number(resData.yzg[i]);
|
||||
}
|
||||
for (let i = 0; i < resData.yys.length; i++) {
|
||||
info.value.yys += Number(resData.yys[i]);
|
||||
}
|
||||
};
|
||||
fnGetData();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.situation {
|
||||
background-image: url("/src/assets/images/bi/C-1.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 540px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.map {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.statistics {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
.item {
|
||||
flex-basis: 30%;
|
||||
border: 4px solid #0d2565;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
|
||||
img {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
margin-left: 10px;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
|
||||
&:first-child {
|
||||
color: #f8b62d;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,311 @@
|
|||
<template>
|
||||
<div class="task_processing">
|
||||
<div class="title">任务处理情况</div>
|
||||
<div class="tabs">
|
||||
<div
|
||||
v-for="(item, index) in tabsList"
|
||||
:key="index"
|
||||
:class="['tab', { active: index === tabsIndex }]"
|
||||
@click="fnChangeTabs(index)"
|
||||
>
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-carousel :autoplay="false" indicator-position="none" height="182px">
|
||||
<el-carousel-item v-for="item1 in 2" :key="item1">
|
||||
<template v-for="(item, index) in tabsContentList" :key="index">
|
||||
<div
|
||||
v-if="(item1 === 1 && index < 3) || (item1 === 2 && index >= 3)"
|
||||
class="item"
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
<img :src="item.img" alt="" />
|
||||
</div>
|
||||
<div class="item_title">{{ item.title1 }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ item.title2 }}</div>
|
||||
<div class="data">{{ item.dayUncheck }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ item.title3 }}</div>
|
||||
<div class="data">{{ item.dayChecked }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ item.title4 }}</div>
|
||||
<div class="data proportion">
|
||||
<span>{{ item.proportion }}</span>
|
||||
<span>%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import {
|
||||
getTaskProcessingCheck,
|
||||
getTaskProcessingHidden,
|
||||
} from "@/request/large_screen_data_display.js";
|
||||
|
||||
const tabsList = ["隐患处理", "日常检查"];
|
||||
const tabsIndex = ref(0);
|
||||
const hiddenDangersList = ref([
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri.png", import.meta.url).href,
|
||||
title1: "本日隐患",
|
||||
title2: "待处理",
|
||||
title3: "已处理",
|
||||
title4: "隐患整改率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri2.png", import.meta.url).href,
|
||||
title1: "本周隐患",
|
||||
title2: "待处理",
|
||||
title3: "已处理",
|
||||
title4: "隐患整改率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri3.png", import.meta.url).href,
|
||||
title1: "本旬隐患",
|
||||
title2: "待处理",
|
||||
title3: "已处理",
|
||||
title4: "隐患整改率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri4.png", import.meta.url).href,
|
||||
title1: "本月隐患",
|
||||
title2: "待处理",
|
||||
title3: "已处理",
|
||||
title4: "隐患整改率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri5.png", import.meta.url).href,
|
||||
title1: "本季隐患",
|
||||
title2: "待处理",
|
||||
title3: "已处理",
|
||||
title4: "隐患整改率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri6.png", import.meta.url).href,
|
||||
title1: "本年隐患",
|
||||
title2: "待处理",
|
||||
title3: "已处理",
|
||||
title4: "隐患整改率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
]);
|
||||
const dailyInspectionList = ref([
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri.png", import.meta.url).href,
|
||||
title1: "本日应检查",
|
||||
title2: "待检查",
|
||||
title3: "已检查",
|
||||
title4: "本日完成率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri2.png", import.meta.url).href,
|
||||
title1: "本周应检查",
|
||||
title2: "待检查",
|
||||
title3: "已检查",
|
||||
title4: "本周完成率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri3.png", import.meta.url).href,
|
||||
title1: "本旬应检查",
|
||||
title2: "待检查",
|
||||
title3: "已检查",
|
||||
title4: "本旬完成率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri4.png", import.meta.url).href,
|
||||
title1: "本月应检查",
|
||||
title2: "待检查",
|
||||
title3: "已检查",
|
||||
title4: "本月完成率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri5.png", import.meta.url).href,
|
||||
title1: "本季应检查",
|
||||
title2: "待检查",
|
||||
title3: "已检查",
|
||||
title4: "本季完成率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
{
|
||||
img: new URL("/src/assets/images/bi/ri6.png", import.meta.url).href,
|
||||
title1: "本年应检查",
|
||||
title2: "待检查",
|
||||
title3: "已检查",
|
||||
title4: "本年完成率",
|
||||
dayChecked: 0,
|
||||
dayUncheck: 0,
|
||||
proportion: 0,
|
||||
},
|
||||
]);
|
||||
const tabsContentList = ref(hiddenDangersList.value);
|
||||
const fnChangeTabs = (index) => {
|
||||
tabsIndex.value = index;
|
||||
tabsContentList.value =
|
||||
index === 0 ? hiddenDangersList.value : dailyInspectionList.value;
|
||||
};
|
||||
const fnGetDataHidden = async () => {
|
||||
const key = {
|
||||
0: "IS_DAY",
|
||||
1: "IS_WEEK",
|
||||
2: "IS_XUN",
|
||||
3: "IS_MONTH",
|
||||
4: "IS_QUARTER",
|
||||
5: "IS_YEAR",
|
||||
};
|
||||
for (const keyKey in key) {
|
||||
const resData = await getTaskProcessingHidden({ [key[keyKey]]: 1 });
|
||||
hiddenDangersList.value[keyKey].dayChecked = resData.checked;
|
||||
hiddenDangersList.value[keyKey].dayUncheck = resData.uncheck;
|
||||
hiddenDangersList.value[keyKey].proportion =
|
||||
resData.total === 0
|
||||
? 0
|
||||
: ((resData.checked / resData.total) * 100).toFixed(2);
|
||||
}
|
||||
};
|
||||
fnGetDataHidden();
|
||||
const fnGetDataCheck = async () => {
|
||||
const key = {
|
||||
0: "day",
|
||||
1: "week",
|
||||
2: "xun",
|
||||
3: "month",
|
||||
4: "quarter",
|
||||
5: "year",
|
||||
};
|
||||
for (const keyKey in key) {
|
||||
const resData = await getTaskProcessingCheck({ COUNTTYPE: key[keyKey] });
|
||||
dailyInspectionList.value[keyKey].dayUncheck =
|
||||
resData.all.denominator - resData.all.molecule;
|
||||
dailyInspectionList.value[keyKey].dayChecked = resData.all.molecule;
|
||||
dailyInspectionList.value[keyKey].proportion = resData.all.percentage;
|
||||
}
|
||||
};
|
||||
fnGetDataCheck();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.task_processing {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/L-4.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 236px;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
padding-top: 20px;
|
||||
|
||||
.tab {
|
||||
width: 116px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
background-image: url("/src/assets/images/bi/tab-1.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-image: url("/src/assets/images/bi/tab-2.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 20px 20px 20px;
|
||||
color: #aaddff;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #1e3677;
|
||||
padding: 7px 0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
}
|
||||
|
||||
.data {
|
||||
padding-top: 7px;
|
||||
font-size: 20px;
|
||||
|
||||
&.proportion {
|
||||
color: #ffb956;
|
||||
|
||||
span:last-child {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,205 @@
|
|||
<template>
|
||||
<div class="troubleshooting_type">
|
||||
<div class="title">排查类型</div>
|
||||
<div class="p-20">
|
||||
<div class="top">
|
||||
<div>
|
||||
<div>现场类清单数</div>
|
||||
<div>{{ info["现场清单"] || 0 }}个</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>基础类清单数</div>
|
||||
<div>{{ info["基础类清单"] || 0 }}个</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>综合类清单数</div>
|
||||
<div>{{ info["综合类清单"] || 0 }}个</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div>
|
||||
<div class="dunpai1" />
|
||||
<div class="bottom_title">现场排查数</div>
|
||||
<div id="main1" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="dunpai2" />
|
||||
<div class="bottom_title">基础排查数</div>
|
||||
<div id="main2" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="dunpai3" />
|
||||
<div class="bottom_title">综合排查数</div>
|
||||
<div id="main3" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import {
|
||||
getTroubleshootingTypeEcharts,
|
||||
getTroubleshootingTypeNumber,
|
||||
} from "@/request/large_screen_data_display.js";
|
||||
import { sumBy } from "lodash-es";
|
||||
import { arrayObjectDeduplication } from "@/assets/js/utils.js";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const info = ref({});
|
||||
|
||||
const fnGetData = async () => {
|
||||
const resDataNumber = await getTroubleshootingTypeNumber();
|
||||
resDataNumber.typeList.forEach((item) => {
|
||||
info.value[item.NAME] = item.count;
|
||||
});
|
||||
const resDataEcharts = await getTroubleshootingTypeEcharts();
|
||||
const total = sumBy(resDataEcharts.typeList, (item) => item.count);
|
||||
const key = {
|
||||
现场清单: { color: "#ec2c26", el: "#main1" },
|
||||
基础类清单: { color: "#ea4e26", el: "#main2" },
|
||||
综合类清单: { color: "#ea6e27", el: "#main3" },
|
||||
};
|
||||
const typeList = [
|
||||
...resDataEcharts.typeList,
|
||||
{ count: 0, NAME: "现场清单" },
|
||||
{ count: 0, NAME: "基础类清单" },
|
||||
{ count: 0, NAME: "综合类清单" },
|
||||
];
|
||||
arrayObjectDeduplication(typeList, "NAME").forEach((item) => {
|
||||
fnInitEcharts(item.count, total, key[item.NAME].color, key[item.NAME].el);
|
||||
});
|
||||
};
|
||||
onMounted(() => {
|
||||
fnGetData();
|
||||
});
|
||||
const fnInitEcharts = (count, total, color, el) => {
|
||||
const myChart = echarts.init(document.querySelector(el));
|
||||
const option = {
|
||||
grid: {
|
||||
left: "10%",
|
||||
right: "0%",
|
||||
bottom: "0%",
|
||||
top: "100%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
show: false,
|
||||
type: "value",
|
||||
},
|
||||
yAxis: {
|
||||
type: "category",
|
||||
show: false,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "次数",
|
||||
type: "bar",
|
||||
zlevel: 1,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
barBorderRadius: 0,
|
||||
color,
|
||||
},
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: "inside",
|
||||
},
|
||||
barWidth: 15,
|
||||
data: [count],
|
||||
},
|
||||
{
|
||||
name: "背景",
|
||||
type: "bar",
|
||||
barWidth: 15,
|
||||
barGap: "-100%",
|
||||
data: [total],
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: "#101f48",
|
||||
barBorderRadius: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
myChart.setOption(option);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.troubleshooting_type {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/L-2.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 190px;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
> div {
|
||||
flex-basis: 32%;
|
||||
border: 4px solid #0d2565;
|
||||
padding: 5px 20px 5px 5px;
|
||||
|
||||
div:nth-child(1) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
color: #04cbfd;
|
||||
text-align: right;
|
||||
padding-top: 5px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
color: #fff;
|
||||
|
||||
> div {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.bottom_title {
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
@for $i from 1 through 3 {
|
||||
.dunpai#{$i} {
|
||||
background-image: url("/src/assets/images/bi/dunpai#{$i}.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 18px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#main1,
|
||||
#main2,
|
||||
#main3 {
|
||||
flex: 1;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<div class="user_usage">
|
||||
<div class="title">企业排查情况</div>
|
||||
<div class="content">
|
||||
<div>
|
||||
<div>企业人员数</div>
|
||||
<div>
|
||||
<span>{{ info.workUser }}/{{ info.allUser }}</span>
|
||||
<span>个</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>使用率</span>
|
||||
<span>
|
||||
{{
|
||||
info.allUser !== 0
|
||||
? ((info.workUser / info.allUser) * 100).toFixed(2)
|
||||
: 0.0
|
||||
}}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>部门</div>
|
||||
<div>
|
||||
<span>{{ info.workDep }}/{{ info.allDep }}</span>
|
||||
<span>个</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>使用率</span>
|
||||
<span>
|
||||
{{
|
||||
info.allDep !== 0
|
||||
? ((info.workDep / info.allDep) * 100).toFixed(2)
|
||||
: 0.0
|
||||
}}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>清单</div>
|
||||
<div>
|
||||
<span>{{ info.workList }}/{{ info.allList }}</span>
|
||||
<span>个</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>使用率</span>
|
||||
<span>
|
||||
{{
|
||||
info.allList !== 0
|
||||
? ((info.workList / info.allList) * 100).toFixed(2)
|
||||
: 0.0
|
||||
}}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { getUserUsage } from "@/request/large_screen_data_display.js";
|
||||
|
||||
const info = ref({});
|
||||
|
||||
const fnGetData = async () => {
|
||||
const resData = await getUserUsage();
|
||||
info.value.allUser = resData.allUser;
|
||||
info.value.workUser = resData.workUser;
|
||||
info.value.allDep = resData.allDep;
|
||||
info.value.workDep = resData.workDep;
|
||||
info.value.allList = resData.allList;
|
||||
info.value.workList = resData.workList;
|
||||
};
|
||||
fnGetData();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.user_usage {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/L-3.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 108px;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #fff;
|
||||
|
||||
> div {
|
||||
flex-basis: 32%;
|
||||
background-color: #061e55;
|
||||
padding: 5px 15px;
|
||||
|
||||
div {
|
||||
padding-top: 5px;
|
||||
|
||||
&:first-child {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
span:nth-child(1) {
|
||||
color: #f8b62d;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
div:nth-child(3) {
|
||||
span:nth-child(2) {
|
||||
color: #f8b62d;
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,97 @@
|
|||
<template>
|
||||
<div class="video_center">
|
||||
<div class="title">视频中心</div>
|
||||
<div class="tabs">
|
||||
<div
|
||||
v-for="(item, index) in tabsList"
|
||||
:key="index"
|
||||
:class="['tab', { active: index === tabsIndex }]"
|
||||
@click="tabsIndex = index"
|
||||
>
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="video">
|
||||
<ali-player
|
||||
:source="VITE_FILE_URL + ptVideoSrc"
|
||||
v-if="tabsIndex === 0 && ptVideoSrc"
|
||||
height="182px"
|
||||
/>
|
||||
<ali-player
|
||||
:source="VITE_FILE_URL + cpVideoSrc"
|
||||
v-if="tabsIndex === 1 && cpVideoSrc"
|
||||
height="182px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { getVideo } from "@/request/large_screen_data_display.js";
|
||||
import AliPlayer from "@/components/ali-player/index.vue";
|
||||
|
||||
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
|
||||
const tabsList = ["平台视频", "企业视频"];
|
||||
const tabsIndex = ref(0);
|
||||
const ptVideoSrc = ref("");
|
||||
const cpVideoSrc = ref("");
|
||||
const fnGetData = async () => {
|
||||
const resData = await getVideo();
|
||||
ptVideoSrc.value = resData.ptVarList?.[0]?.FILEPATH;
|
||||
cpVideoSrc.value = resData.cpvarList?.[0]?.FILEPATH;
|
||||
};
|
||||
fnGetData();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.video_center {
|
||||
margin-top: 15px;
|
||||
background-image: url("/src/assets/images/bi/C-3.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 212px;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
color: #34dcfc;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: 20px;
|
||||
|
||||
.tab {
|
||||
width: 95px;
|
||||
height: 19px;
|
||||
line-height: 19px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
background-image: url("/src/assets/images/bi/558.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&.active {
|
||||
background-image: url("/src/assets/images/bi/559.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.video {
|
||||
width: 95%;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<div class="main_container p-20" id="main_container">
|
||||
<header-view />
|
||||
<div class="main_content">
|
||||
<div class="left">
|
||||
<risk-management />
|
||||
<troubleshooting-type />
|
||||
<user-usage />
|
||||
<task-processing />
|
||||
</div>
|
||||
<div class="center">
|
||||
<situation />
|
||||
<div class="flex">
|
||||
<assignment-type class="mr-5" />
|
||||
<video-center class="ml-5" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<hidden-danger-situation />
|
||||
<full-staff-training />
|
||||
<exam-statistics />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onBeforeUnmount, onMounted } from "vue";
|
||||
import autofit from "autofit.js";
|
||||
import HeaderView from "./components/header.vue";
|
||||
import RiskManagement from "./components/risk_management.vue";
|
||||
import TroubleshootingType from "./components/troubleshooting_type.vue";
|
||||
import UserUsage from "./components/user_usage.vue";
|
||||
import TaskProcessing from "./components/task_processing.vue";
|
||||
import Situation from "./components/situation.vue";
|
||||
import AssignmentType from "./components/assignment_type.vue";
|
||||
import videoCenter from "./components/video_center.vue";
|
||||
import HiddenDangerSituation from "./components/hidden_danger_situation.vue";
|
||||
import FullStaffTraining from "./components/full_staff_training.vue";
|
||||
import ExamStatistics from "./components/exam_statistics.vue";
|
||||
|
||||
onMounted(() => {
|
||||
autofit.init({
|
||||
dh: document.querySelector("#main_container").offsetHeight,
|
||||
dw: 1920,
|
||||
el: "#main_container",
|
||||
resize: true,
|
||||
});
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
autofit.off();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.main_container {
|
||||
background-image: url("/src/assets/images/bi/bg.jpg");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
font-size: 14px;
|
||||
|
||||
.main_content {
|
||||
margin-top: -50px;
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
flex-basis: 25%;
|
||||
}
|
||||
|
||||
.center {
|
||||
flex-basis: 50%;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex-basis: 25%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|