flx:企业数据化大屏调整

This commit is contained in:
Rain_ 2025-07-16 09:03:29 +08:00
parent 632c6c93a0
commit 0259b4e7ff
14 changed files with 1735 additions and 294 deletions

1007
package-lock.json generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

View File

@ -1,7 +1,7 @@
/**
* api接口统一管理
*/
import {post, get} from '../http'
import { post, get } from '../http'
// 统计企业下项目类型统计
export const selectCompanyProjectTypeCountApi = data => post('xmgl/companyBigScreen/selectCompanyProjectTypeCount', data);
@ -51,114 +51,114 @@ export const getComapnyStatisticsList = data => post('xmgl/company/getComapnySta
//获取全部设备信息
export const getAllEquipment = data => post('/xmgl/projectDevStatistics/selectAllDevStatisticsCount',data)
//获取环境预警信息
export const getAllenviromentDangerInfo = data => post('/xmgl/projectDevStatistics/selectEnvironmentAlarmStatisticsCount',data)
//获取升降机预警信息
export const getAllLifterDangerInfo = data => post('/xmgl/projectDevStatistics/selectLifterAlarmStatisticsCount',data)
//获取塔吊预警信息
export const getAllTowerDangerInfo = data => post('/xmgl/projectDevStatistics/selectTowerAlarmStatisticsCount',data)
//获取环境报警列表
export const getDangeralarmList = data => post('xmgl/projectDevStatistics/selectComapnyEnvironmentAlarmCount',data)
//获取AI视频预警信息
export const getAiVideoInfo = data => post('xmgl/aiStatistic/selectAiStatistic',data)
//获取环境预警信息
export const getEnvironmentInfo = data => post('xmgl/environmentDev/selectTotalEnvironmentCountStatistics',data)
// 近七天管理人员出勤统计
export const getSevenDaysAttendance = data => post('xmgl/workerStatistic/selectSevenDaysWorkerAttendanceCount',data)
// 设备在线情况
export const getDevOnlineList = data => post('xmgl/projectDevStatistics/selectProjectDevStatisticList',data)
export const getAllEquipment = data => post('/xmgl/projectDevStatistics/selectAllDevStatisticsCount', data)
//获取环境预警信息
export const getAllenviromentDangerInfo = data => post('/xmgl/projectDevStatistics/selectEnvironmentAlarmStatisticsCount', data)
//获取升降机预警信息
export const getAllLifterDangerInfo = data => post('/xmgl/projectDevStatistics/selectLifterAlarmStatisticsCount', data)
//获取塔吊预警信息
export const getAllTowerDangerInfo = data => post('/xmgl/projectDevStatistics/selectTowerAlarmStatisticsCount', data)
//获取环境报警列表
export const getDangeralarmList = data => post('xmgl/projectDevStatistics/selectComapnyEnvironmentAlarmCount', data)
//获取AI视频预警信息
export const getAiVideoInfo = data => post('xmgl/aiStatistic/selectAiStatistic', data)
//获取环境预警信息
export const getEnvironmentInfo = data => post('xmgl/environmentDev/selectTotalEnvironmentCountStatistics', data)
// 近七天管理人员出勤统计
export const getSevenDaysAttendance = data => post('xmgl/workerStatistic/selectSevenDaysWorkerAttendanceCount', data)
// 设备在线情况
export const getDevOnlineList = data => post('xmgl/projectDevStatistics/selectProjectDevStatisticList', data)
// 塔吊报警表格数据
export const getTowerCraneInfo = data => post('xmgl/towerAlarm/selectComapnyTowerAlarmCount',data)
// 升降机报警表格数据
export const getElevatorInfo = data => post('xmgl/lifterAlarm/selectComapnyLifterAlarmCount',data)
export const getTowerCraneInfo = data => post('xmgl/towerAlarm/selectComapnyTowerAlarmCount', data)
// 升降机报警表格数据
export const getElevatorInfo = data => post('xmgl/lifterAlarm/selectComapnyLifterAlarmCount', data)
//获取当日AI预警情况
export const getNowAIDangerDetail = data => post('/xmgl/aiStatistic/selectAiAlarmAnalyseCountList',data)
//获取AI实时预警列表
export const getAIDangerList = data => post('/xmgl/aiStatistic/selectAiAlarmRecordList',data)
//获取AI预警类型统计
export const getAITypeStatistics = data => post('/xmgl/aiStatistic/selectAiAnalyseHardWareAlarmTypeCount',data)
//获取AI接入情况
export const getAIOnlineDetail = data => post('/xmgl/aiStatistic/selectAiDevCount',data)
//获取AI预警项目列表
export const getAIDangerProgramList = data => post('/xmgl/aiStatistic/selectProjectAiAlarmCountList',data)
// 获取AI预警分析列表
export const getAIDangerAnalysisList = data => post('xmgl/aiStatistic/selectProjectAiStatisticList',data)
export const getNowAIDangerDetail = data => post('/xmgl/aiStatistic/selectAiAlarmAnalyseCountList', data)
//获取AI实时预警列表
export const getAIDangerList = data => post('/xmgl/aiStatistic/selectAiAlarmRecordList', data)
//获取AI预警类型统计
export const getAITypeStatistics = data => post('/xmgl/aiStatistic/selectAiAnalyseHardWareAlarmTypeCount', data)
//获取AI接入情况
export const getAIOnlineDetail = data => post('/xmgl/aiStatistic/selectAiDevCount', data)
//获取AI预警项目列表
export const getAIDangerProgramList = data => post('/xmgl/aiStatistic/selectProjectAiAlarmCountList', data)
// 获取AI预警分析列表
export const getAIDangerAnalysisList = data => post('xmgl/aiStatistic/selectProjectAiStatisticList', data)
//(劳务管理页面)
//获取各区域考勤情况
export const getAreaAttendance = data => post('/xmgl/workerStatistic/selectAreaWorkAttendanceCountList',data)
//获取项目出勤率列表
export const getAttendancerateList = data => post('/xmgl/workerStatistic/selectProjectAttendanceWarningList',data)
//获取工友籍贯统计
export const getWorkerNativePlace = data => post('/xmgl/workerStatistic/selectProvinceWorkerCountList',data)
//今日出勤统计
export const getAttendanceStatisticsToday = data => post('/xmgl/workerStatistic/selectTodayWorkerAttendanceCount',data)
//用工统计分析
export const getUsePeopleInfo = data => post('/xmgl/workerStatistic/selectWorkerAgeGroupStatistics',data)
//工种分析列表
export const getJobAnalysisList = data => post('/xmgl/workerStatistic/selectWorkerTypeCountList',data)
export const getAreaAttendance = data => post('/xmgl/workerStatistic/selectAreaWorkAttendanceCountList', data)
//获取项目出勤率列表
export const getAttendancerateList = data => post('/xmgl/workerStatistic/selectProjectAttendanceWarningList', data)
//获取工友籍贯统计
export const getWorkerNativePlace = data => post('/xmgl/workerStatistic/selectProvinceWorkerCountList', data)
//今日出勤统计
export const getAttendanceStatisticsToday = data => post('/xmgl/workerStatistic/selectTodayWorkerAttendanceCount', data)
//用工统计分析
export const getUsePeopleInfo = data => post('/xmgl/workerStatistic/selectWorkerAgeGroupStatistics', data)
//工种分析列表
export const getJobAnalysisList = data => post('/xmgl/workerStatistic/selectWorkerTypeCountList', data)
//(劳务管理弹窗)
//人员管理列表
export const getPersonManage = data => post('/xmgl/workerStatistic/selectWorkerPageList',data)
//组织结构列表
export const getOrganizationList = data => post('/xmgl/workerStatistic/selectOrganizationList',data)
//查询单位的出勤列表
export const getAttandanceList = data => post('/xmgl/workerStatistic/selectEnterpriseWorkerAttendancePageList',data)
//获取项目危险预警
export const getDangerList = data => post('/xmgl/workerStatistic/selectWorkerAttendancePageList',data)
export const getPersonManage = data => post('/xmgl/workerStatistic/selectWorkerPageList', data)
//组织结构列表
export const getOrganizationList = data => post('/xmgl/workerStatistic/selectOrganizationList', data)
//查询单位的出勤列表
export const getAttandanceList = data => post('/xmgl/workerStatistic/selectEnterpriseWorkerAttendancePageList', data)
//获取项目危险预警
export const getDangerList = data => post('/xmgl/workerStatistic/selectWorkerAttendancePageList', data)
//(总览页面)
//获取今日出勤率数据
export const getTodayAttendanceRate = data => post('/xmgl/workerStatistic/selectTodayWorkAttendanceRatioCount',data)
//获取视频接入情况统计
export const getVideoOnlineDetail = data => post('/xmgl/projectDevStatistics/selectVideoDevAccessCount',data)
//获取扬尘接入统计
export const getRaiseDustDetail = data => post('/xmgl/projectDevStatistics/selectEnvironmentDevAccessCount',data)
//获取项目统计
export const getAllProjectNum = data => post('/xmgl/projectDevStatistics/selectCompanyProjectTypeCount',data)
export const getTodayAttendanceRate = data => post('/xmgl/workerStatistic/selectTodayWorkAttendanceRatioCount', data)
//获取视频接入情况统计
export const getVideoOnlineDetail = data => post('/xmgl/projectDevStatistics/selectVideoDevAccessCount', data)
//获取扬尘接入统计
export const getRaiseDustDetail = data => post('/xmgl/projectDevStatistics/selectEnvironmentDevAccessCount', data)
//获取项目统计
export const getAllProjectNum = data => post('/xmgl/projectDevStatistics/selectCompanyProjectTypeCount', data)
//(质量安全)
//获取项目评分统计
export const getProjectScoreList = data => post('/xmgl/engineeringScore/selectEngineeringScoreCountList',data)
//获取项目工程评分汇总
export const getAllScore= data => post('/xmgl/engineeringScore/selectEngineeringScoreTotal',data)
//查询项目本年管理行为评分信息统计
export const getAllYearScore= data => post('/xmgl/managerialBehaviorScore/selectThisYearManagerialBehaviorScoreTotal',data)
//查询分页列表查询管理行为评分信息
export const getYearManageInfo= data => post('/xmgl/managerialBehaviorScore/selectPageList',data)
//查询一线公司或工管中心检查情况统计
export const getManageAndCenterDetailList= data => post('/xmgl/managerialBehaviorScore/selectManagerialBehaviorScoreCountList',data)
//(进度管控)
//项目概括
export const getProjectStatistics= data => post('/xmgl/panoramaPlanStatistics/selectProjectStatistics',data)
//关键里程碑延期预警
export const getDanger= data => post('/xmgl/panoramaPlanStatistics/selectKeyNodeEarlyWarningStatistics',data)
//项目延期黑榜
export const getBlackList= data => post('/xmgl/panoramaPlanStatistics/selectProjectDelayBlackList',data)
//项目延期情况统计
export const getProjectDetailList= data => post('/xmgl/panoramaPlanStatistics/selectProjectDelayStatisticsList',data)
//项目区域延期对比
export const getAreaList= data => post('/xmgl/panoramaPlanStatistics/selectRegionDelayComparisonList',data)
//项目区域延期情况
export const getAreaDelayDetail= data => post('/xmgl/panoramaPlanStatistics/selectRegionDelayStatisticsList',data)
//项目区域进度红黑榜
export const getAreaBlackAndRedList= data => post('/xmgl/panoramaPlanStatistics/selectRegionRedBlackList',data)
//考勤预警列表
export const getProjectDelayList= data => post('/xmgl/panoramaPlanStatistics/selectProjectNodeDelayList',data)
//区域延期列表
export const getAreaDamgerList= data => post('/xmgl/panoramaPlanStatistics/selectProjectEarlyWarningList',data)
export const getProjectScoreList = data => post('/xmgl/engineeringScore/selectEngineeringScoreCountList', data)
//获取项目工程评分汇总
export const getAllScore = data => post('/xmgl/engineeringScore/selectEngineeringScoreTotal', data)
//查询项目本年管理行为评分信息统计
export const getAllYearScore = data => post('/xmgl/managerialBehaviorScore/selectThisYearManagerialBehaviorScoreTotal', data)
//查询分页列表查询管理行为评分信息
export const getYearManageInfo = data => post('/xmgl/managerialBehaviorScore/selectPageList', data)
//查询一线公司或工管中心检查情况统计
export const getManageAndCenterDetailList = data => post('/xmgl/managerialBehaviorScore/selectManagerialBehaviorScoreCountList', data)
//(进度管控)
//项目概括
export const getProjectStatistics = data => post('/xmgl/panoramaPlanStatistics/selectProjectStatistics', data)
//关键里程碑延期预警
export const getDanger = data => post('/xmgl/panoramaPlanStatistics/selectKeyNodeEarlyWarningStatistics', data)
//项目延期黑榜
export const getBlackList = data => post('/xmgl/panoramaPlanStatistics/selectProjectDelayBlackList', data)
//项目延期情况统计
export const getProjectDetailList = data => post('/xmgl/panoramaPlanStatistics/selectProjectDelayStatisticsList', data)
//项目区域延期对比
export const getAreaList = data => post('/xmgl/panoramaPlanStatistics/selectRegionDelayComparisonList', data)
//项目区域延期情况
export const getAreaDelayDetail = data => post('/xmgl/panoramaPlanStatistics/selectRegionDelayStatisticsList', data)
//项目区域进度红黑榜
export const getAreaBlackAndRedList = data => post('/xmgl/panoramaPlanStatistics/selectRegionRedBlackList', data)
//考勤预警列表
export const getProjectDelayList = data => post('/xmgl/panoramaPlanStatistics/selectProjectNodeDelayList', data)
//区域延期列表
export const getAreaDamgerList = data => post('/xmgl/panoramaPlanStatistics/selectProjectEarlyWarningList', data)
// 查询项目信息
@ -166,3 +166,11 @@ export const getCompanyInfo = data => post('/xmgl/company/queryBySn', data)
// 查询项目列表
export const getProjectList = data => post('/xmgl/project/selectProjectListByCompany', data)
// 列表查询企业大屏配置信息
export const getCompanyBigScreenConfigListApi = data => get('/xmgl/companyBigScreenConfig/list', data)
// 保存企业大屏配置信息
export const saveEntityCompanyBigScreenConfigApi = data => post('/xmgl/companyBigScreenConfig/saveEntity', data)
// 根据企业账号查询该公司的管辖区域范围(总公司看子级的管辖区域范围,其他公司他自己的管辖区域范围)
export const getRangeAddrByUserIdCompanyBigScreenApi = data => post('/xmgl/companyBigScreen/getRangeAddrByUserId', data)

View File

@ -8,7 +8,7 @@
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title>设备中台</title>
<link rel="stylesheet" href="<%= BASE_URL %>/css/font/myFont.css" />
<script src="https://webapi.amap.com/maps?v=1.4.14&key=1eb65a4a1e436b5314d23b773cd4e658&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.MouseTool,AMap.Geocoder,AMap.Driving" defer="defer"></script>
<script src="https://webapi.amap.com/maps?v=2.0&key=e54076dbf392c14b95373a8aad479579&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.MouseTool,AMap.Geocoder,AMap.Driving,AMap.DistrictSearch" defer="defer"></script>
<script src="/js/ckplayer/ckplayer.js"></script>
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
<script src="/js/config.js"></script>

View File

@ -37,7 +37,12 @@
<title>
智慧工地云平台
</title>
<script src="https://webapi.amap.com/maps?v=1.4.14&key=1eb65a4a1e436b5314d23b773cd4e658&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.MouseTool,AMap.Geocoder,AMap.Driving" defer="defer"></script>
<script src="https://webapi.amap.com/maps?v=2.0&key=e54076dbf392c14b95373a8aad479579&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.MouseTool,AMap.Geocoder,AMap.Driving,AMap.DistrictSearch" defer="defer"></script>
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: "5753c41f7a3e6bce6b328cfb81918895",
};
</script>
<!-- <script
src="https://webapi.amap.com/maps?v=1.4.14&key=1eb65a4a1e436b5314d23b773cd4e658&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.MouseTool,AMap.Geocoder,AMap.Driving"
defer="defer"></script> -->

