2025-08-30 16:32:27 +08:00

611 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="LeftTopBox">
<div class="rightEcharts">
<!-- 今日作业人员趋势 -->
<Card title="按分包单位统计工人出勤">
<div class="rightHeader">
<div class="search-item">
<el-date-picker
v-model="rangeTime"
type="date"
size="small"
:clearable="false"
value-format="YYYY-MM-DD"
@change="timeChange"
>
</el-date-picker>
</div>
</div>
<div id="eacherTop" ref="eacherTop" style="width: 100%; height: 100%"></div>
</Card>
<!-- <div class="show-more" @click="openDialogHistoryData('人员总览')">人员总览</div> -->
</div>
</div>
</template>
<script lang="ts" setup>
import Card from "@/components/card.vue";
import { COMPANY } from "@/config/config";
import * as echarts from "echarts";
import { onMounted, reactive, ref, nextTick } from "vue";
import { getCountNumByEnterpriseWorkerDailyAttendanceStatisticsV2Api } from "@/api/modules/labor";
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
dayjs.extend(isBetween);
import { GlobalStore } from "@/stores";
const BASEURL = import.meta.env.VITE_API_URL;
const store = GlobalStore();
const emits = defineEmits(["openDialog"]);
const rangeTime = ref(dayjs().subtract(1, "day").format("YYYY-MM-DD"));
const timeChange = (e: any) => {
getQueryTodayList();
};
function drawChart(result: any) {
let dom = document.getElementById("eacherTop");
if (!dom) return;
console.log(11334455, result);
let eacherTop = echarts.init(dom);
const option = {
grid: {
top: "8%",
left: "4%",
right: "5%",
bottom: "12%"
// containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
crossStyle: {
color: "#ffffff"
}
}
},
// legend: {
// x: "left",
// padding: [13, 13, 13, 13],
// textStyle: {
// color: "#ffffff"
// },
// data: result.map(item => item.enterpriseName)
// },
xAxis: [
{
type: "category",
data: result.map(item => item.enterpriseName),
axisPointer: {
type: "shadow"
},
axisLine: {
show: true,
lineStyle: {
color: "#14346C"
}
},
axisLabel: {
color: "#fff"
}
}
],
yAxis: [
{
type: "value",
splitNumber: 5,
axisLabel: {
color: "#fff",
formatter: "{value}"
},
splitLine: {
show: true,
lineStyle: {
color: "#14346C"
}
},
axisLine: {
show: true,
lineStyle: {
color: "#14346C"
}
}
}
],
animationDurationUpdate: 500,
series: {
type: "bar",
id: "sales",
itemStyle: {
color: new echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: "rgba(0,99,248,0.3)"
},
{
offset: 1,
color: "#00B1F8"
}
],
false
)
},
label: {
normal: {
show: true, // 显示label
position: "top", // 显示的label的位置
color: "#00B0F8"
}
},
symbolSize: 12,
data: result.map(item => {
return {
value: item.workerCount || 0,
groupId: item.enterpriseId
};
}),
universalTransition: {
enabled: true,
divideShape: "clone"
}
},
dataZoom: [
{
type: "slider", //隐藏或显示true组件
show: result.length > 6 ? true : false,
// backgroundColor: "rgb(19, 63, 100)", // 组件的背景颜色。
// fillerColor: "rgb(16, 171, 198)", // 选中范围的填充颜色。
// borderColor: "rgb(19, 63, 100)", // 边框颜色
showDetail: false, //是否显示detail即拖拽时候显示详细数值信息
startValue: 0,
endValue: 6,
filterMode: "empty",
width: "50%", //滚动条高度
height: 6, //滚动条显示位置
left: "center",
zoomLoxk: true, // 是否锁定选择区域(或叫做数据窗口)的大小
handleSize: 0, //控制手柄的尺寸
bottom: 0 // dataZoom-slider组件离容器下侧的距离
},
{
//没有下面这块的话,只能拖动滚动条,鼠标滚轮在区域内不能控制外部滚动条
type: "inside",
zoomOnMouseWheel: false, //滚轮是否触发缩放
moveOnMouseMove: true, //鼠标滚轮触发滚动
moveOnMouseWheel: true
}
]
} as any;
eacherTop.setOption(option);
eacherTop.on("click", async function (event) {
console.log(event.data)
if (event.data) {
const res = await getCountNumByEnterpriseWorkerDailyAttendanceStatisticsV2Api({
projectSn: store.sn,
startDate: dayjs(rangeTime.value).format("YYYY-MM-DD"),
endDate: dayjs(rangeTime.value).format("YYYY-MM-DD"),
parentEnterpriseId: event.data.groupId,
personType: 1,
});
const subData: any = res.result;
if (!subData && subData.length === 0) {
return;
}
eacherTop.setOption({
xAxis: {
data: subData.map(item => item.enterpriseName),
},
series: {
type: "bar",
id: "sales",
dataGroupId: event.data.groupId,
data: subData.map(item => item.workerCount || 0),
universalTransition: {
enabled: true,
divideShape: "clone"
}
},
graphic: [
{
type: "text",
left: 50,
top: 5,
style: {
text: "返回",
fill: "#fff",
fontSize: 16
},
onclick: function () {
eacherTop.setOption(option);
}
}
]
});
}
});
}
//获取今日作业人员趋势
const getQueryTodayList = async () => {
const res = await getCountNumByEnterpriseWorkerDailyAttendanceStatisticsV2Api({
projectSn: store.sn,
startDate: dayjs(rangeTime.value).format("YYYY-MM-DD"),
endDate: dayjs(rangeTime.value).format("YYYY-MM-DD"),
isSecondLevel: 1,
personType: 1,
});
if (res.result) {
nextTick(() => {
drawChart(res.result);
});
}
};
const loadMethod = async () => {
await getQueryTodayList();
};
//将方法暴露给父组件
defineExpose({
loadMethod
});
onMounted(async () => {
getQueryTodayList();
});
</script>
<style lang="scss" scoped>
.LeftTopBox {
width: 100%;
height: 100%;
display: flex;
.leftData {
float: left;
width: 20%;
height: 100%;
.numberPeople {
margin: auto;
width: 100%;
height: 33%;
background: url("@/assets/images/larborManagement/leftDataImg.webp") no-repeat;
background-size: 100% 100%;
color: #fff;
div {
text-align: center;
}
.text {
font-size: calc(100vw * 24 / 1920);
line-height: 140px;
}
.num {
font-size: calc(100vw * 36 / 1920);
margin-top: -20%;
}
}
}
.rightEcharts {
float: right;
width: calc(100% - 20px);
position: relative;
}
}
::v-deep .h-card .content {
margin-top: 1%;
height: 87% !important;
padding: 5px;
}
.rightHeader {
display: flex;
position: absolute;
z-index: 99;
color: #fff;
font-size: 10px;
text-align: center;
line-height: 20px;
// width: 20%;
// left: 80%;
// top: 79%;
width: 100%;
top: 2%;
display: flex;
justify-content: flex-end;
.Selected {
height: 5%;
background: url("@/assets/images/dustNoise/rightImg2.png") no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.day {
// width: 15%;
padding: 0 16px;
margin-right: 3%;
// margin-left: 55%;
}
.year {
// width: 15%;
margin-right: 3%;
padding: 0 16px;
}
.active {
background: url("@/assets/images/dustNoise/rightImg.png") no-repeat;
background-size: 100% 100%;
}
}
.tabList {
display: flex;
width: 100%;
height: 5%;
background: url("@/assets/images/vehicleManagement/ListTitleImg.png") no-repeat;
background-size: 100% 100%;
// position: absolute;
left: 75.5%;
top: 75%;
color: #ccc;
font-size: calc(100vw * 14 / 1920);
line-height: 30px;
justify-content: space-around;
div {
text-align: center;
width: 11%;
}
}
@mixin flex {
display: flex;
align-items: center;
}
.selBox {
width: 100%;
height: 13%;
display: flex;
flex-wrap: wrap;
padding: 0 24px;
gap: 4px;
.search-item {
@include flex;
max-width: 20%;
// margin-right: 20px;
span {
color: white;
margin-right: 10px;
}
}
}
.listBox {
height: 75%;
margin-bottom: 16px;
.listStyle {
display: flex;
justify-content: space-around;
color: #fff;
// line-height: 25px;
font-size: calc(100vw * 12 / 1920);
.list-img {
.el-img {
width: 72px;
height: 36px;
}
.image-slot {
width: 72px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
> img {
width: 62px;
height: 62px;
}
}
div {
text-align: center;
width: 11%;
display: flex;
align-items: center;
justify-content: center;
}
}
.listStyle:hover {
background: #091f3f;
}
}
// element 组件样式
:deep() {
.el-date-editor .el-range-input,
.el-range-separator {
color: #fff;
}
.el-input__wrapper {
background: #112d59;
}
.el-input__inner {
color: #fff;
}
.el-button {
background-color: #2758c0;
color: white;
border-color: transparent;
}
}
::v-deep .el-range-separator {
color: #ccc;
font-size: 10px;
}
::v-deep .el-range-input {
color: #ccc;
font-size: 10px;
}
.notoDta {
top: 35%;
width: 20%;
left: 40%;
position: absolute;
text-align: center;
img {
width: 40%;
margin: 5% 30%;
}
p {
color: #fff;
font-size: calc(100vw * 14 / 1920);
margin: -6% 37%;
}
}
.card-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin: 0 24px;
.card-item {
display: flex;
flex-direction: column;
border: 1px solid #5cc4f2;
height: 124px;
.card-item-title {
display: flex;
align-items: center;
border-bottom: 1px solid #5cc4f2;
position: relative;
height: 24px;
.name {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 16px;
color: #ffffff;
line-height: 24px;
margin: 0 16px;
white-space: nowrap;
}
.date {
font-size: 12px;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #a8abb2;
line-height: 14px;
}
.passType {
position: absolute;
right: 0;
top: 0;
width: 48px;
height: 24px;
font-size: 14px;
color: #000000;
line-height: 18px;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0 0 0 24px;
&.out {
background-color: #81f279;
}
&.in {
background-color: #6375c7;
}
}
}
.card-item-content {
flex: 1;
display: flex;
align-items: center;
padding: 10px 8px;
.img-box {
width: 64px;
height: 80px;
margin-right: 24px;
display: flex;
align-items: center;
overflow: hidden;
}
.info-box {
flex: 1;
display: flex;
flex-direction: column;
.info-item {
display: flex;
flex-direction: column;
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 12px;
color: #a8abb2;
line-height: 14px;
margin-bottom: 2px;
}
.value {
font-size: 12px;
color: #ffffff;
line-height: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
}
.sd-item {
width: 210px;
height: 65px;
margin-bottom: 18px;
background: url("@/assets/images/larborManagement/xd-bg.png") no-repeat;
background-size: 100% 100%;
padding: 6px 18px;
box-sizing: border-box;
&.mt {
margin-top: 24px;
}
&.warn {
background: url("@/assets/images/larborManagement/xd-bg-warn.png") no-repeat;
background-size: 100% 100%;
.sd-item-bottom .num {
color: #ff0000;
}
}
// background: rgba(39, 88, 192, 0.06);
.sd-item-top {
display: flex;
align-items: center;
img {
width: 16px;
height: 16px;
margin-right: 12px;
}
span {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
color: #ffffff;
line-height: 20px;
}
}
.sd-item-bottom {
display: flex;
align-items: center;
margin-top: 8px;
margin-left: 28px;
.title {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 12px;
color: #a8abb2;
margin-right: 30px;
}
.num {
font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
font-weight: 400;
font-size: 20px;
color: #65d7f9;
}
}
}
</style>