feat: 功能弹窗添加以及BUG修改

This commit is contained in:
kun 2024-03-02 16:12:21 +08:00
parent fe752a70da
commit 9d105b06e1
7 changed files with 1102 additions and 27 deletions

View File

@ -49,3 +49,21 @@ export const getworkerAttendanceTrendApi = (params: {}) => {
export const getComapnyWorkTotalListApi = (params: {}) => {
return http.post(BASEURL + `/xmgl/workerInfo/selectProjectComapnyWorkTotalList`, params);
};
// 获取人员实时动态
export const getRealTimeDataApi = (params: {}) => {
return http.post(BASEURL + `/xmgl/workerAttendance/selectWorkerAttendanceNewestList`, params);
};
// 获取人员实时动态(更多数据)
export const getRealTimeMoreDataApi = (params: {}) => {
return http.post(BASEURL + `/xmgl/workerAttendance/list`, params);
};
//获取人员所属班组
export const getTeamDataList = (params: {}) => {
return http.post(BASEURL + `/xmgl/teamInfo/getTeamInfoList`, params);
};
//获取所属部门列表
export const getDepartDataList = (params: {}) => {
return http.post(BASEURL + `/xmgl/departmentInfo/getDepartmentInfoList`, params);
};

View File

@ -1,7 +1,7 @@
<template>
<div class="list-detail" v-if="showDialog">
<div class="dialog-content">
<div class="dialog-title">
<div :class="postData.type == 1?'dialog-content':postData.type == 2?'dialog-content-show':'dialog-content-more'">
<div class="dialog-title" v-if="postData.type == 1 || postData.type == 3">
<div class="title-img"><img src="@/assets/images/titleIcon.png" alt="" /></div>
<div class="title-text">
<i>{{ dialogTitle }}</i>
@ -10,7 +10,13 @@
<div class="political-outlook" v-if="postData.type == 1">
<memberCountList ref="historyAlarmList" :tip="postData.tip"></memberCountList>
</div>
<div class="close-icon" @click="showDialog = false">
<div class="political-outlook" v-if="postData.type == 2">
<MemberAllShow ref="memberAllShow" :tip="postData.tip"></MemberAllShow>
</div>
<div class="political-outlook" v-if="postData.type == 3">
<MemberMoreList ref="memberMoreList"></MemberMoreList>
</div>
<div class="close-icon" @click="closeDialog">
<el-icon><Close /></el-icon>
</div>
</div>
@ -20,13 +26,19 @@
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import memberCountList from "./member-count-list.vue";
import MemberAllShow from "./member-all-show.vue";
import MemberMoreList from "./member-more-list.vue";
import { GlobalStore } from "@/stores";
let showDialog = ref(false as any);
const postData = ref({} as any);
let dialogTitle = ref("" as any);
const closeDialog = () => {
showDialog.value = false;
postData.value = {};
}
function openDialog(obj: any) {
console.log("type", obj);
if(obj.type == 1){
if(obj.type == 1 || obj.type == 3){
dialogTitle.value = obj.tip + '人数统计数据';
} else if(obj.type == 2) {
dialogTitle.value = "历史报警数据";
@ -53,8 +65,8 @@ onMounted(async () => {
top: 0%;
left: 0%;
background: rgba(7, 28, 49, 0.5);
z-index: 20;
.dialog-content {
z-index: 100;
.dialog-content{
position: absolute;
box-sizing: border-box;
padding: 1%;
@ -65,8 +77,34 @@ onMounted(async () => {
background: url("@/assets/images/aIEarlyWarning/dialogBg.png") no-repeat;
background-size: 100% 100%;
z-index: 21;
}
.dialog-content-show{
position: absolute;
box-sizing: border-box;
padding: 1%;
left: 11%;
top: 1%;
width: 81%;
height: 98%;
background: url("@/assets/images/aIEarlyWarning/dialogBg.png") no-repeat;
background-size: 100% 100%;
z-index: 21;
}
.dialog-content-more{
position: absolute;
box-sizing: border-box;
padding: 1%;
left: 2%;
top: 21%;
width: 96%;
height: 60%;
background: url("@/assets/images/aIEarlyWarning/dialogBg.png") no-repeat;
background-size: 100% 100%;
z-index: 21;
}
.dialog-content,.dialog-content-show {
.political-outlook {
height: 95%;
height: 100%;
}
.dialog-article {
height: 95%;

View File

@ -26,6 +26,7 @@
<Card title="今日作业人员趋势">
<div id="myEchartsNum" ref="myEchartsNum" style="width: 100%; height: 100%"></div>
</Card>
<div class="show-more" @click="openDialogHistoryData('人员总览')">人员总览</div>
</div>
</div>
</template>
@ -226,6 +227,9 @@ const option = reactive({
const openDialogData = (tip:any) => {
emits("openDialog",{type: 1, tip})
}
const openDialogHistoryData = (tip:any) => {
emits("openDialog",{type: 2, tip})
}
function drawChart() {
let myEchartsNum = echarts.init(document.getElementById("myEchartsNum"));
myEchartsNum.setOption(option);
@ -292,9 +296,22 @@ onMounted(async () => {
float: right;
width: 82%;
margin-left: 1%;
position: relative;
.show-more {
position: absolute;
right: 1%;
top: 2%;
cursor: pointer;
font-size: 12px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
color: #4ac0f3;
}
}
}
::v-deep .h-card .content {
margin-top: 1%;
}
::v-deep .h-card .title .titltText {
margin: 0% 0 0.3% 1.5%;
}
</style>

View File

@ -0,0 +1,637 @@
<template>
<div class="political-outlook">
<div class="content">
<div class="dialog-title">
<div class="title-img"><img src="@/assets/images/titleIcon.png" alt="" /></div>
<div class="title-text">
<i>人员类型统计</i>
</div>
</div>
<div class="PersonnelType_wrap">
<div class="title_wrap" style="margin-bottom: 18px">
<div>
<div class="headcount">工地总人数{{ memberCountData.totalPersonNum }}</div>
<div class="headcount">今日出勤人数{{ memberCountData.attendancePersonNum }}</div>
<div class="headcount">今日在场人数{{ memberCountData.presencePersonNum }}</div>
</div>
</div>
<div class="echarts" ref="personnelTypeRef"></div>
</div>
</div>
<div class="content">
<div class="dialog-title">
<div class="title-img"><img src="@/assets/images/titleIcon.png" alt="" /></div>
<div class="title-text">
<i>企业出勤排名</i>
</div>
</div>
<div class="manager_wrap">
<div class="echarts" ref="ageChartRef" style="width: 100%; height: 100%"></div>
</div>
</div>
<div class="list-content">
<div class="dialog-title">
<div class="title-img"><img src="@/assets/images/titleIcon.png" alt="" /></div>
<div class="title-text">
<i>人员实时动态</i>
</div>
</div>
<div class="show-more" @click="openPeopleCountDialog({type: 3, tip: '人员实时动态'})">
<span>更多</span>
</div>
<div class="tabList">
<div>类型</div>
<div>姓名</div>
<div>班组</div>
<div>图片</div>
<div>通行时间</div>
</div>
<el-scrollbar class="listBox" ref="refScrollbar" style="height: 82%;">
<div v-for="(item, index) in crewRealTimeList" class="listStyle" :key="item.id">
<div>{{ item.passType == 1 ? "进" : "出" }}</div>
<div>{{ item.workerName }}</div>
<div>{{ item.teamName ? item.teamName : item.departmentName }}</div>
<div class="list-img">
<el-image v-if="item.imageUrl" fit="contain" class="el-img" :src="item.imageUrl" :preview-src-list="[item.imageUrl]">
</el-image>
</div>
<div>{{ item.createTime }}</div>
</div>
<div class="notoDta" v-if="crewRealTimeList.length == 0">
<img src="@/assets/images/noData.png" alt="" />
<p>暂无数据</p>
</div>
</el-scrollbar>
</div>
<div class="list-content">
<div class="dialog-title">
<div class="title-img"><img src="@/assets/images/titleIcon.png" alt="" /></div>
<div class="title-text">
<i>班组人员统计</i>
</div>
</div>
<div class="tabList">
<div>序号</div>
<div>班组名称</div>
<div>在册人数</div>
<div>出场人数</div>
<div>在场人数</div>
</div>
<el-scrollbar class="listBox" ref="refScrollbar">
<div v-for="(item, index) in teamList" class="listStyle" :key="item.id">
<div>{{ index + 1 }}</div>
<div>{{ item.teamName }}</div>
<div>{{ item.totalPerson }}</div>
<div>{{ item.attendancePersonTotal }}</div>
<div>{{ item.presencePersonTotal }}</div>
</div>
<div class="notoDta" v-if="teamList.length == 0">
<img src="@/assets/images/noData.png" alt="" />
<p>暂无数据</p>
</div>
</el-scrollbar>
</div>
<dataDialog ref="partyBuildRefMore"></dataDialog>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { GlobalStore } from "@/stores";
import {
getPersonTypeAndEduStatisticsApi,
getComapnyWorkTotalListApi,
getRealTimeDataApi,
getWorkerInfoApi
} from "@/api/modules/labor";
import * as echarts from "echarts";
import dataDialog from "./data-dialog.vue";
const store = GlobalStore();
const props = defineProps(["tip"]);
const partyBuildRefMore = ref();
const teamList = ref([] as any);
const BASEURL = import.meta.env.VITE_API_URL;
const crewRealTimeList = ref([] as any);
const ageChartRef = ref();
const memberCountData = ref({
totalPersonNum: 0,
totalEducationPerson: 0,
attendancePersonNum: 0,
presencePersonNum: 0
});
const personnelTypeRef = ref();
//
const openPeopleCountDialog = (obj:any) => {
partyBuildRefMore.value.openDialog(obj);
// console.log(partyBuildRef.value);
};
//
const selectWorkerTeamStatistics = async () => {
const res: any = await getWorkerInfoApi({
projectSn: store.sn,
userEnterpriseId: store.userInfo.userEnterpriseId
});
teamList.value = res.result;
};
//
const getCrewRealTimeData = async () => {
let data = {
projectSn: store.sn,
userEnterpriseId: store.userInfo.userEnterpriseId
};
const res: any = await getRealTimeDataApi(data);
if (res.code == 200) {
crewRealTimeList.value = res.result;
crewRealTimeList.value.map((item: any) => {
if (item.imageUrl) {
item.imageUrl = BASEURL + "/image/" + item.imageUrl;
} else if (item.fieldAcquisitionUrl) {
item.fieldAcquisitionUrl = BASEURL + "/image/" + item.fieldAcquisitionUrl;
}
});
}
};
//
const getCompanyAttendData = async () => {
let data = {
projectSn: store.sn
};
const res: any = await getComapnyWorkTotalListApi(data);
if (res.code == 200) {
var Data = res.result;
var xData: any = [],
yData1: any = [],
yData2: any = [],
yData3: any = [];
Data.forEach((element: any) => {
xData.push(element.enterpriseName);
yData1.push(element.attendancePersonNum);
yData2.push(element.totalPersonNum);
yData3.push(element.presencePersonNum);
});
createdBarCharts(xData, yData1, yData2, yData3, ageChartRef.value, ["出勤人数", "在册人数", "在场人数"]);
}
};
//---
const createdBarCharts = (xData: any, yData1: any, yData2: any, yData3: any, el: any, legendData: any) => {
let that = this;
let ageChart = echarts.init(el);
ageChart.clear();
let option = {
grid: {
width: "92%",
height: "86%",
left: 20,
containLabel: true
},
color: ["#5CE2F6", "#5181F6", "#8EBDD2"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
legend: {
show: true,
// align: "left",
top: 0,
// left: 0,
itemWidth: 13,
itemHeight: 5,
textStyle: {
color: "#9fa2ad"
}
},
xAxis: [
{
type: "category",
data: xData,
boundaryGap: true,
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
color: "#9fa2ad",
fontSize: 12
}
}
],
yAxis: {
type: "value",
axisTick: {
show: false
},
axisLine: {
show: false
},
splitLine: {
lineStyle: {
type: "dashed",
color: "rgba(231, 233, 243, 1)"
}
},
axisLabel: {
color: "#9fa2ad"
}
},
// dataZoom: [
// {
// show: true,
// start: 50,
// end: 100,
// height: 8,
// borderColor: "transparent",
// backgroundColor: "#fff",
// filterColor: "#999999",
// bottom: 0,
// },
// ],
series: [
{
name: legendData[1],
type: "bar",
data: yData2,
// stack: 'product',
barWidth: 35,
barGap: 0.1
},
{
name: legendData[0],
type: "bar",
// stack: 'product',
data: yData1,
barMaxWidth: 35
},
{
name: legendData[2],
type: "bar",
data: yData3,
// stack: 'product',
barMaxWidth: 35,
barGap: 0.1
}
]
};
ageChart.setOption(option);
};
//
const createdEcharts = (yAxisData1: any, yAxisData2: any, yAxisData3: any) => {
// let yAxisData1 = [1, 2, 3, 4, 5, 6, 7];
// let yAxisData2 = [2, 3, 7, 4, 5, 6, 7];
let personnelType = echarts.init(personnelTypeRef.value);
let option = {
color: ["#8FC8FF", "rgba(126,150,232,1)", "#61D2B9"],
tooltip: {
show: true,
trigger: "axis",
formatter: "{b} <br /> {a0}: {c0}<br /> {a1}: {c1} <br /> {a2}: {c2}",
axisPointer: {
lineStyle: {
color: "transparent"
}
},
textStyle: {
color: "#000",
fontSize: 12
},
backgroundColor: "rgba(236,236,236,0.75)"
},
grid: {
left: 30,
right: 30,
bottom: 15,
top: 20,
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
axisLine: {
show: false
},
axisTick: { show: false },
data: ["项目管理人员", "劳务工", "临时工"],
axisLabel: {
// rotate: 30,
textStyle: {
color: "#9fa2ad",
fontSize: 10
}
}
},
yAxis: {
show: true,
// type: "time",
axisTick: { show: false },
axisLine: {
show: false
},
splitLine: {
lineStyle: {
type: "dashed",
color: "rgba(231, 233, 243, 0.5)"
}
},
axisLabel: {
// show: false,
textStyle: {
color: "#9fa2ad",
fontSize: 10
}
}
},
series: [
{
name: "在册人数",
data: yAxisData2,
type: "line",
symbolSize: 10,
// symbol: "circle",
lineStyle: {
width: 1
},
areaStyle: {
normal: {
// opacity: 0.2
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(126,150,232,0.56)"
},
{
offset: 1,
color: "rgba(30, 72, 223, 0)"
}
])
}
}
},
{
name: "出勤人数",
data: yAxisData3,
type: "line",
symbolSize: 10,
// symbol: "circle",
lineStyle: {
width: 1
},
areaStyle: {
normal: {
// opacity: 0.2
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(126,150,232,0.56)"
},
{
offset: 1,
color: "rgba(30, 72, 223, 0)"
}
])
}
}
},
{
name: "在场人数",
data: yAxisData1,
type: "line",
symbolSize: 10,
// symbol: "circle",
lineStyle: {
width: 1
},
areaStyle: {
normal: {
// opacity: 0.2
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(37,82,228,0.56)"
},
{
offset: 1,
color: "rgba(30, 72, 223, 0)"
}
])
}
}
}
]
};
personnelType.setOption(option);
};
//
const selectPersonTypeAndEduStatistics = async () => {
const res: any = await getPersonTypeAndEduStatisticsApi({
projectSn: store.sn,
userEnterpriseId: store.userInfo.userEnterpriseId
});
console.log(res);
memberCountData.value.totalPersonNum = res.result.personType.toaltPerson.totalPerson; //
memberCountData.value.totalEducationPerson = res.result.totalEducationPerson;
memberCountData.value.attendancePersonNum = res.result.personType.attendancePerson.totalPerson; //
memberCountData.value.presencePersonNum = res.result.personType.presencePerson.totalPerson; //
var personTypeData = res.result.personType;
var arr1 = [
personTypeData.presencePerson.glPersonTotal,
personTypeData.presencePerson.lwPersonTotal,
personTypeData.presencePerson.lsPersonTotal
];
var arr2 = [
personTypeData.toaltPerson.glPersonTotal,
personTypeData.toaltPerson.lwPersonTotal,
personTypeData.toaltPerson.lsPersonTotal
];
var attendance = [
//
personTypeData.attendancePerson.glPersonTotal,
personTypeData.attendancePerson.lwPersonTotal,
personTypeData.attendancePerson.lsPersonTotal
];
createdEcharts(arr1, arr2, attendance);
// createdEcharts3()
};
onMounted(async () => {
await selectPersonTypeAndEduStatistics();
await getCompanyAttendData();
await getCrewRealTimeData();
await selectWorkerTeamStatistics();
});
</script>
<style lang="scss" scoped>
@mixin flex {
display: flex;
align-items: center;
}
.political-outlook {
width: 100%;
height: 100%;
@include flex;
flex-wrap: wrap;
justify-content: space-between;
.content {
height: 45%;
width: 45%;
margin-top: 10px;
// background: url("@/assets/images/cardImg.png") no-repeat;
background-size: 100% 100%;
.dialog-title {
color: #ffffff;
font-weight: bold;
font-size: 18px;
font-family: "OPPOSans-Bold";
@include flex;
.title-img {
width: 30px;
height: 30px;
img {
width: 100%;
height: 100%;
}
}
.title-text {
margin-bottom: 0.3%;
margin-left: 0.2%;
}
}
.PersonnelType_wrap {
width: 100%;
height: 100%;
.title_wrap {
> div {
@include flex;
justify-content: flex-end;
.headcount {
color: white;
font-size: 14px;
padding: 3px 10px;
// border-radius: 30px;
background: #2758c0;
margin-right: 10px;
}
}
margin-top: 12px;
}
}
.manager_wrap {
width: 100%;
height: 100%;
}
.echarts {
width: 100%;
height: calc(100% - 50px);
}
}
.list-content {
height: 45%;
width: 45%;
margin-top: 10px;
// background: url("@/assets/images/cardImg.png") no-repeat;
background-size: 100% 100%;
.dialog-title {
color: #ffffff;
font-weight: bold;
font-size: 18px;
font-family: "OPPOSans-Bold";
@include flex;
margin-bottom: 20px;
.title-img {
width: 30px;
height: 30px;
img {
width: 100%;
height: 100%;
}
}
.title-text {
margin-bottom: 0.3%;
margin-left: 0.2%;
}
}
.show-more {
cursor: pointer;
font-size: 12px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
color: #4ac0f3;
@include flex;
justify-content: flex-end;
margin-bottom: 10px;
}
.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;
align-items: center;
div {
text-align: center;
width: 25%;
}
}
.listBox {
height: 90%;
.listStyle {
display: flex;
align-items: center;
text-align: center;
color: #fff;
font-size: 12px;
margin-bottom: 5px;
.list-img {
.el-img {
width: 30px;
height: 30px;
img {
display: flex;
align-items: center;
width: 100%;
height: 100%;
}
}
}
div {
width: 25%;
white-space: nowrap; //
overflow: hidden;
text-overflow: ellipsis;
}
}
.listStyle:hover {
background: #091f3f;
}
}
}
}
.notoDta {
top: 28%;
width: 50%;
left: 22%;
position: absolute;
text-align: center;
img {
width: 40%;
margin: 5% 30%;
}
p {
color: #fff;
font-size: calc(100vw * 14 / 1920);
margin: -6% 37%;
}
}
</style>

View File

@ -43,17 +43,17 @@
</div>
<div class="search-item">
<span>姓名</span>
<el-input placeholder="请输入" v-model="searchForm.name" style="width: 150px" />
<el-input placeholder="请输入" v-model="searchForm.name" :clearable="true" style="width: 150px" />
</div>
<div class="search-item">
<span>身份证号</span>
<el-input placeholder="请输入" v-model="searchForm.idCard" style="width: 180px" />
<el-input placeholder="请输入" v-model="searchForm.idCard" :clearable="true" style="width: 180px" />
</div>
<el-button @click="getMemberCountList('search')">查询</el-button>
</div>
<div class="tabList">
<div>序号</div>
<div>照片</div>
<div style="width: 10%">序号</div>
<div style="width: 10%">照片</div>
<div>姓名</div>
<div>联系电话</div>
<div>所属部门</div>
@ -61,29 +61,30 @@
<div>在职状态</div>
<div>身份证号</div>
<div>人员类型</div>
<div>所属企业</div>
<div style="width: 25%;">所属企业</div>
</div>
<el-scrollbar class="listBox" ref="refScrollbar">
<div v-for="(item, index) in partyMemberList" class="listStyle" :key="item.id">
<div>{{index + 1}}</div>
<div class="list-img">
<div style="width: 10%">{{index + 1}}</div>
<div class="list-img" style="width: 10%">
<el-image
fit="contain"
class="el-img"
:src="BASEURL + item.fieldAcquisitionUrl"
:preview-src-list="[BASEURL + item.fieldAcquisitionUrl]"
:src="item.fieldAcquisitionUrl"
:preview-src-list="[item.fieldAcquisitionUrl]"
>
</el-image>
<!-- <img :src="item.fieldAcquisitionUrl" alt="" srcset=""> -->
</div>
<div>{{item.workerName}}</div>
<div>{{item.phoneNumber}}</div>
<div>{{item.phoneNumber}}</div>
<div>{{item.personType == 1?item.teamName:item.personType == 2?item.departmentName:''}}</div>
<div>{{item.phoneNumber}}</div>
<div>身份证号</div>
<div>人员类型</div>
<div>所属企业</div>
<div>{{item.enterDate}}</div>
<div>{{onlineWorkList[item.inserviceType - 1].name}}</div>
<div>{{item.idCard}}</div>
<div>{{memberTypeList[item.personType - 1].name}}</div>
<div style="width: 25%;">{{item.enterpriseName}}</div>
</div>
<div class="notoDta" v-if="partyMemberList.length == 0">
<img src="@/assets/images/noData.png" alt="" />
@ -141,9 +142,21 @@ const getCompanyList = async () => {
const getMemberCountList = async (tip:any) => {
let requestData:any = {
projectSn: store.sn,
personType: searchForm.value.memberType, //
enterpriseId: searchForm.value.belongCompany, //
inserviceType: searchForm.value.workState, //
idCard: searchForm.value.idCard, //
workerName: searchForm.value.name, //
pageNo: tip == 'search'?1:pageNo.value,
pageSize: 100
}
if(props.tip == '实时'){
requestData.presence = 1;
} else if(props.tip == '日累积') {
requestData.attendance = 1;
} else {
requestData.inserviceType = 1;
}
const res: any = await getMemberInfoList(requestData);
console.log("获取人员信息列表", res);
if(tip == 'more'){
@ -151,6 +164,10 @@ const getMemberCountList = async (tip:any) => {
} else {
partyMemberList.value = res.result.records;
}
// IP
partyMemberList.value.map((item:any) => {
item.fieldAcquisitionUrl = BASEURL + '/image/' + item.fieldAcquisitionUrl
})
if (res.result.pages == pageNo.value) {
moreScroll.value = false;
} else {

View File

@ -0,0 +1,331 @@
<template>
<div class="political-outlook">
<div class="content">
<div class="top-search">
<div class="search-item">
<span>姓名</span>
<el-input placeholder="请输入" size="small" v-model="searchForm.name" :clearable="true" style="width: 150px" />
</div>
<div class="search-item">
<span>通行时间</span>
<el-date-picker
v-model="searchForm.rangeTime"
type="datetimerange"
size="small"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
:clearable="true"
/>
</div>
<div class="search-item">
<span>所属企业</span>
<el-select
class="m-2"
placeholder="请选择"
size="small"
v-model="searchForm.belongCompany"
:clearable="true"
@change="companySelect"
style="width: 150px"
>
<el-option v-for="(item, index) in enterpriseListData" :key="index" :label="item.enterpriseName" :value="item.id" />
</el-select>
</div>
<div class="search-item">
<span>所属班组</span>
<el-select
class="m-2"
placeholder="请选择"
size="small"
v-model="searchForm.belongTeam"
:clearable="true"
style="width: 150px"
>
<el-option v-for="(item, index) in teamListData" :key="index" :label="item.teamName" :value="item.id" />
</el-select>
</div>
<div class="search-item">
<span>所属部门</span>
<el-select
class="m-2"
placeholder="请选择"
size="small"
v-model="searchForm.belongDepart"
:clearable="true"
style="width: 150px"
>
<el-option v-for="(item, index) in departListData" :key="index" :label="item.departmentName" :value="item.id" />
</el-select>
</div>
<el-button @click="getMemberCountList('search')">查询</el-button>
</div>
<div class="tabList">
<div>类型</div>
<div>姓名</div>
<div>班组</div>
<div>通行时间</div>
<div>闸机名称</div>
<div>图片</div>
</div>
<el-scrollbar class="listBox" ref="refScrollbar">
<div v-for="(item, index) in crewRealTimeList" class="listStyle" :key="item.id">
<div>{{ item.passType == 1 ? "进" : "出" }}</div>
<div>{{ item.workerName }}</div>
<div>{{ item.teamName ? item.teamName : item.departmentName }}</div>
<div>{{ item.createTime }}</div>
<div>{{ item.passagewayName }}</div>
<div class="list-img">
<el-image v-if="item.imageUrl" fit="contain" class="el-img" :src="item.imageUrl" :preview-src-list="[item.imageUrl]">
</el-image>
</div>
</div>
<div class="notoDta" v-if="partyMemberList.length == 0">
<img src="@/assets/images/noData.png" alt="" />
<p>暂无数据</p>
</div>
</el-scrollbar>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { GlobalStore } from "@/stores";
import {
getCompanyDataList,
getMemberInfoList,
getTeamDataList,
getDepartDataList,
getRealTimeMoreDataApi
} from "@/api/modules/labor";
const store = GlobalStore();
const props = defineProps(["tip"]);
const crewRealTimeList = ref([] as any);
const BASEURL = import.meta.env.VITE_API_URL;
const departListData = ref([] as any);
const teamListData = ref([] as any);
const enterpriseListData = ref([] as any)
let pageNo = ref(1 as any);
let moreScroll = ref(true as any);
const refScrollbar = ref(null as any); //
const searchForm = ref({
name: "",
rangeTime: "",
belongCompany: "",
belongTeam: "",
belongDepart: ""
});
const partyMemberList = ref({} as any);
//
const companySelect = async () => {
await getTeamList();
await getDepartmentList();
};
//
const getDepartmentList = async () => {
let data = {
enterpriseId: searchForm.value.belongCompany,
projectSn: store.sn
};
const res: any = await getDepartDataList(data);
departListData.value = res.result.list;
};
// -
const getTeamList = async () => {
let data = {
enterpriseId: searchForm.value.belongCompany,
projectSn: store.sn
};
const res: any = await getTeamDataList(data);
teamListData.value = res.result.list;
};
//
const getCompanyList = async () => {
let data = {
projectSn: store.sn,
enterpriseName: "",
userEnterpriseId: store.userInfo.userEnterpriseId
};
const res: any = await getCompanyDataList(data);
if (res.code == 200) {
enterpriseListData.value = res.result;
}
};
//
const getMemberCountList = async (tip: any) => {
let data:any = {
projectSn: store.sn,
userEnterpriseId: store.userInfo.userEnterpriseId,
workerName: searchForm.value.name,
enterpriseId: searchForm.value.belongCompany,
teamId: searchForm.value.belongTeam,
departmentId: searchForm.value.belongDepart,
pageNo: tip == 'search'?1:pageNo.value,
pageSize: 20
};
if(searchForm.value.rangeTime){
data.startTime = searchForm.value.rangeTime[0]
data.endTime = searchForm.value.rangeTime[1]
}
const res: any = await getRealTimeMoreDataApi(data);
if (tip == "more") {
crewRealTimeList.value = crewRealTimeList.value.concat(res.result.records);
} else {
crewRealTimeList.value = res.result.records;
}
crewRealTimeList.value.map((item: any) => {
if (item.imageUrl) {
item.imageUrl = BASEURL + "/image/" + item.imageUrl;
} else if (item.fieldAcquisitionUrl) {
item.fieldAcquisitionUrl = BASEURL + "/image/" + item.fieldAcquisitionUrl;
}
});
if (res.result.pages == pageNo.value) {
moreScroll.value = false;
} else {
pageNo.value = pageNo.value + 1;
}
};
onMounted(async () => {
await getCompanyList();
await getMemberCountList("search");
refScrollbar.value.wrapRef.addEventListener("scroll", (e: any) => {
// console.log("", e);
const scrollTop = e.target.scrollTop;
const scrollHeight = e.target.scrollHeight;
const clientHeight = e.target.clientHeight;
// console.log("", scrollTop, scrollHeight, clientHeight);
//
if (scrollTop >= scrollHeight - clientHeight - 1) {
// console.log("");
if (moreScroll.value) {
getMemberCountList("more");
}
}
});
});
</script>
<style lang="scss" scoped>
@mixin flex {
display: flex;
align-items: center;
}
.political-outlook {
width: 100%;
height: 100%;
.content {
height: 95%;
width: 100%;
margin-top: 10px;
// background: url("@/assets/images/cardImg.png") no-repeat;
background-size: 100% 100%;
.top-search {
@include flex;
justify-content: flex-end;
margin-bottom: 15px;
.search-item {
@include flex;
margin-right: 20px;
span {
color: white;
margin-right: 10px;
}
}
}
.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;
align-items: center;
div {
text-align: center;
width: 17%;
}
}
.listBox {
height: 82%;
.listStyle {
display: flex;
align-items: center;
text-align: center;
color: #fff;
font-size: 12px;
margin-bottom: 5px;
.list-img {
.el-img {
width: 30px;
height: 30px;
img {
display: flex;
align-items: center;
width: 100%;
height: 100%;
}
}
}
div {
width: 17%;
white-space: nowrap; //
overflow: hidden;
text-overflow: ellipsis;
}
}
.listStyle:hover {
background: #091f3f;
}
}
}
}
.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%;
}
}
// 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-select .el-input .el-select__caret {
// color: #fff;
// }
</style>

View File

@ -252,16 +252,33 @@ function initOption() {
textStyle: {
color: "#fff"
},
formatter: function (name) {
formatter: function (name:any) {
// name
var dataValue = data.value.find(function (item) {
var dataValue = data.value.find(function (item:any) {
return item.name === name;
});
if (dataValue) {
return name + " " + dataValue.value;
} else {
return name;
let tip1 = "";
let tip = "";
let le = name.length //
if(le > 14){ //
let l = Math.ceil(le/14) //
for(let i = 1;i <= l;i++){ //
if(i < l){ //\n
tip1 += name.slice(i*14-14,i*14)+'\n'; //
}else if(i === l){ //9
tip = tip1 + name.slice((l-1)*14,le) //
}
}
return tip + " " + dataValue.value;
}else{
tip = name //tip
return tip + " " + dataValue.value;
}
// if (dataValue) {
// return name + " " + dataValue.value;
// } else {
// return name;
// }
}