View File

@ -3,21 +3,39 @@
custom-class="bigdata-dialog"
:visible.sync="innerVisible"
:show-close="false"
width="728px"
:width="!listShow ? '728px' : '1200px'"
@close="handleCancel"
:closable="false"
append-to-body
>
<span slot="title" class="bigdata-dialog-title">
<span>{{ title }}</span>
<img class="bigdata-dialog-close" src="@/assets/images/companyBigScreen/dialog-close.png" alt="关闭" @click="handleCancel" />
<img
class="bigdata-dialog-close"
src="@/assets/images/companyBigScreen/dialog-close.png"
alt="关闭"
@click="handleCancel"
/>
</span>
<span slot="footer" class="dialog-footer">
<div class="info-dialog-footer">
<el-button class="cancel-btn" type="danger" @click="handleCancel">取消</el-button>
<el-button class="confirm-btn" type="primary" @click="handleConfirm">确定</el-button>
<div class="info-dialog-footer" v-if="!listShow">
<el-button class="cancel-btn" type="danger" @click="handleCancel"
>取消</el-button
>
<el-button class="confirm-btn" type="primary" @click="handleConfirm"
>确定</el-button
>
</div>
<pagination
v-else
:total="Number(pageInfo.total)"
:page.sync="pageInfo.pageNo"
:limit.sync="pageInfo.pageSize"
@pagination="onPagination"
:pageSizes="[...$store.state.PAGESIZRS]"
layout="total,sizes, prev, pager, next, jumper"
/>
</span>
<el-scrollbar style="height: 100%; overflow-x: hidden">
<div class="bigdata-dialog-content">
@ -27,45 +45,71 @@
</el-dialog>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
const emit = defineEmits(['update:visible', 'confirm'])
import { ref, watch } from "vue";
const emit = defineEmits(["update:visible", "confirm"]);
const props = defineProps({
visible: {
type: Boolean,
default: false
default: false,
},
title: {
type: String,
default: ''
}
})
default: "",
},
listShow: {
type: Boolean,
default: false,
},
pageInfo: {
type: Object,
default: () => ({
pageNo: 1,
pageSize: 10,
total: 0,
}),
},
});
watch(
() => props.visible,
newVal => {
innerVisible.value = newVal
(newVal) => {
innerVisible.value = newVal;
}
)
);
//
const innerVisible = ref(false)
const innerVisible = ref(false);
const handleCancel = () => {
innerVisible.value = false
emit('update:visible', false)
}
innerVisible.value = false;
emit("update:visible", false);
};
const handleConfirm = () => {
emit('confirm')
}
emit("confirm");
};
const onPagination = () => {
emit("pagination", props.pageInfo);
};
</script>
<style scoped lang="less">
:deep(.pagination-container) {
background-color: transparent;
padding: 0;
.el-pagination__total,
.el-pagination__jump {
color: white;
}
}
</style>
<style lang="less">
.bigdata-dialog {
height: 540px;
width: 728px;
background-color: transparent !important;
padding: 0 !important;
background-image: url('~@/assets/images/companyBigScreen/dialog-bg.png');
background-image: url("~@/assets/images/companyBigScreen/dialog-bg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
.el-dialog__body {

View File

@ -2,7 +2,10 @@
<div class="big-card">
<div class="card-header">
<span class="card-title">{{ title }}</span>
<img v-if="isEdit" @click="handleEdit" class="card-header-icon" src="@/assets/images/companyBigScreen/card-edit-icon.png" alt="icon" />
<div class="card-right" v-if="isEdit">
<span @click="handleSubTitle" v-if="subTitle" class="card-subtitle">{{ subTitle }}</span>
<img @click="handleEdit" class="card-header-icon" src="@/assets/images/companyBigScreen/card-edit-icon.png" alt="icon" />
</div>
</div>
<div class="card-body">
<slot></slot>
@ -20,12 +23,19 @@ const props = defineProps({
isEdit: {
type: Boolean,
default: true
},
subTitle: {
type: String,
default: ''
}
})
const handleEdit = () => {
console.log('编辑')
emit('edit')
}
const handleSubTitle = () => {
emit('subTitle')
}
</script>
<style scoped lang="less">
@ -55,6 +65,15 @@ const handleEdit = () => {
color: #ffffff;
text-align: left;
}
.card-right {
display: flex;
.card-subtitle {
font-family: Alibaba PuHuiTi, Alibaba PuHuiTi;
font-weight: 400;
font-size: 16px;
color: #74E3FF;
}
}
.card-header-icon {
visibility: hidden;
width: 24px;
@ -62,6 +81,7 @@ const handleEdit = () => {
cursor: pointer;
user-select: none;
-webkit-user-drag: none;
margin-left: 40px;
}
}
.card-body {

View File

@ -1,8 +1,8 @@
<template>
<Card title="设备数量" :isEdit="false">
<Card title="设备数量" subTitle="各项目设备列表" @subTitle="onDeviceListDialogShow" @edit="handleEdit">
<el-scrollbar style="height: 100%; overflow-x: hidden">
<div class="device-tabs">
<div class="device-item">
<div class="device-item" v-if="companyBigScreenConfigList.enableVideoDev == 1">
<div class="device-item-icon">
<img src="@/assets/images/companyBigScreen/device-monitor.png" alt="" />
</div>
@ -11,7 +11,7 @@
<span class="value">{{ deviceInfo.videoNum }}</span>
</div>
</div>
<div class="device-item">
<div class="device-item" v-if="companyBigScreenConfigList.enableDustDev == 1">
<div class="device-item-icon">
<img src="@/assets/images/companyBigScreen/device-dust.png" alt="" />
</div>
@ -20,34 +20,101 @@
<span class="value">{{ deviceInfo.environmentDevNum }}</span>
</div>
</div>
<div class="device-item" v-if="companyBigScreenConfigList.enablePoliceCameraDev == 1">
<div class="device-item-icon">
<img src="@/assets/images/companyBigScreen/device-bodyworncamera.png" alt="" />
</div>
<div class="device-item-value">
<span>执法记录仪</span>
<span class="value">{{ deviceInfo.policeCameraNum }}</span>
</div>
</div>
<div class="device-item" v-if="companyBigScreenConfigList.enableCarCameraDev == 1">
<div class="device-item-icon">
<img src="@/assets/images/companyBigScreen/device-barriergate.png" alt="" />
</div>
<div class="device-item-value">
<span>车辆道闸</span>
<span class="value">{{ deviceInfo.carCameraNum }}</span>
</div>
</div>
<div class="device-item" v-if="companyBigScreenConfigList.enableAiAnalyseDev == 1">
<div class="device-item-icon">
<img src="@/assets/images/companyBigScreen/device-ai.png" alt="" />
</div>
<div class="device-item-value">
<span>AI设备</span>
<span class="value">{{ deviceInfo.aiAnalyseHardNum }}</span>
</div>
</div>
<div class="device-item" v-if="companyBigScreenConfigList.enableFrontierProtectionDev == 1">
<div class="device-item-icon">
<img src="@/assets/images/companyBigScreen/device-edge.png" alt="" />
</div>
<div class="device-item-value">
<span>临边防护监测</span>
<span class="value">{{ deviceInfo.frontierProtectionDevNum }}</span>
</div>
</div>
</div>
<el-table :data="tableList" tooltip-effect="dark">
<el-table-column label="项目名称" align="center">
<template slot-scope="scope">{{ scope.row.projectName }}</template>
</el-table-column>
<el-table-column label="摄像头数量" align="center">
<template slot-scope="scope">{{ scope.row.videoNum }}</template>
</el-table-column>
<el-table-column label="扬尘设备数量" align="center">
<template slot-scope="scope">{{ scope.row.environmentDevNum }}</template>
</el-table-column>
</el-table>
</el-scrollbar>
<DeviceDialog ref="deviceDialogRef" @refresh="getDeviceConfig" />
<DeviceListDialog ref="deviceListDialogRef" />
</Card>
</template>
<script setup>
import Card from './card.vue'
import { ref } from 'vue'
import Card from './card.vue';
import { ref, onMounted } from 'vue';
import DeviceDialog from './deviceDialog.vue';
import DeviceListDialog from './deviceListDialog.vue';
import {
getCompanyBigScreenConfigListApi
} from "@/assets/js/api/companyBigScreen.js";
const deviceInfo = ref({})
const tableList = ref([])
const deviceDialogRef = ref(null)
const companyBigScreenConfigList = ref({})
const deviceListDialogRef = ref(null)
const projectSn = ref('');
const initDeviceData = (data) => {
console.log(data, 'DeviceData')
deviceInfo.value = data
tableList.value = data.projectDevStatList || []
}
const getDeviceConfig = () => {
getCompanyBigScreenConfigList();
};
const handleEdit = () => {
deviceDialogRef.value.showModal(companyBigScreenConfigList.value)
}
const onDeviceListDialogShow = () => {
console.log("设备列表", tableList.value)
deviceListDialogRef.value.showModal({
tableList: tableList.value,
companyBigScreenConfigList: companyBigScreenConfigList.value
})
}
onMounted(() => {
projectSn.value = JSON.parse(sessionStorage.getItem("vuex")).userInfo.sn;
getCompanyBigScreenConfigList();
})
//
const getCompanyBigScreenConfigList = () => {
const data = { sn: projectSn.value };
getCompanyBigScreenConfigListApi(data).then((res) => {
if (res.code == 200) {
if(res.result.length > 0) {
companyBigScreenConfigList.value = res.result[0];
}
}
});
};
defineExpose({
initDeviceData
@ -63,6 +130,7 @@ defineExpose({
height: 66px;
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
padding: 0 20px;
@ -71,6 +139,9 @@ defineExpose({
background-repeat: no-repeat;
box-sizing: border-box;
margin-bottom: 12px;
> .device-item:nth-child(n + 3) {
margin-top: 20px;
}
.device-item {
display: flex;
align-items: center;
@ -112,20 +183,6 @@ defineExpose({
}
}
}
::v-deep(.el-table thead) {
font-size: 16px;
color: #ffffff;
background-image: url('~@/assets/images/companyBigScreen/device-th-bg.png');
background-size: 100% 100%;
background-repeat: no-repeat;
}
::v-deep(.el-table tr) {
background-color: transparent;
color: #ffffff;
}
::v-deep(.el-table th.el-table__cell) {
background-color: transparent;
}
::v-deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}

View File

@ -0,0 +1,222 @@
<template>
<BDialog title="设备管理" :visible.sync="visible" @close="closeModal" @confirm="handleConfirm">
<div class="info-dialog">
<el-form :model="fromData" :inline="true" label-width="100px" label-position="top">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="摄像头数量统计">
<el-switch v-model="fromData.enableVideoDev" />
</el-form-item>
<el-form-item label="扬尘设备监测数量统计">
<el-switch v-model="fromData.enableDustDev" />
</el-form-item>
<el-form-item label="执法记录仪监测数量统计">
<el-switch v-model="fromData.enablePoliceCameraDev" />
</el-form-item>
<el-form-item label="车辆道闸设备监测数量统计">
<el-switch v-model="fromData.enableCarCameraDev" />
</el-form-item>
<el-form-item label="AI设备监测数量统计">
<el-switch v-model="fromData.enableAiAnalyseDev" />
</el-form-item>
<el-form-item label="临边防护监测数量统计">
<el-switch v-model="fromData.enableFrontierProtectionDev" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</BDialog>
</template>
<script setup>
import BDialog from './b-dialog.vue'
import { ref } from 'vue'
import store from '@/store'
import { Message } from 'element-ui'
import {
saveEntityCompanyBigScreenConfigApi
} from "@/assets/js/api/companyBigScreen.js";
const visible = ref(false)
const editId = ref(null)
const emit = defineEmits(['refresh'])
function showModal(data) {
if (data) {
fromData.value.enableVideoDev = data.enableVideoDev == 1 ? true : false;
fromData.value.enableDustDev = data.enableDustDev == 1 ? true : false;
fromData.value.enablePoliceCameraDev = data.enablePoliceCameraDev == 1 ? true : false;
fromData.value.enableCarCameraDev = data.enableCarCameraDev == 1 ? true : false;
fromData.value.enableAiAnalyseDev = data.enableAiAnalyseDev == 1 ? true : false;
fromData.value.enableFrontierProtectionDev = data.enableFrontierProtectionDev == 1 ? true : false;
}
visible.value = true
}
function closeModal() {
visible.value = false
}
const fromData = ref({
enableVideoDev: false,
enableDustDev: false,
enablePoliceCameraDev: false,
enableCarCameraDev: false,
enableAiAnalyseDev: false,
enableFrontierProtectionDev: false,
})
const handleConfirm = () => {
const params = {
// projectSn: store.state.userInfo.sn,
companySn: store.state.userInfo.sn,
enableVideoDev: fromData.value.enableVideoDev ? 1 : 0,
enableDustDev: fromData.value.enableDustDev ? 1 : 0,
enablePoliceCameraDev: fromData.value.enablePoliceCameraDev ? 1 : 0,
enableCarCameraDev: fromData.value.enableCarCameraDev ? 1 : 0,
enableAiAnalyseDev: fromData.value.enableAiAnalyseDev ? 1 : 0,
enableFrontierProtectionDev: fromData.value.enableFrontierProtectionDev ? 1 : 0,
}
saveEntityCompanyBigScreenConfigApi(params).then(res => {
console.log(res)
if (res.code === 200) {
Message.success('操作成功')
emit('refresh')
closeModal()
}
})
}
defineExpose({
showModal
})
</script>
<style scoped lang="less">
:deep(.el-form-item) {
width: 100%;
display: inline-flex;
margin-bottom: 0px;
.el-form-item__label {
padding: 0;
}
.el-form-item__content {
text-align: right;
flex: 1;
}
}
.company-info-dialog {
width: 100%;
height: 100%;
box-sizing: border-box;
}
::v-deep(.el-form-item__label) {
color: #fff;
}
::v-deep(.el-input__inner) {
background: rgba(27, 68, 121, 0.3);
border-radius: 4px 4px 4px 4px;
border: 1px solid #7e98c8;
color: #fff;
}
::v-deep(.el-textarea__inner) {
background: rgba(27, 68, 121, 0.3);
border-radius: 4px 4px 4px 4px;
border: 1px solid #7e98c8;
color: #fff;
}
::v-deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}
.block {
height: 1px;
width: 100%;
}
.info-list {
display: flex;
flex-direction: column;
gap: 10px;
.info-item {
width: 100%;
display: flex;
gap: 10px;
position: relative;
.info-label {
width: 50%;
vertical-align: middle;
font-size: 14px;
color: #fff;
line-height: 40px;
padding: 0 12px 0 0;
box-sizing: border-box;
}
.info-delete {
cursor: pointer;
font-size: 16px;
color: #fff;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}
.info-input {
width: calc(50% - 16px);
}
}
}
.info-tip {
font-size: 12px;
color: #fff;
line-height: 36px;
box-sizing: border-box;
}
</style>
<style lang="less">
.b-upload .el-upload {
border: 1px dashed rgba(96, 143, 243, 0.3);
cursor: pointer;
position: relative;
overflow: hidden;
background: #0e2749;
box-sizing: border-box;
}
.b-upload .el-upload:hover {
border-color: #608ff3;
}
.b-upload-icon {
font-size: 28px;
color: #8c939d;
width: 294px;
height: 166px;
line-height: 166px;
text-align: center;
}
.b-upload-img {
width: 294px;
height: 166px;
display: block;
}
.b-upload-close {
position: absolute;
right: 0px;
top: 0px;
font-size: 16px;
color: red;
}
</style>

View File

@ -0,0 +1,91 @@
<template>
<BDialog title="设备列表" :pageInfo="pageInfo" :listShow="true" :visible.sync="visible" @pagination="onPagination" @close="closeModal">
<div class="info-dialog">
<el-table :data="tableListUp" :height="370" tooltip-effect="dark">
<el-table-column label="项目名称" align="center">
<template slot-scope="scope">{{ scope.row.projectName }}</template>
</el-table-column>
<el-table-column v-if="companyBigScreenConfigList.enableVideoDev == 1" label="摄像头数量" align="center">
<template slot-scope="scope">{{ scope.row.videoNum }}</template>
</el-table-column>
<el-table-column v-if="companyBigScreenConfigList.enableDustDev == 1" label="扬尘设备数量" align="center">
<template slot-scope="scope">{{ scope.row.environmentDevNum }}</template>
</el-table-column>
<el-table-column v-if="companyBigScreenConfigList.enablePoliceCameraDev == 1" label="执法记录仪设备监测数量" align="center">
<template slot-scope="scope">{{ scope.row.policeCameraNum }}</template>
</el-table-column>
<el-table-column v-if="companyBigScreenConfigList.enableCarCameraDev == 1" label="车辆道闸设备监测数量" align="center">
<template slot-scope="scope">{{ scope.row.carCameraNum }}</template>
</el-table-column>
<el-table-column v-if="companyBigScreenConfigList.enableAiAnalyseDev == 1" label="AI设备监测数量" align="center">
<template slot-scope="scope">{{ scope.row.aiAnalyseHardNum }}</template>
</el-table-column>
<el-table-column v-if="companyBigScreenConfigList.enableFrontierProtectionDev == 1" label="临边防护监测数量" align="center">
<template slot-scope="scope">{{ scope.row.frontierProtectionDevNum }}</template>
</el-table-column>
</el-table>
</div>
</BDialog>
</template>
<script setup>
import BDialog from './b-dialog.vue'
import { computed, reactive, ref } from 'vue'
import store from '@/store'
import { Message } from 'element-ui'
const visible = ref(false)
const tableList = ref([])
const pageInfo = reactive({
pageNo: 1,
pageSize: 10,
total: 0,
})
const companyBigScreenConfigList = ref({});
const emit = defineEmits(['refresh'])
function showModal(data) {
console.log(334455, data)
tableList.value = data.tableList;
companyBigScreenConfigList.value = data.companyBigScreenConfigList;
pageInfo.total = data.tableList.length;
visible.value = true
}
function closeModal() {
visible.value = false
}
const fromData = ref({
isCustom: false,
})
const onPagination = (data) => {
pageInfo.pageNo = data.pageNo;
pageInfo.pageSize = data.pageSize;
}
const tableListUp = computed(() => {
return tableList.value.length > 0 ? tableList.value.slice((pageInfo.pageNo - 1) * pageInfo.pageSize, pageInfo.pageNo * pageInfo.pageSize) : []
})
defineExpose({
showModal
})
</script>
<style scoped lang="less">
::v-deep(.el-table thead) {
font-size: 16px;
color: #ffffff;
background-image: url('~@/assets/images/companyBigScreen/device-th-bg.png');
background-size: 100% 100%;
background-repeat: no-repeat;
}
::v-deep(.el-table tr) {
background-color: transparent;
color: #ffffff;
}
::v-deep(.el-table th.el-table__cell) {
background-color: transparent;
}
</style>

View File

@ -1,15 +1,9 @@
<template>
<div class="bigScreen-wrap">
<headers></headers>
<transition
enter-class="animate__fadeInRight"
enter-to-class="animate__fadeInRight"
enter-active-class="animate__fadeInRight"
leave-class="animate__fadeOutRight"
leave-to-class="animate__fadeOutRight"
leave-active-class="animate__fadeOutRight"
appear
>
<transition enter-class="animate__fadeInRight" enter-to-class="animate__fadeInRight"
enter-active-class="animate__fadeInRight" leave-class="animate__fadeOutRight"
leave-to-class="animate__fadeOutRight" leave-active-class="animate__fadeOutRight" appear>
<right ref="rightRef" />
</transition>
<div class="map-container" id="map">
@ -19,118 +13,248 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Statistics from './components/statistics.vue'
import headers from './components/header.vue'
import right from './components/right.vue'
import { ref, onMounted } from "vue";
import Statistics from "./components/statistics.vue";
import headers from "./components/header.vue";
import right from "./components/right.vue";
import {
getProjectList,
selectCooperateEnterpriseList,
selectAllProjectInfoList,
} from '@/assets/js/api/companyBigScreen.js'
getRangeAddrByUserIdCompanyBigScreenApi
} from "@/assets/js/api/companyBigScreen.js";
//
const mapObj = ref(null)
const projectSn = ref('')
const CooperateEnterpriseList = ref([])
const allProjectData = ref([])
const statisticsData = ref(null)
const statisticsRef = ref(null)
const rightRef = ref(null)
const mapObj = ref(null);
const projectSn = ref("");
const CooperateEnterpriseList = ref([]);
const allProjectData = ref([]);
const statisticsData = ref(null);
const statisticsRef = ref(null);
const rightRef = ref(null);
//
const initMap = () => {
mapObj.value = new AMap.Map('map', {
resizeEnable: true,
mapObj.value = new AMap.Map("map", {
zoom: 5,
mapStyle: 'amap://styles/darkblue',
expandZoomRange: true, //
zooms: [3, 20],
center: [116.333926, 39.997245],
zoomEnable: true, //
resizeEnable: true,
mapStyle: "amap://styles/darkblue",
rotateEnable: true,
pitchEnable: true,
pitch: 50,
buildingAnimation: true,
expandZoomRange: true,
zooms: [3, 20],
center: [116.333926, 39.997245]
})
}
});
getAllProjectInfoList();
};
//
const addMarker = () => {
mapObj.value.clearMap()
const addMarker = (maskPolygon) => {
mapObj.value.clearMap();
allProjectData.value.forEach((data, i) => {
const lng = data.longitude
const lat = data.latitude
const IconUrl = new AMap.Icon({
size: new AMap.Size(36, 36),
image: require('@/assets/images/companyBigScreen/location.svg'),
imageSize: new AMap.Size(36, 36),
imageOffset: new AMap.Pixel(0, 0)
})
const marker = new AMap.Marker({
icon: IconUrl,
map: mapObj.value,
position: [lng, lat],
offset: new AMap.Pixel(-20, -20)
})
marker.setLabel({
direction: 'bottom',
content: `<div class="marker-content">${data.projectName}</div>`
})
marker.on('click', (e) => {
console.log('点击了坐标点', data)
marker.value = marker
mapObj.value.setCenter([e.lnglat.getLng(), e.lnglat.getLat()])
})
})
mapObj.value.setFitView()
}
const lng = data.longitude;
const lat = data.latitude;
const isPointInRing = AMap.GeometryUtil.isPointInRing(
[lng, lat],
maskPolygon
);
// console.log(maskPolygon, isPointInRing,data);
//
if (isPointInRing) {
const IconUrl = new AMap.Icon({
size: new AMap.Size(36, 36),
image: require("@/assets/images/companyBigScreen/location.svg"),
imageSize: new AMap.Size(36, 36),
imageOffset: new AMap.Pixel(0, 0),
});
const marker = new AMap.Marker({
icon: IconUrl,
map: mapObj.value,
position: [lng, lat],
offset: new AMap.Pixel(-20, -20),
});
marker.setLabel({
direction: "bottom",
content: `<div class="marker-content">${data.projectName}</div>`,
});
marker.on("click", (e) => {
console.log("点击了坐标点", data);
marker.value = marker;
mapObj.value.setCenter([e.lnglat.getLng(), e.lnglat.getLat()]);
});
}
});
// mapObj.value.setFitView();
};
//
const getCooperateEnterpriseList = () => {
const data = { sn: projectSn.value }
selectCooperateEnterpriseList(data).then(res => {
const data = { sn: projectSn.value };
selectCooperateEnterpriseList(data).then((res) => {
if (res.code == 200) {
CooperateEnterpriseList.value = res.result
CooperateEnterpriseList.value = res.result;
}
})
}
});
};
//
const getAllProjectInfoList = () => {
const data = { sn: projectSn.value }
selectAllProjectInfoList(data).then(res => {
const getAllProjectInfoList = (maskPolygon) => {
const data = { sn: projectSn.value };
selectAllProjectInfoList(data).then((res) => {
if (res.code == 200) {
allProjectData.value = res.result
addMarker()
allProjectData.value = res.result;
addMarker(maskPolygon);
}
})
}
});
};
//
const getProjectListData = async () => {
const res = await getProjectList({ companySn: projectSn.value })
const res = await getProjectList({ companySn: projectSn.value });
statisticsData.value = {
buildProject: res.result.buildProject,
projectTotal: res.result.projectTotal,
completeProject: res.result.completeProject,
newProject: res.result.newProject
}
statisticsRef.value.initData(statisticsData.value)
rightRef.value.initData(res.result)
}
newProject: res.result.newProject,
};
statisticsRef.value.initData(statisticsData.value);
console.log(333333, res);
rightRef.value.initData(res.result);
};
const getRangeAddrByUserIdCompanyBigScreen = () => {
getRangeAddrByUserIdCompanyBigScreenApi({
companySn: projectSn.value
}).then((res) => {
if (res.code == 200) {
const resultList = res.result.reduce((prev, cur) => {
const rangeAddrList = cur.rangeAddr && JSON.parse(cur.rangeAddr);
console.log(rangeAddrList instanceof Array,cur)
if(rangeAddrList instanceof Array && rangeAddrList.length > 0) {
rangeAddrList.forEach(item => {
console.log(prev.includes(item))
if(prev.includes(item)) return
prev.push(item)
})
}
return prev
}, []);
showProvinceMask(resultList);
console.log(112233, resultList);
}
});
};
//
onMounted(() => {
projectSn.value = JSON.parse(sessionStorage.getItem('vuex')).userInfo.sn
initMap()
getProjectListData()
getCooperateEnterpriseList()
getAllProjectInfoList()
})
projectSn.value = JSON.parse(sessionStorage.getItem("vuex")).userInfo.sn;
getRangeAddrByUserIdCompanyBigScreen();
// showProvinceMask(["广", "", ""]);
// initMap();
getProjectListData();
getCooperateEnterpriseList();
});
const directCities = ["北京市", "天津市", "上海市", "重庆市"];
const specialRegions = ["香港特别行政区", "澳门特别行政区"];
function getLevelByName(name) {
if (
name.endsWith("省") ||
name.endsWith("自治区") ||
specialRegions.includes(name) ||
directCities.includes(name)
) {
return "province";
}
if (name.endsWith("市")) {
//
return directCities.includes(name) ? "province" : "city";
}
//
return "district";
}
const showProvinceMask = (provinceNames) => {
const maskBoundaries = [];
const maskPolygon = provinceNames.reduce((prev, cur) => {
prev.push([]);
return prev
}, []);
const mask = [];
let center = null; //
//
const searchNext = (index) => {
if (index >= provinceNames.length) {
//
mapObj.value = new AMap.Map("map", {
mask: mask, //
zoom: 7,
expandZoomRange: true,
zooms: [3, 20],
center: center,
viewMode: "3D",
zoomEnable: true,
resizeEnable: true,
mapStyle: "amap://styles/darkblue",
backgroundColor: "transparent",
});
getAllProjectInfoList(maskPolygon);
maskBoundaries.forEach((item) => {
//
const polygon = new AMap.Polygon({
path: item,
strokeColor: "#1791fc",
strokeWeight: 2,
fillColor: "#1791fc",
fillOpacity: 0.1,
zIndex: 11,
});
mapObj.value.add(polygon);
});
return;
}
const level = getLevelByName(provinceNames[index]);
//
const district = new AMap.DistrictSearch({
subdistrict: 0,
extensions: "all",
level: level,
});
district.search(provinceNames[index], (status, result) => {
if (status === "complete" && result.districtList.length) {
const boundaries = result.districtList[0].boundaries;
console.log(11122223332, boundaries, index)
if (boundaries.length) {
for (let i = 0; i < boundaries.length; i++) {
mask.push([boundaries[i]]);
let arr = boundaries[i];
arr.map((item) => {
maskPolygon[index].push([item.lng, item.lat]);
});
maskBoundaries.push(boundaries[i]); //
}
if (!center) {
//
const c = result.districtList[0].center;
center = [c.lng, c.lat];
}
}
}
//
searchNext(index + 1);
});
};
searchNext(0);
};
</script>
<style lang="less" scoped>
@import './animate/animate.min.css';
@import "./animate/animate.min.css";
.bigScreen-wrap {
width: 100%;
height: 100%;
@ -139,24 +263,28 @@ onMounted(() => {
position: relative;
color: #fff;
// background: #0a141c;
background: url('~@/assets/images/companyBigScreen/big-screen-bg.png') center no-repeat;
background: url("~@/assets/images/companyBigScreen/big-screen-bg.png") center no-repeat;
background-size: 100% 100%;
overflow: hidden;
:deep(.amap-marker-label) {
padding: 0;
border: none;
background: transparent;
}
}
.active-color {
color: #02fbe2;
}
.map-container {
width: calc(100% - 60px - 450px);
height: calc(100% - 66px - 40px);
position: absolute;
top: 86px;
left: 20px;
background: transparent !important;
}
/*滚动条整体部分,必须要设置*/
@ -165,16 +293,19 @@ onMounted(() => {
height: 26px;
background-color: transparent;
}
/*滚动条的轨道*/
::-webkit-scrollbar-track {
background-color: transparent;
}
/*滚动条的滑块按钮*/
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: rgba(4, 106, 169, 0.3);
box-shadow: inset 0 0 5px rgba(4, 186, 169, 0.3);
}
/*滚动条的上下两端的按钮*/
::-webkit-scrollbar-button {
height: 0;